Verilog: Vending Machine
Specifications
- Choices: CocaCola (INR 10), Pepsi (INR 15). Each can be selected using their designated button.
- After making a choice, pay using INR 5,10 notes. Once enough amount is entered, dispense the product, returning the change, if any. (Note that: In a single turn, you can enter no more than 1 coin - making the input to be either INR 5,10.)
- A cancel button can be used to cancel the transaction if partial deposit is made.
- A reset button resets the machine.
// vm.v
/*
a : select drink (CocaCola/Pepsi: 01/10)
b : enter money (Rs 5/10: 01/10)
y : dispense drink (CocaCola/Pepsi: 01/10)
c : return change (Rs 0/5/10: 00/01/10)
*/
`timescale 1ns/1ns
module VM(
input [1:0] a,b,
input clk,
input reset,
input cancel,
output [0:1] y,c);
reg [2:0] currentstate, nextstate;
// States
parameter s0 = 3'b000; // Reset, Rs.0
parameter s1 = 3'b001; // CocaCola (Rs.10)
parameter s2 = 3'b010; // Pepsi (Rs.15)
parameter s3 = 3'b011; // Rs.5
parameter s4 = 3'b100; // Rs.10
always @(posedge clk) begin
currentstate <= nextstate ;
//while (!reset) begin
case (nextstate)
s0:
if(a==2'b01) nextstate <=s1;
else if(a==2'b10) nextstate <=s2;
else nextstate <=s0;
s1:
if(b==2'b01) nextstate <=s3;
else if(b==2'b10) nextstate <=s0; // c=0
else nextstate <=s1;
s2:
if(b==2'b01) nextstate <=s3;
else if(b==2'b10) nextstate <=s4;
else nextstate <=s2;
s3:
if(cancel) nextstate <=s0; // c=5
else if(a==2'b01 & b==2'b01) nextstate <=s0; // c=0
else if(a==2'b01 & b==2'b10) nextstate <=s0; // c=5
else if(a==2'b10 & b==2'b01) nextstate <=s4;
else if(a==2'b10 & b==2'b10) nextstate <=s0; // c=0
else nextstate <=s3;
s4:
if(cancel) nextstate <=s0; // c=10
else if(b==2'b01) nextstate <=s0; // c=0
else if(b==2'b10) nextstate <=s0; // c=5
else nextstate <=s4;
default: nextstate <=s0;
endcase
end
// Manual Reset
//assign reset = !reset;
//nextstate <=s0;
//end
// Dispense drink/change
assign y = (currentstate == s1 & b == 2'b10)?a :
(currentstate == s3 & a == 2'b01 & b == 2'b01)?a :
(currentstate == s3 & a == 2'b01 & b == 2'b10)?a :
(currentstate == s3 & a == 2'b10 & b == 2'b10)?a :
(currentstate == s4 & a == 2'b10 & b == 2'b01)?a :
(currentstate == s4 & a == 2'b10 & b == 2'b10)?a :
2'b00;
assign c = (currentstate == s3 & cancel)?2'b01 :
(currentstate == s4 & cancel)?2'b10 :
(currentstate == s3 & a == 2'b01 & b == 2'b10)?2'b01 :
(currentstate == s4 & a == 2'b10 & b == 2'b10)?2'b01 :
2'b00;
endmodule
// test.v
`timescale 1ns/1ns
module test_VM();
reg [1:0] A,B;
reg clk;
wire [1:0] Y,C;
reg reset, cancel;
VM VM0(.a(A), .b(B), .clk(clk), .y(Y), .c(C), .reset(reset), .cancel(cancel));
initial begin
clk=0;
forever #5 clk=~clk;
end
initial begin
A=2'b00; B=2'b00; reset=0;
// Select Cocacola, Pay 10. Change=0
#10 A=2'b01; #5 B=2'b10;
// Select Cocacola, Pay 5,10. Change=5
#10 A=2'b01; #5 B=2'b01; #5 B=2'b10;
// Select Pepsi, Pay 5,10. Change=10
#10 A=2'b10; #5 B=2'b01; #5 B=2'b10;
// Select Pepsi, Pay 10,10. Change=5
#10 A=2'b10; #5 B=2'b10; #5 B=2'b10;
// Reset.
#10 reset=1;
// Select Cocacola, Pay 5, cancel. Change=5
#10 A=2'b01; #5 B=2'b01; cancel=1;
// Select Pepsi, Pay 10, cancel. Change=10
#10 A=2'b10; #5 B=2'b10; cancel=1;
#10 $finish;
end
endmodule