Verilog Practice Note

Led 练习:从点灯到串口练习1

题目

一、基础部分
1.让LED灯按照亮0.25s,灭0.75s的状态循环亮灭
2.让LED灯按照亮0.25s,灭0.5秒,亮0.75秒,灭1秒的状态循环亮灭
3.让LED灯按照指定的亮灭模式亮灭,亮灭模式位置,由用户随机指定。以0.25秒为一个变化周期,8个变化状态为一个循环。
二、提高部分
4.让LED灯按照指定亮灭模式亮灭,亮灭模式位置。由用户随机指定。8个变化状态为一个循环,每个变化状态的时间值可以根据不同应用场景选择
5.让多个LED灯按照设置的模式各自在一个变化循环内独立亮灭变化
6.每隔10ms,让LED灯的一个8状态循环执行一次(每个状态变化时间值小一点,方便测试,比如设定在10us)
7.请了解串口的通信协议(学会阅读手册也是一种能力)
8.实现串口通信协议
说明:1.对于基础部分第三问“随机指定”(规定亮为1,灭为0):假设,用户随机指定数据为1100_1010,那么这个周期灯的亮灭就应该是:亮亮灭灭,亮灭亮灭

练习

第一题 counter_led_1.v:

module counter_led_1 (
    clk,
    rst_n,
    led
);
    input clk;
    input rst_n;
    output reg led;

    reg [25:0] counter;
    parameter CNT = 50000000;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        counter <= 0;
    else if(counter == CNT - 1)
        counter <= 0;
    else
        counter <= counter + 1'b1;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        led <= 0;
    else if(counter == (CNT / 2 + CNT / 4) - 1)
        led <= 1;
    else if(counter == CNT - 1)
        led <= 0;
        
endmodule

第二题 counter_led_2.v:

module counter_led_2 (
    clk,
    rst_n,
    led
);
    input clk;
    input rst_n;
    output reg led;

    reg [26:0] counter;
    parameter CNT = 125000000;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        counter <= 0;
    else if(counter == CNT - 1)
        counter <= 0;
    else
        counter <= counter + 1'b1;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        led <= 0;
    else if(counter == (CNT / 5 + CNT / 5) - 1)
        led <= 1;
    else if(counter == (CNT / 5 * 2 + CNT / 10) - 1)
        led <= 0;
    else if(counter == (CNT / 10 + CNT / 5 * 3) - 1)
        led <= 1;
    else if(counter == CNT - 1)
        led <= 0;
        
endmodule

第三题 counter_led_3.v:

module counter_led_3 (
    clk,
    rst_n,
    ctrl,
    led
);
    input clk;
    input rst_n;
    input [7:0] ctrl;
    output reg led;

    reg [26:0] counter;
    parameter CNT = 100000000;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        counter <= 0;
    else if(counter == CNT - 1)
        counter <= 0;
    else
        counter <= counter + 1'b1;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        led <= 0;
    else if(counter == CNT / 8 - 1)
        led <= ctrl[0];
    else if(counter == CNT / 4 - 1)
        led <= ctrl[1];
    else if(counter == CNT / 8 * 3 - 1)
        led <= ctrl[2];
    else if(counter == CNT / 2 - 1)
        led <= ctrl[3];
    else if(counter == CNT / 8 * 5 - 1)
        led <= ctrl[4];
    else if(counter == CNT / 4 * 3 - 1)
        led <= ctrl[5];
    else if(counter == CNT / 8 * 7 - 1)
        led <= ctrl[6];
    else if(counter == CNT - 1)
        led <= ctrl[7];
        
endmodule

第四题 counter_led_4.v:

