Beispiel #1
0
    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)
Beispiel #2
0
    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),
        ]
Beispiel #3
0
    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),
        ]
Beispiel #4
0
    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)
Beispiel #5
0
    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),
        ]
Beispiel #6
0
    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"))
Beispiel #8
0
    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)
Beispiel #9
0
    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")),
        ]
Beispiel #10
0
    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),
        ]
Beispiel #11
0
    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),
        ]
Beispiel #12
0
    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),
        ]
Beispiel #13
0
    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),
            ]