Skip to content

Commit 40d8d6e

Browse files
committed
wip - need to coalesce interface power pins
1 parent 3a9bbfd commit 40d8d6e

File tree

12 files changed

+151
-289
lines changed

12 files changed

+151
-289
lines changed

chipflow_lib/_config_models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ class SiliconConfig(BaseModel):
1414
power: Dict[str, Voltage] = {}
1515
debug: Optional[Dict[str, bool]] = None
1616

17+
# TODO: add validation that top components, clock domains and power domains
18+
# not begin with '_' (unless power domain _core)
1719
class ChipFlowConfig(BaseModel):
1820
"""Root configuration for chipflow.toml."""
1921
project_name: str

chipflow_lib/platforms/_utils.py

Lines changed: 118 additions & 135 deletions
Large diffs are not rendered by default.

chipflow_lib/platforms/sim.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def build(self, e):
7070
print("write_cxxrtl -header sim_soc.cc", file=yosys_file)
7171

7272
def instantiate_ports(self, m: Module):
73-
if hasattr(self, "_pinlock"):
73+
if self._pinlock: # already instantiated
7474
return
7575

7676
pinlock = load_pinlock()
@@ -94,7 +94,7 @@ def instantiate_ports(self, m: Module):
9494
assert 'clock_domain' in reset.iomodel
9595
domain = reset.iomodel['clock_domain']
9696
logger.debug(f"Instantiating reset synchronizer for {reset.port_name}, domain {domain}")
97-
rst_buffer = io.Buffer(reset.direction, self._ports[clock.port_name])
97+
rst_buffer = io.Buffer(reset.direction, self._ports[reset.port_name])
9898
setattr(m.submodules, reset.port_name, rst_buffer)
9999
ffsync = FFSynchronizer(rst_buffer.i, ResetSignal()) # type: ignore[reportAttributeAccessIssue]
100100
setattr(m.submodules, reset.port_name + "_sync", ffsync)

chipflow_lib/steps/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def _wire_up_ports(m: Module, top, platform):
5353
print("> {n}:{t}")
5454
setattr(m.submodules, n, t)
5555

56+
assert platform._pinlock
5657
for component, iface in platform._pinlock.port_map.ports.items():
5758
if component.startswith('_'):
5859
logger.debug(f"Ignoring special component {component}")

chipflow_lib/steps/silicon.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ def network_err(e):
243243
exit(2)
244244

245245
def _long_poll_stream(self, sp, network_err):
246+
assert self._log_stream_url
246247
steps = self._last_log_steps
247248
stream_event_counter = 0
248249
assert self._chipflow_api_key
@@ -305,7 +306,10 @@ def _stream_logs(self, sp, network_err):
305306
build_status = "pending"
306307
stream_event_counter = 0
307308
self._last_log_steps = []
308-
assert self._chipflow_api_key is not None
309+
310+
assert self._chipflow_api_key
311+
assert self._build_status_url
312+
309313
while fail_counter < 10 and stream_event_counter < 10:
310314
sp.text = f"Waiting for build to run... {build_status}"
311315
time.sleep(timeout) # Wait before polling

chipflow_lib/steps/sim.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,12 @@ def build(self, *args):
8989
# m.d.sync += heartbeat_ctr.eq(heartbeat_ctr + 1)
9090
# m.d.comb += platform.request("heartbeat").o.eq(heartbeat_ctr[-1])
9191

92+
assert self._platform._pinlock
93+
9294
top = top_components(self._config)
9395
logger.debug(f"SimStep top = {top}")
96+
logger.debug(f"port map ports =\n{pformat(self._platform._pinlock.port_map.ports)}")
97+
9498

9599
_wire_up_ports(m, top, self._platform)
96100

docs/package_pins.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Each package type (PGA, bare die, etc.) defines its own implementation of these
1919
### Getting Default Pins
2020

2121
```python
22-
from chipflow_lib.platforms._ import PACKAGE_DEFINITIONS, PowerType, JTAGWireName
22+
from chipflow_lib.platforms._utils import PACKAGE_DEFINITIONS, PowerType, JTAGWireName
2323

2424
# Get a package definition
2525
package_def = PACKAGE_DEFINITIONS["pga144"]
@@ -42,7 +42,7 @@ tms_pin = jtag_pins[JTAGWireName.TMS] # Get the TMS pin
4242
### Creating a Package with Default Pins
4343

4444
```python
45-
from chipflow_lib.platforms._ import PACKAGE_DEFINITIONS
45+
from chipflow_lib.platforms._utils import PACKAGE_DEFINITIONS
4646

4747
# Create a package with a specific package definition
4848
package = Package(package_type=PACKAGE_DEFINITIONS["pga144"])

tests/test_config_models.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
import os
33
import unittest
44

5-
from chipflow_lib._config_models import PadConfig
6-
75

