def __init__(self): # phy sdram_module = SimModule(1000, "1:1") phy_settings = PhySettings(memtype="SDR", dfi_databits=1 * 16, nphases=1, rdphase=0, wrphase=0, rdcmdphase=0, wrcmdphase=0, cl=2, read_latency=4, write_latency=0) self.submodules.sdrphy = SDRAMPHYModel(sdram_module, phy_settings, we_granularity=0) # controller self.submodules.controller = LiteDRAMController( phy_settings, sdram_module.geom_settings, sdram_module.timing_settings, ControllerSettings(with_refresh=False)) self.comb += self.controller.dfi.connect(self.sdrphy.dfi) self.submodules.crossbar = LiteDRAMCrossbar(self.controller.interface, self.controller.nrowbits) # ports write_user_port = self.crossbar.get_port("write", cd="write") read_user_port = self.crossbar.get_port("read", cd="read") # generator / checker self.submodules.generator = _LiteDRAMBISTGenerator( write_user_port, True) self.submodules.checker = _LiteDRAMBISTChecker(read_user_port, True)
def __init__(self): self.write_port = LiteDRAMNativeWritePort(address_width=32, data_width=32) self.read_port = LiteDRAMNativeReadPort(address_width=32, data_width=32) self.submodules.generator = _LiteDRAMBISTGenerator( self.write_port) self.submodules.checker = _LiteDRAMBISTChecker(self.read_port)
def __init__(self): self.read_port = LiteDRAMNativeReadPort(address_width=32, data_width=data_width) if pattern is not None: self.submodules.checker = _LiteDRAMPatternChecker( self.read_port, init=pattern) else: self.submodules.checker = _LiteDRAMBISTChecker( self.read_port) self.mem = DRAMMemory(data_width, len(memory), init=memory)
def __init__(self): self.write_port = LiteDRAMWritePort(aw=32, dw=32) self.read_port = LiteDRAMReadPort(aw=32, dw=32) self.submodules.generator = _LiteDRAMBISTGenerator(self.write_port, True) self.submodules.checker = _LiteDRAMBISTChecker(self.read_port, True)
def __init__(self, mode="bist", sdram_module="MT48LC16M16", sdram_data_width=32, bist_base=0x0000000, bist_end=0x0100000, bist_length=1024, bist_random=False, bist_alternating=False, num_generators=1, num_checkers=1, access_pattern=None, **kwargs): assert mode in ["bist", "pattern"] assert not (mode == "pattern" and access_pattern is None) # SimSoC ----------------------------------------------------------------------------------- SimSoC.__init__(self, with_sdram=True, sdram_module=sdram_module, sdram_data_width=sdram_data_width, **kwargs) # BIST/Pattern Generator / Checker --------------------------------------------------------- if mode == "pattern": make_generator = lambda: _LiteDRAMPatternGenerator( self.sdram.crossbar.get_port(), init=access_pattern) make_checker = lambda: _LiteDRAMPatternChecker( self.sdram.crossbar.get_port(), init=access_pattern) if mode == "bist": make_generator = lambda: _LiteDRAMBISTGenerator(self.sdram.crossbar .get_port()) make_checker = lambda: _LiteDRAMBISTChecker(self.sdram.crossbar. get_port()) generators = [make_generator() for _ in range(num_generators)] checkers = [make_checker() for _ in range(num_checkers)] self.submodules += generators + checkers if mode == "pattern": def bist_config(module): return [] if not bist_alternating: address_set = set() for addr, _ in access_pattern: assert addr not in address_set, \ "Duplicate address 0x%08x in access_pattern, write will overwrite previous value!" % addr address_set.add(addr) if mode == "bist": # Make sure that we perform at least one access bist_length = max(bist_length, self.sdram.controller.interface.data_width // 8) def bist_config(module): return [ module.base.eq(bist_base), module.end.eq(bist_end), module.length.eq(bist_length), module.random_addr.eq(bist_random), ] assert not (bist_random and not bist_alternating), \ "Write to random address may overwrite previously written data before reading!" # Check address correctness assert bist_end > bist_base assert bist_end <= 2**(len( generators[0].end)) - 1, "End address outside of range" bist_addr_range = bist_end - bist_base assert bist_addr_range > 0 and bist_addr_range & (bist_addr_range - 1) == 0, \ "Length of the address range must be a power of 2" def combined_read(modules, signal, operator): sig = Signal() self.comb += sig.eq( reduce(operator, (getattr(m, signal) for m in modules))) return sig def combined_write(modules, signal): sig = Signal() self.comb += [getattr(m, signal).eq(sig) for m in modules] return sig # Sequencer -------------------------------------------------------------------------------- class LiteDRAMCoreControl(Module, AutoCSR): def __init__(self): self.init_done = CSRStorage() self.init_error = CSRStorage() self.submodules.ddrctrl = ddrctrl = LiteDRAMCoreControl() self.add_csr("ddrctrl") display = Signal() finish = Signal() self.submodules.fsm = fsm = FSM(reset_state="WAIT-INIT") fsm.act( "WAIT-INIT", If( self.ddrctrl.init_done. storage, # Written by CPU when initialization is done NextState("BIST-GENERATOR"))) if bist_alternating: # Force generators to wait for checkers and vice versa. Connect them in pairs, with each # unpaired connected to the first of the others. bist_connections = [] for generator, checker in zip_longest(generators, checkers): g = generator or generators[0] c = checker or checkers[0] bist_connections += [ g.run_cascade_in.eq(c.run_cascade_out), c.run_cascade_in.eq(g.run_cascade_out), ] fsm.act( "BIST-GENERATOR", combined_write(generators + checkers, "start").eq(1), *bist_connections, *map(bist_config, generators + checkers), If(combined_read(checkers, "done", and_), NextState("DISPLAY"))) else: fsm.act( "BIST-GENERATOR", combined_write(generators, "start").eq(1), *map(bist_config, generators), If(combined_read(generators, "done", and_), NextState("BIST-CHECKER"))) fsm.act( "BIST-CHECKER", combined_write(checkers, "start").eq(1), *map(bist_config, checkers), If(combined_read(checkers, "done", and_), NextState("DISPLAY"))) fsm.act("DISPLAY", display.eq(1), NextState("FINISH")) fsm.act("FINISH", finish.eq(1)) # Simulation Results ----------------------------------------------------------------------- def max_signal(signals): signals = iter(signals) s = next(signals) out = Signal(len(s)) self.comb += out.eq(s) for curr in signals: prev = out out = Signal(max(len(prev), len(curr))) self.comb += If(prev > curr, out.eq(prev)).Else(out.eq(curr)) return out generator_ticks = max_signal((g.ticks for g in generators)) checker_errors = max_signal((c.errors for c in checkers)) checker_ticks = max_signal((c.ticks for c in checkers)) self.sync += [ If( display, Display("BIST-GENERATOR ticks: %08d", generator_ticks), Display("BIST-CHECKER errors: %08d", checker_errors), Display("BIST-CHECKER ticks: %08d", checker_ticks), ) ] # Simulation End --------------------------------------------------------------------------- end_timer = WaitTimer(2**16) self.submodules += end_timer self.comb += end_timer.wait.eq(finish) self.sync += If(end_timer.done, Finish())
def __init__(self, platform): self.clock_domains.cd_sys = ClockDomain() # sdram parameters sdram_aw = 24 sdram_dw = 128 # sdram bist sdram_generator_port = LiteDRAMNativePort("both", sdram_aw, sdram_dw, id=0) self.submodules.sdram_generator = _LiteDRAMBISTGenerator(sdram_generator_port) sdram_checker_port = LiteDRAMNativePort("both", sdram_aw, sdram_dw, id=1) self.submodules.sdram_checker = _LiteDRAMBISTChecker(sdram_checker_port) # micron model ddram_a = Signal(14) ddram_ba = Signal(3) ddram_ras_n = Signal() ddram_cas_n = Signal() ddram_we_n = Signal() ddram_cs_n = Signal() ddram_dm = Signal(2) ddram_dq = Signal(16) ddram_dqs_p = Signal(2) ddram_dqs_n = Signal(2) ddram_clk_p = Signal() ddram_clk_n = Signal() ddram_cke = Signal() ddram_odt = Signal() ddram_reset_n = Signal() self.specials += Instance("ddr3", i_rst_n=ddram_reset_n, i_ck=ddram_clk_p, i_ck_n=ddram_clk_n, i_cke=ddram_cke, i_cs_n=ddram_cs_n, i_ras_n=ddram_ras_n, i_cas_n=ddram_cas_n, i_we_n=ddram_we_n, io_dm_tdqs=ddram_dm, i_ba=ddram_ba, i_addr=ddram_a, io_dq=ddram_dq, io_dqs=ddram_dqs_p, io_dqs_n=ddram_dqs_n, #o_tdqs_n=, i_odt=ddram_odt ) # LiteDRAM standalone core instance init_done = Signal() init_error = Signal() self.specials += Instance("litedram_core", # clk / reset input i_clk=platform.request("clk"), i_rst=platform.request("rst"), # dram pins o_ddram_a=ddram_a, o_ddram_ba=ddram_ba, o_ddram_ras_n=ddram_ras_n, o_ddram_cas_n=ddram_cas_n, o_ddram_we_n=ddram_we_n, o_ddram_cs_n=ddram_cs_n, o_ddram_dm=ddram_dm, io_ddram_dq=ddram_dq, o_ddram_dqs_p=ddram_dqs_p, o_ddram_dqs_n=ddram_dqs_n, o_ddram_clk_p=ddram_clk_p, o_ddram_clk_n=ddram_clk_n, o_ddram_cke=ddram_cke, o_ddram_odt=ddram_odt, o_ddram_reset_n=ddram_reset_n, # dram init o_init_done=init_done, o_init_error=init_error, # user clk / reset o_user_clk=self.cd_sys.clk, o_user_rst=self.cd_sys.rst, # user port 0 # cmd i_user_port0_cmd_valid=sdram_generator_port.cmd.valid, o_user_port0_cmd_ready=sdram_generator_port.cmd.ready, i_user_port0_cmd_we=sdram_generator_port.cmd.we, i_user_port0_cmd_addr=sdram_generator_port.cmd.addr, # wdata i_user_port0_wdata_valid=sdram_generator_port.wdata.valid, o_user_port0_wdata_ready=sdram_generator_port.wdata.ready, i_user_port0_wdata_we=sdram_generator_port.wdata.we, i_user_port0_wdata_data=sdram_generator_port.wdata.data, # rdata o_user_port0_rdata_valid=sdram_generator_port.rdata.valid, i_user_port0_rdata_ready=sdram_generator_port.rdata.ready, o_user_port0_rdata_data=sdram_generator_port.rdata.data, # user port 1 # cmd i_user_port1_cmd_valid=sdram_checker_port.cmd.valid, o_user_port1_cmd_ready=sdram_checker_port.cmd.ready, i_user_port1_cmd_we=sdram_checker_port.cmd.we, i_user_port1_cmd_addr=sdram_checker_port.cmd.addr, # wdata i_user_port1_wdata_valid=sdram_checker_port.wdata.valid, o_user_port1_wdata_ready=sdram_checker_port.wdata.ready, i_user_port1_wdata_we=sdram_checker_port.wdata.we, i_user_port1_wdata_data=sdram_checker_port.wdata.data, # rdata o_user_port1_rdata_valid=sdram_checker_port.rdata.valid, i_user_port1_rdata_ready=sdram_checker_port.rdata.ready, o_user_port1_rdata_data=sdram_checker_port.rdata.data ) # test self.comb += [ self.sdram_generator.base.eq(0x00000000), self.sdram_generator.length.eq(0x00000100), self.sdram_checker.base.eq(0x00000000), self.sdram_checker.length.eq(0x00000100), ] self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", If(init_done, NextState("GENERATOR_START") ) ) fsm.act("GENERATOR_START", self.sdram_generator.start.eq(1), NextState("GENERATOR_WAIT") ) fsm.act("GENERATOR_WAIT", If(self.sdram_generator.done, NextState("CHECKER_START") ) ) fsm.act("CHECKER_START", self.sdram_checker.start.eq(1), NextState("CHECKER_WAIT") ) fsm.act("CHECKER_WAIT", If(self.sdram_checker.done, NextState("DONE") ) ) fsm.act("DONE")