-
Notifications
You must be signed in to change notification settings - Fork 324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LLHD] Support drives with delta delay in mem2reg #8279
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not very familiar with the semantics of blocking and delayed drives to the same signal, but otherwise LGTM.
@@ -884,10 +919,13 @@ void Promoter::propagateForward(LatticeNode *node, bool optimisticMerges) { | |||
return; | |||
} | |||
|
|||
// Drives propagate the driven value as a reaching def. | |||
// Drives propagate the driven value as a reaching def. Blocking drives kill | |||
// earlier non-blocking drives. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate a bit why that is? I'm not very familiar with the Verilog semantics related to that. Is there a specific paragraph in the standard to look at? One could think that the signal has the value of the blocking drive for the duration of 1d and is then overwritten by the value of the delayed drive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Blocking drives kill earlier non-blocking drives." is wrong statement due to that fact from 10.4.2 SystemVerilog LRM section:
At the end of the time step means that the nonblocking assignments are the last assignments executed in a time step
Blocking drives values are need only for other blocking assignments in procedural flow and also for rvalues in right-hand sides of nonblocking assignemnt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me tweak this comment a bit. Consider the following SV:
a <= #10ns 42; // A
a <= 43; // B
a = 44; // C
Since writes with less delay override/kill already scheduled writes with longer delay, (A) schedules a change to 42 after 10ns, but then (B) schedules a change to 43 after a delta delay / at the end of the time step, which overrides the earlier (A), but then (C) applies an immediate change to 44, which overrides the earlier (B). To preserve this, it's important that blocking drives kill the reaching definitions of non-blocking drives to not schedule a later signal change.
// CHECK-NEXT: llhd.halt | ||
llhd.halt | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there are two delayed drives to the same signal some conflict resolution has to happen AFAIK, but in mem2reg we probably just want to leave it as is and not merge the drives. Can you add a test to check what mem2reg does in such a situation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remember correctly, this only happens on wires, where you cannot have procedural drives assign to them. If you have two drives to the same variable, the latter one should win and override the earlier one. Let me go check on the details
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
10.4.2 in IEEE the 1800-2007 standard indicates that driving the same variable from different processes will see one of the assignments win but no conflict resolution occurs:

In the same section, there's an example showing how delayed drives with a shorter delay override already scheduled delayed drives with a longer delay:

Extend the LLHD Mem2Reg pass to also support non-blocking drives. These have a delay value of `1d` instead of the `1e` of blocking drives. To do so, add an additional bit to the slots associated with reaching definitions, indicating whether the definition for a slot is blocking/immediate or applies only after a delta delay. Blocking drives can then appropriately kill earlier non-blocking drives, and probes can only consider earlier blocking drives when resolving their value.
608535d
to
1bb60b4
Compare
Extend the LLHD Mem2Reg pass to also support non-blocking drives. These have a delay value of
1d
instead of the1e
of blocking drives. To do so, add an additional bit to the slots associated with reaching definitions, indicating whether the definition for a slot is blocking/immediate or applies only after a delta delay. Blocking drives can then appropriately kill earlier non-blocking drives, and probes can only consider earlier blocking drives when resolving their value.