news 2026/9/12 1:47:49

PLFM_RADAR FPGA 黄金参考数据(Golden Reference Hex)管理与再生成指南:AERIS-10 多普勒处理链位精确回归测试实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PLFM_RADAR FPGA 黄金参考数据(Golden Reference Hex)管理与再生成指南:AERIS-10 多普勒处理链位精确回归测试实战

PLFM_RADAR FPGA 黄金参考数据(Golden Reference Hex)管理与再生成指南:AERIS-10 多普勒处理链位精确回归测试实战

【免费下载链接】PLFM_RADAROpen-source, low-cost 10.5 GHz PLFM phased array RADAR system项目地址: https://gitcode.com/GitHub_Trending/pl/PLFM_RADAR

本文以 STALE_NOTICE.md 为骨架,讲解 PLFM_RADAR(AERIS-10 10.5 GHz PLFM 相控阵雷达)FPGA 工程中"已提交黄金参考 Hex 文件"的用途、失效条件与再生成流程。读完本文,你将掌握:何时必须重新生成tb/cosim/real_data/hex/下的黄金数据、如何用 golden_reference.py 一键重建刺激与参考文件、如何用 tb_doppler_realdata.v 等测试台做位精确比对,以及双 16 点 FFT 多普勒架构与定点位宽的底层实现细节。

一、这些 Hex 文件是什么:已提交的黄金参考数据

9_Firmware/9_2_FPGA/tb/cosim/real_data/hex/目录下存放着一批.hex.npy文件,它们是已提交(committed)的黄金参考数据(Golden Reference),专供两条严格的"真实数据位精确回归测试"使用:

  • tb_doppler_realdata.v—— 直接路径:喂入 range-FFT 之后的数据,单独验证多普勒处理器;
  • tb_fullchain_realdata.v—— 全链路路径:range FFT → 距离维抽取(peak detection)→ 多普勒 FFT,验证整条处理链。

所谓"黄金参考",意味着这些文件由独立的 Python 定点模型(golden_reference.py)基于真实雷达数据(ADI CN0566 Phaser,10.525 GHz X 波段 FMCW,4 MSPS)生成,并与 RTL 仿真输出做**逐比特(bit-for-bit)**比对,误差容限为 0(MAX_ERROR = 0)。

与"自我祝福式"(self-blessing)的 golden-generate/compare 测试不同,这些已提交的黄金数据一旦生成便固定下来,RTL 若发生架构级改动(如 32 点 FFT 改成双 16 点 FFT)而黄金数据未同步更新,回归测试就会立刻失败。这正是 run_regression.sh 中把这两条用例标记为"exact match required"的原因。

二、何时必须重新生成(STALE 判定条件)

原文档明确列出四条触发条件——只要多普勒处理管线发生以下任一变更,就必须重新生成黄金数据

