资源描述
Verilog HDL课程设计汇报
实 验 名 称:基于Verilog HDL自动售货机
指 导 老 师: 王 冠 军
班 级 :信科12-1
姓 名 :吴涛
学 号 :06122485
第一章 系统设计
1.1 系统设计
(1)用四个发光二极管分别模拟售出价值为5角、1元、1.5元和2元小商品,购置者能够经过开关选择任意一个标价中小商品。
(2)灯亮时表示该小商品售出。
(3)用开关分别模拟5角、1元硬币和5元纸币投入,能够用几只发光二极管(或数码管)分别代表找回剩下硬币。
(4)每次只能售出一个小商品,当所投硬币达成或超出购置者所选面值时,售出货物并找回剩下硬币,回到初始状态;
(5)当所投硬币值不足面值时,可经过一个复位键退回所投硬币,回到初始状态。
第二章 具体设计
2.1 自动售货机状态描述
判定开关被按下个数N。若N>=2表示所选此次选择无效,返回初始状态;若N=1则显示所选商品,并继续实施下面步骤。3个开关分别代表三种商品。4个开关分别代表投入0.5元,1元,2元,5元,统计投入总额。投入总额和商品价格做比较,假如总额<商品价格,退钱并返回初始状态假如总额>=商品价格,则继续实施下面程序。找零=总额-商品价格,数码管显示找零金额。状态图图2.1所表示:
2.2 具体状态描述
2.2.1 初始状态
各变量全部设置为零,按下rst键后,一切恢复到初始状态。
2.2.2 选商品状态
分别有价格为0.5元、1元、1.5元和2元商品,每次选择商品前,设置一个标志位btn_sell表示选择商品状态。此自动售货机每一次售货时只能一次选择一个商品,当同时选择两种以上时,选择商品无效,数码管显示清零,重新进行商品选择。选择商品后,数码管显示所选商品价格。
2.2.3 投币状态
当选好商品后,开始投币。一样有一标志位btn_price表示投币金额。投币口只接收三种面值钱币0.5元、1元和5元,能够同时投入多个面值钱币。投完币后,先有一个确定买商品过程,若投了币但又不购置商品了,就将全部投币金额退回;若确定购置商品,则进入下一状态——找零状态。
2.2.4 找零状态
投完币,并确定购置商品后,进入找零状态。首先要将所投金额和所选商品价格做比较,若所投金额小于商品价格,则退回所投钱币;若大于等于商品价格,则二者做差,得到需要找零钱。
第三章 软件设计
3.1 程序总步骤图
3.2 程序
module seller(clk,rst,dis_mony,btn_ok,btn_mon,btn_sell,led_warn,led,beep);
input clk,rst,btn_ok;
input [2:0] btn_mon;//选择放入钱
input [3:0] btn_sell;//选择商品bbt_5,gz_10,kqs_15,kl_20
output [3:0] led;//led_5,led_10,led_15,led_20
output led_warn;//钱不足,指示灯
output [10:0] dis_mony;//数码管显示投入面值,dia_mony[10:8]=com位选,dis_mony[7:0]=段码
output beep;
integer r;
reg clk_500Hz;
reg [3:0] led;//led_5,led_10,led_15,led_20
reg led_warn;//警告放入钱不足
reg [10:0] dis_mony;
reg [31:0] counter;
reg [9:0] price,price_all;
reg [1:0] flag = 2'b00;//数码管显示标志位
reg beep=0;
parameter COUNT1 = 25'd10000;
/*分频使数码管显示稳定*/
always @ (posedge clk)
begin
if(counter== 0)
begin
counter <= COUNT1;
clk_500Hz <= ~clk_500Hz;
end
else
counter <= counter-1;
end
always @(negedge rst or posedge clk)
begin
if (rst==0)
begin
led = 4'b0000;//LED灭
price_all = 0;//价格清零
led_warn = 0;
price = 0;
beep = 0;
end
else
begin/*三种面值共8种组合*/
case(btn_mon)
3'b001:begin price_all = 5;end
3'b010:begin price_all = 10;end
3'b100:begin price_all = 50;end
3'b011:begin price_all = 15;end
3'b101:begin price_all = 55;end
3'b110:begin price_all = 60;end
3'b111:begin price_all = 65;end
default:begin price_all = 0;end
endcase
case(btn_sell)
4'b0001:begin price = 5;
end
4'b0010:begin price = 10;
end
4'b0100:begin price = 15;
end
4'b1000:begin price = 20;
end
default:begin price = 0;
end
endcase
if(btn_ok == 1)
begin
if(price_all < price) //放入钱不足
begin
led_warn = 1;
price = 0;
end
else
begin //金钱足够
price_all = price_all-price;
beep = 1;
case(price) //LED灯显示货物卖出
5: begin led = 4'b0001;end
10:begin led = 4'b0010;end
15:begin led = 4'b0100;end
20:begin led = 4'b1000;end
endcase
end
end
else
beep = 0;
end
end
/*分频后将时钟给数码管,数码管分别显示放入钱多少、商品价格*/
always @(posedge clk_500Hz)
begin
case(flag)
2'b00:
begin
r=price_all%10;
case(r)
0:begin dis_mony=11'b111_0011_1111;end
1:begin dis_mony=11'b111_0000_0110;end
2:begin dis_mony=11'b111_0101_1011;end
3:begin dis_mony=11'b111_0100_1111;end
4:begin dis_mony=11'b111_0110_0110;end
5:begin dis_mony=11'b111_0110_1101;end
6:begin dis_mony=11'b111_0111_1101;end
7:begin dis_mony=11'b111_0000_0111;end
8:begin dis_mony=11'b111_0111_1111;end
9:begin dis_mony=11'b111_0110_1111;end
endcase
flag = 2'b01;
end
2'b01:
begin
r=price_all/10;
case(r)
0:begin dis_mony=11'b110_1011_1111;end
1:begin dis_mony=11'b110_1000_0110;end
2:begin dis_mony=11'b110_1101_1011;end
3:begin dis_mony=11'b110_1100_1111;end
4:begin dis_mony=11'b110_1110_0110;end
5:begin dis_mony=11'b110_1110_1101;end
6:begin dis_mony=11'b110_1111_1101;end
7:begin dis_mony=11'b110_1000_0111;end
8:begin dis_mony=11'b110_1111_1111;end
9:begin dis_mony=11'b110_1110_1111;end
endcase
flag = 2'b00;
end
endcase
end
/*数码管段码表*/
function [7:0] led7;
input [3:0] dis_input;
begin
case (dis_input)
0 : led7 = 8'b0011_1111;
1 : led7 = 8'b0000_0110;
2 : led7 = 8'b0101_1011;
3 : led7 = 8'b0100_1111;
4 : led7 = 8'b0110_0110;
5 : led7 = 8'b0110_1101;
6 : led7 = 8'b0111_1101;
7 : led7 = 8'b0000_0111;
8 : led7 = 8'b0111_1111;
9 : led7 = 8'b0110_1111;
default : led7 = 8'b0011_1111;
endcase
end
endfunction
endmodule
第四章 结果和讨论
4.1 试验调试
4.1.1 调试步骤
①运行Quartus II软件,新建工程。
②建立文本文件Verilog HDL File。在文件中写入程序。保留,编译。
③分配管脚。保留,编译。
④将生成.sof文件写入FPGA试验箱中。
⑤依据要求选择多个买东西可能情况,在试验箱上试验,观察统计结果。
4.1.2 试验现象
⑴选择买0.5元商品,投5元金额,调试现象以下:
①选择0.5元商品数码管显示0.5,再选择一个商品,数码管显示清零,重新进行商品选择。
②按下5元投币键,对应数码管显示5.0。
③按下确定购置开关,找零时,对应数码管显示4.5,蜂鸣器响,对应0.5元商品LED灯亮。
⑵选择1.5元商品,投1元金额,调试现象以下:
①选择1.5元商品,对应数码管显示1.5。
②按下1元投币键,对应数码管显示1。
③找零显示1元,退回所投钱,表示警告LED灯亮(交易不成功)。
4.2 结果和分析
调试过程中出现问题及原因:
(1) 本程序 定义了函数,注意函数结构定义和函数调用(函数不能作为单独语句进行调用)。
(2) 在编写完程序以后,编译运行成功后,注意数码管管脚连接,参考试验指导书。
(3) 后面一切正常后,不过仍然出不了正确结果,经过和同学相互讨论,才发觉按钮按下是0,悬空是1。最终立即发觉并得出了正确试验结果。
第五章 总结
经过几次试验,让我对Verilog HDL有了很深刻认识,从刚开始接触EDA到现在
Verilog HDL学习,让我对这些硬件描述语言有了深入了解。这些语言和c++,java
软件编程语言比起来全部简单多,所以也很轻易上手。
试验刚开始,老师首先让我们自己经过输入书上源程序来熟悉Verilog HDL,后面就
慢慢加大难度,逐步深入了解Verilog HDL。我刚开始选择了出租车计价器,以后因为
时间原因,没有成功。以后和同学讨论做自动售货机,这个题目相对简单,没有很复杂
模块设计,甚至没有多模块设计,只需要调用函数和使用过程赋值语句就行了。经过不停
试最终在试验结束前做完了。
感谢几节课试验让我对Verilog HDL有了深入了解!
展开阅读全文