考试序号:20
自动打铃系统设计说明书
学 生 姓 名:
学 号:
专 业 班 级:
报告提交日期:
湖 南 理 工 学 院 物 电 学 院
目录
一 系统工作原理 ··································································· 3
设计要求 ············································································ 3
1、计时原理: ······························································· 4
2、模式信号mode 选择各个功能显示的原理: ········· 4
3、时间调整中数字上加的原理: ······························· 4 系统框图 ··········································································· 5
二 选择的FPGA 芯片及配置 ················································· 5
三 各模块分析 ······································································· 6 设计步骤: ············································································· 6 顶层文件端口说明: ·························································· 8 时序仿三真 ······································································· 9 附录:源程序(附注释) ····················································· 11
一系统工作原理
工作原理:时钟系统由八个数码管显示组成,其中第1、2个显示的为时的高位和低位,第3个数码管显示的是分隔符“-”,第4、5个为分的高低位,第6个也为隔符“-”,第7、8个为秒的高低位。时钟工作时用到两个频率,一个是系统频率Clk ,主要用来扫描数码管和分频,第二个是时钟工作频率Clk_1HZ(由Clk 分频得来),按下复位键,秒分时显示清零,工作时Clk (489HZ )不断通过3-8译码器值的改变来扫描时钟的八位数码管,由于人眼分辩不出这么高的频率,所以看到的是八个数码管一直同时亮着,与此同时控制端连着七段数码管的七位不断提供秒时分的高低位译码到数码管上显示,当Clk 计数到244次(500ms)时,Clk_1HZ翻转一次,这样Clk_1HZ的周期就为1s 整,每个Clk_1HZ的上升沿给秒的低位加1。按调时键S1进入调时模式,按下开关时程序里设置扫描到时的高低位时不显示,同时时的低位加1,松开开关时再显示出来,以此实现闪烁的功能,调分键也是同理。
各个输入输出端口定义如下:
Clk: 489HZ 的系统基准时钟输入。作为七段码管扫描频率。将其489分频可得到1HZ 的数字钟工作频率。 Rst: 系统复位信号, 低电平有效。复位后显示00-00-00。 S1: 调节小时信号, 低电平有效。每按下一次, 小时增加一个小时。 S2: 调节分钟信号, 低电平有效。每按下一次, 分钟增加一个分钟。
Spk: 输出到扬声器, 产生嘀、嗒的报时声。
Sel: 七段码管扫描驱动。因为是八个七段码管, 所以Sel 为三位总线。扫描频率为489HZ, 由于人眼的视觉效果, 呈现在眼前的便是整体的时-分-秒显示。 Display: 七段码管显示输出。 除此之外另设了几个寄存器: Clk_1HZ:1HZ 的数字钟工作频率 Clk_Count1:产生1Hz 时钟的分频计数器 Music_Count:产生扬声器声音频率的分频计数器 SECL,SECH:秒的低位和高位 MINL,MINH:分的低位和高位 HOURL,HOURH:时的低位和高位 Disp_Temp:显示存储中间量
数字时钟设计(C)
一、设计要求
(1)显示6位,分别是小时两位,分钟两位,秒两位; (2)可手动调节对时; (3)整点报时功能。 二、数字时钟设计原理 数字时钟设计原理框图:
1、计时原理:
在计时显示模块中,涉及到的是时分秒各个计数器的设计 ,“秒计数器”采用60进制计数器,每累计60秒,发出一个“分脉冲”信号,该信号将被送到“分计数器”。“分计数器”采用60进制计数器,每累计60分钟,发出一个“分脉冲”信号,该信号被送到“时计数器”。“时计数器”采用24进制计数器,可实现24小时的累计计数。 当计到24小时后,计数清零,如此循环。
2、模式信号mode 选择各个功能显示的原理:
使用mode 按键产生0、1信号在正常计时功能、校时功能之间的转换。mode 信号的作用主要体现在控制模块和时间显示模块中,虽然计时模块中也用到mode 信号,但是它只是turn 信号将秒信号清零的辅助作用,保证只有在m=0(即
普通计时显示)下turn 信号清零功能才起作用,在校时功能下只能是分、小时的切换功能。
(1)在控制模块下的作用:
在控制模块下,其实mode 和turn 信号的作用就是将change 数字上加信号按不同的mode 和turn 分成两个信号,分别是count1(时间显示下的分信号) 、counta(时间显示下的小时信号) 。
(2)在显示模块下的作用:
同在控制模块下的作用相同。只是将turn 信号选出的小时和分钟在同一个mode 下一起送至显示模块。
3、时间调整中数字上加的原理:
在时间校时调整模式下,数字的上加不仅受到change 信号的作用(即人工调时),还受本身在1Hz 信号下计时而随时发生的累加。由于在控制模块下设置了快加
的功能,所以有三部分信号对上加起作用,一是快加时以原始时钟的速率上加,二是慢加下的change 具体到各模块、各位的count1或counta ,三是秒信号记到59向分信号的进位。
一系统框图
二选择的FPGA 芯片及配置
① EP1K10TC100-3
主控芯片采用ACEX1K 系列的EP1K10TC100-3。ACEX 系列是当今Altera CPLD 中应用前景最好的器件系列之一[1,2]。该系列的 FPGA 由逻辑阵列块,LAB 、嵌入式阵列块EAB 、快速互联一计IO 单元构成,每个逻辑阵列块包含8个逻辑单元LE (logic element )和一个局部互联。每个逻辑单元则有一个4输入查找表(LUT )、一个可编程触发器、快速进位链、级连链组成,对个LAB 和多个EAB 则可通过快速通道互相连接。EAB 是ACEX 系列器件在结构设计上的一个重要的部件,他是输入端口和输出端口都带有的触发器的一种灵活的RAM 快,其主要功能是实现一些规模不太大FIFO,ROM 、RAM 和双端口RAM 等
② 7段共阳数码管
③ 扬声器
④开关及其相关电路
三各模块分析
设计步骤:
Quartus II 是Altera 公司综合性PLD 开发软件,支持原理图、VHDL 、Verilog HDL以及AHDL 等多种设计输入形式。内嵌自有的综合器和仿真器,可以完成从设计输入到硬件配置的完整PLD 设计流程。他的设计流程包括设计输入、编译、仿真和定时分析、编程及验证。而设计输入又包括原理图输入HD 文本输入、EDIF 网表输入和波形输入等几种方式。编译时要根据设计要求来设定编译方式以及编译策略,然后根据设定参数和策略来对设计项目进行网表提取、逻辑综合和器件适配,供分析、仿真以及编程使用。设计完成后需进行仿真,可以测试设计的逻辑功能以及延时特性。最后,可以用得到的编程文件来通过编程电缆配置PLD ,进行在线测试。在设计过程中,如果出现了错误,则需重新回到设计的输入阶段,改正错误或者调整电路后进行重新测试。
硬件描述语言HDL (Hardware Description Language )诞生于1962年。和SDL (Software Description Language)相似,经历了从机器语言、汇编语言到高级语言(HDL )的过程[7]。HDL 是用形式化方法去描述数字电路和设计数字逻辑系统的语言主要用于描述离散电子系统的结构和行为HDL 和其原理图是两种最常用的数字件电路描述方法,其中HDL 设计法具有更好的可移植性、通用性和模块划分和重用性等特点,在目前的工程设计开发流程主要是基于HDL 的。并且在目前工程设计中被广泛使用。所以,我们在使用EDA 设计数字电路时,其开发流程是基于HDL 的。VHDL 描述的时数字电路系统设计的行为、功能以及输入和输出。它在语法上和现代编程语言C 语言相似。应用VHDL 来进行系统设计,有功能强大、可移植性、独立性、可操作性、灵活性的特点。
FPGA 器件的内部结构
ACEX 1K系列器件是Altera 公司2000年推出的新型CPLD 产品。该器件基于SRAM ,结合查找表(LUT )和嵌入式阵列块(EAB )提供了高密度结构,可提供10 000到100 000可用门,每个嵌入式阵列块增加到16位宽可实现双端口,RAM 位增加到49125个。其多电压引脚可以驱动2.5V 、3.3V 、5.0V 器件,也可以被这些电压所驱动;双向I/O引脚执行速度可达250MHz 。该器件还应用Altera 专利技术进行了重要的生产改进,进一步降低了器件的成本,提高了产品的性能价格比。因此,ACEX 1K器件可用来实现许多逻辑复杂、信息量大的系统。但是在器件操作过程中,ACEX 1K系列器件的配置数据存储在SRAM 单元中,由于SRAM 的易失性,配置数据在每次上电时必须被重新载入SRAM 。
我选择的是ACEX1K 的EP1K100QC208-3芯片
顶层文件端口说明:
module
alarmclock(clk,clk_1k,mode,turn,sel,decodeout,alert,LD_alert,LD_hour,LD_min); input clk,clk_1k,mode,change,turn;
output alert,LD_alert,LD_hour,LD_min;
output[2:0] sel;
output[7:0] decodeout;
reg[7:0] hour,min,sec,hour1,min1,sec1,ahour,amin;
reg[1:0] m,fm,num1,num2,num3,num4;
reg[1:0] loop1,loop2,loop3,loop4,sound;
reg LD_alert,LD_hour,LD_min;
reg clk_1HZ,clk_2HZ,minclk,hclk;
reg alert1,ear;
reg count1,count2,counta,countb;
wire ct1,ct2,cta,ctb,m_clk,h_clk;
reg[2:0] sel;
reg[7:0] decodeout;
endmodule
图(1) 引脚示意图
三 时序仿三真
程序编译通过后,进行了一下仿真,设置Clk 为2周期为2ms (近似489HZ ),
End Time设了100s ,仿真结果如下图。
图2 仿真结果图
在Rst 复位端为从低变到高开始计时,计时Clk489次后秒的低位进1,这里由于244次Clk 上升沿后Clk_1HZ才翻转,故Clk 太密集观察困难,秒的低位到9以后秒高位进1,同理到分以及时,由于如果结束时间设得太长,仿真结果出来得太慢,此处只设了100s ,下图为放大后结果,计时Clk489次后秒的低位进1。
图3 1秒跳变放大图
下图为数码管显示放大后的仿真图,可以看到,Sel 为000时,系统扫描到的是秒的低位, 显示为Display :0111111,即显示0,以此类推,Sel 为001时,扫描
到的是秒的高位,010时为分隔符“-”„直到111时的高位,此处全部显示为零,因为计数还未到达1秒。
图4 数码管显示放大图
功能仿真结束后, 利用综合工具对Verilog HDL源码进行综合, 生成网表文件, 再根据该网表文件和所选可编程逻辑器件FPGA 进行优化、布局布线, 然后进行布线后仿真, 最后生成FPGA 码流文件, 把该文件输入可编程逻辑器件即可制成实际数字电路,最后在实验箱上运行正常,所有功能均能实现。
附录:源程序(附注释)
clk : 标准时钟信号;
clk_1k: 扫描时钟;
mode : 功能控制信号:
为0:计时功能;
为1:闹钟功能;
为2:手动校时功能;
turn : 接按键,在手动校时功能时,选择是调整小时,还是分钟; change : 接按键,手动调整时,每按一次,计数器加1;
hour,min,sec: 分别表示时\分\秒信号,采用BCD 码计数,分别驱动6个数码显示管显示时间;
alert : 输出到扬声器的信号,用于产生打铃声;
LD_alert: 接发光二极管,指示是否设置了闹钟功能;
LD_hour: 接发光二极管,指示当前调整的是小时信号;
LD_min: 接发光二极管,指示当前调整的是分钟信号;
*/ module
alarmclock(clk,clk_1k,mode,change,turn,alert,hour,min,sec,LD_alert,LD_hour,LD_min);
input clk,clk_1k,mode,change,turn;
output alert,LD_alert,LD_hour,LD_min;
output[7:0] hour,min,sec;
reg[7:0] hour,min,sec,hour1,min1,sec1,ahour,amin;
reg[1:0] m,fm,num1,num2,num3,num4;
reg[1:0] loop1,loop2,loop3,loop4,sound;
reg LD_hour,LD_min;
reg clk_1Hz,clk_2Hz,minclk,hclk;
reg alert1,alert2,ear;
reg count1,count2,counta,countb;
wire ct1,ct2,cta,ctb,m_clk,h_clk;
always @(posedge clk)
begin clk_2Hz
if(sound == 3) begin sound
else begin sound
end
always @(posedge clk_2Hz) //用4hz 的输入信号产生1hz 的时基信号
clk_1Hz
always @(posedge mode) //mode信号控制系统在三种功能间的转换
begin if(m == 2) m
always @(posedge turn)
fm
always //产生
count1,count2,counta,countb 四个信号
begin
case(m)
2:begin if(fm)
begin count1
else
begin counta
{counta,countb}
end
1:begin if(fm)
begin count2
else
begin countb
{count1,countb}
end
default:{count1,count2,counta,countb,LD_min,LD_hour}
endcase
end
always @(negedge clk) //如果长按"change" 信号, 则生成信号用于连续快速加1
if(count2) begin
if(loop1 == 3) num1
else begin loop1
end
else begin loop1
always @(negedge clk) //产生num2信号
if(countb) begin
if(loop2 == 3) num2
else begin loop2
end
else begin loop2
always @(negedge clk)
if(count1) begin
if(loop3 == 3) num3
else begin loop3
end
else begin loop3
always @(negedge clk)
if(counta) begin
if(loop4 == 3) num4
else begin loop4
end
else begin loop4
assign ct1 = (num3&clk)|(!num3&m_clk); //ct1用于计时、校时中的分钟计数
assign ct2 = (num1&clk)|(!num1&count2); //ct2用于定时状态下调整分钟信号
assign cta = (num4&clk)|(!num4&h_clk); //cta用于计时、校时中的小时计数 assign ctb = (num2&clk)|(!num2&countb); //ctb用于定时状态下调整小时信号
always @(posedge clk_1Hz) //秒计时和秒调整进程
if(!(sec1^8'h59)|turn&(!m))
begin sec1
//按住"turn" 秒信号清0
else begin
if(sec1[3:0] == 4'b1001)
begin sec1[3:0]
end
assign m_clk = minclk || count1;
always @(posedge ct1) //分计时和分调整进程
begin
if(min1 == 8'h59) begin min1
else begin if(min1[3:0] == 9)
begin min1[3:0]
end
end
assign h_clk = hclk || counta;
always @(posedge cta) //小时计时和小时调整进程 if(hour1 == 8'h23) hour1
else if(hour1[3:0] == 9)
begin hour1[7:4]
else hour1[3:0]
always @(posedge ct2) //闹钟定时功能中的分钟调整进程 if(amin == 8'h59) amin
else if(amin[3:0] == 9)
begin amin[7:4]
else amin[3:0]
always @(posedge ctb) //闹钟定时功能中的小时调整进程 if(ahour == 8'h23) ahour
else if(ahour[3:0] == 9)
begin ahour[7:4]
else ahour[3:0]
always //闹铃功能
if((min1 == amin)&&(hour1 == ahour)&&(amin|ahour)&&(!change))
//若按住键不放,可屏蔽闹铃音 if(sec1
else alert1
else alert1
always //时、分、秒的显示控制 case(m)
3'b00: begin hour
//计时状态下的时、分、秒显示 3'b01: begin hour
//定时状态下的时、分、秒显示 3'b10: begin hour
//校时状态下的时、分、秒显示
endcase
assign LD_alert = (ahour|amin)?1:0;
assign alert = ((alert1)?clk_1k&clk:0) | alert2;
always
begin
if((hour1==8'h06)&&(min1 == 8'h00)&&(sec1
if(sec1
else alert2
else alert2
end
endmodule
考试序号:20
自动打铃系统设计说明书
学 生 姓 名:
学 号:
专 业 班 级:
报告提交日期:
湖 南 理 工 学 院 物 电 学 院
目录
一 系统工作原理 ··································································· 3
设计要求 ············································································ 3
1、计时原理: ······························································· 4
2、模式信号mode 选择各个功能显示的原理: ········· 4
3、时间调整中数字上加的原理: ······························· 4 系统框图 ··········································································· 5
二 选择的FPGA 芯片及配置 ················································· 5
三 各模块分析 ······································································· 6 设计步骤: ············································································· 6 顶层文件端口说明: ·························································· 8 时序仿三真 ······································································· 9 附录:源程序(附注释) ····················································· 11
一系统工作原理
工作原理:时钟系统由八个数码管显示组成,其中第1、2个显示的为时的高位和低位,第3个数码管显示的是分隔符“-”,第4、5个为分的高低位,第6个也为隔符“-”,第7、8个为秒的高低位。时钟工作时用到两个频率,一个是系统频率Clk ,主要用来扫描数码管和分频,第二个是时钟工作频率Clk_1HZ(由Clk 分频得来),按下复位键,秒分时显示清零,工作时Clk (489HZ )不断通过3-8译码器值的改变来扫描时钟的八位数码管,由于人眼分辩不出这么高的频率,所以看到的是八个数码管一直同时亮着,与此同时控制端连着七段数码管的七位不断提供秒时分的高低位译码到数码管上显示,当Clk 计数到244次(500ms)时,Clk_1HZ翻转一次,这样Clk_1HZ的周期就为1s 整,每个Clk_1HZ的上升沿给秒的低位加1。按调时键S1进入调时模式,按下开关时程序里设置扫描到时的高低位时不显示,同时时的低位加1,松开开关时再显示出来,以此实现闪烁的功能,调分键也是同理。
各个输入输出端口定义如下:
Clk: 489HZ 的系统基准时钟输入。作为七段码管扫描频率。将其489分频可得到1HZ 的数字钟工作频率。 Rst: 系统复位信号, 低电平有效。复位后显示00-00-00。 S1: 调节小时信号, 低电平有效。每按下一次, 小时增加一个小时。 S2: 调节分钟信号, 低电平有效。每按下一次, 分钟增加一个分钟。
Spk: 输出到扬声器, 产生嘀、嗒的报时声。
Sel: 七段码管扫描驱动。因为是八个七段码管, 所以Sel 为三位总线。扫描频率为489HZ, 由于人眼的视觉效果, 呈现在眼前的便是整体的时-分-秒显示。 Display: 七段码管显示输出。 除此之外另设了几个寄存器: Clk_1HZ:1HZ 的数字钟工作频率 Clk_Count1:产生1Hz 时钟的分频计数器 Music_Count:产生扬声器声音频率的分频计数器 SECL,SECH:秒的低位和高位 MINL,MINH:分的低位和高位 HOURL,HOURH:时的低位和高位 Disp_Temp:显示存储中间量
数字时钟设计(C)
一、设计要求
(1)显示6位,分别是小时两位,分钟两位,秒两位; (2)可手动调节对时; (3)整点报时功能。 二、数字时钟设计原理 数字时钟设计原理框图:
1、计时原理:
在计时显示模块中,涉及到的是时分秒各个计数器的设计 ,“秒计数器”采用60进制计数器,每累计60秒,发出一个“分脉冲”信号,该信号将被送到“分计数器”。“分计数器”采用60进制计数器,每累计60分钟,发出一个“分脉冲”信号,该信号被送到“时计数器”。“时计数器”采用24进制计数器,可实现24小时的累计计数。 当计到24小时后,计数清零,如此循环。
2、模式信号mode 选择各个功能显示的原理:
使用mode 按键产生0、1信号在正常计时功能、校时功能之间的转换。mode 信号的作用主要体现在控制模块和时间显示模块中,虽然计时模块中也用到mode 信号,但是它只是turn 信号将秒信号清零的辅助作用,保证只有在m=0(即
普通计时显示)下turn 信号清零功能才起作用,在校时功能下只能是分、小时的切换功能。
(1)在控制模块下的作用:
在控制模块下,其实mode 和turn 信号的作用就是将change 数字上加信号按不同的mode 和turn 分成两个信号,分别是count1(时间显示下的分信号) 、counta(时间显示下的小时信号) 。
(2)在显示模块下的作用:
同在控制模块下的作用相同。只是将turn 信号选出的小时和分钟在同一个mode 下一起送至显示模块。
3、时间调整中数字上加的原理:
在时间校时调整模式下,数字的上加不仅受到change 信号的作用(即人工调时),还受本身在1Hz 信号下计时而随时发生的累加。由于在控制模块下设置了快加
的功能,所以有三部分信号对上加起作用,一是快加时以原始时钟的速率上加,二是慢加下的change 具体到各模块、各位的count1或counta ,三是秒信号记到59向分信号的进位。
一系统框图
二选择的FPGA 芯片及配置
① EP1K10TC100-3
主控芯片采用ACEX1K 系列的EP1K10TC100-3。ACEX 系列是当今Altera CPLD 中应用前景最好的器件系列之一[1,2]。该系列的 FPGA 由逻辑阵列块,LAB 、嵌入式阵列块EAB 、快速互联一计IO 单元构成,每个逻辑阵列块包含8个逻辑单元LE (logic element )和一个局部互联。每个逻辑单元则有一个4输入查找表(LUT )、一个可编程触发器、快速进位链、级连链组成,对个LAB 和多个EAB 则可通过快速通道互相连接。EAB 是ACEX 系列器件在结构设计上的一个重要的部件,他是输入端口和输出端口都带有的触发器的一种灵活的RAM 快,其主要功能是实现一些规模不太大FIFO,ROM 、RAM 和双端口RAM 等
② 7段共阳数码管
③ 扬声器
④开关及其相关电路
三各模块分析
设计步骤:
Quartus II 是Altera 公司综合性PLD 开发软件,支持原理图、VHDL 、Verilog HDL以及AHDL 等多种设计输入形式。内嵌自有的综合器和仿真器,可以完成从设计输入到硬件配置的完整PLD 设计流程。他的设计流程包括设计输入、编译、仿真和定时分析、编程及验证。而设计输入又包括原理图输入HD 文本输入、EDIF 网表输入和波形输入等几种方式。编译时要根据设计要求来设定编译方式以及编译策略,然后根据设定参数和策略来对设计项目进行网表提取、逻辑综合和器件适配,供分析、仿真以及编程使用。设计完成后需进行仿真,可以测试设计的逻辑功能以及延时特性。最后,可以用得到的编程文件来通过编程电缆配置PLD ,进行在线测试。在设计过程中,如果出现了错误,则需重新回到设计的输入阶段,改正错误或者调整电路后进行重新测试。
硬件描述语言HDL (Hardware Description Language )诞生于1962年。和SDL (Software Description Language)相似,经历了从机器语言、汇编语言到高级语言(HDL )的过程[7]。HDL 是用形式化方法去描述数字电路和设计数字逻辑系统的语言主要用于描述离散电子系统的结构和行为HDL 和其原理图是两种最常用的数字件电路描述方法,其中HDL 设计法具有更好的可移植性、通用性和模块划分和重用性等特点,在目前的工程设计开发流程主要是基于HDL 的。并且在目前工程设计中被广泛使用。所以,我们在使用EDA 设计数字电路时,其开发流程是基于HDL 的。VHDL 描述的时数字电路系统设计的行为、功能以及输入和输出。它在语法上和现代编程语言C 语言相似。应用VHDL 来进行系统设计,有功能强大、可移植性、独立性、可操作性、灵活性的特点。
FPGA 器件的内部结构
ACEX 1K系列器件是Altera 公司2000年推出的新型CPLD 产品。该器件基于SRAM ,结合查找表(LUT )和嵌入式阵列块(EAB )提供了高密度结构,可提供10 000到100 000可用门,每个嵌入式阵列块增加到16位宽可实现双端口,RAM 位增加到49125个。其多电压引脚可以驱动2.5V 、3.3V 、5.0V 器件,也可以被这些电压所驱动;双向I/O引脚执行速度可达250MHz 。该器件还应用Altera 专利技术进行了重要的生产改进,进一步降低了器件的成本,提高了产品的性能价格比。因此,ACEX 1K器件可用来实现许多逻辑复杂、信息量大的系统。但是在器件操作过程中,ACEX 1K系列器件的配置数据存储在SRAM 单元中,由于SRAM 的易失性,配置数据在每次上电时必须被重新载入SRAM 。
我选择的是ACEX1K 的EP1K100QC208-3芯片
顶层文件端口说明:
module
alarmclock(clk,clk_1k,mode,turn,sel,decodeout,alert,LD_alert,LD_hour,LD_min); input clk,clk_1k,mode,change,turn;
output alert,LD_alert,LD_hour,LD_min;
output[2:0] sel;
output[7:0] decodeout;
reg[7:0] hour,min,sec,hour1,min1,sec1,ahour,amin;
reg[1:0] m,fm,num1,num2,num3,num4;
reg[1:0] loop1,loop2,loop3,loop4,sound;
reg LD_alert,LD_hour,LD_min;
reg clk_1HZ,clk_2HZ,minclk,hclk;
reg alert1,ear;
reg count1,count2,counta,countb;
wire ct1,ct2,cta,ctb,m_clk,h_clk;
reg[2:0] sel;
reg[7:0] decodeout;
endmodule
图(1) 引脚示意图
三 时序仿三真
程序编译通过后,进行了一下仿真,设置Clk 为2周期为2ms (近似489HZ ),
End Time设了100s ,仿真结果如下图。
图2 仿真结果图
在Rst 复位端为从低变到高开始计时,计时Clk489次后秒的低位进1,这里由于244次Clk 上升沿后Clk_1HZ才翻转,故Clk 太密集观察困难,秒的低位到9以后秒高位进1,同理到分以及时,由于如果结束时间设得太长,仿真结果出来得太慢,此处只设了100s ,下图为放大后结果,计时Clk489次后秒的低位进1。
图3 1秒跳变放大图
下图为数码管显示放大后的仿真图,可以看到,Sel 为000时,系统扫描到的是秒的低位, 显示为Display :0111111,即显示0,以此类推,Sel 为001时,扫描
到的是秒的高位,010时为分隔符“-”„直到111时的高位,此处全部显示为零,因为计数还未到达1秒。
图4 数码管显示放大图
功能仿真结束后, 利用综合工具对Verilog HDL源码进行综合, 生成网表文件, 再根据该网表文件和所选可编程逻辑器件FPGA 进行优化、布局布线, 然后进行布线后仿真, 最后生成FPGA 码流文件, 把该文件输入可编程逻辑器件即可制成实际数字电路,最后在实验箱上运行正常,所有功能均能实现。
附录:源程序(附注释)
clk : 标准时钟信号;
clk_1k: 扫描时钟;
mode : 功能控制信号:
为0:计时功能;
为1:闹钟功能;
为2:手动校时功能;
turn : 接按键,在手动校时功能时,选择是调整小时,还是分钟; change : 接按键,手动调整时,每按一次,计数器加1;
hour,min,sec: 分别表示时\分\秒信号,采用BCD 码计数,分别驱动6个数码显示管显示时间;
alert : 输出到扬声器的信号,用于产生打铃声;
LD_alert: 接发光二极管,指示是否设置了闹钟功能;
LD_hour: 接发光二极管,指示当前调整的是小时信号;
LD_min: 接发光二极管,指示当前调整的是分钟信号;
*/ module
alarmclock(clk,clk_1k,mode,change,turn,alert,hour,min,sec,LD_alert,LD_hour,LD_min);
input clk,clk_1k,mode,change,turn;
output alert,LD_alert,LD_hour,LD_min;
output[7:0] hour,min,sec;
reg[7:0] hour,min,sec,hour1,min1,sec1,ahour,amin;
reg[1:0] m,fm,num1,num2,num3,num4;
reg[1:0] loop1,loop2,loop3,loop4,sound;
reg LD_hour,LD_min;
reg clk_1Hz,clk_2Hz,minclk,hclk;
reg alert1,alert2,ear;
reg count1,count2,counta,countb;
wire ct1,ct2,cta,ctb,m_clk,h_clk;
always @(posedge clk)
begin clk_2Hz
if(sound == 3) begin sound
else begin sound
end
always @(posedge clk_2Hz) //用4hz 的输入信号产生1hz 的时基信号
clk_1Hz
always @(posedge mode) //mode信号控制系统在三种功能间的转换
begin if(m == 2) m
always @(posedge turn)
fm
always //产生
count1,count2,counta,countb 四个信号
begin
case(m)
2:begin if(fm)
begin count1
else
begin counta
{counta,countb}
end
1:begin if(fm)
begin count2
else
begin countb
{count1,countb}
end
default:{count1,count2,counta,countb,LD_min,LD_hour}
endcase
end
always @(negedge clk) //如果长按"change" 信号, 则生成信号用于连续快速加1
if(count2) begin
if(loop1 == 3) num1
else begin loop1
end
else begin loop1
always @(negedge clk) //产生num2信号
if(countb) begin
if(loop2 == 3) num2
else begin loop2
end
else begin loop2
always @(negedge clk)
if(count1) begin
if(loop3 == 3) num3
else begin loop3
end
else begin loop3
always @(negedge clk)
if(counta) begin
if(loop4 == 3) num4
else begin loop4
end
else begin loop4
assign ct1 = (num3&clk)|(!num3&m_clk); //ct1用于计时、校时中的分钟计数
assign ct2 = (num1&clk)|(!num1&count2); //ct2用于定时状态下调整分钟信号
assign cta = (num4&clk)|(!num4&h_clk); //cta用于计时、校时中的小时计数 assign ctb = (num2&clk)|(!num2&countb); //ctb用于定时状态下调整小时信号
always @(posedge clk_1Hz) //秒计时和秒调整进程
if(!(sec1^8'h59)|turn&(!m))
begin sec1
//按住"turn" 秒信号清0
else begin
if(sec1[3:0] == 4'b1001)
begin sec1[3:0]
end
assign m_clk = minclk || count1;
always @(posedge ct1) //分计时和分调整进程
begin
if(min1 == 8'h59) begin min1
else begin if(min1[3:0] == 9)
begin min1[3:0]
end
end
assign h_clk = hclk || counta;
always @(posedge cta) //小时计时和小时调整进程 if(hour1 == 8'h23) hour1
else if(hour1[3:0] == 9)
begin hour1[7:4]
else hour1[3:0]
always @(posedge ct2) //闹钟定时功能中的分钟调整进程 if(amin == 8'h59) amin
else if(amin[3:0] == 9)
begin amin[7:4]
else amin[3:0]
always @(posedge ctb) //闹钟定时功能中的小时调整进程 if(ahour == 8'h23) ahour
else if(ahour[3:0] == 9)
begin ahour[7:4]
else ahour[3:0]
always //闹铃功能
if((min1 == amin)&&(hour1 == ahour)&&(amin|ahour)&&(!change))
//若按住键不放,可屏蔽闹铃音 if(sec1
else alert1
else alert1
always //时、分、秒的显示控制 case(m)
3'b00: begin hour
//计时状态下的时、分、秒显示 3'b01: begin hour
//定时状态下的时、分、秒显示 3'b10: begin hour
//校时状态下的时、分、秒显示
endcase
assign LD_alert = (ahour|amin)?1:0;
assign alert = ((alert1)?clk_1k&clk:0) | alert2;
always
begin
if((hour1==8'h06)&&(min1 == 8'h00)&&(sec1
if(sec1
else alert2
else alert2
end
endmodule