触发条件对应 RTL 文件影响面
FFT 尺寸、窗函数、子帧结构变化doppler_processor.v输入输出布局、bin 含义全部改变
蝶形运算、旋转因子查表变化xfft_16.v / fft_engine.v定点算术精度、截断/舍入行为改变
抽取模式、峰值检测逻辑变化range_bin_decimator.v64 个距离 bin 的选择结果改变
旋转因子 ROM 变化fft_twiddle_16.mem(及fft_twiddle_1024.mem所有 FFT 输出数值改变

判定准则:只要上述任一文件被改动,hex/目录下的对应.hex文件即为"过期(STALE)",必须按第三节流程重新生成并提交。反之,若只改动了无关模块(如 USB 接口、CDC),则黄金数据无需变动。

三、如何重新生成:完整命令与逐步解析

原文档给出的标准流程分为两步:先运行 Python 黄金参考模型,再执行一段内联 Python 脚本复制多普勒专用文件。

3.1 第一步:运行黄金参考模型

cd 9_Firmware/9_2_FPGA python3 tb/cosim/real_data/golden_reference.py

该脚本(golden_reference.py)默认处理第 0 帧数据,并支持以下命令行参数:

  • --frame N:选择要处理的帧索引(默认0);
  • --plot:生成 Range-Doppler 图谱、固定点 vs 浮点参考对比与检测点叠加图(保存为golden_reference_plots.png);
  • --threshold N:检测门限(L1 幅度,默认10000)。

输入数据依赖:脚本默认从~/Downloads/adi_radar_data/amp_radar/加载 ADI Phaser 数据集(phaser_amp_4MSPS_500M_300u_256_m3dB.npy及其_config.npy)。这是仓库外的本地数据集,重新生成前需确认该路径存在。

脚本输出内容(全部写入tb/cosim/real_data/hex/):

类别文件说明
刺激文件post_ddc_i/q.hexchirp0_i/q.hexadc_chirp0.hex供 DDC / Range FFT 测试台使用
Range FFTrange_fft_chirp0_i/q.hexrange_fft_all_i/q.npy单 chirp 与 32 chirp 全量结果
多普勒直接路径doppler_map_i/q.hexdoppler_map_i/q.npy直接对前 64 bin 做多普勒 FFT
全链路路径fullchain_range_input.hexdecimated_range_i/q.hexfullchain_doppler_ref_i/q.hex模拟 RTL 真实数据流:range FFT → 抽取 → Doppler
MTI / DC Notchfullchain_mti_ref_*.hexfullchain_mti_doppler_ref_*.hexfullchain_notched_ref_*.hex带 2 脉冲 MTI 与 DC 陷波的全链路参考
CFAR 检测fullchain_cfar_mag/thr/det.hexfullchain_cfar_detections.txtfullchain_detections.txtCA-CFAR 幅度图、门限图、检测标志与检测列表
打包参考doppler_ref_i/q.hexfullchain_doppler_ref_packed.hexfullchain_notched_ref_packed.hex32-bit 打包格式{Q[31:16], I[15:0]},直接供 RTL 比对

3.2 第二步:复制多普勒专用参考文件

python3 -c " import numpy as np, os, shutil h = 'tb/cosim/real_data/hex' # Regenerate packed stimulus from range FFT npy ri = np.load(f'{h}/range_fft_all_i.npy') rq = np.load(f'{h}/range_fft_all_q.npy') with open(f'{h}/doppler_input_realdata.hex','w') as f: for c in range(32): for r in range(64): i=int(ri[c,r])&0xFFFF; q=int(rq[c,r])&0xFFFF f.write(f'{(q<<16)|i:08X}\n') shutil.copy2(f'{h}/doppler_map_i.hex', f'{h}/doppler_ref_i.hex') shutil.copy2(f'{h}/doppler_map_q.hex', f'{h}/doppler_ref_q.hex') "

这段内联脚本做三件事,需要结合源码理解其数据格式约定:

  1. range_fft_all_i/q.npy重建打包刺激golden_reference.pymain()只写了 Range FFT 的 npy 参考,而tb_doppler_realdata.v需要的是 32 chirp × 64 range bin、32-bit 打包({Q[31:16], I[15:0]})的doppler_input_realdata.hex(共 2048 行,chirp-major 顺序);
  2. 复制 I/Q 参考doppler_map_i/q.hexwrite_hex_files写成扁平 16-bit 有符号格式,需复制为测试台读取的doppler_ref_i/q.hex
  3. 格式保证write_hex_files使用signed_to_hex(),负数按二补码输出,且位数按(bits+3)//4补齐,确保$readmemh正确加载。

补充:golden_reference.pymain()中已经为全链路测试生成了fullchain_range_input.hexfullchain_doppler_ref_i/q.hexfullchain_doppler_ref_packed.hex等文件,因此tb_fullchain_realdata.v无需额外复制步骤;第二段脚本只针对直接路径(tb_doppler_realdata.v)补齐缺失的打包刺激。

四、架构基础:双 16 点 FFT 多普勒处理器

原文档指明黄金数据是针对"双 16 点 FFT 多普勒架构(2 个交错 PRI 子帧 × 16 点 Hamming 加窗 FFT)"生成的。这一点必须与代码交叉印证,否则很容易误用旧的 32 点单 FFT 黄金数据。

4.1 子帧结构(doppler_processor.v)

从 doppler_processor.v 源码可确认:

  • CHIRPS_PER_FRAME = 32(每帧总 chirp 数),CHIRPS_PER_SUBFRAME = 16(每子帧 16 个 chirp);
  • 子帧 0(长 PRI,long PRI):chirp 0..15 → Hamming 加窗 → 16 点 FFT → 输出 Doppler bin 0-15;
  • 子帧 1(短 PRI,short PRI):chirp 16..31 → Hamming 加窗 → 16 点 FFT → 输出 Doppler bin 16-31;
  • 输出端口doppler_bin打包为{sub_frame, bin[3:0]},同时提供独立的sub_frame信号(0=长 PRI,1=短 PRI)。

对应地,golden_reference.py 中的run_doppler_fft()逐距离 bin 处理:对每个子帧独立做windowed = chirp * hamming与 16 点 FFT,输出维度为(DOPPLER_RANGE_BINS=64, DOPPLER_TOTAL_BINS=32)

4.2 Hamming 窗系数(Q15 格式)

16 点 Hamming 窗以 Q15 定点保存在golden_reference.pyHAMMING_Q15中(与doppler_processor.v的窗系数一致):

0x0A3D, 0x0E5C, 0x1B6D, 0x3088, 0x4B33, 0x6573, 0x7642, 0x7F62, 0x7F62, 0x7642, 0x6573, 0x4B33, 0x3088, 0x1B6D, 0x0E5C, 0x0A3D

加窗乘法按 RTL 语义实现:(data * hamming + (1<<14)) >> 15,即 Q15 乘法加 0.5 舍入后算术右移 15 位,结果饱和到 16 位。注意系数左右对称(镜像结构),与窗的偶对称性一致。

4.3 16 点 FFT 的定点细节

多普勒 FFT 复用xfft_16.v/fft_engine.v的蝶形单元,其定点约定(golden_reference.pyrun_doppler_fftfft_twiddle_lookup完整复刻):

  • 位反转输入加载;
  • 旋转因子乘法:32-bit × 16-bit = 48-bit,算术右移 15 位(TWIDDLE_W - 1);
  • 蝶形加减在 32 位内部宽度完成;
  • 输出饱和回 16 位有符号。

旋转因子 ROM 来自 fft_twiddle_16.mem(四分一余弦 ROM,按cos_rom[k]cos_rom[N/4-k]及象限取反规则查表),因此该 .mem 文件是黄金数据正确性的关键依赖——这就是原文档把fft_twiddle_16.mem列为再生成触发条件之一的原因。

五、真实数据如何进入管线:AD9484 量化与 IF 上变频

golden_reference.pyload_and_quantize_adi_data()展示了黄金数据的源头处理,值得单独说明:

  1. 取帧:从 ADI 数据取一帧(256 chirp × 1079 采样),仅使用前 32 个 chirp(匹配DOPPLER_CHIRPS)与前 1024 个采样(匹配FFT_SIZE);
  2. 缩放:1024 点 FFT 前向模式无 /N 缩放,相干信号处理增益可达约 300 倍;为避免 16 位输出大量饱和破坏动态范围,输入峰值目标设为约 200(相当于满量程 ADC 以下约 -40 dB 的典型雷达回波),保证 < 0.01% 的 FFT bin 饱和;
  3. 8 位 ADC 刺激:对第 0 chirp 的实部归一化后量化到 8 位无符号(round(x*127+128)后 clip 到 0..255),生成adc_chirp0.hex,用于 DDC 链路验证。

值得一提的设计取舍:ADI 原始数据是 4 MSPS 基带复 IQ,而 AERIS-10 是 400 MSPS 采样、120 MHz 中频的真实 ADC 架构。脚本注释明确说明:不将基带数据上变频到 400 MSPS 中频,而是直接把基带 IQ 作为"post-DDC 等效输入"注入 FFT 之后的阶段。理由很务实——DDC 已由独立的tb_ddc_cosim.v协同仿真覆盖,本数据集聚焦验证"FFT + 多普勒 + 检测"在真实回波数据上的位精确性。这也是刺激文件被命名为post_ddc_i.hex的由来。

六、位精确比对测试台:如何运行与判定

6.1 直接路径测试台 tb_doppler_realdata.v

测试台 的关键参数:

  • 输入:doppler_input_realdata.hex,2048 × 32-bit 打包,chirp-major;
  • 期望:doppler_ref_i.hex/doppler_ref_q.hex,2048 × 16-bit 有符号,range-major(rbin0 × 32 Doppler);
  • 通过准则:全部 2048 个输出 bin 与黄金参考完全一致MAX_ERROR = 0);
  • 超时保护:MAX_CYCLES = 500_000(100 MHz 下 5 ms),另有双倍周期的看门狗。

