If/Else for combinational assignment generates `always @*` that doesn't initialize
I think I've found a problem in the verilog generation. I've created a playground example here.
When you use an m.If(...)/m.Else() for a combinational assignment, an always @* block is generated. Now if one of the signals in the (automatically generated) sensitivity list changes, the block will be reevaluated - but it won't be evaluated at the start of the simulation.
That is one of the pitfalls that was fixed with always_comb in SystemVerilog. But as it is, this can lead to differences between the Amaranth simulation and other simulators. Even doing a reset does not "fix" this, as the signals in the sensitivity list will just be reset to the value that they already have because they were initialized to it, thus not triggering the always @* block.
You can of course work around this issue by just using a Mux(...), which will generate an assign statement. When creating multiple assignments that depend on the same conditions, using one m.If(...)/m.Else() is much cleaner though.
Take a look at this part:
reg \$auto$verilog_backend.cc:2352:dump_module$1 = 0;
// ...
always @* begin
if (\$auto$verilog_backend.cc:2352:dump_module$1 ) begin end
// ...
end
This is equivalent to:
reg \$auto$verilog_backend.cc:2352:dump_module$1 ;
initial \$auto$verilog_backend.cc:2352:dump_module$1 = 0;
// ...
always @* begin
if (\$auto$verilog_backend.cc:2352:dump_module$1 ) begin end
// ...
end
The initial process triggers at time 0, and the variable it assigns is in the sensitivity list of every always @* block. So they should all be evaluated.
Does this not happen for you?
Ok, I see how its supposed to work now. And when I simulate it using icarus, the signal is indeed defined from the start. I was using cadence xcelium (22.09) though, and it leaves data_out undefined at the start.
I see. I don't have access to Xcelium (and I've never used it) so I wouldn't really be able to help here.