当前位置:   article > 正文

【IC设计】Verilog线性序列机点灯案例(三)(小梅哥课程)

【IC设计】Verilog线性序列机点灯案例(三)(小梅哥课程)

声明:案例和代码来自小梅哥课程,本人仅对知识点做做笔记,如有学习需要请支持官方正版。

该系列目录:

Verilog线性序列机点灯案例(一)
Verilog线性序列机点灯案例(二)
Verilog线性序列机点灯案例(三)
Verilog线性序列机点灯案例(四)

设计目标

使用8个拨码开关控制一个LED灯,每个拨码开关负责控制0.25秒的时间,开关为1时亮,开关为0时灭。
举例:
10101010就是亮0.25秒,灭0.25秒,如此循环
10111101就是亮0.25秒,灭0.25秒,亮1秒,灭0.25秒,亮0.25秒,如此循环

设计思路

counter0计数器每计数满0.25秒就向counter1计数器加1,
counter1计数器从0到7计数,
led灯根据当前counter1计数器的值,选中对应的拨码开关进行输出,用软件的写法就是
led = sw[counter1]

RTL及Testbench代码

RTL代码

module led_ctrl2(
    clk,
    rst_n,
    led_out,
    sw
);
    input clk;
    input rst_n;
    input [7:0] sw;
    output reg led_out;
    
    parameter MCNT = 12500_000 - 1;
    reg [26:0] counter0;
    
    //第一个always块负责counter0
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            counter0 <= 0 ;
        else if(counter0 == MCNT)
            counter0 <= 0;
        else
            counter0 <= counter0 + 1'd1;
    end
    
    reg [2:0] counter1;
    
    //第二个always块负责counter1
    always@(posedge clk or negedge rst_n) begin
        if(!rst_n)
            counter1 <= 0 ;
        else if(counter0 == MCNT) begin
            counter1 <= counter1 + 1'd1;
        end
        else
            counter1 <= counter1;
    end
    
    //第三个always块负责根据counter1决定led_out
    //每0.25秒切换一个拨码输出
    always@(posedge clk or negedge rst_n)
    if(!rst_n)
        led_out <= 0;
    else begin
        case(counter1)
            0:led_out <= sw[0];
            1:led_out <= sw[1];
            2:led_out <= sw[2];
            3:led_out <= sw[3];
            4:led_out <= sw[4];
            5:led_out <= sw[5];
            6:led_out <= sw[6];
            7:led_out <= sw[7];
            default:led_out <= led_out;
        endcase
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

Testbench代码

`timescale 1ns / 1ns
module tb_led_ctrl2();
    reg clk;
    reg rst_n;
    wire led_out;
    reg [7:0] sw;
    
    initial clk = 1;
    always #10 clk = ~clk;
    
    led_ctrl2 led_ctrl2_inst0(
        .clk(clk),
        .rst_n(rst_n),
        .sw(sw),
        .led_out(led_out)
    );
    defparam led_ctrl2.MCNT = 12500 - 1; 
    
    initial begin
        rst_n = 0;
        sw = 8'b1010_1010;
        #201;
        rst_n = 1;
        
        #4_000_000;
        sw = 8'b0000_0001;
        
        #4_000_000;
        sw = 8'b1111_0001;
        
        #20_000_000;
        $stop;
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

仿真结果

总结这两张图可以看出来,counter1是在每次counter0计满12499时进1,即counter1每个值维持的时间是counter0等于0~12499,是0.25s,而led_out依赖于counter1,比counter1延迟一拍,所以led_out每个值维持时间也是0.25秒,时序正确。
图1
在这里插入图片描述

上板视频

Verilog线性序列机点灯案例(三)(小梅哥课程)

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

闽ICP备14008679号