@@ -104,8 +104,6 @@ class Interface(Record):
104104 Address width. At most ``(2 ** addr_width) * data_width`` register bits will be available.
105105 data_width : int
106106 Data width. Registers are accessed in ``data_width`` sized chunks.
107- alignment : int
108- Register and window alignment. See :class:`MemoryMap`.
109107 name : str
110108 Name of the underlying record.
111109
@@ -132,7 +130,7 @@ class Interface(Record):
132130 nothing.
133131 """
134132
135- def __init__ (self , * , addr_width , data_width , alignment = 0 , name = None ):
133+ def __init__ (self , * , addr_width , data_width , name = None ):
136134 if not isinstance (addr_width , int ) or addr_width <= 0 :
137135 raise ValueError ("Address width must be a positive integer, not {!r}"
138136 .format (addr_width ))
@@ -141,8 +139,7 @@ def __init__(self, *, addr_width, data_width, alignment=0, name=None):
141139 .format (data_width ))
142140 self .addr_width = addr_width
143141 self .data_width = data_width
144- self .memory_map = MemoryMap (addr_width = addr_width , data_width = data_width ,
145- alignment = alignment )
142+ self ._map = None
146143
147144 super ().__init__ ([
148145 ("addr" , addr_width ),
@@ -152,6 +149,29 @@ def __init__(self, *, addr_width, data_width, alignment=0, name=None):
152149 ("w_stb" , 1 ),
153150 ], name = name , src_loc_at = 1 )
154151
152+ @property
153+ def memory_map (self ):
154+ if self ._map is None :
155+ raise NotImplementedError ("Bus interface {!r} does not have a memory map"
156+ .format (self ))
157+ return self ._map
158+
159+ @memory_map .setter
160+ def memory_map (self , memory_map ):
161+ if not isinstance (memory_map , MemoryMap ):
162+ raise TypeError ("Memory map must be an instance of MemoryMap, not {!r}"
163+ .format (memory_map ))
164+ if memory_map .addr_width != self .addr_width :
165+ raise ValueError ("Memory map has address width {}, which is not the same as "
166+ "bus interface address width {}"
167+ .format (memory_map .addr_width , self .addr_width ))
168+ if memory_map .data_width != self .data_width :
169+ raise ValueError ("Memory map has data width {}, which is not the same as "
170+ "bus interface data width {}"
171+ .format (memory_map .data_width , self .data_width ))
172+ memory_map .freeze ()
173+ self ._map = memory_map
174+
155175
156176class Multiplexer (Elaboratable ):
157177 """CSR register multiplexer.
@@ -201,9 +221,18 @@ class Multiplexer(Elaboratable):
201221 CSR bus providing access to registers.
202222 """
203223 def __init__ (self , * , addr_width , data_width , alignment = 0 ):
204- self .bus = Interface (addr_width = addr_width , data_width = data_width , alignment = alignment ,
205- name = "csr" )
206- self ._map = self .bus .memory_map
224+ self ._map = MemoryMap (addr_width = addr_width , data_width = data_width , alignment = alignment )
225+ self ._bus = None
226+
227+ @property
228+ def bus (self ):
229+ if self ._bus is None :
230+ self ._map .freeze ()
231+ self ._bus = Interface (addr_width = self ._map .addr_width ,
232+ data_width = self ._map .data_width ,
233+ name = "csr" )
234+ self ._bus .memory_map = self ._map
235+ return self ._bus
207236
208237 def align_to (self , alignment ):
209238 """Align the implicit address of the next register.
@@ -212,7 +241,7 @@ def align_to(self, alignment):
212241 """
213242 return self ._map .align_to (alignment )
214243
215- def add (self , element , * , addr = None , alignment = None ):
244+ def add (self , element , * , addr = None , alignment = None , extend = False ):
216245 """Add a register.
217246
218247 See :meth:`MemoryMap.add_resource` for details.
@@ -221,8 +250,9 @@ def add(self, element, *, addr=None, alignment=None):
221250 raise TypeError ("Element must be an instance of csr.Element, not {!r}"
222251 .format (element ))
223252
224- size = (element .width + self .bus .data_width - 1 ) // self .bus .data_width
225- return self ._map .add_resource (element , size = size , addr = addr , alignment = alignment )
253+ size = (element .width + self ._map .data_width - 1 ) // self ._map .data_width
254+ return self ._map .add_resource (element , size = size , addr = addr , alignment = alignment ,
255+ extend = extend )
226256
227257 def elaborate (self , platform ):
228258 m = Module ()
@@ -306,32 +336,41 @@ class Decoder(Elaboratable):
306336 CSR bus providing access to subordinate buses.
307337 """
308338 def __init__ (self , * , addr_width , data_width , alignment = 0 ):
309- self .bus = Interface (addr_width = addr_width , data_width = data_width , alignment = alignment ,
310- name = "csr" )
311- self ._map = self .bus .memory_map
339+ self ._map = MemoryMap (addr_width = addr_width , data_width = data_width , alignment = alignment )
340+ self ._bus = None
312341 self ._subs = dict ()
313342
343+ @property
344+ def bus (self ):
345+ if self ._bus is None :
346+ self ._map .freeze ()
347+ self ._bus = Interface (addr_width = self ._map .addr_width ,
348+ data_width = self ._map .data_width ,
349+ name = "csr" )
350+ self ._bus .memory_map = self ._map
351+ return self ._bus
352+
314353 def align_to (self , alignment ):
315354 """Align the implicit address of the next window.
316355
317356 See :meth:`MemoryMap.align_to` for details.
318357 """
319358 return self ._map .align_to (alignment )
320359
321- def add (self , sub_bus , * , addr = None ):
360+ def add (self , sub_bus , * , addr = None , extend = False ):
322361 """Add a window to a subordinate bus.
323362
324363 See :meth:`MemoryMap.add_resource` for details.
325364 """
326365 if not isinstance (sub_bus , Interface ):
327366 raise TypeError ("Subordinate bus must be an instance of csr.Interface, not {!r}"
328367 .format (sub_bus ))
329- if sub_bus .data_width != self .bus .data_width :
368+ if sub_bus .data_width != self ._map .data_width :
330369 raise ValueError ("Subordinate bus has data width {}, which is not the same as "
331370 "decoder data width {}"
332- .format (sub_bus .data_width , self .bus .data_width ))
371+ .format (sub_bus .data_width , self ._map .data_width ))
333372 self ._subs [sub_bus .memory_map ] = sub_bus
334- return self ._map .add_window (sub_bus .memory_map , addr = addr )
373+ return self ._map .add_window (sub_bus .memory_map , addr = addr , extend = extend )
335374
336375 def elaborate (self , platform ):
337376 m = Module ()
0 commit comments