@@ -60,7 +60,7 @@ def get(obj, platform):
60
60
lineno = code .co_firstlineno )
61
61
obj = new_obj
62
62
63
- def __init__ (self ):
63
+ def __init__ (self , * , src_loc = None ):
64
64
self .ports = _ast .SignalDict ()
65
65
self .drivers = OrderedDict ()
66
66
self .statements = {}
@@ -69,6 +69,7 @@ def __init__(self):
69
69
self .attrs = OrderedDict ()
70
70
self .generated = OrderedDict ()
71
71
self .flatten = False
72
+ self .src_loc = src_loc
72
73
73
74
def add_ports (self , * ports , dir ):
74
75
assert dir in ("i" , "o" , "io" )
@@ -132,18 +133,18 @@ def add_statements(self, domain, *stmts):
132
133
stmt ._MustUse__used = True
133
134
self .statements .setdefault (domain , _ast ._StatementList ()).append (stmt )
134
135
135
- def add_subfragment (self , subfragment , name = None ):
136
+ def add_subfragment (self , subfragment , name = None , * , src_loc = None ):
136
137
assert isinstance (subfragment , Fragment )
137
- self .subfragments .append ((subfragment , name ))
138
+ self .subfragments .append ((subfragment , name , src_loc ))
138
139
139
140
def find_subfragment (self , name_or_index ):
140
141
if isinstance (name_or_index , int ):
141
142
if name_or_index < len (self .subfragments ):
142
- subfragment , name = self .subfragments [name_or_index ]
143
+ subfragment , name , src_loc = self .subfragments [name_or_index ]
143
144
return subfragment
144
145
raise NameError (f"No subfragment at index #{ name_or_index } " )
145
146
else :
146
- for subfragment , name in self .subfragments :
147
+ for subfragment , name , src_loc in self .subfragments :
147
148
if name == name_or_index :
148
149
return subfragment
149
150
raise NameError (f"No subfragment with name '{ name_or_index } '" )
@@ -172,7 +173,7 @@ def _merge_subfragment(self, subfragment):
172
173
173
174
# Remove the merged subfragment.
174
175
found = False
175
- for i , (check_subfrag , check_name ) in enumerate (self .subfragments ): # :nobr:
176
+ for i , (check_subfrag , check_name , check_src_loc ) in enumerate (self .subfragments ): # :nobr:
176
177
if subfragment == check_subfrag :
177
178
del self .subfragments [i ]
178
179
found = True
@@ -204,7 +205,7 @@ def add_subfrag(registry, entity, entry):
204
205
add_subfrag (driver_subfrags , signal , (None , hierarchy ))
205
206
206
207
flatten_subfrags = set ()
207
- for i , (subfrag , name ) in enumerate (self .subfragments ):
208
+ for i , (subfrag , name , src_loc ) in enumerate (self .subfragments ):
208
209
if name is None :
209
210
name = f"<unnamed #{ i } >"
210
211
subfrag_hierarchy = hierarchy + (name ,)
@@ -270,7 +271,7 @@ def _propagate_domains_up(self, hierarchy=("top",)):
270
271
domain_subfrags = defaultdict (set )
271
272
272
273
# For each domain defined by a subfragment, determine which subfragments define it.
273
- for i , (subfrag , name ) in enumerate (self .subfragments ):
274
+ for i , (subfrag , name , src_loc ) in enumerate (self .subfragments ):
274
275
# First, recurse into subfragments and let them propagate domains up as well.
275
276
hier_name = name
276
277
if hier_name is None :
@@ -281,45 +282,45 @@ def _propagate_domains_up(self, hierarchy=("top",)):
281
282
for domain_name , domain in subfrag .domains .items ():
282
283
if domain .local :
283
284
continue
284
- domain_subfrags [domain_name ].add ((subfrag , name , i ))
285
+ domain_subfrags [domain_name ].add ((subfrag , name , src_loc , i ))
285
286
286
287
# For each domain defined by more than one subfragment, rename the domain in each
287
288
# of the subfragments such that they no longer conflict.
288
289
for domain_name , subfrags in domain_subfrags .items ():
289
290
if len (subfrags ) == 1 :
290
291
continue
291
292
292
- names = [n for f , n , i in subfrags ]
293
+ names = [n for f , n , s , i in subfrags ]
293
294
if not all (names ):
294
295
names = sorted (f"<unnamed #{ i } >" if n is None else f"'{ n } '"
295
- for f , n , i in subfrags )
296
+ for f , n , s , i in subfrags )
296
297
raise _cd .DomainError (
297
298
"Domain '{}' is defined by subfragments {} of fragment '{}'; it is necessary "
298
299
"to either rename subfragment domains explicitly, or give names to subfragments"
299
300
.format (domain_name , ", " .join (names ), "." .join (hierarchy )))
300
301
301
302
if len (names ) != len (set (names )):
302
- names = sorted (f"#{ i } " for f , n , i in subfrags )
303
+ names = sorted (f"#{ i } " for f , n , s , i in subfrags )
303
304
raise _cd .DomainError (
304
305
"Domain '{}' is defined by subfragments {} of fragment '{}', some of which "
305
306
"have identical names; it is necessary to either rename subfragment domains "
306
307
"explicitly, or give distinct names to subfragments"
307
308
.format (domain_name , ", " .join (names ), "." .join (hierarchy )))
308
309
309
- for subfrag , name , i in subfrags :
310
+ for subfrag , name , src_loc , i in subfrags :
310
311
domain_name_map = {domain_name : f"{ name } _{ domain_name } " }
311
- self .subfragments [i ] = (DomainRenamer (domain_name_map )(subfrag ), name )
312
+ self .subfragments [i ] = (DomainRenamer (domain_name_map )(subfrag ), name , src_loc )
312
313
313
314
# Finally, collect the (now unique) subfragment domains, and merge them into our domains.
314
- for subfrag , name in self .subfragments :
315
+ for subfrag , name , src_loc in self .subfragments :
315
316
for domain_name , domain in subfrag .domains .items ():
316
317
if domain .local :
317
318
continue
318
319
self .add_domains (domain )
319
320
320
321
def _propagate_domains_down (self ):
321
322
# For each domain defined in this fragment, ensure it also exists in all subfragments.
322
- for subfrag , name in self .subfragments :
323
+ for subfrag , name , src_loc in self .subfragments :
323
324
for domain in self .iter_domains ():
324
325
if domain in subfrag .domains :
325
326
assert self .domains [domain ] is subfrag .domains [domain ]
@@ -403,7 +404,7 @@ def add_io(*sigs):
403
404
add_uses (cd .rst )
404
405
405
406
# Repeat for subfragments.
406
- for subfrag , name in self .subfragments :
407
+ for subfrag , name , src_loc in self .subfragments :
407
408
if isinstance (subfrag , Instance ):
408
409
for port_name , (value , dir ) in subfrag .named_ports .items ():
409
410
if dir == "i" :
@@ -627,7 +628,7 @@ def _assign_names_to_fragments(self, hierarchy=("top",), *, _names=None):
627
628
_names [self ] = hierarchy
628
629
629
630
signal_names = set (self ._assign_names_to_signals ().values ())
630
- for subfragment_index , (subfragment , subfragment_name ) in enumerate (self .subfragments ):
631
+ for subfragment_index , (subfragment , subfragment_name , subfragment_src_loc ) in enumerate (self .subfragments ):
631
632
if subfragment_name is None :
632
633
subfragment_name = f"U${ subfragment_index } "
633
634
elif subfragment_name in signal_names :
@@ -641,12 +642,11 @@ def _assign_names_to_fragments(self, hierarchy=("top",), *, _names=None):
641
642
642
643
class Instance (Fragment ):
643
644
def __init__ (self , type , * args , src_loc = None , src_loc_at = 0 , ** kwargs ):
644
- super ().__init__ ()
645
+ super ().__init__ (src_loc = src_loc or tracer . get_src_loc ( src_loc_at ) )
645
646
646
647
self .type = type
647
648
self .parameters = OrderedDict ()
648
649
self .named_ports = OrderedDict ()
649
- self .src_loc = src_loc or tracer .get_src_loc (src_loc_at )
650
650
651
651
for (kind , name , value ) in args :
652
652
if kind == "a" :
@@ -1064,7 +1064,7 @@ def emit_memory(self, module_idx: int, fragment: '_mem.MemoryInstance', name: st
1064
1064
init = fragment ._init ,
1065
1065
name = name ,
1066
1066
attributes = fragment ._attrs ,
1067
- src_loc = fragment ._src_loc ,
1067
+ src_loc = fragment .src_loc ,
1068
1068
)
1069
1069
return self .netlist .add_cell (cell )
1070
1070
@@ -1205,7 +1205,7 @@ def emit_drivers(self):
1205
1205
if net .is_late and net not in self .netlist .connections :
1206
1206
self .netlist .connections [net ] = _nir .Net .from_const ((signal .init >> bit ) & 1 )
1207
1207
1208
- def emit_fragment (self , fragment : _ir .Fragment , parent_module_idx : 'int | None' ):
1208
+ def emit_fragment (self , fragment : _ir .Fragment , parent_module_idx : 'int | None' , * , cell_src_loc = None ):
1209
1209
from . import _mem
1210
1210
1211
1211
fragment_name = self .fragment_names [fragment ]
@@ -1224,7 +1224,7 @@ def emit_fragment(self, fragment: _ir.Fragment, parent_module_idx: 'int | None')
1224
1224
for port in fragment ._read_ports :
1225
1225
self .emit_read_port (parent_module_idx , fragment , port , memory , write_ports )
1226
1226
elif type (fragment ) is _ir .Fragment :
1227
- module_idx = self .netlist .add_module (parent_module_idx , fragment_name )
1227
+ module_idx = self .netlist .add_module (parent_module_idx , fragment_name , src_loc = fragment . src_loc , cell_src_loc = cell_src_loc )
1228
1228
signal_names = fragment ._assign_names_to_signals ()
1229
1229
self .netlist .modules [module_idx ].signal_names = signal_names
1230
1230
if parent_module_idx is None :
@@ -1234,8 +1234,8 @@ def emit_fragment(self, fragment: _ir.Fragment, parent_module_idx: 'int | None')
1234
1234
for domain , stmts in fragment .statements .items ():
1235
1235
for stmt in stmts :
1236
1236
self .emit_stmt (module_idx , fragment , domain , stmt , _nir .Net .from_const (1 ))
1237
- for subfragment , _name in fragment .subfragments :
1238
- self .emit_fragment (subfragment , module_idx )
1237
+ for subfragment , _name , sub_src_loc in fragment .subfragments :
1238
+ self .emit_fragment (subfragment , module_idx , cell_src_loc = sub_src_loc )
1239
1239
if parent_module_idx is None :
1240
1240
self .emit_drivers ()
1241
1241
else :
0 commit comments