您的当前位置:首页正文

HDL(Verilog)课程设计报告(自动售货机)

2021-01-29 来源:好走旅游网
Verilog HDL课程设计报告

实 验 名 称:基于Verilog HDL的自动售货机 * * * *: * * * 班 级 :信科12-1 * * *** 学 号 :********

第一章 系统设计

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 end else

begin //金钱足够 price_all = price_all-price; beep = 1;

case(price) //LED灯显示货物卖出

5: begin led = 4'b0001;end led_warn = 1; price = 0;

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

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

/*数码管段码表*/ 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有了深入的理解!

因篇幅问题不能全部显示,请点此查看更多更全内容