serdes-transceiver/serdes.py

123 lines
4.5 KiB
Python

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)