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
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)
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)
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)
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)
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)
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)
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