dvisampler: report FIFO overflow
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 10 Jul 2013 17:55:36 +0000 (19:55 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Wed, 10 Jul 2013 17:55:36 +0000 (19:55 +0200)
milkymist/dvisampler/analysis.py
software/videomixer/dvisamplerX.c

index a1fa46ebfbc2a283399af45e20d56e3ed77a633f..bf1663f5f8aaa64aaab528c1b94fd4ae617da403 100644 (file)
@@ -1,5 +1,5 @@
 from migen.fhdl.std import *
-from migen.genlib.cdc import MultiReg
+from migen.genlib.cdc import MultiReg, PulseSynchronizer
 from migen.genlib.fifo import AsyncFIFO
 from migen.genlib.record import Record
 from migen.bank.description import *
@@ -105,7 +105,7 @@ class ResolutionDetection(Module, AutoCSR):
                        )
                self.specials += MultiReg(vcounter_st, self._vres.status)
 
-class FrameExtraction(Module):
+class FrameExtraction(Module, AutoCSR):
        def __init__(self):
                # in pix clock domain
                self.valid_i = Signal()
@@ -119,6 +119,8 @@ class FrameExtraction(Module):
                self.frame = Source(frame_layout)
                self.busy = Signal()
 
+               self._r_overflow = CSR()
+
                ###
 
                fifo_stb = Signal()
@@ -145,3 +147,36 @@ class FrameExtraction(Module):
                        fifo.re.eq(self.frame.ack),
                        self.busy.eq(0)
                ]
+
+               # overflow detection
+               pix_overflow = Signal()
+               pix_overflow_reset = Signal()
+               self.sync.pix += [
+                       If(fifo.we & ~fifo.writable,
+                               pix_overflow.eq(1)
+                       ).Elif(pix_overflow_reset,
+                               pix_overflow.eq(0)
+                       )
+               ]
+
+               sys_overflow = Signal()
+               self.specials += MultiReg(pix_overflow, sys_overflow)
+               self.submodules.overflow_reset = PulseSynchronizer("sys", "pix")
+               self.submodules.overflow_reset_ack = PulseSynchronizer("pix", "sys")
+               self.comb += [
+                       pix_overflow_reset.eq(self.overflow_reset.o),
+                       self.overflow_reset_ack.i.eq(pix_overflow_reset)
+               ]
+
+               overflow_mask = Signal()
+               self.comb += [
+                       self._r_overflow.w.eq(sys_overflow & ~overflow_mask),
+                       self.overflow_reset.i.eq(self._r_overflow.re)
+               ]
+               self.sync += [
+                       If(self._r_overflow.re,
+                               overflow_mask.eq(1)
+                       ).Elif(self.overflow_reset_ack.o,
+                               overflow_mask.eq(0)
+                       )
+               ]
index 6d404c2e5e6aff738b733da8510a8ed1cf60d9e9..fbb0b688fe6f5e752f8922f03a623bd0b59d2253 100644 (file)
@@ -216,6 +216,14 @@ int dvisamplerX_phase_startup(void)
        }
 }
 
+static void dvisamplerX_check_overflow(void)
+{
+       if(dvisamplerX_frame_overflow_read()) {
+               printf("dvisamplerX: FIFO overflow\n");
+               dvisamplerX_frame_overflow_write(1);
+       }
+}
+
 static int dvisamplerX_locked;
 static int dvisamplerX_last_event;
 
@@ -239,4 +247,5 @@ void dvisamplerX_service(void)
                        dvisamplerX_locked = 1;
                }
        }
+       dvisamplerX_check_overflow();
 }