FPGA Verilog实现一个脉冲波形变换

该博客介绍了如何在FPGA中处理脉冲边沿,实现上升沿和下降沿的检测,并通过计数器计算脉冲宽度和周期。在100MHz系统时钟下,代码实现了脉冲的延迟、同步以及宽度和周期的精确测量,适用于数字信号处理和时序分析。
摘要由CSDN通过智能技术生成

一、波形变换需求

二、思路

(1)脉冲边沿提取,得到波形的上升沿r_rise和下降沿r_fall

(2)将上升沿r_rise延迟一节拍r_r_rise,r_rise更新上一周期的周期和脉宽并清空上一次的脉冲周期计数和脉宽周期计数,r_r_rise启动本次脉冲周期计数和脉宽计数,r_fall结束本次脉宽计数

三、代码

`timescale 1ns / 1ps
module pulse_transfer(
					ttl_in	,// mcu ttl input
					sys_clk	,// 100MHz clk input
					reset_n	,// negtive reset input
					ttl_out,  // fpga ttl output				
				);


/*! -------------------------------------------------------------------------- */
/*!  module port defination */
input							ttl_in	;
input							sys_clk	;
input							reset_n	;
output							ttl_out	;

parameter FRE_SYS		 = 30'd100000000;//100MHz

/*! -------------------------------------------------------------------------- */
/*!  module macro defination */
parameter MAX_PULSE_WIDTH_COUNT	= 16'd20000; /*! max width  200us = 10ns*20000 */
parameter MAX_PULSE_PERIOD_COUNT = 30'd100000000;           /*! max period  1s */
parameter COUNT_OFFSET = 3'd2;
parameter TIME_1US = 8'd100;							
parameter TIME_300NS = 8'd30;

/*! -------------------------------------------------------------------------- */
/*!  get rise and fall edge  */
wire 							w_is_rise_trigger;
wire 							w_is_fall_trigger;
reg							    r_ttl_in_delay;
reg							    r_ttl_in_delay_1;
always	@	(	posedge sys_clk  or negedge reset_n )
begin
	if(	!reset_n )	
		begin
			r_ttl_in_delay   	<=	1'b0	;
			r_ttl_in_delay_1	<=	1'b0	;
		end
	else
		begin
			r_ttl_in_delay	    <=	ttl_in	;
			r_ttl_in_delay_1	<=	r_ttl_in_delay	;
		end
end	

//assign	w_is_rise_trigger =  ~r_ttl_in_delay&ttl_in;
//assign	w_is_fall_trigger =  ~ttl_in&r_ttl_in_delay;

/*! -------------------------------------------------------------------------- */
/*!  synch rise and fall trigger  */
reg								r_is_rise_trigger;
reg								r_is_fall_trigger;
always	@	(	posedge sys_clk or negedge reset_n)
begin
	if(	!reset_n )	
	  begin
		  r_is_rise_trigger <= 1'b0;
		  r_is_fall_trigger <= 1'b0;
		end
	else if({r_ttl_in_delay,r_ttl_in_delay_1} == 2b'10)
		begin
		  r_is_rise_trigger	<= 1'b1;
		  r_is_fall_trigger <= 1'b0;
		end
	else if({r_ttl_in_delay,r_ttl_in_delay_1} == 2b'01)
		begin
		  r_is_rise_trigger	<= 1'b0;
		  r_is_fall_trigger <= 1'b1;
		end
	else 
		begin
		  r_is_rise_trigger <= 1'b0;
		  r_is_fall_trigger <= 1'b0;
		end
end

/*! -------------------------------------------------------------------------- */
/*!  get start count trigger  */
reg								r_count_start_trigger;
wire							w_count_clear_trigger;
assign w_count_clear_trigger = r_is_rise_trigger;
always	@	(	posedge sys_clk or negedge reset_n )
begin
	if(	!reset_n )	
		r_count_start_trigger	<=	1'b0;
	else
		r_count_start_trigger	<=	w_count_clear_trigger;
end	

/*! -------------------------------------------------------------------------- */
/*!  get period and width count enable flag  */
reg								r_is_pulse_period_count_enable;
reg								r_is_pulse_width_count_enable;
always	@	(	posedge sys_clk or negedge reset_n)
begin
	if(	!reset_n )	
		begin
			r_is_pulse_period_count_enable = 1'b0;
			r_is_pulse_width_count_enable = 1'b0;
		end
	else	
		begin
			if( r_is_rise_trigger )
				begin
					r_is_pulse_period_count_enable = 1'b0;
					r_is_pulse_width_count_enable = 1'b0;
				end

			if( r_count_start_trigger )
				begin
					r_is_pulse_width_count_enable  = 1'b1;
					r_is_pulse_period_count_enable = 1'b1;
				end
			
			if( r_is_fall_trigger )
				r_is_pulse_width_count_enable = 1'b0;
		end
end	

/*! -------------------------------------------------------------------------- */
/*!  pulse width and period count handle */
reg			[30:0]				r_pulse_period_count;
reg			[30:0]				r_pulse_period;
reg			[30:0]				r_pulse_width_count;
reg			[30:0]				r_pulse_width;
always	@	(	posedge sys_clk or negedge reset_n )
begin
	if(	!reset_n )	
		begin
			r_pulse_width_count <= 30'd0;
			r_pulse_width <= 30'd0;
			r_pulse_period_count <=	30'd0;
			r_pulse_period <= 30'd0;
		end
	else
		begin
			if(	r_is_rise_trigger )
				begin				
					r_pulse_period_count <= 30'd0;
					r_pulse_width_count <= 30'd0;
				end

			if( r_is_pulse_width_count_enable )
				r_pulse_width_count <= r_pulse_width_count + 1'b1;
			else
				begin
					r_pulse_width <= r_pulse_width_count;
				end

			if( r_is_pulse_period_count_enable )
				r_pulse_period_count <= r_pulse_period_count + 1'b1;
			else
				begin
					r_pulse_period <= r_pulse_period_count;
				end
		end
end

/*! -------------------------------------------------------------------------- */
/*!  output pulse handle */
reg			[30:0]			r_out_cnt;
reg							r_ttl_out;		
always	@	(	posedge sys_clk or negedge reset_n )
begin
	if(	!reset_n )	
		begin
			r_ttl_out <= 1'b0;
			r_out_cnt <= 1'b0;
		end
	else
		begin
			//if( r_pulse_period > MAX_PULSE_PERIOD_COUNT || r_pulse_width > MAX_PULSE_WIDTH_COUNT)
			//	begin
			//		r_ttl_out <= 1'b0;
			//		r_out_cnt <= 1'b0;
			//	end
			//else
			if(r_pulse_period == 0 || r_pulse_width == 0)
				begin
					r_out_cnt <= 1'b0;
				end
			else
				begin
					if( r_pulse_width <= TIME_1US + 4'd10 )//*note in <1.1us case
						begin
							if( r_out_cnt < TIME_300NS )//0.3us
								begin
									r_ttl_out <= 1'b1;
									r_out_cnt <= r_out_cnt + 1'b1;
								end
							else if ( r_out_cnt < r_pulse_period )
									begin
										r_ttl_out <= 1'b0;
										r_out_cnt <= r_out_cnt + 1'b1;	
									end
								else
									begin
										r_ttl_out <= 1'b0;	
										r_out_cnt <= 1'b0;	
									end
						end
					else
						begin
							if( r_out_cnt < r_pulse_width - TIME_1US)//*note -1us
								begin
									r_ttl_out <= 1'b1;
									r_out_cnt <= r_out_cnt + 1'b1;
								end
							else if ( r_out_cnt < r_pulse_period )
									begin
										r_ttl_out <= 1'b0;
										r_out_cnt <= r_out_cnt + 1'b1;	
									end
								else
									begin
										r_ttl_out <= 1'b0;	
										r_out_cnt <= 1'b0;	
									end
						end
				end
		end
end

/*! -------------------------------------------------------------------------- */
/*!  output assign handle */
assign	ttl_out	= r_ttl_out;
 
endmodule

四、行为仿真

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值