FPGA开发。包括让8个LED分别以不同的频率闪烁、从计数器到可控线性序列机(让LED灯按照亮0.25秒,灭0.75秒的状态循环亮灭等多个任务).
让8个LED分别以不同的频率闪烁
module led_flash(
Clk,
Reset_n,
Led
);
input Clk;
input Reset_n;
output reg Led;
parameter MCNT = 24999999;
reg [24:0]counter;
always@(posedge Clk or negedge Reset_n)begin
if (!Resnet)
counter <= 0;
else if (counter == MCNT)
counter <= 0;
else
counter <= counter + 1'd1;
end
always@(posedge Clk or negedge Reset_n)begin
if (!Resnet)
Led <= 1;
else if (counter == MCNT)
Led <= !Led;
end
endmodule
================================================================
module Led_run3_test(
Clk;
Reset_n;
Led
);
//例化
input Clk;
input Reset_n;
output [3:0]Led;
Led_flash Led_flash_inst0(
.Clk(Clk);
.Reset_n(Reset_n);
.Led(Led[0])
);
defparam Led_flash_inst0.MCNT = 499999;
Led_flash Led_flash_int1(
.Clk(Clk);
.Reset_n(Reset_n);
.Led(Led[0])
);
defparam Led_flash_inst1.MCNT = 2499999;
Led_flash Led_flash_int2(
.Clk(Clk);
.Reset_n(Reset_n);
.Led(Led[0])
);
defparam Led_flash_inst2.MCNT = 7499999;
Led_flash Led_flash_int3(
.Clk(Clk);
.Reset_n(Reset_n);
.Led(Led[0])
);
defparam Led_flash_inst3.MCNT = 1499999;
endmodule
在开发时,可能会遇到之前的项目具有相同的输入输出,那么此时我们就不必重复定义端口了:
1.一般在项目名\led_run.srcs\constrs_1\new\文件名;
2.打开复制;
3.
4.复制内容到该文件中;
5.
设置为target。
从计数器到可控线性序列机
1.让LED灯按照亮0.25秒,灭0.75秒的状态循环亮灭;
2.让LED灯按照亮0.25秒,灭0.5秒,亮0.75秒,灭1秒的状态循环亮灭;
3.让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。以0.25秒为一个变化周期,8个变化状态为1个循环;
4.让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。8个变化状态为一个循环,每个变化状态的时间值可以根据不同的应用场景选择;
5.让多个LED灯按照设置的模式各自在一个变化循环内独立亮灭变化;
6.每隔10ms,让LED灯的一个8状态循环执行一次(每个状态的变化时间值小一点,方便测试,比如设置为10us)。
让LED灯按照亮0.25秒,灭0.75秒的状态循环亮灭
module led_flash_0(
Clk,
Reset_n,
Led
);
input Clk;
input Reset_n;
output reg Led;
reg [25:0]counter;
parameter MCNT = 50000000;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if(counter == MCNT - 1)
counter <= 0;
else
counter <= counter + 1'b1;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Led <= 0;
else if(counter == MCNT/2 - 1)
Led <= 1;
else if(counter == MCNT - 1)
Led <= 0;
endmodule
=============================================================================
`timescale 1ns / 1ns
module led_flash_tb(
);
reg Clk;
reg Reset_n;
wire Led;
led_flash_0
#(
.MCNT(50000000)
)
led_flash_0(
.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
这是实现0.5s亮,0.5s灭的程序,如果想要0.75s亮,0.25s灭直接修改MCNT处就行。
让LED灯按照亮0.25秒,灭0.5秒,亮0.75秒,灭1秒的状态循环亮灭
module led_flash_1(
Clk,
Reset_n,
Led
);
input Clk;
input Reset_n;
output reg Led;
reg [26:0]counter;
parameter MCNT = 125000000;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if(counter == MCNT - 1)
counter <= 0;
else
counter <= counter + 1'b1;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Led <= 1;
else if(counter == MCNT/10 - 1)
Led <= 0;
else if(counter == MCNT*3/10- 1)
Led <= 1;
else if(counter == MCNT*6/10- 1)
Led <= 0;
else if(counter == MCNT - 1)
Led <= 1;
endmodule
让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。以0.25秒为一个变化周期,8个变化状态为1个循环
2秒为一个循环周期,有一个指定的端口由用户指定亮灭模式
module led_flash_2(
Clk,
Reset_n,
Ctrl,
Led
);
input Clk;
input Reset_n;
input [7:0] Ctrl;
output reg Led;
reg [26:0]counter;
parameter MCNT = 50000000;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if(counter == MCNT - 1)
counter <= 0;
else
counter <= counter + 1'b1;
//always@(posedge Clk or negedge Reset_n)
//if(!Reset_n)
// Led <= 0;
//else if(counter == MCNT/8 - 1)
// Led <= Ctrl[0];
//else if(counter == MCNT/4 - 1)
// Led <= Ctrl[1];
//else if(counter == MCNT*3/8 - 1)
// Led <= Ctrl[2];
//else if(counter == MCNT*4/8 - 1)
// Led <= Ctrl[3];
//else if(counter == MCNT*5/8 - 1)
// Led <= Ctrl[4];
//else if(counter == MCNT*6/8 - 1)
// Led <= Ctrl[5];
//else if(counter == MCNT*7/8 - 1)
// Led <= Ctrl[6];
//else if(counter == MCNT - 1)
// Led <= Ctrl[7];
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Led <= 0;
else case(counter)
MCNT/8 - 1:Led <= Ctrl[0];
MCNT*2/8 - 1:Led <= Ctrl[1];
MCNT*3/8 - 1:Led <= Ctrl[2];
MCNT*4/8 - 1:Led <= Ctrl[3];
MCNT*5/8 - 1:Led <= Ctrl[4];
MCNT*6/8 - 1:Led <= Ctrl[5];
MCNT*7/8 - 1:Led <= Ctrl[6];
MCNT - 1:Led <= Ctrl[7];
default:Led <= Led;
endcase
endmodule
=============================================================================
`timescale 1ns / 1ns
module led_flash_tb(
);
reg Clk;
reg Reset_n;
reg [7:0]Ctrl;
wire Led;
led_flash_2
#(
.MCNT(100000000)
)
led_flash_0(
.Clk(Clk),
.Reset_n(Reset_n),
.Ctrl(Ctrl)
.Led(Led)
);
initial Clk = 1;
always #10 Clk = !Clk;
initial begin
Reset_n = 0;
#201;
Reset_n = 1;
Ctrl = 8'b1000_0111;
#2000000000;
$stop;
end
endmodule
让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。8个变化状态为一个循环,每个变化状态的时间值可以根据不同的应用场景选择
思路:设置一个计数器用于每个状态的计时(这个计时由用户自己定义),设置另一个3位计数器用于一个循环,该计数器在另一个计数器计数达到用户设定的时间时自加1。这个3位计数器不需要清零,在加到111时,会自己清零。
module led_flash_3(
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
让多个LED灯按照设置的模式各自在一个变化循环内独立亮灭变化;
module led_flash_4(
Clk,
Reset_n,
CtrlA,
CtrlB,
Time,
Led
);
input Clk;
input Reset_n;
input [7:0] Ctrl;
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 <= CtrlA[0];Led[1] <= CtrlB[0];end
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
熟悉控制方法,可以控制多个信号
每隔10ms,让LED灯的一个8状态循环执行一次(每个状态的变化时间值小一点,方便测试,比如设置为10us)
EN = 1:counter计数
EN拉低的条件时8个翻转状态结束之时
module led_flash_3(
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;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n) //10ms定时器
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(counter == 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