Пример #1
0
 def add_adapter(self, name, interface):
     if interface.data_width != self.data_width:
         self.logger.info("{} Bus {} from {}-bit to {}-bit.".format(
             colorer(name), colorer("converted", color="cyan"),
             colorer(interface.data_width), colorer(self.data_width)))
         new_interface = wishbone.Interface(data_width=self.data_width)
         self.submodules += wishbone.Converter(interface, new_interface)
         return new_interface
     else:
         return interface
Пример #2
0
 def add_memory(self, mem, *, name, origin, mode='rw'):
     ram = wishbone.SRAM(mem,
                         bus=wishbone.Interface(data_width=mem.width),
                         read_only='w' not in mode)
     # Perform bus width conversion
     ram_bus = wishbone.Interface(data_width=self.bus.data_width)
     self.submodules += wishbone.Converter(ram_bus, ram.bus)
     # Add memory region
     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)
Пример #3
0
 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)
Пример #4
0
    def __init__(
            self,
            platform,
            clk_freq,
            # CPU parameters
            cpu_type="vexriscv",
            cpu_reset_address=0x00000000,
            cpu_variant=None,
            # ROM parameters
            integrated_rom_size=0,
            integrated_rom_init=[],
            # SRAM parameters
            integrated_sram_size=4096,
            integrated_sram_init=[],
            # MAIN_RAM parameters
            integrated_main_ram_size=0,
            integrated_main_ram_init=[],
            # CSR parameters
            csr_data_width=8,
            csr_alignment=32,
            csr_address_width=14,
            # Identifier parameters
            ident="",
            ident_version=False,
            # UART parameters
            with_uart=True,
            uart_name="serial",
            uart_baudrate=115200,
            uart_stub=False,
            # Timer parameters
            with_timer=True,
            # Controller parameters
            with_ctrl=True,
            # Wishbone parameters
            with_wishbone=True,
            wishbone_timeout_cycles=1e6,
            **kwargs):
        self.platform = platform
        self.clk_freq = clk_freq

        # SoC's CSR/Mem/Interrupt mapping (default or user defined + dynamically allocateds)
        self.soc_csr_map = {}
        self.soc_interrupt_map = {}
        self.soc_mem_map = self.mem_map
        self.soc_io_regions = self.io_regions

        # SoC's Config/Constants/Regions
        self.config = {}
        self.constants = {}
        self.mem_regions = {}
        self.csr_regions = {}

        # Wishbone masters/slaves lists
        self._wb_masters = []
        self._wb_slaves = []

        # CSR masters list
        self._csr_masters = []

        self.add_retro_compat(kwargs)

        # Parameters managment ---------------------------------------------------------------------
        if cpu_type == "None":
            cpu_type = None

        if not with_wishbone:
            self.soc_mem_map["csr"] = 0x00000000

        self.cpu_type = cpu_type
        self.cpu_variant = cpu.check_format_cpu_variant(cpu_variant)

        self.integrated_rom_size = integrated_rom_size
        self.integrated_rom_initialized = integrated_rom_init != []
        self.integrated_sram_size = integrated_sram_size
        self.integrated_main_ram_size = integrated_main_ram_size

        assert csr_data_width in [8, 32, 64]
        assert 2**(csr_address_width + 2) <= 0x1000000
        self.csr_data_width = csr_data_width
        self.csr_address_width = csr_address_width

        self.with_ctrl = with_ctrl

        self.with_uart = with_uart
        self.uart_baudrate = uart_baudrate

        self.with_wishbone = with_wishbone
        self.wishbone_timeout_cycles = wishbone_timeout_cycles

        # Modules instances ------------------------------------------------------------------------

        # Add user's CSRs (needs to be done before the first dynamic allocation)
        for _name, _id in self.csr_map.items():
            self.add_csr(_name, _id)

        # Add SoCController
        if with_ctrl:
            self.submodules.ctrl = SoCController()
            self.add_csr("ctrl", allow_user_defined=True)

        # Add CPU
        self.config["CPU_TYPE"] = str(cpu_type).upper()
        if cpu_type is not None:
            if cpu_variant is not None:
                self.config["CPU_VARIANT"] = str(
                    cpu_variant.split('+')[0]).upper()
            # Check type
            if cpu_type not in cpu.CPUS.keys():
                raise ValueError("Unsupported CPU type: {}".format(cpu_type))
            # Add the CPU
            self.add_cpu(cpu.CPUS[cpu_type](platform, self.cpu_variant))

            # Update Memory Map (if defined by CPU)
            self.soc_mem_map.update(self.cpu.mem_map)

            # Update IO Regions (if defined by CPU)
            self.soc_io_regions.update(self.cpu.io_regions)

            # Set reset address
            self.cpu.set_reset_address(
                self.soc_mem_map["rom"]
                if integrated_rom_size else cpu_reset_address)
            self.config["CPU_RESET_ADDR"] = self.cpu.reset_address

            # Add CPU buses as 32-bit Wishbone masters
            for cpu_bus in self.cpu.buses:
                assert cpu_bus.data_width in [32, 64, 128]
                soc_bus = wishbone.Interface(data_width=32)
                self.submodules += wishbone.Converter(cpu_bus, soc_bus)
                self.add_wb_master(soc_bus)

            # Add CPU CSR (dynamic)
            self.add_csr("cpu", allow_user_defined=True)

            # Add CPU interrupts
            for _name, _id in self.cpu.interrupts.items():
                self.add_interrupt(_name, _id)

            # Allow SoCController to reset the CPU
            if with_ctrl:
                self.comb += self.cpu.reset.eq(self.ctrl.reset)
        else:
            self.add_cpu(cpu.CPUNone())
            self.soc_io_regions.update(self.cpu.io_regions)

        # Add user's interrupts (needs to be done after CPU interrupts are allocated)
        for _name, _id in self.interrupt_map.items():
            self.add_interrupt(_name, _id)

        # Add integrated ROM
        if integrated_rom_size:
            self.submodules.rom = wishbone.SRAM(integrated_rom_size,
                                                read_only=True,
                                                init=integrated_rom_init)
            self.register_rom(self.rom.bus, integrated_rom_size)

        # Add integrated SRAM
        if integrated_sram_size:
            self.submodules.sram = wishbone.SRAM(integrated_sram_size,
                                                 init=integrated_sram_init)
            self.register_mem("sram", self.soc_mem_map["sram"], self.sram.bus,
                              integrated_sram_size)

        # Add integrated MAIN_RAM (only useful when no external SRAM/SDRAM is available)
        if integrated_main_ram_size:
            self.submodules.main_ram = wishbone.SRAM(
                integrated_main_ram_size, init=integrated_main_ram_init)
            self.register_mem("main_ram", self.soc_mem_map["main_ram"],
                              self.main_ram.bus, integrated_main_ram_size)

        # Add UART
        if with_uart:
            if uart_stub:
                self.submodules.uart = uart.UARTStub()
            else:
                if uart_name == "jtag_atlantic":
                    from litex.soc.cores.jtag import JTAGAtlantic
                    self.submodules.uart_phy = JTAGAtlantic()
                elif uart_name == "jtag_uart":
                    from litex.soc.cores.jtag import JTAGPHY
                    self.submodules.uart_phy = JTAGPHY(device=platform.device)
                else:
                    self.submodules.uart_phy = uart.UARTPHY(
                        platform.request(uart_name), clk_freq, uart_baudrate)
                self.submodules.uart = ResetInserter()(uart.UART(
                    self.uart_phy))
            self.add_csr("uart_phy", allow_user_defined=True)
            self.add_csr("uart", allow_user_defined=True)
            self.add_interrupt("uart", allow_user_defined=True)

        # Add Identifier
        if ident:
            if ident_version:
                ident = ident + " " + get_version()
            self.submodules.identifier = identifier.Identifier(ident)
            self.add_csr("identifier_mem", allow_user_defined=True)
        self.config["CLOCK_FREQUENCY"] = int(clk_freq)

        # Add Timer
        if with_timer:
            self.submodules.timer0 = timer.Timer()
            self.add_csr("timer0", allow_user_defined=True)
            self.add_interrupt("timer0", allow_user_defined=True)

        # Add Wishbone to CSR bridge
        csr_alignment = max(csr_alignment, self.cpu.data_width)
        self.config["CSR_DATA_WIDTH"] = csr_data_width
        self.config["CSR_ALIGNMENT"] = csr_alignment
        self.csr_data_width = csr_data_width
        self.csr_alignment = csr_alignment
        if with_wishbone:
            self.submodules.wishbone2csr = wishbone2csr.WB2CSR(
                bus_csr=csr_bus.Interface(address_width=csr_address_width,
                                          data_width=csr_data_width))
            self.add_csr_master(self.wishbone2csr.csr)
            self.register_mem("csr", self.soc_mem_map["csr"],
                              self.wishbone2csr.wishbone, 0x1000000)
