Skip to content

Commit ed14d5e

Browse files
committed
wip
1 parent 580ff8e commit ed14d5e

File tree

2 files changed

+55
-55
lines changed

2 files changed

+55
-55
lines changed

chipflow_lib/pin_lock.py

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
import inspect
22
import json
3+
import logging
34
import re
5+
import sys
46

5-
from pprint import pprint
7+
from pprint import pformat
68
from pathlib import Path
79

810
from amaranth import Shape
911
from chipflow_lib import _parse_config, _get_cls_by_reference
10-
from chipflow_lib.platforms import PACKAGE_DEFINITIONS
12+
from chipflow_lib.platforms import PACKAGE_DEFINITIONS, PIN_ANNOTATION_SCHEMA
13+
14+
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
15+
logger = logging.getLogger(__name__)
16+
1117

1218
def has_consecutive_numbers(lst):
1319
if not lst:
@@ -56,23 +62,26 @@ def count_pins(member):
5662
elif member['type'] == 'port':
5763
return member['width']
5864

59-
def allocate_pins(name, member, pins, pin_map):
60-
print(f"allocate_pins: {pins}")
65+
def allocate_pins(name, member, pins:list):
66+
pin_map = {}
67+
logger.debug(f"allocate_pins: name={name}, member={member}, pins={pins}")
6168
if member['type'] == 'interface':
6269
for k, v in member['members'].items():
6370
n = '_'.join([name,k])
64-
pins = allocate_pins(n, v, pins, pin_map)
65-
return pins
66-
elif member['type'] == 'port':
71+
_map, pins = allocate_pins(n, v, pins)
72+
pin_map |= _map
73+
logger.debug(f"{pin_map},{_map}")
74+
elif PIN_ANNOTATION_SCHEMA in member['annotations']:
6775
name = name
68-
width = member['width']
76+
signature = member['annotations'][PIN_ANNOTATION_SCHEMA]
77+
width = signature['width']
78+
direction = signature['direction']
6979
if width == 1:
7080
pin_map[name] = {'pin':pins[0], 'type':member['dir']}
7181
else:
72-
pin_map[name] = {'start':pins[0],
73-
'end':pins[width-1],
74-
'type':member['dir']}
75-
return pins[width:]
82+
pin_map[name] = {'pins':pins,
83+
'direction':direction}
84+
return pin_map, pins[width:]
7685

7786

7887
def check_pins(name, member, old_map, new_map):
@@ -85,27 +94,10 @@ def check_pins(name, member, old_map, new_map):
8594
if width == 1:
8695
assert 'pin' in old_map[name]
8796
else:
88-
assert 'start' in old_map[name]
89-
assert 'end' in old_map[name]
90-
assert old_map[name]['end'] - old_map[name]['start'] + 1 == width
97+
assert 'pins' in old_map[name]
98+
assert len(old_map[name]['pins']) == width
9199
new_map[name] = old_map[name]
92100

93-
def connect_pins(pin_map):
94-
for k,v in interfaces.items():
95-
if member['type'] == 'interface':
96-
for k, v in member['members'].items():
97-
n = '_'.join([name,k])
98-
check_pins(n, v, old_map, new_map)
99-
elif member['type'] == 'port':
100-
width = member['width']
101-
if width == 1:
102-
assert 'pin' in old_map[name]
103-
else:
104-
assert 'start' in old_map[name]
105-
assert 'end' in old_map[name]
106-
assert old_map[name]['end'] - old_map[name]['start'] + 1 == width
107-
new_map[name] = old_map[name]
108-
109101
def lock_pins():
110102
config = _parse_config()
111103
used_pins = set()
@@ -124,11 +116,11 @@ def lock_pins():
124116
package_name = config["chipflow"]["silicon"]["pad_ring"]
125117

126118
if package_name not in PACKAGE_DEFINITIONS:
127-
print(f"Package '{package} is unknown")
119+
logger.debug(f"Package '{package} is unknown")
128120
package = PACKAGE_DEFINITIONS[package_name]
129121

130122
for d in ("pads", "power"):
131-
print(f"Checking [chipflow.silicon.{d}]:")
123+
logger.debug(f"Checking [chipflow.silicon.{d}]:")
132124
for k, v in config["chipflow"]["silicon"][d].items():
133125
pin = v['loc']
134126
used_pins.add(pin)
@@ -141,11 +133,11 @@ def lock_pins():
141133
'type': v['type'] if 'type' in v else None}
142134

143135

144-
print(f'Pins in use: {sorted(used_pins)}')
136+
logger.debug(f'Pins in use: {sorted(used_pins)}')
145137

146138
unallocated = package.pins - used_pins
147139

148-
print(f"unallocated pins = {sorted(unallocated)}")
140+
logger.debug(f"unallocated pins = {sorted(unallocated)}")
149141
interfaces = {}
150142
top_components = config["chipflow"]["top"].items()
151143
component_configs = {}
@@ -154,7 +146,7 @@ def lock_pins():
154146
for name, conf in top_components:
155147
if '.' in name:
156148
assert conf is dict
157-
print("Config found for {name}")
149+
logger.debug("Config found for {name}")
158150
component_configs[name.split('.')[0]] = conf
159151

