EDA数字钟

文章目录

  • 前言
  • 一、设计内容
  • 二、模块结构
  • 三、代码编写
    • 1.顶层模块_module top
    • 2. 分频模块_module Clock
    • 3. 校时功能模块_module Seter
    • 4. n进制计数器模块_module Count_n
    • 5. 计时功能模块_module Counter
    • 6. 秒针模块_module Sec_counter
    • 7. 分针模块_module Min_counter
    • 8. 时针模块_module Hour_counter
    • 9. 闹钟功能模块_module Alarm
    • 10. 取数模块_module Select
    • 11. 扫描模块_module Scan
    • 12. 译码模块_module Trans
  • 四、测试文件
  • 五、波形仿真
  • 总结


前言

Verilog、Xilinx ISE 13.4、BASYS2、EDA、数字钟

一、设计内容

利用实验板设计实现一个能显示时分秒的多功能电子钟。
1.具有“秒”、“分”、“时”计时的功能,小时计数器按24小时制;
2.具有校时功能,能对“分”和“时”进行调整;
3.具有手动输入设置定时闹钟的功能,亮1分钟;
4.可实现时钟复位功能:00:00:00;
5.报整点:几点亮几下。

二、模块结构

EDA数字钟_第1张图片

三、代码编写

1.顶层模块_module top

顶层模块包含:
分频模块:获得1HZ脉冲,供计时模块使用;
校时模块:对时分、分秒、闹钟置数;
计时模块:含时、分、秒三个子模块,用于计时;
闹钟模块:用于整点报时和定时闹钟;
取数模块:决定当前显示的内容(4位),并送到扫描模块;
扫描模块:将取到的数分成4份(1位),分时送到译码模块;
译码模块:将数字转化为数码管引脚电平,并判断是否显示小数点。

//顶层模块
module top(
	input cp,//20ns脉冲
	input reset,//复位按键BTN0
	input set,//置数按键BTN1
	input apply,//移位按键BTN2
	input inc,//增加按键BTN3
	input set_enable,//校时拨码SW7
	input alarm_enable,//闹钟拨码SW6	
	input hour_show,//时分显示拨码SW5
	input sec_show,//分秒显示拨码SW4
	input count_enable,//计时拨码SW3
	output [3:0] loc,//数码管位置
	output [7:0] pin,//数码管引脚电平
	output hour_alarm,//整点报时LD2	
	output alarm,//闹钟LD1
	output sec//秒针LD0
    );
	wire [23:0] counter_num;//当前时间
	wire [15:0] set_num;//校时时间
	wire [15:0] alarm_num;//闹钟时间
	wire [15:0] show_num;//显示内容
	wire [3:0] scan_num;//译码内容
	wire [3:0] set_loc;//置数位置
	//分频模块
	Clock P13(
	.cp(cp),
	.clock(clock)
	);
	//校时模块
	Seter P14(
	.enable(set_enable),
	.inc(inc),
	.apply(apply),
	.set_num(set_num),
	.set_loc(set_loc)
	);
	//计时模块
	Counter P1(
	.cp(clock),
	.enable(count_enable),
	.reset(reset),
	.set(set && !alarm_enable && !set_enable),
	.set_num(set_num),
	.sec_show(sec_show),
	.hour_show(hour_show),
	.counter_num(counter_num),
	.hour(hour),
	.sec(sec)
	);
	//闹钟模块
	Alarm P19(
	.cp(clock),
	.enable(alarm_enable),
	.set(set && !set_enable),
	.set_num(set_num),
	.hour(hour),
	.counter_num(counter_num),
	.alarm(alarm),
	.hour_alarm(hour_alarm),
	.alarm_num(alarm_num)
	);
	//取数模块
	Select P20(
	.cp(cp),
	.counter_num(counter_num),
	.set_num(set_num),
	.alarm_num(alarm_num),
	.set_enable(set_enable),
	.alarm_enable(alarm_enable),
	.hour_show(hour_show),
	.sec_show(sec_show),
	.show_num(show_num)
	);
	//扫描模块
	Scan P5(
	.cp(cp),
	.set_enable(set_enable),	
	.num(show_num),
	.loc(loc),
	.set_loc(set_loc),
	.point(point),
	.scan_num(scan_num)
	);
	//译码模块
	Trans P6(
	.scan_num(scan_num),
	.point(point),
	.pin(pin)
	);
