Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
 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)
Exemplo n.º 4
0
 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)
Exemplo n.º 5
0
    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())
Exemplo n.º 6
0
    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")