# Word alignment / bitslip in LVDS Receiver

I am simulating the Soft LVDS IP core as receiver by passing a bit stream with IP core parameters configured as follows:

Power Supply Mode: Dual (for 10M50DAF484C7G)

Functional mode: RX

Number of Channels: 1

SERDES factor: 8

PLL: Internal

Data rate: 200 Mbps

Inclock frequency: 200 MHz (This value was selected automatically after I entered Data rate)

Enable pll_areset port: checked

Register outputs: checked

In the test bench I am continuously passing a bit stream (consisting 0xAA in a loop) after

asserting the pll_areset for at least 10ns. checking if rx_locked has been asserted. but the deserialized output is not consistent with the serial input. I have tried increasing the rx_inclock frequency to 400 MHz, 800 MHz and 1600 MHz but to no avail. Any ideas what could be the issue? Besides does anyone know how the inclock frequency is calculated from the data rate? I also tried other input sequences but didn't get the same data at output. I am not sure if the SERDES IP core is either skipping bits or the word/byte boundary is misplaced. Would appreciate any help also if somebody could explain bitslip phenomenon. Thanks

Note (Added 19 Nov, 2018): The device being used is Altera's MAX10 and the IP core is "Soft LVDS".

Testbench

timescale 1 ns / 1 fs

module LVDS_Test_4_tb;

integer         i   =   0;

reg             clk;
reg             rx_in;
reg     [256:0] input_bitstream;
reg             pll_areset;
reg             rx_data_align;
//reg               align_data;

wire    [7:0]   rx_out;
wire            outclock;
wire            rx_locked;

initial
begin
clk                 =   1'b0;
//      align_data          =   1'b0;
rx_in               =   1'b0;
rx_data_align       =   1'b0;
input_bitstream     =   256'h0000000000000000_0000000000000000_0000000000000000_0000000000000000;
input_bitstream     =   256'hAAAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAA_AAAAAAAAAAAAAAAA;
pll_areset          =   1'b0;
//#10       pll_areset          =   1'b1;
//#20       pll_areset          =   1'b0;
end

always @ (*)
begin
#2.5    clk     <=  ~clk;
end

always @ (posedge clk)
begin
if (rx_locked)
begin
rx_in   <=  input_bitstream[i];
if (i >= 12'h100)
i = 0;
else
i       <=  i   +   1'b1;
end
end

LVDS_Test_4 lvds (
.rx_inclock     (clk),         //  rx_inclock.rx_inclock
.rx_outclock    (outclock),    // rx_outclock.rx_outclock
.pll_areset     (pll_areset),  //  pll_areset.pll_areset
.rx_in          (rx_in),       //       rx_in.rx_in
.rx_out         (rx_out),
.rx_locked      (rx_locked)    //,
//      .rx_data_align  (rx_data_align)
);

endmodule


Simulation Waveform where rx_in data is synced at posedge of data clock

Update: (24 Nov, 2018) So, I changed the testbench design, instead of an always block based on the posedge of data clock, now the serial data is transmitted using a forever loop in an initial block at the same frequency. This change somehow fixes the issue but partially, so I do like to understand why it behaves so? A data stream comprising 8'b11001100 was transmitted as shown in the following figure. Post-link training the data was aligned.

## bumped to the homepage by Community♦2 days ago

This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.

When you use a frame clock, which in your case would be 200Mbps/8=25MHz, then there is information contained within the clock as to where the word boundary is, and you can (assuming you set the phase relationship correctly) know immediately which bit is bit 0.

When using a data clock, which runs at the same frequency as the serial data - i.e. 200MHz for 200Mbps, then you have no information in the clock signal as to where bit 0 is located. The PLL could lock at any clock edge and the deserialiser will start counting from there. In such situations, you need to implement link training logic to perform word alignment.

If the clock you are feeding in is 200MHz, and the data rate is 200Mbps, that means that you are using a data clock rather than a frame clock. As such there is no information from the clock as to where the word boundary is and will need to perform alignment.

The process of word alignment using link training is roughly as follows:

1. You send a predetermined pattern over the serial link - a value which when deserialised will only result in the correct value when deserialised with the correct word alignment. For example the binary value 11110000 is one such value.

2. In the receiver you deserialise the value and compare it with your test pattern. If it matches you are done.

3. If the value doesn't match your pattern, you perform a bit-slip - that is, you shift the data in the serial stream one serial clock cycle. The SERDES IP core you are using should have some form of bitslip` or similarly named signal to do this. Once you have slipped a bit, go back to 2.

• Thanks for the reply. The Intel's Soft LVDS IP core only has single clock input port (rx_inclock) that I assume is data clock, the frame clock it generates itself based on the deserialization factor that is input during configuration. The IP core also outputs a clock signal (rx_outclock) that is synced with the deserialized frame thus assuming it is frame clock. Regarding link training, the bitslip is not constant neither the frequency of change in bitslip is constant. So, how can I perform link training in this scenario? – SMS Nov 19 '18 at 5:16
• @SMS if the bit-slip is not constant, it means that the data you are feeding in is not in sync with the clock, otherwise there would be a constant and correctable shift. Double check you test bench signals to make sure they match any documentation examples from the datasheet - I believe rising edge of clock should be central in each data bit. – Tom Carpenter Nov 19 '18 at 9:06
• I have tried three different alignments of serial data input with the data clock but to no avail. With clock cycle period exactly equal to the bit width, the first case where the data bit is aligned with positive edge of the clock, second with data bit aligned with negative edge of the clock cycle and the third bit with a quarter of clock cycle delay. What else should I try? – SMS Nov 19 '18 at 12:04
• @SMS could you post a simple simulatable test-bench example that shows the problem? – Tom Carpenter Nov 19 '18 at 13:12
• I made some changes in the testbench and now the deserialized output remains constant after two bitslips. but would appreciate if you can help me in understanding 1. why does it behave like this? 2. when the serial input is 8'b11001100, why the parallel output is 8'b00010011 for the first frame clock cycle? Thanks – SMS Nov 24 '18 at 10:04