Пример #1
0
    def __init__(self, platform, eba_reset):
        self.ibus = i = wishbone.Interface()
        self.dbus = d = wishbone.Interface()
        self.interrupt = Signal(32)

        ###

        i_adr_o = Signal(32)
        d_adr_o = Signal(32)
        self.specials += Instance("lm32_cpu",
                                  p_eba_reset=Instance.PreformattedParam(
                                      "32'h{:08x}".format(eba_reset)),
                                  i_clk_i=ClockSignal(),
                                  i_rst_i=ResetSignal(),
                                  i_interrupt=self.interrupt,
                                  o_I_ADR_O=i_adr_o,
                                  o_I_DAT_O=i.dat_w,
                                  o_I_SEL_O=i.sel,
                                  o_I_CYC_O=i.cyc,
                                  o_I_STB_O=i.stb,
                                  o_I_WE_O=i.we,
                                  o_I_CTI_O=i.cti,
                                  o_I_BTE_O=i.bte,
                                  i_I_DAT_I=i.dat_r,
                                  i_I_ACK_I=i.ack,
                                  i_I_ERR_I=i.err,
                                  i_I_RTY_I=0,
                                  o_D_ADR_O=d_adr_o,
                                  o_D_DAT_O=d.dat_w,
                                  o_D_SEL_O=d.sel,
                                  o_D_CYC_O=d.cyc,
                                  o_D_STB_O=d.stb,
                                  o_D_WE_O=d.we,
                                  o_D_CTI_O=d.cti,
                                  o_D_BTE_O=d.bte,
                                  i_D_DAT_I=d.dat_r,
                                  i_D_ACK_I=d.ack,
                                  i_D_ERR_I=d.err,
                                  i_D_RTY_I=0)

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

        # add Verilog sources
        platform.add_sources(
            os.path.join("extcores", "lm32", "submodule",
                         "rtl"), "lm32_cpu.v", "lm32_instruction_unit.v",
            "lm32_decoder.v", "lm32_load_store_unit.v", "lm32_adder.v",
            "lm32_addsub.v", "lm32_logic_op.v", "lm32_shifter.v",
            "lm32_multiplier.v", "lm32_mc_arithmetic.v", "lm32_interrupt.v",
            "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v", "lm32_dcache.v",
            "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v")
        platform.add_verilog_include_path(os.path.join("extcores", "lm32"))
Пример #2
0
    def __init__(self):
        self.i1 = wishbone.Interface()
        self.i2 = wishbone.Interface()

        # # #

        value = Signal(32)
        for i in self.i1, self.i2:
            self.sync += [
                i.dat_r.eq(value),
                i.ack.eq(0),
                If(i.cyc & i.stb & ~i.ack, i.ack.eq(1),
                   If(i.we, value.eq(i.dat_w)))
            ]
Пример #3
0
    def __init__(self, address_width, wb=None):
        if wb is None:
            wb = wishbone.Interface()
        self.wb = wb
        self.rtlink = rtlink.Interface(
            rtlink.OInterface(flen(wb.dat_w),
                              address_width + 1,
                              suppress_nop=False),
            rtlink.IInterface(flen(wb.dat_r), timestamped=False))

        # # #

        active = Signal()
        self.sync.rio += [
            If(self.rtlink.o.stb, active.eq(1),
               wb.adr.eq(self.rtlink.o.address[:address_width]),
               wb.we.eq(~self.rtlink.o.address[address_width]),
               wb.dat_w.eq(self.rtlink.o.data),
               wb.sel.eq(2**flen(wb.sel) - 1)),
            If(wb.ack, active.eq(0))
        ]
        self.comb += [
            self.rtlink.o.busy.eq(active),
            wb.cyc.eq(active),
            wb.stb.eq(active),
            self.rtlink.i.stb.eq(wb.ack & ~wb.we),
            self.rtlink.i.data.eq(wb.dat_r)
        ]
Пример #4
0
    def __init__(self):
        self.bus = wishbone.Interface()
        self.address = Sink([("a", 30)])
        self.data = Source([("d", 32)])
        self.busy = Signal()

        ###

        bus_stb = Signal()
        data_reg_loaded = Signal()
        data_reg = Signal(32)

        self.comb += [
            self.busy.eq(data_reg_loaded),
            self.bus.we.eq(0),
            bus_stb.eq(self.address.stb & (~data_reg_loaded | self.data.ack)),
            self.bus.cyc.eq(bus_stb),
            self.bus.stb.eq(bus_stb),
            self.bus.adr.eq(self.address.a),
            self.address.ack.eq(self.bus.ack),
            self.data.stb.eq(data_reg_loaded),
            self.data.d.eq(data_reg)
        ]
        self.sync += [
            If(self.data.ack, data_reg_loaded.eq(0)),
            If(self.bus.ack, data_reg_loaded.eq(1),
               data_reg.eq(self.bus.dat_r))
        ]
Пример #5
0
 def __init__(self, cachesize, asmiport):
     self.wishbone = wishbone.Interface()
     self.cachesize = cachesize
     self.asmiport = asmiport
     if len(self.asmiport.slots) != 1:
         raise ValueError("ASMI port must have 1 slot")
     if self.asmiport.hub.dw <= 32:
         raise ValueError("ASMI data width must be strictly larger than 32")
     if (self.asmiport.hub.dw % 32) != 0:
         raise ValueError("ASMI data width must be a multiple of 32")
Пример #6
0
 def __init__(self, platform, clk_freq, sdram_controller_settings,
              **kwargs):
     SoC.__init__(self, platform, clk_freq, **kwargs)
     if isinstance(sdram_controller_settings, str):
         self.sdram_controller_settings = eval(sdram_controller_settings)
     else:
         self.sdram_controller_settings = sdram_controller_settings
     self._sdram_phy_registered = False
     self._wb_sdram_ifs = []
     self._wb_sdram = wishbone.Interface()
Пример #7
0
    def __init__(self, we_bit=28, sel_bits=slice(24, 28)):
        super(Wishbone, self).__init__()
        self.bus = bus = wishbone.Interface()

        ###

        start = Signal()
        read = Signal()
        self.sync += [
            If(
                start,
                self.bus.adr.eq(self.dout.payload.addr),
                self.bus.dat_w.eq(self.dout.payload.data),
            ),
            If(
                read,
                self.din.payload.data.eq(self.bus.dat_r),
            )
        ]
        self.comb += [
            self.dout.ack.eq(1),
            self.din.payload.addr.eq(self.bus.adr),
            self.bus.cyc.eq(self.bus.stb),
            self.bus.we.eq(self.bus.adr[we_bit]),
        ]

        if sel_bits is not None:
            self.comb += self.bus.sel.eq(self.bus.adr[sel_bits])
        else:
            self.bus.sel.reset = 0b1111

        self.submodules.fsm = fsm = FSM()
        fsm.act("IDLE", If(
            self.dout.stb,
            start.eq(1),
            NextState("BUS"),
        ))
        fsm.act(
            "BUS", self.bus.stb.eq(1),
            If(
                self.bus.ack,
                If(
                    self.bus.we,
                    NextState("IDLE"),
                ).Else(
                    read.eq(1),
                    NextState("QUEUE"),
                ),
            ))
        fsm.act("QUEUE", self.din.stb.eq(1),
                If(
                    self.din.ack,
                    NextState("IDLE"),
                ))
