예제 #1
0
    def __init__(self, endianness="big"):
        self.source = source = stream.Endpoint(spi_core2phy_layout)
        self.sink = sink = stream.Endpoint(spi_phy2core_layout)
        self.bus = bus = wishbone.Interface()
        self.cs = cs = Signal()

        # # #

        # Burst Control.
        burst_cs = Signal()
        burst_adr = Signal(len(bus.adr), reset_less=True)
        burst_timeout = WaitTimer(MMAP_DEFAULT_TIMEOUT)
        self.submodules += burst_timeout

        # FSM.
        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act(
            "IDLE",
            # Keep CS active after Burst for Timeout.
            burst_timeout.wait.eq(1),
            NextValue(burst_cs, burst_cs & ~burst_timeout.done),
            cs.eq(burst_cs),
            # On Bus Read access...
            If(
                bus.cyc & bus.stb & ~bus.we,
                # If CS is still active and Bus address matches previous Burst address:
                # Just continue the current Burst.
                If(burst_cs & (bus.adr == burst_adr),
                   NextState("BURST-REQ")
                   # Otherwise initialize a new Burst.
                   ).Else(cs.eq(0), NextState("BURST-CMD"))))
        fsm.act(
            "BURST-CMD",
            cs.eq(1),
            source.valid.eq(1),
            source.cmd.eq(CMD),
            source.data.eq(Cat(Signal(2), bus.adr)),  # Words to Bytes.
            NextValue(burst_cs, 1),
            NextValue(burst_adr, bus.adr),
            If(
                source.ready,
                NextState("BURST-REQ"),
            ))
        fsm.act("BURST-REQ", cs.eq(1), source.valid.eq(1), source.cmd.eq(READ),
                source.last.eq(1), If(
                    source.ready,
                    NextState("BURST-DAT"),
                ))
        fsm.act(
            "BURST-DAT", cs.eq(1), sink.ready.eq(1),
            bus.dat_r.eq({
                "big": sink.data,
                "little": reverse_bytes(sink.data)
            }[endianness]),
            If(
                sink.valid,
                bus.ack.eq(1),
                NextValue(burst_adr, burst_adr + 1),
                NextState("IDLE"),
            ))
예제 #2
0
파일: core.py 프로젝트: xinghuaman/litex
    def __init__(self,
                 platform,
                 core_irq_out=Signal(),
                 int_level_in=Signal(16),
                 endianness="big",
                 variant="standard"):
        self.variant = variant

        self.icp_bus = icp_bus = wishbone.Interface(data_width=32,
                                                    adr_width=12)
        self.ics_bus = ics_bus = wishbone.Interface(data_width=32,
                                                    adr_width=12)

        # Bus endianness handlers
        self.icp_dat_w = Signal(32)
        self.icp_dat_r = Signal(32)
        self.comb += self.icp_dat_w.eq(icp_bus.dat_w if endianness ==
                                       "big" else reverse_bytes(icp_bus.dat_w))
        self.comb += icp_bus.dat_r.eq(self.icp_dat_r if endianness ==
                                      "big" else reverse_bytes(self.icp_dat_r))
        self.ics_dat_w = Signal(32)
        self.ics_dat_r = Signal(32)
        self.comb += self.ics_dat_w.eq(ics_bus.dat_w if endianness ==
                                       "big" else reverse_bytes(ics_bus.dat_w))
        self.comb += ics_bus.dat_r.eq(self.ics_dat_r if endianness ==
                                      "big" else reverse_bytes(self.ics_dat_r))

        # XICS signals
        self.ics_icp_xfer_src = Signal(4)
        self.ics_icp_xfer_pri = Signal(8)

        self.icp_params = dict(
            # Clock / Reset
            i_clk=ClockSignal(),
            i_rst=ResetSignal(),

            # Wishbone bus
            o_wishbone_dat_r=self.icp_dat_r,
            o_wishbone_ack=icp_bus.ack,
            i_wishbone_adr=icp_bus.adr,
            i_wishbone_dat_w=self.icp_dat_w,
            i_wishbone_cyc=icp_bus.cyc,
            i_wishbone_stb=icp_bus.stb,
            i_wishbone_sel=icp_bus.sel,
            i_wishbone_we=icp_bus.we,
            i_ics_in_src=self.ics_icp_xfer_src,
            i_ics_in_pri=self.ics_icp_xfer_pri,
            o_core_irq_out=core_irq_out,
        )

        self.ics_params = dict(
            # Clock / Reset
            i_clk=ClockSignal(),
            i_rst=ResetSignal(),

            # Wishbone bus
            o_wishbone_dat_r=self.ics_dat_r,
            o_wishbone_ack=ics_bus.ack,
            i_wishbone_adr=ics_bus.adr,
            i_wishbone_dat_w=self.ics_dat_w,
            i_wishbone_cyc=ics_bus.cyc,
            i_wishbone_stb=ics_bus.stb,
            i_wishbone_sel=ics_bus.sel,
            i_wishbone_we=ics_bus.we,
            i_int_level_in=int_level_in,
            o_icp_out_src=self.ics_icp_xfer_src,
            o_icp_out_pri=self.ics_icp_xfer_pri,
        )

        # add vhdl sources
        self.add_sources(platform,
                         use_ghdl_yosys_plugin="ghdl" in self.variant)
