cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
anas2012a95
Observer
Observer
1,052 Views
Registered: ‎11-07-2018

Output changes when reading different testing points

Jump to solution

Hi all, 

I'm using Vivado 2018.3 and running quite a complex design on Artix-7. 

The design has many sub-modules within the top module as well as other four FIFOs to read data at multiple testing points of the system. 

The system is working fine and as expected. However, when I change a connection of one of these FIFOs to read a different point of the data flow, the system shows totally different output at the other FIFOs. Let's say I have 10 modules, and I confirmed that the output from 1 to 9 is correct. But when trying to read the output from 10, the output from 1 to 9 becomes wrong at multiple points. what makes it really frustrating is that sometimes there is no signals between these two units! (the unit at where the data goes wrong and the new proped unit).

I understand that everytime a new bit file is generated, the design is implemented differently. However, no timing issues were highlighted and logics were not touched while propping different points to be read out. I'm using a hierarchical design with "keep" attripute to avoid any optimization across the modules. Is there a way to tell the tool to fix the logic of a particular unit and never change it even when a new  synthesis/implementation process is run? Any thoughts on why this is happening and how it can be avoided/solved? 

Any ideas are really appreciated.

Kind regards,

Anas

0 Kudos
1 Solution

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

When you have an unreliable design - one whose behavior changes from implementation run to implementation run - there is something wrong with the design - not with the tools, and not anything that can be (or should be) fixed using KEEP attributes.

First, if you want to make sure that each instance stays separate, then best way is to set flatten_hierarchy to NONE, not to use the KEEP (or DONT_TOUCH) attributes. And this merely prevents the instances from sharing common resources - it does not "lock down" an instance that isn't changed. When you do synthesis and place and route, it is done on the entire FPGA together - unless you are doing something like a Partial Reconfiguration (PR) or full Out-of-Context (OOC) flow (the latter being discontinued), there is no concept of keeping part of the design "locked" when it hasn't changed. (And both PR and OOC flows are very complicated) In the normal flow (i.e. not PR or OOC), any change to any code, constraint, or tool option will yield a completely different implementation - for all modules, whether it has been touched or not - that is the nature of the tool.

Second, the main reasons for unreliable designs are bad constraints, bad clock architectures and/or bad clock domain crossing circuits (or just plain bad code - like code that contains unintentional inferred latches). If your system is properly designed (with proper clock domain crossing circuits where required) uses proper clocking techniques (i.e. uses dedicated and appropriate clock resources everywhere), and has proper constraints (including clock, input/output constraints and any appropriate exceptions), then it will not change behavior from run to run - even if each run yields a completely different implementation. So if it is changing behavior, one of these things (or something similar) is wrong - you need to find that and fix it.

No amount of KEEP or attempts to lock down a placed design will fix this; even if one instance of the design appears to work in a given run, that doesn't mean that it is correct - it is just currently behaving. If it is a bad design, then most likely, a "working" instance will stop working properly at some other combination of process, voltage and temperature (PVT).

Avrum

View solution in original post

3 Replies
rshekhaw
Xilinx Employee
Xilinx Employee
1,004 Views
Registered: ‎05-22-2018

Hi @anas2012a95 ,

You are applying  keep attribute in RTL i guess?

Instead of keep try applying dont_touch attribute.

Please check page no.48 on why to use dont_touch instead of keep for implementation:

https://www.xilinx.com/support/documentation/sw_manuals/xilinx2019_2/ug901-vivado-synthesis.pdf

Thanks and Regards,

Raj

0 Kudos
anas2012a95
Observer
Observer
855 Views
Registered: ‎11-07-2018
Hi Raj,

Thanks for your reply.

Yes I'm using "Keep" attribure in the RTL. I've chganed it to "dont_touch" but the problem is still happening.
I was wondering if there is a comment to fix the logic of a submodule when the implementation of the top module is run. If unit 1 is only changed, why the tools rerun the synthesis and implementation processes of unit 2 everytime a bit file is generated? Optimization across hierarchy boundaries is off by using "dont_touch" isn't it?

Kind regards,
Anas
0 Kudos
avrumw
Expert
Expert
835 Views
Registered: ‎01-23-2009

When you have an unreliable design - one whose behavior changes from implementation run to implementation run - there is something wrong with the design - not with the tools, and not anything that can be (or should be) fixed using KEEP attributes.

First, if you want to make sure that each instance stays separate, then best way is to set flatten_hierarchy to NONE, not to use the KEEP (or DONT_TOUCH) attributes. And this merely prevents the instances from sharing common resources - it does not "lock down" an instance that isn't changed. When you do synthesis and place and route, it is done on the entire FPGA together - unless you are doing something like a Partial Reconfiguration (PR) or full Out-of-Context (OOC) flow (the latter being discontinued), there is no concept of keeping part of the design "locked" when it hasn't changed. (And both PR and OOC flows are very complicated) In the normal flow (i.e. not PR or OOC), any change to any code, constraint, or tool option will yield a completely different implementation - for all modules, whether it has been touched or not - that is the nature of the tool.

Second, the main reasons for unreliable designs are bad constraints, bad clock architectures and/or bad clock domain crossing circuits (or just plain bad code - like code that contains unintentional inferred latches). If your system is properly designed (with proper clock domain crossing circuits where required) uses proper clocking techniques (i.e. uses dedicated and appropriate clock resources everywhere), and has proper constraints (including clock, input/output constraints and any appropriate exceptions), then it will not change behavior from run to run - even if each run yields a completely different implementation. So if it is changing behavior, one of these things (or something similar) is wrong - you need to find that and fix it.

No amount of KEEP or attempts to lock down a placed design will fix this; even if one instance of the design appears to work in a given run, that doesn't mean that it is correct - it is just currently behaving. If it is a bad design, then most likely, a "working" instance will stop working properly at some other combination of process, voltage and temperature (PVT).

Avrum

View solution in original post