Skip to content

Commit af10403

Browse files
committed
wip
1 parent eeaf472 commit af10403

File tree

5 files changed

+73
-68
lines changed

5 files changed

+73
-68
lines changed

.coverage

52 KB
Binary file not shown.

chipflow_lib/pin_lock.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,22 +119,22 @@ def lock_pins() -> None:
119119
logger.debug(f"Interface {component}.{k}:")
120120
logger.debug(pformat(v))
121121
width = count_member_pins(k, v)
122-
print(f" {k}: total {width} pins")
122+
logger.debug(f" {k}: total {width} pins")
123123
old_ports = oldlock.port_map.get_ports(component, k) if oldlock else None
124124
if old_ports:
125-
print(f" {component}.{k} found in pins.lock, reusing")
126-
logger.debug(pformat(port))
127-
old_width = sum([len(p) for p in old_ports])
125+
logger.debug(f" {component}.{k} found in pins.lock, reusing")
126+
logger.debug(pformat(old_ports))
127+
old_width = sum([len(p.pins) for p in old_ports.values()])
128128
if old_width != width:
129129
raise ChipFlowError(
130130
f"top level interface has changed size. "
131131
f"Old size = {old_width}, new size = {width}"
132132
)
133-
port_map.add_ports(old_ports)
133+
port_map.add_ports(component, k, old_ports)
134134
else:
135135
pins = package_type.allocate(unallocated, width)
136136
if len(pins) == 0:
137-
raise ChipFlowError("ERROR: No pins were allocated by {package}")
137+
raise ChipFlowError("No pins were allocated by {package}")
138138
logger.debug(f"allocated range: {pins}")
139139
unallocated = unallocated - set(pins)
140140
_map, _ = allocate_pins(k, v, pins)

chipflow_lib/platforms/utils.py

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def _chipflow_schema_uri(name: str, version: int) -> str:
3030

3131

3232
class _PinAnnotationModel(BaseModel):
33-
model_config = ConfigDict(use_enum_values=True, export_values=True)
33+
model_config = ConfigDict(use_enum_values=True)
3434
direction: io.Direction
3535
width: int
3636

@@ -57,9 +57,7 @@ def origin(self): # type: ignore
5757
return self.model
5858

5959
def as_json(self): # type: ignore
60-
json_dict = self.model.model_dump()
61-
json_dict["direction"] = self.model.direction.name # Use .name to get short enum name
62-
return json_dict
60+
return self.model.model_dump()
6361

6462

6563
PIN_ANNOTATION_SCHEMA = str(_chipflow_schema_uri("pin-annotation", 0))
@@ -87,7 +85,9 @@ def __init__(self, direction, width=1, init=None):
8785
super().__init__(sig)
8886

8987
def annotations(self, *args):
90-
return wiring.Signature.annotations(self, *args) + (_PinAnnotation(direction=self._direction, width=self._width),)
88+
annotations = wiring.Signature.annotations(self, *args)
89+
pin_annotation = _PinAnnotation(direction=self._direction, width=self._width)
90+
return annotations + (pin_annotation,)
9191

9292
def __repr__(self):
9393
return f"PinSignature({self._direction}, {self._width})"
@@ -105,8 +105,9 @@ def BidirPinSignature(width, **kwargs):
105105
return PinSignature(io.Direction.Bidir, width=width, **kwargs)
106106

107107

108-
PinSet = Set[tuple]
109-
PinList = List[tuple]
108+
Pin = Union[tuple, str]
109+
PinSet = Set[Pin]
110+
PinList = List[Pin]
110111
Pins = Union[PinSet, PinList]
111112

112113

