当前位置:   article > 正文

5.2 FPGA:基于verilog的LED流水灯设计(多种方法)_verilog实现多功能灯

verilog实现多功能灯

目录

设计目标:8个LED灯以每0.5s的速率进行循环闪烁

方法1:移位法实现

设计模块

仿真代码

实验结果

 方法2:循环移位方法

 设计模块

方法3:使用三八译码器实现流水灯

顶层模块

底层模块


设计目标:8个LED灯以每0.5s的速率进行循环闪烁

当仿真时时间长,可以减小设计代码的计数次数,对分析移位功能没有影响。

方法1:移位法实现

设计模块

  1. module led_run(
  2. Clk,
  3. Reset_n,
  4. led
  5. );
  6. input Clk;
  7. input Reset_n;
  8. output reg [7:0]led;
  9. reg [24:0] counter;
  10. always@(podedge Clk or negedge Reset_n)
  11. if(!Reset_n)
  12. counter <= 0;
  13. else if(counter == 24999999)
  14. counter <= 0;
  15. else
  16. counter <= counter + 1'd1;
  17. always@(podedge Clk or negedge Reset_n)
  18. if(!Reset_n)
  19. led <= 8'b0000_0001;
  20. else if(counter == 24999999)begin
  21. if(led == 8'b1000_0000)
  22. led <= 8'b0000_0001;
  23. else
  24. led <= led << 1;
  25. end
  26. else
  27. led = led;
  28. endmoduule

仿真代码

  1. `timescale 1ns/1ns
  2. module led_run_tb();
  3. reg Clk;
  4. reg Reset_n;
  5. wire [7:0]led;
  6. led_run led_run(
  7. .Clk(Clk),
  8. .Reset_n(Reset_n),
  9. .led(led)
  10. );
  11. initial Clk = 1;
  12. always #10 Clk = ~Clk;
  13. initial begin
  14. Reset_n = 0;
  15. #201;
  16. Reset_n = 1;
  17. #4000000000; //延时4s
  18. $stop;
  19. end
  20. endmodule

实验结果

 方法2:循环移位方法

知识点:位拼接

 设计模块

  1. module led_run1(
  2. Clk,
  3. Reset_n,
  4. led
  5. );
  6. input Clk;
  7. input Reset_n;
  8. output reg [7:0] led;
  9. reg [24:0] counter;
  10. always@(posedge Clk or negedge Reset_n)
  11. if(!Reset_n)
  12. counter <= 0;
  13. // else if(counter == 24999999)
  14. else if(counter == 24999) //500us
  15. counter <= 0;
  16. else
  17. counter <= counter + 1'd1;
  18. always@(posedge Clk or negedge Reset_n)
  19. if(!Reset_n)
  20. led = 8'b0000_0001;
  21. // else if(counter == 24999999)begin
  22. else if(counter == 24999)
  23. led <= {led[6:0],led[7]}; //位拼接
  24. else
  25. led <= led;
  26. endmodule

方法3:使用三八译码器实现流水灯

知识点:1.计数器记满清零。2. 模块间的调用。

在当前模块中调用三八译码器模块,将38译码器的设计模块添加到当前文件夹中,在led_run2.v中通过接口调用三八译码器。

将led_run2.v中的 led 接到三八译码器的 out 端口上时,led 不能再定义为 reg 型,因为三八译码器底层已经将out定义为reg型。底层已经定义了reg型,顶层就不能再定义reg型。 led是由底层模块驱动的,顶层只能定义为wire型。

顶层模块

  1. module led_run2(
  2. Clk,
  3. Reset_n,
  4. led
  5. );
  6. input Clk;
  7. input Reset_n;
  8. output [7:0] led;
  9. reg [24:0] counter;
  10. reg [2:0] counter1; //二进制8个状态,3
  11. always@(posedge Clk or negedge Reset_n)
  12. if(!Reset_n)
  13. counter <= 0;
  14. // else if(counter == 24999999)
  15. else if(counter == 24999) //500us
  16. counter <= 0;
  17. else
  18. counter <= counter + 1'd1;
  19. always@(posedge Clk or negedge Reset_n)
  20. if(!Reset_n)
  21. counter1 <= 0;
  22. // else if(counter == 24999999)
  23. else if(counter == 24999)
  24. counter1 <= counter1 + 1'b1;
  25. decoder_3_8 decoder_3_8(
  26. .a(counter1[2]), //counter1[2] 是最高位
  27. .b(counter1[1]),
  28. .c(counter1[0]),
  29. .out(led) //底层已将out定义为reg型,所以顶层不能再定义成reg型
  30. );
  31. endmodule

底层模块

  1. module decoder_3_8(
  2. a,
  3. b,
  4. c,
  5. out
  6. );
  7. input a;
  8. input b;
  9. input c;
  10. output reg [7:0] out;
  11. // 2种写法:reg [7:0] out;
  12. //以always块描述的信号赋值,被赋值对象必须定义为reg类型
  13. //{a,b,c}拼接成了一个三位信号
  14. always@(*)begin
  15. case({a,b,c})
  16. 3'b000: out = 8'b0000_0001;
  17. 3'b001: out = 8'b0000_0010;
  18. 3'b010: out = 8'b0000_0100;
  19. 3'b011: out = 8'b0000_1000;
  20. 3'b100: out = 8'b0001_0000;
  21. 3'b101: out = 8'b0010_0000;
  22. 3'b110: out = 8'b0100_0000;
  23. 3'b111: out = 8'b1000_0000;
  24. endcase
  25. end
  26. endmodule

defparam写法不能在testbench中生效

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

闽ICP备14008679号