c8d2ded262acb235ca34cba17d831a2f27a6928f
1 from functools
import reduce
2 from operator
import or_
5 from migen
.genlib
import roundrobin
6 from migen
.genlib
.record
import *
9 class Interface(Record
):
10 def __init__(self
, aw
, dw
, nbanks
, req_queue_size
, read_latency
, write_latency
):
14 self
.req_queue_size
= req_queue_size
15 self
.read_latency
= read_latency
16 self
.write_latency
= write_latency
19 ("adr", aw
, DIR_M_TO_S
),
20 ("we", 1, DIR_M_TO_S
),
21 ("stb", 1, DIR_M_TO_S
),
22 ("req_ack", 1, DIR_S_TO_M
),
23 ("dat_w_ack", 1, DIR_S_TO_M
),
24 ("dat_r_ack", 1, DIR_S_TO_M
),
25 ("lock", 1, DIR_S_TO_M
)
28 layout
= [("bank"+str(i
), bank_layout
) for i
in range(nbanks
)]
32 ("dat_w", dw
, DIR_M_TO_S
),
33 ("dat_we", dw
//8, DIR_M_TO_S
),
34 ("dat_r", dw
, DIR_S_TO_M
)
36 Record
.__init
__(self
, layout
)
39 def _getattr_all(l
, attr
):
41 r
= getattr(next(it
), attr
)
43 if getattr(e
, attr
) != r
:
48 class LASMIxbar(Module
):
49 def __init__(self
, controllers
, cba_shift
):
50 self
._controllers
= controllers
51 self
._cba
_shift
= cba_shift
53 self
._rca
_bits
= _getattr_all(controllers
, "aw")
54 self
._dw
= _getattr_all(controllers
, "dw")
55 self
._nbanks
= _getattr_all(controllers
, "nbanks")
56 self
._req
_queue
_size
= _getattr_all(controllers
, "req_queue_size")
57 self
._read
_latency
= _getattr_all(controllers
, "read_latency")
58 self
._write
_latency
= _getattr_all(controllers
, "write_latency")
60 self
._bank
_bits
= log2_int(self
._nbanks
, False)
61 self
._controller
_bits
= log2_int(len(self
._controllers
), False)
68 lasmi_master
= Interface(self
._rca
_bits
+ self
._bank
_bits
+ self
._controller
_bits
,
69 self
._dw
, 1, self
._req
_queue
_size
, self
._read
_latency
, self
._write
_latency
)
70 self
._masters
.append(lasmi_master
)
73 def do_finalize(self
):
74 nmasters
= len(self
._masters
)
76 m_ca
, m_ba
, m_rca
= self
._split
_master
_addresses
(self
._controller
_bits
,
77 self
._bank
_bits
, self
._rca
_bits
, self
._cba
_shift
)
79 for nc
, controller
in enumerate(self
._controllers
):
80 if self
._controller
_bits
:
81 controller_selected
= [ca
== nc
for ca
in m_ca
]
83 controller_selected
= [1]*nmasters
84 master_req_acks
= [0]*nmasters
85 master_dat_w_acks
= [0]*nmasters
86 master_dat_r_acks
= [0]*nmasters
88 rrs
= [roundrobin
.RoundRobin(nmasters
, roundrobin
.SP_CE
) for n
in range(self
._nbanks
)]
89 self
.submodules
+= rrs
90 for nb
, rr
in enumerate(rrs
):
91 bank
= getattr(controller
, "bank"+str(nb
))
93 # for each master, determine if another bank locks it
95 for nm
, master
in enumerate(self
._masters
):
97 for other_nb
, other_rr
in enumerate(rrs
):
99 other_bank
= getattr(controller
, "bank"+str(other_nb
))
100 locked
= locked |
(other_bank
.lock
& (other_rr
.grant
== nm
))
101 master_locked
.append(locked
)
104 bank_selected
= [cs
& (ba
== nb
) & ~locked
for cs
, ba
, locked
in zip(controller_selected
, m_ba
, master_locked
)]
105 bank_requested
= [bs
& master
.stb
for bs
, master
in zip(bank_selected
, self
._masters
)]
107 rr
.request
.eq(Cat(*bank_requested
)),
108 rr
.ce
.eq(~bank
.stb
& ~bank
.lock
)
113 bank
.adr
.eq(Array(m_rca
)[rr
.grant
]),
114 bank
.we
.eq(Array(self
._masters
)[rr
.grant
].we
),
115 bank
.stb
.eq(Array(bank_requested
)[rr
.grant
])
117 master_req_acks
= [master_req_ack |
((rr
.grant
== nm
) & bank_selected
[nm
] & bank
.req_ack
)
118 for nm
, master_req_ack
in enumerate(master_req_acks
)]
119 master_dat_w_acks
= [master_dat_w_ack |
((rr
.grant
== nm
) & bank
.dat_w_ack
)
120 for nm
, master_dat_w_ack
in enumerate(master_dat_w_acks
)]
121 master_dat_r_acks
= [master_dat_r_ack |
((rr
.grant
== nm
) & bank
.dat_r_ack
)
122 for nm
, master_dat_r_ack
in enumerate(master_dat_r_acks
)]
124 for nm
, master_dat_w_ack
in enumerate(master_dat_w_acks
):
125 for i
in range(self
._write
_latency
):
126 new_master_dat_w_ack
= Signal()
127 self
.sync
+= new_master_dat_w_ack
.eq(master_dat_w_ack
)
128 master_dat_w_ack
= new_master_dat_w_ack
129 master_dat_w_acks
[nm
] = master_dat_w_ack
131 for nm
, master_dat_r_ack
in enumerate(master_dat_r_acks
):
132 for i
in range(self
._read
_latency
):
133 new_master_dat_r_ack
= Signal()
134 self
.sync
+= new_master_dat_r_ack
.eq(master_dat_r_ack
)
135 master_dat_r_ack
= new_master_dat_r_ack
136 master_dat_r_acks
[nm
] = master_dat_r_ack
138 self
.comb
+= [master
.req_ack
.eq(master_req_ack
) for master
, master_req_ack
in zip(self
._masters
, master_req_acks
)]
139 self
.comb
+= [master
.dat_w_ack
.eq(master_dat_w_ack
) for master
, master_dat_w_ack
in zip(self
._masters
, master_dat_w_acks
)]
140 self
.comb
+= [master
.dat_r_ack
.eq(master_dat_r_ack
) for master
, master_dat_r_ack
in zip(self
._masters
, master_dat_r_acks
)]
143 controller_selected_wl
= controller_selected
144 for i
in range(self
._write
_latency
):
145 n_controller_selected_wl
= [Signal() for i
in range(nmasters
)]
146 self
.sync
+= [n
.eq(o
) for n
, o
in zip(n_controller_selected_wl
, controller_selected_wl
)]
147 controller_selected_wl
= n_controller_selected_wl
148 dat_w_maskselect
= []
149 dat_we_maskselect
= []
150 for master
, selected
in zip(self
._masters
, controller_selected_wl
):
151 o_dat_w
= Signal(self
._dw
)
152 o_dat_we
= Signal(self
._dw
//8)
153 self
.comb
+= If(selected
,
154 o_dat_w
.eq(master
.dat_w
),
155 o_dat_we
.eq(master
.dat_we
)
157 dat_w_maskselect
.append(o_dat_w
)
158 dat_we_maskselect
.append(o_dat_we
)
160 controller
.dat_w
.eq(reduce(or_
, dat_w_maskselect
)),
161 controller
.dat_we
.eq(reduce(or_
, dat_we_maskselect
))
165 if self
._controller
_bits
:
166 for master
in self
._masters
:
167 controller_sel
= Signal(self
._controller
_bits
)
168 for nc
, controller
in enumerate(self
._controllers
):
169 for nb
in range(nbanks
):
170 bank
= getattr(controller
, "bank"+str(nb
))
171 self
.comb
+= If(bank
.stb
& bank
.ack
, controller_sel
.eq(nc
))
172 for i
in range(self
._read
_latency
):
173 n_controller_sel
= Signal(self
._controller
_bits
)
174 self
.sync
+= n_controller_sel
.eq(controller_sel
)
175 controller_sel
= n_controller_sel
176 self
.comb
+= master
.dat_r
.eq(Array(self
._controllers
)[controller_sel
].dat_r
)
178 self
.comb
+= [master
.dat_r
.eq(self
._controllers
[0].dat_r
) for master
in self
._masters
]
180 def _split_master_addresses(self
, controller_bits
, bank_bits
, rca_bits
, cba_shift
):
181 m_ca
= [] # controller address
182 m_ba
= [] # bank address
183 m_rca
= [] # row and column address
184 for master
in self
._masters
:
185 cba
= Signal(self
._controller
_bits
+ self
._bank
_bits
)
186 rca
= Signal(self
._rca
_bits
)
187 cba_upper
= cba_shift
+ controller_bits
+ bank_bits
188 self
.comb
+= cba
.eq(master
.adr
[cba_shift
:cba_upper
])
189 if cba_shift
< self
._rca
_bits
:
191 self
.comb
+= rca
.eq(Cat(master
.adr
[:cba_shift
], master
.adr
[cba_upper
:]))
193 self
.comb
+= rca
.eq(master
.adr
[cba_upper
:])
195 self
.comb
+= rca
.eq(master
.adr
[:cba_shift
])
197 if self
._controller
_bits
:
198 ca
= Signal(self
._controller
_bits
)
199 ba
= Signal(self
._bank
_bits
)
200 self
.comb
+= Cat(ba
, ca
).eq(cba
)
208 return m_ca
, m_ba
, m_rca