这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 数字时钟数码管显示-作业

共6条 1/1 1 跳转至

数字时钟数码管显示-作业

助工
2014-11-08 00:22:38     打赏

交综合实验之数字时钟数码管显示作业(带有复位和置位)

设计之前的模型框图:


设计源代码:

顶层:


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Charles Wang 
// 
// Create Date:    11/3/2014 
// Design Name: 	Digital Clock
// Module Name:   digital_clock
// Project Name: 	digital_clock
// Target Devices: EP4CE6E22C8
// Tool versions: Quartus II  12.0 64bit
// Description: 带时/分置位按键及复位按键的数字时钟--顶层模块
//              
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//			
//////////////////////////////////////////////////////////////////////////////////
module digital_clock(sys_clk,sys_rst_n,minu_pre,hour_pre,sel,seg);
input sys_clk;//50MHz 总线时钟
input sys_rst_n;//异步复位,低有效
input minu_pre;//分预设
input hour_pre;//时预设

output [7:0]sel;//数码管位选
output [7:0]seg;//数码管段选

wire sec_clk_w;
wire [6:0]second_w;
wire [6:0]minute_w;
wire [6:0]hour_w;

freq_div Div(.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.sec_clk(sec_clk_w));

cnt_module Cnt(.sec_clk(sec_clk_w),.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),
.minu_pre(minu_pre),.hour_pre(hour_pre),.second(second_w),.minute(minute_w),
.hour(hour_w));

sm_seg     Seg(.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.second(second_w),
.minute(minute_w),.hour(hour_w),.seg(seg),.sel(sel));
endmodule 



分频模块:


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Charles Wang 
// 
// Create Date:    11/3/2014 
// Design Name: 	Digital Clock
// Module Name:   freq_div
// Project Name: 	digital_clock
// Target Devices: EP4CE6E22C8
// Tool versions: Quartus II  12.0 64bit
// Description: 带时/分置位按键及复位按键的数字时钟--分频模块
//              
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//			
//////////////////////////////////////////////////////////////////////////////////
module freq_div(sys_clk,sys_rst_n,sec_clk);
input sys_clk;//50MHz 总线时钟
input sys_rst_n;//异步复位,低有效

output sec_clk;//输出秒时钟

reg [27:0]cnt;
reg sec_clk_r;

