1010from chipflow_lib .platforms import (
1111 PACKAGE_DEFINITIONS ,
1212 PIN_ANNOTATION_SCHEMA ,
13- top_interfaces ,
13+ top_components ,
1414 LockFile ,
1515 Package ,
1616 PortMap ,
2222logger = logging .getLogger (__name__ )
2323
2424
25- def count_member_pins (name : str , member : Dict [str , Any ]) -> int :
26- "Counts the pins from amaranth metadata"
27- logger .debug (
28- f"count_pins { name } { member ['type' ]} "
29- f"{ member ['annotations' ] if 'annotations' in member else 'no annotations' } "
30- )
31- if member ['type' ] == 'interface' and 'annotations' in member \
32- and PIN_ANNOTATION_SCHEMA in member ['annotations' ]:
33- return member ['annotations' ][PIN_ANNOTATION_SCHEMA ]['width' ]
34- elif member ['type' ] == 'interface' :
35- width = 0
36- for n , v in member ['members' ].items ():
37- width += count_member_pins ('_' .join ([name , n ]), v )
38- return width
39- elif member ['type' ] == 'port' :
40- return member ['width' ]
41-
42-
43- def allocate_pins (name : str , member : Dict [str , Any ], pins : List [str ], port_name : str = None ) -> Tuple [Dict [str , Port ], List [str ]]:
44- "Allocate pins based of Amaranth member metadata"
45-
46- if port_name is None :
47- port_name = name
48-
49- pin_map = {}
50-
51- logger .debug (f"allocate_pins: name={ name } , pins={ pins } " )
52- logger .debug (f"member={ pformat (member )} " )
53-
54- if member ['type' ] == 'interface' and 'annotations' in member \
55- and PIN_ANNOTATION_SCHEMA in member ['annotations' ]:
56- logger .debug ("matched IOSignature {sig}" )
57- sig = member ['annotations' ][PIN_ANNOTATION_SCHEMA ]
58- logger .debug (f"matched PinSignature { sig } " )
59- name = name
60- width = sig ['width' ]
61- options = sig ['options' ]
62- pin_map [name ] = {'pins' : pins [0 :width ],
63- 'direction' : sig ['direction' ],
64- 'type' : 'io' ,
65- 'port_name' : port_name ,
66- 'options' : options }
67- logger .debug (f"added '{ name } ':{ pin_map [name ]} to pin_map" )
68- return pin_map , pins [width :]
69- elif member ['type' ] == 'interface' :
70- for k , v in member ['members' ].items ():
71- port_name = '_' .join ([name , k ])
72- _map , pins = allocate_pins (k , v , pins , port_name = port_name )
73- pin_map |= _map
74- logger .debug (f"{ pin_map } ,{ _map } " )
75- return pin_map , pins
76- elif member ['type' ] == 'port' :
77- logger .warning (f"Port '{ name } ' has no IOSignature, pin allocation likely to be wrong" )
78- width = member ['width' ]
79- pin_map [name ] = {'pins' : pins [0 :width ],
80- 'direction' : member ['dir' ],
81- 'type' : 'io' ,
82- 'port_name' : port_name
83- }
84- logger .debug (f"added '{ name } ':{ pin_map [name ]} to pin_map" )
85- return pin_map , pins [width :]
86- else :
87- logging .debug (f"Shouldnt get here. member = { member } " )
88- assert False
89-
90-
9125def lock_pins () -> None :
92- # Get the config as dict for backward compatibility with top_interfaces
26+ # Get the config as dict for backward compatibility with top_components
9327 config_dict = _parse_config ()
9428
9529 # Parse with Pydantic for type checking and strong typing
9630 config_model = Config .model_validate (config_dict )
9731
98- used_pins = set ()
9932 oldlock = None
10033
10134 chipflow_root = _ensure_chipflow_root ()
@@ -111,9 +44,9 @@ def lock_pins() -> None:
11144
11245 if package_name not in PACKAGE_DEFINITIONS :
11346 logger .debug (f"Package '{ package_name } is unknown" )
114- package_type = PACKAGE_DEFINITIONS [package_name ]
11547
116- package = Package (package_type = package_type )
48+ # TODO, ugh, clean this up.
49+ package = Package (package_type = PACKAGE_DEFINITIONS [package_name ])
11750
11851 # Initialize standard pins from package type
11952 package .initialize_from_package_type ()
@@ -123,7 +56,6 @@ def lock_pins() -> None:
12356 silicon_config = getattr (config_model .chipflow .silicon , "pads" , {})
12457 for k , v in silicon_config .items ():
12558 pin = str (v .loc )
126- used_pins .add (pin )
12759
12860 # Convert Pydantic model to dict for backward compatibility
12961 v_dict = {"type" : v .type , "loc" : v .loc }
@@ -146,39 +78,10 @@ def lock_pins() -> None:
14678
14779 logger .debug (f"unallocated pins = { package_type .sortpins (unallocated )} " )
14880
149- # Use the raw dict for top_interfaces since it expects the legacy format
150- _ , interfaces = top_interfaces (config_dict )
81+ top = top_components (config_dict )
15182
152- logger .debug (f"All interfaces:\n { pformat (interfaces )} " )
153-
154- port_map = PortMap ({})
155- # we try to keep pins together for each interface
83+ # Use the PackageDef to allocate the pins:
15684 for component , iface in interfaces .items ():
157- for k , v in iface ['interface' ]['members' ].items ():
158- logger .debug (f"Interface { component } .{ k } :" )
159- logger .debug (pformat (v ))
160- width = count_member_pins (k , v )
161- logger .debug (f" { k } : total { width } pins" )
162- old_ports = oldlock .port_map .get_ports (component , k ) if oldlock else None
163- if old_ports :
164- logger .debug (f" { component } .{ k } found in pins.lock, reusing" )
165- logger .debug (pformat (old_ports ))
166- old_width = sum ([len (p .pins ) for p in old_ports .values ()])
167- if old_width != width :
168- raise ChipFlowError (
169- f"top level interface has changed size. "
170- f"Old size = { old_width } , new size = { width } "
171- )
172- port_map .add_ports (component , k , old_ports )
173- else :
174- pins = package_type .allocate (unallocated , width )
175- if len (pins ) == 0 :
176- raise ChipFlowError ("No pins were allocated by {package}" )
177- logger .debug (f"allocated range: { pins } " )
178- unallocated = unallocated - set (pins )
179- _map , _ = allocate_pins (k , v , pins )
180- port_map .add_ports (component , k , _map )
181-
18285 newlock = LockFile (process = process ,
18386 package = package ,
18487 port_map = port_map ,
0 commit comments