cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Adventurer
Adventurer
399 Views
Registered: ‎04-06-2012

Zynq-7000: As soon as I cascade 2 IDELAYE2 together, it causes implementation failures elsewhere in the design

Jump to solution

Hello,

I have a working design where 36 LVDS lines enter a custom IP Core, where each line is routed through an IBUFDS then immediately into an IDELAYE2. This works #1 and compile fine. However, I've found out that a single IDELAYE2 at 200MHz has 78.125ps steps, for a total maximum delay of 2.5ns. This isn't enough for some of the lines, so I have decided to cascade 2 IDELAYE2 blocks together as I have seen that it is not only possible, but the IDELAYE2 cells are also made to support this.

As required, the first IDELAYE2 uses IDATAIN whereas the cascaded IDELAYE2 uses DATAIN.

However, as soon as I cascade 2 IDELAYE2 cells together I have implementation issues. It turns out there's always an IOBUF for an unrelated signal that somehow end up being unplaced. This isn't a timing issue, the compiler simply states that the required IOBUF on the other pin cannot be placed.

I've tried playing with the synthesis and implementation strategies but the problem always happens. I've also tried reducing the number of lines from 36 to 8 thinking it would loosen up the placement, but it still happened. Interestingly enough, this reduced design requires a total of 8x2 = 16 IDELAYE2 cells and doesn't work, whereas the first version without cascaded IDELAY2 cells used 36 of them and worked just fine.

Would someone be kind enough to help me figure out this issue?I don't understand how an IDELAY2 can make an IOBUF somehow unplaceable, and I'm not sure how I should proceed to figure out exactly what is going wrong.

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
Highlighted
Adventurer
Adventurer
220 Views
Registered: ‎04-06-2012

That was it! Adding a constraint to prohibit using the IDELAYE2 found in the corner cell fixed my issue. I believe this confirms my theory that the signal on the associated IOB was getting "trapped" by the external using its IDELAYE2, but I will admit I'm not entirely sure this is what happened as I have limited knowledge in this area.

Anyhow, thanks for the tips markg@prosensing.com. Your reply forced me to look what was going on "under the hood" and that's how I found what appeared to be the issue, and the corresponding solution.

It seems weird that the compiler let this error happen however, considering there were plenty of unused IDELAYE2 cells that could have been used instead. Do you believe this should be considered a bug? I even tried multiple implementation strategies and all of them used the problematic IDELAYE2 cell, which means that trying different strategies did nothing to help in this case.

compile_good.png

View solution in original post

0 Kudos
6 Replies
Highlighted
359 Views
Registered: ‎01-22-2015

@lauziepi 

The following post suggests that Vivado v2020.1 is having trouble with IOBUF.  Specifically, when packing registers into the IOB with the IOBUF, it seems that two OLOGIC are incorrectly used instead of one OLOGIC.

https://forums.xilinx.com/t5/Synthesis/DRC-UTLZ-1-Resource-utilization-OLOGIC-over-utilized-in-Top/m-p/1123764#M35670

Vivado v2018.3 does not have this problem with IOBUF.

  1. Which version of Vivado are you using?
  2. Can you try your design using Vivado v2018.3?
  3. Are you instantiation IOBUF or inferring it?
  4. If you are using IOB=TRUE for the IOBUF (causing registers to be placed in the IOB), can you remove IOB=TRUE as a test to see if this affects the "IOBUF Unplaced" warnings?
  5. Each IO tile has only one IDELAYE2. So, your cascade of two IDELAYE2 spans two IO tiles. Can you see if the second tile contains the unplaced IOBUF?

Cheers,
Mark

 

Highlighted
Adventurer
Adventurer
263 Views
Registered: ‎04-06-2012

Hi markg@prosensing.com,

thanks for the fast and thorough reply! I will give you partial answers for now, since after posting my thread I recompiled with a temporary version of the project that removed the specific I/O signal that was causing placement errors. Now that I see that there is 1 IDELAY element per IOB, the error I had makes more sense.

I will recompile later the buggy project on my own personal time, as my final solution will end up using only one IDELAY per input which means the error will not affect me. I still want to figure out exactly what is going on since:

  1. I'm curious
  2. You took some time to help me
  3. It could help someone else that runs into a similar issue

Here are some partial answers to your 5 questions for now:

Which version of Vivado are you using?

2019.1

Can you try your design using Vivado v2018.3?

Yes, I should be able to recompile the project as-is using this specific version.

Are you instantiation IOBUF or inferring it?

I instantiate explicitly in VHDL the IBUFDS on the LVDS signals on which I apply the cascaded IDELAYs, and I instantiate explicitly in VHDL the IOBUF on the unrelated signal that ends up unplaced as soon as I cascade IDELAYs.

