FPGA学习二实现LED流水灯
FPGA学习(二)——实现LED流水灯
FPGA学习(二)——实现LED流水灯
一、DE2-115时钟源
DE2-115板子包含一个50MHz的石英
,通过一个时钟缓冲器产生3路抖动低的50MHz时钟信号送到FPGA的时钟输入引脚,如下图所示:
因此可以计算出,时钟信号的周期
T=1/(50*10^6)=20ns
,1s=10^9ns
,则1秒所需的时钟周期数为N=10^9/20=50000000
所以cnt计数器从0计数到50000000-1
时,表示1秒。
二、控制6个LED灯实现流水灯
1、核心逻辑
- 时钟和复位信号的处理
- 代码通过
always
块监听时钟信号clk
的上升沿、复位信号rst_n
的下降沿以及停止信号stop_n
的下降沿。 - 当复位信号
rst_n
为低电平时,计数器cnt
被重置为0,并且LED灯的状态被设置为6'b000001
,即第一个LED亮起 - 按键停止信号的处理
- 当按键停止信号
stop_n
为低电平时,计数器cnt
和LED灯的状态led
保持不变,即停止计数和LED状态的变化。 - 计数器的计数逻辑
- 如果复位信号和停止信号都无效(即
rst_n
和stop_n
都为高电平),计数器cnt
开始计数。 - 当计数器
cnt
达到50_000_000 - 1
时(即1秒的时钟周期,时钟频率为50MHz),计数器cnt
被重置为0,并且LED灯的状态led
进行循环右移一位,实现流水灯效果。
2、代码实现
module LedBlink( input wire clk, // 50MHz时钟输入 input wire rst_n, // 复位信号,低电平有效 input wire stop_n, //停止信号 output reg [5:0] led // 6个LED灯输出 ); reg [25:0] cnt; // 26位计数器,用于计数1秒周期 // 计数器模块 always @(posedge clk or negedge rst_n or negedge stop_n) begin // posedge是指clk的上升沿 negedge是指rst_n的下降沿 if (!rst_n) begin cnt <= 26’d0; // 复位时,计数器从0开始计数 led <= 6’b000001; // 复位时,第一个LED亮 end else if (!stop_n) begin cnt <= cnt; led <= led; end else if (cnt == 50_000_000 - 1) begin // 计数到50,000,000 - 1 cnt <= 26’d0; // 重置计数器 led <= {led[4:0], led[5]}; // 循环右移一位,保持流水灯效果 end else begin cnt <= cnt + 1; // 增加计数器 end end endmodule
3、引脚配置
4、实现效果
FPGA流水灯
三、模块化代码
1、分频模块
module clock( input wire clk, // 50MHz时钟输入 input wire rst_n, // 复位信号,低电平有效 output reg clk_1Hz // 1Hz分频时钟输出 ); reg [25:0] cnt; // 26位计数器,用于计数1秒周期 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin cnt <= 26’d0; // 复位时,计数器清零 clk_1Hz <= 1’b0; // 复位时,1Hz时钟信号置低 end else if (cnt == 50_000_000 - 1) begin // 计数到50,000,000 - 1 cnt <= 26’d0; // 重置计数器 clk_1Hz <= ~clk_1Hz; // 翻转1Hz时钟信号 end else begin cnt <= cnt + 1; // 计数器递增 end end endmodule
2、复位暂停模块
module control( input wire clk_1Hz, // 1Hz时钟输入 input wire rst_n, // 复位信号,低电平有效 input wire stop_n, // 停止信号,低电平有效 output reg [5:0] led // 6个LED灯输出 ); always @(posedge clk_1Hz or negedge rst_n or negedge stop_n) begin if (!rst_n) begin led <= 6’b000001; // 复位时,第一个LED亮 end else if (!stop_n) begin led <= led; // 停止时,LED状态保持不变 end else begin led <= {led[4:0], led[5]}; // 循环右移一位,实现流水灯效果 end end endmodule
3、顶层模块
module led( input wire clk, // 50MHz时钟输入 input wire rst_n, // 复位信号,低电平有效 input wire stop_n, // 停止信号,低电平有效 output wire [5:0] led // 6个LED灯输出 ); wire clk_1Hz; // 1Hz时钟信号 // 实例化时钟模块 clock u_clock( .clk(clk), .rst_n(rst_n), .clk_1Hz(clk_1Hz) ); // 实例化控制模块 control u_control( .clk_1Hz(clk_1Hz), .rst_n(rst_n), .stop_n(stop_n), .led(led) ); endmodule
四、总结
本次实验的核心目的在于通过实践操作,熟悉FPGA的开发流程,并通过编写Verilog代码来实现FPGA的流水灯效果,以此来练习和巩固Verilog编程的相关知识。实验关键点在于时钟和复位信号的处理: 理解时钟信号在数字设计中的重要性,以及如何使用复位信号来初始化和同步系统状态。计数器的设计: 学习如何利用计数器产生定时信号,以实现LED灯的顺序点亮。 ,并通过编写Verilog代码来实现FPGA的流水灯效果,以此来练习和巩固Verilog编程的相关知识。实验关键点在于时钟和复位信号的处理: 理解时钟信号在数字设计中的重要性,以及如何使用复位信号来初始化和同步系统状态。计数器的设计: 学习如何利用计数器产生定时信号,以实现LED灯的顺序点亮。