☰
ZC706+ADRV9009 no-os工程实战:HDL与SDK裸机驱动JESD204B链路搭建
2026/10/17 3:49:08 网站建设 项目流程

简介:本资源为基于Xilinx ZC706开发板与ADI ADRV9009高性能接收器的完整工程包,面向FPGA开发者、嵌入式工程师及高速信号处理方向的研究人员,提供从HDL硬件设计到no-os裸机SDK软件实现的端到端参考案例,可用于无线通信、雷达、测试测量等场景的原型验证。压缩包共约2000个文件,整体201.1MB,以Verilog源码、Tcl脚本、XDC约束、Makefile、C头文件与源文件、XCI IP核配置为主,另含VHDL、SystemVerilog、SDC时序约束及日志报告等,覆盖时钟管理、数据同步、JESD204接口、DMA读写与寄存器映射等模块。目前已有3842人学习下载。工程同时包含HDL与SDK两部分,读者可借此理解FPGA与高速ADC协同工作的接口逻辑、无操作系统下的任务调度与驱动编写方法,并参考现有目录结构快速搭建低延迟、高实时性的信号采集与处理原型系统。

1. 拿到 zc706_adrv9009.rar 之后:这套 HDL + SDK 工程到底能跑出什么

如果你手头正好有一块 ZC706 开发板和一块 ADRV9009 射频收发芯片,又不想从零去啃 ADI 那套庞大的参考设计,那这个 zc706_adrv9009.rar 大概率就是你要找的东西。它把 FPGA 侧的 HDL 工程和处理器侧的 SDK 软件工程打包在一起,走的是 no-os 路线——也就是说,ARM 核上不跑 Linux,直接裸机操作 ADRV9009 的寄存器、配置收发通道、跑 JESD204B 链路。这种组合在快速验证射频链路、做原型收发测试的时候特别省事,不用折腾设备树和内核驱动,上电就能对着寄存器读写。适合谁?一类是做射频前端验证的 FPGA 工程师,另一类是想拿 ADRV9009 做教学或预研的嵌入式开发者。下面我就按“这工程长什么样 → 怎么把它跑起来 → 想改的时候从哪下手”的顺序,把这份资源拆开讲一遍。

2. 工程结构拆解:HDL 顶层、JESD204B 链路和 SDK 裸机驱动怎么串起来

2.1 HDL 侧:从顶层文件看数据通路

拿到压缩包解压之后,HDL 部分通常是一个 Vivado 工程目录,里面最核心的是顶层文件,一般叫system_top.v或者zc706_adrv9009_top.v。这个顶层干的事不复杂,就是把 ADRV9009 的物理接口(LVDS 或者 JESD204B 的 SERDES lane)和 ZC706 上的 FMC 接口对接起来,再往内部挂上 ADI 的 IP 核。常见做法是直接调用 ADI 提供的axi_adrv9009IP,里面封装了 JESD204B 的 PHY、链路层和 ADC/DAC 的数据打包逻辑。

我一般会先看顶层里这几个信号:

// 顶层里典型的 JESD204B 接口信号 output [3:0] rx_data_p, // 接收数据差分对 output [3:0] rx_data_n, input [3:0] tx_data_p, // 发送数据差分对 input [3:0] tx_data_n, output rx_sysref, // SYSREF 同步信号 output tx_sysref, input rx_sync, // SYNC 信号,链路建立用 output tx_sync

这些信号直接连到 FMC 连接器上,对应 ADRV9009 评估板的引脚。逻辑说明:rx_data_p/n和tx_data_p/n是高速 SERDES 差分对,JESD204B 用它们传 IQ 采样数据;sysref用来做多芯片同步,sync是链路握手信号。参数上,lane 数量取决于你配置的 JESD204B 模式(比如 2 lane 还是 4 lane),这个在 IP 核的配置界面里改,改完要重新生成 IP 并综合。

2.2 SDK 侧:no-os 驱动怎么初始化 ADRV9009

SDK 工程里通常有一个main.c和一个adrv9009.c驱动文件。no-os 的意思是没有操作系统,所有初始化都靠顺序调用。典型流程是:先初始化 SPI 和 GPIO,然后读 ADRV9009 的芯片 ID 确认通信正常,再加载 ADI 提供的talise固件(ADRV9009 内部叫 Talise),最后配置收发通道的采样率、本振频率、增益模式。

