让LED灯按照指定的亮灭模式亮灭

题目:
让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随即指定。每八个变化为一个循环,每个变化状态的时间值可以根据不同的应用场景选择。
思路:参考3 8 译码器的设置
需要两个计数器

源文件:

module counter_led_3(
Clk,
Reset_n,
Led,
ctr,
Time
);
input Clk;
input Reset_n;
output reg Led;
input [7:0] ctr;
input [31:0] Time;

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] ctr2;    
     always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
     ctr2 <= 0;
     else if(counter == Time - 1)
        ctr2 <= ctr2 + 1'b1;
    
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
    Led <= 0;
  else case(ctr2)
   0 : Led<=ctr[0];
    1 : Led<=ctr[1];
     2 : Led<=ctr[2];
     3 : Led<=ctr[3];
      4 : Led<=ctr[4];
     5 : Led<=ctr[5];
     6 : Led<=ctr[6];
  7: Led<=ctr[7];
   default : Led <= Led;
     endcase 

endmodule

// Time 指定每个状态的时间;
// ctr 指定某一时刻的等的状态
// ctr2 指定每一个小状态的时段; 即 什么时候开始这个状态 满8个 为一个循环周期

TB文件:

`timescale 1ns / 1ns
module counter_led_3_tb;
reg Clk;
reg Reset_n;
reg [7:0] ctr;
reg [31:0] Time;
wire Led;
counter_led_3 counter_led_3(
.Clk(Clk),
.Reset_n(Reset_n),
.Led(Led),
.ctr(ctr),
.Time(Time)
);
initial Clk = 1;
always #10 Clk = !Clk;

initial begin
    Reset_n = 0;;
    ctr = 0;
    Time= 0;
    #201;
    Reset_n = 1;
    #2001;
    Time = 2500;
    ctr = 8'd1000_0110;
    #20000000; 
    $stop;
end

endmodule

题目二:每隔10ms,让LED的一个8状态循环一次,(每个状态的变化时间小一点,方便测试,列如10us.)
解题关键:10ms怎么来,执行一次怎么做
在这里插入图片描述
源代码:
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;
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
else
    counter <= 0;

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
else
    counter2 <= 0;     
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
TB文件:
`timescale 1ns/1ns
module counter_led_6_tb;
reg Clk;
reg Reset_n;
reg [7:0]Ctrl;
reg [31:0]Time;
wire Led;
counter_led_6 counter_led_6(
.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 = 2500;
    Ctrl = 8'b1000_0110;
    #20000000;  
    Time = 25000;
    Ctrl = 8'b1010_0110;
    #20000000;    
    $stop;
end

endmodule

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值