Пример #8
0
    def __init__(self):
        self.bus = wishbone.Interface()
        self.address_data = Sink([("a", 30), ("d", 32)])
        self.busy = Signal()

        ###

        self.comb += [
            self.busy.eq(0),
            self.bus.we.eq(1),
            self.bus.cyc.eq(self.address_data.stb),
            self.bus.stb.eq(self.address_data.stb),
            self.bus.adr.eq(self.address_data.a),
            self.bus.sel.eq(0xf),
            self.bus.dat_w.eq(self.address_data.d),
            self.address_data.ack.eq(self.bus.ack)
        ]
Пример #9
0
    def __init__(self, dw, nrxslots=2, ntxslots=2):
        self.sink = Sink(eth_phy_description(dw))
        self.source = Source(eth_phy_description(dw))
        self.bus = wishbone.Interface()

        # # #

        # storage in SRAM
        sram_depth = buffer_depth // (dw // 8)
        self.submodules.sram = sram.LiteEthMACSRAM(dw, sram_depth, nrxslots,
                                                   ntxslots)
        self.comb += [
            Record.connect(self.sink, self.sram.sink),
            Record.connect(self.sram.source, self.source)
        ]

        # Wishbone interface
        wb_rx_sram_ifs = [
            wishbone.SRAM(self.sram.writer.mems[n], read_only=True)
            for n in range(nrxslots)
        ]
        # TODO: FullMemoryWE should move to Mibuild
        wb_tx_sram_ifs = [
            FullMemoryWE()(wishbone.SRAM(self.sram.reader.mems[n],
                                         read_only=False))
            for n in range(ntxslots)
        ]
        wb_sram_ifs = wb_rx_sram_ifs + wb_tx_sram_ifs

        wb_slaves = []
        decoderoffset = log2_int(sram_depth)
        decoderbits = log2_int(len(wb_sram_ifs))
        for n, wb_sram_if in enumerate(wb_sram_ifs):

            def slave_filter(a, v=n):
                return a[decoderoffset:decoderoffset + decoderbits] == v

            wb_slaves.append((slave_filter, wb_sram_if.bus))
            self.submodules += wb_sram_if
        wb_con = wishbone.Decoder(self.bus, wb_slaves, register=True)
        self.submodules += wb_con
Пример #10
0
	def __init__(self, bus_wishbone=None, bus_csr=None):
		if bus_wishbone is None:
			bus_wishbone = wishbone.Interface()
		self.wishbone = bus_wishbone
		if bus_csr is None:
			bus_csr = csr.Interface()
		self.csr = bus_csr

		###

		self.sync += [
			self.csr.we.eq(0),
			self.csr.dat_w.eq(self.wishbone.dat_w),
			self.csr.adr.eq(self.wishbone.adr),
			self.wishbone.dat_r.eq(self.csr.dat_r)
		]
		self.sync += timeline(self.wishbone.cyc & self.wishbone.stb, [
			(1, [self.csr.we.eq(self.wishbone.we)]),
			(2, [self.wishbone.ack.eq(1)]),
			(3, [self.wishbone.ack.eq(0)])
		])
Пример #11
0
    def __init__(self,
                 platform,
                 exec_address=0x40400000,
                 main_mem_origin=0x40000000,
                 l2_size=8192):
        self._reset = CSRStorage(reset=1)

        # # #

        self._wb_slaves = []

        # CPU core
        self.clock_domains.cd_sys_kernel = ClockDomain()
        self.comb += [
            self.cd_sys_kernel.clk.eq(ClockSignal()),
            self.cd_sys_kernel.rst.eq(self._reset.storage)
        ]
        self.submodules.cpu = RenameClockDomains(
            mor1kx.MOR1KX(platform, exec_address), "sys_kernel")

        # DRAM access
        self.wb_sdram = wishbone.Interface()
        self.add_wb_slave(mem_decoder(main_mem_origin), self.wb_sdram)
Пример #12
0
    def __init__(self, endpoint, address_decoder):
        self.wishbone = wishbone.Interface()

        # # #

        port = endpoint.crossbar.get_slave_port(address_decoder)
        self.submodules.fsm = fsm = FSM()

        fsm.act(
            "IDLE",
            If(port.sink.stb & port.sink.sop,
               If(
                   port.sink.we,
                   NextState("WRITE"),
               ).Else(NextState("READ"))).Else(port.sink.ack.eq(
                   port.sink.stb)))
        fsm.act("WRITE", self.wishbone.adr.eq(port.sink.adr[2:]),
                self.wishbone.dat_w.eq(port.sink.dat[:32]),
                self.wishbone.sel.eq(0xf), self.wishbone.stb.eq(1),
                self.wishbone.we.eq(1), self.wishbone.cyc.eq(1),
                If(self.wishbone.ack, port.sink.ack.eq(1), NextState("IDLE")))
        fsm.act("READ", self.wishbone.adr.eq(port.sink.adr[2:]),
                self.wishbone.stb.eq(1), self.wishbone.we.eq(0),
                self.wishbone.cyc.eq(1),
                If(self.wishbone.ack, NextState("COMPLETION")))
        self.sync += \
            If(self.wishbone.stb & self.wishbone.ack,
                port.source.dat.eq(self.wishbone.dat_r),
            )
        fsm.act("COMPLETION", port.source.stb.eq(1), port.source.sop.eq(1),
                port.source.eop.eq(1), port.source.len.eq(1),
                port.source.err.eq(0), port.source.tag.eq(port.sink.tag),
                port.source.adr.eq(port.sink.adr),
                port.source.cmp_id.eq(endpoint.phy.id),
                port.source.req_id.eq(port.sink.req_id),
                If(port.source.ack, port.sink.ack.eq(1), NextState("IDLE")))