编译与运行(需在9_Firmware/9_2_FPGA/下执行):

iverilog -Wall -DSIMULATION -g2012 \ -o tb/tb_doppler_realdata.vvp \ tb/tb_doppler_realdata.v doppler_processor.v xfft_16.v fft_engine.v vvp tb/tb_doppler_realdata.vvp

测试台内置 7 项结构检查(复位后进入 IDLE、喂入 2048 样本后进入处理态、输出计数恰为 2048、无超时、处理结束回到 IDLE、首/末输出 bin 地址正确),随后逐样本比对 I/Q 误差,统计Exact matchMax error (I/Q),任何失配打印前 20 个差异点。

6.2 全链路测试台 tb_fullchain_realdata.v

全链路测试台 将range_bin_decimatorINPUT_BINS=1024OUTPUT_BINS=64DECIMATION_FACTOR=16decimation_mode=2'b01即峰值检测)的输出直接接入doppler_processor_optimized,复刻 RTL 真实数据流:

iverilog -Wall -DSIMULATION -g2012 \ -o tb/tb_fullchain_realdata.vvp \ tb/tb_fullchain_realdata.v \ range_bin_decimator.v doppler_processor.v xfft_16.v fft_engine.v vvp tb/tb_fullchain_realdata.vvp

其输入为fullchain_range_input.hex(32768 × 32-bit 打包),期望为fullchain_doppler_ref_i/q.hex,超时放宽到2_000_000周期(抽取 + 多普勒处理需要更长流水时间),通过准则同样是全部 2048 个 Doppler bin 精确匹配。

