예제 #1
0
    def __init__(self,
                 platform,
                 with_cpu=False,
                 with_analyzer=True,
                 with_loopback=False):
        clk_freq = int(100e6)
        SoCSDRAM.__init__(self,
                          platform,
                          clk_freq,
                          cpu_type="lm32" if with_cpu else None,
                          integrated_rom_size=0x8000 if with_cpu else 0,
                          integrated_sram_size=0x8000,
                          with_uart=with_cpu,
                          ident="PCIe Injector example design",
                          with_timer=with_cpu)
        self.submodules.crg = _CRG(platform)

        if not with_cpu:
            # use serial as wishbone bridge when no cpu
            self.add_cpu_or_bridge(
                UARTWishboneBridge(platform.request("serial"),
                                   clk_freq,
                                   baudrate=3000000))
            self.add_wb_master(self.cpu_or_bridge.wishbone)

        # sdram
        self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram"))
        sdram_module = MT41K256M16(self.clk_freq, "1:4")
        self.register_sdram(self.ddrphy, sdram_module.geom_settings,
                            sdram_module.timing_settings)

        # pcie endpoint
        self.submodules.pciephy = S7PCIEPHY(platform,
                                            platform.request("pcie_x1"),
                                            cd="sys")

        # usb core
        usb_pads = platform.request("usb_fifo")
        # self.submodules.usb_phy = FT245PHYSynchronous(usb_pads, clk_freq, fifo_depth=16)
        self.submodules.usb_phy = FT601Sync(usb_pads, dw=32, timeout=1024)

        if with_loopback:
            self.submodules.usb_loopback_fifo = stream.SyncFIFO(
                phy_description(32), 2048)
            self.comb += [
                self.usb_phy.source.connect(self.usb_loopback_fifo.sink),
                self.usb_loopback_fifo.source.connect(self.usb_phy.sink)
            ]
        else:
            self.submodules.usb_core = USBCore(self.usb_phy, clk_freq)

            # usb <--> wishbone
            self.submodules.etherbone = Etherbone(self.usb_core,
                                                  self.usb_map["wishbone"])
            self.add_wb_master(self.etherbone.master.bus)

            # usb <--> tlp
            self.submodules.tlp = TLP(self.usb_core, self.usb_map["tlp"])
            self.comb += [
                self.pciephy.source.connect(self.tlp.sender.sink),
                self.tlp.receiver.source.connect(self.pciephy.sink)
            ]

        # wishbone --> msi
        self.submodules.msi = MSI()
        self.comb += self.msi.source.connect(self.pciephy.msi)

        # led blink
        usb_counter = Signal(32)
        self.sync.usb += usb_counter.eq(usb_counter + 1)
        self.comb += platform.request("user_led", 0).eq(usb_counter[26])

        pcie_counter = Signal(32)
        self.sync.pcie += pcie_counter.eq(pcie_counter + 1)
        self.comb += platform.request("user_led", 1).eq(pcie_counter[26])

        # timing constraints
        self.crg.cd_sys.clk.attr.add("keep")
        self.crg.cd_usb.clk.attr.add("keep")
        self.platform.add_period_constraint(self.crg.cd_sys.clk, 10.0)
        self.platform.add_period_constraint(self.crg.cd_usb.clk, 10.0)
        self.platform.add_period_constraint(
            self.platform.lookup_request("pcie_x1").clk_p, 10.0)

        if with_analyzer:
            analyzer_signals = [
                self.pciephy.sink.valid, self.pciephy.sink.ready,
                self.pciephy.sink.last, self.pciephy.sink.dat,
                self.pciephy.sink.be, self.pciephy.source.valid,
                self.pciephy.source.ready, self.pciephy.source.last,
                self.pciephy.source.dat, self.pciephy.source.be
            ]
            self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals,
                                                         1024,
                                                         cd="sys")