Пример #13
0
    def __init__(self, platform, reset_pc):
        self.ibus = i = wishbone.Interface()
        self.dbus = d = wishbone.Interface()
        self.interrupt = Signal(32)

        ###

        i_adr_o = Signal(32)
        d_adr_o = Signal(32)
        self.specials += Instance("mor1kx",
                                  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="NONE",
                                  p_FEATURE_CMOV="NONE",
                                  p_FEATURE_FFL1="NONE",
                                  p_OPTION_CPU0="CAPPUCCINO",
                                  p_OPTION_RESET_PC=reset_pc,
                                  p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
                                  p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
                                  i_clk=ClockSignal(),
                                  i_rst=ResetSignal(),
                                  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
        platform.add_source_dir(
            os.path.join("extcores", "mor1kx", "submodule", "rtl", "verilog"))
Пример #14
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 = flen(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 = flen(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)
Пример #15
0
 def __init__(self):
     self.bus = wishbone.Interface()
     super().__init__(("address", Sink, [("a", BV(30))]),
                      ("data", Source, [("d", BV(32))]))
Пример #16
0
    def register_sdram_phy(self, phy):
        if self._sdram_phy_registered:
            raise FinalizeError
        self._sdram_phy_registered = True

        # Core
        self.submodules.sdram = SDRAMCore(phy, phy.module.geom_settings,
                                          phy.module.timing_settings,
                                          self.sdram_controller_settings)

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

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

        # LASMICON frontend
        if isinstance(self.sdram_controller_settings, LASMIconSettings):
            if self.sdram_controller_settings.with_bandwidth:
                self.sdram.controller.multiplexer.add_bandwidth()

            if self.sdram_controller_settings.with_memtest:
                self.submodules.memtest_w = memtest.MemtestWriter(
                    self.sdram.crossbar.get_master())
                self.submodules.memtest_r = memtest.MemtestReader(
                    self.sdram.crossbar.get_master())

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

        # MINICON frontend
        elif isinstance(self.sdram_controller_settings, MiniconSettings):
            if l2_size:
                l2_cache = wishbone.Cache(l2_size // 4, self._wb_sdram,
                                          self.sdram.controller.bus)
                # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache.
                # Issue is reported to Xilinx and should be fixed in next releases (2015.2?).
                # Remove this workaround when fixed by Xilinx.
                from mibuild.xilinx.vivado import XilinxVivadoToolchain
                if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
                    from migen.fhdl.simplify import FullMemoryWE
                    self.submodules.l2_cache = FullMemoryWE()(l2_cache)
                else:
                    self.submodules.l2_cache = l2_cache
            else:
                self.submodules.converter = wishbone.Converter(
                    self._wb_sdram, self.sdram.controller.bus)
Пример #17
0
    def __init__(self, slaves, depth=256, bus=None, with_wishbone=True):
        time_width, addr_width, data_width = [_[1] for _ in ventilator_layout]

        self.submodules.ctrl = CycleControl()

        self.submodules.ev = ev = EventManager()
        ev.in_readable = EventSourceLevel()
        ev.out_overflow = EventSourceProcess()
        ev.in_overflow = EventSourceLevel()
        ev.out_readable = EventSourceProcess()
        ev.stopped = EventSourceProcess()
        ev.started = EventSourceProcess()
        ev.finalize()

        self._in_time = CSRStatus(time_width)
        self._in_addr = CSRStatus(addr_width)
        self._in_data = CSRStatus(data_width)
        self._in_next = CSR()
        self._in_flush = CSR()

        self._out_time = CSRStorage(time_width, write_from_dev=with_wishbone)
        self._out_addr = CSRStorage(addr_width, write_from_dev=with_wishbone)
        self._out_data = CSRStorage(data_width, write_from_dev=with_wishbone)
        self._out_next = CSR()
        self._out_flush = CSR()

        self.busy = Signal()

        ###

        if with_wishbone:
            if bus is None:
                bus = wishbone.Interface()
            self.bus = bus

        slaves = [(self.ctrl, 0x00000000, 0xffffff00)] + slaves

        self.submodules.in_fifo = in_fifo = SyncFIFOBuffered(
            ventilator_layout, depth)
        self.submodules.out_fifo = out_fifo = SyncFIFOBuffered(
            ventilator_layout, depth)
        self.submodules.enc = PriorityEncoder(len(slaves))

        wb_in_next = Signal()
        wb_out_next = Signal()
        out_request = Signal()
        in_request = Signal()

        # CSRs and Events
        self.comb += [
            ev.in_readable.trigger.eq(in_fifo.readable),
            ev.out_overflow.trigger.eq(~out_fifo.writable),
            ev.in_overflow.trigger.eq(~in_fifo.writable),
            ev.out_readable.trigger.eq(out_fifo.readable),
            ev.started.trigger.eq(~self.ctrl.run),
            ev.stopped.trigger.eq(self.ctrl.run),
            self.ctrl.have_in.eq(~self.enc.n),
            self.ctrl.have_out.eq(out_fifo.readable),
            self._in_time.status.eq(in_fifo.dout.time),
            self._in_addr.status.eq(in_fifo.dout.addr),
            self._in_data.status.eq(in_fifo.dout.data),
            in_fifo.re.eq(self._in_next.re | wb_in_next),
            in_fifo.flush.eq(self._in_flush.re),
            out_fifo.din.time.eq(self._out_time.storage),
            out_fifo.din.addr.eq(self._out_addr.storage),
            out_fifo.din.data.eq(self._out_data.storage),
            out_fifo.we.eq(self._out_next.re | wb_out_next),
            out_fifo.flush.eq(self._out_flush.re),
        ]

        # din dout strobing
        self.comb += [
            # TODO: 0 <= diff <= plausibility range
            out_request.eq(out_fifo.readable & self.ctrl.run
                           & (self.ctrl.cycle == out_fifo.dout.time)),
            # ignore in_fifo.writable
            in_request.eq(~self.enc.n & self.ctrl.run),
            self.busy.eq(out_request | in_request),
        ]

        # to slaves
        addrs = []
        datas = []
        stbs = []
        acks = []
        for i, (slave, prefix, mask) in enumerate(slaves):
            prefix &= mask
            source = Source(slave_layout)
            sink = Sink(slave_layout)
            self.comb += [
                source.connect(slave.dout),
                sink.connect(slave.din),
            ]
            sel = Signal()
            acks.append(sel & source.ack)
            addrs.append(prefix | (sink.payload.addr & (~mask & 0xffffffff)))
            datas.append(sink.payload.data)
            stbs.append(sink.stb)
            self.comb += [
                sel.eq(out_fifo.dout.addr & mask == prefix),
                source.payload.addr.eq(out_fifo.dout.addr),
                source.payload.data.eq(out_fifo.dout.data),
                source.stb.eq(sel & out_request),
                sink.ack.eq((self.enc.o == i) & in_request),
            ]
        self.comb += out_fifo.re.eq(out_request & optree("|", acks))

        # from slaves
        self.comb += [
            self.enc.i.eq(Cat(stbs)),
            in_fifo.din.time.eq(self.ctrl.cycle),
            in_fifo.din.addr.eq(Array(addrs)[self.enc.o]),
            in_fifo.din.data.eq(Array(datas)[self.enc.o]),
            in_fifo.we.eq(in_request),
        ]

        # optional high throughput wishbone access
        if with_wishbone:
            self.comb += [
                self._out_time.dat_w.eq(bus.dat_w),
                self._out_addr.dat_w.eq(bus.dat_w),
                self._out_data.dat_w.eq(bus.dat_w),
                If(
                    bus.cyc & bus.stb,
                    If(
                        bus.we,
                        Case(
                            bus.adr[:4], {
                                0x5: wb_in_next.eq(1),
                                0x6: self._out_time.we.eq(1),
                                0x7: self._out_addr.we.eq(1),
                                0x8: self._out_data.we.eq(1),
                                0x9: wb_out_next.eq(1),
                            }),
                    ),
                    Case(
                        bus.adr[:4], {
                            0x0: bus.dat_r.eq(self.ctrl.cycle),
                            0x1: bus.dat_r.eq(self.ev.status.w),
                            0x2: bus.dat_r.eq(in_fifo.dout.time),
                            0x3: bus.dat_r.eq(in_fifo.dout.addr),
                            0x4: bus.dat_r.eq(in_fifo.dout.data),
                        }),
                )
            ]
            self.sync += bus.ack.eq(bus.cyc & bus.stb & ~bus.ack)
Пример #18
0
    def __init__(self):
        self.sink = sink = Sink(eth_etherbone_mmap_description(32))
        self.source = source = Source(eth_etherbone_mmap_description(32))
        self.bus = bus = wishbone.Interface()

        # # #

        self.submodules.data = data = FlipFlop(32)
        self.comb += data.d.eq(bus.dat_r)

        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act("IDLE",
            sink.ack.eq(1),
            If(sink.stb & sink.sop,
                sink.ack.eq(0),
                If(sink.we,
                    NextState("WRITE_DATA")
                ).Else(
                    NextState("READ_DATA")
                )
            )
        )
        fsm.act("WRITE_DATA",
            bus.adr.eq(sink.addr),
            bus.dat_w.eq(sink.data),
            bus.sel.eq(sink.be),
            bus.stb.eq(sink.stb),
            bus.we.eq(1),
            bus.cyc.eq(1),
            If(bus.stb & bus.ack,
                sink.ack.eq(1),
                If(sink.eop,
                    NextState("IDLE")
                )
            )
        )
        fsm.act("READ_DATA",
            bus.adr.eq(sink.addr),
            bus.sel.eq(sink.be),
            bus.stb.eq(sink.stb),
            bus.cyc.eq(1),
            If(bus.stb & bus.ack,
                data.ce.eq(1),
                NextState("SEND_DATA")
            )
        )
        fsm.act("SEND_DATA",
            source.stb.eq(sink.stb),
            source.sop.eq(sink.sop),
            source.eop.eq(sink.eop),
            source.base_addr.eq(sink.base_addr),
            source.addr.eq(sink.addr),
            source.count.eq(sink.count),
            source.be.eq(sink.be),
            source.we.eq(1),
            source.data.eq(data.q),
            If(source.stb & source.ack,
                sink.ack.eq(1),
                If(source.eop,
                    NextState("IDLE")
                ).Else(
                    NextState("READ_DATA")
                )
            )
        )
Пример #19
0
    def __init__(self, phy_settings, geom_settings, timing_settings):
        if phy_settings.memtype in ["SDR"]:
            burst_length = phy_settings.nphases * 1  # command multiplication*SDR
        elif phy_settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]:
            burst_length = phy_settings.nphases * 2  # command multiplication*DDR
        burst_width = phy_settings.dfi_databits * phy_settings.nphases
        address_align = log2_int(burst_length)

        # # #

        self.dfi = dfi = dfibus.Interface(geom_settings.addressbits,
                                          geom_settings.bankbits,
                                          phy_settings.dfi_databits,
                                          phy_settings.nphases)

        self.bus = bus = wishbone.Interface(burst_width)

        rdphase = phy_settings.rdphase
        wrphase = phy_settings.wrphase

        precharge_all = Signal()
        activate = Signal()
        refresh = Signal()
        write = Signal()
        read = Signal()

        # Compute current column, bank and row from wishbone address
        slicer = _AddressSlicer(geom_settings.colbits, geom_settings.bankbits,
                                geom_settings.rowbits, address_align)

        # Manage banks
        bank_open = Signal()
        bank_idle = Signal()
        bank_hit = Signal()

        banks = []
        for i in range(2**geom_settings.bankbits):
            bank = _Bank(geom_settings)
            self.comb += [
                bank.open.eq(activate),
                bank.reset.eq(precharge_all),
                bank.row.eq(slicer.row(bus.adr))
            ]
            banks.append(bank)
        self.submodules += banks

        cases = {}
        for i, bank in enumerate(banks):
            cases[i] = [bank.ce.eq(1)]
        self.comb += Case(slicer.bank(bus.adr), cases)

        self.comb += [
            bank_hit.eq(optree("|", [bank.hit & bank.ce for bank in banks])),
            bank_idle.eq(optree("|", [bank.idle & bank.ce for bank in banks])),
        ]

        # Timings
        write2precharge_timer = WaitTimer(2 + timing_settings.tWR - 1)
        self.submodules += write2precharge_timer
        self.comb += write2precharge_timer.wait.eq(~write)

        refresh_timer = WaitTimer(timing_settings.tREFI)
        self.submodules += refresh_timer
        self.comb += refresh_timer.wait.eq(~refresh)

        # Main FSM
        self.submodules.fsm = fsm = FSM()
        fsm.act(
            "IDLE",
            If(refresh_timer.done, NextState("PRECHARGE-ALL")).Elif(
                bus.stb & bus.cyc,
                If(bank_hit,
                   If(bus.we,
                      NextState("WRITE")).Else(NextState("READ"))).Elif(
                          ~bank_idle,
                          If(write2precharge_timer.done,
                             NextState("PRECHARGE"))).Else(
                                 NextState("ACTIVATE"))))
        fsm.act(
            "READ",
            read.eq(1),
            dfi.phases[rdphase].ras_n.eq(1),
            dfi.phases[rdphase].cas_n.eq(0),
            dfi.phases[rdphase].we_n.eq(1),
            dfi.phases[rdphase].rddata_en.eq(1),
            NextState("WAIT-READ-DONE"),
        )
        fsm.act(
            "WAIT-READ-DONE",
            If(dfi.phases[rdphase].rddata_valid, bus.ack.eq(1),
               NextState("IDLE")))
        fsm.act("WRITE", write.eq(1), dfi.phases[wrphase].ras_n.eq(1),
                dfi.phases[wrphase].cas_n.eq(0),
                dfi.phases[wrphase].we_n.eq(0),
                dfi.phases[wrphase].wrdata_en.eq(1),
                NextState("WRITE-LATENCY"))
        fsm.act("WRITE-ACK", bus.ack.eq(1), NextState("IDLE"))
        fsm.act("PRECHARGE-ALL", precharge_all.eq(1),
                dfi.phases[rdphase].ras_n.eq(0),
                dfi.phases[rdphase].cas_n.eq(1),
                dfi.phases[rdphase].we_n.eq(0), NextState("PRE-REFRESH"))
        fsm.act(
            "PRECHARGE",
            # do no reset bank since we are going to re-open it
            dfi.phases[0].ras_n.eq(0),
            dfi.phases[0].cas_n.eq(1),
            dfi.phases[0].we_n.eq(0),
            NextState("TRP"))
        fsm.act(
            "ACTIVATE",
            activate.eq(1),
            dfi.phases[0].ras_n.eq(0),
            dfi.phases[0].cas_n.eq(1),
            dfi.phases[0].we_n.eq(1),
            NextState("TRCD"),
        )
        fsm.act("REFRESH", refresh.eq(1), dfi.phases[rdphase].ras_n.eq(0),
                dfi.phases[rdphase].cas_n.eq(0),
                dfi.phases[rdphase].we_n.eq(1), NextState("POST-REFRESH"))
        fsm.delayed_enter("WRITE-LATENCY", "WRITE-ACK",
                          phy_settings.write_latency - 1)
        fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP - 1)
        fsm.delayed_enter("TRCD", "IDLE", timing_settings.tRCD - 1)
        fsm.delayed_enter("PRE-REFRESH", "REFRESH", timing_settings.tRP - 1)
        fsm.delayed_enter("POST-REFRESH", "IDLE", timing_settings.tRFC - 1)

        # DFI commands
        for phase in dfi.phases:
            if hasattr(phase, "reset_n"):
                self.comb += phase.reset_n.eq(1)
            if hasattr(phase, "odt"):
                self.comb += phase.odt.eq(1)
            self.comb += [
                phase.cke.eq(1),
                phase.cs_n.eq(0),
                phase.bank.eq(slicer.bank(bus.adr)),
                If(precharge_all, phase.address.eq(2**10)).Elif(
                    activate, phase.address.eq(slicer.row(bus.adr))).Elif(
                        write | read, phase.address.eq(slicer.col(bus.adr)))
            ]

        # DFI datapath
        self.comb += [
            bus.dat_r.eq(Cat(phase.rddata for phase in dfi.phases)),
            Cat(phase.wrdata for phase in dfi.phases).eq(bus.dat_w),
            Cat(phase.wrdata_mask for phase in dfi.phases).eq(~bus.sel),
        ]
