cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
vortex1601
Explorer
Explorer
699 Views
Registered: ‎12-11-2017

Bidirectional bus: ODDR without IDDR - possible?

Jump to solution

Hi folks,

I'm working on a system-sync DDR bus implementation (Hyperbus, if you must know) and I'm finding that Vivado won't let me instance regular input flip flops when I am using ODDR for output. Instead, Vivado keeps ignoring my design and placing IDDRs.

Is there a physical reason I can't do that, or is it just a synthesis issue?

Why do I care? I need to let place-and-route add some input delay to help input hold time, and I don't want to go to the trouble of using IDELAY / IDELAYCTL to do that.

This is on Spartan-7.

0 Kudos
1 Solution

Accepted Solutions
avrumw
Expert
Expert
677 Views
Registered: ‎01-23-2009

What you are describing shouldn't happen. The tools should not be able to add an IDDR unless the RTL code specifically instantiates one or infers one (yes, it is possible to infer an IDDR through RTL, although it is rarely done - you can't infer an ODDR, though). So, if the tools are inserting an IDDR when your code doesn't instantiate or infer one, then this is a bug. The tools just aren't allowed to do that. Even if there were a restriction that you had to use an IDDR on an IOBUF that uses an ODDR (which, as far as I know there isn't), the tool can't just insert one if your code doesn't infer/instantiate it - it would have to throw an error saying that your code does not comply with the structural limitation of the IOB (and I repeat, I am pretty sure there is no such limitation).

So, either you are misinterpreting what the tools have done, you have an error in your RTL code that is inferring or instantiating the IDDR, or this is a synthesis bug and should be reported. The best thing to do would be to try and construct a simple test case that does what you want (an IOBUF with an ODDR and a regular SDR fabric flip-flop) and synthesize it and see the result. If it adds an IDDR that it shouldn't, post the code here and someone will file a CR.

That being said, it is generally not the best solution to let the tool solve input hold times by using a fabric flip-flop for capture and letting the tool add extra routing. This extra routing is not PVT compensated and will take a lot of margin away from your setup - the rule of thumb is for every ps of delay it adds to fix hold time, it will take 3ps of margin from your hold check (since the delay of silicon varies roughly 3:1 over process/voltage/temperature). It is better to bite the bullet and use the IDELAY and IDELAYCTRL; that is the reason they are there!

Avrum

View solution in original post

0 Kudos
5 Replies
avrumw
Expert
Expert
678 Views
Registered: ‎01-23-2009

What you are describing shouldn't happen. The tools should not be able to add an IDDR unless the RTL code specifically instantiates one or infers one (yes, it is possible to infer an IDDR through RTL, although it is rarely done - you can't infer an ODDR, though). So, if the tools are inserting an IDDR when your code doesn't instantiate or infer one, then this is a bug. The tools just aren't allowed to do that. Even if there were a restriction that you had to use an IDDR on an IOBUF that uses an ODDR (which, as far as I know there isn't), the tool can't just insert one if your code doesn't infer/instantiate it - it would have to throw an error saying that your code does not comply with the structural limitation of the IOB (and I repeat, I am pretty sure there is no such limitation).

So, either you are misinterpreting what the tools have done, you have an error in your RTL code that is inferring or instantiating the IDDR, or this is a synthesis bug and should be reported. The best thing to do would be to try and construct a simple test case that does what you want (an IOBUF with an ODDR and a regular SDR fabric flip-flop) and synthesize it and see the result. If it adds an IDDR that it shouldn't, post the code here and someone will file a CR.

That being said, it is generally not the best solution to let the tool solve input hold times by using a fabric flip-flop for capture and letting the tool add extra routing. This extra routing is not PVT compensated and will take a lot of margin away from your setup - the rule of thumb is for every ps of delay it adds to fix hold time, it will take 3ps of margin from your hold check (since the delay of silicon varies roughly 3:1 over process/voltage/temperature). It is better to bite the bullet and use the IDELAY and IDELAYCTRL; that is the reason they are there!

Avrum

View solution in original post

0 Kudos
vortex1601
Explorer
Explorer
670 Views
Registered: ‎12-11-2017

Yeah, it's very strange. I've coded it both with and without instancing either IDDR or ODDR, and synthesis still insists on inserting IDDR. The placer seems to figure out that I've fed the same input signal to both a posedge and negedge sampling flop, and so it goes forward from that and infers IDDR. I've even tried inserting some logic on the input paths to try to coax in a LUT - placer throws it away! Stubborn thing.

Here's the message that the placer throws:

  • Implementation
  • Place Design
  • [Place 30-87] Partially locked IO Bus is found. Following components of the IO Bus spi_dq are not locked: 'spi_dq[7]' ' spi_dq[6]' ' spi_dq[5]' ' spi_dq[4]' ' spi_dq[3]' ' spi_dq[2]' ' and spi_dq[1]'
  • Route Design
  • DRC
  • Implementation
  • Placement
  • IOs
  • [DRC PLIO-3] Placement Constraints Check for IO constraints: Partially locked IO Bus is found. Following components of the IO Bus spi_dq[7:0] are not locked: spi_dq[7] spi_dq[6] spi_dq[5] spi_dq[4] spi_dq[3] spi_dq[2] spi_dq[1]
  • [Route 35-426] Router was unable to fix hold violation on unroutable pins. The router cannot add routing detours to improve hold time because the pins are part of one or more of the following unroutable types: partition pins, fixed routes and intra-site connections. Resolution: Run report_timing_summary to analyze the hold violations.

Working on using IDELAY now...

0 Kudos
avrumw
Expert
Expert
665 Views
Registered: ‎01-23-2009

You didn't mention that you were trying to capture on both edges of the clock. This is the way you infer an IDDR.

I don't know if you can have the tool use two fabric capture flip-flops, or if the IDDR inference will always happen... 

Avrum 

0 Kudos
vortex1601
Explorer
Explorer
640 Views
Registered: ‎12-11-2017

I think that there's no reason you couldn't use a pair of fabric flops to do DDR capture. Yes, it's crummy as far as delay skew control, which would be mitigated somewhat by the placer with an appropriate constraint, but it shouldn't behave any different than how SDR capture / IOB packing works. That is controlled by the (* IOB="TRUE" *) directive. Seems like a bug / misfeature to me.

At any rate I got IDELAY to work for a fixed delay without too much pain.

0 Kudos
avrumw
Expert
Expert
588 Views
Registered: ‎01-23-2009

I think that there's no reason you couldn't use a pair of fabric flops to do DDR capture.

Structurally, you are correct. The question is where/how do the tools decide this is an IDDR.

The synthesis RTL elaboration stage looks for specific formats of code that it can map to generic hardware. There are specific RTL code snippets that infer combinatorial logic, mathematical logic (addition/subtraction), things that use the DSP48, RAMs, and flip-flops. Specifically, the code below:

 

always @(posedge clk)
  q <= d;

Infers a flip-flop. This is done without any real knowledge of the target technology that it will eventually be mapped to - during the elaboration phase, RTL is mapped to generic technology cells.

Now consider the code

always @(posedge clk)
  q1 <= d;
always @(negedge clk)
  q2 <= d;

think (I don't know for sure) that when the tools see this, they don't infer two different flip-flops, one for each process, but actually recognize this entire sequence of code as an IDDR. If this is the case (it is determined at elaboration phase), then it won't pay attention to things like DONT_TOUCH, or the IOB property - both of which affect synthesis/place&route processes after elaboration,

It is possible that this is not the case; the tools infer two flip-flops during elaboration, and merge them together into an IDDR at a later stage. In this case, some properties like DONT_TOUCH or controlling the IOB property might make a difference. Note: that the IOB property is often attached to the port these days - in which case it would affect both the output and input flops. However, you should be able to add the property to the flip-flops directly - this way you can add it to the output flip-flops and not the input flip-flops.

It should be possible to determine which of these two it is (done at elaboration or done later) by looking at the elaborated schematic - if it is the former, the elaborated schematic will show some kind of a double data rate flip-flop. If it is the latter, you will see two discrete flip-flops, one on the rising edge and one on the falling edge.

In either case, you should probably be able to force this to keep two separate fabric flip-flops. If controlling the IOB property on the flip-flops (not the port) doesn't do it, and the DONT_TOUCH doesn't do it (which, again, would be the case if the IDDR is inferred directly), then you can probably force it to keep them separate by putting them in separate modules - simply wrapping (at least) one of the two flip-flops in their own sub-module (and maybe forcing the tool to not flatten the hierarchy of this module) will prevent the tool from both inferring the IDDR in the first place (if this is what is happening) or merging the two flip-flops together at a later time.

But, again, the best solution is to use the IDDR  for capture and adjust the timing with the IDELAY.

Avrum

0 Kudos