endmodule

2. 分频模块_module Clock

将20ns的电路板脉冲50000000分频,输出1s的脉冲,作为计时cp。

//分频模块
module Clock(
	input cp,
	output clock
	);
	parameter i = 25000000;//下载(计时频率1Hz)
	//parameter i = 5;//调试程序
	reg [31:0] counter = 0;
	reg clock_temp = 0;
	always @(posedge cp)//上升沿触发
		begin
			if (counter >= i-1)
			begin
				counter = 0;
				clock_temp = ~clock_temp;//取反
			end
			else
				counter = counter+1;
		end
		assign clock = clock_temp;
endmodule

3. 校时功能模块_module Seter

校时模块由4个n进制计数器(n=10)子模块组成,set_loc用于记录操作哪一位计数器,set_num用于记录校时的值。在enable拨码为1时,apply按键每按下一次,指针向右移一位;inc按键每按下一次,当前计数器获得一个cp,即值加1。在enable拨码为0时,该模块不起作用。

//校时功能模块
module Seter(
	input enable,
	input inc,
	input apply,
	output [15:0] set_num,
	output [3:0] set_loc
	);
	//中间变量
	reg [3:0] set_loc_temp = 4'b1000;//修改的位
	always @(posedge apply)
	begin
		if (enable)
		begin
			set_loc_temp[0] <= set_loc_temp[1];
			set_loc_temp[1] <= set_loc_temp[2];
			set_loc_temp[2] <= set_loc_temp[3];
			set_loc_temp[3] <= set_loc_temp[0];//移位
		end
	end
	Count_n P15(
	.cp(set_loc_temp[0] && enable && inc),
	.reset(0),
	.set(0),
	.set_num(0),
	.n(10),//十进制
	.countn_num(set_num[3:0]),
	.countn_co()//输出悬空
	);
	Count_n P16(
	.cp(set_loc_temp[1] && enable && inc),
	.reset(0),
	.set(0),
	.set_num(0),
	.n(10),
	.countn_num(set_num[7:4]),
	.countn_co()
	);
	Count_n P17(
	.cp(set_loc_temp[2] && enable && inc),
	.reset(0),
	.set(0),
	.set_num(0),
	.n(10),
	.countn_num(set_num[11:8]),
	.countn_co()
	);
	Count_n P18(
	.cp(set_loc_temp[3] && enable && inc),
	.reset(0),
	.set(0),
	.set_num(0),
	.n(10),
	.countn_num(set_num[15:12]),
	.countn_co()
	);
	assign set_loc = set_loc_temp;
endmodule

4. n进制计数器模块_module Count_n

计数器的进制n与计数脉冲cp由输入给定,输出当前计数值和进位。具有清零和置数的功能。

//n进制计数器模块
module Count_n(
	input cp,
	input reset,
	input set,
	input [3:0] set_num,//置数值
	input [3:0] n,//进制
	output [3:0] countn_num,//计数值
	output countn_co//进位
	);
	//中间变量
	reg [3:0] counter = 0;
	reg countn_co_temp = 0;
	always @(posedge cp, posedge reset, posedge set)
	begin
		//计数
		if (reset)//高电平清零
		begin
			counter = 0;
			countn_co_temp = 0;		
		end
		else 
		begin
			if (set)//高电平置数
			begin
			if (set_num < n)
				begin
					counter = set_num;
					countn_co_temp = 0;
				end
			end
			else
			begin		
				counter = counter+1;//阻塞赋值,顺序执行	
				if (counter >= n)
				begin
					counter = 0;	
					countn_co_temp = 1;
				end
				else
					countn_co_temp = 0;	
			end
		end
	end
	assign countn_num = counter;
	assign countn_co = countn_co_temp;
