FPGA-Verilog多功能数字时钟

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qr_ljj/article/details/80297965

一.数字时钟设计

1.硬件资源:共阴极数码管一块,FPGA开发板一块(EP4CE40F23C8);

2. 开发板资源:3颗独立按键,数码管接口;

3. 功能设计:三种功能:a.时钟功能;b.校时功能;

4. 按键功能设计:按键调整数字时钟分钟显示;

1.数字时钟顶层模块RTL视图


1) 说明:这个为数字时钟的顶层模块,按键消抖模块xd,计数模块分秒CNT59,时CNT24,数码管显示sz,时间模块div;

2) 端口

输入:clock,reset;

输出:keyl,sel,seg;

3) 代码

module top(keyl,clock,reset,sel,seg);
input clock,reset;
input[2:0] keyl;
output[2:0]    sel;
output[7:0] seg;
wire clk_2k,clk_3k,clk_1k,cp,cp2,clk1,clk2,clk3,rst2,rst3;
wire[31:0] data;
wire[7:0] dout,cout;
wire[2:0] key_w,K1,K2,K3,key_r;
xd m1(.clk_4k(clk3),.key_w(keyl),.key_r(key_r));

div m2(.clock1(clock),.clk1(clk1),.Key(key_r),.clk2(clk2),.clk3(clk3));

CNT59 m3(.clk_3k(clk1),.rst3(reset),.K2(key_r),.K3(key_r),.cp(cp),.cout(data[7:0]),.cout1(data[19:12]));
CNT24 m4(.clk_2k(cp),.rst2(reset),.K1(key_r),.dout(data[31:24]));

sz m5(.clk_1k(clk2),.data(data),.sel(sel),.seg(seg));
endmodule 

2.按键消抖模块


1) 说明:这个模块为按键消抖模块,三颗按键;

2) 端口

输入:clk_4k,key_w;

输出:key_r;

3) 代码

module xd(clk_4k,key_w,key_r);
input clk_4k;
input[2:0] key_w;
output[2:0] key_r;
reg[2:0] k1,k2,k3;
always@(posedge clk_4k)
begin 
	k3 <= k2;  
	k2 <= k1;  
	k1 <= key_w;        
end
assign key_r = k1 & k2 & k3;
endmodule 

3. 数码管模块


1) 说明:这个为8位共阴极数码管模块;

2) 端口

输入:clk——1k,data;

输出:sel,seg;

 3)代码

module sz(clk_1k,data,sel,seg);
input clk_1k;
input[31:0] data;
output[2:0]	sel;
output[7:0] seg;

reg[7:0] seg_r;
reg[2:0] sel_r;
reg[3:0] disp_dat;
reg[2:0]count;

assign sel= sel_r;
assign seg = seg_r;	

always @(posedge clk_1k)
begin
if(count<3'd7)
	begin
		count <= count + 1'b1;
	end
else
	begin
		count<=3'd0;
	end
end

always @(posedge clk_1k)   						
begin
	case(count)
		3'd0:disp_dat = data[31:28];
		3'd1:disp_dat = data[27:24];
		3'd2:disp_dat = 4'ha;
		3'd3:disp_dat = data[19:16];
		3'd4:disp_dat = data[15:12];
		3'd5:disp_dat = 4'hb;
		3'd6:disp_dat = data[7:4];
		3'd7:disp_dat = data[3:0];
	endcase
	case(count)
		3'd7:sel_r = 3'b111;
		3'd6:sel_r = 3'b110;
		3'd5:sel_r = 3'b101;
		3'd4:sel_r = 3'b100;
		3'd3:sel_r = 3'b011;
		3'd2:sel_r = 3'b010;
		3'd1:sel_r = 3'b001;
		3'd0:sel_r = 3'b000;
	endcase	
end

always @(disp_dat)
begin
	case(disp_dat)
		4'h0:seg_r = 8'h3f;
		4'h1:seg_r = 8'h06;
		4'h2:seg_r = 8'h5b;
		4'h3:seg_r = 8'h4f;
		4'h4:seg_r = 8'h66;
		4'h5:seg_r = 8'h6d;
		4'h6:seg_r = 8'h7d;
		4'h7:seg_r = 8'h07;
		4'h8:seg_r = 8'h7f;
		4'h9:seg_r = 8'h6f;
		4'ha:seg_r = 8'h40;
		4'hb:seg_r = 8'h40;
	endcase
end
endmodule

4.时钟钟功能模块


1) 说明:这个模块为数字钟功能模块,包括小时模块CNT24,分秒模块CNT59;

