Пример #1
0
    def __init__(self, phy, clk_freq, mode):
        self.submodules.etherbone = etherbone = Etherbone(mode)
        depacketizer = Depacketizer(clk_freq)
        packetizer = Packetizer()
        self.submodules += depacketizer, packetizer
        tx_cdc = stream.AsyncFIFO([("data", 32)], 8)
        tx_cdc = ClockDomainsRenamer({
            "write": "sys",
            "read": "serwb_serdes"
        })(tx_cdc)
        self.submodules += tx_cdc
        rx_cdc = stream.AsyncFIFO([("data", 32)], 8)
        rx_cdc = ClockDomainsRenamer({
            "write": "serwb_serdes",
            "read": "sys"
        })(rx_cdc)
        self.submodules += rx_cdc
        self.comb += [
            # core <--> etherbone
            depacketizer.source.connect(etherbone.sink),
            etherbone.source.connect(packetizer.sink),

            # core --> serdes
            packetizer.source.connect(tx_cdc.sink),
            If(tx_cdc.source.stb & phy.init.ready,
               phy.serdes.tx_data.eq(tx_cdc.source.data)),
            tx_cdc.source.ack.eq(phy.init.ready),

            # serdes --> core
            rx_cdc.sink.stb.eq(phy.init.ready),
            rx_cdc.sink.data.eq(phy.serdes.rx_data),
            rx_cdc.source.connect(depacketizer.sink),
        ]
Пример #2
0
    def __init__(self, phy, clk_freq, mode, with_scrambling=False):
        # etherbone
        self.submodules.etherbone = etherbone = Etherbone(mode)

        # packetizer / depacketizer
        depacketizer = Depacketizer(clk_freq)
        packetizer = Packetizer()
        self.submodules += depacketizer, packetizer

        # clock domain crossing
        tx_cdc = stream.AsyncFIFO([("data", 32)], 16)
        tx_cdc = ClockDomainsRenamer({"write": "sys", "read": phy.cd})(tx_cdc)
        rx_cdc = stream.AsyncFIFO([("data", 32)], 16)
        rx_cdc = ClockDomainsRenamer({"write": phy.cd, "read": "sys"})(rx_cdc)
        self.submodules += tx_cdc, rx_cdc

        # scrambling
        scrambler = ClockDomainsRenamer(phy.cd)(
            Scrambler(enable=with_scrambling))
        descrambler = ClockDomainsRenamer(phy.cd)(
            Descrambler(enable=with_scrambling))
        self.submodules += scrambler, descrambler

        # modules connection
        self.comb += [
            # core --> phy
            packetizer.source.connect(tx_cdc.sink),
            tx_cdc.source.connect(scrambler.sink),
            If(
                phy.init.ready,
                If(scrambler.source.stb,
                   phy.serdes.tx_k.eq(scrambler.source.k),
                   phy.serdes.tx_d.eq(scrambler.source.d)),
                scrambler.source.ack.eq(1)),

            # phy --> core
            descrambler.sink.stb.eq(phy.init.ready),
            descrambler.sink.k.eq(phy.serdes.rx_k),
            descrambler.sink.d.eq(phy.serdes.rx_d),
            descrambler.source.connect(rx_cdc.sink),
            rx_cdc.source.connect(depacketizer.sink),

            # etherbone <--> core
            depacketizer.source.connect(etherbone.sink),
            etherbone.source.connect(packetizer.sink)
        ]
Пример #3
0
    def __init__(self, n_bits, n_words):
        self.data = Signal()
        self.wck = Signal()
        self.bck = Signal()

        layout = [("data", n_bits)]

        self.clock_domains.cd_decode = ClockDomain()
        self.specials += AsyncResetSynchronizer(self.cd_decode, ResetSignal("sys"))

        decoder = ClockDomainsRenamer("decode")(Decoder(n_bits, n_words))
        self.submodules.decoder = decoder

        cdr = ClockDomainsRenamer({"read": "sys", "write": "decode"})
        self.submodules.fifo = cdr(stream.AsyncFIFO(layout, 8))

        self.source = self.fifo.source

        self.comb += [
            self.cd_decode.clk.eq(self.bck),
            decoder.wck.eq(self.wck),
            decoder.data.eq(self.data),
            decoder.source.connect(self.fifo.sink),
        ]
