概述
实验4:数字钟的设计与仿真
实验框图设计
实验目的
- 优化第8章数字钟的程序,优化的具体内容主要是与时钟相关,采用同源时钟,经过严格的计数器分频后再连接到所有触发器,时钟不能经过多路选择器直接连接到触发器的时钟端
- 编写测试激励,对数字钟进行仿真,要求仿真到的内容有:时分秒、电台报时、定时闹钟、分频,调整时间等,用modelsim完成仿真
- 在quartus新建一个工程,完成编译、综合、器件和引脚分配,生成sof和pof文件,下载
#实验内容
六十进制和二十四进制搭建
十进制计数器设计
module counter10(Q,nCR,EN,CP);
input CP,nCR,EN;
output [3:0]Q;
reg [3:0]Q;
always @(posedge CP or negedge nCR)
begin
if(~nCR)
Q <= 4'b0000;
else if (~EN)
Q <= Q;
else if (Q == 4'b1001)
Q <= 4'b0000;
else
Q <= Q + 1'b1;
end
endmodule
六进制计数器设计
module counter6(Q,nCR,EN,CP);
input CP,nCR,EN;
output [3:0]Q;
reg [3:0]Q;
always @(posedge CP or negedge nCR)
begin
if(~nCR)
Q <= 4'b0000;
else if (~EN)
Q <= Q;
else if (Q == 4'b0101)
Q <= 4'b0000;
else
Q <= Q + 1'b1;
end
endmodule
六十进制计数器设计
调用10进制和6进制底层模块设计
module counter60(Cnt,nCR,EN,CP);
input CP,nCR,EN;
output [7:0]Cnt;
wire [7:0]Cnt;
wire ENP;
counter10 UC0(Cnt[3:0],nCR,EN,CP);
counter6 UC1(Cnt[7:4],nCR,ENP,CP);
assign ENP=(Cnt[3:0] == 4'h9);
endmodule
特殊六十进制计数器设计
因为使用同源时钟连接触发端,所以要使用使能信号去控制分钟,小时的计数
但因六十进制调用底层模块,分钟模块下一个时钟沿更改的是秒钟,但分钟没有得到变化,所以使能信号ENP会一直开启,分钟会自增
特殊六十进制模块加入对秒钟的判断,此模块控制分钟
module scounter60(Cnt,nCR,EN,CP,SECOND);
input CP,nCR,EN;
input [7:0]SECOND;
output [7:0]Cnt;
wire [7:0]Cnt;
wire ENP;
counter10 UC0(Cnt[3:0],nCR,EN,CP);
counter6 UC1(Cnt[7:4],nCR,ENP,CP);
assign ENP=((Cnt[3:0] == 4'h9)&&(SECOND[7:0]==8'h59));
endmodule
二十四进制计数器设计
module counter24(CntH,CntL,nCR,EN,CP);
input CP,nCR,EN;
output [3:0] CntH,CntL;//小时计数器的十位和个位的输出信号。
reg [3:0] CntH,CntL;
always @(posedge CP or negedge nCR)
begin
if(~nCR)
{CntH,CntL} <=8'h00;
else if(~EN)
{CntH,CntL} <= {CntH,CntL};//对使能信号无效
else if((CntH>2)||(CntL>9)||((CntH==2)&&(CntL>=3)))
{CntH,CntL} <=8'h00;//小时计数器出错的处理
else if((CntH==2)&&(CntL<3))
begin
CntH <= CntH;
CntL <= CntL + 1'b1;
end
else if(CntL==9) //小时十位的计数
begin
CntH <= CntH + 1'b1;
CntL <= 4'b0000;
end
else
begin
CntH <= CntH;
CntL <= CntL + 1'b1;
end
end
时钟模块
通过调用三个计数器,通过连接同源时钟_1hz,通过使能信号VDD和MinCP和Hrcp来使得计数器增加
实现代码
module top_clock(Hour,Minute,Second,_1Hz,nCR,AdjMinKey,AdjHrKey);
input _1Hz,nCR,AdjMinKey,AdjHrKey;//
output [7:0] Hour,Minute,Second;//输出端口变量
wire [7:0] Hour,Minute,Second;
supply1 Vdd;
wire MinCP,HrCP; //分钟,小时计数器时钟信号
counter60 UT1(Second,nCR,Vdd,_1Hz); //秒计数器
scounter60 UT2(Minute,nCR,MinCP,_1Hz,Second); //分计数器
counter24 UT3(Hour[7:4],Hour[3:0],nCR,HrCP,_1Hz); //小时计数器
// AdjMinKey=1 矫正分钟,AdjMinKey =0 ,分钟正常计时
assign MinCP = ((AdjMinKey == 1'b1)||(Second == 8'h59)) ? 1'b1:1'b0;
assign HrCP = ((AdjHrKey == 1'b1)||({Minute,Second} == 16'h5959)) ? 1'b1:1'b0;
endmodule
测试激励
`timescale 1ns/1ns
module test;
reg _1HZ=1'b0 ;
wire [7:0]Hour;
wire [7:0]Minute;
wire [7:0]Second;
integer i=0;
reg nCR=1'b1;
reg AdjMinKey=1'b0;
reg AdjHrKey=1'b0;
top_clock u1(Hour,Minute, Second, _1HZ,nCR,AdjMinKey, AdjHrKey);
initial
begin
nCR=1'b0;
#1 nCR=1'b1;
for(;i<200_000;i=i+1)
begin
if(i<=100_000)
begin
#1 _1HZ=_1HZ+1'b1;
end
else if((i>100_000)&&(i<=200_000))
begin
AdjMinKey<=1'b1;
AdjHrKey<=1'b1;
#1 _1HZ<=_1HZ+1'b1;
end
end
end
endmodule
modelism 仿真结果
分频模块的设计
实验提供50Mhz的时钟,但实验需要1khz,500hz,1hz的时钟
通过计数器记到一定程度反转信号达到分频的目的
分频器的功能主要有两个:一是产生计时用的标准秒脉冲信号;二是提供功能扩展电路所需要的信号,如仿电台报时用的1kHz高音频信号和500Hz低音频信号等。由于分频模块在主体电路和扩展电路中都要使用,所以在主体电路中没有包含这个模块,准备放在最后的顶层电路中。
分频
module Divided_Frequency(_1HzOut,_500HzOut,nCR,_1kHzIn,_50MhzIN);
input _50MhzIN;
output _1HzOut,_500HzOut,_1kHzIn;
reg _1HzOut,_500HzOut,_1kHzIn;
input nCR;
reg [31:0] cnt=32'b0,cnt1=32'b0,cnt2=32'b0;
always @(posedge _50MhzIN or negedge nCR) //50Mhz 分频到1khz
begin
if(~nCR)
begin
_1kHzIn <= 1'b0;
cnt <= 0;
end
if (cnt == 32'd50000 -1)
begin
_1kHzIn <= ~_1kHzIn;
cnt <= 0;
end
else
cnt <= cnt +1;
end
always @(posedge _50MhzIN or negedge nCR) //50Mhz 分频到1hz
begin
if(~nCR)
begin
_1HzOut <= 1'b0;
cnt1 <= 0;
end
if (cnt1 == 32'd50_000_000 -1)
begin
_1HzOut <= ~_1HzOut;
cnt1 <=0;
end
else
cnt1 <= cnt1 +1;
end
always @(posedge _50MhzIN or negedge nCR) //50Mhz 分频到500hz
begin
if(~nCR)
begin
_500HzOut <= 1'b0;
cnt2 <= 32'd0;
end
if (cnt2 == 100_000 -1)
begin
_500HzOut <= ~_500HzOut;
cnt2 <=0;
end
else
cnt2 <= cnt2 +1;
end
endmodule
测试激励
`timescale 1us/1us
module testDivided_Frequency;
reg [31:0] _50MhzIN;
wire [9:0] _1Khz,_500Hz,_1Hz;
reg nCR;
Divided_Frequency test(_1Hz,_500Hz,nCR,_1Khz,_50MhzIN);
integer i;
initial
begin
_50MhzIN = 32'b0;
nCR =1'b0;
#10 nCR = 1'b1;
for(i=0;i<200_0000;i=i+1)
begin
#1 _50MhzIN = _50MhzIN + 1'b1;
end
end
endmodule
测试结果
仿电台正点报时模块的设计
仿广播电台正点报时模块的程序如Radio.v所示。ALARM_Radio为输出的正点报时信号,Minute、Second分别为数字钟当前时刻的分钟和秒钟信号,它们作为本模块的输入。程序中使用if-else语句判断数字钟当前时刻是否为59分,若正好为59分,再用case-endcase语句判断秒钟是否为要求发出声响的时刻。若均满足要求,就发出相应频率达信号。即按照4低音1高音的顺序发出间断声响,以最后一声高音结束的时刻为正点时刻。
module Radio(ALARM_Radio,Minute,Second,_1kHzIN,_500Hz);
input _1kHzIN,_500Hz;
input [7:0] Minute,Second;
output [7:0] Minute,Second;
output ALARM_Radio;
reg ALARM_Radio;
always @(Minute or Second)
if (Minute == 8'h9)
case (Second)
8'h51,
8'h53,
8'h55,
8'h57: ALARM_Radio = _500Hz;
8'h59: ALARM_Radio = _1kHzIN;
default:ALARM_Radio = 1'b0;
endcase
else ALARM_Radio = 1'b0;
endmodule
定时闹钟模块设计
SetHrKey、SetMinKey分别为小时、分钟的设置键,用于任意设置闹钟的小时和分钟,Set_Hr和Set_Min为指定的闹铃时刻(8421BCD码)。Hour和Minute为来自主体电路的数字钟当前时刻的小时和分钟信号,当设定的闹铃时间和数字钟当前的时间相等时,就驱动音响电路“闹时”;由于最长闹铃时间为1分钟,所以设置时不需要考虑秒钟。为了能随时关掉闹铃声音,设置了一个控制键CtrlBell。
module Bell(ALARM_CLOCK,Set_Hr,Set_Min,Hour,Minute,Second,SetHrkey,SetMinkey,_1kHzIN,_500Hz,_1Hz,CtrlBell);
output ALARM_CLOCK;
output [7:0] Set_Hr,Set_Min;//设定的闹铃时间(BCD码)
wire [7:0] Set_Hr,Set_Min;
wire ALARM_CLOCK;
input _1kHzIN,_500Hz,_1Hz;//输入时钟变量
input SetHrkey,SetMinkey;
input CtrlBell; //闹钟的声音是否输出
input [7:0] Hour,Minute,Second;
//内部节点
supply1 Vdd;
wire HrH_EQU,HrL_EQU,MinH_EQU,MinL_EQU;// 比较器的内部信号
wire Time_EQU; //相等比较电路的输出
///闹时设定模块
counter60 SU1(Set_Min,Vdd,SetMinkey,_1Hz);
counter24 SU2(Set_Hr[7:4],Set_Hr[3:0],Vdd,SetHrkey,_1Hz);
//比较闹钟的设定时间和计时器的当前时间是否相同
_4bitcomparator SU4(HrH_EQU,Set_Hr[7:4],Hour[7:4]);
_4bitcomparator SU5(HrL_EQU,Set_Hr[3:0],Hour[3:0]);
_4bitcomparator SU6(MinH_EQU,Set_Min[7:4],Minute[7:4]);
_4bitcomparator SU7(MinL_EQU,Set_Min[3:0],Minute[3:0]);
//闹钟声音控制信号
assign Time_EQU=(HrH_EQU && HrL_EQU && MinH_EQU && MinL_EQU);
assign ALARM_CLOCK = CtrlBell ?(Time_EQU && (((Second[0]==1'b1)&&_500Hz)||((Second[0]==1'b0)&&_1kHzIN))):1'b0;
endmodule
顶层电路设计
其中分频模块(U0)、数字钟主体电路(U1)、仿电台正点报时电路(U2)和定时闹钟电路(U3)直接调用下层模块构成,另外两个模块直接在程序中完成,扬声器的总控制模块由连续赋值语句“assign ALARM = ALARM_Radio || ALARM_Clock;”完成,目的是将两个需要用扬声器的信号组合起来输出。2选1数据选择器用于控制显示器模式的切换,当控制键Mode=1时,显示器用于显示闹钟设定的时间;当Mode=0时,显示器用于显示计时器的当前时间。
module Complete_Clock(LED_Hr,LED_Min,LED_Sec,ALARM,_1kHzIN,AdjMinkey,
AdjHrkey,SetMinkey,SetHrkey,CtrlBell,Mode,nCR,_50MhzIN);
input _50MhzIN; //系统输入时钟信号
input nCR;
output [7:0] LED_Hr,LED_Min,LED_Sec;//输出BCD码给显示器
wire [7:0] LED_Hr,LED_Min,LED_Sec;
wire _1Hz,_500Hz,_1kHzIN; //分频器输出信号
input AdjMinkey,AdjHrkey; //矫正计时器小时、分钟的输入案件
wire [7:0] Hour,Minute,Second;
input SetHrkey,SetMinkey;
wire [7:0] Set_Hr,Set_Min; //设定闹钟时间输出信号
wire ALARM_Radio;
wire ALARM_Clock;
output ALARM;
input CtrlBell;
input Mode;
//Mode=1 显示设定的时间,Mode=0,显示计时器的时间
Divided_Frequency U0(_1Hz,_500Hz,nCR,_1kHzIN,_50MhzIN);
top_clock U1(Hour,Minute,Second,_1Hz,nCR,AdjMinkey,AdjHrkey);//计时
Radio U2(ALARM_Radio,Minute,Second,_1Hz,nCR,AdjMinkey,AdjHrkey);
Bell U3(ALARM_Clock,Set_Hr,Set_Min,Hour,Minute,Second,SetHrkey,
SetMinkey,_1kHzIN,_500Hz,_1Hz,CtrlBell);//定时闹钟模块
//扬声器总控制模块
assign ALARM = ALARM_Radio||ALARM_Clock;
//显示的数码送数码管
_2to1MUX MU1(LED_Hr,Mode,Set_Hr,Hour);
_2to1MUX MU2(LED_Min,Mode,Set_Min,Minute);
_2to1MUX MU3(LED_Sec,Mode,8'h00,Second);
endmodule
module _2to1MUX(OUT,SEL,X,Y);
input [7:0] X,Y;
input SEL;
output [7:0] OUT;
assign OUT = SEL?X:Y;
endmodule
最后
以上就是欣慰银耳汤为你收集整理的verilog 实现多功能数字钟,定时,报时,校时功能实验4:数字钟的设计与仿真的全部内容,希望文章能够帮你解决verilog 实现多功能数字钟,定时,报时,校时功能实验4:数字钟的设计与仿真所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复