endmodule

5. 计时功能模块_module Counter

计时功能模块含秒、分、时三个子模块,串行连接,秒针cp由分频模块给出,分针cp由秒进位给出,时针cp由分针进位给出。输出当前时间、秒针LED电平、分针进位(供闹钟整点报时使用)。具有清零和置数功能。
计时功能:当enable拨码为1时,将cp给秒针模块;否则不进行计数。
清零功能:reset按键按下,时分秒全部清零。
置数功能:当sec_show(显示分秒)或hour_show(显示时分)拨码为1时,set按键按下,将置数值赋给分秒/时分;否则置数功能不起作用。

//计时功能模块
module Counter(
	input cp,
	input reset,
	input enable,
	input set,
	input [15:0] set_num,//置数值
	input sec_show,//显示分秒
	input hour_show,//显示时分
	output [23:0] counter_num,//当前时间
	output hour,//分针进位
	output sec//秒针LED
	);
	//中间变量
	wire co_sec;//秒进位
	wire co_min;//分进位
	wire [7:0]sec_num;//秒
	wire [7:0]min_num;//分
	wire [7:0]hour_num;//时
	wire sec_temp;
	reg [23:0] set_num_temp = 0;
	reg [2:0] set_temp = 0;
	//置数判断
	always @(set)
	begin
		if (set)
		begin
			if (hour_show)
			begin
				set_num_temp[23:8] = set_num;
				set_temp = 3'b110;
			end
			else
				if (sec_show)
				begin
					set_num_temp[15:0] = set_num;
					set_temp = 3'b011;
				end
		end
		else
			set_temp = 0;
	end
	//秒针		
	Sec_counter P2(
	.cp(cp),
	.reset(reset),
	.set(set_temp[0]),
	.set_num(set_num_temp[7:0]),
	.enable(enable),
	.sec_num(sec_num),
	.co_sec(co_sec),
	.sec(sec_temp)
	);
	assign sec = sec_temp;
	//分针
	Min_counter P3(
	.cp(co_sec),
	.reset(reset),
	.set(set_temp[1]),
	.set_num(set_num_temp[15:8]),
	.co_min(co_min),
	.min_num(min_num)
	);
	//时针
	Hour_counter P4(
	.cp(co_min),
	.reset(reset),
	.set(set_temp[2]),
	.set_num(set_num_temp[23:16]),
	.hour_num(hour_num)
	);
	assign hour = co_min;
	assign counter_num[23:16] = hour_num;
	assign counter_num[15:8] = min_num;
	assign counter_num[7:0] = sec_num;
endmodule

6. 秒针模块_module Sec_counter

秒针模块包含两个n进制计数器子模块(个位n=10,十位n=6),串行连接,个位进位接到十位cp上。cp、set、reset、置数值由父模块给定。输出秒LED电平、秒针数值、秒针进位。由于当计数使能为0时,计数停止,秒LED应不再闪烁,因此LED电平不能由分频模块直接提供。