module counter_led_4 (
    clk,
    rst_n,
    ctrl,
    Time,
    led
);
    input clk;
    input rst_n;
    input [7:0] ctrl;
    input [31:0] Time;
    output reg led;

    reg [31:0] counter;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        counter <= 0;
    else if(counter == Time - 1)
        counter <= 0;
    else
        counter <= counter + 1'b1;
    
    reg [2:0] counter2;
    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        counter2 <= 0;
    else if(counter == Time - 1)
        counter2 <= counter2 + 1'b1;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        led <= 0;
    else case(counter2)
        0:led <= ctrl[0];
        1:led <= ctrl[1];
        2:led <= ctrl[2];
        3:led <= ctrl[3];
        4:led <= ctrl[4];
        5:led <= ctrl[5];
        6:led <= ctrl[6];
        7:led <= ctrl[7];
        default: led <= led;
    endcase
        
endmodule

第五题 counter_led_5.v:

module counter_led_5 (
    clk,
    rst_n,
    ctrl_1,
    ctrl_2,
    ctrl_3,
    ctrl_4,
    ctrl_5,
    ctrl_6,
    ctrl_7,
    ctrl_8,
    Time,
    led,
);
    input clk;
    input rst_n;
    input [7:0] ctrl_1;
    input [7:0] ctrl_2;
    input [7:0] ctrl_3;
    input [7:0] ctrl_4;
    input [7:0] ctrl_5;
    input [7:0] ctrl_6;
    input [7:0] ctrl_7;
    input [7:0] ctrl_8;
    input [31:0] Time;
    output reg [7:0] led;

    reg [31:0] counter;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        counter <= 0;
    else if(counter == Time - 1)
        counter <= 0;
    else
        counter <= counter + 1'b1;
    
    reg [2:0] counter2;
    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        counter2 <= 0;
    else if(counter == Time - 1)
        counter2 <= counter2 + 1'b1;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        led <= 0;
    else case(counter2)
        0:begin led[0] <= ctrl_1[0];
                led[1] <= ctrl_2[0];
                led[2] <= ctrl_3[0];
                led[3] <= ctrl_4[0];
                led[4] <= ctrl_5[0];
                led[5] <= ctrl_6[0];
                led[6] <= ctrl_7[0];
                led[7] <= ctrl_8[0]; end
        
        1:begin led[0] <= ctrl_1[1];
                led[1] <= ctrl_2[1];
                led[2] <= ctrl_3[1];
                led[3] <= ctrl_4[1];
                led[4] <= ctrl_5[1];
                led[5] <= ctrl_6[1];
                led[6] <= ctrl_7[1];
                led[7] <= ctrl_8[1]; end
        
        2:begin led[0] <= ctrl_1[2];
                led[1] <= ctrl_2[2];
                led[2] <= ctrl_3[2];
                led[3] <= ctrl_4[2];
                led[4] <= ctrl_5[2];
                led[5] <= ctrl_6[2];
                led[6] <= ctrl_7[2];
                led[7] <= ctrl_8[2]; end
        
        3:begin led[0] <= ctrl_1[3];
                led[1] <= ctrl_2[3];
                led[2] <= ctrl_3[3];
                led[3] <= ctrl_4[3];
                led[4] <= ctrl_5[3];
                led[5] <= ctrl_6[3];
                led[6] <= ctrl_7[3];
                led[7] <= ctrl_8[3]; end
        
        4:begin led[0] <= ctrl_1[4];
                led[1] <= ctrl_2[4];
                led[2] <= ctrl_3[4];
                led[3] <= ctrl_4[4];
                led[4] <= ctrl_5[4];
                led[5] <= ctrl_6[4];
                led[6] <= ctrl_7[4];
                led[7] <= ctrl_8[4]; end
        
        5:begin led[0] <= ctrl_1[5];
                led[1] <= ctrl_2[5];
                led[2] <= ctrl_3[5];
                led[3] <= ctrl_4[5];
                led[4] <= ctrl_5[5];
                led[5] <= ctrl_6[5];
                led[6] <= ctrl_7[5];
                led[7] <= ctrl_8[5]; end
        
        6:begin led[0] <= ctrl_1[6];
                led[1] <= ctrl_2[6];
                led[2] <= ctrl_3[6];
                led[3] <= ctrl_4[6];
                led[4] <= ctrl_5[6];
                led[5] <= ctrl_6[6];
                led[6] <= ctrl_7[6];
                led[7] <= ctrl_8[6]; end
        
        7:begin led[0] <= ctrl_1[7];
                led[1] <= ctrl_2[7];
                led[2] <= ctrl_3[7];
                led[3] <= ctrl_4[7];
                led[4] <= ctrl_5[7];
                led[5] <= ctrl_6[7];
                led[6] <= ctrl_7[7];
                led[7] <= ctrl_8[7]; end
        
        default:begin led[0] <= led[0]; led[1] <= led[1]; led[2] <= led[2]; led[3] <= led[3]; led[4] <= led[4]; led[5] <= led[5]; led[6] <= led[6]; led[7] <= led[7]; end
    endcase
        
endmodule

第六题 counter_led_6.v:

module counter_led_6 (
    clk,
    rst_n,
    ctrl,
    Time,
    led
);
    input clk;
    input rst_n;
    input [7:0] ctrl;
    input [31:0] Time;
    output reg led;

    reg [31:0] counter0;
    reg EN;
    reg [31:0] counter;
    reg [2:0] counter2;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        counter0 <= 0;
    else if(counter0 == 500000 - 1)
        counter0 <= 0;
    else
        counter0 <= counter0 + 1'b1;
    
    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        EN <= 0;
    else if(counter0 == 0)
        EN <= 1;
    else if((counter2 == 7)&&(counter == Time - 1))
        EN <= 0;
    
    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        counter <= 0;
    else if(EN)begin
        if(counter == Time - 1)
            counter <= 0;
        else
            counter <= counter + 1'b1;
    end    
    
    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        counter2 <= 0;
    else if(counter == Time - 1)
        counter2 <= counter2 + 1'b1;

    always @ (posedge clk or negedge rst_n)
    if(!rst_n)
        led <= 0;
    else case(counter2)
        0:led <= ctrl[0];
        1:led <= ctrl[1];
        2:led <= ctrl[2];
        3:led <= ctrl[3];
        4:led <= ctrl[4];
        5:led <= ctrl[5];
        6:led <= ctrl[6];
        7:led <= ctrl[7];
        default: led <= led;
    endcase
        
endmodule

总结

第一题中的led设计,围绕着一个计数器开始,在计数器的辅助下,将clk信号量化,实现对时间的记录,并让固定时间的亮灭成为可能。值得注意的是,counter的最大值,代表了一个完整的周期,这意味着我们对led亮灭的控制来源于counter(current)/counter(max),从而达到led不等时长的亮灭。

第二题延续第一题的设计思路,但是将时长增长,并将counter的比例划分细化,从而实现了4种不同时长的亮灭状态。

第三题引入ctrl,实现了用户对led亮灭的控制。8个状态意味着将counter划分为八等份,通过对8位的ctrl在testbench中赋值,来决定led的亮灭。

第四题由于是用户决定时间,因此引入了Time,作为一次变化的时长,相应的,原有的counter不再作为完整的一周期的时长的计数器,成为了每次变化时长的计数器,而counter2的引入则实现了亮灭状态的计数。

第五题沿用counter_led_4.v的设计,不过将led的数量增加到8个,对应地引入了8个ctrl。

第六题由于需要间隔10ms循环亮灭,所以引入counter0来对间隔的10ms进行计数,并加入了EN信号,指示状态执行,在led亮灭中,沿用了counter_led_4.v的设计。

整个led题目中,围绕着时间控制和亮灭状态控制展开,对于时间控制,我们选择了引入计数器,让时间量化,间接实现计时功能;对于状态控制,我们选择加入ctrl信号来指示灯的亮灭状态,EN信号指示亮灭循环的开始与结束。

6道led题目意在为串口通信进行铺垫,8个led和串口的8位信号相对应,而状态的控制,尤其是EN信号的引入,也是串口通信的重要组成部分。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值