Type of issue: Bug Report
Please provide the steps to reproduce the problem:
I'm instantiating an SRAM with 2 read-write ports. I need byte-masking on one of the ports, but not the other:
val mem = SRAM.masked(16 * 1024, Vec(4, UInt(8.W)), numReadPorts = 0, numWritePorts = 0, numReadwritePorts = 2)
val memHostPort = mem.readwritePorts(0)
val memDevicePort = mem.readwritePorts(1)
memDevicePort is linked up with another submodule that uses the byte-mask. memHostPort connects to the Module's IO ports.
Then, I have this, to set the writeMask to 1111 for this port:
val writeMask = Wire(Vec(4, Bool()))
writeMask := VecInit(true.B, true.B, true.B, true.B)
memHostPort.mask.get := writeMask
What is the current behavior?
When producing SystemVerilog output, Chisel/CIRCT ends up producing a module mem_mem_sram_16384x32 for the SRAM, and in my parent Module, passes it (SystemVerilog)
mem_mem_sram_16384x32 mem_mem_sram_ext (
.RW0_wmask ({_GEN_3, _GEN_4, _GEN_5, _GEN_6}),
...
.RW1_wmask (4'h1)
);
which is, of course, the wrong mask for port 1. The mask for port 0 is correct. This is generated with:
ChiselStage.emitSystemVerilogFile(
new MyModule(),
argRest.toArray,
firtoolOpts = Array(
"--preserve-aggregate=1d-vec",
)
)
without --preserve-aggregate=1d-vec, the output is even worse. In the mem_mem_sram_16384x32 module definition, RW0_wmask and RW1_wmask both disappear! So now, there's no masking at all.
What is the expected behavior?
.RW1_wmask (4'hF), to pass all 1s.
Please tell us about your environment:
Version: 7.9.0
OS: macOS Sequoia 15.7.1 (also verified on an Ubuntu 20.04 system).
Other Information
I was previously using Version 6.6.0, which did not have this problem.
I have found a workaround. Wrap the writeMask with dontTouch:
val writeMask = dontTouch(Wire(Vec(4, Bool())))
writeMask := VecInit(true.B, true.B, true.B, true.B)
This produces:
wire [3:0] mem_writeMask = '{1'h1, 1'h1, 1'h1, 1'h1};
mem_mem_sram_16384x32 mem_mem_sram_ext (
.RW0_wmask ({_GEN_3, _GEN_4, _GEN_5, _GEN_6}),
...
.RW1_wmask (mem_writeMask)
);
and without --preserve-aggregate=1d-vec, the masks are still there and correct.
.RW0_wmask
({mem_mem_sram_RW1_wmask_3,
mem_mem_sram_RW1_wmask_2,
mem_mem_sram_RW1_wmask_1,
mem_mem_sram_RW1_wmask_0}),
...
.RW1_wmask ({mem_writeMask_3, mem_writeMask_2, mem_writeMask_1, mem_writeMask_0})
I'll also note that, weirdly enough, other constant values (other than b1111) work. e.g.:
val writeMask = Wire(Vec(4, Bool()))
writeMask := VecInit(true.B, true.B, true.B, false.B)
generates:
.RW1_wmask (4'h7)
and every other combination I've tried also works, except for 1111.
Type of issue: Bug Report
Please provide the steps to reproduce the problem:
I'm instantiating an
SRAMwith 2 read-write ports. I need byte-masking on one of the ports, but not the other:memDevicePortis linked up with another submodule that uses the byte-mask.memHostPortconnects to the Module's IO ports.Then, I have this, to set the writeMask to
1111for this port:What is the current behavior?
When producing SystemVerilog output, Chisel/CIRCT ends up producing a module
mem_mem_sram_16384x32for the SRAM, and in my parent Module, passes it (SystemVerilog)which is, of course, the wrong mask for port 1. The mask for port 0 is correct. This is generated with:
without
--preserve-aggregate=1d-vec, the output is even worse. In themem_mem_sram_16384x32module definition,RW0_wmaskandRW1_wmaskboth disappear! So now, there's no masking at all.What is the expected behavior?
.RW1_wmask (4'hF), to pass all 1s.Please tell us about your environment:
Version: 7.9.0
OS: macOS Sequoia 15.7.1 (also verified on an Ubuntu 20.04 system).
Other Information
I was previously using Version 6.6.0, which did not have this problem.
I have found a workaround. Wrap the
writeMaskwithdontTouch:This produces:
and without
--preserve-aggregate=1d-vec, the masks are still there and correct.I'll also note that, weirdly enough, other constant values (other than
b1111) work. e.g.:generates:
.RW1_wmask (4'h7)and every other combination I've tried also works, except for
1111.