Пример #4
0
    def __init__(self, phy, dw, endianness="big",
            with_preamble_crc=True,
            with_padding=True):
        if dw < phy.dw:
            raise ValueError("Core data width({}) must be larger than PHY data width({})".format(dw, phy.dw))

        rx_pipeline = [phy]
        tx_pipeline = [phy]

        # Interpacket gap
        tx_gap_inserter = gap.LiteEthMACGap(phy.dw)
        self.submodules += ClockDomainsRenamer("eth_tx")(tx_gap_inserter)
        tx_pipeline += [tx_gap_inserter]

        # Preamble / CRC
        if with_preamble_crc:
            self._preamble_crc = CSRStatus(reset=1)
            self.preamble_errors = CSRStatus(32)
            self.crc_errors = CSRStatus(32)

            # Preamble insert/check
            preamble_inserter = preamble.LiteEthMACPreambleInserter(phy.dw)
            preamble_checker = preamble.LiteEthMACPreambleChecker(phy.dw)
            self.submodules += ClockDomainsRenamer("eth_tx")(preamble_inserter)
            self.submodules += ClockDomainsRenamer("eth_rx")(preamble_checker)

            # CRC insert/check
            crc32_inserter = crc.LiteEthMACCRC32Inserter(eth_phy_layout(phy.dw))
            crc32_checker = crc.LiteEthMACCRC32Checker(eth_phy_layout(phy.dw))
            self.submodules += ClockDomainsRenamer("eth_tx")(crc32_inserter)
            self.submodules += ClockDomainsRenamer("eth_rx")(crc32_checker)

            tx_pipeline += [preamble_inserter, crc32_inserter]
            rx_pipeline += [preamble_checker, crc32_checker]

            # Error counters
            self.submodules.ps_preamble_error = PulseSynchronizer("eth_rx", "sys")
            self.submodules.ps_crc_error = PulseSynchronizer("eth_rx", "sys")

            self.comb += [
                self.ps_preamble_error.i.eq(preamble_checker.error),
                self.ps_crc_error.i.eq(crc32_checker.error),
            ]
            self.sync += [
                If(self.ps_preamble_error.o,
                    self.preamble_errors.status.eq(self.preamble_errors.status + 1)),
                If(self.ps_crc_error.o,
                    self.crc_errors.status.eq(self.crc_errors.status + 1)),
            ]

        # Padding
        if with_padding:
            padding_inserter = padding.LiteEthMACPaddingInserter(phy.dw, 60)
            padding_checker = padding.LiteEthMACPaddingChecker(phy.dw, 60)
            self.submodules += ClockDomainsRenamer("eth_tx")(padding_inserter)
            self.submodules += ClockDomainsRenamer("eth_rx")(padding_checker)

            tx_pipeline += [padding_inserter]
            rx_pipeline += [padding_checker]

        # Delimiters
        if dw != 8:
            tx_last_be = last_be.LiteEthMACTXLastBE(phy.dw)
            rx_last_be = last_be.LiteEthMACRXLastBE(phy.dw)
            self.submodules += ClockDomainsRenamer("eth_tx")(tx_last_be)
            self.submodules += ClockDomainsRenamer("eth_rx")(rx_last_be)

            tx_pipeline += [tx_last_be]
            rx_pipeline += [rx_last_be]

        # Converters
        if dw != phy.dw:
            reverse = endianness == "big"
            tx_converter = stream.StrideConverter(eth_phy_layout(dw),
                                     eth_phy_layout(phy.dw),
                                     reverse=reverse)
            rx_converter = stream.StrideConverter(eth_phy_layout(phy.dw),
                                     eth_phy_layout(dw),
                                     reverse=reverse)
            self.submodules += ClockDomainsRenamer("eth_tx")(tx_converter)
            self.submodules += ClockDomainsRenamer("eth_rx")(rx_converter)

            tx_pipeline += [tx_converter]
            rx_pipeline += [rx_converter]

        # Cross Domain Crossing
        tx_cdc = stream.AsyncFIFO(eth_phy_layout(dw), 64)
        rx_cdc = stream.AsyncFIFO(eth_phy_layout(dw), 64)
        self.submodules += ClockDomainsRenamer({"write": "sys", "read": "eth_tx"})(tx_cdc)
        self.submodules += ClockDomainsRenamer({"write": "eth_rx", "read": "sys"})(rx_cdc)

        tx_pipeline += [tx_cdc]
        rx_pipeline += [rx_cdc]

        tx_pipeline_r = list(reversed(tx_pipeline))
        for s, d in zip(tx_pipeline_r, tx_pipeline_r[1:]):
            self.comb += s.source.connect(d.sink)
        for s, d in zip(rx_pipeline, rx_pipeline[1:]):
            self.comb += s.source.connect(d.sink)
        self.sink = tx_pipeline[-1].sink
        self.source = rx_pipeline[-1].source
