用Verilog在AX530开发板上实现一个带闹钟和整点报时的数字钟(附完整代码与Quartus II 13.0工程)
2026/4/22 4:26:45 网站建设 项目流程

基于AX530开发板的Verilog数字钟实战:从模块化设计到整点报时

在FPGA开发领域,数字钟项目堪称"Hello World"般的存在,但真正要实现一个功能完善、稳定可靠的数字钟系统,却需要开发者对数字逻辑设计有深入理解。本文将手把手带你用Verilog HDL在AX530开发板上构建一个具备闹钟和整点报时功能的数字钟系统,从Quartus II 13.0工程创建到最终下载调试,完整呈现项目开发全流程。

1. 项目规划与硬件准备

AX530开发板作为一款性价比较高的FPGA学习平台,搭载了Cyclone IV EP4CE6F17C8芯片,板载资源包括:

  • 6位共阳数码管
  • 4个独立按键
  • 多个LED指示灯
  • 50MHz系统时钟

核心功能需求分析

  • 24小时制时间显示(时:分:秒)
  • 按键校时功能(时/分可调)
  • 闹钟设置与触发(LED指示)
  • 整点报时功能(LED闪烁对应次数)
  • 系统复位功能(归零)

硬件连接方案:

功能模块FPGA引脚开发板资源
数码管段选PIN_XXSMG_A~H
数码管位选PIN_XXDIG1~DIG6
按键输入PIN_XXKEY1~KEY3
LED输出PIN_XXLED1~LED3

2. 系统架构设计与模块划分

采用自顶向下的设计方法,将系统分解为多个功能模块,通过顶层模块实现互联。这种模块化设计不仅便于调试,也符合工业级FPGA开发规范。

2.1 顶层模块设计

顶层模块digclk.v主要实现各子模块的信号连接:

