new library spi2Csr (skeleton)
This commit is contained in:
parent
f586b13d4b
commit
7dd51b3d92
2
README
2
README
|
@ -2,7 +2,7 @@
|
||||||
------------
|
------------
|
||||||
|
|
||||||
This is a small Logic Analyser to be embedded in a Fpga design to debug internal
|
This is a small Logic Analyser to be embedded in a Fpga design to debug internal
|
||||||
or external.signals.
|
or external signals.
|
||||||
|
|
||||||
[> Status:
|
[> Status:
|
||||||
Early development phase
|
Early development phase
|
||||||
|
|
|
@ -268,7 +268,6 @@ class Trigger:
|
||||||
|
|
||||||
# Connect output of trig elements to sum
|
# Connect output of trig elements to sum
|
||||||
# Todo : Add sum tree to have more that 4 inputs
|
# 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))]
|
comb+= [self._sum.i[j].eq(self.ports[j].o) for j in range(len(self.ports))]
|
||||||
|
|
||||||
# Connect sum ouput to hit
|
# Connect sum ouput to hit
|
||||||
|
@ -281,7 +280,6 @@ class Trigger:
|
||||||
frag += port.get_fragment()
|
frag += port.get_fragment()
|
||||||
comb+= [self.dat.eq(self.in_dat)]
|
comb+= [self.dat.eq(self.in_dat)]
|
||||||
|
|
||||||
|
|
||||||
#Connect Registers
|
#Connect Registers
|
||||||
for i in range(len(self.ports)):
|
for i in range(len(self.ports)):
|
||||||
if isinstance(self.ports[i],Term):
|
if isinstance(self.ports[i],Term):
|
||||||
|
@ -468,9 +466,6 @@ class Recorder:
|
||||||
return self.bank.get_fragment()+\
|
return self.bank.get_fragment()+\
|
||||||
self.storage.get_fragment()+self.sequencer.get_fragment()+\
|
self.storage.get_fragment()+self.sequencer.get_fragment()+\
|
||||||
Fragment(comb=comb, sync=sync)
|
Fragment(comb=comb, sync=sync)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MigCon:
|
class MigCon:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -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)
|
23
top.py
23
top.py
|
@ -6,6 +6,7 @@ from migen.fhdl import verilog, autofragment
|
||||||
from migen.bus import csr
|
from migen.bus import csr
|
||||||
|
|
||||||
import migScope
|
import migScope
|
||||||
|
import spi2Csr
|
||||||
|
|
||||||
#
|
#
|
||||||
#Test Term
|
#Test Term
|
||||||
|
@ -73,13 +74,21 @@ import migScope
|
||||||
#
|
#
|
||||||
#Test Trigger
|
#Test Trigger
|
||||||
#
|
#
|
||||||
term0 = migScope.Term(32)
|
#term0 = migScope.Term(32)
|
||||||
term1 = migScope.RangeDetector(32)
|
#term1 = migScope.RangeDetector(32)
|
||||||
term2 = migScope.EdgeDetector(32)
|
#term2 = migScope.EdgeDetector(32)
|
||||||
term3 = migScope.Term(32)
|
#term3 = migScope.Term(32)
|
||||||
|
|
||||||
trigger0 = migScope.Trigger(0,32,64,[term0, term1, term2, term3])
|
#trigger0 = migScope.Trigger(0,32,64,[term0, term1, term2, term3])
|
||||||
#trigger0 = migScope.Trigger(0,32,64,[term0])
|
#recorder0 = migScope.Recorder(0,32,1024)
|
||||||
v = verilog.convert(trigger0.get_fragment())
|
#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)
|
print(v)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue