Verilog自动售货机FSM

时间:2015-02-04 23:45:07

标签: verilog fpga hdl

我正在尝试在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 

2 个答案:

答案 0 :(得分:2)

我不确定你使用的原因:

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 @(*)

如果您需要对输入进行去抖动或确保一次确定不超过一个硬币信号,则应该在状态机外部进行。

答案 1 :(得分:-1)

//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

endmodule