Skip to content

Commit 5f6ee18

Browse files
committed
Remove all passing of pins to constructor and add test for gpio
1 parent 537c3ca commit 5f6ee18

File tree

9 files changed

+473
-203
lines changed

9 files changed

+473
-203
lines changed

amaranth_orchard/base/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .platform_timer import *
2+
from .soc_id import *

amaranth_orchard/base/gpio.py

Lines changed: 0 additions & 84 deletions
This file was deleted.

amaranth_orchard/io/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .gpio import *
2+
from .uart import *

amaranth_orchard/io/gpio.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
from amaranth import Module, unsigned
2+
from amaranth.lib import wiring
3+
from amaranth.lib.wiring import In, Out, flipped, connect
4+
5+
from amaranth_soc import csr, gpio
6+
7+
from chipflow_lib.platforms import BidirPinSignature, PinSignature
8+
9+
__all__ = ["GPIOPeripheral"]
10+
11+
12+
class GPIOPeripheral(wiring.Component):
13+
14+
class Signature(wiring.Signature):
15+
def __init__(self, pin_count=1):
16+
if pin_count > 32:
17+
raise ValueError(f"Pin pin_count must be lesser than or equal to 32, not {pin_count}")
18+
self._pin_count = pin_count
19+
super().__init__({
20+
"gpio": Out(BidirPinSignature(pin_count, all_have_oe=True))
21+
})
22+
23+
@property
24+
def pin_count(self):
25+
return self._pin_count
26+
27+
"""Wrapper for amaranth_soc gpio with chipflow_lib.PinSignature support
28+
29+
Parameters
30+
----------
31+
pin_count : :class:`int`
32+
Number of GPIO pins.
33+
addr_width : :class:`int`
34+
CSR bus address width. Defaults to ``4``.
35+
data_width : :class:`int`
36+
CSR bus data width. Defaults to ``8``.
37+
input_stages : :class:`int`
38+
Number of synchronization stages between pin inputs and the :class:`~Peripheral.Input`
39+
register. Optional. Defaults to ``2``.
40+
41+
Attributes
42+
----------
43+
bus : :class:`csr.Interface`
44+
CSR bus interface providing access to registers.
45+
pins : :class:`list` of :class:`wiring.PureInterface` of :class:`PinSignature`
46+
GPIO pin interfaces.
47+
alt_mode : :class:`Signal`
48+
Indicates which members of the :attr:`Peripheral.pins` array are in alternate mode.
49+
50+
Raises
51+
------
52+
:exc:`TypeError`
53+
If ``pin_count`` is not a positive integer.
54+
:exc:`TypeError`
55+
If ``input_stages`` is not a non-negative integer.
56+
"""
57+
58+
def __init__(self, *, pin_count, addr_width=4, data_width=8, input_stages=2):
59+
self._gpio = gpio.Peripheral(pin_count=pin_count,
60+
addr_width=addr_width,
61+
data_width=data_width,
62+
input_stages=input_stages)
63+
64+
super().__init__({
65+
"bus": In(csr.Signature(addr_width=addr_width, data_width=data_width)),
66+
"pins": Out(self.Signature(pin_count)),
67+
"alt_mode": Out(unsigned(pin_count)),
68+
})
69+
self.bus.memory_map = self._gpio.bus.memory_map
70+
71+
def elaborate(self, platform):
72+
m = Module()
73+
m.submodules._gpio = gpio = self._gpio
74+
75+
connect(m, flipped(self.bus), self._gpio.bus)
76+
for i in range(self._gpio.pin_count):
77+
# m.d.comb += self.pins.gpio.i[i].eq(self._gpio.pins[i].i)
78+
# m.d.comb += self._gpio.pins[i].o.eq(self.pins.gpio.o[i])
79+
# m.d.comb += self._gpio.pins[i].oe.eq(self.pins.gpio.oe[i])
80+
m.d.comb += self._gpio.pins[i].i.eq(self.pins.gpio.i[i])
81+
m.d.comb += self.pins.gpio.o[i].eq(self._gpio.pins[i].o)
82+
m.d.comb += self.pins.gpio.oe[i].eq(self._gpio.pins[i].oe)
83+
84+
return m
85+
86+
@property
87+
def pin_count(self):
88+
return self._gpio.pin_count
89+
90+
@property
91+
def input_stages(self):
92+
return self._gpio.input_stages

amaranth_orchard/io/uart.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,20 @@
88
from chipflow_lib.platforms import OutputPinSignature, InputPinSignature
99

1010

11-
__all__ = ["UARTPins", "UARTPeripheral"]
11+
__all__ = ["UARTPeripheral"]
1212

1313

14-
class UARTPins(wiring.PureInterface):
14+
class UARTPeripheral(wiring.Component):
1515
class Signature(wiring.Signature):
1616
def __init__(self):
1717
super().__init__({
1818
"tx": Out(OutputPinSignature(1)),
1919
"rx": Out(InputPinSignature(1)),
2020
})
2121

22-
def create(self, *, path=(), src_loc_at=0):
23-
return UARTPins(path=path, src_loc_at=1 + src_loc_at)
24-
2522
def __init__(self, *, path=(), src_loc_at=0):
2623
super().__init__(self.Signature(), path=path, src_loc_at=1 + src_loc_at)
2724

28-
29-
class UARTPeripheral(wiring.Component):
3025
class TxData(csr.Register, access="w"):
3126
"""valid to write to when tx_rdy is 1, will trigger a transmit"""
3227
val: csr.Field(csr.action.W, unsigned(8))
@@ -55,22 +50,22 @@ def __init__(self, init_divisor):
5550
5651
TODO: Interrupts support, perhaps mimic something with upstream Linux kernel support...
5752
"""
58-
def __init__(self, *, init_divisor, pins):
53+
def __init__(self, *, init_divisor):
5954
self.init_divisor = init_divisor
60-
self.pins = pins
6155

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

64-
self._tx_data = regs.add("tx_data", self.TxData(), offset=0x00)
65-
self._rx_data = regs.add("rx_data", self.RxData(), offset=0x04)
66-
self._tx_rdy = regs.add("tx_rdy", self.TxReady(), offset=0x08)
58+
self._tx_data = regs.add("tx_data", self.TxData(), offset=0x00)
59+
self._rx_data = regs.add("rx_data", self.RxData(), offset=0x04)
60+
self._tx_rdy = regs.add("tx_rdy", self.TxReady(), offset=0x08)
6761
self._rx_avail = regs.add("rx_avail", self.RxAvail(), offset=0x0c)
68-
self._divisor = regs.add("divisor", self.Divisor(init_divisor), offset=0x10)
62+
self._divisor = regs.add("divisor", self.Divisor(init_divisor), offset=0x10)
6963

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

7266
super().__init__({
7367
"bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)),
68+
"pins": Out(self.Signature()),
7469
})
7570
self.bus.memory_map = self._bridge.bus.memory_map
7671

0 commit comments

Comments
 (0)