// main.c 里典型的初始化片段 spi_init(); // 初始化 SPI 控制器 gpio_init(); // 初始化复位和使能引脚 adrv9009_reset(); // 硬件复位 id = adrv9009_read_reg(0x0000); // 读芯片 ID,正常应该是 0x00AD if (id != 0x00AD) { printf("ADRV9009 not detected!\n"); while(1); } adrv9009_load_firmware(); // 加载 Talise 固件 adrv9009_setup_jesd204b(); // 配置 JESD204B 链路参数 adrv9009_set_rx_freq(2400000000); // 设置接收本振 2.4GHz adrv9009_set_tx_freq(2400000000); // 设置发送本振 2.4GHz

逻辑说明:adrv9009_read_reg通过 SPI 读寄存器,芯片 ID 对不上后面全白搭;load_firmware是把 ADI 提供的二进制固件通过 SPI 写进芯片内部 RAM;setup_jesd204b配置 lane 数、帧格式、多帧长度,必须和 HDL 侧 IP 核的配置完全一致,否则链路起不来。参数上,set_rx_freq的单位是 Hz,实际能设的范围取决于 ADRV9009 的射频 PLL 范围,一般 70MHz 到 6GHz。

2.3 目录结构:文件放哪、编译顺序是什么

解压后典型的目录树长这样:

zc706_adrv9009/ ├── hdl/ # Vivado 工程 │ ├── projects/ │ │ └── zc706_adrv9009/ │ │ ├── system_top.v │ │ └── system_constr.xdc │ └── library/ # ADI IP 核源码 ├── sdk/ # Xilinx SDK 工作空间 │ ├── app/ │ │ ├── main.c │ │ └── adrv9009.c │ └── hw/ # 导出的硬件描述文件 └── scripts/ # 编译和下载脚本

HDL 部分用 Vivado 打开projects/zc706_adrv9009下的工程文件,综合实现后导出xsa文件。SDK 部分新建一个空的应用工程,把app目录下的源文件加进去,然后指定hw目录里的xsa作为硬件平台。编译顺序是先 HDL 后 SDK,因为 SDK 的地址映射依赖 HDL 导出的硬件描述。

3. 跑通全流程:从 Vivado 综合到 SDK 裸机程序上板

3.1 Vivado 侧:综合、实现和导出硬件

打开 Vivado 工程后,第一步是确认 IP 核的配置。在 Block Design 里找到axi_adrv9009,双击进去看 JESD204B 的 lane 数和采样率。常见配置是 4 lane、采样率 245.76MSPS,这个要和 ADRV9009 评估板上的拨码开关一致。确认完直接点 Generate Bitstream,Vivado 会自动跑综合、实现、生成比特流。这一步耗时取决于机器性能,一般 20 到 40 分钟。

跑完之后,菜单里选 File → Export → Export Hardware,勾选 Include Bitstream,导出xsa文件。这个文件是 SDK 用来识别硬件平台的,里面包含了寄存器地址映射和比特流。

注意:导出xsa之前一定要确认没有时序违例,尤其是 JESD204B 的 SERDES 时钟,时序不过链路肯定起不来。

3.2 SDK 侧:新建工程、导入源码、编译

打开 Xilinx SDK,指定一个工作空间目录,然后 File → New → Application Project。在硬件平台那一页选刚刚导出的xsa,处理器选ps7_cortexa9_0,工程模板选 Empty Application。建完之后,把app目录下的main.c、adrv9009.c、adrv9009.h复制到工程的src目录里。

接下来要改的是链接脚本和堆栈大小。no-os 程序里会用到比较大的数组来存 IQ 数据,默认的堆栈可能不够。在lscript.ld里把Heap Size改成0x100000,Stack Size改成0x10000。然后右键工程 → Build Project,编译通过后会生成.elf文件。

# 如果习惯用命令行,也可以用 xsct 脚本编译 xsct create_project.tcl # 脚本里会调用 exec vitis -source build.tcl

逻辑说明:xsct是 Xilinx 的命令行工具,适合做自动化构建。参数上,create_project.tcl里要指定xsa路径和源文件目录,编译完的elf可以直接用program_fpga和dow命令下载。

3.3 上板验证:JTAG 下载和串口打印

把 ZC706 的 JTAG 和串口都连上电脑,先给板子上电,然后打开 SDK 的 Terminal 视图,新建一个串口终端,波特率 115200。接着在 SDK 里点 Program FPGA,选比特流文件,下载完成后右键应用工程 → Run As → Launch on Hardware。程序跑起来后,串口会打印初始化日志:

