forked from M-Labs/artiq-zynq
downconn GW: add tx&rx packet for debug
This commit is contained in:
parent
dddea53d26
commit
ca32914917
|
@ -4,8 +4,10 @@ from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
|
||||||
from misoc.cores.code_8b10b import Encoder, Decoder
|
from misoc.cores.code_8b10b import Encoder, Decoder
|
||||||
from misoc.interconnect.csr import *
|
from misoc.interconnect.csr import *
|
||||||
|
from misoc.interconnect import stream
|
||||||
|
|
||||||
from artiq.gateware.drtio.transceiver.gtx_7series_init import *
|
from artiq.gateware.drtio.transceiver.gtx_7series_init import *
|
||||||
|
from cxp_pipeline import downconn_layout
|
||||||
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from operator import add
|
from operator import add
|
||||||
|
@ -46,7 +48,6 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
||||||
# TODO: add extension gtx connections
|
# TODO: add extension gtx connections
|
||||||
# TODO: add connection interface
|
# TODO: add connection interface
|
||||||
|
|
||||||
|
|
||||||
# TODO: Connect slave cxp_gtx_rx clock tgt
|
# TODO: Connect slave cxp_gtx_rx clock tgt
|
||||||
# checkout channel interfaces & drtio_gtx
|
# checkout channel interfaces & drtio_gtx
|
||||||
# GTPTXPhaseAlignement for inspiration
|
# GTPTXPhaseAlignement for inspiration
|
||||||
|
@ -99,9 +100,35 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
self.sources = []
|
||||||
|
|
||||||
|
for n, gtx in enumerate(self.gtxs):
|
||||||
|
|
||||||
|
# gtx rx -> fifo out -> cdc out
|
||||||
|
|
||||||
|
fifo_out = stream.SyncFIFO(downconn_layout, 128)
|
||||||
|
self.submodules += ClockDomainsRenamer("cxp_gtx_rx")(fifo_out)
|
||||||
|
|
||||||
|
cdc_out = stream.AsyncFIFO(downconn_layout, 128)
|
||||||
|
self.submodules += ClockDomainsRenamer({"write": "cxp_gtx_rx", "read": "sys"})(cdc_out)
|
||||||
|
self.sources.append(cdc_out)
|
||||||
|
self.comb += fifo_out.source.connect(cdc_out.sink)
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(4):
|
||||||
|
self.sync.cxp_gtx_rx += [
|
||||||
|
fifo_out.sink.stb.eq(0),
|
||||||
|
# don't store idle word in fifo
|
||||||
|
If(gtx.rx_ready & fifo_out.sink.ack & (gtx.decoders[0].d != 0xBC),
|
||||||
|
fifo_out.sink.stb.eq(1),
|
||||||
|
fifo_out.sink.data[i*8:(i*8)+8].eq(gtx.decoders[i].d),
|
||||||
|
fifo_out.sink.k[i].eq(gtx.decoders[i].k),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# DEBUG: tx of gtx is not used in CXP
|
||||||
# DEBUG: txusrclk PLL DRG
|
# DEBUG: txusrclk PLL DRG
|
||||||
|
|
||||||
self.txpll_reset = CSRStorage()
|
self.txpll_reset = CSRStorage()
|
||||||
|
@ -118,6 +145,9 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
||||||
self.txinit_phaligndone = CSRStatus()
|
self.txinit_phaligndone = CSRStatus()
|
||||||
self.rxinit_phaligndone = CSRStatus()
|
self.rxinit_phaligndone = CSRStatus()
|
||||||
|
|
||||||
|
self.tx_stb = CSRStorage()
|
||||||
|
self.sinks = []
|
||||||
|
|
||||||
for n, gtx in enumerate(self.gtxs):
|
for n, gtx in enumerate(self.gtxs):
|
||||||
self.comb += [
|
self.comb += [
|
||||||
gtx.txpll_reset.eq(self.txpll_reset.storage),
|
gtx.txpll_reset.eq(self.txpll_reset.storage),
|
||||||
|
@ -137,6 +167,47 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
||||||
self.loopback_mode = CSRStorage(3)
|
self.loopback_mode = CSRStorage(3)
|
||||||
self.comb += gtx.loopback_mode.eq(self.loopback_mode.storage)
|
self.comb += gtx.loopback_mode.eq(self.loopback_mode.storage)
|
||||||
|
|
||||||
|
# DEBUG: datain
|
||||||
|
# fw -> fifo (sys) -> cdc fifo -> fifo in -> gtx tx
|
||||||
|
|
||||||
|
fifo_in = stream.AsyncFIFO(downconn_layout, 128)
|
||||||
|
self.submodules += ClockDomainsRenamer({"write": "sys", "read": "cxp_gtx_tx"})(fifo_in)
|
||||||
|
self.sinks.append(fifo_in)
|
||||||
|
|
||||||
|
# TODO: why there this send an extra 0xFB word
|
||||||
|
txstb = Signal()
|
||||||
|
self.specials += MultiReg(self.tx_stb.storage, txstb, odomain="cxp_gtx_tx")
|
||||||
|
|
||||||
|
self.sync.cxp_gtx_tx += [
|
||||||
|
fifo_in.source.ack.eq(0),
|
||||||
|
If(fifo_in.source.stb & txstb,
|
||||||
|
fifo_in.source.ack.eq(1),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
self.comb += [
|
||||||
|
If(fifo_in.source.stb & fifo_in.source.ack,
|
||||||
|
gtx.encoder.d[0].eq(fifo_in.source.data[:8]),
|
||||||
|
gtx.encoder.d[1].eq(fifo_in.source.data[8:16]),
|
||||||
|
gtx.encoder.d[2].eq(fifo_in.source.data[16:24]),
|
||||||
|
gtx.encoder.d[3].eq(fifo_in.source.data[24:]),
|
||||||
|
gtx.encoder.k[0].eq(fifo_in.source.k[0]),
|
||||||
|
gtx.encoder.k[1].eq(fifo_in.source.k[1]),
|
||||||
|
gtx.encoder.k[2].eq(fifo_in.source.k[2]),
|
||||||
|
gtx.encoder.k[3].eq(fifo_in.source.k[3]),
|
||||||
|
).Else(
|
||||||
|
# NOTE: IDLE WORD
|
||||||
|
gtx.encoder.d[0].eq(0xBC),
|
||||||
|
gtx.encoder.k[0].eq(1),
|
||||||
|
gtx.encoder.d[1].eq(0x3C),
|
||||||
|
gtx.encoder.k[1].eq(1),
|
||||||
|
gtx.encoder.d[2].eq(0x3C),
|
||||||
|
gtx.encoder.k[2].eq(1),
|
||||||
|
gtx.encoder.d[3].eq(0xB5),
|
||||||
|
gtx.encoder.k[3].eq(0),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
# DEBUG: IO SMA & PMOD
|
# DEBUG: IO SMA & PMOD
|
||||||
if n == 0:
|
if n == 0:
|
||||||
self.specials += [
|
self.specials += [
|
||||||
|
@ -144,9 +215,9 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
||||||
# Instance("OBUF", i_I=gtx.cd_cxp_gtx_tx.clk, o_O=debug_sma.n_rx),
|
# Instance("OBUF", i_I=gtx.cd_cxp_gtx_tx.clk, o_O=debug_sma.n_rx),
|
||||||
|
|
||||||
# # pmod 0-7 pin
|
# # pmod 0-7 pin
|
||||||
# Instance("OBUF", i_I=gtx.comma_checker.comma_aligned, o_O=pmod_pads[0]),
|
Instance("OBUF", i_I=txstb, o_O=pmod_pads[0]),
|
||||||
# Instance("OBUF", i_I=gtx.comma_checker.comma_det, o_O=pmod_pads[1]),
|
Instance("OBUF", i_I=fifo_in.source.stb, o_O=pmod_pads[1]),
|
||||||
# Instance("OBUF", i_I=gtx.comma_checker.restart_sys, o_O=pmod_pads[2]),
|
Instance("OBUF", i_I=fifo_in.source.ack, o_O=pmod_pads[2]),
|
||||||
# Instance("OBUF", i_I=gtx.comma_checker.aligner_en, o_O=pmod_pads[3]),
|
# Instance("OBUF", i_I=gtx.comma_checker.aligner_en, o_O=pmod_pads[3]),
|
||||||
# Instance("OBUF", i_I=gtx.comma_checker.check_reset, o_O=pmod_pads[4]),
|
# Instance("OBUF", i_I=gtx.comma_checker.check_reset, o_O=pmod_pads[4]),
|
||||||
# Instance("OBUF", i_I=gtx.comma_checker.has_comma, o_O=pmod_pads[5]),
|
# Instance("OBUF", i_I=gtx.comma_checker.has_comma, o_O=pmod_pads[5]),
|
||||||
|
@ -159,43 +230,6 @@ class CXP_DownConn_PHY(Module, AutoCSR):
|
||||||
# Instance("OBUF", i_I=gtx.dready, o_O=pmod_pads[3]),
|
# Instance("OBUF", i_I=gtx.dready, o_O=pmod_pads[3]),
|
||||||
]
|
]
|
||||||
|
|
||||||
# DEBUG: datain
|
|
||||||
|
|
||||||
|
|
||||||
self.sync.cxp_gtx_tx += [
|
|
||||||
gtx.encoder.d[0].eq(0xBC),
|
|
||||||
gtx.encoder.k[0].eq(1),
|
|
||||||
gtx.encoder.d[1].eq(0x3C),
|
|
||||||
gtx.encoder.k[1].eq(1),
|
|
||||||
gtx.encoder.d[2].eq(0x3C),
|
|
||||||
gtx.encoder.k[2].eq(1),
|
|
||||||
gtx.encoder.d[3].eq(0xB5),
|
|
||||||
gtx.encoder.k[3].eq(0),
|
|
||||||
]
|
|
||||||
|
|
||||||
for i in range(4):
|
|
||||||
gtx.decoders[i].input.attr.add("no_retiming")
|
|
||||||
gtx.decoders[i].d.attr.add("no_retiming")
|
|
||||||
gtx.decoders[i].k.attr.add("no_retiming")
|
|
||||||
|
|
||||||
rxdata_name = "rxdata_" + str(i)
|
|
||||||
rxdata_csr = CSRStatus(10, name=rxdata_name)
|
|
||||||
setattr(self, rxdata_name, rxdata_csr)
|
|
||||||
|
|
||||||
decoded_name = "decoded_data_" + str(i)
|
|
||||||
decoded_csr = CSRStatus(8, name=decoded_name)
|
|
||||||
setattr(self, decoded_name, decoded_csr)
|
|
||||||
|
|
||||||
k_name = "rxdata_" + str(i)
|
|
||||||
k_csr = CSRStatus(1, name=k_name)
|
|
||||||
setattr(self, k_name, k_csr)
|
|
||||||
|
|
||||||
self.sync.cxp_gtx_rx += [
|
|
||||||
rxdata_csr.status.eq(gtx.decoders[i].input),
|
|
||||||
decoded_csr.status.eq(gtx.decoders[i].d),
|
|
||||||
k_csr.status.eq(gtx.decoders[i].k),
|
|
||||||
]
|
|
||||||
|
|
||||||
class QPLL(Module, AutoCSR):
|
class QPLL(Module, AutoCSR):
|
||||||
def __init__(self, refclk, sys_clk_freq):
|
def __init__(self, refclk, sys_clk_freq):
|
||||||
self.clk = Signal()
|
self.clk = Signal()
|
||||||
|
|
Loading…
Reference in New Issue