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
###
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),
)
)
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):
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):
###
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"))
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<<j)):
+ for j in range(width-1):
+ if (polynom & (1<<(j+1))):
curval[j] += feedback
curval[j] = _optimize_eq(curval[j])
+ curval.insert(0, feedback)
# implement logic
for i in range(width):
"""
width = 32
polynom = 0x04C11DB7
+ init = 2**width-1
check = 0xC704DD7B
def __init__(self, dat_width):
self.d = Signal(dat_width)
###
self.submodules.engine = CRCEngine(dat_width, self.width, self.polynom)
- reg = Signal(self.width, reset=2**self.width-1)
+ reg = Signal(self.width, reset=self.init)
self.sync += reg.eq(self.engine.next)
self.comb += [
self.engine.d.eq(self.d),