def test_MT8KTF51264(self): kwargs = dict(clk_freq=100e6, rate="1:4") module_ref = litedram.modules.MT8KTF51264(**kwargs) with self.subTest(speedgrade="-1G4"): data = load_spd_reference("MT8KTF51264HZ-1G4E1.csv") module = SDRAMModule.from_spd_data(data, kwargs["clk_freq"]) self.compare_modules(module, module_ref) sgt = module.speedgrade_timings["1333"] self.assertEqual(sgt.tRP, 13.125) self.assertEqual(sgt.tRCD, 13.125) self.assertEqual(sgt.tRP + sgt.tRAS, 49.125) with self.subTest(speedgrade="-1G6"): data = load_spd_reference("MT8KTF51264HZ-1G6E1.csv") module = SDRAMModule.from_spd_data(data, kwargs["clk_freq"]) self.compare_modules(module, module_ref) sgt = module.speedgrade_timings["1600"] self.assertEqual(sgt.tRP, 13.125) self.assertEqual(sgt.tRCD, 13.125) self.assertEqual(sgt.tRP + sgt.tRAS, 48.125) with self.subTest(speedgrade="-1G9"): data = load_spd_reference("MT8KTF51264HZ-1G9P1.csv") module = SDRAMModule.from_spd_data(data, kwargs["clk_freq"]) # tRRD different for this timing self.compare_modules(module, module_ref, omit={"tRRD"}) self.assertEqual(module.technology_timings.tRRD, (4, 5)) sgt = module.speedgrade_timings["1866"] self.assertEqual(sgt.tRP, 13.125) self.assertEqual(sgt.tRCD, 13.125) self.assertEqual(sgt.tRP + sgt.tRAS, 47.125)
def show_module(spd_data, clk_freq): module = SDRAMModule.from_spd_data(spd_data, clk_freq=clk_freq) dump_object(module) dump_object(module.__class__, header=False) dump_object(module.technology_timings) dump_object(module.speedgrade_timings['default']) dump_object(module.geom_settings) dump_object(module.timing_settings)
def test_MTA4ATF51264HZ_parsing(self): kwargs = dict(clk_freq=100e6, rate="1:4") with self.subTest(speedgrade="-2G3"): data = load_spd_reference("MTA4ATF51264HZ-2G3B1.csv") module = SDRAMModule.from_spd_data(data, kwargs["clk_freq"]) sgt = module.speedgrade_timings["2400"] self.assertEqual(sgt.tRP, 13.75) self.assertEqual(sgt.tRCD, 13.75) self.assertEqual(sgt.tRP + sgt.tRAS, 45.75) with self.subTest(speedgrade="-3G2"): data = load_spd_reference("MTA4ATF51264HZ-3G2E1.csv") module = SDRAMModule.from_spd_data(data, kwargs["clk_freq"]) sgt = module.speedgrade_timings["3200"] self.assertEqual(sgt.tRP, 13.75) self.assertEqual(sgt.tRCD, 13.75) self.assertEqual(sgt.tRP + sgt.tRAS, 45.75)
def test_MT8JTF12864(self): kwargs = dict(clk_freq=125e6, rate="1:4") module_ref = litedram.modules.MT8JTF12864(**kwargs) data = load_spd_reference("MT8JTF12864AZ-1G4G1.csv") module = SDRAMModule.from_spd_data(data, kwargs["clk_freq"]) self.compare_modules(module, module_ref) sgt = module.speedgrade_timings["1333"] self.assertEqual(sgt.tRP, 13.125) self.assertEqual(sgt.tRCD, 13.125) self.assertEqual(sgt.tRP + sgt.tRAS, 49.125)
def test_MT18KSF1G72HZ(self): kwargs = dict(clk_freq=125e6, rate="1:4") module_ref = litedram.modules.MT18KSF1G72HZ(**kwargs) with self.subTest(speedgrade="-1G6"): data = load_spd_reference("MT18KSF1G72HZ-1G6E2.csv") module = SDRAMModule.from_spd_data(data, kwargs["clk_freq"]) self.compare_modules(module, module_ref) sgt = module.speedgrade_timings["1600"] self.assertEqual(sgt.tRP, 13.125) self.assertEqual(sgt.tRCD, 13.125) self.assertEqual(sgt.tRP + sgt.tRAS, 48.125) with self.subTest(speedgrade="-1G4"): data = load_spd_reference("MT18KSF1G72HZ-1G4E2.csv") module = SDRAMModule.from_spd_data(data, kwargs["clk_freq"]) self.compare_modules(module, module_ref) sgt = module.speedgrade_timings["1333"] self.assertEqual(sgt.tRP, 13.125) self.assertEqual(sgt.tRCD, 13.125) self.assertEqual(sgt.tRP + sgt.tRAS, 49.125)
def __init__(self, sys_clk_freq=int(125e6), with_ethernet=False, with_etherbone=False, with_rts_reset=False, with_led_chaser=True, spd_dump=None, **kwargs): platform = berkeleylab_marble.Platform() # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Berkeley-Lab Marble", **kwargs) # CRG, resettable over USB serial RTS signal ----------------------------------------------- resets = [] if with_rts_reset: ser_pads = platform.lookup_request('serial') resets.append(ser_pads.rts) self.submodules.crg = _CRG(platform, sys_clk_freq, resets) # DDR3 SDRAM ------------------------------------------------------------------------------- if not self.integrated_main_ram_size: self.submodules.ddrphy = s7ddrphy.K7DDRPHY( platform.request("ddram"), memtype="DDR3", nphases=4, sys_clk_freq=sys_clk_freq) if spd_dump is not None: ram_spd = parse_spd_hexdump(spd_dump) ram_module = SDRAMModule.from_spd_data(ram_spd, sys_clk_freq) print('DDR3: loaded config from', spd_dump) else: ram_module = MT8JTF12864(sys_clk_freq, "1:4") # KC705 chip, 1 GB print( 'DDR3: No spd data specified, falling back to MT8JTF12864') self.add_sdram( "sdram", phy=self.ddrphy, module=ram_module, # size=0x40000000, # Limit its size to 1 GB l2_cache_size=kwargs.get("l2_size", 8192), with_bist=kwargs.get("with_bist", False)) # Ethernet --------------------------------------------------------------------------------- if with_ethernet or with_etherbone: self.submodules.ethphy = LiteEthPHYRGMII( clock_pads=self.platform.request("eth_clocks"), pads=self.platform.request("eth"), tx_delay=0) if with_ethernet: self.add_ethernet(phy=self.ethphy, dynamic_ip=True, software_debug=False) if with_etherbone: self.add_etherbone(phy=self.ethphy, buffer_depth=255) # System I2C (behing multiplexer) ---------------------------------------------------------- i2c_pads = platform.request('i2c_fpga') self.submodules.i2c = I2CMaster(i2c_pads) # Leds ------------------------------------------------------------------------------------- if with_led_chaser: self.submodules.leds = LedChaser( pads=platform.request_all("user_led"), sys_clk_freq=sys_clk_freq)
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 test_spd_data(self): # Verify that correct _spd_data is added to SDRAMModule data = load_spd_reference("MT16KTF1G64HZ-1G6P1.csv") module = SDRAMModule.from_spd_data(data, 125e6) self.assertEqual(module._spd_data, data)
print('{:3} s'.format(args.mem_timeout - i - 1), end=' \r', flush=True) # print('.', end='', flush=True) if wb.regs.ddrctrl_init_done.read(): print('Ready ', end=' \r', flush=True) break print() time.sleep(2) wb.close() output = read_spd(console, spd_addr, init_commands) spd_data = list(parse_hexdump(output)) with open(args.output_file, 'wb') as f: f.write(bytes(spd_data)) print('SPD saved to file: {}'.format(args.output_file)) elif args.cmd == 'show': with open(args.input_file, 'rb') as f: spd_data = f.read() clk_freq = float(args.clk_freq) module = SDRAMModule.from_spd_data(spd_data, clk_freq=clk_freq) dump_object(module) dump_object(module.__class__, header=False) dump_object(module.technology_timings) dump_object(module.speedgrade_timings['default']) dump_object(module.geom_settings) dump_object(module.timing_settings) else: parser.print_usage()