数字系统设计及仿真十二章选题4

一、实验思路过程
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、进一步理解仿真的原理和目的,加深了对该科目的了解 。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值