Skip to content
code0.HDL

14Implementation

Flag read data from a SyncReadMem

Problem

Intended behavior. Scratchpad stores sixteen bytes in a SyncReadMem. A client requests a word by raising ren with an address on raddr. The module must raise rvalid in the cycle where rdata holds that word, so the client can take rdata whenever rvalid is high without knowing the memory's timing. rvalid is low in the first cycle after reset, whatever was requested while reset was held.

Current state. The memory and its read port are complete. The TODO line sets rvalid equal to ren, as if the memory answered in the cycle of the request.

Your task. Replace the TODO assignment so rvalid matches the memory's read latency. Keep the memory, the ports, and the testbench unchanged.

Read and predict

The testbench writes 11, 22, 33, 44 into addresses 0 to 3, then issues six read cycles. It prints rdata only when rvalid is high, as a real client would. The requests are: read 2, idle, read 0, read 3, idle, idle.

Run the starter first. Its rdata column claims to answer each request in the same cycle. Check the printed words against the addresses: which lines show a word that belongs to an earlier request, or to no request at all?

Do not rely on a particular value when no read was enabled at the preceding edge: SyncReadMem leaves that read data undefined.

Then predict the corrected trace. The value for address 2 should appear one line after the request, and the two back-to-back requests should produce two consecutive valid lines with 11 and then 44.

Find the rule

A SyncReadMem read captures the address at the clock edge and returns data in the next cycle. The valid flag has to make the same journey: it must describe the request that was made one cycle earlier, not the current one.

Run and explain

Run your change and compare it with the corrected trace you predicted. Every valid line must show the word stored at the address requested on the line above it. Explain why the line for cycle 1 is valid even though ren is 0 in that cycle.

Completion check

  • rvalid is high exactly one cycle after each cycle with ren high, and low otherwise, including through idle gaps and back-to-back reads.
  • Whenever rvalid is high, rdata is the word stored at the address requested one cycle earlier.
  • rvalid is low in the first cycle after reset, even if ren was high while reset was held.
  • Writes to other addresses in the same cycle do not disturb the flag.

Hints

Hint 1

Count the edges between a request and its data. The flag needs the same number of edges.

Hint 2

Delay ren by one cycle with a register, and give that register a reset value so the flag is defined right after reset.

Concept

Synchronous-read memories return data one cycle after the request, so any signal that describes that data has to be pipelined alongside it. A valid bit is control state and needs a reset value. The memory contents, by contrast, need none.

Write a location before reading it; resetting the valid flag does not initialize the stored bytes. Simultaneous reads and writes to the same address have undefined read data and are outside this exercise's data guarantee.

Variation

Replace the SyncReadMem with a Mem while keeping your rvalid. Predict the rdata column on the valid lines, and decide what else would have to change for the client to see the correct words again.

Review this concept
Ready

CheerpJ runs Chisel in your browser. A cold Run downloads about 14.5 MB of Java and 47 MB of JARs. Compilation can take a minute. Licenses

Main.scala