Skip to content

Commit 0f05c98

Browse files
committed
Clean up some issues
1 parent bc0a3c2 commit 0f05c98

File tree

1 file changed

+42
-46
lines changed

1 file changed

+42
-46
lines changed

chipflow_lib/platforms/utils.py

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,19 @@ class VoltageRange:
7272
"required": ["width", "signed", "value"]
7373
})
7474

75-
@with_config(ConfigDict(use_enum_values=True, arbitrary_types_allowed=True)) # type: ignore[reportCallIssue]
76-
class IOModel(TypedDict):
75+
76+
@with_config(ConfigDict(arbitrary_types_allowed=True)) # type: ignore[reportCallIssue]
77+
class _IOModelOptions(TypedDict):
78+
all_have_oe: NotRequired[bool]
79+
allocate_power: NotRequired[bool]
80+
power_voltage: NotRequired[VoltageRange]
81+
clock_domain_i: NotRequired[str]
82+
clock_domain_o: NotRequired[str]
83+
init: NotRequired[Annotated[Const, ConstSerializer, ConstSchema]]
84+
85+
86+
@with_config(ConfigDict(arbitrary_types_allowed=True)) # type: ignore[reportCallIssue]
87+
class IOModel(_IOModelOptions):
7788
"""
7889
Options for IO Ports
7990
Attributes:
@@ -89,19 +100,17 @@ class IOModel(TypedDict):
89100
init: a :ref:`Const` value for the initial values of the port
90101
"""
91102

92-
width: NotRequired[int]
103+
width: int
93104
direction: NotRequired[Annotated[io.Direction, PlainSerializer(lambda x: x.value)]]
94-
all_have_oe: NotRequired[bool]
95-
allocate_power: NotRequired[bool]
96-
power_voltage: NotRequired[VoltageRange]
97-
clock_domain_i: NotRequired[str]
98-
clock_domain_o: NotRequired[str]
99-
init: NotRequired[Annotated[Const, ConstSerializer, ConstSchema]]
100-
101105

102106
def io_annotation_schema():
107+
class Model(pydantic.BaseModel):
108+
data_td: IOModel
109+
print(Model.model_json_schema())
110+
103111
PydanticModel = TypeAdapter(IOModel)
104-
schema = PydanticModel.json_schema()
112+
#schema = PydanticModel.json_schema()
113+
schema = Model.model_json_schema()
105114
schema['$schema'] = "https://json-schema.org/draft/2020-12/schema"
106115
schema['$id'] = IO_ANNOTATION_SCHEMA
107116
return schema
@@ -184,45 +193,37 @@ def __repr__(self):
184193
return f"IOSignature({','.join('{0}={1!r}'.format(k,v) for k,v in self._model.items())})"
185194

186195

187-
def OutputIOSignature(width: int, **kwargs: Unpack[IOModel]): # type: ignore[reportGeneralTypeIssues]
196+
def OutputIOSignature(width: int, **kwargs: Unpack[_IOModelOptions]):
188197
"""This creates an :py:obj:`Amaranth Signature <amaranth.lib.wiring.Signature>` which is then used to decorate package output signals
189198
intended for connection to the physical pads of the integrated circuit package.
190199
191200
:param width: specifies the number of individual output wires within this port, each of which will correspond to a separate physical pad on the integrated circuit package.
192-
:type width: int
193-
:param init: a :ref:`const-castable object <lang-constcasting>` for the initial values of the port
194201
"""
195-
kwargs['width'] = width
196-
kwargs['direction'] = io.Direction.Output
197-
return IOSignature(**kwargs)
202+
model: IOModel = kwargs | {'width': width, 'direction': io.Direction.Output} # type: ignore[reportGeneralTypeIssues]
203+
return IOSignature(**model)
198204

199205

200-
def InputIOSignature(width:int, **kwargs: Unpack[IOModel]): # type: ignore[reportGeneralTypeIssues]
206+
def InputIOSignature(width: int, **kwargs: Unpack[_IOModelOptions]): # type: ignore[reportGeneralTypeIssues]
201207
"""This creates an :py:obj:`Amaranth Signature <amaranth.lib.wiring.Signature>` which is then used to decorate package input signals
202208
intended for connection to the physical pads of the integrated circuit package.
203209
204210
:param width: specifies the number of individual input wires within this port, each of which will correspond to a separate physical pad on the integrated circuit package.
205-
:type width: int
206-
:param init: a :ref:`const-castable object <lang-constcasting>` for the initial values of the port
207211
"""
208-
kwargs['width'] = width
209-
kwargs['direction'] = io.Direction.Input
210-
return IOSignature(**kwargs)
212+
213+
model: IOModel = kwargs | {'width': width, 'direction': io.Direction.Input} # type: ignore[reportGeneralTypeIssues]
214+
return IOSignature(**model)
211215

