Skip to content

Commit 0344d87

Browse files
committed
wip
1 parent 6fab0f7 commit 0344d87

File tree

3 files changed

+98
-80
lines changed

3 files changed

+98
-80
lines changed

chipflow_lib/cli.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import inspect
44
import sys
55
import traceback
6+
import logging
67

78
from pprint import pformat
89

@@ -16,6 +17,8 @@
1617
from .pin_lock import PinCommand
1718

1819

20+
logging.basicConfig(stream=sys.stdout, level=logging.WARNING)
21+
1922
class UnexpectedError(ChipFlowError):
2023
pass
2124

@@ -34,6 +37,14 @@ def run(argv=sys.argv[1:]):
3437
f"using `{step_reference}`")
3538

3639
parser = argparse.ArgumentParser()
40+
41+
parser.add_argument(
42+
"--verbose", "-v",
43+
dest="log_level",
44+
action="append_const",
45+
const=10,
46+
)
47+
3748
command_argument = parser.add_subparsers(dest="command", required=True)
3849
for command_name, command in commands.items():
3950
command_subparser = command_argument.add_parser(command_name, help=inspect.getdoc(command))
@@ -44,6 +55,9 @@ def run(argv=sys.argv[1:]):
4455
f"step `{command_name}`")
4556

4657
args = parser.parse_args(argv)
58+
if args.log_level:
59+
log_level = max(logging.DEBUG, logging.WARNING - sum(args.log_level))
60+
logging.getLogger().setLevel(log_level)
4761

4862
try:
4963
try:

chipflow_lib/pin_lock.py

Lines changed: 75 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -9,60 +9,68 @@
99

1010
from amaranth import Shape
1111
from chipflow_lib import _parse_config, _get_cls_by_reference
12-
from chipflow_lib.platforms import PACKAGE_DEFINITIONS, Schemas
12+
from chipflow_lib.platforms import PACKAGE_DEFINITIONS, PIN_ANNOTATION_SCHEMA
1313

14-
# logging.basicConfig(stream=sys.stdout, level=logging.WARNING)
15-
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
14+
# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
1615
logger = logging.getLogger(__name__)
1716

1817

19-
def count_pins(member):
20-
if member['type'] == 'interface':
18+
def count_pins(name, member):
19+
logger.debug(f"count_pins {name} {member['type']} {member['annotations'] if 'annotations' in member else 'no annotations'}")
20+
if member['type']=='interface' and 'annotations' in member \
21+
and PIN_ANNOTATION_SCHEMA in member['annotations']:
22+
return member['annotations'][PIN_ANNOTATION_SCHEMA]['width']
23+
elif member['type'] == 'interface':
2124
width = 0
22-
for _, v in member['members'].items():
23-
width += count_pins(v)
25+
for n, v in member['members'].items():
26+
width += count_pins('_'.join([name,n]), v)
2427
return width
2528
elif member['type'] == 'port':
2629
return member['width']
2730

31+
def count_old_pins(d):
32+
match d:
33+
case {'type':t, 'pins':p}:
34+
return len(p)
35+
case _:
36+
return sum([count_old_pins(v) for v in d.values()])
2837

