一、波形变换需求
二、思路
(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