module Digclk( input clk, // 50MHz系统时钟 input rst_n, // 复位信号(低有效) input [2:0] btn, // 按键输入[切换,移位,加一] output [3:0] led, // LED输出[秒针,闹钟,整点] output [7:0] smg_sig, // 数码管段选 output [5:0] smg_loc // 数码管位选 ); // 状态控制信号线 wire [1:0] mode; // 工作模式 wire [3:0] set_loc; // 设置位置 wire set_inc; // 加一信号 // 实例化各子模块 Ctrl u_ctrl(...); Time u_time(...); Alarm u_alarm(...); Display u_display(...); endmodule

2.2 关键子模块功能说明

  1. 状态控制模块(Ctrl)

    • 处理按键输入(消抖后)
    • 生成当前工作模式信号
    • 输出校时位置和加一脉冲
  2. 计时模块(Time)

    • 实现时分秒计数器
    • 处理校时逻辑
    • 生成秒脉冲和整点报时信号
  3. 闹钟模块(Alarm)

    • 存储闹钟设置时间
    • 比较当前时间与闹钟时间
    • 触发闹钟信号
  4. 显示模块(Display)

    • 根据模式选择显示内容
    • 驱动数码管显示

3. 核心代码实现与技巧

3.1 按键消抖模块优化

机械按键存在10-20ms的抖动期,采用状态机实现的消抖模块更可靠:

module Filter( input clk, input rst_n, input btn, output reg btn_f ); parameter IDLE = 2'b00; parameter DEBOUNCE = 2'b01; parameter PRESS = 2'b10; reg [19:0] cnt; // 20ms计数器 reg [1:0] state; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin state <= IDLE; btn_f <= 1'b0; end else begin case(state) IDLE: if(!btn) begin state <= DEBOUNCE; cnt <= 0; end DEBOUNCE: if(cnt == 20'd999_999) begin // 20ms@50MHz state <= PRESS; btn_f <= 1'b1; end else begin cnt <= cnt + 1; if(btn) state <= IDLE; end PRESS: if(btn) begin state <= IDLE; btn_f <= 1'b0; end endcase end end endmodule

3.2 计时模块的BCD计数器实现

采用BCD码计数器可简化数码管显示逻辑:

// 秒个位计数器示例 reg [3:0] cnt_s0; always @(posedge clk or negedge rst_n) begin if(!rst_n) cnt_s0 <= 4'd0; else if(en_s0) cnt_s0 <= (cnt_s0 == 4'd9) ? 4'd0 : cnt_s0 + 1; end // 产生秒十位使能信号 assign en_s1 = (cnt_s0 == 4'd9) && en_s0;

3.3 整点报时功能实现

整点报时需要两个关键技术点:

  1. 整点检测:当分为59且秒为59时准备触发
  2. 闪烁控制:使用计数器控制LED闪烁次数
// 整点检测逻辑 wire hour_strike = (cnt_h1*10 + cnt_h0 != 0) && (cnt_m1 == 4'd5) && (cnt_m0 == 4'd9) && (cnt_s1 == 4'd5) && (cnt_s0 == 4'd9); // 闪烁控制计数器 reg [5:0] strike_cnt; always @(posedge clk or negedge rst_n) begin if(!rst_n) strike_cnt <= 6'd0; else if(hour_strike) strike_cnt <= 6'd0; else if(strike_cnt < (cnt_h1*10 + cnt_h0)*2) strike_cnt <= strike_cnt + 1; end // LED控制 assign hour_led = (strike_cnt < (cnt_h1*10 + cnt_h0)*2) ? strike_cnt[0] : 1'b0;

4. Quartus II工程配置与下载调试

4.1 工程创建关键步骤

  1. 新建工程

    • 选择Cyclone IV E系列
    • 指定器件型号EP4CE6F17C8
    • 添加所有Verilog源文件
  2. 引脚分配

    • 根据开发板原理图分配引脚
    • 保存为AX530.qsf约束文件
  3. 编译设置

    • 优化策略选择Balanced
    • 开启SignalTap II逻辑分析仪支持

4.2 常见问题解决方案

数码管显示闪烁

  • 检查扫描频率(推荐200Hz-1kHz)
  • 确保位选信号切换与数据更新同步

按键响应不灵敏

  • 调整消抖时间常数(15-20ms为宜)
  • 检查按键引脚上拉电阻配置

计时不准

  • 验证时钟分频计算
  • 使用SignalTap抓取实际计数器波形
# 示例引脚约束(部分) set_location_assignment PIN_E1 -to clk set_location_assignment PIN_M1 -to rst_n set_location_assignment PIN_E16 -to btn[0] set_location_assignment PIN_E15 -to btn[1] set_location_assignment PIN_M2 -to smg_sig[0]

5. 功能扩展与优化建议

5.1 可扩展功能方向

  1. 增加日期显示

    • 扩展计时模块支持年月日
    • 添加闰年判断逻辑
  2. 多组闹钟

    • 使用寄存器堆存储多组闹钟时间
    • 添加闹钟使能控制位
  3. 串口配置

    • 通过UART接口设置时间/闹钟
    • 实现PC端配置工具

5.2 性能优化技巧

  1. 时钟域处理

    • 对按键输入进行同步化处理
    • 添加跨时钟域同步寄存器
  2. 低功耗设计

    • 动态数码管扫描亮度调节
    • 时钟门控技术应用
  3. 代码优化

    • 参数化设计关键时间常数
    • 使用generate语句简化相似逻辑
// 参数化设计示例 parameter CLK_FREQ = 50_000_000; // 50MHz parameter SEC_DIV = CLK_FREQ - 1; // 秒脉冲生成 reg [25:0] sec_cnt; always @(posedge clk or negedge rst_n) begin if(!rst_n) sec_cnt <= 26'd0; else sec_cnt <= (sec_cnt == SEC_DIV) ? 26'd0 : sec_cnt + 1; end wire sec_pulse = (sec_cnt == SEC_DIV);

6. 项目总结与进阶思考

完成这个数字钟项目后,建议尝试以下进阶练习:

  • 将各模块改为使用状态机实现
  • 添加自动亮度调节功能(根据环境光)
  • 实现通过红外遥控器设置时间

在调试过程中发现,良好的模块划分可以显著降低调试难度。例如将显示驱动与业务逻辑分离后,当出现显示问题时可以快速定位到显示模块进行单独测试。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询