1
votes

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 
2
it looks like your second always doesn't have a matching end for its begin. - BlamKiwi
Thanks problem solved! - KoolaidLips
my only other advice is that you should separate your next state logic from your output logic. although it wont help much with Xilinix (some HDL compilers care) it helps a ton with readability. - BlamKiwi
To balance between area cost and module speed you can change state encoding to one-hot. This is implementation of a small algorithm. In case of bigger implementation can be used Compostional Microprogram Control Unit methodology: books.google.pl/… zbc.uz.zgora.pl/Content/14668/… pe.org.pl/articles/2014/12/6.pdf - user1785960

2 Answers

2
votes

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.

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