自动售货机控制模块-Verilog HDL
来源:互联网 发布:淘宝话费充值不到账 编辑:程序博客网 时间:2024/04/28 10:06
一、 问题描述
设计一个自动售货机控制模块,信息如下:
1. 售货机可提供8种可售商品,其中01号商品(代表第一种商品),价格为2元,02商品为4元,依次类推,08号商品售价为16元。
2. 售货机可接受1元,5元和10元的纸币收入。
3. 交易开始,用户需要先投入一定量的货币;在外部货币投入后,售货机累计输入货币总值;完成投币后,用户选择所有需要的商品;选择结束后,按下交易键;交易成功,售货机出货、找零,更新系统的存量货币信息和货物信息;交易不成功,退回用户投入货币。
4. 交易不成功可能可能因为投币不足;货物不足;零钱不足等原因造成;
5. 管理员可以通过外部设备访问和修改可售商品信息和存量货币信息。
二、 功能概括
自动售货机刚初始化时,需要管理员对其剩余钱数和商品数进行管理,之后用户可以进行商品购买。用户首先选择商品,无误后对商品进行确认,否则取消,在用户选择了某种商品后,售货机会对其存货进行确认,如果该商品已经售罄,则交易失败,回到空闲状态。该商品有存货时,售货机延时一段时间(30S)留给用户进行投币,用户只能投入1,5,10元的钱币,否则售货机会将其退出。用户在延时内投币后,售货机进行找零计算,如果售货机内现金不足找零,则退出所有钱币,售货机进入管理员管理状态,此时需要管理员管理现金。正确情况下,零钱足够多,则正常找零,如果找零数额为0直接出货,找零数不为0则是先找零再出货。出于实际情况的考虑,我认为自动售货机更适合使用先选择产品,再投入钱币的方式更为合理,因此在设计时使用的是先选择确认,再延时投币的流程。自动售货机的整个管理和售货流程如下图所示:
图1 自动售货机工作流程图
三、 接口定义
表1 系统接口与描述表
名称
I/O
描述
时钟与复位
clk
I
工作时钟
init
I
交易取消信号
rst
I
初始化与复位
管理员接口
manage
I
管理使能信号
manage_money
I
管理售货机内剩余钱数
load
I
外部串口接收(暂定)
left01
I
管理第01号商品数量
left02
I
管理第02号商品数量
left03
I
管理第03号商品数量
left04
I
管理第04号商品数量
left05
I
管理第05号商品数量
left06
I
管理第06号商品数量
left07
I
管理第07号商品数量
left08
I
管理第08号商品数量
用户接口
select
I
选择商品
confirm
I
确认购买商品
money_input
I
投入钱币
change
O
得到售货机找零
out
O
得到商品
四、 电路设计
系统设计:
根据题目要求,本项目关注点在于自动售货机控制的模块,因此对于一些软件、机械、电气方面的错误无法进行处理,如退钱时卡纸,突然停电等。出于集成化的考虑,采用了3个always块,always39为初始化状态模块,即将state的状态初始化为S_idle(可综合的Verilog不能使用initial进行初始化),always39为计时模块,在选定商品后,必须在规定的时间内投币。always63为自动售货机控制管理模块,是本设计主要电路。自动售货机控制模块的整体功能概括如下:
图2 自动售货机控制模块功能概括
数据通路:
考虑测试输入输出模块,数据流图和控制流图如下图所示,其中蓝线为数据线,红线为控制线。
图3 自动售货机控制模块数据通路
状态机:
自动售货机定义了10种状态,分别是选择(S_select),确认(S_confirm),是否售罄(S_allselled),延时(S_60s),投币是否足够(S_enough),是否需要找零(S_requirechange),找零(S_change),出货(S_out),空闲(S_idle),管理(S_management)。状态机如下图所示。
图4自动售货机控制模块状态机
时序设计:
首先要将售货机初始化,然后管理员进行第一次管理,在管理员管理阶段,需要设定各个商品的剩余数量,以及售货机里用于找零的现金。管理结束后进入用户使用阶段,用户首先选择商品号,在规定的延迟之内完成投币,之后在不缺货和现金的情况下,会进行找零和出货,售货机会更新商品数量和现金信息。如果出现缺货,现金不足,投币超时等情况会进行特殊处理,返回空闲或管理状态。
图5自动售货机控制模块时序图
内部信号定义:
自动售货机控制模块的内部信号主要用于保存信息和中间过程处理,管理员在初始化管理时会输入商品数量以及内部现金余量,这些都需要寄存器进行寄存,在进行正常售货时,因为有找零和出货,内部的信息也在不断的更新。
表2 内部信号描述表
名称
性质
描述
内部信号
cash
reg
内部剩余现金
left1
reg
第01号商品数量
left2
reg
第02号商品数量
left3
reg
第03号商品数量
left4
reg
第04号商品数量
left5
reg
第05号商品数量
left6
reg
第06号商品数量
left7
reg
第07号商品数量
left8
reg
第08号商品数量
select_sta
reg
选择了某个商品
state
reg
状态机状态
isSelled
reg
是否售罄
timeCnting
reg
是否开始计时
time_cnt
reg
延时期限
opt
reg
是否取消交易
//2017.1.5 葛兴//全定制电路课程课程设计//Verilog自动售货机控制模块//Vending Machinemodule VendingMac(clk,money_input,select,confirm,init,left01,left02,left03,left04,left05,left06,left07,left08,change,out,manage,manage_money,rst);input clk;//时钟信号input rst;//使能信号input confirm,init;//?idle=initinput [3:0] money_input;//1,5,10,最大为1010,4位input [1:8] select;//8种商品,选择上升沿触发input [9:0] manage_money;//输入的钱数input [5:0] left01,left02,left03,left04,left05,left06,left07,left08;//剩余商品数,认为不超过63input [1:0] manage;//这个是管理员功能 reg [9:0] cash;//自动售货机内部的钱数reg [3:0] state;//状态机的各种状态reg [5:0] left1,left2,left3,left4,left5,left6,left7,left8;output integer change;//找零,整数output reg [1:8] out;//出货,8种商品之一reg [1:8] select_sta;//选择某种商品reg isSelled;//判断是否售罄reg timeCnting;//延时计时S_enough=4'b0100,S_requirechange=4'b0101,S_change=4'b0110,S_out=4'b0111,reg [8:0] time_cnt;//500个时间单位,2^9=512reg [1:0] opt;//检查init是否启用integer money_sum;//剩余总钱数parameter S_select=4'b0000,S_confirm=4'b0001,S_allselled=4'b0010,S_60s=4'b0011,S_idle=4'b1000,S_management=4'b1001;//9种state的编号start==4b'0000/* initialbeginstate=S_idle;//所以应该在输入中输入?还是直接在45行那儿初始化?end */always@(posedge clk or posedge rst)beginif(rst)beginstate <= S_idle;endend/* always @(posedge clk)beginif (start==4b'1000)state=S_idle;end */select_sta=8'b00000000;always @(posedge clk)beginif(clk && timeCnting)//根据clk上跳延计时time_cnt=time_cnt+1;if(timeCnting==0)time_cnt=0;endalways @(posedge init or posedge clk or manage)beginif(clk)begincase(state)S_idle://初始化状态begintimeCnting=0;left2 = left02;money_sum=0;change=0;out=0;opt=0;if(manage==1)state=S_management;else beginstate=S_select;endendS_management://管理员可以通过外部设备访问和修改可售商品信息和存量货币信息beginleft1 = left01;left3 = left03;if(confirm||init)//确认和初始化居其一(到下一步可以取消交易)left4 = left04;left5 = left05;left6 = left06;left7 = left07;left8 = left08;cash = manage_money;////manage=0;state=S_idle;endS_select://选择某种商品beginselect_sta=select|select_sta;//按位或,应对选择和商品;beginS_allselled://判断是否售罄opt={confirm,init};state=S_confirm;endendS_confirm:beginif(opt==2'b10)state=S_allselled;//也就是说当confirm=1时,进入判判断货物状态?那init是做什么用的?else if(opt==2'b00||2'b01||2'b11)beginstate=S_idle;endendbeginif(select_sta[6]==1 && left6<=0)isSelled=0;//判断选择的商品是否售罄if(select_sta[1]==1 && left1<=0)isSelled=1;if(select_sta[2]==1 && left2<=0)isSelled=1;if(select_sta[3]==1 && left3<=0)isSelled=1;if(select_sta[4]==1 && left4<=0)isSelled=1;if(select_sta[5]==1 && left5<=0)isSelled=1;timeCnting=1;//有商品则进入到计时付款阶段isSelled=1;if(select_sta[7]==1 && left7<=0)isSelled=1;if(select_sta[8]==1 && left8<=0)isSelled=1;if(cash < 16)state=S_management;//没有足够零钱则进入管理员状态else if(isSelled)beginstate=S_idle;//没有商品,回到空闲状态endelsebeginstate=S_60s;endstate=S_idle;endS_60s:beginif(time_cnt<25)beginif(money_input!=0)begin//只接收1,5,10元if(money_input==1||money_input==5||money_input==10||money_input==0)//检查是否为1,5,10元,不是则退钱并回到空闲状态//添加0是因为可能有连续的钱无法区分,实际上是投币间隔money_sum = money_sum + money_input;elseif(select_sta[3]==1)endendelse if(time_cnt==25)if(money_sum!=0)state=S_enough;//在计时结束后有钱放入elsestate=S_idle;endS_enough:begin//其中01号商品价格为2元,02商品为4元,依次类推,08号商品售价为16元。if(select_sta[1]==1)money_sum=money_sum-2;if(select_sta[2]==1)money_sum=money_sum-4;state=S_requirechange;//余额大于等于零,判断是否需要找钱money_sum=money_sum-6;if(select_sta[4]==1)money_sum=money_sum-8;if(select_sta[5]==1)money_sum=money_sum-10;if(select_sta[6]==1)money_sum=money_sum-12;if(select_sta[7]==1)money_sum=money_sum-14;if(select_sta[8]==1)money_sum=money_sum-16;if(money_sum>=0)S_out:else//找零余额不够,退出所有钱,并进入管理状态state=S_management;endS_requirechange:beginif(money_sum==0)//余额为零,不用找零,直接出货state=S_out;else if(money_sum>0)//余额不为零,进入找零模式state=S_change;endS_change:beginchange = money_sum;//将余额找零cash = cash - money_sum;//减去找零state = S_out;endif(select_sta[8]==1)begin//对应的货物减1if(select_sta[1]==1)left1=left1-1;if(select_sta[2]==1)left2=left2-1;if(select_sta[3]==1)left3=left3-1;if(select_sta[4]==1)left4=left4-1;if(select_sta[5]==1)left5=left5-1;if(select_sta[6]==1)left6=left6-1;if(select_sta[7]==1)left7=left7-1;left8=left8-1;out=select_sta;//出货state=S_idle;//进入空闲状态endendcaseendendendmodule
`timescale 1ns/1ns`include "./vending_machine_gx.v"module VendingMac_top;reg clk;reg rst;//复位reg manage;//管理员管理信号reg [9:0] manage_money;//管理售货机内现金reg [3:0] money_input;//用户输入钱reg [7:0] select;reg confirm,init;//确认取消reg [5:0] left01,left02,left03,left04,left05,left06,left07,left08;//剩余商品数,认为不超过63wire integer change;//找零wire [7:0] out;//出货initialbeginclk=0;select=8'b00000000;//初始并没有选择任何商品confirm=0;init=0;money_input=0;manage=0;endalways begin#5 clk=~clk;//产生时钟#5 clk=~clk; end initialbegin#10 rst = 1;//进行初始化,使售货机初始状态为S_idle#10 rst = 0;#10manage=1;#10left01=63;//每种商品的数量left02=62;left03=61;left04=60;left05=59;left06=58;left07=57;left08=56;manage_money=1000;//开始售货机里放1000元#10 manage=0;//管理结束#30#10 select=8'b00000010;//posedge1#10 select=8'b00000000;#10 confirm=1;//确认购买#10 confirm=0;#50 money_input=10;//投币10元#10 money_input=0;//投币间隔#10 money_input=5;#10 money_input=0;#10 money_input=1;#10 money_input=0; end initial begin $monitor($time,,,"select=%b,money_input=%d,confirm=%d,init=%d,out=%b,change=%d",select,money_input,confirm,init,out,change); #60000 $finish; end VendingMac v1(clk,money_input,select,confirm,init,left01,left02,left03,left04,left05,left06,left07,left08,change,out,manage,manage_money,rst);endmodule0 0
- 自动售货机控制模块-Verilog HDL
- Verilog自动售货机设计
- 6-2 Verilog Mealy状态机之自动售货机
- Verilog HDL模块的结构
- 自动售货机
- 自动售货机
- 测试自动售货机
- 自动售货机控制系统
- 自动饮料售货机
- 自动售货机代码
- Verilog HDL中的延迟控制语句
- 自动售货机简单代码
- JAVA模拟自动售货机
- [JAVA]模拟自动售货机
- 华为oj-自动售货机
- FPGA自动售货机设计
- JAVA模拟自动售货机
- FPGA Verilog HDL 系列实例--------直流电机PWM控制
- kotlin--空安全(可空类型和非空类型,Elvis 操作符,!! 操作符)
- 深度学习 -> 强化学习 ->迁移学习(杨强教授报告)
- delphi的bpl、dcp 、dcu文件意义
- Android 中如何计算 App 的启动时间?
- 受宠若惊,听说黑客花钱逆向我的代码:无锁ioking
- 自动售货机控制模块-Verilog HDL
- SwipeRefrenshLayout结合RecyclerView在线性,网格,瀑布流中的下拉刷新与上拉加载
- 使用Origin画出复杂网络博弈中个体策略分布图(斑图)(学术论文)
- Android 系列 1.11使用SDK示例帮助避免不知所措
- Hibernate学习博客推荐
- SolidWorks转3DMAX再到Unity3D的转换模型及单位设置
- 【记录】各种商业车险说明
- licecap--简单易用的Gif录制工具
- Linux每天学习一个命令之cut命令