예제 #3
0
파일: dma.py 프로젝트: ozbenh/litex
def format_bytes(s, endianness):
    return {"big": s, "little": reverse_bytes(s)}[endianness]
예제 #4
0
    def __init__(self,
                 flash,
                 clock_domain="sys",
                 endianness="big",
                 with_csr=True):
        self.source = source = stream.Endpoint(spi_core2phy_layout)
        self.sink = sink = stream.Endpoint(spi_phy2core_layout)
        self.bus = bus = wishbone.Interface()
        self.cs = cs = Signal()

        # Burst Control.
        burst_cs = Signal()
        burst_adr = Signal(len(bus.adr), reset_less=True)
        burst_timeout = WaitTimer(MMAP_DEFAULT_TIMEOUT)
        self.submodules += burst_timeout

        cmd_bits = 8
        data_bits = 32

        if flash.cmd_width == 1:
            self._default_dummy_bits = flash.dummy_bits if flash.fast_mode else 0
        elif flash.cmd_width == 4:
            self._default_dummy_bits = flash.dummy_bits * 3 if flash.fast_mode else 0
        else:
            raise NotImplementedError(
                f'Command width of {flash.cmd_width} bits is currently not supported!'
            )

        self._spi_dummy_bits = spi_dummy_bits = Signal(8)

        if with_csr:
            self.dummy_bits = dummy_bits = CSRStorage(
                8, reset=self._default_dummy_bits)
            if clock_domain != "sys":
                self.specials += MultiReg(dummy_bits.storage, spi_dummy_bits,
                                          clock_domain)
            else:
                self.comb += spi_dummy_bits.eq(dummy_bits.storage)
        else:
            self.comb += spi_dummy_bits.eq(self._default_dummy_bits)

        dummy = Signal(data_bits, reset=0xdead)

        # FSM.
        self.submodules.fsm = fsm = FSM(reset_state="IDLE")
        fsm.act(
            "IDLE",
            # Keep CS active after Burst for Timeout.
            burst_timeout.wait.eq(1),
            NextValue(burst_cs, burst_cs & ~burst_timeout.done),
            cs.eq(burst_cs),
            # On Bus Read access...
            If(
                bus.cyc & bus.stb & ~bus.we,
                # If CS is still active and Bus address matches previous Burst address:
                # Just continue the current Burst.
                If(burst_cs & (bus.adr == burst_adr),
                   NextState("BURST-REQ")
                   # Otherwise initialize a new Burst.
                   ).Else(cs.eq(0), NextState("BURST-CMD"))))

        fsm.act(
            "BURST-CMD",
            cs.eq(1),
            source.valid.eq(1),
            source.data.eq(flash.read_opcode.code),  # send command.
            source.len.eq(cmd_bits),
            source.width.eq(flash.cmd_width),
            source.mask.eq(cmd_oe_mask[flash.cmd_width]),
            NextValue(burst_adr, bus.adr),
            If(
                source.ready,
                NextState("CMD-RET"),
            ))

        fsm.act("CMD-RET", cs.eq(1), sink.ready.eq(1),
                If(
                    sink.valid,
                    NextState("BURST-ADDR"),
                ))

        fsm.act(
            "BURST-ADDR",
            cs.eq(1),
            source.valid.eq(1),
            source.width.eq(flash.addr_width),
            source.mask.eq(addr_oe_mask[flash.addr_width]),
            source.data.eq(Cat(Signal(2), bus.adr)),  # send address.
            source.len.eq(flash.addr_bits),
            NextValue(burst_cs, 1),
            NextValue(burst_adr, bus.adr),
            If(
                source.ready,
                NextState("ADDR-RET"),
            ))

        fsm.act(
            "ADDR-RET", cs.eq(1), sink.ready.eq(1),
            If(
                sink.valid,
                If(
                    spi_dummy_bits == 0,
                    NextState("BURST-REQ"),
                ).Else(NextState("DUMMY"), )))

        fsm.act("DUMMY", cs.eq(1), source.valid.eq(1),
                source.width.eq(flash.addr_width),
                source.mask.eq(addr_oe_mask[flash.addr_width]),
                source.data.eq(dummy), source.len.eq(spi_dummy_bits),
                If(
                    source.ready,
                    NextState("DUMMY-RET"),
                ))

        fsm.act("DUMMY-RET", cs.eq(1), sink.ready.eq(1),
                If(
                    sink.valid,
                    NextState("BURST-REQ"),
                ))

        fsm.act("BURST-REQ", cs.eq(1), source.valid.eq(1), source.last.eq(1),
                source.width.eq(flash.bus_width), source.len.eq(data_bits),
                source.mask.eq(0), If(
                    source.ready,
                    NextState("BURST-DAT"),
                ))

        fsm.act(
            "BURST-DAT", cs.eq(1), sink.ready.eq(1),
            bus.dat_r.eq({
                "big": sink.data,
                "little": reverse_bytes(sink.data)
            }[endianness]),
            If(
                sink.valid,
                bus.ack.eq(1),
                NextValue(burst_adr, burst_adr + 1),
                NextState("IDLE"),
            ))