hdl.mem,lib.fifo: use keyword-only arguments for memory geometry.
Fixes #230.
This commit is contained in:
parent
1aeb11d7e3
commit
bc53bbf564
|
@ -1,6 +1,7 @@
|
||||||
from ...tools import deprecated, extend
|
from ...tools import deprecated, extend
|
||||||
from ...lib.fifo import FIFOInterface as NativeFIFOInterface, \
|
from ...lib.fifo import (FIFOInterface as NativeFIFOInterface,
|
||||||
SyncFIFO, SyncFIFOBuffered, AsyncFIFO, AsyncFIFOBuffered
|
SyncFIFO as NativeSyncFIFO, SyncFIFOBuffered as NativeSyncFIFOBuffered,
|
||||||
|
AsyncFIFO as NativeAsyncFIFO, AsyncFIFOBuffered as NativeAsyncFIFOBuffered)
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["_FIFOInterface", "SyncFIFO", "SyncFIFOBuffered", "AsyncFIFO", "AsyncFIFOBuffered"]
|
__all__ = ["_FIFOInterface", "SyncFIFO", "SyncFIFOBuffered", "AsyncFIFO", "AsyncFIFOBuffered"]
|
||||||
|
@ -9,13 +10,10 @@ __all__ = ["_FIFOInterface", "SyncFIFO", "SyncFIFOBuffered", "AsyncFIFO", "Async
|
||||||
class CompatFIFOInterface(NativeFIFOInterface):
|
class CompatFIFOInterface(NativeFIFOInterface):
|
||||||
@deprecated("attribute `fwft` must be provided to FIFOInterface constructor")
|
@deprecated("attribute `fwft` must be provided to FIFOInterface constructor")
|
||||||
def __init__(self, width, depth):
|
def __init__(self, width, depth):
|
||||||
super().__init__(width, depth, fwft=False)
|
super().__init__(width=width, depth=depth, fwft=False)
|
||||||
del self.fwft
|
del self.fwft
|
||||||
|
|
||||||
|
|
||||||
_FIFOInterface = CompatFIFOInterface
|
|
||||||
|
|
||||||
|
|
||||||
@extend(NativeFIFOInterface)
|
@extend(NativeFIFOInterface)
|
||||||
def read(self):
|
def read(self):
|
||||||
"""Read method for simulation."""
|
"""Read method for simulation."""
|
||||||
|
@ -36,3 +34,30 @@ def write(self, data):
|
||||||
yield
|
yield
|
||||||
yield self.w_en.eq(0)
|
yield self.w_en.eq(0)
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
class CompatSyncFIFO(NativeSyncFIFO):
|
||||||
|
def __init__(self, width, depth, fwft=True):
|
||||||
|
super().__init__(width=width, depth=depth, fwft=fwft)
|
||||||
|
|
||||||
|
|
||||||
|
class CompatSyncFIFOBuffered(NativeSyncFIFOBuffered):
|
||||||
|
def __init__(self, width, depth):
|
||||||
|
super().__init__(width=width, depth=depth)
|
||||||
|
|
||||||
|
|
||||||
|
class CompatAsyncFIFO(NativeAsyncFIFO):
|
||||||
|
def __init__(self, width, depth):
|
||||||
|
super().__init__(width=width, depth=depth)
|
||||||
|
|
||||||
|
|
||||||
|
class CompatAsyncFIFOBuffered(NativeAsyncFIFOBuffered):
|
||||||
|
def __init__(self, width, depth):
|
||||||
|
super().__init__(width=width, depth=depth)
|
||||||
|
|
||||||
|
|
||||||
|
_FIFOInterface = CompatFIFOInterface
|
||||||
|
SyncFIFO = CompatSyncFIFO
|
||||||
|
SyncFIFOBuffered = CompatSyncFIFOBuffered
|
||||||
|
AsyncFIFO = CompatAsyncFIFO
|
||||||
|
AsyncFIFOBuffered = CompatAsyncFIFOBuffered
|
||||||
|
|
|
@ -9,7 +9,7 @@ __all__ = ["Memory", "ReadPort", "WritePort", "DummyPort"]
|
||||||
|
|
||||||
|
|
||||||
class Memory:
|
class Memory:
|
||||||
def __init__(self, width, depth, *, init=None, name=None, simulate=True):
|
def __init__(self, *, width, depth, init=None, name=None, simulate=True):
|
||||||
if not isinstance(width, int) or width < 0:
|
if not isinstance(width, int) or width < 0:
|
||||||
raise TypeError("Memory width must be a non-negative integer, not '{!r}'"
|
raise TypeError("Memory width must be a non-negative integer, not '{!r}'"
|
||||||
.format(width))
|
.format(width))
|
||||||
|
|
|
@ -60,7 +60,7 @@ class FIFOInterface:
|
||||||
w_attributes="",
|
w_attributes="",
|
||||||
r_attributes="")
|
r_attributes="")
|
||||||
|
|
||||||
def __init__(self, width, depth, *, fwft):
|
def __init__(self, *, width, depth, fwft):
|
||||||
if not isinstance(width, int) or width < 0:
|
if not isinstance(width, int) or width < 0:
|
||||||
raise TypeError("FIFO width must be a non-negative integer, not '{!r}'"
|
raise TypeError("FIFO width must be a non-negative integer, not '{!r}'"
|
||||||
.format(width))
|
.format(width))
|
||||||
|
@ -184,8 +184,8 @@ class SyncFIFO(Elaboratable, FIFOInterface):
|
||||||
""".strip(),
|
""".strip(),
|
||||||
w_attributes="")
|
w_attributes="")
|
||||||
|
|
||||||
def __init__(self, width, depth, *, fwft=True):
|
def __init__(self, *, width, depth, fwft=True):
|
||||||
super().__init__(width, depth, fwft=fwft)
|
super().__init__(width=width, depth=depth, fwft=fwft)
|
||||||
|
|
||||||
self.level = Signal.range(depth + 1)
|
self.level = Signal.range(depth + 1)
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ class SyncFIFO(Elaboratable, FIFOInterface):
|
||||||
do_read = self.r_rdy & self.r_en
|
do_read = self.r_rdy & self.r_en
|
||||||
do_write = self.w_rdy & self.w_en
|
do_write = self.w_rdy & self.w_en
|
||||||
|
|
||||||
storage = Memory(self.width, self.depth)
|
storage = Memory(width=self.width, depth=self.depth)
|
||||||
w_port = m.submodules.w_port = storage.write_port()
|
w_port = m.submodules.w_port = storage.write_port()
|
||||||
r_port = m.submodules.r_port = storage.read_port(
|
r_port = m.submodules.r_port = storage.read_port(
|
||||||
domain="comb" if self.fwft else "sync", transparent=self.fwft)
|
domain="comb" if self.fwft else "sync", transparent=self.fwft)
|
||||||
|
@ -279,8 +279,8 @@ class SyncFIFOBuffered(Elaboratable, FIFOInterface):
|
||||||
""".strip(),
|
""".strip(),
|
||||||
w_attributes="")
|
w_attributes="")
|
||||||
|
|
||||||
def __init__(self, width, depth):
|
def __init__(self, *, width, depth):
|
||||||
super().__init__(width, depth, fwft=True)
|
super().__init__(width=width, depth=depth, fwft=True)
|
||||||
|
|
||||||
self.level = Signal.range(depth + 1)
|
self.level = Signal.range(depth + 1)
|
||||||
|
|
||||||
|
@ -289,7 +289,8 @@ class SyncFIFOBuffered(Elaboratable, FIFOInterface):
|
||||||
|
|
||||||
# Effectively, this queue treats the output register of the non-FWFT inner queue as
|
# Effectively, this queue treats the output register of the non-FWFT inner queue as
|
||||||
# an additional storage element.
|
# an additional storage element.
|
||||||
m.submodules.unbuffered = fifo = SyncFIFO(self.width, self.depth - 1, fwft=False)
|
m.submodules.unbuffered = fifo = SyncFIFO(width=self.width, depth=self.depth - 1,
|
||||||
|
fwft=False)
|
||||||
|
|
||||||
m.d.comb += [
|
m.d.comb += [
|
||||||
fifo.w_data.eq(self.w_data),
|
fifo.w_data.eq(self.w_data),
|
||||||
|
@ -336,14 +337,14 @@ class AsyncFIFO(Elaboratable, FIFOInterface):
|
||||||
r_attributes="",
|
r_attributes="",
|
||||||
w_attributes="")
|
w_attributes="")
|
||||||
|
|
||||||
def __init__(self, width, depth, *, r_domain="read", w_domain="write", exact_depth=False):
|
def __init__(self, *, width, depth, r_domain="read", w_domain="write", exact_depth=False):
|
||||||
try:
|
try:
|
||||||
depth_bits = log2_int(depth, need_pow2=exact_depth)
|
depth_bits = log2_int(depth, need_pow2=exact_depth)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise ValueError("AsyncFIFO only supports depths that are powers of 2; requested "
|
raise ValueError("AsyncFIFO only supports depths that are powers of 2; requested "
|
||||||
"exact depth {} is not"
|
"exact depth {} is not"
|
||||||
.format(depth)) from None
|
.format(depth)) from None
|
||||||
super().__init__(width, 1 << depth_bits, fwft=True)
|
super().__init__(width=width, depth=1 << depth_bits, fwft=True)
|
||||||
|
|
||||||
self._r_domain = r_domain
|
self._r_domain = r_domain
|
||||||
self._w_domain = w_domain
|
self._w_domain = w_domain
|
||||||
|
@ -397,7 +398,7 @@ class AsyncFIFO(Elaboratable, FIFOInterface):
|
||||||
r_empty.eq(consume_r_gry == produce_r_gry),
|
r_empty.eq(consume_r_gry == produce_r_gry),
|
||||||
]
|
]
|
||||||
|
|
||||||
storage = Memory(self.width, self.depth)
|
storage = Memory(width=self.width, depth=self.depth)
|
||||||
w_port = m.submodules.w_port = storage.write_port(domain=self._w_domain)
|
w_port = m.submodules.w_port = storage.write_port(domain=self._w_domain)
|
||||||
r_port = m.submodules.r_port = storage.read_port (domain=self._r_domain,
|
r_port = m.submodules.r_port = storage.read_port (domain=self._r_domain,
|
||||||
transparent=False)
|
transparent=False)
|
||||||
|
@ -454,21 +455,21 @@ class AsyncFIFOBuffered(Elaboratable, FIFOInterface):
|
||||||
r_attributes="",
|
r_attributes="",
|
||||||
w_attributes="")
|
w_attributes="")
|
||||||
|
|
||||||
def __init__(self, width, depth, *, r_domain="read", w_domain="write", exact_depth=False):
|
def __init__(self, *, width, depth, r_domain="read", w_domain="write", exact_depth=False):
|
||||||
try:
|
try:
|
||||||
depth_bits = log2_int(max(0, depth - 1), need_pow2=exact_depth)
|
depth_bits = log2_int(max(0, depth - 1), need_pow2=exact_depth)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise ValueError("AsyncFIFOBuffered only supports depths that are one higher "
|
raise ValueError("AsyncFIFOBuffered only supports depths that are one higher "
|
||||||
"than powers of 2; requested exact depth {} is not"
|
"than powers of 2; requested exact depth {} is not"
|
||||||
.format(depth)) from None
|
.format(depth)) from None
|
||||||
super().__init__(width, (1 << depth_bits) + 1, fwft=True)
|
super().__init__(width=width, depth=(1 << depth_bits) + 1, fwft=True)
|
||||||
|
|
||||||
self._r_domain = r_domain
|
self._r_domain = r_domain
|
||||||
self._w_domain = w_domain
|
self._w_domain = w_domain
|
||||||
|
|
||||||
def elaborate(self, platform):
|
def elaborate(self, platform):
|
||||||
m = Module()
|
m = Module()
|
||||||
m.submodules.unbuffered = fifo = AsyncFIFO(self.width, self.depth - 1,
|
m.submodules.unbuffered = fifo = AsyncFIFO(width=self.width, depth=self.depth - 1,
|
||||||
r_domain=self._r_domain, w_domain=self._w_domain)
|
r_domain=self._r_domain, w_domain=self._w_domain)
|
||||||
|
|
||||||
m.d.comb += [
|
m.d.comb += [
|
||||||
|
|
|
@ -49,8 +49,8 @@ class FIFOModel(Elaboratable, FIFOInterface):
|
||||||
"""
|
"""
|
||||||
Non-synthesizable first-in first-out queue, implemented naively as a chain of registers.
|
Non-synthesizable first-in first-out queue, implemented naively as a chain of registers.
|
||||||
"""
|
"""
|
||||||
def __init__(self, width, depth, *, fwft, r_domain, w_domain):
|
def __init__(self, *, width, depth, fwft, r_domain, w_domain):
|
||||||
super().__init__(width, depth, fwft=fwft)
|
super().__init__(width=width, depth=depth, fwft=fwft)
|
||||||
|
|
||||||
self.r_domain = r_domain
|
self.r_domain = r_domain
|
||||||
self.w_domain = w_domain
|
self.w_domain = w_domain
|
||||||
|
@ -60,7 +60,7 @@ class FIFOModel(Elaboratable, FIFOInterface):
|
||||||
def elaborate(self, platform):
|
def elaborate(self, platform):
|
||||||
m = Module()
|
m = Module()
|
||||||
|
|
||||||
storage = Memory(self.width, self.depth)
|
storage = Memory(width=self.width, depth=self.depth)
|
||||||
w_port = m.submodules.w_port = storage.write_port(domain=self.w_domain)
|
w_port = m.submodules.w_port = storage.write_port(domain=self.w_domain)
|
||||||
r_port = m.submodules.r_port = storage.read_port (domain="comb")
|
r_port = m.submodules.r_port = storage.read_port (domain="comb")
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ class FIFOModelEquivalenceSpec(Elaboratable):
|
||||||
def elaborate(self, platform):
|
def elaborate(self, platform):
|
||||||
m = Module()
|
m = Module()
|
||||||
m.submodules.dut = dut = self.fifo
|
m.submodules.dut = dut = self.fifo
|
||||||
m.submodules.gold = gold = FIFOModel(dut.width, dut.depth, fwft=dut.fwft,
|
m.submodules.gold = gold = FIFOModel(width=dut.width, depth=dut.depth, fwft=dut.fwft,
|
||||||
r_domain=self.r_domain, w_domain=self.w_domain)
|
r_domain=self.r_domain, w_domain=self.w_domain)
|
||||||
|
|
||||||
m.d.comb += [
|
m.d.comb += [
|
||||||
|
@ -141,11 +141,11 @@ class FIFOContractSpec(Elaboratable):
|
||||||
consecutively, they must be read out consecutively at some later point, no matter all other
|
consecutively, they must be read out consecutively at some later point, no matter all other
|
||||||
circumstances, with the exception of reset.
|
circumstances, with the exception of reset.
|
||||||
"""
|
"""
|
||||||
def __init__(self, fifo, r_domain, w_domain, bound):
|
def __init__(self, fifo, *, r_domain, w_domain, bound):
|
||||||
self.fifo = fifo
|
self.fifo = fifo
|
||||||
self.r_domain = r_domain
|
self.r_domain = r_domain
|
||||||
self.w_domain = w_domain
|
self.w_domain = w_domain
|
||||||
self.bound = bound
|
self.bound = bound
|
||||||
|
|
||||||
def elaborate(self, platform):
|
def elaborate(self, platform):
|
||||||
m = Module()
|
m = Module()
|
||||||
|
|
Loading…
Reference in a new issue