From 95cfd0b9e5db410b57d99050693ee8bafbe320de Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 22 Jul 2019 10:28:03 +0200 Subject: [PATCH] cores/spi_flash: add SpiFlashCommon and use it to add clk primitives (7-Series/ECP5 support for now) --- litex/soc/cores/spi_flash.py | 49 +++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/litex/soc/cores/spi_flash.py b/litex/soc/cores/spi_flash.py index caf81b80..2e40caa8 100644 --- a/litex/soc/cores/spi_flash.py +++ b/litex/soc/cores/spi_flash.py @@ -37,13 +37,50 @@ def _format_cmd(cmd, spi_width): return c -class SpiFlashDualQuad(Module, AutoCSR): +class SpiFlashCommon(Module): + def __init__(self, pads): + if not hasattr(pads, "clk"): + self.clk_primitive_needed = True + self.clk_primitive_registered = False + pads.clk = Signal() + self.pads = pads + + def add_clk_primitive(self, device): + assert hasattr(self, "clk_primitive_needed") + # Xilinx 7-series + if device[:3] == "xc7": + self.specials += Instance("STARTUPE2", + i_CLK=0, + i_GSR=0, + i_GTS=0, + i_KEYCLEARB=0, + i_PACK=0, + i_USRCCLKO=self.pads.clk, + i_USRCCLKTS=0, + i_USRDONEO=1, + i_USRDONETS=1) + # Lattice ECP5 + elif device[:4] == "LFE5": + self.specials += Instance("USRMCLK", + i_USRMCLKI=self.pads.clk, + i_USRMCLKTS=0) + else: + raise NotImplementedError + self.clk_primitive_registered = True + + def do_finalize(self): + if hasattr(self, "clk_primitive_needed"): + assert self.clk_primitive_registered == True + + +class SpiFlashDualQuad(SpiFlashCommon, AutoCSR): def __init__(self, pads, dummy=15, div=2, with_bitbang=True, endianness="big"): """ Simple SPI flash. Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast Read). Only supports mode0 (cpol=0, cpha=0). """ + SpiFlashCommon.__init__(self, pads) self.bus = bus = wishbone.Interface() spi_width = len(pads.dq) assert spi_width >= 2 @@ -164,12 +201,13 @@ class SpiFlashDualQuad(Module, AutoCSR): self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq) -class SpiFlashSingle(Module, AutoCSR): +class SpiFlashSingle(SpiFlashCommon, AutoCSR): def __init__(self, pads, dummy=15, div=2, with_bitbang=True, endianness="big"): """ Simple SPI flash. Supports 1-bit reads. Only supports mode0 (cpol=0, cpha=0). """ + SpiFlashCommon.__init__(self, pads) self.bus = bus = wishbone.Interface() if with_bitbang: @@ -272,12 +310,11 @@ class SpiFlashSingle(Module, AutoCSR): self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq) -def SpiFlash(pads, *args, **kw): +def SpiFlash(pads, *args, **kwargs): if hasattr(pads, "mosi"): - return SpiFlashSingle(pads, *args, **kw) + return SpiFlashSingle(pads, *args, **kwargs) else: - return SpiFlashDualQuad(pads, *args, **kw) - + return SpiFlashDualQuad(pads, *args, **kwargs) # Xilinx 7-Series FPGAs SPI Flash (non-memory-mapped) ---------------------------------------------- -- 2.30.2