parameter T1S = 28'd2500_0000;
//////////////////////////////////////////////////////////////////////////////////
//分频产生秒信号
always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
			begin	
						cnt <= 28'd0;
				sec_clk_r <= 1'b0;
			end
		else if(cnt == T1S - 1'b1)
			begin
				cnt 		 <= 28'd0;
				sec_clk_r <= ~ sec_clk_r;
			end
		else
			begin
				cnt <= cnt + 1'b1;
			end
	end
assign sec_clk = sec_clk_r;
endmodule



时钟计数及置位模块:


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Charles Wang 
// 
// Create Date:    11/3/2014 
// Design Name: 	Digital Clock
// Module Name:   cnt_module
// Project Name: 	digital_clock
// Target Devices: EP4CE6E22C8
// Tool versions: Quartus II  12.0 64bit
// Description: 带时/分置位按键及复位按键的数字时钟--时钟计时及置位模块
//              
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//			
//////////////////////////////////////////////////////////////////////////////////
module cnt_module(sec_clk,sys_clk,sys_rst_n,minu_pre,hour_pre,hour,minute,second);
input sec_clk;//秒时钟输入
input sys_clk;//50MHz总线时钟
input sys_rst_n;//异步复位,低有效
input minu_pre;//分预置信号
input hour_pre;//时预置信号

output [6:0]second;//输出秒信号
output [6:0]minute;//输出分信号
output [6:0]hour;//输出小时信号

parameter T100MS = 24'd500_0000;//100ms用于过滤按键抖动


reg M1,M2;
reg H1,H2;
reg S1,S2;
reg [6:0]second_r;
reg [6:0]minute_r;
reg [6:0]hour_r;
reg [23:0]cnt1;
reg [23:0]cnt2;
reg isMinu_Pre;
reg isHour_Pre;
reg [2:0]i;
reg [2:0]j;
reg flag1;
reg flag2;

wire isMH2L;
wire isML2H;
wire isHH2L;
wire isHL2H;
wire Sec_L2H;
//////////////////////////////////////////////////////////////////////////////////
//分别用isMinu_Pre/isHour_Pre 作为分/时预设按键的下降沿标志信号
//用Sec_L2H 作为秒时钟的上升沿信号
always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
			begin
				{M1,M2} <= 2'b11;
			end
		else
			begin
				{M2,M1} <= {M1,minu_pre};
			end
	end
assign isMH2L  = (M2 == 1'b1) && (M1 == 1'b0);
assign isML2H  = (M2 == 1'b0) && (M1 == 1'b1);
always@(posedge sys_clk or negedge sys_rst_n)//对minu_pre 进行按键消抖
	begin
		if(!sys_rst_n)
			begin
							i <= 3'd0;
				isMinu_Pre <= 1'b0;
						flag1<= 1'b0;
						cnt1 <= 24'd0;
			end
		else
			case(i)
				3'd0: if(isMH2L)
							begin
								i <= i + 1'b1;
							end
				3'd1:	if(cnt1 == T100MS - 1'b1)
							begin
								cnt1 <= 24'd0;
								i 	  <= i + 1'b1;
							end
						else
							begin
								cnt1 <= cnt1 + 1'b1;
							end
				3'd2: if(isML2H)
							begin
								i <= i + 1'b1;
							end
				3'd3: if(cnt1 == T100MS - 1'b1)	
							begin
								cnt1 <= 24'd0;
								i    <= i + 1'b1;
								flag1<= 1'b1;
							end
						else
							begin
								cnt1 <= cnt1 + 1'b1;
							end
				3'd4: if(flag1 == 1'b1)
							begin
								isMinu_Pre <= 1'b1;
								i 			  <= i + 1'b1;
							end
				3'd5: begin
							i <= i + 1'b1;
							isMinu_Pre <= 1'b0;
						end
				3'd6: begin
							i 		<= 3'd0;
							flag1 <= 1'b0;
						end
				default: i <= 3'd0;
				endcase
	end						
always@(posedge sys_clk or negedge sys_rst_n)
	begin	
		if(!sys_rst_n)
			begin
				{H1,H2} <= 2'b11;
			end
		else
			begin
				{H2,H1} <= {H1,hour_pre};
			end
	end
assign isHH2L	 = (H2 == 1'b1) && (H1 == 1'b0);
assign isHL2H	 = (H2 == 1'b0) && (H1 == 1'b1);
always@(posedge sys_clk or negedge sys_rst_n)//对hour_pre 进行按键消抖
	begin
		if(!sys_rst_n)
			begin
							j <= 3'd0;
				isHour_Pre <= 1'b0;
						flag2<= 1'b0;
						cnt2 <= 24'd0;
			end
		else
			case(j)
				3'd0: if(isHH2L)
							begin
								j <= j + 1'b1;
							end
				3'd1:	if(cnt2 == T100MS - 1'b1)
							begin
								cnt2 <= 24'd0;
								j 	  <= j + 1'b1;
							end
						else
							begin
								cnt2 <= cnt2 + 1'b1;
							end
				3'd2: if(isHL2H)
							begin
								j <= j + 1'b1;
							end
				3'd3: if(cnt2 == T100MS - 1'b1)	
							begin
								cnt2 <= 24'd0;
								j    <= j + 1'b1;
								flag2<= 1'b1;
							end
						else
							begin
								cnt2 <= cnt2 + 1'b1;
							end
				3'd4: if(flag2 == 1'b1)
							begin
								isHour_Pre <= 1'b1;
								j		  	  <= j + 1'b1;
							end
				3'd5: begin
							j 			  <= j + 1'b1;
							isHour_Pre <= 1'b0;
						end
				3'd6: begin
							j 		<= 3'd0;
							flag2 <= 1'b0;
						end
				default: j <= 3'd0;
				endcase
	end	
always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
			begin
				{S1,S2} <= 2'b11;
			end
		else
			begin
				{S2,S1} <= {S1,sec_clk};
			end
	end
