Skip to main content

Module ram

Module ram 

Source
Expand description

The engine’s memories as the FPGA’s block RAM holds them.

logos_ram_w<W> #(D, A) is a simple dual-port memory of D words of W bits: its read port latches the address on the clock’s falling edge and holds the word until the next falling edge; its write port writes on the rising edge under a byte mask. Between two rising edges a read sees the memory as the last rising edge left it, at an address the registers that edge set, which is what a combinational read of a register array sees within the cycle. So a unit’s state machine keeps its reads where they are while the memory maps onto M20K blocks, the address given half a cycle and the data half a cycle.

logos_bram_w<W> #(D, A) is the same memory with the block RAM’s registered read: the address taken on a rising edge and its word out from that edge until the next, a read of the address the same edge writes returning the word before the write. The streaming engine, clocked at the memory interface’s rate, gives each read address a clock ahead.

logos_bram_re_w<W> #(D, A) takes its read address only on a rising edge where re is high and holds the word it read until the next such edge: the hybrid engine’s token-row store, clocked by the fast clock, read at the engine clock’s falling edges while the engine owns it.

Each width is its own module whose write names every byte lane in its own statement, the form the synthesis tools map to a block RAM’s byte enables. A registered or held memory (logos_bram_w<W>, logos_bram_re_w<W>) of 40 bits or wider, more than one layer of 512 words deep in a number of layers that is no power of two, is stacks of powers of two layers, its deepest its own and the rest <name>_parts beside it, so no stack is built past the memory’s depth.

Every memory asks for the block RAM its depth fills (LOGOS_RAMSTYLE, RAMSTYLE): MLABs to MLAB_WORDS words, M20K blocks beyond.

Constants§

DELAY_M20K_LEAST
The width from which logos_delay’s ring deeper than an MLAB asks for M20K blocks, a block’s widest word; a narrower ring asks for MLABs, a block holding it in a fortieth of its bits or less.
DELAY_RING_LEAST
The depth from which logos_delay keeps its words in block RAM: a chain of one or two registers is cheaper than a block, and from three clocks on a chain is three or more flip-flops a bit, which Quartus Prime Pro builds as written.
MLAB_WORDS
The deepest memory kept in MLABs: an MLAB’s depth. A memory this shallow asking for nothing is built by Quartus Prime Pro in an M20K block for every forty bits of its width, a sixteenth of the block’s depth or less filled (hybrid9c2: 5,142 blocks, 44% of the device’s, on 2.2 Mbit, and a fit that failed routing with each column core spread over its 214 blocks). From two words on an MLAB holds a wide memory in fewer ALMs than its flip-flops do (hybrid9d: a column core’s ring of two 5,280-bit beats in registers, 169k across the array, left synthesis at 88% of the device’s ALMs); Quartus keeps a memory too small for one in registers itself.
RAMSTYLE
LOGOS_RAMSTYLE(words): the ramstyle attribute of a memory of words words (a constant expression of the module’s parameters) read into a register — MLABs to MLAB_WORDS words, M20K blocks beyond — and LOGOS_RAMSTYLE_ASYNC(words) the same for a memory read without a register after it (unregistered, or at a registered address, so seeing a word the clock it is written), its MLABs asking for no read-during-write check: Quartus Prime Pro builds an MLAB’s read only through the MLAB’s output register otherwise, and builds such a memory in flip-flops (a probe’s 32 x 1,056-bit buffer: 33,797 registers). An engine’s build times an MLAB’s read of a word in the clock after its write (logos_settings.tcl, super::super::ofs), so the word read is the one written, as the RTL reads it. Defined once in whichever text names it first, so every unit’s text carries it.
STORE_GROUP
Layers of a pipelined store whose words one register of its first gathering takes.
STORE_READ_LATENCY
Clocks the pipelined token-row store (logos_store_w512, store_verilog) takes from a read’s address to its word: the ports registered, the layer read, the layers’ words gathered a group at a time, and the groups’ into the word.

Functions§

bram_name
The module name of the memory w bits wide whose read is registered on the rising edge.
bram_re_name
The module name of the memory w bits wide whose read is registered on the rising edges re is high on.
bram_re_verilog
The memory modules for the widths widths whose read is registered on the rising edges re is high on, the word held between them.
bram_verilog
The registered-read memory modules for the widths widths (each a whole number of bytes).
delay_verilog
logos_delay #(W, D), a word of W bits delayed D clocks (the word itself at depth 0). One or two clocks are a chain of registers. From DELAY_RING_LEAST clocks on the words go round a ring, a memory of the next power of two of D words written a word a clock and read D - 1 words behind the write into its port’s register, the chain’s D·W flip-flops left as the ring’s write address: logos_delay_mlab in MLABs to MLAB_WORDS words whatever its width, and beyond that logos_delay_m20k in M20K blocks from DELAY_M20K_LEAST bits wide and logos_delay_mlab below.
ram_ce_name
The module name of the memory w bits wide of an engine whose registers step on the rising edges ce is high on.
ram_ce_verilog
logos_ram_w<W> for an engine whose registers step on the rising edges ce is high on: the read registered on the edges cr is high on, the word held between them, the write on the edges ce is high on. With ce high the user clock’s cycle that ends with an engine step and cr high the cycle after the engine cycle’s middle, a read sees the memory as the step before left it, at an address the registers that step set, as the falling-edge read does.
ram_name
The module name of the memory w bits wide.
ram_verilog
The memory modules for the widths widths (each a whole number of bytes), each asking for the block RAM its depth fills.
store_verilog
logos_store_w512 #(D, A): the token-row store’s bank as bram_re_verilog’s logos_bram_re_w512 holds it — its read taken on the edges re is high on and held between them, a write under a byte mask — its word out STORE_READ_LATENCY clocks after its address instead of one. Its words are layers of 512, each a block RAM of its own read every clock (logos_bram_w512_part), so the block takes its read register whole and reads the word before a write of its address in the same clock, as its port does; a layer read under the read enable would hand the block the address register instead and need pass-through logic in the fabric for its read-during-write. Every port is taken into registers a clock before the layers see it, each layer’s write enable decoded there, the read’s address and the write’s row, data and mask copied near the layers they reach (maxfan). Each layer’s word is zero unless the read was of it, and the words are gathered by an OR, STORE_GROUP layers at a time into registers, then across the groups into the word read, which alone is held between the clocks re is high on (the read enable carried beside the read). A write lands a clock after it is asked, as a read does, so each read sees the writes it would if neither waited: a reader that takes its word STORE_READ_LATENCY clocks after its address reads what it read a clock after its address from the bank of one.