예제 #1
0
파일: spi_flash.py 프로젝트: zeta1999/litex
    def __init__(self, pads, dummy=15, div=2, with_bitbang=True, endianness="big"):
        """
        Simple SPI flash.
        Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast
        Read). Only supports mode3 (cpol=1, cpha=1).
        """
        SpiFlashCommon.__init__(self, pads)
        self.bus = bus = wishbone.Interface()
        spi_width = len(pads.dq)
        max_transfer_size = 8*8
        assert spi_width >= 2

        if with_bitbang:
            self.bitbang = CSRStorage(4, reset_less=True, fields=[
                CSRField("mosi", description="Output value for MOSI pin, valid whenever ``dir`` is ``0``."),
                CSRField("clk", description="Output value for SPI CLK pin."),
                CSRField("cs_n", description="Output value for SPI CSn pin."),
                CSRField("dir", description="Sets the direction for *ALL* SPI data pins except CLK and CSn.", values=[
                    ("0", "OUT", "SPI pins are all output"),
                    ("1", "IN", "SPI pins are all input"),
                ])
            ], description="""
                Bitbang controls for SPI output.  Only standard 1x SPI is supported, and as
                a result all four wires are ganged together.  This means that it is only possible
                to perform half-duplex operations, using this SPI core.
            """)
            self.miso = CSRStatus(description="Incoming value of MISO signal.")
            self.bitbang_en = CSRStorage(description="Write a ``1`` here to disable memory-mapped mode and enable bitbang mode.")

        queue = self.queue = CSRStatus(4)
        in_len = self.in_len = CSRStorage(4)
        out_len = self.out_len = CSRStorage(4)
        in_left = self.in_left = Signal(max=2**8)
        out_left = self.out_left = Signal(max=2**8)
        self.quad_transfer = Signal(reset=0)
        spi_in = self.spi_in = CSRStorage(max_transfer_size)
        spi_out = self.spi_out = CSRStatus(max_transfer_size)

        cs_n = Signal(reset=1)
        clk = Signal()
        dq_oe = Signal()
        wbone_width = len(bus.dat_r)

        cmd_width = 8
        addr_width = 24

        dq = TSTriple(spi_width)

        sr = Signal(max(cmd_width, addr_width, wbone_width))
        if endianness == "big":
            self.comb += bus.dat_r.eq(sr)
        else:
            self.comb += bus.dat_r.eq(reverse_bytes(sr))

        self.specials.dq0 = Tristate(pads.dq[0], o=dq.o[0], i=dq.i[0], oe=dq.oe)
        self.specials.dq1 = Tristate(pads.dq[1], o=dq.o[1], i=dq.i[1], oe=dq.oe)
        if with_bitbang:
            # Keep DQ2,DQ3 as outputs during bitbang, this ensures they activate ~WP or ~HOLD functions
            self.specials.dq2 = Tristate(pads.dq[2], o=dq.o[2], i=dq.i[2], oe=(dq.oe | self.bitbang_en.storage))
            self.specials.dq3 = Tristate(pads.dq[3], o=dq.o[3], i=dq.i[3], oe=(dq.oe | self.bitbang_en.storage))
        else:
            self.specials.dq2 = Tristate(pads.dq[2], o=dq.o[2], i=dq.i[2], oe=dq.oe)
            self.specials.dq3 = Tristate(pads.dq[3], o=dq.o[3], i=dq.i[3], oe=dq.oe)

        sr = Signal(max(cmd_width, addr_width, wbone_width, max_transfer_size))

        if endianness == "big":
            self.comb += bus.dat_r.eq(sr[:wbone_width])
        else:
            self.comb += bus.dat_r.eq(reverse_bytes(sr[:wbone_width]))
        hw_read_logic_single = [
            pads.clk.eq(clk),
            pads.cs_n.eq(cs_n),
            dq.o.eq(sr[-spi_width:]),
            dq.oe.eq(dq_oe)
        ]
        hw_read_logic_quad = [
            pads.clk.eq(clk),
            pads.cs_n.eq(cs_n),
            dq.o.eq(Cat(sr[-1:], Replicate(1, 3))),
            dq.oe.eq(dq_oe)
        ]

        if with_bitbang:
            bitbang_logic = [
                pads.clk.eq(self.bitbang.storage[1]),
                pads.cs_n.eq(self.bitbang.storage[2]),

                # In Dual/Quad mode, no single data pin is consistently
                # an input or output thanks to dual/quad reads, so we need a bit
                # to swap direction of the pins. Aside from this additional bit,
                # bitbang mode is identical for Single/Dual/Quad; dq[0] is mosi
                # and dq[1] is miso, meaning remaining data pin values don't
                # appear in CSR registers.
                If(self.bitbang.storage[3],
                    dq.oe.eq(0)
                ).Else(
                    dq.oe.eq(1)
                ),
                If(self.bitbang.storage[1], # CPOL=0/CPHA=0 or CPOL=1/CPHA=1 only.
                    self.miso.status.eq(dq.i[1])
                ),
                dq.o.eq(Cat(self.bitbang.storage[0], Replicate(1, spi_width-1)))
            ]

            self.comb += [
                If(self.bitbang_en.storage,
                    bitbang_logic
                ).Elif(self.quad_transfer,
                    hw_read_logic_single
                ).Else(
                    hw_read_logic_quad
                )
            ]

        else:
            self.comb += [
                If(self.quad_transfer,
                    hw_read_logic_single
                ).Else(
                    hw_read_logic_quad
                )
            ]

        if div < 2:
            raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))

        # spi is byte-addressed, prefix by zeros
        z = Replicate(0, log2_int(wbone_width//8))
        i = Signal(max=div)
        dqi = Signal(spi_width)

        # SPI or memmap mode
        self.mode = Signal()

        self.sync += [
            If(i == div//2 - 1,
                clk.eq(1),
                dqi.eq(dq.i),
            ),
            If(i == div - 1,
                i.eq(0),
                clk.eq(0),
               If(self.quad_transfer,
                  sr.eq(Cat(dqi, sr[:-spi_width]))
               ).Else(
                   sr.eq(Cat(dqi[1], sr[:-1]))
                  )
            ).Else(
                i.eq(i + 1),
            ),
        ]

        read_seq = [
            (4*cmd_width//spi_width*div,
                [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(_QIOFR), self.quad_transfer.eq(0)]),
            (addr_width//spi_width*div,
                [sr[-addr_width:].eq(Cat(z, bus.adr)), self.quad_transfer.eq(1)]),
            ((1+dummy + wbone_width//spi_width)*div,
                [dq_oe.eq(0)]),
            (1,
                [bus.ack.eq(1), cs_n.eq(1)]),
            (div, # tSHSL!
                [bus.ack.eq(0)]),
            (0,
             [queue.status[0].eq(0)]),
        ]


        write_seq = [
            (4*cmd_width//spi_width*div,
                [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(_QIOPP), self.quad_transfer.eq(0)]),
            (addr_width//spi_width*div,
                [sr[-addr_width:].eq(Cat(z, bus.adr)), self.quad_transfer.eq(1)]),
            ((wbone_width//spi_width)*div,
                [sr[-wbone_width:].eq(reverse_bytes(bus.dat_w))]),
            (1,
                [bus.ack.eq(1), cs_n.eq(1)]),
            (div,
                [bus.ack.eq(0)]),
            (0,
             [queue.status[1].eq(0)]),
        ]

        # prepare spi transfer
        self.sync += If(self.out_len.re & (self.out_len.storage != 0) & self.en_quad.storage[0],
                        self.out_left.eq(Cat(1, self.out_len.storage)
                        )
        )

        self.sync += If(self.out_len.re & (self.out_len.storage == 0),
                        self.out_left.eq(0)
        )
        self.sync += If(self.out_len.re & (self.out_len.storage != 0) & ~self.en_quad.storage[0],
                        self.out_left.eq(Cat(1, Replicate(0, 2), self.out_len.storage))
        )
        self.sync += If(self.in_len.re & (self.in_len.storage != 0) & ~self.en_quad.storage[0],
                        [queue.status[2].eq(1),
                         self.in_left.eq(Cat(Replicate(0, 3), in_len.storage)),
                         self.quad_transfer.eq(0)]
        )

        # write data to sr
        self.sync += If(queue.status[2] & (i == div - 1) & ~self.en_quad.storage[0],
                        sr[-max_transfer_size:].eq(self.spi_in.storage), queue.status[2].eq(0), queue.status[3].eq(1), cs_n.eq(0), dq_oe.eq(1))

        # count spi to slave transfer cycles
        self.sync += If(queue.status[3] & (self.in_left > 0) & (i == div - 1), self.in_left.eq(self.in_left - 1), dq_oe.eq(1))
        # count spi to master transfer cycles
        self.sync += If(queue.status[3] & (self.in_left < 1) & (self.out_left > 0) & (i == div - 1), self.out_left.eq(self.out_left - 1), dq_oe.eq(0))

        #end transmision and read data from sr
        self.sync += If(~self.in_len.re & (in_left < 1) & (out_left < 1) & queue.status[3], queue.status[3].eq(0), cs_n.eq(1),
                        If(self.out_len.storage == 1, self.spi_out.status.eq(Cat(Replicate(0, 8*7), sr))
                        ).Elif(self.out_len.storage == 2, self.spi_out.status.eq(Cat(Replicate(0, 8*6), sr))
                        ).Elif(self.out_len.storage == 3, self.spi_out.status.eq(Cat(Replicate(0, 8*5), sr))
                        ).Elif(self.out_len.storage == 4, self.spi_out.status.eq(Cat(Replicate(0, 8*4), sr))
                        ).Elif(self.out_len.storage == 5, self.spi_out.status.eq(Cat(Replicate(0, 8*3), sr))
                        ).Elif(self.out_len.storage == 6, self.spi_out.status.eq(Cat(Replicate(0, 8*2), sr))
                        ).Elif(self.out_len.storage == 7, self.spi_out.status.eq(Cat(Replicate(0, 8*1), sr))
                        ).Else(self.spi_out.status.eq(sr)))

        # detect mem map access
        self.sync += If(~self.mode & bus.cyc & bus.stb & ~bus.we, queue.status[0].eq(1))
        self.sync += If(~self.mode & bus.cyc & bus.stb & bus.we, queue.status[1].eq(1))

        self.sync += timeline(queue.status[0] & ~self.en_quad.storage[0] & (i == div - 1), accumulate_timeline_deltas(read_seq))
        self.sync += timeline(queue.status[1] & ~self.en_quad.storage[0] & (i == div - 1), accumulate_timeline_deltas(write_seq))
예제 #2
0
    def __init__(self, platform, core_config, **kwargs):
        platform.add_extension(get_common_ios())
        sys_clk_freq = core_config["sys_clk_freq"]
        SoCSDRAM.__init__(self, platform, sys_clk_freq,
            cpu_type=core_config["cpu"],
            l2_size=16*core_config["sdram_module_nb"],
            **kwargs)

        # crg
        self.submodules.crg = LiteDRAMCRG(platform, core_config)

        # sdram
        platform.add_extension(get_dram_ios(core_config))
        assert core_config["memtype"] in ["DDR2", "DDR3"]
        self.submodules.ddrphy = core_config["sdram_phy"](
            platform.request("ddram"),
            memtype=core_config["memtype"],
            nphases=4 if core_config["memtype"] == "DDR3" else 2,
            sys_clk_freq=sys_clk_freq,
            iodelay_clk_freq=core_config["iodelay_clk_freq"],
            cmd_latency=core_config["cmd_latency"])
        self.add_constant("CMD_DELAY", core_config["cmd_delay"])
        if core_config["memtype"] == "DDR3":
            self.ddrphy.settings.add_electrical_settings(
                rtt_nom=core_config["rtt_nom"],
                rtt_wr=core_config["rtt_wr"],
                ron=core_config["ron"])
        sdram_module = core_config["sdram_module"](sys_clk_freq,
            "1:4" if core_config["memtype"] == "DDR3" else "1:2")
        controller_settings = controller_settings=ControllerSettings(
            cmd_buffer_depth=core_config["cmd_buffer_depth"])
        self.register_sdram(self.ddrphy,
                            sdram_module.geom_settings,
                            sdram_module.timing_settings,
                            controller_settings=controller_settings)

        # sdram init
        self.submodules.ddrctrl = LiteDRAMCoreControl()
        self.comb += [
            platform.request("init_done").eq(self.ddrctrl.init_done.storage),
            platform.request("init_error").eq(self.ddrctrl.init_error.storage)
        ]

        # CSR port
        if core_config.get("expose_csr_port", "no") == "yes":
            csr_port = csr_bus.Interface(self.csr_address_width, self.csr_data_width)
            self.add_csr_master(csr_port)
            platform.add_extension(get_csr_ios(self.csr_address_width,
                                               self.csr_data_width))
            _csr_port_io = platform.request("csr_port", 0)
            self.comb += [
                csr_port.adr.eq(_csr_port_io.adr),
                csr_port.we.eq(_csr_port_io.we),
                csr_port.dat_w.eq(_csr_port_io.dat_w),
                _csr_port_io.dat_r.eq(csr_port.dat_r),
            ]

        # user port
        self.comb += [
            platform.request("user_clk").eq(ClockSignal()),
            platform.request("user_rst").eq(ResetSignal())
        ]
        if core_config["user_ports_type"] == "native":
            for i in range(core_config["user_ports_nb"]):
                user_port = self.sdram.crossbar.get_port()
                platform.add_extension(get_native_user_port_ios(i,
                    user_port.address_width,
                    user_port.data_width))
                _user_port_io = platform.request("user_port", i)
                self.comb += [
                    # cmd
                    user_port.cmd.valid.eq(_user_port_io.cmd_valid),
                    _user_port_io.cmd_ready.eq(user_port.cmd.ready),
                    user_port.cmd.we.eq(_user_port_io.cmd_we),
                    user_port.cmd.addr.eq(_user_port_io.cmd_addr),

                    # wdata
                    user_port.wdata.valid.eq(_user_port_io.wdata_valid),
                    _user_port_io.wdata_ready.eq(user_port.wdata.ready),
                    user_port.wdata.we.eq(_user_port_io.wdata_we),
                    user_port.wdata.data.eq(_user_port_io.wdata_data),

                    # rdata
                    _user_port_io.rdata_valid.eq(user_port.rdata.valid),
                    user_port.rdata.ready.eq(_user_port_io.rdata_ready),
                    _user_port_io.rdata_data.eq(user_port.rdata.data),
                ]
        elif core_config["user_ports_type"] == "wishbone":
            for i in range(core_config["user_ports_nb"]):
                user_port = self.sdram.crossbar.get_port()
                wb_port = wishbone.Interface(
                    user_port.data_width,
                    user_port.address_width)
                wishbone2native = LiteDRAMWishbone2Native(wb_port, user_port)
                self.submodules += wishbone2native
                platform.add_extension(get_wishbone_user_port_ios(i,
                        len(wb_port.adr),
                        len(wb_port.dat_w)))
                _wb_port_io = platform.request("user_port", i)
                self.comb += [
                    wb_port.adr.eq(_wb_port_io.adr),
                    wb_port.dat_w.eq(_wb_port_io.dat_w),
                    _wb_port_io.dat_r.eq(wb_port.dat_r),
                    wb_port.sel.eq(_wb_port_io.sel),
                    wb_port.cyc.eq(_wb_port_io.cyc),
                    wb_port.stb.eq(_wb_port_io.stb),
                    _wb_port_io.ack.eq(wb_port.ack),
                    wb_port.we.eq(_wb_port_io.we),
                    _wb_port_io.err.eq(wb_port.err),
                ]
        elif core_config["user_ports_type"] == "axi":
            for i in range(core_config["user_ports_nb"]):
                user_port = self.sdram.crossbar.get_port()
                axi_port = LiteDRAMAXIPort(
                    user_port.data_width,
                    user_port.address_width + log2_int(user_port.data_width//8),
                    core_config["user_ports_id_width"])
                axi2native = LiteDRAMAXI2Native(axi_port, user_port)
                self.submodules += axi2native
                platform.add_extension(get_axi_user_port_ios(i,
                        axi_port.address_width,
                        axi_port.data_width,
                        core_config["user_ports_id_width"]))
                _axi_port_io = platform.request("user_port", i)
                self.comb += [
                    # aw
                    axi_port.aw.valid.eq(_axi_port_io.aw_valid),
                    _axi_port_io.aw_ready.eq(axi_port.aw.ready),
                    axi_port.aw.addr.eq(_axi_port_io.aw_addr),
                    axi_port.aw.burst.eq(_axi_port_io.aw_burst),
                    axi_port.aw.len.eq(_axi_port_io.aw_len),
                    axi_port.aw.size.eq(_axi_port_io.aw_size),
                    axi_port.aw.id.eq(_axi_port_io.aw_id),

                    # w
                    axi_port.w.valid.eq(_axi_port_io.w_valid),
                    _axi_port_io.w_ready.eq(axi_port.w.ready),
                    axi_port.w.last.eq(_axi_port_io.w_last),
                    axi_port.w.strb.eq(_axi_port_io.w_strb),
                    axi_port.w.data.eq(_axi_port_io.w_data),

                    # b
                    _axi_port_io.b_valid.eq(axi_port.b.valid),
                    axi_port.b.ready.eq(_axi_port_io.b_ready),
                    _axi_port_io.b_resp.eq(axi_port.b.resp),
                    _axi_port_io.b_id.eq(axi_port.b.id),

                    # ar
                    axi_port.ar.valid.eq(_axi_port_io.ar_valid),
                    _axi_port_io.ar_ready.eq(axi_port.ar.ready),
                    axi_port.ar.addr.eq(_axi_port_io.ar_addr),
                    axi_port.ar.burst.eq(_axi_port_io.ar_burst),
                    axi_port.ar.len.eq(_axi_port_io.ar_len),
                    axi_port.ar.size.eq(_axi_port_io.ar_size),
                    axi_port.ar.id.eq(_axi_port_io.ar_id),

                    # r
                    _axi_port_io.r_valid.eq(axi_port.r.valid),
                    axi_port.r.ready.eq(_axi_port_io.r_ready),
                    _axi_port_io.r_last.eq(axi_port.r.last),
                    _axi_port_io.r_resp.eq(axi_port.r.resp),
                    _axi_port_io.r_data.eq(axi_port.r.data),
                    _axi_port_io.r_id.eq(axi_port.r.id),
                ]
        else:
            raise ValueError("Unsupported port type: {}".format(core_config["user_ports_type"]))
예제 #3
0
    def __init__(self, platform, variant="standard"):
        self.platform = platform
        self.variant = variant
        self.reset = Signal()
        self.ibus = wishbone.Interface()
        self.dbus = wishbone.Interface()
        self.periph_buses = [self.ibus, self.dbus]
        self.memory_buses = []
        self.interrupt = Signal(15)

        ibus = Record(obi_layout)
        dbus = Record(obi_layout)

        # OBI <> Wishbone.
        self.submodules.ibus_conv = OBI2Wishbone(ibus, self.ibus)
        self.submodules.dbus_conv = OBI2Wishbone(dbus, self.dbus)

        self.comb += [
            ibus.we.eq(0),
            ibus.be.eq(1111),
        ]

        self.cpu_params = dict(
            # Clk / Rst.
            i_clk_i=ClockSignal("sys"),
            i_rst_ni=~ResetSignal("sys"),

            # Controls.
            i_clock_en_i=1,
            i_test_en_i=0,
            i_fregfile_disable_i=0,
            i_core_id_i=0,
            i_cluster_id_i=0,

            # IBus.
            o_instr_req_o=ibus.req,
            i_instr_gnt_i=ibus.gnt,
            i_instr_rvalid_i=ibus.rvalid,
            o_instr_addr_o=ibus.addr,
            i_instr_rdata_i=ibus.rdata,

            # DBus.
            o_data_req_o=dbus.req,
            i_data_gnt_i=dbus.gnt,
            i_data_rvalid_i=dbus.rvalid,
            o_data_we_o=dbus.we,
            o_data_be_o=dbus.be,
            o_data_addr_o=dbus.addr,
            o_data_wdata_o=dbus.wdata,
            i_data_rdata_i=dbus.rdata,

            # APU.
            i_apu_master_gnt_i=0,
            i_apu_master_valid_i=0,

            # IRQ.
            i_irq_sec_i=0,
            i_irq_software_i=0,
            i_irq_external_i=0,
            i_irq_fast_i=self.interrupt,
            i_irq_nmi_i=0,
            i_irq_fastx_i=0,

            # Debug.
            i_debug_req_i=0,

            # CPU Control.
            i_fetch_enable_i=1,
        )

        # Add Verilog sources.
        add_manifest_sources(platform, 'cv32e40p_manifest.flist')

        # Specific FPU variant parameters/files.
        if variant in self.has_fpu:
            self.cpu_params.update(p_FPU=1)
            add_manifest_sources(platform, 'cv32e40p_fpu_manifest.flist')
예제 #4
0
파일: gen.py 프로젝트: sergachev/litepcie
    def __init__(self, platform, core_config):
        platform.add_extension(get_pcie_ios(core_config["phy_lanes"]))
        for i in range(core_config["dma_channels"]):
            platform.add_extension(
                get_axi_dma_ios(i, core_config["phy_data_width"]))
        platform.add_extension(get_msi_irqs_ios(width=core_config["msi_irqs"]))
        sys_clk_freq = float(core_config.get("clk_freq", 125e6))

        # SoCMini ----------------------------------------------------------------------------------
        SoCMini.__init__(self,
                         platform,
                         clk_freq=sys_clk_freq,
                         csr_data_width=32,
                         csr_ordering=core_config.get("csr_ordering", "big"),
                         ident="LitePCIe standalone core",
                         ident_version=True)

        # CRG --------------------------------------------------------------------------------------
        clk_external = core_config.get("clk_external", False)
        self.submodules.crg = LitePCIeCRG(platform, sys_clk_freq, clk_external)

        # PCIe PHY ---------------------------------------------------------------------------------
        self.submodules.pcie_phy = core_config["phy"](
            platform,
            platform.request("pcie"),
            pcie_data_width=core_config.get("phy_pcie_data_width", 64),
            data_width=core_config["phy_data_width"],
            bar0_size=core_config["phy_bar0_size"])

        # PCIe Endpoint ----------------------------------------------------------------------------
        self.submodules.pcie_endpoint = LitePCIeEndpoint(
            self.pcie_phy,
            endianness=self.pcie_phy.endianness,
            max_pending_requests=core_config.get("ep_max_pending_requests", 4))

        # PCIe Wishbone Master ---------------------------------------------------------------------
        pcie_wishbone_master = LitePCIeWishboneMaster(
            self.pcie_endpoint, qword_aligned=self.pcie_phy.qword_aligned)
        self.submodules += pcie_wishbone_master
        self.add_wb_master(pcie_wishbone_master.wishbone)

        # PCIe MMAP Master -------------------------------------------------------------------------
        if core_config.get("mmap", False):
            mmap_base = core_config["mmap_base"]
            mmap_size = core_config["mmap_size"]
            mmap_translation = core_config.get("mmap_translation", 0x00000000)
            wb = wishbone.Interface(data_width=32)
            self.mem_map["mmap"] = mmap_base
            self.add_wb_slave(mmap_base, wb, mmap_size)
            self.add_memory_region("mmap", mmap_base, mmap_size, type="io")
            axi = AXILiteInterface(data_width=32, address_width=32)
            wb2axi = Wishbone2AXILite(wb, axi, base_address=-mmap_translation)
            self.submodules += wb2axi
            platform.add_extension(axi.get_ios("mmap_axi_lite"))
            axi_pads = platform.request("mmap_axi_lite")
            self.comb += axi.connect_to_pads(axi_pads, mode="master")

        # PCIe MMAP Slave --------------------------------------------------------------------------
        if core_config.get("mmap_slave", False):
            # AXI-Full
            if core_config.get("mmap_slave_axi_full", False):
                pcie_axi_slave = LitePCIeAXISlave(self.pcie_endpoint,
                                                  data_width=128)
                self.submodules += pcie_axi_slave
                platform.add_extension(
                    pcie_axi_slave.axi.get_ios("mmap_slave_axi"))
                axi_pads = platform.request("mmap_slave_axi")
                self.comb += pcie_axi_slave.axi.connect_to_pads(axi_pads,
                                                                mode="slave")
            # AXI-Lite
            else:
                platform.add_extension(axi.get_ios("mmap_slave_axi_lite"))
                axi_pads = platform.request("mmap_slave_axi_lite")
                wb = wishbone.Interface(data_width=32)
                axi = AXILiteInterface(data_width=32, address_width=32)
                self.comb += axi.connect_to_pads(axi_pads, mode="slave")
                axi2wb = AXILite2Wishbone(axi, wb)
                self.submodules += axi2wb
                pcie_wishbone_slave = LitePCIeWishboneSlave(
                    self.pcie_endpoint,
                    qword_aligned=self.pcie_phy.qword_aligned)
                self.submodules += pcie_wishbone_slave
                self.comb += wb.connect(pcie_wishbone_slave.wishbone)

        # PCIe DMA ---------------------------------------------------------------------------------
        pcie_dmas = []
        self.add_constant("DMA_CHANNELS", core_config["dma_channels"])
        for i in range(core_config["dma_channels"]):
            pcie_dma = LitePCIeDMA(
                self.pcie_phy,
                self.pcie_endpoint,
                with_buffering=core_config["dma_buffering"] != 0,
                buffering_depth=core_config["dma_buffering"],
                with_loopback=core_config["dma_loopback"],
                with_synchronizer=core_config["dma_synchronizer"],
                with_monitor=core_config["dma_monitor"])
            pcie_dma = stream.BufferizeEndpoints({"sink":
                                                  stream.DIR_SINK})(pcie_dma)
            pcie_dma = stream.BufferizeEndpoints({"source":
                                                  stream.DIR_SOURCE})(pcie_dma)
            setattr(self.submodules, "pcie_dma" + str(i), pcie_dma)
            self.add_csr("pcie_dma{}".format(i))
            dma_writer_ios = platform.request("dma{}_writer_axi".format(i))
            dma_reader_ios = platform.request("dma{}_reader_axi".format(i))
            self.comb += [
                # Writer IOs
                pcie_dma.sink.valid.eq(dma_writer_ios.tvalid),
                dma_writer_ios.tready.eq(pcie_dma.sink.ready),
                pcie_dma.sink.last.eq(dma_writer_ios.tlast),
                pcie_dma.sink.data.eq(dma_writer_ios.tdata),
                pcie_dma.sink.first.eq(dma_writer_ios.tuser),

                # Reader IOs
                dma_reader_ios.tvalid.eq(pcie_dma.source.valid),
                pcie_dma.source.ready.eq(dma_reader_ios.tready),
                dma_reader_ios.tlast.eq(pcie_dma.source.last),
                dma_reader_ios.tdata.eq(pcie_dma.source.data),
                dma_reader_ios.tuser.eq(pcie_dma.source.first),
            ]

        # PCIe MSI ---------------------------------------------------------------------------------
        if core_config.get("msi_x", False):
            assert core_config["msi_irqs"] <= 32
            self.submodules.pcie_msi = LitePCIeMSIX(self.pcie_endpoint,
                                                    width=64)
            self.comb += self.pcie_msi.irqs[32:32 +
                                            core_config["msi_irqs"]].eq(
                                                platform.request("msi_irqs"))
        else:
            assert core_config["msi_irqs"] <= 16
            if core_config.get("msi_multivector", False):
                self.submodules.pcie_msi = LitePCIeMSIMultiVector(width=32)
            else:
                self.submodules.pcie_msi = LitePCIeMSI(width=32)
            self.comb += self.pcie_msi.source.connect(self.pcie_phy.msi)
            self.comb += self.pcie_msi.irqs[16:16 +
                                            core_config["msi_irqs"]].eq(
                                                platform.request("msi_irqs"))
        self.interrupts = {}
        for i in range(core_config["dma_channels"]):
            self.interrupts["pcie_dma" + str(i) + "_writer"] = getattr(
                self, "pcie_dma" + str(i)).writer.irq
            self.interrupts["pcie_dma" + str(i) + "_reader"] = getattr(
                self, "pcie_dma" + str(i)).reader.irq
        for i, (k, v) in enumerate(sorted(self.interrupts.items())):
            self.comb += self.pcie_msi.irqs[i].eq(v)
            self.add_constant(k.upper() + "_INTERRUPT", i)
        assert len(self.interrupts.keys()) <= 16
예제 #5
0
 def test_wishbone_8bit(self):
     # Verify Wishbone with 8-bit data width.
     data = self.pattern_test_data["8bit"]
     wb   = wishbone.Interface(adr_width=30, data_width=8)
     port = LiteDRAMNativePort("both", address_width=30, data_width=8)
     self.wishbone_readback_test(data["pattern"], data["expected"], wb, port)
예제 #6
0
    def __init__(self, platform):
        self.bus = bus = wishbone.Interface()
        wdata = Signal(32)
        wmask = Signal(4)
        wdata_we = Signal()
        wdata_avail = Signal()
        wdata_ready = Signal()
        self.sync.clk50 += [
            wdata_avail.eq(bus.cyc & bus.stb & bus.we),
            If(
                bus.cyc & bus.stb & bus.we & ~bus.ack,
                If(
                    wdata_ready,
                    wdata.eq(bus.dat_w),
                    wmask.eq(bus.sel),
                    wdata_we.eq(1),
                    bus.ack.eq(
                        1
                    ),  #### TODO check that this works with the clk50->clk100 domain crossing
                ).Else(
                    wdata_we.eq(0),
                    bus.ack.eq(0),
                )).Else(
                    wdata_we.eq(0),
                    bus.ack.eq(0),
                )
        ]

        self.key_re = Signal(8)
        for k in range(0, 8):
            setattr(
                self, "key" + str(k),
                CSRStorage(32,
                           name="key" + str(k),
                           description="""secret key word {}""".format(k)))
            self.key_re[k].eq(getattr(self, "key" + str(k)).re)

        self.config = CSRStorage(
            description="Configuration register for the HMAC block",
            fields=[
                CSRField("sha_en",
                         size=1,
                         description="Enable the SHA256 core"),
                CSRField("endian_swap",
                         size=1,
                         description="Swap the endianness on the input data"),
                CSRField(
                    "digest_swap",
                    size=1,
                    description="Swap the endianness on the output digest"),
                CSRField("hmac_en", size=1,
                         description="Enable the HMAC core"),
            ])
        control_latch = Signal(self.config.size)
        ctrl_freeze = Signal()
        self.sync.clk50 += [
            If(ctrl_freeze, control_latch.eq(control_latch)).Else(
                control_latch.eq(self.config.storage))
        ]
        self.command = CSRStorage(
            description="Command register for the HMAC block",
            fields=[
                CSRField("hash_start",
                         size=1,
                         description=
                         "Writing a 1 indicates the beginning of hash data",
                         pulse=True),
                CSRField("hash_process",
                         size=1,
                         description="Writing a 1 digests the hash data",
                         pulse=True),
            ])

        self.wipe = CSRStorage(
            32,
            description=
            "wipe the secret key using the written value. Wipe happens upon write."
        )

        for k in range(0, 8):
            setattr(
                self, "digest" + str(k),
                CSRStatus(32,
                          name="digest" + str(k),
                          description="""digest word {}""".format(k)))

        self.msg_length = CSRStatus(
            size=64, description="Length of digested message, in bits")
        self.error_code = CSRStatus(size=32, description="Error code")

        self.submodules.ev = EventManager()
        self.ev.err_valid = EventSourcePulse(
            description="Error flag was generated")
        self.ev.fifo_full = EventSourcePulse(description="FIFO is full")
        self.ev.hash_done = EventSourcePulse(description="HMAC is done")
        self.ev.sha256_done = EventSourcePulse(description="SHA256 is done")
        self.ev.finalize()
        err_valid = Signal()
        err_valid_r = Signal()
        fifo_full = Signal()
        fifo_full_r = Signal()
        hmac_hash_done = Signal()
        sha256_hash_done = Signal()
        self.sync += [
            err_valid_r.eq(err_valid),
            fifo_full_r.eq(fifo_full),
        ]
        self.comb += [
            self.ev.err_valid.trigger.eq(~err_valid_r & err_valid),
            self.ev.fifo_full.trigger.eq(~fifo_full_r & fifo_full),
            self.ev.hash_done.trigger.eq(hmac_hash_done),
            self.ev.sha256_done.trigger.eq(sha256_hash_done),
        ]

        # At a width of 32 bits, an 36kiB fifo is 1024 entries deep
        fifo_wvalid = Signal()
        fifo_wdata_mask = Signal(36)
        fifo_rready = Signal()
        fifo_rdata_mask = Signal(36)
        self.fifo = CSRStatus(description="FIFO status",
                              fields=[
                                  CSRField("read_count",
                                           size=10,
                                           description="read pointer"),
                                  CSRField("write_count",
                                           size=10,
                                           description="write pointer"),
                                  CSRField("read_error",
                                           size=1,
                                           description="read error occurred"),
                                  CSRField("write_error",
                                           size=1,
                                           description="write error occurred"),
                                  CSRField("almost_full",
                                           size=1,
                                           description="almost full"),
                                  CSRField("almost_empty",
                                           size=1,
                                           description="almost empty"),
                              ])
        fifo_rvalid = Signal()
        fifo_empty = Signal()
        fifo_wready = Signal()
        fifo_full_local = Signal()
        self.comb += fifo_rvalid.eq(~fifo_empty)
        self.comb += fifo_wready.eq(~fifo_full_local)
        self.specials += Instance(
            "FIFO36E1",
            p_DATA_WIDTH=36,
            p_ALMOST_EMPTY_OFFSET=8,
            p_ALMOST_FULL_OFFSET=8,
            p_DO_REG=1,
            p_FIRST_WORD_FALL_THROUGH="TRUE",
            p_EN_SYN="FALSE",
            i_RDCLK=ClockSignal("clk50"),
            i_WRCLK=ClockSignal("clk50"),
            i_RST=ResetSignal("clk50"),
            o_FULL=fifo_full_local,
            i_WREN=fifo_wvalid,
            i_DI=fifo_wdata_mask[:32],
            i_DIP=fifo_wdata_mask[32:],
            o_EMPTY=fifo_empty,
            i_RDEN=fifo_rready & fifo_rvalid,
            o_DO=fifo_rdata_mask[:32],
            o_DOP=fifo_rdata_mask[32:],
            o_RDCOUNT=self.fifo.fields.read_count,
            o_RDERR=self.fifo.fields.read_error,
            o_WRCOUNT=self.fifo.fields.write_count,
            o_WRERR=self.fifo.fields.write_error,
            o_ALMOSTFULL=self.fifo.fields.almost_full,
            o_ALMOSTEMPTY=self.fifo.fields.almost_empty,
        )

        key_re_50 = Signal(8)
        for k in range(0, 8):
            setattr(self.submodules, 'keyre50_' + str(k),
                    BlindTransfer("sys", "clk50"))
            getattr(self, 'keyre50_' + str(k)).i.eq(
                getattr(self, 'key' + str(k)).re)
            self.comb += key_re_50[k].eq(getattr(self, 'keyre50_' + str(k)).o)

        hash_start_50 = Signal()
        self.submodules.hashstart = BlindTransfer("sys", "clk50")
        self.comb += [
            self.hashstart.i.eq(self.command.fields.hash_start),
            hash_start_50.eq(self.hashstart.o)
        ]

        hash_proc_50 = Signal()
        self.submodules.hashproc = BlindTransfer("sys", "clk50")
        self.comb += [
            self.hashproc.i.eq(self.command.fields.hash_process),
            hash_proc_50.eq(self.hashproc.o)
        ]

        wipe_50 = Signal()
        self.submodules.wipe50 = BlindTransfer("sys", "clk50")
        self.comb += [
            self.wipe50.i.eq(self.wipe.re),
            wipe_50.eq(self.wipe50.o)
        ]

        self.specials += Instance(
            "sha2_litex",
            i_clk_i=ClockSignal("clk50"),
            i_rst_ni=~ResetSignal("clk50"),
            i_secret_key_0=self.key0.storage,
            i_secret_key_1=self.key1.storage,
            i_secret_key_2=self.key2.storage,
            i_secret_key_3=self.key3.storage,
            i_secret_key_4=self.key4.storage,
            i_secret_key_5=self.key5.storage,
            i_secret_key_6=self.key6.storage,
            i_secret_key_7=self.key7.storage,
            i_secret_key_re=key_re_50,
            i_reg_hash_start=hash_start_50,
            i_reg_hash_process=hash_proc_50,
            o_ctrl_freeze=ctrl_freeze,
            i_sha_en=control_latch[0],
            i_endian_swap=control_latch[1],
            i_digest_swap=control_latch[2],
            i_hmac_en=control_latch[3],
            o_reg_hash_done=hmac_hash_done,
            o_sha_hash_done=sha256_hash_done,
            i_wipe_secret_re=wipe_50,
            i_wipe_secret_v=self.wipe.storage,
            o_digest_0=self.digest0.status,
            o_digest_1=self.digest1.status,
            o_digest_2=self.digest2.status,
            o_digest_3=self.digest3.status,
            o_digest_4=self.digest4.status,
            o_digest_5=self.digest5.status,
            o_digest_6=self.digest6.status,
            o_digest_7=self.digest7.status,
            o_msg_length=self.msg_length.status,
            o_error_code=self.error_code.status,
            i_msg_fifo_wdata=wdata,
            i_msg_fifo_write_mask=wmask,
            i_msg_fifo_we=wdata_we,
            i_msg_fifo_req=wdata_avail,
            o_msg_fifo_gnt=wdata_ready,
            o_local_fifo_wvalid=fifo_wvalid,
            i_local_fifo_wready=fifo_wready,
            o_local_fifo_wdata_mask=fifo_wdata_mask,
            i_local_fifo_rvalid=fifo_rvalid,
            o_local_fifo_rready=fifo_rready,
            i_local_fifo_rdata_mask=fifo_rdata_mask,
            o_err_valid=err_valid,
            i_err_valid_pending=self.ev.err_valid.pending,
            o_fifo_full_event=fifo_full,
        )

        platform.add_source(
            os.path.join("deps", "opentitan", "hw", "ip", "hmac", "rtl",
                         "hmac_pkg.sv"))
        platform.add_source(
            os.path.join("deps", "opentitan", "hw", "ip", "hmac", "rtl",
                         "sha2.sv"))
        platform.add_source(
            os.path.join("deps", "opentitan", "hw", "ip", "hmac", "rtl",
                         "sha2_pad.sv"))
        platform.add_source(
            os.path.join("deps", "opentitan", "hw", "ip", "prim", "rtl",
                         "prim_packer.sv"))
        platform.add_source(
            os.path.join("deps", "opentitan", "hw", "ip", "hmac", "rtl",
                         "hmac_core.sv"))
        platform.add_source(
            os.path.join("deps", "gateware", "gateware", "sha2_litex.sv"))
예제 #7
0
    def __init__(self, platform):
        self.sink = stream.Endpoint([("data", 16)])
        self.source = stream.Endpoint([("data", 8)])
        self.bus = wishbone.Interface()

        # # #

        # chroma upsampler
        self.submodules.chroma_upsampler = chroma_upsampler = ClockDomainsRenamer("encoder")(YCbCr422to444())
        self.comb += [
            Record.connect(self.sink, chroma_upsampler.sink, omit=["data"]),
            chroma_upsampler.sink.y.eq(self.sink.data[:8]),
            chroma_upsampler.sink.cb_cr.eq(self.sink.data[8:])
        ]

        fdct_fifo_rd = Signal()
        fdct_fifo_q = Signal(24)
        fdct_fifo_hf_full = Signal()

        fdct_data_d1 = Signal(24)
        fdct_data_d2 = Signal(24)
        fdct_data_d3 = Signal(24)
        fdct_data_d4 = Signal(24)
        fdct_data_d5 = Signal(24)

        self.sync.encoder += [
            If(fdct_fifo_rd,
                fdct_data_d1.eq(Cat(chroma_upsampler.source.y,
                                    chroma_upsampler.source.cb,
                                    chroma_upsampler.source.cr)),
            ),
            fdct_data_d2.eq(fdct_data_d1),
            fdct_data_d3.eq(fdct_data_d2),
            fdct_data_d4.eq(fdct_data_d3),
            fdct_data_d5.eq(fdct_data_d4)
        ]
        self.comb += [
            fdct_fifo_q.eq(fdct_data_d4),
            fdct_fifo_hf_full.eq(chroma_upsampler.source.valid),
            chroma_upsampler.source.ready.eq(fdct_fifo_rd)
        ]

        # output fifo
        output_fifo_almost_full = Signal()
        self.submodules.output_fifo = output_fifo = ClockDomainsRenamer("encoder")(stream.SyncFIFO([("data", 8)], 1024))
        self.comb += [
            output_fifo_almost_full.eq(output_fifo.fifo.level > 1024-128),
            Record.connect(output_fifo.source, self.source)
        ]

        # Wishbone cross domain crossing
        jpeg_bus = wishbone.Interface()
        self.specials += Instance("wb_async_reg",
                            i_wbm_clk=ClockSignal(),
                            i_wbm_rst=ResetSignal(),
                            i_wbm_adr_i=self.bus.adr,
                            i_wbm_dat_i=self.bus.dat_w,
                            o_wbm_dat_o=self.bus.dat_r,
                            i_wbm_we_i=self.bus.we,
                            i_wbm_sel_i=self.bus.sel,
                            i_wbm_stb_i=self.bus.stb,
                            o_wbm_ack_o=self.bus.ack,
                            o_wbm_err_o=self.bus.err,
                            #o_wbm_rty_o=,
                            i_wbm_cyc_i=self.bus.cyc,

                            i_wbs_clk=ClockSignal("encoder"),
                            i_wbs_rst=ResetSignal("encoder"),
                            o_wbs_adr_o=jpeg_bus.adr,
                            i_wbs_dat_i=jpeg_bus.dat_r,
                            o_wbs_dat_o=jpeg_bus.dat_w,
                            o_wbs_we_o=jpeg_bus.we,
                            o_wbs_sel_o=jpeg_bus.sel,
                            o_wbs_stb_o=jpeg_bus.stb,
                            i_wbs_ack_i=jpeg_bus.ack,
                            i_wbs_err_i=jpeg_bus.err,
                            i_wbs_rty_i=0,
                            o_wbs_cyc_o=jpeg_bus.cyc)


        # encoder
        self.specials += Instance("JpegEnc",
                            i_CLK=ClockSignal("encoder"),
                            i_RST=ResetSignal("encoder"),

            i_OPB_ABus=Cat(Signal(2), jpeg_bus.adr) & 0x3ff,
            i_OPB_BE=jpeg_bus.sel,
            i_OPB_DBus_in=jpeg_bus.dat_w,
            i_OPB_RNW=~jpeg_bus.we,
            i_OPB_select=jpeg_bus.stb & jpeg_bus.cyc,
            o_OPB_DBus_out=jpeg_bus.dat_r,
            o_OPB_XferAck=jpeg_bus.ack,
            #o_OPB_retry=,
            #o_OPB_toutSup=,
            o_OPB_errAck=jpeg_bus.err,

            o_fdct_fifo_rd=fdct_fifo_rd,
            i_fdct_fifo_q=fdct_fifo_q,
            i_fdct_fifo_hf_full=fdct_fifo_hf_full,
            #o_fdct_fifo_dval_o=,

            o_ram_byte=output_fifo.sink.data,
            o_ram_wren=output_fifo.sink.valid,
            #o_ram_wraddr=,
            #o_frame_size=,
            i_outif_almost_full=output_fifo_almost_full)

        # add vhdl sources
        platform.add_source_dir(os.path.join("gateware", "encoder", "vhdl"))
        # add verilog sources
        platform.add_source(os.path.join("gateware", "encoder", "verilog", "wb_async_reg.v"))
예제 #8
0
    def __init__(self, platform, connector="fmc", gen="gen3",
        with_global_analyzer     = False,
        with_sector2mem_analyzer = False,
        with_mem2sector_analyzer = False):
        assert connector in ["fmc", "sfp", "pcie"]
        assert gen in ["gen1", "gen2", "gen3"]
        sys_clk_freq  = int(200e6)
        sata_clk_freq = {"gen1": 75e6, "gen2": 150e6, "gen3": 300e6}[gen]

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = _CRG(platform, sys_clk_freq)

        # SoCMini ----------------------------------------------------------------------------------
        SoCMini.__init__(self, platform, sys_clk_freq,
            ident         = "LiteSATA bench on KC705",
            ident_version = True,
            with_uart     = True,
            uart_name     = "bridge")

        # SATA -------------------------------------------------------------------------------------
        # RefClk
        sata_refclk = None
        if connector != "fmc":
            # Generate 150MHz from PLL.
            self.clock_domains.cd_sata_refclk = ClockDomain()
            self.crg.pll.create_clkout(self.cd_sata_refclk, 150e6)
            sata_refclk = ClockSignal("sata_refclk")
            platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks REQP-52]")

        # PHY
        self.submodules.sata_phy = LiteSATAPHY(platform.device,
            refclk     = sata_refclk,
            pads       = platform.request(connector+"2sata"),
            gen        = gen,
            clk_freq   = sys_clk_freq,
            data_width = 16)
        self.add_csr("sata_phy")

        # Core
        self.submodules.sata_core = LiteSATACore(self.sata_phy)

        # Crossbar
        self.submodules.sata_crossbar = LiteSATACrossbar(self.sata_core)

        # BIST
        self.submodules.sata_bist = LiteSATABIST(self.sata_crossbar, with_csr=True)
        self.add_csr("sata_bist")

        # Sector2Mem DMA
        bus =  wishbone.Interface(data_width=32, adr_width=32)
        self.submodules.sata_sector2mem = LiteSATASector2MemDMA(self.sata_crossbar.get_port(), bus)
        self.bus.add_master("sata_sector2mem", master=bus)
        self.add_csr("sata_sector2mem")

        # Mem2Sector DMA
        bus =  wishbone.Interface(data_width=32, adr_width=32)
        self.submodules.sata_mem2sector = LiteSATAMem2SectorDMA(bus, self.sata_crossbar.get_port())
        self.bus.add_master("sata_mem2sector", master=bus)
        self.add_csr("sata_mem2sector")

        # Timing constraints
        platform.add_period_constraint(self.sata_phy.crg.cd_sata_tx.clk, 1e9/sata_clk_freq)
        platform.add_period_constraint(self.sata_phy.crg.cd_sata_rx.clk, 1e9/sata_clk_freq)
        self.platform.add_false_path_constraints(
            self.crg.cd_sys.clk,
            self.sata_phy.crg.cd_sata_tx.clk,
            self.sata_phy.crg.cd_sata_rx.clk)

        # Leds -------------------------------------------------------------------------------------
        # sys_clk
        sys_counter = Signal(32)
        self.sync.sys += sys_counter.eq(sys_counter + 1)
        self.comb += platform.request("user_led", 0).eq(sys_counter[26])
        # tx_clk
        tx_counter = Signal(32)
        self.sync.sata_tx += tx_counter.eq(tx_counter + 1)
        self.comb += platform.request("user_led", 1).eq(tx_counter[26])
        # rx_clk
        rx_counter = Signal(32)
        self.sync.sata_rx += rx_counter.eq(rx_counter + 1)
        self.comb += platform.request("user_led", 2).eq(rx_counter[26])
        # ready
        self.comb += platform.request("user_led", 3).eq(self.sata_phy.ctrl.ready)

        # Analyzers ---------------------------------------------------------------------------------
        if with_global_analyzer:
            analyzer_signals = [
                self.sata_phy.phy.tx_init.fsm,
                self.sata_phy.phy.rx_init.fsm,
                self.sata_phy.ctrl.fsm,

                self.sata_phy.ctrl.ready,
                self.sata_phy.source,
                self.sata_phy.sink,

                self.sata_core.command.sink,
                self.sata_core.command.source,

                self.sata_core.link.rx.fsm,
                self.sata_core.link.tx.fsm,
                self.sata_core.transport.rx.fsm,
                self.sata_core.transport.tx.fsm,
                self.sata_core.command.rx.fsm,
                self.sata_core.command.tx.fsm,
            ]
            self.submodules.global_analyzer = LiteScopeAnalyzer(analyzer_signals, 512, csr_csv="global_analyzer.csv")
            self.add_csr("global_analyzer")

        if with_sector2mem_analyzer:
            analyzer_signals = [
                self.sata_sector2mem.start.re,
                self.sata_sector2mem.fsm,
                self.sata_sector2mem.port.sink,
                self.sata_sector2mem.port.source,
                self.sata_sector2mem.bus,
            ]
            self.submodules.sector2mem_analyzer = LiteScopeAnalyzer(analyzer_signals, 2048, csr_csv="sector2mem_analyzer.csv")
            self.add_csr("sector2mem_analyzer")

        if with_mem2sector_analyzer:
            analyzer_signals = [
                self.sata_mem2sector.start.re,
                self.sata_mem2sector.fsm,
                self.sata_mem2sector.port.sink,
                self.sata_mem2sector.port.source,
                self.sata_mem2sector.bus,
            ]
            self.submodules.mem2sector_analyzer = LiteScopeAnalyzer(analyzer_signals, 2048, csr_csv="mem2sector_analyzer.csv")
            self.add_csr("mem2sector_analyzer")
예제 #9
0
    def __init__(self, pads=None, font_filename="cp437.bin", screen_init_filename="screen-init.bin"):
        # Wishbone interface
        self.bus = bus = wishbone.Interface(data_width=8)

        # Acknowledge immediately
        self.sync += [
            bus.ack.eq(0),
            If (bus.cyc & bus.stb & ~bus.ack, bus.ack.eq(1))
        ]

        # RAM initialization
        screen_init = read_ram_init_file(screen_init_filename, 4800)
        font = read_ram_init_file(font_filename, 4096)
        ram_init = screen_init + font

        # Create RAM
        mem = Memory(width=8, depth=8896, init=ram_init)
        self.specials += mem
        wrport = mem.get_port(write_capable=True, clock_domain="sys")
        self.specials += wrport
        rdport = mem.get_port(write_capable=False, clock_domain="vga")
        self.specials += rdport

        # Memory map internal block RAM to Wishbone interface
        self.sync += [
            wrport.we.eq(0),
            If (bus.cyc & bus.stb & bus.we,
                wrport.we.eq(1),
                wrport.adr.eq(bus.adr),
                wrport.dat_w.eq(bus.dat_w),
            )
        ]

        # Display resolution
        WIDTH  = 640
        HEIGHT = 480

        # Offset to font data in RAM
        FONT_ADDR = 80 * 30 * 2

        # VGA output
        self.red   = red   = Signal(8) if pads is None else pads.red
        self.green = green = Signal(8) if pads is None else pads.green
        self.blue  = blue  = Signal(8) if pads is None else pads.blue
        self.hsync = hsync = Signal()  if pads is None else pads.hsync
        self.vsync = vsync = Signal()  if pads is None else pads.vsync

        # VGA timings
        H_SYNC_PULSE  = 96
        H_BACK_PORCH  = 48 + H_SYNC_PULSE
        H_DATA        = WIDTH + H_BACK_PORCH
        H_FRONT_PORCH = 16 + H_DATA

        V_SYNC_PULSE  = 2
        V_BACK_PORCH  = 29 + V_SYNC_PULSE
        V_DATA        = HEIGHT + V_BACK_PORCH
        V_FRONT_PORCH = 10 + V_DATA

        pixel_counter = Signal(10)
        line_counter  = Signal(10)

        # Read address in text RAM
        text_addr = Signal(16)

        # Read address in text RAM at line start
        text_addr_start = Signal(16)

        # Current line within a character, 0 to 15
        fline = Signal(4)

        # Current x position within a character, 0 to 7
        fx = Signal(3)

        # Current and next byte for a character line
        fbyte     = Signal(8)
        next_byte = Signal(8)

        # Current foreground color
        fgcolor      = Signal(24)
        next_fgcolor = Signal(24)

        # Current background color
        bgcolor = Signal(24)

        # Current fg/bg color index from RAM
        color = Signal(8)

        # Color index and lookup
        color_index  = Signal(4)
        color_lookup = Signal(24)

        # VGA palette
        palette = [
            0x000000, 0x0000aa, 0x00aa00, 0x00aaaa, 0xaa0000, 0xaa00aa, 0xaa5500, 0xaaaaaa,
            0x555555, 0x5555ff, 0x55ff55, 0x55ffff, 0xff5555, 0xff55ff, 0xffff55, 0xffffff
        ]
        cases = {}
        for i in range(16):
            cases[i] = color_lookup.eq(palette[i])
        self.comb += Case(color_index, cases)

        self.sync.vga += [
            # Default values
            red.eq(0),
            green.eq(0),
            blue.eq(0),

            # Show pixels
            If((line_counter >= V_BACK_PORCH) & (line_counter < V_DATA),
                If((pixel_counter >= H_BACK_PORCH) & (pixel_counter < H_DATA),
                    If(fbyte[7],
                        red.eq(fgcolor[16:24]),
                        green.eq(fgcolor[8:16]),
                        blue.eq(fgcolor[0:8])
                    ).Else(
                        red.eq(bgcolor[16:24]),
                        green.eq(bgcolor[8:16]),
                        blue.eq(bgcolor[0:8])
                    ),
                    fbyte.eq(Cat(Signal(), fbyte[:-1]))
                )
            ),

            # Load next character code, font line and color
            If(fx == 1,
                # schedule reading the character code
                rdport.adr.eq(text_addr),
                text_addr.eq(text_addr + 1)
            ),
            If(fx == 2,
                # Schedule reading the color
                rdport.adr.eq(text_addr),
                text_addr.eq(text_addr + 1)
            ),
            If(fx == 3,
                # Read character code, and set address for font line
                rdport.adr.eq(FONT_ADDR + Cat(Signal(4), rdport.dat_r) + fline)
            ),
            If(fx == 4,
                # Read color
                color.eq(rdport.dat_r)
            ),
            If(fx == 5,
                # Read font line, and set color index to get foreground color
                next_byte.eq(rdport.dat_r),
                color_index.eq(color[0:4]),
            ),
            If(fx == 6,
                # Get next foreground color, and set color index for background color
                next_fgcolor.eq(color_lookup),
                color_index.eq(color[4:8])
            ),
            If(fx == 7,
                # Set background color and everything for the next 8 pixels
                bgcolor.eq(color_lookup),
                fgcolor.eq(next_fgcolor),
                fbyte.eq(next_byte)
            ),
            fx.eq(fx + 1),
            If(fx == 7, fx.eq(0)),

            # Horizontal timing for one line
            pixel_counter.eq(pixel_counter + 1),
            If(pixel_counter < H_SYNC_PULSE,
                hsync.eq(0)
            ).Elif (pixel_counter < H_BACK_PORCH,
                hsync.eq(1)
            ),
            If(pixel_counter == H_BACK_PORCH - 9,
                # Prepare reading first character of next line
                fx.eq(0),
                text_addr.eq(text_addr_start)
            ),
            If(pixel_counter == H_FRONT_PORCH,
                # Initilize next line
                pixel_counter.eq(0),
                line_counter.eq(line_counter + 1),

                # Font height is 16 pixels
                fline.eq(fline + 1),
                If(fline == 15,
                    fline.eq(0),
                    text_addr_start.eq(text_addr_start + 2 * 80)
                )
            ),

            # Vertical timing for one screen
            If(line_counter < V_SYNC_PULSE,
                vsync.eq(0)
            ).Elif(line_counter < V_BACK_PORCH,
                vsync.eq(1)
            ),
            If(line_counter == V_FRONT_PORCH,
                # End of image
                line_counter.eq(0)
            ),
            If(line_counter == V_BACK_PORCH - 1,
                # Prepare generating next image data
                fline.eq(0),
                text_addr_start.eq(0)
            )
        ]
예제 #10
0
    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)
예제 #11
0
    def __init__(self,
                 pad,
                 nleds,
                 sys_clk_freq,
                 bus_mastering=False,
                 bus_base=None,
                 revision="new",
                 init=None):
        if bus_mastering:
            self.bus = bus = wishbone.Interface(data_width=32)
        else:
            # Memory.
            mem = Memory(32, nleds, init=init)
            port = mem.get_port()
            self.specials += mem, port

            # Wishone Memory.
            self.submodules.wb_mem = wishbone.SRAM(
                mem_or_size=mem,
                read_only=False,
                bus=wishbone.Interface(data_width=32))
            self.bus = self.wb_mem.bus

        # Internal Signals.
        led_count = Signal(max=nleds)
        led_data = Signal(24)
        xfer_start = Signal()
        xfer_done = Signal()
        xfer_data = Signal(24)

        # Timings
        self.trst = trst = {
            "old": 50e-6 * 1.25,
            "new": 280e-6 * 1.25
        }[revision]
        self.t0h = t0h = 0.40e-6
        self.t0l = t0l = 0.85e-6
        self.t1h = t1h = 0.80e-6
        self.t1l = t1l = 0.45e-6

        # Timers.
        trst_timer = WaitTimer(int(trst * sys_clk_freq))
        self.submodules += trst_timer

        t0h_timer = WaitTimer(int(t0h * sys_clk_freq))
        t0l_timer = WaitTimer(int(t0l * sys_clk_freq) -
                              1)  # Compensate Xfer FSM latency.
        self.submodules += t0h_timer, t0l_timer

        t1h_timer = WaitTimer(int(t1h * sys_clk_freq))
        t1l_timer = WaitTimer(int(t1l * sys_clk_freq) -
                              1)  # Compensate Xfer FSM latency.
        self.submodules += t1h_timer, t1l_timer

        # Main FSM.
        self.submodules.fsm = fsm = FSM(reset_state="RST")
        fsm.act("RST", NextValue(led_count, 0), trst_timer.wait.eq(xfer_done),
                If(trst_timer.done, NextState("LED-READ")))
        if bus_mastering:
            fsm.act(
                "LED-READ", bus.stb.eq(1), bus.cyc.eq(1), bus.we.eq(0),
                bus.sel.eq(2**(bus.data_width // 8) - 1),
                bus.adr.eq(bus_base[2:] + led_count),
                If(bus.ack, NextValue(led_data, bus.dat_r),
                   NextState("LED-SEND")))
        else:
            self.comb += port.adr.eq(led_count)
            fsm.act("LED-READ", NextState("LED-LATCH"))
            fsm.act("LED-LATCH", NextValue(led_data, port.dat_r),
                    NextState("LED-SEND"))

        fsm.act("LED-SEND",
                If(xfer_done, xfer_start.eq(1), NextState("LED-SHIFT")))
        fsm.act(
            "LED-SHIFT",
            If(led_count == (nleds - 1),
               NextState("RST")).Else(NextValue(led_count, led_count + 1),
                                      NextState("LED-READ")))

        # XFER FSM.
        xfer_bit = Signal(5)
        xfer_fsm = FSM(reset_state="IDLE")
        self.submodules += xfer_fsm
        xfer_fsm.act(
            "IDLE", xfer_done.eq(1),
            If(xfer_start, NextValue(xfer_bit, 24 - 1),
               NextValue(xfer_data, led_data), NextState("RUN")))
        xfer_fsm.act(
            "RUN",
            # Send a one.
            If(
                xfer_data[-1],
                t1h_timer.wait.eq(1),
                t1l_timer.wait.eq(t1h_timer.done),
                pad.eq(~t1h_timer.done),
                # Send a zero.
            ).Else(
                t0h_timer.wait.eq(1),
                t0l_timer.wait.eq(t0h_timer.done),
                pad.eq(~t0h_timer.done),
            ),

            # When bit has been sent:
            If(
                t0l_timer.done | t1l_timer.done,
                # Clear wait on timers.
                t0h_timer.wait.eq(0),
                t0l_timer.wait.eq(0),
                t1h_timer.wait.eq(0),
                t1l_timer.wait.eq(0),
                # Shift xfer_data.
                NextValue(xfer_data, Cat(Signal(), xfer_data)),
                # Decrement xfer_bit.
                NextValue(xfer_bit, xfer_bit - 1),
                # When xfer_bit reaches 0.
                If(xfer_bit == 0, NextState("IDLE"))))
예제 #12
0
파일: core.py 프로젝트: miracleswt/litex
    def __init__(self, platform, cpu_reset_address, variant=None):
        assert variant in (None, "debug"), "Unsupported variant %s" % variant
        self.reset = Signal()
        self.ibus = i = wishbone.Interface()
        self.dbus = d = wishbone.Interface()
        i_err = Signal()
        d_err = Signal()

        self.interrupt = Signal(32)

        # Output reset signal -- set to 1 when CPU reset is asserted
        self.debug_reset = Signal()

        if variant == None:
            cpu_reset = ResetSignal()
            cpu_args = {}
            cpu_filename = "VexRiscv.v"
        elif variant == "debug":
            cpu_reset = Signal()
            cpu_args = {}
            cpu_filename = "VexRiscv-Debug.v"


            self.i_cmd_valid = Signal()
            self.i_cmd_payload_wr = Signal()
            self.i_cmd_payload_address = Signal(8)
            self.i_cmd_payload_data = Signal(32)
            self.o_cmd_ready = Signal()
            self.o_rsp_data = Signal(32)
            self.o_resetOut = Signal()

            reset_debug_logic = Signal()

            self.transfer_complete = Signal()
            self.transfer_in_progress = Signal()
            self.transfer_wait_for_ack = Signal()

            self.debug_bus = wishbone.Interface()

            self.sync += [
                self.debug_bus.dat_r.eq(self.o_rsp_data),
                cpu_reset.eq(reset_debug_logic | ResetSignal()),
            ]

            self.sync += [
                # CYC is held high for the duration of the transfer.
                # STB is kept high when the transfer finishes (write)
                # or the master is waiting for data (read), and stays
                # there until ACK, ERR, or RTY are asserted.
                If((self.debug_bus.stb & self.debug_bus.cyc)
                & (~self.transfer_in_progress)
                & (~self.transfer_complete)
                & (~self.transfer_wait_for_ack),
                    self.i_cmd_payload_data.eq(self.debug_bus.dat_w),
                    self.i_cmd_payload_address.eq((self.debug_bus.adr[0:6] << 2) | 0),
                    self.i_cmd_payload_wr.eq(self.debug_bus.we),
                    self.i_cmd_valid.eq(1),
                    self.transfer_in_progress.eq(1),
                    self.transfer_complete.eq(0),
                    self.debug_bus.ack.eq(0)
                ).Elif(self.transfer_in_progress,
                    If(self.o_cmd_ready,
                        self.i_cmd_valid.eq(0),
                        self.i_cmd_payload_wr.eq(0),
                        self.transfer_complete.eq(1),
                        self.transfer_in_progress.eq(0)
                    )
                ).Elif(self.transfer_complete,
                    self.transfer_complete.eq(0),
                    self.debug_bus.ack.eq(1),
                    self.transfer_wait_for_ack.eq(1)
                ).Elif(self.transfer_wait_for_ack & ~(self.debug_bus.stb & self.debug_bus.cyc),
                    self.transfer_wait_for_ack.eq(0),
                    self.debug_bus.ack.eq(0)
                ),
                # Force a Wishbone error if transferring during a reset sequence.
                # Because o_resetOut is multiple cycles and i.stb/d.stb should
                # deassert one cycle after i_err/i_ack/d_err/d_ack are asserted,
                # this will give i_err and o_err enough time to be reset to 0
                # once the reset cycle finishes.
                If(self.o_resetOut,
                    If(i.cyc & i.stb, i_err.eq(1)).Else(i_err.eq(0)),
                    If(d.cyc & d.stb, d_err.eq(1)).Else(d_err.eq(0)),
                    reset_debug_logic.eq(1))
                .Else(
                    reset_debug_logic.eq(0)
                )
            ]

            cpu_args.update({
                "i_debugReset": ResetSignal(),
                "i_debug_bus_cmd_valid": self.i_cmd_valid,
                "i_debug_bus_cmd_payload_wr": self.i_cmd_payload_wr,
                "i_debug_bus_cmd_payload_address": self.i_cmd_payload_address,
                "i_debug_bus_cmd_payload_data": self.i_cmd_payload_data,
                "o_debug_bus_cmd_ready": self.o_cmd_ready,
                "o_debug_bus_rsp_data": self.o_rsp_data,
                "o_debug_resetOut": self.o_resetOut
            })

        self.comb += [
            i.err.eq(i_err),
            d.err.eq(d_err),
        ]
        self.specials += Instance("VexRiscv",
                **cpu_args,

                i_clk=ClockSignal(),
                i_reset=cpu_reset | self.reset,

                i_externalResetVector=cpu_reset_address,
                i_externalInterruptArray=self.interrupt,
                i_timerInterrupt=0,

                o_iBusWishbone_ADR=i.adr,
                o_iBusWishbone_DAT_MOSI=i.dat_w,
                o_iBusWishbone_SEL=i.sel,
                o_iBusWishbone_CYC=i.cyc,
                o_iBusWishbone_STB=i.stb,
                o_iBusWishbone_WE=i.we,
                o_iBusWishbone_CTI=i.cti,
                o_iBusWishbone_BTE=i.bte,
                i_iBusWishbone_DAT_MISO=i.dat_r,
                i_iBusWishbone_ACK=i.ack,
                i_iBusWishbone_ERR=i_err,

                o_dBusWishbone_ADR=d.adr,
                o_dBusWishbone_DAT_MOSI=d.dat_w,
                o_dBusWishbone_SEL=d.sel,
                o_dBusWishbone_CYC=d.cyc,
                o_dBusWishbone_STB=d.stb,
                o_dBusWishbone_WE=d.we,
                o_dBusWishbone_CTI=d.cti,
                o_dBusWishbone_BTE=d.bte,
                i_dBusWishbone_DAT_MISO=d.dat_r,
                i_dBusWishbone_ACK=d.ack,
                i_dBusWishbone_ERR=d_err)

        # add verilog sources
        self.add_sources(platform, cpu_filename)
예제 #13
0
파일: core.py 프로젝트: tcal-x/litex
    def __init__(self, platform, variant="standard"):
        self.platform     = platform
        self.variant      = variant
        self.reset        = Signal()
        self.idbus        = idbus = wishbone.Interface()
        self.periph_buses = [idbus] # Peripheral buses (Connected to main SoC's bus).
        self.memory_buses = []      # Memory buses (Connected directly to LiteDRAM).

        # # #

        # FemtoRV Mem Bus.
        # ----------------
        mbus = Record([
            ("addr",  32),
            ("wdata", 32),
            ("wmask",  4),
            ("rdata", 32),
            ("rstrb",  1),
            ("rbusy",  1),
            ("wbusy",  1),
        ])

        # FemtoRV Instance.
        # -----------------
        self.cpu_params = dict(
            # Parameters.
            p_ADDR_WIDTH = 32,
            p_RESET_ADDR = Constant(0, 32),

            # Clk / Rst.
            i_clk   = ClockSignal("sys"),
            i_reset = ~ResetSignal("sys"), # Active Low.

            # I/D Bus.
            o_mem_addr  = mbus.addr,
            o_mem_wdata = mbus.wdata,
            o_mem_wmask = mbus.wmask,
            i_mem_rdata = mbus.rdata,
            o_mem_rstrb = mbus.rstrb,
            i_mem_rbusy = mbus.rbusy,
            i_mem_wbusy = mbus.wbusy,
        )

        # Adapt FemtoRV Mem Bus to Wishbone.
        # ----------------------------------

        # Bytes to Words addressing conversion.
        self.comb += idbus.adr.eq(mbus.addr[2:])

        # Wdata/WMask direct connection.
        self.comb += idbus.dat_w.eq(mbus.wdata)
        self.comb += idbus.sel.eq(mbus.wmask)

        # Control adaptation.
        latch = Signal()
        write = mbus.wmask != 0
        read  = mbus.rstrb

        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act("IDLE",
            idbus.stb.eq(read | write),
            idbus.cyc.eq(read | write),
            idbus.we.eq(write),
            If(read,
                mbus.rbusy.eq(1),
                NextState("READ")
            ).Elif(write,
                mbus.wbusy.eq(1),
                NextState("WRITE")
            )
        )
        fsm.act("READ",
            idbus.stb.eq(1),
            idbus.cyc.eq(1),
            mbus.rbusy.eq(1),
            If(idbus.ack,
                latch.eq(1),
                NextState("IDLE")
            )
        )
        fsm.act("WRITE",
            idbus.stb.eq(1),
            idbus.cyc.eq(1),
            idbus.we.eq(1),
            mbus.wbusy.eq(1),
            If(idbus.ack,
                NextState("IDLE")
            )
        )

        # Latch RData on Wishbone ack.
        self.sync += If(latch, mbus.rdata.eq(idbus.dat_r))

        # Add Verilog sources.
        # --------------------
        self.add_sources(platform)
예제 #14
0
파일: spi_flash.py 프로젝트: zeta1999/litex
    def __init__(self, pads, dummy=15, div=2, with_bitbang=True, endianness="big"):
        """
        Simple SPI flash.
        Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast
        Read). Only supports mode3 (cpol=1, cpha=1).
        """
        SpiFlashCommon.__init__(self, pads)
        self.bus = bus = wishbone.Interface()
        spi_width = len(pads.dq)
        assert spi_width >= 2

        if with_bitbang:
            self.bitbang = CSRStorage(4, reset_less=True, fields=[
                CSRField("mosi", description="Output value for MOSI pin, valid whenever ``dir`` is ``0``."),
                CSRField("clk", description="Output value for SPI CLK pin."),
                CSRField("cs_n", description="Output value for SPI CSn pin."),
                CSRField("dir", description="Sets the direction for *ALL* SPI data pins except CLK and CSn.", values=[
                    ("0", "OUT", "SPI pins are all output"),
                    ("1", "IN", "SPI pins are all input"),
                ])
            ], description="""
                Bitbang controls for SPI output.  Only standard 1x SPI is supported, and as
                a result all four wires are ganged together.  This means that it is only possible
                to perform half-duplex operations, using this SPI core.
            """)
            self.miso = CSRStatus(description="Incoming value of MISO signal.")
            self.bitbang_en = CSRStorage(description="Write a ``1`` here to disable memory-mapped mode and enable bitbang mode.")

        # # #

        cs_n = Signal(reset=1)
        clk = Signal()
        dq_oe = Signal()
        wbone_width = len(bus.dat_r)


        read_cmd_params = {
            4: (_format_cmd(_QIOFR, 4), 4*8),
            2: (_format_cmd(_DIOFR, 2), 2*8),
            1: (_format_cmd(_FAST_READ, 1), 1*8)
        }
        read_cmd, cmd_width = read_cmd_params[spi_width]
        addr_width = 24

        dq = TSTriple(spi_width)
        # Keep DQ2,DQ3 as outputs during bitbang, this ensures they activate ~WP or ~HOLD functions
        self.specials.dq0 = Tristate(pads.dq[0], o=dq.o[0], i=dq.i[0], oe=dq.oe)
        self.specials.dq1 = Tristate(pads.dq[1], o=dq.o[1], i=dq.i[1], oe=dq.oe)
        self.specials.dq2 = Tristate(pads.dq[2], o=dq.o[2], i=dq.i[2], oe=(dq.oe | self.bitbang_en.storage))
        self.specials.dq3 = Tristate(pads.dq[3], o=dq.o[3], i=dq.i[3], oe=(dq.oe | self.bitbang_en.storage))

        sr = Signal(max(cmd_width, addr_width, wbone_width))
        if endianness == "big":
            self.comb += bus.dat_r.eq(sr)
        else:
            self.comb += bus.dat_r.eq(reverse_bytes(sr))

        hw_read_logic = [
            pads.clk.eq(clk),
            pads.cs_n.eq(cs_n),
            dq.o.eq(sr[-spi_width:]),
            dq.oe.eq(dq_oe)
        ]

        if with_bitbang:
            bitbang_logic = [
                pads.clk.eq(self.bitbang.storage[1]),
                pads.cs_n.eq(self.bitbang.storage[2]),

                # In Dual/Quad mode, no single data pin is consistently
                # an input or output thanks to dual/quad reads, so we need a bit
                # to swap direction of the pins. Aside from this additional bit,
                # bitbang mode is identical for Single/Dual/Quad; dq[0] is mosi
                # and dq[1] is miso, meaning remaining data pin values don't
                # appear in CSR registers.
                If(self.bitbang.storage[3],
                    dq.oe.eq(0)
                ).Else(
                    dq.oe.eq(1)
                ),
                If(self.bitbang.storage[1], # CPOL=0/CPHA=0 or CPOL=1/CPHA=1 only.
                    self.miso.status.eq(dq.i[1])
                ),
                dq.o.eq(Cat(self.bitbang.storage[0], Replicate(1, spi_width-1)))
            ]

            self.comb += [
                If(self.bitbang_en.storage,
                    bitbang_logic
                ).Else(
                    hw_read_logic
                )
            ]

        else:
            self.comb += hw_read_logic

        if div < 2:
            raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))
        else:
            i = Signal(max=div)
            dqi = Signal(spi_width)
            self.sync += [
                If(i == div//2 - 1,
                    clk.eq(1),
                    dqi.eq(dq.i),
                ),
                If(i == div - 1,
                    i.eq(0),
                    clk.eq(0),
                    sr.eq(Cat(dqi, sr[:-spi_width]))
                ).Else(
                    i.eq(i + 1),
                ),
            ]

        # spi is byte-addressed, prefix by zeros
        z = Replicate(0, log2_int(wbone_width//8))

        seq = [
            (cmd_width//spi_width*div,
                [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
            (addr_width//spi_width*div,
                [sr[-addr_width:].eq(Cat(z, bus.adr))]),
            ((dummy + wbone_width//spi_width)*div,
                [dq_oe.eq(0)]),
            (1,
                [bus.ack.eq(1), cs_n.eq(1)]),
            (div, # tSHSL!
                [bus.ack.eq(0)]),
            (0,
                []),
        ]

        # accumulate timeline deltas
        t, tseq = 0, []
        for dt, a in seq:
            tseq.append((t, a))
            t += dt

        self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
예제 #15
0
    def __init__(self, pads, rd_timing, wr_timing, page_rd_timing):
        self.bus = wishbone.Interface()

        config_status = self.config_status = CSRStatus(fields=[
            CSRField("mode",
                     size=32,
                     description="The current configuration mode of the SRAM")
        ])
        read_config = self.read_config = CSRStorage(fields=[
            CSRField(
                "trigger",
                size=1,
                description=
                "Writing to this bit triggers the SRAM mode status read update",
                pulse=True)
        ])

        # # #

        # min 150us, at 100MHz this is 15,000 cycles
        sram_zz = Signal(reset=1)
        load_config = Signal()
        self.sram_ready = Signal()
        reset_counter = Signal(
            14, reset=50)  # Cut short because 150us > FPGA config time
        self.sync += [
            If(reset_counter != 0, reset_counter.eq(reset_counter - 1),
               self.sram_ready.eq(0)).Else(self.sram_ready.eq(1)),
            If(reset_counter == 1, load_config.eq(1)).Else(load_config.eq(0))
        ]

        data = TSTriple(32)

        self.specials += data.get_tristate(pads.d)

        store = Signal()
        self.load = load = Signal()
        config = Signal()
        config_override = Signal()
        config_ce_n = Signal(reset=1)
        config_we_n = Signal(reset=1)
        config_oe_n = Signal(reset=1)

        comb_oe_n = Signal()
        comb_we_n = Signal()
        comb_zz_n = Signal()
        comb_ce_n = Signal()
        comb_dm_n = Signal(4)
        comb_adr = Signal(22)
        comb_data_o = Signal(32)

        comb_oe_n.reset, comb_we_n.reset = 1, 1
        comb_zz_n.reset, comb_ce_n.reset = 1, 1
        self.comb += [
            comb_oe_n.eq(1),
            comb_we_n.eq(1),
            comb_zz_n.eq(sram_zz),
            comb_ce_n.eq(1),
            If(
                config_override,
                comb_oe_n.eq(config_oe_n),
                comb_we_n.eq(config_we_n),
                comb_ce_n.eq(config_ce_n),
                comb_zz_n.eq(1),
                If(
                    config_ce_n,  # DM should track CE_n
                    comb_dm_n.eq(0xf),
                ).Else(comb_dm_n.eq(0x0)),
                comb_adr.eq(0x3fffff),
                comb_data_o.eq(0),
            ).Else(
                # Register data/address to avoid off-chip glitches
                If(
                    sram_zz == 0,
                    comb_adr.eq(
                        0xf0
                    ),  # 1111_0000   page mode enabled, TCR = 85C, PAR enabled, full array PAR
                    comb_dm_n.eq(0xf),
                ).Elif(
                    self.bus.cyc & self.bus.stb, comb_adr.eq(self.bus.adr),
                    comb_dm_n.eq(~self.bus.sel),
                    If(self.bus.we,
                       comb_data_o.eq(self.bus.dat_w)).Else(comb_oe_n.eq(0))),
                If(store | config, comb_we_n.eq(0)),
                If(
                    store | config |
                    (self.bus.cyc & self.bus.stb & ~self.bus.we),
                    comb_ce_n.eq(0)))
        ]
        self.sync_oe_n = sync_oe_n = Signal()
        self.sync += sync_oe_n.eq(
            comb_oe_n)  # Register internally to match ODDR
        self.comb += data.oe.eq(sync_oe_n)

        self.specials += [
            Instance(
                "ODDR",
                p_DDR_CLK_EDGE="SAME_EDGE",
                i_C=ClockSignal(),
                i_R=ResetSignal(),
                i_S=0,
                i_CE=1,
                i_D1=comb_oe_n,
                i_D2=comb_oe_n,
                o_Q=pads.oe_n,
            ),
            Instance(
                "ODDR",
                p_DDR_CLK_EDGE="SAME_EDGE",
                i_C=ClockSignal(),
                i_R=ResetSignal(),
                i_S=0,
                i_CE=1,
                i_D1=comb_we_n,
                i_D2=comb_we_n,
                o_Q=pads.we_n,
            ),
            Instance(
                "ODDR",
                p_DDR_CLK_EDGE="SAME_EDGE",
                i_C=ClockSignal(),
                i_R=ResetSignal(),
                i_S=0,
                i_CE=1,
                i_D1=comb_zz_n,
                i_D2=comb_zz_n,
                o_Q=pads.zz_n,
            ),
            Instance(
                "ODDR",
                p_DDR_CLK_EDGE="SAME_EDGE",
                i_C=ClockSignal(),
                i_R=ResetSignal(),
                i_S=0,
                i_CE=1,
                i_D1=comb_ce_n,
                i_D2=comb_ce_n,
                o_Q=pads.ce_n,
            ),
        ]

        for i in range(4):
            self.specials += Instance(
                "ODDR",
                p_DDR_CLK_EDGE="SAME_EDGE",
                i_C=ClockSignal(),
                i_R=ResetSignal(),
                i_S=0,
                i_CE=1,
                i_D1=comb_dm_n[i],
                i_D2=comb_dm_n[i],
                o_Q=pads.dm_n[i],
            ),

        for i in range(22):
            self.specials += Instance(
                "ODDR",
                p_DDR_CLK_EDGE="SAME_EDGE",
                i_C=ClockSignal(),
                i_R=ResetSignal(),
                i_S=0,
                i_CE=1,
                i_D1=comb_adr[i],
                i_D2=comb_adr[i],
                o_Q=pads.adr[i],
            ),

        for i in range(32):
            self.specials += Instance(
                "ODDR",
                p_DDR_CLK_EDGE="SAME_EDGE",
                i_C=ClockSignal(),
                i_R=ResetSignal(),
                i_S=0,
                i_CE=1,
                i_D1=comb_data_o[i],
                i_D2=comb_data_o[i],
                o_Q=data.o[i],
            ),

        for i in range(32):
            self.specials += Instance("IDDR",
                                      p_DDR_CLK_EDGE="OPPOSITE_EDGE",
                                      i_C=ClockSignal(),
                                      i_R=ResetSignal(),
                                      i_S=0,
                                      i_CE=load,
                                      i_D=data.i[i],
                                      o_Q1=self.bus.dat_r[i]),

        counter = Signal(max=max(rd_timing, wr_timing, 15) + 1)
        counter_limit = Signal(max=max(rd_timing, wr_timing, 15) + 1)
        counter_en = Signal()
        counter_done = Signal()
        self.comb += counter_done.eq(counter == counter_limit)
        self.sync += [
            If(counter_en & ~counter_done,
               counter.eq(counter + 1)).Else(counter.eq(0))
        ]

        last_page_adr = Signal(22)
        last_cycle_was_rd = Signal()

        self.submodules.fsm = fsm = FSM()
        fsm.act(
            "IDLE",
            NextValue(config, 0),
            If(read_config.fields.trigger, NextValue(config_override, 1),
               NextState("CONFIG_READ")),
            If(
                load_config,
                NextValue(last_cycle_was_rd, 0),
                NextValue(
                    counter_limit, 10
                ),  # 100 ns, assuming sysclk = 10ns. A little margin over min 70ns
                NextValue(sram_zz, 0),  # zz has to fall before WE
                NextState("CONFIG_PRE")).
            Elif(
                self.bus.cyc & self.bus.stb,
                NextValue(sram_zz, 1),
                If(self.bus.we, NextValue(counter_limit, wr_timing),
                   counter_en.eq(1), store.eq(1),
                   NextValue(last_cycle_was_rd, 0), NextState("WR"))
                .Else(
                    counter_en
                    .eq(1),
                    NextValue(last_page_adr, self.bus.adr
                              ),
                    NextValue(
                        last_cycle_was_rd, 1),
                    If(
                        (self.bus.adr[2:last_page_adr.nbits]
                         == last_page_adr[2:last_page_adr.nbits])
                        &
                        last_cycle_was_rd,  # doc says 4:nbits, but it doesn't work in practice...
                        NextState("RD"),
                        NextValue(counter_limit, page_rd_timing),
                    ).Else(NextValue(counter_limit, rd_timing),
                           NextState("RD")))).Else(NextValue(sram_zz, 1), ))
        fsm.act(
            "CONFIG_READ",
            NextValue(counter_limit, rd_timing),
            NextValue(config_ce_n, 1),
            NextValue(config_we_n, 1),
            NextValue(config_oe_n, 1),
            NextState("CFGRD1"),
        )
        fsm.act(
            "CFGRD1",
            counter_en.eq(1),
            NextValue(config_ce_n, 0),
            NextValue(config_oe_n, 0),
            If(
                counter_done,
                NextValue(counter_limit, rd_timing),
                NextValue(config_ce_n, 1),  # Should be 5ns min high time
                NextValue(config_oe_n, 1),
                NextState("CFGRD2"),
            ))
        fsm.act(
            "CFGRD2",
            counter_en.eq(1),
            NextValue(config_ce_n, 0),
            NextValue(config_oe_n, 0),
            If(
                counter_done,
                NextValue(counter_limit, rd_timing),
                NextValue(config_ce_n, 1),  # Should be 5ns min high time
                NextValue(config_oe_n, 1),
                NextState("CFGWR1"),
            ))
        fsm.act(
            "CFGWR1",
            counter_en.eq(1),
            NextValue(config_ce_n, 0),
            NextValue(config_we_n, 0),
            If(
                counter_done,
                NextValue(counter_limit, rd_timing),
                NextValue(config_ce_n, 1),  # Should be 5ns min high time
                NextValue(config_we_n, 1),
                NextState("CFGRD3"),
            ))
        fsm.act(
            "CFGRD3",
            counter_en.eq(1),
            NextValue(config_ce_n, 0),
            NextValue(config_oe_n, 0),
            If(
                counter_done,
                NextValue(config_status.fields.mode, data.i),
                NextValue(config_ce_n, 1),  # Should be 5ns min high time
                NextValue(config_oe_n, 1),
                NextValue(config_override, 0),
                NextState("IDLE"),
            ))

        fsm.act("CONFIG_PRE", NextState("CONFIG"))
        fsm.act(
            "CONFIG",
            counter_en.eq(1),
            If(
                counter_done,
                NextValue(config, 0),
                NextState("ZZ_UP"),
            ).Else(NextValue(config, 1), ),
        )
        fsm.act(
            "ZZ_UP",
            NextValue(config, 0),
            NextValue(sram_zz, 1),
            NextState("IDLE"),
        )
        fsm.act("RD", counter_en.eq(1),
                If(counter_done, load.eq(1), NextState("ACK")))
        fsm.act("WR", counter_en.eq(1), store.eq(1),
                If(counter_done, NextState("ACK")))
        fsm.act("ACK", self.bus.ack.eq(1), NextState("IDLE"))
예제 #16
0
    def __init__(self, pads, dummy=15, div=2, with_bitbang=True):
        """
        Simple SPI flash, e.g. N25Q128 on the LX9 Microboard.

        Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast
        Read). Only supports mode0 (cpol=0, cpha=0).
        Optionally supports software bitbanging (for write, erase, or other commands).
        """
        self.bus = bus = wishbone.Interface()
        spi_width = len(pads.dq)
        if with_bitbang:
            self.bitbang = CSRStorage(4)
            self.miso = CSRStatus()
            self.bitbang_en = CSRStorage()

        ###

        cs_n = Signal(reset=1)
        clk = Signal()
        dq_oe = Signal()
        wbone_width = len(bus.dat_r)

        read_cmd_params = {
            4: (_format_cmd(_QIOFR, 4), 4 * 8),
            2: (_format_cmd(_DIOFR, 2), 2 * 8),
            1: (_format_cmd(_FAST_READ, 1), 1 * 8)
        }
        read_cmd, cmd_width = read_cmd_params[spi_width]
        addr_width = 24

        pads.cs_n.reset = 1

        dq = TSTriple(spi_width)
        self.specials.dq = dq.get_tristate(pads.dq)

        sr = Signal(max(cmd_width, addr_width, wbone_width))
        dqs = Replicate(1, spi_width - 1)

        self.comb += bus.dat_r.eq(sr)

        hw_read_logic = [
            pads.clk.eq(clk),
            pads.cs_n.eq(cs_n),
            dq.o.eq(sr[-spi_width:]),
            dq.oe.eq(dq_oe)
        ]

        if with_bitbang:
            bitbang_logic = [
                pads.clk.eq(self.bitbang.storage[1]),
                pads.cs_n.eq(self.bitbang.storage[2]),
                dq.o.eq(Cat(self.bitbang.storage[0], dqs)),
                If(self.bitbang.storage[3], dq.oe.eq(0)).Else(dq.oe.eq(1)),
                If(self.bitbang.storage[1], self.miso.status.eq(dq.i[1]))
            ]

            self.comb += \
                If(self.bitbang_en.storage,
                    bitbang_logic
                ).Else(
                    hw_read_logic
                )
        else:
            self.comb += hw_read_logic

        if div < 2:
            raise ValueError(
                "Unsupported value \'{}\' for div parameter for SpiFlash core".
                format(div))
        else:
            i = Signal(max=div)
            dqi = Signal(spi_width)
            self.sync += [
                If(
                    i == div // 2 - 1,
                    clk.eq(1),
                    dqi.eq(dq.i),
                ),
                If(i == div - 1, i.eq(0), clk.eq(0),
                   sr.eq(Cat(dqi, sr[:-spi_width]))).Else(i.eq(i + 1), ),
            ]

        # spi is byte-addressed, prefix by zeros
        z = Replicate(0, log2_int(wbone_width // 8))

        seq = [
            (cmd_width // spi_width * div,
             [dq_oe.eq(1),
              cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
            (addr_width // spi_width * div,
             [sr[-addr_width:].eq(Cat(z, bus.adr))]),
            ((dummy + wbone_width // spi_width) * div, [dq_oe.eq(0)]),
            (1, [bus.ack.eq(1), cs_n.eq(1)]),
            (
                div,  # tSHSL!
                [bus.ack.eq(0)]),
            (0, []),
        ]

        # accumulate timeline deltas
        t, tseq = 0, []
        for dt, a in seq:
            tseq.append((t, a))
            t += dt

        self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
예제 #17
0
    def __init__(self, platform, pads):
        self.submodules.ll = ClockDomainsRenamer("local")(SDLinkLayer(
            platform, pads))

        # Event interrupts and acknowledgment
        self.submodules.ev = EventManager()
        self.ev.read = EventSourcePulse()
        self.ev.write = EventSourcePulse()
        self.ev.finalize()
        self._connect_event(self.ev.read, self.ll.block_read_act,
                            self.ll.block_read_go)
        self._connect_event(self.ev.write, self.ll.block_write_act,
                            self.ll.block_write_done)

        # Wishbone access to SRAM buffers
        self.bus = wishbone.Interface()
        self.submodules.wb_rd_buffer = wishbone.SRAM(self.ll.rd_buffer,
                                                     read_only=False)
        self.submodules.wb_wr_buffer = wishbone.SRAM(self.ll.wr_buffer,
                                                     read_only=False)
        wb_slaves = [(lambda a: a[9] == 0, self.wb_rd_buffer.bus),
                     (lambda a: a[9] == 1, self.wb_wr_buffer.bus)]
        self.submodules.wb_decoder = wishbone.Decoder(self.bus,
                                                      wb_slaves,
                                                      register=True)

        # Local reset domain
        self._reset = CSRStorage()
        self.clock_domains.cd_local = ClockDomain()
        self.comb += self.cd_local.clk.eq(ClockSignal())
        self.comb += self.cd_local.rst.eq(ResetSignal() | self._reset.storage)

        # Current data operation
        self._read_act = CSRStatus()
        self._read_addr = CSRStatus(32)
        self._read_byteaddr = CSRStatus(32)
        self._read_num = CSRStatus(32)
        self._read_stop = CSRStatus()
        self._write_act = CSRStatus()
        self._write_addr = CSRStatus(32)
        self._write_byteaddr = CSRStatus(32)
        self._write_num = CSRStatus(32)
        self._preerase_num = CSRStatus(23)
        self._erase_start = CSRStatus(32)
        self._erase_end = CSRStatus(32)
        self.comb += [
            self._read_act.status.eq(self.ll.block_read_act),
            self._read_addr.status.eq(self.ll.block_read_addr),
            self._read_byteaddr.status.eq(self.ll.block_read_byteaddr),
            self._read_num.status.eq(self.ll.block_read_num),
            self._read_stop.status.eq(self.ll.block_read_stop),
            self._write_act.status.eq(self.ll.block_write_act),
            self._write_addr.status.eq(self.ll.block_write_addr),
            self._write_byteaddr.status.eq(self.ll.block_write_byteaddr),
            self._write_num.status.eq(self.ll.block_write_num),
            self._preerase_num.status.eq(self.ll.block_preerase_num),
            self._erase_start.status.eq(self.ll.block_erase_start),
            self._erase_end.status.eq(self.ll.block_erase_end),
        ]

        # Informational registers, not needed for data transfer
        self._info_bits = CSRStatus(16)
        self.comb += self._info_bits.status.eq(
            Cat(
                self.ll.mode_4bit,
                self.ll.mode_spi,
                self.ll.host_hc_support,
                Constant(False),  # Reserved bit 3
                Constant(False),  # Reserved bit 4
                Constant(False),  # Reserved bit 5
                Constant(False),  # Reserved bit 6
                Constant(False),  # Reserved bit 7
                self.ll.info_card_desel,
                self.ll.err_op_out_range,
                self.ll.err_unhandled_cmd,
                self.ll.err_cmd_crc,
            ))
        self._most_recent_cmd = CSRStatus(len(self.ll.cmd_in_cmd))
        self.comb += self._most_recent_cmd.status.eq(self.ll.cmd_in_cmd)
        self._card_status = CSRStatus(len(self.ll.card_status))
        self.comb += self._card_status.status.eq(self.ll.card_status)
예제 #18
0
    def __init__(self, platform, variant="standard"):
        self.platform = platform
        self.variant = variant
        self.reset = Signal()
        self.ibus = ibus = wishbone.Interface(data_width=64, adr_width=29)
        self.dbus = dbus = wishbone.Interface(data_width=64, adr_width=29)
        self.periph_buses = [
            ibus, dbus
        ]  # Peripheral buses (Connected to main SoC's bus).
        self.memory_buses = [
        ]  # Memory buses (Connected directly to LiteDRAM).
        if "irq" in variant:
            self.interrupt = Signal(16)
        self.core_ext_irq = Signal()

        # # #

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

            # IBus.
            i_wishbone_insn_dat_r=ibus.dat_r,
            i_wishbone_insn_ack=ibus.ack,
            i_wishbone_insn_stall=ibus.cyc & ~ibus.ack,  # No burst support
            o_wishbone_insn_adr=ibus.adr,
            o_wishbone_insn_dat_w=ibus.dat_w,
            o_wishbone_insn_cyc=ibus.cyc,
            o_wishbone_insn_stb=ibus.stb,
            o_wishbone_insn_sel=ibus.sel,
            o_wishbone_insn_we=ibus.we,

            # DBus.
            i_wishbone_data_dat_r=dbus.dat_r,
            i_wishbone_data_ack=dbus.ack,
            i_wishbone_data_stall=dbus.cyc & ~dbus.ack,  # No burst support
            o_wishbone_data_adr=dbus.adr,
            o_wishbone_data_dat_w=dbus.dat_w,
            o_wishbone_data_cyc=dbus.cyc,
            o_wishbone_data_stb=dbus.stb,
            o_wishbone_data_sel=dbus.sel,
            o_wishbone_data_we=dbus.we,

            # Snoop.
            i_wb_snoop_in_adr=0,
            i_wb_snoop_in_dat_w=0,
            i_wb_snoop_in_cyc=0,
            i_wb_snoop_in_stb=0,
            i_wb_snoop_in_sel=0,
            i_wb_snoop_in_we=0,

            # Debug.
            i_dmi_addr=0,
            i_dmi_din=0,
            o_dmi_dout=Open(),
            i_dmi_req=0,
            i_dmi_wr=0,
            o_dmi_ack=Open(),

            # IRQ.
            i_core_ext_irq=self.core_ext_irq,
        )

        # Add VHDL sources.
        self.add_sources(platform,
                         use_ghdl_yosys_plugin="ghdl" in self.variant)
예제 #19
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=0x1000,
            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,
            # 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, 16, 32]
        self.csr_data_width = csr_data_width
        self.csr_address_width = csr_address_width

        assert csr_alignment in [32, 64]

        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: {} -- supported CPU types: {}".
                    format(cpu_type, ", ".join(cpu.CPUS.keys())))

            # Declare the CPU
            self.submodules.cpu = cpu.CPUS[cpu_type](platform,
                                                     self.cpu_variant)
            if cpu_type == "microwatt":
                self.add_constant("UART_POLLING", None)

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

            assert csr_alignment <= self.cpu.data_width
            csr_alignment = self.cpu.data_width
        else:
            self.submodules.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_name in ["stub", "stream"]:
                self.submodules.uart = uart.UART()
                if uart_name == "stub":
                    self.comb += self.uart.sink.ready.eq(1)
            elif uart_name == "bridge":
                self.submodules.uart = uart.UARTWishboneBridge(
                    platform.request("serial"), clk_freq, uart_baudrate)
                self.add_wb_master(self.uart.wishbone)
            elif uart_name == "crossover":
                self.submodules.uart = uart.UARTCrossover()
            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
        self.config["CSR_DATA_WIDTH"] = csr_data_width
        self.config["CSR_ALIGNMENT"] = csr_alignment
        assert csr_data_width <= 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,
                              2**(csr_address_width + 2))
예제 #20
0
    def __init__(self, platform, variant="standard"):
        self.platform = platform
        self.variant = variant
        self.trap = Signal()
        self.reset = Signal()
        self.interrupt = Signal(32)
        self.idbus = idbus = wishbone.Interface()
        self.periph_buses = [
            idbus
        ]  # Peripheral buses (Connected to main SoC's bus).
        self.memory_buses = [
        ]  # Memory buses (Connected directly to LiteDRAM).

        # # #

        mem_valid = Signal()
        mem_instr = Signal()
        mem_ready = Signal()
        mem_addr = Signal(32)
        mem_wdata = Signal(32)
        mem_wstrb = Signal(4)
        mem_rdata = Signal(32)

        # PicoRV32 parameters, change the desired parameters to create a create a new variant.
        self.cpu_params = dict(
            p_ENABLE_COUNTERS=1,
            p_ENABLE_COUNTERS64=1,
            p_ENABLE_REGS_16_31=
            1,  # Changing REGS has no effect as on FPGAs, the regs are
            p_ENABLE_REGS_DUALPORT=
            1,  # implemented using a register file stored in DPRAM.
            p_LATCHED_MEM_RDATA=0,
            p_TWO_STAGE_SHIFT=1,
            p_TWO_CYCLE_COMPARE=0,
            p_TWO_CYCLE_ALU=0,
            p_CATCH_MISALIGN=1,
            p_CATCH_ILLINSN=1,
            p_ENABLE_PCPI=0,
            p_ENABLE_MUL=1,
            p_ENABLE_DIV=1,
            p_ENABLE_FAST_MUL=0,
            p_ENABLE_IRQ=1,
            p_ENABLE_IRQ_QREGS=1,
            p_ENABLE_IRQ_TIMER=1,
            p_ENABLE_TRACE=0,
            p_MASKED_IRQ=0x00000000,
            p_LATCHED_IRQ=0xffffffff,
            p_STACKADDR=0xffffffff,
        )

        # Enforce default parameters for Minimal variant.
        if variant == "minimal":
            self.cpu_params.update(
                p_ENABLE_COUNTERS=0,
                p_ENABLE_COUNTERS64=0,
                p_TWO_STAGE_SHIFT=0,
                p_CATCH_MISALIGN=0,
                p_ENABLE_MUL=0,
                p_ENABLE_DIV=0,
                p_ENABLE_IRQ_TIMER=0,
            )

        self.cpu_params.update(
            # Clk / Rst.
            i_clk=ClockSignal("sys"),
            i_resetn=~(ResetSignal("sys") | self.reset),

            # Trap.
            o_trap=self.trap,

            # Memory Interface.
            o_mem_valid=mem_valid,
            o_mem_instr=mem_instr,
            i_mem_ready=mem_ready,
            o_mem_addr=mem_addr,
            o_mem_wdata=mem_wdata,
            o_mem_wstrb=mem_wstrb,
            i_mem_rdata=mem_rdata,

            # Look Ahead Interface (not used).
            o_mem_la_read=Signal(),
            o_mem_la_write=Signal(),
            o_mem_la_addr=Signal(32),
            o_mem_la_wdata=Signal(32),
            o_mem_la_wstrb=Signal(4),

            # Co-Processor interface (not used).
            o_pcpi_valid=Signal(),
            o_pcpi_insn=Signal(32),
            o_pcpi_rs1=Signal(32),
            o_pcpi_rs2=Signal(32),
            i_pcpi_wr=0,
            i_pcpi_rd=0,
            i_pcpi_wait=0,
            i_pcpi_ready=0,

            # IRQ interface.
            i_irq=self.interrupt,
            o_eoi=Signal(32))  # not used

        # Adapt Memory Interface to Wishbone.
        self.comb += [
            idbus.adr.eq(mem_addr[2:]),
            idbus.dat_w.eq(mem_wdata),
            idbus.we.eq(mem_wstrb != 0),
            idbus.sel.eq(mem_wstrb),
            idbus.cyc.eq(mem_valid),
            idbus.stb.eq(mem_valid),
            idbus.cti.eq(0),
            idbus.bte.eq(0),
            mem_ready.eq(idbus.ack),
            mem_rdata.eq(idbus.dat_r),
        ]

        # Add Verilog sources
        self.add_sources(platform)
예제 #21
0
    def __init__(self, platform, variant):
        self.platform = platform
        self.variant = "standard"
        self.human_name = self.human_name + "-" + variant.upper()
        self.reset = Signal()
        self.jtag_clk = Signal()
        self.jtag_enable = Signal()
        self.jtag_capture = Signal()
        self.jtag_shift = Signal()
        self.jtag_update = Signal()
        self.jtag_reset = Signal()
        self.jtag_tdo = Signal()
        self.jtag_tdi = Signal()
        self.interrupt = Signal(32)
        self.pbus = pbus = wishbone.Interface()

        self.periph_buses = [
            pbus
        ]  # Peripheral buses (Connected to main SoC's bus).
        self.memory_buses = [
        ]  # Memory buses (Connected directly to LiteDRAM).

        # # #
        self.cpu_params = dict(
            # Clk / Rst.
            i_debugCd_external_clk=ClockSignal(),
            i_debugCd_external_reset=ResetSignal() | self.reset,

            # Interrupts.
            i_interrupts=self.interrupt,

            # JTAG.
            i_jtag_clk=self.jtag_clk,
            i_debugPort_enable=self.jtag_enable,
            i_debugPort_capture=self.jtag_capture,
            i_debugPort_shift=self.jtag_shift,
            i_debugPort_update=self.jtag_update,
            i_debugPort_reset=self.jtag_reset,
            i_debugPort_tdi=self.jtag_tdi,
            o_debugPort_tdo=self.jtag_tdo,

            # Peripheral Bus (Master).
            o_peripheral_CYC=pbus.cyc,
            o_peripheral_STB=pbus.stb,
            i_peripheral_ACK=pbus.ack,
            o_peripheral_WE=pbus.we,
            o_peripheral_ADR=pbus.adr,
            i_peripheral_DAT_MISO=pbus.dat_r,
            o_peripheral_DAT_MOSI=pbus.dat_w,
            o_peripheral_SEL=pbus.sel,
            i_peripheral_ERR=pbus.err,
            o_peripheral_CTI=pbus.cti,
            o_peripheral_BTE=pbus.bte)

        if VexRiscvSMP.coherent_dma:
            self.dma_bus = dma_bus = wishbone.Interface(
                data_width=VexRiscvSMP.dcache_width)
            dma_bus_stall = Signal()
            dma_bus_inhibit = Signal()
            self.cpu_params.update(
                # DMA Bus (Slave).
                i_dma_wishbone_CYC=dma_bus.cyc,
                i_dma_wishbone_STB=dma_bus.stb & ~dma_bus_inhibit,
                o_dma_wishbone_ACK=dma_bus.ack,
                i_dma_wishbone_WE=dma_bus.we,
                i_dma_wishbone_SEL=dma_bus.sel,
                i_dma_wishbone_ADR=dma_bus.adr,
                o_dma_wishbone_DAT_MISO=dma_bus.dat_r,
                i_dma_wishbone_DAT_MOSI=dma_bus.dat_w,
                o_dma_wishbone_STALL=dma_bus_stall)
            self.sync += [
                If(
                    dma_bus.stb & dma_bus.cyc & ~dma_bus_stall,
                    dma_bus_inhibit.eq(1),
                ),
                If(dma_bus.ack, dma_bus_inhibit.eq(0))
            ]
예제 #22
0
    def __init__(self, pads, dummy=15, div=2):
        """
        Simple SPI flash.
        Supports 1-bit reads. Only supports mode0 (cpol=0, cpha=0).
        """
        self.bus = bus = wishbone.Interface()

        # # #

        if hasattr(pads, "wp"):
            self.comb += pads.wp.eq(1)

        if hasattr(pads, "hold"):
            self.comb += pads.hold.eq(1)

        cs_n = Signal(reset=1)
        clk = Signal()
        wbone_width = len(bus.dat_r)

        read_cmd = _FAST_READ
        cmd_width = 8
        addr_width = 24

        sr = Signal(max(cmd_width, addr_width, wbone_width))
        if endianness == "big":
            self.comb += bus.dat_r.eq(sr)
        else:
            self.comb += bus.dat_r.eq(reverse_bytes(sr))

        self.comb += [
            pads.clk.eq(clk),
            pads.cs_n.eq(cs_n),
            pads.mosi.eq(sr[-1:])
        ]

        if div < 2:
            raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))
        else:
            i = Signal(max=div)
            miso = Signal()
            self.sync += [
                If(i == div//2 - 1,
                    clk.eq(1),
                    miso.eq(pads.miso),
                ),
                If(i == div - 1,
                    i.eq(0),
                    clk.eq(0),
                    sr.eq(Cat(miso, sr[:-1]))
                ).Else(
                    i.eq(i + 1),
                ),
            ]

        # spi is byte-addressed, prefix by zeros
        z = Replicate(0, log2_int(wbone_width//8))

        seq = [
            (cmd_width*div,
                [cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
            (addr_width*div,
                [sr[-addr_width:].eq(Cat(z, bus.adr))]),
            ((dummy + wbone_width)*div,
                []),
            (1,
                [bus.ack.eq(1), cs_n.eq(1)]),
            (div, # tSHSL!
                [bus.ack.eq(0)]),
            (0,
                []),
        ]

        # accumulate timeline deltas
        t, tseq = 0, []
        for dt, a in seq:
            tseq.append((t, a))
            t += dt

        self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
예제 #23
0
    def add_debug(self):
        debug_reset = Signal()

        ibus_err = Signal()
        dbus_err = Signal()

        self.i_cmd_valid = Signal()
        self.i_cmd_payload_wr = Signal()
        self.i_cmd_payload_address = Signal(8)
        self.i_cmd_payload_data = Signal(32)
        self.o_cmd_ready = Signal()
        self.o_rsp_data = Signal(32)
        self.o_resetOut = Signal()

        reset_debug_logic = Signal()

        self.transfer_complete = Signal()
        self.transfer_in_progress = Signal()
        self.transfer_wait_for_ack = Signal()

        self.debug_bus = wishbone.Interface()

        self.sync += [
            self.debug_bus.dat_r.eq(self.o_rsp_data),
            debug_reset.eq(reset_debug_logic | ResetSignal()),
        ]

        self.sync += [
            # CYC is held high for the duration of the transfer.
            # STB is kept high when the transfer finishes (write)
            # or the master is waiting for data (read), and stays
            # there until ACK, ERR, or RTY are asserted.
            If((self.debug_bus.stb & self.debug_bus.cyc)
               & (~self.transfer_in_progress)
               & (~self.transfer_complete)
               & (~self.transfer_wait_for_ack),
               self.i_cmd_payload_data.eq(self.debug_bus.dat_w),
               self.i_cmd_payload_address.eq((self.debug_bus.adr[0:6] << 2)
                                             | 0),
               self.i_cmd_payload_wr.eq(self.debug_bus.we),
               self.i_cmd_valid.eq(1), self.transfer_in_progress.eq(1),
               self.transfer_complete.eq(0), self.debug_bus.ack.eq(0)).Elif(
                   self.transfer_in_progress,
                   If(self.o_cmd_ready, self.i_cmd_valid.eq(0),
                      self.i_cmd_payload_wr.eq(0),
                      self.transfer_complete.eq(1),
                      self.transfer_in_progress.eq(0))).Elif(
                          self.transfer_complete, self.transfer_complete.eq(0),
                          self.debug_bus.ack.eq(1),
                          self.transfer_wait_for_ack.eq(1)).Elif(
                              self.transfer_wait_for_ack
                              & ~(self.debug_bus.stb & self.debug_bus.cyc),
                              self.transfer_wait_for_ack.eq(0),
                              self.debug_bus.ack.eq(0)),
            # Force a Wishbone error if transferring during a reset sequence.
            # Because o_resetOut is multiple cycles and i.stb/d.stb should
            # deassert one cycle after i_err/i_ack/d_err/d_ack are asserted,
            # this will give i_err and o_err enough time to be reset to 0
            # once the reset cycle finishes.
            If(
                self.o_resetOut,
                If(self.ibus.cyc & self.ibus.stb,
                   ibus_err.eq(1)).Else(ibus_err.eq(0)),
                If(self.dbus.cyc & self.dbus.stb,
                   dbus_err.eq(1)).Else(dbus_err.eq(0)),
                reset_debug_logic.eq(1)).Else(reset_debug_logic.eq(0))
        ]

        self.cpu_params.update(
            i_reset=ResetSignal() | self.reset | debug_reset,
            i_iBusWishbone_ERR=self.ibus.err | ibus_err,
            i_dBusWishbone_ERR=self.dbus.err | dbus_err,
            i_debugReset=ResetSignal(),
            i_debug_bus_cmd_valid=self.i_cmd_valid,
            i_debug_bus_cmd_payload_wr=self.i_cmd_payload_wr,
            i_debug_bus_cmd_payload_address=self.i_cmd_payload_address,
            i_debug_bus_cmd_payload_data=self.i_cmd_payload_data,
            o_debug_bus_cmd_ready=self.o_cmd_ready,
            o_debug_bus_rsp_data=self.o_rsp_data,
            o_debug_resetOut=self.o_resetOut)
예제 #24
0
    def __init__(self, pads, dummy=15, div=2, endianness="big"):
        """
        Simple SPI flash.
        Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast
        Read). Only supports mode0 (cpol=0, cpha=0).
        """
        self.bus = bus = wishbone.Interface()
        spi_width = len(pads.dq)
        assert spi_width >= 2

        # # #

        cs_n = Signal(reset=1)
        clk = Signal()
        dq_oe = Signal()
        wbone_width = len(bus.dat_r)


        read_cmd_params = {
            4: (_format_cmd(_QIOFR, 4), 4*8),
            2: (_format_cmd(_DIOFR, 2), 2*8),
            1: (_format_cmd(_FAST_READ, 1), 1*8)
        }
        read_cmd, cmd_width = read_cmd_params[spi_width]
        addr_width = 24

        dq = TSTriple(spi_width)
        self.specials.dq = dq.get_tristate(pads.dq)

        sr = Signal(max(cmd_width, addr_width, wbone_width))
        if endianness == "big":
            self.comb += bus.dat_r.eq(sr)
        else:
            self.comb += bus.dat_r.eq(reverse_bytes(sr))

        self.comb += [
            pads.clk.eq(clk),
            pads.cs_n.eq(cs_n),
            dq.o.eq(sr[-spi_width:]),
            dq.oe.eq(dq_oe)
        ]

        if div < 2:
            raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))
        else:
            i = Signal(max=div)
            dqi = Signal(spi_width)
            self.sync += [
                If(i == div//2 - 1,
                    clk.eq(1),
                    dqi.eq(dq.i),
                ),
                If(i == div - 1,
                    i.eq(0),
                    clk.eq(0),
                    sr.eq(Cat(dqi, sr[:-spi_width]))
                ).Else(
                    i.eq(i + 1),
                ),
            ]

        # spi is byte-addressed, prefix by zeros
        z = Replicate(0, log2_int(wbone_width//8))

        seq = [
            (cmd_width//spi_width*div,
                [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
            (addr_width//spi_width*div,
                [sr[-addr_width:].eq(Cat(z, bus.adr))]),
            ((dummy + wbone_width//spi_width)*div,
                [dq_oe.eq(0)]),
            (1,
                [bus.ack.eq(1), cs_n.eq(1)]),
            (div, # tSHSL!
                [bus.ack.eq(0)]),
            (0,
                []),
        ]

        # accumulate timeline deltas
        t, tseq = 0, []
        for dt, a in seq:
            tseq.append((t, a))
            t += dt

        self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
예제 #25
0
 def test_wishbone_32bit_to_64bit(self):
     # Verify Wishbone with 32-bit data width up-converted to 64-bit data width.
     data = self.pattern_test_data["32bit_to_64bit"]
     wb   = wishbone.Interface(adr_width=30, data_width=32)
     port = LiteDRAMNativePort("both", address_width=30, data_width=64)
     self.wishbone_readback_test(data["pattern"], data["expected"], wb, port)
예제 #26
0
    def __init__(self,
                 sys_clk_freq=int(768e4),
                 with_pwm=False,
                 with_gpio=False,
                 gpio_width=32,
                 with_spi_master=False,
                 spi_master_data_width=8,
                 spi_master_clk_freq=8e6,
                 **kwargs):

        platform = Platform(_io)

        # UART
        if kwargs["with_uart"]:
            platform.add_extension([(
                "serial",
                0,
                Subsignal("tx", Pins(1)),
                Subsignal("rx", Pins(1)),
            )])

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = CRG(platform.request("sys_clk"),
                                  rst=platform.request("sys_rst"))

        # SoCMini ----------------------------------------------------------------------------------
        SoCMini.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs)

        # SPI Master
        if with_spi_master:
            platform.add_extension([(
                "spi_master",
                0,
                Subsignal("clk", Pins(1)),
                Subsignal("cs_n", Pins(1)),
                Subsignal("mosi", Pins(1)),
                Subsignal("miso", Pins(1)),
            )])
            self.submodules.spi_master = SPIMaster(
                pads=platform.request("spi_master"),
                data_width=spi_master_data_width,
                sys_clk_freq=sys_clk_freq,
                spi_clk_freq=spi_master_clk_freq,
            )
            self.add_csr("spi_master")

        # PWM
        if with_pwm:
            platform.add_extension([("pwm0", 0, Pins(1))])
            self.submodules.pwm0 = PWM(platform.request("pwm0"))
            self.add_csr("pwm0")

            platform.add_extension([("pwm1", 0, Pins(1))])
            self.submodules.pwm1 = PWM(platform.request("pwm1"))
            self.add_csr("pwm1")

            platform.add_extension([("pwm2", 0, Pins(1))])
            self.submodules.pwm2 = PWM(platform.request("pwm2"))
            self.add_csr("pwm2")

        # GPIO
        if with_gpio:
            platform.add_extension([("gpio", 0, Pins(gpio_width))])
            self.submodules.gpio = GPIOTristate(platform.request("gpio"))
            self.add_csr("gpio")

        # Wishbone Master
        if kwargs["bus"] == "wishbone":
            wb_bus = wishbone.Interface()
            self.bus.add_master(master=wb_bus)
            platform.add_extension(wb_bus.get_ios("wb"))
            wb_pads = platform.request("wb")
            self.comb += wb_bus.connect_to_pads(wb_pads, mode="slave")

        # AXI-Lite Master
        if kwargs["bus"] == "axi":
            axi_bus = axi.AXILiteInterface(data_width=32, address_width=32)
            wb_bus = wishbone.Interface()
            axi2wb = axi.AXILite2Wishbone(axi_bus, wb_bus)
            self.submodules += axi2wb
            self.bus.add_master(master=wb_bus)
            platform.add_extension(axi_bus.get_ios("axi"))
            axi_pads = platform.request("axi")
            self.comb += axi_bus.connect_to_pads(axi_pads, mode="slave")

        # IRQs
        for name, loc in sorted(self.irq.locs.items()):
            module = getattr(self, name)
            platform.add_extension([("irq_" + name, 0, Pins(1))])
            irq_pin = platform.request("irq_" + name)
            self.comb += irq_pin.eq(module.ev.irq)
예제 #27
0
    def __init__(self, pads=None):
        if pads is None:
            pads = Record(self.jtag_layout)
        self.pads = pads
        self.dmbus = wishbone.Interface()
        self.sbbus = wishbone.Interface()
        dmbus = Record(obi_layout)
        sbbus = Record(obi_layout)

        self.submodules.sbbus_conv = OBI2Wishbone(sbbus, self.sbbus)
        self.submodules.dmbus_conv = Wishbone2OBI(self.dmbus, dmbus)

        self.debug_req = Signal()
        self.ndmreset = Signal()

        tdo_i = Signal()
        tdo_o = Signal()
        tdo_oe = Signal()

        self.specials += Tristate(pads.tdo, tdo_o, tdo_oe, tdo_i)

        self.dm_params = dict(
            # Clk / Rst.
            i_clk=ClockSignal("sys"),
            i_rst_n=~ResetSignal("sys"),
            o_ndmreset=self.ndmreset,
            o_debug_req=self.debug_req,

            # Slave Bus.
            i_dm_req=dmbus.req,
            i_dm_we=dmbus.we,
            i_dm_addr=dmbus.addr,
            i_dm_be=dmbus.be,
            i_dm_wdata=dmbus.wdata,
            o_dm_rdata=dmbus.rdata,

            # Master Bus.
            o_sb_req=sbbus.req,
            o_sb_addr=sbbus.addr,
            o_sb_we=sbbus.we,
            o_sb_wdata=sbbus.wdata,
            o_sb_be=sbbus.be,
            i_sb_gnt=sbbus.gnt,
            i_sb_rvalid=sbbus.rvalid,
            i_sb_rdata=sbbus.rdata,

            # JTAG.
            i_tck=pads.tck,
            i_tms=pads.tms,
            i_trst_n=pads.trst,
            i_tdi=pads.tdi,
            o_tdo=tdo_o,
            o_tdo_oe=tdo_oe,
        )

        self.comb += [
            dmbus.gnt.eq(dmbus.req),
            dmbus.rvalid.eq(dmbus.gnt),
        ]

        self.specials += Instance("dm_wrap", **self.dm_params)
예제 #28
0
파일: core.py 프로젝트: John-K/litex
    def __init__(self, platform, variant="standard"):
        assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant
        self.platform = platform
        self.variant = variant
        self.reset = Signal()
        self.interrupt = Signal(32)
        self.ibus = i = wishbone.Interface()
        self.dbus = d = wishbone.Interface()
        self.periph_buses = [i, d]
        self.memory_buses = []

        if variant == "linux":
            self.mem_map = self.mem_map_linux

        # # #

        cpu_args = dict(
            p_FEATURE_INSTRUCTIONCACHE="ENABLED",
            p_OPTION_ICACHE_BLOCK_WIDTH=4,
            p_OPTION_ICACHE_SET_WIDTH=8,
            p_OPTION_ICACHE_WAYS=1,
            p_OPTION_ICACHE_LIMIT_WIDTH=31,
            p_FEATURE_DATACACHE="ENABLED",
            p_OPTION_DCACHE_BLOCK_WIDTH=4,
            p_OPTION_DCACHE_SET_WIDTH=8,
            p_OPTION_DCACHE_WAYS=1,
            p_OPTION_DCACHE_LIMIT_WIDTH=31,
            p_FEATURE_TIMER="NONE",
            p_OPTION_PIC_TRIGGER="LEVEL",
            p_FEATURE_SYSCALL="NONE",
            p_FEATURE_TRAP="NONE",
            p_FEATURE_RANGE="NONE",
            p_FEATURE_OVERFLOW="NONE",
            p_FEATURE_ADDC="ENABLED",
            p_FEATURE_CMOV="ENABLED",
            p_FEATURE_FFL1="ENABLED",
            p_OPTION_CPU0="CAPPUCCINO",
            p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
            p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
        )

        if variant == "linux":
            cpu_args.update(
                # Linux needs the memory management units.
                p_FEATURE_IMMU="ENABLED",
                p_FEATURE_DMMU="ENABLED",
                # FIXME: Currently we need the or1k timer when we should be
                # using the litex timer.
                p_FEATURE_TIMER="ENABLED",
            )
            # FIXME: Check if these are needed?
            use_defaults = (
                "p_FEATURE_SYSCALL",
                "p_FEATURE_TRAP",
                "p_FEATURE_RANGE",
                "p_FEATURE_OVERFLOW",
            )
            for to_remove in use_defaults:
                del cpu_args[to_remove]

        i_adr_o = Signal(32)
        d_adr_o = Signal(32)
        self.cpu_params = dict(
            **cpu_args,
            i_clk=ClockSignal(),
            i_rst=ResetSignal() | self.reset,
            i_irq_i=self.interrupt,
            o_iwbm_adr_o=i_adr_o,
            o_iwbm_dat_o=i.dat_w,
            o_iwbm_sel_o=i.sel,
            o_iwbm_cyc_o=i.cyc,
            o_iwbm_stb_o=i.stb,
            o_iwbm_we_o=i.we,
            o_iwbm_cti_o=i.cti,
            o_iwbm_bte_o=i.bte,
            i_iwbm_dat_i=i.dat_r,
            i_iwbm_ack_i=i.ack,
            i_iwbm_err_i=i.err,
            i_iwbm_rty_i=0,
            o_dwbm_adr_o=d_adr_o,
            o_dwbm_dat_o=d.dat_w,
            o_dwbm_sel_o=d.sel,
            o_dwbm_cyc_o=d.cyc,
            o_dwbm_stb_o=d.stb,
            o_dwbm_we_o=d.we,
            o_dwbm_cti_o=d.cti,
            o_dwbm_bte_o=d.bte,
            i_dwbm_dat_i=d.dat_r,
            i_dwbm_ack_i=d.ack,
            i_dwbm_err_i=d.err,
            i_dwbm_rty_i=0,
        )

        self.comb += [
            self.ibus.adr.eq(i_adr_o[2:]),
            self.dbus.adr.eq(d_adr_o[2:])
        ]

        # add verilog sources
        self.add_sources(platform)
예제 #29
0
    def __init__(self,
                 pads,
                 dummy=15,
                 div=2,
                 with_bitbang=True,
                 endianness="big"):
        """
        Simple memory-mapped SPI flash.
        Supports 1-bit reads. Only supports mode3 (cpol=1, cpha=1).
        """
        SpiFlashCommon.__init__(self, pads)
        self.bus = bus = wishbone.Interface()

        if with_bitbang:
            self.bitbang = CSRStorage(
                4,
                reset_less=True,
                fields=[
                    CSRField("mosi",
                             description="Output value for SPI MOSI pin."),
                    CSRField("clk",
                             description="Output value for SPI CLK pin."),
                    CSRField("cs_n",
                             description="Output value for SPI CSn pin."),
                    CSRField("dir", description="Unused in this design.")
                ],
                description="""Bitbang controls for SPI output.""")
            self.miso = CSRStatus(description="Incoming value of MISO pin.")
            self.bitbang_en = CSRStorage(
                description=
                "Write a ``1`` here to disable memory-mapped mode and enable bitbang mode."
            )

        # # #

        if hasattr(pads, "wp"):
            self.comb += pads.wp.eq(1)

        if hasattr(pads, "hold"):
            self.comb += pads.hold.eq(1)

        cs_n = Signal(reset=1)
        clk = Signal()
        wbone_width = len(bus.dat_r)

        read_cmd = _FAST_READ
        cmd_width = 8
        addr_width = 24

        sr = Signal(max(cmd_width, addr_width, wbone_width))
        if endianness == "big":
            self.comb += bus.dat_r.eq(sr)
        else:
            self.comb += bus.dat_r.eq(reverse_bytes(sr))

        hw_read_logic = [
            pads.clk.eq(clk),
            pads.cs_n.eq(cs_n),
            pads.mosi.eq(sr[-1:])
        ]

        if with_bitbang:
            bitbang_logic = [
                pads.clk.eq(self.bitbang.storage[1]),
                pads.cs_n.eq(self.bitbang.storage[2]),
                If(
                    self.bitbang.
                    storage[1],  # CPOL=0/CPHA=0 or CPOL=1/CPHA=1 only.
                    self.miso.status.eq(pads.miso)),
                pads.mosi.eq(self.bitbang.storage[0])
            ]

            self.comb += [
                If(self.bitbang_en.storage, bitbang_logic).Else(hw_read_logic)
            ]

        else:
            self.comb += hw_read_logic

        if div < 2:
            raise ValueError(
                "Unsupported value \'{}\' for div parameter for SpiFlash core".
                format(div))
        else:
            i = Signal(max=div)
            miso = Signal()
            self.sync += [
                If(
                    i == div // 2 - 1,
                    clk.eq(1),
                    miso.eq(pads.miso),
                ),
                If(i == div - 1, i.eq(0), clk.eq(0),
                   sr.eq(Cat(miso, sr[:-1]))).Else(i.eq(i + 1), ),
            ]

        # spi is byte-addressed, prefix by zeros
        z = Replicate(0, log2_int(wbone_width // 8))

        seq = [
            (cmd_width * div, [cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
            (addr_width * div, [sr[-addr_width:].eq(Cat(z, bus.adr))]),
            ((dummy + wbone_width) * div, []),
            (1, [bus.ack.eq(1), cs_n.eq(1)]),
            (
                div,  # tSHSL!
                [bus.ack.eq(0)]),
            (0, []),
        ]

        # accumulate timeline deltas
        t, tseq = 0, []
        for dt, a in seq:
            tseq.append((t, a))
            t += dt

        self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
예제 #30
0
파일: core.py 프로젝트: lolsborn/litex
    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=32,
                                                  address_width=32,
                                                  id_width=4)
        self.mmio_axi = mmio_axi = axi.AXIInterface(data_width=32,
                                                    address_width=32,
                                                    id_width=4)

        self.mem_wb = mem_wb = wishbone.Interface()
        self.mmio_wb = mmio_wb = wishbone.Interface()

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

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