[Vivado] Prevent compiler from optimizing logic away - Page 1
Forum section: electronics / beginners

author: Digitalio
author_rank: Contributor
timestamp: September 29, 2020, 08:59:04 pm
content: I'm writing a test bench that generates the data for the code being tested (this part was easy), and I also need to write a module that takes the output from the code being tested and doesn't let the compiler to optimize it away. Any ideas how to do that?

author: ledtester
author_rank: Super Contributor
timestamp: September 29, 2020, 09:17:09 pm
content: What compiler are you using?If it's a C compiler, how about compiling each module separately and then linking them?E.g.:Code:$ cc -c file1.c$ cc -c file2.c$ cc -o output file1.o file2.o

author: rstofer
author_rank: Super Contributor
timestamp: September 29, 2020, 09:19:43 pm
content: Generally, logic that doesn't ultimately lead to a pin (something in the port list of the top entity) will be optimized away. To look deep in the hierarchy with a logic analyzer, I have had to bring signals up through the various port lists. From the synthesizer's point of view. what good is logic that doesn't go anywhere?I don't do a lot of simulation but I think the issues are the same.

author: Digitalio
author_rank: Contributor
timestamp: September 29, 2020, 09:30:28 pm
content: Quote from: rstofer on September 29, 2020, 09:19:43 pmWell, it's only for simulation.

author: Digitalio
author_rank: Contributor
timestamp: September 29, 2020, 09:31:25 pm
content: Quote from: ledtester on September 29, 2020, 09:17:09 pmGiven that I mentioned Vivado, it's actually Verilog.

author: filssavi
author_rank: Frequent Contributor
timestamp: September 29, 2020, 09:48:32 pm
content: Unfortunately finding the root cause of why the logic has been optimised away in HDL can be extremely frustrating...There are few common problems that lead to it1) the logic does not exit the FPGA.The result of a chain of logic circuits/operations must always lead outside the chip itself, either through a Pin, or through the internal Busses on a SoC like the zynq, if everything stays inside the FPGA it will get optimised away2）the top outputs must not have a predefined value (otherwise the tool will just connect the pin directly to GND/VCC3) if you use AXI stream (or equivalent) channels make sure that the ready signals does go to 1 otherwise anything else is ignored3) if you have bus controlled peripherals (AXI, AXI lite, Avalon or whisk one) make extra sure that the bus interface part is connected and working correctly otherwise everything else gets thrown outThe tools output are unfortunately are quite bad, as they will not tell you clearly where is the root problem that caused the whole logic to be thrown out. However they usually tell you when something is removed so try looking for that in the synthesiser logAt the beginning my advice is also to Turn off the hierarchy flattening, as otherwise the synthesis result is quite far from your code, in terms of structure, even if it is functionally equivalent/better (don’t forget to turn it back on once done debugging though, as you are otherwise making timing closure much more difficult)Last but not least make shure that the testvench for simulation does test the top level module even if it is painful ( with SoCs for example it usually involves complex AXI bus functional models)All in all my general advice is to hang in there and not give up on FPGAs, past the initial learning curve you will start to get the hang of it and the disappearing logic will be mostly a problem of the past

author: filssavi
author_rank: Frequent Contributor
timestamp: September 29, 2020, 09:52:30 pm
content: Quote from: Digitalio on September 29, 2020, 09:30:28 pmThan you should not be running synthesis (AKA compile) but only the behavioural simulation.Synthesis is only useful if you want to (sooner rather than later) actually run the code in hardware

author: Cerebus
author_rank: Super Contributor
timestamp: September 30, 2020, 02:32:17 am
content: I've not used Vivado, but in all the other synthesis tools I've used a "syn_keep" directive ensures that something doesn't get optimised away. e.g.Code:wire iWantToSeeThis /* synthesis syn_keep */;If it's not exactly that in Vivado, I'm sure there's a functional equivalent under another name.A quick search seems to suggest (here) that in Vivado it's:Code:(* dont_touch = "true" *) <signal_name>;

author: ejeffrey
author_rank: Super Contributor
timestamp: September 30, 2020, 05:53:53 am
content: Quote from: Digitalio on September 29, 2020, 08:59:04 pmBehavioral simulation should simulate all named internal signals. post-synthesis simulation won't but are you sure that is what you need?I'm not sure how to do do this in Vivado, but in Quartus you can assign something to be a "virtual pin." This is treated like an external signal and will prevent logic from being optimized away but doesn't need to be assigned to a physical pin. The main purpose of this (at least for me) is to be able to synthesize and check timing on a module that can't be a top level module, particularly if it has more IO signals than the target FPGA has pins. That should do what you are looking for if you really need post synthesis simulation to work like this.

author: emece67
author_rank: Frequent Contributor
timestamp: September 30, 2020, 07:39:27 am
content: .

author: filssavi
author_rank: Frequent Contributor
timestamp: September 30, 2020, 10:44:17 am
content: In vivado you can use the (* keep="true" *) directive on a signal (wire, reg, logic) etc to force vivado to keep the signal around even if it is useless.That said I would strongly suggest against using it unless it is really necessary, as that is only a band-aidas for simulating stuff with more IO than the whole fpga post synthesis it is really an exercise in futility, as the timing results you get form such a simulation are largely irrelevant once the module is instantiated inside a real design, since as opposed to software compilers, fpga toolchains do global optimization ( full program LTO in software term) by default, thus the results depend on the whole system not just the compilation unit.