Where a ROM shows up
Chips are full of small fixed lookup tables that never change after synthesis: opcode-to-microcode decode tables, sine/cosine coefficient tables for a DSP core, gamma-correction curves in a display pipeline, or a tiny boot ROM holding a first-stage bootloader. All of these have the same shape: an address goes in, a fixed value comes out, and the mapping is baked into the hardware (as opposed to a RAM’s contents, which are written at runtime).
Interface
| Signal | Direction | Width | Description |
|---|---|---|---|
clk |
input | 1 | Clock. |
addr |
input | AW |
Address to look up. |
data |
output | DW |
Registered lookup-table value for addr, one cycle later. |
Timing
| Cycle | addr |
data (this cycle) |
|---|---|---|
| 0 | 0x4 |
(previous value) |
| 1 | 0x8 |
0x10 (table[0x4]) |
| 2 | 0x0 |
0xFF (table[0x8]) |
| 3 | — | 0x00 (table[0x0]) |
This mirrors how a real synchronous block-ROM behaves: addr is combinational into the lookup, but the output is registered, giving one cycle of latency — the same shape as a block-RAM read port, just without a write side.
Correctness constraints
- Every entry in the table must be reproduced exactly; this is a fixed content ROM, not a RAM — there is no write port at all.
datamust reflectaddrfrom one cycle earlier (registered output), not the current cycle’saddrcombinationally.- Reading the same address multiple times must always return the same value (a genuine read-only table has no hidden state beyond the address-to-data mapping).
- Any address not explicitly listed in the table (if
AWallows more addresses than entries are defined) should return a well-defined default rather thanx.