assign Sec_L2H	= (S2 == 1'b0) && (S1 == 1'b1);
//////////////////////////////////////////////////////////////////////////////////
//时钟计数及预设部分
always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
			begin
				second_r <= 7'h0;
				minute_r <= 7'h0;
				hour_r   <= 7'h0;
			end
		else if(isMinu_Pre)//对分进行预设
			begin
				if(minute_r[3:0] == 4'h9)
					begin
						if(minute_r[6:4] == 3'h5)
							begin
								minute_r <= 7'h0;
							end
						else
							begin
								minute_r[6:4] <= minute_r[6:4] + 1'b1;
								minute_r[3:0] <= 4'h0;
							end
					end
				else
					begin
						minute_r[3:0] <= minute_r[3:0] + 1'b1;
					end							
			end
		else if(isHour_Pre)//对时进行预设
			begin
				if(hour_r[3:0] == 4'h3 && hour_r[6:4] == 3'h2)
					begin
						hour_r <= 7'h0;
					end
				else if(hour_r[6:4] < 3'h2 && hour_r[3:0] == 4'h9)
					begin
						hour_r[3:0] <= 4'h0;
						hour_r[6:4] <= hour_r[6:4] + 1'b1;
					end
				else 
					begin
						hour_r[3:0] <= hour_r[3:0] + 1'b1;
						hour_r[6:4] <= hour_r[6:4];
					end
			end
		else if(Sec_L2H)//时钟计数部分
			begin
				if(second_r[3:0] == 4'h9)
					begin
						if(second_r[6:4] == 3'h5)
							begin
								if(minute_r[3:0] == 4'h9)	
									begin	
										if(minute_r[6:4] == 3'h5)
											begin
												if(hour_r[6:4] == 4'h2 && hour_r[3:0] == 4'h3)
													begin
														hour_r 	<= 7'h0;
														minute_r	<= 7'h0;
														second_r <= 7'h0;
													end
												else if(hour_r[6:4] < 3'h2 && hour_r[3:0] == 4'h9)
													begin
														hour_r[3:0] <= 4'h0;
														hour_r[6:4] <= hour_r[6:4] + 1'b1;
														minute_r		<= 7'h0;
														second_r		<= 7'h0;
													end
												else 
													begin	
														hour_r[3:0] <= hour_r[3:0] + 1'b1;
														hour_r[6:4] <= hour_r[6:4];
														minute_r		<= 7'h0;
														second_r 	<= 7'h0;
													end
											end
										else
											begin	
												hour_r 		  <= hour_r;
												minute_r[6:4] <= minute_r[6:4] + 1'b1;
												minute_r[3:0] <= 4'h0;
												second_r		  <= 7'h0;
											end
									end
								else
									begin
										hour_r		  <= hour_r;
										minute_r[3:0] <= minute_r[3:0] + 1'b1;
										minute_r[6:4] <= minute_r[6:4];
										second_r 	  <= 7'h0;
									end
							end
						else
							begin	
								hour_r 	     <= hour_r;
								minute_r		  <= minute_r;
								second_r[6:4] <= second_r[6:4] + 1'b1;
								second_r[3:0] <= 4'h0;
							end
					end
				else
					begin
						hour_r 	     <= hour_r;
						minute_r 	  <= minute_r;
						second_r[6:4] <= second_r[6:4];
						second_r[3:0] <= second_r[3:0] + 1'b1;
					end
			end
		else
			begin	
				hour_r   <= hour_r;
				minute_r <= minute_r;
				second_r	<= second_r;
			end
end		
assign hour   = hour_r;
assign minute = minute_r;
assign second = second_r;	
endmodule



数码管驱动模块:


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Charles Wang 
// 
// Create Date:    11/4/2014 
// Design Name: 	Digital Clock
// Module Name:   sm_seg
// Project Name: 	digital_clock
// Target Devices: EP4CE6E22C8
// Tool versions: Quartus II  12.0 64bit
// Description: 带时/分置位按键及复位按键的数字时钟--数码管驱动模块
//              
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//			
//////////////////////////////////////////////////////////////////////////////////
module sm_seg(sys_clk,sys_rst_n,second,minute,hour,seg,sel);

input sys_clk;//总线时钟50MHz
input sys_rst_n;//异步复位,低有效
input[6:0]second;//秒数据
input[6:0]minute;//分数据
input[6:0]hour;//时数据

output [7:0]seg;//输出段码驱动数据
output [7:0]sel;//输出位码驱动数据

parameter T10MS = 16'd5_0000;//用于位选扫描

reg [7:0]seg_r;
reg [7:0]sel_r;
reg [2:0]cnt_scan;
reg [15:0]cnt;

always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
			begin
				cnt <= 16'd0;
			end
		else if(cnt == T10MS - 1'b1)
			begin
				cnt <= 16'd0;
			end
		else
			begin
				cnt <= cnt + 1'b1;
			end
	end
always@(posedge sys_clk or negedge sys_rst_n)
	begin	
		if(!sys_rst_n)
			begin
				cnt_scan <= 3'd0;
			end
		else if(cnt == T10MS - 1'b1)
			begin
				cnt_scan <= cnt_scan + 1'b1;
			end
	end
always@(posedge sys_clk or negedge sys_rst_n)//位选扫描
	begin
		if(!sys_rst_n)
			begin
				sel_r <= 8'd0;
			end
		else
			case(cnt_scan)
				3'd0: sel_r <= 8'b1111_1110;
				3'd1: sel_r <= 8'b1111_1101;
				3'd2: sel_r <= 8'b1111_1011;
				3'd3: sel_r <= 8'b1111_0111;
				3'd4: sel_r <= 8'b1110_1111;
				3'd5: sel_r <= 8'b1101_1111;
				3'd6: sel_r <= 8'b1011_1111;
				3'd7: sel_r <= 8'b0111_1111;
			default: sel_r <= 8'b1111_1111;
			endcase
	end
reg[7:0]seg_r_sec1;
reg[7:0]seg_r_sec2;
reg[7:0]seg_r_minu1;
reg[7:0]seg_r_minu2;
reg[7:0]seg_r_hour1;
reg[7:0]seg_r_hour2;
always@(posedge sys_clk or negedge sys_rst_n)//段选驱动
	begin
		if(!sys_rst_n)
			begin
				seg_r_sec1 <= 8'hff;
				seg_r_sec2 <= 8'hff;
				seg_r_minu1<= 8'hff;
				seg_r_minu2<= 8'hff;
				seg_r_hour1<= 8'hff;
				seg_r_hour2<= 8'hff;
			end
		else
			case(second[3:0])
				4'h0 : seg_r_sec1 <= 8'hc0;   // "0"
				4'h1 : seg_r_sec1 <= 8'hf9;   // "1"
				4'h2 : seg_r_sec1 <= 8'ha4;   // "2"
				4'h3 : seg_r_sec1 <= 8'hb0;   // "3"
				4'h4 : seg_r_sec1 <= 8'h99;   // "4"
				4'h5 : seg_r_sec1 <= 8'h92;   // "5"
				4'h6 : seg_r_sec1 <= 8'h82;   // "6"
				4'h7 : seg_r_sec1 <= 8'hf8;   // "7"
				4'h8 : seg_r_sec1 <= 8'h80;   // "8"
				4'h9 : seg_r_sec1 <= 8'h90;   // "9"
			default : seg_r_sec1 <= 8'hff;
			endcase
			case(second[6:4])
				3'h0 : seg_r_sec2 <= 8'hc0;   // "0"
				3'h1 : seg_r_sec2 <= 8'hf9;   // "1"
				3'h2 : seg_r_sec2 <= 8'ha4;   // "2"
				3'h3 : seg_r_sec2 <= 8'hb0;   // "3"
				3'h4 : seg_r_sec2 <= 8'h99;   // "4"
				3'h5 : seg_r_sec2 <= 8'h92;   // "5"
			default : seg_r_sec2 <= 8'hff;		
			endcase
			case(minute[3:0])
				4'h0 : seg_r_minu1 <= 8'hc0;   // "0"
				4'h1 : seg_r_minu1 <= 8'hf9;   // "1"
				4'h2 : seg_r_minu1 <= 8'ha4;   // "2"
				4'h3 : seg_r_minu1 <= 8'hb0;   // "3"
				4'h4 : seg_r_minu1 <= 8'h99;   // "4"
				4'h5 : seg_r_minu1 <= 8'h92;   // "5"
				4'h6 : seg_r_minu1 <= 8'h82;   // "6"
				4'h7 : seg_r_minu1 <= 8'hf8;   // "7"
				4'h8 : seg_r_minu1 <= 8'h80;   // "8"
				4'h9 : seg_r_minu1 <= 8'h90;   // "9"
			default : seg_r_minu1<= 8'hff;
			endcase
			case(minute[6:4])
				3'h0 : seg_r_minu2 <= 8'hc0;   // "0"
				3'h1 : seg_r_minu2 <= 8'hf9;   // "1"
				3'h2 : seg_r_minu2 <= 8'ha4;   // "2"
				3'h3 : seg_r_minu2 <= 8'hb0;   // "3"
				3'h4 : seg_r_minu2 <= 8'h99;   // "4"
				3'h5 : seg_r_minu2 <= 8'h92;   // "5"
			default : seg_r_minu2 <= 8'hff;		
			endcase
			case(hour[3:0])
				4'h0 : seg_r_hour1 <= 8'hc0;   // "0"
				4'h1 : seg_r_hour1 <= 8'hf9;   // "1"
				4'h2 : seg_r_hour1 <= 8'ha4;   // "2"
				4'h3 : seg_r_hour1 <= 8'hb0;   // "3"
				4'h4 : seg_r_hour1 <= 8'h99;   // "4"
				4'h5 : seg_r_hour1 <= 8'h92;   // "5"
				4'h6 : seg_r_hour1 <= 8'h82;   // "6"
				4'h7 : seg_r_hour1 <= 8'hf8;   // "7"
				4'h8 : seg_r_hour1 <= 8'h80;   // "8"
				4'h9 : seg_r_hour1 <= 8'h90;   // "9"
			default : seg_r_hour1<= 8'hff;
			endcase
			case(hour[6:4])
				3'h0 : seg_r_hour2 <= 8'hc0;   // "0"
				3'h1 : seg_r_hour2 <= 8'hf9;   // "1"
				3'h2 : seg_r_hour2 <= 8'ha4;   // "2"
			default : seg_r_hour2 <= 8'hff;		
			endcase
	end
always@(posedge sys_clk or negedge sys_rst_n)
	begin
		if(!sys_rst_n)
			begin
				seg_r <= 8'hff;
			end
		else
			case(sel_r)
				8'b1111_1110: seg_r <= seg_r_sec1;
				8'b1111_1101: seg_r <= seg_r_sec2;
				8'b1111_1011: seg_r <= seg_r_sec1[0] ? 8'hbf:8'hff;
				8'b1111_0111: seg_r <= seg_r_minu1;
				8'b1110_1111: seg_r <= seg_r_minu2;
				8'b1101_1111: seg_r <= seg_r_sec1[0] ? 8'hbf:8'hff;
				8'b1011_1111: seg_r <= seg_r_hour1;
				8'b0111_1111: seg_r <= seg_r_hour2;
				default		: seg_r <= 8'hff;
			endcase
	end
assign sel = sel_r;
assign seg = seg_r;
endmodule 



以上就是源代码,实验视频:v.youku.com/v_show/id_XODIxNzM3NjI4.html




关键词: 数字     时钟     数码     显示     作业    

助工
2014-11-08 00:31:13     打赏
2楼

设计之前的模型其实和编译成功之后的RTL viewer 视图是一样的,通过这个可以检查一下框架符不符合自己的设计初衷


RTL Viewer 视图:


高工
2014-11-08 13:17:14     打赏
3楼
赞一个

菜鸟
2014-12-08 19:40:11     打赏
4楼
怎样用个键使其停止计时

助工
2014-12-14 22:14:13     打赏
5楼
只需要在按下该按键的时候,使寄存器的数值保持当前值就好了,类似一个锁存器,这样就实现了按键停止计时

助工
2014-12-17 16:21:21     打赏
6楼
楼主好厉害,这么大的代码

共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]