主题中讨论的其他器件:, LMK04828
尊敬的 TI 支持团队:
我将与我取得联系、以获得有关在我的开发板上设置 JESD204C 接口的帮助。 我目前正在使用 ADC12QJ1600EVM 电路板上的 ADC12QJ1600、并将其连接到 ZCU102 rev 1.1开发电路板上的 Xilinx Ultrascale+ SoC。 我的主要问题出现在 JESD204C 接口(版本4.2)的初始化阶段。 在通过 AXI 总线进行初始化期间、状态寄存器(STAT_STATUS 0x060)中的"同步标头锁定已实现"标志不会被设置(请参阅 Vivado 设计套件 PG242版本中的 JESD204C v4.2 LogiCORE IP 产品指南。 4.22023年2月1日)[1]。
我将详细介绍我的设置、并在下面列出一些具体问题。 非常感谢您提供有关解决此问题的见解、答案和任何建议。
1. JESD 设置
以下是接口设置的基本参数:
- JMODE:8、
- 通道:4、
- 扩展多码组中的多码组数(E):3,
- 采样率:1GSPS、
- 通道速率:12.375Gbps、
- 编码:64B/66B。
2. FPGA 模块设计及 IP 内核设置
此设置由 MicroBlaze 软件处理器控制。 它通过 SPI 接口处理 ADC 和 LMK04828时钟管理器的设置加载。 此外、它还通过 AXI 总线配置 JESD 接收器。 在 ZCU102电路板上、SI5341B 时钟发生器的输出125MHz 应用到 FPGA、然后应用到 PLL、以产生100MHz 时钟。 该时钟用于 Microblaze、AXI 总线和 JESD204C PHY 的 DRP clk。 JESD 时钟配置的详细信息在时钟树一节中有进一步描述。
我在下面添加了一个设计图:
具有设置的 JESD204C PHY IP 向导屏幕截图:
和 JESD204C 内核 IP 向导屏幕截图、其中包括设置:
3.时钟树
3.1 SYSREF 时钟计算
- LEMC 时钟 的计算基础为:LEMC CLOCK = LANE_RATE /(64 x 32 x E)。 LEMC 时钟的计算公式为2.0141601613 MHz、@ LANE_RATE 为12.375Gbps、E = 3。
- SYSREF 频率等于 LEMC 时钟的或整数分频、 SYSREF = LEMC / n。SYSREF 为 0.5035400403 MHz @ n = 4。
3.2 LMK04828设置和 CLK_ADC 选择
在 ADC12QJ1600EVM 电路板上、J31连接器用于将来自发生器的参考时钟信号注入 LMK04828 (CLK_IN_1输入)、以生成用于 ADC、FPGA 和 ADC 器件时钟的 SYSREF。
设置如下@ CLK_IN_1 = 249.755860 MHz:
- CLK_IN_1 ->[CLK1_MUX = FIN]->[VCO_MUX = FIN]->[CLK_DIV = 1]-> DCLK_OUT_0 = 249.75586000 MHz (CLK_ADC_LMK)
- CLK_IN_1 ->[SUSREF_DIV = 496]-> SDCLK_OUT_3 = 0.5035400403 MHz (SYSREF_ADC_LMK)
- CLK_IN_1 ->[SUSREF_DIV = 496]-> SDCLK_OUT_11 = 0.5035400403 MHz (FPGA_SYSREF_FMC)
3.3 ADC 采样时钟配置
使用 CPLL 从 CLK_ADC_LMK 生成 ADC 的1GHz 采样时钟。 为 CPLL 设置的参数如下:
- V: 4
- P:2
- N:4
3.4. FPGA 端的 JESD204C 接收器时钟
为了为 FPGA 上的 JESD204C 接收器生成所需的 REFCLK 信号、使用了 ADC 的 TRIGOUT 输出。 按照 IP 内核向导中的配置、应用 RX_DIV = 32的分频系数来实现必要的频率。 这会导致 REFCLK 为12.375GHz/32、相当于386.71875 MHz。 随后、根据以下方案在 JESD204C PHY 和 JESD204C 内核逻辑之间分配该 REFCLK:
JESD204C 逻辑的内核时钟和 JESD204C PHY 的 CPLL 参考时钟是相同的、因为 IBUFDS_GTE4配置为不执行分频操作。
在 BUF_GT 缓冲器输出和内核时钟输入之间使用 MMCM、在时钟缓冲模式下运行、频率分频因子为1。 采用此设置来生成稳定且纯净的时钟信号。 MMCM 的设置如下:
4.初始化
4.1.通过 SPI 接口配置 LMK04828
write lmk reg | addr : 0x0149 | data : 0x0033 read lmk reg | addr : 0x0003 | data : 0x0006 read lmk reg | addr : 0x0004 | data : 0x00D0 read lmk reg | addr : 0x0005 | data : 0x005B read lmk reg | addr : 0x0006 | data : 0x0020 read lmk reg | addr : 0x000C | data : 0x0051 read lmk reg | addr : 0x000D | data : 0x0004 write lmk reg | addr : 0x0000 | data : 0x0080 write lmk reg | addr : 0x0000 | data : 0x0000 write lmk reg | addr : 0x0002 | data : 0x0000 write lmk reg | addr : 0x0003 | data : 0x0000 write lmk reg | addr : 0x0004 | data : 0x0000 write lmk reg | addr : 0x0005 | data : 0x0000 write lmk reg | addr : 0x0006 | data : 0x0000 write lmk reg | addr : 0x000C | data : 0x0000 write lmk reg | addr : 0x000D | data : 0x0000 write lmk reg | addr : 0x0100 | data : 0x0061 write lmk reg | addr : 0x0101 | data : 0x0055 write lmk reg | addr : 0x0102 | data : 0x0055 write lmk reg | addr : 0x0103 | data : 0x0001 write lmk reg | addr : 0x0104 | data : 0x0020 write lmk reg | addr : 0x0105 | data : 0x0000 write lmk reg | addr : 0x0106 | data : 0x00F1 write lmk reg | addr : 0x0107 | data : 0x0066 write lmk reg | addr : 0x0108 | data : 0x0061 write lmk reg | addr : 0x0109 | data : 0x0055 write lmk reg | addr : 0x010A | data : 0x0055 write lmk reg | addr : 0x010B | data : 0x0000 write lmk reg | addr : 0x010C | data : 0x0033 write lmk reg | addr : 0x010D | data : 0x0000 write lmk reg | addr : 0x010E | data : 0x00F0 write lmk reg | addr : 0x010F | data : 0x0060 write lmk reg | addr : 0x0110 | data : 0x0001 write lmk reg | addr : 0x0111 | data : 0x0055 write lmk reg | addr : 0x0112 | data : 0x0055 write lmk reg | addr : 0x0113 | data : 0x0000 write lmk reg | addr : 0x0114 | data : 0x0002 write lmk reg | addr : 0x0115 | data : 0x0000 write lmk reg | addr : 0x0116 | data : 0x00F9 write lmk reg | addr : 0x0117 | data : 0x0001 write lmk reg | addr : 0x0118 | data : 0x0001 write lmk reg | addr : 0x0119 | data : 0x0055 write lmk reg | addr : 0x011A | data : 0x0055 write lmk reg | addr : 0x011B | data : 0x0002 write lmk reg | addr : 0x011C | data : 0x0002 write lmk reg | addr : 0x011D | data : 0x0000 write lmk reg | addr : 0x011E | data : 0x00F9 write lmk reg | addr : 0x011F | data : 0x0001 write lmk reg | addr : 0x0120 | data : 0x0001 write lmk reg | addr : 0x0121 | data : 0x0055 write lmk reg | addr : 0x0122 | data : 0x0055 write lmk reg | addr : 0x0123 | data : 0x0000 write lmk reg | addr : 0x0124 | data : 0x0022 write lmk reg | addr : 0x0125 | data : 0x0000 write lmk reg | addr : 0x0126 | data : 0x00F9 write lmk reg | addr : 0x0127 | data : 0x0001 write lmk reg | addr : 0x0128 | data : 0x0061 write lmk reg | addr : 0x0129 | data : 0x0055 write lmk reg | addr : 0x012A | data : 0x0055 write lmk reg | addr : 0x012B | data : 0x0002 write lmk reg | addr : 0x012C | data : 0x0020 write lmk reg | addr : 0x012D | data : 0x0000 write lmk reg | addr : 0x012E | data : 0x00F0 write lmk reg | addr : 0x012F | data : 0x0010 write lmk reg | addr : 0x0130 | data : 0x0001 write lmk reg | addr : 0x0131 | data : 0x0055 write lmk reg | addr : 0x0132 | data : 0x0055 write lmk reg | addr : 0x0133 | data : 0x0002 write lmk reg | addr : 0x0134 | data : 0x0022 write lmk reg | addr : 0x0135 | data : 0x0000 write lmk reg | addr : 0x0136 | data : 0x00F9 write lmk reg | addr : 0x0137 | data : 0x0001 write lmk reg | addr : 0x0138 | data : 0x0055 write lmk reg | addr : 0x0139 | data : 0x0003 write lmk reg | addr : 0x013A | data : 0x0001 write lmk reg | addr : 0x013B | data : 0x00F0 write lmk reg | addr : 0x013C | data : 0x0000 write lmk reg | addr : 0x013D | data : 0x0000 write lmk reg | addr : 0x013E | data : 0x0000 write lmk reg | addr : 0x013F | data : 0x000F write lmk reg | addr : 0x0140 | data : 0x00F1 write lmk reg | addr : 0x0141 | data : 0x0000 write lmk reg | addr : 0x0142 | data : 0x0008 write lmk reg | addr : 0x0143 | data : 0x0010 write lmk reg | addr : 0x0144 | data : 0x00FF write lmk reg | addr : 0x0145 | data : 0x007F write lmk reg | addr : 0x0146 | data : 0x0010 write lmk reg | addr : 0x0147 | data : 0x0003 write lmk reg | addr : 0x0148 | data : 0x0002 write lmk reg | addr : 0x0149 | data : 0x0033 write lmk reg | addr : 0x014A | data : 0x0006 write lmk reg | addr : 0x014B | data : 0x0002 write lmk reg | addr : 0x014C | data : 0x0000 write lmk reg | addr : 0x014D | data : 0x0000 write lmk reg | addr : 0x014E | data : 0x0000 write lmk reg | addr : 0x014F | data : 0x007F write lmk reg | addr : 0x0150 | data : 0x0001 write lmk reg | addr : 0x0151 | data : 0x0002 write lmk reg | addr : 0x0152 | data : 0x0000 write lmk reg | addr : 0x0153 | data : 0x0000 write lmk reg | addr : 0x0154 | data : 0x0001 write lmk reg | addr : 0x0155 | data : 0x0000 write lmk reg | addr : 0x0156 | data : 0x0001 write lmk reg | addr : 0x0157 | data : 0x0000 write lmk reg | addr : 0x0158 | data : 0x0001 write lmk reg | addr : 0x0159 | data : 0x0000 write lmk reg | addr : 0x015A | data : 0x0018 write lmk reg | addr : 0x015B | data : 0x00D4 write lmk reg | addr : 0x015C | data : 0x0020 write lmk reg | addr : 0x015D | data : 0x0000 write lmk reg | addr : 0x015E | data : 0x0000 write lmk reg | addr : 0x015F | data : 0x000B write lmk reg | addr : 0x0160 | data : 0x0000 write lmk reg | addr : 0x0161 | data : 0x0008 write lmk reg | addr : 0x0162 | data : 0x0004 write lmk reg | addr : 0x0163 | data : 0x0000 write lmk reg | addr : 0x0164 | data : 0x0000 write lmk reg | addr : 0x0165 | data : 0x000C write lmk reg | addr : 0x0171 | data : 0x00AA write lmk reg | addr : 0x0172 | data : 0x0002 write lmk reg | addr : 0x017C | data : 0x0015 write lmk reg | addr : 0x017D | data : 0x0033 write lmk reg | addr : 0x0166 | data : 0x0000 write lmk reg | addr : 0x0167 | data : 0x0000 write lmk reg | addr : 0x0168 | data : 0x000C write lmk reg | addr : 0x0169 | data : 0x0059 write lmk reg | addr : 0x016A | data : 0x0020 write lmk reg | addr : 0x016B | data : 0x0000 write lmk reg | addr : 0x016C | data : 0x0000 write lmk reg | addr : 0x016D | data : 0x0000 write lmk reg | addr : 0x016E | data : 0x0004 write lmk reg | addr : 0x0171 | data : 0x00AA write lmk reg | addr : 0x0172 | data : 0x0002 write lmk reg | addr : 0x0173 | data : 0x0020 write lmk reg | addr : 0x017C | data : 0x0015 write lmk reg | addr : 0x017D | data : 0x0033 write lmk reg | addr : 0x0182 | data : 0x0000 write lmk reg | addr : 0x0183 | data : 0x0000 write lmk reg | addr : 0x0184 | data : 0x0000 write lmk reg | addr : 0x0185 | data : 0x0000 write lmk reg | addr : 0x0188 | data : 0x0000 write lmk reg | addr : 0x0189 | data : 0x0000 write lmk reg | addr : 0x018A | data : 0x0000 write lmk reg | addr : 0x018B | data : 0x0000 write lmk reg | addr : 0x1FFD | data : 0x0000 write lmk reg | addr : 0x1FFE | data : 0x0000 write lmk reg | addr : 0x1FFF | data : 0x0083
4.2. 通过 SPI 接口配置 ADC12QJ1600
read adc reg | addr : 0x000C | data : 0x0051 read adc reg | addr : 0x000D | data : 0x0004 write adc reg | addr : 0x0000 | data : 0x00B0 read adc reg | addr : 0x0270 | data : 0x0001 write adc reg | addr : 0x0058 | data : 0x0081 write adc reg | addr : 0x005C | data : 0x0001 write adc reg | addr : 0x003F | data : 0x0000 write adc reg | addr : 0x003D | data : 0x0005 write adc reg | addr : 0x003E | data : 0x0004 write adc reg | addr : 0x005D | data : 0x0041 write adc reg | addr : 0x005C | data : 0x0000 read adc reg | addr : 0x005E | data : 0x0003 read adc reg | addr : 0x0208 | data : 0x0005 write adc reg | addr : 0x0057 | data : 0x0001 write adc reg | addr : 0x0057 | data : 0x0081 write adc reg | addr : 0x002B | data : 0x0015 write adc reg | addr : 0x0200 | data : 0x0000 write adc reg | addr : 0x0061 | data : 0x0000 write adc reg | addr : 0x0201 | data : 0x0008 write adc reg | addr : 0x0202 | data : 0x00FF write adc reg | addr : 0x0204 | data : 0x000F write adc reg | addr : 0x003B | data : 0x0003 write adc reg | addr : 0x0213 | data : 0x000F write adc reg | addr : 0x0061 | data : 0x0001 write adc reg | addr : 0x0200 | data : 0x0001 write adc reg | addr : 0x006C | data : 0x0000 write adc reg | addr : 0x006C | data : 0x0001 read adc reg | addr : 0x006A | data : 0x000F read adc reg | addr : 0x0208 | data : 0x0065
4.3.通过 AXI 总线进行 JESD204C 内核配置
write jesd reg | addr : 0x0038 | data : 0x0000 write jesd reg | addr : 0x0030 | data : 0x0003 write jesd reg | addr : 0x004C | data : 0x0004 write jesd reg | addr : 0x0034 | data : 0x0001 write jesd reg | addr : 0x0050 | data : 0x0000 write jesd reg | addr : 0x0020 | data : 0x0001 write jesd reg | addr : 0x0020 | data : 0x00A0 read jesd reg | addr : 0x0020 | data : 0x0000 read jesd reg | addr : 0x0054 | data : 0x000F read jesd reg | addr : 0x0060 | data : 0x0012
问题1: 如何实现同步报头锁定?
我还想就与64B66B 同步标题锁定相关的问题寻求帮助。 在初始化阶段、64B66B 同步报头不会锁定、即使 JESD 逻辑内核在复位后正确唤醒("REST_DONE"处于高电平状态)、JESD PHY 的 CPLL 锁定全部四个通道并捕获 SYSREF。
从 STAT_STATUS 寄存器中、我读取值0x12、这表示实现了多块锁定且捕获了 SYSREF、但没有同步头锁定。
我的设置中是否存在阻止同步报头锁定的错误?
问题2. SYSREF 窗口操作过程和重新对齐标志
为了解决这个问题、我决定实施 SYSREF 窗口化过程。 下面是我正在做的工作:
- 启用 SYSREF 处理。
- SYSREF 接收器和缩放被激活。
- 读取 SYSREF_POS 寄存器。
- 零的数量被计数并且最佳位置被选择。
- 对 SYSREF_SEL 进行编程。
- 等待出现"已对齐"和"已对齐"标志。
- "重新排列"标志将被清除并进行检查、以查看它是否再次出现。
下面列出了此过程的代码:
int adc12qj1600_sysref_windowing(const adc12qj1600_config *config) { unsigned int sysref_pos[3] = {0x00,0x00,0x00}; unsigned int combined_sysref_pos = 0x000000; unsigned int count_zeros = 0; unsigned int longest_zeros = 0; unsigned int best_position = 0; int i; adc12qj1600_spi_streaming_mode_reg_modify(config->slave_select, 1, CLK_CTRL0, CLK_CTRL0_SYSREF_PROC_EN_MSK, CLK_CTRL0_SYSREF_PROC_EN_MSK); adc12qj1600_spi_streaming_mode_reg_modify(config->slave_select, 1, CLK_CTRL0, CLK_CTRL0_SYSREF_RECV_EN_MSK|CLK_CTRL0_SYSREF_ZOOM_MSK, CLK_CTRL0_SYSREF_RECV_EN_MSK|CLK_CTRL0_SYSREF_ZOOM_MSK ); for(i=0;i<3;i++) { adc12qj1600_spi_streaming_mode_rd(config->slave_select, 1, SYSREF_POS + i, &sysref_pos[i]); combined_sysref_pos |= sysref_pos[i] << (i*8); } for(int i = 0; i < 24; i++) { if( !(combined_sysref_pos & (1 << i) ) ) { count_zeros++; if(count_zeros > longest_zeros) { longest_zeros = count_zeros; best_position = i - (count_zeros >> 1); } } else count_zeros = 0; } if( (best_position != 0) && (best_position <= 15) ) adc12qj1600_spi_streaming_mode_reg_modify(config->slave_select, 1, CLK_CTRL0, CLK_CTRL0_SYSREF_SEL_MSK, best_position); if( !(adc12qj1600_wait_sysref_aligned(config->slave_select) == ADC12QJ1600_WAIT_FOR_FLAG_DONE) ) return ADC12QJ1600_SYSREF_NOT_ALIGHED; adc12qj1600_spi_streaming_mode_reg_modify(config->slave_select, 1, JESD_STATUS, JESD_STATUS_REALIGNED_MSK, 0x00); if( (adc12qj1600_wait_sysref_aligned(config->slave_select) == ADC12QJ1600_WAIT_FOR_FLAG_DONE) ) return ADC12QJ1600_SYSREF_FREQ_ERR; return ADC12QJ1600_SYSREF_IS_ALIGNED; }
遗憾的是、重新对齐标志正在被置位、这表明 SYSREF 时钟信号有问题。 为了解决此问题、我们尝试在初始化期间使用 LMK04828芯片的寄存器0x10D、使用具有不同延迟值的 SYSREF 输出的模拟延迟。 但是、这无法解决问题。
因此、在 ADC 初始化过程结束时、寄存器0x208的值为0x7D。 此过程的命令列表如下所示:
read adc reg | addr : 0x000C | data : 0x0051 read adc reg | addr : 0x000D | data : 0x0004 write adc reg | addr : 0x0000 | data : 0x00B0 read adc reg | addr : 0x0270 | data : 0x0001 write adc reg | addr : 0x0058 | data : 0x0081 write adc reg | addr : 0x005C | data : 0x0001 write adc reg | addr : 0x003F | data : 0x0000 write adc reg | addr : 0x003D | data : 0x0005 write adc reg | addr : 0x003E | data : 0x0004 write adc reg | addr : 0x005D | data : 0x0041 write adc reg | addr : 0x005C | data : 0x0000 read adc reg | addr : 0x005E | data : 0x0003 read adc reg | addr : 0x0208 | data : 0x0005 write adc reg | addr : 0x0057 | data : 0x0001 write adc reg | addr : 0x0057 | data : 0x0081 write adc reg | addr : 0x0029 | data : 0x00C0 write adc reg | addr : 0x0029 | data : 0x00F0 read adc reg | addr : 0x002C | data : 0x0001 read adc reg | addr : 0x002D | data : 0x0000 read adc reg | addr : 0x002E | data : 0x0080 write adc reg | addr : 0x0029 | data : 0x00FB read adc reg | addr : 0x0208 | data : 0x001D write adc reg | addr : 0x0208 | data : 0x000D read adc reg | addr : 0x0208 | data : 0x001D write adc reg | addr : 0x002B | data : 0x0015 write adc reg | addr : 0x0200 | data : 0x0000 write adc reg | addr : 0x0061 | data : 0x0000 write adc reg | addr : 0x0201 | data : 0x0008 write adc reg | addr : 0x0202 | data : 0x00FF write adc reg | addr : 0x0204 | data : 0x000F write adc reg | addr : 0x003B | data : 0x0003 write adc reg | addr : 0x0213 | data : 0x000F write adc reg | addr : 0x0061 | data : 0x0001 write adc reg | addr : 0x0200 | data : 0x0001 write adc reg | addr : 0x006C | data : 0x0000 write adc reg | addr : 0x006C | data : 0x0001 read adc reg | addr : 0x006A | data : 0x000F read adc reg | addr : 0x0208 | data : 0x007D
在通过 AXI 总线对 JESD204C 进行初始化期间执行 SYSREF 窗口化过程后、64B66B 多块锁定将丢失。
此过程的命令列表也在下面提供:
write jesd reg | addr : 0x0038 | data : 0x0000 write jesd reg | addr : 0x0030 | data : 0x0003 write jesd reg | addr : 0x004C | data : 0x0004 write jesd reg | addr : 0x0034 | data : 0x0001 write jesd reg | addr : 0x0050 | data : 0x0000 write jesd reg | addr : 0x0020 | data : 0x0001 write jesd reg | addr : 0x0020 | data : 0x00A0 read jesd reg | addr : 0x0020 | data : 0x0000 read jesd reg | addr : 0x0054 | data : 0x0000 read jesd reg | addr : 0x0060 | data : 0x0002
请帮我弄清楚如何以使重新排列标志不会第二次出现的方式组织 SYSREF。 寻求有关解决这些问题和实现同步报头锁定和多块位置的见解和建议。
[1] https://docs.xilinx.com/r/en-US/pg242-jesd204c/Register-Space
感谢您投入宝贵的时间给予大力支持。
此致、
米哈伊尔·瓦西列乌