Memory blocks refer to chunks of computer memory with a specified number of rows (words) and word width (bits per word row). We can compose larger memory blocks from smaller memory blocks.

For large memory blocks, density is important. This means that latches and flip-flops aren’t suitable (they’re huge!), and it’s better to just use a few transistors.

Low-level view

This memory cell uses SRAM to store each bit. Each row is a word. A line from the address decoder will drive the word line to give access to that row. Each cell drives a bit line which connects all cells in a column.

The write enable controls a tri-state buffer to drive data onto a bit line and into a cell during a write.

Composition

Smaller memory blocks can be combined to make larger memory blocks in a systematic way. We must make sure that our combination is consistent.

For example, say we want to build memory with:

  • One block
  • Two
  • Two

Then to compose the full block, we need to ensure we stack vertically/horizontally properly. We also need additional logic to account for splitting everything up. On the input side, write enable should be determined by the address bits (i.e., addr[15] for the 32k block, ~addr[15] for the bottom blocks; addr[14] for the first 16k block, ~addr[14] for the second). The data should also be split up if needed (i.e., data[15:8] for the 16k blocks, data[7:4] and data[3:0] for the ). At the output, we need logic to decide what should be output and to concatenate signals if necessary.