名称秒表计时器 FPGA 设计 Verilog Vivado软件Vivado语言Verilog功能介绍本设计实现一个 FPGA 秒表计时器核心功能包括启动计时、暂停保持和复位清零。计时精度以 10ms 为单位输出包含 10毫秒、秒、分三组 BCD 风格计数数据适合用于 FPGA 入门计时器、数码管显示控制、按键状态机控制等实验场景。 秒表控制通过 start_key 与 reset_key 两个按键信号完成。start_key 用于在空闲、计时、暂停状态之间切换reset_key 用于进入复位状态并清零计时结果。计时范围按 10ms、秒、分逐级进位10ms 计数到 99 后秒加 1秒计数到 59 后分加 1分计数到 59 后回到 0。 工程采用 Verilog 编写配套 Vivado 工程文件和 XDC 管脚约束文件便于直接查看源码结构、综合实现结果以及板级管脚分配。整体结构清晰适合作为 FPGA 秒表、数字计时显示、按键控制状态机设计的参考工程。运行环境开发语言Verilog 开发软件Vivado 工程类型FPGA 工程 主要文件stopwatch.v、Digital_clock.v、display.v、fenping.v、key_jitter.v、pins.xdc、stopwatch.xpr 顶层相关模块stopwatch、Digital_clock、display、fenping、key_jitter设计思路设计以秒表计时状态机为核心通过 idle_state、cnt_time_state、hold_time_state、reset_time_state 四个状态描述秒表的工作流程。复位按键优先级最高触发后进入复位状态并清空计时值在空闲状态下按下启动键进入计时状态计时过程中再次按下启动键进入暂停状态暂停状态下再次按下启动键恢复计时。 计时部分采用 50MHz 系统时钟驱动寄存器更新并通过 100Hz 节拍信号作为 10ms 计时使能。这样既保留了统一时钟域下的同步逻辑结构又能用低频节拍控制实际计数递增便于综合实现和时序分析。 计数逻辑分为 10毫秒、秒、分三个层级。10毫秒计数器在 0 到 99 之间循环达到 99 后回零并推动秒计数秒计数器在 0 到 59 之间循环达到 59 后回零并推动分钟计数分钟计数器同样在 0 到 59 之间循环。该结构直观体现了数字秒表的级联进位关系。 工程还包含显示、分频、按键消抖等配套模块可将核心秒表计数结果进一步用于数码管动态显示。按键消抖模块用于提升机械按键输入的稳定性分频模块用于产生计时和显示所需的节拍信号显示模块负责将计时数据转换为可显示的输出形式。模块结构stopwatch秒表核心计时模块完成启动、暂停、复位状态控制以及 10毫秒、秒、分计数。 Digital_clock工程顶层相关模块用于组织秒表、显示、分频和按键处理等功能单元。 display显示控制模块用于计时数据的显示驱动。 fenping分频模块用于产生低频计时或扫描节拍。 key_jitter按键消抖模块用于处理启动、复位等机械按键信号。开发板验证工程包含 Vivado XDC 管脚约束文件 pins.xdc并已给出实现流程相关文件可用于 FPGA 开发板管脚分配和上板验证。约束文件为时钟、按键和显示相关信号提供了板级连接依据适合在对应硬件环境中进行下载测试与功能观察。部分代码以下展示顶层模块stopwatch的部分代码完整代码可关注下方公众号卡片获取。module stopwatch( input clk_50M, input clk_100Hz,//100Hz--对应10ms input start_key,//启动//暂停 input reset_key,//复位 output [7:0] stopwatch_Millisecond,//10毫秒 output [7:0] stopwatch_second,//秒 output [7:0] stopwatch_minute//分 ); parameter idle_state3d0; parameter cnt_time_state3d1; parameter hold_time_state3d2; parameter reset_time_state3d3; reg [2:0] state3d0; //计时状态机 always(posedge clk_50M) if(reset_key) statereset_time_state;//复位状态 else case(state) reset_time_state://复位状态 stateidle_state; idle_state://空闲状态 if(start_key) statecnt_time_state; else stateidle_state; cnt_time_state://计时状态 if(start_key) statehold_time_state; else statecnt_time_state; hold_time_state://暂停状态 if(start_key) statecnt_time_state; else statehold_time_state; default:; endcase reg [7:0] Millisecond_cnt8d0;//10毫秒 reg [7:0] second_cnt8d0;//秒 reg [7:0] minute_cnt8d0;//分 always(posedge clk_50M) if(statereset_time_state)//复位状态 minute_cnt8d0; else if(statecnt_time_state clk_100Hz1)//计时状态 if(Millisecond_cnt8d99 second_cnt8d59)//59秒99时向前记1分 if(minute_cnt8d59) minute_cntminute_cnt8d1;//计时到990ms下一次就到1秒了 else minute_cnt8d0; else minute_cntminute_cnt; else; always(posedge clk_50M) if(statereset_time_state)//复位状态 second_cnt8d0; else if(statecnt_time_state clk_100Hz1)//计时状态 if(Millisecond_cnt8d99)//990ms时向前记1秒 if(second_cnt8d59) second_cntsecond_cnt8d1;//计时到990ms下一次就到1秒了 else second_cnt8d0; else second_cntsecond_cnt; else; always(posedge clk_50M) if(statereset_time_state)//复位状态 Millisecond_cnt8d0; else if(statecnt_time_state clk_100Hz1)//计时状态 if(Millisecond_cnt8d99)//计时到990ms下一次就到1秒了 Millisecond_cntMillisecond_cnt8d1; else Millisecond_cnt8d0;//计时到990ms下一次就到1秒了 else; assign stopwatch_MillisecondMillisecond_cnt; assign stopwatch_secondsecond_cnt; assign stopwatch_minuteminute_cnt; endmodule代码获取点击下方公众号卡片