genlib/fifo: add flush, expose level in SyncFIFO
authorRobert Jordens <jordens@gmail.com>
Sat, 15 Mar 2014 22:15:47 +0000 (16:15 -0600)
committerSebastien Bourdeauducq <sb@m-labs.hk>
Sun, 16 Mar 2014 06:10:46 +0000 (23:10 -0700)
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>
migen/genlib/fifo.py

index ad478ef0a580c5a345ac3225718dc8fa97aa13e4..703e7d346b319d05fadcaccf9b93d22ebaf6c2b3 100644 (file)
@@ -70,12 +70,21 @@ class SyncFIFO(Module, _FIFOInterface):
        If different clock domains are needed, use :class:`AsyncFIFO`.
 
        {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__)
 
        def __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()
@@ -85,7 +94,6 @@ class SyncFIFO(Module, _FIFOInterface):
                        do_read.eq(self.readable & self.re)
                ]
 
-               level = Signal(max=depth+1)
                produce = Signal(max=depth)
                consume = Signal(max=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_write,
-                               If(~do_read, level.eq(level + 1))
+                       If(self.flush,
+                               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,
-                               level.eq(level - 1)
+                               self.level.eq(self.level - 1)
                        )
                ]
                self.comb += [
-                       self.writable.eq(level != depth),
-                       self.readable.eq(level != 0)
+                       self.writable.eq(self.level != depth),
+                       self.readable.eq(self.level != 0)
                ]
 
 class AsyncFIFO(Module, _FIFOInterface):