212216

213-
def BidirIOSignature(width:int , **kwargs: Unpack[IOModel]): # type: ignore[reportGeneralTypeIssues]
217+
def BidirIOSignature(width: int, **kwargs: Unpack[_IOModelOptions]): # type: ignore[reportGeneralTypeIssues]
214218
"""This creates an :py:obj:`Amaranth Signature <amaranth.lib.wiring.Signature>` which is then used to decorate package bi-directional signals
215219
intended for connection to the physical pads of the integrated circuit package.
216220
217221
:param width: specifies the number of individual input/output wires within this port. Each pair of input/output wires will correspond to a separate physical pad on the integrated circuit package.
218-
:type width: int
219-
:param all_have_oe: controls whether each output wire is associated with an individual Output Enable bit or a single OE bit will be used for entire port, the default value is False, indicating that a single OE bit controls the entire port.
220-
:type all_have_oe: bool, optional
221-
:param init: a :ref:`const-castable object <lang-constcasting>` for the initial values of the port
222222
"""
223-
kwargs['width'] = width
224-
kwargs['direction'] = io.Direction.Bidir
225-
return IOSignature(**kwargs)
223+
224+
225+
model: IOModel = kwargs | {'width': width, 'direction': io.Direction.Bidir} # type: ignore[reportGeneralTypeIssues]
226+
return IOSignature(**model)
226227

227228

228229
Pin = Union[Tuple[Any,...], str, int]
@@ -298,12 +299,13 @@ class Port(pydantic.BaseModel):
298299
type: str
299300
pins: List[Pin] | None # None implies must be allocated at end
300301
port_name: str
301-
direction: Optional[io.Direction] = None
302-
options: Optional[dict] = None
302+
iomodel: IOModel
303303

304304
@property
305305
def width(self):
306-
return len(self.pins) if self.pins else 0
306+
assert self.pins and 'width' in self.iomodel
307+
assert len(self.pins) == self.iomodel['width']
308+
return self.iomodel['width']
307309

308310

309311
def _group_consecutive_items(ordering: PinList, lst: PinList) -> OrderedDict[int, List[PinList]]:
@@ -406,14 +408,11 @@ def _allocate_pins(name: str, member: Dict[str, Any], pins: List[Pin], port_name
406408

407409
if member['type'] == 'interface' and 'annotations' in member \
408410
and IO_ANNOTATION_SCHEMA in member['annotations']:
409-
logger.debug("matched IOSignature {sig}")
410-
sig = member['annotations'][IO_ANNOTATION_SCHEMA]
411-
logger.debug(f"matched PinSignature {sig}")
411+
model:IOModel = member['annotations'][IO_ANNOTATION_SCHEMA]
412+
logger.debug(f"matched IOSignature {model}")
412413
name = name
413-
width = sig['width']
414-
pin_map[name] = {'pins': pins[0:width],
415-
'type': 'io',
416-
'port_name': port_name } | sig
414+
width = model['width']
415+
pin_map[name] = Port(pins=pins[0:width], type='io', port_name=port_name, iomodel=model)
417416
logger.debug(f"added '{name}':{pin_map[name]} to pin_map")
418417
return pin_map, pins[width:]
419418
elif member['type'] == 'interface':
@@ -426,11 +425,8 @@ def _allocate_pins(name: str, member: Dict[str, Any], pins: List[Pin], port_name
426425
elif member['type'] == 'port':
427426
logger.warning(f"Port '{name}' has no IOSignature, pin allocation likely to be wrong")
428427
width = member['width']
429-
pin_map[name] = {'pins': pins[0:width],
430-
'direction': member['dir'],
431-
'type': 'io',
432-
'port_name': port_name
433-
}
428+
model = IOModel(width=width, direction=io.Direction(member['dir']))
429+
pin_map[name] = Port(pins=pins[0:width], type='io', port_name=port_name, iomodel=model)
434430
logger.debug(f"added '{name}':{pin_map[name]} to pin_map")
435431
return pin_map, pins[width:]
436432
else:

0 commit comments

Comments
 (0)