FPGA电子秒表计时器verilog实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
华中科技大学
《电子线路设计、测试与实验》实验报告
实验名称:用EDA技术设计多功能数字钟
院(系):电子信息与通信学院
专业班级:
姓名:
学号:
时间:
地点:
实验成绩:
指导教师:
2018 年 3 月 27 日
一. 实验任务及要求
基本要求:电子秒表
1)可计时的范围0.00s~99.99s(显示用七段数码管,显示小数点)。
2)能够暂停,能够在计时结束使用灯光或者声音报警提示。
提高要求: PWM波产生器
1)可输出占空比按10%递进的PWM波(示波器测量查看)。
二.实验条件
实验板:Nexys4 DDR
实验软件:ISE14.7,ModelSim
三.预习要求
1.NEXYS 4 DDR开发板说明。
2.有限状态机。
3.数码管扫描显示。
四.实验原理
1.电子秒表
设计框图
模块分析
1)分频模块(Divider.v)
将系统给定的100MHZ 的频率通过分频模块变成100Hz 的clk(用来计时)和4000Hz的
clk_seg(用来扫描数码管)。
代码如下:
原理:输入的100MHz 的信号为CLK_100MHz,每当CLK_100MHz 上升沿来时,Count_DIV 计数加1,且每当Count_DIV =100M/(2*100)=0.5M 时,CLK_Out取反一次并且Count_DIV <=0,这样会得到一个100Hz 的信号。
当需要得到4000Hz的clk_seg时,在顶层模块中修改parameter OUT_Freq=4000;这样,每当Count_DIV=100M/(2*4000)=12500时,CLK_Out取反一次并且Count_DIV <=0,这样会得到一个4000Hz 的信号。
在主程序中修改参数如下:
仿真时,为便于观察,在testbench中,将CLK_100MHz的周期设为2ns:
always #1 CLK_100MHz <= ~CLK_100MHz;
并修改参数如下,验证分频模块的正确性(图中数字16,8,1只表示频率的倍数关系,并非真正的频率)
其仿真图如下图:
从图中可以看出,CLK_100MHz的周期为2ns,clk_seg的周期为4ns,clk的周期为32ns,符合倍数关系,故分频模块的正确性得到验证。
2)七段数码管显示模块
运用4个七段数码管,前两个显示秒的十位和个位,后两个显示小数点后两位,因为要显示4个数码管,因此用4000Hz的频率扫描4个数码管,使每个数码管每隔1ms亮一次。
代码如下:
3)十进制计数器模块
因为每个数码管的计数规律都为:0-1-2-3-4-5-6-7-8-9-0-1……,所以采用十进制计数器。传入的参数stop表示暂停信号,若有暂停信号或没有使能,则保持计数不变。
代码如下:
4)主程序模块
代码如下:
代码分析:
Second0[3:0]表示百分位的数字,Second0[7:4]表示十分位的数字,Second1[3:0]表示个位的数字,Second1[7:4]表示十位的数字。
如果start为1,即计时开始,则开启数码管使能,数码管开始显示计数值,如果finish 等于1,表示计时完成,则alarm=1;点亮报警灯。
接下来调用四个counter10模块,通过控制其使能信号实现正确计时,第一个(C1)的使能信号为start,也就是按下开启键便开始计时,第二个(C2)的使能信号为Second0[3:0]==4’d9,也就是当百分位计时到了9,且下一个时钟的上升沿到来时,则十分位加1;第三个(C3)的使能信号为Second0==8’h99,也就是当小数点后计时到了99,且下一个时钟的上升沿到来时,则个位加1;第四个(C4)的使能信号为Second1[3:0]==4’h9 && Second0==8’h99,也就是当小数点后计时到了99而且个位计数到了9,且下一个时钟的上升沿到来时,则十位加1;这样,就能确保计时的准确性。
TestBench
`timescale 1ns / 1ns
module stopwatch_test;
reg CLK_100MHz;
reg rst;
reg start;
reg stop;
reg finish;
wire [6:0] HEX0;
wire [7:0] scan;
wire alarm;
wire dot;
stopwatch uut (
.CLK_100MHz(CLK_100MHz),
.rst(rst),
.start(start),
.stop(stop),
.finish(finish),
.HEX0(HEX0),
.scan(scan),
.alarm(alarm),
.dot(dot)
);
initial begin
CLK_100MHz = 0;
rst = 0;
start = 0;
stop = 0;
finish = 0;
#5;rst=1;#5;rst=0;
start=1'b1;
#64;stop=1'b1;#64;stop=0;
#6400;finish=1'b1;
#700;
end
always #1 CLK_100MHz<=~CLK_100MHz; endmodule