verilog四位秒表实现.doc_第1页
verilog四位秒表实现.doc_第2页
verilog四位秒表实现.doc_第3页
verilog四位秒表实现.doc_第4页
verilog四位秒表实现.doc_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

西北工业大学FPGA技术实验实验报告四(四位秒表的设计与实现)学 院: 软件与微电子学院 学号: 姓 名: 专 业: 微电子学 实验时间: 2011.11.16 实验地点: 毅字楼335 指导教师: 王少熙 西北工业大学2011年 11月一、实验目的及要求实验目的:学会复杂编程的思想,综合运用verilog语言,进行复杂电路设计及根据模拟综合仿真结果对设计进行优化。实验要求:设计时长度为1小时,计时精度为1秒;初始值为:00:00 计时最大值:59:59。按照三个模块进行,顶层模块不做逻辑设计,只对底层模块例化,底层模块分为计时模块和译码模块。二、实验设备(环境)及要求 本次实验使用的主要工具为:Synplify Pro 9.6.2和 ModelSim SE 6.2b。三、实验内容与步骤1. 实验总体设计思路按照题目要求本次实验的总体分为三块,即:顶层模块、计时模块和译码模块。先设计底层模块,然后在顶层模块进行例化。计时模块:通过在例化时对分频系数的改变,得到1 秒,10 秒,1 分,10 分的输出,再对每位计数值的最大值进行例化。在译码模块:对输出要显示的时间数字进行译码。系统框图如图1 所示:系统时钟1KHz分频计数模块时钟分频500Hz通用扫描显示模块个秒位0到9显示十秒位0到5显示个分位0到9显示十分位0到5显示Rst_n控制端图1 数字秒表总体框图下面具体说说每一个模块的实现原理:计数模块:我们要实现“分分:秒秒”显示的电子秒表,需要设计计数频率为1Hz 的计数器。因为“分分:秒秒”的结构对应有4个十进制数字(个位的秒,十位的秒,个位的分,十位的分),考虑到需要用硬件实现,在此,我们将每个显示的值分别进行计数,即分别针对个位的秒、十位的秒、个位的分、十位的分设计对应的计数器,其中个位的秒计数频率为1Hz,即在现实生活中的1秒 个位的秒变化一次,其从0到9计数,当从9回到0时,同时向十位秒前进一位,使得十位的秒进行计数加1。十位的秒从0到5计数,当从5回到0时,向前进一位,使得个位的分进行计数加1。个位的分从0到9计数,当从9回到0 时,向前进一位,使得十位的分进行计数加1。十位的分则从0 到5计数,计数到5时,又回到0。当四位都达到最大值后,下一秒从0开始。有分频计数,但我们在此所利用的是系统的1KHz(即本代码中的sysclk_1KHz)的时钟,这样更符合代码规范和要求。译码模块:发光二极管七段显示器(也叫七段数码管)的每一个字段是一个发光二极管。图2为七个显示字段的示意图,图3为七段数码管可以显示的16种字符,当某些发光二极管因为有驱动电流而发光时,因为发光的字段不同,可以组成不同的数字,当输入代码小于9时,译码器的输出应该使七段显示器显示09十种数字;当输入代码大于9时,译码器的输出应该使七段显示器显示一定的图形,这些图形应该与有效的数字有较大的区别,不至于引起混淆。当输入代码为15时,七段数码管所有的LED都不亮,这时为灭零状态。为了使用方便,通常将各发光二极管的阳极或阴极连接在一起,这样七段LED显示器就有两种连接方式,如果将各发光二极管的阳极连接在一起成为公共电极,则称为共阳极接法,如图4;如果将各发光二极管的阴极连接在一起成为公共电极,则称为共阴极接法,如图5。我们在本次试验中用共阴极接法。图2 七段数码管显示字段的示意图图3 七段数码管可以显示的16种字符 图4 共阳极7段LED 图5 共阴极7段LEDLED 的静态显示虽然有编程容易、管理简单等优点,但是静态显示所要占的资源很多,所以在显示的LED 点较多的情况下,一般都采用动态显示方式。七段LED数码显示器结构利用人的视觉延迟的特点,采用扫描的方式驱动多位七段LED数码管,节省驱动电路,降低功耗。保证一定的扫描循环频率,得到较好的显示质量。各位七段LED数码管公用一个段驱动器、一个段码锁存器,为段驱动器提供逻辑输入。每位七段LED数码管的公共端连接一个位驱动器,控制各位数码管的点燃。位驱动器由一个位码锁存器提供输入逻辑电平。显示器在系统中占用两个端口号:段码口与位码口。在本模块中,以扫描显示的频率进行2比特宽的模4计数,然后由其值从4个数码管的待显示值输入(本模块的输入为计时模块的输出,即各个位上的的数字data_0、data_1、data_2、data_3)中选择对应的一个经译码后连接到公共的段控制输入端,同时将计数值经2到4译码后输出到对应数码管位的公共端,点亮对应的数码管。输出很简单:led_data(控制七段显示译码加上冒点)led_sel(控制当前时刻显示的位(个秒还是十秒还是个分还是十分)。冒点的处理:数码管中间的时间分隔冒号点(对应为左边第2个数码管位的DP点)每秒钟闪烁一次,其频率为1Hz,只需要输出1Hz,占空比为50%的周期信号即可。其他数码管位的点号不需要显示,对应的DP 点输出低电平无效信号即可。这4个信号 所示的显示切换计数值进行4 选1 选择后接到数码管上公共的DP控制端。在这里我们还是利用一个计数器,当计数达到500的时候就归零,并且控制DP的时钟就翻转一次,就可以完美得到频率为1Hz的信号,在显示的时候我们利用语句(dp)&(led_sel_num=2h2),即可控制。顶层模块:在前两个底层模块实现的基础上,实现此模块并不难,首先是对个秒位进行例化,主要是控制最大计数个数(个秒为500)以及输出端口。其余三位也是同样的方法只不过十分位最大计数5000,个秒为30000,十秒为300000。然后是对译码模块例化,要把计时模块的输出对应到此模块的输入以及对扫描频率最大值进行控制。2. 系统结构和模块划分,关键子模块之间的接口实现定义。本次实验划分为三个模块:顶层模块、计时模块和译码模块,顶层模块只做例化,不做逻辑设计,底层模块进行具体功能实现。由于两个底层模块所用的时钟(sysclk_1KHz)和控制信号(rst_n)都是全局的,接口的实现比较容易,关键是计时模块的输出与译码模块输入的衔接,在顶层模块设了四个wire 变量data_0、data_1、data_2、data_3,然后在对计时模块例化(四个输出端口分别与之对应),再在译码模块例化(四个输出端口也分别与之对应),这样就可以完美把两个底层模块衔接起来。3. 子模块设计以及接口定义 计时模块:此模块主要是进行计数分频,通过不同分频系数得到我们需要的,通过在例化时对分频系数的改变,得到1 秒,10 秒,1 分,10分的输出,再对每位计数值的最大值进行例化。接口分别为系统时钟sysclk_1KHz,系统控制端rst_n,子分频系数sub_counter_max,以及分频系数counter_max和输出data_out。译码模块:利用扫描技术,对输出要显示的时间数字进行译码。接口分别为系统时钟sysclk_1KHz,系统控制端rst_n,扫描频率scan_freq,个分位的输入data_0,十分位的输入data_1,个秒位的输入data_2,十秒位输入data_3,七段控制控制led_data,以及当前显示位led_sel。4. 测试平台设计本次实验的实验平台很简单,从顶层模块来看只有两个输入,两个输出,即:系统时钟sysclk_1KHz,系统控制端rst_n,七段控制控制led_data,以及当前显示位led_sel。我们只要对时钟和控制端进行简单例化即可实现。具体实现代码如下:timescale 1ms/100us / 按照1KHz要求实现module stopwatchtb; reg clk; reg rst; wire 7:0 led_data; wire 3:0 led_sel;initialbeginrst=0; #1 rst=1; / 对控制信号赋值 #1000000 $finish;endalwaysbegin #0.5 clk=1; / 时钟周期11ms #0.5 clk=0;end / 实例化stopwatch s1(clk,rst,led_data,led_sel);endmodule四、实验结果与数据处理1. Modelsim仿真结果,波形图,代码覆盖率图等。由于波形图太长,我们只能选取几个有代表行的点来进行说明与分析。首先来看图6:左边为系统的输入输出以及中间一些端口,从上到下依次为系统时钟(clk),控制端(rst),七段译码控制端(led_data),显示位控制端(led _sel)以及计数模块的输出(个分位的输出data_0,十分位的输出data_1,个秒位的输出data_2,十秒位输出data_3)(虽然这几个端口并没有在顶层模块输入输出端口,但是这几个端口是确定我们设计对否的关键,于是在此列出),我们可以看到竖线是显示器上00:59到01:00的分界,七段译码控制端(led_data)显示的是10001000,其中最高位是冒点DP控制端,后七位是七段译码(低电平有效),对照显示结构,可知此时显示的是1,显示位控制端(led _sel)(低电平有效)是0111,即此时点亮的是个秒位,下面四个从上到下依次对应个秒,十秒,个分,十分位,即竖线左边的是00:59而右边的是01:00。图6 modelsim仿真结果关键展示(1)再来看看图7:经过上面的分析我们可以很容易的看到,此图展示09:59到10:00转换的过程,七段译码控制端(led_data)为0(0001000),显示位控制端(led _sel)为十分位(1110)。图7 modelsim仿真结果关键展示(2)最后再来看看图8:次图展示的是从59:59到00:00跳转的过程,此时(竖线左边)七段译码控制端(led_data)为5(0010100),显示位控制端(led _sel)为十秒位(1011)。图8 modelsim仿真结果关键展示(3)通过以上几幅仿真图的展示,可以认为程序是正确的,能够实现我们想要到达的目的。再用modelsim进行代码覆盖率测试如图9所示,图9 modelsim代码覆盖率测图可见覆盖率已经很好了,到达了100%。设计程序的代码如下:/ 顶层模块,只做例化,不做设计module stopwatch(sysclk_1KHz,/ 系统时钟1kHzrst_n,/ 全局控制端,低电平有效led_data,/ 七段译码控制led_sel/ 显示位控制);input sysclk_1KHz;input rst_n;output 7:0 led_data;/ 最高位控制冒点,低七位七段译码output 3:0 led_sel;parameter COUNTER_MAX_1S = 19h1F4; / 个秒分频系数500parameter COUNTER_MAX_10S = 19h1388;/ 十秒分频系数5000parameter COUNTER_MAX_1M = 19h7530; /个分分频系数30000parameter COUNTER_MAX_10M = 19h493E0;/ 十分分频系数300000wire 3:0 data_0; / 用于计数模块和分频模块衔接wire 3:0 data_1;wire 3:0 data_2;wire 3:0 data_3; / 调用计时模块,对个秒位例化count U_counter_1s(.sysclk_1KHz(sysclk_1KHz),.rst_n(rst_n),.sub_counter_max(4h9), / 周期为10.counter_max(COUNTER_MAX_1S),.data_out(data_0); / 调用计时模块,对十秒位例化count U_counter_10s(.sysclk_1KHz(sysclk_1KHz),.rst_n(rst_n),.sub_counter_max(4h5), / 周期为6.counter_max(COUNTER_MAX_10S),.data_out(data_1); /调用计时模块,对个分位例化count U_counter_1m(.sysclk_1KHz(sysclk_1KHz),.rst_n(rst_n),.sub_counter_max(4h9), / 周期为10.counter_max(COUNTER_MAX_1M),.data_out(data_2); /调用计时模块,对十分位例化count U_counter_10m(.sysclk_1KHz(sysclk_1KHz),.rst_n(rst_n),.sub_counter_max(4h5), / 周期为6.counter_max(COUNTER_MAX_10M),.data_out(data_3); / 调用译码模块led_decoder U_decoder(.sysclk_1KHz(sysclk_1KHz),.rst_n(rst_n),.scan_freq(8hFA), / 扫描频率500Hz.data_0(data_0),.data_1(data_1),.data_2(data_2),.data_3(data_3),.led_data(led_data),.led_sel(led_sel);endmodule/ 计数模块module count(sysclk_1KHz,rst_n,sub_counter_max, / 各个显示位周期counter_max, / 计系统时钟最大值data_out);parameter M=19; input sysclk_1KHz;input rst_n;input M-1:0 counter_max; / 最大值300000,18位input 3:0 sub_counter_max;/ 最大值9,4位output 3:0data_out;reg M-1:0 counter; / 计数器,计系统时钟reg sub_clk; / 分频产生的时钟 reg 3:0 sub_counter; /计数器,计counteralways(posedge sysclk_1KHz or negedge rst_n)begin /用于产生counter ,为下面服务if(!rst_n)counter=0;elseif(counter=counter_max-1)counter=0;elsecounter=counter+1;endalways (posedge sysclk_1KHz or negedge rst_n)beginif(!rst_n)sub_clk=0;elseif(counter=counter_max-1)sub_clk=sub_clk; / 当counter 达到 最大时翻转elsesub_clk=sub_clk;endalways(posedge sysclk_1KHz or negedge rst_n)beginif(!rst_n)sub_counter=0;else if(sub_counter=sub_counter_max)&(counter=counter_max-1)sub_counter=0; / 如果两个都到最大值,清零elseif(counter=counter_max-1) / sub_counter计数条件sub_counter=sub_counter+1;elsesub_counter=sub_counter;endassigndata_out=sub_counter; / sub_counter就是我们要的结果endmodule/译码模块module led_decoder(sysclk_1KHz,rst_n,scan_freq, / 扫描频率,500Hzdata_0, / 各个位输入data_1,data_2,data_3,led_data, / 七段译码控制led_sel / 显示位控制);input sysclk_1KHz; / 系统时钟 1KHz.input rst_n; / 全局控制端input 7:0 scan_freq; input 3:0 data_0; / 个秒输入input 3:0 data_1; / 十秒输入 input 3:0 data_2; / 个分输入input 3:0 data_3; /十分输入output 7:0 led_data; output 3:0 led_sel;reg 7:0 led_data;reg 3:0 led_sel;reg 3:0 led_data_hex; / 传输此时输入的数据reg 7:0 scan_counter; / 扫描计数器reg 1:0 led_sel_num; / led选择管子reg 8:0 cnt_time; / 计数器,用于控制冒点dpreg dp; / 冒点always (posedge sysclk_1KHz or negedge rst_n)beginif(!rst_n)scan_counter = 0; / 产生扫描频率,用于选择ledelse scan_counter = scan_counter+1;endalways (posedge sysclk_1KHz or negedge rst_n)beginif(!rst_n)led_sel_num = 2b0;else / 四个led依次点亮if(scan_counter = scan_freq)led_sel_num = led_sel_num+1;elseled_sel_num = led_sel_num;endalways (led_sel_num)begincase(led_sel_num) / 具体到电平控制2b00 : led_sel = 4b0111;2b01 : led_sel = 4b1011;2b10 : led_sel = 4b1101;2b11 : led_sel = 4b1110;default : led_sel = 4b0000;endcaseendalways (led_sel_num or data_0 or data_1 or data_2 or data_3)begincase(led_sel_num) / 不同时刻传送不同位2b00 : led_data_hex = data_03:0;2b01 : led_data_hex = data_13:0;2b10 : led_data_hex = data_23:0;2b11 : led_data_hex = data_33:0;default : led_data_hex = 4h0;endcaseendalways (posedge sysclk_1KHz or negedge rst_n)begin / 此计数用于控制dpif(!rst_n)cnt_time = 9h0;elseif(cnt_time=9h1F4)cnt_time = 9h0;elsecnt_time = cnt_time + 9h1;endalways (posedge sysclk_1KHz or negedge rst_n)begin if(!rst_n)dp = 1b1;else if(cnt_time=9h1F4)dp= dp;elsedp = dp;endalways (dp or led_sel_num) / 冒点的显示,1s一次begin if(dp)&(led_sel_num=2h2)led_data7 = 1h0;elseled_data7 = 1h1;endalways (led_data_hex) / 七段译码beginc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论