Vending Machine - Computer Architecture
Vending Machine - Computer Architecture
- The input signal generate set or clear the signal when the coins pushed into
or buttons pressed, repectively.
- Controller Block is the main part of the vending machine that we have to
design to resolve all the requirements above.
- Beverages and Coins output actualtor block are reponsible for execute the
output signals of Controller block, like push water/soda out or give some
coins out.
- State Init: all output = 0 ; wait for user push coins into
- State Coin1: user had pushed coins into machine but the money was < 7k
- State Coin2: the money was equal or greater than 7k but smaller than 9k,
Water is ready now
- State Coin3: the money was greater than 9k already, cannot accept anymore
coin. Water and Soda is ready
- State Water : output of Water is set, and if money input greater than 7k,
change will gave back to user.
- State Soda : similar state water
- State Return: Return all money when return button was pressed.
3.3 Verilog HDL Code
For the design above, we convert it to HDL code
module VendingMachine (clk, reset, c1k, c2k, c5k, return, water_in, soda_in,
water_out, soda_out, c1k_o, c2k_o, c5k_o) ;
input wire clk, reset;
// clock; reset; received 1k, 2k or 5k coin;
input c1k, c2k, c5k, return, water_in, soda_in ;
// pressed coin return button; pressed water or soda buying button
output reg water_out, soda_out ; //the signal to push water or soda out
output reg [1:0] c1k_o, c2k_o, c5k_o ; //the number of coins to return
integer sum = 0 ;
// total amount of coins input
reg [2:0] currentState = 0 , nextState = 0;
// states of the amount of money that pushed into machine
parameter STATE_INIT = 3'd0, // assign each state with a value
STATE_COIN1 = 3'd1,
STATE_COIN2 = 3'd2,
STATE_COIN3 = 3'd3,
STATE_WATER = 3'd4,
STATE_SODA = 3'd5,
STATE_RETURN = 3'd6;
//-------------------------------------------
always @(posedge clk ) // update state every positive edge of clock pulse
begin
if( reset) currentState <= STATE_INIT ;
else currentState <= nextState ;
end
//----------------------------------------------------------
// this block use to update next state base on the input //
always @(* )
begin
nextState = currentState ; // default if nothing happen
case ( currentState)
STATE_INIT:
begin
if ( c1k) begin sum = 1;
nextState = STATE_COIN1; // in initial state , if
end // one coin pushed into machine
else if ( c2k) begin // the sum will update and
sum = 2; // the state will change to state coin1
nextState = STATE_COIN1; end
if ( c5k) begin sum = 5;
nextState = STATE_COIN1; end
repeat (1) @(negedge clk); // wait a second
end
STATE_COIN1: // state coin1: 0< money < 7k
begin
if (c1k) sum = sum + 1; //update money
else if(c2k) sum = sum + 2;
else if (c5k) sum = sum + 5 ;
if ( return ) nextState = STATE_RETURN ;
if (( sum >= 7) & ( sum < 9) )
nextState = STATE_COIN2 ; // if 7k <= money < 9k -> goto coin2
else if ( sum >= 9)
nextState = STATE_COIN3 ; // if money >9k -> goto coin3
end
STATE_COIN2: begin //state coin2: 7k <= money < 9k
if (water_in) nextState = STATE_WATER ; // if water button is pressed, then go to
state WATER
else if (c1k) sum = sum + 1 ; // if not, update money
else if (c5k) sum = sum + 5 ;
else if (c2k) sum = sum + 2 ;
// if money > 9k, then change state to state coin3
if ( sum >= 9) nextState = STATE_COIN3 ;
if (return) nextState = STATE_RETURN ; // if Coin Return button is pressed
//repeat (1) @(negedge clk);// then go to state RETURN
end
STATE_COIN3: begin //state coin 3: money already > 9k
if (c1k) c1k_o = 1; // if user continuous push coin into
- In order to test and verify the design above, we create a testbench code and
test in ModelSim.
- Because the testbench code for each case is similar, so the testbench code
above just one of the cases
Test code for case:
push 1k -> push 2k -> push 5k -> press water button
module testbench;
initial
begin
CLOCK = `FALSE ;
forever #5 CLOCK = ~CLOCK ; //clock pulse
end
initial
begin
c1k = 0 ; c2k = 0 ; c5k = 0 ; return = 0; // initial value
water_in = 0; soda_in = 0 ;
repeat (1) @(negedge CLOCK ) ; c1k = `TRUE; //money = 1k
repeat (1) @(negedge CLOCK ) ; c1k = `FALSE ;
repeat (1) @(negedge CLOCK ) ; c2k = `TRUE ; //money = 3k
repeat (1) @(negedge CLOCK ) ; c2k = `FALSE ;
repeat (1) @(negedge CLOCK ) ; c5k = `TRUE ; //money = 8k
repeat (1) @(negedge CLOCK ) ; c5k = `FALSE ;
repeat (1) @(negedge CLOCK ) ; water_in = `TRUE ; // buy a water
bottle
repeat (1) @(negedge CLOCK ) ; water_in= `FALSE ;
end
endmodule
And the result here:
After water button was pressed, the value of water_out is set to notify
that water bottle is out and then give the change is 1k because: (1k +
2k + 5k ) = 8k and 8k 7k = 1k
In the fist press of soda, the money just 6k, is not enough for soda (
9k) so the output of soda is not set. When user push additionally 5k
and press soda again, the output of soda is set because the money
now was 11k. And the change is : 11k 9k = 2k
Result for case:
push 1k push 5k push 5k push 2k press water button
Before the user push coin 2k, the money has been 11k already, so
when the user push additional 2k, the coin was rejected ( output of 2k
is set to return that coin). When user press water button output
of water was set and the change: 11k 7k = 4k = 2 x 2k ;
In this case when the user press water button, the money just 5k,
hasnt enough for water, so the output of water is not set. When user
pushed coin 5k additionally, the money was 10k and suddenly change
his/her mind and pressed return button, all of coin is back with just
two coins 5k ( 10k = 2x 5k)
5. Conclusions and Discussions
For those of cases that we have tested, the result of output for each
case is correct and proved that our design worked fine.
The lab helped me understand how to design and implement a FSM
in ModelSim with Verilog HDL.
The design can be more optimum with a lots of algorithms to create a
FSM and implement.