예제 #2
0
    def __init__(self, pads, dw=32, timeout=1024):
        read_fifo = ClockDomainsRenamer({
            "write": "usb",
            "read": "sys"
        })(stream.AsyncFIFO(phy_description(dw), 128))
        write_fifo = ClockDomainsRenamer({
            "write": "sys",
            "read": "usb"
        })(stream.AsyncFIFO(phy_description(dw), 128))

        read_buffer = ClockDomainsRenamer("usb")(stream.SyncFIFO(
            phy_description(dw), 4))
        self.comb += read_buffer.source.connect(read_fifo.sink)

        self.submodules += read_fifo
        self.submodules += read_buffer
        self.submodules += write_fifo

        self.read_buffer = read_buffer

        self.sink = write_fifo.sink
        self.source = read_fifo.source

        self.tdata_w = tdata_w = Signal(dw)
        self.data_r = data_r = Signal(dw)
        self.data_oe = data_oe = Signal()
        self.specials += Tristate(pads.data, tdata_w, data_oe, data_r)

        data_w = Signal(dw)
        _data_w = Signal(dw)
        self.sync.usb += [_data_w.eq(data_w)]
        for i in range(dw):
            self.specials += [
                Instance("ODDR",
                         p_DDR_CLK_EDGE="SAME_EDGE",
                         i_C=ClockSignal("usb"),
                         i_CE=1,
                         i_S=0,
                         i_R=0,
                         i_D1=_data_w[i],
                         i_D2=data_w[i],
                         o_Q=tdata_w[i])
            ]

        self.rd_n = rd_n = Signal()
        _rd_n = Signal(reset=1)
        self.wr_n = wr_n = Signal()
        _wr_n = Signal(reset=1)
        self.oe_n = oe_n = Signal()
        _oe_n = Signal(reset=1)
        self.sync.usb += [
            _rd_n.eq(rd_n),
            _wr_n.eq(wr_n),
            _oe_n.eq(oe_n),
        ]
        self.specials += [
            Instance("ODDR",
                     p_DDR_CLK_EDGE="SAME_EDGE",
                     i_C=ClockSignal("usb"),
                     i_CE=1,
                     i_S=0,
                     i_R=0,
                     i_D1=_rd_n,
                     i_D2=rd_n,
                     o_Q=pads.rd_n),
            Instance("ODDR",
                     p_DDR_CLK_EDGE="SAME_EDGE",
                     i_C=ClockSignal("usb"),
                     i_CE=1,
                     i_S=0,
                     i_R=0,
                     i_D1=_wr_n,
                     i_D2=wr_n,
                     o_Q=pads.wr_n),
            Instance("ODDR",
                     p_DDR_CLK_EDGE="SAME_EDGE",
                     i_C=ClockSignal("usb"),
                     i_CE=1,
                     i_S=0,
                     i_R=0,
                     i_D1=_oe_n,
                     i_D2=oe_n,
                     o_Q=pads.oe_n)
        ]

        self.comb += [
            pads.rst.eq(~ResetSignal("usb")),
            pads.be.eq(0xf),
            pads.siwua.eq(1),
            data_oe.eq(oe_n),
        ]

        fsm = FSM()
        self.submodules.fsm = ClockDomainsRenamer("usb")(fsm)

        self.tempsendval = tempsendval = Signal(dw)
        self.temptosend = temptosend = Signal()

        self.tempreadval = tempreadval = Signal(dw)
        self.temptoread = temptoread = Signal()

        self.wants_read = wants_read = Signal()
        self.wants_write = wants_write = Signal()
        self.cnt_write = cnt_write = Signal(max=timeout + 1)
        self.cnt_read = cnt_read = Signal(max=timeout + 1)

        first_write = Signal()

        self.comb += [
            wants_read.eq(~temptoread & ~pads.rxf_n),
            wants_write.eq((temptosend | write_fifo.source.valid)
                           & (pads.txe_n == 0)),
        ]

        self.fsmstate = Signal(4)
        self.comb += [
            self.fsmstate.eq(
                Cat(fsm.ongoing("IDLE"), fsm.ongoing("WRITE"),
                    fsm.ongoing("RDWAIT"), fsm.ongoing("READ")))
        ]

        self.sync.usb += [
            If(~fsm.ongoing("READ"),
               If(temptoread, If(read_buffer.sink.ready, temptoread.eq(0))))
        ]
        self.comb += [
            If(
                ~fsm.ongoing("READ"),
                If(
                    temptoread,
                    read_buffer.sink.data.eq(tempreadval),
                    read_buffer.sink.valid.eq(1),
                ))
        ]

        fsm.act(
            "IDLE", rd_n.eq(1), wr_n.eq(1),
            If(
                wants_write,
                oe_n.eq(1),
                NextValue(cnt_write, 0),
                NextValue(first_write, 1),
                NextState("WRITE"),
            ).Elif(wants_read, oe_n.eq(0),
                   NextState("RDWAIT")).Else(oe_n.eq(1), ))

        fsm.act(
            "WRITE", If(
                wants_read,
                NextValue(cnt_write, cnt_write + 1),
            ), NextValue(first_write, 0), rd_n.eq(1),
            If(
                pads.txe_n, oe_n.eq(1), wr_n.eq(1),
                write_fifo.source.ready.eq(0),
                If(write_fifo.source.valid & ~first_write,
                   NextValue(temptosend, 1)),
                NextState("IDLE")).Elif(
                    temptosend, oe_n.eq(1), data_w.eq(tempsendval), wr_n.eq(0),
                    NextValue(temptosend,
                              0)).Elif(cnt_write > timeout, oe_n.eq(0),
                                       NextState("RDWAIT")).Elif(
                                           write_fifo.source.valid,
                                           oe_n.eq(1),
                                           data_w.eq(write_fifo.source.data),
                                           write_fifo.source.ready.eq(1),
                                           NextValue(tempsendval,
                                                     write_fifo.source.data),
                                           NextValue(temptosend, 0),
                                           wr_n.eq(0),
                                       ).Else(oe_n.eq(1), wr_n.eq(1),
                                              NextValue(temptosend, 0),
                                              NextState("IDLE")))

        fsm.act("RDWAIT", rd_n.eq(0), oe_n.eq(0), wr_n.eq(1),
                NextValue(cnt_read, 0), NextState("READ"))

        fsm.act(
            "READ", If(
                wants_write,
                NextValue(cnt_read, cnt_read + 1),
            ), wr_n.eq(1),
            If(
                pads.rxf_n,
                oe_n.eq(0),
                rd_n.eq(1),
                NextState("IDLE"),
            ).Elif(
                cnt_read > timeout,
                NextValue(cnt_write, 0),
                NextValue(first_write, 1),
                NextState("WRITE"),
                oe_n.eq(1),
            ).Else(
                oe_n.eq(0), read_buffer.sink.valid.eq(1),
                read_buffer.sink.data.eq(data_r),
                NextValue(tempreadval, data_r),
                If(read_buffer.sink.ready,
                   rd_n.eq(0)).Else(NextValue(temptoread, 1),
                                    NextState("IDLE"), rd_n.eq(1))))