soc/cores: move flash cores to cores directory
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 19 Apr 2017 08:55:58 +0000 (10:55 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 19 Apr 2017 08:58:15 +0000 (10:58 +0200)
litex/boards/targets/kc705.py
litex/soc/cores/flash/__init__.py [deleted file]
litex/soc/cores/flash/nor_flash_16.py [deleted file]
litex/soc/cores/flash/spi_flash.py [deleted file]
litex/soc/cores/nor_flash_16.py [new file with mode: 0644]
litex/soc/cores/spi_flash.py [new file with mode: 0644]

index 128d318faacb46095aef84acc538d9e8fc5c31da..297159d0030fd5a3d23023c465cb58f5d2873ff2 100755 (executable)
@@ -6,7 +6,6 @@ from litex.gen import *
 from litex.gen.genlib.resetsync import AsyncResetSynchronizer
 from litex.boards.platforms import kc705
 
-from litex.soc.cores.flash import spi_flash
 from litex.soc.integration.soc_core import mem_decoder
 from litex.soc.integration.soc_sdram import *
 from litex.soc.integration.builder import *
diff --git a/litex/soc/cores/flash/__init__.py b/litex/soc/cores/flash/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/litex/soc/cores/flash/nor_flash_16.py b/litex/soc/cores/flash/nor_flash_16.py
deleted file mode 100644 (file)
index 3027882..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-from litex.gen import *
-from litex.gen.genlib.fsm import FSM, NextState
-
-from litex.soc.interconnect import wishbone
-
-
-class NorFlash16(Module):
-    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")
-        )
diff --git a/litex/soc/cores/flash/spi_flash.py b/litex/soc/cores/flash/spi_flash.py
deleted file mode 100644 (file)
index 14df3a4..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-from litex.gen import *
-from litex.gen.genlib.misc import timeline
-
-from litex.soc.interconnect import wishbone
-from litex.soc.interconnect.csr import AutoCSR, CSRStorage, CSRStatus
-
-
-_FAST_READ = 0x0b
-_DIOFR = 0xbb
-_QIOFR = 0xeb
-
-
-def _format_cmd(cmd, spi_width):
-    """
-    `cmd` is the read instruction. Since everything is transmitted on all
-    dq lines (cmd, adr and data), extend/interleave cmd to full pads.dq
-    width even if dq1-dq3 are don't care during the command phase:
-    For example, for N25Q128, 0xeb is the quad i/o fast read, and
-    extended to 4 bits (dq1,dq2,dq3 high) is: 0xfffefeff
-    """
-    c = 2**(8*spi_width)-1
-    for b in range(8):
-        if not (cmd>>b)%2:
-            c &= ~(1<<(b*spi_width))
-    return c
-
-
-class SpiFlashDualQuad(Module, AutoCSR):
-    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)
-
-
-class SpiFlashSingle(Module, AutoCSR):
-    def __init__(self, pads, dummy=15, div=2):
-        """
-        Simple SPI flash.
-        Supports 1-bit reads. Only supports mode0 (cpol=0, cpha=0).
-        """
-        self.bus = bus = wishbone.Interface()
-
-        # # #
-
-        if hasattr(pads, "wp"):
-            self.comb += pads.wp.eq(1)
-
-        if hasattr(pads, "hold"):
-            self.comb += pads.hold.eq(1)
-
-        cs_n = Signal(reset=1)
-        clk = Signal()
-        wbone_width = len(bus.dat_r)
-
-        read_cmd = _FAST_READ
-        cmd_width = 8
-        addr_width = 24
-
-        sr = Signal(max(cmd_width, addr_width, wbone_width))
-        self.comb += bus.dat_r.eq(sr)
-
-        self.comb += [
-            pads.clk.eq(clk),
-            pads.cs_n.eq(cs_n),
-            pads.mosi.eq(sr[-1:])
-        ]
-
-        if div < 2:
-            raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))
-        else:
-            i = Signal(max=div)
-            miso = Signal()
-            self.sync += [
-                If(i == div//2 - 1,
-                    clk.eq(1),
-                    miso.eq(pads.miso),
-                ),
-                If(i == div - 1,
-                    i.eq(0),
-                    clk.eq(0),
-                    sr.eq(Cat(miso, sr[:-1]))
-                ).Else(
-                    i.eq(i + 1),
-                ),
-            ]
-
-        # spi is byte-addressed, prefix by zeros
-        z = Replicate(0, log2_int(wbone_width//8))
-
-        seq = [
-            (cmd_width*div,
-                [cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
-            (addr_width*div,
-                [sr[-addr_width:].eq(Cat(z, bus.adr))]),
-            ((dummy + wbone_width)*div,
-                []),
-            (1,
-                [bus.ack.eq(1), cs_n.eq(1)]),
-            (div, # tSHSL!
-                [bus.ack.eq(0)]),
-            (0,
-                []),
-        ]
-
-        # accumulate timeline deltas
-        t, tseq = 0, []
-        for dt, a in seq:
-            tseq.append((t, a))
-            t += dt
-
-        self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
-
-
-def SpiFlash(pads, *args, **kw):
-    if hasattr(pads, "mosi"):
-        return SpiFlashSingle(pads, *args, **kw)
-    else:
-        return SpiFlashDualQuad(pads, *args, **kw)
diff --git a/litex/soc/cores/nor_flash_16.py b/litex/soc/cores/nor_flash_16.py
new file mode 100644 (file)
index 0000000..3027882
--- /dev/null
@@ -0,0 +1,104 @@
+from litex.gen import *
+from litex.gen.genlib.fsm import FSM, NextState
+
+from litex.soc.interconnect import wishbone
+
+
+class NorFlash16(Module):
+    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")
+        )
diff --git a/litex/soc/cores/spi_flash.py b/litex/soc/cores/spi_flash.py
new file mode 100644 (file)
index 0000000..14df3a4
--- /dev/null
@@ -0,0 +1,197 @@
+from litex.gen import *
+from litex.gen.genlib.misc import timeline
+
+from litex.soc.interconnect import wishbone
+from litex.soc.interconnect.csr import AutoCSR, CSRStorage, CSRStatus
+
+
+_FAST_READ = 0x0b
+_DIOFR = 0xbb
+_QIOFR = 0xeb
+
+
+def _format_cmd(cmd, spi_width):
+    """
+    `cmd` is the read instruction. Since everything is transmitted on all
+    dq lines (cmd, adr and data), extend/interleave cmd to full pads.dq
+    width even if dq1-dq3 are don't care during the command phase:
+    For example, for N25Q128, 0xeb is the quad i/o fast read, and
+    extended to 4 bits (dq1,dq2,dq3 high) is: 0xfffefeff
+    """
+    c = 2**(8*spi_width)-1
+    for b in range(8):
+        if not (cmd>>b)%2:
+            c &= ~(1<<(b*spi_width))
+    return c
+
+
+class SpiFlashDualQuad(Module, AutoCSR):
+    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)
+
+
+class SpiFlashSingle(Module, AutoCSR):
+    def __init__(self, pads, dummy=15, div=2):
+        """
+        Simple SPI flash.
+        Supports 1-bit reads. Only supports mode0 (cpol=0, cpha=0).
+        """
+        self.bus = bus = wishbone.Interface()
+
+        # # #
+
+        if hasattr(pads, "wp"):
+            self.comb += pads.wp.eq(1)
+
+        if hasattr(pads, "hold"):
+            self.comb += pads.hold.eq(1)
+
+        cs_n = Signal(reset=1)
+        clk = Signal()
+        wbone_width = len(bus.dat_r)
+
+        read_cmd = _FAST_READ
+        cmd_width = 8
+        addr_width = 24
+
+        sr = Signal(max(cmd_width, addr_width, wbone_width))
+        self.comb += bus.dat_r.eq(sr)
+
+        self.comb += [
+            pads.clk.eq(clk),
+            pads.cs_n.eq(cs_n),
+            pads.mosi.eq(sr[-1:])
+        ]
+
+        if div < 2:
+            raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))
+        else:
+            i = Signal(max=div)
+            miso = Signal()
+            self.sync += [
+                If(i == div//2 - 1,
+                    clk.eq(1),
+                    miso.eq(pads.miso),
+                ),
+                If(i == div - 1,
+                    i.eq(0),
+                    clk.eq(0),
+                    sr.eq(Cat(miso, sr[:-1]))
+                ).Else(
+                    i.eq(i + 1),
+                ),
+            ]
+
+        # spi is byte-addressed, prefix by zeros
+        z = Replicate(0, log2_int(wbone_width//8))
+
+        seq = [
+            (cmd_width*div,
+                [cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
+            (addr_width*div,
+                [sr[-addr_width:].eq(Cat(z, bus.adr))]),
+            ((dummy + wbone_width)*div,
+                []),
+            (1,
+                [bus.ack.eq(1), cs_n.eq(1)]),
+            (div, # tSHSL!
+                [bus.ack.eq(0)]),
+            (0,
+                []),
+        ]
+
+        # accumulate timeline deltas
+        t, tseq = 0, []
+        for dt, a in seq:
+            tseq.append((t, a))
+            t += dt
+
+        self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
+
+
+def SpiFlash(pads, *args, **kw):
+    if hasattr(pads, "mosi"):
+        return SpiFlashSingle(pads, *args, **kw)
+    else:
+        return SpiFlashDualQuad(pads, *args, **kw)