Beispiel #1
0
    def __init__(self, settings):
        # 1st command 1 cycle after assertion of ready
        self.cmd = cmd = stream.Endpoint(cmd_request_rw_layout(settings.geom.addressbits,
                                                               settings.geom.bankbits))

        # # #

        # Refresh sequence generator:
        # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
        seq_start = Signal()
        seq_done = Signal()
        self.sync += [
            cmd.a.eq(2**10),
            cmd.ba.eq(0),
            cmd.cas.eq(0),
            cmd.ras.eq(0),
            cmd.we.eq(0),
            seq_done.eq(0)
        ]
        self.sync += timeline(seq_start, [
            (1, [
                cmd.ras.eq(1),
                cmd.we.eq(1)
            ]),
            (1+settings.timing.tRP, [
                cmd.cas.eq(1),
                cmd.ras.eq(1)
            ]),
            (1+settings.timing.tRP+settings.timing.tRFC, [
                seq_done.eq(1)
            ])
        ])

        # Periodic refresh counter
        self.submodules.timer = WaitTimer(settings.timing.tREFI)
        self.comb += self.timer.wait.eq(settings.with_refresh & ~self.timer.done)

        # Control FSM
        self.submodules.fsm = fsm = FSM()
        fsm.act("IDLE",
            If(self.timer.done,
                NextState("WAIT_GRANT")
            )
        )
        fsm.act("WAIT_GRANT",
            cmd.valid.eq(1),
            If(cmd.ready,
                seq_start.eq(1),
                NextState("WAIT_SEQ")
            )
        )
        fsm.act("WAIT_SEQ",
            If(seq_done,
                cmd.last.eq(1),
                NextState("IDLE")
            ).Else(
                cmd.valid.eq(1)
            )
        )
Beispiel #2
0
    def __init__(self, platform):
        self.clock_domains.cd_sys = ClockDomain("sys")

        # soft reset generaton
        self._soft_rst = CSR()
        soft_rst = Signal()
        # trigger soft reset 1us after CSR access to terminate
        # Wishbone access when reseting from PCIe
        self.sync += [
            timeline(self._soft_rst.re & self._soft_rst.r, [(125, [soft_rst.eq(1)])]),
        ]

        # sys_clk / sys_rst (from PCIe)
        self.comb += self.cd_sys.clk.eq(ClockSignal("pcie"))
        self.specials += AsyncResetSynchronizer(self.cd_sys, ResetSignal("pcie") | soft_rst)
Beispiel #3
0
    def __init__(self, platform):
        self.clock_domains.cd_sys = ClockDomain("sys")
        self.clock_domains.cd_clk125 = ClockDomain("clk125")

        # soft reset generaton
        self._soft_rst = CSR()
        soft_rst = Signal()
        # trigger soft reset 1us after CSR access to terminate
        # Wishbone access when reseting from PCIe
        self.sync += [
            timeline(self._soft_rst.re & self._soft_rst.r, [(125, [soft_rst.eq(1)])]),
        ]

        # sys_clk / sys_rst (from PCIe)
        self.comb += self.cd_sys.clk.eq(self.cd_clk125.clk)
        self.specials += AsyncResetSynchronizer(self.cd_sys, self.cd_clk125.rst | soft_rst)
Beispiel #4
0
    def __init__(self, a, ba, tRP, tREFI, tRFC):
        self.req = Signal()
        self.ack = Signal()  # 1st command 1 cycle after assertion of ack
        self.cmd = CommandRequest(a, ba)

        ###

        # Refresh sequence generator:
        # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
        seq_start = Signal()
        seq_done = Signal()
        self.sync += [
            self.cmd.a.eq(2**10),
            self.cmd.ba.eq(0),
            self.cmd.cas_n.eq(1),
            self.cmd.ras_n.eq(1),
            self.cmd.we_n.eq(1),
            seq_done.eq(0)
        ]
        self.sync += timeline(
            seq_start, [(1, [self.cmd.ras_n.eq(0),
                             self.cmd.we_n.eq(0)]),
                        (1 + tRP, [self.cmd.cas_n.eq(0),
                                   self.cmd.ras_n.eq(0)]),
                        (1 + tRP + tRFC, [seq_done.eq(1)])])

        # Periodic refresh counter
        counter = Signal(max=tREFI)
        start = Signal()
        self.sync += [
            start.eq(0),
            If(counter == 0, start.eq(1),
               counter.eq(tREFI - 1)).Else(counter.eq(counter - 1))
        ]

        # Control FSM
        fsm = FSM()
        self.submodules += fsm
        fsm.act("IDLE", If(start, NextState("WAIT_GRANT")))
        fsm.act("WAIT_GRANT", self.req.eq(1),
                If(self.ack, seq_start.eq(1), NextState("WAIT_SEQ")))
        fsm.act("WAIT_SEQ", self.req.eq(1), If(seq_done, NextState("IDLE")))
Beispiel #5
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_bus.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)])])
Beispiel #6
0
    def __init__(self, settings):
        # 1st command 1 cycle after assertion of ready
        self.cmd = cmd = stream.Endpoint(
            cmd_request_rw_layout(settings.geom.addressbits,
                                  settings.geom.bankbits))

        # # #

        # Refresh sequence generator:
        # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
        seq_start = Signal()
        seq_done = Signal()
        self.sync += [
            cmd.a.eq(2**10),
            cmd.ba.eq(0),
            cmd.cas.eq(0),
            cmd.ras.eq(0),
            cmd.we.eq(0),
            seq_done.eq(0)
        ]
        self.sync += timeline(seq_start, [
            (1, [cmd.ras.eq(1), cmd.we.eq(1)]),
            (1 + settings.timing.tRP, [cmd.cas.eq(1),
                                       cmd.ras.eq(1)]),
            (1 + settings.timing.tRP + settings.timing.tRFC, [seq_done.eq(1)])
        ])

        # Periodic refresh counter
        self.submodules.timer = WaitTimer(settings.timing.tREFI)
        self.comb += self.timer.wait.eq(settings.with_refresh
                                        & ~self.timer.done)

        # Control FSM
        self.submodules.fsm = fsm = FSM()
        fsm.act("IDLE", If(self.timer.done, NextState("WAIT_GRANT")))
        fsm.act("WAIT_GRANT", cmd.valid.eq(1),
                If(cmd.ready, seq_start.eq(1), NextState("WAIT_SEQ")))
        fsm.act(
            "WAIT_SEQ",
            If(seq_done, cmd.last.eq(1),
               NextState("IDLE")).Else(cmd.valid.eq(1)))
Beispiel #7
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_bus.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)])
        ])
Beispiel #8
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, [bus.ack.eq(0)]),  # tSHSL!
            (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)
Beispiel #9
0
    def __init__(self, pads, dummy=15, div=2, with_bitbang=True):
        """
        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

        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),
        }
        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))
        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]),

                # 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)
Beispiel #10
0
    def __init__(self, pads, dummy=15, div=2, with_bitbang=True):
        """
        Simple SPI flash.
        Supports 1-bit reads. Only supports mode0 (cpol=0, cpha=0).
        """
        self.bus = bus = wishbone.Interface()

        if with_bitbang:
            self.bitbang = CSRStorage(4)
            self.miso = CSRStatus()
            self.bitbang_en = CSRStorage()

        # # #

        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))
        self.comb += bus.dat_r.eq(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)
Beispiel #11
0
    def __init__(self, pads, dummy=15, div=2):
        """
        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))
        self.comb += bus.dat_r.eq(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)
Beispiel #12
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)