Skip to content

Commit 6fab0f7

Browse files
committed
Pin Locking now working
1 parent ed14d5e commit 6fab0f7

File tree

3 files changed

+58
-76
lines changed

3 files changed

+58
-76
lines changed

chipflow_lib/pin_lock.py

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -9,50 +9,13 @@
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, PIN_ANNOTATION_SCHEMA
12+
from chipflow_lib.platforms import PACKAGE_DEFINITIONS, Schemas
1313

14+
# logging.basicConfig(stream=sys.stdout, level=logging.WARNING)
1415
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
1516
logger = logging.getLogger(__name__)
1617

1718

18-
def has_consecutive_numbers(lst):
19-
if not lst:
20-
return False
21-
lst.sort()
22-
return all(lst[i] + 1 == lst[i + 1] for i in range(len(lst) - 1))
23-
24-
def strip_pin_suffix(name):
25-
"""Strip _i, _o, and _oe suffixes from a pin name.
26-
27-
Args:
28-
name: Pin name string
29-
30-
Returns:
31-
Name with suffix removed
32-
"""
33-
return re.sub(r'(_i|_o|_oe)$', '', name)
34-
35-
def signature_width(signature):
36-
width = 0
37-
obj = signature.create()
38-
for a,b,c in signature.flatten(obj):
39-
shape = Shape.cast(b.shape)
40-
width += shape.width
41-
return width
42-
43-
def member_width(member):
44-
if member.is_signature:
45-
return signature_width(member.signature)
46-
else:
47-
shape = Shape.cast(member.shape)
48-
return shape.width
49-
50-
MATCH_TRIPLE = re.compile(r'(_i|_o|_oe)$')
51-
52-
def coalesce_triples(sig: dict) -> None:
53-
if sig['type'] == 'port':
54-
pass
55-
5619
def count_pins(member):
5720
if member['type'] == 'interface':
5821
width = 0
@@ -62,26 +25,44 @@ def count_pins(member):
6225
elif member['type'] == 'port':
6326
return member['width']
6427

28+
6529
def allocate_pins(name, member, pins:list):
6630
pin_map = {}
6731
logger.debug(f"allocate_pins: name={name}, member={member}, pins={pins}")
68-
if member['type'] == 'interface':
69-
for k, v in member['members'].items():
70-
n = '_'.join([name,k])
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']:
75-
name = name
76-
signature = member['annotations'][PIN_ANNOTATION_SCHEMA]
77-
width = signature['width']
78-
direction = signature['direction']
79-
if width == 1:
80-
pin_map[name] = {'pin':pins[0], 'type':member['dir']}
81-
else:
82-
pin_map[name] = {'pins':pins,
83-
'direction':direction}
84-
return pin_map, pins[width:]
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
8566

8667

8768
def check_pins(name, member, old_map, new_map):

chipflow_lib/platforms/__init__.py

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1+
import logging
2+
3+
from enum import Enum
14
from dataclasses import dataclass
2-
from typing import Set, List
5+
from typing import Set, List, TypeVar, Dict
36

47
from amaranth import Shape
58
from amaranth.lib import wiring, io, meta
69
from amaranth.lib.wiring import In, Out
710
from pydantic import BaseModel, ConfigDict
811
from pprint import pformat
912

13+
from .. import ChipFlowError
1014
from .silicon import *
1115
from .sim import *
1216

17+
logger = logging.getLogger(__name__)
18+
1319
def chipflow_schema_uri(name: str, version:int) -> str:
1420
return f"https://api.chipflow.com/schemas/{version}/{name}"
1521

@@ -66,10 +72,10 @@ def origin(self): # type: ignore
6672
return self.model
6773

6874
def as_json(self): # type: ignore
69-
print(f"PinAnnotations: {pformat(self.model.model_dump_json())}")
7075
return self.model.model_dump()
7176

72-
PIN_ANNOTATION_SCHEMA = chipflow_schema_uri("pin-annotation",0)
77+
class Schemas(Enum):
78+
PIN_ANNOTATION = chipflow_schema_uri("pin-annotation",0)
7379

