from migen import * class SerTX(Module): def __init__(self): self.txdata = Signal(20) self.ser_out = Signal(4) self.t_out = Signal(4) # TODO: Create T pins # Transmitter PHY: 4-wire for i in range(4): # Serialize 5 bits into each channel # TX SERDES self.specials += Instance("OSERDESE2", p_DATA_RATE_OQ="SDR", p_DATA_RATE_TQ="BUF", p_DATA_WIDTH=5, p_TRISTATE_WIDTH=1, p_INIT_OQ=0b00000, o_OQ=self.ser_out[i], o_TQ=self.t_out[i], i_RST=ResetSignal(), i_CLK=ClockSignal("sys5x"), i_CLKDIV=ClockSignal(), i_D1=self.txdata[i*5 + 0], i_D2=self.txdata[i*5 + 1], i_D3=self.txdata[i*5 + 2], i_D4=self.txdata[i*5 + 3], i_D5=self.txdata[i*5 + 4], i_TCE=1, i_OCE=1, # TODO: Hardcode t_in? Output disable is always unnecessary? i_T1=0) class DesRX(Module): def __init__(self): self.rxdata = Signal(20) self.ser_in = Signal(4) for i in range(4): # Deserialize 5 bits from each channel # RX SERDES self.specials += [ Instance("ISERDESE2", p_DATA_RATE="SDR", p_DATA_WIDTH=5, p_INTERFACE_TYPE="NETWORKING", p_NUM_CE=1, o_Q1=self.rxdata[i*5 + 4], o_Q2=self.rxdata[i*5 + 3], o_Q3=self.rxdata[i*5 + 2], o_Q4=self.rxdata[i*5 + 1], o_Q5=self.rxdata[i*5 + 0], i_D=self.ser_in[i], i_CLK=ClockSignal("rx_sys5x"), i_CLKB=~ClockSignal("rx_sys5x"), i_CE1=1, i_RST=ResetSignal("rx_sys"), i_CLKDIV=ClockSignal("rx_sys")), # # Tunable delay # Instance("IDELAYE2", # p_DELAY_SRC="IDATAIN", p_SIGNAL_PATTERN="DATA", # p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="TRUE", p_REFCLK_FREQUENCY=200.0, # p_PIPE_SEL="FALSE", p_IDELAY_TYPE="VARIABLE", p_IDELAY_VALUE=0, # i_C=ClockSignal(), # 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_LDPIPEEN=0, i_INC=1, # i_IDATAIN=dq_i_nodelay, o_DATAOUT=dq_i_delayed # ) ] # class DoubleDesRX(Module): # def __init__(self): # self.rxdata = Signal(20) # self.rx_first_edge = Signal() # rx_raw = Array(Signal(20) for _ in range(2)) # self.comb += [ # rxdata.eq(rx_raw[self.rx_first_edge]) # ] # # Receiver PHY: 4-wire # for i in range(4): # # Deserialize 5 bits from each channel # # With 2x oversampling # # RX SERDES # self.specials += Instance("ISERDESE2", p_DATA_RATE="DDR", # p_DATA_WIDTH=10, # p_INTERFACE_TYPE="NETWORKING", p_NUM_CE=1, # p_SERDES_MODE="MASTER", # o_Q1=rx_raw[1][i*5 + 4], o_Q2=rx_raw[0][i*5 + 4], # o_Q3=rx_raw[1][i*5 + 3], o_Q4=rx_raw[0][i*5 + 3], # o_Q5=rx_raw[1][i*5 + 2], o_Q6=rx_raw[0][i*5 + 2], # o_Q7=rx_raw[1][i*5 + 1], o_Q8=rx_raw[0][i*5 + 1], # i_D=self.ser_in[i], # # We are using 5x for SDR # i_CLK=ClockSignal("sys5x"), # i_CLKB=~ClockSignal("sys5x"), # i_CE1=1, # i_RST=ResetSignal(), # i_CLKDIV=ClockSignal(), # o_SHIFTOUT1=serdes_link1, # o_SHIFTOUT2=serdes_link2) # self.specials += Instance("ISERDESE2", p_DATA_RATE="DDR", # p_DATA_WIDTH=10, # p_INTERFACE_TYPE="NETWORKING", p_NUM_CE=1, # p_SERDES_MODE="SLAVE", # o_Q1=rx_raw[1][i*5], o_Q2=rx_raw[0][i*5], # i_D=self.ser_in[i], # # We are using 5x for SDR # i_CLK=ClockSignal("sys5x"), # i_CLKB=~ClockSignal("sys5x"), # i_CE1=1, # i_RST=ResetSignal(), # i_CLKDIV=ClockSignal(), # i_SHIFTIN1=serdes_link1, # i_SHIFTIN2=serdes_link2)