@@ -128,15 +129,17 @@ def _group_consecutive_items(ordering: PinList, lst: PinList) -> OrderedDict[int
128129
last = lst[0]
129130
current_group = [last]
130131

132+
logger.debug(f"_group_consecutive_items starting with {current_group}")
133+
131134
for item in lst[1:]:
132135
idx = ordering.index(last)
133136
next = ordering[idx + 1] if idx < len(ordering) - 1 else None
134-
# logger.debug(f"inspecting {item}, index {idx}, next {next}")
137+
logger.debug(f"inspecting {item}, index {idx}, next {next}")
135138
if item == next:
136139
current_group.append(item)
137-
# logger.debug("found consecutive, adding to current group")
140+
logger.debug("found consecutive, adding to current group")
138141
else:
139-
# logger.debug("found nonconsecutive, creating new group")
142+
logger.debug("found nonconsecutive, creating new group")
140143
grouped.append(current_group)
141144
current_group = [item]
142145
last = item
@@ -212,7 +215,7 @@ def sortpins(self, pins: Pins) -> PinList:
212215
return list(pins).sort()
213216

214217

215-
class _QuadPackageDef(_BasePackageDef):
218+
class _BareDiePackageDef(_BasePackageDef):
216219
"""Definition of a package with pins on four sides, labelled north, south, east, west
217220
with an integer identifier within each side.
218221
"""
@@ -223,22 +226,26 @@ class _QuadPackageDef(_BasePackageDef):
223226
width: int
224227
height: int
225228

229+
def model_post_init(self, __context):
230+
self._ordered_pins = sorted(
231+
list(itertools.product((_Side.N, _Side.S), range(self.width))) +
232+
list(itertools.product((_Side.W, _Side.E), range(self.height))))
233+
return super().model_post_init(__context)
234+
226235
@property
227236
def pins(self) -> PinSet:
228-
return set(
229-
itertools.product((_Side.N, _Side.S), range(self.width)) +
230-
itertools.product((_Side.W, _Side.E), range(self.height)))
237+
return set(self._ordered_pins)
231238

232239
def allocate(self, available: PinSet, width: int) -> PinList:
233240
avail_n = self.sortpins(available)
234-
logger.debug(f"QuadPackageDef.allocate {width} from {len(avail_n)} remaining")
235-
ret = _find_contiguous_sequence(avail_n, width)
236-
logger.debug(f"QuadPackageDef.returned {ret}")
241+
logger.debug(f"_BareDiePackageDef.allocate {width} from {len(avail_n)} remaining")
242+
ret = _find_contiguous_sequence(self._ordered_pins, avail_n, width)
243+
logger.debug(f"_BareDiePackageDef.returned {ret}")
237244
assert len(ret) == width
238245
return ret
239246

240247

241-
class _PGAPackageDef(_BasePackageDef):
248+
class _QuadPackageDef(_BasePackageDef):
242249
"""Definiton of a PGA package with `size` pins
243250
244251
This is package with `size` pins, numbered, with the assumption that adjacent pins
@@ -248,31 +255,38 @@ class _PGAPackageDef(_BasePackageDef):
248255
# Used by pydantic to differentate when deserialising
249256
type: Literal["_PGAPackageDef"] = "_PGAPackageDef"
250257

251-
size: int
258+
width:int
259+
height: int
260+
261+
def model_post_init(self, __context):
262+
self._ordered_pins = sorted(
263+
[str(i) for i in range(1, self.width * 2 + self.height * 2)])
264+
return super().model_post_init(__context)
265+
252266

253267
@property
254-
def pins(self) -> Set[str]:
255-
return set([str(i) for i in range(self.size - 1)])
268+
def pins(self) -> PinSet:
269+
return set(self._ordered_pins)
256270

257271
def allocate(self, available: Set[str], width: int) -> List[str]:
258-
avail_n = sorted([int(i) for i in available])
259-
logger.debug(f"PGAPackageDef.allocate {width} from {len(avail_n)} remaining")
260-
ret = _find_contiguous_sequence(avail_n, width)
261-
logger.debug(f"PGAPackageDef.returned {ret}")
272+
avail_n = sorted(available)
273+
logger.debug(f"QuadPackageDef.allocate {width} from {len(avail_n)} remaining: {available}")
274+
ret = _find_contiguous_sequence(self._ordered_pins, avail_n, width)
275+
logger.debug(f"QuadPackageDef.returned {ret}")
262276
assert len(ret) == width
263-
return [str(i) for i in ret]
277+
return ret
264278

265279
def sortpins(self, pins: Union[List[str], Set[str]]) -> List[str]:
266280
return sorted(list(pins), key=int)
267281

268282

269283
# Add any new package types to both PACKAGE_DEFINITIONS and the PackageDef union
270284
PACKAGE_DEFINITIONS = {
271-
"pga144": _PGAPackageDef(name="pga144", size=144),
272-
"cf20": _QuadPackageDef(name="cf20", width=7, height=3)
285+
"pga144": _QuadPackageDef(name="pga144", width=36, height=36),
286+
"cf20": _BareDiePackageDef(name="cf20", width=7, height=3)
273287
}
274288

275-
PackageDef = Union[_PGAPackageDef, _BasePackageDef]
289+
PackageDef = Union[_QuadPackageDef, _BasePackageDef]
276290

277291

278292
class Port(pydantic.BaseModel):

pyproject.toml

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
# Project metadata
44

5-
[tool.pdm.version]
6-
source = "scm"
7-
85
[project]
96
name = "chipflow-lib"
107
dynamic = ["version"]
@@ -43,21 +40,6 @@ build-backend = "pdm.backend"
4340

4441
# Development workflow configuration
4542

46-
[tool.pdm.dev-dependencies]
47-
test = [
48-
"pytest>=7.2.0",
49-
"sphinx>=7.1.2",
50-
]
51-
lint = [
52-
"ruff",
53-
]
54-
55-
[tool.pdm.scripts]
56-
test.cmd = "pytest"
57-
test-docs.cmd = "sphinx-build -b doctest docs/ docs/_build"
58-
lint.cmd = "ruff check"
59-
document.cmd = "sphinx-build docs/ docs/_build/ -W --keep-going"
60-
6143
[tool.pyright]
6244
diagnosticMode=false
6345
typeCheckingMode = "off"
@@ -70,3 +52,25 @@ include = ["pyproject.toml", "**/*.py", "chipflow.toml"]
7052

7153
[tool.ruff.lint]
7254
ignore = ['F403', 'F405']
55+
56+
[tool.pdm.version]
57+
source = "scm"
58+
59+
[tool.pdm.scripts]
60+
test-cov.cmd = "pytest --cov=chipflow_lib --cov-report=html"
61+
test.cmd = "pytest"
62+
test-docs.cmd = "sphinx-build -b doctest docs/ docs/_build"
63+
lint.cmd = "ruff check"
64+
document.cmd = "sphinx-build docs/ docs/_build/ -W --keep-going"
65+
66+
67+
[dependency-groups]
68+
lint = [
69+
"ruff",
70+
"pytest-cov",
71+
]
72+
test = [
73+
"pytest>=7.2.0",
74+
"sphinx>=7.1.2",
75+
"pytest-cov>=6.0.0",
76+
]

tests/test_utils.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,5 @@ def test_pin_annotation_as_json():
100100
json_output = annotation.as_json()
101101
print(f"json_output: {json_output}") # Debug print using print()
102102
assert isinstance(json_output, dict)
103-
assert json_output["direction"] == "b"
104-
assert json_output["width"] == 8
105-
106-
def test_pin_annotation_in_interface():
107-
108-
interface_signature = wiring.Signature([ # Define signature as a list of members directly
109-
wiring.Out(PinSignature(io.Direction.Output, width=32)) # List of wiring.Member instances, removed name="p1"
110-
])
111-
112-
iface = wiring.PureInterface(signature=interface_signature) # Create anonymous PureInterface instance
113-
assert hasattr(iface.p1, "metadata") # Uncomment assertions to use iface.p1
114-
assert isinstance(iface.p1.metadata, meta.Metadata)
115-
assert isinstance(iface.p1.metadata.annotation_value, _PinAnnotation)
116-
assert iface.p1.metadata.annotation_value.model.direction is io.Direction.Output
117-
assert iface.p1.metadata.annotation_value.model.width == 32
103+
assert json_output["direction"] == "io"
104+
assert json_output["width"] == 8

0 commit comments

Comments
 (0)