Guest User

Untitled

a guest
Oct 14th, 2014
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.81 KB | None | 0 0
  1. from migen.fhdl.std import *
  2. from migen.bank.description import *
  3. from migen.genlib.fsm import FSM, NextState
  4.  
  5. class SPI(Module, AutoCSR):
  6.     def __init__(self, pads, width=24, div=2, cpha=1):
  7.         self.pads = pads
  8.  
  9.         self._ctrl = CSR()
  10.         self._length = CSRStorage(8)
  11.         self._status = CSRStatus()
  12.         self._mosi = CSRStorage(width)
  13.         self._miso = CSRStatus(width)
  14.  
  15.         self.irq = Signal()
  16.  
  17.     ###
  18.  
  19.         # ctrl
  20.         start = Signal()
  21.         length = self._length.storage
  22.         enable_cs = Signal()
  23.         enable_shift = Signal()
  24.         done = Signal()
  25.  
  26.         self.comb += [
  27.             start.eq(self._ctrl.re & self._ctrl.r[0]),
  28.             self._status.status.eq(done)
  29.         ]
  30.  
  31.         # clk
  32.         i = Signal(max=div)
  33.         clk_en = Signal()
  34.         set_clk = Signal()
  35.         clr_clk = Signal()
  36.         self.sync += [
  37.             If(set_clk,
  38.                 pads.clk.eq(enable_cs)
  39.             ),
  40.             If(clr_clk,
  41.                 pads.clk.eq(0),
  42.                 i.eq(0)
  43.             ).Else(
  44.                 i.eq(i + 1),
  45.             )
  46.         ]
  47.  
  48.         self.comb +=[
  49.             set_clk.eq(i==div//2-1),
  50.             clr_clk.eq(i==div-1)
  51.         ]
  52.  
  53.         # fsm
  54.         cnt = Signal(8)
  55.         clr_cnt = Signal()
  56.         inc_cnt = Signal()
  57.         self.sync += \
  58.             If(clr_cnt,
  59.                 cnt.eq(0)
  60.             ).Elif(inc_cnt,
  61.                 cnt.eq(cnt+1)
  62.             )
  63.  
  64.         fsm = FSM(reset_state="IDLE")
  65.         self.submodules += fsm
  66.  
  67.         fsm.act("IDLE",
  68.             If(start,
  69.                 NextState("WAIT_CLK")
  70.             ),
  71.             done.eq(1),
  72.             clr_cnt.eq(1)
  73.         )
  74.  
  75.         fsm.act("WAIT_CLK",
  76.             If(clr_clk,
  77.                 NextState("SHIFT")
  78.             ),
  79.         )
  80.  
  81.         fsm.act("SHIFT",
  82.             If(cnt == length,
  83.                 NextState("END")
  84.             ).Else(
  85.                 inc_cnt.eq(clr_clk),
  86.             ),
  87.             enable_cs.eq(1),
  88.             enable_shift.eq(1),
  89.         )
  90.  
  91.  
  92.         fsm.act("END",
  93.             If(set_clk,
  94.                 NextState("IDLE")
  95.             ),
  96.             enable_shift.eq(1),
  97.             self.irq.eq(1)
  98.         )
  99.  
  100.         # miso
  101.         miso = Signal()
  102.         sr_miso = Signal(width)
  103.  
  104.         # (cpha = 1: capture on clk falling edge)
  105.         if cpha:
  106.             self.sync += \
  107.                 If(enable_shift,
  108.                     If(clr_clk,
  109.                         miso.eq(pads.miso),
  110.                     ).Elif(set_clk,
  111.                         sr_miso.eq(Cat(miso, sr_miso[:-1]))
  112.                     )
  113.                 )
  114.         # (cpha = 0: capture on clk rising edge)
  115.         else:
  116.             self.sync += \
  117.                 If(enable_shift,
  118.                     If(set_clk,
  119.                         miso.eq(pads.miso),
  120.                     ).Elif(clr_clk,
  121.                         sr_miso.eq(Cat(miso, sr_miso[:-1]))
  122.                     )
  123.                 )
  124.         self.comb += self._miso.status.eq(sr_miso)
  125.  
  126.         # mosi
  127.         mosi = Signal()
  128.         sr_mosi = Signal(width)
  129.  
  130.         # (cpha = 1: propagated on clk rising edge)
  131.         if cpha:
  132.             self.sync += \
  133.                 If(start,
  134.                     sr_mosi.eq(self._mosi.storage)
  135.                 ).Elif(clr_clk & enable_shift,
  136.                     sr_mosi.eq(Cat(Signal(), sr_mosi[:-1]))
  137.                 ).Elif(set_clk,
  138.                     pads.mosi.eq(sr_mosi[-1])
  139.                 )
  140.  
  141.         # (cpha = 0: propagated on clk falling edge)
  142.         else:
  143.             self.sync += [
  144.                 If(start,
  145.                     sr_mosi.eq(self._mosi.storage)
  146.                 ).Elif(set_clk & enable_shift,
  147.                     sr_mosi.eq(Cat(Signal(), sr_mosi[:-1]))
  148.                 ).Elif(clr_clk,
  149.                     pads.mosi.eq(sr_mosi[-1])
  150.                 )
  151.             ]
  152.  
  153.         # cs_n
  154.         self.comb += pads.cs_n.eq(~enable_cs)
Advertisement
Add Comment
Please, Sign In to add comment