Skip to content

vendor.*: fix [io]_domain propagation when creating buffers. #1348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 5, 2024
Merged
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
32 changes: 16 additions & 16 deletions amaranth/lib/io.py
Original file line number Diff line number Diff line change
@@ -477,12 +477,16 @@ def __init__(self, direction, port, *, i_domain=None, o_domain=None):
super().__init__(FFBuffer.Signature(direction, len(port)).flip())
if self.signature.direction is not Direction.Output:
self._i_domain = i_domain or "sync"
elif i_domain is not None:
raise ValueError("Output buffer doesn't have an input domain")
else:
if i_domain is not None:
raise ValueError("Output buffer doesn't have an input domain")
self._i_domain = None
if self.signature.direction is not Direction.Input:
self._o_domain = o_domain or "sync"
elif o_domain is not None:
raise ValueError("Input buffer doesn't have an output domain")
else:
if o_domain is not None:
raise ValueError("Input buffer doesn't have an output domain")
self._o_domain = None
if port.direction is Direction.Input and self.direction is not Direction.Input:
raise ValueError(f"Input port cannot be used with {self.direction.name} buffer")
if port.direction is Direction.Output and self.direction is not Direction.Output:
@@ -498,14 +502,10 @@ def direction(self):

@property
def i_domain(self):
if self.direction is Direction.Output:
raise AttributeError("Output buffer doesn't have an input domain")
return self._i_domain

@property
def o_domain(self):
if self.direction is Direction.Input:
raise AttributeError("Input buffer doesn't have an output domain")
return self._o_domain

def elaborate(self, platform):
@@ -608,12 +608,16 @@ def __init__(self, direction, port, *, i_domain=None, o_domain=None):
super().__init__(DDRBuffer.Signature(direction, len(port)).flip())
if self.signature.direction is not Direction.Output:
self._i_domain = i_domain or "sync"
elif i_domain is not None:
raise ValueError("Output buffer doesn't have an input domain")
else:
if i_domain is not None:
raise ValueError("Output buffer doesn't have an input domain")
self._i_domain = None
if self.signature.direction is not Direction.Input:
self._o_domain = o_domain or "sync"
elif o_domain is not None:
raise ValueError("Input buffer doesn't have an output domain")
else:
if o_domain is not None:
raise ValueError("Input buffer doesn't have an output domain")
self._o_domain = None
if port.direction is Direction.Input and self.direction is not Direction.Input:
raise ValueError(f"Input port cannot be used with {self.direction.name} buffer")
if port.direction is Direction.Output and self.direction is not Direction.Output:
@@ -629,14 +633,10 @@ def direction(self):

@property
def i_domain(self):
if self.direction is Direction.Output:
raise AttributeError("Output buffer doesn't have an input domain")
return self._i_domain

@property
def o_domain(self):
if self.direction is Direction.Input:
raise AttributeError("Input buffer doesn't have an output domain")
return self._o_domain

