EDA课程设计报告自动售货机Word文档下载推荐.docx
《EDA课程设计报告自动售货机Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《EDA课程设计报告自动售货机Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。
开关级基本结构模型,例如pmos和nmos等也被内置在语言中。
提供显式语言结构指定设计中的端口到端口的时延及路径时延和设计的时序检查。
可采用三种不同方式或混合方式对设计建模。
这些方式包括:
行为描述方式—使用过程化结构建模;
数据流方式—使用连续赋值语句方式建模;
结构化方式—使用门和模块实例语句描述建模。
VerilogHDL中有两类数据类型:
线网数据类型和寄存器数据类型。
线网类型表示构件间的物理连线,而寄存器类型表示抽象的数据存储元件。
能够描述层次设计,可使用模块实例结构描述任何层次。
设计的规模可以是任意的;
语言不对设计的规模(大小)施加任何限制。
VerilogHDL不再是某些公司的专有语言而是IEEE标准。
人和机器都可阅读Verilog语言,因此它可作为EDA的工具和设计者之间的交互语言。
VerilogHDL语言的描述能力能够通过使用编程语言接口(PLI)机制进一步扩展。
PLI是允许外部函数访问Verilog模块内信息、允许设计者与模拟器交互的例程集合。
设计能够在多个层次上加以描述,从开关级、门级、寄存器传送级(RTL)到算法级,包括进程和队列级。
能够使用内置开关级原语在开关级对设计完整建模。
同一语言可用于生成模拟激励和指定测试的验证约束条件,例如输入值的指定。
VerilogHDL能够监控模拟验证的执行,即模拟验证执行过程中设计的值能够被监控和显示。
这些值也能够用于与期望值比较,在不匹配的情况下,打印报告消息。
在行为级描述中,VerilogHDL不仅能够在RTL级上进行设计描述,而且能够在体系结构级描述及其算法级行为上进行设计描述。
能够使用门和模块实例化语句在结构级进行结构描述。
在VerilogHDL的混合方式建模能力,即在一个设计中每个模块均可以在不同设计层次上建模。
VerilogHDL还具有内置逻辑函数,例如&
(按位与)和|(按位或)。
对高级编程语言结构,例如条件语句、情况语句和循环语句,语言中都可以使用。
可以显式地对并发和定时进行建模。
提供强有力的文件读写能力。
·
语言在特定情况下是非确定性的,即在不同的模拟器上模型可以产生不同的结果;
例如,事件队列上的事件顺序在标准中没有定义。
1.1系统设计
(1)用四个发光二极管分别模拟售出价值为5角、1元、1.5元和2元的小商品,购买者可以通过开关选择任意一种标价中的小商品。
(2)灯亮时表示该小商品售出成功。
(3)用开关分别模拟5角、1元硬币和5元纸币投入,用两个数码管显示商品价格,及应找回的钱数。
(4)每次只能售出一种小商品,当投币结束时,按下确认键,若交易成功,则售出货物并找回剩余的硬币;
若交易不成功,则找回所投的硬币。
按下复位按键,并将所有拨码开关复位,则回到初始状态。
1.2总体设计
采用FPGA来设计的原理图如图1.1所示.它由控制输入电路、FPGA、电机驱动、显示电路电路组成。
图1.1采用FPGA设计的自动售货机原理方框图
控制输入电路主要是为用户设计的,起到一个输入控制的作用。
FPGA是现场可编程逻辑器件,也是本设计方案的核心内容,它是实现自动售货机运作的主要控制模块。
将编写好的verilogHDL程序烧制到现场可编程逻辑器件FPGA中,然后通过控制输入电路把信号输入到FPGA,由八个开关控制输入信号,即消费者选择商品和消费者投币及确认消费,动态数码管显示输出信号,即找零环节和所选择的商品、消费者投币。
1.3方案设计
使用现场可编程逻辑器件(FPGA)制作,利用VerilogHDL硬件描述语言编程进行控制,然后烧写实现。
对于自动售货机的设计,本方案采用的是现场可编程逻辑器件来实现,它的优点是所有电路集成在一块芯片上,此方案所需的外围电路简单,这样它的体积就减少了,同时还提高了系统的稳定度,还可以用软件QuartusⅡ软件进行仿真和调试等,可以充分利用verilogHDL硬件描述语言方便的编程,提高开发效率,缩短研发周期,降低研发成本;
而且易于进行功能的扩展,实现方法灵活,调试方便,修改容易。
第二章详细设计
2.1自动售货机状态描述
判断开关被按下的个数N。
若N>
=2表示所选本次选择无效,返回初始状态;
若N=1则显示所选商品,并继续执行下面的流程。
4个开关分别代表4种商品。
3个开关分别代表投入0.5元,1元,5元,统计投入总额。
投入总额与商品价格做比较,如果总额<
商品价格,退钱并返回初始状态;
如果总额>
=商品价格,则继续执行下面的程序。
找零=总额-商品价格,数码管显示找零金额。
状态图如图2.1所示:
图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框图(Visio绘制)
3.3VerilogHDL源程序(见附录)
第四章结果与讨论
4.1实验调试
4.1.1调试步骤
软件调试:
运行QuartusII软件,观看仿真波形,为了让数码管显示稳定,我们将原来的50MHZ的时钟信号进行了10000分频,这样以来,我们的display就不能很好的在仿真波形中显示,为此,我们把中间变量price和price_all(即控制display的变量)调出来显示,只要price和price_all显示正确,仿真就成功。
仿真波形如下:
硬件调试:
在软件调试调试成功的情况下,接下来我们要进行硬件调试,步骤如下:
①运行QuartusII软件,打开工程。
②再次编译源程序(见附录)。
③分配管脚(见附录)。
④将生成的.sof文件写入FPGA试验箱中。
⑤根据要求选择几种买东西的可能情况,在实验箱上实验,观察记录结果。
实物拍照:
交易成功的照片流程(图中拨码开关从左到右依次对应:
商品1(0.5元),商品2(1元),商品3(1.5元),商品4(2元),投币0.5元,投币1元,投币5元。
图中按键从左到右第三个为确认,第四个为复位):
照片依次为:
初始状态,商品选择状态,投币状态,确认交易状态。
交易不成功的照片流程(第三个图中左边的LED不应该亮,之所以亮是忘了复位了):
4.1.2实验现象
⑴选择买1.5元的商品,投5元的金额,调试现象如下:
①选择1.5元商品数码管显示1.5,再选择一种商品,数码管显示初始状态(88),重新进行商品选择。
②按下5元投币键,对应数码管显示5.0。
③按下确认购买开关,找零时,对应数码管显示3.5,对应1.5元商品的LED灯亮。
⑵选择1.5元的商品,投0.5元的金额,调试现象如下:
①选择1.5元的商品,对应数码管显示1.5。
②按下0.5元的投币键,对应数码管显示0.5。
③找零显示0.5元,退回所投的钱,表示警告的LED灯亮(交易不成功)。
4.2结果与分析
调试过程中出现的问题及原因:
①数码管显示不正确。
管脚配置不正确导致数码管显示异常。
②重新分配管脚后,仍为先前程序的操作结果。
重新配置管脚后,未运行程序,使得烧写进去的仍为原先的程序。
③步进电机送货不理想,该送的时候送,不该送的时候也送,再次查看相关源程序,多次修改调试。
。
参考文献
[1]夏宇闻编著《Verilog数字系统教程》北京航空航天出版社
[2]梁瑞宇编写《FPGA设计实验指导书(VerilogHDL)》
[3]潘松等著EDA技术实用教程:
Verilog_HDL版(第4版)
附录
(1)自动售货机主模块
moduleauto_seller(clk,rst,display,btn_ok,btn_mon,btn_sell,
led_warn,led,StepDrive);
inputclk,rst,btn_ok;
input[2:
0]btn_mon;
//选择放入的钱
input[3:
0]btn_sell;
//选择商品bbt_5,gz_10,kqs_15,kl_20
output[6:
0]led;
//led_5,led_10,led_15,led_20
outputled_warn;
//钱不足,指示灯
output[15:
0]display;
//数码管显示投入面值,diaplay[15:
8]=com位选,display[7:
0]=段码
output[3:
0]StepDrive;
regclk_500Hz;
reg[6:
wires;
regled_warn;
//警告放入钱不足
reg[15:
reg[31:
0]counter;
(*synthesis,keep*)reg[9:
0]price,price_all;
reg[1:
0]flag=2'
b00;
//数码管显示标志位
0]flag1=2'
0]flag2=2'
parameterCOUNT1=25'
d10000;
step_motoru(.StepDrive(StepDrive),.clk(clk),
.StepEnable(s),.rst(rst));
//步进电机例化
assigns=(led[3:
0]==4'
b1111)||(btn_ok==1)||(led_warn==0);
/*分频使数码管显示稳定*/
always@(posedgeclk)
begin
if(counter==0)
begin
counter<
=COUNT1;
clk_500Hz<
=~clk_500Hz;
end
else
=counter-1;
end
always@(negedgerstorposedgeclk)
begin
if(!
rst)
led=7'
b111_1111;
//LED灭
price_all=0;
//价格清零
led_warn=1;
price=0;
end
else
begin/*三种面值共8种组合*/
case(btn_mon)
3'
b001:
beginprice_all=5;
end
b010:
beginprice_all=10;
b100:
beginprice_all=50;
b011:
beginprice_all=15;
b101:
beginprice_all=55;
b110:
beginprice_all=60;
b111:
beginprice_all=65;
default:
beginprice_all=0;
endcase
case(btn_sell)
4'
b0001:
beginprice=5;
end
b0010:
beginprice=10;
b0100:
beginprice=15;
b1000:
beginprice=20;
beginprice=0;
endcase
if(btn_ok==0)
if(price_all<
price)//放入钱不足
begin
led_warn=0;
price=0;
end
begin//金钱足够
price_all=price_all-price;
if(price_all==0)led_warn=1;
case(price)//LED灯显示货物卖出
5:
beginled=7'
b111_1110;
10:
b111_1101;
15:
b111_1011;
20:
b111_0111;
default:
endcase
end
/*分频后将时钟给数码管,数码管分别显示放入钱的多少、商品价格*/
always@(posedgeclk_500Hz)
begin
if(btn_sell)
case(flag)
2'
b00:
begindisplay<
={8'
b1111_1110,1'
b1,led7(price%10)};
flag=2'
b01;
b01:
b1111_1101,1'
b0,led7(price/10)};
endcase
if(btn_mon)
case(flag1)
2'
begin
display<
b1,led7(price_all%10)};
flag1=2'
b0,led7(price_all/10)};
flag1=2'
endcase
case(flag2)
2'
begindisplay<
={8'
b1,7'
b0};
flag2=2'
endcase
/*数码管段码表,供阳数码管[6:
0]=hgfedcba*/
function[6:
0]led7;
0]dis_input;
case(dis_input)
0:
led7=7'
b100_0000;
1:
b111_1001;
2:
b010_0100;
3:
b011_0000;
4:
b001_1001;
5:
b001_0010;
6:
b000_0010;
7:
b111_1000;
8:
b000_0000;
9:
b001_1000;
default:
endcase
endfunction
endmodule
(2)步进电机送货模块
modulestep_motor(StepDrive,clk,StepEnable,rst);
inputclk;
inputStepEnable;
inputrst;
regDir,t;
reg[11:
0]c;
output[3:
reg[3:
reg[2:
0]state;
reg[31:
0]StepCounter=32'
b0;
parameterStepLockOut=32'
d200000;
regInternalStepEnable;
always@(posedget)
beginif(c==12'
h1111_1111_1111)
Dir=~Dir;
always@(posedgeclkornegedgerst)
if(!
rst)
StepDrive<
=4'
state<
=3'
StepCounter<
=32'
else
if(~StepEnable==1'
b1)
InternalStepEnable<
=1'
b1;
=StepCounter+31'
if(StepCounter>
=StepLockOut)
b0;
t=~t;
if(InternalStepEnable==1'
b1)
=~StepEnable;
if(Dir==1'
b1)state<
=state+3'
b001;
elseif(Dir==1'
b0)state<
=state-3'
case(state)
3'
b000:
b0001;
b001:
b0011;
b010:
b0010;
b011:
b0110;
b100:
b0100;
b101:
b1100;
b110:
b1000;
b111:
b1001;
endcase
end
(3)引脚分配