[Seq][FirMemLowering] Create correct width constant for mask (#6214)

`FirMemLowering` is creating incorrect width mask, when the optional mask input
 is missing from the memory access ops. Instead of creating a one bit mask for
 the optional mask input, it must be of appropriate mask width as determined by
 the `firmem`.
Fixes https://github.com/llvm/circt/issues/6213
This commit is contained in:
Prithayan Barua 2023-09-27 14:31:13 -07:00 committed by GitHub
parent 44ec36e3e8
commit c8ab1e1163
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 8 deletions

View File

@ -308,15 +308,17 @@ void FirMemLowering::lowerMemoriesInModule(
<< module.getName() << "\n");
hw::ConstantOp constOneOp;
auto constOne = [&] {
auto constOne = [&](unsigned width = 1) {
if (!constOneOp) {
auto builder = OpBuilder::atBlockBegin(module.getBodyBlock());
constOneOp = builder.create<hw::ConstantOp>(module.getLoc(),
builder.getI1Type(), 1);
constOneOp = builder.create<hw::ConstantOp>(
module.getLoc(), builder.getIntegerType(width), 1);
}
return constOneOp;
};
auto valueOrOne = [&](Value value) { return value ? value : constOne(); };
auto valueOrOne = [&](Value value, unsigned width = 1) {
return value ? value : constOne(width);
};
for (auto [config, genOp, memOp] : mems) {
LLVM_DEBUG(llvm::dbgs() << "- Lowering " << memOp.getName() << "\n");
@ -349,7 +351,7 @@ void FirMemLowering::lowerMemoriesInModule(
addInput(port.getWriteData());
addOutput(port.getReadData());
if (config->maskBits > 1)
addInput(valueOrOne(port.getMask()));
addInput(valueOrOne(port.getMask(), config->maskBits));
}
// Add the write ports.
@ -362,7 +364,7 @@ void FirMemLowering::lowerMemoriesInModule(
addInput(port.getClock());
addInput(port.getData());
if (config->maskBits > 1)
addInput(valueOrOne(port.getMask()));
addInput(valueOrOne(port.getMask(), config->maskBits));
}
// Create the module instance.

View File

@ -12,6 +12,7 @@ sv.macro.decl @SomeMacro
// CHECK-LABEL: hw.module @Foo
hw.module @Foo(%clk: !seq.clock, %en: i1, %addr: i4, %wdata: i42, %wmode: i1, %mask2: i2, %mask3: i3, %mask6: i6) {
// CHECK-NEXT: %[[c1_i2:.+]] = hw.constant 1 : i2
// CHECK-NEXT: [[TMP0:%.+]] = hw.instance "m0_mem1A_ext" @m0_mem1_12x42(R0_addr: %addr: i4, R0_en: %en: i1, R0_clk: %clk: !seq.clock) -> (R0_data: i42)
// CHECK-NEXT: [[TMP1:%.+]] = hw.instance "m0_mem1B_ext" @m0_mem1_12x42(R0_addr: %addr: i4, R0_en: %en: i1, R0_clk: %clk: !seq.clock) -> (R0_data: i42)
// CHECK-NEXT: comb.xor [[TMP0]], [[TMP1]]
@ -21,9 +22,9 @@ hw.module @Foo(%clk: !seq.clock, %en: i1, %addr: i4, %wdata: i42, %wmode: i1, %m
%1 = seq.firmem.read_port %m0_mem1B[%addr], clock %clk enable %en : <12 x 42>
comb.xor %0, %1 : i42
// CHECK-NEXT: hw.instance "m0_mem2_ext" @m0_mem2_12x42(W0_addr: %addr: i4, W0_en: %en: i1, W0_clk: %clk: !seq.clock, W0_data: %wdata: i42, W0_mask: %mask2: i2) -> ()
// CHECK-NEXT: hw.instance "m0_mem2_ext" @m0_mem2_12x42(W0_addr: %addr: i4, W0_en: %en: i1, W0_clk: %clk: !seq.clock, W0_data: %wdata: i42, W0_mask: %[[c1_i2]]: i2) -> ()
%m0_mem2 = seq.firmem 0, 1, undefined, port_order : <12 x 42, mask 2>
seq.firmem.write_port %m0_mem2[%addr] = %wdata, clock %clk enable %en mask %mask2 : <12 x 42, mask 2>, i2
seq.firmem.write_port %m0_mem2[%addr] = %wdata, clock %clk enable %en : <12 x 42, mask 2>
// CHECK-NEXT: [[TMP:%.+]] = hw.instance "m0_mem3_ext" @m0_mem3_12x42(RW0_addr: %addr: i4, RW0_en: %en: i1, RW0_clk: %clk: !seq.clock, RW0_wmode: %wmode: i1, RW0_wdata: %wdata: i42, RW0_wmask: %mask3: i3) -> (RW0_rdata: i42)
// CHECK-NEXT: comb.xor [[TMP]]