From 3248caa1843b4bbd09ab8d54472639739004e643 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 3 Apr 2018 18:48:08 +0200 Subject: [PATCH] gateware/serwb: move all clocking outside of serwb, use existing sys/sys4x clocks --- artiq/gateware/serwb/kusphy.py | 68 ++++++++++++++------------------ artiq/gateware/serwb/phy.py | 72 +++------------------------------- artiq/gateware/serwb/s7phy.py | 54 +++++++++++-------------- 3 files changed, 59 insertions(+), 135 deletions(-) diff --git a/artiq/gateware/serwb/kusphy.py b/artiq/gateware/serwb/kusphy.py index 054971612..e0b9baa1f 100644 --- a/artiq/gateware/serwb/kusphy.py +++ b/artiq/gateware/serwb/kusphy.py @@ -7,7 +7,10 @@ from misoc.cores.code_8b10b import Encoder, Decoder class KUSSerdes(Module): - def __init__(self, pll, pads, mode="master"): + def __init__(self, pads, mode="master"): + if mode == "slave": + self.refclk = Signal() + self.tx_k = Signal(4) self.tx_d = Signal(32) self.rx_k = Signal(4) @@ -26,29 +29,18 @@ class KUSSerdes(Module): # # # - self.submodules.encoder = ClockDomainsRenamer("serwb_serdes")( + self.submodules.encoder = ClockDomainsRenamer("sys0p2x")( Encoder(4, True)) - self.decoders = [ClockDomainsRenamer("serwb_serdes")( + self.decoders = [ClockDomainsRenamer("sys0p2x")( Decoder(True)) for _ in range(4)] self.submodules += self.decoders # clocking: # In master mode: - # - linerate/10 pll refclk provided by user - # - linerate/10 slave refclk generated on clk_pads + # - linerate/10 refclk generated on clk_pads # In Slave mode: - # - linerate/10 pll refclk provided by clk_pads - self.clock_domains.cd_serwb_serdes = ClockDomain() - self.clock_domains.cd_serwb_serdes_5x = ClockDomain() - self.clock_domains.cd_serwb_serdes_20x = ClockDomain(reset_less=True) - self.comb += [ - self.cd_serwb_serdes.clk.eq(pll.serwb_serdes_clk), - self.cd_serwb_serdes_5x.clk.eq(pll.serwb_serdes_5x_clk), - self.cd_serwb_serdes_20x.clk.eq(pll.serwb_serdes_20x_clk) - ] - self.specials += AsyncResetSynchronizer(self.cd_serwb_serdes, ~pll.lock) - self.comb += self.cd_serwb_serdes_5x.rst.eq(self.cd_serwb_serdes.rst) + # - linerate/10 refclk provided by clk_pads # control/status cdc tx_idle = Signal() @@ -61,20 +53,20 @@ class KUSSerdes(Module): rx_delay_en_vtc = Signal() rx_delay_ce = Signal() self.specials += [ - MultiReg(self.tx_idle, tx_idle, "serwb_serdes"), - MultiReg(self.tx_comma, tx_comma, "serwb_serdes"), + MultiReg(self.tx_idle, tx_idle, "sys0p2x"), + MultiReg(self.tx_comma, tx_comma, "sys0p2x"), MultiReg(rx_idle, self.rx_idle, "sys"), MultiReg(rx_comma, self.rx_comma, "sys"), - MultiReg(self.rx_bitslip_value, rx_bitslip_value, "serwb_serdes"), - MultiReg(self.rx_delay_inc, rx_delay_inc, "serwb_serdes_5x"), - MultiReg(self.rx_delay_en_vtc, rx_delay_en_vtc, "serwb_serdes_5x") + MultiReg(self.rx_bitslip_value, rx_bitslip_value, "sys0p2x"), + MultiReg(self.rx_delay_inc, rx_delay_inc, "sys"), + MultiReg(self.rx_delay_en_vtc, rx_delay_en_vtc, "sys") ] - self.submodules.do_rx_delay_rst = PulseSynchronizer("sys", "serwb_serdes_5x") + self.submodules.do_rx_delay_rst = PulseSynchronizer("sys", "sys") self.comb += [ rx_delay_rst.eq(self.do_rx_delay_rst.o), self.do_rx_delay_rst.i.eq(self.rx_delay_rst) ] - self.submodules.do_rx_delay_ce = PulseSynchronizer("sys", "serwb_serdes_5x") + self.submodules.do_rx_delay_ce = PulseSynchronizer("sys", "sys") self.comb += [ rx_delay_ce.eq(self.do_rx_delay_ce.o), self.do_rx_delay_ce.i.eq(self.rx_delay_ce) @@ -82,7 +74,7 @@ class KUSSerdes(Module): # tx clock (linerate/10) if mode == "master": - self.submodules.tx_clk_gearbox = Gearbox(40, "serwb_serdes", 8, "serwb_serdes_5x") + self.submodules.tx_clk_gearbox = Gearbox(40, "sys0p2x", 8, "sys") self.comb += self.tx_clk_gearbox.i.eq((0b1111100000 << 30) | (0b1111100000 << 20) | (0b1111100000 << 10) | @@ -94,8 +86,8 @@ class KUSSerdes(Module): p_IS_CLK_INVERTED=0, p_IS_CLKDIV_INVERTED=0, p_IS_RST_INVERTED=0, o_OQ=clk_o, - i_RST=ResetSignal("serwb_serdes"), - i_CLK=ClockSignal("serwb_serdes_20x"), i_CLKDIV=ClockSignal("serwb_serdes_5x"), + i_RST=ResetSignal("sys"), + i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal("sys"), i_D=self.tx_clk_gearbox.o ), Instance("OBUFDS", @@ -107,7 +99,7 @@ class KUSSerdes(Module): # tx datapath # tx_data -> encoders -> gearbox -> serdes - self.submodules.tx_gearbox = Gearbox(40, "serwb_serdes", 8, "serwb_serdes_5x") + self.submodules.tx_gearbox = Gearbox(40, "sys0p2x", 8, "sys") self.comb += [ If(tx_comma, self.encoder.k[0].eq(1), @@ -123,7 +115,7 @@ class KUSSerdes(Module): self.encoder.d[3].eq(self.tx_d[24:32]) ) ] - self.sync.serwb_serdes += \ + self.sync.sys0p2x += \ If(tx_idle, self.tx_gearbox.i.eq(0) ).Else( @@ -137,8 +129,8 @@ class KUSSerdes(Module): p_IS_CLK_INVERTED=0, p_IS_CLKDIV_INVERTED=0, p_IS_RST_INVERTED=0, o_OQ=serdes_o, - i_RST=ResetSignal("serwb_serdes"), - i_CLK=ClockSignal("serwb_serdes_20x"), i_CLKDIV=ClockSignal("serwb_serdes_5x"), + i_RST=ResetSignal("sys"), + i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal("sys"), i_D=self.tx_gearbox.o ), Instance("OBUFDS", @@ -168,12 +160,12 @@ class KUSSerdes(Module): ] else: self.specials += Instance("BUFG", i_I=clk_i, o_O=clk_i_bufg) - self.comb += pll.refclk.eq(clk_i_bufg) + self.comb += self.refclk.eq(clk_i_bufg) # rx datapath # serdes -> gearbox -> bitslip -> decoders -> rx_data - self.submodules.rx_gearbox = Gearbox(8, "serwb_serdes_5x", 40, "serwb_serdes") - self.submodules.rx_bitslip = ClockDomainsRenamer("serwb_serdes")(BitSlip(40)) + self.submodules.rx_gearbox = Gearbox(8, "sys", 40, "sys0p2x") + self.submodules.rx_bitslip = ClockDomainsRenamer("sys0p2x")(BitSlip(40)) serdes_i_nodelay = Signal() self.specials += [ @@ -193,7 +185,7 @@ class KUSSerdes(Module): p_DELAY_FORMAT="COUNT", p_DELAY_SRC="IDATAIN", p_DELAY_TYPE="VARIABLE", p_DELAY_VALUE=0, - i_CLK=ClockSignal("serwb_serdes_5x"), + i_CLK=ClockSignal("sys"), i_RST=rx_delay_rst, i_LOAD=0, i_INC=rx_delay_inc, i_EN_VTC=rx_delay_en_vtc, i_CE=rx_delay_ce, @@ -206,11 +198,11 @@ class KUSSerdes(Module): p_DATA_WIDTH=8, i_D=serdes_i_delayed, - i_RST=ResetSignal("serwb_serdes"), + i_RST=ResetSignal("sys"), i_FIFO_RD_CLK=0, i_FIFO_RD_EN=0, - i_CLK=ClockSignal("serwb_serdes_20x"), - i_CLK_B=ClockSignal("serwb_serdes_20x"), # locally inverted - i_CLKDIV=ClockSignal("serwb_serdes_5x"), + i_CLK=ClockSignal("sys4x"), + i_CLK_B=ClockSignal("sys4x"), # locally inverted + i_CLKDIV=ClockSignal("sys"), o_Q=serdes_q ) ] diff --git a/artiq/gateware/serwb/phy.py b/artiq/gateware/serwb/phy.py index b6436cdca..e22e436fe 100644 --- a/artiq/gateware/serwb/phy.py +++ b/artiq/gateware/serwb/phy.py @@ -154,7 +154,6 @@ class _SerdesMasterInit(Module): class _SerdesSlaveInit(Module, AutoCSR): def __init__(self, serdes, taps, timeout=4096): - self.reset = Signal() self.ready = Signal() self.error = Signal() @@ -170,11 +169,10 @@ class _SerdesSlaveInit(Module, AutoCSR): timer = WaitTimer(timeout) self.submodules += timer - self.comb += self.reset.eq(serdes.rx_idle) - self.comb += serdes.rx_delay_inc.eq(1) - self.submodules.fsm = fsm = FSM(reset_state="IDLE") + self.submodules.fsm = fsm = ResetInserter()(FSM(reset_state="IDLE")) + self.comb += fsm.reset.eq(serdes.rx_idle) fsm.act("IDLE", NextValue(delay, 0), NextValue(delay_min, 0), @@ -311,74 +309,16 @@ class _SerdesControl(Module, AutoCSR): ] -class SERWBPLL(Module): - def __init__(self, refclk_freq, linerate, vco_div=1): - assert refclk_freq in [62.5e6, 125e6] - assert linerate in [625e6, 1.25e9] - - self.lock = Signal() - self.refclk = Signal() - self.serwb_serdes_clk = Signal() - self.serwb_serdes_20x_clk = Signal() - self.serwb_serdes_5x_clk = Signal() - - # # # - - self.linerate = linerate - - refclk_mult = 125e6//refclk_freq - linerate_div = 1.25e9//linerate - - pll_locked = Signal() - pll_fb = Signal() - pll_serwb_serdes_clk = Signal() - pll_serwb_serdes_20x_clk = Signal() - pll_serwb_serdes_5x_clk = Signal() - self.specials += [ - Instance("PLLE2_BASE", - p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, - - # VCO @ 1.25GHz / vco_div - p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=8.0*refclk_mult, - p_CLKFBOUT_MULT=10*refclk_mult, p_DIVCLK_DIVIDE=vco_div, - i_CLKIN1=self.refclk, i_CLKFBIN=pll_fb, - o_CLKFBOUT=pll_fb, - - # serwb_serdes - p_CLKOUT0_DIVIDE=linerate_div*40//vco_div, p_CLKOUT0_PHASE=0.0, - o_CLKOUT0=pll_serwb_serdes_clk, - - # serwb_serdes_20x - p_CLKOUT1_DIVIDE=linerate_div*2//vco_div, p_CLKOUT1_PHASE=0.0, - o_CLKOUT1=pll_serwb_serdes_20x_clk, - - # serwb_serdes_5x - p_CLKOUT2_DIVIDE=linerate_div*8//vco_div, p_CLKOUT2_PHASE=0.0, - o_CLKOUT2=pll_serwb_serdes_5x_clk - ), - Instance("BUFG", - i_I=pll_serwb_serdes_clk, - o_O=self.serwb_serdes_clk), - Instance("BUFG", - i_I=pll_serwb_serdes_20x_clk, - o_O=self.serwb_serdes_20x_clk), - Instance("BUFG", - i_I=pll_serwb_serdes_5x_clk, - o_O=self.serwb_serdes_5x_clk) - ] - self.specials += MultiReg(pll_locked, self.lock) - - class SERWBPHY(Module, AutoCSR): - cd = "serwb_serdes" - def __init__(self, device, pll, pads, mode="master"): + cd = "sys0p2x" + def __init__(self, device, pads, mode="master"): assert mode in ["master", "slave"] if device[:4] == "xcku": taps = 512 - self.submodules.serdes = KUSSerdes(pll, pads, mode) + self.submodules.serdes = KUSSerdes(pads, mode) elif device[:4] == "xc7a": taps = 32 - self.submodules.serdes = S7Serdes(pll, pads, mode) + self.submodules.serdes = S7Serdes(pads, mode) else: raise NotImplementedError if mode == "master": diff --git a/artiq/gateware/serwb/s7phy.py b/artiq/gateware/serwb/s7phy.py index f21d39a4b..a345d6823 100644 --- a/artiq/gateware/serwb/s7phy.py +++ b/artiq/gateware/serwb/s7phy.py @@ -7,7 +7,10 @@ from misoc.cores.code_8b10b import Encoder, Decoder class S7Serdes(Module): - def __init__(self, pll, pads, mode="master"): + def __init__(self, pads, mode="master"): + if mode == "slave": + self.refclk = Signal() + self.tx_k = Signal(4) self.tx_d = Signal(32) self.rx_k = Signal(4) @@ -25,29 +28,18 @@ class S7Serdes(Module): # # # - self.submodules.encoder = ClockDomainsRenamer("serwb_serdes")( + self.submodules.encoder = ClockDomainsRenamer("sys0p2x")( Encoder(4, True)) - self.decoders = [ClockDomainsRenamer("serwb_serdes")( + self.decoders = [ClockDomainsRenamer("sys0p2x")( Decoder(True)) for _ in range(4)] self.submodules += self.decoders # clocking: # In master mode: - # - linerate/10 pll refclk provided by user # - linerate/10 slave refclk generated on clk_pads # In Slave mode: - # - linerate/10 pll refclk provided by clk_pads - self.clock_domains.cd_serwb_serdes = ClockDomain() - self.clock_domains.cd_serwb_serdes_5x = ClockDomain() - self.clock_domains.cd_serwb_serdes_20x = ClockDomain(reset_less=True) - self.comb += [ - self.cd_serwb_serdes.clk.eq(pll.serwb_serdes_clk), - self.cd_serwb_serdes_5x.clk.eq(pll.serwb_serdes_5x_clk), - self.cd_serwb_serdes_20x.clk.eq(pll.serwb_serdes_20x_clk) - ] - self.specials += AsyncResetSynchronizer(self.cd_serwb_serdes, ~pll.lock) - self.comb += self.cd_serwb_serdes_5x.rst.eq(self.cd_serwb_serdes.rst) + # - linerate/10 refclk provided by clk_pads # control/status cdc tx_idle = Signal() @@ -56,16 +48,16 @@ class S7Serdes(Module): rx_comma = Signal() rx_bitslip_value = Signal(6) self.specials += [ - MultiReg(self.tx_idle, tx_idle, "serwb_serdes"), - MultiReg(self.tx_comma, tx_comma, "serwb_serdes"), + MultiReg(self.tx_idle, tx_idle, "sys0p2x"), + MultiReg(self.tx_comma, tx_comma, "sys0p2x"), MultiReg(rx_idle, self.rx_idle, "sys"), MultiReg(rx_comma, self.rx_comma, "sys") ] - self.specials += MultiReg(self.rx_bitslip_value, rx_bitslip_value, "serwb_serdes"), + self.specials += MultiReg(self.rx_bitslip_value, rx_bitslip_value, "sys0p2x"), # tx clock (linerate/10) if mode == "master": - self.submodules.tx_clk_gearbox = Gearbox(40, "serwb_serdes", 8, "serwb_serdes_5x") + self.submodules.tx_clk_gearbox = Gearbox(40, "sys0p2x", 8, "sys") self.comb += self.tx_clk_gearbox.i.eq((0b1111100000 << 30) | (0b1111100000 << 20) | (0b1111100000 << 10) | @@ -79,8 +71,8 @@ class S7Serdes(Module): o_OQ=clk_o, i_OCE=1, - i_RST=ResetSignal("serwb_serdes"), - i_CLK=ClockSignal("serwb_serdes_20x"), i_CLKDIV=ClockSignal("serwb_serdes_5x"), + i_RST=ResetSignal("sys"), + i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal("sys"), i_D1=self.tx_clk_gearbox.o[0], i_D2=self.tx_clk_gearbox.o[1], i_D3=self.tx_clk_gearbox.o[2], i_D4=self.tx_clk_gearbox.o[3], i_D5=self.tx_clk_gearbox.o[4], i_D6=self.tx_clk_gearbox.o[5], @@ -95,7 +87,7 @@ class S7Serdes(Module): # tx datapath # tx_data -> encoders -> gearbox -> serdes - self.submodules.tx_gearbox = Gearbox(40, "serwb_serdes", 8, "serwb_serdes_5x") + self.submodules.tx_gearbox = Gearbox(40, "sys0p2x", 8, "sys") self.comb += [ If(tx_comma, self.encoder.k[0].eq(1), @@ -111,7 +103,7 @@ class S7Serdes(Module): self.encoder.d[3].eq(self.tx_d[24:32]) ) ] - self.sync.serwb_serdes += \ + self.sync.sys0p2x += \ If(tx_idle, self.tx_gearbox.i.eq(0) ).Else( @@ -127,8 +119,8 @@ class S7Serdes(Module): o_OQ=serdes_o, i_OCE=1, - i_RST=ResetSignal("serwb_serdes"), - i_CLK=ClockSignal("serwb_serdes_20x"), i_CLKDIV=ClockSignal("serwb_serdes_5x"), + i_RST=ResetSignal("sys"), + i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal("sys"), i_D1=self.tx_gearbox.o[0], i_D2=self.tx_gearbox.o[1], i_D3=self.tx_gearbox.o[2], i_D4=self.tx_gearbox.o[3], i_D5=self.tx_gearbox.o[4], i_D6=self.tx_gearbox.o[5], @@ -161,12 +153,12 @@ class S7Serdes(Module): ] else: self.specials += Instance("BUFG", i_I=clk_i, o_O=clk_i_bufg) - self.comb += pll.refclk.eq(clk_i_bufg) + self.comb += self.refclk.eq(clk_i_bufg) # rx datapath # serdes -> gearbox -> bitslip -> decoders -> rx_data - self.submodules.rx_gearbox = Gearbox(8, "serwb_serdes_5x", 40, "serwb_serdes") - self.submodules.rx_bitslip = ClockDomainsRenamer("serwb_serdes")(BitSlip(40)) + self.submodules.rx_gearbox = Gearbox(8, "sys", 40, "sys0p2x") + self.submodules.rx_bitslip = ClockDomainsRenamer("sys0p2x")(BitSlip(40)) serdes_i_nodelay = Signal() self.specials += [ @@ -200,9 +192,9 @@ class S7Serdes(Module): i_DDLY=serdes_i_delayed, i_CE1=1, - i_RST=ResetSignal("serwb_serdes"), - i_CLK=ClockSignal("serwb_serdes_20x"), i_CLKB=~ClockSignal("serwb_serdes_20x"), - i_CLKDIV=ClockSignal("serwb_serdes_5x"), + i_RST=ResetSignal("sys"), + i_CLK=ClockSignal("sys4x"), i_CLKB=~ClockSignal("sys4x"), + i_CLKDIV=ClockSignal("sys"), i_BITSLIP=0, o_Q8=serdes_q[0], o_Q7=serdes_q[1], o_Q6=serdes_q[2], o_Q5=serdes_q[3],