一.数字时钟设计2
本代码借鉴了一些,网上资源。
1.硬件资源:共阴极数码管一块,FPGA开发板一块(EP2C8Q208C8);
2.开发板资源:3颗独立按键,数码管接口;
3 功能设计:三种功能:a.时钟功能;b.校时功能;整点报时。
4.按键功能设计:按键调整数字时钟分钟显示;
A代码
module top(
input sys_clk,
input rst_n,
input key,
input key1,
input key2,
output reg [5:0]sel_seg,
output reg [7:0]seg_led,
output reg outy);
localparam MAX_NUM = 14'd5000;
reg [7:0]sec;
reg [7:0]min;
reg [7:0]hour;
reg flag_sec;//秒进位信号
reg flag_min;//分进位信号
//分频模块
parameter CLK_DIV=4'd10;//分频系数
reg dri_clk;//5MHz数码管驱动时钟
reg [3:0]div_cnt;//分频计数
reg [23:0]sec_cnt;//秒计数,sec_cnt计满5M次为1s
wire [3:0]shuju0;//秒个位
wire [3:0]shuju1;//秒十位
wire [3:0]shuju2;//分个位
wire [3:0]shuju3;//分十位
wire [3:0]shuju4;//时个位
wire [3:0]shuju5;//时十位
assign shuju5=hour/4'd10;
assign shuju4=hour%4'd10;
assign shuju3=min/4'd10;
assign shuju2=min%4'd10;
assign shuju1=sec/4'd10;
assign shuju0=sec%4'd10;
wire key_value;
wire key_flag;
wire key_value1;
wire key_flag1;
wire key_value2;
wire key_flag2;
key_debounce u_key_debounce(
.sys_clk(dri_clk),.sys_rst_n(rst_n),
.key(key),.key_flag(key_flag),.key_value(key_value));
key_debounce u_key_debounce1(
.sys_clk(dri_clk),.sys_rst_n(rst_n),
.key(key1),.key_flag(key_flag1),.key_value(key_value1));
key_debounce u_key_debounce2(
.sys_clk(dri_clk),.sys_rst_n(rst_n),
.key(key2),.key_flag(key_flag2),.key_value(key_value2));
always @(posedge sys_clk or negedge rst_n)begin
if(!rst_n)begin
div_cnt<=1'b0;
dri_clk<=1'b0;
end
else if(div_cnt==CLK_DIV/2-1)begin
dri_clk<=~dri_clk;
div_cnt<=4'd0;
end
else begin
div_cnt<=div_cnt+1'b1;
dri_clk<=dri_clk;
end
end
//秒计数模块
always @(posedge dri_clk or negedge rst_n)begin
if(!rst_n)begin
sec_cnt<=1'b0;
sec<=8'd0;
flag_sec<=1'b0;
end
else if(key_flag1&&(~key_value1))begin
if(sec==8'd59)
begin
sec<=8'd0;
flag_sec<=1'b1;
end
else begin
flag_sec<=1'b0;
sec<=sec+1'b1;
end
end
else if(sec_cnt==24'd500_0000)begin
if(sec==8'd59)begin
sec_cnt<=24'd0;
sec<=8'd0;
flag_sec<=1'b1;
end
else begin
flag_sec<=1'b0;
sec_cnt<=24'd0;
sec<=sec+1'b1;
end
end
else begin
flag_sec<=1'b0;
sec<=sec;
sec_cnt<=sec_cnt+1'b1;
end
end
//分计数模块
always @(posedge dri_clk or negedge rst_n)begin
if(!rst_n)begin
min<=8'd0;
flag_min<=1'b0;
end
else if(key_flag&&(~key_value)) begin
if(min==8'd59)
begin
min<=8'd0;
flag_min<=1'b1;
end
else begin
flag_min<=1'b0;
min<=min+1'b1;
end
end
else if(flag_sec)begin
if(min==8'd59)begin
flag_min<=1'b1;
min<=8'd0;
end
else begin
flag_min<=1'b0;
min<=min+1'b1;
end
end
else begin
flag_min<=1'b0;
min<=min;
end
end
//时计数模块
always @(posedge dri_clk or negedge rst_n)begin
if(!rst_n)begin
hour<=8'd0;
end
else if(key_flag2&&(~key_value2)) begin
if(hour==8'd59)
begin
hour<=8'd0;
end
else begin
hour<=hour+1'b1;
end
end
else if(flag_min)begin
if(hour==8'd23)begin
hour<=8'd0;
end
else begin
hour<=hour+1'b1;
end
end
else begin
hour<=hour;
end
end
always@(posedge dri_clk)
begin
if(shuju3==5 && shuju2==9 && shuju1==5 && shuju0>=0)
outy<=1'b0;
else
outy<=1'b1;
end
reg [3:0]display_num;
reg [2:0]cnt0;//位选计数
reg [13:0]cnt1;
//数码管位选
reg flag;
always @(posedge dri_clk or negedge rst_n)begin
if(!rst_n)begin
cnt1<=14'd0;
flag<=1'b0;
end
else if(cnt1==MAX_NUM-1)begin
cnt1<=14'd0;
flag<=1'b1;
end
else begin
flag<=1'b0;
cnt1<=cnt1+1'b1;
end
end
always @(posedge dri_clk or negedge rst_n)begin
if(!rst_n)begin
cnt0<=3'd0;
end
else if(flag)begin
if(cnt0==3'd5)
cnt0<=3'd0;
else cnt0<=cnt0+1'b1;
end
else cnt0<=cnt0;
end
always @(posedge dri_clk or negedge rst_n)begin
if(!rst_n)begin
sel_seg<=6'b111111;
display_num<=4'd0;
end
else begin
case(cnt0)
3'd0:begin
sel_seg<=6'b111110;
display_num<=shuju0;
end
3'd1:begin
sel_seg<=6'b111101;
display_num<=shuju1;
end
3'd2:begin
sel_seg<=6'b111011;
display_num<=shuju2;
end
3'd3:begin
sel_seg<=6'b110111;
display_num<=shuju3;
end
3'd4:begin
sel_seg<=6'b101111;
display_num<=shuju4;
end
3'd5:begin
sel_seg<=6'b011111;
display_num<=shuju5;
end
default:begin
sel_seg<=6'b111111;
display_num<=4'd0;
end
endcase
end
end
//数码管显示
always@(posedge dri_clk or negedge rst_n)begin
if(!rst_n)
seg_led<=8'd1111111;
else begin
case(display_num)
4'd0:begin
if(cnt0==3'd2||cnt0==3'd4)
seg_led<=8'b01000000;
else seg_led<=8'b11000000;
end
4'd1:begin
if(cnt0==3'd2||cnt0==3'd4) seg_led<=8'b01111001;
else seg_led<=8'b11111001;
end
4'd2:begin
if(cnt0==3'd2||cnt0==3'd4)
seg_led<=8'b00100100;
else seg_led<=8'b10100100;
end
4'd3:begin
if(cnt0==3'd2||cnt0==3'd4)
seg_led<=8'b00110000;
else seg_led<=8'b10110000;
end
4'd4:begin
if(cnt0==3'd2||cnt0==3'd4)
seg_led<=8'b00011001;
else seg_led<=8'b10011001;
end
4'd5:begin
if(cnt0==3'd2||cnt0==3'd4)
seg_led<=8'b00010010;
else
seg_led<=8'b10010010;
end
4'd6:begin
if(cnt0==3'd2||cnt0==3'd4)
seg_led<=8'b00000010;
else seg_led<=8'b10000010;
end
4'd7:begin
if(cnt0==3'd2||cnt0==3'd4)
seg_led<=8'b01111000;
else seg_led<=8'b11111000;
end
4'd8:begin
if(cnt0==3'd2||cnt0==3'd4)
seg_led<=8'b00000000;
else seg_led<=8'b10000000;
end
4'd9:begin
if(cnt0==3'd2||cnt0==3'd4)
seg_led<=8'b00010000;
else seg_led<=8'b10010000;
end
default:seg_led<=8'b1111111;
endcase
end
end
endmodule
module key_debounce(
input sys_clk,
input sys_rst_n,
input key,
output reg key_value,
output reg key_flag
);
reg [31:0] delay_cnt;
reg key_reg;
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
key_reg <= 1'b1;
delay_cnt <= 32'd0;
end
else begin
key_reg <= key;
if(key_reg != key)
delay_cnt <= 32'd100_0000;
else if(key_reg == key)begin
if(delay_cnt > 32'd0)
delay_cnt <= delay_cnt - 1'b1;
else
delay_cnt <= delay_cnt;
end
end
end
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
key_flag <= 1'b0;
key_value <= 1'b1;
end
else begin
if(delay_cnt == 32'd1)begin
key_flag <= 1'b1;
key_value <= key;
end
else begin
key_flag <= 1'b0;
key_value <= key_value;
end
end
end
endmodule
B引脚锁定