diff --git a/amaranth_orchard/base/gpio.py b/amaranth_orchard/base/gpio.py index 4910f9d..7177016 100644 --- a/amaranth_orchard/base/gpio.py +++ b/amaranth_orchard/base/gpio.py @@ -1,9 +1,10 @@ -from amaranth import * +from amaranth import Module, unsigned from amaranth.lib import wiring from amaranth.lib.wiring import In, Out, flipped, connect from amaranth_soc import csr +from chipflow_lib.platforms import BidirPinSignature __all__ = ["GPIOPins", "GPIOPeripheral"] @@ -11,12 +12,13 @@ class GPIOPins(wiring.PureInterface): class Signature(wiring.Signature): def __init__(self, width): + if width > 32: + raise ValueError(f"Pin width must be lesser than or equal to 32, not {width}") self._width = width - super().__init__({ - "o": Out(unsigned(width)), - "oe": Out(unsigned(width)), - "i": In(unsigned(width)), - }) + super().__init__( + # each pin has seperate output enable + {f"gpio{n}":Out(BidirPinSignature(1)) for n in range(width)} + ) @property def width(self): @@ -27,6 +29,10 @@ def create(self, *, path=(), src_loc_at=0): def __init__(self, width, *, path=(), src_loc_at=0): super().__init__(self.Signature(width), path=path, src_loc_at=1 + src_loc_at) + + @property + def width(self): + return self.signature.width class GPIOPeripheral(wiring.Component): @@ -45,16 +51,13 @@ class DI(csr.Register, access="r"): def __init__(self, width): super().__init__({"pins": csr.Field(csr.action.R, unsigned(width))}) - """Simple GPIO peripheral. + def __init__(self, *, pins: GPIOPins): + """Simple GPIO peripheral. - All pins default to input at power up. - """ - def __init__(self, *, pins): - if len(pins.o) > 32: - raise ValueError(f"Pin width must be lesser than or equal to 32, not {len(pins.o)}") - - self.width = len(pins.o) - self.pins = pins + All pins default to input at power up. + """ + self.width = pins.width + self.pins = pins regs = csr.Builder(addr_width=4, data_width=8) @@ -75,10 +78,8 @@ def elaborate(self, platform): connect(m, flipped(self.bus), self._bridge.bus) - m.d.comb += [ - self.pins.o .eq(self._do.f.pins.data), - self.pins.oe.eq(self._oe.f.pins.data), - ] - m.d.sync += self._di.f.pins.r_data.eq(self.pins.i) + m.d.comb += [ getattr(self.pins, f"gpio{n}").o.eq(self._do.f.pins.data[n]) for n in range(self.width)] + m.d.comb += [ getattr(self.pins, f"gpio{n}").oe.eq(self._oe.f.pins.data[n]) for n in range(self.width)] + m.d.comb += [ self._di.f.pins.r_data[n].eq(getattr(self.pins, f"gpio{n}").i) for n in range(self.width)] return m diff --git a/amaranth_orchard/io/uart.py b/amaranth_orchard/io/uart.py index dec89d9..bab4152 100644 --- a/amaranth_orchard/io/uart.py +++ b/amaranth_orchard/io/uart.py @@ -1,10 +1,12 @@ -from amaranth import * +from amaranth import Module, Signal, unsigned from amaranth.lib import wiring from amaranth.lib.wiring import In, Out, flipped, connect from amaranth_soc import csr from amaranth_stdio.serial import AsyncSerialRX, AsyncSerialTX +from chipflow_lib.platforms import OutputPinSignature, InputPinSignature + __all__ = ["UARTPins", "UARTPeripheral"] @@ -13,8 +15,8 @@ class UARTPins(wiring.PureInterface): class Signature(wiring.Signature): def __init__(self): super().__init__({ - "tx_o": Out(1), - "rx_i": In(1), + "tx": Out(OutputPinSignature(1)), + "rx": In(InputPinSignature(1)), }) def create(self, *, path=(), src_loc_at=0): @@ -80,7 +82,7 @@ def elaborate(self, platform): m.submodules.tx = tx = AsyncSerialTX(divisor=self.init_divisor, divisor_bits=24) m.d.comb += [ - self.pins.tx_o.eq(tx.o), + self.pins.tx.o.eq(tx.o), tx.data.eq(self._tx_data.f.val.w_data), tx.ack.eq(self._tx_data.f.val.w_stb), self._tx_rdy.f.val.r_data.eq(tx.rdy), @@ -102,7 +104,7 @@ def elaborate(self, platform): ] m.d.comb += [ - rx.i.eq(self.pins.rx_i), + rx.i.eq(self.pins.rx.i), rx.ack.eq(~rx_avail), rx.divisor.eq(self._divisor.f.val.data), self._rx_data.f.val.r_data.eq(rx_buf), diff --git a/amaranth_orchard/memory/hyperram.py b/amaranth_orchard/memory/hyperram.py index 61b3d25..a3283d7 100644 --- a/amaranth_orchard/memory/hyperram.py +++ b/amaranth_orchard/memory/hyperram.py @@ -7,14 +7,15 @@ from amaranth import * from amaranth.lib import wiring -from amaranth.lib.wiring import In, Out, connect, flipped +from amaranth.lib.wiring import Out, connect, flipped from amaranth.utils import ceil_log2 -from amaranth.sim import * +from amaranth.sim import Simulator from amaranth_soc import csr, wishbone from amaranth_soc.memory import MemoryMap +from chipflow_lib.platforms import BidirPinSignature, OutputPinSignature __all__ = ["HyperRAMPins", "HyperRAM"] @@ -24,15 +25,11 @@ class Signature(wiring.Signature): def __init__(self, *, cs_count=1): self.cs_count = cs_count super().__init__({ - "clk_o": Out(1), - "csn_o": Out(cs_count), - "rstn_o": Out(1), - "rwds_o": Out(1), - "rwds_oe": Out(1), - "rwds_i": In(1), - "dq_o": Out(8), - "dq_oe": Out(8), - "dq_i": In(8), + "clk": Out(OutputPinSignature(1)), + "csn": Out(OutputPinSignature(cs_count)), + "rstn": Out(OutputPinSignature(1)), + "rwds": Out(BidirPinSignature(1)), + "dq": Out(BidirPinSignature(1)), }) def create(self, *, path=(), src_loc_at=0): @@ -104,7 +101,6 @@ def elaborate(self, platform): # Data shift register sr = Signal(48) - sr_shift = Signal() # Whether or not we need to apply x2 latency x2_lat = Signal() diff --git a/amaranth_orchard/memory/spimemio.py b/amaranth_orchard/memory/spimemio.py index 9731f58..ec1928b 100644 --- a/amaranth_orchard/memory/spimemio.py +++ b/amaranth_orchard/memory/spimemio.py @@ -7,6 +7,7 @@ from amaranth_soc import csr, wishbone from amaranth_soc.memory import MemoryMap +from chipflow_lib.platforms import BidirPinSignature,OutputPinSignature __all__ = ["QSPIPins", "SPIMemIO"] @@ -15,12 +16,10 @@ class QSPIPins(wiring.PureInterface): class Signature(wiring.Signature): def __init__(self): super().__init__({ - "clk_o": Out(1), - "csn_o": Out(1), - "d_o": Out(4), - "d_oe": Out(4), - "d_i": In(4), - }) + "clk": Out(OutputPinSignature(1)), + "csn": Out(OutputPinSignature(1)), + } | + {f"d{n}": Out(BidirPinSignature(1)) for n in range(4)}) def create(self, *, path=(), src_loc_at=0): return QSPIPins(path=path, src_loc_at=1 + src_loc_at) @@ -63,6 +62,7 @@ def __init__(self, mem_name=("mem",), cfg_name=("cfg",), *, flash): size_words = (self.size * 8) // 32 super().__init__({ + "qspi": Out(QSPIPins.Signature()), "ctrl_bus": In(csr.Signature(addr_width=exact_log2(4), data_width=8)), "data_bus": In(wishbone.Signature(addr_width=exact_log2(size_words), data_width=32, granularity=8)), @@ -85,32 +85,28 @@ def elaborate(self, platform): spi_ready = Signal() # TODO : QSPI - m.submodules.spimemio = Instance( - "spimemio", - i_clk=ClockSignal(), - i_resetn=~ResetSignal(), - i_valid=self.data_bus.cyc & self.data_bus.stb, - o_ready=spi_ready, - i_addr=Cat(Const(0, 2), self.data_bus.adr), # Hack to force a 1MB offset - o_rdata=self.data_bus.dat_r, - o_flash_csb=self.flash.csn_o, - o_flash_clk=self.flash.clk_o, - o_flash_io0_oe=self.flash.d_oe[0], - o_flash_io1_oe=self.flash.d_oe[1], - o_flash_io2_oe=self.flash.d_oe[2], - o_flash_io3_oe=self.flash.d_oe[3], - o_flash_io0_do=self.flash.d_o[0], - o_flash_io1_do=self.flash.d_o[1], - o_flash_io2_do=self.flash.d_o[2], - o_flash_io3_do=self.flash.d_o[3], - i_flash_io0_di=self.flash.d_i[0], - i_flash_io1_di=self.flash.d_i[1], - i_flash_io2_di=self.flash.d_i[2], - i_flash_io3_di=self.flash.d_i[3], - i_cfgreg_we=ctrl_bridge.cfgreg_we, - i_cfgreg_di=ctrl_bridge.cfgreg_di, - o_cfgreg_do=ctrl_bridge.cfgreg_do, - ) + verilog_map = { + "i_clk": ClockSignal(), + "i_resetn": ~ResetSignal(), + "i_valid": self.data_bus.cyc & self.data_bus.stb, + "o_ready": spi_ready, + "i_addr": Cat(Const(0, 2), self.data_bus.adr), # Hack to force a 1MB offset + "o_rdata": self.data_bus.dat_r, + "o_flash_csb": self.qspi.csn.o, + "o_flash_clk": self.qspi.clk.o, + "i_cfgreg_we": ctrl_bridge.cfgreg_we, + "i_cfgreg_di": ctrl_bridge.cfgreg_di, + "o_cfgreg_do": ctrl_bridge.cfgreg_do, + } | { + f"o_flash_io{n}_oe": getattr(self.qspi, f"d{n}").oe for n in range(4) + } | { + f"o_flash_io{n}_o": getattr(self.qspi, f"d{n}").o for n in range(4) + } | { + f"o_flash_io{n}_i": getattr(self.qspi, f"d{n}").i for n in range(4) + } + + m.submodules.spimemio = Instance("spimemio", **verilog_map) + # From https://github.com/im-tomu/foboot/blob/master/hw/rtl/picorvspi.py read_active = Signal() with m.If(self.data_bus.stb & self.data_bus.cyc & ~read_active): @@ -123,7 +119,7 @@ def elaborate(self, platform): m.d.sync += self.data_bus.ack.eq(0) if platform is not None: - path = Path(__file__).parent / f"verilog/spimemio.v" + path = Path(__file__).parent / "verilog/spimemio.v" with open(path, 'r') as f: platform.add_file(path.name, f) diff --git a/pyproject.toml b/pyproject.toml index 4b9e5f8..240704a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,9 +13,12 @@ authors = [ readme = {file = "README.md", content-type = "text/markdown"} license = {file = "LICENSE.txt"} -requires-python = "~=3.8" +requires-python = ">=3.10" dependencies = [ - "amaranth>=0.5,<0.7", + "amaranth>=0.5,<0.6", + "chipflow-lib @ git+https://github.com/ChipFlow/chipflow-lib.git", + "amaranth-soc @ git+https://github.com/amaranth-lang/amaranth-soc", + "amaranth-stdio @ git+https://github.com/amaranth-lang/amaranth-stdio", ] # Build system configuration @@ -25,3 +28,13 @@ requires = ["pdm-backend"] build-backend = "pdm.backend" # Development workflow configuration + +[tool.pyright] +diagnosticMode=false +typeCheckingMode = "off" +reportInvalidTypeForm = false +reportMissingImports = false +reportUnboundVariable = false + +[tool.ruff.lint] +ignore = ['F403', 'F405']