当前位置:   article > 正文

FPGA开发——LED流水灯实现先从左往右流水,再从右往左流水

FPGA开发——LED流水灯实现先从左往右流水,再从右往左流水

一、概述

我们在设计完一个方向的流水灯的设计时,总是会想实现让流水灯倒着流水回去的设计,这里我也是一样,实现这种设计的方法有很多种,其中就有直接使用case语句将所有可能包含进去编写,这种设计方法是最简单的,还有就是使用多个计数器的方式进行标志判断,实现方向流水的切换,以及我们最常用的状态机方法的实现。因为这里的设计不太难,所以我就讲解前面两种实现方式,至于最后一种方法感兴趣的可以去实现一下。

二、实现思路

1、方法一

这个方法就是不考虑其他条件,直接从第一个LED状态开始编写,一直编写到所有的LED状态编写完(这里以四个LED为例)

2、方法二

这个方法的实现思路就是在第一个计数器(LED流水间隔时间计数器)计数的基础上叠加一个计数器统计不同方向流水完成,使用次计数器编写状态标志位。从而利用标志位实现不同方向流水。

三、测试文件的编写

1、方法一

  1. //模块定义
  2. module led(
  3. input rst_n,
  4. input clk,
  5. output reg [3:0] led_out
  6. );
  7. //参数定义
  8. parameter TIME_500ms= 25_000_000;
  9. //内部信号定义
  10. reg [24:0] cnt;//计数500ms所需要的二进制位数
  11. wire add_cnt;//计数器开启条件
  12. wire end_cnt;//计数器结束条件
  13. reg [3:0] state_n;
  14. //计数器实现功能,0.5秒技术
  15. always @(posedge clk or negedge rst_n)begin
  16. if(!rst_n)begin
  17. cnt<=0;
  18. end
  19. else if(add_cnt)begin
  20. if(end_cnt)
  21. cnt<=0;
  22. else
  23. cnt<=cnt+1;
  24. end
  25. else
  26. cnt<=0;
  27. end
  28. assign add_cnt=1'b1;
  29. assign end_cnt=add_cnt && cnt ==(TIME_500ms-1);
  30. //LED从左往右,在从右往左流水
  31. always @(posedge clk or negedge rst_n)begin
  32. if(!rst_n)
  33. led_out<=4'b0001;
  34. else case(state_n)
  35. 3'd0:led_out<=4'b0001;
  36. 3'd1:led_out<=4'b0010;
  37. 3'd2:led_out<=4'b0100;
  38. 3'd3:led_out<=4'b1000;
  39. 3'd4:led_out<=4'b0100;
  40. 3'd5:led_out<=4'b0010;
  41. 3'd6:led_out<=4'b0001;
  42. default:led_out<=4'b0001;
  43. endcase
  44. end
  45. always @(posedge clk or negedge rst_n)begin
  46. if(!rst_n)
  47. state_n <=0;
  48. else if(state_n==3'd6 && end_cnt)
  49. state_n<=0;
  50. else if(state_n<3'd6 && end_cnt)
  51. state_n<=state_n+1;
  52. end
  53. endmodule

2、方法二

  1. //模块定义
  2. module led(
  3. input rst_n,
  4. input clk,
  5. output reg [3:0] led_out
  6. );
  7. //参数定义
  8. parameter TIME_500ms= 25_000_000;
  9. //内部信号定义
  10. reg [24:0] cnt;//计数500ms所需要的二进制位数
  11. wire add_cnt;//计数器开启条件
  12. wire end_cnt;//计数器结束条件
  13. reg [3:0] state_n;
  14. reg [1:0] cnt_state;
  15. wire add_cnt_state;//计数器开启条件
  16. wire end_cnt_state;//计数器结束条件
  17. reg cnt_flag;
  18. //计数器实现功能,0.5秒技术
  19. always @(posedge clk or negedge rst_n)begin
  20. if(!rst_n)begin
  21. cnt<=0;
  22. end
  23. else if(add_cnt)begin
  24. if(end_cnt)
  25. cnt<=0;
  26. else
  27. cnt<=cnt+1;
  28. end
  29. else
  30. cnt<=0;
  31. end
  32. assign add_cnt=1'b1;
  33. assign end_cnt=add_cnt && cnt ==(TIME_500ms-1);
  34. always @(posedge clk or negedge rst_n)begin
  35. if(!rst_n)begin
  36. cnt_state<=0;
  37. end
  38. else if(add_cnt_state)begin
  39. if(end_cnt_state)
  40. cnt_state<=0;
  41. else
  42. cnt_state<=cnt_state+1;
  43. end
  44. end
  45. assign add_cnt_state=end_cnt;
  46. assign end_cnt_state=add_cnt_state && (cnt_state ==3);
  47. always @(posedge clk or negedge rst_n)begin
  48. if(!rst_n)begin
  49. cnt_flag<=0;
  50. end
  51. else if(end_cnt_state)begin
  52. cnt_flag<=~cnt_flag;
  53. end
  54. else
  55. cnt_flag<=cnt_flag;
  56. end
  57. //功能编写
  58. always @(posedge clk or negedge rst_n)begin
  59. if(!rst_n)
  60. led_out<=4'b0001;
  61. else if(cnt_flag==1'b0 && end_cnt)begin
  62. led_out<={led_out[2:0],led_out[3]};//循环以为实现轮流闪烁
  63. end
  64. else if(cnt_flag==1'b1 && end_cnt)begin
  65. led_out<={led_out[0],led_out[3:1]};//循环以为实现轮流闪烁
  66. end
  67. else
  68. led_out<=led_out;
  69. end
  70. endmodule

四、测试文件的编写

这里我们要放着的条件都是一样的,所以只要使用同一个测试文件就可以

  1. //定义时间尺度
  2. `timescale 1ns/1ps
  3. module led_tb();
  4. //重定义
  5. defparam led_inst.TIME_500ms = 25;
  6. //内部变量定义
  7. reg clk;
  8. reg rst_n;
  9. wire [3:0] led_out;
  10. //模块实例化
  11. led led_inst(
  12. /*input */ .rst_n (rst_n ),
  13. /*input */ .clk (clk ),
  14. /*output reg [3:0] */ .led_out (led_out )
  15. );
  16. //时钟
  17. parameter CLK_CLY =20;
  18. initial clk=0;
  19. always #(CLK_CLY/2) clk=~clk;
  20. //复位
  21. initial begin
  22. rst_n =1'b0;
  23. #(CLK_CLY*2);
  24. #3;
  25. rst_n =1'b1;
  26. end
  27. //激励
  28. endmodule

五、仿真波形图

从波形图中我们可以看到LED灯首先会从0001——1000进行流水,然后又会从1000——0001进行反方向流水,与我们设计的要求一致,设计简单,所以就不进行下板验证了。 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/905903
推荐阅读
相关标签
  

闽ICP备14008679号