其他分享
首页 > 其他分享> > FPGA数字时钟2

FPGA数字时钟2

作者:互联网

一.数字时钟设计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引脚锁定
在这里插入图片描述

标签:wire,数字,FPGA,clk,sys,key,rst,reg,时钟
来源: https://blog.csdn.net/m0_64565172/article/details/122458648