-
Notifications
You must be signed in to change notification settings - Fork 241
Description
The RAM initialization in https://github.com/olofk/serv/blob/main/serving/serving_ram.v#L40 seems to be insufficient:
Consider:
initial
if(|memfile) begin
$display("Preloading %m from %s", memfile);
$readmemh(memfile, mem);
end
The top (highest addresses) of mem can remain uninitialized on simulators that support this kind of memory state, such as Vivado's xsim. On xsim the regions of mem that are not initialized are in an undefined state at simulation start. Now, yes, one can load values into mem, but often mem is loaded from a program of variable length, so may not initialize the entire mem.
As on serv the topmost addresses are reserved for the zero register, the above effectively makes zero == 32'hXXXXXXXX. Since the register zero is often used as a constant in various instructions, its undefined value quickly "infects" the rest of the simulation with each executed instruction that uses the zero register in some way.
I originally thought that the zero register is treated specially on reads in serv, but it doesn't seem to be. You can't write to it, but when you read, serv seems to "just" read from its index position in the register file. This works fine when the values stored there are zeros; but doesn't work well if the values are X.
I suspect that the code should unconditionally initialize the top 4 bytes of mem to all zeros to prevent starting a multi-valued simulation with a wrong value for zero (x0).
You can't see this on Verilator, for example, since it is a two-value simulator only.