Пример #20
0
def add_interfaces(obj):
    obj.result = Source(layout)
    obj.wb = wishbone.Interface()
    obj.mem = Memory(32, 3, init=[42, 37, 81])
    obj.finalize()
Пример #21
0
    def __init__(self, platform):
        self.sink = Sink(EndpointDescription([("data", 16)], packetized=True))
        self.source = Source([("data", 8)])
        self.bus = wishbone.Interface()

        # # #

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

        # output fifo
        output_fifo_almost_full = Signal()
        output_fifo = RenameClockDomains(SyncFIFO([("data", 8)], 1024),
                                         "encoder")
        self.submodules += output_fifo
        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,
            i_fdct_ack=chroma_upsampler.source.ack,
            i_fdct_stb=chroma_upsampler.source.stb,
            i_fdct_data=Cat(chroma_upsampler.source.y,
                            chroma_upsampler.source.cb,
                            chroma_upsampler.source.cr),
            o_ram_byte=output_fifo.sink.data,
            o_ram_wren=output_fifo.sink.stb,
            #o_ram_wraddr=,
            #o_frame_size=,
            i_outif_almost_full=output_fifo_almost_full)
        # add vhdl sources
        platform.add_source_dir(
            os.path.join(platform.soc_ext_path, "gateware", "encoder", "vhdl"))

        # add verilog sources
        platform.add_source(
            os.path.join(platform.soc_ext_path, "gateware", "encoder",
                         "verilog", "wb_async_reg.v"))

        # bandwidth
        self.submodules.bandwidth = EncoderBandwidth()  # XXX add CDC
        self.comb += self.bandwidth.nbytes_inc.eq(self.source.stb
                                                  & self.source.ack)
