mirror of https://github.com/llvm/circt.git
[FIRRTL] Allow layers under when and match. (#7234)
Behavior is same as-if the contained operations were not under a layer.
This commit is contained in:
parent
03626d4a93
commit
3f0dcf4405
|
@ -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";
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -533,6 +533,7 @@ public:
|
|||
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);
|
||||
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue