verilog编写的自动售货机,使用状态机实现。
基于verilog的自动售货机,平台为:quartues,仿真:altera-modelsim。
项目要求利用FPGA实现自动售货机的核心控制部分。说明如下:
1.核心控制部分的时钟输入为50MHz。
2.外部复位输入为低电平有效的复位。
3.自动售货机能够输入的钱数只有0.5元和1元,辅助设备将以脉冲的形式提供给核心控制部分(脉冲宽度为50MHZ的一个时钟周期)。
4.当输入的钱数刚好等于2.5元(只卖一种水,水的价格为2.5元)时,输出水。如果输入的钱数为3元,则输出水的同时,找回0.5元。
5.输出水和找零用一个时钟周期的脉冲表示即可。
经过仔细分析上述要求,得出以下顶层架构。:
在本设计中,采用状态机的方式实现。共分为5个状态,分别为:ZERO、HALF、ONE、ONE_HALF、TWO。状态转移图如下:
上代码:
module auto_seller(clk,rst_n,flag_half,flag_one,flag_water,flag_money);
input wire clk;
input wire rst_n;
input wire flag_half;
input wire flag_one;
output reg flag_water;
output reg flag_money;
parameter ZERO = 5'b00001;
parameter HALF = 5'b00010;
parameter ONE = 5'b00100;
parameter ONE_HALF = 5'b01000;
parameter TWO = 5'b10000;
reg [4:0] c_state;
reg [4:0] n_state;
[email protected](posedge clk) begin
if(!rst_n)
c_state<=ZERO;
else
c_state<=n_state;
end
[email protected](*) begin
case(c_state)
ZERO : begin
if(flag_half = =1’b1)
n_state=HALF;
else
if(flag_one==1’b1)
n_state=ONE;
else
n_state=ZERO;
end
HALF : begin
if(flag_half==1'b1)
n_state=ONE;
else
if(flag_one==1'b1)
n_state=ONE_HALF;
else
n_state=HALF;
end
ONE : begin
if(flag_half==1'b1)
n_state=ONE_HALF;
else
if(flag_one==1'b1)
n_state=TWO;
else
n_state=ONE;
end
ONE_HALF: begin
if(flag_half==1'b1)
n_state=TWO;
else
if(flag_one==1'b1)
n_state=ZERO;
else
n_state=ONE_HALF;
end
TWO : begin
if(flag_half==1'b1)
n_state=ZERO;
else
if(flag_one==1'b1)
n_state=ZERO;
else
n_state=TWO;
end
default : n_state=ZERO;
endcase
end
[email protected](posedge clk) begin
if(!rst_n)
flag_water<=1’b0;
else
case(c_state)
ZERO : flag_water<=1’b0;
HALF : flag_water<=1’b0;
ONE : flag_water<=1’b0;
ONE_HALF: if(flag_one= =1’b1)
flag_water<=1’b1;
else
flag_water<=1’b0;
TWO : if(flag_half1’b1 | | flag_one1’b1)
flag_water<=1’b1;
else
flag_water<=1’b0;
default : flag_water<=1’b0;
endcase
end
[email protected](posedge clk)begin
if(!rst_n)
flag_money<=1’b0;
else
if(c_stateTWO && flag_one1’b1)
flag_money<=1’b1;
else
flag_money<=1’b0;
end
endmodule
testbench产生的波形图:
测试代码在我主页里面可自行下载,欢迎各位老铁批评指正。