-
Notifications
You must be signed in to change notification settings - Fork 298
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
[HW] Add hw.triggered
op
#5582
[HW] Add hw.triggered
op
#5582
Conversation
Here's a stab at the `hw.triggered` operation. I think the main issue is to decide where to place the lowering. AFAICT, the closest we have to a "hw to sv" conversion pass is `hw-legalize-modules` (which really should be named to `sv-legalize-modules` seeing as it's lowering away HW constructs in favor of SV constructs). I chose to introduce a new pass - `lower-hw-to-sv` which could serve as a clear home for these kinds of lowerings (maybe some things in `HWLegalizeModules` could be moved to here?). Lastly, just went with a simple assembly format. If people would like to see something more fancy, e.g. an initializer-list style format with an elided entry block: > `hw.triggered postedge %t (%a0 : i32 = %in) { ...` let me know.
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.
Looks good to me!
Initializer-style asm format would be nice, but not necessary. It seems so nice and general; someone should add it to mlir-tblgen assemblyFormat...
def AtPosEdge: I32EnumAttrCase<"AtPosEdge", 0, "posedge">; | ||
/// AtNegEdge triggers on a drop from 1 to 0/X/Z, or X/Z to 0. | ||
def AtNegEdge: I32EnumAttrCase<"AtNegEdge", 1, "negedge">; | ||
/// AtEdge(v) is syntactic sugar for "AtPosEdge(v) or AtNegEdge(v)". |
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 don't think it's just syntactic sugar so much as the only way to specify this behavior.
|
||
let regions = (region SizedRegion<1>:$body); | ||
let arguments = (ins EventControlAttr:$event, I1:$trigger, Variadic<AnyType>:$inputs); | ||
let results = (outs); |
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.
We may want results in the future, but let's add it when we have a use case.
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.
LGTM!
I'm starting to wonder if we should have a LowerCoreToSV
pass that combines all the Seq and HW and Comb lowerings into SV in one place. Not sure how useful that would be though 🤔
static sv::EventControl hwToSvEventControl(hw::EventControl ec) { | ||
switch (ec) { | ||
case hw::EventControl::AtPosEdge: | ||
return sv::EventControl::AtPosEdge; | ||
case hw::EventControl::AtNegEdge: | ||
return sv::EventControl::AtNegEdge; | ||
case hw::EventControl::AtEdge: | ||
return sv::EventControl::AtEdge; | ||
} | ||
llvm_unreachable("Unknown event control kind"); | ||
} |
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.
Now that we have EventControl
in HW, we might be able to replace all other dialect-local EventControl
things with the HW flavor! I think I've seen a few dialects where we redefine that enum.
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.
Captured in #5601.
hw.module @foo(%trigger : i1, %in : i32) { | ||
// CHECK: sv.always posedge %trigger { | ||
// CHECK-NEXT: "some.user"(%in) : (i32) -> () | ||
// CHECK-NEXT: } | ||
hw.triggered posedge %trigger (%in) : i32 { | ||
^bb0(%arg0 : i32): | ||
"some.user" (%arg0) : (i32) -> () | ||
} | ||
} |
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.
Cool!
Here's a stab at #5574.
I think the main issue is to decide where to place the lowering. AFAICT, the closest we have to a "hw to sv" conversion pass is
hw-legalize-modules
(which really should be named tosv-legalize-modules
seeing as it's lowering away HW constructs in favor of SV constructs). I chose to introduce a new pass -lower-hw-to-sv
which could serve as a clear home for these kinds of lowerings (maybe some things inHWLegalizeModules
could be moved to here?).Lastly, just went with a simple assembly format. If people would like to see something more fancy, e.g. an initializer-list style format with an elided entry block, let me know: