当前位置: 首页 > news >正文

【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:用于控制流水灯的移动。当 pause 为 1 时,流水灯停止移动;当 pause 为 0 时,流水灯继续移动。

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

  4. LED控制逻辑:在 end_cnt_1s 为 1 且 pause 为 0 时,流水灯才会移动。

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语言有更深入的了解。

相关文章:

  • Oracle底层原理解析
  • JS | JS中的日期和时间的获取方法
  • 二阶近似 是什么意思
  • Web开发-PHP应用文件操作安全上传下载任意读取删除目录遍历文件包含
  • 字符串p型编码(信息学奥赛一本通-1145)
  • 理解我们单片机拥有的资源
  • 【操作系统安全】任务4:Windows 系统网络安全实践里常用 DOS 命令
  • linux系统——创建swap分区和移除磁盘
  • ftp替代品,如何提升数据交换的安全性与高效性?
  • css3有哪些新属性
  • 它,让机器人与HMI屏无缝对接
  • STM32输入捕获采集超声波模块HC-SR04响应的高电平
  • 问deepseek: 如何处理CGNS网格文件里,多个zone之间的链接数据
  • Java:引用其他类的方法
  • 09-ArcGIS For JavaScript -- 基于ThreeJS实现动态GLTF模型加载
  • 如何在AI时代处理 PDF
  • RabbitMQ 全面详解(附面试重点)
  • 【第15届蓝桥杯】软件赛CB组省赛
  • 微服务存在的问题及解决方案
  • Docker基础知识介绍
  • 对谈|李钧鹏、周忆粟:安德鲁·阿伯特过程社会学的魅力
  • 船只深夜撞上海上风机后沉没1死1失踪,调查报告公布
  • 柳州警方通报临牌车撞倒行人:扣留涉事车辆,行人无生命危险
  • 上海灵活就业人员公积金新政有哪些“创新点”?
  • “五一”假期全国口岸日均出入境人员将达215万人次
  • 海南旅文局通报游客入住酒店港币被调包:成立调查组赴陵水调查