def __init__(self, *, args, sys_clk_freq, sdram_module_cls, sdram_module_speedgrade=None, sdram_module_spd_file=None, ip_address="192.168.100.50", mac_address=0x10e2d5000001, udp_port=1234, **kwargs): self.args = args self.sys_clk_freq = sys_clk_freq self.ip_address = ip_address self.mac_address = mac_address self.udp_port = udp_port # Platform --------------------------------------------------------------------------------- if not args.sim: self.platform = self.get_platform() else: self.platform = SimPlatform() githash = git.Repo( '.', search_parent_directories=True).git.rev_parse("HEAD") # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__( self, self.platform, sys_clk_freq, ident="LiteX Row Hammer Tester SoC on {}, git: {}".format( self.platform.device, githash), ident_version=True, integrated_rom_mode='rw' if args.rw_bios_mem else 'r', **kwargs) # CRG -------------------------------------------------------------------------------------- if not args.sim: self.submodules.crg = self.get_crg() else: self.submodules.crg = CRG(self.platform.request('sys_clk')) # Add dynamic simulation trace control, start enabled self.platform.add_debug(self, reset=1) # Leds ------------------------------------------------------------------------------------- self.submodules.leds = LedChaser( pads=self.platform.request_all("user_led"), sys_clk_freq=sys_clk_freq) self.add_csr("leds") # SDRAM PHY -------------------------------------------------------------------------------- if sdram_module_spd_file is not None: self.logger.info('Using DRAM module {} data: {}'.format( colorer('SPD'), sdram_module_spd_file)) with open(sdram_module_spd_file, 'rb') as f: spd_data = f.read() module = SDRAMModule.from_spd_data(spd_data, self.sys_clk_freq) else: ratio = self.get_sdram_ratio() self.logger.info('Using DRAM module {} ratio {}'.format( colorer(sdram_module_cls.__name__), colorer(ratio))) module = sdram_module_cls(self.sys_clk_freq, ratio, speedgrade=sdram_module_speedgrade) if args.sim: # Use the hardware platform to retrieve values for simulation hw_pads = self.get_platform().request('ddram') core_config = dict( sdram_module_nb=len(hw_pads.dq) // 8, # number of byte groups sdram_rank_nb=len(hw_pads.cs_n), # number of ranks sdram_module=module, memtype=module.memtype, ) # Add IO pins self.platform.add_extension(get_dram_ios(core_config)) phy_settings = get_sdram_phy_settings( memtype=module.memtype, data_width=core_config["sdram_module_nb"] * 8, clk_freq=sys_clk_freq) self.submodules.ddrphy = SDRAMPHYModel( module=module, settings=phy_settings, clk_freq=sys_clk_freq, verbosity=3, ) else: # hardware self.submodules.ddrphy = self.get_ddrphy() self.add_csr("ddrphy") # SDRAM Controller-------------------------------------------------------------------------- class ControllerDynamicSettings(Module, AutoCSR, AutoDoc, ModuleDoc): """Allows to change LiteDRAMController behaviour at runtime""" def __init__(self): self.refresh = CSRStorage( reset=1, description="Enable/disable Refresh commands sending") self.submodules.controller_settings = ControllerDynamicSettings() self.add_csr("controller_settings") controller_settings = ControllerSettings() controller_settings.with_auto_precharge = True controller_settings.with_refresh = self.controller_settings.refresh.storage controller_settings.refresh_cls = SyncableRefresher assert self.ddrphy.settings.memtype == module.memtype, \ 'Wrong DRAM module type: {} vs {}'.format(self.ddrphy.settings.memtype, module.memtype) self.add_sdram("sdram", phy=self.ddrphy, module=module, origin=self.mem_map["main_ram"], size=kwargs.get("max_sdram_size", 0x40000000), l2_cache_size=0, controller_settings=controller_settings) # CPU will report that leveling finished by writing to ddrctrl CSRs self.submodules.ddrctrl = LiteDRAMCoreControl() self.add_csr("ddrctrl") # Ethernet / Etherbone --------------------------------------------------------------------- if not args.sim: self.add_host_bridge() else: # simulation self.submodules.ethphy = LiteEthPHYModel( self.platform.request("eth")) self.add_csr("ethphy") # Ethernet Core ethcore = LiteEthUDPIPCore(self.ethphy, ip_address=self.ip_address, mac_address=self.mac_address, clk_freq=self.sys_clk_freq) self.submodules.ethcore = ethcore # Etherbone self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp, self.udp_port, mode="master") self.add_wb_master(self.etherbone.wishbone.bus) # Rowhammer -------------------------------------------------------------------------------- self.submodules.rowhammer_dma = LiteDRAMDMAReader( self.sdram.crossbar.get_port()) self.submodules.rowhammer = RowHammerDMA(self.rowhammer_dma) self.add_csr("rowhammer") # Bist ------------------------------------------------------------------------------------- if not args.no_memory_bist: pattern_data_size = int(args.pattern_data_size, 0) phy_settings = self.sdram.controller.settings.phy pattern_data_width = phy_settings.dfi_databits * phy_settings.nphases pattern_length = pattern_data_size // (pattern_data_width // 8) assert pattern_data_size % (pattern_data_width//8) == 0, \ 'Pattern data memory size must be multiple of {} bytes'.format(pattern_data_width//8) self.submodules.pattern_mem = PatternMemory( data_width=pattern_data_width, mem_depth=pattern_length) self.add_memory(self.pattern_mem.data, name='pattern_data', origin=0x20000000) self.add_memory(self.pattern_mem.addr, name='pattern_addr', origin=0x21000000) self.logger.info( '{}: Length: {}, Data Width: {}-bit, Address width: {}-bit'. format(colorer('BIST pattern'), colorer(pattern_length), colorer(pattern_data_width), colorer(32))) assert controller_settings.address_mapping == 'ROW_BANK_COL' row_offset = controller_settings.geom.bankbits + controller_settings.geom.colbits inversion_kwargs = dict( rowbits=int(self.args.bist_inversion_rowbits, 0), row_shift=row_offset - self.sdram.controller.interface.address_align, ) # Writer dram_wr_port = self.sdram.crossbar.get_port() self.submodules.writer = Writer(dram_wr_port, self.pattern_mem, **inversion_kwargs) self.writer.add_csrs() self.add_csr('writer') # Reader dram_rd_port = self.sdram.crossbar.get_port() self.submodules.reader = Reader(dram_rd_port, self.pattern_mem, **inversion_kwargs) self.reader.add_csrs() self.add_csr('reader') assert pattern_data_width == dram_wr_port.data_width assert pattern_data_width == dram_rd_port.data_width # Payload executor ------------------------------------------------------------------------- if not args.no_payload_executor: # TODO: disconnect bus during payload execution phy_settings = self.sdram.controller.settings.phy scratchpad_width = phy_settings.dfi_databits * phy_settings.nphases payload_size = int(args.payload_size, 0) scratchpad_size = int(args.scratchpad_size, 0) assert payload_size % 4 == 0, 'Payload memory size must be multiple of 4 bytes' assert scratchpad_size % (scratchpad_width//8) == 0, \ 'Scratchpad memory size must be multiple of {} bytes'.format(scratchpad_width//8) scratchpad_depth = scratchpad_size // (scratchpad_width // 8) payload_mem = Memory(32, payload_size // 4) scratchpad_mem = Memory(scratchpad_width, scratchpad_depth) self.specials += payload_mem, scratchpad_mem self.add_memory(payload_mem, name='payload', origin=0x30000000) self.add_memory(scratchpad_mem, name='scratchpad', origin=0x31000000, mode='r') self.logger.info('{}: Length: {}, Data Width: {}-bit'.format( colorer('Instruction payload'), colorer(payload_size // 4), colorer(32))) self.logger.info('{}: Length: {}, Data Width: {}-bit'.format( colorer('Scratchpad memory'), colorer(scratchpad_depth), colorer(scratchpad_width))) self.submodules.dfi_switch = DFISwitch( with_refresh=self.sdram.controller.settings.with_refresh, dfii=self.sdram.dfii, refresher_reset=self.sdram.controller.refresher.reset, ) self.dfi_switch.add_csrs() self.add_csr('dfi_switch') self.submodules.payload_executor = PayloadExecutor( mem_payload=payload_mem, mem_scratchpad=scratchpad_mem, dfi_switch=self.dfi_switch, nranks=self.sdram.controller.settings.phy.nranks, bankbits=self.sdram.controller.settings.geom.bankbits, rowbits=self.sdram.controller.settings.geom.rowbits, colbits=self.sdram.controller.settings.geom.colbits, rdphase=self.sdram.controller.settings.phy.rdphase, ) self.payload_executor.add_csrs() self.add_csr('payload_executor')
def __init__(self, platform, core_config, **kwargs): platform.add_extension(get_common_ios()) # Parameters ------------------------------------------------------------------------------- sys_clk_freq = core_config["sys_clk_freq"] cpu_type = core_config["cpu"] cpu_variant = core_config.get("cpu_variant", "standard") csr_alignment = core_config.get("csr_alignment", 32) csr_data_width = core_config.get("csr_data_width", 8) if cpu_type is None: kwargs["integrated_rom_size"] = 0 kwargs["integrated_sram_size"] = 0 kwargs["with_uart"] = False kwargs["with_timer"] = False kwargs["with_ctrl"] = False # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, cpu_type=cpu_type, cpu_variant=cpu_variant, csr_data_width=csr_data_width, csr_alignment=csr_alignment, **kwargs) # CRG -------------------------------------------------------------------------------------- if isinstance(platform, SimPlatform): self.submodules.crg = CRG(platform.request("clk")) elif core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]: self.submodules.crg = crg = LiteDRAMECP5DDRPHYCRG( platform, core_config) elif core_config["sdram_phy"] in [ litedram_phys.A7DDRPHY, litedram_phys.K7DDRPHY, litedram_phys.V7DDRPHY ]: self.submodules.crg = LiteDRAMS7DDRPHYCRG(platform, core_config) # DRAM ------------------------------------------------------------------------------------- platform.add_extension(get_dram_ios(core_config)) sdram_module = core_config["sdram_module"]( sys_clk_freq, "1:4" if core_config["memtype"] == "DDR3" else "1:2") # Sim if isinstance(platform, SimPlatform): from litex.tools.litex_sim import get_sdram_phy_settings sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings phy_settings = get_sdram_phy_settings( memtype=sdram_module.memtype, data_width=core_config["sdram_module_nb"] * 8, clk_freq=sdram_clk_freq) self.submodules.ddrphy = SDRAMPHYModel(module=sdram_module, settings=phy_settings, clk_freq=sdram_clk_freq) # ECP5DDRPHY elif core_config["sdram_phy"] in [litedram_phys.ECP5DDRPHY]: assert core_config["memtype"] in ["DDR3"] self.submodules.ddrphy = core_config["sdram_phy"]( pads=platform.request("ddram"), sys_clk_freq=sys_clk_freq) self.comb += crg.stop.eq(self.ddrphy.init.stop) self.add_constant("ECP5DDRPHY") sdram_module = core_config["sdram_module"](sys_clk_freq, "1:2") # S7DDRPHY elif core_config["sdram_phy"] in [ litedram_phys.A7DDRPHY, litedram_phys.K7DDRPHY, litedram_phys.V7DDRPHY ]: assert core_config["memtype"] in ["DDR2", "DDR3"] self.submodules.ddrphy = core_config["sdram_phy"]( pads=platform.request("ddram"), memtype=core_config["memtype"], nphases=4 if core_config["memtype"] == "DDR3" else 2, sys_clk_freq=sys_clk_freq, iodelay_clk_freq=core_config["iodelay_clk_freq"], cmd_latency=core_config["cmd_latency"]) self.add_constant("CMD_DELAY", core_config["cmd_delay"]) if core_config["memtype"] == "DDR3": self.ddrphy.settings.add_electrical_settings( rtt_nom=core_config["rtt_nom"], rtt_wr=core_config["rtt_wr"], ron=core_config["ron"]) self.add_csr("ddrphy") controller_settings = controller_settings = ControllerSettings( cmd_buffer_depth=core_config["cmd_buffer_depth"]) self.add_sdram( "sdram", phy=self.ddrphy, module=sdram_module, origin=self.mem_map["main_ram"], size= 0x01000000, # Only expose 16MB to the CPU, enough for Init/Calib. with_soc_interconnect=cpu_type is not None, l2_cache_size=8, l2_cache_min_data_width=0, controller_settings=controller_settings, ) # DRAM Control/Status ---------------------------------------------------------------------- # Expose calibration status to user. self.submodules.ddrctrl = LiteDRAMCoreControl() self.add_csr("ddrctrl") self.comb += platform.request("init_done").eq( self.ddrctrl.init_done.storage) self.comb += platform.request("init_error").eq( self.ddrctrl.init_error.storage) # If no CPU, expose a bus control interface to user. if cpu_type is None: wb_bus = wishbone.Interface() self.bus.add_master(master=wb_bus) platform.add_extension(wb_bus.get_ios("wb_ctrl")) wb_pads = platform.request("wb_ctrl") self.comb += wb_bus.connect_to_pads(wb_pads, mode="slave") # User ports ------------------------------------------------------------------------------- self.comb += [ platform.request("user_clk").eq(ClockSignal()), platform.request("user_rst").eq(ResetSignal()) ] for name, port in core_config["user_ports"].items(): # Native ------------------------------------------------------------------------------- if port["type"] == "native": user_port = self.sdram.crossbar.get_port() platform.add_extension( get_native_user_port_ios(name, user_port.address_width, user_port.data_width)) _user_port_io = platform.request("user_port_{}".format(name)) self.comb += [ # cmd user_port.cmd.valid.eq(_user_port_io.cmd_valid), _user_port_io.cmd_ready.eq(user_port.cmd.ready), user_port.cmd.we.eq(_user_port_io.cmd_we), user_port.cmd.addr.eq(_user_port_io.cmd_addr), # wdata user_port.wdata.valid.eq(_user_port_io.wdata_valid), _user_port_io.wdata_ready.eq(user_port.wdata.ready), user_port.wdata.we.eq(_user_port_io.wdata_we), user_port.wdata.data.eq(_user_port_io.wdata_data), # rdata _user_port_io.rdata_valid.eq(user_port.rdata.valid), user_port.rdata.ready.eq(_user_port_io.rdata_ready), _user_port_io.rdata_data.eq(user_port.rdata.data), ] # Wishbone ----------------------------------------------------------------------------- elif port["type"] == "wishbone": user_port = self.sdram.crossbar.get_port() wb_port = wishbone.Interface(user_port.data_width, user_port.address_width) wishbone2native = LiteDRAMWishbone2Native(wb_port, user_port) self.submodules += wishbone2native platform.add_extension( get_wishbone_user_port_ios(name, len(wb_port.adr), len(wb_port.dat_w))) _wb_port_io = platform.request("user_port_{}".format(name)) self.comb += [ wb_port.adr.eq(_wb_port_io.adr), wb_port.dat_w.eq(_wb_port_io.dat_w), _wb_port_io.dat_r.eq(wb_port.dat_r), wb_port.sel.eq(_wb_port_io.sel), wb_port.cyc.eq(_wb_port_io.cyc), wb_port.stb.eq(_wb_port_io.stb), _wb_port_io.ack.eq(wb_port.ack), wb_port.we.eq(_wb_port_io.we), _wb_port_io.err.eq(wb_port.err), ] # AXI ---------------------------------------------------------------------------------- elif port["type"] == "axi": user_port = self.sdram.crossbar.get_port() axi_port = LiteDRAMAXIPort( user_port.data_width, user_port.address_width + log2_int(user_port.data_width // 8), port["id_width"]) axi2native = LiteDRAMAXI2Native(axi_port, user_port) self.submodules += axi2native platform.add_extension( get_axi_user_port_ios(name, axi_port.address_width, axi_port.data_width, port["id_width"])) _axi_port_io = platform.request("user_port_{}".format(name)) self.comb += [ # aw axi_port.aw.valid.eq(_axi_port_io.awvalid), _axi_port_io.awready.eq(axi_port.aw.ready), axi_port.aw.addr.eq(_axi_port_io.awaddr), axi_port.aw.burst.eq(_axi_port_io.awburst), axi_port.aw.len.eq(_axi_port_io.awlen), axi_port.aw.size.eq(_axi_port_io.awsize), axi_port.aw.id.eq(_axi_port_io.awid), # w axi_port.w.valid.eq(_axi_port_io.wvalid), _axi_port_io.wready.eq(axi_port.w.ready), axi_port.w.last.eq(_axi_port_io.wlast), axi_port.w.strb.eq(_axi_port_io.wstrb), axi_port.w.data.eq(_axi_port_io.wdata), # b _axi_port_io.bvalid.eq(axi_port.b.valid), axi_port.b.ready.eq(_axi_port_io.bready), _axi_port_io.bresp.eq(axi_port.b.resp), _axi_port_io.bid.eq(axi_port.b.id), # ar axi_port.ar.valid.eq(_axi_port_io.arvalid), _axi_port_io.arready.eq(axi_port.ar.ready), axi_port.ar.addr.eq(_axi_port_io.araddr), axi_port.ar.burst.eq(_axi_port_io.arburst), axi_port.ar.len.eq(_axi_port_io.arlen), axi_port.ar.size.eq(_axi_port_io.arsize), axi_port.ar.id.eq(_axi_port_io.arid), # r _axi_port_io.rvalid.eq(axi_port.r.valid), axi_port.r.ready.eq(_axi_port_io.rready), _axi_port_io.rlast.eq(axi_port.r.last), _axi_port_io.rresp.eq(axi_port.r.resp), _axi_port_io.rdata.eq(axi_port.r.data), _axi_port_io.rid.eq(axi_port.r.id), ] # FIFO --------------------------------------------------------------------------------- elif port["type"] == "fifo": platform.add_extension( get_fifo_user_port_ios(name, user_port.data_width)) _user_fifo_io = platform.request("user_fifo_{}".format(name)) fifo = LiteDRAMFIFO( data_width=user_port.data_width, base=port["base"], depth=port["depth"], write_port=self.sdram.crossbar.get_port("write"), write_threshold=port["depth"] - 32, # FIXME read_port=self.sdram.crossbar.get_port("read"), read_threshold=32 # FIXME ) self.submodules += fifo self.comb += [ # in fifo.sink.valid.eq(_user_fifo_io.in_valid), _user_fifo_io.in_ready.eq(fifo.sink.ready), fifo.sink.data.eq(_user_fifo_io.in_data), # out _user_fifo_io.out_valid.eq(fifo.source.valid), fifo.source.ready.eq(_user_fifo_io.out_ready), _user_fifo_io.out_data.eq(fifo.source.data), ] else: raise ValueError("Unsupported port type: {}".format( port["type"]))
def __init__(self, init_memories=False, sdram_module="MT48LC16M16", sdram_data_width=32, sdram_verbosity=0, with_ethernet=False): platform = Platform() sys_clk_freq = int(1e6) ram_init = [] if init_memories: ram_init = get_mem_data( { "images/Image": "0x00000000", "images/rv32.dtb": "0x00ef0000", "images/rootfs.cpio": "0x01000000", "images/opensbi.bin": "0x00f00000" }, "little") # CRG -------------------------------------------------------------------------------------- self.submodules.crg = CRG(platform.request("sys_clk")) # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, cpu_type="vexriscv_smp", cpu_variant="linux", csr_data_width=8, integrated_rom_size=0x8000, uart_name="sim") self.add_constant("SIM") self.add_constant("config_cpu_count", VexRiscvSMP.cpu_count) # for dts generation # Add linker region for OpenSBI self.add_memory_region("opensbi", self.mem_map["main_ram"] + 0x00f00000, 0x80000, type="cached+linker") self.add_constant("ROM_BOOT_ADDRESS", self.bus.regions["opensbi"].origin) # PLIC ------------------------------------------------------------------------------------ self.bus.add_slave("plic", self.cpu.plicbus, region=SoCRegion(origin=0xf0c00000, size=0x400000, cached=False)) # CLINT ------------------------------------------------------------------------------------ self.bus.add_slave("clint", self.cpu.cbus, region=SoCRegion(origin=0xf0010000, size=0x10000, cached=False)) # Supervisor ------------------------------------------------------------------------------- self.submodules.supervisor = Supervisor() self.add_csr("supervisor") # SDRAM ------------------------------------------------------------------------------------ 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, verbosity=sdram_verbosity, init=ram_init) self.add_sdram("sdram", phy=self.sdrphy, module=sdram_module, origin=self.mem_map["main_ram"], l2_cache_size=0) self.add_constant( "SDRAM_TEST_DISABLE" ) # Skip SDRAM test to avoid corrupting pre-initialized contents. # Ethernet --------------------------------------------------------------------------------- if with_ethernet: # eth phy self.submodules.ethphy = LiteEthPHYModel( self.platform.request("eth", 0)) self.add_csr("ethphy") # eth mac ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) self.submodules.ethmac = ethmac self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) self.add_csr("ethmac") self.add_interrupt("ethmac")
def __init__(self, init_memories=False, with_sdram=False, sdram_module="MT48LC16M16", sdram_data_width=32, sdram_verbosity=0, with_ethernet=False): platform = Platform() sys_clk_freq = int(1e6) ram_init = [] if init_memories: ram_init = get_mem_data( { "buildroot/Image": "0x00000000", "buildroot/rootfs.cpio": "0x00800000", "buildroot/rv32.dtb": "0x01000000", "emulator/emulator.bin": "0x01100000", }, "little") # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__( self, platform, clk_freq=sys_clk_freq, cpu_type="vexriscv", cpu_variant="linux", uart_name="sim", l2_reverse=False, max_sdram_size=0x10000000, # Limit mapped SDRAM to 1GB. integrated_rom_size=0x8000, integrated_main_ram_size=0x00000000 if with_sdram else 0x02000000, # 32MB integrated_main_ram_init=[] if (with_sdram or not init_memories) else ram_init) self.add_constant("SIM", None) # Supervisor ------------------------------------------------------------------------------- self.submodules.supervisor = Supervisor() self.add_csr("supervisor") # CRG -------------------------------------------------------------------------------------- self.submodules.crg = CRG(platform.request("sys_clk")) # Machine mode emulator RAM ---------------------------------------------------------------- self.add_memory_region("emulator", self.mem_map["main_ram"] + 0x01100000, 0x4000, type="cached+linker") self.add_constant("ROM_BOOT_ADDRESS", self.bus.regions["emulator"].origin) # SDRAM ------------------------------------------------------------------------------------ if with_sdram: 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, verbosity=sdram_verbosity, init=ram_init) self.add_sdram( "sdram", phy=self.sdrphy, module=sdram_module, origin=self.mem_map["main_ram"], size=0x10000000, # Limit mapped SDRAM to 1GB. l2_cache_reverse=False) # FIXME: skip memtest to avoid corrupting memory self.add_constant("MEMTEST_BUS_SIZE", 0) self.add_constant("MEMTEST_ADDR_SIZE", 0) self.add_constant("MEMTEST_DATA_SIZE", 0) # Ethernet --------------------------------------------------------------------------------- if with_ethernet: # eth phy self.submodules.ethphy = LiteEthPHYModel( self.platform.request("eth", 0)) self.add_csr("ethphy") # eth mac ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) self.submodules.ethmac = ethmac self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) self.add_csr("ethmac") self.add_interrupt("ethmac")
def __init__(self, cpu_count, init_memories=False, with_sdcard=False): # Cluster configs --------------------------------------------------------------------- VexRiscvSMP.litedram_width = 128 VexRiscvSMP.ibus_width = 64 VexRiscvSMP.dbus_width = 64 VexRiscvSMP.coherent_dma = with_sdcard # ------------------------------------------------------------------------------------------- platform = Platform() sys_clk_freq = int(1e6) sdram_init = [] if init_memories: sdram_init = get_mem_data( { "images/fw_jump.bin": "0x00f00000", "images/Image": "0x00000000", "images/dtb": "0x00ef0000", "images/rootfs.cpio": "0x01000000", }, "little") # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, cpu_type="vexriscv", cpu_variant="default", cpu_cls=VexRiscvSMP, uart_name="sim", integrated_rom_size=0x10000, integrated_main_ram_size=0x00000000) self.platform.name = "sim" self.add_constant("SIM") self.add_constant("config_cpu_count", cpu_count) # for dts generation # PLIC ------------------------------------------------------------------------------------ self.bus.add_slave("plic", self.cpu.plicbus, region=SoCRegion(origin=0xf0C00000, size=0x400000, cached=False)) interrupt_map = { **SoCCore.interrupt_map, **{ "uart": 1, } } # CLINT ------------------------------------------------------------------------------------ self.bus.add_slave("clint", self.cpu.cbus, region=SoCRegion(origin=0xf0010000, size=0x10000, cached=False)) # CRG -------------------------------------------------------------------------------------- self.submodules.crg = CRG(platform.request("sys_clk")) # SDRAM ------------------------------------------------------------------------------------ phy_settings = get_sdram_phy_settings(memtype="DDR3", data_width=16, clk_freq=100e6) self.submodules.sdrphy = SDRAMPHYModel(module=MT41K128M16( 100e6, "1:4"), settings=phy_settings, clk_freq=100e6, init=sdram_init) self.add_sdram( "sdram", phy=self.sdrphy, module=MT41K128M16(100e6, "1:4"), origin=self.mem_map["main_ram"], controller_settings=ControllerSettings(cmd_buffer_buffered=False, with_auto_precharge=True)) if init_memories: self.add_constant("MEMTEST_BUS_SIZE", 0) # Skip test if memory is initialized to avoid self.add_constant("MEMTEST_ADDR_SIZE", 0) # corrumpting the content. self.add_constant("MEMTEST_DATA_SIZE", 0) self.add_constant("ROM_BOOT_ADDRESS", 0x40f00000) # Jump to fw_jump.bin else: self.add_constant("MEMTEST_BUS_SIZE", 4096) self.add_constant("MEMTEST_ADDR_SIZE", 4096) self.add_constant("MEMTEST_DATA_SIZE", 4096) # SDCard ----------------------------------------------------------------------------------- if with_sdcard: self.add_sdcard("sdcard", use_emulator=True)
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), ]
def __init__(self, toolchain="vivado", sys_clk_freq=int(100e6), args=None, ip_address="192.168.100.50", mac_address=0x10e2d5000001, udp_port=1234, **kwargs): if not args.sim: platform = arty.Platform(toolchain=toolchain) else: platform = SimPlatform("SIM", _io) # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Arty A7", ident_version=True, **kwargs) # CRG -------------------------------------------------------------------------------------- if not args.sim: self.submodules.crg = _CRG(platform, sys_clk_freq, args) else: self.submodules.crg = CRG(platform.request("sys_clk")) # DDR3 SDRAM ------------------------------------------------------------------------------- if not args.sim: self.submodules.ddrphy = s7ddrphy.A7DDRPHY( platform.request("ddram"), memtype="DDR3", nphases=4, sys_clk_freq=sys_clk_freq) else: from litedram.gen import get_dram_ios core_config = dict() core_config["sdram_module_nb"] = 2 # Number of byte groups core_config["sdram_rank_nb"] = 1 # Number of ranks core_config['sdram_module'] = getattr(litedram_modules, 'MT41K128M16') core_config["memtype"] = "DDR3" # DRAM type platform.add_extension(get_dram_ios(core_config)) sdram_module = core_config["sdram_module"]( sys_clk_freq, rate={ "DDR2": "1:2", "DDR3": "1:4", "DDR4": "1:4" }[core_config["memtype"]]) from litex.tools.litex_sim import get_sdram_phy_settings sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings phy_settings = get_sdram_phy_settings( memtype=sdram_module.memtype, data_width=core_config["sdram_module_nb"] * 8, clk_freq=sdram_clk_freq) self.submodules.ddrphy = SDRAMPHYModel( module=sdram_module, settings=phy_settings, clk_freq=sdram_clk_freq, verbosity=3, ) class ControllerDynamicSettings(Module, AutoCSR, AutoDoc): """Allows to change LiteDRAMController behaviour at runtime""" def __init__(self): self.refresh = CSRStorage( reset=1, description="Enable/disable Refresh commands sending") self.submodules.controller_settings = ControllerDynamicSettings() self.add_csr("controller_settings") controller_settings = ControllerSettings() controller_settings.with_auto_precharge = True controller_settings.with_refresh = self.controller_settings.refresh.storage self.add_csr("ddrphy") self.add_sdram( "sdram", phy=self.ddrphy, module=MT41K128M16(sys_clk_freq, "1:4"), origin=self.mem_map["main_ram"], size=kwargs.get("max_sdram_size", 0x40000000), l2_cache_size=0, l2_cache_min_data_width=0, #128 l2_cache_reverse=True, controller_settings=controller_settings) # Ethernet / Etherbone --------------------------------------------------------------------- if not args.sim: # Ethernet PHY (arty) self.submodules.ethphy = LiteEthPHYMII( clock_pads=self.platform.request("eth_clocks"), pads=self.platform.request("eth")) self.add_csr("ethphy") self.add_etherbone(phy=self.ethphy, ip_address=ip_address, mac_address=mac_address, udp_port=udp_port) else: # Ethernet PHY (simulation) self.submodules.ethphy = LiteEthPHYModel( self.platform.request("eth", 0)) # FIXME self.add_csr("ethphy") # Ethernet Core ethcore = LiteEthUDPIPCore(self.ethphy, ip_address=ip_address, mac_address=mac_address, clk_freq=sys_clk_freq) self.submodules.ethcore = ethcore # Etherbone self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp, udp_port, mode="master") self.add_wb_master(self.etherbone.wishbone.bus) # Leds ------------------------------------------------------------------------------------- self.submodules.leds = LedChaser(pads=platform.request_all("user_led"), sys_clk_freq=sys_clk_freq) self.add_csr("leds") if args.sim: self.comb += platform.trace.eq(1) # Rowhammer -------------------------------------------------------------------------------- self.submodules.rowhammer_dma = LiteDRAMDMAReader( self.sdram.crossbar.get_port()) self.submodules.rowhammer = RowHammerDMA(self.rowhammer_dma) self.add_csr("rowhammer") def add_xram(self, name, origin, mem, mode='rw'): from litex.soc.interconnect import wishbone from litex.soc.integration.soc import SoCRegion ram = wishbone.SRAM(mem, bus=wishbone.Interface(data_width=mem.width), read_only='w' not in mode) ram_bus = wishbone.Interface(data_width=self.bus.data_width) self.submodules += wishbone.Converter(ram_bus, ram.bus) region = SoCRegion(origin=origin, size=mem.width // 8 * mem.depth, mode=mode) self.bus.add_slave(name, ram_bus, region) self.check_if_exists(name) self.logger.info("RAM {} {} {}.".format( colorer(name), colorer("added", color="green"), self.bus.regions[name])) setattr(self.submodules, name, ram) # Bist ------------------------------------------------------------------------------------- if not args.no_memory_bist: # ------------------------------ writer ------------------------------------ dram_wr_port = self.sdram.crossbar.get_port() self.submodules.writer = Writer(dram_wr_port) self.add_csr('writer') # TODO: Rename as 'pattern_wr_w?' add_xram(self, name='pattern_w0', mem=self.writer.memory_w0, origin=0x20000000) add_xram(self, name='pattern_w1', mem=self.writer.memory_w1, origin=0x21000000) add_xram(self, name='pattern_w2', mem=self.writer.memory_w2, origin=0x22000000) add_xram(self, name='pattern_w3', mem=self.writer.memory_w3, origin=0x23000000) add_xram(self, name='pattern_adr', mem=self.writer.memory_adr, origin=0x24000000) # ----------------------------- reader ------------------------------------- dram_rd_port = self.sdram.crossbar.get_port() self.submodules.reader = Reader(dram_rd_port) self.add_csr('reader') add_xram(self, name='pattern_rd_w0', mem=self.reader.memory_w0, origin=0x30000000) add_xram(self, name='pattern_rd_w1', mem=self.reader.memory_w1, origin=0x31000000) add_xram(self, name='pattern_rd_w2', mem=self.reader.memory_w2, origin=0x32000000) add_xram(self, name='pattern_rd_w3', mem=self.reader.memory_w3, origin=0x33000000) add_xram(self, name='pattern_rd_adr', mem=self.reader.memory_adr, origin=0x34000000) # Payload executor ------------------------------------------------------------------------- if not args.no_payload_executor: # TODO: disconnect bus during payload execution phy_settings = self.sdram.controller.settings.phy scratchpad_width = phy_settings.dfi_databits * phy_settings.nphases scratchpad_size = 2**10 payload_mem = Memory(32, 2**10) scratchpad_mem = Memory(scratchpad_width, scratchpad_size // (scratchpad_width // 8)) self.specials += payload_mem, scratchpad_mem add_xram(self, name='payload', mem=payload_mem, origin=0x35000000) add_xram(self, name='scratchpad', mem=scratchpad_mem, origin=0x36000000, mode='r') self.submodules.payload_executor = PayloadExecutor( mem_payload=payload_mem, mem_scratchpad=scratchpad_mem, dfi=self.sdram.dfii.ext_dfi, dfi_sel=self.sdram.dfii.ext_dfi_sel, nranks=self.sdram.controller.settings.phy.nranks, bankbits=self.sdram.controller.settings.geom.bankbits, rowbits=self.sdram.controller.settings.geom.rowbits, colbits=self.sdram.controller.settings.geom.colbits, rdphase=self.sdram.controller.settings.phy.rdphase, ) self.payload_executor.add_csrs() self.add_csr('payload_executor')
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), ]
def __init__(self, toolchain="vivado", sys_clk_freq=int(100e6), args=None, ip_address="192.168.100.50", mac_address=0x10e2d5000001, udp_port=1234, **kwargs): if not args.sim: platform = arty.Platform(toolchain=toolchain) else: platform = Platform() # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Arty A7", ident_version=True, **kwargs) # CRG -------------------------------------------------------------------------------------- if not args.sim: self.submodules.crg = _CRG(platform, sys_clk_freq, args) else: self.submodules.crg = CRG(platform.request("sys_clk")) # DDR3 SDRAM ------------------------------------------------------------------------------- if not args.sim: self.submodules.ddrphy = s7ddrphy.A7DDRPHY( platform.request("ddram"), memtype="DDR3", nphases=4, sys_clk_freq=sys_clk_freq) else: from litedram.gen import get_dram_ios core_config = dict() core_config["sdram_module_nb"] = 2 # Number of byte groups core_config["sdram_rank_nb"] = 1 # Number of ranks core_config['sdram_module'] = getattr(litedram_modules, 'MT41K128M16') core_config["memtype"] = "DDR3" # DRAM type platform.add_extension(get_dram_ios(core_config)) sdram_module = core_config["sdram_module"]( sys_clk_freq, rate={ "DDR2": "1:2", "DDR3": "1:4", "DDR4": "1:4" }[core_config["memtype"]]) from litex.tools.litex_sim import get_sdram_phy_settings sdram_clk_freq = int(100e6) # FIXME: use 100MHz timings phy_settings = get_sdram_phy_settings( memtype=sdram_module.memtype, data_width=core_config["sdram_module_nb"] * 8, clk_freq=sdram_clk_freq) self.submodules.ddrphy = SDRAMPHYModel( module=sdram_module, settings=phy_settings, clk_freq=sdram_clk_freq, verbosity=3, ) class ControllerDynamicSettings(Module, AutoCSR, AutoDoc): """Allows to change LiteDRAMController behaviour at runtime""" def __init__(self): self.refresh = CSRStorage( reset=1, description="Enable/disable Refresh commands sending") self.submodules.controller_settings = ControllerDynamicSettings() self.add_csr("controller_settings") controller_settings = ControllerSettings() controller_settings.with_auto_precharge = True controller_settings.with_refresh = self.controller_settings.refresh.storage self.add_csr("ddrphy") self.add_sdram( "sdram", phy=self.ddrphy, module=MT41K128M16(sys_clk_freq, "1:4"), origin=self.mem_map["main_ram"], size=kwargs.get("max_sdram_size", 0x40000000), l2_cache_size=0, l2_cache_min_data_width=0, #128 l2_cache_reverse=True, controller_settings=controller_settings) # Ethernet / Etherbone --------------------------------------------------------------------- if not args.sim: # Ethernet PHY (arty) self.submodules.ethphy = LiteEthPHYMII( clock_pads=self.platform.request("eth_clocks"), pads=self.platform.request("eth")) self.add_csr("ethphy") self.add_etherbone(phy=self.ethphy, ip_address=ip_address, mac_address=mac_address, udp_port=udp_port) else: # Ethernet PHY (simulation) self.submodules.ethphy = LiteEthPHYModel( self.platform.request("eth", 0)) # FIXME self.add_csr("ethphy") # Ethernet Core ethcore = LiteEthUDPIPCore(self.ethphy, ip_address=ip_address, mac_address=mac_address, clk_freq=sys_clk_freq) self.submodules.ethcore = ethcore # Etherbone self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp, udp_port, mode="master") self.add_wb_master(self.etherbone.wishbone.bus) # Leds ------------------------------------------------------------------------------------- self.submodules.leds = LedChaser(pads=platform.request_all("user_led"), sys_clk_freq=sys_clk_freq) self.add_csr("leds") # Analyzer --------------------------------------------------------------------------------- # analyzer_signals = [ # self.bus.masters['master0'].stb, # self.bus.masters['master0'].cyc, # self.bus.masters['master0'].adr, # self.bus.masters['master0'].we, # self.bus.masters['master0'].ack, # self.bus.masters['master0'].sel, # self.bus.masters['master0'].dat_w, # self.bus.masters['master0'].dat_r, # ] # from litescope import LiteScopeAnalyzer # self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, # depth = 512, # clock_domain = "sys", # csr_csv = "analyzer.csv") # self.add_csr("analyzer") if args.sim: self.comb += platform.trace.eq(1) # Rowhammer -------------------------------------------------------------------------------- from litedram.frontend.dma import LiteDRAMDMAReader, LiteDRAMDMAWriter self.submodules.rowhammer_dma = LiteDRAMDMAReader( self.sdram.crossbar.get_port()) self.submodules.rowhammer = RowHammerDMA(self.rowhammer_dma) self.add_csr("rowhammer") # Bist ------------------------------------------------------------------------------------- if not args.no_memory_bist: from litedram.frontend.bist import LiteDRAMBISTGenerator, LiteDRAMBISTChecker def add_xram(self, name, origin, mem): from litex.soc.interconnect import wishbone from litex.soc.integration.soc import SoCRegion ram_bus = wishbone.Interface(data_width=self.bus.data_width) ram = wishbone.SRAM(mem, bus=ram_bus) self.bus.add_slave( name, ram.bus, SoCRegion(origin=origin, size=mem.width * mem.depth, mode='rw')) self.check_if_exists(name) self.logger.info("RAM {} {} {}.".format( colorer(name), colorer("added", color="green"), self.bus.regions[name])) setattr(self.submodules, name, ram) return # ------------------------------ writer ------------------------------------ memory_w0 = Memory(32, 1024) memory_w1 = Memory(32, 1024) memory_w2 = Memory(32, 1024) memory_w3 = Memory(32, 1024) memory_adr = Memory(32, 1024) add_xram(self, name='pattern_w0', mem=memory_w0, origin=0x20000000) add_xram(self, name='pattern_w1', mem=memory_w1, origin=0x21000000) add_xram(self, name='pattern_w2', mem=memory_w2, origin=0x22000000) add_xram(self, name='pattern_w3', mem=memory_w3, origin=0x23000000) add_xram(self, name='pattern_adr', mem=memory_adr, origin=0x24000000) class Writer(Module, AutoCSR): 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"))) dram_port = self.sdram.crossbar.get_port() w0_port = memory_w0.get_port() w1_port = memory_w1.get_port() w2_port = memory_w2.get_port() w3_port = memory_w3.get_port() adr_port = memory_adr.get_port() self.specials += w0_port, w1_port, w2_port, w3_port, adr_port self.submodules.writer = Writer(dram_port, w0_port, w1_port, w2_port, w3_port, adr_port) self.add_csr('writer') # ----------------------------- reader ------------------------------------- memory_rd_w0 = Memory(32, 1024) memory_rd_w1 = Memory(32, 1024) memory_rd_w2 = Memory(32, 1024) memory_rd_w3 = Memory(32, 1024) memory_rd_adr = Memory(32, 1024) add_xram(self, name='pattern_rd_w0', mem=memory_rd_w0, origin=0x30000000) add_xram(self, name='pattern_rd_w1', mem=memory_rd_w1, origin=0x31000000) add_xram(self, name='pattern_rd_w2', mem=memory_rd_w2, origin=0x32000000) add_xram(self, name='pattern_rd_w3', mem=memory_rd_w3, origin=0x33000000) add_xram(self, name='pattern_rd_adr', mem=memory_rd_adr, origin=0x34000000) class Reader(Module, AutoCSR): 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) self.pointer = CSRStatus(size=32) self.mem_base = CSRStorage(size=32) self.mem_mask = CSRStorage(size=32) self.data_mask = CSRStorage(size=32) # patterns dma = LiteDRAMDMAReader(dram_port, fifo_depth=1, fifo_buffered=False) 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), ] data_pattern = Signal(32 * 4) self.comb += [ dma.sink.address.eq(self.mem_base.storage + adr_port.dat_r + (cmd_counter & self.mem_mask.storage)), data_pattern.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), NextValue(self.pointer.status, 0xdeadbeef), NextState("WAIT"), )) fsm.act( "WAIT", If(cmd_counter >= self.count.storage, NextState("DONE")).Else(NextState("WR_ADR"))) fsm.act("WR_ADR", dma.sink.valid.eq(1), If(dma.sink.ready, NextState("RD_DATA"))) fsm.act( "RD_DATA", dma.source.ready.eq(1), If( dma.source.valid, NextValue(cmd_counter, cmd_counter + 1), If(dma.source.data != data_pattern, NextValue(self.pointer.status, cmd_counter)), NextState("WAIT"))) fsm.act("DONE", self.done.status.eq(1), If(self.reset.storage, NextState("IDLE"))) dram_rd_port = self.sdram.crossbar.get_port() w0_port = memory_rd_w0.get_port() w1_port = memory_rd_w1.get_port() w2_port = memory_rd_w2.get_port() w3_port = memory_rd_w3.get_port() adr_port = memory_rd_adr.get_port() self.specials += w0_port, w1_port, w2_port, w3_port, adr_port self.submodules.reader = Reader(dram_rd_port, w0_port, w1_port, w2_port, w3_port, adr_port) self.add_csr('reader')