From 037ea05b1eee1444e144af40e8ef929028bd7061 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 17 Dec 2014 09:22:08 +0100 Subject: [PATCH] crc: modify CRCChecker to remove CRC and clean up --- migen/actorlib/crc.py | 112 ++++++++++++++++++++++++++++-------------- migen/genlib/crc.py | 9 ++-- 2 files changed, 79 insertions(+), 42 deletions(-) diff --git a/migen/actorlib/crc.py b/migen/actorlib/crc.py index 2e42344b..25e696d4 100644 --- a/migen/actorlib/crc.py +++ b/migen/actorlib/crc.py @@ -4,6 +4,7 @@ from migen.genlib.record import * from migen.genlib.misc import chooser from migen.genlib.crc import * from migen.flow.actor import Sink, Source +from migen.actorlib.fifo import SyncFIFO class CRCInserter(Module): """CRC Inserter @@ -30,11 +31,12 @@ class CRCInserter(Module): ### dw = flen(sink.d) - self.submodules.crc = crc_class(dw) - self.submodules.fsm = fsm = FSM(reset_state="IDLE") + crc = crc_class(dw) + fsm = FSM(reset_state="IDLE") + self.submodules += crc, fsm fsm.act("IDLE", - self.crc.reset.eq(1), + crc.reset.eq(1), sink.ack.eq(1), If(sink.stb & sink.sop, sink.ack.eq(0), @@ -42,32 +44,40 @@ class CRCInserter(Module): ) ) fsm.act("COPY", - self.crc.ce.eq(sink.stb & source.ack), - self.crc.d.eq(sink.d), + crc.ce.eq(sink.stb & source.ack), + crc.d.eq(sink.d), Record.connect(sink, source), source.eop.eq(0), If(sink.stb & sink.eop & source.ack, NextState("INSERT"), ) ) - ratio = self.crc.width//dw - cnt = Signal(max=ratio, reset=ratio-1) - cnt_done = Signal() - fsm.act("INSERT", - source.stb.eq(1), - chooser(self.crc.value, cnt, source.d, reverse=True), - If(cnt_done, + ratio = crc.width//dw + if ratio > 1: + cnt = Signal(max=ratio, reset=ratio-1) + cnt_done = Signal() + fsm.act("INSERT", + source.stb.eq(1), + chooser(crc.value, cnt, source.d, reverse=True), + If(cnt_done, + source.eop.eq(1), + If(source.ack, NextState("IDLE")) + ) + ) + self.comb += cnt_done.eq(cnt == 0) + self.sync += \ + If(fsm.ongoing("IDLE"), + cnt.eq(cnt.reset) + ).Elif(fsm.ongoing("INSERT") & ~cnt_done, + cnt.eq(cnt - source.ack) + ) + else: + fsm.act("INSERT", + source.stb.eq(1), source.eop.eq(1), + source.d.eq(crc.value), If(source.ack, NextState("IDLE")) ) - ) - self.comb += cnt_done.eq(cnt == 0) - self.sync += \ - If(fsm.ongoing("IDLE"), - cnt.eq(cnt.reset) - ).Elif(fsm.ongoing("INSERT") & ~cnt_done, - cnt.eq(cnt - source.ack) - ) self.comb += self.busy.eq(~fsm.ongoing("IDLE")) class CRC32Inserter(CRCInserter): @@ -89,7 +99,7 @@ class CRCChecker(Module): sink : in Packets input with CRC. source : out - Packets output with CRC and "error" set to 0 + Packets output without CRC and "error" set to 0 on eop when CRC OK / set to 1 when CRC KO. """ def __init__(self, crc_class, layout): @@ -100,32 +110,58 @@ class CRCChecker(Module): ### dw = flen(sink.d) - self.submodules.crc = crc_class(dw) + crc = crc_class(dw) + self.submodules += crc + ratio = crc.width//dw - fsm = FSM(reset_state="RESET_CRC") + error = Signal() + fifo = InsertReset(SyncFIFO(layout, ratio + 1)) + self.submodules += fifo + + fsm = FSM(reset_state="RESET") self.submodules += fsm - fsm.act("RESET_CRC", - sink.ack.eq(0), - self.crc.reset.eq(1), - NextState("IDLE") + fifo_in = Signal() + fifo_out = Signal() + fifo_full = Signal() + + self.comb += [ + fifo_full.eq(fifo.fifo.level == ratio), + fifo_in.eq(sink.stb & (~fifo_full | fifo_out)), + fifo_out.eq(source.stb & source.ack), + + Record.connect(sink, fifo.sink), + fifo.sink.stb.eq(fifo_in), + self.sink.ack.eq(fifo_in), + + source.stb.eq(sink.stb & fifo_full), + source.sop.eq(fifo.source.sop), + source.eop.eq(sink.eop), + fifo.source.ack.eq(fifo_out), + source.payload.eq(fifo.source.payload), + + source.error.eq(sink.error | crc.error), + ] + + fsm.act("RESET", + crc.reset.eq(1), + fifo.reset.eq(1), + 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), + crc.d.eq(sink.d), + If(sink.stb & sink.sop & sink.ack, + crc.ce.eq(1), NextState("COPY") ) ) fsm.act("COPY", - 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") + crc.d.eq(sink.d), + If(sink.stb & sink.ack, + crc.ce.eq(1), + If(sink.eop, + NextState("RESET") + ) ) ) self.comb += self.busy.eq(~fsm.ongoing("IDLE")) diff --git a/migen/genlib/crc.py b/migen/genlib/crc.py index e0a6672c..51a9ab10 100644 --- a/migen/genlib/crc.py +++ b/migen/genlib/crc.py @@ -53,11 +53,11 @@ class CRCEngine(Module): curval = [[("state", i)] for i in range(width)] for i in range(dat_width): feedback = curval.pop() + [("din", i)] - curval.insert(0, feedback) - for j in range(1, width-1): - if (polynom&(1<