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)