serdes-transceiver/serdes_loopback.py

103 lines
3.2 KiB
Python
Raw Permalink Normal View History

2023-04-23 11:42:18 +08:00
from migen import *
from serdes import *
from migen.genlib.fifo import SyncFIFO
from migen.build.platforms.sinara import kasli
from migen.genlib.misc import WaitTimer
from kasli_crg import KasliCRG
from eem_helpers import generate_pads
from uart import UART
from io_loopback import IOLoopBack
SEPARATOR = Constant(0b0101)
class SerDesLoopBack(Module):
def __init__(self, io_pads, 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 = SerTX()
self.submodules.rx = DesRX()
# The actual channel
self.submodules.channel = IOLoopBack(io_pads)
# # Additional timer: Only permit UART transmission when timer is not up
# self.submodules.wait_timer = WaitTimer(10)
# Memoize the previous rxdata
self.rxdata_r = Signal(8)
# Attach FIFO to UART TX, send rate is too slow w.r.t sysclk
self.submodules.tx_fifo = SyncFIFO(8, 64)
self.comb += [
# RX path: From UART to channel
# self.rx_buffer.din.eq(self.uart.rx_data),
# self.rx_buffer.we.eq(self.uart.rx_stb),
self.tx.txdata[:8].eq(Mux(self.uart.rx_stb, self.uart.rx_data, 0)),
self.tx.txdata[8:12].eq(Mux(SEPARATOR, self.uart.rx_data, 0)),
self.tx.txdata[12:].eq(Mux(self.uart.rx_stb, self.uart.rx_data, 0)),
# Loopback channel
self.channel.i.eq(self.tx.ser_out),
self.rx.ser_in.eq(self.channel.o),
self.channel.t.eq(self.tx.t_out),
# self.rx.ser_in.eq(self.tx.ser_out),
# self.rx.ser_in[3].eq(self.tx.ser_out[3]),
# TX path
# self.uart.tx_data.eq(self.tx_buffer.dout),
# self.uart.tx_stb.eq(self.tx_buffer.readable),
# self.tx_buffer.re.eq(self.uart.tx_ack),
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),
]
# Timer control
self.sync += [
# Send data to FIFO if not repeated
If(self.rxdata_r != self.rx.rxdata[:8],
self.rxdata_r.eq(self.rx.rxdata),
self.tx_fifo.din.eq(self.rx.rxdata),
self.tx_fifo.we.eq(1)
).Else(
self.tx_fifo.we.eq(0)
)
]
# self.sync.sys5x += [
# self.rx.ser_in.eq(self.tx.ser_out),
# ]
if __name__ == "__main__":
platform = kasli.Platform(hw_rev="v2.0")
# Generate pads for the I/O blocks
eem = 0
generate_pads(platform, eem)
pads = [
platform.request("dio{}".format(eem), i) for i in range(4)
]
crg = KasliCRG(platform)
top = SerDesLoopBack(pads, 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)