【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

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

仿真结果

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

上板视频

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

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民真快落

我琢磨着也没人给我打赏呀。。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值