1.让LED灯按照亮0.25秒,灭0.75秒的状态循环亮灭。
2. 让LED灯按照亮0.25秒,灭0.5秒,亮0.75秒,灭1秒的状态循环亮灭。
3. 让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定;以0.25秒为一个变化周期,8个变化状态为一个循环。
4. 让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定;8个变化状态为一个循环,每个变化状态的时间值可以根据不同的应用场景选择。
5.让多个LED灯按照设置的模式各自在一个变化循环内独立亮灭变化。
6. 每隔10ms,让 LED灯的一个8状态循环执行一次(每个状态的变化时间值小一点,方便测试, 比如设置为10us)
目录
实验一 让LED灯按照亮0.25秒,灭0.75秒的状态循环亮灭
实验二 让LED灯按照亮0.25秒,灭0.5秒,亮0.75秒,灭1秒的状态循环亮灭
实验三 让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。以0.25秒为一个变化周期,8个变化状态为一个循环。
实验四 让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。8个变化状态为一个循环,每个变化状态的时间值可以根据不同的应用场景选择。
实验五 让多个LED灯按照设置的模式各自在一个变化循环内独立亮灭变化
实验六 每隔10ms,让 LED灯的一个8状态循环执行一次(每个状态的变化时间值小一点,方便测试, 比如设置为10us)
实验一 让LED灯按照亮0.25秒,灭0.75秒的状态循环亮灭
功能分析
一个循环共两个状态,共1s,设置一个计数周期为1s,
设置Led初始状态为高电平,即处于亮的状态,
经过0.25s,即到0.25s时,此时计数到四分之一个周期,使Led反转一次,LED为0;
经过0.75s,即到1s时,此时一个计数周期结束,使Led反转一次,LED为1。
设计输入
module counter_led_1(
Clk,
Reset_n,
Led
);
input Clk;
input Reset_n;
output reg Led;
reg [25:0]counter;
//计数周期为1s,1_000_000_000ns/20ns = 50_000_000次
parameter MCUT = 50_000_000;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if (counter == MCUT - 1 )
counter <= 0;
else
counter <= counter + 1'b1;
// LED亮0.25s,灭0.75s
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Led <= 0; //复位的时候,即计数开始的时候,LED为0
else if(counter == MCUT*3/4 - 1) // 灭0.75秒
Led <= 1; //计数到四分之三个周期,即0.75s的时候,LED为1
else if(counter == MCUT - 1) //亮0.25s
Led <= 0; //一个计数周期结束,即1s的时候,LED为0
endmodule
功能仿真代码
`timescale 1ns/1ns
module counter_led_1_tb;
reg Clk;
reg Reset_n;
wire Led;
counter_led_1
#(
.MCUT(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;
#20000000;
$stop;
end
endmodule
功能仿真结果
实验二 让LED灯按照亮0.25秒,灭0.5秒,亮0.75秒,灭1秒的状态循环亮灭
功能分析
一个循环共有四个状态,共2.5s,设置一个计数周期为2.5s,设置Led初始状态为1,即处于亮的状态;
经过0.25s,即到0.25s时,此时计数到十分之一个周期,使Led反转一次,LED为0;
经过0.5s,即到0.75s时,此时计数到十分之三个周期,使Led反转一次,LED为1;
经过0.75s,即到1.5s时,此时计数到十分之六个周期,使Led反转一次,LED为0;
经过1s,即到2.5s时,此时一个计数周期结束,使Led反转一次,LED为1。
设计输入
module counter_led_2(
Clk,
Reset_n,
Led
);
input Clk;
input Reset_n;
output reg Led;
reg [25:0]counter;
//计数周期为2.5s,2_500_000_000ns/20ns = 125_000_000次
parameter MCUT = 125_000_000;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if (counter == MCUT - 1 )
counter <= 0;
else
counter <= counter + 1'b1;
// LED亮0.25s,灭0.5s,亮0.75s,灭1s;共2.5s
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Led <= 1; //复位的时候LED为1
else if(counter == MCUT*1/10 - 1)
Led <= 0; //计数到十分之一个周期,即0.25s的时候,LED为0
else if(counter == MCUT*3/10 - 1)
Led <= 1; //计数到十分之三个周期,即0.75s的时候,LED为1
else if(counter == MCUT*6/10 - 1)
Led <= 0; //计数到十分之六个周期,即1.5s的时候,LED为0
else if(counter == MCUT - 1)
Led <= 1; //计数到一个周期,即2.5s的时候,LED为1
endmodule
功能仿真代码
`timescale 1ns/1ns
module counter_led_2_tb;
reg Clk;
reg Reset_n;
wire Led;
counter_led_2
#(
.MCUT(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;
#2000000;
$stop;
end
endmodule
功能仿真结果
实验三 让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。以0.25秒为一个变化周期,8个变化状态为一个循环。
功能分析
一个循环共有八个状态,一个状态0.25s,则一个循环周期为2s,设置一个计数周期为2s;
设置一个指定亮灭状态的输入端口Ctrl,Ctrl为八位,每一位控制Led的一个状态。
设计输入
module counter_led_3(
Clk,
Reset_n,
Ctrl,
Led
);
input Clk;
input Reset_n;
input [7:0] Ctrl;
output reg Led;
// 八个状态,一个状态0.25s,八个状态一个循环,则一个循环为2s
//计数次数为,2_000_000_000ns/20ns=100_000_000次,计数器要用27位
reg [26:0] counter;
parameter MCUT = 100_000_000;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if (counter == MCUT-1)
counter <= 0;
else
counter <= counter + 1'b1;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Led <= 0;
else if(counter == MCUT*1/8 - 1)
Led <= Ctrl[0];
else if(counter == MCUT*2/8 - 1)
Led <= Ctrl[1];
else if(counter == MCUT*3/8 - 1)
Led <= Ctrl[2];
else if(counter == MCUT*4/8 - 1)
Led <= Ctrl[3];
else if(counter == MCUT*5/8 - 1)
Led <= Ctrl[4];
else if(counter == MCUT*6/8 - 1)
Led <= Ctrl[5];
else if(counter == MCUT*7/8 - 1)
Led <= Ctrl[6];
else if(counter == MCUT*8/8 - 1)
Led <= Ctrl[7];
// always@(posedge Clk or negedge Reset_n)
// if(!Reset_n)
// Led <= 0;
// else case(counter)
// MCUT*1/8 - 1: Led <= Ctrl[0];
// MCUT*2/8 - 1: Led <= Ctrl[1];
// MCUT*3/8 - 1: Led <= Ctrl[2];
// MCUT*4/8 - 1: Led <= Ctrl[3];
// MCUT*5/8 - 1: Led <= Ctrl[4];
// MCUT*6/8 - 1: Led <= Ctrl[5];
// MCUT*7/8 - 1: Led <= Ctrl[6];
// MCUT*8/8 - 1: Led <= Ctrl[7];
// default:Led <= Led;
// endcase
endmodule
功能仿真代码
`timescale 1ns/1ns
module tb_counter_led_3;
reg Clk;
reg Reset_n;
reg [7:0]Ctrl;
wire Led;
counter_led_3
#(
.MCUT(125000)
)
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'b1010_0110;
#2000000;
$stop;
end
endmodule
功能仿真结果
实验四 让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。8个变化状态为一个循环,每个变化状态的时间值可以根据不同的应用场景选择。
功能分析
化零为整,设置八个相同时间段,第一个计数器计数每个时间段,位数和每个时间段时间相匹配,Time的值为计数次数,即代表每个时间段是时间长短,计数器位数和Time位数一致;
第二个计数器计数八个时间段,共8次,需要三位的计数器;
根据计数器2的值,共八个值,通过八位的Ctrl分别控制八个信号的亮灭状态。
设计输入
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 [7:0]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
功能仿真代码
`timescale 1ns/1ns
module tb_counter_led_4;
reg Clk;
reg Reset_n;
reg [7:0]Ctrl;
reg [31:0]Time;
wire Led;
counter_led_4 counter_led_4(
.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;
#201;
Reset_n = 1;
#2000;
Time = 2500; // 2500*20ns=50_000ns 一个时间段
Ctrl = 8'b1000_0110;
#2000000;
$stop;
end
endmodule
功能仿真结果
实验五 让多个LED灯按照设置的模式各自在一个变化循环内独立亮灭变化
功能分析
与实验四基本设计思想相同,区别在于实验四为一个Ctrl控制一个Led,该实验为两个Ctrl控制两个Led
设计输入
module counter_led_5(
Clk,
Reset_n,
CtrlA,
CtrlB,
Time,
Led
);
input Clk;
input Reset_n;
input [7:0]CtrlA,CtrlB;
input [31:0]Time;
output reg [1:0]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:begin Led[0] <= CtrlA[0];Led[1] <= CtrlB[0];end
1:begin Led[0] <= CtrlA[1];Led[1] <= CtrlB[1];end
2:begin Led[0] <= CtrlA[2];Led[1] <= CtrlB[2];end
3:begin Led[0] <= CtrlA[3];Led[1] <= CtrlB[3];end
4:begin Led[0] <= CtrlA[4];Led[1] <= CtrlB[4];end
5:begin Led[0] <= CtrlA[5];Led[1] <= CtrlB[5];end
6:begin Led[0] <= CtrlA[6];Led[1] <= CtrlB[6];end
7:begin Led[0] <= CtrlA[7];Led[1] <= CtrlB[7];end
default:Led <= Led;
endcase
endmodule
功能仿真代码
`timescale 1ns/1ns
module tb_counter_led_5;
reg Clk;
reg Reset_n;
reg [7:0]CtrlA,CtrlB;
reg [31:0]Time;
wire [1:0]Led;
counter_led_5 counter_led_5(
.Clk(Clk),
.Reset_n(Reset_n),
.CtrlA(CtrlA),
.CtrlB(CtrlB),
.Time(Time),
.Led(Led)
);
initial Clk = 1;
always #10 Clk=!Clk;
initial begin
Reset_n = 0;
CtrlA = 0;
CtrlB = 0;
#201;
Reset_n = 1;
#2000;
Time = 2500; // 2500*20ns=50_000ns 一个时间段
CtrlA = 8'b1000_0110;
CtrlB = 8'b0101_0011;
#2000000;
$stop;
end
endmodule
功能仿真结果
知识点总结
通过计数器序列的方式控制最小时间单位一致的多个信号,在SPI,IIC总线中有应用
实验六 每隔10ms,让 LED灯的一个8状态循环执行一次(每个状态的变化时间值小一点,方便测试, 比如设置为10us)
功能分析
计数器counter0计数一个大的时间段,为10ms,在这一个大的时间段内,设置一个EN,当EN为高时,LED的一个8状态循环执行一次,执行完之后,EN拉低;
在EN拉高时,counter2计数
设计输入
//每隔10ms,让 LED灯的一个8状态循环执行一次(每个状态的变化时间值小一点,方便测试, 比如设置为10us)
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周期计数器
reg[2:0]counter2;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter0 <= 0;
else if (counter0 == 500_000 - 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))//counter2 == 7维持满一个时间段
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
功能仿真代码
`timescale 1ns/1ns
module tb_counter_led_6;
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;
#201;
Reset_n = 1;
#2000;
Time = 25000; // 25000*20ns=500_000ns 一个时间段
Ctrl = 8'b0100_0110;
#200000000;
$stop;
end
endmodule
功能仿真结果
知识点总结
可将仿真中用到的所有端口的波形全部显示,用于功能调试