//秒针模块
module Sec_counter (
	input cp,
	input reset,
	input set,
	input [7:0] set_num,
	input enable,
	output [7:0] sec_num,//秒针数值
	output co_sec,//进位
	output sec//秒LED
	);
	//中间变量
	wire [1:0] co_sec_temp;
	wire enable_h;
	wire [7:0] sec_num_temp;
	reg sec_temp = 0;
	//10进制计数器计个位
	Count_n P7(
	.cp(cp && enable),
	.reset(reset),
	.set(set),
	.set_num(set_num[3:0]),
	.n(10),
	.countn_num(sec_num_temp[3:0]),
	.countn_co(co_sec_temp[0])
	);
	//6进制计数器计十位
	assign enable_h = co_sec_temp[0];
	Count_n P8(
	.cp(enable_h),
	.reset(reset),
	.set(set),
	.set_num(set_num[7:4]),
	.n(6),
	.countn_num(sec_num_temp[7:4]),
	.countn_co(co_sec_temp[1])
	);
	assign co_sec = co_sec_temp[1];
	//采取秒针LED电平
	always @(sec_num_temp)
	begin
		if (sec_num_temp[0])
			sec_temp = 1;
		else
			sec_temp = 0;
	end
	assign sec = sec_temp;
	assign sec_num = sec_num_temp;
endmodule

7. 分针模块_module Min_counter

原理同秒针模块,不再赘述。

//分针模块
module Min_counter(
	input cp,
	input reset,	
	input set,
	input [7:0] set_num,
	output co_min,
	output [7:0] min_num
	);
	//中间变量
	wire [1:0] co_min_temp;
	wire [7:0] min_num_temp;
	wire enable_h;
	//10进制计数器计个位
	Count_n P9(
	.cp(cp),
	.reset(reset),
	.set(set),
	.set_num(set_num[3:0]),
	.n(10),
	.countn_num(min_num_temp[3:0]),
	.countn_co(co_min_temp[0])
	);
	//6进制计数器计十位
	assign enable_h = co_min_temp[0];
	Count_n P10(
	.cp(enable_h),
	.reset(reset),
	.set(set),
	.set_num(set_num[7:4]),
	.n(6),
	.countn_num(min_num_temp[7:4]),
	.countn_co(co_min_temp[1])
	);
	assign min_num = min_num_temp;
	assign co_min = co_min_temp[1];
endmodule

8. 时针模块_module Hour_counter

十位为3进制,个位进制由十位数值决定,当十位为0或1时,个位为10进制;当十位为2时,个位为4进制。其余原理同分、秒模块。

//时针模块
module Hour_counter(
	input cp,
	input reset,
	input set,
	input [7:0] set_num,
	output [7:0] hour_num
	);
	//中间变量
	wire [1:0] co_hour_temp;
	wire [7:0] hour_num_temp;
	reg [3:0] n_low = 10;
	wire enable_h;
	//10-4进制计数器计个位
	Count_n P11(
	.cp(cp),
	.reset(reset),
	.set(set),
	.set_num(set_num[3:0]),
	.n(n_low),
	.countn_num(hour_num_temp[3:0]),
	.countn_co(co_hour_temp[0])
	);
	assign enable_h = co_hour_temp[0];
	//3进制计数器计十位
	Count_n P12(
	.cp(enable_h),
	.reset(reset),
	.set(set),
	.set_num(set_num[7:4]),
	.n(3),
	.countn_num(hour_num_temp[7:4]),
	.countn_co(co_hour_temp[1])
	);
	//控制个位进制
	always @(hour_num_temp[7:4])
		begin
			case(hour_num_temp[7:4])
				2:	n_low = 4;		
				default: n_low = 10;
			endcase	
		end
	assign hour_num = hour_num_temp;
endmodule

9. 闹钟功能模块_module Alarm

闹钟模块有整点报时和定时闹钟两个功能:
整点报时:当产生分进位信号时,根据当前时针数值(由计时模块给定)决定LED闪烁次数,(闪烁频率由分频模块给定)。
定时闹钟: 置数方式与计时模块相似,当alarm_show(显示闹钟)拨码为1时,set按键按下,将置数值赋给闹钟;否则置数功能不起作用。当前时间与闹钟数值相同时,闹钟LED常亮一分钟。

