Esempio n. 1
0
    def __init__(self, dram_port, random):
        ashift = log2_int(dram_port.dw // 8)
        awidth = dram_port.aw + ashift
        self.start = Signal()
        self.done = Signal()
        self.base = Signal(awidth)
        self.length = Signal(awidth)
        self.ticks = Signal(32)

        # # #

        gen_cls = LFSR if random else Counter
        gen = gen_cls(min(dram_port.dw, 32))  # FIXME: remove lfsr limitation
        dma = LiteDRAMDMAWriter(dram_port)
        self.submodules += dma, gen

        cmd_counter = Signal(dram_port.aw, reset_less=True)

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm
        fsm.act("IDLE",
                If(self.start, NextValue(cmd_counter, 0), NextState("RUN")),
                NextValue(self.ticks, 0))
        fsm.act(
            "RUN", dma.sink.valid.eq(1),
            If(
                dma.sink.ready, gen.ce.eq(1),
                NextValue(cmd_counter, cmd_counter + 1),
                If(cmd_counter == (self.length[ashift:] - 1),
                   NextState("DONE"))), NextValue(self.ticks, self.ticks + 1))
        fsm.act("DONE", self.done.eq(1))
        self.comb += [
            dma.sink.address.eq(self.base[ashift:] + cmd_counter),
            dma.sink.data.eq(gen.o)
        ]
Esempio n. 2
0
    def __init__(self, dram_port, init=[]):
        ashift, awidth = get_ashift_awidth(dram_port)
        self.start = Signal()
        self.done = Signal()
        self.ticks = Signal(32)

        self.run_cascade_in = Signal(reset=1)
        self.run_cascade_out = Signal()

        # # #

        # Data / Address pattern -------------------------------------------------------------------
        addr_init, data_init = zip(*init)
        addr_mem = Memory(dram_port.address_width,
                          len(addr_init),
                          init=addr_init)
        data_mem = Memory(dram_port.data_width, len(data_init), init=data_init)
        addr_port = addr_mem.get_port(async_read=True)
        data_port = data_mem.get_port(async_read=True)
        self.specials += addr_mem, data_mem, addr_port, data_port

        # DMA --------------------------------------------------------------------------------------
        dma = LiteDRAMDMAWriter(dram_port)
        self.submodules += dma

        cmd_counter = Signal(dram_port.address_width, reset_less=True)

        # Data / Address FSM -----------------------------------------------------------------------
        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm
        fsm.act("IDLE",
                If(self.start, NextValue(cmd_counter, 0), NextState("RUN")),
                NextValue(self.ticks, 0))
        fsm.act("WAIT", If(self.run_cascade_in, NextState("RUN")))
        fsm.act(
            "RUN", dma.sink.valid.eq(1),
            If(
                dma.sink.ready, self.run_cascade_out.eq(1),
                NextValue(cmd_counter, cmd_counter + 1),
                If(cmd_counter == (len(init) - 1),
                   NextState("DONE")).Elif(~self.run_cascade_in,
                                           NextState("WAIT"))),
            NextValue(self.ticks, self.ticks + 1))
        fsm.act("DONE", self.run_cascade_out.eq(1), self.done.eq(1))

        if isinstance(dram_port, LiteDRAMNativePort):  # addressing in dwords
            dma_sink_addr = dma.sink.address
        elif isinstance(dram_port, LiteDRAMAXIPort):  # addressing in bytes
            dma_sink_addr = dma.sink.address[ashift:]
        else:
            raise NotImplementedError

        self.comb += [
            addr_port.adr.eq(cmd_counter),
            dma_sink_addr.eq(addr_port.dat_r),
            data_port.adr.eq(cmd_counter),
            dma.sink.data.eq(data_port.dat_r),
        ]
Esempio n. 3
0
                def __init__(self, dram_port, w0_port, w1_port, w2_port,
                             w3_port, adr_port):
                    self.reset = CSRStorage()
                    self.start = CSRStorage()
                    self.done = CSRStatus()

                    self.count = CSRStorage(size=(32 * 1))

                    self.mem_base = CSRStorage(size=32)
                    self.mem_mask = CSRStorage(size=32)
                    self.data_mask = CSRStorage(size=32)  # patterns

                    dma = LiteDRAMDMAWriter(dram_port, fifo_depth=1)
                    self.submodules += dma

                    cmd_counter = Signal(32)

                    self.comb += [
                        w0_port.adr.eq(cmd_counter & self.data_mask.storage),
                        w1_port.adr.eq(cmd_counter & self.data_mask.storage),
                        w2_port.adr.eq(cmd_counter & self.data_mask.storage),
                        w3_port.adr.eq(cmd_counter & self.data_mask.storage),
                        adr_port.adr.eq(cmd_counter & self.data_mask.storage),
                    ]

                    self.comb += [
                        dma.sink.address.eq(self.mem_base.storage +
                                            adr_port.dat_r +
                                            (cmd_counter
                                             & self.mem_mask.storage)),
                        dma.sink.data.eq(
                            Cat(w0_port.dat_r, w1_port.dat_r, w2_port.dat_r,
                                w3_port.dat_r)),
                    ]

                    fsm = FSM(reset_state="IDLE")
                    self.submodules += fsm
                    fsm.act(
                        "IDLE",
                        If(
                            self.start.storage,
                            NextValue(cmd_counter, 0),
                            NextState("WAIT"),
                        ))
                    fsm.act(
                        "WAIT",
                        If(cmd_counter >= self.count.storage,
                           NextState("DONE")).Else(NextState("RUN")))
                    fsm.act(
                        "RUN", dma.sink.valid.eq(1),
                        If(dma.sink.ready,
                           NextValue(cmd_counter, cmd_counter + 1),
                           NextState("WAIT")))
                    fsm.act("DONE", self.done.status.eq(1),
                            If(self.reset.storage, NextState("IDLE")))
Esempio n. 4
0
    def __init__(self, dram_port):
        ashift, awidth = get_ashift_awidth(dram_port)
        self.start  = Signal()
        self.done   = Signal()
        self.base   = Signal(awidth)
        self.length = Signal(awidth)
        self.random = Signal()
        self.ticks  = Signal(32)

        # # #

        # Data / Address generators ----------------------------------------------------------------
        data_gen = Generator(31, n_state=31, taps=[27, 30]) # PRBS31
        addr_gen = CEInserter()(Counter(awidth))
        self.submodules += data_gen, addr_gen
        self.comb += data_gen.random_enable.eq(self.random)

        # DMA --------------------------------------------------------------------------------------
        dma = LiteDRAMDMAWriter(dram_port)
        self.submodules += dma

        cmd_counter = Signal(dram_port.address_width, reset_less=True)

        # Data / Address FSM -----------------------------------------------------------------------
        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm
        fsm.act("IDLE",
            If(self.start,
                NextValue(cmd_counter, 0),
                NextState("RUN")
            ),
            NextValue(self.ticks, 0)
        )
        fsm.act("RUN",
            dma.sink.valid.eq(1),
            If(dma.sink.ready,
                data_gen.ce.eq(1),
                addr_gen.ce.eq(1),
                NextValue(cmd_counter, cmd_counter + 1),
                If(cmd_counter == (self.length[ashift:] - 1),
                    NextState("DONE")
                )
            ),
            NextValue(self.ticks, self.ticks + 1)
        )
        fsm.act("DONE",
            self.done.eq(1)
        )
        if isinstance(dram_port, LiteDRAMNativePort): # addressing in dwords
            self.comb += dma.sink.address.eq(self.base[ashift:] + addr_gen.o)
        elif isinstance(dram_port, LiteDRAMAXIPort):  # addressing in bytes
            self.comb += dma.sink.address[ashift:].eq(self.base[ashift:] + addr_gen.o)
        else:
            raise NotImplementedError
        self.comb += dma.sink.data.eq(data_gen.o)
Esempio n. 5
0
    def __init__(self, dram_port, pattern_mem, *, rowbits, row_shift):
        super().__init__(pattern_mem)

        self.doc = ModuleDoc("""
DMA DRAM writer.

Allows to fill DRAM with a predefined pattern using DMA.

Pattern
-------

{common}
        """.format(common=BISTModule.__doc__))

        dma = LiteDRAMDMAWriter(dram_port, fifo_depth=4)
        self.submodules += dma

        cmd_counter = Signal(32)

        self.comb += [
            self.done.eq(cmd_counter),
            # pattern
            self.data_port.adr.eq(cmd_counter & self.data_mask),
            self.addr_port.adr.eq(cmd_counter & self.data_mask),
            # DMA
            dma.sink.address.eq(self.addr_port.dat_r +
                                (cmd_counter & self.mem_mask)),
        ]

        # DMA data may be inverted using AddressSelector
        self.submodules.inverter = RowDataInverter(
            addr=dma.sink.address,
            data_in=self.data_port.dat_r,
            data_out=dma.sink.data,
            rowbits=rowbits,
            row_shift=row_shift,
        )

        self.submodules.fsm = fsm = FSM()
        fsm.act("READY", self.ready.eq(1),
                If(
                    self.start,
                    NextValue(cmd_counter, 0),
                    NextState("WAIT"),
                ))
        fsm.act(
            "WAIT",  # TODO: we could pipeline the access
            If(cmd_counter >= self.count,
               NextState("READY")).Else(NextState("RUN")))
        fsm.act(
            "RUN", dma.sink.valid.eq(1),
            If(dma.sink.ready, NextValue(cmd_counter, cmd_counter + 1),
               NextState("WAIT")))
Esempio n. 6
0
    def __init__(self, dram_port, pattern_mem):
        super().__init__(pattern_mem)

        self.doc = ModuleDoc("""
DMA DRAM writer.

Allows to fill DRAM with a predefined pattern using DMA.

Pattern
-------

{common}
        """.format(common=BISTModule.__doc__))

        # FIXME: Increase fifo depth
        dma = LiteDRAMDMAWriter(dram_port, fifo_depth=1)
        self.submodules += dma

        cmd_counter = Signal(32)

        self.comb += [
            self.done.eq(cmd_counter),
            # pattern
            self.data_port.adr.eq(cmd_counter & self.data_mask),
            self.addr_port.adr.eq(cmd_counter & self.data_mask),
            # DMA
            dma.sink.address.eq(self.addr_port.dat_r +
                                (cmd_counter & self.mem_mask)),
            dma.sink.data.eq(self.data_port.dat_r),
        ]

        self.submodules.fsm = fsm = FSM()
        fsm.act("READY", self.ready.eq(1),
                If(
                    self.start,
                    NextValue(cmd_counter, 0),
                    NextState("WAIT"),
                ))
        fsm.act(
            "WAIT",  # TODO: we could pipeline the access
            If(cmd_counter >= self.count,
               NextState("READY")).Else(NextState("RUN")))
        fsm.act(
            "RUN", dma.sink.valid.eq(1),
            If(dma.sink.ready, NextValue(cmd_counter, cmd_counter + 1),
               NextState("WAIT")))
Esempio n. 7
0
    def __init__(self, dram_port, random):
        self.start = Signal()
        self.done = Signal()
        self.base = Signal(dram_port.aw)
        self.length = Signal(dram_port.aw)

        # # #

        self.submodules.dma = dma = LiteDRAMDMAWriter(dram_port)
        gen_cls = LFSR if random else Counter
        self.submodules.gen = gen = gen_cls(dram_port.dw)

        self.cmd_counter = cmd_counter = Signal(dram_port.aw)

        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act(
            "IDLE",
            If(
                self.start,
                NextValue(cmd_counter, 0),
                NextState("RUN"),
            ),
        )
        fsm.act(
            "RUN",
            dma.sink.valid.eq(1),
            If(
                dma.sink.ready,
                gen.ce.eq(1),
                NextValue(cmd_counter, cmd_counter + 1),
                If(
                    cmd_counter == (self.length - 1),
                    NextState("DONE"),
                ),
            ),
        )
        fsm.act(
            "DONE",
            self.done.eq(1),
        )
        self.comb += [
            dma.sink.address.eq(self.base + cmd_counter),
            dma.sink.data.eq(gen.o),
        ]
Esempio n. 8
0
    def __init__(self, dram_port):
        self._ready = CSRStatus(8)
        self._value = CSRStorage(32)
        self._base = CSRStorage(32)
        self._offset = CSRStorage(32)

        self._start = CSRStorage(
            fields=[CSRField("start", size=1, offset=0, pulse=True)])

        base = Signal(dram_port.address_width)
        offset = Signal(dram_port.address_width)

        # determine the first significant bit of an byte address in memory
        shift = log2_int(dram_port.data_width // 8)

        self.comb += [
            base.eq(self._base.storage[shift:]),
        ]

        self.dma = LiteDRAMDMAWriter(dram_port)
        self.submodules += self.dma

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm

        fsm.act("IDLE", self._ready.status.eq(1),
                If(
                    self._start.fields.start,
                    NextState("RUN"),
                ))

        fsm.act(
            "RUN",
            self.dma.sink.valid.eq(1),
            self._ready.status.eq(0),
            If(
                self.dma.sink.ready,
                NextState("IDLE"),
            ),
        )

        self.comb += self.dma.sink.address.eq(base + self._offset.storage)
        self.comb += self.dma.sink.data.eq(self._value.storage)
Esempio n. 9
0
    def __init__(self,
                 platform,
                 with_cpu=True,
                 with_sdram=True,
                 with_etherbone=True,
                 with_gtp=True,
                 gtp_connector="pcie",
                 gtp_refclk="pcie",
                 gtp_linerate=5e9,
                 with_gtp_bist=True,
                 with_gtp_freqmeter=True,
                 with_record=True):
        sys_clk_freq = int(100e6)

        # SoCSDRAM ---------------------------------------------------------------------------------
        SoCSDRAM.__init__(
            self,
            platform,
            sys_clk_freq,
            cpu_type="vexriscv" if with_cpu else None,
            csr_data_width=32,
            with_uart=with_cpu,
            uart_name="crossover",
            integrated_rom_size=0x8000 if with_cpu else 0x0000,
            integrated_main_ram_size=0x1000 if not with_sdram else 0x0000,
            ident="PCIe Analyzer LiteX SoC",
            ident_version=True)

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = _CRG(platform, sys_clk_freq)

        # DDR3 SDRAM -------------------------------------------------------------------------------
        if not self.integrated_main_ram_size:
            self.submodules.ddrphy = s7ddrphy.A7DDRPHY(
                platform.request("ddram"),
                memtype="DDR3",
                nphases=4,
                sys_clk_freq=sys_clk_freq)
            self.add_csr("ddrphy")
            sdram_module = K4B2G1646F(sys_clk_freq, "1:4")
            self.register_sdram(self.ddrphy,
                                geom_settings=sdram_module.geom_settings,
                                timing_settings=sdram_module.timing_settings)

        # Etherbone --------------------------------------------------------------------------------
        if with_etherbone:
            # ethphy
            self.submodules.ethphy = LiteEthPHYRMII(
                clock_pads=self.platform.request("eth_clocks"),
                pads=self.platform.request("eth"))
            self.add_csr("ethphy")
            # ethcore
            self.submodules.ethcore = LiteEthUDPIPCore(
                phy=self.ethphy,
                mac_address=0x10e2d5000000,
                ip_address="192.168.1.50",
                clk_freq=self.clk_freq)
            # etherbone
            self.submodules.etherbone = LiteEthEtherbone(
                self.ethcore.udp, 1234)
            self.add_wb_master(self.etherbone.wishbone.bus)
            # timing constraints
            self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk,
                                                1e9 / 50e6)
            self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk,
                                                1e9 / 50e6)
            self.platform.add_false_path_constraints(
                self.crg.cd_sys.clk, self.ethphy.crg.cd_eth_rx.clk,
                self.ethphy.crg.cd_eth_tx.clk)

        # GTP RefClk -------------------------------------------------------------------------------
        if with_gtp:
            assert gtp_refclk in ["pcie", "internal"]
            if gtp_refclk == "pcie":
                refclk = Signal()
                refclk_freq = 100e6
                refclk_pads = platform.request("pcie_refclk")
                self.specials += Instance("IBUFDS_GTE2",
                                          i_CEB=0,
                                          i_I=refclk_pads.p,
                                          i_IB=refclk_pads.n,
                                          o_O=refclk)
            else:
                refclk = Signal()
                refclk_freq = 100e6
                self.comb += refclk.eq(ClockSignal("clk100"))
                platform.add_platform_command(
                    "set_property SEVERITY {{Warning}} [get_drc_checks REQP-49]"
                )

        # GTP PLL ----------------------------------------------------------------------------------
        if with_gtp:
            qpll = GTPQuadPLL(refclk, refclk_freq, gtp_linerate)
            print(qpll)
            self.submodules += qpll

        # GTPs -------------------------------------------------------------------------------------
        if with_gtp:
            for i in range(2):
                tx_pads = platform.request(gtp_connector + "_tx", i)
                rx_pads = platform.request(gtp_connector + "_rx", i)
                gtp = GTP(qpll,
                          tx_pads,
                          rx_pads,
                          sys_clk_freq,
                          data_width=20,
                          clock_aligner=False,
                          tx_buffer_enable=True,
                          rx_buffer_enable=True)
                gtp.add_stream_endpoints()
                setattr(self.submodules, "gtp" + str(i), gtp)
                platform.add_period_constraint(gtp.cd_tx.clk,
                                               1e9 / gtp.tx_clk_freq)
                platform.add_period_constraint(gtp.cd_rx.clk,
                                               1e9 / gtp.rx_clk_freq)
                self.platform.add_false_path_constraints(
                    self.crg.cd_sys.clk, gtp.cd_tx.clk, gtp.cd_rx.clk)

        # GTPs FreqMeters --------------------------------------------------------------------------
        if with_gtp_freqmeter:
            self.submodules.gtp0_tx_freq = FreqMeter(ClockSignal("gtp0_tx"))
            self.submodules.gtp0_rx_freq = FreqMeter(ClockSignal("gtp0_rx"))
            self.submodules.gtp1_tx_freq = FreqMeter(ClockSignal("gtp1_tx"))
            self.submodules.gtp1_rx_freq = FreqMeter(ClockSignal("gtp1_rx"))
            self.add_csr("gtp0_tx_freq")
            self.add_csr("gtp0_rx_freq")
            self.add_csr("gtp1_tx_freq")
            self.add_csr("gtp1_rx_freq")

        # GTPs BIST --------------------------------------------------------------------------------
        if with_gtp_bist:
            self.submodules.gtp0_tx_bist = GTPTXBIST(self.gtp0, "gtp0_tx")
            self.submodules.gtp0_rx_bist = GTPRXBIST(self.gtp0, "gtp0_rx")
            self.submodules.gtp1_tx_bist = GTPTXBIST(self.gtp1, "gtp1_tx")
            self.submodules.gtp1_rx_bist = GTPRXBIST(self.gtp1, "gtp1_rx")
            self.add_csr("gtp0_tx_bist")
            self.add_csr("gtp0_rx_bist")
            self.add_csr("gtp1_tx_bist")
            self.add_csr("gtp1_rx_bist")

        # Record -----------------------------------------------------------------------------------
        # FIXME: use better data/ctrl packing (or separate recorders)
        if with_record:
            # Convert RX stream from 16-bit@250MHz to 64-bit@sys_clk
            rx_converter = stream.StrideConverter([("data", 16), ("ctrl", 2)],
                                                  [("data", 96), ("ctrl", 12)],
                                                  reverse=False)
            rx_converter = ClockDomainsRenamer("gtp0_rx")(rx_converter)
            self.submodules.rx_converter = rx_converter
            rx_cdc = stream.AsyncFIFO([("data", 96), ("ctrl", 12)],
                                      8,
                                      buffered=True)
            rx_cdc = ClockDomainsRenamer({
                "write": "gtp0_rx",
                "read": "sys"
            })(rx_cdc)
            self.submodules.rx_cdc = rx_cdc
            # RX DMA Recorder
            self.submodules.rx_dma_recorder = LiteDRAMDMAWriter(
                self.sdram.crossbar.get_port("write", 128))
            self.rx_dma_recorder.add_csr()
            self.add_csr("rx_dma_recorder")
            self.comb += [
                gtp.source.connect(rx_converter.sink),
                rx_converter.source.connect(rx_cdc.sink),
                self.rx_dma_recorder.sink.valid.eq(rx_cdc.source.valid),
                self.rx_dma_recorder.sink.data[0:96].eq(rx_cdc.source.data),
                self.rx_dma_recorder.sink.data[96:108].eq(rx_cdc.source.ctrl),
            ]
