目录
设计目标:8个LED灯以每0.5s的速率进行循环闪烁
方法1:移位法实现
设计模块
仿真代码
实验结果
方法2:循环移位方法
设计模块
方法3:使用三八译码器实现流水灯
顶层模块
底层模块
设计目标:8个LED灯以每0.5s的速率进行循环闪烁
当仿真时时间长,可以减小设计代码的计数次数,对分析移位功能没有影响。
方法1:移位法实现
设计模块
module led_run(
Clk,
Reset_n,
led
);
input Clk;
input Reset_n;
output reg [7:0]led;
reg [24:0] counter;
always@(podedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if(counter == 24999999)
counter <= 0;
else
counter <= counter + 1'd1;
always@(podedge Clk or negedge Reset_n)
if(!Reset_n)
led <= 8'b0000_0001;
else if(counter == 24999999)begin
if(led == 8'b1000_0000)
led <= 8'b0000_0001;
else
led <= led << 1;
end
else
led = led;
endmoduule
仿真代码
`timescale 1ns/1ns
module led_run_tb();
reg Clk;
reg Reset_n;
wire [7:0]led;
led_run led_run(
.Clk(Clk),
.Reset_n(Reset_n),
.led(led)
);
initial Clk = 1;
always #10 Clk = ~Clk;
initial begin
Reset_n = 0;
#201;
Reset_n = 1;
#4000000000; //延时4s
$stop;
end
endmodule
实验结果
方法2:循环移位方法
知识点:位拼接
设计模块
module led_run1(
Clk,
Reset_n,
led
);
input Clk;
input Reset_n;
output reg [7:0] led;
reg [24:0] counter;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
// else if(counter == 24999999)
else if(counter == 24999) //500us
counter <= 0;
else
counter <= counter + 1'd1;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
led = 8'b0000_0001;
// else if(counter == 24999999)begin
else if(counter == 24999)
led <= {led[6:0],led[7]}; //位拼接
else
led <= led;
endmodule
方法3:使用三八译码器实现流水灯
知识点:1.计数器记满清零。2. 模块间的调用。
在当前模块中调用三八译码器模块,将38译码器的设计模块添加到当前文件夹中,在led_run2.v中通过接口调用三八译码器。
将led_run2.v中的 led 接到三八译码器的 out 端口上时,led 不能再定义为 reg 型,因为三八译码器底层已经将out定义为reg型。底层已经定义了reg型,顶层就不能再定义reg型。 led是由底层模块驱动的,顶层只能定义为wire型。文章来源:https://www.toymoban.com/news/detail-741425.html
顶层模块
module led_run2(
Clk,
Reset_n,
led
);
input Clk;
input Reset_n;
output [7:0] led;
reg [24:0] counter;
reg [2:0] counter1; //二进制8个状态,3位
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
// else if(counter == 24999999)
else if(counter == 24999) //500us
counter <= 0;
else
counter <= counter + 1'd1;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter1 <= 0;
// else if(counter == 24999999)
else if(counter == 24999)
counter1 <= counter1 + 1'b1;
decoder_3_8 decoder_3_8(
.a(counter1[2]), //counter1[2] 是最高位
.b(counter1[1]),
.c(counter1[0]),
.out(led) //底层已将out定义为reg型,所以顶层不能再定义成reg型
);
endmodule
底层模块
module decoder_3_8(
a,
b,
c,
out
);
input a;
input b;
input c;
output reg [7:0] out;
// 2种写法:reg [7:0] out;
//以always块描述的信号赋值,被赋值对象必须定义为reg类型
//{a,b,c}拼接成了一个三位信号
always@(*)begin
case({a,b,c})
3'b000: out = 8'b0000_0001;
3'b001: out = 8'b0000_0010;
3'b010: out = 8'b0000_0100;
3'b011: out = 8'b0000_1000;
3'b100: out = 8'b0001_0000;
3'b101: out = 8'b0010_0000;
3'b110: out = 8'b0100_0000;
3'b111: out = 8'b1000_0000;
endcase
end
endmodule
defparam写法不能在testbench中生效文章来源地址https://www.toymoban.com/news/detail-741425.html
到了这里,关于5.2 FPGA:基于verilog的LED流水灯设计(多种方法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!