Пример #5
0
    def __init__(self, plat):
        # Clocking

        clk_ref = plat.request(
            "clk12")  # 12mhz reference clock from which all else is derived

        self.submodules.clockgen = clocking.ClockGen(clk_ref)
        self.clock_domains.cd_sys = self.clockgen.cd_sys
        self.clock_domains.cd_pix1x = self.clockgen.cd_pix1x
        self.clock_domains.cd_pix8x = self.clockgen.cd_pix8x

        # SDRAM Controller
        sd_param = ovplatform.sdram_params.getSDRAMParams('mt48lc16m16a2')

        # Build the SDRAM controller (TODO: Replace with MISOC SDRAM controller)
        self.submodules.sdramctl = SDRAMCTL(
            plat.request("sdram"),
            clk_out=self.clockgen.clk_sdram,
            clk_sample=self.clockgen.clk_sdram_sample,
            **sd_param._asdict())

        # SDRAM Master arbiter (TODO: Replace with MISOC bus arbiter)
        self.submodules.sdram_mux = SDRAMMux(self.sdramctl.hostif)

        # SDRAM BIST (TODO: Rewrite to use internal bus)
        memsize = 2**(sd_param.colbits + sd_param.rowbits + sd_param.bankbits)
        self.submodules.bist = SDRAMBIST(self.sdram_mux.getPort(), memsize)
        self.submodules.sdram_test = SDRAMBISTCfg(self.bist)

        # SDRAM host read translator
        self.submodules.sdram_host_read = SDRAM_Host_Read(
            self.sdram_mux.getPort(), host_burst_length=0x20)

        # SDRAM sink - sends data from USB capture to host
        self.submodules.sdram_sink = SDRAM_Sink(self.sdram_mux.getPort())

        # connect wptr/rptr for ringbuffer flow control
        self.comb += self.sdram_host_read.wptr.eq(self.sdram_sink.wptr)
        self.comb += self.sdram_sink.rptr.eq(self.sdram_host_read.rptr)

        # ULPI Interfce

        # Diagnostics/Testing signals
        ulpi_cd_rst = Signal()
        ulpi_stp_ovr = Signal(1)

        # ULPI physical layer
        self.submodules.ulpi_pl = ULPI_pl(plat.request("ulpi"), ulpi_cd_rst,
                                          ulpi_stp_ovr)
        self.clock_domains.cd_ulpi = self.ulpi_pl.cd_ulpi

        # ULPI controller
        ulpi_reg = Record(ULPI_REG)
        self.submodules.ulpi = ClockDomainsRenamer({"sys": "ulpi"})(ULPI_ctrl(
            self.ulpi_pl.ulpi_bus, ulpi_reg), )

        # ULPI register R/W CSR interface
        self.submodules.ucfg = ULPICfg(self.cd_ulpi.clk, ulpi_cd_rst,
                                       self.ulpi_pl.ulpi_bus.rst, ulpi_stp_ovr,
                                       ulpi_reg)

        # Receive Path
        self.submodules.ovf_insert = ClockDomainsRenamer({"sys": "ulpi"})(
            OverflowInserter())

        self.submodules.udata_fifo = ClockDomainsRenamer({
            "write": "ulpi",
            "read": "sys"
        })(al_fifo.AsyncFIFO(ULPI_DATA_D, 1024))

        self.submodules.cfilt = RXCmdFilter()
        self.submodules.cstream = Whacker(1024)

        self.comb += [
            self.ulpi.data_out_source.connect(self.ovf_insert.sink),
            self.ovf_insert.source.connect(self.udata_fifo.sink),
            self.udata_fifo.source.connect(self.cfilt.sink),
            self.cfilt.source.connect(self.cstream.sink),
            #                self.cstream.source.connect(self.sdram_sink.sink),
        ]

        # FPD receiver
        lvds_in = Cat(plat.request('spare', 0), plat.request('spare', 1))
        debug = Cat(plat.request('spare', i) for i in range(2, 2 + 14))

        self.submodules.fpdtop = FpdTop(lvds_in, debug)
        self.comb += [
            self.fpdtop.source.connect(self.sdram_sink.sink),
            self.fpdtop.serdesstrobe.eq(self.clockgen.serdesstrobe)
        ]

        # FTDI bus interface
        ftdi_io = plat.request("ftdi")
        self.submodules.ftdi_bus = ftdi_bus = FTDI_sync245(
            self.clockgen.cd_sys.rst, ftdi_io)

        # FTDI command processor
        self.submodules.randtest = FTDI_randtest()
        self.submodules.cmdproc = CmdProc(
            self.ftdi_bus, [self.randtest, self.sdram_host_read])

        # GPIOs (leds/buttons)
        self.submodules.leds = LED_outputs(
            plat.request('leds'),
            [[self.bist.busy, self.ftdi_bus.tx_ind], [0, self.ftdi_bus.rx_ind],
             [self.fpdtop.lock]],
            active=0)

        # Bind all device CSRs
        self.csr_map = {
            'leds': 0,
            'buttons': 1,
            'ucfg': 2,
            'randtest': 3,
            'cstream': 4,
            'sdram_test': 5,
            'sdram_host_read': 6,
            'sdram_sink': 7,
            'ovf_insert': 8,
            'fpdtop': 9,
        }

        self.submodules.csrbankarray = CSRBankArray(
            self, lambda name, _: self.csr_map[name])

        # Connect FTDI CSR Master to CSR bus
        self.submodules.incon = Interconnect(self.cmdproc.master,
                                             self.csrbankarray.get_buses())