Closed uv-xiao closed 2 months ago
so this is how the Reg semantics are defined to be, isn't it?
from src/Libraries/Base1/Prelude.bs
in lines 1846 et seq:
vMkReg v =
module verilog "RegN" (("width",valueOf n), ("init",v)) "CLK" "RST" {
read = "Q_OUT"{reg};
write = "D_IN"{reg} "EN";
} [ read <> read,
read < write,
write << write ]
basically what the last line says is that if you have two rules that write diff values to the same reg then bsc can pick one of them to logically happen "before" the other "in the same cycle," which means that the "logically later" write will trump the other one.
note this only happens when there are no ordering constraints in the other direction, though. if you had two rules where one copies reg x to reg y and the other copies y to x, they won't get scheduled in the same cycle because there is no way to pick the one that happens "logically before."
basically the question that the bsc scheduler is asking is, is there a way to schedule some rules in one cycle so that the overall outcome can be explained by some sequence of these rules being applied individually one after the other? if so, it will schedule them together. this is how the rule semantics work.
a trivial way for this to happen is of course if the rules don't access the same state. a less trivial (but still trivial) way is if both rules read the same state; you can see this in <>
above.
a still less trivial case is that one rule reads a reg and the other writes the same reg; you can see this with the <
case above, which requires the read to occur "logically before" the write (because otherwise a RAW hazard would ensue). notice that actually this is what makes a register different from a wire from a scheduling perspective: for a wire the write would need to come before the read (which you can verify in src/Libraries/Base1/PreludeBSV.bsv:121
).
the final way for this to happen is what you saw: if both rules write then if you let them both happen but one clobbers the other's write, then it still appears as if they happened in some sequence provided you can't observe the intermediate state in between the two rules happening in this sequence. at least that is the intuition behind this behaviour.
i'm personally not a fan of this being a thing with Reg
either — i too would prefer for reg writes to conflict and the writer having to explicitly choose one — but it has always been thus from the beginning of time and i don't see it changing for Reg
. (of course you could make your own version of Reg
that behaves differently by making a different vMkReg
and the relevant wrappers, although it that case it might be wise to change the type name as well to avoid confusion.)
Thanks a lot for the clear explanation!
I encounter a situation where two rules that have conflicts (writing to the same register) can happen at the same cycle. The design and testbench are as follows:
The bsim give the following output:
It shows that both the rule
often
andodd
happen in steps 1, 3, and 5, where theodd
rule shadows theoften
rule. I wonder why this would happen.I appreciate any help you can provide.