(4)8个led每0.5s闪烁(跑马灯)

设计思路:

设计代码:

module led_run(
    clk,rst,led
    );
    
    input clk,rst;
    output reg [7:0] led = 8'b0000_0001;
    reg [24:0] cnt;
    
    parameter TIME = 24_999_999;
    always@(posedge clk or negedge rst)
        if(!rst)
            cnt <= 0;
        else if (cnt == TIME)
            cnt <= 0;
        else cnt <= cnt + 1;
        
    //通过移位实现
    always@(posedge clk or negedge rst)
        if(!rst)
            led <= 8'b0000_0001;
        else if(cnt == TIME)
            begin
                if(led == 8'b1000_0000)
                    led <=  8'b0000_0001;
                else
                    led <= (led<<1);    //led每0.5s左移一次
            end
        else
            led <= led;

endmodule

验证tb:

`timescale 1ns / 1ps

module led_run_tb();

reg clk,rst;
wire [7:0] led;

led_run u_led_run(
    .clk(clk),
    .rst(rst),
    .led(led)
    );

initial clk = 1;
always #10 clk = ~clk;

initial begin
rst = 0;
#201;   //错开时钟边沿
rst = 1;
#5_000_000_000;//8个led,每个0.5s 
$stop;

end endmodule

波形验证:

  注:为了提高设计开发效率,在仿真验证的时候没必要真的用0.5s跑,比如本设计在实现时设置为500us,这样可以节省时间。

仿真结果:

   可以观察到8个led依次闪烁,证明设计符合要求。


 

方法二:

  直接用代码

led <= {led[6:0],led[7]};

就可以省略两个嵌套if的判断。


 

方法三:

  使用上一节提到的38译码器完成设计,具体代码如下:

 

  这里注意两点:

  1.   这里是将cnt设置为3位,然后调用底层模块,所以要注意这里的例化格式
  2.   由于在底层模块已经对reg out 了,因此这里的led就不能再reg了,要把上面的reg删掉!!
posted @ 2024-04-03 11:54  xuxuxu69  阅读(32)  评论(0编辑  收藏  举报