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