一、实验思路过程
1、对自动售货机这个课题进行研究背景分析和查找文献进一步了解程序的过程、分析方案选出最优方案。
2、对需要用到的工具进行了解主要用到VHDL Quartus II
3、开始构思自动售货机系统的总体设计
4、对自动售货机的VHDL进行设计
5、对自动售货机的仿真结果及分析
6、对结果进行分析
1、在编译软件输入主代码
module machine(clk,money_in1,money_in2,select,item_confirm,money_confirm,cancel,sold_out,money_out,item_out,sta);
input clk;
input money_in1; //投入五角硬币
input money_in2; //投入一元硬币
input [1:4] select; //选择货物,只有一位有效
input item_confirm,money_confirm,cancel;
input [1:4] sold_out; //四种货物是否售空的状态,为1表示售空
output reg [2:0] money_out; //退款或找零的钱数
output reg [1:4] item_out; //出货物,只有一位有效
reg [1:4] select_sta;
output reg [2:0] sta; //状态机的状态
reg timeing; //计时状态
reg [31:0] time_cnt_s;
reg [8:0] time_cnt_l;
reg [2:0] money_sum;
reg [2:0] money_sum1;
reg [2:0] money_sum2;
parameter S_init=4’b000,S_select=4’b001,S_soldout=4’b010,S_30sec=4’b011,
S_enough=4’b100,S_change=4’b101,S_out=4’b110;
parameter item1=3'd4,item2=3'd4,item3=3'd3,item4=3'd3; //货物单价
initial
begin
sta=S_init;
money_sum1=0;
money_sum2=0;
end
always@(posedge clk) //分频模块,波形测试时需减小分频,方便看波形
begin
if(sta==S_init)
begin
time_cnt_s=0;
time_cnt_l=0;
end
if(timeing)
time_cnt_s=time_cnt_s+1;
if(time_cnt_s==32'd5_000_000)
time_cnt_l=time_cnt_l+1;
end
always@(posedge money_in1) //投币模块,上升沿为投币
begin
if(timeing)
begin
money_sum1=money_sum1+1;
end
if(sta!=S_30sec)
money_sum1=0;
end
always@(posedge money_in2) //投币模块,上升沿为投币
begin
if(timeing)
begin
money_sum2=money_sum2+2;
end
if(sta!=S_30sec)
money_sum2=0;
end
always@(posedge clk)
begin
case(sta)
S_init:
begin
select_sta=4'b0000;
timeing=0;
money_sum=0;
money_out=0;
item_out=4'b0000;
sta=S_select;
end
S_select:
begin
select_sta=select|select_sta;
if(item_confirm)
begin
sta=S_soldout;
end
if(cancel)
begin
sta=S_init;
end
end
S_soldout:
begin
if(select_sta&sold_out!=4'b0000) //若相同位同时为1
sta=S_init;
else
sta=S_30sec;
end
S_30sec:
begin
timeing=1;
if(money_confirm==1 || time_cnt_l>=288) //经计算,若时钟频率为48MHz,30s则对应288个time_cnt_l
begin
timeing=0;
money_sum=money_sum1+money_sum2;
sta=S_enough;
end
else
sta=S_30sec;
end
S_enough:
begin
case(select_sta)
4'b1000:
begin
if(money_sum1>=item1)
begin
money_sum=money_sum-item1; //求出找钱数
sta=S_change;
end
else
begin
money_out=money_sum; //退钱
sta=S_init;
end
end
4'b0100:
begin
if(money_sum>=item2)
begin
money_sum=money_sum-item2;
sta=S_change;
end
else
begin
money_out=money_sum;
sta=S_init;
end
end
4'b0010:
begin
if(money_sum>=item3)
begin
money_sum=money_sum-item3;
sta=S_change;
end
else
begin
money_out=money_sum;
sta=S_init;
end
end
4'b0001:
begin
if(money_sum>=item4)
begin
money_sum=money_sum-item4;
sta=S_change;
end
else
begin
money_out=money_sum;
sta=S_init;
end
end
default:
begin
money_out=money_sum;
sta=S_init;
end
endcase
end
S_change:
begin
if(money_sum>0)
begin
money_out=money_sum;
sta=S_out;
end
else
sta=S_out;
end
S_out:
begin
item_out=select_sta;
sta=S_init;
end
endcase
end
endmodule
商品选择模块代码
当顾客选择1元、5元或10元三种商品时分别由状态SO跳转至S1、S2、S3状态,否则停留在SO状态,选择货物的钱数在数码管上显示出来,程序代码如下所示:
when sO=>jing<='o’ ; out1<='O’ ; out5<='O’ ;out10<='0’ ;digit<=O;
if sel1='1’ and se15='0’and sel10='o’ then
ns<=s1;
elseif sell='0’ and sel5='1’ and sel10='0’thenns<=s2;
elseif sell='0’ and sel5='0’and sel10='1’thenns<=s3;
else
ns<=s0;end if;
投币模块
.1.当顾客投币为1元、5元或10元时,若当前为Sl状态,则分别跳转至S4、S5、S6三种状态,投币钱数显示在数码管上,否则停留在S1状态,程序如下所示:
when s1=>digit<=1;
if put1='1’ and put5=‘0’ and put10=‘0’ then
ns<=s4;V
elseif put1='0’ and put5='1’ and put10='0O’then
ns<=s5; elseif put='0’ and put5='0’and put10=l’then
ns<=s6;
else ns<=s1;
end if;
2.当顾客投币为1元、5元或10元时,若当前为S2状态,则分别跳转至S7、S8、S9三种状态,投币钱数显示在数码管上,否则停留在S2状态,程序如下所示:
when s2=>digit<=5;
if put l=‘l’ and put5='0’and put10='O’ then
ns<=s7;
else if put1='0’ and put5=‘1’ and put10='0’thenns<=s8;
else if put1=‘0’’ and put5='0’ and put10=‘1’’ then ns<=s9;
else ns<=s2;
end if;
3.当顾客投币为1元、5元或10元时,若当前为S3状态,则分别跳转至S10、S11、S12三种状态,投币钱数显示在数码管上,否则停留在S3状态,程序如下所示:
when s3=>digit<=10;
if put1='1’ and put5=‘0’’ and put10='0’then
ns<=s10;
else f put l='0’and put5-I’ and put10='O’then ns<=s1 1;
else if put1='0’and put5='0’and put10=‘1’then
ns<=s12;else
ns<=s3;
end if:1
送出商品模块
假设选择的1元商品,投入1元货币并按下确认,送出商品后延时3秒回到初始状态;投入5元并确认后,数码管显示4元找零,送出商品并找出零钱,3秒延时后回到初始状态;投入10元并确认后数码管显示9元找零,送出商品并找出零钱,3秒延时后回到初始状态。程序如下所示:
when s13=>out1<=‘1’ ; out5<=’ 0’ ;out10<=‘0’ ; jing<='O’ ;digit<=0;
if b='1’then
ns<=s0;–延时控制else
ns<=s13;
end if;
when s14=>out1<=‘1’; out5<=‘O’ ; out10<=’ O’ ; jing<=‘O’ ; digit<=4;if b='l’ then
ns<=s0; else
ns<=s14;
end if;
when s15=>out1<='1’ ; out5<='O’ ; out10<='O’ ;jing<=‘O’ ; digit<=9;if b='l’ then
ns<=s0; else
ns<=s15;
end if;
计时模块
此次设计中要求售货过程结束后有一个3秒复位以o出错后有3秒的警告时向,需要通过延时来实现,延时程序如下所示:
if rst='l ‘then
ps<=5s0;-当复位信号有效时,s0赋给现态else if clk’ event and cl k=‘1’ then
ps<=ns;–当上升沿到来时,次态赋值给现态if(a=‘1’)then
temp;=temp+1;if(temp=3 )
then b<=‘1’;
else b<=‘0’;
end if;
else
temp: =0;
end if;
end if;–延时程序end process;
结果
1.当所选商品钱数与投币钱数相等时波形仿真结果图如图5.1所示
2.当所选商品钱数比投币钱数多时波形仿真结果图如图5.2所示
3.当所选商品钱数比投币钱数少时波形仿真结果图如图5.3:
完成这次实验
实验视频:https://v.qq.com/x/page/q3254j1km1p.html
5、总结:1、这次实验代码很长,输入花费了比较多时间。
2、进一步理解仿真的原理和目的,加深了对该科目的了解 。