Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions chipflow_digital_ip/io/__init__.py
Original file line number Diff line number Diff line change
@@ -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']
25 changes: 9 additions & 16 deletions chipflow_digital_ip/io/_gpio.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,17 @@
from typing import Unpack

from amaranth import Module, unsigned
from amaranth.lib import wiring
from amaranth.lib.wiring import In, Out, flipped, connect

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
Expand Down Expand Up @@ -58,14 +44,21 @@ 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,
input_stages=input_stages)

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
Expand Down
11 changes: 3 additions & 8 deletions chipflow_digital_ip/io/_i2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand Down
15 changes: 4 additions & 11 deletions chipflow_digital_ip/io/_spi.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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
Expand Down
12 changes: 2 additions & 10 deletions chipflow_digital_ip/io/_uart.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
12 changes: 2 additions & 10 deletions chipflow_digital_ip/memory/_qspi_flash.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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)),
})
Expand Down
19 changes: 16 additions & 3 deletions tests/test_gpio.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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,
Expand All @@ -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
Expand Down
Loading