08-11-2017 05:31 AM
How to Snyc one 7 Series Transceiver to another 7 series Transceiver?
I am working with 12G SDI video Reciver which gives 4 3G-SDI video ouput running in one Transeiver bank(in my case Bank 115 of kintex xc7k325tffg900-3) . Now I want to foreward/transport this 3G-SDI video to another Transceiver bank(in my case Bank 117 of kintex xc7k325tffg900-3).
The problem is sync failed time to time and I have error in 3G-SDI video output time to time.
I would like to know is there any way to sync one transceiver to another?
08-11-2017 07:16 AM
I think to synchronize (align) two tranceiver you have to use the same clock and get rid of the tranceiver FIFO (Tx buffer off).
Hope this helps,
08-15-2017 06:44 PM - edited 08-17-2017 08:11 AM
This is actually a really tough problem.
SDI requires each frame to be identical in terms of the number of blanking pixels and blanking lines. In other words, your serial data rate must be the exact multiple of the pixel rate.
So, when you receive a stream, you work with it at the recovered clock rate - this is effectively synchronized to the clock rate of the transmitting device.
To send the data forward and not accumulate some long term drift, you must transmit the data forward at exactly the bit rate of the incoming stream.
However, for a high speed transceiver, the bit rate of the transmitter is derived from the REFCLK - this is the high stability clock that is used for the transceiver.
So, to lock a SDI-TX to the SDI-RX you would have to lock the REFCLK of the transmitter to the recovered clock of the receiver. This can't be done for a couple of reasons:
- REFCLK is an external pin to the transceiver - you cannot access it from inside the FPGA
- (in some architectures there is a test mode to allow internal connections to REFCLK, but it is not to be used for user designs).
- the recovered clock from a GT RX has far too much jitter to be used as a reference clock for the GT...
So, there are a couple of solutions.
The first (and most common) is to use some kind of external clock component to generate REFCLK - this can be an external PLL with extremely good jitter rejection that can "clean up" the recovered clock enough to be used as REFCLK (EDIT: the internal MMCMs or PLLs are not sufficient for this task), or a VCXO that uses information generated by the FPGA to lock to the recovered clock's bit rate.
The other solution is to use something called PICXO. In a nutshell, the GT still uses the REFCLK for the transmitter, but uses a mechanism within the GT through the dynamic reconfiguration port (DRP) to continually adjust the phase of the output datastream. By continually adjusting the phase, you can tweak the outgoing frequency to match the incoming frequency (after all if you change the phase by a constant amount every unit of time, you are changing the frequency).
The PICXO solution does not necessarily work in all situations - there is an upper limit to how much frequency it can compensate for, and, presumably, adds some jitter to the outgoing data stream.
Information on the PICXO can be found in this application note (and forwarding an SDI input to an output is one of the example applications of this solution).
08-16-2017 10:03 PM
Thanks Avrum for the very detailed and very good answer.
I would like to add a few points:
The main advantages over an external VCXO:
It is Free!
You can change the gain (G1/G2) on the fly, meaning you can change the frequency response/lock time/jitter rejection on the fly.
hope this helps.
If there are questions about the PICXO/FRACXO, then make sure your post contains the "PICXO" keyword. I will try my best to answer.
08-17-2017 07:59 AM
Direct PLL didn't show any improvement.
Integrating PICXO seems to be quite confusing. I downloaded, installed and generated it in vivado.
As in page 21 and page 22 of
here are the ports:
PICXO_FRACXO_0 jitter_removal_inst (
.RESET_I(RESET_I), // input wire RESET_I
.REF_CLK_I(REF_CLK_I), // input wire REF_CLK_I
.TXOUTCLK_I(TXOUTCLK_I), // input wire TXOUTCLK_I
.DRPEN_O(DRPEN_O), // output wire DRPEN_O
.DRPWEN_O(DRPWEN_O), // output wire DRPWEN_O
.DRPDO_I(DRPDO_I), // input wire [15 : 0] DRPDO_I
.DRPDATA_O(DRPDATA_O), // output wire [15 : 0] DRPDATA_O
.DRPADDR_O(DRPADDR_O), // output wire [8 : 0] DRPADDR_O
.DRPRDY_I(DRPRDY_I), // input wire DRPRDY_I
.RSIGCE_I(RSIGCE_I), // input wire RSIGCE_I
.VSIGCE_I(VSIGCE_I), // input wire VSIGCE_I
.VSIGCE_O(VSIGCE_O), // output wire VSIGCE_O
.ACC_STEP(ACC_STEP), // input wire [3 : 0] ACC_STEP
.G1(G1), // input wire [4 : 0] G1
.G2(G2), // input wire [4 : 0] G2
.R(R), // input wire [15 : 0] R
.V(V), // input wire [15 : 0] V
.CE_DSP_RATE(CE_DSP_RATE), // input wire [15 : 0] CE_DSP_RATE
.C_I(C_I), // input wire [6 : 0] C_I
.P_I(P_I), // input wire [9 : 0] P_I
.N_I(N_I), // input wire [9 : 0] N_I
.OFFSET_PPM(OFFSET_PPM), // input wire [21 : 0] OFFSET_PPM
.OFFSET_EN(OFFSET_EN), // input wire OFFSET_EN
.HOLD(HOLD), // input wire HOLD
.DON_I(DON_I), // input wire [0 : 0] DON_I
.DRP_USER_REQ_I(DRP_USER_REQ_I), // input wire DRP_USER_REQ_I
.DRP_USER_DONE_I(DRP_USER_DONE_I), // input wire DRP_USER_DONE_I
.DRPEN_USER_I(DRPEN_USER_I), // input wire DRPEN_USER_I
.DRPWEN_USER_I(DRPWEN_USER_I), // input wire DRPWEN_USER_I
.DRPADDR_USER_I(DRPADDR_USER_I), // input wire [8 : 0] DRPADDR_USER_I
.DRPDATA_USER_I(DRPDATA_USER_I), // input wire [15 : 0] DRPDATA_USER_I
.DRPDATA_USER_O(DRPDATA_USER_O), // output wire [15 : 0] DRPDATA_USER_O
.DRPRDY_USER_O(DRPRDY_USER_O), // output wire DRPRDY_USER_O
.DRPBUSY_O(DRPBUSY_O), // output wire DRPBUSY_O
.ACC_DATA(ACC_DATA), // output wire [4 : 0] ACC_DATA
.ERROR_O(ERROR_O), // output wire [20 : 0] ERROR_O
.VOLT_O(VOLT_O), // output wire [21 : 0] VOLT_O
.DRPDATA_SHORT_O(DRPDATA_SHORT_O), // output wire [7 : 0] DRPDATA_SHORT_O
.CE_PI_O(CE_PI_O), // output wire CE_PI_O
.CE_PI2_O(CE_PI2_O), // output wire CE_PI2_O
.CE_DSP_O(CE_DSP_O), // output wire CE_DSP_O
.OVF_PD(OVF_PD), // output wire OVF_PD
.OVF_AB(OVF_AB), // output wire OVF_AB
.OVF_VOLT(OVF_VOLT), // output wire OVF_VOLT
.OVF_INT(OVF_INT) // output wire OVF_INT
but didn't understand what are optimal parameters to instantiate it.
Where I found these parameters?