serdes-transceiver/pulse_read_rx.py

256 lines
7.7 KiB
Python

from migen import *
from migen.genlib.fifo import SyncFIFO
from migen.genlib.misc import WaitTimer
from migen.build.platforms.sinara import kasli, efc
from eem_helpers import generate_pads
from serdes_comm import BiDirectionalIO
from sync_serdes import SingleLineRX, BitSlipReader, SlaveAligner
from uart_log import UARTLogger
from kasli_crg import TransceiverCRG
class SingleLineReader(Module):
def __init__(self, uart_log, i_pads, o_pads):
# UART Logger
self.submodules.uart_logger = uart_log
# Recorder
self.submodules.rx_buffer = SyncFIFO(10, 64)
# PHY Channel
self.submodules.channel = BiDirectionalIO(i_pads, o_pads)
# Single line RX SERDES
self.submodules.rx = SingleLineRX()
# bitslip reader
self.submodules.bitslip_reader = BitSlipReader()
self.submodules.postslip_reader = BitSlipReader()
# Alignment modules
self.submodules.slave_aligner = SlaveAligner()
# Connect SERDES to PHY
self.comb += [
self.rx.ser_in_no_dly.eq(self.channel.o[0]),
]
# Debugging logics
self.comb += [
self.bitslip_reader.loopback_rxdata.eq(self.rx.rxdata),
self.postslip_reader.loopback_rxdata.eq(self.rx.rxdata),
self.slave_aligner.loopback_rxdata.eq(self.rx.rxdata),
self.rx.master_bitslip.eq(
self.bitslip_reader.bitslip
| self.slave_aligner.master_bitslip
| self.postslip_reader.bitslip
),
self.rx.slave_bitslip.eq(
self.bitslip_reader.bitslip
| self.slave_aligner.master_bitslip
| self.postslip_reader.bitslip
),
]
bitslip_count = Signal(3)
fsm = FSM(reset_state="WAIT_DONE")
self.submodules += fsm
fsm.act("WAIT_DONE",
self.bitslip_reader.start.eq(1),
If(self.bitslip_reader.done,
NextValue(bitslip_count, 0),
NextState("WRITE_UPPER"),
),
)
fsm.act("WRITE_UPPER",
If(bitslip_count == 5,
NextState("WAIT_BITSLIP_ALIGNED"),
).Elif(self.uart_logger.tx_fifo.writable,
self.uart_logger.tx_fifo.we.eq(1),
self.uart_logger.tx_fifo.din.eq(self.bitslip_reader.data_result[bitslip_count][8:]),
NextState("WRITE_LOWER"),
),
)
fsm.act("WRITE_LOWER",
If(self.uart_logger.tx_fifo.writable,
self.uart_logger.tx_fifo.we.eq(1),
self.uart_logger.tx_fifo.din.eq(self.bitslip_reader.data_result[bitslip_count][:8]),
NextValue(bitslip_count, bitslip_count + 1),
NextState("WRITE_UPPER"),
)
)
fsm.act("WAIT_BITSLIP_ALIGNED",
self.slave_aligner.start.eq(1),
If(self.slave_aligner.done,
NextState("BARRIER_UPPER"),
),
)
fsm.act("BARRIER_UPPER",
If(self.uart_logger.tx_fifo.writable,
self.uart_logger.tx_fifo.we.eq(1),
self.uart_logger.tx_fifo.din.eq(0xFF),
NextState("BARRIER_LOWER"),
),
)
fsm.act("BARRIER_LOWER",
If(self.uart_logger.tx_fifo.writable,
self.uart_logger.tx_fifo.we.eq(1),
self.uart_logger.tx_fifo.din.eq(0xFF),
NextState("REWAIT_BITSLIP_READ_DONE"),
),
)
fsm.act("REWAIT_BITSLIP_READ_DONE",
self.postslip_reader.start.eq(1),
If(self.postslip_reader.done,
NextValue(bitslip_count, 0),
NextState("REWRITE_UPPER"),
),
)
fsm.act("REWRITE_UPPER",
If(bitslip_count == 5,
NextState("TERMINATE"),
).Elif(self.uart_logger.tx_fifo.writable,
self.uart_logger.tx_fifo.we.eq(1),
self.uart_logger.tx_fifo.din.eq(self.postslip_reader.data_result[bitslip_count][8:]),
NextState("REWRITE_LOWER"),
),
)
fsm.act("REWRITE_LOWER",
If(self.uart_logger.tx_fifo.writable,
self.uart_logger.tx_fifo.we.eq(1),
self.uart_logger.tx_fifo.din.eq(self.postslip_reader.data_result[bitslip_count][:8]),
NextValue(bitslip_count, bitslip_count + 1),
NextState("REWRITE_UPPER"),
)
)
fsm.act("TERMINATE",
NextState("TERMINATE"),
)
# self.submodules.wait_timer = WaitTimer(127)
# shift_count = Signal(5)
# self.submodules.fsm = FSM(reset_state="WAIT")
# self.fsm.act("WAIT",
# self.wait_timer.wait.eq(1),
# If(shift_count == 10,
# NextState("DUMP_UPPER"),
# ).Elif(self.wait_timer.done,
# NextState("MEASURE"),
# ),
# )
# self.fsm.act("MEASURE",
# If(self.rx_buffer.writable,
# self.rx_buffer.we.eq(1),
# self.rx_buffer.din.eq(self.rx.rxdata),
# NextState("SHIFT1"),
# ),
# )
# self.fsm.act("SHIFT1",
# self.rx.master_bitslip.eq(1),
# self.rx.slave_bitslip.eq(1),
# NextState("GAP"),
# )
# self.fsm.act("GAP",
# NextState("SHIFT2"),
# )
# self.fsm.act("SHIFT2",
# self.rx.master_bitslip.eq(1),
# self.rx.slave_bitslip.eq(1),
# NextValue(shift_count, shift_count + 1),
# NextState("WAIT"),
# )
# self.fsm.act("DUMP_UPPER",
# If(self.rx_buffer.readable,
# If(self.uart_logger.tx_fifo.writable,
# self.uart_logger.tx_fifo.we.eq(1),
# self.uart_logger.tx_fifo.din.eq(self.rx_buffer.dout[8:]),
# NextState("DUMP_LOWER"),
# ),
# ).Else(
# NextState("TERMINATE"),
# )
# )
# self.fsm.act("DUMP_LOWER",
# If(self.uart_logger.tx_fifo.writable,
# self.uart_logger.tx_fifo.we.eq(1),
# self.uart_logger.tx_fifo.din.eq(self.rx_buffer.dout[:8]),
# self.rx_buffer.re.eq(1),
# NextState("DUMP_UPPER"),
# ),
# )
# self.fsm.act("TERMINATE",
# NextState("TERMINATE"),
# )
if __name__ == "__main__":
import argparse
import functools
import os
parser = argparse.ArgumentParser()
parser.add_argument("platform")
args = parser.parse_args()
platform_dict = {
"kasli": kasli.Platform(hw_rev="v2.0"),
"efc": efc.Platform(),
}
sysclk_name = {
"kasli": "clk125_gtp",
"efc": "gtp_clk",
}
platform = platform_dict[args.platform]
sysclk = platform.request(sysclk_name[args.platform])
# Generate pads for the I/O blocks
for eem in range(2):
generate_pads(platform, eem)
data_eem = 0
i_pads = [
platform.request("dio{}".format(data_eem), i) for i in range(4)
]
o_pads = [
platform.request("dio{}".format(data_eem), i+4) for i in range(4)
]
crg = TransceiverCRG(platform, sysclk)
uart_logger = UARTLogger(crg.sys_clk_freq)
top = SingleLineReader(uart_logger, i_pads, o_pads)
# Wire up UART core to the pads
uart_pads = platform.request("serial")
top.comb += [
uart_logger.uart_rx.eq(uart_pads.rx),
uart_pads.tx.eq(uart_logger.uart_tx),
]
top.submodules += crg
output_dir = "{}_{}_build".format(args.platform, "satellite")
platform.build(top, build_dir=output_dir)