基于FPGA的低延迟实时雷达脉冲压缩处理方法

学习摘自FPGA开源工作室

一、背景知识

雷达是一种对目标进行测距与测速的设备。为了提高测距精度,要求雷达脉冲信号具有大的带宽B;为了提高测速精度,要求雷达脉冲信号具有大的时宽T;同时为了提高测距范围,要求信号具有大的能量。一般在系统的发射峰值功率受限的情况下,大的能量只能通过加大信号的时宽来解决,因此,要提高雷达发现目标的能力,需要雷达信号具有大的时宽和带宽,大时宽带宽的信号是通过脉冲压缩处理来实现的。
在这里插入图片描述

雷达脉冲压缩即信号的匹配滤波,主要有时域和频域两种算法,由于雷达脉冲时宽的可变性,时域算法需要设计可变点数的匹配滤波器,基于FPGA实现需要预留最大可能点数的乘法器资源,本文基于频域算法来实现。

二、频域脉冲压缩算法原理框图

图1 频域脉冲压缩算法原理框图
图1 频域脉冲压缩算法原理框图

其中X(n)为大时宽带宽回波信号,H(n)为大时宽带宽信号。

三、低延迟实时雷达脉冲压缩算法原理

1、FPGA中的FFT核可以用来实现频域算法中所需的FFT和IFFT,其点数是相对固定的,经过FFT(IFFT)处理的延时也是相对固定的,受制于FFT(IFFT)的运算点数,常规算法需要舍弃一段雷达探测距离,同时大点数的FFT(IFFT)运算有很大的处理延时;

2、一般雷达回波信号的长度远远大于发射的脉冲信号长度,基于等效快速卷积的频域算法的优势难以表现,对距离接收窗内的回波进行分段,再通过重叠相加法实现完整回波的脉冲压缩可以通过小点数的脉冲压缩来实现全点数的脉冲压缩;

3、FFT(IFFT)点数是通过雷达发射脉宽时长与FPGA采样率来确定的,假设雷达发射脉宽对应的点数为,则FFT(IFFT)点数
在这里插入图片描述
其中,nextpow2(x)表示最靠近的基数2的幂指数。

4、FFT(IFFT)点数是超过雷达发射脉宽点数的,需要通过补零来实现快速卷积与线性卷积的等效,因此,回波信号的分段长度

在这里插入图片描述

5、大时宽带宽回波信号的补零点数为,大时宽带宽信号的补零点数为

6、由于雷达回波的持续性,要实时处理,需要通过FPGA乒乓操作来实现,具体实现如下图所示:
在这里插入图片描述

图2 低延迟实时雷达脉冲压缩算法原理

四、FPGA实现