Пример #5
0
    def register_sdram(self,
                       phy,
                       geom_settings,
                       timing_settings,
                       main_ram_size_limit=None,
                       **kwargs):
        assert not self._sdram_phy
        self._sdram_phy.append(
            phy)  # encapsulate in list to prevent CSR scanning

        # LiteDRAM core ----------------------------------------------------------------------------
        self.submodules.sdram = LiteDRAMCore(phy=phy,
                                             geom_settings=geom_settings,
                                             timing_settings=timing_settings,
                                             clk_freq=self.clk_freq,
                                             **kwargs)

        # LiteDRAM port ------------------------------------------------------------------------
        port = self.sdram.crossbar.get_port()
        port.data_width = 2**int(log2(
            port.data_width))  # Round to nearest power of 2

        # Main RAM size ------------------------------------------------------------------------
        main_ram_size = 2**(geom_settings.bankbits + geom_settings.rowbits +
                            geom_settings.colbits) * phy.settings.databits // 8
        if main_ram_size_limit is not None:
            main_ram_size = min(main_ram_size, main_ram_size_limit)

        # SoC [<--> L2 Cache] <--> LiteDRAM ----------------------------------------------------
        if self.cpu.name == "rocket":
            # Rocket has its own I/D L1 cache: connect directly to LiteDRAM, also bypassing MMIO/CSR wb bus:
            if port.data_width == self.cpu.mem_axi.data_width:
                # straightforward AXI link, no data_width conversion needed:
                self.submodules += LiteDRAMAXI2Native(
                    self.cpu.mem_axi,
                    port,
                    base_address=self.mem_map["main_ram"])
            else:
                # FIXME: replace WB data-width converter with native AXI converter!!!
                mem_wb = wishbone.Interface(
                    data_width=self.cpu.mem_axi.data_width,
                    adr_width=32 - log2_int(self.cpu.mem_axi.data_width // 8))
                # NOTE: AXI2Wishbone FSMs must be reset with the CPU!
                mem_a2w = ResetInserter()(AXI2Wishbone(self.cpu.mem_axi,
                                                       mem_wb,
                                                       base_address=0))
                self.comb += mem_a2w.reset.eq(ResetSignal() | self.cpu.reset)
                self.submodules += mem_a2w
                litedram_wb = wishbone.Interface(port.data_width)
                self.submodules += LiteDRAMWishbone2Native(
                    litedram_wb, port, base_address=self.mem_map["main_ram"])
                self.submodules += wishbone.Converter(mem_wb, litedram_wb)
            # Register main_ram region (so it will be added to generated/mem.h):
            self.add_memory_region("main_ram", self.mem_map["main_ram"],
                                   main_ram_size)
        elif self.with_wishbone:
            # Insert L2 cache inbetween Wishbone bus and LiteDRAM
            l2_size = max(self.l2_size,
                          int(2 * port.data_width /
                              8))  # L2 has a minimal size, use it if lower
            l2_size = 2**int(log2(l2_size))  # Round to nearest power of 2

            # SoC <--> L2 Cache Wishbone interface -------------------------------------------------
            wb_sdram = wishbone.Interface()
            self.add_wb_sdram_if(wb_sdram)
            self.register_mem("main_ram", self.mem_map["main_ram"], wb_sdram,
                              main_ram_size)

            # L2 Cache -----------------------------------------------------------------------------
            l2_cache = wishbone.Cache(l2_size // 4, self._wb_sdram,
                                      wishbone.Interface(port.data_width))
            # XXX Vivado ->2018.2 workaround, Vivado is not able to map correctly our L2 cache.
            # Issue is reported to Xilinx, Remove this if ever fixed by Xilinx...
            from litex.build.xilinx.vivado import XilinxVivadoToolchain
            if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
                from migen.fhdl.simplify import FullMemoryWE
                self.submodules.l2_cache = FullMemoryWE()(l2_cache)
            else:
                self.submodules.l2_cache = l2_cache
            self.config["L2_SIZE"] = l2_size

            # L2 Cache <--> LiteDRAM bridge --------------------------------------------------------
            self.submodules.wishbone_bridge = LiteDRAMWishbone2Native(
                self.l2_cache.slave, port)
Пример #6
0
    def __init__(self, platform, cpu_reset_addr, variant="standard"):
        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
        assert cpu_reset_addr == 0x10000000, "cpu_reset_addr hardcoded in Chisel elaboration!"

        self.platform = platform
        self.variant = variant
        self.reset = Signal()

        self.interrupt = Signal(4)

        self.mem_axi = mem_axi = axi.AXIInterface(
            data_width=64, address_width=32, id_width=4)
        self.mmio_axi = mmio_axi = axi.AXIInterface(
            data_width=64, address_width=32, id_width=4)

        self.mem_wb = mem_wb = wishbone.Interface(data_width=64, adr_width=29)
        self.mmio_wb = mmio_wb = wishbone.Interface(data_width=64, adr_width=29)

        self.ibus = ibus = wishbone.Interface()
        self.dbus = dbus = wishbone.Interface()


        # # #

        self.specials += Instance("ExampleRocketSystem",
            # clock, reset
            i_clock=ClockSignal(),
            i_reset=ResetSignal() | self.reset,

            # debug (ignored)
            #o_debug_clockeddmi_dmi_req_ready=,
            i_debug_clockeddmi_dmi_req_valid=0,
            i_debug_clockeddmi_dmi_req_bits_addr=0,
            i_debug_clockeddmi_dmi_req_bits_data=0,
            i_debug_clockeddmi_dmi_req_bits_op=0,
            i_debug_clockeddmi_dmi_resp_ready=0,
            #o_debug_clockeddmi_dmi_resp_valid=,
            #o_debug_clockeddmi_dmi_resp_bits_data=,
            #o_debug_clockeddmi_dmi_resp_bits_resp=,
            i_debug_clockeddmi_dmiClock=0,
            i_debug_clockeddmi_dmiReset=0,
            #o_debug_ndreset=,
            #o_debug_dmactive=,


            # irq
            i_interrupts=self.interrupt,

            # axi memory (L1-cached)
            i_mem_axi4_0_aw_ready=mem_axi.aw.ready,
            o_mem_axi4_0_aw_valid=mem_axi.aw.valid,
            o_mem_axi4_0_aw_bits_id=mem_axi.aw.id,
            o_mem_axi4_0_aw_bits_addr=mem_axi.aw.addr,
            o_mem_axi4_0_aw_bits_len=mem_axi.aw.len,
            o_mem_axi4_0_aw_bits_size=mem_axi.aw.size,
            o_mem_axi4_0_aw_bits_burst=mem_axi.aw.burst,
            o_mem_axi4_0_aw_bits_lock=mem_axi.aw.lock,
            o_mem_axi4_0_aw_bits_cache=mem_axi.aw.cache,
            o_mem_axi4_0_aw_bits_prot=mem_axi.aw.prot,
            o_mem_axi4_0_aw_bits_qos=mem_axi.aw.qos,

            i_mem_axi4_0_w_ready=mem_axi.w.ready,
            o_mem_axi4_0_w_valid=mem_axi.w.valid,
            o_mem_axi4_0_w_bits_data=mem_axi.w.data,
            o_mem_axi4_0_w_bits_strb=mem_axi.w.strb,
            o_mem_axi4_0_w_bits_last=mem_axi.w.last,

            o_mem_axi4_0_b_ready=mem_axi.b.ready,
            i_mem_axi4_0_b_valid=mem_axi.b.valid,
            i_mem_axi4_0_b_bits_id=mem_axi.b.id,
            i_mem_axi4_0_b_bits_resp=mem_axi.b.resp,

            i_mem_axi4_0_ar_ready=mem_axi.ar.ready,
            o_mem_axi4_0_ar_valid=mem_axi.ar.valid,
            o_mem_axi4_0_ar_bits_id=mem_axi.ar.id,
            o_mem_axi4_0_ar_bits_addr=mem_axi.ar.addr,
            o_mem_axi4_0_ar_bits_len=mem_axi.ar.len,
            o_mem_axi4_0_ar_bits_size=mem_axi.ar.size,
            o_mem_axi4_0_ar_bits_burst=mem_axi.ar.burst,
            o_mem_axi4_0_ar_bits_lock=mem_axi.ar.lock,
            o_mem_axi4_0_ar_bits_cache=mem_axi.ar.cache,
            o_mem_axi4_0_ar_bits_prot=mem_axi.ar.prot,
            o_mem_axi4_0_ar_bits_qos=mem_axi.ar.qos,

            o_mem_axi4_0_r_ready=mem_axi.r.ready,
            i_mem_axi4_0_r_valid=mem_axi.r.valid,
            i_mem_axi4_0_r_bits_id=mem_axi.r.id,
            i_mem_axi4_0_r_bits_data=mem_axi.r.data,
            i_mem_axi4_0_r_bits_resp=mem_axi.r.resp,
            i_mem_axi4_0_r_bits_last=mem_axi.r.last,

            # axi mmio (not cached)
            i_mmio_axi4_0_aw_ready=mmio_axi.aw.ready,
            o_mmio_axi4_0_aw_valid=mmio_axi.aw.valid,
            o_mmio_axi4_0_aw_bits_id=mmio_axi.aw.id,
            o_mmio_axi4_0_aw_bits_addr=mmio_axi.aw.addr,
            o_mmio_axi4_0_aw_bits_len=mmio_axi.aw.len,
            o_mmio_axi4_0_aw_bits_size=mmio_axi.aw.size,
            o_mmio_axi4_0_aw_bits_burst=mmio_axi.aw.burst,
            o_mmio_axi4_0_aw_bits_lock=mmio_axi.aw.lock,
            o_mmio_axi4_0_aw_bits_cache=mmio_axi.aw.cache,
            o_mmio_axi4_0_aw_bits_prot=mmio_axi.aw.prot,
            o_mmio_axi4_0_aw_bits_qos=mmio_axi.aw.qos,

            i_mmio_axi4_0_w_ready=mmio_axi.w.ready,
            o_mmio_axi4_0_w_valid=mmio_axi.w.valid,
            o_mmio_axi4_0_w_bits_data=mmio_axi.w.data,
            o_mmio_axi4_0_w_bits_strb=mmio_axi.w.strb,
            o_mmio_axi4_0_w_bits_last=mmio_axi.w.last,

            o_mmio_axi4_0_b_ready=mmio_axi.b.ready,
            i_mmio_axi4_0_b_valid=mmio_axi.b.valid,
            i_mmio_axi4_0_b_bits_id=mmio_axi.b.id,
            i_mmio_axi4_0_b_bits_resp=mmio_axi.b.resp,

            i_mmio_axi4_0_ar_ready=mmio_axi.ar.ready,
            o_mmio_axi4_0_ar_valid=mmio_axi.ar.valid,
            o_mmio_axi4_0_ar_bits_id=mmio_axi.ar.id,
            o_mmio_axi4_0_ar_bits_addr=mmio_axi.ar.addr,
            o_mmio_axi4_0_ar_bits_len=mmio_axi.ar.len,
            o_mmio_axi4_0_ar_bits_size=mmio_axi.ar.size,
            o_mmio_axi4_0_ar_bits_burst=mmio_axi.ar.burst,
            o_mmio_axi4_0_ar_bits_lock=mmio_axi.ar.lock,
            o_mmio_axi4_0_ar_bits_cache=mmio_axi.ar.cache,
            o_mmio_axi4_0_ar_bits_prot=mmio_axi.ar.prot,
            o_mmio_axi4_0_ar_bits_qos=mmio_axi.ar.qos,

            o_mmio_axi4_0_r_ready=mmio_axi.r.ready,
            i_mmio_axi4_0_r_valid=mmio_axi.r.valid,
            i_mmio_axi4_0_r_bits_id=mmio_axi.r.id,
            i_mmio_axi4_0_r_bits_data=mmio_axi.r.data,
            i_mmio_axi4_0_r_bits_resp=mmio_axi.r.resp,
            i_mmio_axi4_0_r_bits_last=mmio_axi.r.last,
        )

        # adapt axi interfaces to wishbone
        mem_a2w = ResetInserter()(
            axi.AXI2Wishbone(mem_axi, mem_wb, base_address=0))
        mmio_a2w = ResetInserter()(
            axi.AXI2Wishbone(mmio_axi, mmio_wb, base_address=0))
        # NOTE: AXI2Wishbone FSMs must be reset with the CPU!
        self.comb += [
            mem_a2w.reset.eq(ResetSignal() | self.reset),
            mmio_a2w.reset.eq(ResetSignal() | self.reset),
        ]

        # down-convert wishbone from 64 to 32 bit data width
        mem_dc = wishbone.Converter(mem_wb, ibus)
        mmio_dc = wishbone.Converter(mmio_wb, dbus)

        self.submodules += mem_a2w, mem_dc, mmio_a2w, mmio_dc

        # add verilog sources
        self.add_sources(platform)
Пример #7
0
    def add_sdram(self, name, phy, module, origin, size=None,
        l2_cache_size           = 8192,
        l2_cache_min_data_width = 128,
        l2_cache_reverse        = True,
        l2_cache_full_memory_we = True,
        **kwargs):

        # LiteDRAM core ----------------------------------------------------------------------------
        self.submodules.sdram = LiteDRAMCore(
            phy             = phy,
            geom_settings   = module.geom_settings,
            timing_settings = module.timing_settings,
            clk_freq        = self.sys_clk_freq,
            **kwargs)
        self.csr.add("sdram")

        # LiteDRAM port ----------------------------------------------------------------------------
        port = self.sdram.crossbar.get_port()
        port.data_width = 2**int(log2(port.data_width)) # Round to nearest power of 2

        # SDRAM size -------------------------------------------------------------------------------
        sdram_size = 2**(module.geom_settings.bankbits +
                         module.geom_settings.rowbits +
                         module.geom_settings.colbits)*phy.settings.databits//8
        if size is not None:
            sdram_size = min(sdram_size, size)
        self.bus.add_region("main_ram", SoCRegion(origin=origin, size=sdram_size))

        # SoC [<--> L2 Cache] <--> LiteDRAM --------------------------------------------------------
        if self.cpu.name == "rocket":
            # Rocket has its own I/D L1 cache: connect directly to LiteDRAM when possible.
            if port.data_width == self.cpu.mem_axi.data_width:
                self.logger.info("Matching AXI MEM data width ({})\n".format(port.data_width))
                self.submodules += LiteDRAMAXI2Native(
                    axi          = self.cpu.mem_axi,
                    port         = port,
                    base_address = self.bus.regions["main_ram"].origin)
            else:
                self.logger.info("Converting MEM data width: {} to {} via Wishbone".format(
                    port.data_width,
                    self.cpu.mem_axi.data_width))
                # FIXME: replace WB data-width converter with native AXI converter!!!
                mem_wb  = wishbone.Interface(
                    data_width = self.cpu.mem_axi.data_width,
                    adr_width  = 32-log2_int(self.cpu.mem_axi.data_width//8))
                # NOTE: AXI2Wishbone FSMs must be reset with the CPU!
                mem_a2w = ResetInserter()(axi.AXI2Wishbone(
                    axi          = self.cpu.mem_axi,
                    wishbone     = mem_wb,
                    base_address = 0))
                self.comb += mem_a2w.reset.eq(ResetSignal() | self.cpu.reset)
                self.submodules += mem_a2w
                litedram_wb = wishbone.Interface(port.data_width)
                self.submodules += LiteDRAMWishbone2Native(
                    wishbone     = litedram_wb,
                    port         = port,
                    base_address = origin)
                self.submodules += wishbone.Converter(mem_wb, litedram_wb)
        elif self.with_wishbone:
            # Wishbone Slave SDRAM interface -------------------------------------------------------
            wb_sdram = wishbone.Interface()
            self.bus.add_slave("main_ram", wb_sdram)

            # L2 Cache -----------------------------------------------------------------------------
            if l2_cache_size != 0:
                # Insert L2 cache inbetween Wishbone bus and LiteDRAM
                l2_cache_size = max(l2_cache_size, int(2*port.data_width/8)) # Use minimal size if lower
                l2_cache_size = 2**int(log2(l2_cache_size))                  # Round to nearest power of 2
                l2_cache_data_width = max(port.data_width, l2_cache_min_data_width)
                l2_cache            = wishbone.Cache(
                    cachesize = l2_cache_size//4,
                    master    = wb_sdram,
                    slave     = wishbone.Interface(l2_cache_data_width),
                    reverse   = l2_cache_reverse)
                if l2_cache_full_memory_we:
                    l2_cache = FullMemoryWE()(l2_cache)
                self.submodules.l2_cache = l2_cache
                litedram_wb = self.l2_cache.slave
            else:
                litedram_wb     = wishbone.Interface(port.data_width)
                self.submodules += wishbone.Converter(wb_sdram, litedram_wb)
            self.add_config("L2_SIZE", l2_cache_size)

            # Wishbone Slave <--> LiteDRAM bridge --------------------------------------------------
            self.submodules.wishbone_bridge = LiteDRAMWishbone2Native(litedram_wb, port,
                base_address = self.bus.regions["main_ram"].origin)
Пример #8
0
    def register_sdram(self,
                       phy,
                       sdram_controller_type,
                       geom_settings,
                       timing_settings,
                       controller_settings=None):
        assert not self._sdram_phy
        self._sdram_phy.append(
            phy)  # encapsulate in list to prevent CSR scanning

        self.submodules.sdram = ControllerInjector(phy, sdram_controller_type,
                                                   geom_settings,
                                                   timing_settings,
                                                   controller_settings)

        dfi_databits_divisor = 1 if phy.settings.memtype == "SDR" else 2
        sdram_width = phy.settings.dfi_databits // dfi_databits_divisor
        main_ram_size = 2**(geom_settings.bankbits + geom_settings.rowbits +
                            geom_settings.colbits) * sdram_width // 8
        # XXX: Limit main_ram_size to 256MB, we should modify mem_map to allow larger memories.
        main_ram_size = min(main_ram_size, 256 * 1024 * 1024)
        if self.l2_size:
            self.add_constant("L2_SIZE", self.l2_size)

        # add a Wishbone interface to the DRAM
        wb_sdram = wishbone.Interface()
        self.add_wb_sdram_if(wb_sdram)
        self.register_mem("main_ram", self.mem_map["main_ram"], wb_sdram,
                          main_ram_size)

        if sdram_controller_type == "lasmicon":
            if self.l2_size:
                lasmim = self.sdram.crossbar.get_master()
                l2_cache = wishbone.Cache(self.l2_size // 4, self._wb_sdram,
                                          wishbone.Interface(lasmim.dw))
                # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache.
                # Issue is reported to Xilinx and should be fixed in next releases (2015.2?).
                # Remove this workaround when fixed by Xilinx.
                from litex.build.xilinx.vivado import XilinxVivadoToolchain
                if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
                    from litex.gen.fhdl.simplify import FullMemoryWE
                    self.submodules.l2_cache = FullMemoryWE()(l2_cache)
                else:
                    self.submodules.l2_cache = l2_cache
                self.submodules.wishbone2lasmi = wishbone2lasmi.WB2LASMI(
                    self.l2_cache.slave, lasmim)
        elif sdram_controller_type == "minicon":
            if self.l2_size:
                l2_cache = wishbone.Cache(self.l2_size // 4, self._wb_sdram,
                                          self.sdram.controller.bus)
                # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache.
                # Issue is reported to Xilinx and should be fixed in next releases (2015.2?).
                # Remove this workaround when fixed by Xilinx.
                from litex.build.xilinx.vivado import XilinxVivadoToolchain
                if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
                    from litex.gen.fhdl.simplify import FullMemoryWE
                    self.submodules.l2_cache = FullMemoryWE()(l2_cache)
                else:
                    self.submodules.l2_cache = l2_cache
            else:
                self.submodules.converter = wishbone.Converter(
                    self._wb_sdram, self.sdram.controller.bus)
        else:
            raise ValueError