6.3 在回归套件中的位置

run_regression.sh 在 Phase 2(集成测试)中注册了这两条用例,并明确注释其价值:

Real-data co-simulation: committed golden hex vs RTL (exact match required). These catch architecture mismatches (e.g. 32-pt → dual 16-pt Doppler FFT) that self-blessing golden-generate/compare tests cannot detect.

即:已提交黄金数据与 RTL 的精确比对,能捕获自生成/自比对测试无法发现的架构级漂移(例如从单 32 点 FFT 改成双 16 点 FFT)。执行整套回归:

cd 9_Firmware/9_2_FPGA ./run_regression.sh # 完整回归(含 receiver golden、system top、E2E) ./run_regression.sh --quick # 跳过耗时集成测试,仅跑单元 + 两条真实数据协同仿真

七、与定点模型配套的其它链级参考

除多普勒外,golden_reference.py还以位精确方式建模了整条接收链,理解这些有助于判断"改动波及范围":

链级Python 模型函数对应 RTL关键位宽/参数
ADCload_and_quantize_adi_dataAD9484 接口8-bit 无符号
NCObuild_nco_lut/nco_lookupnco_400m_enhanced.v相位累加 32-bit,NCO_PHASE_INC=0x4CCCCCCD(400 MHz 采样下的 120 MHz IF),64 项四分之一波正弦 LUT,输出 16-bit 有符号
混频器run_ddcddc_400m18-bit × 16-bit = 34-bit,截取[33:16]
CICrun_ddccic_decimator_4x_enhanced.v5 级、4 倍抽取、差分延迟 1,积分器 48-bit、梳状 28-bit,增益右移 10(补偿 4⁵=1024),饱和到 18-bit
FIRrun_ddcfir_lowpass.v32 抽头、18-bit 系数(源码中 32 个 18'sh 十六进制系数在 Python 中逐项复刻)、36-bit 累加器,取[34:17]
DDC 接口run_ddcddc_input_interface18→16 bit,收敛舍入 + 饱和
Range FFTrun_range_fftfft_engine.v1024 点 radix-2 DIT,位反转加载,32-bit 内部宽度,twiddle 乘右移 15,输出饱和 16-bit
距离抽取run_range_bin_decimatorrange_bin_decimator.v三种模式:0=简单抽取(取组内中心样点)、1=峰值检测(I+Q最大)、2=平均(求和 >>4);黄金数据用峰值检测模式
MTIrun_mti_cancellermti_canceller.v2 脉冲对消,首 chirp 输出置零,差分饱和 16-bit
DC 陷波run_dc_notchradar_system_top.v 内联逻辑将两子帧中距 DC 为 ±width 的 bin 清零;width=2时清零{0,1,15,16,17,31}
CA-CFARrun_cfar_cacfar_ca.v幅度 = |I|+|Q|(L1 范数 17-bit),guard=2、train=8、alpha=0x30(Q4.4,即 3.0),阈值饱和 17-bit,支持 CA/GO/SO 三种模式

需要说明的是:golden_reference.py的定点模型刻意**忽略 NCO 抖动(dithering)**以保持位精确可比性,这是黄金数据与 RTL 之间唯一有意的差异来源;其余每个环节(截断位、舍入方式、饱和边界)都严格对齐 RTL 源码中的注释约定。

八、实操清单:何时该跑、跑完看什么

改代码前:先git确认hex/目录下黄金文件未被意外改动;若改动涉及第四节表格中的文件,运行回归前必须重新生成。

重新生成的完整流程

cd 9_Firmware/9_2_FPGA # 1. 确保 ADI 数据集存在于 ~/Downloads/adi_radar_data/amp_radar/ # 2. 重新生成全部黄金参考与刺激文件 python3 tb/cosim/real_data/golden_reference.py --plot # 3. 复制/重建多普勒专用打包文件 python3 -c "..." # 见 3.2 节内联脚本 # 4. 本地验证直接路径与全链路路径 iverilog ... && vvp ... # tb_doppler_realdata iverilog ... && vvp ... # tb_fullchain_realdata # 5. 跑全套回归 ./run_regression.sh

跑完看什么:两条真实数据测试的输出应显示Exact match: 2048 / 2048Max error (I): 0Max error (Q): 0RESULT: ALL TESTS PASSED。若出现失配,测试台会打印前 20 个差异点的(rbin, dbin, RTL值, REF值, 误差),据此定位是 RTL 漂移还是黄金数据过期——前者查doppler_processor.v/xfft_16.v等实现,后者按本文第二节触发条件重新生成。

九、结论

PLFM_RADAR 的黄金参考 Hex 机制是一套"数据驱动 + 位精确"的回归保障体系:以真实 ADI CN0566 雷达回波为输入,用独立 Python 定点模型生成不可篡改的参考,再用两条 iverilog 测试台对 RTL 输出做零容差比对。理解 STALE_NOTICE.md 所规定的"何时重生成、如何重生成、基于何种架构",是维护 AERIS-10 多普勒处理链正确性的关键能力——任何 FFT 架构、抽取逻辑或 twiddle ROM 的变更,都必须同步重建黄金数据并验证全部 2048 个输出 bin 的位精确一致。

【免费下载链接】PLFM_RADAROpen-source, low-cost 10.5 GHz PLFM phased array RADAR system项目地址: https://gitcode.com/GitHub_Trending/pl/PLFM_RADAR

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 1:46:11

SpringBoot+Vue智慧养老系统开发实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 1:45:42

ETSI EN 303 645标准:消费级IoT设备安全实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 1:44:14

Sunshine 游戏串流实战:零成本把 PC 游戏库搬上客厅电视和手机

Sunshine 游戏串流实战&#xff1a;零成本把 PC 游戏库搬上客厅电视和手机 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine 是一款完全免费、开源的自托管游戏串流服务器&…

作者头像 李华