Eliminate infinite loops in simulation
Created by: TobiasKaiser
During regular operation of the RI5CY core, the riscv_controller and riscv_prefetch_buffer modules can lead the HDL simulator into an infinite loop of two combinational processes causing each other to be evaluated again and again: Under specific circumstances, each of the processes assigns a variable that the other process is sensitive to first with zero and then with one. At least one of these assignments causes the variable to change, therefore causing another evaluation event for the other process, which in turn does the same, just with a different variable.
The processes and corresponding variables that caused this behavior were:
In riscv_controller:
- The core controller process
- is sensitive to changes of jr_stall_o
- resets and then sets is_decoding_o
- The stall control process
- is sensitive to changes of is_decoding_o
- resets and then sets jr_stall_o
In riscv_prefetch_buffer:
- The fetch addr process
- is sensitive to changes of fetch_is_hwlp
- resets and then sets hwlp_masked
- The instruction fetch FSM process
- is sensitive to changes of hwlp_masked
- resets and then sets fetch_is_hwlp
This behavior was encountered with Vivado 2017.2 XSIM and seems to be in accordance with the simulation reference algorithm outlined in the SystemVerilog standard IEEE 1800-2012 in section 4.5 and the scheduling implications of blocking assignments in section 4.9.3.
I got rid of this infinite loop behavior by removing the default zero assignment of hwlp_masked / is_decoding_o at the beginning of the fetch addr / core controller process and instead making explicit assignments in each of the case branches. This way, if the value of the variables does not change, the other process is not triggered again unintentionally.
No actual logic feedback circuit is described by the behavioral HDL in either riscv_controller or riscv_prefetch_buffer, so this problem is only relevant for behavioral simulation, not the post-synthesis circuit.