Skip to content

Commit 85acb84

Browse files
committed
skil sim.trigger in moveOpsIntoIfdefGuardsAndProcesses
1 parent f36a74f commit 85acb84

1 file changed

Lines changed: 87 additions & 78 deletions

File tree

lib/Conversion/SimToSV/SimToSV.cpp

Lines changed: 87 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -468,89 +468,98 @@ addFragments(hw::HWModuleOp module,
468468
static bool moveOpsIntoIfdefGuardsAndProcesses(Operation *rootOp) {
469469
bool usedSynthesisMacro = false;
470470

471-
rootOp->walk([&](Operation *op) {
472-
auto loc = op->getLoc();
473-
474-
// Move the op into an ifdef guard if needed.
475-
if (needsIfdefGuard(op)) {
476-
// Try to reuse an ifdef guard immediately before the op.
477-
Block *block = nullptr;
478-
if (op->getPrevNode())
479-
block = TypeSwitch<Operation *, Block *>(op->getPrevNode())
480-
.Case<sv::IfDefOp, sv::IfDefProceduralOp>(
481-
[&](auto guardOp) -> Block * {
482-
if (guardOp.getCond().getIdent().getAttr() ==
483-
"SYNTHESIS" &&
484-
guardOp.hasElse())
485-
return guardOp.getElseBlock();
486-
return nullptr;
487-
})
488-
.Default([](auto) { return nullptr; });
489-
490-
// If there was no pre-existing guard, create one.
491-
if (!block) {
492-
OpBuilder builder(op);
493-
if (op->getParentOp()->hasTrait<ProceduralRegion>())
494-
block = sv::IfDefProceduralOp::create(
495-
builder, loc, "SYNTHESIS", [] {}, [] {})
496-
.getElseBlock();
497-
else
498-
block = sv::IfDefOp::create(
499-
builder, loc, "SYNTHESIS", [] {}, [] {})
500-
.getElseBlock();
501-
usedSynthesisMacro = true;
502-
}
471+
rootOp->walk<mlir::WalkOrder::PreOrder>(
472+
[&](Operation *op) -> mlir::WalkResult {
473+
// `sim.triggered` is lowered as a whole later on. Do not pre-wrap the
474+
// ops nested inside it here, or we may create redundant/invalid
475+
// structure.
476+
if (isa<TriggeredOp>(op))
477+
return mlir::WalkResult::skip();
478+
479+
auto loc = op->getLoc();
480+
481+
// Move the op into an ifdef guard if needed.
482+
if (needsIfdefGuard(op)) {
483+
// Try to reuse an ifdef guard immediately before the op.
484+
Block *block = nullptr;
485+
if (op->getPrevNode())
486+
block = TypeSwitch<Operation *, Block *>(op->getPrevNode())
487+
.Case<sv::IfDefOp, sv::IfDefProceduralOp>(
488+
[&](auto guardOp) -> Block * {
489+
if (guardOp.getCond().getIdent().getAttr() ==
490+
"SYNTHESIS" &&
491+
guardOp.hasElse())
492+
return guardOp.getElseBlock();
493+
return nullptr;
494+
})
495+
.Default([](auto) { return nullptr; });
496+
497+
// If there was no pre-existing guard, create one.
498+
if (!block) {
499+
OpBuilder builder(op);
500+
if (op->getParentOp()->hasTrait<ProceduralRegion>())
501+
block = sv::IfDefProceduralOp::create(
502+
builder, loc, "SYNTHESIS", [] {}, [] {})
503+
.getElseBlock();
504+
else
505+
block = sv::IfDefOp::create(
506+
builder, loc, "SYNTHESIS", [] {}, [] {})
507+
.getElseBlock();
508+
usedSynthesisMacro = true;
509+
}
503510

504-
// Move the op into the guard block.
505-
op->moveBefore(block, block->end());
506-
}
511+
// Move the op into the guard block.
512+
op->moveBefore(block, block->end());
513+
}
507514

508-
// Check if the op requires an clock and condition wrapper.
509-
auto [clock, condition] = needsClockAndConditionWrapper(op);
510-
511-
// Create an enclosing always process.
512-
if (clock) {
513-
// Try to reuse an always process immediately before the op.
514-
Block *block = nullptr;
515-
if (auto alwaysOp = dyn_cast_or_null<sv::AlwaysOp>(op->getPrevNode()))
516-
if (alwaysOp.getNumConditions() == 1 &&
517-
alwaysOp.getCondition(0).event == sv::EventControl::AtPosEdge)
518-
if (auto clockOp = alwaysOp.getCondition(0)
519-
.value.getDefiningOp<seq::FromClockOp>())
520-
if (clockOp.getInput() == clock)
521-
block = alwaysOp.getBodyBlock();
522-
523-
// If there was no pre-existing always process, create one.
524-
if (!block) {
525-
OpBuilder builder(op);
526-
clock = seq::FromClockOp::create(builder, loc, clock);
527-
block = sv::AlwaysOp::create(builder, loc, sv::EventControl::AtPosEdge,
528-
clock, [] {})
529-
.getBodyBlock();
530-
}
515+
// Check if the op requires an clock and condition wrapper.
516+
auto [clock, condition] = needsClockAndConditionWrapper(op);
517+
518+
// Create an enclosing always process.
519+
if (clock) {
520+
// Try to reuse an always process immediately before the op.
521+
Block *block = nullptr;
522+
if (auto alwaysOp = dyn_cast_or_null<sv::AlwaysOp>(op->getPrevNode()))
523+
if (alwaysOp.getNumConditions() == 1 &&
524+
alwaysOp.getCondition(0).event == sv::EventControl::AtPosEdge)
525+
if (auto clockOp = alwaysOp.getCondition(0)
526+
.value.getDefiningOp<seq::FromClockOp>())
527+
if (clockOp.getInput() == clock)
528+
block = alwaysOp.getBodyBlock();
529+
530+
// If there was no pre-existing always process, create one.
531+
if (!block) {
532+
OpBuilder builder(op);
533+
clock = seq::FromClockOp::create(builder, loc, clock);
534+
block = sv::AlwaysOp::create(
535+
builder, loc, sv::EventControl::AtPosEdge, clock, [] {})
536+
.getBodyBlock();
537+
}
531538

532-
// Move the op into the process.
533-
op->moveBefore(block, block->end());
534-
}
539+
// Move the op into the process.
540+
op->moveBefore(block, block->end());
541+
}
535542

536-
// Create an enclosing if condition.
537-
if (condition) {
538-
// Try to reuse an if statement immediately before the op.
539-
Block *block = nullptr;
540-
if (auto ifOp = dyn_cast_or_null<sv::IfOp>(op->getPrevNode()))
541-
if (ifOp.getCond() == condition)
542-
block = ifOp.getThenBlock();
543-
544-
// If there was no pre-existing if statement, create one.
545-
if (!block) {
546-
OpBuilder builder(op);
547-
block = sv::IfOp::create(builder, loc, condition, [] {}).getThenBlock();
548-
}
543+
// Create an enclosing if condition.
544+
if (condition) {
545+
// Try to reuse an if statement immediately before the op.
546+
Block *block = nullptr;
547+
if (auto ifOp = dyn_cast_or_null<sv::IfOp>(op->getPrevNode()))
548+
if (ifOp.getCond() == condition)
549+
block = ifOp.getThenBlock();
550+
551+
// If there was no pre-existing if statement, create one.
552+
if (!block) {
553+
OpBuilder builder(op);
554+
block =
555+
sv::IfOp::create(builder, loc, condition, [] {}).getThenBlock();
556+
}
549557

550-
// Move the op into the if body.
551-
op->moveBefore(block, block->end());
552-
}
553-
});
558+
// Move the op into the if body.
559+
op->moveBefore(block, block->end());
560+
}
561+
return mlir::WalkResult::advance();
562+
});
554563

555564
return usedSynthesisMacro;
556565
}

0 commit comments

Comments
 (0)