Other Parts Discussed in Thread: , LMK04828
Dear TI Support Team,
I am reaching out for assistance with setting up the JESD204C interface on my development boards. I am currently working with the ADC12QJ1600 on the ADC12QJ1600EVM board and interfacing it with the Xilinx UltraScale+ SoC on the ZCU102 rev 1.1 development board. My primary issue arises during the initialization phase of the JESD204C interface (version 4.2). The “Sync Header lock achieved” flag in the status registers (STAT_STATUS 0x060) does not get set during initialization over the AXI bus (see JESD204C v4.2 LogiCORE IP Product Guide from the Vivado Design Suite PG242 ver. 4.2, February 1, 2023) [1].
I will provide a detailed description of my setup and list some specific questions below. Your insights, answers, and any suggestions to resolve this issue would be highly appreciated.
1. JESD Settings
Here are the basic parameters of the interface setup:
- JMODE: 8,
- LANES: 4,
- The Number of Multiblocks in an Extended Multiblock (E) : 3,
- Sampling Rate: 1 GSPS,
- Lane Rate: 12.375 Gbps,
- Coding: 64b/66b.
2. FPGA block design and IP-cores settings
The setup is controlled by the MicroBlaze software processor. It handles the loading of settings into the ADC and the LMK04828 clock manager through the SPI interface. Additionally, it configures the JESD receiver through the AXI bus. On the ZCU102 board, the output of the SI5341B clock generator, which is 125MHz, is applied to a FPGA and then to PLL to produce a 100MHz clock. This clock is used for the Microblaze, the AXI-bus, and the DRP clk of the JESD204C Phy. The details of the JESD clock configuration are further described in the clock tree section.
I have included a design diagram below:
screenshot of JESD204C PHY IP wizard with settings:
and screenshots of JESD204C CORE IP wizard with settings:
3. Clock tree
3.1 SYSREF clock calculation
- The LEMC clock is calculated based on: LEMC clock = LANE_RATE / (64 x 32 x E). LEMC clock is calculated to be 2.0141601613 MHz, @ LANE_RATE of 12.375 Gbps and E = 3.
- The SYSREF frequency is equal to or an integer division of the LEMC clock, SYSREF = LEMC / n. SYSREF is 0.5035400403 MHz @ n = 4.
3.2 LMK04828 settings and CLK_ADC selection
On the ADC12QJ1600EVM board the J31 connector is used to inject reference clock signal from generator into LMK04828 (CLK_IN_1 input) in order to produce SYSREF for ADC and FPGA and ADC device clock.
Settings are the following @ 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 Sampling Clock Configuration
1GHz sampling clock for the ADC is generated from CLK_ADC_LMK using the CPLL. The parameters set for the CPLL are as follows:
- V: 4
- P: 2
- N: 4
3.4. JESD204C Receiver Clocking on the FPGA Side
To generate the required REFCLK signal for the JESD204C receiver on the FPGA, the TRIGOUT output from the ADC is used. A division coefficient of RX_DIV = 32 is applied to achieve the necessary frequency, as configured in the IP core wizard. This results in a REFCLK of 12.375 GHz / 32, equaling 386.71875 MHz. Subsequently, this REFCLK is distributed between the JESD204C PHY and the JESD204C core logic according to the following scheme:
The core clock for the JESD204C logic and the CPLL reference clock for the JESD204C PHY are identical, as the IBUFDS_GTE4 is configured to operate without division.
An MMCM is used between the BUF_GT buffer output and the CORE clk inputs, operating in clock buffer mode with a frequency division factor of 1. This setup is employed to generate a stable and clean clock signal. The settings of the MMCM are the following:
4. Initialization
4.1. LMK04828 configuration via SPI interface
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. ADC12QJ1600 configuration via SPI interfaceread 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. JESD204C Core configuration via AXI buswrite 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
Q1. How to achive Sync Header Lock?
I would also like to ask for assistance with an issue related to the 64B66B Sync Header Lock. During the initialization phase, the 64B66B Sync Header does not lock, even though the JESD logic core correctly wakes up after the reset (with 'rest_done' in a high state), the CPLL of the JESD PHY is locked for all four lanes, and SYSREF is captured.
From the STAT_STATUS register, I read the value 0x12, which indicates that the Multiblock lock is achieved and SYSREF is captured, but without the Sync Header lock.
Could there be something wrong in my setup that is preventing the Sync Header from locking?
Q2. SYSREF windowing procedure and realigned flag
To address this, I decided to implement the SYSREF windowing procedure. Here's what I am doing:
- SYSREF processing is enabled.
- SYSREF receiver and ZOOM are activated.
- SYSREF_POS registers are read.
- The number of zeros is counted and the best position is selected.
- SYSREF_SEL is programmed.
- Waiting for the 'Aligned' and 'Realigned' flags occurs.
- The 'Realigned' flag is cleared and checked to see if it appears again,
The code for this procedure is listed below:
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; }
Unfortunately, the REALIGNED flag is being set again, indicating a problem with the SYSREF clock signal. To fix this, an attempt was made to use the analog delay for the SYSREF outputs with different delay values using register 0x10D of the LMK04828 chip during initialization. However, this did not resolve the issue.
As a result, at the end of the ADC initialization procedure, register 0x208 takes on the value 0x7D. The command listing for this process is provided below:
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
With SYSREF windowing procedure during the initialization of JESD204C via the AXI bus, the 64B66B Multiblock Lock is lost.
The command listing for this process is also provided below:
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
Please help me figure out how to organize SYSREF in such a way that the REALIGNED flag does not appear a second time. Insights and suggestions on resolving these issues and achieving the Sync Header lock and Multiblock Loc are sought.
[1] https://docs.xilinx.com/r/en-US/pg242-jesd204c/Register-Space
Thank you for your time and consideration.
Best regards,
Mikhail Vasilev