SRAM & Memory Design

Memories fill most of a modern SoC's area. Learn the 6T SRAM cell, read and write operations, read stability and writability (cell ratio, pull-up ratio), static noise margin, array organisation (rows, columns, decoders, sense amplifiers), bitline timing, memory compilers, register files, DRAM and non-volatile memories, and how RTL infers memories.

An SRAM bit is two cross-coupled inverters (storing Q and Q̄) plus two access transistors connecting it to a pair of bitlines when its wordline is raised: six transistors per bit. It is fast and uses the standard logic process, which is why caches and on-chip buffers are SRAM.

Designing SRAM is a balancing act: the cell must be strong enough not to flip during a read, yet weak enough to be overwritten during a write — while being as small as the process allows, because there are billions of them.

An analogy

An SRAM cell is a light switch held in place by two springs (the cross-coupled inverters). Reading is peeking at the switch without bumping it; writing is pushing hard enough to flip it. The access transistors are the door you open to peek or push.

The 6T cell

Two inverters in a loop hold a value indefinitely while powered. Two NMOS access transistors, gated by the wordline, connect the storage nodes to bitlines BL and BLB. Many cells share each bitline (a column) and each wordline (a row).

Read and write

Read: precharge both bitlines to VDD, raise the wordline; the side storing 0 slowly discharges its bitline; a sense amplifier detects the small difference. Write: drive one bitline to 0 and raise the wordline; the access transistor overpowers the cell's pull-up and flips it. Sizing ratios make both operations reliable across process variation.

Array organisation

A memory macro is more than cells:

Variation, assist circuits and other memories

At advanced nodes random V_t variation threatens stability, so SRAMs add read/write assists (wordline under-drive, negative bitline), use 8T cells with separate read ports, or separate voltage rails. Register files use multi-port cells; DRAM stores charge on a capacitor (1T1C, dense but needs refresh); Flash, MRAM and ReRAM are non-volatile. Memory BIST tests every cell at production.

Formulas

Worked example: Capacity

Given: 12 address bits, 32-bit words

Find: Capacity.

Answer: 131 072 bits = 16 KiB

Worked example: Bitline time

Given: 256 rows, 0.5 fF/cell, 50 fF wire, 40 µA, ΔV = 100 mV

Find: Swing time.

Answer: ≈ 0.445 ns

Worked example: Cell ratio

Given: Pull-down W/L = 2, access W/L = 1.2

Find: β and read stability.

Answer: β ≈ 1.67 — within the typical stable range

Synchronous single-port RAM that tools map to an SRAM macro

// Synchronous single-port RAM (behavioural model that synthesis maps to
// an SRAM macro / block RAM). One read or write per clock.
module sp_ram #(
    parameter AW = 8,            // address width -> 2**AW words
    parameter DW = 32            // word width
) (
    input  wire          clk,
    input  wire          we,     // write enable
    input  wire [AW-1:0] addr,
    input  wire [DW-1:0] wdata,
    output reg  [DW-1:0] rdata
);
    reg [DW-1:0] mem [0:(1<<AW)-1];
    always @(posedge clk) begin
        if (we) mem[addr] <= wdata;
        rdata <= mem[addr];      // read-first behaviour
    end
endmodule

A registered read port is what lets synthesis recognise a memory (Yosys infers a single $mem cell here). In ASIC flows this behavioural model is replaced by a memory-compiler macro with the same ports.

Bitline timing estimate

# SRAM read: time for the cell to develop a sense-amp swing on the bitline
rows = 256
c_cell, c_wire = 0.5e-15, 50e-15      # F per attached cell, F of wire
I_cell = 40e-6                        # read current, A
dV = 0.1                              # required bitline swing, V

C_bl = rows * c_cell + c_wire
t = C_bl * dV / I_cell
print(f"bitline C = {C_bl*1e15:.0f} fF, swing time = {t*1e9:.3f} ns")

for rows in (128, 512):
    C_bl = rows * c_cell + c_wire
    print(f"{rows} rows/bitline -> {C_bl*dV/I_cell*1e9:.3f} ns")
# bitline C = 178 fF, swing time = 0.445 ns
# 128 rows/bitline -> 0.285 ns
# 512 rows/bitline -> 0.765 ns

A tiny cell current must discharge the whole bitline; taller arrays are slower. That is why arrays are split into banks and why sense amplifiers detect ~100 mV instead of waiting for a full swing.

Common mistakes

Applications

Key takeaways

Going further