def elaborate(self, platform):
8 changes: 6 additions & 2 deletions amaranth/vendor/_altera.py
Original file line number Diff line number Diff line change
@@ -475,9 +475,13 @@ def get_io_buffer(self, buffer):
if isinstance(buffer, io.Buffer):
result = IOBuffer(buffer.direction, buffer.port)
elif isinstance(buffer, io.FFBuffer):
result = FFBuffer(buffer.direction, buffer.port)
result = FFBuffer(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
elif isinstance(buffer, io.DDRBuffer):
result = DDRBuffer(buffer.direction, buffer.port)
result = DDRBuffer(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
else:
raise TypeError(f"Unsupported buffer type {buffer!r}") # :nocov:
if buffer.direction is not io.Direction.Output:
8 changes: 6 additions & 2 deletions amaranth/vendor/_gowin.py
Original file line number Diff line number Diff line change
@@ -543,9 +543,13 @@ def get_io_buffer(self, buffer):
if isinstance(buffer, io.Buffer):
result = IOBuffer(buffer.direction, buffer.port)
elif isinstance(buffer, io.FFBuffer):
result = FFBuffer(buffer.direction, buffer.port)
result = FFBuffer(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
elif isinstance(buffer, io.DDRBuffer):
result = DDRBuffer(buffer.direction, buffer.port)
result = DDRBuffer(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
else:
raise TypeError(f"Unsupported buffer type {buffer!r}") # :nocov:
if buffer.direction is not io.Direction.Output:
20 changes: 15 additions & 5 deletions amaranth/vendor/_lattice.py
Original file line number Diff line number Diff line change
@@ -998,18 +998,28 @@ def get_io_buffer(self, buffer):
result = IOBuffer(buffer.direction, buffer.port)
elif isinstance(buffer, io.FFBuffer):
if self.family in ("ecp5", "machxo2"):
result = FFBufferECP5(buffer.direction, buffer.port)
result = FFBufferECP5(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
elif self.family == "nexus":
result = FFBufferNexus(buffer.direction, buffer.port)
result = FFBufferNexus(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
else:
raise NotImplementedError # :nocov:
elif isinstance(buffer, io.DDRBuffer):
if self.family == "ecp5":
result = DDRBufferECP5(buffer.direction, buffer.port)
result = DDRBufferECP5(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
elif self.family == "machxo2":
result = DDRBufferMachXO2(buffer.direction, buffer.port)
result = DDRBufferMachXO2(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
elif self.family == "nexus":
result = DDRBufferNexus(buffer.direction, buffer.port)
result = DDRBufferNexus(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
else:
raise NotImplementedError # :nocov:
else:
20 changes: 15 additions & 5 deletions amaranth/vendor/_xilinx.py
Original file line number Diff line number Diff line change
@@ -1168,16 +1168,26 @@ def get_io_buffer(self, buffer):
if isinstance(buffer, io.Buffer):
result = IOBuffer(buffer.direction, buffer.port)
elif isinstance(buffer, io.FFBuffer):
result = FFBuffer(buffer.direction, buffer.port)
result = FFBuffer(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
elif isinstance(buffer, io.DDRBuffer):
if self.family in ("virtex2", "virtex2p", "spartan3"):
result = DDRBufferVirtex2(buffer.direction, buffer.port)
result = DDRBufferVirtex2(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
elif self.family in ("spartan3e", "spartan3a", "spartan3adsp", "spartan6"):
result = DDRBufferSpartan3E(buffer.direction, buffer.port)
result = DDRBufferSpartan3E(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
elif self.family in ("virtex4", "virtex5", "virtex6", "series7"):
result = DDRBufferVirtex4(buffer.direction, buffer.port)
result = DDRBufferVirtex4(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
elif self.family in ("ultrascale", "ultrascaleplus"):
result = DDRBufferUltrascale(buffer.direction, buffer.port)
result = DDRBufferUltrascale(buffer.direction, buffer.port,
i_domain=buffer.i_domain,
o_domain=buffer.o_domain)
else:
raise TypeError(f"Family {self.family} doesn't implement DDR buffers")
else:
16 changes: 4 additions & 12 deletions tests/test_lib_io.py
Original file line number Diff line number Diff line change
@@ -426,19 +426,15 @@ def test_construct(self):
self.assertIs(buf.port, port)
self.assertRepr(buf.signature, "FFBuffer.Signature(Direction.Input, 4).flip()")
self.assertEqual(buf.i_domain, "sync")
with self.assertRaisesRegex(AttributeError,
r"^Input buffer doesn't have an output domain$"):
buf.o_domain
self.assertIs(buf.o_domain, None)
buf = FFBuffer("i", port, i_domain="inp")
self.assertEqual(buf.i_domain, "inp")
buf = FFBuffer("o", port)
self.assertEqual(buf.direction, Direction.Output)
self.assertIs(buf.port, port)
self.assertRepr(buf.signature, "FFBuffer.Signature(Direction.Output, 4).flip()")
self.assertIs(buf.i_domain, None)
self.assertEqual(buf.o_domain, "sync")
with self.assertRaisesRegex(AttributeError,
r"^Output buffer doesn't have an input domain$"):
buf.i_domain
buf = FFBuffer("o", port, o_domain="out")
self.assertEqual(buf.o_domain, "out")
buf = FFBuffer("io", port)
@@ -668,19 +664,15 @@ def test_construct(self):
self.assertIs(buf.port, port)
self.assertRepr(buf.signature, "DDRBuffer.Signature(Direction.Input, 4).flip()")
self.assertEqual(buf.i_domain, "sync")
with self.assertRaisesRegex(AttributeError,
r"^Input buffer doesn't have an output domain$"):
buf.o_domain
self.assertIs(buf.o_domain, None)
buf = DDRBuffer("i", port, i_domain="inp")
self.assertEqual(buf.i_domain, "inp")
buf = DDRBuffer("o", port)
self.assertEqual(buf.direction, Direction.Output)
self.assertIs(buf.port, port)
self.assertRepr(buf.signature, "DDRBuffer.Signature(Direction.Output, 4).flip()")
self.assertIs(buf.i_domain, None)
self.assertEqual(buf.o_domain, "sync")
with self.assertRaisesRegex(AttributeError,
r"^Output buffer doesn't have an input domain$"):
buf.i_domain
buf = DDRBuffer("o", port, o_domain="out")
self.assertEqual(buf.o_domain, "out")
buf = DDRBuffer("io", port)