If you are using IOB=TRUE for the IOBUF (causing registers to be placed in the IOB), can you remove IOB=TRUE as a test to see if this affects the "IOBUF Unplaced" warnings?

Where is this property usually set? My instantiation of the IOBUFs is based on the example from the language template library. I set DRIVE, IOSTANDARD, SLEW and IBUF_LOW_PWR according to my needs. Here's a copy of the language template library example:

IOBUF #(
.DRIVE(12), // Specify the output drive strength
.IBUF_LOW_PWR("TRUE"), // Low Power - "TRUE", High Performance = "FALSE"
.IOSTANDARD("DEFAULT"), // Specify the I/O standard
.SLEW("SLOW") // Specify the output slew rate
) IOBUF_inst (
.O(O), // Buffer output
.IO(IO), // Buffer inout port (connect directly to top-level port)
.I(I), // Buffer input
.T(T) // 3-state enable input, high=input, low=output
);

Each IO tile has only one IDELAYE2. So, your cascade of two IDELAYE2 spans two IO tiles. Can you see if the second tile contains the unplaced IOBUF?

I'll have to recompile another version of the project to answer this, but I went ahead and opened the floor planner. When I used the cascaded IDELAYE2s I indeed noticed that they were getting routed all over the place (to IOBs that had unused IDELAYE2 elements).

Highlighted
Adventurer
Adventurer
234 Views
Registered: ‎04-06-2012

markg@prosensing.com 

Some more information for now. I have recompiled the version of the project that has an unplaced net error. The error message says one specific net could not be routed: RTSTAT #1 Critical Warning 1 net(s) are unrouted. The problem bus(es) and/or net(s) are system_i/uid_reader/U0/strip_uid_driver/UnqIdIOMng/IOBUF_Unique_Id_AdapterBoard[5].IOBUF_Unique_Id_AB_inst0/O. 

Could the issue be that the other unrelated resource that uses the IDELAY2 block from that IOB, somehow "traps" the signal that ends ups being unplaced? It would make sense since only this very specific I/O has issues, and it happens to be located in a corner (thus more easily "trapped").

Is there something I can do to force the compiler NOT to use the IDELAY2 from this specific IOB?

EDIT: I have answered myself. Playing around the floorplaner I have noticed that I could apply a "prohibit" property on a cell. I will see if this compile and report back.

 

failed_nets.png

0 Kudos
Highlighted
Adventurer
Adventurer
221 Views
Registered: ‎04-06-2012

That was it! Adding a constraint to prohibit using the IDELAYE2 found in the corner cell fixed my issue. I believe this confirms my theory that the signal on the associated IOB was getting "trapped" by the external using its IDELAYE2, but I will admit I'm not entirely sure this is what happened as I have limited knowledge in this area.

Anyhow, thanks for the tips markg@prosensing.com. Your reply forced me to look what was going on "under the hood" and that's how I found what appeared to be the issue, and the corresponding solution.

It seems weird that the compiler let this error happen however, considering there were plenty of unused IDELAYE2 cells that could have been used instead. Do you believe this should be considered a bug? I even tried multiple implementation strategies and all of them used the problematic IDELAYE2 cell, which means that trying different strategies did nothing to help in this case.

compile_good.png

View solution in original post

0 Kudos
Highlighted
205 Views
Registered: ‎01-22-2015

Good job finding a workaround to the problem!

Yes, this does seem to be a bug in Vivado v2019.1.   I don’t think the problems you are seeing occur in Vivado v2018.3.

 

You asked:

1) Where is IOB=TRUE property usually set? 
You can set it in the XDC file using the following Tcl.  There are also attribute commands you can used in VHDL and Verilog (see UG901).

set_property IOB TRUE [get_ports {my_port_name}]

 

2) Is there a report showing registers placed in the IOB?
Please see the following post for ways of doing this.

https://forums.xilinx.com/t5/Design-Entry/How-to-indentify-if-IOB-Flip-Flop-was-used-after-P-amp-R-Vivado/m-p/979846

Highlighted
Adventurer
Adventurer
194 Views
Registered: ‎04-06-2012

I ran the TCL command from the post you linked and I can confirm that none of the FDRE in my IOB cells are used. In fact, that's what I could see when I opened the floorplan view but I still wanted to run the command, just in case.

It seems like this issue might entirely different from the other bug you posted as a reference. Maybe I'm over-simplifying things, but it appears the solution could be to prohibit fabric signals from using the IDELAYE2 cells found in the corner IOBs. That is, only allow these specific IDELAYE2 to be used by the IOBUF of the same IOB (unless the pads are unused, of course). This might also apply if the other elements part of these corner IOBs are used by signals coming from the fabric instead of the IOBUF from the IOB itself, in which case I guess it could be considered part of the same bug.

0 Kudos