04-18-2018 03:26 PM
We are having timing problems caused by a LUT being put on a Clock line to invert it rather than using an inverted clock Flip-Flop.
Why are the tools doing this? Are we out of Flip-Flops that support an inverted clock? Is our code somehow responsible (reset inside of Clock block?
Our code is similar to the following:
process(i_SysClk) begin if falling_edge(i_SysClk) then if i_InternalReset = '0' then r_ADCWordCount <= 0; ... else if (i_ADCWritePtr /= r_PrevADCWritePtr) and (i_ADCReadPtr = r_PrevADCReadPtr) then r_ADCWordCount <= r_ADCWordCount + 1; elsif (i_ADCReadPtr /= r_PrevADCReadPtr) and (i_ADCWritePtr = r_PrevADCWritePtr) then if r_ADCWordCount > i_ADCWordsPerBuffer then
r_ADCWordCount <= i_ADCWordsPerBuffer - 1;
elsif r_ADCWordCount - 1 >= 0 then
r_ADCWordCount <= r_ADCWordCount - 1;
r_ADCWordCount <= 0;
end if; end if;
We have seen this several times now and would like to know what we are doing so we can avoid this.
Please let me know if there is more detail or information I can provide.
04-18-2018 03:38 PM
Falling edge to rising edge timing essentially cuts your timing margin in half. Or equivalently, it's like doubling your clock speed, so it's not surprising that you are having timing problems. But just flipping the polarity of this process from falling edge to rising edge is likely to have consequences elsewhere, especially if this code is involved in a specific data capture circuit to external devices. If this is entirely internal, then why does this code use the falling edge at all? There must be some design reason to use this.
04-18-2018 04:19 PM - edited 04-18-2018 04:22 PM
Yes, there are design reasons to have this on the falling edge. This is probably not directly our issue. Our system clock is running at 128MHz or about 7.8ns period.
The issue we have is that the tool is putting the Clock through a lut to invert it and this causes significant enough delays that timing is not met when the output of this flip-flop goes to another one that has the non-inverted clock.
In other locations of the design the falling edge detection is synthesized by the tools directly on a flip-flop with an inverted clock pin and so the delay is less than running it through a LUT.
What I would like to know is why it uses a LUT for inversion in some areas and in other areas it uses an inverted clock pin on the flip-flop.
04-18-2018 11:37 PM
04-19-2018 04:45 AM
Shot in the dark, wonder if this style avoids it, since the clock edge is not snarled up in the if-elsif-etc.
process --(i_SysClk) begin wait until falling_edge (i_SysClk); if i_InternalReset = '0' then r_ADCWordCount <= 0; ... else if (i_ADCWritePtr /= r_PrevADCWritePtr) and (i_ADCReadPtr = r_PrevADCReadPtr) then r_ADCWordCount <= r_ADCWordCount + 1; elsif (i_ADCReadPtr /= r_PrevADCReadPtr) and (i_ADCWritePtr = ..... ... end process;
04-19-2018 11:49 AM
to aher: So are you saying that you think if we run an optimization on the synthesized design it would change how it is inferring the LUT? We have tried various combinations of strategies for both Synthesis and Implementation but we don't have a good grasp on what Strategy we should be using, it is more of a trial and error process right now so any guidance in that area might be useful as well.
We are building for an Artix 7 part using Vivado 2017.4.
We can try using a different construct rather than If else type ones so see what happens but I guess we are still left to see if there are timing errors somewhere to see if this issue exists in other areas of the design as well. How could I find out if a LUT was being put on a clock line if it didn't fail timing, or should we care?
06-04-2018 12:05 AM