Search code examples
verilogfpgahdl

Verilog Vending machine FSM


I am trying to build a finite state machine in verilog for a vending machine that accepts 5,10, 25 cents as inputs and then output a a soda or diet and also output the appropriate change(as the number of nickels). I am currently getting an error that says ERROR:HDLCompiler:806 - "D:/Xilinx Stuff/FSM/FSM.v" Line 128: Syntax error near "endmodule". I am fairly new to verilog and whilst I get that this is probably a silly error like forgetting a semi-colon or something, I just cannot for the life of me find it. My code is below:

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 

Solution

  • I'm not sure why you are using:

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

    the standard coding style would be to use:

    always @(current_state or quarter or nickel or dime)
    

    With Verilog 2001 or System Verilog you can use a comma separated sensitivity list as follows:

    always @(current_state, quarter, nickel, dime)
    

    Finally in verilog 2001 and later, you can use a wildcard for combinatorial logic always blocks:

    always @(*)
    

    If you need to debounce your inputs or make sure no more than one of the coin signals is asserted at a time, that should probably be done outside of the state machine.