serdes-transceiver/multi_serdes_loopback.py

105 lines
2.9 KiB
Python
Raw Normal View History

2023-04-25 07:59:04 +08:00
from migen import *
from sync_serdes import SyncSingleRX, SingleLineTX
from migen.genlib.fifo import SyncFIFO
from migen.build.platforms.sinara import kasli
from kasli_crg import KasliCRG
from eem_helpers import generate_pads
from uart import UART
from io_loopback import SingleIOLoopback
class MultiSerDesLoopBack(Module):
def __init__(self, io_pad, sys_clk_freq):
self.uart_rx = Signal()
self.uart_tx = Signal()
self.submodules.uart = UART(round((115200/sys_clk_freq)*2**32))
self.comb += [
self.uart.phy_rx.eq(self.uart_rx),
self.uart_tx.eq(self.uart.phy_tx),
]
self.submodules.tx = SingleLineTX()
self.submodules.sync_rx = SyncSingleRX()
# The actual channel
self.submodules.channel = SingleIOLoopback(io_pad)
# Attach FIFO to UART TX, send rate is too slow w.r.t sysclk
self.submodules.tx_fifo = SyncFIFO(8, 64)
self.comb += [
# Repetitively send 0b00100
self.tx.txdata.eq(0b00100),
# Loopback channel
self.channel.i.eq(self.tx.ser_out),
self.sync_rx.ser_in_no_dly.eq(self.channel.o),
self.channel.t.eq(self.tx.t_out),
# TX path
self.uart.tx_data.eq(self.tx_fifo.dout),
self.uart.tx_stb.eq(self.tx_fifo.readable),
self.tx_fifo.re.eq(self.uart.tx_ack),
]
self.submodules.fsm = FSM(reset_state="WAIT_SELF_ALIGN")
self.fsm.act("WAIT_SELF_ALIGN",
If(self.sync_rx.align_done,
NextState("SAMPLE_RXDATA"),
),
)
sampled_rxdata = Signal(5)
self.fsm.act("SAMPLE_RXDATA",
NextValue(sampled_rxdata, self.sync_rx.rxdata),
NextState("WRITE_PATTERN_UPPER"),
)
self.fsm.act("WRITE_PATTERN_UPPER",
If(self.tx_fifo.writable,
self.tx_fifo.we.eq(1),
self.tx_fifo.din.eq(sampled_rxdata),
NextState("WRITE_PATTERN_LOWER"),
),
)
self.fsm.act("WRITE_PATTERN_LOWER",
If(self.tx_fifo.writable,
self.tx_fifo.we.eq(1),
self.tx_fifo.din.eq(sampled_rxdata),
NextState("TERMINATE"),
),
)
self.fsm.act("TERMINATE",
NextState("TERMINATE"),
)
if __name__ == "__main__":
platform = kasli.Platform(hw_rev="v2.0")
# Generate pads for the I/O blocks
eem = 3
generate_pads(platform, eem)
# pads = [
# platform.request("dio{}".format(eem), i) for i in range(4)
# ]
pad = platform.request("dio{}".format(eem), 0)
crg = KasliCRG(platform)
top = MultiSerDesLoopBack(pad, crg.sys_clk_freq)
# Wire up UART core to the pads
uart_pads = platform.request("serial")
top.comb += [
top.uart_rx.eq(uart_pads.rx),
uart_pads.tx.eq(top.uart_tx),
]
top.submodules += crg
platform.build(top)