Skip to content

Commit

Permalink
[FIRRTL] Allow layers under when and match. (llvm#7234)
Browse files Browse the repository at this point in the history
Behavior is same as-if the contained operations were
not under a layer.
  • Loading branch information
dtzSiFive authored and mingzheTerapines committed Jun 27, 2024
1 parent 48b680a commit 2fee76f
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 3 deletions.
4 changes: 3 additions & 1 deletion include/circt/Dialect/FIRRTL/FIRRTLStatements.td
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,9 @@ def VerifCoverIntrinsicOp : VerifIntrinsicOp<"cover">;
def LayerBlockOp : FIRRTLOp<
"layerblock",
[SingleBlock, NoTerminator, NoRegionArguments,
ParentOneOf<["firrtl::FModuleOp", "firrtl::LayerBlockOp"]>,
ParentOneOf<[
"firrtl::FModuleOp", "firrtl::LayerBlockOp",
"firrtl::WhenOp", "firrtl::MatchOp"]>,
DeclareOpInterfaceMethods<SymbolUserOpInterface>]
> {
let summary = "A definition of a layer block";
Expand Down
4 changes: 4 additions & 0 deletions lib/Dialect/FIRRTL/FIRRTLOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6171,6 +6171,10 @@ LogicalResult LayerBlockOp::verify() {
auto layerName = getLayerName();
auto *parentOp = (*this)->getParentOp();

// Get parent operation that isn't a when or match.
while (isa<WhenOp, MatchOp>(parentOp))
parentOp = parentOp->getParentOp();

// Verify the correctness of the symbol reference. Only verify that this
// layer block makes sense in its parent module or layer block.
auto nestedReferences = layerName.getNestedReferences();
Expand Down
6 changes: 6 additions & 0 deletions lib/Dialect/FIRRTL/Transforms/ExpandWhens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ class WhenOpVisitor : public LastConnectResolver<WhenOpVisitor> {
void visitStmt(PrintFOp op);
void visitStmt(StopOp op);
void visitStmt(WhenOp op);
void visitStmt(LayerBlockOp op);
void visitStmt(RefForceOp op);
void visitStmt(RefForceInitialOp op);
void visitStmt(RefReleaseOp op);
Expand Down Expand Up @@ -619,6 +620,11 @@ void WhenOpVisitor::visitStmt(WhenOp whenOp) {
processWhenOp(whenOp, condition);
}

// NOLINTNEXTLINE(misc-no-recursion)
void WhenOpVisitor::visitStmt(LayerBlockOp layerBlockOp) {
process(*layerBlockOp.getBody());
}

void WhenOpVisitor::visitStmt(RefForceOp op) {
op.getPredicateMutable().assign(andWithCondition(op, op.getPredicate()));
}
Expand Down
14 changes: 14 additions & 0 deletions test/Dialect/FIRRTL/expand-whens.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,20 @@ firrtl.module @WhenInGroup(in %cond : !firrtl.uint<1>) {
}
}

// Check that expand whens works for layers under when's.
firrtl.layer @Layer bind {}
// CHECK-LABEL: firrtl.module @LayerUnderWhen(
// CHECK-NEXT: firrtl.layerblock @Layer
// CHECK: firrtl.printf %clock, %cond
firrtl.module @LayerUnderWhen(in %cond : !firrtl.uint<1>, in %clock : !firrtl.clock) {
firrtl.when %cond : !firrtl.uint<1> {
firrtl.layerblock @Layer {
%c1_ui1 = firrtl.constant 1 : !firrtl.uint<1>
firrtl.printf %clock, %c1_ui1, "Condition is true" : !firrtl.clock, !firrtl.uint<1>
}
}
}

// CHECK: firrtl.class @ClassWithInput(in %in: !firrtl.string)
firrtl.class @ClassWithInput(in %in: !firrtl.string) {}

Expand Down
29 changes: 27 additions & 2 deletions test/firtool/layers.fir
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ circuit Foo: %[[
{
"class": "firrtl.transforms.DontTouchAnnotation",
"target": "~Foo|Foo>y"
},
{
"class": "firrtl.transforms.DontTouchAnnotation",
"target": "~Foo|Foo>z"
}
]]
layer A, bind:
Expand All @@ -17,16 +21,34 @@ circuit Foo: %[[
public module Foo:
input in: UInt<1>

input clock: Clock
input cond: UInt<1>
input enable: UInt<1>

layerblock A:
node x = in

layerblock B:
node y = x

when cond:
layerblock B:
when x:
node z = x
assert(clock, cond, enable, "Test")

; CHECK-LABEL: module Foo_A_B(
; CHECK-NEXT: input x
; CHECK-NEXT: input x,
; CHECK-NEXT: cond,
; CHECK-NEXT: enable,
; CHECK-NEXT: clock
; CHECK-NEXT: );
; CHECK: wire y = x;
; CHECK: wire z = x;
; CHECK: always @(posedge clock) begin
; CHECK-NEXT: if (cond & x & enable)
; CHECK-NEXT: assert(cond) else $error("Test");
; CHECK-NEXT: end // always @(posedge)
; CHECK-NEXT: endmodule

; CHECK-LABEL: module Foo_A(
Expand All @@ -40,7 +62,10 @@ circuit Foo: %[[
; CHECK-NEXT: `ifndef layers_Foo_A_B
; CHECK-NEXT: `define layers_Foo_A_B
; CHECK-NEXT: bind Foo Foo_A_B a_b (
; CHECK-NEXT: x (Foo.a.x_probe)
; CHECK-NEXT: .x (Foo.a.x_probe),
; CHECK-NEXT: .cond (cond),
; CHECK-NEXT: .enable (enable),
; CHECK-NEXT: .clock (clock)
; CHECK-NEXT: );
; CHECK-NEXT: `endif // layers_Foo_A_B

Expand Down

0 comments on commit 2fee76f

Please sign in to comment.