litex: reorganize things, first work working version
[litex.git] / litex / soc / interconnect / dma_lasmi.py
1 from litex.gen import *
2 from litex.gen.genlib.fifo import SyncFIFO
3
4
5 class Reader(Module):
6 def __init__(self, lasmim, fifo_depth=None):
7 self.address = Sink([("a", lasmim.aw)])
8 self.data = Source([("d", lasmim.dw)])
9 self.busy = Signal()
10
11 ###
12
13 if fifo_depth is None:
14 fifo_depth = lasmim.req_queue_size + lasmim.read_latency + 2
15
16 # request issuance
17 request_enable = Signal()
18 request_issued = Signal()
19
20 self.comb += [
21 lasmim.we.eq(0),
22 lasmim.stb.eq(self.address.stb & request_enable),
23 lasmim.adr.eq(self.address.a),
24 self.address.ack.eq(lasmim.req_ack & request_enable),
25 request_issued.eq(lasmim.stb & lasmim.req_ack)
26 ]
27
28 # FIFO reservation level counter
29 # incremented when data is planned to be queued
30 # decremented when data is dequeued
31 data_dequeued = Signal()
32 rsv_level = Signal(max=fifo_depth+1)
33 self.sync += [
34 If(request_issued,
35 If(~data_dequeued, rsv_level.eq(rsv_level + 1))
36 ).Elif(data_dequeued,
37 rsv_level.eq(rsv_level - 1)
38 )
39 ]
40 self.comb += [
41 self.busy.eq(rsv_level != 0),
42 request_enable.eq(rsv_level != fifo_depth)
43 ]
44
45 # FIFO
46 fifo = SyncFIFO(lasmim.dw, fifo_depth)
47 self.submodules += fifo
48
49 self.comb += [
50 fifo.din.eq(lasmim.dat_r),
51 fifo.we.eq(lasmim.dat_r_ack),
52
53 self.data.stb.eq(fifo.readable),
54 fifo.re.eq(self.data.ack),
55 self.data.d.eq(fifo.dout),
56 data_dequeued.eq(self.data.stb & self.data.ack)
57 ]
58
59
60 class Writer(Module):
61 def __init__(self, lasmim, fifo_depth=None):
62 self.address_data = Sink([("a", lasmim.aw), ("d", lasmim.dw)])
63 self.busy = Signal()
64
65 ###
66
67 if fifo_depth is None:
68 fifo_depth = lasmim.req_queue_size + lasmim.write_latency + 2
69
70 fifo = SyncFIFO(lasmim.dw, fifo_depth)
71 self.submodules += fifo
72
73 self.comb += [
74 lasmim.we.eq(1),
75 lasmim.stb.eq(fifo.writable & self.address_data.stb),
76 lasmim.adr.eq(self.address_data.a),
77 self.address_data.ack.eq(fifo.writable & lasmim.req_ack),
78 fifo.we.eq(self.address_data.stb & lasmim.req_ack),
79 fifo.din.eq(self.address_data.d)
80 ]
81
82 self.comb += [
83 If(lasmim.dat_w_ack,
84 fifo.re.eq(1),
85 lasmim.dat_we.eq(2**(lasmim.dw//8)-1),
86 lasmim.dat_w.eq(fifo.dout)
87 ),
88 self.busy.eq(fifo.readable)
89 ]