-
Notifications
You must be signed in to change notification settings - Fork 315
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
[MooreToCore] Support ProcedureOp and sequential assign operations #7362
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.
This looks fantastic! 🥳
Regarding ref types in the event op: I think you can theoretically type any expression into an event control statement in SV, so even something like @(posedge ~(a+b))
. That might be more annoying to handle at the Moore level than figuring out the a
and b
to observe at the LLHD level 🤔, WDYT?
We should probably also tweak the moore.event
op a bit in the future. Right now you type something like:
moore.event posedge a
moore.event posedge b
to mean "posedge on a or b", but the IR reads more like the process would block and wait for posedge a
, and then block and wait for posedge b
. I wonder if there's a way to define moore.event
such that it lowers to llhd.wait
more directly. That way the conversion for moore.procedure
will no longer have to create the edge detection, but leave that to the conversion for moore.event
instead.
I'm not entirely sure how such an event op would look like to capture things like @(posedge ~(a+b))
. Feels like it actually needs a region where you can have arbitrary code to check the condition, since you can have multiple and complicated edge expressions that need to be evaluated as part of the event check. Maybe something like the following?
moore.wait_event {
%0 = moore.read %a
%1 = moore.read %b
%2 = moore.add %0, %1
%3 = moore.not %2
%4 = moore.detect_event posedge %3 : -> !moore.event ???
// maybe others: moore.event_or %4, %5, %6 ???
moore.yield %4
}
We'd have to handle the more weird cases of event control, like:
always begin
x = 42;
@(posedge (a == 0));
x = 43;
@(posedge ~(a+b));
x = 44;
end
for (auto &operand : operation->getOpOperands()) { | ||
Value value = getSignal(operand.get()); | ||
auto memOp = dyn_cast<MemoryEffectOpInterface>(operation); | ||
if (!memOp) | ||
return; | ||
|
||
// The process is only sensitive to values that are read. | ||
if (isa<RefType>(operand.get().getType()) && | ||
memOp.getEffectOnValue<MemoryEffects::Read>(operand.get()) | ||
.has_value()) { | ||
if (!alreadyObserved.contains(value)) | ||
toObserve.push_back(value); | ||
|
||
alreadyObserved.insert(value); | ||
} | ||
} |
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.
Very neat 😎
signal = | ||
rewriter | ||
.create<UnrealizedConversionCastOp>(loc, convertedType, input) | ||
->getResult(0); | ||
} |
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.
Oh~! I learned this 😎 !
if (event.getEdge() == Edge::PosEdge || | ||
event.getEdge() == Edge::BothEdges) { | ||
Value currVal = rewriter.create<llhd::PrbOp>(loc, signal); | ||
Value trueVal = rewriter.create<hw::ConstantOp>(loc, APInt(1, 1)); | ||
Value notOldVal = | ||
rewriter.create<comb::XorOp>(loc, oldValues[i], trueVal); | ||
Value posedge = rewriter.create<comb::AndOp>(loc, notOldVal, currVal); | ||
disjuncts.push_back(posedge); | ||
} | ||
if (event.getEdge() == Edge::NegEdge || | ||
event.getEdge() == Edge::BothEdges) { | ||
Value currVal = rewriter.create<llhd::PrbOp>(loc, signal); | ||
Value trueVal = rewriter.create<hw::ConstantOp>(loc, APInt(1, 1)); | ||
Value notCurrVal = | ||
rewriter.create<comb::XorOp>(loc, currVal, trueVal); | ||
Value posedge = | ||
rewriter.create<comb::AndOp>(loc, oldValues[i], notCurrVal); | ||
disjuncts.push_back(posedge); | ||
} | ||
} |
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.
Amazing! Here is aimed to monitor the signals/clocks change 🚀.
Could we reimplement
When we handle the pseudo code
If there exist nested event controls, I think it will become more complex. |
Awesome, I can continue my |
The problem with having a
|
You're right! We must read the current value on e.g. re-execute |
ea35f05
to
830173c
Compare
Thanks for the reviews! A lot of great ideas and insights here. We should definitely revisits the design of
That's a great point! I agree that doing that at LLHD level probably makes more sense. |
830173c
to
0de9ffe
Compare
@hailongSun2000 @fabianschuiki Would it make sense to take the
moore.ref
value as operand for the EventOp directly instead of the read value?