123 lines
4.5 KiB
Python
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)
|