lib.io, build.res: Make Pin and related objects interfaces.

Fixes #1040.
This commit is contained in:
Wanda 2024-02-27 10:42:57 +01:00 committed by Catherine
parent c30585b47b
commit f524dd041a
4 changed files with 249 additions and 266 deletions

View file

@ -64,7 +64,7 @@ class ResourceManagerTestCase(FHDLTestCase):
user_led = self.cm.request("user_led", 0)
self.assertIsInstance(flipped(user_led), Pin)
self.assertEqual(user_led.name, "user_led_0")
self.assertEqual(user_led.o.name, "user_led_0__o")
self.assertEqual(user_led.width, 1)
self.assertEqual(user_led.dir, "o")
@ -77,12 +77,14 @@ class ResourceManagerTestCase(FHDLTestCase):
def test_request_with_dir(self):
i2c = self.cm.request("i2c", 0, dir={"sda": "o"})
self.assertIsInstance(i2c, Record)
self.assertIsInstance(i2c.sda, Pin)
self.assertIsInstance(i2c, PureInterface)
self.assertTrue(i2c.signature.is_compliant(i2c))
self.assertIsInstance(flipped(i2c.sda), Pin)
self.assertEqual(i2c.sda.dir, "o")
def test_request_tristate(self):
i2c = self.cm.request("i2c", 0)
self.assertTrue(i2c.signature.is_compliant(i2c))
self.assertEqual(i2c.sda.dir, "io")
ports = list(self.cm.iter_ports())
@ -92,11 +94,11 @@ class ResourceManagerTestCase(FHDLTestCase):
self.assertEqual(ports[1].width, 1)
scl_info, sda_info = self.cm.iter_single_ended_pins()
self.assertIs(flipped(scl_info[0]), i2c.scl)
self.assertIs(scl_info[0], i2c.scl)
self.assertIs(scl_info[1].io, scl)
self.assertEqual(scl_info[2], {})
self.assertEqual(scl_info[3], False)
self.assertIs(flipped(sda_info[0]), i2c.sda)
self.assertIs(sda_info[0], i2c.sda)
self.assertIs(sda_info[1].io, sda)
self.assertEqual(list(self.cm.iter_port_constraints()), [
@ -315,12 +317,3 @@ class ResourceManagerTestCase(FHDLTestCase):
(r"^Cannot add clock constraint on \(sig clk100_0__i\), which is already "
r"constrained to 100000000\.0 Hz$")):
self.cm.add_clock_constraint(clk100.i, 1e6)
def test_eq_deprecation(self):
user_led = self.cm.request("user_led", 0)
m = Module()
with self.assertWarns(DeprecationWarning):
m.d.sync += user_led.eq(1)
p = Pin(4, "o")
with self.assertWarns(DeprecationWarning):
m.d.sync += p.eq(1)

View file

@ -1,207 +1,201 @@
import warnings
from amaranth.hdl import *
with warnings.catch_warnings():
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
from amaranth.hdl.rec import *
from amaranth.sim import *
from amaranth.lib.io import *
from amaranth.lib.wiring import *
from .utils import *
class PinLayoutTestCase(FHDLTestCase):
def assertLayoutEqual(self, layout, expected):
casted_layout = {}
for name, (shape, dir) in layout.items():
casted_layout[name] = (Shape.cast(shape), dir)
self.assertEqual(casted_layout, expected)
class PinSignatureTestCase(FHDLTestCase):
def assertSignatureEqual(self, signature, expected):
self.assertEqual(signature.members, Signature(expected).members)
class PinLayoutCombTestCase(PinLayoutTestCase):
def test_pin_layout_i(self):
layout_1 = pin_layout(1, dir="i")
self.assertLayoutEqual(layout_1.fields, {
"i": (unsigned(1), DIR_NONE),
class PinSignatureCombTestCase(PinSignatureTestCase):
def test_signature_i(self):
sig_1 = Pin.Signature(1, dir="i")
self.assertSignatureEqual(sig_1, {
"i": In(1),
})
layout_2 = pin_layout(2, dir="i")
self.assertLayoutEqual(layout_2.fields, {
"i": (unsigned(2), DIR_NONE),
sig_2 = Pin.Signature(2, dir="i")
self.assertSignatureEqual(sig_2, {
"i": In(2),
})
def test_pin_layout_o(self):
layout_1 = pin_layout(1, dir="o")
self.assertLayoutEqual(layout_1.fields, {
"o": (unsigned(1), DIR_NONE),
def test_signature_o(self):
sig_1 = Pin.Signature(1, dir="o")
self.assertSignatureEqual(sig_1, {
"o": Out(1),
})
layout_2 = pin_layout(2, dir="o")
self.assertLayoutEqual(layout_2.fields, {
"o": (unsigned(2), DIR_NONE),
sig_2 = Pin.Signature(2, dir="o")
self.assertSignatureEqual(sig_2, {
"o": Out(2),
})
def test_pin_layout_oe(self):
layout_1 = pin_layout(1, dir="oe")
self.assertLayoutEqual(layout_1.fields, {
"o": (unsigned(1), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
def test_signature_oe(self):
sig_1 = Pin.Signature(1, dir="oe")
self.assertSignatureEqual(sig_1, {
"o": Out(1),
"oe": Out(1),
})
layout_2 = pin_layout(2, dir="oe")
self.assertLayoutEqual(layout_2.fields, {
"o": (unsigned(2), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
sig_2 = Pin.Signature(2, dir="oe")
self.assertSignatureEqual(sig_2, {
"o": Out(2),
"oe": Out(1),
})
def test_pin_layout_io(self):
layout_1 = pin_layout(1, dir="io")
self.assertLayoutEqual(layout_1.fields, {
"i": (unsigned(1), DIR_NONE),
"o": (unsigned(1), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
def test_signature_io(self):
sig_1 = Pin.Signature(1, dir="io")
self.assertSignatureEqual(sig_1, {
"i": In(1),
"o": Out(1),
"oe": Out(1),
})
layout_2 = pin_layout(2, dir="io")
self.assertLayoutEqual(layout_2.fields, {
"i": (unsigned(2), DIR_NONE),
"o": (unsigned(2), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
sig_2 = Pin.Signature(2, dir="io")
self.assertSignatureEqual(sig_2, {
"i": In(2),
"o": Out(2),
"oe": Out(1),
})
class PinLayoutSDRTestCase(PinLayoutTestCase):
def test_pin_layout_i(self):
layout_1 = pin_layout(1, dir="i", xdr=1)
self.assertLayoutEqual(layout_1.fields, {
"i_clk": (unsigned(1), DIR_NONE),
"i": (unsigned(1), DIR_NONE),
class PinSignatureSDRTestCase(PinSignatureTestCase):
def test_signature_i(self):
sig_1 = Pin.Signature(1, dir="i", xdr=1)
self.assertSignatureEqual(sig_1, {
"i_clk": Out(1),
"i": In(1),
})
layout_2 = pin_layout(2, dir="i", xdr=1)
self.assertLayoutEqual(layout_2.fields, {
"i_clk": (unsigned(1), DIR_NONE),
"i": (unsigned(2), DIR_NONE),
sig_2 = Pin.Signature(2, dir="i", xdr=1)
self.assertSignatureEqual(sig_2, {
"i_clk": Out(1),
"i": In(2),
})
def test_pin_layout_o(self):
layout_1 = pin_layout(1, dir="o", xdr=1)
self.assertLayoutEqual(layout_1.fields, {
"o_clk": (unsigned(1), DIR_NONE),
"o": (unsigned(1), DIR_NONE),
def test_signature_o(self):
sig_1 = Pin.Signature(1, dir="o", xdr=1)
self.assertSignatureEqual(sig_1, {
"o_clk": Out(1),
"o": Out(1),
})
layout_2 = pin_layout(2, dir="o", xdr=1)
self.assertLayoutEqual(layout_2.fields, {
"o_clk": (unsigned(1), DIR_NONE),
"o": (unsigned(2), DIR_NONE),
sig_2 = Pin.Signature(2, dir="o", xdr=1)
self.assertSignatureEqual(sig_2, {
"o_clk": Out(1),
"o": Out(2),
})
def test_pin_layout_oe(self):
layout_1 = pin_layout(1, dir="oe", xdr=1)
self.assertLayoutEqual(layout_1.fields, {
"o_clk": (unsigned(1), DIR_NONE),
"o": (unsigned(1), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
def test_signature_oe(self):
sig_1 = Pin.Signature(1, dir="oe", xdr=1)
self.assertSignatureEqual(sig_1, {
"o_clk": Out(1),
"o": Out(1),
"oe": Out(1),
})
layout_2 = pin_layout(2, dir="oe", xdr=1)
self.assertLayoutEqual(layout_2.fields, {
"o_clk": (unsigned(1), DIR_NONE),
"o": (unsigned(2), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
sig_2 = Pin.Signature(2, dir="oe", xdr=1)
self.assertSignatureEqual(sig_2, {
"o_clk": Out(1),
"o": Out(2),
"oe": Out(1),
})
def test_pin_layout_io(self):
layout_1 = pin_layout(1, dir="io", xdr=1)
self.assertLayoutEqual(layout_1.fields, {
"i_clk": (unsigned(1), DIR_NONE),
"i": (unsigned(1), DIR_NONE),
"o_clk": (unsigned(1), DIR_NONE),
"o": (unsigned(1), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
def test_signature_io(self):
sig_1 = Pin.Signature(1, dir="io", xdr=1)
self.assertSignatureEqual(sig_1, {
"i_clk": Out(1),
"i": In(1),
"o_clk": Out(1),
"o": Out(1),
"oe": Out(1),
})
layout_2 = pin_layout(2, dir="io", xdr=1)
self.assertLayoutEqual(layout_2.fields, {
"i_clk": (unsigned(1), DIR_NONE),
"i": (unsigned(2), DIR_NONE),
"o_clk": (unsigned(1), DIR_NONE),
"o": (unsigned(2), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
sig_2 = Pin.Signature(2, dir="io", xdr=1)
self.assertSignatureEqual(sig_2, {
"i_clk": Out(1),
"i": In(2),
"o_clk": Out(1),
"o": Out(2),
"oe": Out(1),
})
class PinLayoutDDRTestCase(PinLayoutTestCase):
def test_pin_layout_i(self):
layout_1 = pin_layout(1, dir="i", xdr=2)
self.assertLayoutEqual(layout_1.fields, {
"i_clk": (unsigned(1), DIR_NONE),
"i0": (unsigned(1), DIR_NONE),
"i1": (unsigned(1), DIR_NONE),
class PinSignatureDDRTestCase(PinSignatureTestCase):
def test_signature_i(self):
sig_1 = Pin.Signature(1, dir="i", xdr=2)
self.assertSignatureEqual(sig_1, {
"i_clk": Out(1),
"i0": In(1),
"i1": In(1),
})
layout_2 = pin_layout(2, dir="i", xdr=2)
self.assertLayoutEqual(layout_2.fields, {
"i_clk": (unsigned(1), DIR_NONE),
"i0": (unsigned(2), DIR_NONE),
"i1": (unsigned(2), DIR_NONE),
sig_2 = Pin.Signature(2, dir="i", xdr=2)
self.assertSignatureEqual(sig_2, {
"i_clk": Out(1),
"i0": In(2),
"i1": In(2),
})
def test_pin_layout_o(self):
layout_1 = pin_layout(1, dir="o", xdr=2)
self.assertLayoutEqual(layout_1.fields, {
"o_clk": (unsigned(1), DIR_NONE),
"o0": (unsigned(1), DIR_NONE),
"o1": (unsigned(1), DIR_NONE),
def test_signature_o(self):
sig_1 = Pin.Signature(1, dir="o", xdr=2)
self.assertSignatureEqual(sig_1, {
"o_clk": Out(1),
"o0": Out(1),
"o1": Out(1),
})
layout_2 = pin_layout(2, dir="o", xdr=2)
self.assertLayoutEqual(layout_2.fields, {
"o_clk": (unsigned(1), DIR_NONE),
"o0": (unsigned(2), DIR_NONE),
"o1": (unsigned(2), DIR_NONE),
sig_2 = Pin.Signature(2, dir="o", xdr=2)
self.assertSignatureEqual(sig_2, {
"o_clk": Out(1),
"o0": Out(2),
"o1": Out(2),
})
def test_pin_layout_oe(self):
layout_1 = pin_layout(1, dir="oe", xdr=2)
self.assertLayoutEqual(layout_1.fields, {
"o_clk": (unsigned(1), DIR_NONE),
"o0": (unsigned(1), DIR_NONE),
"o1": (unsigned(1), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
def test_signature_oe(self):
sig_1 = Pin.Signature(1, dir="oe", xdr=2)
self.assertSignatureEqual(sig_1, {
"o_clk": Out(1),
"o0": Out(1),
"o1": Out(1),
"oe": Out(1),
})
layout_2 = pin_layout(2, dir="oe", xdr=2)
self.assertLayoutEqual(layout_2.fields, {
"o_clk": (unsigned(1), DIR_NONE),
"o0": (unsigned(2), DIR_NONE),
"o1": (unsigned(2), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
sig_2 = Pin.Signature(2, dir="oe", xdr=2)
self.assertSignatureEqual(sig_2, {
"o_clk": Out(1),
"o0": Out(2),
"o1": Out(2),
"oe": Out(1),
})
def test_pin_layout_io(self):
layout_1 = pin_layout(1, dir="io", xdr=2)
self.assertLayoutEqual(layout_1.fields, {
"i_clk": (unsigned(1), DIR_NONE),
"i0": (unsigned(1), DIR_NONE),
"i1": (unsigned(1), DIR_NONE),
"o_clk": (unsigned(1), DIR_NONE),
"o0": (unsigned(1), DIR_NONE),
"o1": (unsigned(1), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
def test_signature_io(self):
sig_1 = Pin.Signature(1, dir="io", xdr=2)
self.assertSignatureEqual(sig_1, {
"i_clk": Out(1),
"i0": In(1),
"i1": In(1),
"o_clk": Out(1),
"o0": Out(1),
"o1": Out(1),
"oe": Out(1),
})
layout_2 = pin_layout(2, dir="io", xdr=2)
self.assertLayoutEqual(layout_2.fields, {
"i_clk": (unsigned(1), DIR_NONE),
"i0": (unsigned(2), DIR_NONE),
"i1": (unsigned(2), DIR_NONE),
"o_clk": (unsigned(1), DIR_NONE),
"o0": (unsigned(2), DIR_NONE),
"o1": (unsigned(2), DIR_NONE),
"oe": (unsigned(1), DIR_NONE),
sig_2 = Pin.Signature(2, dir="io", xdr=2)
self.assertSignatureEqual(sig_2, {
"i_clk": Out(1),
"i0": In(2),
"i1": In(2),
"o_clk": Out(1),
"o0": Out(2),
"o1": Out(2),
"oe": Out(1),
})
@ -211,3 +205,7 @@ class PinTestCase(FHDLTestCase):
self.assertEqual(pin.width, 2)
self.assertEqual(pin.dir, "io")
self.assertEqual(pin.xdr, 2)
self.assertEqual(pin.signature.width, 2)
self.assertEqual(pin.signature.dir, "io")
self.assertEqual(pin.signature.xdr, 2)