一、实验原理根据原理图,将计数器模块、显示模块、扫描模块、译码器模块等分别做出。其原理是在1S内用待测信号给计数器计数,并在一秒结束时给计数器清零,计出来用缓存器缓存,在数码管中显示出来。二、方案论证一、通过50M的时钟进行计数获得精密的1HZ——计数器用VerilogHDL语言实现在1HZ为底电平时计数——门控电路用或门开启——1HZ为高电平时进行数据锁存与显示——利用VerilogHDL语言使前面的0不显示。计数器用VerilogHDL语言在写代码时可以用复制粘贴的方法可以简便的实现。通过50M的时钟进行计数获得精密的1HZ后只是经过很短的时间内进行计数器的清零及数据的琐存,并且得到的是1HZ的精密时钟。把锁存的数据进行清0的转换后利用分时扫描,后通过数码管译码显示。说明:Cnt9999:0000~9999计数器;Buffer:锁存器;Scan:扫描显示共8个模块三、实验步骤一、计数器模块计数器模块的仿真波形二、锁存模块利用32位的D触发器进行储存计数器送给它的数据。在时钟为上升沿的时候触发保存数据。锁存模块的源代码:modulebuffer_32(clr,clear,in,out);inputclear,clr;input[31:0]in;output[31:0]out;reg[31:0]out;always@(posedgeclearornegedgeclr)if(!clr)out=0;//elseif(clear)out=in;elseout=in;endmodule三、转化清零模块波形仿真波形modulecnt9999(clr,clk,q,c);inputclr,clk;outputc;output[15:0]q;regc;reg[15:0]q;always@(posedgeclkornegedgeclr)beginif(!clr)beginq[15:0]=0;c=1'b0;endelseif(q[15:0]==16'H9999)beginq[15:0]=0;c=1'b1;endelseif(q[11:0]==12'H999)beginq[15:0]=q[15:0]+12'H667;c=1'b0;endelseif(q[7:0]==8'H99)beginq[15:0]=q[15:0]+8'H67;c=1'b0;endelseif(q[3:0]==4'H9)beginq[15:0]=q[15:0]+4'H7;c=1'b0;endelsebeginq[15:0]=q[15:0]+1'b1;c=1'b0;endendendmodule四、扫描显示模块把存储的数据分别分给8个数码管,利用循环扫描即可显示出所要显示的数据。扫描显示模块的仿真波形modulescan(clk,q);inputclk;output[2:0]q;reg[2:0]q;always@(posedgeclk)beginq=q+1;endendmodule四、引脚分配五、实验总结频率就是信号在1s内发生相同变化的次数,简易频率计就是基于这个原理设计的。我们先产生一个低电平为1s,高电平为1/50M秒的周期信号clk,用该信号与待测信号相与作为计数器的输入时钟,并把clk的上升沿作为缓存器的开关,把clk的高电平作为计数器的清零信号,这样就能保证缓冲器中存放的始终是待测信号在一秒内的跳变次数,也即待测信号的频率。实验的原理尽管很清楚,但真正看到实验现象还是经历了一番波折,在写8选1数据选择器的时候,定义模块端口时,由于疏忽,把四位位宽漏写成了1位,结果在数码管上显示的始终只有0和1两种数字。为了改正这个错误,我把程序的主要模块都检查了一遍,结果不管怎么改实验现象都没有出来,这让我郁闷了很长一段时间,原理明明是对的,为什么就没有效果呢?最后我把整个程序都打印出来,一行一行地检查,最后终于找到了症结所在,就是8选1数据选择器的位宽弄错了!经历了这次错误,让我明白了写程序还是不能大意,8选1数据选择器虽然简单,却因为位宽这个小小的错误让我浪费了很长的时间,检查错误时也因为其简单而没有认真对待。