一、概述
众所周知,在我们学习任何一款硬件,不管是单片机MCU,DSP以及其他的一系列硬件在内的最开始接触的都是LED流水灯的实现,这就和我们在学习编程时的输出“Hello World”一样,我们在学习FPGA的过程当中也是要从LED流水灯开始学起。
在FPGA开发中我们不管是实现什么功能,基本上都是需要使用计数器作为基础,这里也不例外。
二、设计代码的编写
//模块定义
module led(
input rst_n,
input clk,
output reg [3:0] led_out
);
//参数定义
parameter TIME_500ms= 25_000_000;
//内部信号定义
reg [24:0] cnt;//计数500ms所需要的二进制位数
wire add_cnt;//计数器开启条件
wire end_cnt;//计数器结束条件
reg [3:0] state_n;
//计数器实现功能,0.5秒技术
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt<=0;
end
else if(add_cnt)begin
if(end_cnt)
cnt<=0;
else
cnt<=cnt+1;
end
else
cnt<=0;
end
assign add_cnt=1'b1;
assign end_cnt=add_cnt && cnt ==(TIME_500ms-1);
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
led_out<=4'b0011;
else if(end_cnt)begin
led_out<={led_out[2:0],led_out[3]};
end
else
led_out<=led_out;
end
endmodule
三、测试文件的编写
//定义时间尺度
`timescale 1ns/1ps
module led_tb();
//重定义
defparam led_inst.TIME_500ms = 25;
//内部变量定义
reg clk;
reg rst_n;
wire [3:0] led_out;
//模块实例化
led led_inst(
/*input */ .rst_n (rst_n ),
/*input */ .clk (clk ),
/*output reg [3:0] */ .led_out (led_out )
);
//时钟
parameter CLK_CLY =20;
initial clk=0;
always #(CLK_CLY/2) clk=~clk;
//复位
initial begin
rst_n =1'b0;
#(CLK_CLY*2);
#3;
rst_n =1'b1;
end
//激励
endmodule
四、波形仿真
在波形图中我们可以看到LED灯从 0001——1000进行不断的循环流水。
四、下板验证