Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions lib/Conversion/ExportVerilog/PrepareForEmission.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,8 +779,11 @@ bool EmittedExpressionStateManager::shouldSpillWireBasedOnState(Operation &op) {
/// After the legalization, we are able to know accurate verilog AST structures.
/// So this function walks and prettifies verilog IR with a heuristic method
/// specified by `options.wireSpillingHeuristic` based on the structures.
/// Also move the declarations to the top of the block when
/// `disallowDeclAssignments` is set.
static void prettifyAfterLegalization(
Block &block, EmittedExpressionStateManager &expressionStateManager) {
Block &block, const LoweringOptions &options,
EmittedExpressionStateManager &expressionStateManager) {
// TODO: Handle procedural regions as well.
if (block.getParentOp()->hasTrait<ProceduralRegion>())
return;
Expand All @@ -794,11 +797,20 @@ static void prettifyAfterLegalization(
}
}

for (auto &op : block) {
// Recursively process nested regions, and move declarations to the top of the
// block when `disallowDeclAssignments` is set.
Operation *insertionPoint = block.empty() ? nullptr : &block.front();
for (auto &op : llvm::make_early_inc_range(block)) {
// If the operations has regions, visit each of the region bodies.
for (auto &region : op.getRegions()) {
if (!region.empty())
prettifyAfterLegalization(region.front(), expressionStateManager);
prettifyAfterLegalization(region.front(), options,
expressionStateManager);
}

if (options.disallowDeclAssignments && isMovableDeclaration(&op)) {
op.moveBefore(insertionPoint);
insertionPoint = op.getNextNode();
}
}
}
Expand Down Expand Up @@ -1384,7 +1396,8 @@ LogicalResult ExportVerilog::prepareHWModule(hw::HWEmittableModuleLike module,

EmittedExpressionStateManager expressionStateManager(options);
// Spill wires to prettify verilog outputs.
prettifyAfterLegalization(*module.getBodyBlock(), expressionStateManager);
prettifyAfterLegalization(*module.getBodyBlock(), options,
expressionStateManager);

return success();
}
Expand Down
15 changes: 12 additions & 3 deletions test/Conversion/ExportVerilog/decl-assignments.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@

// CHECK-LABEL: module test(
hw.module @test(in %v: i1) {
// ALLOW: wire w = v;
// DISALLOW: wire w;
// DISALLOW: assign w = v;
// ALLOW: wire w = v;
// DISALLOW: wire w;
// DISALLOW-NEXT: wire u;
// DISALLOW-NEXT: wire x;
// DISALLOW-NEXT: assign w = v;
// DISALLOW-NEXT: assign u = v;
%w = sv.wire : !hw.inout<i1>
sv.assign %w, %v : i1
%u = sv.wire : !hw.inout<i1>
sv.assign %u, %v : i1
// CHECK: initial begin
sv.initial {
// ALLOW: automatic logic l = v;
Expand All @@ -16,4 +21,8 @@ hw.module @test(in %v: i1) {
%l = sv.logic : !hw.inout<i1>
sv.bpassign %l, %v : i1
}
// ALLOW: wire x = v;
// DISALLOW: assign x = v;
%x = sv.wire : !hw.inout<i1>
sv.assign %x, %v : i1
}