//闹钟功能模块
module Alarm(
	input cp,
	input enable,
	input set,
	input [15:0] set_num,
	input hour,//进位信号
	input [23:0] counter_num,
	output alarm,//定时闹钟
	output hour_alarm,//整点报时
	output [15:0] alarm_num//闹钟时间
	);
	//中间变量
	reg [7:0] hour_num = 0;//时针时间
	reg [15:0] alarm_num_temp = 0;
	reg hour_alarm_temp = 0;
	reg alarm_temp = 0;
	reg switch = 1;//控制闪烁
	always @(posedge cp)
	begin
		//整点报时
		if (hour && (counter_num[15:0] == 0))//装入初值,不断减一,直到为0
			hour_num = counter_num[23:20]*10 + counter_num[19:16];
		else
		begin
			if (hour_num > 0)
			begin
				if (switch)
				begin
					hour_num = hour_num - 1;
					hour_alarm_temp = 1;
					switch = ~switch;
				end
				else 
				begin
					hour_alarm_temp = 0;
					switch = ~switch;
				end
			end
			else
				hour_alarm_temp = 0;
		end
		//定时闹钟
		if (alarm_num == counter_num[23:8])
			alarm_temp = 1;
		else
			alarm_temp = 0;			
	end
	assign hour_alarm = hour_alarm_temp;
	assign alarm = alarm_temp;
	//定时
	always @(posedge set)
	begin
		if (enable)
			alarm_num_temp = set_num;
	end
	assign alarm_num = alarm_num_temp;
endmodule

10. 取数模块_module Select

按优先级排列如下:
当set_enable(置数使能)拨码为1时,输出置数内容;
当alarm_enable(显示闹钟)拨码为1时,输出闹钟内容;
当hour_show(显示时分)拨码为1时,输出时分内容;
当sec_show(显示分秒)拨码为1时,输出分秒内容。

//取数模块
module Select(
	input cp,
	input [23:0] counter_num,
	input [15:0] set_num,
	input [15:0] alarm_num,
	input set_enable,
	input alarm_enable,
	input hour_show,
	input sec_show,
	output [15:0] show_num
    );
	reg [15:0] show_num_temp = 0;
	always @(posedge cp)
		begin
			if(set_enable)
				show_num_temp <= set_num;
			else if (alarm_enable)
				show_num_temp <= alarm_num;
			else if (hour_show)
				show_num_temp <= counter_num[23:8];
			else if (sec_show)
				show_num_temp <= counter_num[15:0];			
			else			
				show_num_temp <= 0;
		end
		assign show_num = show_num_temp;
endmodule

11. 扫描模块_module Scan

将取数模块输出值分时送到译码模块。扫描频率的计算方法与模六十计数器相同,但由于是对4个数码管进行动态显示,分频数应是模六十计数器的一半,即2的18次方。

//扫描模块
module Scan(
	input cp,
	input [15:0] num,
	input set_enable,	
	input [3:0] set_loc,
	output [3:0] loc,
	output [3:0] scan_num,
	output point
	);
	//中间变量
	parameter j = 18;//控制扫描速率,仿真时取1;下载时取18(扫描频率100Hz)
	reg [33:0] scan_counter = 0;
	reg [3:0] loc_temp = 4'b1111;
	reg [3:0] scan_num_temp = 0;
	reg point_temp = 1;
	wire [15:0] num_temp;
	assign num_temp = num;
	always @(posedge cp)//上升沿触发
	begin
			scan_counter <= scan_counter+1;
	end
	always @(scan_counter[j])
	begin
		case(scan_counter[j+1:j])
			2'b00:
				begin
					loc_temp <= 4'b1110;
					scan_num_temp <= num_temp[3:0];
					point_temp <= set_loc[0];
				end
			2'b01:
				begin
					loc_temp <= 4'b1101;
					scan_num_temp <= num_temp[7:4];
					point_temp <= set_loc[1];
				end
			2'b10:
				begin
					loc_temp <= 4'b1011;
					scan_num_temp <= num_temp[11:8];
					point_temp <= set_loc[2];
				end			
			2'b11:
				begin
					loc_temp <= 4'b0111;
					scan_num_temp <= num_temp[15:12];
					point_temp <= set_loc[3];
				end
		endcase
		if (set_enable == 0)
			point_temp <= 0;
	end
	assign loc = loc_temp;
	assign point = point_temp;
	assign scan_num = scan_num_temp;
endmodule

12. 译码模块_module Trans

将扫描模块输入的数字转化成对应的数码管电平输出,与模六十计数器相同。但由于置数时需要用小数点来显示设置的位置,当set_enable(置数使能)拨码为1时,根据置数位置来确定是否显示小数点;当set_enable(置数使能)拨码为0时,不显示小数点。

//译码模块
module Trans(
	input [3:0] scan_num,
	input point,
	output [7:0] pin
	);
	//中间变量
	wire [3:0] scan_num_temp;
	assign scan_num_temp = scan_num;
	reg [7:0] pin_temp;
	always @(scan_num_temp, point)
	begin
		case(scan_num_temp)
			0: pin_temp[7:1] = 7'b0000001;
			1: pin_temp[7:1] = 7'b1001111;
			2: pin_temp[7:1] = 7'b0010010;
			3: pin_temp[7:1] = 7'b0000110;
			4: pin_temp[7:1] = 7'b1001100;
			5: pin_temp[7:1] = 7'b0100100;
			6: pin_temp[7:1] = 7'b0100000;
			7: pin_temp[7:1] = 7'b0001111;
			8: pin_temp[7:1] = 7'b0000000;
			9: pin_temp[7:1] = 7'b0000100;
			default: pin_temp = 7'b0110000;//其他状态显示E
		endcase
			pin_temp[0] = !point;
	end
	assign pin = pin_temp;
endmodule

四、测试文件

	仿真代码如下:
module Test_Top;
	// Inputs
	reg cp;
	reg reset;
	reg set;
	reg apply;
	reg inc;
	reg set_enable;
	reg alarm_enable;
	reg hour_show;
	reg sec_show;
	reg count_enable;

	// Outputs
	wire [3:0] loc;
	wire [7:0] pin;
	wire alarm;
	wire hour_alarm;
	wire sec;

	// Instantiate the Unit Under Test (UUT)
	top uut (
		.cp(cp), 
		.reset(reset), 	
		.set(set), 
		.apply(apply), 
		.inc(inc), 
		.set_enable(set_enable), 
		.alarm_enable(alarm_enable), 
		.hour_show(hour_show), 
		.sec_show(sec_show),
		.count_enable(count_enable),
		.loc(loc),
		.pin(pin),
		.alarm(alarm),
		.hour_alarm(hour_alarm),
		.sec(sec)
	);
	
	//时钟周期20ns
	parameter PERIOD = 20;
	
	//时钟信号
	always begin
		cp = 1'b0;
		#(PERIOD/2)cp = 1'b1;
		#(PERIOD/2);
	end
		
	initial begin
		// Initialize Inputs
		cp = 0;
		reset = 1;
		set = 0;
		apply = 0;
		inc = 0;
		set_enable = 0;
		alarm_enable = 0;
		hour_show = 0;
		sec_show = 0;
		count_enable = 0;
		
		// Wait 100 ns for global reset to finish
		#100;
 		reset = 0;
		
		// Add stimulus here
//////////////////////////////////////////////使能拨码测试
		//开始计数
		#100;count_enable=1;
		//显示分秒
		#100;sec_show=1;
		//显示时分
		#100;hour_show=1;
		//闹钟模式
		#100;alarm_enable=1;
		//置数模式
		#100;set_enable=1;
//////////////////////////////////////////////闹钟置数测试
		//闹钟置数1200
		#100;inc=1; #20;inc=0;//1
		#100;apply=1; #20;apply=0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;//2
		#100;set_enable=0;
		#100;set=1; #20;set=0;
