cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
yinlinlijuan
Adventurer
Adventurer
507 Views
Registered: ‎03-14-2012

I cant receive right data ,when I use selectIO 10: 1 mode.

Hello all,

I am developing a camera with XC7A35TFTG256, imx274.  I used a selectIO IP as the receiver interface.

 

when imx274 output is 12bit, 10channel, I can receive right data, the system works well.

But when imx274 output is 10bit, I cant receive the right data.  I'm very confused. I can promise that the configure of imx274 regs is correct.

Now, let me show you the problem.

 

10bit.pngselectIO.png

 

Firstly, the sync code of imx274 10bit mode is {0x3FF  0x000, 0x000, 0x274}. 

I took a screenshot of the wrong data. we can see that there are only two right channel (data_decode[1], datadecode[8]).  

I must say, when imx274 output is 12bit data, it works well. so I think my hardware design is correct.   

 

So where is wrong ?

Need your help, thanks.

 

0 Kudos
3 Replies
yinlinlijuan
Adventurer
Adventurer
475 Views
Registered: ‎03-14-2012

Additionally, we can see that the first three bytes of sync code{0x3FF, 0x000, 0x000} are right at all channel, but the last bytes is wrong. 

Further, we find that the two bits [9:8] of the last sync code byte are wrong, the last bytes [7:0] are right. 

When imx274 output is 12bit, I set the selectIO  serialization factor  to 6, so there is only one ISERDESE2, with no cascaded.

But When imx274 output is 10bit, I set the selectIO  serialization factor  to 10, so there is needed  two cascaded ISERDESE2.  The master ISERDESE2 will output the low 8bit, and the slave ISERDESE2  will output the high 2bit. 

so this problem is caused of  cascaded ISERDESE2. Is that possible? if so, how to fix it ?

 

Thanks.

 

 

Tags (1)
0 Kudos
sandrao
Community Manager
Community Manager
371 Views
Registered: ‎08-08-2007

Hi @yinlinlijuan 

 

You are using a BUFIO so that would mean an BUFR for the divided clock. It would be dividing by an even number for 12:1 I'd suspect but an odd number for 10:1.

Makes me wonder how are you controlling the CE and CLR of the BUFR?

Thanks,

Sandy


------------------------------------------------------------------------------------------------

Don’t forget to reply, kudo, and accept as solution.

If starting with Versal take a look at our Versal Design Process Hub , Versal Blogs and the Versal Useful Resources .

------------------------------------------------------------------------------------------------
0 Kudos
yinlinlijuan
Adventurer
Adventurer
101 Views
Registered: ‎03-14-2012

Hi sandrao,

When the factor is 10:1, the code is as follows,

//----------------------------------------------------------------------------
// User entered comments
//----------------------------------------------------------------------------
// None
//----------------------------------------------------------------------------

