Skip to main content

Module psram

Module psram 

Source
Expand description

The off-chip memory edge for a QSPI PSRAM — the block behind the memory-edge descriptor contract when the far side is a pseudo-SRAM instead of a DRAM.

The part is data (PsramPart, its numbers quoted from the datasheet). A transfer descriptor is split at compile time into bursts the part can legally take (plan_stream): a burst never crosses a page, because the part wraps inside a page, and never holds CE# low past tCEM, because the part refreshes itself only while deselected. check_legal re-checks a plan independently. The controller (emit_psram_edge_verilog) runs the power-up sequence the part requires (tPU, Reset-Enable + Reset, tRST, enter QPI) and then one QPI burst per request; the pin-level model (emit_psram_model_verilog) implements the part’s semantics and counts every timing and pin rule a host breaks, so a co-simulation reports violations rather than assuming there are none.

Structs§

EdgeOverrides
Controller parameters a test may override, to drive the part out of its rules on purpose.
PsramBurst
One burst: words consecutive 64-bit words from word address word_addr, one CE# low.
PsramCache
The heap cache in front of the edge: direct-mapped, write-back and write-allocate, 2^index_bits lines of 2^offset_bits words, each line filled and written back as one burst.
PsramEdge
The edge: a part, the system clock that drives the controller, and the number of system cycles per SCLK half-period. The controller counts cycles, so the rules that set a minimum time — tPU, tRST, tCPH, tCLK, tACLK — are met for every clock no faster than sys_period_ps, while tCEM, which caps how long a burst may hold CE# low, must hold at the slowest clock the edge is run at, slowest_period_ps.
PsramPart
A QSPI PSRAM, as its datasheet specifies it. Times in picoseconds.

Enums§

PsramUnplaceable
Why an edge or a plan cannot be built for a part.

Constants§

APS6404L_3SQN
AP Memory APS6404L-3SQN: 64 Mb (8M x 8) QSPI PSRAM, 3.3 V package, standard temperature grade.
EDGE_WORD_ADDR_BITS
Width of the edge’s word address (req_addr): the 24-bit QPI byte address of an 8 MiB part, less the three bits inside a word.

Functions§

check_legal
Every rule a burst plan must satisfy, checked independently of the planner.
emit_psram_arbiter_testbench
A randomized testbench for caches sharing the edge through the arbiter: n caches, each over its own region of the part, driven by one engine-shaped driver that issues to any subset of them in the same cycle — a read, a write, or a write and a read each — and nothing while any is busy. Prints MULTI-ERRORS, PSRAM-VIOLATIONS, the longest stall as MULTI-MAX-STALL, then MULTI-DONE.
emit_psram_arbiter_verilog
Several caches share one edge. When the edge is idle the lowest-numbered requester is granted and its request goes to the edge; that cache owns the edge until the burst completes and sees c_ready exactly once more when it does, in a cycle in which no other cache is granted. The edge’s write-data takes and read strobes go to every cache: only the owner is ever in a burst state, the only states that listen.
emit_psram_cache_hit_function
The engine-side lookup of a cache’s registered hits: {inst}_hit(a), the hit of address a in the cache instance inst’s lines as they will hold after this edge — none after a reset, and a fill completing now holding the line it fills — read from the instance’s exported {inst}_tags, {inst}_vals, {inst}_filled, {inst}_fidx and {inst}_ftag. Registering {inst}_hit(a) beside an address a the engine sets, and {inst}_hit of the held address every other cycle, gives the cache exactly the hit it would have looked up itself, a cycle earlier.
emit_psram_cache_hit_wires
The wires a cache instance inst exports to its engine-side lookup (emit_psram_cache_hit_function), declared.
emit_psram_cache_testbench
A randomized testbench for the cache: an engine-shaped driver that issues nothing while busy and otherwise a read (then waits a cycle and checks rd against a reference memory), a write of one or both halves of a word, or a write and a read together. Once the edge has initialized the part it writes every word it will use — words consecutive from 0 and words scattered over the whole part — then runs ops random operations. Prints CACHE-ERRORS, PSRAM-VIOLATIONS, the longest busy run as CACHE-MAX-STALL, the rising edge after reset at which req_ready was first seen as EDGE-READY-AT, then CACHE-DONE. The clock runs at run_period_ps, anywhere in the edge’s range.
emit_psram_cache_verilog
The cache. Its engine side is a registered-read memory port: ra holds the read address and rd is data[ra] one cycle later, refreshed every cycle, so a resident line reads exactly as a block RAM does; req_r/req_w pulse the cycle after the engine issues a read or a write, whose address, data and half-word enables wm hold until its next one. busy is high while a miss is served — a dirty victim written back, then the line filled, with a write miss merging its enabled halves into the fill — and while a read issued together with a write waits for it.
emit_psram_edge_testbench
A testbench: the controller and the model, the bursts issued in order (write data taken from wdata in order), every word read printed as RD <hex>, every burst’s cycles from acceptance to the next req_ready as BURST <n>, then the model’s total and PSRAM-DONE.
emit_psram_edge_verilog
The controller. One request is one burst: req_len words at word address req_addr. A write takes wdata at the start of each word (pulsing wdata_take); a read returns each word on rdata with a one-cycle rdata_valid. req_ready is high whenever a request can be taken.
emit_psram_model_verilog
A pin-level model of the part: its semantics (SPI until Enter-QPI, Reset-Enable + Reset before use, bursts wrapping inside a page) and every rule it checks — the timing rules, an SIO bit the part samples that nobody drives (float), and a host driving against the part’s read data (contend) — each counted by name on a PSRAM-VIOLATION <rule> line. violations holds the total.
plan_stream
Split a stream of 8-byte words into bursts the part can take: at every page boundary and at the longest burst tCEM allows. A strided stream is one burst per word.
psram_cache_hit_ports
The port connections of a cache instance inst whose engine registers its hits in rhit and whit.