回答

收藏

STEP BY STEP! 带你快速上手小脚丫FPGA开发板——5.流水灯

#竞赛 #竞赛 4787 人阅读 | 0 人回复 | 2017-08-14

LED流水灯

在时钟分频实验中我们练习了如何处理时钟,接下来我们要学习如何利用时钟来完成时序逻辑。

硬件说明

流水灯实现是很常见的一个实验,虽然逻辑比较简单,但是里面也包含了实现时序逻辑的基本思想。要用FPGA实现流水灯有很多种方法,在这里我们会用两种不同的方法实现。
1,模块化设计:在之前的实验中我们做了[[3. 3-8译码器|3-8译码器]]和[[5. 时钟分频|时钟分频]],如果把这两个结合起来,我们就能搭建一个自动操作的流水LED显示。框图如下:

2,循环赋值:这是一种很简洁的实现流水灯效果逻辑,就是定义一个8位的变量,在每个时钟上升沿将最低位赋值给最高位,其他位右移一位,这就实现了循环赋值。这8位输出到LED就能实现流水灯。

Verilog代码

模块化设计是用硬件描述语言进行数字电路设计的精髓,代码可重复利用。而且模块化的设计使得程序的结构也很清晰。这里我们首先看看流水灯的模块化设计。利用了之前的3-8译码器和分频器,你需要把这两个程序也拷贝到一个工程。
  1. // ********************************************************************
  2. // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
  3. // ********************************************************************
  4. // File name    : flashled.v
  5. // Module name  : flashled
  6. // Author       : STEP
  7. // Description  : segment initial
  8. // Web          : www.stepfpga.com
  9. //
  10. // --------------------------------------------------------------------
  11. // Code Revision History :
  12. // --------------------------------------------------------------------
  13. // Version: |Mod. Date:   |Changes Made:
  14. // V1.0     |2017/03/02   |Initial ver
  15. // --------------------------------------------------------------------
  16. // Module Function:流水灯的模块化设计

  17. module flashled (clk,rst,led);

  18.         input clk,rst;                                               
  19.         output [7:0] led;                               


  20.         reg   [2:0] cnt ;                               //定义了一个3位的计数器,输出可以作为3-8译码器的输入
  21.         
  22.         wire clk1h;                                     //定义一个中间变量,表示分频得到的时钟,用作计数器的触发        

  23.         //例化module decode38,相当于调用
  24.         decode38 u1 (                                   
  25.                         .sw(cnt),                       //例化的输入端口连接到cnt,输出端口连接到led  
  26.                         .led(led)
  27.                         );
  28.        
  29.         //例化分频器模块,产生一个1Hz时钟信号               
  30.         divide #(.WIDTH(32),.N(12000000)) u2 (         //传递参数
  31.                         .clk(clk),
  32.                         .rst_n(rst),                   //例化的端口信号都连接到定义好的信号
  33.                         .clkout(clk1h)
  34.                         );                             
  35.        
  36.         //1Hz时钟上升沿触发计数器,循环计数               
  37.         always @(posedge clk1h or negedge rst)
  38.              if (!rst)
  39.                 cnt <= 0;
  40.              else
  41.                 cnt <= cnt +1;
  42.                
  43.         endmodule
复制代码
模块化设计结构清晰,verilog语言是很灵活的。对于流水灯还有一种很简洁的实现方法。

  1. // ********************************************************************
  2. // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
  3. // ********************************************************************
  4. // File name    : flashled.v
  5. // Module name  : flashled
  6. // Author       : STEP
  7. // Description  : segment initial
  8. // Web          : www.stepfpga.com
  9. //
  10. // --------------------------------------------------------------------
  11. // Code Revision History :
  12. // --------------------------------------------------------------------
  13. // Version: |Mod. Date:   |Changes Made:
  14. // V1.0     |2017/03/02   |Initial ver
  15. // --------------------------------------------------------------------
  16. // Module Function:流水灯的模块化设计

  17. module flashled (clk,rst,led);

  18.         input clk,rst;                                               
  19.         output [7:0] led;                               
  20.         
  21.         wire clk1h;                                     //定义一个中间变量,表示分频得到的时钟,用作计数器的触发        

  22.         //例化分频器模块,产生一个1Hz时钟信号               
  23.         divide #(.WIDTH(32),.N(12000000)) u2 (         //传递参数
  24.                         .clk(clk),
  25.                         .rst_n(rst),                   //例化的端口信号都连接到定义好的信号
  26.                         .clkout(clk1h)
  27.                         );                             
  28.        
  29.         //1Hz时钟上升沿触发循环赋值       
  30.         always@(posedge clk1h or negedge rst)
  31.         begin
  32.                 if(!rst)
  33.                         led <= 8'b11111110;            // <=为非阻塞赋值
  34.                 else
  35.                         led <= {led[0],led[7:1]};      //当时钟上升沿来一次,执行一次赋值,赋值内容是led[0]与led[7:1]重新拼接成8位赋给led,相当于循环右移
  36.         end       
  37.         
复制代码
引脚分配

按照下面表格定义输入输出信号

信号   引脚 信号 引脚
clk C1 led[3]M11
rst L14 led[4] P11
led[0]   N13 led[5] N10
led[1] M12 led[6] N9
led[2] P12 led[7]p9

配置好以后编译下载程序。可以调整例化分频器时传递的参数来调整流水灯的速度。

小结
掌握了verilog里面例化module的用法,采用模块化设计程序。模块化设计是非常重要的FPGA设计思想。在下一节我们会学习按键的另外用法——按键消抖。

分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条