Unpacked Array Memory Initialization
Digital signal processing pipelines and lookup tables often require on-chip memory blocks initialized to specific default patterns before normal operation begins. Using unpacked arrays ensures synthesis tools map the structure to dedicated block RAM rather than thousands of discrete flip-flops.
The module implements a 16 word deep memory where each word is 16 bits wide. During a reset condition, a procedural loop initializes the memory such that every address i contains the value i * 2. During normal operation, it acts as a standard synchronous single port RAM. When write enable is asserted, the input data is written to the specified address. The read data output always reflects the memory contents of the provided address from the previous clock cycle, demonstrating read before write behaviour.
Timing and reset rules: • Clock edge: posedge clk • Reset type: Synchronous • Reset polarity: Active low (rst_n) • On reset, all 16 memory locations are initialized synchronously in one clock cycle using a procedural loop. The rdata output is forced to 0. • Read operations are synchronous; rdata updates on the clock edge to reflect the value at addr. • Write operations are synchronous; when we is 1, wdata is written to addr on the clock edge. • Priority rules: If reading and writing to the same address simultaneously, rdata outputs the old memory value before the new write takes effect.
Cycle 1: rst_n=0, we=0, addr=0 → mem is initialized (mem[i] = i * 2), rdata=0 Cycle 2: rst_n=1, we=0, addr=3 → rdata=6 (reads mem[3]) Cycle 3: rst_n=1, we=1, addr=3, wdata=99 → rdata=6 (read before write behaviour), mem[3] updates to 99 Cycle 4: rst_n=1, we=0, addr=3 → rdata=99 (reads updated mem[3])
{ "signal": [
{ "name": "clk", "wave": "p......" },
{ "name": "rst_n", "wave": "01....." },
{ "name": "we", "wave": "0..10.." },
{ "name": "addr", "wave": "=.=....", "data": ["0", "3"] },
{ "name": "wdata", "wave": "x..=x.." , "data": ["99"] },
{},
{ "name": "rdata", "wave": "=.=.=.=", "data": ["0", "6", "6", "99"] }
], "head": { "text": "Memory initialization, read, and write sequence." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive edge triggered clock | | rst_n | input | 1 | Synchronous active low reset; initializes memory array and clears rdata | | we | input | 1 | Write enable; memory writes occur on posedge clk when we=1 | | addr | input | 4 | Memory address for both read and write operations | | wdata | input | 16 | Data to be written into memory | | rdata | output | 16 | Registered read data output; resets to 16'b0 |
Constraints
- You must declare the memory as an unpacked array:
logic [15:0] mem [0:15]; - You must use an integer and a
forloop inside your sequential block to initialize the memory during reset. - The memory must be exactly 16 words deep and 16 bits wide.
- Write operations must not corrupt the old data being read on the exact same clock edge (read before write).
- Both memory writes and
rdataupdates must occur strictly on the positive edge ofclk.
Topics
Solve this problem
Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.
This problem is part of Codiode Pro. The statement above is free to read.
The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.