Forum Discussion
Trying to understand on-chip memory
- 1 year ago
You should declare the output q as a wire, because the ROM module already registers the output internally.
You do not need to add your own always @(posedge clk) just to capture q, unless you want to add pipeline stages or synchronize it further.
The altsyncram component is configured with:
altsyncram_component.outdata_reg_a = "CLOCK0"
This means the output is registered on the rising edge of clock0 inside the IP — so the ROM fetches data synchronously, with output changes one clock cycle after the address is applied.
So even though q is declared as a wire, it is driven by a register inside the ROM IP. That’s why your code can simply declare:
wire [7:0] q;
rom rom_inst (
.address (address),
.clock (clock),
.q (q)
);And it should works exactly as a synchronous ROM should.
So yes — you're absolutely right: you cannot use q on the same clock edge that you apply the address. You need to wait one clock cycle.
Regards,
Richard Tan
Hi,
small correction to above description.
Internal block RAM doesn't necessarily register RAM/ROM output. It always registers memory address, write data and related control signals, output register is optional and controlled by parameter outdata_reg_a/b which can be UNREGISTERED, CLOCK0 or CLOCK1.
Respectively RAM/ROM output has either 1 or 2 clock cycles latency.
Using "wire" to connect memory output port q should work for both configurations.
Regards
Frank