carwe
Newbie level 2
- Joined
- Jan 3, 2011
- Messages
- 2
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,396
Hi,
I'm having some problems to understand the exact behavior of the ISERDESE2 primitive. What I need to understand is exactly how the unit will distribute the serial input to the bits in the output (paralell) words, or in other words, how ISERDESE aligns the frames on the incoming serial data stream in order to deliver the paralell words.
Here is a screenshot showing the signals on some of the ports of a cascaded (width expansion) ISERDES-pair:
This example is actually from a simulation of the example design that is generated by Coregen (SelectIO Interface Wizard). Width is 14 bits, DDR mode. The VHDL code is inserted below this message.
The signal iserdes_q_vec is a vector [slave q8..q3] & [master q8..q1].
From the input (ddly) and output (iserdes_q_vec) I can clearly see how the frame is aligned - I have marked the frame by the two cursors. It is clear that the ddly input within this frame (10000111100100) is what appears on iserdes_q_vec on the next rising edge of clkdiv.
The reason for this particular alignment is however unknown to me. I've looked in the User Guide (ug471) but can't find info on this.
I tried to de-assert rst in various ways but couldn't really make anything out of the results (in this design, rst is de-asserted synchronously with clkdiv, as suggested by the user guide).
In my case, I have no training pattern and hance can't find the right alignment with bitslip operations. In my case, for the serial data, clkdiv is equal to the frame clock. From the simulation I can of course determine how the frame is placed in the serial data, and fix the paralell words in custom logic, but then I need to understand why I get this particular offset, and be convinced that I will always get exactly this particular offset.
I would intuitively have expected clkdiv to act as a frame clock as well, but nothing in the UG suggests that, and according to the simulation, that is also clearly not the case.
Device: xc7k160t-2
Thanks in advance,
Carl
I'm having some problems to understand the exact behavior of the ISERDESE2 primitive. What I need to understand is exactly how the unit will distribute the serial input to the bits in the output (paralell) words, or in other words, how ISERDESE aligns the frames on the incoming serial data stream in order to deliver the paralell words.
Here is a screenshot showing the signals on some of the ports of a cascaded (width expansion) ISERDES-pair:
This example is actually from a simulation of the example design that is generated by Coregen (SelectIO Interface Wizard). Width is 14 bits, DDR mode. The VHDL code is inserted below this message.
The signal iserdes_q_vec is a vector [slave q8..q3] & [master q8..q1].
From the input (ddly) and output (iserdes_q_vec) I can clearly see how the frame is aligned - I have marked the frame by the two cursors. It is clear that the ddly input within this frame (10000111100100) is what appears on iserdes_q_vec on the next rising edge of clkdiv.
The reason for this particular alignment is however unknown to me. I've looked in the User Guide (ug471) but can't find info on this.
I tried to de-assert rst in various ways but couldn't really make anything out of the results (in this design, rst is de-asserted synchronously with clkdiv, as suggested by the user guide).
In my case, I have no training pattern and hance can't find the right alignment with bitslip operations. In my case, for the serial data, clkdiv is equal to the frame clock. From the simulation I can of course determine how the frame is placed in the serial data, and fix the paralell words in custom logic, but then I need to understand why I get this particular offset, and be convinced that I will always get exactly this particular offset.
I would intuitively have expected clkdiv to act as a frame clock as well, but nothing in the UG suggests that, and according to the simulation, that is also clearly not the case.
Device: xc7k160t-2
Thanks in advance,
Carl
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 -- file: selectio_if_wiz_v4_1.vhd -- (c) Copyright 2009 - 2011 Xilinx, Inc. All rights reserved. -- -- This file contains confidential and proprietary information -- of Xilinx, Inc. and is protected under U.S. and -- international copyright and other intellectual property -- laws. -- -- DISCLAIMER -- This disclaimer is not a license and does not grant any -- rights to the materials distributed herewith. Except as -- otherwise provided in a valid license issued to you by -- Xilinx, and to the maximum extent permitted by applicable -- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND -- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES -- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING -- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- -- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and -- (2) Xilinx shall not be liable (whether in contract or tort, -- including negligence, or under any other theory of -- liability) for any loss or damage of any kind or nature -- related to, arising under or in connection with these -- materials, including for any direct, or any indirect, -- special, incidental, or consequential loss or damage -- (including loss of data, profits, goodwill, or any type of -- loss or damage suffered as a result of any action brought -- by a third party) even if such damage or loss was -- reasonably foreseeable or Xilinx had been advised of the -- possibility of the same. -- -- CRITICAL APPLICATIONS -- Xilinx products are not designed or intended to be fail- -- safe, or for use in any application requiring fail-safe -- performance, such as life-support or safety devices or -- systems, Class III medical devices, nuclear facilities, -- applications related to the deployment of airbags, or any -- other applications that could lead to death, personal -- injury, or severe property or environmental damage -- (individually and collectively, "Critical -- Applications"). Customer assumes the sole risk and -- liability of any use of Xilinx products in Critical -- Applications, subject only to applicable laws and -- regulations governing limitations on product liability. -- -- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS -- PART OF THIS FILE AT ALL TIMES. ------------------------------------------------------------------------------ -- User entered comments ------------------------------------------------------------------------------ -- None ------------------------------------------------------------------------------ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; use ieee.std_logic_misc.all; use ieee.numeric_std.all; library unisim; use unisim.vcomponents.all; entity selectio_if_wiz_v4_1 is generic (-- width of the data for the system sys_w : integer := 1; -- width of the data for the device dev_w : integer := 14); port ( -- From the system into the device DATA_IN_FROM_PINS : in std_logic_vector(sys_w-1 downto 0); DATA_IN_TO_DEVICE : out std_logic_vector(dev_w-1 downto 0); DELAY_LOCKED : out std_logic; -- Locked signal from IDELAYCTRL REF_CLOCK : in std_logic; -- Reference Clock for IDELAYCTRL. Has to come from BUFG. BITSLIP : in std_logic; -- Bitslip module is enabled in NETWORKING mode -- User should tie it to '0' if not needed -- Clock and reset signals CLK_IN : in std_logic; -- Fast clock from PLL/MMCM CLK_DIV_IN : in std_logic; -- Slow clock from PLL/MMCM IO_RESET : in std_logic); -- Reset signal for IO circuit end selectio_if_wiz_v4_1; architecture xilinx of selectio_if_wiz_v4_1 is attribute CORE_GENERATION_INFO : string; attribute CORE_GENERATION_INFO of xilinx : architecture is "selectio_if_wiz_v4_1,selectio_wiz_v4_1,{component_name=selectio_if_wiz_v4_1,bus_dir=INPUTS,bus_sig_type=SINGLE,bus_io_std=LVCMOS18,use_serialization=true,use_phase_detector=false,serialization_factor=14,enable_bitslip=false,enable_train=false,system_data_width=1,bus_in_delay=NONE,bus_out_delay=NONE,clk_sig_type=SINGLE,clk_io_std=LVCMOS18,clk_buf=BUFIO2,active_edge=RISING,clk_delay=NONE,v6_bus_in_delay=FIXED,v6_bus_out_delay=NONE,v6_clk_buf=MMCM,v6_active_edge=DDR,v6_ddr_alignment=SAME_EDGE_PIPELINED,v6_oddr_alignment=SAME_EDGE,ddr_alignment=C0,v6_interface_type=NETWORKING,interface_type=NETWORKING,v6_bus_in_tap=2,v6_bus_out_tap=0,v6_clk_io_std=LVCMOS18,v6_clk_sig_type=SINGLE}"; constant clock_enable : std_logic := '1'; signal unused : std_logic; signal clk_in_int_buf : std_logic; signal clk_div_in_int : std_logic; -- After the buffer signal data_in_from_pins_int : std_logic_vector(sys_w-1 downto 0); -- Between the delay and serdes signal data_in_from_pins_delay : std_logic_vector(sys_w-1 downto 0); signal ce_in_uc : std_logic; signal inc_in_uc : std_logic; signal regrst_in_uc : std_logic; signal ce_out_uc : std_logic; signal inc_out_uc : std_logic; signal regrst_out_uc : std_logic; constant num_serial_bits : integer := dev_w/sys_w; type serdarr is array (0 to 13) of std_logic_vector(sys_w-1 downto 0); -- Array to use intermediately from the serdes to the internal -- devices. bus "0" is the leftmost bus -- * fills in starting with 0 signal iserdes_q : serdarr := (( others => (others => '0'))); signal serdesstrobe : std_logic; signal icascade1 : std_logic_vector(sys_w-1 downto 0); signal icascade2 : std_logic_vector(sys_w-1 downto 0); signal clk_in_int_inv : std_logic; attribute IODELAY_GROUP : string; attribute IODELAY_GROUP of delayctrl : label is "selectio_if_wiz_v4_1_group"; begin -- Create the clock logic -- We have multiple bits- step over every bit, instantiating the required elements pins: for pin_count in 0 to sys_w-1 generate attribute IODELAY_GROUP of idelaye2_bus: label is "selectio_if_wiz_v4_1_group"; signal iserdes_q_vec: std_logic_vector(13 downto 0); begin -- Instantiate the buffers ---------------------------------- -- Instantiate a buffer for every bit of the data bus ibuf_inst : IBUF generic map ( IOSTANDARD => "LVCMOS18") port map ( I => DATA_IN_FROM_PINS (pin_count), O => data_in_from_pins_int(pin_count)); -- Instantiate the delay primitive ----------------------------------- idelaye2_bus : IDELAYE2 generic map ( 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 => 16, -- 0 to 31 REFCLK_FREQUENCY => 200.0, PIPE_SEL => "FALSE", SIGNAL_PATTERN => "DATA" -- CLOCK, DATA ) port map ( DATAOUT => data_in_from_pins_delay(pin_count), DATAIN => '0', -- Data from FPGA logic C => CLK_DIV_IN, CE => ce_in_uc, INC => inc_in_uc, IDATAIN => data_in_from_pins_int (pin_count), -- Driven by IOB LD => '0', REGRST => regrst_in_uc, LDPIPEEN => '0', CNTVALUEIN => "00000", CNTVALUEOUT => open, CINVCTRL => '0' ); -- Instantiate the serdes primitive ---------------------------------- clk_in_int_inv <= not CLK_IN; process(iserdes_q) begin for i in 13 downto 0 loop iserdes_q_vec(i) <= iserdes_q(i)(pin_count); end loop; end process; -- declare the iserdes iserdese2_master : ISERDESE2 generic map ( DATA_RATE => "DDR", DATA_WIDTH => 14, 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 Q1-Q6 SERDES_MODE => "MASTER") port map ( 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 connection to Slave ISERDES SHIFTOUT2 => icascade2(pin_count), -- Cascade connection to Slave ISERDES BITSLIP => BITSLIP, -- 1-bit Invoke Bitslip. This can be used with any -- DATA_WIDTH, cascaded or not. CE1 => clock_enable, -- 1-bit Clock enable input CE2 => clock_enable, -- 1-bit Clock enable input CLK => CLK_IN, -- Fast clock driven by MMCM CLKB => clk_in_int_inv, -- Locally inverted clock CLKDIV => CLK_DIV_IN, -- Slow clock driven by MMCM CLKDIVP => '0', D => '0', DDLY => data_in_from_pins_delay(pin_count), -- 1-bit Input signal from IODELAYE1. RST => IO_RESET, -- 1-bit Asynchronous reset only. SHIFTIN1 => '0', SHIFTIN2 => '0', -- unused connections DYNCLKDIVSEL => '0', DYNCLKSEL => '0', OFB => '0', OCLK => '0', OCLKB => '0', O => open); -- unregistered output of ISERDESE1 iserdese2_slave : ISERDESE2 generic map ( DATA_RATE => "DDR", DATA_WIDTH => 14, 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 Q1-Q6 SERDES_MODE => "SLAVE") port map ( Q1 => open, Q2 => open, 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 => open, SHIFTOUT2 => open, SHIFTIN1 => icascade1(pin_count), -- Cascade connections from Master ISERDES SHIFTIN2 => icascade2(pin_count), -- Cascade connections from Master ISERDES BITSLIP => BITSLIP, -- 1-bit Invoke Bitslip. This can be used with any -- DATA_WIDTH, cascaded or not. CE1 => clock_enable, -- 1-bit Clock enable input CE2 => clock_enable, -- 1-bit Clock enable input CLK => CLK_IN, -- Fast clock driven by MMCM CLKB => clk_in_int_inv, -- locally inverted clock CLKDIV => CLK_DIV_IN, -- Slow clock driven by MMCM CLKDIVP => '0', D => '0', -- Slave ISERDES module. No need to connect D, DDLY DDLY => '0', RST => IO_RESET, -- 1-bit Asynchronous reset only. -- unused connections DYNCLKDIVSEL => '0', DYNCLKSEL => '0', OFB => '0', OCLK => '0', OCLKB => '0', O => open); -- 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, ... ------------------------------------------------------------- in_slices: for slice_count in 0 to num_serial_bits-1 generate begin -- This places the first data in time on the right DATA_IN_TO_DEVICE(slice_count) <= iserdes_q(num_serial_bits-slice_count-1)(0); -- To place the first data in time on the left, use the -- following code, instead -- DATA_IN_TO_DEVICE(slice_count) <= -- iserdes_q(slice_count); end generate in_slices; end generate pins; -- IDELAYCTRL is needed for calibration delayctrl : IDELAYCTRL port map ( RDY => DELAY_LOCKED, REFCLK => REF_CLOCK, RST => IO_RESET ); end xilinx;
Last edited by a moderator: