Open Gloria-cpu opened 1 month ago
Can you describe the "sudden unexpected values" with more details?
I did observe differences in the outputs between the first run and the following runs. They are caused by reset values of the simulation. For example, Chisel inserts the random initialization for the variables and they are randomly reset upon initialization. However, this issue should be fixed by the random seed (-s
command line argument). By default, the seed is zero. Therefore, this random reset should not affect the simulation between multiple runs.
Other possibilities include any C/C++ data structure or Verilog/SV variables without a reset. After a case is executed, if you do not reset them or they are not reset by the reset IO pin, their values will remain unchanged, the same as the previous run results. Then, this run will be different from a total clean run.
After some investigation, we found that certain Verilog/SV variables were not properly reset. I would like to ask, in the current designs such as Xiangshan or RocketChip, how do they ensure that these Verilog/SV variables are fully reset?
I would like to ask, in the current designs such as Xiangshan or RocketChip, how do they ensure that these Verilog/SV variables are fully reset?
There're two types of reset.
The first one is any variable with an explicit reset in Verilog (always @(..) if (reset) ...
). They will be explicitly reset to the specified reset values during the reset period (https://github.com/OpenXiangShan/difftest/blob/master/src/test/csrc/verilator/emu.cpp#L385).
The others (registers without an explicit reset) are deterministically reset by the macros generated by Chisel. Basically, Chisel generates the reset expressions for every register, and these expressions are wrapped by the macro RANDOMIZE_REG_INIT
and put in the initial
scope. Therefore, all registers will have a reset during the simulation, though not actually in the hardware. These random reset values is controlled by the random seed I mentioned before.
The code generated generally looks like:
initial begin // src/main/scala/nutcore/backend/fu/MDU.scala:135:7
automatic logic [31:0] _RANDOM[0:0]; // src/main/scala/nutcore/backend/fu/MDU.scala:135:7
`ifdef INIT_RANDOM_PROLOG_ // src/main/scala/nutcore/backend/fu/MDU.scala:135:7
`INIT_RANDOM_PROLOG_ // src/main/scala/nutcore/backend/fu/MDU.scala:135:7
`endif // INIT_RANDOM_PROLOG_
`ifdef RANDOMIZE_REG_INIT // src/main/scala/nutcore/backend/fu/MDU.scala:135:7
_RANDOM[/*Zero width*/ 1'b0] = `RANDOM; // src/main/scala/nutcore/backend/fu/MDU.scala:135:7
isDivReg_REG = _RANDOM[/*Zero width*/ 1'b0][0]; // src/main/scala/nutcore/backend/fu/MDU.scala:135:7, :184:48
`endif // RANDOMIZE_REG_INIT
end // initial
For non-Chisel-generated designs, it may be hard to implement such features. However, Verilator also provides the support for random or fixed reset. See https://verilator.org/guide/latest/exe_verilator.html#cmdoption-x-assign. I just noticed difftest is using --x-assign unique
in https://github.com/OpenXiangShan/difftest/blob/master/verilator.mk#L109. Probably you can change it to --x-assign 0
or others to get a fixed reset values for all registers if you are not using Chisel-generated code. VCS provides similar arguments as well. Hope that helps.
Describe the question
I am currently using the xfuzz and difftest frameworks. When I set --max-runs to 1 in xfuzz, the execution works normally. However, when I set --max-runs to a value greater than 1, the first run executes as expected, but starting from the second run, the simulation begins to show anomalies. Upon inspecting the waveform, we observed sudden unexpected values during the simulation.
Interestingly, when I export the case from the second run and execute it individually, it runs perfectly without any issues.
What you expect us to do for you
Have you encountered a similar problem before? Your insights would be greatly appreciated.