Skip to content

Commit 7669340

Browse files
authored
[FIRRTL] Sink fstring.time in LowerLayers (#8357)
Avoid an error when trying to create ports of `fstring` type. We currently only have one operation which can create these, `fstring.time`, which has simple semantics. When we see an op like this, if it is not already in the right layer block, then clone it. Signed-off-by: Schuyler Eldridge <[email protected]>
1 parent 75a8f00 commit 7669340

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

lib/Dialect/FIRRTL/Transforms/LowerLayers.cpp

+22-3
Original file line numberDiff line numberDiff line change
@@ -602,9 +602,28 @@ LogicalResult LowerLayersPass::runOnModuleBody(FModuleOp moduleOp,
602602
}
603603

604604
// For any other ops, create input ports for any captured operands.
605-
for (auto operand : op->getOperands()) {
606-
if (!isAncestorOfValueOwner(layerBlock, operand))
607-
createInputPort(operand, op->getLoc());
605+
for (size_t i = 0, e = op->getNumOperands(); i != e; ++i) {
606+
auto operand = op->getOperand(i);
607+
608+
// If the operand is in this layer block, do nothing.
609+
if (isAncestorOfValueOwner(layerBlock, operand))
610+
continue;
611+
612+
// If the operand is "special", e.g., it has no port representation,
613+
// then we need to clone it.
614+
//
615+
// TODO: Change this to recursively clone. This will matter once
616+
// FString operations have operands.
617+
if (type_isa<FStringType>(operand.getType())) {
618+
OpBuilder::InsertionGuard guard(builder);
619+
builder.setInsertionPoint(op);
620+
op->setOperand(i,
621+
builder.clone(*operand.getDefiningOp())->getResult(0));
622+
continue;
623+
}
624+
625+
// Create a port to capture the operand.
626+
createInputPort(operand, op->getLoc());
608627
}
609628

610629
if (auto verbatim = dyn_cast<sv::VerbatimOp>(op))

test/Dialect/FIRRTL/lower-layers.mlir

+16
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,22 @@ firrtl.circuit "Test" {
322322
}
323323
}
324324

325+
// An FString operation is outside the layer block. This needs to be cloned.
326+
//
327+
// CHECK: firrtl.module private @[[A:.+]]() {
328+
// CHECK: %time = firrtl.fstring.time
329+
// CHECK: firrtl.printf %clock, %c1_ui1, "{{.*}}" (%time)
330+
// CHECK: }
331+
// CHECK: firrtl.module @FStringOp
332+
firrtl.module @FStringOp() {
333+
%time = firrtl.fstring.time : !firrtl.fstring
334+
firrtl.layerblock @A {
335+
%clock = firrtl.wire : !firrtl.clock
336+
%c1_ui1 = firrtl.constant 1 : !firrtl.uint<1>
337+
firrtl.printf %clock, %c1_ui1, "{{}}" (%time) : !firrtl.clock, !firrtl.uint<1>, !firrtl.fstring
338+
}
339+
}
340+
325341
//===--------------------------------------------------------------------===//
326342
// Resolving Colored Probes
327343
//===--------------------------------------------------------------------===//

0 commit comments

Comments
 (0)