3.LED 实验进化六部曲(可控线性序列机)

zhanglei 2022年10月18日 288次浏览

3.LED 实验进化六部曲(可控线性序列机)

1.让 LED 灯按照亮 0.25 秒,灭 0.75 秒的状态循环亮灭

counter_led_1

module counter_led_1(
    Clk,
    Reset_n,
    Led
    );
    input Clk;
    input Reset_n;
    output reg Led;
    
    parameter MAX = 50000000;
    reg[25:0] counter;
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter <= 0;
    else if(counter == MAX - 1)
        counter <=0;
    else counter <= counter + 1'b1;
    
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        Led <= 1;
    else if(counter == MAX/4-1)
        Led <= 0;
    else if(counter == MAX-1)
        Led <= 1;
endmodule

counter_led_1_tb

`timescale 1ns / 1ps

module counter_led_1_tb();

    reg Clk;
    reg Reset_n;
    wire Led;
    
    counter_led_1 
    #(
        .MAX(50000)
    )
    counter_led_1 (
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Led(Led)
    );
    
 
    initial Clk = 1;
    always #10 Clk = !Clk;
    
    initial begin
        Reset_n = 0;
        #201
        Reset_n = 1;
        #2000000000
        $stop;
    end
    

endmodule

仿真波形

image-20221017153714949

2.让 LED 灯按照亮 0.25 秒,灭 0.5 秒,亮 0.75 秒,灭 1 秒的状态循环亮灭

counter_led_2

module counter_led_2(
    Clk,
    Reset_n,
    Led
    );
    input Clk;
    input Reset_n;
    output reg Led;
    
    parameter MAX = 125000000;
    reg[26:0] counter;
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter <= 0;
    else if(counter == MAX - 1)
        counter <=0;
    else counter <= counter + 1'b1;
    
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        Led <= 1;
    else if(counter == MAX/10-1)
        Led <= 0;
    else if(counter == MAX/10+MAX/5-1)
        Led <= 1;
    else if(counter == MAX/10+MAX/5+MAX*3/10-1)
        Led <= 0;
    else if(counter == MAX-1)
        Led <= 1;
endmodule

counter_led_2_tb

`timescale 1ns / 1ps

module counter_led_1_tb();

    reg Clk;
    reg Reset_n;
    wire Led;
    
    counter_led_2 
    #(
        .MAX(125000)
    )
    counter_led_2 (
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Led(Led)
    );
    
 
    initial Clk = 1;
    always #10 Clk = !Clk;
    
    initial begin
        Reset_n = 0;
        #201
        Reset_n = 1;
        #2000000000
        $stop;
    end
    

endmodule

仿真波形

image-20221017161049436

3.让 LED 灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随即指定。以 0.25 秒为一个变化周期,8个变化状态为一个循环

counter_led_3

module counter_led_3(
    Clk,
    Reset_n,
    Ctrl,
    Led
    );
    input Clk;
    input Reset_n;
    input  [7:0] Ctrl;
    output reg Led;
    
    parameter MAX = 100000000;
    reg[26:0] counter;
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter <= 0;
    else if(counter == MAX - 1)
        counter <=0;
    else 
        counter <= counter + 1'b1;
    
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        Led <= 0;
    else case(counter)
        MAX/8-1:Led <= Ctrl[0];
        MAX*2/8-1:Led <= Ctrl[1];
        MAX*3/8-1:Led <= Ctrl[2];
        MAX*4/8-1:Led <= Ctrl[3];
        MAX*5/8-1:Led <= Ctrl[4];
        MAX*6/8-1:Led <= Ctrl[5];
        MAX*7/8-1:Led <= Ctrl[6];
        MAX*8/8-1:Led <= Ctrl[7];
        default:Led <= Led;
    endcase
endmodule

counter_led_3_tb

`timescale 1ns / 1ps

module counter_led_3_tb();

    reg Clk;
    reg Reset_n;
    reg [7:0] Ctrl;
    wire Led;
    
    counter_led_3 
    #(
        .MAX(100000)
    )
    counter_led_3 (
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Ctrl(Ctrl),
        .Led(Led)
    );
    
 
    initial Clk = 1;
    always #10 Clk = !Clk;
    
    initial begin
        Reset_n = 0;
        Ctrl = 0;
        #201;
        Reset_n = 1;
        #2000;
        Ctrl = 8'b10100101;
        #2000000000;
        $stop;
    end
    

endmodule

仿真波形

image-20221017195244827

4.让 LED 灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随即指定。8个变化状态为一个循环,每个变化状态的时间值可以根据不同的应用场景选择

counter_led_4

module counter_led_4(
    Clk,
    Reset_n,
    Ctrl,
    Time,
    Led
    );
    input Clk;
    input Reset_n;
    input  [7:0] Ctrl;
    //随便给一个比较大的范围
    input [31:0] Time;
    output reg Led;
    
    reg[31:0] counter;
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter <= 0;
    else if(counter == Time - 1)
        counter <=0;
    else 
        counter <= counter + 1'b1;
        
    reg[2:0]counter2;
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter2 <= 0;
    else if(counter == Time - 1)
        counter2 <= counter2 + 1'b1;
        
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_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_4_tb

`timescale 1ns / 1ps

module counter_led_4_tb();

    reg Clk;
    reg Reset_n;
    reg [7:0] Ctrl;
    reg [31:0] Time;
    wire Led;
    
 
    counter_led_4 DUT (
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Ctrl(Ctrl),
        .Time(Time),
        .Led(Led)
    );
    
 
    initial Clk = 1;
    always #10 Clk = !Clk;
    
    initial begin
        Reset_n = 0;
        Ctrl = 0;
        Time = 0;
        #201;
        Reset_n = 1;
        #2000;
        Time = 2499;
        Ctrl = 8'b10100101;
        #2000000000;
        $stop;
    end
    

endmodule

仿真波形

image-20221017215944827

5.让多个 LED 灯按照设置的模式各自在一个变化循环内独立亮灭变化变化

在4的条件下加入 Led2 以及 Ctrl2 即可

6.每隔 10ms,让 LED 灯的一个8状态循环执行一次(每个状态的变化时间值小一点,方便测试,比如设置为 10 us)

示意图如下:

image-20221018141749728

counter_led_6

module counter_led_6(
    Clk,
    Reset_n,
    Ctrl,
    Time,
    Led
    );
    input Clk;
    input Reset_n;
    input  [7:0] Ctrl;
    //随便给一个比较大的范围
    input [31:0] Time;
    output reg Led;
    
    reg[31:0] counter;
    //使能信号控制counter0记数
    reg EN;
    reg[18:0] counter0;
    //10ms的计数器
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter0 <= 0;
    else if(counter0 == 500000 - 1)
        counter0 <=0;
    else 
        counter0 <= counter0 + 1'b1;
        
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        EN <= 0;
    else if(counter0 == 0)
        EN <= 1;
    else if((counter2 == 7)&& (counter == Time - 1))
        EN <= 0;
        
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter <= 0;
    else if(EN)begin
        if(counter == Time - 1)
            counter <= 0;
        else
            counter <= counter + 1'b1;
    end
        
    reg[2:0]counter2;
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter2 <= 0;
    else if(EN)begin
        if(counter == Time - 1)
            counter2 <= counter2 + 1'b1;
    end
        
    
    always @(posedge Clk or negedge Reset_n)
    if(!Reset_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_6_tb

`timescale 1ns / 1ps

module counter_led_6_tb();

    reg Clk;
    reg Reset_n;
    reg [7:0] Ctrl;
    reg [31:0] Time;
    wire Led;
    
 
    counter_led_6 DUT (
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Ctrl(Ctrl),
        .Time(Time),
        .Led(Led)
    );
    
 
    initial Clk = 1;
    always #10 Clk = !Clk;
    
    initial begin
        Reset_n = 0;
        Ctrl = 0;
        Time = 0;
        #201;
        Reset_n = 1;
        #2000;
        Time = 2499;
        Ctrl = 8'b10100101;
        #2000000000;
        $stop;
    end
    

endmodule

仿真波形

image-20221018151631994