Verilog 自动售货机 FSM

Verilog Vending machine FSM

我正在尝试在 verilog 中为自动售货机构建一个有限状态机,它接受 5、10、25 美分作为输入,然后输出苏打水或饮食,并输出适当的零钱(作为五分硬币的数量) .我目前收到一条错误消息,显示 ERROR:HDLCompiler:806 - "D:/Xilinx Stuff/FSM/FSM.v" 第 128 行:"endmodule" 附近的语法错误。 我对 verilog 还很陌生,虽然我知道这可能是一个愚蠢的错误,比如忘记了分号或其他东西,但我终其一生都找不到它。我的代码如下:

module FSM(quarter, nickel, dime, soda, diet,clk, reset, change_count, give_soda,give_diet);
    input quarter, nickel, dime, soda, diet,clk, reset,give_soda,give_diet;
    output change_count;
    reg[3:0] current_state, next_state;
    parameter cent0 = 0, cent5= 1, cent10 = 2, cent15=3, cent20 =4, cent25 =5, cent30=6,cent35=7,cent40=8;

    always @(posedge clock or posedge reset)
        begin
            if(reset)
            begin
                current_state = cent0;
            end
            else
                current_state = next_state;
        end

    always @(current_state | ((quarter ^ nickel) ^ dime))
        begin
        case(current_state)
            cent0: begin
                if(nickel)  
                        next_state = cent5;
                else if(dime)
                        next_state = cent10;
                else if(quarter)
                        next_state = cent25;
                end
            cent5: begin
                if(nickel)  
                        next_state = cent10;
                else if(dime)
                        next_state = cent15;
                else if(quarter)
                        next_state = cent30;
                end
            cent10: begin
                if(nickel)  
                        next_state = cent15;
                else if(dime)
                        next_state = cent20;
                else if(quarter)
                        next_state = cent35;
                end
            cent15: begin
                if(nickel)  
                        next_state = cent20;
                else if(dime)
                        next_state = cent25;
                else if(quarter)
                        next_state = cent40;
                end
            cent20: begin
                if(nickel)  
                        next_state = cent25;
                else if(dime)
                        next_state = cent30;
                else if(quarter)
                        next_state = cent0;
                        if(soda)    
                                give_soda = 1;
                        else if(diet)
                                give_diet = 1;
                end
                cent25: begin
                    if(nickel)  
                            next_state = cent30;
                    else if(dime)
                            next_state = cent35;
                    else if(quarter)
                            next_state = cent0;
                            change_count = 1;
                            if(soda)    
                                    give_soda = 1;
                            else if(diet)
                                    give_diet = 1;
                    end
                cent30: begin
                    if(nickel)
                            next_state = cent35;
                    else if(dime)
                            next_state = cent40;
                    else if(quarter)
                            next_state = cent0;
                            change_count = 2;
                            if(soda)    
                                    give_soda = 1;
                            else if(diet)
                                    give_diet = 1;
                    end
                cent35: begin
                    if(nickel)
                            next_state = cent40;
                    else if(dime)
                            next_state = cent40;
                    else if(quarter)
                            next_state = cent0;
                            change_count = 2;
                            if(soda)
                                    give_soda = 1;
                            else if(diet)
                                    give_diet = 1;
                    end
                cent40: begin
                    if(nickel)
                            next_state = cent0;
                            if(soda)
                                    give_soda = 1;
                            else if(diet)
                                    give_diet = 1;
                    else if(dime)
                            next_state = cent0;
                            change_count = 1;
                            if(soda)
                                    give_soda = 1;
                            else if(diet)
                                    give_diet = 1;
                    else if(quarter)
                            next_state = cent0;
                            change_count = 4;
                            if(soda)
                                    give_soda = 1;
                            else if(diet)
                                    give_diet = 1;
                    end
                default: next_state = current_state;
                endcase


endmodule 

我不确定你为什么使用:

always @(current_state | ((quarter ^ nickel) ^ dime))

标准编码风格将使用:

always @(current_state or quarter or nickel or dime)

对于 Verilog 2001 或 System Verilog,您可以使用逗号分隔的敏感度列表,如下所示:

always @(current_state, quarter, nickel, dime)

最后在 verilog 2001 及更高版本中,您可以对组合逻辑始终块使用通配符:

always @(*)

如果您需要对输入进行去抖动或确保一次断言的硬币信号不超过一个,则可能应该在状态机之外完成。

//this is the correct verilog code,

module FSM(quarter, nickel, dime, soda, diet,clk, reset, current_state, next_state, change_count, give_soda, give_diet);
input quarter, nickel, dime, soda, diet,clk, reset;
output [3:0] current_state; 
 output next_state, change_count, give_soda, give_diet;
reg current_state, change_count, next_state, give_soda, give_diet;
parameter cent0 = 0, cent5= 1, cent10 = 2, cent15=3, cent20 =4, cent25 =5, cent30=6,cent35=7,cent40=8;

always @(posedge clk or posedge reset)
    begin
        if(reset)
            current_state = cent0;
        else
            current_state = next_state;
    end

always @(nickel or dime or quarter)
    begin
    case(current_state)
        cent0: begin
            if(nickel)  
                    next_state = cent5;
            else if(dime)
                    next_state = cent10;
            else if(quarter)
                    next_state = cent25;
            end
        cent5: begin
            if(nickel)  
                    next_state = cent10;
            else if(dime)
                    next_state = cent15;
            else if(quarter)
                    next_state = cent30;
            end
        cent10: begin
            if(nickel)  
                    next_state = cent15;
            else if(dime)
                    next_state = cent20;
            else if(quarter)
                    next_state = cent35;
            end
        cent15: begin
            if(nickel)  
                    next_state = cent20;
            else if(dime)
                    next_state = cent25;
            else if(quarter)
                    next_state = cent40;
            end
        cent20: begin
            if(nickel)  
                    next_state = cent25;
            else if(dime)
                    next_state = cent30;
            else if(quarter)
                    next_state = cent0;
                    if(soda)    
                            give_soda = 1;
                    else if(diet)
                            give_diet = 1;
            end
            cent25: begin
                if(nickel)  
                        next_state = cent30;
                else if(dime)
                        next_state = cent35;
                else if(quarter)
                        next_state = cent0;
                        change_count = 1;
                        if(soda)    
                                give_soda = 1;
                        else if(diet)
                                give_diet = 1;
                end
            cent30: begin
                if(nickel)
                        next_state = cent35;
                else if(dime)
                        next_state = cent40;
                else if(quarter)
                        next_state = cent0;
                        change_count = 2;
                        if(soda)    
                                give_soda = 1;
                        else if(diet)
                                give_diet = 1;
                end
            cent35: begin
                if(nickel)
                        next_state = cent40;
                else if(dime)
                        next_state = cent40;
                else if(quarter)
                        next_state = cent0;
                        change_count = 2;
                        if(soda)
                                give_soda = 1;
                        else if(diet)
                                give_diet = 1;
                end
            cent40: begin
                if(nickel)
                        next_state = cent0;
                        if(soda)
                                give_soda = 1;
                        else if(diet)
                                give_diet = 1;
                else if(dime)
                        next_state = cent0;
                        change_count = 1;
                        if(soda)
                                give_soda = 1;
                        else if(diet)
                                give_diet = 1;
                else if(quarter)
                        next_state = cent0;
                        change_count = 4;
                        if(soda)
                                give_soda = 1;
                        else if(diet)
                                give_diet = 1;
                end
            default: next_state = current_state;
            endcase
end

endmodule