当前位置:文档之家› 数电自主实验——多功能电子表的设计与实现

数电自主实验——多功能电子表的设计与实现

多功能电子表的设计与实现——基于Basys2开发板电路设计及仿真1.实验目的1.了解有关FPGA的基本知识以及在电路设计的应用;2.了解并学会利用Verilog HDL硬件开发语言设计特定功能的电路,加深对知识的理解;3.了解Basys2开发板的特点并利用其元件在硬件上实现电路功能;4.在完成电路设计的过程中积累实际工程开发的经验;5.培养对于新型实验器材的理解和学习能力;6.在实验中练习并熟悉有关嵌入式系统开发的过程,为未来的学习打下基础。

2.总体设计方案或技术路线1.查阅资料,了解Basys2工作相关特点,对于FPGA的开发过程有初步认识;2.学习Verilog HDL硬件开发语言,阅读相关程序实例加深对于编程语言及模块的理解;3.确定本次试验电子表的功能,编写程序进行实现;4.对于编写程序进行调试,修改编写过程中出现的语法错误;5.再对上一步中调试好的程序进行仿真,编写仿真代码,分析输出并进一步修改程序;6.对于仿真好的程序建立ucf文件进行引脚约束及综合,生成bit文件;7.将bit文件烧写到开发板中,在硬件中实现预定功能;8.对整个实验过程进行总结,分析输出效果并寻找改进方法。

3.实验电路图由于本实验的电路设计基本全部由Verilog HDL硬件编程语言完成(具体代码附于报告结尾处),因此,没有具体芯片电路图。

而在仿真软件中,提供了实验电路的RTL级原理图和技术原理图。

因此我们可以利用ISE Design Suite 14.7电路设计和仿真软件自动生成实验电路的原理图,具体操作过程为,在编写好程序后,双击鼠标左键选择运行Synthesize - XST对电路进行综合,综合成功后,在其子目录下会有View RTL Schematic和View Technology Schematic两个选项,双击这两个选项即可查看该电路的RTL级原理图和技术原理图(如下图)。

由于电路的搭建主要由代码实现,因此软件提供的主要为电路的输入输出原理图,而非具体的电路图,但对于工程的建立与调试已经足够,也就不需要另画详细的电路图了RTL级原理图:技术原理图:4. 仪器设备名称、型号1.Basys2 FPGA开发板(配有电源及烧写程序线,可与PC计算机相连);2.Xilinx电路设计及仿真软件ISE Design Suite(版本号14.7);3.PC计算机,Win7系统;5.理论分析或仿真分析结果1.电路理论及功能分析本实验的目的是设计一个电子表,目前市面上销售的电子表主要有以下功能:时钟计时、调整时间、秒表和照明及发送信号功能(由于Basys2开发板上没有自带蜂鸣器,因此闹钟功能相对较难实现)。

记时功能,以一秒为单位,由Basys2内部时钟可以使得led显示数码管在每秒可以自动加一,从而实现电子表的计时功能,同时需要一个开关控制继续和暂停,并且在暂停的情况下,通过按键来控制数码管调节时间;调整时间,在电子表处在计时功能下,操纵按键可以控制相应位数的数码管变化,可以调整时间;秒表功能,通过开发板上的开关控制数码管一0.01秒的精度进行计时,并且之前的暂停信号在秒表功能下依然有效,此外,还可通过另一个开关对于秒表的清零进行控制;照明及发送信号功能,通过功能选择开关控制进入照明模式,可以使开发板上的8位led 灯按次序进行一定周期的闪烁,完成照明以及必要时发送信号的功能。

各模块流程图如下图所示:结束电子表效果图2.实验元器件介绍(1)可编程逻辑器件FPGAFPGA(Field-Programmable Gate Array)即现场可编程门阵列,是近年来十分流行的可编程元件,它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点,因此在工程中得到了广泛的应用。

对于FPGA的开发,通常以硬件描述语言(Verilog或VHDL)所完成的电路设计,可以经过简单的综合与布局,快速的烧录至FPGA 上进行测试,是现代IC设计验证的技术主流。

这些可编辑元件可以被用来实现一些基本的逻辑门电路(比如AND、OR、XOR、NOT)或者更复杂一些的组合功能比如解码器或数学方程式。

在大多数的FPGA里面,这些可编辑的元件里也包含记忆元件例如触发器(Flip-flop)或者其他更加完整的记忆块。

(2)Xilinx公司Basys2开发板Basys2是围绕着Xilinx公司的Spartan-3E FPGA芯片和一个Atmel AT90USB USB控制器搭建的,它提供了完整、随时可以使用的硬件平台,并且它适合于从基本逻辑器件到复杂控制器件的各种主机电路。

可兼容所有版本的ISE电路设计和仿真软件。

