题目:
让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