cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
pallison
Adventurer
Adventurer
1,004 Views
Registered: ‎03-30-2012

Vivado generates synthesis/implementation which does not match (incorrect) hardware behavior when ILOGIC DINV used

With Vivado 2018.2 (I don't have more recent versions installed to check), if the D inverter is used in an ILOGIC to feed an IDDR2 and then the O output of that ILOGIC is used elsewhere, the behavior on hardware will be incorrect - it will not match the behavior of the HDL. In addition the behavior on hardware will not match any of the simulations of the firmware. I've searched through the answer records as best I can and haven't seen this issue recorded anywhere.

Using this extremely simple code:

 

`timescale 1ns / 1ps
module test( input A, input B, output Q1, output Q2, output C);

     wire rclk;
     BUFG abufio(.I(A),.O(rclk));
     IDDR bddr(.D(~B),.CE(1'b1),.C(rclk),.S(1'b0),.R(1'b0),.Q1(Q1),.Q2(Q2));
     assign C = ~B;
endmodule

Synthesis will generate an IDDR with its data pin inverted, but will also generate a LUT1 as an inverter for between the O output of the ILOGIC and the C output. Implementation happily places the IDDR in the ILOGIC, configures the ILOGIC to have an inverted D input, and still takes the O output through a LUT1 inverter. See attached images.

 

The expected behavior here is that the Q1/Q2 outputs should always be the same as the C output if B is constant. All simulations of this code (behavioral, post-synthesis functional/timing, post-implementation functional/timing) will generate the expected behavior: Q1, Q2, and C all have the same polarity.

Programming this on an actual device does not result in the expected behavior. Tested on an Arty-A7 board using an XC7A35TICSG324-1L, when the B input is constant, C is the opposite polarity as Q1/Q2.

Attached below are the resulting implemented schematic (test_schem.png), the behavioral simulation (test_behavioral.png), the post-implementation timing simulation (test_post_implementation.png). All of these are incredibly boring, just showing that q1 = q2 = c = not B, except for the various clock-related timings.

Here's a video showing the hardware's incorrect behavior:

In this video LD5/LD6 are Q1/Q2, and LD4 is C. BTN0 is the B input and is driven high when pushed. As you can see in the video, the outputs are opposite each other, which does not match the logic (or simulation): the C output actually follows B, and Q1/Q2 are "not B."

Like I said the reason for this is straightforward if you take a look at the device view post-implementation, including the simulation mismatch. The output of the input buffer is shown going straight to the LUT1 and the IDDR in the schematic, whereas in reality it goes to the ILOGIC's D input, through the DINV inverter, to the O output, and then through the LUT1 where it is inverted again.

I've also attached an archive of the project as well, and this can be replicated on any Arty A7 by pushing BTN0 and watching the LEDs. I can't file a support case about this because I'm an academic user and not a professor (research scientists like me aren't special enough, apparently).

test_schem.png
test_post_implementation.png
test_behavioral.png
0 Kudos
6 Replies
amaccre
Moderator
Moderator
884 Views
Registered: ‎04-24-2013

Hi @pallison ,

There has been a Change Request filed to highlight this issue and a Design Rule Check has been included in the 2019.1 version of the tools

The reason for the behaviour is that there cannot be a signal driving an Inverted IDDR D input and the fabric at the same time. This is an invalid topology as there is no path available to provide both and inverted and a non inverted signal at the same time.

If you look at the Device view you can see that the input goes through the D_B to provide the inversion for the D input and then this signal is passed on to the fabric where it goes through the LUT and is incorrectly inverted again.

Capture.PNG

In the RTL there is an inverter prior to the IDDR which is not allowed

Capture1.PNG

The D pin of an IDDR can only be driven by a top level port.

Extract from UG 768:
D Input: This pin is where the DDR data is presented into the IDDR module.
This pin connects to a top-level input or bi-directional port, and IODELAY configured for an input delay or to an appropriate input or bidirectional buffer

Best Regards
Aidan

 

------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if this answered your question
Give Kudos to a post which you think is helpful and may help other users
------------------------------------------------------------------------------------------------------------------
pallison
Adventurer
Adventurer
843 Views
Registered: ‎03-30-2012

"The reason for the behaviour is that there cannot be a signal driving an Inverted IDDR D input and the fabric at the same time. This is an invalid topology as there is no path available to provide both and inverted and a non inverted signal at the same time."

Sorry, I'm *really* confused now. What exactly will the change be? Is the idea that if you feed an IDDR D input with an inverted signal, you can no longer use that signal in fabric? I just don't understand what the design rule check will be against.

In the example I'm giving there's an IDDR being given an inverted signal, and fabric being given an inverted signal. This is a completely valid topology as the DINV inverter feeds both the fabric output and the IDDR input.

Moreover even if for some reason I wanted fabric to see a non-inverted signal, and the IDDR seeing an inverted signal, that just requires fabric to have a LUT1 following the inverted ILOGIC output.

0 Kudos
amaccre
Moderator
Moderator
815 Views
Registered: ‎04-24-2013

Hi @pallison 

The IDDR D input can only be driven from one of the following sources, a top-level input or bi-directional port, and IODELAY configured for an input delay or to an appropriate input or bidirectional buffer

If you look at the ILOGIC site in 7 series devices you can trace the internal path from the D input through the ILOGICE2_DINV Bel (basic element). It is in the ILOGICE2_DINV that the signal is either inverted or not depending on whether the IDDR is to have the D pin inverted.

Capture.PNG

This signal is then passed via the 2 mux to the O pin where it is available to the fabric, so if the D input to the IDDR is inverted then the output on the O will also be.

Capture1.PNG

This is in the hardware and why in later versions of the tools, from 2019.1, an error is given if this topology is used.

Best Regards
Aidan

 

------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if this answered your question
Give Kudos to a post which you think is helpful and may help other users
------------------------------------------------------------------------------------------------------------------
0 Kudos
pallison
Adventurer
Adventurer
797 Views
Registered: ‎03-30-2012

Hi @amaccre  :

"This signal is then passed via the 2 mux to the O pin where it is available to the fabric, so if the D input to the IDDR is inverted then the output on the O will also be."

Right, I know - and this is the topology that the example code that I posted is using. The problem is that the tools insert an additional inverter at the fabric side because for some reason they think the O output is not inverted.

"This is in the hardware and why in later versions of the tools, from 2019.1, an error is given if this topology is used."

Obviously you can't have a topology from the ILOGIC where the IDDR sees an inverted signal and the O output sees a non-inverted signal. I understand that part.

Maybe I can ask my question more clearly: are you saying that from 2019.1 on, the code I gave in the first post in this thread - that is -

`timescale 1ns / 1ps
module test( input A, input B, output Q1, output Q2, output C);

     wire rclk;
     BUFG abufio(.I(A),.O(rclk));
     IDDR bddr(.D(~B),.CE(1'b1),.C(rclk),.S(1'b0),.R(1'b0),.Q1(Q1),.Q2(Q2));
     assign C = ~B;
endmodule

will generate an error? Because this *isn't* an unroutable topology: both fabric (the C output) and the IDDR2 (the bddr element) are both using the inverted signal.

0 Kudos
amaccre
Moderator
Moderator
777 Views
Registered: ‎04-24-2013

Hi @pallison ,

Yes if you run this in 2019.1 you will receive a DRC error:

Capture.PNG

As a test if you remove the IDDR and just leave the Inverted you can see that the net is still routed through the ILOGIC, but uses the non inverted path

Capture1.PNG

So there is no way to use both the inverted and non-inverted paths at the same time.

There are a few ways to workaround this. You could have separate but indentical inputs for the IDDR and LUT, you can accept that the output from the ILOGIC is already inverted and not use the LUT. Or you could modify the LUT truth table if you need to keep it.

Best Regards
Aidan

 

------------------------------------------------------------------------------------------------------------------
Please mark the Answer as "Accept as solution" if this answered your question
Give Kudos to a post which you think is helpful and may help other users
------------------------------------------------------------------------------------------------------------------
0 Kudos
pallison
Adventurer
Adventurer
761 Views
Registered: ‎03-30-2012


There are a few ways to workaround this. You could have separate but indentical inputs for the IDDR and LUT, you can accept that the output from the ILOGIC is already inverted and not use the LUT. Or you could modify the LUT truth table if you need to keep it.

I don't *want* to use the LUT. The LUT shouldn't be there. It was generated by the synthesis tools and not merged into the ILOGIC, so it's either a bug in synthesis or implementation.

0 Kudos