需要实现的效果
波形图如下,时钟周期假设为50MHz,每隔0.5s转换一次灯的效果。
Verilog代码如下
module water_led
#(parameter CNT_MAX=25'd24_999_999)
(
input wire sys_clk,
input wire sys_rst_n,
output reg [3:0]led_out
);
reg [24:0]cnt;
reg cnt_flag;
always@(posedge sys_clk or negedge sys_rst_n)
begin
if(sys_rst_n==1'b0)
cnt<=25'd0;
else if(cnt==CNT_MAX)
cnt<=25'd0;
else
cnt<=cnt+25'd1;
end
always@(posedge sys_clk or negedge sys_rst_n)
begin
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;
end
always@(posedge sys_clk or negedge sys_rst_n)
begin
if(sys_rst_n==1'b0)
led_out<=4'b1110;
else if((led_out==4'b0111)&&(cnt_flag==1'b1))
led_out<=4'b1110;
else if(cnt_flag==1'b1)
led_out<=~((~led_out)<<1);//由于循环左移是补0,需要特别地注意这一点
else
led_out<=led_out;
end
endmodule
仿真测试代码
`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))//假设计数的最大值为25
water_led_inst
(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.led_out(led_out)
);
endmodule
vivado仿真波形
计数到最大值减1是产生一个时钟脉冲,并且led灯变换一次状态,
vivado波形图整体状态