【FPGA】——实现六位流水灯

目录

一、六位流水灯

二、按键控制流水灯

总结


一、六位流水灯

代码实现分为三阶段:

  1. 复位阶段:rst_n 为低电平时,模块复位。计数器 cnt_1s 清零。LED 状态 led 初始化为 6'b000001(第一个 LED 亮,其余灭)。

  2. 正常运行阶段:rst_n 为高电平时,模块开始工作:LED 状态向左循环移位一次。当计数器达到 TIME_1s - 1 时:end_cnt_1s 信号变为 1,触发 LED 状态更新。计数器清零。计数器 cnt_1s 在每个时钟上升沿加 1。

  3. **循环流水灯效果:**LED 状态每 1 秒更新一次,依次向左移动,形成流水灯效果。

具体代码如下:

复制代码
module led (
    input  clk,        // 时钟信号
    input  rst_n,      // 复位信号(低电平有效)
    output reg[5:0] led // 6位LED输出
);

    parameter  TIME_1s = 50_000_000; // 1秒的时间常数(假设时钟频率为25MHz)

    reg    [30-1:0]    cnt_1s     ; // 30位宽的计数器
    wire   add_cnt_1s ,  end_cnt_1s ; // 计数器使能信号和结束信号

    // 计数器逻辑
    always @(posedge clk or negedge rst_n) 
        if (!rst_n)
            cnt_1s  <= 30'b0; // 复位时计数器清零
        else if (add_cnt_1s )
            if (end_cnt_1s )
                cnt_1s <=30'b0; // 计数器达到1秒时清零
            else 
                cnt_1s  <= cnt_1s  +1'd1; // 计数器加1
        else 
            cnt_1s  <= cnt_1s ; // 保持计数器值

    assign add_cnt_1s  = 1'b1; // 计数器始终使能
    assign end_cnt_1s  = add_cnt_1s  && (TIME_1s-1 == cnt_1s ); // 计数器达到1秒时结束信号为1

    // LED控制逻辑
    always @(posedge clk or negedge rst_n)
        if(!rst_n)
            led <= 6'b000001; // 复位时第一个LED亮,其余灭
        else if(end_cnt_1s)
            led <= {led[4:0], led[5]}; // 每1秒LED向左循环移位一次
        else
            led <= led; // 保持LED状态

endmodule

实现效果如下:

6位流水灯

二、按键控制流水灯

按键按下时流水灯停止移动,再次按下时恢复移动。

  1. 按键输入信号 key :按键按下时为低电平(0),松开时为高电平(1)。

  2. 暂停状态寄存器 pause :用于控制流水灯的移动。当 pause1 时,流水灯停止移动;当 pause0 时,流水灯继续移动。

  3. 按键处理逻辑 :在时钟上升沿检测按键状态,如果按键按下(key 为低电平),则切换 pause 的状态。

  4. LED控制逻辑 :在 end_cnt_1s1pause0 时,流水灯才会移动。

    module led (
    input clk, // 时钟信号
    input rst_n, // 复位信号(低电平有效)
    input key, // 按键信号(按下为低电平)
    output reg[5:0] led // 6位LED输出
    );

    复制代码
     parameter  TIME_1s = 50_000_000; // 1秒的时间常数(假设时钟频率为25MHz)
    
     reg    [30-1:0]    cnt_1s     ; // 30位宽的计数器
     wire   add_cnt_1s ,  end_cnt_1s ; // 计数器使能信号和结束信号
     reg    pause;                   // 暂停状态寄存器
    
     // 计数器逻辑
     always @(posedge clk or negedge rst_n) 
         if (!rst_n)
             cnt_1s  <= 30'b0; // 复位时计数器清零
         else if (add_cnt_1s )
             if (end_cnt_1s )
                 cnt_1s <=30'b0; // 计数器达到1秒时清零
             else 
                 cnt_1s  <= cnt_1s  +1'd1; // 计数器加1
         else 
             cnt_1s  <= cnt_1s ; // 保持计数器值
    
     assign add_cnt_1s  = 1'b1; // 计数器始终使能
     assign end_cnt_1s  = add_cnt_1s  && (TIME_1s-1 == cnt_1s ); // 计数器达到1秒时结束信号为1
    
     // 按键处理逻辑
     always @(posedge clk or negedge rst_n)
         if (!rst_n)
             pause <= 1'b0; // 复位时暂停状态为0(流水灯移动)
         else if (!key) // 按键按下(低电平有效)
             pause <= ~pause; // 切换暂停状态
    
     // LED控制逻辑
     always @(posedge clk or negedge rst_n)
         if(!rst_n)
             led <= 6'b000001; // 复位时第一个LED亮,其余灭
         else if(end_cnt_1s && !pause) // 只有在不暂停时才会移动LED
             led <= {led[4:0], led[5]}; // 每1秒LED向左循环移位一次
         else
             led <= led; // 保持LED状态

    endmodule

实现效果如下:

按键控制流水灯


总结

从简单的流水灯入手,开始逐步对verilog语言有更深入的了解。

相关推荐
坏孩子的诺亚方舟16 天前
FPGA系统架构设计实践15_高云Arora V系列时钟体系
fpga开发·系统架构
FPGA小徐16 天前
入门 CNN 结构全解析|从流程图理论到 FPGA Verilog 硬件实现(含习题带讲解)
fpga开发
FPGA小徐16 天前
FPGA 数字信号处理:并行 FIR 与串行滤波器设计原理、对比与完整 Verilog 实现
fpga开发
Saniffer_SH17 天前
【高清视频】Gen6 服务器还没到,Gen6 SSD 怎么测?Emily 现场演示三种测试环境
人工智能·驱动开发·测试工具·缓存·fpga开发·计算机外设·压力测试
zlinear数据采集卡17 天前
双核架构深度解析:ARM+FPGA如何让数据采集卡实现500Ksps高性能?
arm开发·fpga开发·架构
9527华安17 天前
FPGA实现GTH Transceivers Wizard传输2路视频,基于aurora 8b10b编解码架构,提供4套工程源码和技术支持
fpga开发·gth·aurora 8b10b·transceivers
FPGA小徐18 天前
FPGA 数字信号处理(二):并行 FIR 滤波器的 Verilog 全流程设计与实现
fpga开发
国科安芯18 天前
基于AS32S601ZIT2型抗辐照MCU的商业航天卫星姿态确定与控制系统研究
单片机·嵌入式硬件·安全·fpga开发·架构·risc-v
ALINX技术博客18 天前
【黑金云课堂】FPGA技术教程FPGA基础:I2C 总线通信技术
fpga开发·i2c
Hello-FPGA18 天前
Xilinx KU040 FPGA Camera Link 图像采集
c++·fpga开发