160152
for name, ref in top_components:
@@ -163,36 +155,36 @@ def lock_pins():
163155
top[name] = cls(component_configs[name])
164156
else:
165157
top[name] = cls()
166-
pprint(top[name].metadata.origin.signature.members)
158+
logger.debug(pformat(top[name].metadata.origin.signature.members))
167159
metadata = top[name].metadata.as_json()
168160
interfaces |= metadata['interface']['members']
169161

170-
print(f"All interfaces: {interfaces.keys()}")
162+
logger.debug(f"All interfaces: {interfaces.keys()}")
171163
pin_map_interfaces = {}
172164

173165
# we try to keep pins together for each interface
174166
for k,v in interfaces.items():
175-
print(f"Interface {k}:")
176-
pprint(v)
167+
logger.debug(f"Interface {k}:")
168+
logger.debug(pformat(v))
177169
width = count_pins(v)
178-
print(f"member {k} total width = {width}")
170+
logger.debug(f"member {k} total width = {width}")
179171
pins = package.allocate(unallocated, width)
180-
print(f"allocated range: {pins}")
172+
logger.debug(f"allocated range: {pins}")
181173
if len(pins) == 0:
182-
print("ERROR")
174+
logger.error("No pins were allocation by {package}")
175+
exit(1)
183176
if k in old_interfaces:
184-
if old_interfaces[k]['start'] != pins.start or \
185-
old_interfaces[k]['end'] != pins.stop:
177+
if len(old_interfaces[k]['pins']) != len(pins):
186178
# TODO: option to allocate new pins nonconsecutively
187179
print("top level interface has changed size")
188180
exit(1)
189181
check_pins(k, v, old_map, pin_map)
190-
pin_map_interfaces[k] = {'top': True, 'start':pins.start, 'end':pins.stop}
182+
pin_map_interfaces[k] = {'top': True, 'pins':pins}
191183
else:
192-
pin_map_interfaces[k] = {'top': True, 'start':pins.start, 'end':pins.stop}
193-
newpins = unallocated[pins]
194-
unallocated[pins] = []
195-
allocate_pins(k, v, newpins, pin_map)
184+
pin_map_interfaces[k] = {'top': True, 'pins':pins}
185+
unallocated = unallocated - set(pins)
186+
_map,_ = allocate_pins(k, v, pins)
187+
pin_map |= _map
196188

197189
with open('pins.lock', 'w') as f:
198190
newlock = {'interfaces': pin_map_interfaces,
@@ -210,7 +202,7 @@ def build_cli_parser(self, parser):
210202
"lock", help=inspect.getdoc(self.lock).splitlines()[0])
211203

212204
def run_cli(self, args):
213-
print(f"command {args}")
205+
logger.debug(f"command {args}")
214206
if args.action == "lock":
215207
self.lock()
216208

chipflow_lib/platforms/__init__.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from dataclasses import dataclass
2-
from typing import Set
2+
from typing import Set, List
33

4+
from amaranth import Shape
45
from amaranth.lib import wiring, io, meta
56
from amaranth.lib.wiring import In, Out
67
from pydantic import BaseModel, ConfigDict
@@ -68,10 +69,13 @@ def as_json(self): # type: ignore
6869
print(f"PinAnnotations: {pformat(self.model.model_dump_json())}")
6970
return self.model.model_dump()
7071

72+
PIN_ANNOTATION_SCHEMA = chipflow_schema_uri("pin-annotation",0)
73+
7174
class PinSignature(wiring.Signature):
72-
def __init__(self, direction, width=1):
75+
def __init__(self, direction, width=1, init=None):
7376
self._direction = direction
7477
self._width = width
78+
self._init = init
7579
match direction:
7680
case io.Direction.Bidir:
7781
sig = {
@@ -90,7 +94,11 @@ def __init__(self, direction, width=1):
9094

9195
def annotations(self, *args):
9296
return wiring.Signature.annotations(self, *args) + (PinAnnotation(direction=self._direction, width=self._width),)
93-
97+
98+
def create(self, *args, **kwargs):
99+
print(f"Calling PinSignature.create({args},{kwargs})")
100+
return super().create(*args, **kwargs)
101+
94102
def __repr__(self):
95103
return f"PinSignature({self._direction}, {self._width})"
96104

@@ -163,7 +171,7 @@ class PGAPackageDef:
163171
def pins(self) -> Set[str]:
164172
return set([str(i) for i in range(self.size-1)])
165173

166-
def allocate(self, available: Set[str], width:int):
174+
def allocate(self, available: Set[str], width:int) -> List[str]:
167175
avail_n = sorted([int(i) for i in available])
168176
print(f"PGAPackageDef.allocate {avail_n}, {width}")
169177
ret = find_contiguous_sequence(avail_n, width)

0 commit comments

Comments
 (0)