基于Verilog,设计一个自动售卖饮料机。2.5元/瓶,可投1元硬币和5角硬币,可找零。
设计思路:基于有限状态机。
引入5个状态:IDLE,S1,S2,S3,S4;
分别代表空闲状态,已投币0.5元,已投币1.0元,已投币1.5元,已投币2.0元。
verilog代码:
module vendor(clk, rst_n, half_in, one_in, collect, half_out);
input clk;
input rst_n;
input half_in;
input one_in;
output collect;
output half_out;
parameter IDLE=0;
parameter S1=1;
parameter S2=2;
parameter S3=3;
parameter S4=4;
reg [2:0] state_c;
reg [2:0] state_n;
reg collect;
reg [1:0] half_out;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state_c<=IDLE;
end
else begin
state_c<=state_n;
end
end
always @(*) begin
if (!rst_n) begin
state_n=IDLE;
end
else begin
case (state_c)
IDLE: begin
if (half_in==0&&one_in==0)
state_n=state_c;
else if (half_in==0&&one_in==1)
state_n=S2;
else if (half_in==1&&one_in==0)
state_n=S1;
else if (half_in==1&&one_in==1)
state_n=S3;
else
state_n=state_c;
end
S1: begin
if (half_in==0&&one_in==0)
state_n=state_c;
else if (half_in==0&&one_in==1)
state_n=S3;
else if (half_in==1&&one_in==0)
state_n=S2;
else if (half_in==1&&one_in==1)
state_n=S4;
else
state_n=state_c;
end
S2: begin
if (half_in==0&&one_in==0)
state_n=state_c;
else if (half_in==0&&one_in==1)
state_n=S4;
else if (half_in==1&&one_in==0)
state_n=S3;
else if (half_in==1&&one_in==1)
state_n=S4;
else
state_n=state_c;
end
S3: begin // 1.5 多投就找回
if (half_in==0&&one_in==0)
state_n=state_c;
else if (half_in==0&&one_in==1)
state_n=IDLE;
else if (half_in==1&&one_in==0)
state_n=S4;
else if (half_in==1&&one_in==1)
state_n=IDLE;
else
state_n=state_c;
end
S4: begin // S4多投了就全找回 不考虑一次性买2瓶饮料 一瓶一瓶地买
if (half_in==0&&one_in==0)
state_n=state_c;
else if (half_in==0&&one_in==1)
state_n=IDLE;
else if (half_in==1&&one_in==0)
state_n=IDLE;
else if (half_in==1&&one_in==1)
state_n=IDLE;
else
state_n=state_c;
end
default: begin
state_n=state_c;
end
endcase
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
collect<=1'b0;
half_out<=2'b00;
end
else begin
if (state_c==IDLE) begin
collect<=1'b0;
half_out<=2'b00;
end
else if (state_c==S1) begin
collect<=1'b0;
half_out<=2'b00;
end
else if (state_c==S2) begin
collect<=1'b0;
half_out<=2'b00;
end
else if (state_c==S4) begin
if (half_in==1&&one_in==1) begin
collect<=1'b1;
half_out<=2'b10;//
end
else if (half_in==0&&one_in==1) begin
collect<=1'b1;
half_out<=2'b01;
end
else if (half_in==1&&one_in==0) begin
collect<=1'b1;
half_out<=2'b00;
end
else begin
collect<=1'b0;
half_out<=2'b00;
end
end
else if (state_c==S3) begin
if (half_in==1&&one_in==1) begin
collect<=1'b1;
half_out<=2'b01;
end
else if (half_in==0&&one_in==1) begin
collect<=1'b1;
half_out<=2'b00;
end
else begin
collect<=1'b0;
half_out<=2'b00;
end
end
else begin
collect<=1'b0;
half_out<=2'b00;
end
end
end
endmodule
testbench文件:
`timescale 1ns / 1ns
module sim_vendor();
reg clk;
reg rst_n;
reg half_in;
reg one_in;
wire [1:0] half_out;
wire collect;
vendor sim_vendor(
.clk(clk),
.rst_n(rst_n),
.half_in(half_in),
.one_in(one_in),
.collect(collect),
.half_out(half_out)
);
initial begin
rst_n =1'b0;
clk = 1'b1;
half_in = 1'b0;
one_in = 1'b0;
# 2 rst_n = 1'b1;
end
always #1 clk = ~clk;
always # 2 half_in = ~half_in;
always # 3 one_in = ~one_in;
endmodule
vivado仿真结果: