When trying to keep critical logic outside your loops, try precomputation first. The Compiler cannot optimize logic within a loop easily using retiming only. The Compiler cannot move registers inside the loop to the outside of the loop. The Compiler cannot retime registers outside the loop into the loop. Therefore, keep the logic inside the loop as small as possible so that the logic does not negatively impact fMAX.
After precomputation, logic is minimized in the loop and the design precomputes the encodings. The calculation is outside of the loop, and you can optimize the calculation with pipelining or retiming. You cannot remove the loop, but can better control the effect of the loop on the design speed.
The following code example shows a similar problem. The original loop contains comparison operators.
StateJam:if (RetryCnt <=MaxRetry&&JamCounter==16) Next_state=StateBackOff; else if (RetryCnt>MaxRetry) Next_state=StateJamDrop; else Next_state=Current_state;
Precomputing the values of RetryCnt<=MaxRetry and JamCounter==16 removes the expensive computation from the StateJam loop and replaces the computation with simple boolean operations. The modified code is:
reg RetryCntGTMaxRetry; reg JamCounterEqSixteen; StateJam:if (!RetryCntGTMaxRetry && JamCounterEqSixteen) Next_state=StateBackOff; else if (RetryCntGTMaxRetry) Next_state=StateJamDrop; else Next_state=Current_state; always @ (posedge Clk or posedge Reset) if (Reset) JamCounterEqSixteen <= 0; else if (Current_state!=StateJam) JamCounterEqSixteen <= 0; else JamCounterEqSixteen <= (JamCounter == 15) ? 1:0; always @ (posedge Clk or posedge Reset) if (Reset) RetryCntGTMaxRetry <= 0; else if (Current_state==StateSwitchNext) RetryCntGTMaxRetry <= 0; else if (Current_state==StateJam&&Next_state==StateBackOff) RetryCntGTMaxRetry <= (RetryCnt >= MaxRetry) ? 1: 0;
Did you find the information on this page useful?