Пример #22
0
    def __init__(self, phy, clk_freq):
        self.wishbone = wishbone.Interface()

        # # #

        byte_counter = Counter(3)
        word_counter = Counter(8)
        self.submodules += byte_counter, word_counter

        cmd = Signal(8)
        cmd_ce = Signal()

        length = Signal(8)
        length_ce = Signal()

        address = Signal(32)
        address_ce = Signal()

        data = Signal(32)
        rx_data_ce = Signal()
        tx_data_ce = Signal()

        self.sync += [
            If(cmd_ce, cmd.eq(phy.source.data)),
            If(length_ce, length.eq(phy.source.data)),
            If(address_ce, address.eq(Cat(phy.source.data, address[0:24]))),
            If(rx_data_ce,
               data.eq(Cat(phy.source.data,
                           data[0:24]))).Elif(tx_data_ce,
                                              data.eq(self.wishbone.dat_r))
        ]

        fsm = InsertReset(FSM(reset_state="IDLE"))
        timer = WaitTimer(clk_freq // 10)
        self.submodules += fsm, timer
        self.comb += [fsm.reset.eq(timer.done), phy.source.ack.eq(1)]
        fsm.act(
            "IDLE",
            If(
                phy.source.stb, cmd_ce.eq(1),
                If((phy.source.data == self.cmds["write"]) |
                   (phy.source.data == self.cmds["read"]),
                   NextState("RECEIVE_LENGTH")), byte_counter.reset.eq(1),
                word_counter.reset.eq(1)))
        fsm.act(
            "RECEIVE_LENGTH",
            If(phy.source.stb, length_ce.eq(1), NextState("RECEIVE_ADDRESS")))
        fsm.act(
            "RECEIVE_ADDRESS",
            If(
                phy.source.stb, address_ce.eq(1), byte_counter.ce.eq(1),
                If(
                    byte_counter.value == 3,
                    If(cmd == self.cmds["write"],
                       NextState("RECEIVE_DATA")).Elif(
                           cmd == self.cmds["read"], NextState("READ_DATA")),
                    byte_counter.reset.eq(1),
                )))
        fsm.act(
            "RECEIVE_DATA",
            If(
                phy.source.stb, rx_data_ce.eq(1), byte_counter.ce.eq(1),
                If(byte_counter.value == 3, NextState("WRITE_DATA"),
                   byte_counter.reset.eq(1))))
        self.comb += [
            self.wishbone.adr.eq(address + word_counter.value),
            self.wishbone.dat_w.eq(data),
            self.wishbone.sel.eq(2**flen(self.wishbone.sel) - 1)
        ]
        fsm.act(
            "WRITE_DATA", self.wishbone.stb.eq(1), self.wishbone.we.eq(1),
            self.wishbone.cyc.eq(1),
            If(
                self.wishbone.ack, word_counter.ce.eq(1),
                If(word_counter.value == (length - 1),
                   NextState("IDLE")).Else(NextState("RECEIVE_DATA"))))
        fsm.act(
            "READ_DATA", self.wishbone.stb.eq(1), self.wishbone.we.eq(0),
            self.wishbone.cyc.eq(1),
            If(self.wishbone.ack, tx_data_ce.eq(1), NextState("SEND_DATA")))
        self.comb += \
            chooser(data, byte_counter.value, phy.sink.data, n=4, reverse=True)
        fsm.act(
            "SEND_DATA", phy.sink.stb.eq(1),
            If(
                phy.sink.ack, byte_counter.ce.eq(1),
                If(
                    byte_counter.value == 3, word_counter.ce.eq(1),
                    If(word_counter.value == (length - 1),
                       NextState("IDLE")).Else(NextState("READ_DATA"),
                                               byte_counter.reset.eq(1)))))

        self.comb += timer.wait.eq(~fsm.ongoing("IDLE"))

        if phy.sink.description.packetized:
            self.comb += [
                phy.sink.sop.eq((byte_counter.value == 0)
                                & (word_counter.value == 0)),
                phy.sink.eop.eq((byte_counter.value == 3)
                                & (word_counter.value == (length - 1)))
            ]
            if hasattr(phy.sink, "length"):
                self.comb += phy.sink.length.eq(4 * length)
Пример #23
0
    def __init__(self, pads, rd_timing, wr_timing):
        self.bus = wishbone.Interface()

        ###

        data = TSTriple(16)
        lsb = Signal()

        self.specials += data.get_tristate(pads.d)
        self.comb += [data.oe.eq(pads.oe_n), pads.ce_n.eq(0)]

        load_lo = Signal()
        load_hi = Signal()
        store = Signal()

        pads.oe_n.reset, pads.we_n.reset = 1, 1
        self.sync += [
            pads.oe_n.eq(1),
            pads.we_n.eq(1),

            # Register data/address to avoid off-chip glitches
            If(
                self.bus.cyc & self.bus.stb,
                pads.adr.eq(Cat(lsb, self.bus.adr)),
                If(
                    self.bus.we,
                    # Only 16-bit writes are supported. Assume sel=0011 or 1100.
                    If(self.bus.sel[0], data.o.eq(self.bus.dat_w[:16])).Else(
                        data.o.eq(self.bus.dat_w[16:])
                    )).Else(pads.oe_n.eq(0))),
            If(load_lo, self.bus.dat_r[:16].eq(data.i)),
            If(load_hi, self.bus.dat_r[16:].eq(data.i)),
            If(store, pads.we_n.eq(0))
        ]

        # Typical timing of the flash chips:
        #  - 110ns address to output
        #  - 50ns write pulse width
        counter = Signal(max=max(rd_timing, wr_timing) + 1)
        counter_en = Signal()
        counter_wr_mode = Signal()
        counter_done = Signal()
        self.comb += counter_done.eq(
            counter == Mux(counter_wr_mode, wr_timing, rd_timing))
        self.sync += If(counter_en & ~counter_done,
                        counter.eq(counter + 1)).Else(counter.eq(0))

        fsm = FSM()
        self.submodules += fsm

        fsm.act(
            "IDLE",
            If(self.bus.cyc & self.bus.stb,
               If(self.bus.we, NextState("WR")).Else(NextState("RD_HI"))))
        fsm.act("RD_HI", lsb.eq(0), counter_en.eq(1),
                If(counter_done, load_hi.eq(1), NextState("RD_LO")))
        fsm.act("RD_LO", lsb.eq(1), counter_en.eq(1),
                If(counter_done, load_lo.eq(1), NextState("ACK")))
        fsm.act(
            "WR",
            # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0]
            lsb.eq(self.bus.sel[0]),
            counter_wr_mode.eq(1),
            counter_en.eq(1),
            store.eq(1),
            If(counter_done, NextState("ACK")))
        fsm.act("ACK", self.bus.ack.eq(1), NextState("IDLE"))
Пример #24
0
    def __init__(self, pads, drive_fud=False, bus=None):
        if bus is None:
            bus = wishbone.Interface()
        self.bus = bus

        # # #

        dts = TSTriple(8)
        self.specials += dts.get_tristate(pads.d)
        dr = Signal(8)
        rx = Signal()
        self.sync += [
            pads.a.eq(bus.adr),
            dts.o.eq(bus.dat_w),
            dr.eq(dts.i),
            dts.oe.eq(~rx)
        ]

        gpio = Signal(flen(pads.sel) + flen(pads.p) + 1)
        gpio_load = Signal()
        self.sync += If(gpio_load, gpio.eq(bus.dat_w))
        self.comb += [
            Cat(pads.sel, pads.p).eq(gpio),
            pads.rst_n.eq(~gpio[-1]),
        ]

        bus_r_gpio = Signal()
        self.comb += If(bus_r_gpio, bus.dat_r.eq(gpio)).Else(bus.dat_r.eq(dr))

        if drive_fud:
            fud = Signal()
            self.sync += pads.fud_n.eq(~fud)

        pads.wr_n.reset = 1
        pads.rd_n.reset = 1
        wr = Signal()
        rd = Signal()
        self.sync += pads.wr_n.eq(~wr), pads.rd_n.eq(~rd)

        fsm = FSM("IDLE")
        self.submodules += fsm

        fsm.act(
            "IDLE",
            If(
                bus.cyc & bus.stb,
                If(
                    bus.adr[6],
                    If(bus.adr[0], NextState("GPIO")).Else(
                        NextState("FUD") if drive_fud else None)).Else(
                            If(bus.we,
                               NextState("WRITE")).Else(NextState("READ")))))
        fsm.act(
            "WRITE",
            # 3ns A setup to WR active
            wr.eq(1),
            NextState("WRITE0"))
        fsm.act(
            "WRITE0",
            # 3.5ns D setup to WR inactive
            # 0ns D and A hold to WR inactive
            bus.ack.eq(1),
            NextState("IDLE"))
        fsm.act(
            "READ",
            # 15ns D valid to A setup
            # 15ns D valid to RD active
            rx.eq(1),
            rd.eq(1),
            NextState("READ0"))
        fsm.act("READ0", rx.eq(1), rd.eq(1), NextState("READ1"))
        fsm.act("READ1", rx.eq(1), rd.eq(1), NextState("READ2"))
        fsm.act("READ2", rx.eq(1), rd.eq(1), NextState("READ3"))
        fsm.act("READ3", rx.eq(1), rd.eq(1), NextState("READ4"))
        fsm.act("READ4", rx.eq(1), NextState("READ5"))
        fsm.act(
            "READ5",
            # 5ns D three-state to RD inactive
            # 10ns A hold to RD inactive
            rx.eq(1),
            bus.ack.eq(1),
            NextState("IDLE"))
        if drive_fud:
            fsm.act(
                "FUD",
                # 4ns FUD setup to SYNCLK
                # 0ns FUD hold to SYNCLK
                fud.eq(1),
                bus.ack.eq(1),
                NextState("IDLE"))
        fsm.act("GPIO", bus.ack.eq(1), bus_r_gpio.eq(1),
                If(bus.we, gpio_load.eq(1)), NextState("IDLE"))
Пример #25
0
 def __init__(self):
     self.wishbone = wishbone.Interface()
     self.csr = csr.Interface()
Пример #26
0
    def __init__(self, cachesize, lasmim):
        self.wishbone = wishbone.Interface()

        ###

        data_width = flen(self.wishbone.dat_r)
        if lasmim.dw > data_width and (lasmim.dw % data_width) != 0:
            raise ValueError(
                "LASMI data width must be a multiple of {dw}".format(
                    dw=data_width))
        if lasmim.dw < data_width and (data_width % lasmim.dw) != 0:
            raise ValueError(
                "WISHBONE data width must be a multiple of {dw}".format(
                    dw=lasmim.dw))

        # Split address:
        # TAG | LINE NUMBER | LINE OFFSET
        offsetbits = log2_int(max(lasmim.dw // data_width, 1))
        addressbits = lasmim.aw + offsetbits
        linebits = log2_int(cachesize) - offsetbits
        tagbits = addressbits - linebits
        wordbits = log2_int(max(data_width // lasmim.dw, 1))
        adr_offset, adr_line, adr_tag = split(self.wishbone.adr, offsetbits,
                                              linebits, tagbits)
        word = Signal(wordbits) if wordbits else None

        # Data memory
        data_mem = Memory(lasmim.dw * 2**wordbits, 2**linebits)
        data_port = data_mem.get_port(write_capable=True, we_granularity=8)
        self.specials += data_mem, data_port

        write_from_lasmi = Signal()
        write_to_lasmi = Signal()
        if adr_offset is None:
            adr_offset_r = None
        else:
            adr_offset_r = Signal(offsetbits)
            self.sync += adr_offset_r.eq(adr_offset)

        self.comb += [
            data_port.adr.eq(adr_line),
            If(write_from_lasmi, displacer(lasmim.dat_r, word,
                                           data_port.dat_w),
               displacer(Replicate(1, lasmim.dw // 8), word,
                         data_port.we)).Else(
                             data_port.dat_w.eq(
                                 Replicate(self.wishbone.dat_w,
                                           max(lasmim.dw // data_width, 1))),
                             If(
                                 self.wishbone.cyc & self.wishbone.stb
                                 & self.wishbone.we & self.wishbone.ack,
                                 displacer(self.wishbone.sel,
                                           adr_offset,
                                           data_port.we,
                                           2**offsetbits,
                                           reverse=True))),
            If(write_to_lasmi, chooser(data_port.dat_r, word, lasmim.dat_w),
               lasmim.dat_we.eq(2**(lasmim.dw // 8) - 1)),
            chooser(data_port.dat_r,
                    adr_offset_r,
                    self.wishbone.dat_r,
                    reverse=True)
        ]

        # Tag memory
        tag_layout = [("tag", tagbits), ("dirty", 1)]
        tag_mem = Memory(layout_len(tag_layout), 2**linebits)
        tag_port = tag_mem.get_port(write_capable=True)
        self.specials += tag_mem, tag_port
        tag_do = Record(tag_layout)
        tag_di = Record(tag_layout)
        self.comb += [
            tag_do.raw_bits().eq(tag_port.dat_r),
            tag_port.dat_w.eq(tag_di.raw_bits())
        ]

        self.comb += [tag_port.adr.eq(adr_line), tag_di.tag.eq(adr_tag)]
        if word is not None:
            self.comb += lasmim.adr.eq(Cat(word, adr_line, tag_do.tag))
        else:
            self.comb += lasmim.adr.eq(Cat(adr_line, tag_do.tag))

        # Lasmim word computation, word_clr and word_inc will be simplified
        # at synthesis when wordbits=0
        word_clr = Signal()
        word_inc = Signal()
        if word is not None:
            self.sync += \
             If(word_clr,
              word.eq(0),
             ).Elif(word_inc,
              word.eq(word+1)
             )

        def word_is_last(word):
            if word is not None:
                return word == 2**wordbits - 1
            else:
                return 1

        # Control FSM
        assert (lasmim.write_latency >= 1 and lasmim.read_latency >= 1)
        fsm = FSM(reset_state="IDLE")
        self.submodules += fsm

        fsm.delayed_enter("EVICT_DATAD", "EVICT_DATA",
                          lasmim.write_latency - 1)
        fsm.delayed_enter("REFILL_DATAD", "REFILL_DATA",
                          lasmim.read_latency - 1)

        fsm.act(
            "IDLE",
            If(self.wishbone.cyc & self.wishbone.stb, NextState("TEST_HIT")))
        fsm.act(
            "TEST_HIT", word_clr.eq(1),
            If(tag_do.tag == adr_tag, self.wishbone.ack.eq(1),
               If(self.wishbone.we, tag_di.dirty.eq(1), tag_port.we.eq(1)),
               NextState("IDLE")).Else(
                   If(tag_do.dirty, NextState("EVICT_REQUEST")).Else(
                       NextState("REFILL_WRTAG"))))

        fsm.act("EVICT_REQUEST", lasmim.stb.eq(1), lasmim.we.eq(1),
                If(lasmim.req_ack, NextState("EVICT_WAIT_DATA_ACK")))
        fsm.act("EVICT_WAIT_DATA_ACK",
                If(lasmim.dat_ack, NextState("EVICT_DATAD")))
        fsm.act(
            "EVICT_DATA", write_to_lasmi.eq(1), word_inc.eq(1),
            If(
                word_is_last(word),
                NextState("REFILL_WRTAG"),
            ).Else(NextState("EVICT_REQUEST")))

        fsm.act(
            "REFILL_WRTAG",
            # Write the tag first to set the LASMI address
            tag_port.we.eq(1),
            word_clr.eq(1),
            NextState("REFILL_REQUEST"))
        fsm.act("REFILL_REQUEST", lasmim.stb.eq(1),
                If(lasmim.req_ack, NextState("REFILL_WAIT_DATA_ACK")))
        fsm.act("REFILL_WAIT_DATA_ACK",
                If(lasmim.dat_ack, NextState("REFILL_DATAD")))
        fsm.act(
            "REFILL_DATA", write_from_lasmi.eq(1), word_inc.eq(1),
            If(
                word_is_last(word),
                NextState("TEST_HIT"),
            ).Else(NextState("REFILL_REQUEST")))
Пример #27
0
 def __init__(self):
     self.bus = wishbone.Interface()
     self.ack_en = Signal()
     self.prng = Random(763627)
Пример #28
0
    def __init__(self, pads,
                 read_wait_cycles=10, hiz_wait_cycles=3,
                 bus=None):
        if bus is None:
            bus = wishbone.Interface(data_width=flen(pads.d))
        self.bus = bus

        # # #

        dts = TSTriple(flen(pads.d))
        self.specials += dts.get_tristate(pads.d)
        hold_address = Signal()
        dr = Signal(flen(pads.d))
        rx = Signal()
        self.sync += [
            If(~hold_address, pads.a.eq(bus.adr)),
            dts.o.eq(bus.dat_w),
            dr.eq(dts.i),
            dts.oe.eq(~rx)
        ]

        if hasattr(pads, "sel"):
            sel_len = flen(pads.sel)
        else:
            sel_len = flen(pads.sel_n)
        gpio = Signal(sel_len + 1)
        gpio_load = Signal()
        self.sync += If(gpio_load, gpio.eq(bus.dat_w))
        if hasattr(pads, "rst"):
            self.comb += pads.rst.eq(gpio[0])
        else:
            self.comb += pads.rst_n.eq(~gpio[0])
        if hasattr(pads, "sel"):
            self.comb += pads.sel.eq(gpio[1:])
        else:
            self.comb += pads.sel_n.eq(~gpio[1:])

        bus_r_gpio = Signal()
        self.comb += If(bus_r_gpio,
                bus.dat_r.eq(gpio)
            ).Else(
                bus.dat_r.eq(dr)
            )

        fud = Signal()
        if hasattr(pads, "fud"):
            self.sync += pads.fud.eq(fud)
        else:
            self.sync += pads.fud_n.eq(~fud)

        pads.wr_n.reset = 1
        pads.rd_n.reset = 1
        wr = Signal()
        rd = Signal()
        self.sync += pads.wr_n.eq(~wr), pads.rd_n.eq(~rd)

        self.submodules.read_timer = WaitTimer(read_wait_cycles)
        self.submodules.hiz_timer = WaitTimer(hiz_wait_cycles)

        fsm = FSM("IDLE")
        self.submodules += fsm

        fsm.act("IDLE",
            If(bus.cyc & bus.stb,
                If(bus.adr[flen(pads.a)],
                    If(bus.adr[0],
                        NextState("GPIO")
                    ).Else(
                        NextState("FUD")
                    )
                ).Else(
                    If(bus.we,
                        NextState("WRITE")
                    ).Else(
                        NextState("READ")
                    )
                )
            )
        )
        fsm.act("WRITE",
            # 3ns A setup to WR active
            wr.eq(1),
            NextState("WRITE0")
        )
        fsm.act("WRITE0",
            # 3.5ns D setup to WR inactive
            # 0ns D and A hold to WR inactive
            bus.ack.eq(1),
            NextState("IDLE")
        )
        fsm.act("READ",
            # 15ns D valid to A setup
            # 15ns D valid to RD active
            rx.eq(1),
            rd.eq(1),
            self.read_timer.wait.eq(1),
            If(self.read_timer.done,
               bus.ack.eq(1),
               NextState("WAIT_HIZ")
            )
        )
        fsm.act("WAIT_HIZ",
            rx.eq(1),
            # For some reason, AD9858 has an address hold time to RD inactive.
            hold_address.eq(1),
            self.hiz_timer.wait.eq(1),
            If(self.hiz_timer.done, NextState("IDLE"))
        )
        fsm.act("FUD",
            # 4ns FUD setup to SYNCLK
            # 0ns FUD hold to SYNCLK
            fud.eq(1),
            bus.ack.eq(1),
            NextState("IDLE")
        )
        fsm.act("GPIO",
            bus.ack.eq(1),
            bus_r_gpio.eq(1),
            If(bus.we, gpio_load.eq(1)),
            NextState("IDLE")
        )
Пример #29
0
	def __init__(self, cachesize, lasmim, wbm=None):
		if wbm is None:
			wbm = wishbone.Interface()
		self.wishbone = wbm

		###

		data_width = flen(self.wishbone.dat_r)
		if lasmim.dw < data_width:
			raise ValueError("LASMI data width must be >= {dw}".format(dw=data_width))
		if (lasmim.dw % data_width) != 0:
			raise ValueError("LASMI data width must be a multiple of {dw}".format(dw=data_width))

		# Split address:
		# TAG | LINE NUMBER | LINE OFFSET
		offsetbits = log2_int(lasmim.dw//data_width)
		addressbits = lasmim.aw + offsetbits
		linebits = log2_int(cachesize) - offsetbits
		tagbits = addressbits - linebits
		adr_offset, adr_line, adr_tag = split(self.wishbone.adr, offsetbits, linebits, tagbits)
		
		# Data memory
		data_mem = Memory(lasmim.dw, 2**linebits)
		data_port = data_mem.get_port(write_capable=True, we_granularity=8)
		self.specials += data_mem, data_port
		
		write_from_lasmi = Signal()
		write_to_lasmi = Signal()
		if adr_offset is None:
			adr_offset_r = None
		else:
			adr_offset_r = Signal(offsetbits)
			self.sync += adr_offset_r.eq(adr_offset)

		self.comb += [
			data_port.adr.eq(adr_line),
			If(write_from_lasmi,
				data_port.dat_w.eq(lasmim.dat_r),
				data_port.we.eq(Replicate(1, lasmim.dw//8))
			).Else(
				data_port.dat_w.eq(Replicate(self.wishbone.dat_w, lasmim.dw//data_width)),
				If(self.wishbone.cyc & self.wishbone.stb & self.wishbone.we & self.wishbone.ack,
					displacer(self.wishbone.sel, adr_offset, data_port.we, 2**offsetbits, reverse=True)
				)
			),
			If(write_to_lasmi, 
				lasmim.dat_w.eq(data_port.dat_r),
				lasmim.dat_we.eq(2**(lasmim.dw//8)-1)
			),
			chooser(data_port.dat_r, adr_offset_r, self.wishbone.dat_r, reverse=True)
		]

		
		# Tag memory
		tag_layout = [("tag", tagbits), ("dirty", 1)]
		tag_mem = Memory(layout_len(tag_layout), 2**linebits)
		tag_port = tag_mem.get_port(write_capable=True)
		self.specials += tag_mem, tag_port
		tag_do = Record(tag_layout)
		tag_di = Record(tag_layout)
		self.comb += [
			tag_do.raw_bits().eq(tag_port.dat_r),
			tag_port.dat_w.eq(tag_di.raw_bits())
		]
			
		self.comb += [
			tag_port.adr.eq(adr_line),
			tag_di.tag.eq(adr_tag),
			lasmim.adr.eq(Cat(adr_line, tag_do.tag))
		]
		
		# Control FSM
		assert(lasmim.write_latency >= 1 and lasmim.read_latency >= 1)
		fsm = FSM()
		self.submodules += fsm
		
		fsm.delayed_enter("EVICT_DATAD", "EVICT_DATA", lasmim.write_latency-1)
		fsm.delayed_enter("REFILL_DATAD", "REFILL_DATA", lasmim.read_latency-1)

		fsm.act("IDLE",
			If(self.wishbone.cyc & self.wishbone.stb, NextState("TEST_HIT"))
		)
		fsm.act("TEST_HIT",
			If(tag_do.tag == adr_tag,
				self.wishbone.ack.eq(1),
				If(self.wishbone.we,
					tag_di.dirty.eq(1),
					tag_port.we.eq(1)
				),
				NextState("IDLE")
			).Else(
				If(tag_do.dirty,
					NextState("EVICT_REQUEST")
				).Else(
					NextState("REFILL_WRTAG")
				)
			)
		)
		
		fsm.act("EVICT_REQUEST",
			lasmim.stb.eq(1),
			lasmim.we.eq(1),
			If(lasmim.req_ack, NextState("EVICT_WAIT_DATA_ACK"))
		)
		fsm.act("EVICT_WAIT_DATA_ACK",
			If(lasmim.dat_ack, NextState("EVICT_DATAD"))
		)
		fsm.act("EVICT_DATA",
			write_to_lasmi.eq(1),
			NextState("REFILL_WRTAG")
		)
		
		fsm.act("REFILL_WRTAG",
			# Write the tag first to set the LASMI address
			tag_port.we.eq(1),
			NextState("REFILL_REQUEST")
		)
		fsm.act("REFILL_REQUEST",
			lasmim.stb.eq(1),
			If(lasmim.req_ack, NextState("REFILL_WAIT_DATA_ACK"))
		)
		fsm.act("REFILL_WAIT_DATA_ACK",
			If(lasmim.dat_ack, NextState("REFILL_DATAD"))
		)
		fsm.act("REFILL_DATA",
			write_from_lasmi.eq(1),
			NextState("TEST_HIT")
		)