我是靠谱客的博主 欣慰银耳汤,最近开发中收集的这篇文章主要介绍verilog 实现多功能数字钟,定时,报时,校时功能实验4:数字钟的设计与仿真,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

实验4:数字钟的设计与仿真

实验框图设计

实验目的

  1. 优化第8章数字钟的程序,优化的具体内容主要是与时钟相关,采用同源时钟,经过严格的计数器分频后再连接到所有触发器,时钟不能经过多路选择器直接连接到触发器的时钟端
  2. 编写测试激励,对数字钟进行仿真,要求仿真到的内容有:时分秒、电台报时、定时闹钟、分频,调整时间等,用modelsim完成仿真
  3. 在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:数字钟的设计与仿真所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(77)

评论列表共有 0 条评论

立即
投稿
返回
顶部