3
3
from collections .abc import MutableSequence
4
4
5
5
from ..hdl import MemoryData , MemoryInstance , Shape , ShapeCastable , Const
6
- from ..hdl ._mem import FrozenError
6
+ from ..hdl ._mem import FrozenMemory
7
7
from ..utils import ceil_log2
8
8
from .._utils import final
9
9
from .. import tracer
10
10
from . import wiring , data
11
11
12
12
13
- __all__ = ["Memory" , "ReadPort" , "WritePort" ]
13
+ __all__ = ["FrozenMemory" , " Memory" , "ReadPort" , "WritePort" ]
14
14
15
15
16
16
class Memory (wiring .Component ):
17
17
"""Addressable array of rows.
18
18
19
19
This :ref:`component <wiring>` is used to construct a memory array by first specifying its
20
- dimensions and initial contents using the :py:`shape`, :py:`depth`, and :py:`init` parameters,
21
- and then adding memory ports using the :meth:`read_port` and :meth:`write_port` methods.
22
- Because it is mutable, it should be created and used locally within
23
- the :ref:`elaborate <lang-elaboration>` method. It is an error to add ports to or change
24
- initial contents of a memory after it has been elaborated .
20
+ dimensions and initial contents using the :class:`~amaranth.hdl.MemoryData` object and
21
+ the :py:`data` parameter (or by providing :py:`shape`, :py:`depth`, and :py:`init` parameters
22
+ directly instead) and then adding memory ports using the :meth:`read_port` and
23
+ :meth:`write_port` methods. Because it is mutable, it should be created and used locally within
24
+ the :ref:`elaborate <lang-elaboration>` method .
25
25
26
- The :py:`init` parameter and assignment to the :py:`init` attribute have the same effect, with
27
- :class:`Memory.Init` converting elements of the iterable to match :py:`shape` and using
28
- a default value for rows that are not explicitly initialized.
26
+ Adding ports or changing initial contents of a :class:`Memory` is only possible until it is
27
+ elaborated; afterwards, attempting to do so will raise :class:`~amaranth.hdl.FrozenMemory`.
29
28
30
- .. warning::
31
-
32
- Uninitialized memories (including ASIC memories and some FPGA memories) are
33
- `not yet supported <https://github.com/amaranth-lang/amaranth/issues/270>`_, and
34
- the :py:`init` parameter must be always provided, if only as :py:`init=[]`.
29
+ Platform overrides
30
+ ------------------
31
+ Define the :py:`get_memory()` platform method to override the implementation of
32
+ :class:`Memory`, e.g. to instantiate library cells directly.
35
33
36
34
Parameters
37
35
----------
36
+ data : :class:`~amaranth.hdl.MemoryData`
37
+ Representation of memory geometry and contents.
38
38
shape : :ref:`shape-like <lang-shapelike>` object
39
39
Shape of each memory row.
40
40
depth : :class:`int`
41
41
Number of memory rows.
42
42
init : iterable of initial values
43
43
Initial values for memory rows.
44
-
45
- Platform overrides
46
- ------------------
47
- Define the :py:`get_memory()` platform method to override the implementation of
48
- :class:`Memory`, e.g. to instantiate library cells directly.
49
44
"""
50
45
51
- Init = MemoryData .Init
52
-
53
46
def __init__ (self , data = None , * , shape = None , depth = None , init = None , attrs = None , src_loc_at = 0 ):
54
47
if data is None :
55
48
if shape is None :
@@ -128,7 +121,7 @@ def read_port(self, *, domain="sync", transparent_for=(), src_loc_at=0):
128
121
:class:`ReadPort`
129
122
"""
130
123
if self ._frozen :
131
- raise FrozenError ("Cannot add a memory port to a memory that has already been elaborated" )
124
+ raise FrozenMemory ("Cannot add a memory port to a memory that has already been elaborated" )
132
125
signature = ReadPort .Signature (shape = self .shape , addr_width = ceil_log2 (self .depth ))
133
126
return ReadPort (signature , memory = self , domain = domain , transparent_for = transparent_for ,
134
127
src_loc_at = 1 + src_loc_at )
@@ -153,7 +146,7 @@ def write_port(self, *, domain="sync", granularity=None, src_loc_at=0):
153
146
:class:`WritePort`
154
147
"""
155
148
if self ._frozen :
156
- raise FrozenError ("Cannot add a memory port to a memory that has already been elaborated" )
149
+ raise FrozenMemory ("Cannot add a memory port to a memory that has already been elaborated" )
157
150
signature = WritePort .Signature (
158
151
shape = self .shape , addr_width = ceil_log2 (self .depth ), granularity = granularity )
159
152
return WritePort (signature , memory = self , domain = domain ,
@@ -195,6 +188,7 @@ def elaborate(self, platform):
195
188
return instance
196
189
197
190
191
+ @final
198
192
class ReadPort :
199
193
"""A read memory port.
200
194
@@ -318,6 +312,7 @@ def transparent_for(self):
318
312
return self ._transparent_for
319
313
320
314
315
+ @final
321
316
class WritePort :
322
317
"""A write memory port.
323
318
0 commit comments