ADRV9009 detected, ID = 0x00AD Loading Talise firmware... JESD204B link status: 0x01 (SYNC asserted) RX LO locked at 2400 MHz TX LO locked at 2400 MHz

如果看到JESD204B link status一直是 0,说明链路没建立,先检查 HDL 侧和 SDK 侧的 lane 配置是否一致,再查 SYSREF 有没有接对。如果 LO 没锁,多半是参考时钟没给对,ADRV9009 需要外部提供 30.72MHz 或 122.88MHz 的参考时钟。

4. 避坑与排查:JESD204B 链路起不来、SPI 读不到 ID 怎么办

4.1 现象:串口打印 “ADRV9009 not detected”

原因:SPI 通信失败。常见的是 SPI 片选接错、时钟极性配反,或者 ADRV9009 的复位引脚没释放。解决:先用示波器量 SPI 的 SCLK 和 MOSI,看有没有波形;再确认adrv9009_reset()里拉低复位后有没有延时足够时间(一般至少 10ms)再拉高。

4.2 现象:JESD204B link status 一直是 0

原因:HDL 侧和 SDK 侧的 JESD204B 参数不匹配。比如 HDL 配的是 4 lane,SDK 里配的是 2 lane;或者多帧长度(K 值)对不上。解决:两边都打开配置界面,逐项核对 lane 数、帧长度、多帧长度、子类模式(Subclass 1)。改完 HDL 要重新综合,改完 SDK 要重新编译。

4.3 现象:RX 能收到数据但全是噪声

原因:ADRV9009 的增益模式没配对,或者本振频率设到了芯片不支持的范围。解决:检查adrv9009_set_rx_freq的参数是否在 70MHz 到 6GHz 之间;如果是手动增益模式,确认增益索引有没有写对寄存器。

4.4 现象:程序跑一会儿就挂死

原因:no-os 程序里没有中断处理,如果 JESD204B 链路断了,程序可能卡在轮询循环里。解决:在轮询链路状态的地方加超时计数,超时就打印错误并重新初始化,别死等。

提示:上板调试时先把串口终端打开再下载程序,否则可能错过最开始的打印信息。

5. 二次开发怎么改:换采样率、加自定义逻辑、做自动化构建

5.1 改采样率:HDL 和 SDK 要同步动

想换采样率,比如从 245.76MSPS 改成 122.88MSPS,不能只改一边。HDL 侧要在axi_adrv9009IP 核里改采样率参数,然后重新生成 IP、综合、实现、导出xsa。SDK 侧要在adrv9009_setup_jesd204b里改对应的时钟分频和 JESD204B 参数。两边都改完再编译下载。我一般会拿个表格把两边参数列清楚,改完逐项打勾,避免漏改。

参数HDL 侧位置SDK 侧位置
采样率IP 核配置界面adrv9009_setup_jesd204b
Lane 数IP 核配置界面adrv9009_setup_jesd204b
多帧长度IP 核配置界面adrv9009_setup_jesd204b
参考时钟顶层约束文件adrv9009_load_firmware前

5.2 加自定义逻辑:在 HDL 里挂 AXI 外设

如果想在 FPGA 侧加自己的数据处理逻辑,比如做个简单的数字下变频,可以在 Block Design 里加一个 AXI 外设,把 ADRV9009 的 RX 数据流引出来。常见做法是用 AXI-Stream 接口,把axi_adrv9009的 RX 输出接到自己的 IP 上,处理完再写回 DDR 或者通过 AXI-Lite 给 ARM 读。改完 HDL 同样要重新导出xsa,SDK 侧用Xil_Out32和Xil_In32读写自定义寄存器。

5.3 自动化构建:用 xsct 脚本一键编译

手动点 SDK 编译容易漏步骤,我习惯写个build.tcl脚本,把创建工程、导入源码、编译全串起来。这样每次改完代码,命令行跑一下就行,不用来回点界面。

# build.tcl 片段 setws ./workspace createhw -name hw_design -hwspec ./hw/system.xsa createapp -name adrv9009_app -hwproject hw_design -proc ps7_cortexa9_0 -os standalone -lang C importsources -name adrv9009_app -path ./app projects -build

逻辑说明:createhw用xsa建硬件平台,createapp建空应用工程,importsources把源码拷进去,projects -build触发编译。参数上,-proc指定处理器核,-os指定 standalone 表示裸机。跑完脚本直接生成elf,省去手动操作。

从那以后我每次改完 HDL 或者 SDK 代码,都强制走一遍脚本编译加串口验证,确认链路状态和 LO 锁定再往下做。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询