//////////////////////////////////////////////时钟置数测试
		//时分置数1100
		set_enable=1;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;//1
		#100;set_enable=0;alarm_enable=0;//1
		#100;set=1; #20;set=0;
		//分秒置数5949
		set_enable=1;
		#100;apply=1; #20;apply=0; #100;apply=1; #20;apply=0; #100;apply=1; #20;apply=0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #20;inc=0;//5
		#100;apply=1; #20;apply = 0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;//9
		#100;apply=1; #20;apply = 0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #20;inc=0; //4
		#100;apply=1; #20;apply=0;			
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;//9
		#100;set_enable=0;hour_show=0;
		#100;set=1; #20;set=0;
		#500;
//////////////////////////////////////////////清零测试
		//清零
		#100;reset=1;#20;reset=0;
//////////////////////////////////////////////计时使能拨码测试
		//停止计时
		#100;count_enable=0;
//////////////////////////////////////////////进位测试
		//分秒置数5949
		#100;set=1; #20;set=0;
		//时分置数2359	
		set_enable=1;
		#100;apply=1; #20;apply=0;//9
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #100;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #20;inc=0;//2
		#100;apply=1; #20;apply=0;
		#100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0; #100;inc=1; #20;inc=0;
		#100;inc=1; #20;inc=0;//3
		#100;apply=1; #20;apply=0;
		#100;inc=1; #20;inc=0;//5
		#100;set=1; #20;set=0;//空置数(当置数使能为0时,inc按键不应起作用)
		#100;set_enable=0;	
		#100;sec_show=0; #100;set=1; #20;set=0;//空置数	
		#100;hour_show=1; #100;set=1; #20;set=0;//时分置数
		//恢复计时
		#100;count_enable=1;
	end
endmodule

五、波形仿真

  1. 变量名称说明
    EDA数字钟_第2张图片

cp:电路板脉冲(20ns);
clock:分频模块产生脉冲,仿真时为10分频;
reset:清零按键;
set:置数按键;
inc:加一按键,在置数模式下对选定位加一;
apply:移位按键,在置数模式下改变选定的位置;
set_enable:置数使能拨码;
alarm_enable:显示闹钟拨码;
hour_show:显示时分拨码;
sec_show:显示分秒拨码;
count_enable:计时使能拨码;
set_num:置数内容:为观察方便,采用16进制显示,下同;
alarm_num:闹钟时间;
count_num:计时时间;
show_num:数码管显示内容;
loc:扫描位置;
scan_num:扫描数字,初始值为X,因为是中间变量,不会对引脚电平产生影响;
pin:数码管引脚电平,最后一位为小数点;
sec:秒LED;
hour_alarm:整点报时LED;
alarm:闹钟LED。
2. 使能拨码测试
EDA数字钟_第3张图片

初始化时关闭所有拨码,数码管显示0000;逐步打开拨码,数码管显示对应内容,如黄线所示,此时hour_show拨码打开,显示时分,counter_num内容为000001,故show_num为0000。
3. 闹钟置数测试
EDA数字钟_第4张图片

通过inc和apply按键使置数值达到1200,关闭set_enable,此时alarm_enable优先级最高,按下set按键,如黄线所示,alarm_num由0000变为1200。
4. 时钟置数测试
EDA数字钟_第5张图片

用同样的方法,先后使时钟的时分置1100,分秒置5949,如黄线所示。
5. 清零测试
EDA数字钟_第6张图片

如黄线所示,reset按下后,counter_num清零。
6. 计时使能拨码测试
EDA数字钟_第7张图片

如黄线所示,count_enable拨码置0后,不再计数,count_num保持不变。
7. 进位测试
EDA数字钟_第8张图片

将时间置到235949,进位正常,由235959到000000,如黄线所示。

总结

从电路角度去想问题
不要像我这么复杂

你可能感兴趣的:(Verilog,verilog,fpga)