02-11-2019 02:04 AM
I'm using an IDDR block in a Artix7 device to sample a centre aligned clock, so that I can set a delay inside the fpga to compenstate for the clock buffer delay.
As part of this, I'm wanting to set the IDDR default outputs to '1' and '1'.
I then connect an inverted resetn signal, called set to the set pin of the IDDR, and connect the reset pin to '0'.
When I open the elaborated design to view the schematic, the set inverting gate is present, but not connected the the set pin of the IDDR. The IDDR for some reason is connected to ground?
And the code that was used (The whole design isn't finished yet):
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; library UNISIM; use UNISIM.VComponents.all; entity CLK_SYNC is Port ( RESETn : in STD_LOGIC; sysCLK : in STD_LOGIC; CLK_P : in STD_LOGIC; CLK_N : in STD_LOGIC; CLK_BUFIO : out STD_LOGIC; CLK_BUFR : out STD_LOGIC ); end CLK_SYNC; architecture Behavioral of CLK_SYNC is signal CLK : STD_LOGIC; signal CLK_BUFIOi : STD_LOGIC; signal CLK_BUFRi : STD_LOGIC; signal CLK_DELAYED : STD_LOGIC; signal CLK_Q1 : STD_LOGIC; signal CLK_Q2 : STD_LOGIC; signal CLK_LOCKED_ASYNC : STD_LOGIC; signal CLK_LOCKED_ASYNC_LATCHED : STD_LOGIC; signal CLK_RUNNING : STD_LOGIC; signal SET : STD_LOGIC; signal DELAY_CE : STD_LOGIC := '0'; signal CLK_FINISHED_SYNCRO : STD_LOGIC_VECTOR(2 downto 0); attribute ASYNC_REG : string; attribute ASYNC_REG of CLK_FINISHED_SYNCRO: signal is "TRUE"; begin SET <= not(RESETn); CLK_DIFF_BUF : IBUFDS generic map ( DIFF_TERM => TRUE, IBUF_LOW_PWR => TRUE, IOSTANDARD => "DEFAULT") port map ( O => CLK, I => CLK_P, IB => CLK_N ); CLK_BUFIO_BUF : BUFIO port map ( O => CLK_BUFIOi, I => CLK_DELAYED ); CLK_BUFR_BUF : BUFR generic map ( BUFR_DIVIDE => "BYPASS", -- Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8" SIM_DEVICE => "7SERIES" -- Must be set to "7SERIES" ) port map ( O => CLK_BUFRi, -- 1-bit output: Clock output port CE => '1', -- 1-bit input: Active high, clock enable (Divided modes only) CLR => '0', -- 1-bit input: Active high, asynchronous clear (Divided modes only) I => CLK_DELAYED -- 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect ); CLK_IDDR : IDDR generic map ( DDR_CLK_EDGE => "SAME_EDGE_PIPELINED", -- "OPPOSITE_EDGE", "SAME_EDGE" -- or "SAME_EDGE_PIPELINED" INIT_Q1 => '1', -- Initial value of Q1: '0' or '1' INIT_Q2 => '1', -- Initial value of Q2: '0' or '1' SRTYPE => "ASYNC") -- Set/Reset type: "SYNC" or "ASYNC" port map ( Q1 => CLK_Q1, Q2 => open, C => CLK_BUFIOi, -- 1-bit clock input CE => '1', -- 1-bit clock enable input D => CLK, -- 1-bit DDR data input R => '0', -- 1-bit reset S => SET -- 1-bit set ); CLK_IDELAYE2 : IDELAYE2 generic map ( CINVCTRL_SEL => "FALSE", -- Enable dynamic clock inversion (FALSE, TRUE) DELAY_src=> "IDATAIN", -- Delay input (IDATAIN, DATAIN) HIGH_PERFORMANCE_MODE => "FALSE", -- Reduced jitter ("TRUE"), Reduced power ("FALSE") IDELAY_TYPE => "VARIABLE", -- FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE IDELAY_VALUE => 0, -- Input delay tap setting (0-31) PIPE_SEL => "FALSE", -- Select pipelined mode, FALSE, TRUE REFCLK_FREQUENCY => 200.0, -- IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). SIGNAL_PATTERN => "CLOCK" -- DATA, CLOCK input signal ) port map ( CNTVALUEOUT => open, DATAOUT => CLK_DELAYED, -- 1-bit output: Delayed data output C => sysCLK, -- 1-bit input: Clock input CE => DELAY_CE, -- 1-bit input: Active high enable increment/decrement input CINVCTRL => '0', CNTVALUEIN => "00000", DATAIN => '0', IDATAIN => CLK, -- 1-bit input: Data input from the I/O INC => '1', -- 1-bit input: Increment / Decrement tap delay input LD => '0', -- 1-bit input: Load IDELAY_VALUE input LDPIPEEN => '0', -- 1-bit input: Enable PIPELINE register to load data input REGRST => '0'--rSET -- 1-bit input: Active-high reset tap-delay input ); CLK_Q2_PROC :process(RESETn, CLK_BUFRi) begin if RESETn = '0' then CLK_Q2 <= '1'; elsif rising_edge(CLK_BUFRi) then CLK_Q2 <= CLK_Q1; end if; end process; CLK_LOCKED_ASYNC <= CLK_Q1 AND not(CLK_Q2); --This goes high when a rising edge between taps occures CLK_LOCKED_ASYNC_LATCHED_proc : process(RESETn, CLK_BUFRi) begin if RESETn = '0' then CLK_LOCKED_ASYNC_LATCHED <= '0'; elsif rising_edge(CLK_BUFRi) then if(CLK_LOCKED_ASYNC = '1') then CLK_LOCKED_ASYNC_LATCHED <= '1'; end if; end if; end process; CLK_RUNNING_proc : process(RESETn, CLK_BUFRi) begin if RESETn = '0' then CLK_RUNNING <= '0'; elsif rising_edge(CLK_BUFRi) then CLK_RUNNING <= '1'; end if; end process; CLK_FINISHED_SYNCRO_proc :process(sysCLK) begin if rising_edge(sysCLK) then CLK_FINISHED_SYNCRO <= CLK_FINISHED_SYNCRO(2 downto 1) & CLK_LOCKED_ASYNC_LATCHED; end if; end process; CLK_BUFIO <= CLK_BUFIOi; CLK_BUFR <= CLK_BUFRi; end Behavioral;
I can set the Set/Reset connections to '0' or '1', and the schematic will reflect this.
Is there anything obvious I'm doing/not doing that is causing this?
02-11-2019 05:09 AM - edited 02-11-2019 05:20 AM
Putting an IDDR on the clock path is not recommended.
I would rather advise you to put the IDDR on the data path and adjust it accordingly.
btw - I didn't take a look at your code.
02-11-2019 05:34 AM
02-11-2019 06:58 AM - edited 02-11-2019 07:06 AM
I'm using the IDDR in order to capture the clock, using the same clock thats been buffered.
This makes little sense. No need for that.
From the schematic, I see that the o/p of the IBUFDS is connected to the D i/p of IDDR. I am not very sure if an IDDR should be used in this way.
You use the IDDR to capture the incoming data (from its clock) and the IDDR should be clocked with this incoming clock. Here is an eg of IDDR instiantiation for RGMII data capture.
rgmii_rx_data_in: IDDR generic map( DDR_CLK_EDGE => "SAME_EDGE_PIPELINED", INIT_Q1 => '0', -- Initial value of Q1: ’0’ or ’1’ INIT_Q2 => '0', -- Initial value of Q2: ’0’ or ’1’ SRTYPE => "SYNC" -- Set/Reset type: "SYNC" or "ASYNC" ) port map( Q1 => lower_nibble_output, Q2 => higher_nibble_output, C => input_ddr_clock, CE => '1', D => input_data, R => '0', S => '0' );
02-11-2019 07:32 AM - edited 02-11-2019 07:33 AM
I'm not using this particular IDDR to capture the data stream.
I'm using it to set the idelay tap value that delays the clock.
Because when you take a clock from a clock pin onto the clock network you introduce a delay, it becomes out of sync with the data that doesn't have this clock buffer delay.
To rectify this, you can sample the incoming clock as if it was data with a buffered verison that goes through a delay, adjust the delay until the clock is sampling the clock edge. At this point your clock is one cycle behind, but phase aligned.
My Incoming Data stream I'm sampling is 360MHz DDR, so I have a very small valid window, the clock is also center aligned, i.e it is already in the correct place to sample the data so all I have to do is remove the clock insertion delay.
02-11-2019 08:39 AM
I agree with your above comments.
In that case you can feed your incoming clock directly to the IDELAY2 to its IDATAIN pin.
02-11-2019 09:13 AM
This kind of circuit (sampling the clock with a delayed version of itself) is part of a dynamic calibration technique to find the ideal sample point of an incoming data stream. The result of this clock sampled with itself is used to tune the tap setting of the IDELAY - since this interface is center aligned, you use the IDELAY to find the "metastability" point of the clock sampled with itself - if the sampled clock is at the metastability point, then you are sampling it at the "worst possible time" - as the clock is changing. Using this same clock to sample the data is therefore at the "best possible time" since the clock and data are 90 degrees out of phase (center aligned).
I can't comment on the issue you have with the SET/RESETn - it looks like a bug???
But I do have a couple of comments.
First, since you are using only the IDDR (and not an ISERDES), I am not sure you need the BUFIO. The clock of the IDDR can be clocked directly with the output of the BUFR, and I have observed that timing is slightly better when doing this (but I mean VERY slightly).
Secondly, an IDDR with the Q2 ignored is just an IOB flip-flop (and Q2 is currently not connected in your design) - you may find it easier to control how the reset of this circuit works if you infer a conventional flip-flop (and force it into the IOB) instead of instantiating the IDDR.
02-11-2019 09:18 AM
Thank you for the reply,
You describe exactly the technique I'm looking at. I didn't realise I didn't need the BUFIO and could just use the BUFR.
I used the IDDR as a quick way to force the flipflop into the IOB as its not something I've yet needed to do before.
I'll raise the bug with Xilinx,as I can connect to the Set/Reset pin if its connected to any port of the entity... just not any signals within the entity itself.
02-12-2019 04:02 AM
Thanks for the explanation, it was not clear to me before.