PipelineC
PipelineC copied to clipboard
Synthesis timing loops (rarely only w/ Vivado so far)
Code like below, but only for Vivado synthesis seen so far (2019.2, tried a few syn strategy options, didnt help)...
#pragma PART "xc7a100tcsg324-1"
//#pragma PART "5CEBA4F23C8"
//#pragma PART "LFE5U-85F-6BG381C"
#include "uintN_t.h"
#pragma MAIN main
float main(float a, float b, uint16_t x)
{
float fconst = 1.23;
float fx = (float)x;
float mults = (fx * fconst) * a;
float rv = mults + b;
return rv;
}
Will result with synthesis warnings like
CRITICAL WARNING: [Synth 8-326] inferred exception to break timing loop: 'set_false_path -through main_0CLK_1ad76fbfi_0/i_255/O'
CRITICAL WARNING: [Synth 8-326] inferred exception to break timing loop: 'set_false_path -through main_0CLK_1ad76fbfi_0/i_254/O'
CRITICAL WARNING: [Synth 8-326] inferred exception to break timing loop: 'set_false_path -through i_200/O'
No other tools seem to find combinatorial loops (tried Quartus and yosys+nextpnr). Getting Vivado to report loops after syn completes reports no loops in the design - can't find those nets from the error messages.
Changing float mults = (fx * fconst) * a;
to float mults = fx * (fconst * a);
makes it so Vivado no longer sees a timing loop.
I have not ruled out that somehow this is in the HDL - maybe simulating more will help...
I have reason to believe this is a serious issue where needed functionality is being flagged as a loop and optimizing away incorrectly.
Best work around for now is as above - start commenting out / trimming down your design until you find the problem function and subtly rewrite it maintaining the original functionality.
I know - it's F'd.