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
仿真波形
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
仿真波形
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
仿真波形
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
仿真波形
5.让多个 LED 灯按照设置的模式各自在一个变化循环内独立亮灭变化变化
在4的条件下加入 Led2 以及 Ctrl2 即可
6.每隔 10ms,让 LED 灯的一个8状态循环执行一次(每个状态的变化时间值小一点,方便测试,比如设置为 10 us)
示意图如下:
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