def __init__(self, pads): self.sink = sink = stream.Endpoint(eth_phy_layout(8)) # # # self.specials += DDROutput(sink.stb, sink.stb, pads.tx_ctl, ClockSignal("eth_tx")) for i in range(4): self.specials += DDROutput(sink.data[i], sink.data[4+i], pads.tx_data[i], ClockSignal("eth_tx")) self.comb += sink.ack.eq(1)
def __init__(self, clock_pads, pads, with_hw_init_reset): self._reset = CSRStorage() # # # self.clock_domains.cd_eth_rx = ClockDomain() self.clock_domains.cd_eth_tx = ClockDomain() self.comb += [ self.cd_eth_rx.clk.eq(ClockSignal("eth")), self.cd_eth_tx.clk.eq(ClockSignal("eth")) ] self.specials += DDROutput(0, 1, clock_pads.ref_clk, ClockSignal("eth_tx")) reset = Signal() if with_hw_init_reset: self.submodules.hw_reset = LiteEthPHYHWReset() self.comb += reset.eq(self._reset.storage | self.hw_reset.reset) else: self.comb += reset.eq(self._reset.storage) self.comb += pads.rst_n.eq(~reset) self.specials += [ AsyncResetSynchronizer(self.cd_eth_tx, reset), AsyncResetSynchronizer(self.cd_eth_rx, reset), ]
def __init__(self, clock_pads, pads, mii_mode=0): self._reset = CSRStorage() # # # self.clock_domains.cd_eth_rx = ClockDomain() self.clock_domains.cd_eth_tx = ClockDomain() # RX : Let the synthesis tool insert the appropriate clock buffer self.comb += self.cd_eth_rx.clk.eq(clock_pads.rx) # TX : GMII: Drive clock_pads.gtx, clock_pads.tx unused # MII: Use PHY clock_pads.tx as eth_tx_clk, do not drive clock_pads.gtx self.specials += DDROutput(1, mii_mode, clock_pads.gtx, ClockSignal("eth_tx")) # XXX Xilinx specific, replace BUFGMUX with a generic clock buffer? self.specials += Instance("BUFGMUX", i_I0=self.cd_eth_rx.clk, i_I1=clock_pads.tx, i_S=mii_mode, o_O=self.cd_eth_tx.clk) reset = self._reset.storage self.comb += pads.rst_n.eq(~reset) self.specials += [ AsyncResetSynchronizer(self.cd_eth_tx, reset), AsyncResetSynchronizer(self.cd_eth_rx, reset), ]
def __init__(self, platform, eem): self.sck_en = Signal() self.cnv = Signal() self.clkout = Signal() spip = platform.request("{}_adc_spi_p".format(eem)) spin = platform.request("{}_adc_spi_n".format(eem)) cnv = platform.request("{}_cnv".format(eem)) sdr = platform.request("{}_sdr".format(eem)) dp = platform.request("{}_adc_data_p".format(eem)) dn = platform.request("{}_adc_data_n".format(eem)) clkout_se = Signal() clkout_inv = Signal() sck = Signal() self.specials += [ DifferentialOutput(self.cnv, cnv.p, cnv.n), DifferentialOutput(1, sdr.p, sdr.n), DDROutput(self.sck_en, 0, sck, ClockSignal("sys")), DifferentialOutput(sck, spip.clk, spin.clk), DifferentialInput(dp.clkout, dn.clkout, clkout_se), # FIXME (hardware): CLKOUT is inverted # (Sampler v2.0, v2.1) out on rising, in on falling Instance("BUFR", i_I=clkout_se, o_O=clkout_inv) ] self.comb += self.clkout.eq(~clkout_inv) # define clock here before the input delays below self.clkout_p = dp.clkout # available for false paths platform.add_platform_command( "create_clock -name {clk} -period 8 [get_nets {clk}]", clk=dp.clkout) # platform.add_period_constraint(sampler_pads.clkout_p, 8.) for i in "abcd": sdo = Signal() setattr(self, "sdo{}".format(i), sdo) if i != "a": # FIXME (hardware): sdob, sdoc, sdod are inverted # (Sampler v2.0, v2.1) sdo, sdo_inv = Signal(), sdo self.comb += sdo_inv.eq(~sdo) sdop = getattr(dp, "sdo{}".format(i)) sdon = getattr(dn, "sdo{}".format(i)) self.specials += [ DifferentialInput(sdop, sdon, sdo), ] # -0+1.5 hold (t_HSDO_SDR), -0.5+0.5 skew platform.add_platform_command( "set_input_delay -clock {clk} -max 2 [get_ports {port}]\n" "set_input_delay -clock {clk} -min -0.5 [get_ports {port}]", clk=dp.clkout, port=sdop)
def __init__(self, clock_pads, pads): self._reset = CSRStorage() # # # self.clock_domains.cd_eth_rx = ClockDomain() self.clock_domains.cd_eth_tx = ClockDomain() # RX dcm_reset = Signal() dcm_locked = Signal() timer = WaitTimer(1024) fsm = FSM(reset_state="DCM_RESET") self.submodules += timer, fsm fsm.act("DCM_RESET", dcm_reset.eq(1), timer.wait.eq(1), If(timer.done, timer.wait.eq(0), NextState("DCM_WAIT"))) fsm.act("DCM_WAIT", timer.wait.eq(1), If(timer.done, NextState("DCM_CHECK_LOCK"))) fsm.act("DCM_CHECK_LOCK", If(~dcm_locked, NextState("DCM_RESET"))) clk90_rx = Signal() clk0_rx = Signal() clk0_rx_bufg = Signal() self.specials += Instance("DCM", i_CLKIN=clock_pads.rx, i_CLKFB=clk0_rx_bufg, o_CLK0=clk0_rx, o_CLK90=clk90_rx, o_LOCKED=dcm_locked, i_PSEN=0, i_PSCLK=0, i_PSINCDEC=0, i_RST=dcm_reset) self.specials += Instance("BUFG", i_I=clk0_rx, o_O=clk0_rx_bufg) self.specials += Instance("BUFG", i_I=clk90_rx, o_O=self.cd_eth_rx.clk) # TX self.specials += DDROutput(1, 0, clock_pads.tx, ClockSignal("eth_tx")) self.specials += Instance("BUFG", i_I=self.cd_eth_rx.clk, o_O=self.cd_eth_tx.clk) # Reset reset = self._reset.storage self.comb += pads.rst_n.eq(~reset) self.specials += [ AsyncResetSynchronizer(self.cd_eth_tx, reset), AsyncResetSynchronizer(self.cd_eth_rx, reset), ]
def __init__(self, platform, clk_freq): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True) # # # self.submodules.pll = pll = S6PLL(speedgrade=-1) pll.register_clkin(platform.request("clk32"), 32e6) pll.create_clkout(self.cd_sys, clk_freq) pll.create_clkout(self.cd_sys_ps, clk_freq, phase=90) # SDRAM clock self.specials += DDROutput(0, 1, platform.request("sdram_clock"), ClockSignal("sys_ps"))
def __init__(self, platform, sys_clk_freq): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True) # # # clk25 = platform.request("clk25") platform.add_period_constraint(clk25, 1e9 / 25e6) self.submodules.pll = pll = S6PLL(speedgrade=-2) pll.register_clkin(clk25, 25e6) pll.create_clkout(self.cd_sys, sys_clk_freq) pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=90) # SDRAM clock self.specials += DDROutput(0, 1, platform.request("sdram_clock"), ClockSignal("sys_ps"))
def __init__(self, platform, eem): self.sck_en = Signal() self.cnv = Signal() self.clkout = Signal() spip = platform.request("{}_adc_spi_p".format(eem)) spin = platform.request("{}_adc_spi_n".format(eem)) cnv = platform.request("{}_cnv".format(eem)) sdr = platform.request("{}_sdr".format(eem)) dp = platform.request("{}_adc_data_p".format(eem)) dn = platform.request("{}_adc_data_n".format(eem)) clkout_se = Signal() sck = Signal() self.specials += [ DifferentialOutput(self.cnv, cnv.p, cnv.n), DifferentialOutput(1, sdr.p, sdr.n), DDROutput(0, self.sck_en, sck, ClockSignal("rio_phy")), DifferentialOutput(sck, spip.clk, spin.clk), DifferentialInput(dp.clkout, dn.clkout, clkout_se), Instance("BUFR", i_I=clkout_se, o_O=self.clkout) ] # here to be early before the input delays below to have the clock # available self.clkout_p = dp.clkout # availabel for false paths platform.add_platform_command( "create_clock -name {clk} -period 8 [get_nets {clk}]", clk=dp.clkout) # platform.add_period_constraint(sampler_pads.clkout_p, 8.) for i in "abcd": sdo = Signal() setattr(self, "sdo{}".format(i), sdo) sdop = getattr(dp, "sdo{}".format(i)) sdon = getattr(dn, "sdo{}".format(i)) self.specials += [ DifferentialInput(sdop, sdon, sdo), ] # 8, -0+1.5 hold (t_HSDO_DDR), -0.5+0.5 skew platform.add_platform_command( "set_input_delay -clock {clk} " "-max 2 [get_ports {port}] -clock_fall\n" "set_input_delay -clock {clk} " "-min -0.5 [get_ports {port}] -clock_fall", clk=dp.clkout, port=sdop)
def __init__(self, pins, pins_n): self.data = [Signal(2) for _ in range(2 + len(pins.mosi))] for d, pp, pn in zip(self.data, [pins.clk] + list(pins.mosi), [pins_n.clk] + list(pins_n.mosi)): ddr = Signal() self.specials += [ # d1 closer to q DDROutput(d[1], d[0], ddr, ClockSignal("rio_phy")), DifferentialOutput(ddr, pp, pn), ] ddr = Signal() self.specials += [ DifferentialInput(pins.miso, pins_n.miso, ddr), # q1 closer to d DDRInput(ddr, self.data[-1][0], self.data[-1][1], ClockSignal("rio_phy")), ]
def __init__(self, clock_pads, pads): self._reset = CSRStorage() # # # self.clock_domains.cd_eth_rx = ClockDomain() self.clock_domains.cd_eth_tx = ClockDomain() self.specials += [ Instance("BUFG", i_I=clock_pads.rx, o_O=self.cd_eth_rx.clk), DDROutput(1, 0, clock_pads.tx, ClockSignal("eth_tx")) ] self.comb += self.cd_eth_tx.clk.eq(self.cd_eth_rx.clk) reset = self._reset.storage if hasattr(pads, "rst_n"): self.comb += pads.rst_n.eq(~reset) self.specials += [ AsyncResetSynchronizer(self.cd_eth_tx, reset), AsyncResetSynchronizer(self.cd_eth_rx, reset), ]
def __init__(self, clock_pads, pads, with_hw_init_reset, mii_mode=0): self._reset = CSRStorage() # # # self.clock_domains.cd_eth_rx = ClockDomain() self.clock_domains.cd_eth_tx = ClockDomain() # RX : Let the synthesis tool insert the appropriate clock buffer self.comb += self.cd_eth_rx.clk.eq(clock_pads.rx) # TX : GMII: Drive clock_pads.gtx, clock_pads.tx unused # MII: Use PHY clock_pads.tx as eth_tx_clk, do not drive clock_pads.gtx self.specials += DDROutput(1, mii_mode, clock_pads.gtx, ClockSignal("eth_tx")) if isinstance(mii_mode, int) and (mii_mode == 0): self.specials += Instance("BUFG", i_I = self.cd_eth_rx.clk, o_O = self.cd_eth_tx.clk, ) else: # XXX Xilinx specific, replace BUFGMUX with a generic clock buffer? self.specials += Instance("BUFGMUX", i_I0 = self.cd_eth_rx.clk, i_I1 = clock_pads.tx, i_S = mii_mode, o_O = self.cd_eth_tx.clk, ) reset = Signal() if with_hw_init_reset: self.submodules.hw_reset = LiteEthPHYHWReset() self.comb += reset.eq(self._reset.storage | self.hw_reset.reset) else: self.comb += reset.eq(self._reset.storage) self.comb += pads.rst_n.eq(~reset) self.specials += [ AsyncResetSynchronizer(self.cd_eth_tx, reset), AsyncResetSynchronizer(self.cd_eth_rx, reset), ]
def __init__(self, clock_pads, pads, with_hw_init_reset, mii_mode=0): self._reset = CSRStorage() # # # self.clock_domains.cd_eth_rx = ClockDomain() self.clock_domains.cd_eth_tx = ClockDomain() # RX : Let the synthesis tool insert the appropriate clock buffer self.comb += self.cd_eth_rx.clk.eq(clock_pads.rx) # TX : GMII: Drive clock_pads.gtx, clock_pads.tx unused # MII: Use PHY clock_pads.tx as eth_tx_clk, do not drive clock_pads.gtx self.specials += DDROutput(1, mii_mode, clock_pads.gtx, ClockSignal("eth_tx")) # XXX Xilinx specific, replace BUFGMUX with a generic clock buffer? self.specials += Instance("BUFGMUX", i_I0=self.cd_eth_rx.clk, i_I1=clock_pads.tx, i_S=mii_mode, o_O=self.cd_eth_tx.clk) if with_hw_init_reset: reset = Signal() counter_done = Signal() self.submodules.counter = counter = Counter(max=512) self.comb += [ counter_done.eq(counter.value == 256), counter.ce.eq(~counter_done), reset.eq(~counter_done | self._reset.storage) ] else: reset = self._reset.storage self.comb += pads.rst_n.eq(~reset) self.specials += [ AsyncResetSynchronizer(self.cd_eth_tx, reset), AsyncResetSynchronizer(self.cd_eth_rx, reset), ]
def __init__(self, pins, pins_n): n_bits = 16 # bits per dac data word n_channels = 32 # channels per fastino n_div = 7 # bits per lane and word assert n_div == 7 n_frame = 14 # word per frame n_lanes = len(pins.mosi) # number of data lanes n_checksum = 12 # checksum bits n_addr = 4 # readback address bits n_word = n_lanes*n_div n_body = n_word*n_frame - (n_frame//2 + 1) - n_checksum # dac data words self.dacs = [Signal(n_bits) for i in range(n_channels)] # dac update enable self.enable = Signal(n_channels) # configuration word self.cfg = Signal(20) # readback data self.dat_r = Signal(n_frame//2*(1 << n_addr)) # data load synchronization event self.stb = Signal() # # # # crc-12 telco self.submodules.crc = LiteEthMACCRCEngine( data_width=2*n_lanes, width=n_checksum, polynom=0x80f) addr = Signal(4) body_ = Cat(self.cfg, addr, self.enable, self.dacs) assert len(body_) == n_body body = Signal(n_body) self.comb += body.eq(body_) words_ = [] j = 0 for i in range(n_frame): # iterate over words if i == 0: # data and checksum k = n_word - n_checksum elif i == 1: # marker words_.append(C(1)) k = n_word - 1 elif i < n_frame//2 + 2: # marker words_.append(C(0)) k = n_word - 1 else: # full word k = n_word # append corresponding frame body bits words_.append(body[j:j + k]) j += k words_ = Cat(words_) assert len(words_) == n_frame*n_word - n_checksum words = Signal(len(words_)) self.comb += words.eq(words_) clk = Signal(n_div, reset=0b1100011) clk_stb = Signal() i_frame = Signal(max=n_div*n_frame//2) # DDR frame_stb = Signal() sr = [Signal(n_frame*n_div - n_checksum//n_lanes, reset_less=True) for i in range(n_lanes)] assert len(Cat(sr)) == len(words) # DDR bits for each register ddr_data = Cat([sri[-2] for sri in sr], [sri[-1] for sri in sr]) self.comb += [ # assert one cycle ahead clk_stb.eq(~clk[0] & clk[-1]), # double period because of DDR frame_stb.eq(i_frame == n_div*n_frame//2 - 1), # LiteETHMACCRCEngine takes data LSB first self.crc.data[::-1].eq(ddr_data), self.stb.eq(frame_stb & clk_stb), ] miso = Signal() miso_sr = Signal(n_frame, reset_less=True) self.sync.rio_phy += [ # shift 7 bit clock pattern by two bits each DDR cycle clk.eq(Cat(clk[-2:], clk)), [sri[2:].eq(sri) for sri in sr], self.crc.last.eq(self.crc.next), If(clk[:2] == 0, # TODO: tweak MISO sampling miso_sr.eq(Cat(miso, miso_sr)), ), If(~frame_stb, i_frame.eq(i_frame + 1), ), If(frame_stb & clk_stb, i_frame.eq(0), self.crc.last.eq(0), # transpose, load Cat(sr).eq(Cat(words[mm::n_lanes] for mm in range(n_lanes))), Array([self.dat_r[i*n_frame//2:(i + 1)*n_frame//2] for i in range(1 << len(addr))])[addr].eq(miso_sr), addr.eq(addr + 1), ), If(i_frame == n_div*n_frame//2 - 2, # inject crc ddr_data.eq(self.crc.next), ), ] clk_ddr = Signal() miso0 = Signal() self.specials += [ DDROutput(clk[-1], clk[-2], clk_ddr, ClockSignal("rio_phy")), DifferentialOutput(clk_ddr, pins.clk, pins_n.clk), DifferentialInput(pins.miso, pins_n.miso, miso0), MultiReg(miso0, miso, "rio_phy"), ] for sri, ddr, mp, mn in zip( sr, Signal(n_lanes), pins.mosi, pins_n.mosi): self.specials += [ DDROutput(sri[-1], sri[-2], ddr, ClockSignal("rio_phy")), DifferentialOutput(ddr, mp, mn), ]