cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Adventurer
Adventurer
6,791 Views
Registered: ‎05-15-2014

How to connect output of ODELAY to IOB

Jump to solution

Hello

 

In the below figure taken from SelectIO Interface Wizard v5.1 (pg070-selectio-wiz.pdf) it is shown that:

  • a signal from FPGA fabric can be connected to the input of ODDR,
  • output of ODDR can be connected to input of ODELAY,
  • output of ODELAY can be connected to IOB. 

1.jpg

In order to check this connection manually I wrote the code below.

Since IOB constraint are for registers I tried to drive LED (output reg) signal sequentially.

 

However I get the error.

 

[Route 35-54] Net: clkAfterDelay is not completely routed.

 

Can anyone tell what the problem is? 

________________________________________________________________________________________________
module top(
     input SYSCLK_P, input SYSCLK_N, input rst, output reg LED=0
);

wire SYSCLK;
wire clk200MHz;

 

IBUFDS #(
     .DIFF_TERM("FALSE"), // Differential Termination
     .IBUF_LOW_PWR("TRUE"), // Low power="TRUE", Highest performance="FALSE"
     .IOSTANDARD("DEFAULT") // Specify the input I/O standard
) IBUFDS_inst (
     .O(SYSCLK), // Buffer output
     .I(SYSCLK_P), // Diff_p buffer input (connect directly to top-level port)
     .IB(SYSCLK_N) // Diff_n buffer input (connect directly to top-level port)
);

 

BUFG BUFG_inst_C0 (
     .O(clk200MHz), // 1-bit output: Clock output
     .I(SYSCLK) // 1-bit input: Clock input
);

wire clkAfterODDR;
wire clkAfterDelay;

 

ODDR #(
     .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
     .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1
     .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
) ODDR_inst (
     .Q(clkAfterODDR), // 1-bit DDR output
     .C(clk200MHz), // 1-bit clock input
     .CE(1'b1), // 1-bit clock enable input
     .D1(1'b0), // 1-bit data input (positive edge)
     .D2(1'b1), // 1-bit data input (negative edge)
     .R(1'b0), // 1-bit reset
     .S(1'b0) // 1-bit set
);

 

(* IODELAY_GROUP = "iodelay_group_T" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL

IDELAYCTRL IDELAYCTRL_inst (
     .RDY(IDELAYCTRLRDY), // 1-bit output: Ready output
     .REFCLK(clk200MHz), // 1-bit input: Reference clock input
     .RST(rst) // 1-bit input: Active high reset input
);

 

(* IODELAY_GROUP = "iodelay_group_T" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL

ODELAYE2 #(
     .CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE)
     .DELAY_SRC("ODATAIN"), // Delay input (ODATAIN, CLKIN)
     .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
     .ODELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
     .ODELAY_VALUE(7), // Output 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
)
ODELAYE2_inst (
     .CNTVALUEOUT(CNTVALUEOUT), // 5-bit output: Counter value output
     .DATAOUT(clkAfterDelay), // 1-bit output: Delayed data/clock output
     .C(1'b0), // 1-bit input: Clock input
     .CE(1'b0), // 1-bit input: Active high enable increment/decrement input
     .CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input
     .CLKIN(1'b0), // 1-bit input: Clock delay input
     .CNTVALUEIN(5'b00000), // 5-bit input: Counter value input
     .INC(1'b0), // 1-bit input: Increment / Decrement tap delay input
     .LD(1'b0), // 1-bit input: Loads ODELAY_VALUE tap delay in VARIABLE mode, in VAR_LOAD or
                              // VAR_LOAD_PIPE mode, loads the value of CNTVALUEIN

     .LDPIPEEN(1'b0), // 1-bit input: Enables the pipeline register to load data
     .ODATAIN(clkAfterODDR), // 1-bit input: Output delay data input
     .REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input
);

 

always @ (posedge clk200MHz)begin
     LED<=clkAfterDelay;
end


endmodule

________________________________________________________________________________________________

 

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Guide
Guide
11,786 Views
Registered: ‎01-23-2009

The output of the ODELAY must go directly to the OBUF.

 

In your code, you are trying to instantiate a flip-flop on the signal coming out of the ODELAY (which is illegal.

 

always @ (posedge clk200MHz)begin
     LED<=clkAfterDelay; 
end

 

You need to send the output directly to an OBUF either by direct instantiation

 

OBUF OBUF_inst (.I(clkAfterDelay), .O(LED));

 

or by letting the tools infer the OBUF - so either rename clkAfterDelay to be LED, and have that be the output of the ODELAY, or you may be able to use

 

assign LED = clkAfterDelay;

 

(although I am not sure what you expect to accomplish by mirroring a delayed version of a 200MHz clock to an LED)

 

Avrum

View solution in original post

0 Kudos
3 Replies
Highlighted
Guide
Guide
11,787 Views
Registered: ‎01-23-2009

The output of the ODELAY must go directly to the OBUF.

 

In your code, you are trying to instantiate a flip-flop on the signal coming out of the ODELAY (which is illegal.

 

always @ (posedge clk200MHz)begin
     LED<=clkAfterDelay; 
end

 

You need to send the output directly to an OBUF either by direct instantiation

 

OBUF OBUF_inst (.I(clkAfterDelay), .O(LED));

 

or by letting the tools infer the OBUF - so either rename clkAfterDelay to be LED, and have that be the output of the ODELAY, or you may be able to use

 

assign LED = clkAfterDelay;

 

(although I am not sure what you expect to accomplish by mirroring a delayed version of a 200MHz clock to an LED)

 

Avrum

View solution in original post

0 Kudos
Highlighted
Adventurer
Adventurer
6,765 Views
Registered: ‎05-15-2014

thanks for your answer

 

 

I misunderstood the IOB abbreviation. I thought that IOB was the register that we use by the constraints

 

set_property DONT_TOUCH TRUE [get_cells {a_reg} ]

set_property IOB TRUE [get_cells {a_reg} ]

 

but it is not the case. it stands for I/O block.

 

I will write my actual problem to another post

 

best regards.

0 Kudos
Highlighted
Guide
Guide
6,754 Views
Registered: ‎01-23-2009

Your confusion comes from the fact that we refer to the flip-flop that is located in the IOB as the "IOB flip-flop". In ISE, we would force a flip-flop into the IOB by setting the IOB attribute to "true" on the flip-flop - in this case, the nomenclature was clear - we want this flip-flop to be forced into the IOB (or more specifically to have this register use the flip-flop that exists in the IOB - we want it placed there).

 

In Vivado, the IOB property can still be applied to the flip-flop (as you showed in your example), which says the same thing - put this flip-flop in the input/output block. However in Vivado the IOB property can also be applied to the port instead of the flip-flop - it is actually pushed backward to the flip-flop connected to the port. So that makes the nomenclature a bit more confusing.

 

Avrum

0 Kudos