Skip to content

Commit d3082d0

Browse files
committed
wip
1 parent fdb4d58 commit d3082d0

File tree

3 files changed

+249
-306
lines changed

3 files changed

+249
-306
lines changed

chipflow_lib/pin_lock.py

Lines changed: 6 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from chipflow_lib.platforms import (
1111
PACKAGE_DEFINITIONS,
1212
PIN_ANNOTATION_SCHEMA,
13-
top_interfaces,
13+
top_components,
1414
LockFile,
1515
Package,
1616
PortMap,
@@ -22,80 +22,13 @@
2222
logger = 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-
9125
def 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

Comments
 (0)