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")
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))))