forked from M-Labs/artiq-zynq
cxp: use CXPCRC32inserter in pipeline
This commit is contained in:
parent
6ebd3d4315
commit
4458c28736
|
@ -1,16 +1,13 @@
|
||||||
from migen import *
|
from migen import *
|
||||||
from misoc.interconnect.csr import *
|
from misoc.interconnect.csr import *
|
||||||
from misoc.interconnect import stream
|
from misoc.interconnect import stream
|
||||||
from misoc.cores.liteeth_mini.mac.crc import LiteEthMACCRCEngine, LiteEthMACCRC32Inserter
|
|
||||||
|
|
||||||
from cxp_downconn import CXP_DownConn
|
from cxp_downconn import CXP_DownConn
|
||||||
from cxp_upconn import CXP_UpConn
|
from cxp_upconn import CXP_UpConn
|
||||||
from cxp_pipeline import Code_Inserter
|
from cxp_pipeline import Code_Inserter, CXPCRC32Inserter
|
||||||
|
|
||||||
class CXP(Module, AutoCSR):
|
class CXP(Module, AutoCSR):
|
||||||
def __init__(self, refclk, downconn_pads, upconn_pads, sys_clk_freq, debug_sma, pmod_pads):
|
def __init__(self, refclk, downconn_pads, upconn_pads, sys_clk_freq, debug_sma, pmod_pads):
|
||||||
# self.submodules.crc = CXP_CRC(8)
|
|
||||||
|
|
||||||
self.submodules.txcore = CXP_TX_Core(pmod_pads)
|
self.submodules.txcore = CXP_TX_Core(pmod_pads)
|
||||||
|
|
||||||
self.submodules.upconn = UpConn_Packets(upconn_pads, sys_clk_freq, debug_sma, pmod_pads)
|
self.submodules.upconn = UpConn_Packets(upconn_pads, sys_clk_freq, debug_sma, pmod_pads)
|
||||||
|
@ -91,6 +88,7 @@ def cxp_phy_layout():
|
||||||
class CXP_TX_Core(Module, AutoCSR):
|
class CXP_TX_Core(Module, AutoCSR):
|
||||||
def __init__(self, pmod_pads):
|
def __init__(self, pmod_pads):
|
||||||
|
|
||||||
|
self.din_len = CSRStorage(6)
|
||||||
self.din_pak = CSR(8)
|
self.din_pak = CSR(8)
|
||||||
self.din_k = CSRStorage()
|
self.din_k = CSRStorage()
|
||||||
self.din_ready = CSRStatus()
|
self.din_ready = CSRStatus()
|
||||||
|
@ -100,21 +98,34 @@ class CXP_TX_Core(Module, AutoCSR):
|
||||||
self.kout_pak = CSRStatus()
|
self.kout_pak = CSRStatus()
|
||||||
self.dout_valid =CSRStatus()
|
self.dout_valid =CSRStatus()
|
||||||
|
|
||||||
|
len = Signal(6, reset=1)
|
||||||
|
|
||||||
|
# TODO: add end of packet (eop) interface for firmware and try out crc_inserters
|
||||||
|
|
||||||
# a buf is used to simulated a proper endpoint which hold source.stb high as long as data is available
|
# a buf is used to simulated a proper endpoint which hold source.stb high as long as data is available
|
||||||
# otherwise, CSR.re only hold when CSR is written too and it cannot act as a proper source
|
# otherwise, CSR.re only hold when CSR is written to and it cannot act as a proper source
|
||||||
self.submodules.buf_in = buf_in = stream.SyncFIFO(cxp_phy_layout(), 2)
|
self.submodules.buf_in = buf_in = stream.SyncFIFO(cxp_phy_layout(), 2)
|
||||||
self.submodules.buf_out = buf_out = stream.SyncFIFO(cxp_phy_layout(), 64)
|
self.submodules.buf_out = buf_out = stream.SyncFIFO(cxp_phy_layout(), 64)
|
||||||
|
|
||||||
self.submodules.pak_start = pak_start = Code_Inserter(*K(27, 7), cxp_phy_layout())
|
self.submodules.pak_start = pak_start = Code_Inserter(*K(27, 7), cxp_phy_layout())
|
||||||
# self.submodules.crc_inserter = crc_inserters = LiteEthMACCRC32Inserter(CXP_LAYOUT)
|
self.submodules.crc_inserter = crc_inserters = CXPCRC32Inserter(cxp_phy_layout())
|
||||||
|
|
||||||
self.sync += [
|
self.sync += [
|
||||||
# input
|
# input
|
||||||
self.din_ready.status.eq(buf_in.sink.ack),
|
self.din_ready.status.eq(buf_in.sink.ack),
|
||||||
buf_in.sink.stb.eq(self.din_pak.re),
|
buf_in.sink.stb.eq(0),
|
||||||
|
If(self.din_pak.re,
|
||||||
|
If(len == self.din_len.storage,
|
||||||
|
len.eq(len.reset),
|
||||||
|
buf_in.sink.eop.eq(1),
|
||||||
|
).Else(
|
||||||
|
len.eq(len + 1),
|
||||||
|
buf_in.sink.eop.eq(0),
|
||||||
|
),
|
||||||
|
buf_in.sink.stb.eq(1),
|
||||||
buf_in.sink.data.eq(self.din_pak.r),
|
buf_in.sink.data.eq(self.din_pak.r),
|
||||||
buf_in.sink.k.eq(self.din_k.storage),
|
buf_in.sink.k.eq(self.din_k.storage),
|
||||||
|
),
|
||||||
|
|
||||||
# output
|
# output
|
||||||
buf_out.source.ack.eq(self.inc.re),
|
buf_out.source.ack.eq(self.inc.re),
|
||||||
|
@ -124,7 +135,7 @@ class CXP_TX_Core(Module, AutoCSR):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
tx_pipeline = [ buf_in, pak_start, buf_out]
|
tx_pipeline = [ buf_in, crc_inserters, buf_out]
|
||||||
|
|
||||||
for s, d in zip(tx_pipeline, tx_pipeline[1:]):
|
for s, d in zip(tx_pipeline, tx_pipeline[1:]):
|
||||||
self.comb += s.source.connect(d.sink)
|
self.comb += s.source.connect(d.sink)
|
||||||
|
@ -143,66 +154,3 @@ class CXP_TX_Core(Module, AutoCSR):
|
||||||
Instance("OBUF", i_I=buf_out.source.stb, o_O=pmod_pads[6]),
|
Instance("OBUF", i_I=buf_out.source.stb, o_O=pmod_pads[6]),
|
||||||
Instance("OBUF", i_I=buf_out.source.ack, o_O=pmod_pads[7]),
|
Instance("OBUF", i_I=buf_out.source.ack, o_O=pmod_pads[7]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CXP_CRC(Module, AutoCSR):
|
|
||||||
def __init__(self, data_width):
|
|
||||||
# Section 9.2.2.2 (CXP-001-2021)
|
|
||||||
crc_width = 32
|
|
||||||
polynom = 0x04C11DB7
|
|
||||||
seed = 2**crc_width-1
|
|
||||||
|
|
||||||
self.d = Signal(data_width)
|
|
||||||
self.stb = Signal()
|
|
||||||
self.reset = Signal()
|
|
||||||
self.val = Signal(crc_width, reset=seed)
|
|
||||||
|
|
||||||
|
|
||||||
# # #
|
|
||||||
|
|
||||||
self.submodules.engine = LiteEthMACCRCEngine(data_width, crc_width, polynom)
|
|
||||||
|
|
||||||
self.sync += [
|
|
||||||
self.val.eq(self.engine.next),
|
|
||||||
If(self.stb,
|
|
||||||
self.engine.data.eq(self.d),
|
|
||||||
|
|
||||||
If(self.reset,
|
|
||||||
# because the seed is non zero, even if the data is 0x00, the engine output will be change :<
|
|
||||||
self.engine.last.eq(seed),
|
|
||||||
# clear reset bit
|
|
||||||
self.reset.eq(0),
|
|
||||||
).Else(
|
|
||||||
self.engine.last.eq(self.val),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
# DEBUG: remove those csr
|
|
||||||
# TODO: do char bit reverse outside of this submodule
|
|
||||||
|
|
||||||
p0 = Signal(8)
|
|
||||||
p1 = Signal(8)
|
|
||||||
p2 = Signal(8)
|
|
||||||
p3 = Signal(8)
|
|
||||||
self.comb += [
|
|
||||||
p3.eq(self.engine.next[:8][::-1]),
|
|
||||||
p2.eq(self.engine.next[8:16][::-1]),
|
|
||||||
p1.eq(self.engine.next[16:24][::-1]),
|
|
||||||
p0.eq(self.engine.next[24:32][::-1]),
|
|
||||||
]
|
|
||||||
|
|
||||||
self.data = CSR(data_width)
|
|
||||||
self.en = CSR()
|
|
||||||
self.value = CSRStatus(crc_width)
|
|
||||||
self.processed = CSRStatus(crc_width)
|
|
||||||
|
|
||||||
self.sync += [
|
|
||||||
self.d.eq(self.data.r),
|
|
||||||
self.stb.eq(self.data.re),
|
|
||||||
If(self.en.re, self.reset.eq(1)),
|
|
||||||
|
|
||||||
self.value.status.eq(self.engine.next),
|
|
||||||
self.processed.status.eq(Cat(p3, p2, p1, p0)),
|
|
||||||
]
|
|
||||||
|
|
Loading…
Reference in New Issue