Skip to content

Commit 4b8be16

Browse files
authored
[ExportVerilog] Move declarations to the top of blocks when disallowDeclAssignments is set. (#9309)
This patch implements the logic to move wire and register declarations to the beginning of blocks when the disallowDeclAssignments option is enabled. This is solely for readability not for correctness.
1 parent 2b42ecb commit 4b8be16

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

lib/Conversion/ExportVerilog/PrepareForEmission.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -779,8 +779,11 @@ bool EmittedExpressionStateManager::shouldSpillWireBasedOnState(Operation &op) {
779779
/// After the legalization, we are able to know accurate verilog AST structures.
780780
/// So this function walks and prettifies verilog IR with a heuristic method
781781
/// specified by `options.wireSpillingHeuristic` based on the structures.
782+
/// Also move the declarations to the top of the block when
783+
/// `disallowDeclAssignments` is set.
782784
static void prettifyAfterLegalization(
783-
Block &block, EmittedExpressionStateManager &expressionStateManager) {
785+
Block &block, const LoweringOptions &options,
786+
EmittedExpressionStateManager &expressionStateManager) {
784787
// TODO: Handle procedural regions as well.
785788
if (block.getParentOp()->hasTrait<ProceduralRegion>())
786789
return;
@@ -794,11 +797,20 @@ static void prettifyAfterLegalization(
794797
}
795798
}
796799

797-
for (auto &op : block) {
800+
// Recursively process nested regions, and move declarations to the top of the
801+
// block when `disallowDeclAssignments` is set.
802+
Operation *insertionPoint = block.empty() ? nullptr : &block.front();
803+
for (auto &op : llvm::make_early_inc_range(block)) {
798804
// If the operations has regions, visit each of the region bodies.
799805
for (auto &region : op.getRegions()) {
800806
if (!region.empty())
801-
prettifyAfterLegalization(region.front(), expressionStateManager);
807+
prettifyAfterLegalization(region.front(), options,
808+
expressionStateManager);
809+
}
810+
811+
if (options.disallowDeclAssignments && isMovableDeclaration(&op)) {
812+
op.moveBefore(insertionPoint);
813+
insertionPoint = op.getNextNode();
802814
}
803815
}
804816
}
@@ -1384,7 +1396,8 @@ LogicalResult ExportVerilog::prepareHWModule(hw::HWEmittableModuleLike module,
13841396

13851397
EmittedExpressionStateManager expressionStateManager(options);
13861398
// Spill wires to prettify verilog outputs.
1387-
prettifyAfterLegalization(*module.getBodyBlock(), expressionStateManager);
1399+
prettifyAfterLegalization(*module.getBodyBlock(), options,
1400+
expressionStateManager);
13881401

13891402
return success();
13901403
}

test/Conversion/ExportVerilog/decl-assignments.mlir

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33

44
// CHECK-LABEL: module test(
55
hw.module @test(in %v: i1) {
6-
// ALLOW: wire w = v;
7-
// DISALLOW: wire w;
8-
// DISALLOW: assign w = v;
6+
// ALLOW: wire w = v;
7+
// DISALLOW: wire w;
8+
// DISALLOW-NEXT: wire u;
9+
// DISALLOW-NEXT: wire x;
10+
// DISALLOW-NEXT: assign w = v;
11+
// DISALLOW-NEXT: assign u = v;
912
%w = sv.wire : !hw.inout<i1>
1013
sv.assign %w, %v : i1
14+
%u = sv.wire : !hw.inout<i1>
15+
sv.assign %u, %v : i1
1116
// CHECK: initial begin
1217
sv.initial {
1318
// ALLOW: automatic logic l = v;
@@ -16,4 +21,8 @@ hw.module @test(in %v: i1) {
1621
%l = sv.logic : !hw.inout<i1>
1722
sv.bpassign %l, %v : i1
1823
}
24+
// ALLOW: wire x = v;
25+
// DISALLOW: assign x = v;
26+
%x = sv.wire : !hw.inout<i1>
27+
sv.assign %x, %v : i1
1928
}

0 commit comments

Comments
 (0)