def __init__(self, with_sdram=False, with_ethernet=False, ethernet_phy_model="sim", with_etherbone=False, etherbone_mac_address=0x10e2d5000001, etherbone_ip_address="192.168.1.51", with_analyzer=False, sdram_module="MT48LC16M16", sdram_init=[], sdram_data_width=32, sdram_spd_data=None, sdram_verbosity=0, with_i2c=False, with_sdcard=False, with_spi_flash=False, spi_flash_init=[], with_gpio=False, sim_debug=False, trace_reset_on=False, **kwargs): platform = Platform() sys_clk_freq = int(1e6) # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, ident="LiteX Simulation", **kwargs) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = CRG(platform.request("sys_clk")) # SDRAM ------------------------------------------------------------------------------------ if not self.integrated_main_ram_size and with_sdram: sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings if sdram_spd_data is None: 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) else: sdram_module = litedram_modules.SDRAMModule.from_spd_data( sdram_spd_data, sdram_clk_freq) self.submodules.sdrphy = SDRAMPHYModel(module=sdram_module, data_width=sdram_data_width, clk_freq=sdram_clk_freq, verbosity=sdram_verbosity, init=sdram_init) self.add_sdram("sdram", phy=self.sdrphy, module=sdram_module, origin=self.mem_map["main_ram"], size=kwargs.get("max_sdram_size", 0x40000000), l2_cache_size=kwargs.get("l2_size", 8192), l2_cache_min_data_width=kwargs.get( "min_l2_data_width", 128), l2_cache_reverse=False) if sdram_init != []: # Skip SDRAM test to avoid corrupting pre-initialized contents. self.add_constant("SDRAM_TEST_DISABLE") else: # Reduce memtest size for simulation speedup self.add_constant("MEMTEST_DATA_SIZE", 8 * 1024) self.add_constant("MEMTEST_ADDR_SIZE", 8 * 1024) # Ethernet / Etherbone PHY ----------------------------------------------------------------- if with_ethernet or with_etherbone: if ethernet_phy_model == "sim": self.submodules.ethphy = LiteEthPHYModel( self.platform.request("eth", 0)) elif ethernet_phy_model == "xgmii": self.submodules.ethphy = LiteEthPHYXGMII(None, self.platform.request( "xgmii_eth", 0), model=True) elif ethernet_phy_model == "gmii": self.submodules.ethphy = LiteEthPHYGMII(None, self.platform.request( "gmii_eth", 0), model=True) else: raise ValueError("Unknown Ethernet PHY model:", ethernet_phy_model) # Ethernet and Etherbone ------------------------------------------------------------------- if with_ethernet and with_etherbone: etherbone_ip_address = convert_ip(etherbone_ip_address) # Ethernet MAC self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=8, interface="hybrid", endianness=self.cpu.endianness, hw_mac=etherbone_mac_address) # SoftCPU self.add_memory_region("ethmac", self.mem_map.get("ethmac", None), 0x2000, type="io") self.add_wb_slave(self.mem_regions["ethmac"].origin, self.ethmac.bus, 0x2000) if self.irq.enabled: self.irq.add("ethmac", use_loc_if_exists=True) # HW ethernet self.submodules.arp = LiteEthARP(self.ethmac, etherbone_mac_address, etherbone_ip_address, sys_clk_freq, dw=8) self.submodules.ip = LiteEthIP(self.ethmac, etherbone_mac_address, etherbone_ip_address, self.arp.table, dw=8) self.submodules.icmp = LiteEthICMP(self.ip, etherbone_ip_address, dw=8) self.submodules.udp = LiteEthUDP(self.ip, etherbone_ip_address, dw=8) # Etherbone self.submodules.etherbone = LiteEthEtherbone(self.udp, 1234, mode="master") self.add_wb_master(self.etherbone.wishbone.bus) # Ethernet --------------------------------------------------------------------------------- elif with_ethernet: # Ethernet MAC self.submodules.ethmac = ethmac = LiteEthMAC( phy=self.ethphy, dw=64 if ethernet_phy_model == "xgmii" else 32, interface="wishbone", endianness=self.cpu.endianness) ethmac_region_size = ( ethmac.rx_slots.read() + ethmac.tx_slots.read()) * ethmac.slot_size.read() self.add_memory_region("ethmac", self.mem_map.get("ethmac", None), ethmac_region_size, type="io") self.add_wb_slave(self.mem_regions["ethmac"].origin, ethmac.bus, ethmac_region_size) if self.irq.enabled: self.irq.add("ethmac", use_loc_if_exists=True) # Etherbone -------------------------------------------------------------------------------- elif with_etherbone: self.add_etherbone(phy=self.ethphy, ip_address=etherbone_ip_address, mac_address=etherbone_mac_address) # I2C -------------------------------------------------------------------------------------- if with_i2c: pads = platform.request("i2c", 0) self.submodules.i2c = I2CMasterSim(pads) # SDCard ----------------------------------------------------------------------------------- if with_sdcard: self.add_sdcard("sdcard", use_emulator=True) # SPI Flash -------------------------------------------------------------------------------- if with_spi_flash: from litespi.phy.model import LiteSPIPHYModel from litespi.modules import S25FL128L from litespi.opcodes import SpiNorFlashOpCodes as Codes spiflash_module = S25FL128L(Codes.READ_1_1_4) if spi_flash_init is None: platform.add_sources( os.path.abspath(os.path.dirname(__file__)), "../build/sim/verilog/iddr_verilog.v") platform.add_sources( os.path.abspath(os.path.dirname(__file__)), "../build/sim/verilog/oddr_verilog.v") self.submodules.spiflash_phy = LiteSPIPHYModel(spiflash_module, init=spi_flash_init) self.add_spi_flash(phy=self.spiflash_phy, mode="4x", module=spiflash_module, with_master=True) # GPIO -------------------------------------------------------------------------------------- if with_gpio: self.submodules.gpio = GPIOTristate(platform.request("gpio"), with_irq=True) self.irq.add("gpio", use_loc_if_exists=True) # Simulation debugging ---------------------------------------------------------------------- if sim_debug: platform.add_debug(self, reset=1 if trace_reset_on else 0) else: self.comb += platform.trace.eq(1) # Analyzer --------------------------------------------------------------------------------- if with_analyzer: analyzer_signals = [ # IBus (could also just added as self.cpu.ibus) self.cpu.ibus.stb, self.cpu.ibus.cyc, self.cpu.ibus.adr, self.cpu.ibus.we, self.cpu.ibus.ack, self.cpu.ibus.sel, self.cpu.ibus.dat_w, self.cpu.ibus.dat_r, # DBus (could also just added as self.cpu.dbus) self.cpu.dbus.stb, self.cpu.dbus.cyc, self.cpu.dbus.adr, self.cpu.dbus.we, self.cpu.dbus.ack, self.cpu.dbus.sel, self.cpu.dbus.dat_w, self.cpu.dbus.dat_r, ] self.submodules.analyzer = LiteScopeAnalyzer( analyzer_signals, depth=512, clock_domain="sys", csr_csv="analyzer.csv")
def add_xgmii(self): self.submodules.xgmii = XilinxXGMII(self.crg.cd_sys, self.platform) self.add_csr('xgmii') self.platform.add_period_constraint(self.xgmii.cd_clkmgt.clk, 1e9/156.25e6) self.platform.add_false_path_constraints(self.crg.cd_sys.clk, self.xgmii.cd_clkmgt.clk) self.submodules.xgmiiphy = LiteEthPHYXGMII(self.xgmii.pads, self.xgmii.pads) # Keeping this away from sys_clk domain, and strictly leaving it in 156.25e6 self.submodules.teng_udp_core = ClockDomainsRenamer("clkmgt")(LiteEthUDPIPCore(self.xgmiiphy, 0xaa1233445566, convert_ip("10.1.0.3"), self.sys_clk_freq, dw=64)) self.add_csr("xgmiiphy") self.udp_port = udp_port = self.teng_udp_core.udp.crossbar.get_port(3000, 64) send_pkt = Signal(reset=0) always_xmit = True if always_xmit: send_pkt_counter_d = Signal() self.sync.clkmgt += [ send_pkt_counter_d.eq(self.counter[26]), send_pkt.eq(send_pkt_counter_d ^ self.counter[26]) ] sink_counter = Signal(16) SINK_LENGTH = 64 # 8 words shift = log2_int(64 // 8) # bits required to represent bytes per word words_per_packet = SINK_LENGTH >> shift # Note the clkmgt domain self.sync.clkmgt += [ If(send_pkt, sink_counter.eq(words_per_packet)), If((sink_counter > 0) & (udp_port.sink.ready == 1), sink_counter.eq(sink_counter - 1) ).Else( udp_port.sink.valid.eq(0), udp_port.sink.last.eq(0) ), udp_port.sink.valid.eq(sink_counter > 0), udp_port.sink.last.eq(sink_counter == 1), If(sink_counter == 1, udp_port.sink.last_be.eq(0x80) ).Else( udp_port.sink.last_be.eq(0x0) ) ] self.comb += self.user_leds[1].eq(udp_port.sink.valid) self.comb += [ # param udp_port.sink.src_port.eq(3000), udp_port.sink.dst_port.eq(7778), udp_port.sink.ip_address.eq(convert_ip("10.1.0.4")), udp_port.sink.length.eq(SINK_LENGTH), # payload udp_port.sink.data.eq(Cat(0xc0ffeec1ffee, sink_counter)), udp_port.sink.error.eq(0) ] self.add_csr("teng_udp_core")