crc: generate error asynchronously to avoid stalling the flow and simplify
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 31 Oct 2014 11:56:03 +0000 (12:56 +0100)
committerSebastien Bourdeauducq <sb@m-labs.hk>
Sat, 1 Nov 2014 13:21:46 +0000 (21:21 +0800)
migen/actorlib/crc.py
migen/genlib/crc.py

index 74139c94b01b2ac14e9d9e90dce0ecdd577ed77b..ab5ebf7a5f155dcb8e883ef351a85aed2b99f556 100644 (file)
@@ -23,30 +23,30 @@ class CRCInserter(Module):
                Packets output with CRC.
        """
        def __init__(self, crc_class, layout):
-               self.sink = Sink(layout, True)
-               self.source = Source(layout, True)
+               self.sink = sink = Sink(layout, True)
+               self.source = source = Source(layout, True)
                self.busy = Signal()
 
                ###
 
-               dw = flen(self.sink.d)
+               dw = flen(sink.d)
                self.submodules.crc = crc_class(dw)
                self.submodules.fsm = fsm = FSM(reset_state="IDLE")
 
                fsm.act("IDLE",
                        self.crc.reset.eq(1),
-                       self.sink.ack.eq(1),
-                       If(self.sink.stb & self.sink.sop,
-                               self.sink.ack.eq(0),
+                       sink.ack.eq(1),
+                       If(sink.stb & sink.sop,
+                               sink.ack.eq(0),
                                NextState("COPY"),
                        )
                )
                fsm.act("COPY",
-                       self.crc.ce.eq(self.sink.stb & self.source.ack),
-                       self.crc.d.eq(self.sink.d),
-                       Record.connect(self.sink, self.source),
-                       self.source.eop.eq(0),
-                       If(self.sink.stb & self.sink.eop & self.source.ack,
+                       self.crc.ce.eq(sink.stb & source.ack),
+                       self.crc.d.eq(sink.d),
+                       Record.connect(sink, source),
+                       source.eop.eq(0),
+                       If(sink.stb & sink.eop & source.ack,
                                NextState("INSERT"),
                        )
                )
@@ -54,11 +54,11 @@ class CRCInserter(Module):
                cnt = Signal(max=ratio, reset=ratio-1)
                cnt_done = Signal()
                fsm.act("INSERT",
-                       self.source.stb.eq(1),
-                       chooser(self.crc.value, cnt, self.source.d, reverse=True),
+                       source.stb.eq(1),
+                       chooser(self.crc.value, cnt, source.d, reverse=True),
                        If(cnt_done,
-                               self.source.eop.eq(1),
-                               If(self.source.ack, NextState("IDLE"))
+                               source.eop.eq(1),
+                               If(source.ack, NextState("IDLE"))
                        )
                )
                self.comb += cnt_done.eq(cnt == 0)
@@ -66,7 +66,7 @@ class CRCInserter(Module):
                        If(fsm.ongoing("IDLE"),
                                cnt.eq(cnt.reset)
                        ).Elif(fsm.ongoing("INSERT") & ~cnt_done,
-                               cnt.eq(cnt - self.source.ack)
+                               cnt.eq(cnt - source.ack)
                        )
                self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
 
@@ -89,45 +89,45 @@ class CRCChecker(Module):
        sink : in
                Packets input with CRC.
        source : out
-               Packets output with CRC and "discarded" set to 0
-               on eop if CRC OK / set to 1 is CRC KO.
+               Packets output with CRC and "error" set to 0
+               on eop when CRC OK / set to 1 when CRC KO.
        """
        def __init__(self, crc_class, layout):
-               self.sink = Sink(layout, True)
-               self.source = Source(layout, True)
+               self.sink = sink = Sink(layout, True)
+               self.source = source = Source(layout, True)
                self.busy = Signal()
 
                ###
 
-               dw = flen(self.sink.d)
+               dw = flen(sink.d)
                self.submodules.crc = crc_class(dw)
 
-               fsm = FSM(reset_state="IDLE")
+               fsm = FSM(reset_state="RESET_CRC")
                self.submodules += fsm
 
-               fsm.act("IDLE",
+               fsm.act("RESET_CRC",
+                       sink.ack.eq(0),
                        self.crc.reset.eq(1),
-                       self.sink.ack.eq(self.sink.stb),
-                       If(self.sink.stb & self.sink.sop,
-                               self.sink.ack.eq(0),
+                       NextState("IDLE")
+               )
+               fsm.act("IDLE",
+                       sink.ack.eq(sink.stb),
+                       If(sink.stb & sink.sop,
+                               Record.connect(sink, source),
+                               self.crc.ce.eq(sink.ack),
+                               self.crc.d.eq(sink.d),
                                NextState("COPY")
                        )
                )
                fsm.act("COPY",
-                       Record.connect(self.sink, self.source),
-                       self.crc.ce.eq(self.sink.stb & (self.sink.ack | self.sink.eop)),
-                       self.crc.d.eq(self.sink.d),
-                       If(self.sink.stb & self.sink.eop,
-                               self.sink.ack.eq(0),
-                               self.source.stb.eq(0),
-                               NextState("CHECK")
+                       Record.connect(sink, source),
+                       self.crc.ce.eq(sink.stb & sink.ack),
+                       self.crc.d.eq(sink.d),
+                       source.error.eq(sink.eop & self.crc.error),
+                       If(sink.stb & sink.ack & sink.eop,
+                               NextState("RESET_CRC")
                        )
                )
-               fsm.act("CHECK",
-                       Record.connect(self.sink, self.source),
-                       self.source.discarded.eq(self.crc.error),
-                       If(self.source.stb & self.source.ack, NextState("IDLE"))
-               )
                self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
 
 class CRC32Checker(CRCChecker):
index afd40fd5e62bfc8db734a62d8ad93bd8010cf4f5..e0a6672c0e93b068cb64162d1a7a6ff5596bfb0c 100644 (file)
@@ -108,5 +108,5 @@ class CRC32(Module):
                        self.engine.last.eq(reg),
 
                        self.value.eq(~reg[::-1]),
-                       self.error.eq(reg != self.check)
+                       self.error.eq(self.engine.next != self.check)
                ]