7480
class PinSignature(wiring.Signature):
7581
def __init__(self, direction, width=1, init=None):
@@ -95,10 +101,6 @@ def __init__(self, direction, width=1, init=None):
95101
def annotations(self, *args):
96102
return wiring.Signature.annotations(self, *args) + (PinAnnotation(direction=self._direction, width=self._width),)
97103

98-
def create(self, *args, **kwargs):
99-
print(f"Calling PinSignature.create({args},{kwargs})")
100-
return super().create(*args, **kwargs)
101-
102104
def __repr__(self):
103105
return f"PinSignature({self._direction}, {self._width})"
104106

@@ -111,9 +113,9 @@ def InputPinSignature(width):
111113
def BidirPinSignature(width):
112114
return PinSignature(io.Direction.Bidir)
113115

114-
def group_consecutive_items(lst):
116+
def group_consecutive_items(lst: List[int]) -> Dict[int, List[int]]:
115117
if not lst:
116-
return []
118+
return {}
117119

118120
grouped = []
119121
current_group = [lst[0]]
@@ -131,8 +133,7 @@ def group_consecutive_items(lst):
131133
d.setdefault(len(g), []).append(g)
132134
return d
133135

134-
135-
def find_contiguous_sequence(lst, n):
136+
def find_contiguous_sequence(lst: List[int], total: int) -> List[int]:
136137
"""Find the next sequence of n consecutive numbers in a sorted list
137138
138139
Args:
@@ -143,22 +144,22 @@ def find_contiguous_sequence(lst, n):
143144
A slice indexing the first sequence of n consecutive numbers found within the given list
144145
if unable to find a consecutive list, allocate as contigously as possible
145146
"""
146-
if not lst or len(lst) < n:
147-
return None
147+
if not lst or len(lst) < total:
148+
raise ChipFlowError("Invalid request to find_contiguous_argument")
148149

149150
grouped = group_consecutive_items(lst)
150151

151-
print(f"grouped list: {pformat(grouped)}")
152152
ret = []
153+
n = total
153154
for k in sorted(grouped.keys(), reverse=True):
154155
for g in grouped[k]:
155-
print(f"{g} {k} {n}")
156+
assert (n+len(ret)==total)
156157
if k >= n:
157-
ret += g[0:min(n-1,k-1)]
158+
ret += g[0:min(n,k)]
158159
return ret
159160
else:
160161
n = n - k
161-
ret += g[0:min(n-1,k-1)]
162+
ret += g[0:k]
162163

163164
return ret
164165

@@ -173,8 +174,10 @@ def pins(self) -> Set[str]:
173174

174175
def allocate(self, available: Set[str], width:int) -> List[str]:
175176
avail_n = sorted([int(i) for i in available])
176-
print(f"PGAPackageDef.allocate {avail_n}, {width}")
177+
logger.debug(f"PGAPackageDef.allocate {width} from {len(avail_n)} remaining")
177178
ret = find_contiguous_sequence(avail_n, width)
179+
logger.debug(f"PGAPackageDef.returned {ret}")
180+
assert(len(ret)==width)
178181
return [str(i) for i in ret]
179182

180183
PACKAGE_DEFINITIONS = {

pyproject.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ dependencies = [
2121
"amaranth>=0.5,<0.7",
2222
"amaranth-soc @ git+https://github.com/amaranth-lang/amaranth-soc",
2323
"amaranth-boards @ git+https://github.com/amaranth-lang/amaranth-boards",
24-
"amaranth-stdio @ git+https://github.com/amaranth-lang/amaranth-stdio",
25-
"amaranth-orchard @ git+https://github.com/ChipFlow/amaranth-orchard",
2624
"yowasp-yosys>=0.41.0.0",
2725
"yowasp-nextpnr-ecp5>=0.7",
2826
"yowasp-runtime",

0 commit comments

Comments
 (0)