86
class ConfigModelsTestCase(unittest.TestCase):
97
def setUp(self):
@@ -36,16 +34,6 @@ def test_config_validation(self):
3634
# self.assertEqual(config.chipflow.silicon.process, Process.SKY130)
3735
self.skipTest("Config validation temporarily disabled")
3836

39-
def test_pad_config(self):
40-
"""Test validation of pad configuration."""
41-
pad = PadConfig(type="clock", loc="114")
42-
self.assertEqual(pad.type, "clock")
43-
self.assertEqual(pad.loc, "114")
44-
45-
# Test validation of loc format
46-
with self.assertRaises(ValueError):
47-
PadConfig(type="clock", loc="invalid-format")
48-
4937
def test_nested_structure(self):
5038
"""Test the nested structure of the Config model."""
5139
# Temporarily disabled due to power config validation issues

tests/test_package_pins.py

Lines changed: 4 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# SPDX-License-Identifier: BSD-2-Clause
22
import unittest
33

4-
from chipflow_lib.platforms._ import (
5-
BareDiePackageDef, QuadPackageDef, Package, GAPackageDef, GALayout, GAPin
4+
from chipflow_lib.platforms import (
5+
BareDiePackageDef, QuadPackageDef, GAPackageDef
66
)
77

88

@@ -74,56 +74,11 @@ def test_bringup_pins(self):
7474
self.assertIsNotNone(jtag.tdo)
7575

7676

77-
class TestPackage(unittest.TestCase):
78-
def setUp(self):
79-
self.package_def = BareDiePackageDef(name="test_package", width=8, height=4)
80-
self.package = Package(type=self.package_def)
81-
82-
def test_package_initialization(self):
83-
"""Test basic package initialization"""
84-
self.assertIsNotNone(self.package.type)
85-
self.assertEqual(self.package.type.name, "test_package")
86-
self.assertEqual(self.package.type.width, 8)
87-
self.assertEqual(self.package.type.height, 4)
88-
89-
def test_package_type_access(self):
90-
"""Test accessing package type properties through Package"""
91-
# Should be able to access package type bringup pins
92-
bringup_pins = self.package.type.bringup_pins
93-
self.assertIsNotNone(bringup_pins)
94-
95-
# Test package discriminator
96-
self.assertEqual(self.package.type.package_type, "BareDiePackageDef")
97-
98-
9977
class TestGAPackage(unittest.TestCase):
100-
def test_gapin_creation(self):
101-
"""Test GAPin creation and equality"""
102-
pin1 = GAPin(h="A", w=1)
103-
pin2 = GAPin(h="A", w=1)
104-
pin3 = GAPin(h="B", w=2)
105-
106-
# Test equality
107-
self.assertEqual(pin1, pin2)
108-
self.assertNotEqual(pin1, pin3)
109-
110-
# Test attributes
111-
self.assertEqual(pin1.h, "A")
112-
self.assertEqual(pin1.w, 1)
113-
self.assertEqual(pin3.h, "B")
114-
self.assertEqual(pin3.w, 2)
115-
116-
def test_galayout_enum_values(self):
117-
"""Test GALayout enum values"""
118-
self.assertEqual(GALayout.FULL, "full")
119-
self.assertEqual(GALayout.PERIMETER, "perimeter")
120-
self.assertEqual(GALayout.CHANNEL, "channel")
121-
self.assertEqual(GALayout.ISLAND, "island")
122-
12378
def test_gapackagedef_class_structure(self):
12479
"""Test GAPackageDef class structure and type"""
12580
# Test that we can import and access the class
126-
from chipflow_lib.platforms._ import BasePackageDef
81+
from chipflow_lib.platforms._utils import BasePackageDef
12782

12883
# Test that GAPackageDef inherits from BasePackageDef
12984
self.assertTrue(issubclass(GAPackageDef, BasePackageDef))
@@ -155,90 +110,15 @@ def test_gapackagedef_pydantic_model(self):
155110
# Test that it has the expected type field in model_fields
156111
self.assertIn('package_type', GAPackageDef.model_fields)
157112

158-
def test_missing_pins_configuration(self):
159-
"""Test missing pins configuration"""
160-
# Since GAPin is not hashable, test individual pins
161-
pin1 = GAPin(h="A", w=1)
162-
pin2 = GAPin(h="B", w=2)
163-
pin3 = GAPin(h="C", w=3)
164-
165-
# Test that pins can be created correctly
166-
self.assertEqual(pin1.h, "A")
167-
self.assertEqual(pin1.w, 1)
168-
self.assertEqual(pin2.h, "B")
169-
self.assertEqual(pin2.w, 2)
170-
self.assertEqual(pin3.h, "C")
171-
self.assertEqual(pin3.w, 3)
172-
173-
# Test that pins are equal to themselves
174-
self.assertEqual(pin1, GAPin(h="A", w=1))
175-
self.assertEqual(pin2, GAPin(h="B", w=2))
176-
177-
def test_additional_pins_configuration(self):
178-
"""Test additional pins configuration"""
179-
# Since GAPin is not hashable, test individual pins
180-
pin1 = GAPin(h="D", w=4)
181-
pin2 = GAPin(h="E", w=5)
182-
183-
# Test that additional pins can be created correctly
184-
self.assertEqual(pin1.h, "D")
185-
self.assertEqual(pin1.w, 4)
186-
self.assertEqual(pin2.h, "E")
187-
self.assertEqual(pin2.w, 5)
188-
189-
# Test equality
190-
self.assertEqual(pin1, GAPin(h="D", w=4))
191-
self.assertEqual(pin2, GAPin(h="E", w=5))
192-
193-
def test_layout_type_values(self):
194-
"""Test different layout type values"""
195-
# Test that GALayout values are correct
196-
self.assertEqual(GALayout.FULL.value, "full")
197-
self.assertEqual(GALayout.PERIMETER.value, "perimeter")
198-
self.assertEqual(GALayout.CHANNEL.value, "channel")
199-
self.assertEqual(GALayout.ISLAND.value, "island")
200-
201113
def test_package_public_api_methods(self):
202114
"""Test that expected public API methods exist"""
203115

204116
# Test that expected methods exist
205-
self.assertTrue(hasattr(GAPackageDef, 'allocate_pins'))
206117
self.assertTrue(hasattr(GAPackageDef, 'bringup_pins'))
207-
self.assertTrue(hasattr(GAPackageDef, 'heartbeat'))
208-
self.assertTrue(hasattr(GAPackageDef, '_power'))
209-
self.assertTrue(hasattr(GAPackageDef, '_jtag'))
210-
211-
# Test that these are callable or properties
212-
self.assertTrue(callable(GAPackageDef.allocate_pins))
213-
# bringup_pins, heartbeat, _power, _jtag are properties
214-
215-
def test_gapin_equality_operations(self):
216-
"""Test that GAPin equality works correctly"""
217-
pin1 = GAPin(h="A", w=1)
218-
pin2 = GAPin(h="A", w=1) # Duplicate
219-
pin3 = GAPin(h="B", w=2)
220-
221-
# Test that GAPin equality works correctly
222-
self.assertEqual(pin1, pin2) # pin1 and pin2 are equal
223-
self.assertNotEqual(pin1, pin3) # pin1 and pin3 are different
224-
self.assertNotEqual(pin2, pin3) # pin2 and pin3 are different
225-
226-
# Test that different coordinates create different pins
227-
self.assertNotEqual(GAPin(h="A", w=1), GAPin(h="A", w=2))
228-
self.assertNotEqual(GAPin(h="A", w=1), GAPin(h="B", w=1))
229-
230-
def test_gapin_string_representation(self):
231-
"""Test GAPin string representation"""
232-
pin = GAPin(h="A", w=1)
233-
234-
# Test that pin has reasonable string representation
235-
str_repr = str(pin)
236-
self.assertIn("A", str_repr)
237-
self.assertIn("1", str_repr)
238118

239119
def test_inheritance_from_basepackagedef(self):
240120
"""Test that GAPackageDef properly inherits from BasePackageDef"""
241-
from chipflow_lib.platforms._ import BasePackageDef
121+
from chipflow_lib.platforms._utils import BasePackageDef
242122

243123
# Test inheritance
244124
self.assertTrue(issubclass(GAPackageDef, BasePackageDef))

tests/test_pin_lock.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from amaranth.lib import io
88

99
from chipflow_lib import ChipFlowError
10-
from chipflow_lib.platforms._ import (
10+
from chipflow_lib.platforms._utils import (
1111
IOModel,
1212
Port,
1313
PortMap,
@@ -28,13 +28,13 @@ def __init__(self, name="test_package"):
2828
self._components = {}
2929
# Create mocks for the methods
3030
self.register_component = mock.MagicMock(side_effect=self._register_component)
31-
self.allocate_pins = mock.MagicMock()
32-
self.allocate = mock.MagicMock(side_effect=self._allocate)
31+
self._allocate_pins = mock.MagicMock()
32+
self._allocate = mock.MagicMock(side_effect=self._allocate)
3333
self.bringup_pins = mock.PropertyMock()
3434

3535
# Setup allocate_pins to return a mock LockFile
3636
mock_lockfile = mock.MagicMock()
37-
self.allocate_pins.return_value = mock_lockfile
37+
self._allocate_pins.return_value = mock_lockfile
3838

3939
def _register_component(self, name, component):
4040
"""Mock implementation of register_component"""
@@ -199,7 +199,7 @@ def test_lock_pins_new_lockfile(self, mock_lock_file, mock_package_defs,
199199

200200
# Verify the package definition was used
201201
mock_package_type.register_component.assert_called()
202-
mock_package_type.allocate_pins.assert_called()
202+
mock_package_type._allocate_pins.assert_called()
203203

204204
# Verify write was called with the JSON data
205205
file_handle = mock_open.return_value.__enter__.return_value

0 commit comments

Comments
 (0)