FPGA 23 ,使用 Vivado 实现花式跑马灯( 使用 Vivado 实现花式流水灯,采用模块化编程,从按键消抖到LED控制 )
目录
前言
一. 模块化设计介绍
二. 模块设计
1. 按键消抖模块 (key.v)
模块功能:
注意事项:
2. LED控制模块 (led.v)
模块功能:
注意事项:
3. 模块工作流程
三. 模块化设计优势
四. 本文总结
五. 更多操作
前言
在FPGA开发中,跑马灯和流水灯是最基础且常见的实验项目之一。通过跑马灯和流水灯的设计,我们可以熟悉FPGA的基本开发流程、Verilog语言的使用以及模块化编程的思想。之前介绍过基本的跑马灯和流水灯的实现,这里将详细介绍如何使用Verilog语言,实现一个花式跑马灯和流水灯的设计,并通过模块化编程的方式,将按键消抖模块与LED控制模块分离,提升代码的可读性和可维护性(流水灯就是跑马灯)。
先看下使用模块化实现的花式跑马灯效果,当按下K2按键时,LED灯从右向左依此亮起,再次按下时LED灯从左向右依此亮起:
一. 模块化设计介绍
模块化设计是FPGA开发中非常重要的思想。通过将系统功能划分为多个独立的模块,每个模块负责完成特定的功能,可以显著提高代码的可读性、可维护性和可复用性。在本项目中,我们采用了模块化设计,将系统分为以下两个主要模块:
按键消抖模块 (
key.v
):负责检测按键的稳定状态,消除机械按键的抖动问题。LED控制模块 (
led.v
):负责根据按键状态切换LED的显示模式,实现跑马灯和流水灯效果。
通过模块化设计,我们可以将复杂的功能分解为简单的子模块,每个子模块独立开发、测试和优化,最后通过模块例化的方式将各个子模块组合成一个完整的系统。
二. 模块设计
1. 按键消抖模块 (key.v
)
按键消抖模块用于检测按键的稳定状态。由于机械按键在按下和释放时会产生抖动,直接读取按键状态可能会导致误触发。因此,按键消抖模块通过延时计数的方式,确保按键状态稳定后再输出。
module key(
input clk, // 时钟信号
input rst_n, // 复位信号,低电平有效
input key, // 按键输入信号
output flag // 按键稳定状态标志,1表示按键稳定按下
);
parameter delay = 50_000; // 消抖延时计数,根据时钟频率调整
reg [18:0] cnt; // 计数器,用于延时
always @(posedge clk) begin
if (!rst_n) // 复位时计数器清零
cnt <= 0;
else if (key == 0) begin // 按键按下时开始计数
if (cnt == delay - 1)
cnt <= cnt; // 计数达到最大值时保持
else
cnt <= cnt + 1; // 计数加1
end else
cnt <= 0; // 按键释放时计数器清零
end
assign flag = (cnt == delay - 2) ? 1 : 0; // 当计数接近最大值时,输出稳定标志
endmodule
该模块(key.v
)旨在解决机械按键的抖动问题,确保按键信号的稳定性。它通过一个计数器检测按键是否稳定按下一段时间(如1毫秒),从而输出一个稳定的标志位 flag
表示按键已被有效触发。此模块接收系统时钟 clk
、复位信号 rst_n
和按键输入 key
,为后续逻辑提供可靠的按键状态。
模块功能:
-
检测按键的稳定状态,消除抖动。
-
输出
flag
信号,表示按键是否稳定按下。
注意事项:
-
delay
参数需要根据实际的时钟频率进行调整,以确保消抖时间足够长。 -
按键消抖模块的输出
flag
在按键稳定按下时为1,否则为0。
2. LED控制模块 (led.v
)
LED控制模块负责根据按键的状态切换LED的显示模式。模块内部包含两个状态机,分别控制跑马灯和流水灯的显示效果。
module led(
input sysclk, // 系统时钟
input sys_rst_n, // 系统复位信号,低电平有效
input key, // 按键输入信号
output reg [3:0] led // LED输出信号,控制4个LED
);
parameter delay = 50_000_000; // LED状态切换延时计数
reg [27:0] cnt; // 计数器,用于延时
wire flag; // 按键稳定状态标志
reg [3:0] led_0001; // 跑马灯模式下的LED状态
reg [3:0] led_1000; // 流水灯模式下的LED状态
// 延时计数器
always @(posedge sysclk) begin
if (!sys_rst_n)
cnt <= 0;
else if (cnt == delay - 1)
cnt <= 0;
else
cnt <= cnt + 1;
end
// 跑马灯模式下的LED状态切换
always @(posedge sysclk) begin
if (!sys_rst_n)
led_0001 <= 4'b0001; // 初始状态为0001
else if (cnt == delay - 1)
led_0001 <= {led_0001[2:0], led_0001[3]}; // 循环左移
else
led_0001 <= led_0001;
end
// 流水灯模式下的LED状态切换
always @(posedge sysclk) begin
if (!sys_rst_n)
led_1000 <= 4'b1000; // 初始状态为1000
else if (cnt == delay - 1)
led_1000 <= {led_1000[0], led_1000[3:1]}; // 循环右移
else
led_1000 <= led_1000;
end
// 状态机定义
parameter IDLE = 3'b001, // 空闲状态
s0 = 3'b010, // 跑马灯模式
s1 = 3'b100; // 流水灯模式
reg [2:0] cur_state; // 当前状态
reg [2:0] next_state; // 下一个状态
// 状态转移
always @(posedge sysclk) begin
if (!sys_rst_n)
cur_state <= IDLE;
else
cur_state <= next_state;
end
// 状态机逻辑
always @(*) begin
case (cur_state)
IDLE: begin
if (flag == 1)
next_state = s0; // 按键按下,切换到跑马灯模式
else
next_state = IDLE;
end
s0: begin
if (flag == 1)
next_state = s1; // 按键按下,切换到流水灯模式
else
next_state = s0;
end
s1: begin
if (flag == 1)
next_state = IDLE; // 按键按下,切换到空闲状态
else
next_state = s1;
end
default: next_state = IDLE;
endcase
end
// LED输出控制
always @(*) begin
if (!sys_rst_n)
led = 4'b0000; // 复位时LED全灭
else case (cur_state)
IDLE: led = 4'b0000; // 空闲状态,LED全灭
s0: led = led_0001; // 跑马灯模式
s1: led = led_1000; // 流水灯模式
default: led = 4'b0000;
endcase
end
// 按键消抖模块例化
key key_u(
.clk(sysclk),
.rst_n(sys_rst_n),
.key(key),
.flag(flag)
);
endmodule
该模块(led.v
)负责生成动态的LED显示效果,例如跑马灯和流水灯。它根据来自 key.v
的按键有效信号 flag
来切换四个LED的不同显示模式。该模块包含延时计数器和状态机,用于管理LED模式之间的转换,提供视觉反馈给用户,并确保显示效果的流畅性和准确性。
模块功能:
-
根据按键状态切换LED显示模式。
-
实现跑马灯和流水灯效果。
注意事项:
-
delay
参数需要根据实际的时钟频率进行调整,以确保LED状态切换的速度合适。 -
状态机的设计使得系统能够在跑马灯模式和流水灯模式之间切换,按键每次按下都会切换到下一个模式。
3. 模块工作流程
复位状态:系统上电或复位时,LED全灭,状态机处于
IDLE
状态。按键检测:按键消抖模块检测按键的稳定状态,输出
flag
信号。状态切换:根据
flag
信号,状态机在IDLE
、s0
(跑马灯模式)和s1
(流水灯模式)之间切换。LED显示:根据当前状态,LED显示跑马灯或流水灯效果。
三. 模块化设计优势
代码复用性:模块化设计使得每个模块可以独立开发和测试,并且可以在其他项目中复用。例如,按键消抖模块可以用于其他需要按键输入的项目。
可维护性:将系统功能划分为多个模块后,每个模块的功能清晰明确,便于后续的维护和升级。
可读性:模块化设计使得代码结构清晰,便于理解和调试。
并行开发:多个开发者可以同时开发不同的模块,提高开发效率。
四. 本文总结
通过简单的项目模块设计与实现,我们掌握了如何使用Verilog语言进行FPGA开发,并通过模块化编程的方式将按键消抖模块与LED控制模块分离。这种设计方式不仅提高了代码的可读性和可维护性,还为后续更复杂的FPGA项目开发奠定了基础。希望本文对你理解FPGA开发、Verilog编程以及模块化设计有所帮助。
五. 更多操作
基本的跑马灯实现,请看
FPGA 18 ,使用 Xilinx Vivado 实现跑马灯和流水灯https://blog.csdn.net/weixin_65793170/article/details/144018031?ops_request_misc=%257B%2522request%255Fid%2522%253A%25222c89a542394575afd4e7c0f6a3b41aa7%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=2c89a542394575afd4e7c0f6a3b41aa7&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144018031-null-null.nonecase&utm_term=%E8%B7%91%E9%A9%AC%E7%81%AF&spm=1018.2226.3001.4450https://blog.csdn.net/weixin_65793170/article/details/144018031?ops_request_misc=%257B%2522request%255Fid%2522%253A%25222c89a542394575afd4e7c0f6a3b41aa7%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=2c89a542394575afd4e7c0f6a3b41aa7&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144018031-null-null.nonecase&utm_term=%E8%B7%91%E9%A9%AC%E7%81%AF&spm=1018.2226.3001.4450https://blog.csdn.net/weixin_65793170/article/details/144018031?ops_request_misc=%257B%2522request%255Fid%2522%253A%25222c89a542394575afd4e7c0f6a3b41aa7%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=2c89a542394575afd4e7c0f6a3b41aa7&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144018031-null-null.nonecase&utm_term=%E8%B7%91%E9%A9%AC%E7%81%AF&spm=1018.2226.3001.4450https://blog.csdn.net/weixin_65793170/article/details/144018031?ops_request_misc=%257B%2522request%255Fid%2522%253A%25222c89a542394575afd4e7c0f6a3b41aa7%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=2c89a542394575afd4e7c0f6a3b41aa7&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144018031-null-null.nonecase&utm_term=%E8%B7%91%E9%A9%AC%E7%81%AF&spm=1018.2226.3001.4450https://blog.csdn.net/weixin_65793170/article/details/144018031?ops_request_misc=%257B%2522request%255Fid%2522%253A%25222c89a542394575afd4e7c0f6a3b41aa7%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=2c89a542394575afd4e7c0f6a3b41aa7&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144018031-null-null.nonecase&utm_term=%E8%B7%91%E9%A9%AC%E7%81%AF&spm=1018.2226.3001.4450https://blog.csdn.net/weixin_65793170/article/details/144018031?ops_request_misc=%257B%2522request%255Fid%2522%253A%25222c89a542394575afd4e7c0f6a3b41aa7%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=2c89a542394575afd4e7c0f6a3b41aa7&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144018031-null-null.nonecase&utm_term=%E8%B7%91%E9%A9%AC%E7%81%AF&spm=1018.2226.3001.4450基本的状态机和按键消抖的实现,请看
FPGA 22 ,基于状态机的按键消抖设计与实现https://blog.csdn.net/weixin_65793170/article/details/144378347?ops_request_misc=%257B%2522request%255Fid%2522%253A%25226d70fbf082f7f2ad78171a71effd1edf%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=6d70fbf082f7f2ad78171a71effd1edf&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144378347-null-null.nonecase&utm_term=%E7%8A%B6%E6%80%81%E6%9C%BA&spm=1018.2226.3001.4450https://blog.csdn.net/weixin_65793170/article/details/144378347?ops_request_misc=%257B%2522request%255Fid%2522%253A%25226d70fbf082f7f2ad78171a71effd1edf%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=6d70fbf082f7f2ad78171a71effd1edf&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144378347-null-null.nonecase&utm_term=%E7%8A%B6%E6%80%81%E6%9C%BA&spm=1018.2226.3001.4450https://blog.csdn.net/weixin_65793170/article/details/144378347?ops_request_misc=%257B%2522request%255Fid%2522%253A%25226d70fbf082f7f2ad78171a71effd1edf%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=6d70fbf082f7f2ad78171a71effd1edf&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144378347-null-null.nonecase&utm_term=%E7%8A%B6%E6%80%81%E6%9C%BA&spm=1018.2226.3001.4450https://blog.csdn.net/weixin_65793170/article/details/144378347?ops_request_misc=%257B%2522request%255Fid%2522%253A%25226d70fbf082f7f2ad78171a71effd1edf%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=6d70fbf082f7f2ad78171a71effd1edf&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144378347-null-null.nonecase&utm_term=%E7%8A%B6%E6%80%81%E6%9C%BA&spm=1018.2226.3001.4450https://blog.csdn.net/weixin_65793170/article/details/144378347?ops_request_misc=%257B%2522request%255Fid%2522%253A%25226d70fbf082f7f2ad78171a71effd1edf%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=6d70fbf082f7f2ad78171a71effd1edf&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144378347-null-null.nonecase&utm_term=%E7%8A%B6%E6%80%81%E6%9C%BA&spm=1018.2226.3001.4450https://blog.csdn.net/weixin_65793170/article/details/144378347?ops_request_misc=%257B%2522request%255Fid%2522%253A%25226d70fbf082f7f2ad78171a71effd1edf%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=6d70fbf082f7f2ad78171a71effd1edf&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-144378347-null-null.nonecase&utm_term=%E7%8A%B6%E6%80%81%E6%9C%BA&spm=1018.2226.3001.4450完整FPGA系列,请看
FPGA系列,文章目录https://blog.csdn.net/weixin_65793170/article/details/144185217?spm=1001.2014.3001.5501https://blog.csdn.net/weixin_65793170/article/details/144185217?spm=1001.2014.3001.5501https://blog.csdn.net/weixin_65793170/article/details/144185217?spm=1001.2014.3001.5501https://blog.csdn.net/weixin_65793170/article/details/144185217?spm=1001.2014.3001.5501https://blog.csdn.net/weixin_65793170/article/details/144185217?spm=1001.2014.3001.5501https://blog.csdn.net/weixin_65793170/article/details/144185217?spm=1001.2014.3001.5501https://blog.csdn.net/weixin_65793170/article/details/144185217?spm=1001.2014.3001.5501