Skip to content

Commit 4d3dfb7

Browse files
committed
[SeqToSV] Use XMR to set up async reset of firreg
With inline layers, firregs may now appear under ifdef blocks. This PR updates the generation of the reset IR to reference a firreg by XMR if the register is buried under an ifdef.
1 parent dbc2954 commit 4d3dfb7

File tree

2 files changed

+51
-10
lines changed

2 files changed

+51
-10
lines changed

lib/Conversion/SeqToSV/FirRegLowering.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ using llvm::MapVector;
2323

2424
#define DEBUG_TYPE "lower-seq-firreg"
2525

26+
static Value buildXMRTo(OpBuilder &builder, HierPathOp path, Location loc,
27+
Type type) {
28+
auto name = path.getSymNameAttr();
29+
auto ref = mlir::FlatSymbolRefAttr::get(name);
30+
return sv::XMRRefOp::create(builder, loc, type, ref);
31+
}
32+
2633
/// Immediately before the terminator, if present. Otherwise, the block's end.
2734
static Block::iterator getBlockEnd(Block *block) {
2835
if (block->mightHaveTerminator())
@@ -370,13 +377,22 @@ void FirRegLowering::createPresetInitialization(ImplicitLocOpBuilder &builder) {
370377
void FirRegLowering::createAsyncResetInitialization(
371378
ImplicitLocOpBuilder &builder) {
372379
for (auto &reset : asyncResets) {
380+
OpBuilder::InsertionGuard guard(builder);
381+
373382
// if (reset) begin
374383
// ..
375384
// end
376-
sv::IfOp::create(builder, reset.first, [&] {
377-
for (auto &reg : reset.second)
378-
sv::BPAssignOp::create(builder, reg.reg.getLoc(), reg.reg,
385+
sv::IfOp::create(builder, reset.first, [&]() {
386+
for (auto &reg : reset.second) {
387+
OpBuilder::InsertionGuard guard(builder);
388+
buildRegConditions(builder, reg.reg);
389+
Value target = reg.reg;
390+
if (reg.path)
391+
target = buildXMRTo(builder, reg.path, reg.reg.getLoc(),
392+
reg.reg.getType());
393+
sv::BPAssignOp::create(builder, reg.reg.getLoc(), target,
379394
reg.asyncResetValue);
395+
}
380396
});
381397
}
382398
}
@@ -798,13 +814,6 @@ void FirRegLowering::buildRegConditions(OpBuilder &b, sv::RegOp reg) {
798814
}
799815
}
800816

801-
static Value buildXMRTo(OpBuilder &builder, HierPathOp path, Location loc,
802-
Type type) {
803-
auto name = path.getSymNameAttr();
804-
auto ref = mlir::FlatSymbolRefAttr::get(name);
805-
return sv::XMRRefOp::create(builder, loc, type, ref);
806-
}
807-
808817
void FirRegLowering::initialize(OpBuilder &builder, RegLowerInfo reg,
809818
ArrayRef<Value> rands) {
810819
auto loc = reg.reg.getLoc();

test/Dialect/Seq/firreg.mlir

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,3 +1011,35 @@ hw.module @RegUnderIfdefDupName(in %clock : !seq.clock, in %reset : i1, in %valu
10111011
}
10121012
hw.output
10131013
}
1014+
1015+
// Test for registers with async resets.
1016+
1017+
// CHECK: hw.hierpath @[[reg_path:.+]] [@AsyncResetRegUnderIfdef::@reg]
1018+
hw.module @AsyncResetRegUnderIfdef(in %clock : !seq.clock, in %reset : i1, in %value : i1) {
1019+
%c = hw.constant 0 : i1
1020+
1021+
// CHECK: sv.ifdef @MyMacro {
1022+
// CHECK: %reg = sv.reg sym @reg : !hw.inout<i1>
1023+
// CHECK: %0 = sv.read_inout %reg : !hw.inout<i1>
1024+
// CHECK: sv.always posedge %clock, posedge %reset {
1025+
// CHECK: sv.if %reset {
1026+
// CHECK: sv.passign %reg, %false_0 : i1
1027+
// CHECK: } else {
1028+
// CHECK: sv.passign %reg, %value : i1
1029+
// CHECK: }
1030+
// CHECK: }
1031+
// CHECK: }
1032+
sv.ifdef @MyMacro {
1033+
%reg = seq.firreg %value clock %clock reset async %reset, %c : i1
1034+
}
1035+
1036+
// CHECK: sv.initial {
1037+
// CHECK: sv.if %reset {
1038+
// CHECK: sv.ifdef.procedural @MyMacro {
1039+
// CHECK: %0 = sv.xmr.ref @[[reg_path]] : !hw.inout<i1>
1040+
// CHECK: sv.bpassign %0, %false_0 : i1
1041+
// CHECK: }
1042+
// CHECK: }
1043+
// CHECK: }
1044+
hw.output
1045+
}

0 commit comments

Comments
 (0)