2938
def allocate_pins(name, member, pins:list):
3039
pin_map = {}
31-
logger.debug(f"allocate_pins: name={name}, member={member}, pins={pins}")
32-
33-
match member:
34-
case {'type':'interface', 'annotations':{Schemas.PIN_ANNOTATION: sig}}:
35-
logger.debug("matched PinSignature {sig}")
36-
name = name
37-
width = sig['width']
38-
direction = sig['direction']
39-
if width == 1:
40-
pin_map[name] = {'pin':pins[0], 'direction':direction}
41-
else:
42-
pin_map[name] = {'pins':pins,
43-
'direction':direction}
44-
return pin_map, pins[width:]
45-
case {'type': 'interface'}:
46-
for k, v in member['members'].items():
47-
n = '_'.join([name,k])
48-
_map, pins = allocate_pins(n, v, pins)
49-
pin_map |= _map
50-
logger.debug(f"{pin_map},{_map}")
51-
return pin_map, pins
52-
case {'type': 'port'}:
53-
logging.warning(f"Component `{name}` in this design is not using PinSignature")
54-
name = name
55-
width = member['width']
56-
direction = member['dir']
57-
if width == 1:
58-
pin_map[name] = {'pin':pins[0], 'direction':direction}
59-
else:
60-
pin_map[name] = {'pins':pins,
61-
'direction':direction}
62-
return pin_map, pins[width:]
63-
case _:
64-
logging.debug(f"Shouldnt get here. member = {member}")
65-
assert False
40+
logger.debug(f"allocate_pins: name={name}, pins={pins}")
41+
logger.debug(f"member={pformat(member)}")
42+
43+
if member['type']=='interface' and 'annotations' in member \
44+
and PIN_ANNOTATION_SCHEMA in member['annotations']:
45+
logger.debug("matched PinSignature {sig}")
46+
name = name
47+
sig = member['annotations'][PIN_ANNOTATION_SCHEMA]
48+
width = sig['width']
49+
direction = sig['direction']
50+
pin_map[name] = {'pins':pins[0:width],
51+
'direction':direction,
52+
'type':'io'}
53+
return pin_map, pins[width:]
54+
elif member['type'] == 'interface':
55+
logger.warning("member without PinSignature, pin allocation likely to be wrong")
56+
for k, v in member['members'].items():
57+
n = '_'.join([name,k])
58+
_map, pins = allocate_pins(n, v, pins)
59+
pin_map |= _map
60+
logger.debug(f"{pin_map},{_map}")
61+
return pin_map, pins
62+
elif member['type'] == 'port':
63+
logger.warning(f"Component `{name}` in this design is not using PinSignature")
64+
name = name
65+
width = member['width']
66+
direction = member['dir']
67+
pin_map[name] = {'pins':pins[0:width],
68+
'direction':direction,
69+
'type': 'io'}
70+
return pin_map, pins[width:]
71+
else:
72+
logging.debug(f"Shouldnt get here. member = {member}")
73+
assert False
6674

6775

6876
def check_pins(name, member, old_map, new_map):
@@ -72,11 +80,8 @@ def check_pins(name, member, old_map, new_map):
7280
check_pins(n, v, old_map, new_map)
7381
elif member['type'] == 'port':
7482
width = member['width']
75-
if width == 1:
76-
assert 'pin' in old_map[name]
77-
else:
78-
assert 'pins' in old_map[name]
79-
assert len(old_map[name]['pins']) == width
83+
assert 'pins' in old_map[name]
84+
assert len(old_map[name]['pins']) == width
8085
new_map[name] = old_map[name]
8186

8287
def lock_pins():
@@ -87,13 +92,10 @@ def lock_pins():
8792
if lockfile.exists():
8893
with open(lockfile) as f:
8994
old_lock = json.load(f)
90-
old_interfaces = old_lock['interfaces']
9195
old_map = old_lock['map']
9296
else:
9397
old_map = {}
94-
old_interfaces = {}
95-
96-
print(f"Locking pins: {'using pins.lock' if lockfile else ''}")
98+
print(f"Locking pins: {'using pins.lock' if lockfile.exists() else ''}")
9799
package_name = config["chipflow"]["silicon"]["pad_ring"]
98100

99101
if package_name not in PACKAGE_DEFINITIONS:
@@ -103,14 +105,14 @@ def lock_pins():
103105
for d in ("pads", "power"):
104106
logger.debug(f"Checking [chipflow.silicon.{d}]:")
105107
for k, v in config["chipflow"]["silicon"][d].items():
106-
pin = v['loc']
108+
pin = str(v['loc'])
107109
used_pins.add(pin)
108-
if k in old_map and old_map[k]['pin'] != pin:
110+
if k in old_map and old_map[k]['pins'] != [pin]:
109111
print(f"chipflow.toml conflicts with pins.lock: "
110-
f"{k} had pin {old_map[k]}, now {pin}.")
112+
f"{k} had pin {old_map[k]['pins']}, now {[pin]}.")
111113
exit(1)
112114
pin_map[k] = {
113-
'pin': pin,
115+
'pins': [pin],
114116
'type': v['type'] if 'type' in v else None}
115117

