Guest User

spiflash

a guest
Oct 15th, 2014
289
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.78 KB | None | 0 0
  1. diff --git a/misoclib/spiflash/__init__.py b/misoclib/spiflash/__init__.py
  2. index 8f83673..d4cf8d0 100644
  3. --- a/misoclib/spiflash/__init__.py
  4. +++ b/misoclib/spiflash/__init__.py
  5. @@ -3,6 +3,7 @@ from migen.bus.transactions import *
  6.  from migen.bus import wishbone
  7.  from migen.genlib.misc import timeline
  8.  from migen.genlib.record import Record
  9. +from migen.bank.description import AutoCSR, CSRStorage, CSR
  10.  
  11.  _FAST_READ = 0x0b
  12.  _DIOFR = 0xbb
  13. @@ -22,7 +23,7 @@ def _format_cmd(cmd, spi_width):
  14.             c &= ~(1<<(b*spi_width))
  15.     return c
  16.  
  17. -class SpiFlash(Module):
  18. +class SpiFlash(Module, AutoCSR):
  19.     def __init__(self, pads, dummy=15, div=2):
  20.         """
  21.         Simple read-only SPI flash, e.g. N25Q128 on the LX9 Microboard.
  22. @@ -31,18 +32,24 @@ class SpiFlash(Module):
  23.         Read). Only supports mode0 (cpol=0, cpha=0).
  24.         """
  25.         self.bus = bus = wishbone.Interface()
  26. +       spi_width = flen(pads.dq)
  27. +       bitbang_width = spi_width + 4
  28. +       self.bitbang = CSRStorage(bitbang_width)
  29. +       self.miso = CSR(1)
  30.  
  31.         ##
  32.  
  33. +       cs_n = Signal(reset=1)
  34. +       clk = Signal()
  35.         wbone_width = flen(bus.dat_r)
  36. -       spi_width = flen(pads.dq)
  37.  
  38. -       cmd_params = {
  39. +
  40. +       read_cmd_params = {
  41.             4: (_format_cmd(_QIOFR, 4), 4*8),
  42.             2: (_format_cmd(_DIOFR, 2), 2*8),
  43.             1: (_format_cmd(_FAST_READ, 1), 1*8)
  44.         }
  45. -       cmd, cmd_width = cmd_params[spi_width]
  46. +       read_cmd, cmd_width = read_cmd_params[spi_width]
  47.         addr_width = 24
  48.  
  49.         pads.cs_n.reset = 1
  50. @@ -51,26 +58,43 @@ class SpiFlash(Module):
  51.         self.specials.dq = dq.get_tristate(pads.dq)
  52.  
  53.         sr = Signal(max(cmd_width, addr_width, wbone_width))
  54. -       self.comb += [
  55. -           bus.dat_r.eq(sr),
  56. -           dq.o.eq(sr[-spi_width:]),
  57. +       self.comb += bus.dat_r.eq(sr)
  58. +
  59. +       self.sync += [
  60. +               If(self.bitbang.storage[bitbang_width-1],
  61. +                   pads.cs_n.eq(self.bitbang.storage[spi_width+1:spi_width+2]),
  62. +                   pads.clk.eq(self.bitbang.storage[spi_width:spi_width+1]),
  63. +                   dq.o.eq(self.bitbang.storage[0:spi_width]),
  64. +                   If(self.bitbang.storage[spi_width+2:spi_width+3],
  65. +                       dq.oe.eq(0)
  66. +                   ).Else(
  67. +                       dq.oe.eq(1)
  68. +                   ),
  69. +                   If(self.bitbang.storage[spi_width:spi_width+1],
  70. +                       self.miso.w.eq(1) # dq.i
  71. +                   )
  72. +               ).Else(
  73. +                   pads.cs_n.eq(cs_n),
  74. +                   pads.clk.eq(clk),
  75. +                   dq.o.eq(sr[-spi_width:])
  76. +               )
  77.         ]
  78.  
  79.         if div == 1:
  80.             i = 0
  81. -           self.comb += pads.clk.eq(~ClockSignal())
  82. +           self.comb += clk.eq(~ClockSignal())
  83.             self.sync += sr.eq(Cat(dq.i, sr[:-spi_width]))
  84.         else:
  85.             i = Signal(max=div)
  86.             dqi = Signal(spi_width)
  87.             self.sync += [
  88.                 If(i == div//2 - 1,
  89. -                   pads.clk.eq(1),
  90. +                   clk.eq(1),
  91.                     dqi.eq(dq.i),
  92.                 ),
  93.                 If(i == div - 1,
  94.                     i.eq(0),
  95. -                   pads.clk.eq(0),
  96. +                   clk.eq(0),
  97.                     sr.eq(Cat(dqi, sr[:-spi_width]))
  98.                 ).Else(
  99.                     i.eq(i + 1),
  100. @@ -82,13 +106,13 @@ class SpiFlash(Module):
  101.  
  102.         seq = [
  103.             (cmd_width//spi_width*div,
  104. -               [dq.oe.eq(1), pads.cs_n.eq(0), sr[-cmd_width:].eq(cmd)]),
  105. +               [dq.oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
  106.             (addr_width//spi_width*div,
  107.                 [sr[-addr_width:].eq(Cat(z, bus.adr))]),
  108.             ((dummy + wbone_width//spi_width)*div,
  109.                 [dq.oe.eq(0)]),
  110.             (1,
  111. -               [bus.ack.eq(1), pads.cs_n.eq(1)]),
  112. +               [bus.ack.eq(1), cs_n.eq(1)]),
  113.             (div, # tSHSL!
  114.                 [bus.ack.eq(0)]),
  115.             (0,
  116. @@ -128,13 +152,40 @@ class SpiFlashTB(Module):
  117.                 selfp.slave.dq.i = self.cycle & 0xf
  118.     do_simulation.passive = True
  119.  
  120. +BITBANG_CLK      = (1 << 2)
  121. +BITBANG_CS_N     = (1 << 3)
  122. +BITBANG_DQ_INPUT = (1 << 4)
  123. +BITBANG_ENABLE   = (1 << 5)
  124. +
  125. +def spiflash_bitbang_write(selfp, c):
  126. +   selfp.slave.bitbang.storage = c
  127. +
  128. +def _spiflash_bitbang_write(selfp, c):
  129. +   selfp.slave.bitbang.storage = c | BITBANG_ENABLE
  130. +
  131. +class SpiFlashBitBangTB(Module):
  132. +   def __init__(self):
  133. +       self.pads = Record([("cs_n", 1), ("clk", 1), ("dq", 2)])
  134. +       self.submodules.slave = SpiFlash(self.pads)
  135. +
  136. +   def gen_simulation(self, selfp):
  137. +       _spiflash_bitbang_write(selfp, BITBANG_DQ_INPUT)
  138. +       yield
  139. +       _spiflash_bitbang_write(selfp, BITBANG_DQ_INPUT | BITBANG_CLK)
  140. +#      selfp.slave.specials.dq.i = 1
  141. +       selfp.slave.dq.i = 1
  142. +       yield
  143. +       _spiflash_bitbang_write(selfp, BITBANG_DQ_INPUT | 0)
  144. +       yield
  145. +       print("miso = " + str(selfp.slave.miso.w))
  146. +
  147.  if __name__ == "__main__":
  148.     from migen.sim.generic import run_simulation
  149.     from migen.fhdl import verilog
  150.  
  151. -   pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)])
  152. -   s = SpiFlash(pads)
  153. -   print(verilog.convert(s, ios={pads.clk, pads.cs_n, pads.dq, s.bus.adr,
  154. -       s.bus.dat_r, s.bus.cyc, s.bus.ack, s.bus.stb}))
  155. +#  pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)])
  156. +#  s = SpiFlash(pads)
  157. +#  print(verilog.convert(s, ios={pads.clk, pads.cs_n, pads.dq, s.bus.adr,
  158. +#      s.bus.dat_r, s.bus.cyc, s.bus.ack, s.bus.stb}))
  159.  
  160. -   run_simulation(SpiFlashTB(), vcd_name="spiflash.vcd")
  161. +   run_simulation(SpiFlashBitBangTB(), vcd_name="spiflash.vcd")
Advertisement
Add Comment
Please, Sign In to add comment