llvm / llvm/circt

[circt-verilog][RegOfVecToMem] Fail to recognize SRAM with mask

Open
#11,097 3 comments 0 reactions 1 assignee Claimed by @SawyDust1228 View on GitHub
Dominant language
C++
Stars
2.2k
Forks
524
Avg merge
3d 2h
Merged PRs (30d)
46

Description

```verilog
module mem_8192x64( // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
input [12:0] RW0_addr,
input RW0_en,
input RW0_clk,
input RW0_wmode,
input [63:0] RW0_wdata,
output [63:0] RW0_rdata,
input [7:0] RW0_wmask
);

reg [63:0] Memory[0:8191]; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
reg [12:0] _RW0_raddr_d0; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
reg _RW0_ren_d0; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
reg _RW0_rmode_d0; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
always @(posedge RW0_clk) begin // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
_RW0_raddr_d0 <= RW0_addr; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
_RW0_ren_d0 <= RW0_en; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
_RW0_rmode_d0 <= RW0_wmode; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
if (RW0_en & RW0_wmask[0] & RW0_wmode) // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
Memory[RW0_addr][32'h0 +: 8] <= RW0_wdata[7:0]; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
if (RW0_en & RW0_wmask[1] & RW0_wmode) // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
Memory[RW0_addr][32'h8 +: 8] <= RW0_wdata[15:8]; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
if (RW0_en & RW0_wmask[2] & RW0_wmode) // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
Memory[RW0_addr][32'h10 +: 8] <= RW0_wdata[23:16]; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
if (RW0_en & RW0_wmask[3] & RW0_wmode) // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
Memory[RW0_addr][32'h18 +: 8] <= RW0_wdata[31:24]; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
if (RW0_en & RW0_wmask[4] & RW0_wmode) // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
Memory[RW0_addr][32'h20 +: 8] <= RW0_wdata[39:32]; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
if (RW0_en & RW0_wmask[5] & RW0_wmode) // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
Memory[RW0_addr][32'h28 +: 8] <= RW0_wdata[47:40]; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
if (RW0_en & RW0_wmask[6] & RW0_wmode) // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
Memory[RW0_addr][32'h30 +: 8] <= RW0_wdata[55:48]; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
if (RW0_en & RW0_wmask[7] & RW0_wmode) // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
Memory[RW0_addr][32'h38 +: 8] <= RW0_wdata[63:56]; // @[generators/rocket-chip/src/main/scala/util/DescribedSRAM.scala:17:26]
end // always @(posedge)
endmodule
```
It should be lowered to like this:
```mlir
%mem = seq.firmem 1, 1, undefined, port_order : <8192 x 64, mask 8>
%0 = seq.firmem.read_write_port %mem[%26] = %auto_in_a_bits_data if %23,
clock %clock enable %1 mask %auto_in_a_bits_mask : <8192 x 64, mask 8>, i8
```
Currently there are a bunch of array inject of large array, which makes circt-synth not scale for this verilog.
```mlir
hw.module private @mem_8192x64(in %RW0_addr : i13, in %RW0_en : i1, in %RW0_clk : i1, in %RW0_wmode : i1, in %RW0_wdata : i64, out RW0_rdata : i64, in %RW0_wmask : i8) {
%true = hw.constant true
%c0_i64 = hw.constant 0 : i64
%c-1_i13 = hw.constant -1 : i13
%0 = comb.extract %RW0_wmask from 0 : (i8) -> i1
%1 = comb.and %RW0_en, %0, %RW0_wmode : i1
%2 = comb.sub %c-1_i13, %RW0_addr : i13
%3 = comb.extract %RW0_wdata from 0 : (i64) -> i8
%4 = hw.array_get %Memory[%2] : !hw.array<8192xi64>, i13
%5 = comb.extract %4 from 8 : (i64) -> i56
%6 = comb.concat %5, %3 : i56, i8
%7 = hw.array_inject %Memory[%2], %6 : !hw.array<8192xi64>, i13
%8 = comb.mux %1, %7, %Memory : !hw.array<8192xi64>
%9 = comb.extract %RW0_wmask from 1 : (i8) -> i1
%10 = comb.and %RW0_en, %9, %RW0_wmode : i1
%11 = comb.extract %RW0_wdata from 8 : (i64) -> i8
%12 = hw.array_get %8[%2] : !hw.array<8192xi64>, i13
%13 = comb.extract %12 from 16 : (i64) -> i48
%14 = comb.extract %12 from 0 : (i64) -> i8
%15 = comb.concat %13, %11, %14 : i48, i8, i8
%16 = hw.array_inject %8[%2], %15 : !hw.array<8192xi64>, i13
%17 = comb.mux %10, %16, %8 : !hw.array<8192xi64>
%18 = comb.extract %RW0_wmask from 2 : (i8) -> i1
%19 = comb.and %RW0_en, %18, %RW0_wmode : i1
%20 = comb.extract %RW0_wdata from 16 : (i64) -> i8
%21 = hw.array_get %17[%2] : !hw.array<8192xi64>, i13
%22 = comb.extract %21 from 24 : (i64) -> i40
%23 = comb.extract %21 from 0 : (i64) -> i16
%24 = comb.concat %22, %20, %23 : i40, i8, i16
%25 = hw.array_inject %17[%2], %24 : !hw.array<8192xi64>, i13
%26 = comb.mux %19, %25, %17 : !hw.array<8192xi64>
%27 = comb.extract %RW0_wmask from 3 : (i8) -> i1
%28 = comb.and %RW0_en, %27, %RW0_wmode : i1
%29 = comb.extract %RW0_wdata from 24 : (i64) -> i8
%30 = hw.array_get %26[%2] : !hw.array<8192xi64>, i13
%31 = comb.extract %30 from 32 : (i64) -> i32
%32 = comb.extract %30 from 0 : (i64) -> i24
%33 = comb.concat %31, %29, %32 : i32, i8, i24
%34 = hw.array_inject %26[%2], %33 : !hw.array<8192xi64>, i13
%35 = comb.mux %28, %34, %26 : !hw.array<8192xi64>
%36 = comb.extract %RW0_wmask from 4 : (i8) -> i1
%37 = comb.and %RW0_en, %36, %RW0_wmode : i1
%38 = comb.extract %RW0_wdata from 32 : (i64) -> i8
%39 = hw.array_get %35[%2] : !hw.array<8192xi64>, i13
%40 = comb.extract %39 from 40 : (i64) -> i24
%41 = comb.extract %39 from 0 : (i64) -> i32
%42 = comb.concat %40, %38, %41 : i24, i8, i32
%43 = hw.array_inject %35[%2], %42 : !hw.array<8192xi64>, i13
%44 = comb.mux %37, %43, %35 : !hw.array<8192xi64>
%45 = comb.extract %RW0_wmask from 5 : (i8) -> i1
%46 = comb.and %RW0_en, %45, %RW0_wmode : i1
%47 = comb.extract %RW0_wdata from 40 : (i64) -> i8
%48 = hw.array_get %44[%2] : !hw.array<8192xi64>, i13
%49 = comb.extract %48 from 48 : (i64) -> i16
%50 = comb.extract %48 from 0 : (i64) -> i40
%51 = comb.concat %49, %47, %50 : i16, i8, i40
%52 = hw.array_inject %44[%2], %51 : !hw.array<8192xi64>, i13
%53 = comb.mux %46, %52, %44 : !hw.array<8192xi64>
%54 = comb.extract %RW0_wmask from 6 : (i8) -> i1
%55 = comb.and %RW0_en, %54, %RW0_wmode : i1
%56 = comb.extract %RW0_wdata from 48 : (i64) -> i8
%57 = hw.array_get %53[%2] : !hw.array<8192xi64>, i13
%58 = comb.extract %57 from 56 : (i64) -> i8
%59 = comb.extract %57 from 0 : (i64) -> i48
%60 = comb.concat %58, %56, %59 : i8, i8, i48
%61 = hw.array_inject %53[%2], %60 : !hw.array<8192xi64>, i13
%62 = comb.mux %55, %61, %53 : !hw.array<8192xi64>
%63 = comb.extract %RW0_wmask from 7 : (i8) -> i1
%64 = comb.and %RW0_en, %63, %RW0_wmode : i1
%65 = comb.extract %RW0_wdata from 56 : (i64) -> i8
%66 = hw.array_get %62[%2] : !hw.array<8192xi64>, i13
%67 = comb.extract %66 from 0 : (i64) -> i56
%68 = comb.concat %65, %67 : i8, i56
%69 = hw.array_inject %62[%2], %68 : !hw.array<8192xi64>, i13
%70 = comb.mux %64, %69, %62 : !hw.array<8192xi64>
%71 = comb.or %64, %55, %46, %37, %28, %19, %10, %1 : i1
%72 = seq.to_clock %RW0_clk
%_RW0_raddr_d0 = seq.firreg %RW0_addr clock %72 : i13
%_RW0_ren_d0 = seq.firreg %RW0_en clock %72 : i1
%_RW0_rmode_d0 = seq.firreg %RW0_wmode clock %72 : i1
%73 = comb.mux bin %71, %70, %Memory : !hw.array<8192xi64>
%Memory = seq.firreg %73 clock %72 : !hw.array<8192xi64>
%74 = comb.xor %_RW0_rmode_d0, %true : i1
%75 = comb.and %_RW0_ren_d0, %74 : i1
%76 = comb.sub %c-1_i13, %_RW0_raddr_d0 : i13
%77 = hw.array_get %Memory[%76] : !hw.array<8192xi64>, i13
%78 = comb.mux %75, %77, %c0_i64 : i64
hw.output %78 : i64
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.