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
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
32 changes: 16 additions & 16 deletions amaranth/lib/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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):
Expand Down Expand Up @@ -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:
Expand All @@ -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):
Expand Down
8 changes: 6 additions & 2 deletions amaranth/vendor/_altera.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 6 additions & 2 deletions amaranth/vendor/_gowin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
20 changes: 15 additions & 5 deletions amaranth/vendor/_lattice.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
20 changes: 15 additions & 5 deletions amaranth/vendor/_xilinx.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
16 changes: 4 additions & 12 deletions tests/test_lib_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down