点亮流水灯

目录

1.water_led

2.tb_water_led


点亮流水灯_第1张图片

50MHZ一个周期是20ns,0.5秒就是20ns=0.02um=0.00002ms=0.000_00002s。0.5/0.000_00002s=25_000_000个时钟周期,表示要从0计数到24_999_999

点亮流水灯_第2张图片

LED灯是低电平点亮,前0.5秒点亮第一个LED灯,当检测到脉冲信号点亮第二个灯,然后依次点亮。以上的波形图是采用左移的方式来led_out的赋值的,但是实际会发生错误,因为左移右移都是在空位补零并不会出现如上图的led_out的输出情况,因此考虑增添一个信号。

点亮流水灯_第3张图片

通过对led_out_reg取反就可以得到需要的输出。

1.water_led

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	;
reg  cnt_flag	;
reg [3:0] led_out_reg;

assign led_out=~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-1'b1)
		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;
		//左移,右移这两种移位运算都用0来填补移出的空位
	else
		led_out_reg<=led_out_reg;

endmodule

2.tb_water_led

`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

点亮流水灯_第4张图片

点亮流水灯_第5张图片

Verilog中的逻辑移位和算术移位仿真_verilog 有符号数 左移-CSDN博客

你可能感兴趣的:(FPGA,fpga开发)