`timescale 1ps/1ps

module selectio_wiz_imx274_mode1_selectio_wiz
// width of the data for the system
#(parameter SYS_W = 10,
// width of the data for the device
parameter DEV_W = 100)
(
// From the system into the device
input [SYS_W-1:0] data_in_from_pins_p,
input [SYS_W-1:0] data_in_from_pins_n,
output [DEV_W-1:0] data_in_to_device,

output delay_locked, // Locked signal from IDELAYCTRL
input ref_clock, // Reference clock for IDELAYCTRL. Has to come from BUFG.
input [SYS_W-1:0] bitslip, // Bitslip module is enabled in NETWORKING mode
// User should tie it to '0' if not needed
input clk_in_p, // Differential clock from IOB
input clk_in_n,
output clk_div_out, // Slow clock output
input clk_reset,
input io_reset);
localparam num_serial_bits = DEV_W/SYS_W;
wire clock_enable = 1'b1;
// Signal declarations
////------------------------------
// After the buffer
wire [SYS_W-1:0] data_in_from_pins_int;
// Between the delay and serdes
wire [SYS_W-1:0] data_in_from_pins_delay;
wire ref_clock_bufg;
// Array to use intermediately from the serdes to the internal
// devices. bus "0" is the leftmost bus
wire [SYS_W-1:0] iserdes_q[0:13]; // fills in starting with 0
// Create the clock logic

IBUFDS
#(.IOSTANDARD ("DIFF_HSTL_II_18"))
ibufds_clk_inst
(.I (clk_in_p),
.IB (clk_in_n),
.O (clk_in_int));

// delay the input clock
(* IODELAY_GROUP = "selectio_wiz_imx274_mode1_group" *)
IDELAYE2
# (
.CINVCTRL_SEL ("FALSE"), // TRUE, FALSE
.DELAY_SRC ("IDATAIN"), // IDATAIN, DATAIN
.HIGH_PERFORMANCE_MODE ("FALSE"), // TRUE, FALSE
.IDELAY_TYPE ("FIXED"), // FIXED, VARIABLE, or VAR_LOADABLE
.IDELAY_VALUE (0), // 0 to 31
.REFCLK_FREQUENCY (200.0),
.PIPE_SEL ("FALSE"),
.SIGNAL_PATTERN ("CLOCK")) // CLOCK, DATA
idelaye2_clk
(
.DATAOUT (clk_in_int_delay), // Delayed clock
.DATAIN (1'b0), // Data from FPGA logic
.C (1'b0),
.CE (1'b0),
.INC (1'b0),
.IDATAIN (clk_in_int),
.LD (io_reset),
.LDPIPEEN (1'b0),
.REGRST (1'b0),
.CNTVALUEIN (5'b00000),
.CNTVALUEOUT (),
.CINVCTRL (1'b0)
);

// High Speed BUFIO clock buffer
BUFIO bufio_inst
(.O(clk_in_int_buf),
.I(clk_in_int_delay));


// BUFR generates the slow clock
BUFR
#(.SIM_DEVICE("7SERIES"),
.BUFR_DIVIDE("5"))
clkout_buf_inst
(.O (clk_div),
.CE(1'b1),
.CLR(clk_reset),
.I (clk_in_int_delay));

assign clk_div_out = clk_div; // This is regional clock

// We have multiple bits- step over every bit, instantiating the required elements
genvar pin_count;
genvar slice_count;
generate for (pin_count = 0; pin_count < SYS_W; pin_count = pin_count + 1) begin: pins
// Instantiate the buffers
////------------------------------
// Instantiate a buffer for every bit of the data bus
IBUFDS
#(.DIFF_TERM ("FALSE"), // Differential termination
.IOSTANDARD ("DIFF_HSTL_II_18"))
ibufds_inst
(.I (data_in_from_pins_p [pin_count]),
.IB (data_in_from_pins_n [pin_count]),
.O (data_in_from_pins_int[pin_count]));

// Instantiate the delay primitive
////-------------------------------

(* IODELAY_GROUP = "selectio_wiz_imx274_mode1_group" *)
IDELAYE2
# (
.CINVCTRL_SEL ("FALSE"), // TRUE, FALSE
.DELAY_SRC ("IDATAIN"), // IDATAIN, DATAIN
.HIGH_PERFORMANCE_MODE ("FALSE"), // TRUE, FALSE
.IDELAY_TYPE ("FIXED"), // FIXED, VARIABLE, or VAR_LOADABLE
.IDELAY_VALUE (17), // 0 to 31
.REFCLK_FREQUENCY (200.0),
.PIPE_SEL ("FALSE"),
.SIGNAL_PATTERN ("DATA")) // CLOCK, DATA
idelaye2_bus
(
.DATAOUT (data_in_from_pins_delay[pin_count]),
.DATAIN (1'b0), // Data from FPGA logic
.C (clk_div),
.CE (1'b0),
.INC (1'b0),
.IDATAIN (data_in_from_pins_int [pin_count]), // Driven by IOB
.LD (1'b0),
.REGRST (1'b0),
.LDPIPEEN (1'b0),
.CNTVALUEIN (5'b00000),
.CNTVALUEOUT (),
.CINVCTRL (1'b0)
);


// Instantiate the serdes primitive
////------------------------------

// local wire only for use in this generate loop
wire cascade_shift;
wire [SYS_W-1:0] icascade1;
wire [SYS_W-1:0] icascade2;
wire clk_in_int_inv;

assign clk_in_int_inv = ~ (clk_in_int_buf);

// declare the iserdes
ISERDESE2
# (
.DATA_RATE ("DDR"),
.DATA_WIDTH (10),
.INTERFACE_TYPE ("NETWORKING"),
.DYN_CLKDIV_INV_EN ("FALSE"),
.DYN_CLK_INV_EN ("FALSE"),
.NUM_CE (2),
.OFB_USED ("FALSE"),
.IOBDELAY ("IFD"), // Use input at DDLY to output the data on Q
.SERDES_MODE ("MASTER"))
iserdese2_master (
.Q1 (iserdes_q[0][pin_count]),
.Q2 (iserdes_q[1][pin_count]),
.Q3 (iserdes_q[2][pin_count]),
.Q4 (iserdes_q[3][pin_count]),
.Q5 (iserdes_q[4][pin_count]),
.Q6 (iserdes_q[5][pin_count]),
.Q7 (iserdes_q[6][pin_count]),
.Q8 (iserdes_q[7][pin_count]),
.SHIFTOUT1 (icascade1[pin_count]), // Cascade connections to Slave ISERDES
.SHIFTOUT2 (icascade2[pin_count]), // Cascade connections to Slave ISERDES
.BITSLIP (bitslip[pin_count]), // 1-bit Invoke Bitslip. This can be used with any DATA_WIDTH, cascaded or not.
// The amount of BITSLIP is fixed by the DATA_WIDTH selection.
.CE1 (clock_enable), // 1-bit Clock enable input
.CE2 (clock_enable), // 1-bit Clock enable input
.CLK (clk_in_int_buf), // Fast source synchronous clock driven by BUFIO
.CLKB (clk_in_int_inv), // Locally inverted fast
.CLKDIV (clk_div), // Slow clock from BUFR.
.CLKDIVP (1'b0),
.D (1'b0), // 1-bit Input signal from IOB
.DDLY (data_in_from_pins_delay[pin_count]), // 1-bit Input from Input Delay component
.RST (io_reset), // 1-bit Asynchronous reset only.
.SHIFTIN1 (1'b0),
.SHIFTIN2 (1'b0),
// unused connections
.DYNCLKDIVSEL (1'b0),
.DYNCLKSEL (1'b0),
.OFB (1'b0),
.OCLK (1'b0),
.OCLKB (1'b0),
.O ()); // unregistered output of ISERDESE1

ISERDESE2
# (
.DATA_RATE ("DDR"),
.DATA_WIDTH (10),
.INTERFACE_TYPE ("NETWORKING"),
.DYN_CLKDIV_INV_EN ("FALSE"),
.DYN_CLK_INV_EN ("FALSE"),
.NUM_CE (2),
.OFB_USED ("FALSE"),
.IOBDELAY ("IFD"), // Use input at DDLY to output the data on Q
.SERDES_MODE ("SLAVE"))
iserdese2_slave (
.Q1 (),
.Q2 (),
.Q3 (iserdes_q[8][pin_count]),
.Q4 (iserdes_q[9][pin_count]),
.Q5 (iserdes_q[10][pin_count]),
.Q6 (iserdes_q[11][pin_count]),
.Q7 (iserdes_q[12][pin_count]),
.Q8 (iserdes_q[13][pin_count]),
.SHIFTOUT1 (),
.SHIFTOUT2 (),
.SHIFTIN1 (icascade1[pin_count]), // Cascade connection with Master ISERDES
.SHIFTIN2 (icascade2[pin_count]), // Cascade connection with Master ISERDES
.BITSLIP (bitslip[pin_count]), // 1-bit Invoke Bitslip. This can be used with any DATA_WIDTH, cascaded or not.
// The amount of BITSLIP is fixed by the DATA_WIDTH selection .
.CE1 (clock_enable), // 1-bit Clock enable input
.CE2 (clock_enable), // 1-bit Clock enable input
.CLK (clk_in_int_buf), // Fast source synchronous serdes clock
.CLKB (clk_in_int_inv), // Locally inverted fast clock
.CLKDIV (clk_div), // Slow clock from BUFR.
.CLKDIVP (1'b0),
.D (1'b0), // Slave ISERDES. No need to connect D, DDLY
.DDLY (1'b0),
.RST (io_reset), // 1-bit Asynchronous reset only.
// unused connections
.DYNCLKDIVSEL (1'b0),
.DYNCLKSEL (1'b0),
.OFB (1'b0),
.OCLK (1'b0),
.OCLKB (1'b0),
.O ()); // unregistered output of ISERDESE1
// Concatenate the serdes outputs together. Keep the timesliced
// bits together, and placing the earliest bits on the right
// ie, if data comes in 0, 1, 2, 3, 4, 5, 6, 7, ...
// the output will be 3210, 7654, ...
////---------------------------------------------------------
for (slice_count = 0; slice_count < num_serial_bits; slice_count = slice_count + 1) begin: in_slices
// This places the first data in time on the right
assign data_in_to_device[slice_count*SYS_W+:SYS_W] =
iserdes_q[num_serial_bits-slice_count-1];
// To place the first data in time on the left, use the
// following code, instead
// assign data_in_to_device[slice_count*SYS_W+:SYS_W] =
// iserdes_q[slice_count];
end
end
endgenerate

// IDELAYCTRL is needed for calibration
(* IODELAY_GROUP = "selectio_wiz_imx274_mode1_group" *)
IDELAYCTRL
delayctrl (
.RDY (delay_locked),
.REFCLK (ref_clock_bufg),
.RST (io_reset));

BUFG
ref_clk_bufg (
.I (ref_clock),
.O (ref_clock_bufg));
endmodule

 

0 Kudos