3.实验仿真利用ISE软件对于各个功能进行仿真,仿真时要建立Verilog Test Fixture文件,同时还要加入时钟信号,具体代码如下:parameter PERIOD = 20; //开发板自身晶振50MHzalways beginCLK = 1'b0;#(PERIOD/2) CLK = 1'b1; #(PERIOD/2);end具体各功能仿真如下图:照明及信号发送功能:秒表功能:计时功能:6.详细实验步骤及实验结果数据记录(包括各仪器、仪表量程及内阻的记录)1.确定本次试验电子表的功能,具体模块如以上部分介绍,并利用Verilog HDL语言编写程序进行实现(具体源程序文件附在报告后);2.对于编写程序在ISE Design Suite 14.7软件中选择Check Syntax选项进行编译,修改编写过程中出现的语法错误;3.再对上一步中调试好的程序进行仿真,编写仿真代码,分析输出并进一步修改程序;4.对于仿真好的程序建立ucf文件进行引脚约束(ucf文件代码附在报告后);5.对于程序文件和引脚约束文件在ISE Design Suite 14.7软件中选择Synthesize – XST选项进行程序的综合6.综合结束后,可以查看RTL级原理图和技术原理图;7.综合成功后,继续选择Implement Design完成电路的连接;8.完成后,进一步选择Generate Programming File选项生成可烧写到开发版中的二进制程序文件,即bit文件;9.选择Manage Configuration Project选项,将bit文件烧写到开发板中,在硬件中实现预定功能,具体界面如下图;10.对整个实验过程进行总结,分析输出效果并寻找改进方法。

7.实验现象及结论电路具体效果见下图:计时功能:调整时间功能:照明及信号发送功能:秒表计时及清零功能:经过实际观察,电子表电路预定功能全部实现,稳定性也较好,基本达到了预期的计划预实验目的。

至此,实验设计的主体部分完成。

8.实验中出现的问题及解决对策出现的问题:1. 在实验中,在实现功能选择时,由于Verilog HDL语言无法在同一个或者不同模块中对外设进行两次赋值,因此对于功能选择的实现造成了困难。

2.在开始将程序烧写到开发板上时,开发板一直在执行内部程序,而不响应计算机烧写的程序。

3.实验调试初期,功能显示一直不稳定,功能切换时总出现卡顿,而且经常输出不稳定信号。

解决对策:1.在编写代码时采用了单模块的结构,并且利用if条件判断语句对于赋值语句进行分割,以避免出现重复赋值的情况;2.将开发板右上角处的短路块由ROM MODE调节到PC MODE,即可实现计算机程序的执行;3.多次调试并仔细分析和优化代码,不断尝试修改代码以使得输出达到预期。

9.本次实验的收获和体会、对电路实验室的意见或建议本实验我有以下几点体会:1.对于课内没有学过的器材和知识,可以自己去学习和设计,例如试验中Basys2开发板和编程语言;2.要认识到理论和实际的区别,多进行电路的调试,了解实际情况不可能和仿真波形完全一致,要学会抓住主要特点进行功能的分析和代码的优化;3.对于好的想法,一定要勇于尝试,深入探究才能更深刻的理解元件特点;4.充分利用仿真软件与实际硬件电路相结合进行功能测试,这样可以达到事半功倍的效果;5.最后,强烈建议实验室能够再多提供一些外设(例如蜂鸣器)并多给一些实例程序和历程以供学习和参考。

