Altifigence Academy

7 / 24 · Concept

Timing contracts for memory requests and responses

Distinguish synchronous reads, delayed tags, and same-address collisions.

A memory is more than a large register array

A memory interface needs a timing contract as well as capacity. An asynchronous read changes combinational output when its address changes. A synchronous read samples an address at an edge and changes the output afterward. These models require different schedules. Inference into a device memory resource also depends on coding style and the target tool. Here we specify sixteen eight-bit entries with a synchronous read.

Sample address and tag at edge k. The corresponding data and delayed tag appear after that edge; their first consumption opportunity is edge k+1. A one-cycle read does not mean immediate combinational response. Response valid must follow the same delay. Combining a delayed value with the current input tag breaks successive requests.

SystemVerilog
logic [7:0] mem [0:15];
logic [7:0] rd_data;
logic [3:0] rd_tag;
logic rd_valid;
always_ff @(posedge clk) begin
  if (wr_en) mem[wr_addr] <= wr_data;
  rd_valid <= req_valid;
  if (req_valid) begin
    rd_data <= mem[req_addr];
    rd_tag <= req_tag;
  end
  if (rst) rd_valid <= 1'b0;
end

For this behavioral model, simultaneous reading and writing of one address returns the old value because nonblocking assignments read old state. Actual memory primitives have explicit collision modes and restrictions; see AMD UG901's read/write modes and verify the intended mode against the target and synthesis result. Resetting valid does not initialize the array.

EdgeAccepted requestEffect
2addr=3,tag=7Capture old mem[3]=42
3addr=4,tag=8Consume 42,7 and capture the next value
4No requestClear response valid

This schedule assumes the consumer never stalls. If it stalls at edge 3, the next response can overwrite rd_data. Add response storage or limit requests using available capacity, including responses already in flight. Initialize test memory explicitly before checking values. Verify address and tag correspondence, not only response data; a correct value attached to the wrong request is still a failure.

Try it yourself

With mem[3]=42, read address 3 and write 99 to it at the same edge. What does this model put in rd_data, and what is the new memory value? What is needed for output stalls?

Read the explanation

rd_data becomes 42, while mem[3] becomes 99. Both assignments read old state. Stalls require response storage and admission control that counts in-flight responses. Verify the actual target memory's collision mode separately.

Your choice applies to this browser. Change it any time using the footer.