From b73777b39f345715d9005d48b00d8f96a0e6d1c8 Mon Sep 17 00:00:00 2001 From: occheung Date: Mon, 24 Apr 2023 07:41:58 +0800 Subject: [PATCH] load optimal delay tap --- single_serdes_loopback.py | 30 +++++++++++++++++++++--------- sync_serdes.py | 26 ++++++++++++++++++-------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/single_serdes_loopback.py b/single_serdes_loopback.py index c941038..a7ecf6a 100644 --- a/single_serdes_loopback.py +++ b/single_serdes_loopback.py @@ -78,14 +78,8 @@ class SingleSerDesLoopBack(Module): 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 - # Re-assign the incremnet control to the optimizer after the optimizer has started - # If(self.delay_optimizer.start, - # self.rx.ce.eq(self.delay_optimizer.inc_en), - # ).Else( - # self.rx.ce.eq(self.phase_reader.inc_en), - # ) + # IDELAY delay tap control, such that phase_reader can + # change tap value after delay measurement self.rx.ce.eq( self.phase_reader.inc_en | self.delay_solver.inc_en @@ -100,6 +94,8 @@ class SingleSerDesLoopBack(Module): self.slave_aligner.slave_bitslip | self.post_align_reader.bitslip ), + self.rx.ld.eq(self.delay_solver.ld), + self.rx.cnt_in.eq(self.delay_solver.opt_delay_tap), ] # Show measured result on UART @@ -271,10 +267,26 @@ class SingleSerDesLoopBack(Module): If(self.tx_fifo.writable, self.tx_fifo.we.eq(1), self.tx_fifo.din.eq(self.delay_solver.opt_delay_tap), - NextState("TERMINATE"), + NextState("RESAMPLE_RXDATA_UPPER"), ), ) + fsm.act("RESAMPLE_RXDATA_UPPER", + If(self.tx_fifo.writable, + self.tx_fifo.we.eq(1), + self.tx_fifo.din.eq(self.rx.rxdata[8:]), + NextState("RESAMPLE_RXDATA_LOWER"), + ) + ) + + fsm.act("RESAMPLE_RXDATA_LOWER", + If(self.tx_fifo.writable, + self.tx_fifo.we.eq(1), + self.tx_fifo.din.eq(self.rx.rxdata[:8]), + NextState("TERMINATE"), + ) + ) + fsm.act("TERMINATE", NextState("TERMINATE"), ) diff --git a/sync_serdes.py b/sync_serdes.py index b4eee35..5c99505 100644 --- a/sync_serdes.py +++ b/sync_serdes.py @@ -32,7 +32,9 @@ class SingleLineRX(Module): def __init__(self): self.rxdata = Signal(10) self.ser_in_no_dly = Signal() + self.ld = Signal() self.ce = Signal() + self.cnt_in = Signal(5) self.cnt_out = Signal(5) self.opt_delay = Signal(5) self.master_bitslip = Signal() @@ -97,21 +99,22 @@ class SingleLineRX(Module): # REFCLK refers to the clock source of IDELAYCTRL p_REFCLK_FREQUENCY=200.0, p_PIPE_SEL="FALSE", - p_IDELAY_TYPE="VARIABLE", + p_IDELAY_TYPE="VAR_LOAD", p_IDELAY_VALUE=0, i_C=ClockSignal("rx_sys"), - # i_LD=self._dly_sel.storage[i//8] & self._rdly_dq_rst.re, - # i_CE=self._dly_sel.storage[i//8] & self._rdly_dq_inc.re, - i_LD=0, - i_CE=self.ce, # TODO: Port output + i_LD=self.ld, + i_CE=self.ce, i_LDPIPEEN=0, i_INC=1, # Always increment - # Allow aligner to check delay tap value + # Set the optimal delay tap via the aligner + i_CNTVALUEIN=self.cnt_in, + # Allow the aligner to check the tap value o_CNTVALUEOUT=self.cnt_out, - i_IDATAIN=self.ser_in_no_dly, o_DATAOUT=ser_in + i_IDATAIN=self.ser_in_no_dly, + o_DATAOUT=ser_in ), # IDELAYCTRL is with the clocking @@ -434,6 +437,7 @@ class DelayOptimizer(Module): # OUT # Signal for controlling the channel delay tap + self.ld = Signal() self.inc_en = Signal() # OUT @@ -528,7 +532,7 @@ class DelayOptimizer(Module): fsm.act("SAMPLE_PULSE_OUT", If(~self.rxdata_array[self.expected_pulse], NextValue(self.opt_delay_tap, self.min_delay + (self.max_offset >> 1)), - NextState("TERMINATE"), + NextState("LOAD_OPT_DELAY"), ).Else( NextValue(self.max_offset, self.max_offset + 1), NextState("INC_PULSE_DELAY_OUT"), @@ -541,6 +545,12 @@ class DelayOptimizer(Module): NextState("WAIT_PULSE_OUT"), ) + fsm.act("LOAD_OPT_DELAY", + self.ld.eq(1), + # The optimal delay tap is prepared in the SAMPLE_PULSE_OUT state + NextState("TERMINATE"), + ) + fsm.act("TERMINATE", self.done.eq(1), NextState("TERMINATE"),