new library spi2Csr (skeleton)
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 12 Aug 2012 23:02:38 +0000 (01:02 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 12 Aug 2012 23:02:38 +0000 (01:02 +0200)
README
migScope/__init__.py
spi2Csr/__init__.py [new file with mode: 0644]
top.py

diff --git a/README b/README
index 14be3ec262af1443e7ba1ffe2b311ea2dee2408e..7c968f1dd111048d36dd9d772581af582342f814 100644 (file)
--- a/README
+++ b/README
@@ -2,7 +2,7 @@
 ------------
 
 This is a small Logic Analyser to be embedded in a Fpga design to debug internal
-or external.signals.
+or external signals.
 
 [> Status:
 Early development phase
index 020089f8712ae9a5f4a826216be04fb2bc1c7a4c..6d999814bc3a1fe472973268ef869a707aa2b9b6 100644 (file)
@@ -268,7 +268,6 @@ class Trigger:
                
                # Connect output of trig elements to sum
                # Todo : Add sum tree to have more that 4 inputs
-               
                comb+= [self._sum.i[j].eq(self.ports[j].o) for j in range(len(self.ports))]
                
                # Connect sum ouput to hit
@@ -281,7 +280,6 @@ class Trigger:
                        frag += port.get_fragment()
                comb+= [self.dat.eq(self.in_dat)]
                
-               
                #Connect Registers
                for i in range(len(self.ports)):
                        if isinstance(self.ports[i],Term):
@@ -468,9 +466,6 @@ class Recorder:
                return self.bank.get_fragment()+\
                        self.storage.get_fragment()+self.sequencer.get_fragment()+\
                        Fragment(comb=comb, sync=sync)
-                       
-
-
 
 class MigCon:
        pass
diff --git a/spi2Csr/__init__.py b/spi2Csr/__init__.py
new file mode 100644 (file)
index 0000000..1bc187d
--- /dev/null
@@ -0,0 +1,157 @@
+from migen.fhdl.structure import *
+from migen.bus import csr
+from migen.bank import description, csrgen
+from migen.bank.description import *
+
+class Spi2Csr : 
+       def __init__(self, a_width, d_width, max_burst = 8):
+               self.a_width = a_width
+               self.d_width = d_width
+               self.max_burst = 8
+               # Csr interface
+               self.csr = csr.Interface(self.d_width)
+               # Spi interface
+               self.spi_clk = Signal()
+               self.spi_cs_n = Signal()
+               self.spi_mosi = Signal()
+               self.spi_miso = Signal()
+               self.spi_int_n = Signal()
+               
+       def get_fragment(self):
+               comb = []
+               sync = []
+               
+               # Resychronisation
+               spi_clk_d1 = Signal()
+               spi_clk_d2 = Signal()
+               spi_clk_d3 = Signal()
+               
+               sync += [
+                       spi_clk_d1.eq(self.spi_clk),
+                       spi_clk_d2.eq(spi_clk_d1),
+                       spi_clk_d3.eq(spi_clk_d2)
+               ]
+               
+               spi_cs_n_d1 = Signal()
+               spi_cs_n_d2 = Signal()
+               spi_cs_n_d3 = Signal()
+               
+               sync += [
+                       spi_cs_n_d1.eq(self.spi_cs_n),
+                       spi_cs_n_d2.eq(spi_cs_n_d1),
+                       spi_cs_n_d3.eq(spi_cs_n_d2)
+               ]
+               
+               spi_mosi_d1 = Signal()
+               spi_mosi_d2 = Signal()
+               spi_mosi_d3 = Signal()
+               
+               sync += [
+                       spi_mosi_d1.eq(self.spi_mosi),
+                       spi_mosi_d2.eq(spi_mosi_d1),
+                       spi_mosi_d3.eq(spi_mosi_d2)
+               ]
+               
+               # Decode
+               spi_clk_rising = Signal()
+               spi_clk_falling = Signal()
+               spi_cs_n_active = Signal()
+               spi_mosi_dat = Signal()
+               
+               comb += [
+                       spi_clk_rising.eq(spi_clk_d3 & ~spi_clk_d2),
+                       spi_clk_falling.eq(~spi_clk_d3 & spi_clk_d2),
+                       spi_cs_n_active.eq(~spi_cs_n_d3),
+                       spi_mosi_dat.eq(spi_mosi_d3)
+               ]
+               
+               #
+               # Spi --> Csr
+               #
+               spi_cnt = Signal(BV(bits_for(self.a_width+self.max_burst*self.d_width)))
+               spi_addr = Signal(BV(self.a_width))
+               spi_w_dat = Signal(BV(self.d_width))
+               spi_r_dat = Signal(BV(self.d_width))
+               spi_we = Signal()
+               spi_re = Signal()
+               spi_we_re_done = Signal(reset = 1)
+               spi_miso_dat = Signal()
+               
+               # Re/We Signals Decoding
+               first_b = Signal()
+               last_b = Signal()
+               
+               comb +=[
+                       first_b.eq(spi_cnt[0:bits_for(self.d_width)] == 0),
+                       last_b.eq(spi_cnt[0:bits_for(self.d_width)] == 2**self.d_width-1)
+               ]
+               sync +=[
+                       If(spi_cnt >= self.a_width & first_b,
+                               spi_we.eq(spi_addr[self.a_width-1] & ~spi_we_re_done),
+                               spi_re.eq(~spi_addr[self.a_width-1] & ~spi_we_re_done),
+                               spi_we_re_done.eq(1)
+                       ).Else(
+                               spi_we.eq(0),
+                               spi_re.eq(0),
+                               spi_we_re_done.eq(0)
+                       )
+               ]
+               
+               # Spi Addr / Data Decoding
+               sync +=[
+                       If(~spi_cs_n_active,
+                               spi_cnt.eq(0),
+                       ).Elif(spi_clk_rising,
+                               # addr
+                               If(spi_cnt < self.a_width,
+                                       spi_addr.eq(spi_addr[0:self.a_width-1]&spi_mosi_dat)
+                               ).Elif(spi_cnt >= self.a_width+self.d_width & last_b,
+                                       spi_addr.eq(spi_addr+1)
+                               ).Elif(spi_cnt >= self.a_width & last_b & spi_cnt[self.a_width-1] == 0,
+                                       spi_addr.eq(spi_addr+1)
+                               ),
+                               # dat
+                               If(spi_cnt >= self.a_width,
+                                       spi_w_dat.eq(Cat(spi_w_dat[:self.d_width],spi_mosi_dat))
+                               ),
+                               
+                               # spi_cnt
+                               spi_cnt.eq(spi_cnt+1)
+                       )
+               ]
+               
+               #
+               # Csr --> Spi
+               #
+               spi_r_dat_shift = Signal(BV(self.d_width))
+               sync +=[
+                       If(spi_re,
+                               spi_r_dat_shift.eq(spi_r_dat)
+                       ),
+                       
+                       If(~spi_cs_n_active,
+                               spi_miso_dat.eq(0)
+                       ).Elif(spi_clk_falling,
+                               spi_miso_dat.eq(spi_r_dat_shift[self.d_width-1]),
+                               spi_r_dat_shift.eq(Cat(spi_r_dat_shift[:self.d_width-2],0))
+                       )
+                       ]
+                       
+               
+               #
+               # Csr Interface
+               #
+               comb += [
+                       self.csr.adr.eq(spi_addr),
+                       self.csr.dat_w.eq(spi_w_dat),
+                       self.csr.we.eq(spi_we)
+               ]
+               
+               #
+               # Spi Interface
+               #
+               comb += [
+                       spi_r_dat.eq(self.csr.dat_r),
+                       self.spi_miso.eq(spi_miso_dat)
+               ]
+               return Fragment(comb=comb,sync=sync)
\ No newline at end of file
diff --git a/top.py b/top.py
index c64f66b09fe5019c78156df84e6abbbac2bb0227..7790f8647ea6f3ae57bb9d234d3d69755cdd0b57 100644 (file)
--- a/top.py
+++ b/top.py
@@ -6,6 +6,7 @@ from migen.fhdl import verilog, autofragment
 from migen.bus import csr
 
 import migScope
+import spi2Csr
 
 #
 #Test Term
@@ -73,13 +74,21 @@ import migScope
 #
 #Test Trigger
 #
-term0 = migScope.Term(32)
-term1 = migScope.RangeDetector(32)
-term2 = migScope.EdgeDetector(32)
-term3 = migScope.Term(32)
+#term0 = migScope.Term(32)
+#term1 = migScope.RangeDetector(32)
+#term2 = migScope.EdgeDetector(32)
+#term3 = migScope.Term(32)
 
-trigger0 = migScope.Trigger(0,32,64,[term0, term1, term2, term3])
-#trigger0 = migScope.Trigger(0,32,64,[term0])
-v = verilog.convert(trigger0.get_fragment())
+#trigger0 = migScope.Trigger(0,32,64,[term0, term1, term2, term3])
+#recorder0 = migScope.Recorder(0,32,1024)
+#v = verilog.convert(trigger0.get_fragment()+recorder0.get_fragment())
+#print(v)
+
+#
+#Test spi2Csr
+#
+spi2csr0 = spi2Csr.Spi2Csr(16,8)
+v = verilog.convert(spi2csr0.get_fragment())
 print(v)
 
+