Esempio n. 10
0
    def __init__(self, dram_port, adc_pins):
        self._start = CSRStorage(fields=[CSRField("start_burst", size=1, offset=0, pulse=True)])
        self._ready = CSRStatus(8)
        self._base = CSRStorage(32)
        self._offset = CSRStorage(32)

        self.sample_index = Signal(11)
    
        SAMPLE_BUFFER = 1024
        ADC_BITS = 18

        base = Signal(dram_port.address_width)
        offset = Signal(dram_port.address_width)

        # determine the first significant bit of an byte address in memory
        shift = log2_int(dram_port.data_width//8)
        self.comb += [
            base.eq(self._base.storage[shift:]),
        ]
        self.dma = LiteDRAMDMAWriter(dram_port)
        self.submodules += self.dma



        # hook up pins of ADC 
        self.adc_sdi = Signal()
        self.adc_sck = Signal()
        self.adc_sdo = Signal()
        self.adc_cnv = Signal()
        
        self.comb += adc_pins.sdi.eq(self.adc_sdi)
        self.comb += adc_pins.sck.eq(self.adc_sck)
        self.comb += self.adc_sdo.eq(adc_pins.sdo)
        self.comb += adc_pins.cnv.eq(self.adc_cnv)

        adc_value = Signal(ADC_BITS)
        cnv_settle = Signal(10)

        self.comb += self.dma.sink.address.eq(base + self._offset.storage + self.sample_index)
        self.comb += self.dma.sink.data.eq(adc_value)
        #self.comb += self.dma.sink.data.eq(self.sample_index)


        # divide system clock by adc_clk_divisor * 2 
        self.cnv_strobe = Signal(12)
        cnv_clk_divisor = 1000

        self.sync += \
            If(self.cnv_strobe == 0,
                self.cnv_strobe.eq(cnv_clk_divisor - 1),
            ).Else(
                self.cnv_strobe.eq(self.cnv_strobe - 1),
            )


        # divide system 20 for spi clock
        self.spi_strobe = Signal(5)
        spi_clk_divisor = 10

        self.sync += \
            If(self.spi_strobe == 0,
                self.spi_strobe.eq(spi_clk_divisor - 1),
            ).Else(
                self.spi_strobe.eq(self.spi_strobe - 1),
            )


        self.adc_bit = Signal(5)

        adc_fsm = FSM(reset_state="INIT")
        self.submodules += adc_fsm 

        # wait for a start pulse
        adc_fsm.act("INIT",
            NextValue(self.sample_index, 0),
            self._ready.status.eq(1),

            If(self._start.fields.start_burst,
                NextState("CNV_PREPARE"),
            ),
        )

        # prepare for conversion
        adc_fsm.act("CNV_PREPARE",
            self.adc_cnv.eq(0),
            NextValue(self.adc_bit, 0),
            If(self.cnv_strobe == 0,
                If(self.sample_index == SAMPLE_BUFFER,
                    NextState("INIT"),
                ).Else(
                    NextState("CNV_START"),
                ),
            ).Else(
                NextState("CNV_PREPARE"),
            )
        )
        
        # start conversion 
        adc_fsm.act("CNV_START",
            self.adc_cnv.eq(1),
            NextValue(cnv_settle, 100), # max tcnv is 500 ns, max flck is ~50 MHz. so, 100 cycles should do it
            NextState("CNV_WAIT"),
        )

        # wait for conversion to end
        adc_fsm.act("CNV_WAIT",
            self.adc_cnv.eq(1),
            NextValue(cnv_settle, cnv_settle -1),
            # eventually, work off ready signal?
            #If(self.adc_sdo == 0,
            #    NextState("ACQ_INIT")
            #)

            If(cnv_settle == 0,
                NextState("ACQ_INIT"),
            ),
        )
       
        # start acquisition
        adc_fsm.act("ACQ_INIT",
            self.adc_cnv.eq(0),
            NextValue(self.adc_bit, 0),
            If(self.spi_strobe == 0,
                NextState("ACQ_CLKH"),
            ),
        ) 

        # capture ADC_BITS + 1 bits
        # read data on rising edg eof sck
        adc_fsm.act("ACQ_CLKH",
            self.adc_sck.eq(1),
            self.adc_cnv.eq(0),
            If(self.spi_strobe == 0,
                NextValue(adc_value, (adc_value << 1) + self.adc_sdo),
                NextState("ACQ_CLKL"),
            ),
        )

        adc_fsm.act("ACQ_CLKL",
            self.adc_sck.eq(0),
            self.adc_cnv.eq(0),
            If(self.spi_strobe == 0,
                If(self.adc_bit == ADC_BITS,
                    NextValue(self.sample_index, self.sample_index+1),
                    NextState("ACQ_END"),
                    self.dma.sink.valid.eq(1),
                ).Else(
                    NextState("ACQ_CLKH"),
                    NextValue(self.adc_bit, self.adc_bit + 1),

                )
            )

        )

        adc_fsm.act("ACQ_END",
            self.adc_cnv.eq(0),
            If(self.spi_strobe == 0,
                NextState("CNV_PREPARE"),
            ),
        )
Esempio n. 11
0
    def __init__(self, dram_port, nslots):
        bus_aw = dram_port.aw
        bus_dw = dram_port.dw
        alignment_bits = bits_for(bus_dw // 8) - 1

        fifo_word_width = bus_dw
        self.frame = stream.Endpoint([("sof", 1), ("pixels", fifo_word_width)])
        self._frame_size = CSRStorage(bus_aw + alignment_bits)
        self.submodules._slot_array = _SlotArray(nslots, bus_aw,
                                                 alignment_bits)
        self.ev = self._slot_array.ev

        # # #

        # address generator + maximum memory word count to prevent DMA buffer
        # overrun
        reset_words = Signal()
        count_word = Signal()
        last_word = Signal()
        current_address = Signal(bus_aw)
        mwords_remaining = Signal(bus_aw)
        self.comb += [
            self._slot_array.address_reached.eq(current_address),
            last_word.eq(mwords_remaining == 1)
        ]
        self.sync += [
            If(reset_words, current_address.eq(self._slot_array.address),
               mwords_remaining.eq(
                   self._frame_size.storage[alignment_bits:])).Elif(
                       count_word, current_address.eq(current_address + 1),
                       mwords_remaining.eq(mwords_remaining - 1))
        ]

        memory_word = Signal(bus_dw)
        pixbits = []
        for i in range(bus_dw // 16):
            pixbits.append(self.frame.pixels)
        self.comb += memory_word.eq(Cat(*pixbits))

        # bus accessor
        self.submodules._bus_accessor = LiteDRAMDMAWriter(dram_port)
        self.comb += [
            self._bus_accessor.sink.address.eq(current_address),
            self._bus_accessor.sink.data.eq(memory_word)
        ]

        # control FSM
        fsm = FSM()
        self.submodules += fsm

        fsm.act(
            "WAIT_SOF", reset_words.eq(1),
            self.frame.ready.eq(~self._slot_array.address_valid
                                | ~self.frame.sof),
            If(
                self._slot_array.address_valid & self.frame.sof
                & self.frame.valid, NextState("TRANSFER_PIXELS")))
        fsm.act(
            "TRANSFER_PIXELS",
            self.frame.ready.eq(self._bus_accessor.sink.ready),
            If(
                self.frame.valid, self._bus_accessor.sink.valid.eq(1),
                If(self._bus_accessor.sink.ready, count_word.eq(1),
                   If(last_word, NextState("EOF")))))
        fsm.act(
            "EOF",
            If(~dram_port.wdata.valid, self._slot_array.address_done.eq(1),
               NextState("WAIT_SOF")))
Esempio n. 12
0
    def __init__(self, mode, dram_port, fifo_depth):
        assert mode == dram_port.mode
        ashift = log2_int(dram_port.dw // 8)
        awidth = dram_port.aw + ashift
        self.cd = dram_port.cd

        # control
        self.enable = Signal(reset=1)  # reset to 1 if not used
        self.start = Signal(reset=1)  # i / reset to 1 if not used
        self.idle = Signal()  # o
        self.slot = Signal()  # o

        # parameters
        self.slot0_base = Signal(awidth)  # in bytes
        self.slot1_base = Signal(awidth)  # in bytes
        self.length = Signal(awidth)  # in bytes

        # stream
        self.endpoint = endpoint = stream.Endpoint([("data", dram_port.dw)])

        # # #

        base = Signal(dram_port.aw)
        length = Signal(dram_port.aw)
        offset = Signal(dram_port.aw)

        # slot selection
        self.comb += \
            If(self.slot,
                base.eq(self.slot1_base[ashift:])
            ).Else(
                base.eq(self.slot0_base[ashift:]))

        # length
        self.comb += length.eq(self.length[ashift:])

        # dma
        if mode == "write":
            # dma
            self.submodules.dma = dma = ResetInserter()(LiteDRAMDMAWriter(
                dram_port, fifo_depth, True))
            # data
            self.comb += dma.sink.data.eq(endpoint.data)
        elif mode == "read":
            # dma
            self.submodules.dma = dma = ResetInserter()(LiteDRAMDMAReader(
                dram_port, fifo_depth, True))
            # data
            self.comb += [
                endpoint.valid.eq(dma.source.valid),
                dma.source.ready.eq(endpoint.ready),
                endpoint.data.eq(dma.source.data)
            ]

        # control
        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act(
            "IDLE", self.idle.eq(1),
            If(self.enable & self.start, NextValue(offset, 0),
               NextState("RUN")))
        fsm.act(
            "RUN",
            If(
                mode == "write",
                dma.sink.valid.eq(endpoint.valid),
                endpoint.ready.eq(dma.sink.ready),
            ).Elif(
                mode == "read",
                dma.sink.valid.eq(1),
            ),
            If(~self.enable, dma.reset.eq(1), dram_port.flush.eq(1),
               NextState("IDLE")).Elif(
                   dma.sink.valid & dma.sink.ready,
                   NextValue(offset, offset + 1),
                   If(offset == (length - 1), NextValue(offset, 0),
                      NextValue(self.slot, ~self.slot))))
        self.comb += dma.sink.address.eq(base + offset)
Esempio n. 13
0
    def __init__(self, platform, connector="pcie", linerate=2.5e9):
        assert connector in ["pcie"]
        sys_clk_freq = int(50e6)

        # SoCSDRAM ----------------------------------------------------------------------------------
        SoCSDRAM.__init__(
            self,
            platform,
            sys_clk_freq,
            integrated_rom_size=0x8000,
            integrated_sram_size=0x1000,
            uart_name="serial",
            l2_size=0,
            csr_data_width=32,
        )

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = _CRG(platform, sys_clk_freq)
        platform.add_period_constraint(self.crg.cd_sys.clk, 1e9 / 100e6)

        # DDR3 SDRAM -------------------------------------------------------------------------------
        self.submodules.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
                                                   memtype="DDR3",
                                                   nphases=4,
                                                   sys_clk_freq=sys_clk_freq)
        self.add_csr("ddrphy")
        sdram_module = MT8JTF12864(sys_clk_freq, "1:4")
        self.register_sdram(self.ddrphy,
                            geom_settings=sdram_module.geom_settings,
                            timing_settings=sdram_module.timing_settings)

        # Ethernet ---------------------------------------------------------------------------------
        # phy
        eth_phy = LiteEthPHYRGMII(clock_pads=platform.request("eth_clocks"),
                                  pads=platform.request("eth"),
                                  with_hw_init_reset=False,
                                  tx_delay=0e-9,
                                  rx_delay=0e-9)
        self.submodules.eth_phy = ClockDomainsRenamer("eth_tx")(eth_phy)
        self.add_csr("eth_phy")

        # core
        eth_core = LiteEthUDPIPCore(phy=self.eth_phy,
                                    mac_address=0x10e2d5000000,
                                    ip_address="172.30.28.201",
                                    clk_freq=125000000)
        self.submodules.eth_core = ClockDomainsRenamer("eth_tx")(eth_core)

        # etherbone bridge
        etherbone_cd = ClockDomain(
            "etherbone")  # similar to sys but need for correct
        self.clock_domains += etherbone_cd  # clock domain renaming
        self.comb += [
            etherbone_cd.clk.eq(ClockSignal("sys")),
            etherbone_cd.rst.eq(ResetSignal("sys"))
        ]
        self.submodules.etherbone = LiteEthEtherbone(self.eth_core.udp,
                                                     1234,
                                                     cd="etherbone")
        self.add_wb_master(self.etherbone.wishbone.bus)

        # timing constraints
        self.platform.add_period_constraint(self.eth_phy.crg.cd_eth_rx.clk,
                                            1e9 / 125e6)
        self.platform.add_period_constraint(self.eth_phy.crg.cd_eth_tx.clk,
                                            1e9 / 125e6)
        self.platform.add_false_path_constraints(
            self.crg.cd_sys.clk, self.eth_phy.crg.cd_eth_rx.clk,
            self.eth_phy.crg.cd_eth_tx.clk)

        # GTP RefClk -------------------------------------------------------------------------------
        refclk = Signal()
        refclk_freq = 100e6
        refclk_pads = platform.request("pcie_refclk")
        self.specials += Instance("IBUFDS_GTE2",
                                  i_CEB=0,
                                  i_I=refclk_pads.p,
                                  i_IB=refclk_pads.n,
                                  o_O=refclk)

        # GTP PLL ----------------------------------------------------------------------------------
        qpll = GTPQuadPLL(refclk, refclk_freq, linerate)
        print(qpll)
        self.submodules += qpll

        # GTPs -------------------------------------------------------------------------------------
        for i in range(2):
            tx_pads = platform.request(connector + "_tx", i)
            rx_pads = platform.request(connector + "_rx", i)
            gtp = GTP(qpll,
                      tx_pads,
                      rx_pads,
                      sys_clk_freq,
                      data_width=20,
                      clock_aligner=False,
                      tx_buffer_enable=True,
                      rx_buffer_enable=True)
            gtp.add_stream_endpoints()
            setattr(self.submodules, "gtp" + str(i), gtp)
            platform.add_period_constraint(gtp.cd_tx.clk,
                                           1e9 / gtp.tx_clk_freq)
            platform.add_period_constraint(gtp.cd_rx.clk,
                                           1e9 / gtp.rx_clk_freq)
            self.platform.add_false_path_constraints(self.crg.cd_sys.clk,
                                                     gtp.cd_tx.clk,
                                                     gtp.cd_rx.clk)

        # Record -------------------------------------------------------------------------------------
        self.submodules.rx_dma_recorder = LiteDRAMDMAWriter(
            self.sdram.crossbar.get_port("write", 32, clock_domain="gtp0_rx"))
        self.rx_dma_recorder.add_csr()
        self.add_csr("rx_dma_recorder")

        self.submodules.tx_dma_recorder = LiteDRAMDMAWriter(
            self.sdram.crossbar.get_port("write", 32, clock_domain="gtp1_rx"))
        self.tx_dma_recorder.add_csr()
        self.add_csr("tx_dma_recorder")

        self.comb += [
            self.rx_dma_recorder.sink.valid.eq(self.gtp0.source.valid),
            self.rx_dma_recorder.sink.data.eq(
                self.gtp0.source.payload.raw_bits()),
            self.tx_dma_recorder.sink.valid.eq(self.gtp1.source.valid),
            self.tx_dma_recorder.sink.data.eq(
                self.gtp1.source.payload.raw_bits()),
        ]
Esempio n. 14
0
    def __init__(self, dram_port):
        self.reset = CSRStorage()
        self.start = CSRStorage()
        self.done = CSRStatus()

        self.count = CSRStorage(size=(32 * 1))

        self.mem_base = CSRStorage(size=32)
        self.mem_mask = CSRStorage(size=32)
        self.data_mask = CSRStorage(size=32)  # patterns

        # FIXME: Increase fifo depth
        dma = LiteDRAMDMAWriter(dram_port, fifo_depth=1)
        self.submodules += dma

        self.memory_w0 = Memory(32, 1024)
        self.memory_w1 = Memory(32, 1024)
        self.memory_w2 = Memory(32, 1024)
        self.memory_w3 = Memory(32, 1024)
        self.memory_adr = Memory(32, 1024)
        self.specials += self.memory_w0, self.memory_w1, \
                         self.memory_w2, self.memory_w3, \
                         self.memory_adr

        self.autocsr_exclude = 'memory_w0', 'memory_w1', \
                               'memory_w2', 'memory_w3', \
                               'memory_adr'

        w0_port = self.memory_w0.get_port()
        w1_port = self.memory_w1.get_port()
        w2_port = self.memory_w2.get_port()
        w3_port = self.memory_w3.get_port()
        adr_port = self.memory_adr.get_port()
        self.specials += w0_port, w1_port, w2_port, w3_port, adr_port

        cmd_counter = Signal(32)

        self.comb += [
            w0_port.adr.eq(cmd_counter & self.data_mask.storage),
            w1_port.adr.eq(cmd_counter & self.data_mask.storage),
            w2_port.adr.eq(cmd_counter & self.data_mask.storage),
            w3_port.adr.eq(cmd_counter & self.data_mask.storage),
            adr_port.adr.eq(cmd_counter & self.data_mask.storage),
        ]

        self.comb += [
            dma.sink.address.eq(self.mem_base.storage + adr_port.dat_r +
                                (cmd_counter & self.mem_mask.storage)),
            dma.sink.data.eq(
                Cat(w0_port.dat_r, w1_port.dat_r, w2_port.dat_r,
                    w3_port.dat_r)),
        ]

        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm
        fsm.act(
            "IDLE",
            If(
                self.start.storage,
                NextValue(cmd_counter, 0),
                NextState("WAIT"),
            ))
        fsm.act(
            "WAIT",
            If(cmd_counter >= self.count.storage,
               NextState("DONE")).Else(NextState("RUN")))
        fsm.act(
            "RUN", dma.sink.valid.eq(1),
            If(dma.sink.ready, NextValue(cmd_counter, cmd_counter + 1),
               NextState("WAIT")))
        fsm.act("DONE", self.done.status.eq(1),
                If(self.reset.storage, NextState("IDLE")))
Esempio n. 15
0
    def __init__(self, clock_domain,
                       dram_port,
                       ring_buffer_base_address,
                       ring_buffer_size,
                       filter_fifo_size=2048,
                       trigger_memory_size=128,
                       cdc_stream_fifo_size=1024):

        # *********************************************************
        # *                    Interface                          *
        # *********************************************************
        self.simu            = CSRStorage()    # GTP or Exerciser datas
  
        self.source = source = stream.Endpoint([("address", dram_port.address_width),
                                                ("data", dram_port.data_width)])
        self.sink   = sink   = stream.Endpoint(gtp_layout)

        self.forced    = Signal()          # Another CapturePipeline ask us to record datas
        self.record    = Signal()          # Ask another CapturePipeline to record datas
        self.trigOut   = Signal()          # Inform another recorder that we trigged
        self.trigExt   = Signal()          # Another recorder has trigged
        self.time      = Signal(32)        # Time source
        self.simmode   = Signal()

        # *********************************************************
        # *                         CDC                           *
        # *********************************************************
        self.specials += MultiReg(self.simu.storage, self.simmode, clock_domain)

        # *********************************************************
        # *                     Submodules                        *
        # *********************************************************

        self.submodules.exerciser   = Exerciser(clock_domain)
        self.submodules.multiplexer = stream.Multiplexer(gtp_layout, 2)
        self.submodules.descrambler = Descrambler(clock_domain)
        self.submodules.detect      = ClockDomainsRenamer(clock_domain)(DetectOrderedSets())
        self.submodules.aligner     = ClockDomainsRenamer(clock_domain)(Aligner())
        self.submodules.filter      = Filter(clock_domain, filter_fifo_size)
        self.submodules.trigger     = Trigger(clock_domain, trigger_memory_size)
        self.submodules.recorder    = RingRecorder(clock_domain, dram_port,
                                                   ring_buffer_base_address,
                                                   ring_buffer_size)

        cdc = stream.AsyncFIFO([("address", dram_port.address_width),
                                ("data",    dram_port.data_width)],
                                cdc_stream_fifo_size, buffered=True)

        cdc                 = ClockDomainsRenamer({"write": clock_domain, "read": "sys"})(cdc)
        self.submodules.cdc = cdc
        self.submodules.dma = LiteDRAMDMAWriter(dram_port)

        # *********************************************************
        # *                    Combinatorial                      *
        # *********************************************************

        self.comb += [
            self.multiplexer.sel.eq(self.simmode),
            self.sink.connect(self.multiplexer.sink0),
            self.exerciser.source.connect(self.multiplexer.sink1),
            self.exerciser.time.eq(self.time),

            self.multiplexer.source.connect(self.detect.sink),

            self.detect.source.connect(self.descrambler.sink),
            self.descrambler.source.connect(self.aligner.sink),
            self.aligner.source.connect(self.filter.sink),

            self.filter.source.connect(self.trigger.sink),
            self.filter.ts.eq(self.time),

            self.trigger.source.connect(self.recorder.sink),
            self.trigger.enable.eq(self.recorder.enableTrigger),
            self.trigOut.eq(self.trigger.trigExt),
            self.filter.trigExt.eq(self.trigExt),

            self.recorder.source.connect(self.cdc.sink),
            self.recorder.forced.eq(self.forced),
            self.record.eq(self.recorder.record),

            self.recorder.trigExt.eq(self.trigExt),

            self.cdc.source.connect(self.dma.sink),
        ]
Esempio n. 16
0
    def __init__(self, dram_port):
        ashift, awidth = get_ashift_awidth(dram_port)
        self.start = Signal()
        self.done = Signal()
        self.base = Signal(awidth)
        self.end = Signal(awidth)
        self.length = Signal(awidth)
        self.random_data = Signal()
        self.random_addr = Signal()
        self.ticks = Signal(32)

        self.run_cascade_in = Signal(reset=1)
        self.run_cascade_out = Signal()

        # # #

        # Data / Address generators ----------------------------------------------------------------
        data_gen = Generator(31, n_state=31, taps=[27, 30])  # PRBS31
        addr_gen = Generator(31, n_state=31, taps=[27, 30])
        self.submodules += data_gen, addr_gen
        self.comb += data_gen.random_enable.eq(self.random_data)
        self.comb += addr_gen.random_enable.eq(self.random_addr)

        # mask random address to the range <base, end), range size must be power of 2
        addr_mask = Signal(awidth)
        self.comb += addr_mask.eq((self.end - self.base) - 1)

        # DMA --------------------------------------------------------------------------------------
        dma = LiteDRAMDMAWriter(dram_port)
        self.submodules += dma

        cmd_counter = Signal(dram_port.address_width, reset_less=True)

        # Data / Address FSM -----------------------------------------------------------------------
        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm
        fsm.act("IDLE",
                If(self.start, NextValue(cmd_counter, 0), NextState("RUN")),
                NextValue(self.ticks, 0))
        fsm.act("WAIT", If(self.run_cascade_in, NextState("RUN")))
        fsm.act(
            "RUN", dma.sink.valid.eq(1),
            If(
                dma.sink.ready, self.run_cascade_out.eq(1), data_gen.ce.eq(1),
                addr_gen.ce.eq(1), NextValue(cmd_counter, cmd_counter + 1),
                If(cmd_counter == (self.length[ashift:] - 1),
                   NextState("DONE")).Elif(~self.run_cascade_in,
                                           NextState("WAIT"))),
            NextValue(self.ticks, self.ticks + 1))
        fsm.act("DONE", self.run_cascade_out.eq(1), self.done.eq(1))

        if isinstance(dram_port, LiteDRAMNativePort):  # addressing in dwords
            dma_sink_addr = dma.sink.address
        elif isinstance(dram_port, LiteDRAMAXIPort):  # addressing in bytes
            dma_sink_addr = dma.sink.address[ashift:]
        else:
            raise NotImplementedError

        self.comb += dma_sink_addr.eq(self.base[ashift:] +
                                      (addr_gen.o & addr_mask))
        self.comb += dma.sink.data.eq(data_gen.o)
Esempio n. 17
0
    def __init__(self, sdram_module, sdram_data_width, **kwargs):
        platform     = Platform()
        sys_clk_freq = int(1e6)

        # SoCSDRAM ---------------------------------------------------------------------------------
        SoCSDRAM.__init__(self, platform, sys_clk_freq,
            integrated_rom_size  = 0x8000,
            integrated_sram_size = 0x1000,
            uart_name            = "crossover",
            l2_size              = 0,
            csr_data_width       = 32,
            **kwargs
        )

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = CRG(platform.request("sys_clk"))

        # SDR SDRAM --------------------------------------------------------------------------------
        from litex.tools.litex_sim import sdram_module_nphases, get_sdram_phy_settings
        sdram_clk_freq   = int(100e6) # FIXME: use 100MHz timings
        sdram_module_cls = getattr(litedram_modules, sdram_module)
        sdram_rate       = "1:{}".format(sdram_module_nphases[sdram_module_cls.memtype])
        sdram_module     = sdram_module_cls(sdram_clk_freq, sdram_rate)
        phy_settings     = get_sdram_phy_settings(
            memtype    = sdram_module.memtype,
            data_width = sdram_data_width,
            clk_freq   = sdram_clk_freq)
        self.submodules.sdrphy = SDRAMPHYModel(
            module    = sdram_module,
            settings  = phy_settings,
            clk_freq  = sdram_clk_freq)
        self.register_sdram(
            self.sdrphy,
            sdram_module.geom_settings,
            sdram_module.timing_settings)
        # Disable Memtest for simulation speedup
        self.add_constant("MEMTEST_BUS_SIZE",  0)
        self.add_constant("MEMTEST_ADDR_SIZE", 0)
        self.add_constant("MEMTEST_DATA_SIZE", 0)

        # Ethernet ---------------------------------------------------------------------------------
        # phy
        self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth"))
        self.add_csr("ethphy")
        # core
        ethcore = LiteEthUDPIPCore(self.ethphy,
            mac_address = 0x10e2d5000000,
            ip_address  = "192.168.1.50",
            clk_freq    = sys_clk_freq)
        self.submodules.ethcore = ethcore
        # etherbone
        self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp, 1234, mode="master")
        self.add_wb_master(self.etherbone.wishbone.bus)

        # Record -----------------------------------------------------------------------------------
        self.submodules.rx_dma_recorder = LiteDRAMDMAWriter(self.sdram.crossbar.get_port("write", 32))
        self.rx_dma_recorder.add_csr()
        self.add_csr("rx_dma_recorder")
        self.submodules.tx_dma_recorder = LiteDRAMDMAWriter(self.sdram.crossbar.get_port("write", 32))
        self.tx_dma_recorder.add_csr()
        self.add_csr("tx_dma_recorder")
        counter = Signal(32)
        self.sync += counter.eq(counter + 1)
        self.comb += [
            self.rx_dma_recorder.sink.valid.eq(1),
            self.rx_dma_recorder.sink.data.eq(counter),
            self.tx_dma_recorder.sink.valid.eq(1),
            self.tx_dma_recorder.sink.data.eq(counter),
        ]
Esempio n. 18
0
    def __init__(self, sdram_module, sdram_data_width, **kwargs):
        platform = Platform()
        sys_clk_freq = int(1e6)

        # *********************************************************
        # *                      SoC SDRAM                        *
        # *********************************************************
        SoCSDRAM.__init__(self,
                          platform,
                          sys_clk_freq,
                          integrated_rom_size=0x8000,
                          integrated_sram_size=0x1000,
                          uart_name="crossover",
                          l2_size=0,
                          csr_data_width=32,
                          **kwargs)

        # *********************************************************
        # *                      CRG                              *
        # *********************************************************
        self.submodules.crg = CRG(platform.request("sys_clk"))

        # *********************************************************
        # *                   SDR SDRAM                           *
        # *********************************************************
        from litex.tools.litex_sim import sdram_module_nphases, get_sdram_phy_settings
        sdram_clk_freq = int(100e6)  # FIXME: use 100MHz timings
        sdram_module_cls = getattr(litedram_modules, sdram_module)
        sdram_rate = "1:{}".format(
            sdram_module_nphases[sdram_module_cls.memtype])
        sdram_module = sdram_module_cls(sdram_clk_freq, sdram_rate)
        phy_settings = get_sdram_phy_settings(memtype=sdram_module.memtype,
                                              data_width=sdram_data_width,
                                              clk_freq=sdram_clk_freq)
        self.submodules.sdrphy = SDRAMPHYModel(module=sdram_module,
                                               settings=phy_settings,
                                               clk_freq=sdram_clk_freq)
        self.register_sdram(self.sdrphy, sdram_module.geom_settings,
                            sdram_module.timing_settings)
        # Disable Memtest for simulation speedup
        self.add_constant("MEMTEST_BUS_SIZE", 0)
        self.add_constant("MEMTEST_ADDR_SIZE", 0)
        self.add_constant("MEMTEST_DATA_SIZE", 0)

        # *********************************************************
        # *                  Ethernet PHY                         *
        # *********************************************************
        self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth"))
        self.add_csr("ethphy")

        # *********************************************************
        # *                  Ethernet Core                        *
        # *********************************************************
        ethcore = LiteEthUDPIPCore(self.ethphy,
                                   mac_address=0x10e2d5000000,
                                   ip_address="172.30.28.201",
                                   clk_freq=sys_clk_freq)
        self.submodules.ethcore = ethcore

        # *********************************************************
        # *                 Etherbone bridge                      *
        # *********************************************************
        self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp,
                                                     1234,
                                                     mode="master")
        self.add_wb_master(self.etherbone.wishbone.bus)

        # *********************************************************
        # *        Ordered Sets Detector / Descrambler RX         *
        # *********************************************************
        self.submodules.rx_detector = DetectOrderedSets()
        self.submodules.rx_descrambler = Descrambler("sys")
        self.add_csr("rx_descrambler")

        self.comb += [
            #self.gtp0.source.connect(self.rx_detector.sink, omit={"valid"}),
            self.rx_detector.sink.valid.eq(1),
            self.rx_detector.source.connect(self.rx_descrambler.sink),
        ]

        # *********************************************************
        # *        Ordered Sets Detector / Descrambler TX         *
        # *********************************************************
        self.submodules.tx_detector = DetectOrderedSets()
        self.submodules.tx_descrambler = Descrambler("sys")
        self.add_csr("tx_descrambler")

        self.comb += [
            #self.gtp1.source.connect(self.tx_detector.sink, omit={"valid"}),
            self.tx_detector.sink.valid.eq(1),
            self.tx_detector.source.connect(self.tx_descrambler.sink),
        ]

        # *********************************************************
        # *                     Trigger RX                        *
        # *********************************************************
        self.submodules.rx_trigger = Trigger("sys")
        self.comb += [
            self.rx_descrambler.source.connect(self.rx_trigger.sink),
        ]
        self.add_csr("rx_trigger_mem")
        self.add_csr("rx_trigger")

        # *********************************************************
        # *                     Trigger TX                        *
        # *********************************************************
        self.submodules.tx_trigger = Trigger("sys")
        self.comb += [
            self.tx_descrambler.source.connect(self.tx_trigger.sink),
        ]
        self.add_csr("tx_trigger_mem")
        self.add_csr("tx_trigger")

        # *********************************************************
        # *                    Recorder RX                        *
        # *********************************************************
        rx_port = self.sdram.crossbar.get_port("write", 256)

        STRIDE_MULTIPLIER = 12

        rx_recorder = RingRecorder("sys", rx_port, 0, 0x100000,
                                   STRIDE_MULTIPLIER)
        self.submodules.rx_recorder = rx_recorder
        self.add_csr("rx_recorder")

        rx_cdc = stream.AsyncFIFO([("address", rx_port.address_width),
                                   ("data", rx_port.data_width)],
                                  1024,
                                  buffered=True)
        rx_cdc = ClockDomainsRenamer({"write": "sys", "read": "sys"})(rx_cdc)
        self.submodules.rx_cdc = rx_cdc

        self.submodules.rx_dma = LiteDRAMDMAWriter(rx_port)

        self.comb += [
            self.rx_trigger.source.connect(self.rx_recorder.sink),
            self.rx_trigger.enable.eq(self.rx_recorder.enable),
            self.rx_recorder.source.connect(self.rx_cdc.sink),
            self.rx_cdc.source.connect(self.rx_dma.sink),
        ]

        # *********************************************************
        # *                    Recorder TX                        *
        # *********************************************************
        tx_port = self.sdram.crossbar.get_port("write", 256)

        tx_recorder = RingRecorder("sys", tx_port, 0x100000, 0x100000,
                                   STRIDE_MULTIPLIER)
        self.submodules.tx_recorder = tx_recorder
        self.add_csr("tx_recorder")

        tx_cdc = stream.AsyncFIFO([("address", tx_port.address_width),
                                   ("data", tx_port.data_width)],
                                  1024,
                                  buffered=True)
        tx_cdc = ClockDomainsRenamer({"write": "sys", "read": "sys"})(tx_cdc)
        self.submodules.tx_cdc = tx_cdc

        self.submodules.tx_dma = LiteDRAMDMAWriter(tx_port)

        self.comb += [
            self.tx_trigger.source.connect(self.tx_recorder.sink),
            self.tx_trigger.enable.eq(self.tx_recorder.enable),
            self.tx_recorder.source.connect(self.tx_cdc.sink),
            self.tx_cdc.source.connect(self.tx_dma.sink),
        ]

        # *********************************************************
        # *                 Recorder RX/TX                        *
        # *********************************************************
        self.comb += [
            self.tx_recorder.force.eq(self.rx_recorder.enable),
            self.rx_recorder.force.eq(self.tx_recorder.enable),
        ]