You are on page 1of 11

Bach Khoa University

Faculty of Electrical & Electronics Engineering


Department of Electronics Engineering

EE3043 - COMPUTER ARCHITECTURE


Lab 3 report: Vending Machine

Instructor : Dr. Trn Hong Linh


Student : Hong Minh Nhng 1412770
Submission Date : Mar, 2017
1. Objective
- This lab help students to review and know the basic steps to design
and implement the real application with logic circuit using HDL
- Help students familiarize with the logic design of sequential digital
system using finite state machine.
- To enhance ability to use and debug code with simulated software like
Modelsim.
2. Design specifications
Design a vending machine followed by below specifications:
- Soda cost 9000, Water cost 7000.
- The machine accepts 1000, 2000 and 5000 coin.
- Give a change as small as possible.
- If the total coin pushed into machine already equaled or greater than 9000,
the machine has no longer accepts the coins and put it back.
- Coin return button: put all the coins that user pushed into machine out.
- If no buttons pressed, keep the state.
- Output:
+ Coin return out
+ Water out
+ Soda out
+ Changes
3. Procedure
3.1 Block diagram
Fist at all, we establish a block diagram of the vending machine

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

3.2 Finite State Machine


Secondly, we design a finite state machine and create our state encoding
for Verilog :

- 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

else if (c2k) c2k_o = 1; // the coin should be push out


else if (c5k) c5k_o = 5;
if (water_in) nextState = STATE_WATER ; // if user press water => go water state
else if (soda_in) nextState = STATE_SODA ; // the same with soda
else if (return) nextState = STATE_RETURN ; // if user change their mind and want to
//repeat (1) @(negedge clk);
end // take coin back, go to State RETURN
STATE_WATER: begin // State Water :push out a water bottle and gives change( if money > 7)
repeat (1) @(posedge clk); // wait a second to output
nextState = STATE_INIT ; // and then go back to initial state
end
STATE_SODA: begin // state SODA : the same with State WATER
repeat (1) @(posedge clk);
nextState = STATE_INIT ;
end
STATE_RETURN: begin // State RETURN : gives back all coin and go to initial state
repeat (1) @(posedge clk);
nextState = STATE_INIT ;
end
endcase
end

always @( currentState ) //output for each state,


begin
case(currentState)
STATE_INIT : begin
sum =0 ;
water_out = 0 ; soda_out = 0; c1k_o = 0; c2k_o = 0; c5k_o = 0;
end
STATE_COIN1 :
begin
water_out = 0 ; soda_out = 0; c1k_o = 0; c2k_o = 0; c5k_o = 0;
end
STATE_COIN2 :
begin
water_out = 0 ; soda_out = 0; c1k_o = 0; c2k_o = 0; c5k_o = 0;
end
STATE_COIN3 :
begin
water_out = 0 ; soda_out = 0; c1k_o = 0; c2k_o = 0; c5k_o = 0;
end
STATE_WATER :
begin
water_out = 1 ; //water out
repeat (1) @(negedge clk ) ;
water_out = 0 ;
case(sum - 7 ) // give change, because change always =< 5
5: begin c5k_o = 2'd1 ;
repeat (1) @(negedge clk ) ;
c5k_o = 0 ;
end
4: begin c2k_o = 2'd2 ;
repeat (1) @(negedge clk ) ;
c2k_o = 0 ;
end
3: begin c2k_o = 2'd1; c1k_o = 2'd1 ;
repeat (1) @(negedge clk) ;
c2k_o = 2'd0; c1k_o = 2'd0 ;
end
2: begin c2k_o = 2'd1 ;
repeat (1) @(posedge clk ) ;
c2k_o = 0 ;
end
1: begin c1k_o = 2'd1 ;
repeat (2) @(posedge clk ) ;
c1k_o = 0 ;
end
default : begin
c5k_o = 2'd0; c2k_o = 2'd0; c1k_o = 2'd0 ; end
endcase
end
STATE_SODA: // soda out, and give change
begin
soda_out = 1;
repeat (1) @(negedge clk ) ;
soda_out = 0 ;
case ( sum - 9) // change always <= 4 (13 -9 = 4)
4: begin c2k_o = 2'd2 ;
repeat (2) @(posedge clk ) ;
c2k_o = 0 ;
end
3: begin c2k_o = 2'd1; c1k_o = 2'd1 ;
repeat (2) @(posedge clk) ;
c2k_o = 2'd0; c1k_o = 2'd0 ;
end
2: begin c2k_o = 2'd1 ;
repeat (2) @(posedge clk ) ;
c2k_o = 0 ;
end
1: begin c1k_o = 2'd1 ;
repeat (2) @(posedge clk ) ;
c2k_o = 0 ;
end
default : begin
c5k_o = 2'd0; c2k_o = 2'd0; c1k_o = 2'd0 ; end
endcase
end
STATE_RETURN: // return all coin back
begin // calculate to gives the number of coins as small as possible
if (sum >= 10) // because the maximum of money is 13k
begin // so just return 5k back fist if possible
c5k_o = 2'd2; // and then 2k and finally, 1k
sum = sum - 10 ;
end
case (sum)
4 : begin c2k_o = 2'd2; end
3 : begin c2k_o =1; c1k_o=1; end
2 : begin c2k_o = 2'd1 ; end
1 : begin c1k_o = 3'd1 ; end
default: begin c2k_o = 0; c1k_o = 0 ; end
endcase
end
endcase
end
endmodule // that's all. thanks for reading my stupid code

4. TestBench code and Simulation

- 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

`define TRUE 1'b1


`define FALSE 1'b0

module testbench;

reg c1k, c2k, c5k, return, water_in, soda_in ;


wire water_out, soda_out ;
wire [1:0] c1k_o, c2k_o, c5k_o ;
reg CLOCK, RESET ;
wire [5:0] temp ;
VendingMachine VM( CLOCK, RESET, c1k, c2k, c5k, return, water_in,
soda_in, water_out, soda_out, c1k_o, c2k_o, c5k_o, temp );

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

Similarly, result for case:


Push 1k push 5k press soda push 5k press soda again

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 ;

Result for case:


Push 2k push 1k push 2k press water button push 5k
press return button

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.

You might also like