AD9173是ADI公司推出的一款超高性能数模转换器,支持高达12GHz的DA更新率。这个频率直接覆盖毫米波频段,配合内部上变频功能,使其成为射频系统设计的利器。本文将详细解析基于Verilog的AD9173驱动开发全过程,从时钟架构设计到JESD204B接口实现,再到数据生成与处理。
AD9173的核心优势在于其超高的采样率和丰富的数字处理功能。芯片内部集成了24倍插值滤波器、数字上变频器(DUC)和时钟乘法器,可以接受较低的输入数据速率,最终输出高频模拟信号。
典型的应用系统架构包含以下几个关键部分:
在实际项目中,时钟设计的合理性往往决定了整个系统的成败。特别是当涉及到GHz级别的时钟信号时,PCB布局布线和电源完整性变得至关重要。
AD9173需要三个关键时钟:
我们的设计采用500MHz外部参考时钟,通过内部PLL倍频到12GHz。考虑到FPGA内部的MMCM/PLL很难直接生成12GHz时钟,我们采用了两级方案:
verilog复制// 第一级:500MHz -> 6GHz (12倍频)
mmcm_adv #(
.CLKIN1_PERIOD(2.0), // 500MHz输入
.CLKFBOUT_MULT_F(12), // 12倍频
.CLKOUT0_DIVIDE_F(1) // 不分频
) pll_stage1 (
.clkfbout(clkfb1),
.clkout0 (clk_6g),
//...其他信号连接
);
// 第二级:AD9173内部Clock Multiplier将6GHz倍频到12GHz
高速时钟分配需要特别注意以下几点:
对于FPGA内部的时钟处理,Xilinx Ultrascale+系列器件提供了高性能的MMCM和PLL资源。关键配置参数包括:
| 参数 | 说明 | 推荐值 |
|---|---|---|
| CLKIN1_PERIOD | 输入时钟周期(ns) | 2.0(500MHz) |
| CLKFBOUT_MULT_F | 反馈环路倍频系数 | 12 |
| CLKOUT0_DIVIDE_F | 输出时钟分频系数 | 1 |
| BANDWIDTH | PLL带宽 | HIGH |
实测中发现,当输出时钟超过800MHz时,建议将CLKOUT0_DIVIDE设为2,然后通过ODDR2实现2倍频,这样可以获得更好的时钟质量。
AD9173采用JESD204B Subclass 1接口,关键参数如下:
对应的Verilog实例化代码如下:
verilog复制jesd204b_tx #(
.LANES(4), // 4个传输通道
.LANE_RATE(10000), // 10Gbps线速率
.SCRAMBLER_EN(1), // 启用加扰
.FRAME_CLK_DIV(2) // 6GHz时钟2分频
) jesd_core (
.tx_clk(clk_6g), // 传输时钟
.sysref(sysref), // SYSREF信号
.lmfc_offset(8'd0), // LMFC偏移
.phy_data(phy_data) // 物理层数据
);
SYSREF信号是JESD204B同步的关键,必须满足以下要求:
调试技巧:
常见问题排查:
AD9173的SPI接口配置必须严格按照以下顺序进行:
对应的Verilog任务实现:
verilog复制task spi_write;
input [15:0] addr;
input [7:0] data;
begin
spi_cs_n <= 1'b0;
spi_sck <= 1'b0;
spi_mosi <= {addr, data};
repeat(24) begin
#SPI_CLK_PERIOD spi_sck <= ~spi_sck;
end
spi_cs_n <= 1'b1;
#SPI_CS_DELAY; // 片选保持时间
end
endtask
必须配置的几个关键寄存器:
| 寄存器地址 | 功能 | 典型值 |
|---|---|---|
| 0x0010 | PLL使能 | 0x01 |
| 0x0102 | 数据路径配置 | 0x1F |
| 0x0200 | JESD链路使能 | 0x01 |
| 0x0301 | 插值滤波器设置 | 0x18 |
实际调试中发现,SPI时钟频率不宜超过10MHz,否则可能导致配置失败。建议在关键寄存器配置完成后进行回读验证。
采用双DDS结构生成I/Q基带信号:
verilog复制// 相位累加器
reg [31:0] phase_acc_i, phase_acc_q;
always @(posedge dac_clk) begin
phase_acc_i <= phase_acc_i + 32'h19999999; // I路200MHz
phase_acc_q <= phase_acc_q + 32'h19999999; // Q路200MHz
end
// 正弦/余弦查找表
wire [15:0] dds_i = sin_lut(phase_acc_i[31:24]);
wire [15:0] dds_q = cos_lut(phase_acc_q[31:24]);
AD9173支持多种数据格式,最常用的是sample interleave模式。数据需要按照以下顺序排列:
code复制Lane0: S0[15:8] | S0[7:0] | S4[15:8] | S4[7:0] | ...
Lane1: S1[15:8] | S1[7:0] | S5[15:8] | S5[7:0] | ...
Lane2: S2[15:8] | S2[7:0] | S6[15:8] | S6[7:0] | ...
Lane3: S3[15:8] | S3[7:0] | S7[15:8] | S7[7:0] | ...
对应的Verilog实现:
verilog复制wire [127:0] jesd_data = {
// Lane3数据
{dds_q[15:8], dds_q[7:0], dds_i[15:8], dds_i[7:0]},
// Lane2数据
{dds_q[15:8], dds_q[7:0], dds_i[15:8], dds_i[7:0]},
// Lane1数据
{dds_q[15:8], dds_q[7:0], dds_i[15:8], dds_i[7:0]},
// Lane0数据
{dds_q[15:8], dds_q[7:0], dds_i[15:8], dds_i[7:0]}
};
无输出信号
输出频谱异常
周期性毛刺
使用差分探棒测量高速信号
在频谱分析仪上设置合适的RBW
优化PCB布局:
固件优化:
在KCU105开发板上的实测结果:
完整的驱动代码包含以下模块:
code复制/ad9173_driver
│── spi_controller.v // SPI配置引擎
│── jesd204b_tx_wrapper.v // JESD204B接口封装
│── dds_signal_gen.v // 多波形信号发生器
│── data_interleave.v // 数据交织处理
│── clock_gen.v // 时钟产生与分配
│── ad9173_top.v // 顶层集成
│── tb/ // 测试平台
│ ├── ad9173_tb.v
│ └── test_cases.v
│── scripts/ // 辅助脚本
│ ├── spi_config.tcl
│ └── jesd_align.py
每个模块都包含详细的注释和仿真测试点。在实际应用中,可以根据具体需求调整数据路径和时钟配置。