前言
流水灯的效果是让4个LED灯从右往左依次点亮,每次点亮的时间间隔为0.5s。
一、代码
1.rtl代码
代码如下(示例):
module water_led
#(
parameter CNT_MAX=25'd24_999_999
)
(
input wire sys_clk,
input wire sys_rst_n,
output wire [3:0] led_out//输出没有延迟,用组合逻辑
);
reg [24:0] cnt;//十进制24_999_999对应二进制为25位,用计算器
reg cnt_flag;
reg [3:0]led_out_reg;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)
cnt<=25'd0;
else if(cnt==CNT_MAX)
cnt<=25'd0;
else
cnt<=cnt+25'd1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)
cnt_flag<=1'b0;
else if(cnt==(CNT_MAX)-25'd1)
cnt_flag<=1'b1;
else
cnt_flag<=1'b0;
// <<:左移运算符,>>:右移运算符
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)
led_out_reg<=4'b0001;
else if((led_out_reg==4'b1000)&&(cnt_flag==1'b1))
led_out_reg<=4'b0001;
else if(cnt_flag==1'b1)
led_out_reg<=led_out_reg<<1;
else
led_out_reg<=led_out_reg;
assign led_out=~led_out_reg;
endmodule
2.测试代码
代码如下(示例):
`timescale 1ns/1ns
module tb_water_led();
reg sys_clk;
reg sys_rst_n;
wire [3:0] led_out;
initial
begin
sys_clk=1'b1;
sys_rst_n<=1'b0;
#20
sys_rst_n<=1'b1;
end
always #10 sys_clk=~sys_clk;
water_led
#(
.CNT_MAX(25'd24)
)
water_led_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.led_out(led_out)
);
endmodule
三、仿真结果
输出与绘制波形图一致,是左移的。
计数器到达最大值24时又恢复为0,flag信号在最大值-1时拉高电平,与理论一致。