From: Florent Kermarrec Date: Sun, 12 Aug 2012 23:02:38 +0000 (+0200) Subject: new library spi2Csr (skeleton) X-Git-Tag: 24jan2021_ls180~2575^2~174 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7dd51b3d924d078ba9fb16730d8587c01029b675;p=litex.git new library spi2Csr (skeleton) --- diff --git a/README b/README index 14be3ec2..7c968f1d 100644 --- 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 diff --git a/migScope/__init__.py b/migScope/__init__.py index 020089f8..6d999814 100644 --- a/migScope/__init__.py +++ b/migScope/__init__.py @@ -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 index 00000000..1bc187db --- /dev/null +++ b/spi2Csr/__init__.py @@ -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 c64f66b0..7790f864 100644 --- 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) +