//==确定FFT点数以及补零个数以及回波信号每帧的点数==//
always @ ( posedge clk or negedge rst_n)
begin
   if ( rst_n == 1'b0 ) begin
       n_fft <= 8'b00000000;       //IP核设置的最大点数为1024
       n_zero <= 32'd0;
       n_data <= 16'd0;
       delay  <= 16'd0;
       shift_position <= 16'd0;
   end
   else begin
       if ( pulse_width[15:0] > 16'd1024 ) begin
            n_fft <= 8'b0000_1100;
            n_zero <= 32'd4096;
            n_data <= 16'd4097 -pulse_width[15:0];
            delay  <= 16'd4094;//原为2047
           shift_position <=16'd4096 -  pulse_width[15:0];
       end
       else if ( pulse_width[15:0] > 16'd512 ) begin     //点数超过512
            n_fft <= 8'b0000_1011;
            n_zero <= 32'd2048;
            n_data <= 16'd2049 -pulse_width[15:0];
            delay  <= 16'd2046;//原为2047
            shift_position <= 16'd2048-  pulse_width[15:0];
       end
       else if ( pulse_width[15:0] > 16'd256 ) begin //点数超过256
            n_fft <= 8'b0000_1010;
            n_zero <= 32'd1024;
            n_data <= 16'd1025 -pulse_width[15:0];
            delay  <= 16'd1022;
            shift_position <= 16'd1024-  pulse_width[15:0];
       end
       else if ( pulse_width[15:0] > 16'd128 ) begin //点数超过128
            n_fft <= 8'b0000_1001;
            n_zero <= 32'd512;
            n_data <= 16'd513 -pulse_width[15:0];
            delay  <= 16'd510;
            shift_position <= 16'd512 -  pulse_width[15:0];
       end
       else if ( pulse_width[15:0] > 16'd64 ) begin //点数超过64
            n_fft <= 8'b0000_1000;
            n_zero <= 32'd256;
            n_data <= 16'd257 -pulse_width[15:0];
            delay  <= 16'd254;
            shift_position <= 16'd256 -  pulse_width[15:0];
       end
       else begin
            n_fft <= 8'b0000_0111;
           n_zero <= 32'd128;
            n_data <= 16'd129 -pulse_width[15:0];
            delay  <= 16'd126;
            shift_position <= 16'd128 -  pulse_width[15:0];
       end
   end
end
 
//==回波信号补零FFT输入数据流控制==////////////////////////////
always @ ( posedge clk or negedge rst_n)
begin
   if ( rst_n == 1'b0 ) begin
       catch_st <= CATCH_IDLE;
ch1_catch <= 1'b0;
ch2_catch <= 1'b0;
n_data_cnt <= 16'd0;
catch_1_num <= 16'd0;
catch_2_num <= 16'd0;
   end
   else begin
       case(catch_st)
       CATCH_IDLE:begin
            if ( fft1_s_axis_data_tvalid ==1'b0 && echo_data_valid == 1'b1 ) begin
                catch_st <= CATCH_MID1;
                ch1_catch <= 1'b1;
                ch2_catch <= 1'b0;
                n_data_cnt <= 16'd1;
                catch_1_num <= 16'd1;
                catch_2_num <= 16'd0;
            end
            else if ( fft2_s_axis_data_tvalid== 1'b0 && echo_data_valid == 1'b1 ) begin
                catch_st <= CATCH_MID2;
                ch1_catch <= 1'b0;
                ch2_catch <= 1'b1;
                n_data_cnt <= 16'd1;
                catch_1_num <= 16'd0;
                catch_2_num <= 16'd1;
            end
            else begin
                catch_st <= CATCH_IDLE;
                n_data_cnt <= 16'd0;
                ch1_catch <= 1'b0;
                ch2_catch <= 1'b0;
                catch_1_num <= 16'd0;
                catch_2_num <= 16'd0;
            end
       end
        CATCH_MID1:begin
             if ( n_data_cnt < n_data ) begin
                catch_st <= CATCH_MID1;
                ch1_catch <= 1'b1;
                ch2_catch <= 1'b0;
                n_data_cnt <= n_data_cnt +1'b1;
                catch_1_num <= n_data_cnt +1'b1;
             end
             else if ( echo_data_valid == 1'b1)begin
                ch1_catch <= 1'b0;
                 ch2_catch <= 1'b1;
                 catch_st <= CATCH_MID2;
                 n_data_cnt <= 16'd1;
                 catch_2_num <= 16'd1;
             end
             elsebegin
                catch_st <= CATCH_IDLE;
                n_data_cnt <= 16'd0;
                ch1_catch <= 1'b0;
                ch2_catch <= 1'b0;
                catch_1_num <= 16'd0;
                catch_2_num <= 16'd0;
             end
        end
         CATCH_MID2:begin
             if ( n_data_cnt < n_data  ) begin
                catch_st <= CATCH_MID2;
                ch1_catch <= 1'b0;
                ch2_catch <= 1'b1;
                n_data_cnt <= n_data_cnt +1'b1;
                catch_2_num <= n_data_cnt +1'b1;
             end
             elseif ( echo_data_valid == 1'b1 )begin
                 ch1_catch <= 1'b1;
                 ch2_catch <= 1'b0;
                 catch_st <= CATCH_MID1;
                 n_data_cnt <= 16'd1;
                 catch_1_num <= 16'd1;
             end
             elsebegin
                catch_st <= CATCH_IDLE;
                n_data_cnt <= 16'd0;
                ch1_catch <= 1'b0;
                ch2_catch <= 1'b0;
                catch_1_num <= 16'd0;
                catch_2_num <= 16'd0;
             end
         end
       endcase
   end
end
always @ ( posedge clk or negedge rst_n)
begin
   if ( rst_n == 1'b0 ) begin
       fft1_tdata <= 32'd0;
       fft1_tvalid <= 1'b0;
       fft2_tdata <= 32'd0;
       fft2_tvalid <= 1'b0;
       fft1_cnt <= 32'b0;
       fft2_cnt <= 32'b0;
   end
   else begin
        if ( ch1_catch == 1'b1 ) begin
             fft1_cnt <= catch_1_num;
            if ( echo_data_valid_i == 1'b1 )begin
                 fft1_tdata <={echo_imag_data_i,echo_real_data_i};
            end
            else begin
                fft1_tdata <= 32'd0;
            end
            fft1_tvalid <= 1'b1;
         end
         elseif ( (fft1_cnt < n_zero) && (fft1_tvalid == 1'b1) ) begin
            fft1_cnt <= fft1_cnt + 1'b1;
            fft1_tdata <= 32'b0;
            fft1_tvalid <= 1'b1;
         end
         elsebegin
            fft1_cnt <= 32'b0;
            fft1_tdata <= 32'b0;
            fft1_tvalid <= 1'b0;
         end
 
       if ( ch2_catch == 1'b1 ) begin
            fft2_cnt <= catch_2_num;
            if ( echo_data_valid_i == 1'b1 )begin
                 fft2_tdata <={echo_imag_data_i,echo_real_data_i};
            end
            else begin
                fft2_tdata <= 32'd0;
            end
            fft2_tvalid <= 1'b1;
         end
         elseif ( (fft2_cnt < n_zero) && (fft2_tvalid == 1'b1) ) begin
            fft2_cnt <= fft2_cnt + 1'b1;
            fft2_tdata <= 32'b0;
            fft2_tvalid <= 1'b1;
         end
         elsebegin
            fft2_cnt <= 32'b0;
            fft2_tdata <= 32'b0;
            fft2_tvalid <= 1'b0;
         end
    end
end
//==FFT与IFFT例化示例
fft_pc fft_pc_inst10 (
              .aclk(clk),                                                 
              .aresetn(rst_n),                                          
             .s_axis_config_tdata(s_fft_config_tdata),                 
             .s_axis_config_tvalid(s_fft_config_tvalid),               
             .s_axis_config_tready(s_fft_config_tready10),               
             .s_axis_data_tdata(fft1_s_axis_data_tdata),                
             .s_axis_data_tvalid(fft1_s_axis_data_tvalid),              
              .s_axis_data_tready(s_axis_data_tready_10),                   
              .s_axis_data_tlast(1'b0),                                      
             .m_axis_data_tdata(m_axis_data_tdata_10),                  
             .m_axis_data_tuser({expt_10,position_10}),      
             .m_axis_data_tvalid(m_axis_data_tvalid_10),                
             .m_axis_data_tready(m_axis_data_tready),                                 
              .m_axis_data_tlast( ),                                     
              .m_axis_status_tdata(),                                    
             .m_axis_status_tvalid(m_axis_status_tvalid_10),            
             .m_axis_status_tready(m_axis_status_tready),                               
              .event_frame_started(),              
              .event_tlast_unexpected(),        
              .event_tlast_missing(),              
             .event_status_channel_halt(),  
              .event_data_in_channel_halt(),
              .event_data_out_channel_halt()
);
 
ifft_pc ifft_pc_inst10 (
              .aclk(clk),                                                
              .aresetn(rst_n),                                          
             .s_axis_config_tdata(s_ifft_config_tdata),                 
             .s_axis_config_tvalid(s_ifft_config_tvalid),               
             .s_axis_config_tready(s_ifft_config_tready10),               
             .s_axis_data_tdata({4'b0,ifft10_in_data_Q,4'b0,ifft10_in_data_I}),
              .s_axis_data_tvalid(ifft10_in_data_valid),              
             .s_axis_data_tready(s_ifft_data_tready10),                   
              .s_axis_data_tlast(1'b0),                                      
              .m_axis_data_tdata(m_ifft_data_tdata_10),                  
             .m_axis_data_tuser({ifft1_expt,ifft1_position}),      
             .m_axis_data_tvalid(m_ifft_data_tvalid_10),                
             .m_axis_data_tready(m_ifft_data_tready),                                  
              .m_axis_data_tlast( ),                                     
              .m_axis_status_tdata(),                                    
             .m_axis_status_tvalid(m_ifft_status_tvalid_10),            
             .m_axis_status_tready(m_ifft_status_tready),                               
              .event_frame_started(),              
              .event_tlast_unexpected(),        
              .event_tlast_missing(),              
              .event_status_channel_halt(),  
              .event_data_in_channel_halt(),
              .event_data_out_channel_halt()
);
 
//==重叠相加法示例代码
always @ ( posedge clk or negedge rst_n)
begin
   if ( rst_n == 1'b0 ) begin
       pc_data_valid <= 1'b0;
       pc_real_data  <= 32'd0;
       pc_imag_data  <= 32'd0;
       pc_status_cnt <= 16'd0;
       pc_status     <= 16'd0;
   end
   else begin
       case({ifft_data_tvalid_10,ifft_data_tvalid_20})
       2'b00:begin
            pc_data_valid <= 1'd0;
            pc_real_data  <= 32'd0;
            pc_imag_data  <= 32'd0;
            pc_status     <= 16'd0;
            pc_status_cnt <=-{pulse_width[15],pulse_width[15:1]} + 1'b1;
       end
       2'b10:begin
            if ( pc_status_cnt <= jam_window_length) begin
                pc_data_valid <= 1'd1;
                pc_status     <= pc_status_cnt;
            end
            else begin
                pc_data_valid <= 1'd0;
                pc_status     <= 16'd0;
            end
            pc_real_data  <={ifft_data_tdata_10_i[31],ifft_data_tdata_10_i[31 :1]};
            pc_imag_data  <={ifft_data_tdata_10_i[63],ifft_data_tdata_10_i[63:32]};
            pc_status_cnt <= pc_status_cnt +1'b1;
       end
       2'b01:begin
            if ( pc_status_cnt <=jam_window_length ) begin
                pc_data_valid <= 1'd1;
                pc_status     <= pc_status_cnt;
            end
            else begin
                pc_data_valid <= 1'd0;
                pc_status     <= 16'd0;
           end
            pc_real_data <={ifft_data_tdata_20_i[31],ifft_data_tdata_20_i[31 :1]};
            pc_imag_data <={ifft_data_tdata_20_i[63],ifft_data_tdata_20_i[63:32]};
            pc_status_cnt <= pc_status_cnt +1'b1;
       end
       2'b11:begin
            if ( pc_status_cnt <=jam_window_length ) begin
                pc_data_valid <= 1'd1;
                pc_status     <= pc_status_cnt;
            end
            else begin
                pc_data_valid <= 1'd0;
                pc_status     <= 16'd0;
            end
            pc_real_data <={ifft_data_tdata_10_i[31],ifft_data_tdata_10_i[31:1]} +{ifft_data_tdata_20_i[31],ifft_data_tdata_20_i[31 :1]};
            pc_imag_data <={ifft_data_tdata_10_i[63],ifft_data_tdata_10_i[63:32]} + {ifft_data_tdata_20_i[63],ifft_data_tdata_20_i[63:32]};
            pc_status_cnt <= pc_status_cnt +1'b1;
       end
       endcase
   end
end

五、FPGA仿真结果

在这里插入图片描述
图3 大时宽带宽回波信号

在这里插入图片描述

图4 大时宽带宽回波经脉冲压缩后的信号

六、matlab仿真对比结果

在这里插入图片描述

图5 matlab仿真参数

在这里插入图片描述
图6 常规脉冲压缩算法实现结果

在这里插入图片描述

图7 分段卷积脉冲压缩算法实现结果

发布了32 篇原创文章 · 获赞 2 · 访问量 1511

猜你喜欢

转载自blog.csdn.net/qq_36248682/article/details/105345664