crc: generate error asynchronously to avoid stalling the flow and simplify
This commit is contained in:
parent
648ab8fa7a
commit
fcf2f7517c
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue