五邑大学实验报告实验课程名称数字频率计的VerilogHDL语言实现院系名称:信息工程学院专业名称:通信工程(物联网工程)实验项目名称:EDA实验班级:110711学号:11071107报告人:冯剑波实验六数字频率计的VerilogHDL语言实现一、实验目的:1、掌握较复杂数字电路或系统的纯VerilogHDL实现方法;2、体会纯VerilogHDL语言输入设计与原理图输入设计的差别。二、实验原理:数字频率计是用来测量输入信号的频率并显示测量结果的系统。一般基准时钟的高电平的持续时间为sT10,若在这0T内被测信号的周期数为N则被测信号的频率就是N,选择不同的0T,可以得到不同的测量精度。一般0T越大,测量精度越高,但一次的测量时间及频率计所需的硬件资源也增加。三、设计任务与要求:1、设计一个6位频率计,测量范围从1Hz到999999Hz,测量结果用6个数码管显示,基准时钟频率为1Hz;2、只显示测量结果,中间计数过程不显示;结果更新时间2秒一次;3、频率计只设一个复位键,按下该键(reset=0)系统复位,释放该键(reset=1)系统工作,测量并显示结果。4、显示用静态方式;5、用VerilogHDL实现上述要求的频率计。四、设计源程序及注释与仿真结果设计源程序:modulepinlvji(oHEX0,oHEX1,oHEX2,oHEX3,oHEX4,oHEX5,clk_50M,clk_1Hz,reset,signal_out);inputclk_50M,reset;//50MHz时钟输入、复位output[6:0]oHEX0,oHEX1,oHEX2,oHEX3,oHEX4,oHEX5;//数码管0-5,分别显示个、十、百、千、万、十万位的数字outputregclk_1Hz;outputregsignal_out;regsignal_in;reg[29:0]cnt;reg[29:0]cnt1;regcount_en;//计数允许,count_en=1时计数,下降沿到来时锁存regload;reg[3:0]ge,shi,bai,qian,wan,shiwan;regcout1,cout2,cout3,cout4,cout5;reg[3:0]q0,q1,q2,q3,q4,q5;wireclr;always@(posedgeclk_50M)//改变Hz的范围,自己设定的频率1Hz-999999Hzbegincnt1=cnt1+1;if(cnt1=25_000_0)beginsignal_out=0;signal_in=0;endelseif(cnt1==50_000_0)cnt1=0;elsebeginsignal_out=1;signal_in=0;endendalways@(posedgeclk_50M)//50M分频产生1Hz时钟begincnt=cnt+1;if(cnt=25_000_000)clk_1Hz=0;elseif(cnt==50_000_000)cnt=0;elseclk_1Hz=1;end/*被测信号signal_in作为个位的输入,,signal_in上升沿到来时ge位+1;进位输出是cout1,作为十位的输入*/always@(posedgesignal_outorposedgeresetorposedgeclr)beginif(reset)ge=0;elseif(clr)ge=0;elsebeginif(count_en)beginif(ge==9)beginge=0;cout1=1;endelsebeginge=ge+1;cout1=0;endendendend/*cout1作为十位的输入,cout1上升沿到来时shi位+1;进位输出是cout2,作为百位的输入*/always@(posedgecout1orposedgeresetorposedgeclr)beginif(reset)shi=0;elseif(clr)shi=0;elsebeginif(count_en)beginif(shi==9)beginshi=0;cout2=1;endelsebeginshi=shi+1;cout2=0;endendendend/*cout2作为百位的输入,cout2上升沿到来时bai位+1;进位输出是cout3,作为千位的输入*/always@(posedgecout2orposedgeresetorposedgeclr)beginif(reset)bai=0;elseif(clr)bai=0;elsebeginif(count_en)beginif(bai==9)beginbai=0;cout3=1;endelsebeginbai=bai+1;cout3=0;endendendend/*cout3作为千位的输入,cout3上升沿到来时qian位+1;进位输出是cout4,作为万位的输入*/always@(posedgecout3orposedgeresetorposedgeclr)beginif(reset)qian=0;elseif(clr)qian=0;elsebeginif(count_en)beginif(qian==9)beginqian=0;cout4=1;endelsebeginqian=qian+1;cout4=0;endendendendalways@(posedgecout4orposedgeresetorposedgeclr)beginif(reset)wan=0;elseif(clr)wan=0;elsebeginif(count_en)beginif(wan==9)beginwan=0;cout5=1;endelsebeginwan=wan+1;cout5=0;endendendendalways@(posedgecout5orposedgeresetorposedgeclr)beginif(reset)shiwan=0;elseif(clr)shiwan=0;elsebeginif(count_en)beginif(bai==9)beginshiwan=9;endelsebeginshiwan=shiwan+1;endendendend/*****count_en=1时计数,count_en=0不允许计数********/always@(posedgeclk_1Hzorposedgereset)beginif(reset)begincount_en=0;endelsebegincount_en=~count_en;load=~count_en;endend/*****count_en下降沿到来时锁存数据****/always@(negedgecount_en)beginq0=ge;q1=shi;q2=bai;q3=qian;q4=wan;q5=shiwan;endassignclr=~clk_1Hz&load;/****调用数码管显示*****/led7su0(q0,oHEX0);led7su1(q1,oHEX1);led7su2(q2,oHEX2);led7su3(q3,oHEX3);led7su4(q4,oHEX4);led7su5(q5,oHEX5);endmodulemoduleled7s(datain,ledout);input[3:0]datain;outputreg[6:0]ledout;alwaysbegincase(datain)0:ledout=7'b1000000;1:ledout=7'b1111001;2:ledout=7'b0100100;3:ledout=7'b0110000;4:ledout=7'b0011001;5:ledout=7'b0010010;6:ledout=7'b0000010;7:ledout=7'b1111000;8:ledout=7'b0000000;9:ledout=7'b0010000;default:ledout=7'b1000000;endcaseendendmodule仿真波型:五、心得体会虽然我以前上了VerilogHDL语言,但是这都实习中还是碰到了一些问题,通过向老师,向同学寻求帮助和在网上,在图书馆查找相关的资料来一点点解决遇到的问题,从中感觉自己对VHDL语言的理解又进了一步!对硬件描述语言和纯元件语言,如c语言之间的差别又有了更深一层次的理解,不过自我感觉想要对VHDL语言要很熟练的掌握的话,还需要多多的联系才行的。六、思考题1、本设计的测量结果在6个数码管上显示,若采用静态显示的方式,每位显示需4根输出线,共需24根据输出线;若用动态扫描方式,只需6+7=13根线。什么叫动态扫描显示方式?你能写出动态扫描输出显示的程序吗?答:动态数码扫描显示方式是利用了人眼的视觉暂留效应,把6个数码管按一定顺序(从左至右或从右至左)进行点亮,当点亮的频率(即扫描频率)不大时,我们看到的是数码管一个个的点亮,然而,当点亮频率足够大时,我们看到的不再是一个一个的点亮,而是全部同时显示(点亮),与传统方式得到的视觉效果完全一样。动态扫描输出显示的程序如下:moduleled_dong(seg,sl,clk);//静态模块显示output[7:0]seg;//定义数码管段输出引脚output[3:0]sl;//定义数码管位(选择)输出引脚inputclk;//定义输入时钟引脚reg[7:0]seg_reg;//定义数码管段输出寄存器reg[5:0]sl_reg;//定义数码管位输出寄存器reg[5:0]disp_dat;//定义显示数据寄存器reg[29:0]count;//定义计数器寄存器always@(posedgeclk)//定义clk信号下降延触发begincount=count+1;//计数器加1endalways@(count[18:17])//定义显示数据触发事件begincase(count[18:17])//定义扫描显示数据3'b000:disp_dat=6'b100000;//显示十万位数3'b001:disp_dat=6'b010000;//显示万位数3'b010:disp_dat=6'b001000;//显示千位数3'b011:disp_dat=6'b000100;//显示百位数3'b100:disp_dat=6'b000010;//显示十位数3'b101:disp_dat=6'b000001;//显示个位数endcasecase(count[19:17])//选择数码管显示位3'b000:sl_reg=6'b100000;;//选择个位数码管3'b001:sl_reg=6'b010000;;//选择十位数码管3'b010:sl_reg=6'b001000;;//选择百位数码管3'b011:sl_reg=6'b000100;;//选择千位数码管3'b100:sl_reg=6'b000010;;//选择万位数码管3'b101:sl_reg=6'b000001;;//选择十万位数码管endcaseendalways@(disp_dat)//显示译码输出begincase(disp_dat)//选择输出数据6'h0:seg_reg=8'hc0;//显示06'h1:seg_reg=8'hf9;//显示16'h2:seg_reg=8'ha4;//显示26'h3:seg_reg=8'hb0;//显示36'h4:seg_reg=8'h99;//显示46'h5:seg_reg=8'h92;//显示56'h6:seg_reg=8'h82;//显示66'h7:seg_reg=8'hf8;//显示76'h8:seg_reg=8'h80;//显示86'h9:seg_reg=8'h90;//显示96'ha:seg_reg=8'h88;//显示a6'hb:seg_reg=8'h83;//显示b6'hc:seg_reg=8'hc6;//显示c6'hd:seg_reg=8'ha1;//显示