116118

@@ -147,29 +149,30 @@ def lock_pins():
147149
for k,v in interfaces.items():
148150
logger.debug(f"Interface {k}:")
149151
logger.debug(pformat(v))
150-
width = count_pins(v)
151-
logger.debug(f"member {k} total width = {width}")
152-
pins = package.allocate(unallocated, width)
153-
logger.debug(f"allocated range: {pins}")
154-
if len(pins) == 0:
155-
logger.error("No pins were allocation by {package}")
156-
exit(1)
157-
if k in old_interfaces:
158-
if len(old_interfaces[k]['pins']) != len(pins):
152+
width = count_pins(k, v)
153+
print(f" {k}: total {width} pins")
154+
if k in old_map:
155+
print(f" {k} found in pins.lock, reusing")
156+
logger.debug(pformat(old_map[k]))
157+
old_width = count_old_pins(old_map[k])
158+
if old_width != width:
159159
# TODO: option to allocate new pins nonconsecutively
160-
print("top level interface has changed size")
160+
print(f"top level interface has changed size. Old size = {old_width}, new size = {width}")
161161
exit(1)
162-
check_pins(k, v, old_map, pin_map)
163-
pin_map_interfaces[k] = {'top': True, 'pins':pins}
162+
pin_map[k] = old_map[k]
164163
else:
165-
pin_map_interfaces[k] = {'top': True, 'pins':pins}
164+
pins = package.allocate(unallocated, width)
165+
if len(pins) == 0:
166+
print("ERROR: No pins were allocation by {package}")
167+
exit(1)
168+
logger.debug(f"allocated range: {pins}")
166169
unallocated = unallocated - set(pins)
167-
_map,_ = allocate_pins(k, v, pins)
168-
pin_map |= _map
170+
_map, _ = allocate_pins(k, v, pins)
171+
pin_map[k] = _map
169172

170173
with open('pins.lock', 'w') as f:
171-
newlock = {'interfaces': pin_map_interfaces,
172-
'map': pin_map}
174+
newlock = {'map': pin_map,
175+
'metadata': metadata}
173176

174177
json.dump(newlock, f, indent=2, sort_keys=True)
175178

chipflow_lib/platforms/__init__.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ def as_json(self): # type: ignore
7575
return self.model.model_dump()
7676

7777
class Schemas(Enum):
78-
PIN_ANNOTATION = chipflow_schema_uri("pin-annotation",0)
78+
PIN_ANNOTATION = str(chipflow_schema_uri("pin-annotation",0))
79+
PIN_ANNOTATION_SCHEMA = str(chipflow_schema_uri("pin-annotation",0))
7980

8081
class PinSignature(wiring.Signature):
8182
def __init__(self, direction, width=1, init=None):
@@ -104,16 +105,16 @@ def annotations(self, *args):
104105
def __repr__(self):
105106
return f"PinSignature({self._direction}, {self._width})"
106107

107-
def OutputPinSignature(width):
108-
return PinSignature(io.Direction.Output)
108+
def OutputPinSignature(width, **kwargs):
109+
return PinSignature(io.Direction.Output, width=width, **kwargs)
109110

110-
def InputPinSignature(width):
111-
return PinSignature(io.Direction.Input)
111+
def InputPinSignature(width, **kwargs):
112+
return PinSignature(io.Direction.Input, width=width, **kwargs)
112113

113-
def BidirPinSignature(width):
114-
return PinSignature(io.Direction.Bidir)
114+
def BidirPinSignature(width, **kwargs):
115+
return PinSignature(io.Direction.Bidir, width=width, **kwargs)
115116

116-
def group_consecutive_items(lst: List[int]) -> Dict[int, List[int]]:
117+
def group_consecutive_items(lst: List[int]) -> Dict[int, List[List[int]]]:
117118
if not lst:
118119
return {}
119120

0 commit comments

Comments
 (0)