I need help with a state machine. I have the state diagram and I need someone to
ID: 2991220 • Letter: I
Question
I need help with a state machine. I have the state diagram and I need someone to help me with the verilog code. The vending machine on my design dispenses soda and water at the same price, 25cents. When the 25 cents are collected the dispense state prompts the user to chose between water and soda. Also reset is an option at any state and the machine will return change and will go back to state Zero
Inputs: N,D,Q,S,W,reset, clock;
//Nickel, dime, quarter, soda, water, reset, clock
Outputs: RN,RD,RND,R2D,RS,RW;
//Return nickel, return dime, return dime and nickel, return 2 dimes, return soda, return water;
Explanation / Answer
module vending_machine(nickel, quarter, dime, clk_in, reset, segments, digit);
input nickel, quarter, dime, clk_in, reset;
output reg [7:0] segments;
output reg [3:0] digit;
wire clk, disp_clk, vend;
wire [5:0] sum, change;
wire [2:0] state;
reg [5:0] select;
reg [1:0] choice;
reg [7:0] disp;
clock_divider1 divider(.clkin(clk_in),.clkout(clk)); //slow clock
clock_divider2 divider2(.clkin(clk_in),.clkout(disp_clk)); //fast clock
controller my_controller(nickel, dime, quarter, clk, state, reset, change, sum, vend);
/*Code to display results on the 7-seg displays should follow*/
initial begin
choice <= 0;
disp <= 8'b0;
end
always @ (posedge clk) begin
if (change) begin //display C when there's change
select <= change;
disp <= 8'b01100011; //C
end
else if (vend && !change) begin //there's no change, again
select <= 1;
disp <= 8'b00010001; //A
end
else if (reset || state == 6) begin // if reset or reset state
select <= 1;
disp <= 8'b01100001; //E
end
else if (state == 0 || state == 1 || state == 2 || state == 3)begin //o-wise an E
select <= sum;
disp <= 8'b01100001; //E
end
end
always @ (posedge disp_clk) begin
case (choice)
0: begin
choice <= 1;
digit <= 4'b1110;
segments <= disp; //letters
end
1: begin
choice <= 2;
digit <= 4'b0111;
case (select)
20 : begin
segments <= 8'b00000011; //0 - 20
end
15 : begin
segments <= 8'b01001001; //5 - 15
end
10 : begin
segments <= 8'b00000011; //0 - 10
end
5 : begin
segments <= 8'b01001001; //5 - 5
end
default : begin
segments <= 8'b11111111; //all off
end
endcase
end
2: begin
choice <= 0;
digit <= 4'b1011;
case (select)
20 : begin
segments <= 8'b00100101; //2 - 20
end
15 : begin
segments <= 8'b10011111; //1 - 15
end
10 : begin
segments <= 8'b10011111; //1 - 10
end
5 : begin
segments <= 8'b11111111; //off - 5
end
default : begin
segments <= 8'b11111111; //all off
end
endcase
end
endcase
end
endmodule
Controller
module controller (nickel, dime, quarter, clk, state, reset, change, sum, vend);
input nickel, dime, quarter, clk, reset;
output reg vend;
output reg [5:0] sum, change;
output reg [2:0] state;
reg [2:0] next_state;
reg [5:0] local_change;
reg cont;
parameter S0 = 0, //these are the states of the FSM
S1 = 1,
S2 = 2,
S3 = 3,
S4 = 4,
S5 = 5,
S_reset = 6;
initial begin //initialize variables
sum <= 0; change <= 0; vend <= 0;
next_state <= S0; cont <= 1;
local_change <= 0;
end
always @ (posedge clk) begin
state <= next_state;
case (state)
S0: begin
sum <= sum + 0;
end
S1: begin
if (!nickel) sum <= sum + 5; //add a nickel
end
S2: begin
if (!dime) sum <= sum + 10; //add a dime
end
S3: begin
if (!quarter) sum <= sum + 25; //add a quarter
end
S4: begin
sum <= sum + 0;
end
S5: begin
if (sum == 25) begin //is the money enough?
cont <= 0;
vend <= 1;
end
else if (!cont) vend <= 1;
else if (cont) local_change <= sum - 25;
case (local_change) //determine change
21: begin
change <= 1; // flash on/off between change of 2 dimes
local_change <= 10;
vend <= 0;
end
20: begin
change <= 10;
local_change <= 21;
vend <= 0;
end
15: begin
change <= 10;
local_change <= 2;
vend <= 0;
end
10: begin
change <= 10;
local_change <= 0;
vend <= 0;
end
5: begin
change <= 5;
local_change <= 0;
vend <= 0;
end
0: begin
change <= 0;
local_change <= 1;
end
1: begin //this case enables return to displaying "A"
cont <= 0;
vend <= 0;
end
2: begin
change <= 1; // flash on/off between change of dime $ nickel
local_change <= 5;
vend <= 0;
end
endcase
end
S_reset: begin //reset all variables
sum <= 0; change <= 0;
vend <= 0; cont <= 1; local_change <= 0;
end
default: state <= S0;
endcase
end
always @ (state or nickel or dime or quarter) begin
case (state) // determine the next state
S0: begin //wait here until a coin is entered
if (nickel) next_state = S1;
else if (dime) next_state = S2;
else if (quarter) next_state = S3;
else if (reset) next_state = S_reset;
else next_state = S0;
end
S1: begin // wait until the coin button is released
if (nickel) next_state = S1;
else if (reset) next_state = S_reset;
else next_state = S4;
end
S2: begin // wait until the coin button is released
if (dime) next_state = S2;
else if (reset) next_state = S_reset;
else next_state = S4;
end
S3: begin // wait until the coin button is released
if (quarter) next_state = S3;
else if (reset) next_state = S_reset;
else next_state = S4;
end
S4: begin //determine if money is enough for candy
if (sum < 25) next_state = S0;
else if (reset) next_state = S_reset;
else next_state = S5;
end
S5: begin
if (reset) next_state = S_reset; //wait here until reset
else next_state = S5;
end
S_reset: next_state = S0;
default: next_state = S0; //reset state
endcase
end
endmodule
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.