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
2 changes: 2 additions & 0 deletions amaranth_orchard/base/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .platform_timer import *
from .soc_id import *
84 changes: 0 additions & 84 deletions amaranth_orchard/base/gpio.py

This file was deleted.

2 changes: 2 additions & 0 deletions amaranth_orchard/io/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .gpio import *
from .uart import *
92 changes: 92 additions & 0 deletions amaranth_orchard/io/gpio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
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 BidirPinSignature, PinSignature

__all__ = ["GPIOPeripheral"]


class GPIOPeripheral(wiring.Component):

class Signature(wiring.Signature):
def __init__(self, pin_count=1):
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(BidirPinSignature(pin_count, all_have_oe=True))
})

@property
def pin_count(self):
return self._pin_count

"""Wrapper for amaranth_soc gpio with chipflow_lib.PinSignature support

Parameters
----------
pin_count : :class:`int`
Number of GPIO pins.
addr_width : :class:`int`
CSR bus address width. Defaults to ``4``.
data_width : :class:`int`
CSR bus data width. Defaults to ``8``.
input_stages : :class:`int`
Number of synchronization stages between pin inputs and the :class:`~Peripheral.Input`
register. Optional. Defaults to ``2``.

Attributes
----------
bus : :class:`csr.Interface`
CSR bus interface providing access to registers.
pins : :class:`list` of :class:`wiring.PureInterface` of :class:`PinSignature`
GPIO pin interfaces.
alt_mode : :class:`Signal`
Indicates which members of the :attr:`Peripheral.pins` array are in alternate mode.

Raises
------
:exc:`TypeError`
If ``pin_count`` is not a positive integer.
:exc:`TypeError`
If ``input_stages`` is not a non-negative integer.
"""

def __init__(self, *, pin_count, addr_width=4, data_width=8, input_stages=2):
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)),
"alt_mode": Out(unsigned(pin_count)),
})
self.bus.memory_map = self._gpio.bus.memory_map

def elaborate(self, platform):
m = Module()
m.submodules._gpio = gpio = self._gpio

connect(m, flipped(self.bus), self._gpio.bus)
for i in range(self._gpio.pin_count):
# m.d.comb += self.pins.gpio.i[i].eq(self._gpio.pins[i].i)
# m.d.comb += self._gpio.pins[i].o.eq(self.pins.gpio.o[i])
# m.d.comb += self._gpio.pins[i].oe.eq(self.pins.gpio.oe[i])
m.d.comb += self._gpio.pins[i].i.eq(self.pins.gpio.i[i])
m.d.comb += self.pins.gpio.o[i].eq(self._gpio.pins[i].o)
m.d.comb += self.pins.gpio.oe[i].eq(self._gpio.pins[i].oe)

return m

@property
def pin_count(self):
return self._gpio.pin_count

@property
def input_stages(self):
return self._gpio.input_stages
33 changes: 15 additions & 18 deletions amaranth_orchard/io/uart.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
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"]

__all__ = ["UARTPeripheral"]

class UARTPins(wiring.PureInterface):

class UARTPeripheral(wiring.Component):
class Signature(wiring.Signature):
def __init__(self):
super().__init__({
"tx_o": Out(1),
"rx_i": In(1),
"tx": Out(OutputPinSignature(1)),
"rx": Out(InputPinSignature(1)),
})

def create(self, *, path=(), src_loc_at=0):
return UARTPins(path=path, src_loc_at=1 + src_loc_at)

def __init__(self, *, path=(), src_loc_at=0):
super().__init__(self.Signature(), path=path, src_loc_at=1 + src_loc_at)


class UARTPeripheral(wiring.Component):
class TxData(csr.Register, access="w"):
"""valid to write to when tx_rdy is 1, will trigger a transmit"""
val: csr.Field(csr.action.W, unsigned(8))
Expand Down Expand Up @@ -53,22 +50,22 @@ def __init__(self, init_divisor):

TODO: Interrupts support, perhaps mimic something with upstream Linux kernel support...
"""
def __init__(self, *, init_divisor, pins):
def __init__(self, *, init_divisor):
self.init_divisor = init_divisor
self.pins = pins

regs = csr.Builder(addr_width=5, data_width=8)

self._tx_data = regs.add("tx_data", self.TxData(), offset=0x00)
self._rx_data = regs.add("rx_data", self.RxData(), offset=0x04)
self._tx_rdy = regs.add("tx_rdy", self.TxReady(), offset=0x08)
self._tx_data = regs.add("tx_data", self.TxData(), offset=0x00)
self._rx_data = regs.add("rx_data", self.RxData(), offset=0x04)
self._tx_rdy = regs.add("tx_rdy", self.TxReady(), offset=0x08)
self._rx_avail = regs.add("rx_avail", self.RxAvail(), offset=0x0c)
self._divisor = regs.add("divisor", self.Divisor(init_divisor), offset=0x10)
self._divisor = regs.add("divisor", self.Divisor(init_divisor), offset=0x10)

self._bridge = csr.Bridge(regs.as_memory_map())

super().__init__({
"bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)),
"pins": Out(self.Signature()),
})
self.bus.memory_map = self._bridge.bus.memory_map

Expand All @@ -80,7 +77,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),
Expand All @@ -102,7 +99,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),
Expand Down
3 changes: 3 additions & 0 deletions amaranth_orchard/memory/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .hyperram import * # noqa
from .spimemio import * # noqa
from .sram import * # noqa
Loading