diff --git a/single_serdes_loopback.py b/single_serdes_loopback.py index 39e6a68..c941038 100644 --- a/single_serdes_loopback.py +++ b/single_serdes_loopback.py @@ -24,9 +24,16 @@ class SingleSerDesLoopBack(Module): self.submodules.tx = SingleLineTX() self.submodules.rx = SingleLineRX() + + # Primary adjustment to master-slave bitslip self.submodules.bitslip_reader = BitSlipReader() self.submodules.slave_aligner = SlaveAligner() self.submodules.post_align_reader = BitSlipReader() + + # Optimal delay solver + self.submodules.phase_reader = PhaseReader() + self.submodules.delay_solver = DelayOptimizer() + # self.submodules.delay_optimizer = DelayOptimizer() # The actual channel @@ -55,21 +62,21 @@ class SingleSerDesLoopBack(Module): # Start the reader initially self.bitslip_reader.start.eq(1), # Delay tap optimizer will start after the reader is done - # self.delay_optimizer.start.eq(0), self.slave_aligner.start.eq(0), self.post_align_reader.start.eq(0), + self.phase_reader.start.eq(0), + self.delay_solver.start.eq(0), # RXDATA for both reader and optimzer self.bitslip_reader.loopback_rxdata.eq(self.rx.rxdata), - # TODO: Reconnet - # self.delay_optimizer.loopback_rxdata.eq(self.rx.rxdata), self.slave_aligner.loopback_rxdata.eq(self.rx.rxdata), self.post_align_reader.loopback_rxdata.eq(self.rx.rxdata), + self.phase_reader.loopback_rxdata.eq(self.rx.rxdata), + self.delay_solver.loopback_rxdata.eq(self.rx.rxdata), # Delay tap value - # self.phase_reader.delay_tap.eq(self.rx.cnt_out), - # TODO: Reconnet - # self.delay_optimizer.delay_tap.eq(self.rx.cnt_out), + self.phase_reader.delay_tap.eq(self.rx.cnt_out), + self.delay_solver.delay_tap.eq(self.rx.cnt_out), # Increment control enable, such that phase_reader can # increment tap value after delay measurement @@ -79,7 +86,10 @@ class SingleSerDesLoopBack(Module): # ).Else( # self.rx.ce.eq(self.phase_reader.inc_en), # ) - # self.rx.ce.eq(self.phase_reader.inc_en), + self.rx.ce.eq( + self.phase_reader.inc_en | + self.delay_solver.inc_en + ), self.rx.master_bitslip.eq( self.bitslip_reader.bitslip | self.slave_aligner.master_bitslip | @@ -93,7 +103,7 @@ class SingleSerDesLoopBack(Module): ] # Show measured result on UART - delay_tap = Signal(6) + delay_tap_count = Signal(6) bitslip_count = Signal(3) post_align_bitslip_count = Signal(3) @@ -109,7 +119,7 @@ class SingleSerDesLoopBack(Module): fsm.act("WRITE_UPPER", # Exist state if all results are sent If(bitslip_count == 5, - NextState("FIND_OPT_DELAY"), + NextState("START_SLAVE_ALIGNER"), ).Elif(self.tx_fifo.writable, self.tx_fifo.we.eq(1), self.tx_fifo.din.eq(self.bitslip_reader.data_result[bitslip_count][8:]), @@ -124,13 +134,13 @@ class SingleSerDesLoopBack(Module): NextState("WRITE_UPPER"), ) - fsm.act("FIND_OPT_DELAY", + fsm.act("START_SLAVE_ALIGNER", self.slave_aligner.start.eq(1), # self.rx.ce.eq(self.delay_optimizer.inc_en), If(self.slave_aligner.done, NextState("WRITE_DONE_UPPER"), ).Else( - NextState("FIND_OPT_DELAY") + NextState("START_SLAVE_ALIGNER") ) ) @@ -163,7 +173,7 @@ class SingleSerDesLoopBack(Module): fsm.act("REWRITE_UPPER", # Exist state if all results are sent If(post_align_bitslip_count == 5, - NextState("TERMINATE"), + NextState("WRITE_B2P_DIVIDER_UPPER"), ).Elif(self.tx_fifo.writable, self.tx_fifo.we.eq(1), self.tx_fifo.din.eq(self.post_align_reader.data_result[post_align_bitslip_count][8:]), @@ -178,6 +188,93 @@ class SingleSerDesLoopBack(Module): NextState("REWRITE_UPPER"), ) + fsm.act("WRITE_B2P_DIVIDER_UPPER", + self.phase_reader.start.eq(1), + If(self.tx_fifo.writable, + self.tx_fifo.we.eq(1), + self.tx_fifo.din.eq(0xFF), + NextState("WRITE_B2P_DIVIDER_LOWER"), + ) + ) + + fsm.act("WRITE_B2P_DIVIDER_LOWER", + self.phase_reader.start.eq(1), + If(self.tx_fifo.writable, + self.tx_fifo.we.eq(1), + self.tx_fifo.din.eq(0xFF), + NextState("WAIT_PHASE_READER"), + ) + ) + + fsm.act("WAIT_PHASE_READER", + If(self.phase_reader.done, + NextState("WRITE_DELAY_UPPER"), + ).Else( + NextState("WAIT_PHASE_READER"), + ) + ) + + fsm.act("WRITE_DELAY_UPPER", + If(delay_tap_count == 32, + NextState("DELAY_SOLVER_DIVIDER_UPPER") + ).Elif(self.tx_fifo.writable, + self.tx_fifo.we.eq(1), + self.tx_fifo.din.eq(self.phase_reader.data_result[delay_tap_count][8:]), + NextState("WRITE_DELAY_LOWER"), + ), + ) + + fsm.act("WRITE_DELAY_LOWER", + If(self.tx_fifo.writable, + self.tx_fifo.we.eq(1), + self.tx_fifo.din.eq(self.phase_reader.data_result[delay_tap_count][:8]), + NextValue(delay_tap_count, delay_tap_count + 1), + NextState("WRITE_DELAY_UPPER") + ), + ) + + fsm.act("DELAY_SOLVER_DIVIDER_UPPER", + self.delay_solver.start.eq(1), + If(self.tx_fifo.writable, + self.tx_fifo.we.eq(1), + self.tx_fifo.din.eq(0xFF), + NextState("DELAY_SOLVER_DIVIDER_LOWER"), + ) + ) + + fsm.act("DELAY_SOLVER_DIVIDER_LOWER", + self.delay_solver.start.eq(1), + If(self.tx_fifo.writable, + self.tx_fifo.we.eq(1), + self.tx_fifo.din.eq(0xFF), + NextState("WAIT_DELAY_SOLVER"), + ) + ) + + fsm.act("WAIT_DELAY_SOLVER", + If(self.delay_solver.done, + NextState("WRITE_UPPER_ZERO"), + ).Else( + NextState("WAIT_DELAY_SOLVER"), + ) + ) + + fsm.act("WRITE_UPPER_ZERO", + If(self.tx_fifo.writable, + self.tx_fifo.we.eq(1), + self.tx_fifo.din.eq(0x00), + NextState("WRITE_LOWER_OPT"), + ) + ) + + fsm.act("WRITE_LOWER_OPT", + If(self.tx_fifo.writable, + self.tx_fifo.we.eq(1), + self.tx_fifo.din.eq(self.delay_solver.opt_delay_tap), + NextState("TERMINATE"), + ), + ) + fsm.act("TERMINATE", NextState("TERMINATE"), )