跳到主要内容
FPGA 雷达信号处理指南:从采样到目标检测的系统实现 | 极客日志
C++ 算法
FPGA 雷达信号处理指南:从采样到目标检测的系统实现 综述由AI生成 基于 FPGA 的毫米波雷达信号处理系统设计与实现。内容涵盖雷达基础原理、正交采样与 I/Q 解调、脉冲压缩与匹配滤波、FFT 频域分析、动目标检测 (MTD) 及恒虚警检测 (CFAR) 算法。文章提供了完整的 Verilog 代码示例,包括 DDS 查表、FIR 滤波器、FFT IP 核调用及流水线架构设计。此外,还分析了 FPGA 资源优化、时钟约束、跨时钟域同步及功耗管理策略,并通过 77GHz 雷达案例展示了系统性能指标与实测结果。
利刃 发布于 2026/4/6 更新于 2026/5/30 39 浏览概述
雷达信号处理是 FPGA 应用中最具挑战性的领域之一。从毫米波雷达到相控阵雷达,从目标检测到参数估计,每一个环节都对实时性和计算效率提出了极高的要求。
为什么选择 FPGA 做雷达信号处理?
实时性强 : 毫秒级延迟,满足实时检测需求
并行计算 : 充分利用 DSP 资源进行大规模矩阵运算
功耗低 : 相比 GPU,功耗降低 50-70%
可定制 : 灵活调整算法参数和处理流程
可靠性高 : 工业级应用,支持恶劣环境
一、雷达信号处理基础概念与系统架构
1.1 雷达工作原理快速入门
雷达 (Radio Detection and Ranging) 通过发射电磁波并接收回波来探测目标。理解基本原理是实现信号处理的前提。
1.1.1 基本工作流程
发射信号 → 传播 → 目标反射 → 接收信号 → 信号处理 → 目标检测
关键参数:
发射功率 : 决定探测距离
工作频率 : 毫米波 (77GHz)、微波 (10GHz) 等
脉冲宽度 : 影响距离分辨率
重复周期 : 影响最大不模糊距离
1.1.2 距离与速度测量
距离测量原理:
R = (c × τ) / 2
其中 c 为光速,τ为往返时间
速度测量原理 (多普勒效应):
v = (Δf × c) / (2 × f0)
其中 Δf 为频率偏移,f0 为工作频率
1.1.3 雷达方程
Pr = (Pt × Gt × Gr × λ² × σ) / ((4 π)³ × R ⁴ × L)
Pr: 接收功率
Pt: 发射功率
Gt/Gr: 天线增益
σ: 目标散射截面
L: 系统损耗
1.2 雷达信号处理流程
典型的雷达信号处理包含以下关键环节:
原始采样数据 ↓ 正交采样 (I/Q 解调) ↓ 脉冲压缩 (匹配滤波) ↓ FFT (频域分析) ↓ 动目标检测 (MTD) ↓ 恒虚警检测 (CFAR) ↓ 目标参数估计 ↓ 目标跟踪
各环节的作用:
环节 功能 输入 输出 I/Q 解调 提取基带信号 RF 采样
1.3 FPGA 在雷达系统中的角色
处理延迟:毫秒级
吞吐量:Gbps 级
功耗:瓦级
1.4 系统架构设计
1.4.1 典型系统框图 ┌─────────────┐ │ RF 前端 │ (混频、放大、滤波) └──────┬──────┘ │ ┌──────▼──────┐ │ ADC 采样 │ (多通道、高速) └──────┬──────┘ │ ┌──────▼──────────────────────┐ │ FPGA 信号处理 │ │ ┌──────────────────────┐ │ │ │ I /Q 解调模块 │ │ │ ├──────────────────────┤ │ │ │ 脉冲压缩模块 │ │ │ ├──────────────────────┤ │ │ │ FFT 模块 │ │ │ ├──────────────────────┤ │ │ │ MTD/CFAR 模块 │ │ │ └──────────────────────┘ │ └──────┬──────────────────────┘ │ ┌──────▼──────┐ │ 主处理器 │ (目标跟踪、显示) └─────────────┘
1.4.2 FPGA 内部架构 ┌─────────────────────────────────────┐ │ FPGA 芯片 │ │ │ │ ┌─────────────────────────────┐ │ │ │ AXI 互联 │ │ │ └──┬──────────────────────┬───┘ │ │ │ │ │ │ ┌──▼──┐ ┌──────┐ ┌────▼──┐ │ │ │ I /Q │ │ 脉冲 │ │ FFT │ │ │ │解调 │ │压缩 │ │ IP 核 │ │ │ └──┬──┘ └──┬───┘ └────┬──┘ │ │ │ │ │ │ │ ┌──▼────────▼───────────▼──┐ │ │ │ MTD/CFAR 处理模块 │ │ │ └──┬──────────────────────┘ │ │ │ │ │ ┌──▼──────────────────────┐ │ │ │ BRAM/DDR 缓存 │ │ │ └──────────────────────────┘ │ │ │ └─────────────────────────────────────┘
1.4.3 关键设计考虑
DSP 资源利用率
BRAM 容量规划
LUT/FF 分配
二、正交采样与 I/Q 解调
2.1 正交采样基础 正交采样是将射频信号转换为基带 I/Q 信号的关键步骤。理解其原理对于后续的信号处理至关重要。
2.1.1 为什么需要正交采样 在雷达接收链中,ADC 直接采样射频信号会面临以下问题:
根据奈奎斯特定理,采样率需要 ≥ 2×射频频率
77GHz 毫米波雷达需要采样率 > 154GHz,这对 ADC 要求极高
高采样率导致数据吞吐量巨大
存储和处理成本急剧增加
解决方案:正交采样
通过 I/Q 解调将射频信号转换为基带复信号,可以:
降低采样率至信号带宽的 2 倍
减少数据量 50% 以上
保留所有有用信息
2.1.2 复信号与实信号 s (t) = A ·cos (2 πf_c·t + φ)
s_c (t) = I (t) + j·Q (t) = A ·e^(j(2 πf_c·t + φ))
I(t): 同相分量 (In-phase)
Q(t): 正交分量 (Quadrature)
两者相位差 90°
实信号:双边带频谱 (正负频率)
复信号:单边带频谱 (仅正频率)
2.1.3 采样率选择 f_s ≥ 2 (f_c + B/2 ) (奈奎斯特采样)
实信号采样:f_s ≥ 155GHz (不现实)
I/Q 采样:f_s ≥ 2GHz (可实现)
2.2 I/Q 解调原理 I/Q 解调是将射频信号转换为基带 I/Q 信号的过程。
2.2.1 解调数学原理 s (t) = A ·cos (2 πf_c·t + φ)
LO_I (t) = cos (2 πf_c·t) LO_Q (t) = -sin (2 πf_c·t)
I (t) = s (t)·LO_I (t) = A ·cos (2 πf_c·t + φ)·cos (2 πf_c·t) = A /2 ·[cos(φ) + cos(4πf_c·t + φ)] Q (t) = s (t)·LO_Q (t) = -A ·cos (2 πf_c·t + φ)·sin (2 πf_c·t) = A /2 ·[sin(φ) - sin(4πf_c·t + φ)]
I_bb (t) = A /2 ·cos (φ) Q_bb (t) = A /2 ·sin (φ)
2.2.2 复信号表示 s_bb (t) = I_bb (t) + j·Q_bb (t) = (A/2 )·e^(jφ)
幅度:|s_bb| = A/2 相位:∠s_bb = φ
2.2.3 I/Q 解调框图 ┌─────────────┐ │ RF 信号 │ (77 GHz) └──────┬──────┘ │ ┌──┴──┐ │混频 │ └──┬──┘ │ ┌──┴──────────────┐ │ │ ┌───▼────┐ ┌────▼───┐ │ LPF │ │ LPF │ │(I 路) │ │(Q 路) │ └───┬────┘ └────┬───┘ │ │ ┌───▼────┐ ┌────▼───┐ │ ADC │ │ ADC │ └───┬────┘ └────┬───┘ │ │ └────┬───────────┘ │ ┌────▼────┐ │ I /Q 数据 │ (基带) └─────────┘
2.2.4 本振信号生成
频率精确:与射频频率相同
相位连续:避免相位跳变
正交性好:I/Q 相位差严格 90°
DDS(直接数字合成)
NCO(数控振荡器)
基于 CORDIC 算法
高精度相位控制
支持动态调整
PLL(锁相环)
2.3 FPGA 实现
2.3.1 I/Q 解调模块架构 module iq_demodulator #( parameter DATA_WIDTH = 16, parameter PHASE_WIDTH = 32 )( input clk, input rst_n, // RF 输入 input signed [DATA_WIDTH-1:0] rf_data, input rf_valid, // 本振控制 input [PHASE_WIDTH-1:0] lo_freq, input [PHASE_WIDTH-1:0] lo_phase_init, // I/Q 输出 output signed [DATA_WIDTH-1:0] i_data, output signed [DATA_WIDTH-1:0] q_data, output iq_valid ); // 相位累加器 reg [PHASE_WIDTH-1:0] phase_acc; wire [PHASE_WIDTH-1:0] phase_next; // DDS 正弦波生成 wire signed [DATA_WIDTH-1:0] sin_val, cos_val; // 混频器 wire signed [2*DATA_WIDTH-1:0] i_mix, q_mix; // 相位累加 assign phase_next = phase_acc + lo_freq; always @(posedge clk or negedge rst_n) begin if (!rst_n) phase_acc <= lo_phase_init; else if (rf_valid) phase_acc <= phase_next; end // DDS 查表 dds_lut dds_inst ( .phase(phase_acc[PHASE_WIDTH-1:PHASE_WIDTH-10]), .sin_out(sin_val), .cos_out(cos_val) ); // 混频 assign i_mix = rf_data * cos_val; assign q_mix = rf_data * sin_val; // 低通滤波 (简化示例) assign i_data = i_mix[2*DATA_WIDTH-1:DATA_WIDTH]; assign q_data = q_mix[2*DATA_WIDTH-1:DATA_WIDTH]; assign iq_valid = rf_valid; endmodule
2.3.2 DDS 查表实现 module dds_lut #( parameter PHASE_WIDTH = 10, parameter DATA_WIDTH = 16 )( input [PHASE_WIDTH-1:0] phase, output reg signed [DATA_WIDTH-1:0] sin_out, output reg signed [DATA_WIDTH-1:0] cos_out ); // 四分之一周期查表 (90 个点) reg signed [DATA_WIDTH-1:0] sin_table [0:89]; initial begin // 初始化正弦表 (0 到π/2) sin_table[0] = 16'd0; sin_table[1] = 16'd1144; sin_table[2] = 16'd2287; // ... 更多值 sin_table[89] = 16'd32767; end always @(*) begin case(phase[9:8]) 2'b00: begin // 0 到π/2 sin_out = sin_table[phase[7:0]]; cos_out = sin_table[89-phase[7:0]]; end 2'b01: begin // π/2 到π sin_out = sin_table[89-phase[7:0]]; cos_out = -sin_table[phase[7:0]]; end 2'b10: begin // π到 3π/2 sin_out = -sin_table[phase[7:0]]; cos_out = -sin_table[89-phase[7:0]]; end 2'b11: begin // 3π/2 到 2π sin_out = -sin_table[89-phase[7:0]]; cos_out = sin_table[phase[7:0]]; end endcase end endmodule
2.3.3 低通滤波器 module lpf_fir #( parameter DATA_WIDTH = 16, parameter TAP_NUM = 32 )( input clk, input rst_n, input signed [DATA_WIDTH-1:0] data_in, input data_valid, output signed [DATA_WIDTH-1:0] data_out, output out_valid ); reg signed [DATA_WIDTH-1:0] shift_reg [0:TAP_NUM-1]; wire signed [DATA_WIDTH+8:0] sum; // FIR 系数 (32 阶低通滤波器) reg signed [15:0] coeff [0:TAP_NUM-1]; integer i; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin for (i = 0; i < TAP_NUM; i = i + 1) shift_reg[i] <= 0; end else if (data_valid) begin shift_reg[0] <= data_in; for (i = 1; i < TAP_NUM; i = i + 1) shift_reg[i] <= shift_reg[i-1]; end end // 卷积计算 assign sum = shift_reg[0] * coeff[0] + shift_reg[1] * coeff[1] + // ... 更多项 shift_reg[TAP_NUM-1] * coeff[TAP_NUM-1]; assign data_out = sum[DATA_WIDTH+7:8]; assign out_valid = data_valid; endmodule
2.3.4 关键设计要点
相位累加器宽度决定频率分辨率
32 位相位宽度可达到 mHz 级分辨率
使用 DSP 资源进行乘法
注意数据宽度扩展
考虑舍入误差
截止频率 = 信号带宽
阶数与性能权衡
使用 CIC 或 FIR 滤波器
采样时钟与本振时钟同步
避免时钟抖动
使用 PLL 锁定
三、脉冲压缩与匹配滤波
3.1 脉冲压缩原理 脉冲压缩是雷达信号处理中最关键的技术之一,它解决了探测距离与距离分辨率之间的矛盾。
3.1.1 问题的提出
要提高分辨率,需要减小脉冲宽度 τ
但脉冲宽度减小会导致发射能量减少
能量减少导致探测距离缩短
发射能量:E = A ² × τ 信噪比:SNR = (K² × A ² × τ) / σ²
脉冲越宽,能量越大,SNR 越高,探测距离越远
脉冲越窄,能量越小,SNR 越低,探测距离越近
3.1.2 脉冲压缩的解决方案
发射宽脉冲信号 (保证能量)
对宽脉冲进行特殊调制 (增加带宽)
接收时进行匹配滤波 (压缩脉冲)
得到窄脉冲的效果 (提高分辨率)
原始分辨率:δR = (c × τ₀) / 2 压缩后分辨率:δR ' = (c × τ₀) / (2 × D) = c / (2 B)
3.1.3 线性调频 (LFM) 信号 s (t) = A × rect (t/τ₀) × exp (j × π × K × t²)
A: 幅度
τ₀: 脉冲宽度
K: 调频斜率 (Hz/s)
rect(): 矩形窗函数
波形产生简单 (只需相位累加)
对多普勒频移不敏感
时宽带宽积大 (可达 100 以上)
易于 FPGA 实现
3.2 匹配滤波器设计
3.2.1 匹配滤波原理 最优性证明:
对于加性高斯白噪声,匹配滤波器在输出端达到最大信噪比。
H (f) = K × S*(f) × e^(-j2πft₀)
S(f): 发射信号的傅里叶变换
*: 复共轭
t₀: 时延
y (t) = x (t) * h (t) = ∫ x (τ) × h (t-τ) dτ
3.2.2 LFM 匹配滤波 r (t) = A × rect ((t-t₀)/τ₀) × exp (j × π × K × (t-t₀)²)
h (t) = A × rect (t/τ₀) × exp (-j × π × K × t²)
y (t) = A ² × τ₀ × sinc (π × B × (t - t₀))
其中 sinc(x) = sin(πx)/(πx)
主瓣宽度:2/B (时间域)
第一旁瓣:-13.2dB (相对主瓣)
压缩增益:B × τ₀
3.2.3 旁瓣抑制 窗函数 主瓣宽度 第一旁瓣 应用 矩形窗 2/B -13.2dB 基准 Hamming 窗 2.3/B -43dB 强旁瓣抑制 Hanning 窗 2.3/B -32dB 平衡 Taylor 窗 2.2/B -35dB 最优
3.3 FPGA 实现
3.3.1 脉冲压缩处理流程 接收信号 ↓ LFM 信号生成 ↓ 混频 (频率搬移) ↓ FFT (频域变换) ↓ 匹配滤波 (频域乘法) ↓ IFFT (时域变换) ↓ 取幅度 ↓ 压缩脉冲
3.3.2 时域匹配滤波实现 module pulse_compression #( parameter DATA_WIDTH = 16, parameter FILTER_LEN = 256 )( input clk, input rst_n, // 接收信号 input signed [DATA_WIDTH-1:0] rx_i, input signed [DATA_WIDTH-1:0] rx_q, input rx_valid, // 发射信号 (参考) input signed [DATA_WIDTH-1:0] tx_i, input signed [DATA_WIDTH-1:0] tx_q, // 输出 output signed [DATA_WIDTH+8:0] out_mag, output out_valid ); // 延迟线 reg signed [DATA_WIDTH-1:0] rx_i_delay [0:FILTER_LEN-1]; reg signed [DATA_WIDTH-1:0] rx_q_delay [0:FILTER_LEN-1]; // 累加器 reg signed [DATA_WIDTH+16:0] sum_i, sum_q; integer i; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin for (i = 0; i < FILTER_LEN; i = i + 1) begin rx_i_delay[i] <= 0; rx_q_delay[i] <= 0; end sum_i <= 0; sum_q <= 0; end else if (rx_valid) begin // 移位 for (i = FILTER_LEN-1; i > 0; i = i - 1) begin rx_i_delay[i] <= rx_i_delay[i-1]; rx_q_delay[i] <= rx_q_delay[i-1]; end rx_i_delay[0] <= rx_i; rx_q_delay[0] <= rx_q; // 互相关计算 sum_i <= 0; sum_q <= 0; for (i = 0; i < FILTER_LEN; i = i + 1) begin sum_i <= sum_i + rx_i_delay[i] * tx_i; sum_q <= sum_q + rx_q_delay[i] * tx_q; end end end // 幅度计算 wire signed [DATA_WIDTH+16:0] mag_sq; assign mag_sq = sum_i * sum_i + sum_q * sum_q; assign out_mag = $sqrt(mag_sq); assign out_valid = rx_valid; endmodule
3.3.3 频域匹配滤波实现 module freq_domain_compression #( parameter FFT_SIZE = 256, parameter DATA_WIDTH = 16 )( input clk, input rst_n, // 接收信号 (I/Q) input signed [DATA_WIDTH-1:0] rx_i, input signed [DATA_WIDTH-1:0] rx_q, input rx_valid, // 匹配滤波器系数 (预计算) input signed [DATA_WIDTH-1:0] h_i, input signed [DATA_WIDTH-1:0] h_q, // 输出 output signed [DATA_WIDTH+8:0] out_mag, output out_valid ); // FFT 输出 wire signed [DATA_WIDTH+4:0] fft_i, fft_q; wire fft_valid; // 乘法结果 wire signed [2*DATA_WIDTH+8:0] mul_i, mul_q; // IFFT 输出 wire signed [DATA_WIDTH+4:0] ifft_i, ifft_q; wire ifft_valid; // FFT 模块 fft_core fft_inst ( .clk(clk), .rst_n(rst_n), .data_i(rx_i), .data_q(rx_q), .data_valid(rx_valid), .fft_i(fft_i), .fft_q(fft_q), .fft_valid(fft_valid) ); // 频域乘法 (复数乘法) assign mul_i = fft_i * h_i - fft_q * h_q; assign mul_q = fft_i * h_q + fft_q * h_i; // IFFT 模块 ifft_core ifft_inst ( .clk(clk), .rst_n(rst_n), .data_i(mul_i[2*DATA_WIDTH+7:DATA_WIDTH]), .data_q(mul_q[2*DATA_WIDTH+7:DATA_WIDTH]), .data_valid(fft_valid), .ifft_i(ifft_i), .ifft_q(ifft_q), .ifft_valid(ifft_valid) ); // 幅度计算 assign out_mag = $sqrt(ifft_i*ifft_i + ifft_q*ifft_q); assign out_valid = ifft_valid; endmodule
3.3.4 关键设计要点
时域:低延迟,适合实时处理
频域:高效率,适合长脉冲
流水线设计提高吞吐量
并行处理多个脉冲
内存访问优化
四、FFT 与频域分析
4.1 FFT 在雷达中的应用 FFT(快速傅里叶变换) 是雷达信号处理中最重要的算法之一,它将时域信号转换为频域,实现高效的多普勒处理和目标检测。
4.1.1 为什么需要 FFT
脉冲压缩后的信号仍在时域
无法直接提取多普勒信息
无法进行高效的滤波和检测
直接获得多普勒频移
高效的频域滤波
便于目标检测和参数估计
4.1.2 DFT 与 FFT X (k) = Σ(n=0 to N-1 ) x (n) × W_N^(nk)
DFT: O(N²)
FFT: O(N log N)
N=1024: 加速 100 倍
N=4096: 加速 400 倍
4.1.3 Cooley-Tukey FFT 算法 N 点 FFT = 两个 N/2 点 FFT + 旋转因子乘法
级数:log₂(N)
每级蝶形数:N/2
总蝶形数:(N/2) × log₂(N)
X_out[0] = X_in[0] + X_in[1] × W X_out[1] = X_in[0] - X_in[1] × W
4.1.4 多普勒处理 Δv = (c × Δf) / (2 × f_c × M)
v_max = (c × f_s) / (4 × f_c)
4.2 FPGA FFT IP 核使用 Xilinx 提供的 FFT IP 核是 FPGA 实现 FFT 的最佳选择。
4.2.1 FFT IP 核特性
支持的功能:
正向/反向 FFT(FFT/IFFT)
点数:2^m, m=316 (865536 点)
数据宽度:8~34 bit
相位因子精度:8~34 bit
Radix-2: 通用,资源少
Radix-4: 高效,资源多
流水线 I/O: 高吞吐量
突发 I/O: 低延迟
无缩放:全精度
定点缩放:用户控制
块浮点:自动缩放
4.2.2 位宽管理
蝶形运算位宽增长:
Radix-2 DIT FFT:
每级增长:1 bit 总增长:log₂(N) bit
每级增长:1.58 bit (约 3 bit) 总增长:1.58 × log₄(N) bit
输出宽度 = 输入宽度 + log ₂(N) + 1
输出宽度 = 16 + 10 + 1 = 27 bit
4.2.3 AXI4-Stream 接口 FFT IP 核使用标准 AXI4-Stream 接口。
s_axis_data_tdata: 输入数据
s_axis_data_tvalid: 输入有效
s_axis_data_tlast: 帧结束标志
m_axis_data_tdata: 输出数据
m_axis_data_tvalid: 输出有效
NFFT: FFT 点数
FWD/INV: 正向/反向
SCALE_SCH: 缩放方案
4.3 频域处理
4.3.1 频域滤波 时域信号 → FFT → 频域乘法 → IFFT → 时域结果
避免长卷积
计算量:O(N log N) vs O(N²)
易于实现自适应滤波
4.3.2 多普勒谱图 对每个距离单元:1. 提取该距离的所有脉冲 2. 进行 FFT 3. 取幅度谱
4.3.3 FPGA 实现框架 module fft_processor #( parameter FFT_SIZE = 1024, parameter DATA_WIDTH = 16 )( input clk, input rst_n, // 输入 input signed [DATA_WIDTH-1:0] data_i, input signed [DATA_WIDTH-1:0] data_q, input data_valid, // 输出 output signed [DATA_WIDTH+10:0] fft_mag, output fft_valid ); // FFT IP 核例化 fft_ip_v9_0 fft_inst ( .aclk(clk), .aresetn(rst_n), // 配置接口 .s_axis_config_tdata({ 10'd10, // NFFT = 1024 1'b0, // FWD = FFT 3'b001 // SCALE = 1/N }), .s_axis_config_tvalid(1'b1), // 数据输入 .s_axis_data_tdata({data_q, data_i}), .s_axis_data_tvalid(data_valid), .s_axis_data_tlast(data_valid), // 数据输出 .m_axis_data_tdata({fft_q, fft_i}), .m_axis_data_tvalid(fft_valid), // 事件信号 .event_frame_started(), .event_fft_overflow() ); // 幅度计算 wire signed [DATA_WIDTH+10:0] mag_sq; assign mag_sq = fft_i*fft_i + fft_q*fft_q; assign fft_mag = $sqrt(mag_sq); endmodule
4.3.4 性能指标
1024 点 FFT: ~10000 次操作
4096 点 FFT: ~50000 次操作
LUT: 2000~5000
BRAM: 10~20
DSP: 20~50
最高时钟:250~400 MHz
处理延迟:1~2 μs
吞吐量:250M~400M 样本/秒
五、动目标检测 (MTD) 与 CFAR
5.1 MTD 原理 动目标检测 (Moving Target Detection, MTD) 是利用多普勒效应检测运动目标的关键技术。
5.1.1 MTD 的作用
主要功能:
抑制杂波 (地杂波、海杂波等)
提高运动目标的可检测性
增大信号处理的动态范围
MTI(动目标指示): 简单的差分处理
MTD(动目标检测): 多普勒滤波器组
5.1.2 多普勒滤波器组 每个滤波器对应一个速度 滤波器数 = FFT 点数 速度分辨率 = c × Δf / ( 2 × f_c × M)
H_k (f) = 1 , 当 f = f_d_k H_k (f) = 0 , 当 f ≠ f_d_k
5.1.3 MTD 处理流程 脉冲压缩后信号 ↓ 相干积累 (多脉冲) ↓ FFT (多普勒分析) ↓ 取幅度谱 ↓ MTD 输出 (距离 - 多普勒矩阵)
y (n) = Σ(m=0 to M-1 ) x (n,m) × e^(j2πf_d×m×T_r)
5.1.4 距离 - 多普勒图 行数 = 距离单元数 (脉冲压缩后) 列数 = 多普勒单元数 (FFT 点数)
静止目标:多普勒=0
接近目标:多普勒<0
远离目标:多普勒>0
5.2 CFAR 算法 恒虚警检测 (Constant False Alarm Rate, CFAR) 是自适应目标检测的核心。
5.2.1 CFAR 基本原理
5.2.2 CA-CFAR 算法 最常用的 CFAR 算法是单元平均 CFAR(Cell Averaging CFAR)。
定义检测单元 (CUT)
选择参考单元 (保护单元外)
计算参考单元平均功率
设置门限 = 缩放因子 × 平均功率
判决:若 CUT > 门限,则检测到目标
|参考 | 保护 | 检测 | 保护 | 参考 | | 8 | 2 | 1 | 2 | 8 |
T = α × (1 /N) × Σ(参考单元功率)
5.2.3 其他 CFAR 算法
5.2.4 二维 CFAR 参考窗口 = 距离方向 × 多普勒方向 T = α × (1 /N) × Σ(参考窗口功率)
距离 ↑ │ R R R R R │ R P P P R │ R P C P R │ R P P P R │ R R R R R └─────────→ 多普勒
5.3 FPGA 实现
5.3.1 MTD 处理模块 module mtd_processor #( parameter RANGE_BINS = 256, parameter DOPPLER_BINS = 64, parameter DATA_WIDTH = 16 )( input clk, input rst_n, // 脉冲压缩输入 input signed [DATA_WIDTH-1:0] pc_i, input signed [DATA_WIDTH-1:0] pc_q, input pc_valid, input [7:0] range_idx, input [5:0] pulse_idx, // MTD 输出 output signed [DATA_WIDTH+8:0] mtd_mag, output mtd_valid, output [7:0] out_range, output [5:0] out_doppler ); // 相干积累缓存 reg signed [DATA_WIDTH+6:0] accum_i [0:RANGE_BINS-1][0:DOPPLER_BINS-1]; reg signed [DATA_WIDTH+6:0] accum_q [0:RANGE_BINS-1][0:DOPPLER_BINS-1]; // FFT 输出 wire signed [DATA_WIDTH+10:0] fft_i, fft_q; wire fft_valid; // 相干积累 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin // 清空缓存 end else if (pc_valid) begin accum_i[range_idx][pulse_idx] <= accum_i[range_idx][pulse_idx] + pc_i; accum_q[range_idx][pulse_idx] <= accum_q[range_idx][pulse_idx] + pc_q; end end // FFT 处理 (对每个距离单元) fft_ip_v9_0 fft_inst ( .aclk(clk), .aresetn(rst_n), .s_axis_data_tdata({accum_q[range_idx], accum_i[range_idx]}), .s_axis_data_tvalid(pc_valid), .m_axis_data_tdata({fft_q, fft_i}), .m_axis_data_tvalid(fft_valid) ); // 幅度计算 assign mtd_mag = $sqrt(fft_i*fft_i + fft_q*fft_q); assign mtd_valid = fft_valid; endmodule
5.3.2 CA-CFAR 检测模块 module ca_cfar #( parameter DATA_WIDTH = 16, parameter REF_CELLS = 16, parameter GUARD_CELLS = 2 )( input clk, input rst_n, // 输入 input [DATA_WIDTH-1:0] data_in, input data_valid, // 输出 output target_detected, output [DATA_WIDTH+8:0] threshold ); // 参考单元缓存 reg [DATA_WIDTH-1:0] ref_buffer [0:REF_CELLS-1]; wire [DATA_WIDTH+8:0] ref_sum; // 缩放因子 (可调) parameter SCALE_FACTOR = 16'd2; // 参考单元求和 assign ref_sum = ref_buffer[0] + ref_buffer[1] + ... + ref_buffer[REF_CELLS-1]; // 门限计算 assign threshold = (ref_sum >> 4) * SCALE_FACTOR; // 目标检测 assign target_detected = (data_in > threshold) ? 1'b1 : 1'b0; // 缓存管理 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin // 清空缓存 end else if (data_valid) begin ref_buffer[0] <= data_in; ref_buffer[1] <= ref_buffer[0]; // ... 移位 ref_buffer[REF_CELLS-1] <= ref_buffer[REF_CELLS-2]; end end endmodule
5.3.3 性能指标
检测概率:90%~99%
虚警概率:10^-6 ~ 10^-8
检测增益:10~20 dB
LUT: 1000~3000
BRAM: 5~10
DSP: 10~20
处理延迟:1~5 μs
吞吐量:100M~500M 样本/秒
六、FPGA 实现架构与优化
6.1 流水线架构设计 流水线是 FPGA 实现高性能信号处理的关键技术。
6.1.1 流水线的必要性
提高吞吐量:每个时钟周期处理一个数据
降低延迟:分阶段处理
提高时序:减少单级组合逻辑深度
指标 非流水线 流水线 吞吐量 1 个/N个周期 1 个/周期 延迟 N 个周期 N 个周期 时钟 低 高 资源 少 多
6.1.2 雷达信号处理流水线 ┌─────────┐ │ ADC 采样 │ (第 1 级) └────┬────┘ │ ┌────▼──────────┐ │ I /Q 解调 │ (第 2 -3 级) └────┬──────────┘ │ ┌────▼──────────┐ │ 脉冲压缩 │ (第 4 -6 级) └────┬──────────┘ │ ┌────▼──────────┐ │ FFT │ (第 7 -15 级) └────┬──────────┘ │ ┌────▼──────────┐ │ MTD/CFAR │ (第 16 -18 级) └────┬──────────┘ │ ┌────▼──────────┐ │ 输出 │ (第 19 级) └───────────────┘
6.1.3 流水线寄存器插入 module pipeline_stage #( parameter WIDTH = 16, parameter STAGES = 3 )( input clk, input rst_n, input [WIDTH-1:0] data_in, input valid_in, output [WIDTH-1:0] data_out, output valid_out ); reg [WIDTH-1:0] pipe_data [0:STAGES-1]; reg [STAGES-1:0] pipe_valid; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin pipe_data[0] <= 0; pipe_valid[0] <= 1'b0; end else begin pipe_data[0] <= data_in; pipe_valid[0] <= valid_in; end end genvar i; generate for (i = 1; i < STAGES; i = i + 1) begin always @(posedge clk or negedge rst_n) begin if (!rst_n) begin pipe_data[i] <= 0; pipe_valid[i] <= 1'b0; end else begin pipe_data[i] <= pipe_data[i-1]; pipe_valid[i] <= pipe_valid[i-1]; end end end endgenerate assign data_out = pipe_data[STAGES-1]; assign valid_out = pipe_valid[STAGES-1]; endmodule
6.2 内存优化
6.2.1 BRAM vs 分布式 RAM
容量:36Kb/块
速度:快 (1 个周期)
功耗:低
成本:高
容量:小 (LUT 实现)
速度:快 (1 个周期)
功耗:中等
成本:低
容量 > 100Kb → BRAM 容量 < 10Kb → 分布式 RAM 10Kb ~ 100Kb → 权衡
6.2.2 内存访问优化 地址:0, 1, 2, 3, ... 优点:缓存友好,带宽高
尽量使用顺序访问
使用双端口 RAM
实现缓存机制
6.2.3 双端口 RAM 设计 module dual_port_ram #( parameter ADDR_WIDTH = 10, parameter DATA_WIDTH = 16, parameter DEPTH = 1024 )( input clk, // 读端口 input [ADDR_WIDTH-1:0] rd_addr, output reg [DATA_WIDTH-1:0] rd_data, // 写端口 input [ADDR_WIDTH-1:0] wr_addr, input [DATA_WIDTH-1:0] wr_data, input wr_en ); reg [DATA_WIDTH-1:0] mem [0:DEPTH-1]; always @(posedge clk) begin rd_data <= mem[rd_addr]; end always @(posedge clk) begin if (wr_en) mem[wr_addr] <= wr_data; end endmodule
6.3 时钟约束
6.3.1 时钟约束基础 create_clock -period 5 -name clk [get_ports clk]
period: 时钟周期 (ns)
name: 时钟名称
get_ports: 获取端口
频率 = 1000 / 周期 (ns) 例:周期=5 ns → 频率=200 MHz
6.3.2 多时钟域设计
ADC 采样时钟:200~400MHz
处理时钟:100~250MHz
输出时钟:50~100MHz
create_clock -period 5 -name adc_clk [get_ports adc_clk] create_clock -period 10 -name proc_clk [get_ports proc_clk] create_clock -period 20 -name out_clk [get_ports out_clk]
6.3.3 跨时钟域同步 CDC(Clock Domain Crossing) 问题:
reg sync1, sync2; always @(posedge clk_dst) begin sync1 <= signal_src; sync2 <= sync1; end assign signal_dst = sync2;
// 源时钟域 always @(posedge clk_src) begin if (data_valid && ack) req <= ~req; end // 目标时钟域 always @(posedge clk_dst) begin req_sync <= req; ack <= (req_sync == req); end
6.3.4 时序约束文件示例 # 主时钟 create_clock -period 5 -name clk [get_ports clk] # 输入延迟 set_input_delay -clock clk -min 1 [get_ports data_in] set_input_delay -clock clk -max 2 [get_ports data_in] # 输出延迟 set_output_delay -clock clk -min 0.5 [get_ports data_out] set_output_delay -clock clk -max 1.5 [get_ports data_out] # 虚假路径 set_false_path -from [get_clocks clk_src] -to [get_clocks clk_dst] # 多周期路径 set_multicycle_path 2 -from [get_pins reg1/Q] -to [get_pins reg2/D]
6.4 资源优化
6.4.1 DSP 资源利用
乘法:18×25 bit
加法:48 bit
流水线:3 级
充分利用 DSP 的流水线
避免 DSP 资源浪费
合理分配乘法和加法
6.4.2 LUT 优化
6 输入 LUT
可实现任意 6 变量函数
可配置为分布式 RAM
6.4.3 功耗优化
七、完整工程案例与性能指标
7.1 毫米波雷达案例 本案例基于 77GHz 毫米波雷达的完整 FPGA 实现。
7.1.1 系统规格
工作频率:77GHz
带宽:1GHz
脉冲宽度:100μs
脉冲重复周期:200μs
最大探测距离:200m
距离分辨率:0.15m
速度范围:-100~100 km/h
速度分辨率:0.5 km/h
芯片:Xilinx Zynq-7045
LUT: 215K
BRAM: 545Kb
DSP: 900
工作频率:200MHz
7.1.2 完整系统框图 ┌──────────────┐ │ 77 GHz RF 前端 │ └──────┬───────┘ │ (ADC 采样,400 MHz) ┌──────▼──────────────────────────────────┐ │ FPGA 信号处理 (Zynq-7045 ) │ │ │ │ ┌─────────────────────────────────┐ │ │ │ I /Q 解调 (DDS+ 混频+LPF) │ │ │ │ 资源:2 K LUT, 4 DSP │ │ │ └──────────┬──────────────────────┘ │ │ │ │ │ ┌──────────▼──────────────────────┐ │ │ │ 脉冲压缩 (时域 FIR) │ │ │ │ 资源:5 K LUT, 32 DSP │ │ │ └──────────┬──────────────────────┘ │ │ │ │ │ ┌──────────▼──────────────────────┐ │ │ │ FFT (1024 点,Xilinx IP 核) │ │ │ │ 资源:3 K LUT, 20 BRAM │ │ │ └──────────┬──────────────────────┘ │ │ │ │ │ ┌──────────▼──────────────────────┐ │ │ │ MTD/CFAR (二维处理) │ │ │ │ 资源:4 K LUT, 8 BRAM │ │ │ └──────────┬──────────────────────┘ │ │ │ │ │ ┌──────────▼──────────────────────┐ │ │ │ 目标参数估计 │ │ │ │ 资源:2 K LUT, 10 DSP │ │ │ └──────────┬──────────────────────┘ │ │ │ │ │ ┌──────────▼──────────────────────┐ │ │ │ 输出接口 (AXI/UART) │ │ │ │ 资源:1 K LUT │ │ │ └──────────────────────────────────┘ │ │ │ │ 总资源:17 K LUT, 66 DSP, 28 BRAM │ │ 利用率:8% , 7% , 5% │ └──────┬──────────────────────────────────┘ │ ┌──────▼──────────┐ │ 主处理器 (ARM) │ │ 目标跟踪/显示 │ └─────────────────┘
7.1.3 关键模块实现 输入:400 MHz 采样的 RF 信号 处理:DDS 生成 77 GHz 本振 → 混频 → LPF 输出:200 MHz I /Q 数据 延迟:3 个周期
输入:I /Q 数据 (200 MHz) 处理:256 阶 FIR 匹配滤波 输出:压缩脉冲 (200 MHz) 延迟:256 个周期
输入:压缩脉冲 (200 MHz) 处理:1024 点 FFT 输出:频域数据 (200 MHz) 延迟:1024 个周期
输入:频域数据 (200 MHz) 处理:相干积累 → 二维 CFAR 输出:检测结果 (50 MHz) 延迟:64 个周期
7.2 性能指标
7.2.1 处理性能 采样率:400 MHz 处理延迟:~2 μs 实时处理:✓ (满足要求)
检测概率:95% 虚警概率:10^-7 检测增益:18dB
理论分辨率:0.5 km/h 实际精度:±0.3 km/h
7.2.2 资源消耗 资源 使用 总量 利用率 LUT 17K 215K 8% BRAM 28 545 5% DSP 66 900 7% FF 12K 430K 3%
I/Q 缓存:2 BRAM (256 ×32 bit) 脉冲压缩:4 BRAM (1024 ×16 bit) FFT 中间:8 BRAM (1024 ×32 bit) MTD 矩阵:10 BRAM (256 ×64 ×16 bit) 其他:4 BRAM
7.2.3 时序性能 主时钟:200 MHz (5 ns 周期) ADC 时钟:400 MHz (2.5 ns 周期) 输出时钟:50 MHz (20 ns 周期)
最长路径:FFT 输出 → CFAR 检测 延迟:4.8 ns 时序裕度:0.2 ns
7.3 调试与验证
7.3.1 仿真验证 工具:ModelSim/Vivado 时间:1ms (5000 个采样) 信号:合成 LFM 信号 + 高斯噪声
I/Q 解调正确性
脉冲压缩输出
FFT 频谱
CFAR 检测结果
7.3.2 硬件测试 1. 加载比特流到 FPGA 2. 配置 ADC 采样参数 3. 发送测试信号 4. 采集处理结果 5. 与仿真结果对比
单目标:距离 100m, 速度 50km/h
多目标:3 个目标,不同距离和速度
杂波:高斯白噪声,SNR=10dB
7.3.3 性能评估 检测率 = 正确检测数 / 总目标数 虚警率 = 虚警数 / 总检测数 定位误差 = |估计值 - 真实值|
单目标检测率:99% 多目标检测率:95% 虚警率:< 10^-7 距离误差:< 0.1m 速度误差:< 0.3 km/h
7.4 常见问题与解决方案 原因:组合逻辑过深 解决:增加流水线级数,降低时钟频率
原因:缓存过大 解决:使用 DDR 存储,分块处理
原因:CFAR 参数不合适 解决:调整缩放因子,优化参考窗口
原因:时钟频率过高 解决:降低采样率,使用时钟门控
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online