Skip to content
seanhalle edited this page Mar 2, 2019 · 6 revisions

Memories in Chisel In chisel there are three different ways to specify a memory:

  1. Vector: Vec(DEPTH, Reg(Bits(width=WIDTH)))
  2. SeqMem(DEPTH, WIDTH)
  3. Mem(DEPTH, WIDTH) -- See Mem keyword in Chisel

-] The first — Chisel generates individual flip flops in verilog.

-] The second — Chisel generates verilog of this form “module XYZ: reg DEPTH:0 ram WIDTH:0” Then, we modify the verilog and insert a reference to a wrapper. We also write the wrapper, ties “module XYZ” to a specific file that was generated by the memory compiler. The backend take the wrapper and substitutes the memory layout in place of “module XYZ”

-] The third — Chisel generates verilog of the form “reg DEPTH:0 ram WIDTH:0” but this is also the form that is matched by backend tools and instantiated with a compiled SRAM. See [Mem in Chisel]

2- SeqMem

“SeqMem(DEPTH, WIDTH)” in Chisel, generates this verilog:

==== module XYZ( input CLK, input RST, input init, input 2:0 W0A, input W0E, input 73:0 W0I, input 2:0 R1A, input R1E, output 73:0 R1O );

reg 2:0 reg_R1A; reg 73:0 ram 7:0; ifndef SYNTHESIS ` `integer initvar; ` `initial begin ` `#0.002; ` `for (initvar = 0; initvar < 8; initvar = initvar+1) ` `raminitvar = {3 {$random}}; ` `reg_R1A = {1 {$random}}; ` `end ` endif integer i; always @(posedge CLK) begin if (R1E) reg_R1A <= R1A; for (i = 0; i < 74; i=i+1) begin if (W0E) ramW0Ai <= W0Ii; end end assign R1O = ramreg_R1A;`

endmodule

====

During simulation, the variable SYNTHESIS is not defined, so it simulates this as a collection of flip flops.

During synthesis, though, SYNTHESIS is defined, so the ifndef statement is false.. in that case, some magic happens that we haven’t quite figured out yet..

Somehow the synthesizer decides to use registers and generates registers to implement this.

However, if you modify the generated Verilog and insert a reference to a wrapper, and make the wrapper reference a specific name of a memory array that was generated by a compiler, then it will include the memory array.

The modified verilog file, which invokes a wrapper, looks like this:

====== module XYZ ( <SAME INTERFACE as above> ); assign wea_b = ~(|wea); SRAM2RW128x32 SRAM2RW128x32_0 ( .A1 (addra), .CE1 (clka), .WEB1 (wea_b), .OEB1 (), .CSB1 (wea_b), .I1 (dina0 +: 32), .O1 (), .A2 (addrb), .CE2 (clka), .WEB2 (enb), .OEB2 (~enb), .CSB2 (~enb), .I2 (), .O2 (doutb0 +: 32) ); SRAM2RW128x32 SRAM2RW128x32_1 ( .A1 (addra), .CE1 (clka), .WEB1 (wea_b), .OEB1 (), .CSB1 (wea_b), .I1 (dina32 +: 32), .O1 (), .A2 (addrb), .CE2 (clka), .WEB2 (enb), .OEB2 (~enb), .CSB2 (~enb), .I2 (), .O2 (doutb32 +: 32) ); endmodule

If we removed this file, which defines module XYZ, then the memory XYZ will be a hole. It will then not be considered in timing and area.

Clone this wiki locally