Пример #1
0
Файл: core.py Проект: hplp/litex
    def __init__(self, platform, variant="standard"):
        self.platform = platform
        self.variant = variant

        self.reset = Signal()
        self.interrupt = Signal(8)

        mem_dw, mmio_dw, num_cores = CPU_SIZE_PARAMS[self.variant]

        self.mem_axi = mem_axi = axi.AXIInterface(data_width=mem_dw,
                                                  address_width=32,
                                                  id_width=4)
        self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=mmio_dw,
                                                    address_width=32,
                                                    id_width=4)
        self.l2fb_axi = l2fb_axi = axi.AXIInterface(data_width=mmio_dw,
                                                    address_width=32,
                                                    id_width=4)

        self.mmio_wb = mmio_wb = wishbone.Interface(data_width=mmio_dw,
                                                    adr_width=32 -
                                                    log2_int(mmio_dw // 8))
        self.l2fb_wb = l2fb_wb = wishbone.Interface(data_width=mmio_dw,
                                                    adr_width=32 -
                                                    log2_int(mmio_dw // 8))

        self.memory_buses = [
            mem_axi
        ]  # Peripheral buses (Connected to main SoC's bus).
        self.periph_buses = [
            mmio_wb
        ]  # Memory buses (Connected directly to LiteDRAM).
        self.dma_bus = l2fb_wb  # DMA bus (Arbitrated and connected to SoC's bus).

        # # #

        self.cpu_params = dict(
            # Clk / Rst.
            i_clock=ClockSignal("sys"),
            i_reset=ResetSignal("sys") | self.reset,

            # Debug (ignored).
            i_debug_clock=0,
            i_debug_reset=ResetSignal() | self.reset,
            o_debug_clockeddmi_dmi_req_ready=Open(),
            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=Open(),
            o_debug_clockeddmi_dmi_resp_bits_data=Open(),
            o_debug_clockeddmi_dmi_resp_bits_resp=Open(),
            i_debug_clockeddmi_dmiClock=0,
            i_debug_clockeddmi_dmiReset=ResetSignal() | self.reset,
            o_debug_ndreset=Open(),
            o_debug_dmactive=Open(),
            i_debug_dmactiveAck=0,

            # 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,

            # AXI L2FB (Slave, for e.g., DMA).
            o_l2_frontend_bus_axi4_0_aw_ready=l2fb_axi.aw.ready,
            i_l2_frontend_bus_axi4_0_aw_valid=l2fb_axi.aw.valid,
            i_l2_frontend_bus_axi4_0_aw_bits_id=l2fb_axi.aw.id,
            i_l2_frontend_bus_axi4_0_aw_bits_addr=l2fb_axi.aw.addr,
            i_l2_frontend_bus_axi4_0_aw_bits_len=l2fb_axi.aw.len,
            i_l2_frontend_bus_axi4_0_aw_bits_size=l2fb_axi.aw.size,
            i_l2_frontend_bus_axi4_0_aw_bits_burst=l2fb_axi.aw.burst,
            i_l2_frontend_bus_axi4_0_aw_bits_lock=l2fb_axi.aw.lock,
            i_l2_frontend_bus_axi4_0_aw_bits_cache=l2fb_axi.aw.cache,
            i_l2_frontend_bus_axi4_0_aw_bits_prot=l2fb_axi.aw.prot,
            i_l2_frontend_bus_axi4_0_aw_bits_qos=l2fb_axi.aw.qos,
            o_l2_frontend_bus_axi4_0_w_ready=l2fb_axi.w.ready,
            i_l2_frontend_bus_axi4_0_w_valid=l2fb_axi.w.valid,
            i_l2_frontend_bus_axi4_0_w_bits_data=l2fb_axi.w.data,
            i_l2_frontend_bus_axi4_0_w_bits_strb=l2fb_axi.w.strb,
            i_l2_frontend_bus_axi4_0_w_bits_last=l2fb_axi.w.last,
            i_l2_frontend_bus_axi4_0_b_ready=l2fb_axi.b.ready,
            o_l2_frontend_bus_axi4_0_b_valid=l2fb_axi.b.valid,
            o_l2_frontend_bus_axi4_0_b_bits_id=l2fb_axi.b.id,
            o_l2_frontend_bus_axi4_0_b_bits_resp=l2fb_axi.b.resp,
            o_l2_frontend_bus_axi4_0_ar_ready=l2fb_axi.ar.ready,
            i_l2_frontend_bus_axi4_0_ar_valid=l2fb_axi.ar.valid,
            i_l2_frontend_bus_axi4_0_ar_bits_id=l2fb_axi.ar.id,
            i_l2_frontend_bus_axi4_0_ar_bits_addr=l2fb_axi.ar.addr,
            i_l2_frontend_bus_axi4_0_ar_bits_len=l2fb_axi.ar.len,
            i_l2_frontend_bus_axi4_0_ar_bits_size=l2fb_axi.ar.size,
            i_l2_frontend_bus_axi4_0_ar_bits_burst=l2fb_axi.ar.burst,
            i_l2_frontend_bus_axi4_0_ar_bits_lock=l2fb_axi.ar.lock,
            i_l2_frontend_bus_axi4_0_ar_bits_cache=l2fb_axi.ar.cache,
            i_l2_frontend_bus_axi4_0_ar_bits_prot=l2fb_axi.ar.prot,
            i_l2_frontend_bus_axi4_0_ar_bits_qos=l2fb_axi.ar.qos,
            i_l2_frontend_bus_axi4_0_r_ready=l2fb_axi.r.ready,
            o_l2_frontend_bus_axi4_0_r_valid=l2fb_axi.r.valid,
            o_l2_frontend_bus_axi4_0_r_bits_id=l2fb_axi.r.id,
            o_l2_frontend_bus_axi4_0_r_bits_data=l2fb_axi.r.data,
            o_l2_frontend_bus_axi4_0_r_bits_resp=l2fb_axi.r.resp,
            o_l2_frontend_bus_axi4_0_r_bits_last=l2fb_axi.r.last,
        )
        # additional per-core debug signals:
        self.cpu_params.update({
            'i_resetctrl_hartIsInReset_%s' % i: Open()
            for i in range(num_cores)
        })

        # Adapt AXI interfaces to Wishbone.
        mmio_a2w = axi.AXI2Wishbone(mmio_axi, mmio_wb, base_address=0)
        self.submodules += mmio_a2w

        l2fb_a2w = axi.Wishbone2AXI(l2fb_wb, l2fb_axi, base_address=0)
        self.submodules += l2fb_a2w

        # Add Verilog sources.
        self.add_sources(platform, variant)
Пример #2
0
    def __init__(self, platform, variant="standard"):
        self.platform = platform
        self.variant = variant

        self.reset = Signal()
        self.interrupt = Signal(4)

        mem_dw, mmio_dw = AXI_DATA_WIDTHS[self.variant]

        self.mem_axi = mem_axi = axi.AXIInterface(data_width=mem_dw,
                                                  address_width=32,
                                                  id_width=4)
        self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=mmio_dw,
                                                    address_width=32,
                                                    id_width=4)
        self.l2fb_axi = l2fb_axi = axi.AXIInterface(data_width=mmio_dw,
                                                    address_width=32,
                                                    id_width=4)

        self.mmio_wb = mmio_wb = wishbone.Interface(data_width=mmio_dw,
                                                    adr_width=32 -
                                                    log2_int(mmio_dw // 8))
        self.l2fb_wb = l2fb_wb = wishbone.Interface(data_width=mmio_dw,
                                                    adr_width=32 -
                                                    log2_int(mmio_dw // 8))

        self.memory_buses = [mem_axi]
        self.periph_buses = [mmio_wb]
        self.dma_bus = l2fb_wb

        # # #

        self.cpu_params = dict(
            # clock, reset
            i_clock=ClockSignal(),
            i_reset=ResetSignal() | self.reset,

            # debug (ignored)
            #i_resetctrl_hartIsInReset_0           = 0,
            i_debug_clock=0,
            i_debug_reset=ResetSignal() | self.reset,
            #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=ResetSignal() | self.reset,
            #o_debug_ndreset                       = ,
            #o_debug_dmactive                      = ,
            i_debug_dmactiveAck=0,

            # 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,

            # axi l2fb (slave, for e.g., DMA)
            o_l2_frontend_bus_axi4_0_aw_ready=l2fb_axi.aw.ready,
            i_l2_frontend_bus_axi4_0_aw_valid=l2fb_axi.aw.valid,
            i_l2_frontend_bus_axi4_0_aw_bits_id=l2fb_axi.aw.id,
            i_l2_frontend_bus_axi4_0_aw_bits_addr=l2fb_axi.aw.addr,
            i_l2_frontend_bus_axi4_0_aw_bits_len=l2fb_axi.aw.len,
            i_l2_frontend_bus_axi4_0_aw_bits_size=l2fb_axi.aw.size,
            i_l2_frontend_bus_axi4_0_aw_bits_burst=l2fb_axi.aw.burst,
            i_l2_frontend_bus_axi4_0_aw_bits_lock=l2fb_axi.aw.lock,
            i_l2_frontend_bus_axi4_0_aw_bits_cache=l2fb_axi.aw.cache,
            i_l2_frontend_bus_axi4_0_aw_bits_prot=l2fb_axi.aw.prot,
            i_l2_frontend_bus_axi4_0_aw_bits_qos=l2fb_axi.aw.qos,
            o_l2_frontend_bus_axi4_0_w_ready=l2fb_axi.w.ready,
            i_l2_frontend_bus_axi4_0_w_valid=l2fb_axi.w.valid,
            i_l2_frontend_bus_axi4_0_w_bits_data=l2fb_axi.w.data,
            i_l2_frontend_bus_axi4_0_w_bits_strb=l2fb_axi.w.strb,
            i_l2_frontend_bus_axi4_0_w_bits_last=l2fb_axi.w.last,
            i_l2_frontend_bus_axi4_0_b_ready=l2fb_axi.b.ready,
            o_l2_frontend_bus_axi4_0_b_valid=l2fb_axi.b.valid,
            o_l2_frontend_bus_axi4_0_b_bits_id=l2fb_axi.b.id,
            o_l2_frontend_bus_axi4_0_b_bits_resp=l2fb_axi.b.resp,
            o_l2_frontend_bus_axi4_0_ar_ready=l2fb_axi.ar.ready,
            i_l2_frontend_bus_axi4_0_ar_valid=l2fb_axi.ar.valid,
            i_l2_frontend_bus_axi4_0_ar_bits_id=l2fb_axi.ar.id,
            i_l2_frontend_bus_axi4_0_ar_bits_addr=l2fb_axi.ar.addr,
            i_l2_frontend_bus_axi4_0_ar_bits_len=l2fb_axi.ar.len,
            i_l2_frontend_bus_axi4_0_ar_bits_size=l2fb_axi.ar.size,
            i_l2_frontend_bus_axi4_0_ar_bits_burst=l2fb_axi.ar.burst,
            i_l2_frontend_bus_axi4_0_ar_bits_lock=l2fb_axi.ar.lock,
            i_l2_frontend_bus_axi4_0_ar_bits_cache=l2fb_axi.ar.cache,
            i_l2_frontend_bus_axi4_0_ar_bits_prot=l2fb_axi.ar.prot,
            i_l2_frontend_bus_axi4_0_ar_bits_qos=l2fb_axi.ar.qos,
            i_l2_frontend_bus_axi4_0_r_ready=l2fb_axi.r.ready,
            o_l2_frontend_bus_axi4_0_r_valid=l2fb_axi.r.valid,
            o_l2_frontend_bus_axi4_0_r_bits_id=l2fb_axi.r.id,
            o_l2_frontend_bus_axi4_0_r_bits_data=l2fb_axi.r.data,
            o_l2_frontend_bus_axi4_0_r_bits_resp=l2fb_axi.r.resp,
            o_l2_frontend_bus_axi4_0_r_bits_last=l2fb_axi.r.last,
        )

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

        l2fb_a2w = ResetInserter()(axi.Wishbone2AXI(l2fb_wb,
                                                    l2fb_axi,
                                                    base_address=0))
        self.comb += l2fb_a2w.reset.eq(ResetSignal() | self.reset)
        self.submodules += l2fb_a2w

        # add verilog sources
        self.add_sources(platform, variant)