一.数字时钟设计
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