2) 端口

输入:clk,reset,key;

输出:cout;

3) 代码

module CNT59(clk_3k,rst3,K2,K3,cp,cout,cout1);
input clk_3k,rst3;
input[2:0] K2,K3;
output[7:0] cout,cout1;
output cp;
reg [7:0] n,m;
reg cp,cq;
assign cout=n;
assign cout1=m;
always@(posedge clk_3k || K2 == 3'b110)
begin
	n[3:0]<=n[3:0]+4'd1;
	if(n[3:0] == 4'd9)
	begin
		n[3:0]<=4'b0;
		n[7:4]<=n[7:4]+4'b1;
		if(n[3:0] == 4'd9 && n[7:4] == 4'd5)
		begin
			n<=8'h00;
		end
	end
end

always@(n)
begin
	if(n[7:4]==4'd5 && n[3:0]==4'd9 ) cq=1'b1;
	else cq=1'b0;
end

always@(posedge cq || K3 == 3'b101)
begin
	m[3:0]<=m[3:0]+4'd1;
	if(m[3:0] == 4'd9)
	begin
		m[3:0]<=4'b0;
		m[7:4]<=m[7:4]+4'b1;
		if(m[3:0] == 4'd9 && m[7:4] == 4'd5)
		begin
			m<=8'h00;
		end
	end
end

always@(m)
begin
	if(m[7:4]==4'd5 && m[3:0]==4'd9 ) cp=1'b1;
	else cp=1'b0;
end
endmodule 

module CNT24(K1,clk_2k,rst2,dout);
input clk_2k,rst2;
input[2:0] K1;
output[7:0] dout;
reg [7:0] dout;
always@(posedge clk_2k || K1 == 3'b011)
begin
	if(dout[7:4]!=2)
	begin
		if(dout[3:0]==4'b1001)
		begin
			dout[7:4]<=dout[7:4]+4'b0001;
			dout[3:0]<=4'b0000;
		end
		else
		begin
			dout[7:4]<=dout[7:4];
			dout[3:0]<=dout[3:0]+4'b0001;
		end
	end
	else
		if(dout[3:0]==4'b0011)
		begin
			dout[7:4]<=4'b0000;
			dout[3:0]<=4'b0000;
		end
		else
		begin
			dout[7:4]<=dout[7:4];
			dout[3:0]<=dout[3:0]+4'b0001;
		end
end
endmodule 

5.div模块


1) 说明:这个模块为分频模块;

2) 端口

输入:clock1,key;

输出:clk1,clk2,clk3;

3) 代码

module div(clock1,clk1,Key,clk2,clk3);
input clock1;
input[2:0] Key;
output clk1,clk2,clk3;
reg clk1,clk2,clk3;
reg[24:0] count1;
reg[24:0] count2;
reg[24:0] count3;  
parameter  N1=50000000; 
parameter  N2=2500;
parameter  N3=500000;  
always@(posedge clock1)
	begin
	if(Key == 3'b111)
	begin
		count1<=count1+1'b1;
		  if(count1== N1/2-1)
			begin	
				clk1 <=~ clk1;
			 	count1<=0;
			end
	end
		count2<=count2+1'b1;
		  if(count2==N2/2-1)
		    begin
	            clk2<=~clk2;
	            count2<=0;
	        end 
		count3<=count3+1'b1;
		  if(count3==N3/2-1)
		    begin
	            clk3<=~clk3;
	            count3<=0;
	        end 
	end
endmodule 


猜你喜欢

转载自blog.csdn.net/qr_ljj/article/details/80297965
今日推荐