名称:数字时钟 FPGA 设计 Verilog Vivado(2)
软件:Vivado
语言:Verilog
开发板/平台:Basys 3
功能介绍
本设计实现了一个基于 FPGA 的数字时钟系统,使用 Verilog 语言在 Vivado 环境下完成工程开发。系统以 100MHz 时钟作为输入,通过分频模块产生 1Hz 计时节拍,用于驱动时、分、秒的递增计数,并将当前时间输出到八位数码管显示接口。
数字时钟支持基本的时间显示与按键设置功能。BTNL 用于进入或触发设置时间,BTNR 用于确认设置,BTNU 用于切换设置的时、分、秒位置。按键输入经过消抖处理后再送入计时控制模块,减少机械按键抖动对时间设置逻辑的影响。
显示部分通过数码管位选 bit_select 和段选 lednum_select 输出当前的小时、分钟和秒钟信息,适合用于 FPGA 课程设计、数字逻辑综合实验、Basys 3 开发板数码管显示实验等场景。工程结构清晰,顶层模块完成按键、分频、计时和显示模块的连接,便于学习和二次修改。
运行环境
开发语言:Verilog
开发软件:Vivado
适配开发板:Basys 3
工程包含 Vivado 项目文件、Verilog 源码文件、Basys 3 管脚约束文件以及实现生成的 bit 文件,可用于综合、实现和开发板下载验证。
设计思路
系统采用模块化设计思路,将数字时钟拆分为顶层连接、时钟分频、按键消抖、计时控制和数码管显示几个部分。顶层 digital_clock 模块负责接收 100MHz 系统时钟和三个按键输入,并将各子模块的信号连接起来,最终输出数码管位选和段选控制信号。
分频模块 fenping 将板载 100MHz 时钟转换为 1Hz 时钟节拍,使计时模块能够按秒递增。计时模块 jishi 根据 1Hz 节拍维护 hour_time、minute_time、second_time 三组时间数据,同时响应设置、确认和切换按键,实现对时、分、秒的设置控制。
按键处理部分使用 key_jitter 模块对 BTNL、BTNR、BTNU 三个按键分别进行消抖,并提取消抖后的下降沿作为有效控制脉冲。这样可以避免按键抖动造成一次按压被识别为多次触发,提高时间设置过程的稳定性。
显示模块 display_num 接收时、分、秒数据,完成数码管动态扫描显示控制。该设计将计时逻辑与显示逻辑分开,顶层只负责模块例化和信号连接,结构直观,适合用于理解 FPGA 数字时钟设计中的分频、按键处理、状态控制和数码管显示流程。
模块结构
主要模块包括:
1. digital_clock:顶层模块,连接 100MHz 时钟、三个按键输入、分频模块、计时模块和数码管显示模块。
2. fenping:时钟分频模块,将 clk_100M 分频得到 clk_1Hz,为秒计时提供基准节拍。
3. key_jitter:按键消抖模块,对设置时间、确认、切换时分秒三个按键分别进行消抖处理。
4. jishi:计时与时间设置模块,输出 hour_time、minute_time、second_time。
5. display_num:数码管显示模块,输出 bit_select 和 lednum_select,用于显示当前时分秒。
开发板验证
工程面向 Basys 3 开发板设计,包含对应的 Vivado 管脚约束文件 pins_basys3.xdc,并生成了实现相关结果与 bit 文件。按键输入对应 BTNL、BTNR、BTNU,显示输出连接到开发板数码管位选和段选接口,可用于在 Basys 3 上进行数字时钟显示和按键设置验证。
部分代码
以下展示顶层模块 Name 的部分代码,完整源码请下载压缩包查看。
Module Name: digital_clock
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module digital_clock(
input clk_100M,
input BTNL,//设置时间
input BTNR,//确认
input BTNU,//设置时分秒
output [7:0] bit_select,
output [7:0] lednum_select
);
wire set_time_key;//设置时间
wire confirm_key;//确认
wire change_time_key;//设置时分秒
wire clk_1Hz;
wire [7:0] hour_time;//时
wire [7:0] minute_time;//分
wire [7:0] second_time;//秒
key_jitter key_set_time_key(
. clkin(clk_100M),
. key_in(BTNL),//输入
. key_posedge(),//消抖后按键上升沿
. key_negedge(set_time_key),//消抖后按键下降沿
. key_value()//消抖后按键
);
key_jitter key_confirm_key(
. clkin(clk_100M),
. key_in(BTNR),//输入
. key_posedge(),//消抖后按键上升沿
. key_negedge(confirm_key),//消抖后按键下降沿
. key_value()//消抖后按键
);
key_jitter key_change_time_key(
. clkin(clk_100M),
. key_in(BTNU),//输入
. key_posedge(),//消抖后按键上升沿
. key_negedge(change_time_key),//消抖后按键下降沿
. key_value()//消抖后按键
);
fenping i_fenping(
. clk_100M(clk_100M),
. clk_1Hz(clk_1Hz)
);
jishi i_jishi(
. clk_100M(clk_100M),
. clk_1Hz(clk_1Hz),
. set_time_key(set_time_key),//设置时间
. confirm_key(confirm_key),//确认
. change_time_key(change_time_key),//设置时分秒
. hour_time(hour_time),//时
. minute_time(minute_time),//分
. second_time(second_time)//秒
);
display_num i_display_num(
. clk(clk_100M),
. hour_time(hour_time),//时
. minute_time(minute_time),//分
. second_time(second_time),//秒
. bit_select(bit_select),
. lednum_select(lednum_select)
);
endmodule
218