1.设计规划及波形绘制
1.1原理
流水灯原理很简单,不再赘述。
1.2波形绘制及实验目标
实验目标:板子上电后实现四个LED灯从右到左依次点亮,每个灯间隔0.5s(肉眼能够看到流水的时间)
模块框图:

波形绘制:
先给正确的波形展示:

注意:这里使用了一个flag信号,如果不使用,当counter'计数到24999999时led输出跳变也是可以,但是代码编写时,容易出现时序问题,在进入第24999999个周期时,第一个always块,满足第二个条件,会进行counter清零操作。而第二个always块满足counter最大值要进入led跳变操作,则这两个操作可能会混乱。
因此,加一个flag信号,当counter计数到(cnt_max-1)时拉高,则会产生一个一周期的脉冲,实现效果与计数到24999999时led输出跳变一样,且不会产生操作混乱情况。

2.代码编写
2.1 rtl
这里rtl编写注意看好板子手册led灯到底是低电平还是高电平点亮,不要想当然!!!!
向正点这块板子就是高电平点亮(左边高右边接地才能导通。)

module flow_led
#(
parameter cnt_max = 25'd24999999
)
(
input sys_clk ,
input rst_n ,
output reg[3:0] led
);
reg [25:0] counter;
reg cnt_flag;
always @(posedge sys_clk or negedge rst_n) begin
if(!rst_n)
counter <= 'b0;
else if (counter == cnt_max)
counter <= 'b0;
else
counter <= counter +1;
end
always @(posedge sys_clk or negedge rst_n) begin
if(!rst_n)
cnt_flag <= 'b0;
else if(counter == (cnt_max - 1))
cnt_flag <= 'b1;
else
cnt_flag <= 'b0;
end
always @(posedge sys_clk or negedge rst_n) begin
if(!rst_n)
led <= 4'b0001;
else if( (led[3] == 'b0) && (cnt_flag == 'b1) )
led <= led << 1;
else if( (led[3] == 'b1) && (cnt_flag == 'b1) )
led <= (led << 1) + 1;
else
led <= led;
end
endmodule
2.2 tb
`timescale 1ns/1ns
module tb_flow_led();
reg sys_clk;
reg rst_n ;
wire [3:0] led ;
initial begin
sys_clk <= 1'b0;
rst_n <= 1'b0;
#53
rst_n <= 1'b1;
end
//时钟50MHZ
always #10 sys_clk <= ~sys_clk;
flow_led #(
.cnt_max (24999999 ))
u_flow_led(
.sys_clk (sys_clk ),
.rst_n (rst_n ),
.led (led )
);
endmodule
3 逻辑仿真及波形验证
与上面波形图一致。
(本贴仅是个人经验,如有侵权请联系我~)