All port and parameter names are subject to change, they have been chosen to be as descriptive as possible for demonstration purposes.
Unable to represent more than the most basic memory constructs. Removed.
Memory initialization. Unchanged. For any given \MEMID
:
- If no
$meminit
cells exist, or all$meminit
\DATA
ports are entirely undef, the memory is uninitialized (may map to any or no initialization mode in hardware) - If all non-undef bits in all
$meminit
\DATA
ports have the same value, the entire memory may be zero- or one-initilized, respectively. - In all other cases, arbitrary data initialization must be used.
Single read port with no associated write port. Synchronous or asynchronous; initializable and resettable output register for synchronous operation
Unchanged: \CLK
, \EN
, \ADDR
, \DATA
Added: \OUTREG_RESET
- resets the output register to the value given by \OUTREG_INIT
. If
const undef or 0, no outreg reset is required. Must be const undef or 0 when
\CLK_ENABLE == 0
.
Unchanged:
\MEMID
\ABITS
\WIDTH
\CLK_ENABLE
\CLK_POLARITY
Added:
\TRANSPARENCY_GROUP
: integer/string identifying the write ports this read port is transparent to. If a write port in the same transparency group writes to the same address as the read in the same cycle, the read port returns the newly written data. Otherwise, the old data is returned.\OUTREG_INIT
: Initial and reset value of the output register\OUTREG_RESET_CLK_ENABLE
: When non-zero, the output register is reset synchronously (\OUTREG_RESET @ \CLK
). Otherwise, the output register is reset asynchronously by an asserted\OUTREG_RESET
.
Removed:
\TRANSPARENT
: not flexible enough to support more complicated transparency relationships.
Single write port with no associated read port. Synchronous or asynchronous.
Unchanged: \CLK
, \EN
(bit enable), \ADDR
, \DATA
Unchanged:
\MEMID
\ABITS
\WIDTH
\CLK_ENABLE
\CLK_POLARITY
\PRIORITY
Added:
\TRANSPARENCY_GROUP
: see$memrd
Combined read + write port, supports transparency. Synchronous or asynchronous.
\CLK
: shared clock\ADDR
: shared read and write address\READ_EN
: read enable\READ_DATA
: read data\OUTREG_RESET
: read output register reset\WRITE_EN
:\WIDTH
-bit write enable\WRITE_DATA
: write data
Shared:
\MEMID
\ABITS
\WIDTH
\CLK_POLARITY
Read (see $memrd
for explanations):
\READ_CLK_ENABLE
\OUTREG_INIT
\OUTREG_RESET_CLK_ENABLE
\READ_TRANSPARENCY_GROUP
Write (see $memwr
for explanations):
\WRITE_CLK_ENABLE
\PRIORITY
\WRITE_TRANSPARENCY_GROUP
Different ports should be able to access the same underlying memory using different word widths. The only way to easily achieve this in hardware is if all data widths are power- of-two multiples of each other, then addresses can be scaled easily simply by adding or removing bits.
The underlying RTLIL::Memory
defines a base word width and the number of base words
in the memory. This number of base words can be converted to a base address width using
the formula base address width = ceil(log2(number of base words))
.
For every memory port, the \WIDTH
parameter must be a power-of-two multiple of the
base word width, while the \ABITS
parameter must be log2(\WIDTH / base word width)
bits narrower than the base address width. Example:
base word width = 5 bits
number of base words = 1000
-> base address width = ceil(log2(1000)) = 10
$memrd:
\WIDTH = 5
\ABITS = 10
$memwr:
\WIDTH = 20
\ABITS = 10 - log2(20 / 5) = 8