10.参考文献[1] 沈涛,李传志,张小平,李斌. Xilinx FPGA/CPLD设计初级教程[M]. 西安电子科技大学出版社, 2009.[2] 杜勇. FPGA/VHDL设计入门与进阶[M]. 机械工业出版社, 2011.[3] 刘颖. 电路实验研究. 哈尔滨:哈尔滨工业大学,2009:8-13.[4] 周兴华. 手把手教你学CPLD/FPGA与单片机联合设计[M]. 北京航空航天大学出版社, 2010.11.[5] Reece T, Kiddie B T, Robinson W H. Identification of Trojans in an FPGA using Low-Precision Equipment[J].附录A 电路设计源程序代码1.模块定义以及初始化部分:module ewatch(clk,clr,digit,out1,pause,switch,led,adj);input clk,clr,pause,adj,switch;output digit,out1,led;wire pause; //定义暂停控制变量wire[7:6] switch;wire[3:0] adj; //定义时间调整变量adjreg[7:0] led;reg[6:0] out1; //定义数码管段选,即译码后的数据reg[3:0] digit; //定义数码管位选reg[31:0] count; //定义计数器reg[31:0] counter; //定义计数器reg cn; //cn为0.01秒向秒的进位位reg[3:0] sec_l,sec_h,min_l,min_h,display; //定义时钟各位及译码前数据initial out1<=7'b0000001;initial led<=8'b00000000;2.功能选择部分(包括照明和信号输出、时钟计时以及秒表功能):照明和信号输出:always@(posedge clk) //功能选择always部分begincount=count+1; //定义分频计数器count和countercounter=counter+1;if(switch[6]==1) //如果switch6为1进入照明及信号选择功能begin //发送SOS信号if(count==10000000) //短信号beginled<=8'b11111111;endif(count==20000000)beginled<=8'b00000000;endif(count==30000000)beginled<=8'b11111111;endif(count==40000000)beginled<=8'b00000000;endif(count==50000000)beginled<=8'b11111111;endif(count==60000000)beginled<=8'b00000000;endif(count==70000000) //长信号beginled<=8'b11111111;endif(count==90000000)beginled<=8'b00000000;endif(count==110000000)beginled<=8'b11111111;endif(count==130000000)beginled<=8'b00000000;endif(count==150000000)beginled<=8'b11111111;endif(count==170000000)beginled<=8'b00000000;endif(count==190000000)beginled<=8'b11111111;endif(count==200000000) //短信号beginled<=8'b00000000;endif(count==210000000)beginled<=8'b11111111;endif(count==220000000)beginled<=8'b00000000;endif(count==230000000)beginled<=8'b11111111;endif(count==240000000)beginled<=8'b00000000;endif(count==300000000)begincount=0;endend秒表功能部分:else if(switch[7]==1) //如果switch7为1则进入beginif(clr) //判断清零begincounter=30'd0;{sec_h,sec_l}=8'h00;{min_h,min_l}=8'h00;cn=1'b0;endelse if(!pause&&{min_h,min_l,sec_h,sec_l}!=16'b0101_1001_1001_1001) if(counter>=30'd499999)begincounter=30'd0;if(sec_l==9) //判断低位是否为9beginsec_l=0;if(sec_h==9)beginsec_h=0;cn=1;endelse sec_h=sec_h+1;endelsebeginsec_l=sec_l+1;cn=0;endif(cn==1)begincn=0;if(min_l==9)beginmin_l=0;if(min_h==5);elsemin_h=min_h+1;endelse min_l=min_l+1;endelse;endelse;end时钟计时部分:else //awitch6和7均为零时进入时钟计时功能beginif((count>=50000000)&&(pause==0)) //计算器以一秒钟为周期,整秒时刻时,如没有外加控制,则秒个位加1,计算器清零beginsec_l=sec_l+1;count=0;if(sec_l==10) //秒个位到10,秒十位加1,秒个位置零beginsec_l=0;sec_h=sec_h+1;if(sec_h==6) //秒十位到6,分个位加1,秒十位置零beginmin_l=min_l+1;sec_h=0;if(min_l==10) //分钟个位到10,分十位加1,分个位置零beginmin_h=min_h+1;min_l=0;if(min_h==6) //分钟十位到6,分十位置零min_h=0;endendendendelse if((count==25000000)&&(pause==1)) //在整秒时,若有外加控制,调整时钟,如不调整就为暂停begincount=0; //计数器置零if(adj[0]==1) //改变秒个位beginsec_l=sec_l+1;if(sec_l==10) sec_l=0;endif(adj[1]==1) //改变秒十位beginsec_h=sec_h+1;if(sec_h==6) sec_h=0;endif(adj[2]==1) //改变分个位beginmin_l=min_l+1;if(min_l==10) min_l=0;endif(adj[3]==1) //改变分十位beginmin_h=min_h+1;if(min_h==6) min_h=0;endendendend3.数码管选择及显示部分:always@(posedge clk)begincase(count[17:16]) //将需要显示的值付给display2'b00:begin digit<=4'b1110;display<=sec_l;end2'b01:begin digit<=4'b1101;display<=sec_h;end2'b10:begin digit<=4'b1011;display<=min_l;end2'b11:begin digit<=4'b0111;display<=min_h;endendcaseend4.数码管译码及输出部分:always@(posedge clk) //将display译码为七段数码管的二进制数字,赋给out1输出begincase(display)0:out1<=7'b0000001;1:out1<=7'b1001111;2:out1<=7'b0010010;3:out1<=7'b0000110;4:out1<=7'b1001100;5:out1<=7'b0100100;6:out1<=7'b0100000;7:out1<=7'b0001111;8:out1<=7'b0000000;9:out1<=7'b0000100;endcaseendendmodule附录B UCF源程序代码NET "clk" LOC = "B8" ;NET "clr" LOC = "F3" ;NET "pause" LOC = "P11" ; NET "switch<6>" LOC = "E2" ; NET "switch<7>" LOC = "N3" ; NET "adj<0>" LOC = "G12" ; NET "adj<1>" LOC = "C11" ; NET "adj<2>" LOC = "M4" ; NET "adj<3>" LOC = "A7" ; NET "digit<3>" LOC = "K14" ; NET "digit<2>" LOC = "M13" ; NET "digit<1>" LOC = "J12" ; NET "digit<0>" LOC = "F12" ; NET "out1<6>" LOC = "L14" ; NET "out1<5>" LOC = "H12" ; NET "out1<4>" LOC = "N14" ; NET "out1<3>" LOC = "N11" ; NET "out1<2>" LOC = "P12" ; NET "out1<1>" LOC = "L13" ; NET "out1<0>" LOC = "M12" ; NET "led<7>" LOC = "G1" ; NET "led<6>" LOC = "P4" ; NET "led<5>" LOC = "N4" ; NET "led<4>" LOC = "N5" ; NET "led<3>" LOC = "P6" ; NET "led<2>" LOC = "P7" ; NET "led<1>" LOC = "M11" ; NET "led<0>" LOC = "M5" ;。

相关主题