FPGA时钟设计

实现功能:基于Verilog的动态显示时钟设计,支持整点(时:00:00)闪烁功能。代码包含时钟计数、动态扫描、整点检测和闪烁控制模块:

复制代码
module dynamic_clock(
    input clk,          // 主时钟(假设50MHz)
    input rst_n,        // 异步复位(低电平有效)
    output reg [7:0] seg,    // 数码管段选(a-g + dp)
    output reg [3:0] dig     // 数码管位选(共4位,显示时:分)
);

// 内部信号定义
reg [25:0] cnt_div;         // 分频计数器
reg [3:0] scan_cnt;         // 扫描计数器
reg [1:0] blink_ctrl;       // 闪烁控制
reg [5:0] sec, min, hour;   // 时间计数器(0-59, 0-59, 0-23)
wire clk_1k;                // 扫描时钟(1kHz)
wire clk_1hz;               // 1Hz时钟
wire clk_2hz;               // 2Hz闪烁时钟
wire blink_en;              // 闪烁使能信号

// 分频模块:生成1kHz扫描时钟和1Hz基准时钟
assign clk_1k = cnt_div[17];  // 50MHz/(2^18) ≈ 190Hz(实际需调整至1kHz)
assign clk_1hz = cnt_div[25]; // 50MHz/(2^26) ≈ 1.49Hz(需校准至精确1Hz)

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) cnt_div <= 0;
    else cnt_div <= cnt_div + 1;
end

// 时间计数模块
always @(posedge clk_1hz or negedge rst_n) begin
    if(!rst_n) begin
        sec <= 0;
        min <= 0;
        hour <= 0;
    end else begin
        sec <= (sec == 59) ? 0 : sec + 1;
        if(sec == 59) begin
            min <= (min == 59) ? 0 : min + 1;
            if(min == 59) begin
                hour <= (hour == 23) ? 0 : hour + 1;
            end
        end
    end
end

// 整点检测与闪烁控制(每分钟0秒时闪烁)
assign blink_en = (min == 0) && (sec < 10); // 每分钟前10秒检测
assign clk_2hz = cnt_div[24];               // 约2Hz闪烁频率

always @(posedge clk_2hz or negedge rst_n) begin
    if(!rst_n) blink_ctrl <= 0;
    else if(blink_en) blink_ctrl <= ~blink_ctrl;
    else blink_ctrl <= 2'b11; // 非闪烁时段常亮
end

// 动态扫描模块
always @(posedge clk_1k or negedge rst_n) begin
    if(!rst_n) begin
        scan_cnt <= 0;
        dig <= 4'b1111;
    end else begin
        scan_cnt <= scan_cnt + 1;
        case(scan_cnt[1:0])
            2'b00: dig <= 4'b1110; // 显示小时十位
            2'b01: dig <= 4'b1101; // 显示小时个位
            2'b10: dig <= 4'b1011; // 显示分钟十位
            2'b11: dig <= 4'b0111; // 显示分钟个位
        endcase
    end
end

// BCD转七段码(共阴数码管)
always @(*) begin
    if(blink_ctrl[0]) seg = 8'hff; // 闪烁时关闭显示
    else case({dig, scan_cnt[1:0]})
        // 小时十位
        4'b1110: seg = (hour >= 20) ? 8'h86 : // 显示"2"
                      (hour >= 10) ? 8'hc0 :  // 显示"1"
                      8'hff;                 // 不显示
        // 小时个位
        4'b1101: seg = bcd_to_seg(hour % 10);
        // 分钟十位
        4'b1011: seg = bcd_to_seg(min / 10);
        // 分钟个位
        4'b0111: seg = bcd_to_seg(min % 10);
        default: seg = 8'hff;
    endcase
end

// BCD转换函数
function [7:0] bcd_to_seg;
    input [3:0] num;
    begin
        case(num)
            0: bcd_to_seg = 8'hc0; // 0
            1: bcd_to_seg = 8'hf9; // 1
            2: bcd_to_seg = 8'ha4; // 2
            3: bcd_to_seg = 8'hb0; // 3
            4: bcd_to_seg = 8'h99; // 4
            5: bcd_to_seg = 8'h92; // 5
            6: bcd_to_seg = 8'h82; // 6
            7: bcd_to_seg = 8'hf8; // 7
            8: bcd_to_seg = 8'h80; // 8
            9: bcd_to_seg = 8'h90; // 9
            default: bcd_to_seg = 8'hff;
        endcase
    end
endfunction

endmodule

关键设计说明:

  1. 时钟分频

    • 使用计数器生成1Hz基准时钟(精确计时需要校准)
    • 生成1kHz扫描时钟用于动态显示
    • 2Hz信号用于控制闪烁频率
  2. 时间计数器

    • 秒计数器(0-59)
    • 分计数器(0-59)
    • 时计数器(0-23)
    • 自动进位逻辑
  3. 动态扫描

    • 4位数码管显示(时十位、时个位、分十位、分个位)
    • 位选信号循环扫描(1kHz频率)
  4. 整点闪烁

    • 检测每分钟的0秒时刻(min==0 && sec<10
    • 使用2Hz信号控制显示开关(亮灭各0.25秒)
    • 闪烁期间段选信号强制为全灭(8'hff
  5. 显示处理

    • 小时十位智能显示(>=20显示2,>=10显示1)
    • BCD转七段码译码器
    • 冒号处理(示例代码未包含,可通过dp点扩展)

扩展建议:

  1. 精确计时

    // 校准50MHz到精确1Hz(需根据实际时钟频率修改)
    parameter DIV_1HZ = 50_000_000; // 50MHz时钟
    reg [25:0] cnt_1hz;

    always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
    cnt_1hz <= 0;
    clk_1hz <= 0;
    end else if(cnt_1hz == DIV_1HZ-1) begin
    cnt_1hz <= 0;
    clk_1hz <= ~clk_1hz;
    end else begin
    cnt_1hz <= cnt_1hz + 1;
    end
    end

  2. 添加设置功能

  • 增加按键输入接口
  • 实现时间调整模式
  • 长按/短按区分设置
  1. 声音提示

    // 整点报时模块示例
    reg buzzer;
    always @(posedge clk_1hz) begin
    buzzer <= (sec == 0) && (min == 0) && (hour < 23);
    end

  2. 显示优化

  • 添加冒号闪烁(每秒一次)
  • 低电量指示
  • 12/24小时制切换

该设计需要配合硬件开发板(如FPGA)上的数码管电路实现,实际使用时需根据具体硬件调整位选和段选的极性(共阴/共阳)。

相关推荐
JNTeresa6 小时前
锁存器知识点详解
fpga开发
Cao1234567893219 小时前
FPGA基础之基础语法
fpga开发
一大Cpp9 小时前
通过Quartus II实现Nios II编程
fpga开发
7yewh10 小时前
Verilog 语法 (二)
fpga开发
边缘计算社区1 天前
FPGA与边缘AI:计算革命的前沿力量
人工智能·fpga开发
S&Z34631 天前
[官方IP] Shift RAM
网络协议·tcp/ip·fpga开发
S&Z34631 天前
[FPGA Video IP] Video Processing Subsystem
网络协议·tcp/ip·fpga开发·video
FPGA_Linuxer1 天前
FPGA 100G UDP纯逻辑协议栈
网络协议·fpga开发·udp
Terasic友晶科技2 天前
第13篇:Linux程序访问控制FPGA端Switch<二>
fpga开发·嵌入式系统·de1-soc开发板