diff --git a/chipflow_digital_ip/io/__init__.py b/chipflow_digital_ip/io/__init__.py index a95c66e..8ce595c 100644 --- a/chipflow_digital_ip/io/__init__.py +++ b/chipflow_digital_ip/io/__init__.py @@ -1,7 +1,6 @@ from ._gpio import GPIOPeripheral from ._uart import UARTPeripheral -from ._i2c import I2CPeripheral, I2CSignature -from ._spi import SPIPeripheral, SPISignature +from ._i2c import I2CPeripheral +from ._spi import SPIPeripheral -__all__ = ['GPIOPeripheral', 'UARTPeripheral', 'I2CPeripheral', 'SPIPeripheral', - 'I2CSignature', 'SPISignature'] +__all__ = ['GPIOPeripheral', 'UARTPeripheral', 'I2CPeripheral', 'SPIPeripheral'] diff --git a/chipflow_digital_ip/io/_gpio.py b/chipflow_digital_ip/io/_gpio.py index ef1eb27..ae4ae94 100644 --- a/chipflow_digital_ip/io/_gpio.py +++ b/chipflow_digital_ip/io/_gpio.py @@ -1,4 +1,3 @@ -from typing import Unpack from amaranth import Module, unsigned from amaranth.lib import wiring @@ -6,26 +5,13 @@ from amaranth_soc import csr, gpio -from chipflow_lib.platforms import BidirIOSignature, IOModelOptions +from chipflow_lib.platforms import GPIOSignature __all__ = ["GPIOPeripheral"] class GPIOPeripheral(wiring.Component): - class Signature(wiring.Signature): - def __init__(self, pin_count=1, **kwargs: Unpack[IOModelOptions]): - if pin_count > 32: - raise ValueError(f"Pin pin_count must be lesser than or equal to 32, not {pin_count}") - self._pin_count = pin_count - super().__init__({ - "gpio": Out(BidirIOSignature(pin_count, individual_oe=True, **kwargs)) - }) - - @property - def pin_count(self): - return self._pin_count - """Wrapper for amaranth_soc gpio with chipflow_lib.IOSignature support Parameters @@ -58,6 +44,13 @@ def pin_count(self): """ def __init__(self, *, pin_count, addr_width=4, data_width=8, input_stages=2): + if type(pin_count) is not int: + raise TypeError(f"Pin count must be a positive integer, not {pin_count}") + + if pin_count > 32 or pin_count <= 0: + # TODO: why? + raise ValueError(f"Pin pin_count must be a postive integrer less than 32, not {pin_count}") + self._gpio = gpio.Peripheral(pin_count=pin_count, addr_width=addr_width, data_width=data_width, @@ -65,7 +58,7 @@ def __init__(self, *, pin_count, addr_width=4, data_width=8, input_stages=2): super().__init__({ "bus": In(csr.Signature(addr_width=addr_width, data_width=data_width)), - "pins": Out(self.Signature(pin_count)), + "pins": Out(GPIOSignature(pin_count)), "alt_mode": Out(unsigned(pin_count)), }) self.bus.memory_map = self._gpio.bus.memory_map diff --git a/chipflow_digital_ip/io/_i2c.py b/chipflow_digital_ip/io/_i2c.py index 7e02682..fa02ea0 100644 --- a/chipflow_digital_ip/io/_i2c.py +++ b/chipflow_digital_ip/io/_i2c.py @@ -3,15 +3,10 @@ from amaranth.lib.wiring import In, Out, connect, flipped from amaranth_soc import csr -from chipflow_lib.platforms import BidirIOSignature +from chipflow_lib.platforms import I2CSignature from ._glasgow_i2c import I2CInitiator -__all__ = ["I2CPeripheral", "I2CSignature"] - -I2CSignature = wiring.Signature({ - "scl": Out(BidirIOSignature(1)), - "sda": Out(BidirIOSignature(1)) - }) +__all__ = ["I2CPeripheral"] class I2CPeripheral(wiring.Component): @@ -61,7 +56,7 @@ def __init__(self): self._bridge = csr.Bridge(regs.as_memory_map()) super().__init__({ - "i2c_pins": Out(I2CSignature), + "i2c_pins": Out(I2CSignature()), "bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)), }) self.bus.memory_map = self._bridge.bus.memory_map diff --git a/chipflow_digital_ip/io/_spi.py b/chipflow_digital_ip/io/_spi.py index e6a083e..576f960 100644 --- a/chipflow_digital_ip/io/_spi.py +++ b/chipflow_digital_ip/io/_spi.py @@ -3,21 +3,14 @@ from amaranth.lib.wiring import In, Out, connect, flipped from amaranth_soc import csr -from chipflow_lib.platforms import InputIOSignature, OutputIOSignature +from chipflow_lib.platforms import SPISignature -__all__ = ["SPISignature", "SPIPeripheral"] - -SPISignature = wiring.Signature({ - "sck": Out(OutputIOSignature(1)), - "copi": Out(OutputIOSignature(1)), - "cipo": Out(InputIOSignature(1)), - "csn": Out(OutputIOSignature(1)), -}) +__all__ = ["SPIPeripheral"] class SPIController(wiring.Component): def __init__(self): super().__init__({ - "spi": Out(SPISignature), + "spi": Out(SPISignature()), "sck_idle": In(1), "sck_edge": In(1), "cs": In(1), @@ -157,7 +150,7 @@ def __init__(self): self._bridge = csr.Bridge(regs.as_memory_map()) super().__init__({ - "spi_pins": Out(SPISignature), + "spi_pins": Out(SPISignature()), "bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)), }) self.bus.memory_map = self._bridge.bus.memory_map diff --git a/chipflow_digital_ip/io/_uart.py b/chipflow_digital_ip/io/_uart.py index a92aa67..17b001f 100644 --- a/chipflow_digital_ip/io/_uart.py +++ b/chipflow_digital_ip/io/_uart.py @@ -5,7 +5,7 @@ from amaranth_soc import csr from amaranth_stdio.serial import AsyncSerialRX, AsyncSerialTX -from chipflow_lib.platforms import OutputIOSignature, InputIOSignature +from chipflow_lib.platforms import UARTSignature from . import _rfc_uart @@ -120,14 +120,6 @@ def elaborate(self, platform): class UARTPeripheral(wiring.Component): - class Signature(wiring.Signature): - def __init__(self): - super().__init__({ - "tx": Out(OutputIOSignature(1)), - "rx": Out(InputIOSignature(1)), - }) - - """Wrapper for amaranth_soc RFC UART with PHY and chipflow_lib.IOSignature support Parameters @@ -159,7 +151,7 @@ def __init__(self, *, addr_width=5, data_width=8, init_divisor=0): super().__init__({ "bus": In(csr.Signature(addr_width=addr_width, data_width=data_width)), - "pins": Out(self.Signature()), + "pins": Out(UARTSignature()), }) self.bus.memory_map = self._uart.bus.memory_map self._phy = UARTPhy(ports=self.pins, init_divisor=init_divisor) diff --git a/chipflow_digital_ip/memory/_qspi_flash.py b/chipflow_digital_ip/memory/_qspi_flash.py index 7b60b0b..eae4a57 100644 --- a/chipflow_digital_ip/memory/_qspi_flash.py +++ b/chipflow_digital_ip/memory/_qspi_flash.py @@ -9,7 +9,7 @@ from ..io._glasgow_iostream import PortGroup from ..memory._glasgow_qspi import QSPIMode, QSPIController -from chipflow_lib.platforms import BidirIOSignature, OutputIOSignature +from chipflow_lib.platforms import QSPIFlashSignature class QSPIFlashCommand(enum.Enum, shape=8): @@ -248,17 +248,9 @@ def elaborate(self, platform): return m class QSPIFlash(wiring.Component): - class Signature(wiring.Signature): - def __init__(self): - super().__init__({ - "clk": Out(OutputIOSignature(1)), - "csn": Out(OutputIOSignature(1)), - "d": Out(BidirIOSignature(4, individual_oe=True)), - }) - def __init__(self, *, addr_width, data_width): super().__init__({ - "pins": Out(self.Signature()), + "pins": Out(QSPIFlashSignature()), "csr_bus": In(csr.Signature(addr_width=4, data_width=8)), "wb_bus": In(wishbone.Signature(addr_width=addr_width, data_width=data_width, granularity=8)), }) diff --git a/tests/test_gpio.py b/tests/test_gpio.py index 2e423c2..da87ab4 100644 --- a/tests/test_gpio.py +++ b/tests/test_gpio.py @@ -3,8 +3,11 @@ # SPDX-License-Identifier: BSD-2-Clause import unittest +import warnings + from amaranth import * from amaranth.sim import * +from amaranth.hdl import UnusedElaboratable from chipflow_digital_ip.io import GPIOPeripheral @@ -24,11 +27,18 @@ def test_init(self): def test_init_wrong_pin_count(self): with self.assertRaisesRegex(TypeError, - r"Pin count must be a positive integer, not 'foo'"): + r"Pin count must be a positive integer, not foo"): GPIOPeripheral(pin_count="foo", addr_width=2, data_width=8) - with self.assertRaisesRegex(TypeError, - r"Pin count must be a positive integer, not 0"): + with self.assertRaisesRegex(ValueError, + r"Pin pin_count must be a postive integrer less than 32, not -1"): + GPIOPeripheral(pin_count=-1, addr_width=2, data_width=8) + with self.assertRaisesRegex(ValueError, + r"Pin pin_count must be a postive integrer less than 32, not 0"): GPIOPeripheral(pin_count=0, addr_width=2, data_width=8) + with self.assertRaisesRegex(ValueError, + r"Pin pin_count must be a postive integrer less than 32, not 33"): + GPIOPeripheral(pin_count=33, addr_width=2, data_width=8) + def test_init_wrong_input_stages(self): with self.assertRaisesRegex(TypeError, @@ -53,6 +63,9 @@ def test_smoke_test(self): """ Smoke test GPIO. We assume that amaranth-soc GPIO tests are fully testing functionality. """ + + warnings.simplefilter(action="ignore", category=UnusedElaboratable) + dut = GPIOPeripheral(pin_count=4, addr_width=2, data_width=8) mode_addr = 0x0