genlib/fifo: add flush, expose level in SyncFIFO

AsyncFIFO would need versions of flush and level in each clock domain
plus some handshaking on double flush.

Signed-off-by: Robert Jordens <jordens@gmail.com>
This commit is contained in:
Robert Jordens 2014-03-15 16:15:47 -06:00 committed by Sebastien Bourdeauducq
parent bf6ab2b4f6
commit b03d9f4c14

View file

@ -70,12 +70,21 @@ class SyncFIFO(Module, _FIFOInterface):
If different clock domains are needed, use :class:`AsyncFIFO`. If different clock domains are needed, use :class:`AsyncFIFO`.
{interface} {interface}
level : out
Number of unread entries.
flush : in
Flush the FIFO discarding pending write.
In the next cycle `readable` will be deasserted
and `writable` will be asserted, `level` will be zero.
""" """
__doc__ = __doc__.format(interface=_FIFOInterface.__doc__) __doc__ = __doc__.format(interface=_FIFOInterface.__doc__)
def __init__(self, width_or_layout, depth): def __init__(self, width_or_layout, depth):
_FIFOInterface.__init__(self, width_or_layout, depth) _FIFOInterface.__init__(self, width_or_layout, depth)
self.flush = Signal()
self.level = Signal(max=depth+1)
### ###
do_write = Signal() do_write = Signal()
@ -85,7 +94,6 @@ class SyncFIFO(Module, _FIFOInterface):
do_read.eq(self.readable & self.re) do_read.eq(self.readable & self.re)
] ]
level = Signal(max=depth+1)
produce = Signal(max=depth) produce = Signal(max=depth)
consume = Signal(max=depth) consume = Signal(max=depth)
storage = Memory(self.width, depth) storage = Memory(self.width, depth)
@ -109,15 +117,19 @@ class SyncFIFO(Module, _FIFOInterface):
self.sync += If(do_read, _inc(consume, depth)) self.sync += If(do_read, _inc(consume, depth))
self.sync += [ self.sync += [
If(do_write, If(self.flush,
If(~do_read, level.eq(level + 1)) produce.eq(0),
consume.eq(0),
self.level.eq(0),
).Elif(do_write,
If(~do_read, self.level.eq(self.level + 1))
).Elif(do_read, ).Elif(do_read,
level.eq(level - 1) self.level.eq(self.level - 1)
) )
] ]
self.comb += [ self.comb += [
self.writable.eq(level != depth), self.writable.eq(self.level != depth),
self.readable.eq(level != 0) self.readable.eq(self.level != 0)
] ]
class AsyncFIFO(Module, _FIFOInterface): class AsyncFIFO(Module, _FIFOInterface):