Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / unused_please_ignore_completely / iommu / axi_rab / axi_rab_top.py
1 # this file has been generated by sv2nmigen
2
3 from nmigen import Signal, Module, Const, Cat, Elaboratable
4
5
6 class axi_rab_top(Elaboratable):
7
8 def __init__(self):
9 self.Clk_CI = Signal() # input
10 self.NonGatedClk_CI = Signal() # input
11 self.Rst_RBI = Signal() # input
12 self.s_axi4_awid = Signal() # input
13 self.s_axi4_awaddr = Signal() # input
14 self.s_axi4_awvalid = Signal(N_PORTS) # input
15 self.s_axi4_awready = Signal(N_PORTS) # output
16 self.s_axi4_awlen = Signal() # input
17 self.s_axi4_awsize = Signal() # input
18 self.s_axi4_awburst = Signal() # input
19 self.s_axi4_awlock = Signal(N_PORTS) # input
20 self.s_axi4_awprot = Signal() # input
21 self.s_axi4_awcache = Signal() # input
22 self.s_axi4_awregion = Signal() # input
23 self.s_axi4_awqos = Signal() # input
24 self.s_axi4_awuser = Signal() # input
25 self.s_axi4_wdata = Signal() # input
26 self.s_axi4_wvalid = Signal(N_PORTS) # input
27 self.s_axi4_wready = Signal(N_PORTS) # output
28 self.s_axi4_wstrb = Signal() # input
29 self.s_axi4_wlast = Signal(N_PORTS) # input
30 self.s_axi4_wuser = Signal() # input
31 self.s_axi4_bid = Signal() # output
32 self.s_axi4_bresp = Signal() # output
33 self.s_axi4_bvalid = Signal(N_PORTS) # output
34 self.s_axi4_buser = Signal() # output
35 self.s_axi4_bready = Signal(N_PORTS) # input
36 self.s_axi4_arid = Signal() # input
37 self.s_axi4_araddr = Signal() # input
38 self.s_axi4_arvalid = Signal(N_PORTS) # input
39 self.s_axi4_arready = Signal(N_PORTS) # output
40 self.s_axi4_arlen = Signal() # input
41 self.s_axi4_arsize = Signal() # input
42 self.s_axi4_arburst = Signal() # input
43 self.s_axi4_arlock = Signal(N_PORTS) # input
44 self.s_axi4_arprot = Signal() # input
45 self.s_axi4_arcache = Signal() # input
46 self.s_axi4_aruser = Signal() # input
47 self.s_axi4_rid = Signal() # output
48 self.s_axi4_rdata = Signal() # output
49 self.s_axi4_rresp = Signal() # output
50 self.s_axi4_rvalid = Signal(N_PORTS) # output
51 self.s_axi4_rready = Signal(N_PORTS) # input
52 self.s_axi4_rlast = Signal(N_PORTS) # output
53 self.s_axi4_ruser = Signal() # output
54 self.m0_axi4_awid = Signal() # output
55 self.m0_axi4_awaddr = Signal() # output
56 self.m0_axi4_awvalid = Signal(N_PORTS) # output
57 self.m0_axi4_awready = Signal(N_PORTS) # input
58 self.m0_axi4_awlen = Signal() # output
59 self.m0_axi4_awsize = Signal() # output
60 self.m0_axi4_awburst = Signal() # output
61 self.m0_axi4_awlock = Signal(N_PORTS) # output
62 self.m0_axi4_awprot = Signal() # output
63 self.m0_axi4_awcache = Signal() # output
64 self.m0_axi4_awregion = Signal() # output
65 self.m0_axi4_awqos = Signal() # output
66 self.m0_axi4_awuser = Signal() # output
67 self.m0_axi4_wdata = Signal() # output
68 self.m0_axi4_wvalid = Signal(N_PORTS) # output
69 self.m0_axi4_wready = Signal(N_PORTS) # input
70 self.m0_axi4_wstrb = Signal() # output
71 self.m0_axi4_wlast = Signal(N_PORTS) # output
72 self.m0_axi4_wuser = Signal() # output
73 self.m0_axi4_bid = Signal() # input
74 self.m0_axi4_bresp = Signal() # input
75 self.m0_axi4_bvalid = Signal(N_PORTS) # input
76 self.m0_axi4_buser = Signal() # input
77 self.m0_axi4_bready = Signal(N_PORTS) # output
78 self.m0_axi4_arid = Signal() # output
79 self.m0_axi4_araddr = Signal() # output
80 self.m0_axi4_arvalid = Signal(N_PORTS) # output
81 self.m0_axi4_arready = Signal(N_PORTS) # input
82 self.m0_axi4_arlen = Signal() # output
83 self.m0_axi4_arsize = Signal() # output
84 self.m0_axi4_arburst = Signal() # output
85 self.m0_axi4_arlock = Signal(N_PORTS) # output
86 self.m0_axi4_arprot = Signal() # output
87 self.m0_axi4_arcache = Signal() # output
88 self.m0_axi4_aruser = Signal() # output
89 self.m0_axi4_rid = Signal() # input
90 self.m0_axi4_rdata = Signal() # input
91 self.m0_axi4_rresp = Signal() # input
92 self.m0_axi4_rvalid = Signal(N_PORTS) # input
93 self.m0_axi4_rready = Signal(N_PORTS) # output
94 self.m0_axi4_rlast = Signal(N_PORTS) # input
95 self.m0_axi4_ruser = Signal() # input
96 self.m1_axi4_awid = Signal() # output
97 self.m1_axi4_awaddr = Signal() # output
98 self.m1_axi4_awvalid = Signal(N_PORTS) # output
99 self.m1_axi4_awready = Signal(N_PORTS) # input
100 self.m1_axi4_awlen = Signal() # output
101 self.m1_axi4_awsize = Signal() # output
102 self.m1_axi4_awburst = Signal() # output
103 self.m1_axi4_awlock = Signal(N_PORTS) # output
104 self.m1_axi4_awprot = Signal() # output
105 self.m1_axi4_awcache = Signal() # output
106 self.m1_axi4_awregion = Signal() # output
107 self.m1_axi4_awqos = Signal() # output
108 self.m1_axi4_awuser = Signal() # output
109 self.m1_axi4_wdata = Signal() # output
110 self.m1_axi4_wvalid = Signal(N_PORTS) # output
111 self.m1_axi4_wready = Signal(N_PORTS) # input
112 self.m1_axi4_wstrb = Signal() # output
113 self.m1_axi4_wlast = Signal(N_PORTS) # output
114 self.m1_axi4_wuser = Signal() # output
115 self.m1_axi4_bid = Signal() # input
116 self.m1_axi4_bresp = Signal() # input
117 self.m1_axi4_bvalid = Signal(N_PORTS) # input
118 self.m1_axi4_buser = Signal() # input
119 self.m1_axi4_bready = Signal(N_PORTS) # output
120 self.m1_axi4_arid = Signal() # output
121 self.m1_axi4_araddr = Signal() # output
122 self.m1_axi4_arvalid = Signal(N_PORTS) # output
123 self.m1_axi4_arready = Signal(N_PORTS) # input
124 self.m1_axi4_arlen = Signal() # output
125 self.m1_axi4_arsize = Signal() # output
126 self.m1_axi4_arburst = Signal() # output
127 self.m1_axi4_arlock = Signal(N_PORTS) # output
128 self.m1_axi4_arprot = Signal() # output
129 self.m1_axi4_arcache = Signal() # output
130 self.m1_axi4_aruser = Signal() # output
131 self.m1_axi4_rid = Signal() # input
132 self.m1_axi4_rdata = Signal() # input
133 self.m1_axi4_rresp = Signal() # input
134 self.m1_axi4_rvalid = Signal(N_PORTS) # input
135 self.m1_axi4_rready = Signal(N_PORTS) # output
136 self.m1_axi4_rlast = Signal(N_PORTS) # input
137 self.m1_axi4_ruser = Signal() # input
138 self.s_axi4lite_awaddr = Signal(AXI_LITE_ADDR_WIDTH) # input
139 self.s_axi4lite_awvalid = Signal() # input
140 self.s_axi4lite_awready = Signal() # output
141 self.s_axi4lite_wdata = Signal(AXI_LITE_DATA_WIDTH) # input
142 self.s_axi4lite_wvalid = Signal() # input
143 self.s_axi4lite_wready = Signal() # output
144 self.s_axi4lite_wstrb = Signal(1+ERROR p_expression_25) # input
145 self.s_axi4lite_bresp = Signal(2) # output
146 self.s_axi4lite_bvalid = Signal() # output
147 self.s_axi4lite_bready = Signal() # input
148 self.s_axi4lite_araddr = Signal(AXI_LITE_ADDR_WIDTH) # input
149 self.s_axi4lite_arvalid = Signal() # input
150 self.s_axi4lite_arready = Signal() # output
151 self.s_axi4lite_rdata = Signal(AXI_LITE_DATA_WIDTH) # output
152 self.s_axi4lite_rresp = Signal(2) # output
153 self.s_axi4lite_rvalid = Signal() # output
154 self.s_axi4lite_rready = Signal() # input
155 self.int_miss = Signal(N_PORTS) # output
156 self.int_multi = Signal(N_PORTS) # output
157 self.int_prot = Signal(N_PORTS) # output
158 self.int_mhf_full = Signal() # output
159
160 def elaborate(self, platform=None):
161 m = Module()
162 return m
163
164
165 # // Copyright 2018 ETH Zurich and University of Bologna.
166 # // Copyright and related rights are licensed under the Solderpad Hardware
167 # // License, Version 0.51 (the "License"); you may not use this file except in
168 # // compliance with the License. You may obtain a copy of the License at
169 # // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
170 # // or agreed to in writing, software, hardware and materials distributed under
171 # // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
172 # // CONDITIONS OF ANY KIND, either express or implied. See the License for the
173 # // specific language governing permissions and limitations under the License.
174 #
175 # // --=========================================================================--
176 # //
177 # // █████╗ ██╗ ██╗██╗ ██████╗ █████╗ ██████╗ ████████╗ ██████╗ ██████╗
178 # // ██╔══██╗╚██╗██╔╝██║ ██╔══██╗██╔══██╗██╔══██╗ ╚══██╔══╝██╔═══██╗██╔══██╗
179 # // ███████║ ╚███╔╝ ██║ ██████╔╝███████║██████╔╝ ██║ ██║ ██║██████╔╝
180 # // ██╔══██║ ██╔██╗ ██║ ██╔══██╗██╔══██║██╔══██╗ ██║ ██║ ██║██╔═══╝
181 # // ██║ ██║██╔╝ ██╗██║ ██║ ██║██║ ██║██████╔╝ ██║ ╚██████╔╝██║
182 # // ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═════╝ ╚═╝
183 # //
184 # // --=========================================================================--
185 # /*
186 # * axi_rab_top
187 # *
188 # * The remapping address block (RAB) performs address translation for AXI
189 # * transactions arriving at the input port and forwards them to different
190 # * downstream AXI ports.
191 # *
192 # * The five axi channels are each buffered on the input side using a FIFO,
193 # * described in axi4_XX_buffer. The RAB lookup result is merged into the
194 # * AXI transaction via the axi4_XX_sender instances, which manages upstream
195 # * error signaling for failed lookups.
196 # *
197 # * Address translation is performed based on data stored in up to two
198 # * translation lookaside buffers (TLBs), which are private per RAB port (each
199 # * of which having two AXI master ports and one AXI slave port). These TLBs
200 # * are managed in software through the AXI-Lite interface.
201 # *
202 # * If ACP is enabled, the `cache_coherent` flag in the TLBs is used to
203 # * multiplex between the two ports. If ACP is disabled, only the first master
204 # * port is used. In this case, the `cache_coherent` flag is used to set the
205 # * AxCACHE signals of the AXI bus accordingly.
206 # *
207 # * Authors:
208 # * Antonio Pullini <pullinia@iis.ee.ethz.ch>
209 # * Conrad Burchert <bconrad@ethz.ch>
210 # * Maheshwara Sharma <msharma@student.ethz.ch>
211 # * Andreas Kurth <akurth@iis.ee.ethz.ch>
212 # * Johannes Weinbuch <jweinbuch@student.ethz.ch>
213 # * Pirmin Vogel <vogelpi@iis.ee.ethz.ch>
214 # */
215 #
216 # //`include "pulp_soc_defines.sv"
217 #
218 # ////import CfMath::log2;
219 #
220 # module axi_rab_top
221 #
222 # // Parameters {{{
223 # #(
224 # parameter N_PORTS = 2,
225 # parameter N_L2_SETS = 32,
226 # parameter N_L2_SET_ENTRIES = 32,
227 # parameter AXI_DATA_WIDTH = 64,
228 # parameter AXI_S_ADDR_WIDTH = 32,
229 # parameter AXI_M_ADDR_WIDTH = 40,
230 # parameter AXI_LITE_DATA_WIDTH = 64,
231 # parameter AXI_LITE_ADDR_WIDTH = 32,
232 # parameter AXI_ID_WIDTH = 10,
233 # parameter AXI_USER_WIDTH = 6,
234 # parameter MH_FIFO_DEPTH = 16
235 # )
236 # // }}}
237 #
238 # // Ports {{{
239 # (
240 #
241 # input logic Clk_CI, // This clock may be gated.
242 # input logic NonGatedClk_CI,
243 # input logic Rst_RBI,
244 #
245 # // For every slave port there are two master ports. The master
246 # // port to use can be set using the master_select flag of the protection
247 # // bits of a slice
248 #
249 # // AXI4 Slave {{{
250 # input logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] s_axi4_awid,
251 # input logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] s_axi4_awaddr,
252 # input logic [N_PORTS-1:0] s_axi4_awvalid,
253 # output logic [N_PORTS-1:0] s_axi4_awready,
254 # input logic [N_PORTS-1:0] [7:0] s_axi4_awlen,
255 # input logic [N_PORTS-1:0] [2:0] s_axi4_awsize,
256 # input logic [N_PORTS-1:0] [1:0] s_axi4_awburst,
257 # input logic [N_PORTS-1:0] s_axi4_awlock,
258 # input logic [N_PORTS-1:0] [2:0] s_axi4_awprot,
259 # input logic [N_PORTS-1:0] [3:0] s_axi4_awcache,
260 # input logic [N_PORTS-1:0] [3:0] s_axi4_awregion,
261 # input logic [N_PORTS-1:0] [3:0] s_axi4_awqos,
262 # input logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] s_axi4_awuser,
263 #
264 # input logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] s_axi4_wdata,
265 # input logic [N_PORTS-1:0] s_axi4_wvalid,
266 # output logic [N_PORTS-1:0] s_axi4_wready,
267 # input logic [N_PORTS-1:0] [AXI_DATA_WIDTH/8-1:0] s_axi4_wstrb,
268 # input logic [N_PORTS-1:0] s_axi4_wlast,
269 # input logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] s_axi4_wuser,
270 #
271 # output logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] s_axi4_bid,
272 # output logic [N_PORTS-1:0] [1:0] s_axi4_bresp,
273 # output logic [N_PORTS-1:0] s_axi4_bvalid,
274 # output logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] s_axi4_buser,
275 # input logic [N_PORTS-1:0] s_axi4_bready,
276 #
277 # input logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] s_axi4_arid,
278 # input logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] s_axi4_araddr,
279 # input logic [N_PORTS-1:0] s_axi4_arvalid,
280 # output logic [N_PORTS-1:0] s_axi4_arready,
281 # input logic [N_PORTS-1:0] [7:0] s_axi4_arlen,
282 # input logic [N_PORTS-1:0] [2:0] s_axi4_arsize,
283 # input logic [N_PORTS-1:0] [1:0] s_axi4_arburst,
284 # input logic [N_PORTS-1:0] s_axi4_arlock,
285 # input logic [N_PORTS-1:0] [2:0] s_axi4_arprot,
286 # input logic [N_PORTS-1:0] [3:0] s_axi4_arcache,
287 # input logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] s_axi4_aruser,
288 #
289 # output logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] s_axi4_rid,
290 # output logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] s_axi4_rdata,
291 # output logic [N_PORTS-1:0] [1:0] s_axi4_rresp,
292 # output logic [N_PORTS-1:0] s_axi4_rvalid,
293 # input logic [N_PORTS-1:0] s_axi4_rready,
294 # output logic [N_PORTS-1:0] s_axi4_rlast,
295 # output logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] s_axi4_ruser,
296 # // }}}
297 #
298 # // AXI4 Master 0 {{{
299 # output logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] m0_axi4_awid,
300 # output logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] m0_axi4_awaddr,
301 # output logic [N_PORTS-1:0] m0_axi4_awvalid,
302 # input logic [N_PORTS-1:0] m0_axi4_awready,
303 # output logic [N_PORTS-1:0] [7:0] m0_axi4_awlen,
304 # output logic [N_PORTS-1:0] [2:0] m0_axi4_awsize,
305 # output logic [N_PORTS-1:0] [1:0] m0_axi4_awburst,
306 # output logic [N_PORTS-1:0] m0_axi4_awlock,
307 # output logic [N_PORTS-1:0] [2:0] m0_axi4_awprot,
308 # output logic [N_PORTS-1:0] [3:0] m0_axi4_awcache,
309 # output logic [N_PORTS-1:0] [3:0] m0_axi4_awregion,
310 # output logic [N_PORTS-1:0] [3:0] m0_axi4_awqos,
311 # output logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] m0_axi4_awuser,
312 #
313 # output logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] m0_axi4_wdata,
314 # output logic [N_PORTS-1:0] m0_axi4_wvalid,
315 # input logic [N_PORTS-1:0] m0_axi4_wready,
316 # output logic [N_PORTS-1:0] [AXI_DATA_WIDTH/8-1:0] m0_axi4_wstrb,
317 # output logic [N_PORTS-1:0] m0_axi4_wlast,
318 # output logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] m0_axi4_wuser,
319 #
320 # input logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] m0_axi4_bid,
321 # input logic [N_PORTS-1:0] [1:0] m0_axi4_bresp,
322 # input logic [N_PORTS-1:0] m0_axi4_bvalid,
323 # input logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] m0_axi4_buser,
324 # output logic [N_PORTS-1:0] m0_axi4_bready,
325 #
326 # output logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] m0_axi4_arid,
327 # output logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] m0_axi4_araddr,
328 # output logic [N_PORTS-1:0] m0_axi4_arvalid,
329 # input logic [N_PORTS-1:0] m0_axi4_arready,
330 # output logic [N_PORTS-1:0] [7:0] m0_axi4_arlen,
331 # output logic [N_PORTS-1:0] [2:0] m0_axi4_arsize,
332 # output logic [N_PORTS-1:0] [1:0] m0_axi4_arburst,
333 # output logic [N_PORTS-1:0] m0_axi4_arlock,
334 # output logic [N_PORTS-1:0] [2:0] m0_axi4_arprot,
335 # output logic [N_PORTS-1:0] [3:0] m0_axi4_arcache,
336 # output logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] m0_axi4_aruser,
337 #
338 # input logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] m0_axi4_rid,
339 # input logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] m0_axi4_rdata,
340 # input logic [N_PORTS-1:0] [1:0] m0_axi4_rresp,
341 # input logic [N_PORTS-1:0] m0_axi4_rvalid,
342 # output logic [N_PORTS-1:0] m0_axi4_rready,
343 # input logic [N_PORTS-1:0] m0_axi4_rlast,
344 # input logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] m0_axi4_ruser,
345 # // }}}
346 #
347 # // AXI4 Master 1 {{{
348 # output logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] m1_axi4_awid,
349 # output logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] m1_axi4_awaddr,
350 # output logic [N_PORTS-1:0] m1_axi4_awvalid,
351 # input logic [N_PORTS-1:0] m1_axi4_awready,
352 # output logic [N_PORTS-1:0] [7:0] m1_axi4_awlen,
353 # output logic [N_PORTS-1:0] [2:0] m1_axi4_awsize,
354 # output logic [N_PORTS-1:0] [1:0] m1_axi4_awburst,
355 # output logic [N_PORTS-1:0] m1_axi4_awlock,
356 # output logic [N_PORTS-1:0] [2:0] m1_axi4_awprot,
357 # output logic [N_PORTS-1:0] [3:0] m1_axi4_awcache,
358 # output logic [N_PORTS-1:0] [3:0] m1_axi4_awregion,
359 # output logic [N_PORTS-1:0] [3:0] m1_axi4_awqos,
360 # output logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] m1_axi4_awuser,
361 #
362 # output logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] m1_axi4_wdata,
363 # output logic [N_PORTS-1:0] m1_axi4_wvalid,
364 # input logic [N_PORTS-1:0] m1_axi4_wready,
365 # output logic [N_PORTS-1:0] [AXI_DATA_WIDTH/8-1:0] m1_axi4_wstrb,
366 # output logic [N_PORTS-1:0] m1_axi4_wlast,
367 # output logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] m1_axi4_wuser,
368 #
369 # input logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] m1_axi4_bid,
370 # input logic [N_PORTS-1:0] [1:0] m1_axi4_bresp,
371 # input logic [N_PORTS-1:0] m1_axi4_bvalid,
372 # input logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] m1_axi4_buser,
373 # output logic [N_PORTS-1:0] m1_axi4_bready,
374 #
375 # output logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] m1_axi4_arid,
376 # output logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] m1_axi4_araddr,
377 # output logic [N_PORTS-1:0] m1_axi4_arvalid,
378 # input logic [N_PORTS-1:0] m1_axi4_arready,
379 # output logic [N_PORTS-1:0] [7:0] m1_axi4_arlen,
380 # output logic [N_PORTS-1:0] [2:0] m1_axi4_arsize,
381 # output logic [N_PORTS-1:0] [1:0] m1_axi4_arburst,
382 # output logic [N_PORTS-1:0] m1_axi4_arlock,
383 # output logic [N_PORTS-1:0] [2:0] m1_axi4_arprot,
384 # output logic [N_PORTS-1:0] [3:0] m1_axi4_arcache,
385 # output logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] m1_axi4_aruser,
386 #
387 # input logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] m1_axi4_rid,
388 # input logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] m1_axi4_rdata,
389 # input logic [N_PORTS-1:0] [1:0] m1_axi4_rresp,
390 # input logic [N_PORTS-1:0] m1_axi4_rvalid,
391 # output logic [N_PORTS-1:0] m1_axi4_rready,
392 # input logic [N_PORTS-1:0] m1_axi4_rlast,
393 # input logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] m1_axi4_ruser,
394 # // }}}
395 #
396 # // AXI 4 Lite Slave (Configuration Interface) {{{
397 # // AXI4-Lite port to setup the rab slices
398 # // use this to program the configuration registers
399 # input logic [AXI_LITE_ADDR_WIDTH-1:0] s_axi4lite_awaddr,
400 # input logic s_axi4lite_awvalid,
401 # output logic s_axi4lite_awready,
402 #
403 # input logic [AXI_LITE_DATA_WIDTH-1:0] s_axi4lite_wdata,
404 # input logic s_axi4lite_wvalid,
405 # output logic s_axi4lite_wready,
406 # input logic [AXI_LITE_DATA_WIDTH/8-1:0] s_axi4lite_wstrb,
407 #
408 # output logic [1:0] s_axi4lite_bresp,
409 # output logic s_axi4lite_bvalid,
410 # input logic s_axi4lite_bready,
411 #
412 # input logic [AXI_LITE_ADDR_WIDTH-1:0] s_axi4lite_araddr,
413 # input logic s_axi4lite_arvalid,
414 # output logic s_axi4lite_arready,
415 #
416 # output logic [AXI_LITE_DATA_WIDTH-1:0] s_axi4lite_rdata,
417 # output logic [1:0] s_axi4lite_rresp,
418 # output logic s_axi4lite_rvalid,
419 # input logic s_axi4lite_rready,
420 # // }}}
421 #
422 # // BRAMs {{{
423 # //`ifdef RAB_AX_LOG_EN
424 # // BramPort.Slave ArBram_PS,
425 # // BramPort.Slave AwBram_PS,
426 # //`endif
427 # // }}}
428 #
429 # // Logger Control {{{
430 # //`ifdef RAB_AX_LOG_EN
431 # // input logic LogEn_SI,
432 # // input logic ArLogClr_SI,
433 # // input logic AwLogClr_SI,
434 # // output logic ArLogRdy_SO,
435 # // output logic AwLogRdy_SO,
436 # //`endif
437 # // }}}
438 #
439 # // Interrupt Outputs {{{
440 # // Interrupt lines to handle misses, collisions of slices/multiple hits,
441 # // protection faults and overflow of the miss handling fifo
442 # //`ifdef RAB_AX_LOG_EN
443 # // output logic int_ar_log_full,
444 # // output logic int_aw_log_full,
445 # //`endif
446 # output logic [N_PORTS-1:0] int_miss,
447 # output logic [N_PORTS-1:0] int_multi,
448 # output logic [N_PORTS-1:0] int_prot,
449 # output logic int_mhf_full
450 # // }}}
451 #
452 # );
453 #
454 """#docstring_begin
455
456 // }}}
457
458 // Signals {{{
459 // ███████╗██╗ ██████╗ ███╗ ██╗ █████╗ ██╗ ███████╗
460 // ██╔════╝██║██╔════╝ ████╗ ██║██╔══██╗██║ ██╔════╝
461 // ███████╗██║██║ ███╗██╔██╗ ██║███████║██║ ███████╗
462 // ╚════██║██║██║ ██║██║╚██╗██║██╔══██║██║ ╚════██║
463 // ███████║██║╚██████╔╝██║ ╚████║██║ ██║███████╗███████║
464 // ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚══════╝╚══════╝
465 //
466
467 // Internal AXI4 lines, these connect buffers on the slave side to the rab core and
468 // multiplexers which switch between the two master outputs
469 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] int_awid;
470 logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] int_awaddr;
471 logic [N_PORTS-1:0] int_awvalid;
472 logic [N_PORTS-1:0] int_awready;
473 logic [N_PORTS-1:0] [7:0] int_awlen;
474 logic [N_PORTS-1:0] [2:0] int_awsize;
475 logic [N_PORTS-1:0] [1:0] int_awburst;
476 logic [N_PORTS-1:0] int_awlock;
477 logic [N_PORTS-1:0] [2:0] int_awprot;
478 logic [N_PORTS-1:0] [3:0] int_awcache;
479 logic [N_PORTS-1:0] [3:0] int_awregion;
480 logic [N_PORTS-1:0] [3:0] int_awqos;
481 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_awuser;
482
483 logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] int_wdata;
484 logic [N_PORTS-1:0] int_wvalid;
485 logic [N_PORTS-1:0] int_wready;
486 logic [N_PORTS-1:0] [AXI_DATA_WIDTH/8-1:0] int_wstrb;
487 logic [N_PORTS-1:0] int_wlast;
488 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_wuser;
489
490 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] int_bid;
491 logic [N_PORTS-1:0] [1:0] int_bresp;
492 logic [N_PORTS-1:0] int_bvalid;
493 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_buser;
494 logic [N_PORTS-1:0] int_bready;
495
496 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] int_arid;
497 logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] int_araddr;
498 logic [N_PORTS-1:0] int_arvalid;
499 logic [N_PORTS-1:0] int_arready;
500 logic [N_PORTS-1:0] [7:0] int_arlen;
501 logic [N_PORTS-1:0] [2:0] int_arsize;
502 logic [N_PORTS-1:0] [1:0] int_arburst;
503 logic [N_PORTS-1:0] int_arlock;
504 logic [N_PORTS-1:0] [2:0] int_arprot;
505 logic [N_PORTS-1:0] [3:0] int_arcache;
506 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_aruser;
507
508 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] int_rid;
509 logic [N_PORTS-1:0] [1:0] int_rresp;
510 logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] int_rdata;
511 logic [N_PORTS-1:0] int_rlast;
512 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_ruser;
513 logic [N_PORTS-1:0] int_rvalid;
514 logic [N_PORTS-1:0] int_rready;
515
516 // rab_core outputs
517 logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] int_wtrans_addr;
518 logic [N_PORTS-1:0] int_wtrans_accept;
519 logic [N_PORTS-1:0] int_wtrans_drop;
520 logic [N_PORTS-1:0] int_wtrans_miss;
521 logic [N_PORTS-1:0] int_wtrans_sent;
522 logic [N_PORTS-1:0] int_wtrans_cache_coherent;
523 logic [N_PORTS-1:0] int_wmaster_select;
524
525 logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] int_rtrans_addr;
526 logic [N_PORTS-1:0] int_rtrans_accept;
527 logic [N_PORTS-1:0] int_rtrans_drop;
528 logic [N_PORTS-1:0] int_rtrans_miss;
529 logic [N_PORTS-1:0] int_rtrans_sent;
530 logic [N_PORTS-1:0] int_rtrans_cache_coherent;
531 logic [N_PORTS-1:0] int_rmaster_select;
532
533 logic [N_PORTS-1:0] w_master_select;
534
535 // Internal master0 AXI4 lines. These connect the first master port to the
536 // multiplexers
537 // For channels read address, write address and write data the other lines
538 // are ignored if valid is not set, therefore we only need to multiplex those
539 logic [N_PORTS-1:0] int_m0_awvalid;
540 logic [N_PORTS-1:0] int_m0_awready;
541
542 logic [N_PORTS-1:0] int_m0_wvalid;
543 logic [N_PORTS-1:0] int_m0_wready;
544
545 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] int_m0_bid;
546 logic [N_PORTS-1:0] [1:0] int_m0_bresp;
547 logic [N_PORTS-1:0] int_m0_bvalid;
548 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_m0_buser;
549 logic [N_PORTS-1:0] int_m0_bready;
550
551 logic [N_PORTS-1:0] int_m0_arvalid;
552 logic [N_PORTS-1:0] int_m0_arready;
553
554 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] int_m0_rid;
555 logic [N_PORTS-1:0] [1:0] int_m0_rresp;
556 logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] int_m0_rdata;
557 logic [N_PORTS-1:0] int_m0_rlast;
558 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_m0_ruser;
559 logic [N_PORTS-1:0] int_m0_rready;
560 logic [N_PORTS-1:0] int_m0_rvalid;
561
562 logic [N_PORTS-1:0] l1_m0_ar_accept;
563 logic [N_PORTS-1:0] l1_m0_ar_drop;
564 logic [N_PORTS-1:0] l1_m0_ar_save;
565 logic [N_PORTS-1:0] l1_m0_ar_done;
566 logic [N_PORTS-1:0] l2_m0_ar_accept;
567 logic [N_PORTS-1:0] l2_m0_ar_drop;
568 logic [N_PORTS-1:0] l2_m0_ar_done;
569 logic [N_PORTS-1:0] l2_m0_ar_sending;
570
571 logic [N_PORTS-1:0] l1_m0_aw_accept;
572 logic [N_PORTS-1:0] l1_m0_aw_drop;
573 logic [N_PORTS-1:0] l1_m0_aw_save;
574 logic [N_PORTS-1:0] l1_m0_aw_done;
575 logic [N_PORTS-1:0] l2_m0_aw_accept;
576 logic [N_PORTS-1:0] l2_m0_aw_drop;
577 logic [N_PORTS-1:0] l2_m0_aw_done;
578 logic [N_PORTS-1:0] l2_m0_aw_sending;
579
580 // Internal master1 AXI4 lines. These connect the second master port to the
581 // multiplexers
582 // For channels read address, write address and write data the other lines
583 // are ignored if valid is not set, therefore we only need to multiplex those
584 logic [N_PORTS-1:0] int_m1_awvalid;
585 logic [N_PORTS-1:0] int_m1_awready;
586
587 logic [N_PORTS-1:0] int_m1_wvalid;
588 logic [N_PORTS-1:0] int_m1_wready;
589
590 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] int_m1_bid;
591 logic [N_PORTS-1:0] [1:0] int_m1_bresp;
592 logic [N_PORTS-1:0] int_m1_bvalid;
593 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_m1_buser;
594 logic [N_PORTS-1:0] int_m1_bready;
595
596 logic [N_PORTS-1:0] int_m1_arvalid;
597 logic [N_PORTS-1:0] int_m1_arready;
598
599 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] int_m1_rid;
600 logic [N_PORTS-1:0] [1:0] int_m1_rresp;
601 logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] int_m1_rdata;
602 logic [N_PORTS-1:0] int_m1_rlast;
603 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] int_m1_ruser;
604 logic [N_PORTS-1:0] int_m1_rvalid;
605 logic [N_PORTS-1:0] int_m1_rready;
606
607 logic [N_PORTS-1:0] l1_m1_ar_accept;
608 logic [N_PORTS-1:0] l1_m1_ar_drop;
609 logic [N_PORTS-1:0] l1_m1_ar_save;
610 logic [N_PORTS-1:0] l1_m1_ar_done;
611 logic [N_PORTS-1:0] l2_m1_ar_accept;
612 logic [N_PORTS-1:0] l2_m1_ar_drop;
613 logic [N_PORTS-1:0] l2_m1_ar_done;
614
615 logic [N_PORTS-1:0] l1_m1_aw_accept;
616 logic [N_PORTS-1:0] l1_m1_aw_drop;
617 logic [N_PORTS-1:0] l1_m1_aw_save;
618 logic [N_PORTS-1:0] l1_m1_aw_done;
619 logic [N_PORTS-1:0] l2_m1_aw_accept;
620 logic [N_PORTS-1:0] l2_m1_aw_drop;
621 logic [N_PORTS-1:0] l2_m1_aw_done;
622
623 // L1 outputs
624 logic [N_PORTS-1:0] rab_miss; // L1 RAB miss
625 logic [N_PORTS-1:0] rab_prot;
626 logic [N_PORTS-1:0] rab_multi;
627 logic [N_PORTS-1:0] rab_prefetch;
628
629 //
630 // Signals used to support L2 TLB
631 //
632 // L2 RAM configuration signals
633 logic [N_PORTS-1:0] [AXI_LITE_DATA_WIDTH-1:0] L2CfgWData_D;
634 logic [N_PORTS-1:0] [AXI_LITE_ADDR_WIDTH-1:0] L2CfgWAddr_D;
635 logic [N_PORTS-1:0] L2CfgWE_S;
636
637 // L1 output and drop Buffer
638 logic [N_PORTS-1:0] L1OutRwType_D, L1DropRwType_DP;
639 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] L1OutUser_D, L1DropUser_DP;
640 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] L1OutId_D, L1DropId_DP;
641 logic [N_PORTS-1:0] [7:0] L1OutLen_D, L1DropLen_DP;
642 logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] L1OutAddr_D, L1DropAddr_DP;
643 logic [N_PORTS-1:0] L1OutProt_D, L1DropProt_DP;
644 logic [N_PORTS-1:0] L1OutMulti_D, L1DropMulti_DP;
645 logic [N_PORTS-1:0] L1DropEn_S;
646 logic [N_PORTS-1:0] L1DropPrefetch_S;
647
648 logic [N_PORTS-1:0] L1DropValid_SN, L1DropValid_SP;
649
650 // L2 input Buffer
651 logic [N_PORTS-1:0] L2InRwType_DP;
652 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] L2InUser_DP;
653 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] L2InId_DP;
654 logic [N_PORTS-1:0] [7:0] L2InLen_DP;
655 logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] L2InAddr_DP;
656 logic [N_PORTS-1:0] L2InEn_S;
657
658 // L2 output Buffer
659 logic [N_PORTS-1:0] L2OutRwType_DP;
660 logic [N_PORTS-1:0] [AXI_USER_WIDTH-1:0] L2OutUser_DP;
661 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] L2OutId_DP;
662 logic [N_PORTS-1:0] [7:0] L2OutLen_DP;
663 logic [N_PORTS-1:0] [AXI_S_ADDR_WIDTH-1:0] L2OutInAddr_DP;
664
665 logic [N_PORTS-1:0] L2OutHit_SN, L2OutHit_SP;
666 logic [N_PORTS-1:0] L2OutMiss_SN, L2OutMiss_SP;
667 logic [N_PORTS-1:0] L2OutProt_SN, L2OutProt_SP;
668 logic [N_PORTS-1:0] L2OutMulti_SN, L2OutMulti_SP;
669 logic [N_PORTS-1:0] L2OutCC_SN, L2OutCC_SP;
670 logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] L2OutAddr_DN, L2OutAddr_DP;
671
672 logic [N_PORTS-1:0] L2OutValid_SN, L2OutValid_SP;
673 logic [N_PORTS-1:0] L2OutPrefetch_S;
674 logic [N_PORTS-1:0] L2OutReady_S;
675 logic [N_PORTS-1:0] L2OutEn_S;
676
677 // L2 outputs
678 logic [N_PORTS-1:0] L2Busy_S;
679 logic [N_PORTS-1:0] L2OutValid_S;
680
681 logic [N_PORTS-1:0] L2Miss_S;
682
683 // Signals for interfacing the AXI modules
684 logic [N_PORTS-1:0] l1_ar_accept;
685 logic [N_PORTS-1:0] l1_aw_accept;
686 logic [N_PORTS-1:0] l1_w_accept;
687 logic [N_PORTS-1:0] l1_xw_accept;
688
689 logic [N_PORTS-1:0] l1_ar_drop;
690 logic [N_PORTS-1:0] l1_aw_drop;
691 logic [N_PORTS-1:0] l1_w_drop;
692 logic [N_PORTS-1:0] l1_xw_drop;
693
694 logic [N_PORTS-1:0] l1_ar_save;
695 logic [N_PORTS-1:0] l1_aw_save;
696 logic [N_PORTS-1:0] l1_w_save;
697 logic [N_PORTS-1:0] l1_xw_save;
698
699 logic [N_PORTS-1:0] l1_ar_done;
700 logic [N_PORTS-1:0] l1_r_done;
701 logic [N_PORTS-1:0] l1_r_drop;
702 logic [N_PORTS-1:0] lx_r_drop;
703 logic [N_PORTS-1:0] lx_r_done;
704
705 logic [N_PORTS-1:0] l1_aw_done;
706 logic [N_PORTS-1:0] l1_w_done;
707 logic [N_PORTS-1:0] l1_xw_done;
708 logic [N_PORTS-1:0] l1_aw_done_SP;
709 logic [N_PORTS-1:0] l1_w_done_SP;
710
711 logic [N_PORTS-1:0] l2_ar_accept;
712 logic [N_PORTS-1:0] l2_aw_accept;
713 logic [N_PORTS-1:0] l2_w_accept;
714 logic [N_PORTS-1:0] l2_xw_accept;
715
716 logic [N_PORTS-1:0] l2_ar_drop;
717 logic [N_PORTS-1:0] l2_r_drop;
718 logic [N_PORTS-1:0] l2_xr_drop;
719 logic [N_PORTS-1:0] l2_aw_drop;
720 logic [N_PORTS-1:0] l2_w_drop;
721 logic [N_PORTS-1:0] l2_xw_drop;
722
723 logic [N_PORTS-1:0] l2_aw_done;
724 logic [N_PORTS-1:0] l2_w_done;
725 logic [N_PORTS-1:0] l2_xw_done;
726 logic [N_PORTS-1:0] l2_aw_done_SP;
727 logic [N_PORTS-1:0] l2_w_done_SP;
728
729 logic [N_PORTS-1:0] l2_ar_done;
730 logic [N_PORTS-1:0] l2_r_done;
731 logic [N_PORTS-1:0] l2_xr_done;
732 logic [N_PORTS-1:0] l2_ar_done_SP;
733 logic [N_PORTS-1:0] l2_r_done_SP;
734
735 logic [N_PORTS-1:0] l1_mx_aw_done;
736 logic [N_PORTS-1:0] l1_mx_ar_done;
737 logic [N_PORTS-1:0] l1_m0_aw_done_SP;
738 logic [N_PORTS-1:0] l1_m0_ar_done_SP;
739 logic [N_PORTS-1:0] l1_m1_aw_done_SP;
740 logic [N_PORTS-1:0] l1_m1_ar_done_SP;
741
742 logic [N_PORTS-1:0] l2_mx_aw_done;
743 logic [N_PORTS-1:0] l2_mx_ar_done;
744 logic [N_PORTS-1:0] l2_m0_aw_done_SP;
745 logic [N_PORTS-1:0] l2_m0_ar_done_SP;
746 logic [N_PORTS-1:0] l2_m1_aw_done_SP;
747 logic [N_PORTS-1:0] l2_m1_ar_done_SP;
748
749 logic [N_PORTS-1:0] [AXI_ID_WIDTH-1:0] l1_id_drop, lx_id_drop, b_id_drop;
750 logic [N_PORTS-1:0] [7:0] l1_len_drop, lx_len_drop;
751 logic [N_PORTS-1:0] l1_prefetch_drop, lx_prefetch_drop, b_prefetch_drop;
752 logic [N_PORTS-1:0] l1_hit_drop, lx_hit_drop, b_hit_drop;
753
754 logic [N_PORTS-1:0] b_drop;
755 logic [N_PORTS-1:0] b_done;
756
757 logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] l2_aw_addr;
758 logic [N_PORTS-1:0] [AXI_M_ADDR_WIDTH-1:0] l2_ar_addr;
759
760 logic [N_PORTS-1:0] l2_cache_coherent;
761 logic [N_PORTS-1:0] l2_master_select;
762
763 logic [N_PORTS-1:0] aw_in_stall;
764 logic [N_PORTS-1:0] aw_out_stall;
765
766 genvar i;
767
768 // RRESP FSM
769 typedef enum logic {IDLE, BUSY} r_resp_mux_ctrl_state_t;
770 r_resp_mux_ctrl_state_t [N_PORTS-1:0] RRespMuxCtrl_SN, RRespMuxCtrl_SP;
771 logic [N_PORTS-1:0] RRespSel_SN, RRespSel_SP;
772 logic [N_PORTS-1:0] RRespBurst_S;
773 logic [N_PORTS-1:0] RRespSelIm_S;
774
775 // }}}
776
777 // Local parameters {{{
778
779 // Enable L2 for select ports
780 localparam integer ENABLE_L2TLB[N_PORTS-1:0] = `EN_L2TLB_ARRAY;
781
782 // L2TLB parameters
783 localparam integer HUM_BUFFER_DEPTH = (N_L2_SET_ENTRIES/2/`RAB_L2_N_PAR_VA_RAMS)+13;
784
785 // }}}
786
787 // Derive `master_select` from cache coherency flag. {{{
788 `ifdef EN_ACP
789 assign int_wmaster_select = int_wtrans_cache_coherent;
790 assign int_rmaster_select = int_rtrans_cache_coherent;
791 assign l2_master_select = l2_cache_coherent;
792 `else
793 assign int_wmaster_select = '0;
794 assign int_rmaster_select = '0;
795 assign l2_master_select = '0;
796 `endif
797 // }}}
798
799 // Buf and Send {{{
800 // ██████╗ ██╗ ██╗███████╗ ██╗ ███████╗███████╗███╗ ██╗██████╗
801 // ██╔══██╗██║ ██║██╔════╝ ██║ ██╔════╝██╔════╝████╗ ██║██╔══██╗
802 // ██████╔╝██║ ██║█████╗ ████████╗ ███████╗█████╗ ██╔██╗ ██║██║ ██║
803 // ██╔══██╗██║ ██║██╔══╝ ██╔═██╔═╝ ╚════██║██╔══╝ ██║╚██╗██║██║ ██║
804 // ██████╔╝╚██████╔╝██║ ██████║ ███████║███████╗██║ ╚████║██████╔╝
805 // ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═══╝╚═════╝
806 //
807 logic[N_PORTS-1:0] m0_write_is_burst, m0_read_is_burst;
808 logic[N_PORTS-1:0] m1_write_is_burst, m1_read_is_burst;
809
810 generate for (i = 0; i < N_PORTS; i++) begin : BUF_AND_SEND
811
812 // Write Address channel (aw) {{{
813 /*
814 * write address channel (aw)
815 *
816 * ██╗ ██╗██████╗ ██╗████████╗███████╗ █████╗ ██████╗ ██████╗ ██████╗
817 * ██║ ██║██╔══██╗██║╚══██╔══╝██╔════╝ ██╔══██╗██╔══██╗██╔══██╗██╔══██╗
818 * ██║ █╗ ██║██████╔╝██║ ██║ █████╗ ███████║██║ ██║██║ ██║██████╔╝
819 * ██║███╗██║██╔══██╗██║ ██║ ██╔══╝ ██╔══██║██║ ██║██║ ██║██╔══██╗
820 * ╚███╔███╔╝██║ ██║██║ ██║ ███████╗ ██║ ██║██████╔╝██████╔╝██║ ██║
821 * ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═╝ ╚═╝
822 *
823 */
824
825 axi4_aw_buffer
826 #(
827 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
828 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
829 )
830 u_aw_buffer
831 (
832 .axi4_aclk ( Clk_CI ),
833 .axi4_arstn ( Rst_RBI ),
834 .s_axi4_awid ( s_axi4_awid[i] ),
835 .s_axi4_awaddr ( s_axi4_awaddr[i] ),
836 .s_axi4_awvalid ( s_axi4_awvalid[i] ),
837 .s_axi4_awready ( s_axi4_awready[i] ),
838 .s_axi4_awlen ( s_axi4_awlen[i] ),
839 .s_axi4_awsize ( s_axi4_awsize[i] ),
840 .s_axi4_awburst ( s_axi4_awburst[i] ),
841 .s_axi4_awlock ( s_axi4_awlock[i] ),
842 .s_axi4_awprot ( s_axi4_awprot[i] ),
843 .s_axi4_awcache ( s_axi4_awcache[i] ),
844 .s_axi4_awregion ( s_axi4_awregion[i] ),
845 .s_axi4_awqos ( s_axi4_awqos[i] ),
846 .s_axi4_awuser ( s_axi4_awuser[i] ),
847 .m_axi4_awid ( int_awid[i] ),
848 .m_axi4_awaddr ( int_awaddr[i] ),
849 .m_axi4_awvalid ( int_awvalid[i] ),
850 .m_axi4_awready ( int_awready[i] ),
851 .m_axi4_awlen ( int_awlen[i] ),
852 .m_axi4_awsize ( int_awsize[i] ),
853 .m_axi4_awburst ( int_awburst[i] ),
854 .m_axi4_awlock ( int_awlock[i] ),
855 .m_axi4_awprot ( int_awprot[i] ),
856 .m_axi4_awcache ( int_awcache[i] ),
857 .m_axi4_awregion ( int_awregion[i] ),
858 .m_axi4_awqos ( int_awqos[i] ),
859 .m_axi4_awuser ( int_awuser[i] )
860 );
861
862 axi4_aw_sender
863 #(
864 .AXI_ADDR_WIDTH ( AXI_M_ADDR_WIDTH ),
865 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
866 .AXI_USER_WIDTH ( AXI_USER_WIDTH ),
867 .ENABLE_L2TLB ( ENABLE_L2TLB[i] )
868 )
869 u_aw_sender_m0
870 (
871 .axi4_aclk ( Clk_CI ),
872 .axi4_arstn ( Rst_RBI ),
873 .l1_done_o ( l1_m0_aw_done[i] ),
874 .l1_accept_i ( l1_m0_aw_accept[i] ),
875 .l1_drop_i ( l1_m0_aw_drop[i] ),
876 .l1_save_i ( l1_m0_aw_save[i] ),
877 .l2_done_o ( l2_m0_aw_done[i] ),
878 .l2_accept_i ( l2_m0_aw_accept[i] ),
879 .l2_drop_i ( l2_m0_aw_drop[i] ),
880 .l2_sending_o ( l2_m0_aw_sending[i] ),
881 .l1_awaddr_i ( int_wtrans_addr[i] ),
882 .l2_awaddr_i ( l2_aw_addr[i] ),
883 .s_axi4_awid ( int_awid[i] ),
884 .s_axi4_awvalid ( int_m0_awvalid[i] ),
885 .s_axi4_awready ( int_m0_awready[i] ),
886 .s_axi4_awlen ( int_awlen[i] ),
887 .s_axi4_awsize ( int_awsize[i] ),
888 .s_axi4_awburst ( int_awburst[i] ),
889 .s_axi4_awlock ( int_awlock[i] ),
890 .s_axi4_awprot ( int_awprot[i] ),
891 .s_axi4_awcache ( int_awcache[i] ),
892 .s_axi4_awregion ( int_awregion[i] ),
893 .s_axi4_awqos ( int_awqos[i] ),
894 .s_axi4_awuser ( int_awuser[i] ),
895 .m_axi4_awid ( m0_axi4_awid[i] ),
896 .m_axi4_awaddr ( m0_axi4_awaddr[i] ),
897 .m_axi4_awvalid ( m0_axi4_awvalid[i] ),
898 .m_axi4_awready ( m0_axi4_awready[i] ),
899 .m_axi4_awlen ( m0_axi4_awlen[i] ),
900 .m_axi4_awsize ( m0_axi4_awsize[i] ),
901 .m_axi4_awburst ( m0_axi4_awburst[i] ),
902 .m_axi4_awlock ( m0_axi4_awlock[i] ),
903 .m_axi4_awprot ( m0_axi4_awprot[i] ),
904 .m_axi4_awcache ( ),
905 .m_axi4_awregion ( m0_axi4_awregion[i] ),
906 .m_axi4_awqos ( m0_axi4_awqos[i] ),
907 .m_axi4_awuser ( m0_axi4_awuser[i] )
908 );
909
910 // The AXCACHE signals are set according to burstiness and cache coherence or statically
911 // when not connected to ACP on Zynq (implemented below).
912 assign m0_write_is_burst[i] = (m0_axi4_awlen[i] != {8{1'b0}}) && (m0_axi4_awburst[i] != 2'b00);
913 `ifndef EN_ACP
914 always_comb begin
915 if ( (l2_m0_aw_sending[i] & l2_cache_coherent[i]) | int_wtrans_cache_coherent[i]) begin
916 if (m0_write_is_burst[i]) begin
917 m0_axi4_awcache[i] = 4'b0111;
918 end else begin
919 m0_axi4_awcache[i] = 4'b1111;
920 end
921 end else begin
922 m0_axi4_awcache[i] = 4'b0011;
923 end
924 end
925 `else
926 assign m0_axi4_awcache[i] = 4'b0011;
927 `endif
928
929 axi4_aw_sender
930 #(
931 .AXI_ADDR_WIDTH ( AXI_M_ADDR_WIDTH ),
932 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
933 .AXI_USER_WIDTH ( AXI_USER_WIDTH ),
934 .ENABLE_L2TLB ( ENABLE_L2TLB[i] )
935 )
936 u_aw_sender_m1
937 (
938 .axi4_aclk ( Clk_CI ),
939 .axi4_arstn ( Rst_RBI ),
940 .l1_accept_i ( l1_m1_aw_accept[i] ),
941 .l1_drop_i ( l1_m1_aw_drop[i] ),
942 .l1_save_i ( l1_m1_aw_save[i] ),
943 .l1_done_o ( l1_m1_aw_done[i] ),
944 .l2_accept_i ( l2_m1_aw_accept[i] ),
945 .l2_drop_i ( l2_m1_aw_drop[i] ),
946 .l2_done_o ( l2_m1_aw_done[i] ),
947 .l2_sending_o ( ), // just helps to set axcache
948 .l1_awaddr_i ( int_wtrans_addr[i] ),
949 .l2_awaddr_i ( l2_aw_addr[i] ),
950 .s_axi4_awid ( int_awid[i] ),
951 .s_axi4_awvalid ( int_m1_awvalid[i] ),
952 .s_axi4_awready ( int_m1_awready[i] ),
953 .s_axi4_awlen ( int_awlen[i] ),
954 .s_axi4_awsize ( int_awsize[i] ),
955 .s_axi4_awburst ( int_awburst[i] ),
956 .s_axi4_awlock ( int_awlock[i] ),
957 .s_axi4_awprot ( int_awprot[i] ),
958 .s_axi4_awcache ( int_awcache[i] ),
959 .s_axi4_awregion ( int_awregion[i] ),
960 .s_axi4_awqos ( int_awqos[i] ),
961 .s_axi4_awuser ( int_awuser[i] ),
962 .m_axi4_awid ( m1_axi4_awid[i] ),
963 .m_axi4_awaddr ( m1_axi4_awaddr[i] ),
964 .m_axi4_awvalid ( m1_axi4_awvalid[i] ),
965 .m_axi4_awready ( m1_axi4_awready[i] ),
966 .m_axi4_awlen ( m1_axi4_awlen[i] ),
967 .m_axi4_awsize ( m1_axi4_awsize[i] ),
968 .m_axi4_awburst ( m1_axi4_awburst[i] ),
969 .m_axi4_awlock ( m1_axi4_awlock[i] ),
970 .m_axi4_awprot ( m1_axi4_awprot[i] ),
971 .m_axi4_awcache ( ),
972 .m_axi4_awregion ( m1_axi4_awregion[i] ),
973 .m_axi4_awqos ( m1_axi4_awqos[i] ),
974 .m_axi4_awuser ( m1_axi4_awuser[i] )
975 );
976
977 // The AXCACHE signals are set according to burstiness and cache coherence or statically
978 // when not connected to ACP on Zynq (implemented below).
979 assign m1_write_is_burst[i] = (m1_axi4_awlen[i] != {8{1'b0}}) && (m1_axi4_awburst[i] != 2'b00);
980 `ifdef EN_ACP
981 always_comb begin
982 if (m1_write_is_burst[i]) begin
983 m1_axi4_awcache[i] = 4'b1011;
984 end else begin
985 m1_axi4_awcache[i] = 4'b1111;
986 end
987 end
988 `else
989 assign m1_axi4_awcache[i] = 4'b0011;
990 `endif
991
992 // }}}
993
994 // Write Data channel (w) {{{
995 /*
996 * write data channel (w)
997 *
998 * ██╗ ██╗██████╗ ██╗████████╗███████╗ ██████╗ █████╗ ████████╗ █████╗
999 * ██║ ██║██╔══██╗██║╚══██╔══╝██╔════╝ ██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗
1000 * ██║ █╗ ██║██████╔╝██║ ██║ █████╗ ██║ ██║███████║ ██║ ███████║
1001 * ██║███╗██║██╔══██╗██║ ██║ ██╔══╝ ██║ ██║██╔══██║ ██║ ██╔══██║
1002 * ╚███╔███╔╝██║ ██║██║ ██║ ███████╗ ██████╔╝██║ ██║ ██║ ██║ ██║
1003 * ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
1004 *
1005 */
1006 axi4_w_buffer
1007 #(
1008 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1009 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1010 .AXI_USER_WIDTH ( AXI_USER_WIDTH ),
1011 .ENABLE_L2TLB ( ENABLE_L2TLB[i] ),
1012 .HUM_BUFFER_DEPTH ( HUM_BUFFER_DEPTH )
1013 )
1014 u_w_buffer
1015 (
1016 .axi4_aclk ( Clk_CI ),
1017 .axi4_arstn ( Rst_RBI ),
1018
1019 // L1 interface
1020 .l1_done_o ( l1_w_done[i] ),
1021 .l1_accept_i ( l1_w_accept[i] ),
1022 .l1_save_i ( l1_w_save[i] ),
1023 .l1_drop_i ( l1_w_drop[i] ),
1024 .l1_master_i ( int_wmaster_select[i] ),
1025 .l1_id_i ( l1_id_drop[i] ),
1026 .l1_len_i ( l1_len_drop[i] ),
1027 .l1_prefetch_i ( l1_prefetch_drop[i] ),
1028 .l1_hit_i ( l1_hit_drop[i] ),
1029
1030 // L2 interface
1031 .l2_done_o ( l2_w_done[i] ),
1032 .l2_accept_i ( l2_w_accept[i] ),
1033 .l2_drop_i ( l2_w_drop[i] ),
1034 .l2_master_i ( l2_master_select[i] ),
1035 .l2_id_i ( lx_id_drop[i] ),
1036 .l2_len_i ( lx_len_drop[i] ),
1037 .l2_prefetch_i ( lx_prefetch_drop[i] ),
1038 .l2_hit_i ( lx_hit_drop[i] ),
1039
1040 // Top-level control outputs
1041 .master_select_o ( w_master_select[i] ),
1042 .input_stall_o ( aw_in_stall[i] ), // stall L1 AW input if request buffers full
1043 .output_stall_o ( aw_out_stall[i] ), // stall L1 AW hit forwarding if bypass not possible
1044
1045 // B sender interface
1046 .b_drop_o ( b_drop[i] ),
1047 .b_done_i ( b_done[i] ),
1048 .id_o ( b_id_drop[i] ),
1049 .prefetch_o ( b_prefetch_drop[i] ),
1050 .hit_o ( b_hit_drop[i] ),
1051
1052 // AXI W channel interfaces
1053 .s_axi4_wdata ( s_axi4_wdata[i] ),
1054 .s_axi4_wvalid ( s_axi4_wvalid[i] ),
1055 .s_axi4_wready ( s_axi4_wready[i] ),
1056 .s_axi4_wstrb ( s_axi4_wstrb[i] ),
1057 .s_axi4_wlast ( s_axi4_wlast[i] ),
1058 .s_axi4_wuser ( s_axi4_wuser[i] ),
1059 .m_axi4_wdata ( int_wdata[i] ),
1060 .m_axi4_wvalid ( int_wvalid[i] ),
1061 .m_axi4_wready ( int_wready[i] ),
1062 .m_axi4_wstrb ( int_wstrb[i] ),
1063 .m_axi4_wlast ( int_wlast[i] ),
1064 .m_axi4_wuser ( int_wuser[i] )
1065 );
1066
1067 axi4_w_sender
1068 #(
1069 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1070 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
1071 )
1072 u_w_sender_m0
1073 (
1074 .axi4_aclk ( Clk_CI ),
1075 .axi4_arstn ( Rst_RBI ),
1076 .s_axi4_wdata ( int_wdata[i] ),
1077 .s_axi4_wvalid ( int_m0_wvalid[i] ),
1078 .s_axi4_wready ( int_m0_wready[i] ),
1079 .s_axi4_wstrb ( int_wstrb[i] ),
1080 .s_axi4_wlast ( int_wlast[i] ),
1081 .s_axi4_wuser ( int_wuser[i] ),
1082 .m_axi4_wdata ( m0_axi4_wdata[i] ),
1083 .m_axi4_wvalid ( m0_axi4_wvalid[i] ),
1084 .m_axi4_wready ( m0_axi4_wready[i] ),
1085 .m_axi4_wstrb ( m0_axi4_wstrb[i] ),
1086 .m_axi4_wlast ( m0_axi4_wlast[i] ),
1087 .m_axi4_wuser ( m0_axi4_wuser[i] )
1088 );
1089
1090 axi4_w_sender
1091 #(
1092 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1093 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
1094
1095 )
1096 u_w_sender_m1
1097 (
1098 .axi4_aclk ( Clk_CI ),
1099 .axi4_arstn ( Rst_RBI ),
1100 .s_axi4_wdata ( int_wdata[i] ),
1101 .s_axi4_wvalid ( int_m1_wvalid[i] ),
1102 .s_axi4_wready ( int_m1_wready[i] ),
1103 .s_axi4_wstrb ( int_wstrb[i] ),
1104 .s_axi4_wlast ( int_wlast[i] ),
1105 .s_axi4_wuser ( int_wuser[i] ),
1106 .m_axi4_wdata ( m1_axi4_wdata[i] ),
1107 .m_axi4_wvalid ( m1_axi4_wvalid[i] ),
1108 .m_axi4_wready ( m1_axi4_wready[i] ),
1109 .m_axi4_wstrb ( m1_axi4_wstrb[i] ),
1110 .m_axi4_wlast ( m1_axi4_wlast[i] ),
1111 .m_axi4_wuser ( m1_axi4_wuser[i] )
1112 );
1113
1114 /*
1115 * Multiplexer to switch between the two output master ports on the write data (w) channel
1116 */
1117 always_comb begin
1118 /* Only one output can be selected at any time */
1119 if (w_master_select[i] == 1'b0) begin
1120 int_m0_wvalid[i] = int_wvalid[i];
1121 int_m1_wvalid[i] = 1'b0;
1122 int_wready[i] = int_m0_wready[i];
1123 end else begin
1124 int_m0_wvalid[i] = 1'b0;
1125 int_m1_wvalid[i] = int_wvalid[i];
1126 int_wready[i] = int_m1_wready[i];
1127 end
1128 end
1129
1130 // }}}
1131
1132 // Write Response channel (b) {{{
1133 /*
1134 * write response channel (b)
1135 *
1136 * ██╗ ██╗██████╗ ██╗████████╗███████╗ ██████╗ ███████╗███████╗██████╗
1137 * ██║ ██║██╔══██╗██║╚══██╔══╝██╔════╝ ██╔══██╗██╔════╝██╔════╝██╔══██╗
1138 * ██║ █╗ ██║██████╔╝██║ ██║ █████╗ ██████╔╝█████╗ ███████╗██████╔╝
1139 * ██║███╗██║██╔══██╗██║ ██║ ██╔══╝ ██╔══██╗██╔══╝ ╚════██║██╔═══╝
1140 * ╚███╔███╔╝██║ ██║██║ ██║ ███████╗ ██║ ██║███████╗███████║██║
1141 * ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝
1142 *
1143 */
1144 axi4_b_buffer
1145 #(
1146 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1147 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
1148 )
1149 u_b_buffer_m0
1150 (
1151 .axi4_aclk ( Clk_CI ),
1152 .axi4_arstn ( Rst_RBI ),
1153 .s_axi4_bid ( int_m0_bid[i] ),
1154 .s_axi4_bresp ( int_m0_bresp[i] ),
1155 .s_axi4_bvalid ( int_m0_bvalid[i] ),
1156 .s_axi4_buser ( int_m0_buser[i] ),
1157 .s_axi4_bready ( int_m0_bready[i] ),
1158 .m_axi4_bid ( m0_axi4_bid[i] ),
1159 .m_axi4_bresp ( m0_axi4_bresp[i] ),
1160 .m_axi4_bvalid ( m0_axi4_bvalid[i] ),
1161 .m_axi4_buser ( m0_axi4_buser[i] ),
1162 .m_axi4_bready ( m0_axi4_bready[i] )
1163 );
1164
1165 axi4_b_buffer
1166 #(
1167 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1168 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
1169 )
1170 u_b_buffer_m1
1171 (
1172 .axi4_aclk ( Clk_CI ),
1173 .axi4_arstn ( Rst_RBI ),
1174 .s_axi4_bid ( int_m1_bid[i] ),
1175 .s_axi4_bresp ( int_m1_bresp[i] ),
1176 .s_axi4_bvalid ( int_m1_bvalid[i] ),
1177 .s_axi4_buser ( int_m1_buser[i] ),
1178 .s_axi4_bready ( int_m1_bready[i] ),
1179 .m_axi4_bid ( m1_axi4_bid[i] ),
1180 .m_axi4_bresp ( m1_axi4_bresp[i] ),
1181 .m_axi4_bvalid ( m1_axi4_bvalid[i] ),
1182 .m_axi4_buser ( m1_axi4_buser[i] ),
1183 .m_axi4_bready ( m1_axi4_bready[i] )
1184 );
1185
1186 axi4_b_sender
1187 #(
1188 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1189 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
1190 )
1191 u_b_sender
1192 (
1193 .axi4_aclk ( Clk_CI ),
1194 .axi4_arstn ( Rst_RBI ),
1195 .drop_i ( b_drop[i] ),
1196 .done_o ( b_done[i] ),
1197 .id_i ( b_id_drop[i] ),
1198 .prefetch_i ( b_prefetch_drop[i] ),
1199 .hit_i ( b_hit_drop[i] ),
1200 .s_axi4_bid ( s_axi4_bid[i] ),
1201 .s_axi4_bresp ( s_axi4_bresp[i] ),
1202 .s_axi4_bvalid ( s_axi4_bvalid[i] ),
1203 .s_axi4_buser ( s_axi4_buser[i] ),
1204 .s_axi4_bready ( s_axi4_bready[i] ),
1205 .m_axi4_bid ( int_bid[i] ),
1206 .m_axi4_bresp ( int_bresp[i] ),
1207 .m_axi4_bvalid ( int_bvalid[i] ),
1208 .m_axi4_buser ( int_buser[i] ),
1209 .m_axi4_bready ( int_bready[i] )
1210 );
1211
1212 /*
1213 * Multiplexer to switch between the two output master ports on the write response (b) channel
1214 */
1215 always_comb begin
1216 /* Output 1 always gets priority, so if it has something to send connect
1217 it and let output 0 wait using rready = 0 */
1218 if (int_m1_bvalid[i] == 1'b1) begin
1219 int_m0_bready[i] = 1'b0;
1220 int_m1_bready[i] = int_bready[i];
1221
1222 int_bid[i] = int_m1_bid[i];
1223 int_bresp[i] = int_m1_bresp[i];
1224 int_buser[i] = int_m1_buser[i];
1225 int_bvalid[i] = int_m1_bvalid[i];
1226 end else begin
1227 int_m0_bready[i] = int_bready[i];
1228 int_m1_bready[i] = 1'b0;
1229
1230 int_bid[i] = int_m0_bid[i];
1231 int_bresp[i] = int_m0_bresp[i];
1232 int_buser[i] = int_m0_buser[i];
1233 int_bvalid[i] = int_m0_bvalid[i];
1234 end
1235 end
1236
1237 // }}}
1238
1239 // Read Address channel (ar) {{{
1240 /*
1241 * read address channel (ar)
1242 *
1243 * ██████╗ ███████╗ █████╗ ██████╗ █████╗ ██████╗ ██████╗ ██████╗
1244 * ██╔══██╗██╔════╝██╔══██╗██╔══██╗ ██╔══██╗██╔══██╗██╔══██╗██╔══██╗
1245 * ██████╔╝█████╗ ███████║██║ ██║ ███████║██║ ██║██║ ██║██████╔╝
1246 * ██╔══██╗██╔══╝ ██╔══██║██║ ██║ ██╔══██║██║ ██║██║ ██║██╔══██╗
1247 * ██║ ██║███████╗██║ ██║██████╔╝ ██║ ██║██████╔╝██████╔╝██║ ██║
1248 * ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═╝ ╚═╝
1249 *
1250 */
1251 axi4_ar_buffer
1252 #(
1253 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1254 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
1255 )
1256 u_ar_buffer
1257 (
1258 .axi4_aclk ( Clk_CI ),
1259 .axi4_arstn ( Rst_RBI ),
1260 .s_axi4_arid ( s_axi4_arid[i] ),
1261 .s_axi4_araddr ( s_axi4_araddr[i] ),
1262 .s_axi4_arvalid ( s_axi4_arvalid[i] ),
1263 .s_axi4_arready ( s_axi4_arready[i] ),
1264 .s_axi4_arlen ( s_axi4_arlen[i] ),
1265 .s_axi4_arsize ( s_axi4_arsize[i] ),
1266 .s_axi4_arburst ( s_axi4_arburst[i] ),
1267 .s_axi4_arlock ( s_axi4_arlock[i] ),
1268 .s_axi4_arprot ( s_axi4_arprot[i] ),
1269 .s_axi4_arcache ( s_axi4_arcache[i] ),
1270 .s_axi4_aruser ( s_axi4_aruser[i] ),
1271 .m_axi4_arid ( int_arid[i] ),
1272 .m_axi4_araddr ( int_araddr[i] ),
1273 .m_axi4_arvalid ( int_arvalid[i] ),
1274 .m_axi4_arready ( int_arready[i] ),
1275 .m_axi4_arlen ( int_arlen[i] ),
1276 .m_axi4_arsize ( int_arsize[i] ),
1277 .m_axi4_arburst ( int_arburst[i] ),
1278 .m_axi4_arlock ( int_arlock[i] ),
1279 .m_axi4_arprot ( int_arprot[i] ),
1280 .m_axi4_arcache ( int_arcache[i] ),
1281 .m_axi4_aruser ( int_aruser[i] )
1282 );
1283
1284 axi4_ar_sender
1285 #(
1286 .AXI_ADDR_WIDTH ( AXI_M_ADDR_WIDTH ),
1287 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1288 .AXI_USER_WIDTH ( AXI_USER_WIDTH ),
1289 .ENABLE_L2TLB ( ENABLE_L2TLB[i] )
1290 )
1291 u_ar_sender_m0
1292 (
1293 .axi4_aclk ( Clk_CI ),
1294 .axi4_arstn ( Rst_RBI ),
1295 .l1_done_o ( l1_m0_ar_done[i] ),
1296 .l1_accept_i ( l1_m0_ar_accept[i] ),
1297 .l1_drop_i ( l1_m0_ar_drop[i] ),
1298 .l1_save_i ( l1_m0_ar_save[i] ),
1299 .l2_done_o ( l2_m0_ar_done[i] ),
1300 .l2_accept_i ( l2_m0_ar_accept[i] ),
1301 .l2_drop_i ( l2_m0_ar_drop[i] ),
1302 .l2_sending_o ( l2_m0_ar_sending[i] ),
1303 .l1_araddr_i ( int_rtrans_addr[i] ),
1304 .l2_araddr_i ( l2_ar_addr[i] ),
1305 .s_axi4_arid ( int_arid[i] ),
1306 .s_axi4_arvalid ( int_m0_arvalid[i] ),
1307 .s_axi4_arready ( int_m0_arready[i] ),
1308 .s_axi4_arlen ( int_arlen[i] ),
1309 .s_axi4_arsize ( int_arsize[i] ),
1310 .s_axi4_arburst ( int_arburst[i] ),
1311 .s_axi4_arlock ( int_arlock[i] ),
1312 .s_axi4_arprot ( int_arprot[i] ),
1313 .s_axi4_arcache ( int_arcache[i] ),
1314 .s_axi4_aruser ( int_aruser[i] ),
1315 .m_axi4_arid ( m0_axi4_arid[i] ),
1316 .m_axi4_araddr ( m0_axi4_araddr[i] ),
1317 .m_axi4_arvalid ( m0_axi4_arvalid[i] ),
1318 .m_axi4_arready ( m0_axi4_arready[i] ),
1319 .m_axi4_arlen ( m0_axi4_arlen[i] ),
1320 .m_axi4_arsize ( m0_axi4_arsize[i] ),
1321 .m_axi4_arburst ( m0_axi4_arburst[i] ),
1322 .m_axi4_arlock ( m0_axi4_arlock[i] ),
1323 .m_axi4_arprot ( m0_axi4_arprot[i] ),
1324 .m_axi4_arcache ( ),
1325 .m_axi4_aruser ( m0_axi4_aruser[i] )
1326 );
1327
1328 // The AXCACHE signals are set according to burstiness and cache coherence or statically
1329 // when not connected to ACP on Zynq (implemented below).
1330 assign m0_read_is_burst[i] = (m0_axi4_arlen[i] != {8{1'b0}}) && (m0_axi4_arburst[i] != 2'b00);
1331 `ifndef EN_ACP
1332 always_comb begin
1333 if ( (l2_m0_ar_sending[i] & l2_cache_coherent[i]) | int_rtrans_cache_coherent[i]) begin
1334 if (m0_read_is_burst[i]) begin
1335 m0_axi4_arcache[i] = 4'b1011;
1336 end else begin
1337 m0_axi4_arcache[i] = 4'b1111;
1338 end
1339 end else begin
1340 m0_axi4_arcache[i] = 4'b0011;
1341 end
1342 end
1343 `else
1344 assign m0_axi4_arcache[i] = 4'b0011;
1345 `endif
1346
1347 axi4_ar_sender
1348 #(
1349 .AXI_ADDR_WIDTH ( AXI_M_ADDR_WIDTH ),
1350 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1351 .AXI_USER_WIDTH ( AXI_USER_WIDTH ),
1352 .ENABLE_L2TLB ( ENABLE_L2TLB[i] )
1353 )
1354 u_ar_sender_m1
1355 (
1356 .axi4_aclk ( Clk_CI ),
1357 .axi4_arstn ( Rst_RBI ),
1358 .l1_done_o ( l1_m1_ar_done[i] ),
1359 .l1_accept_i ( l1_m1_ar_accept[i] ),
1360 .l1_drop_i ( l1_m1_ar_drop[i] ),
1361 .l1_save_i ( l1_m1_ar_save[i] ),
1362 .l2_done_o ( l2_m1_ar_done[i] ),
1363 .l2_accept_i ( l2_m1_ar_accept[i] ),
1364 .l2_drop_i ( l2_m1_ar_drop[i] ),
1365 .l2_sending_o ( ), // just helps to set axcache
1366 .l1_araddr_i ( int_rtrans_addr[i] ),
1367 .l2_araddr_i ( l2_ar_addr[i] ),
1368 .s_axi4_arid ( int_arid[i] ),
1369 .s_axi4_arvalid ( int_m1_arvalid[i] ),
1370 .s_axi4_arready ( int_m1_arready[i] ),
1371 .s_axi4_arlen ( int_arlen[i] ),
1372 .s_axi4_arsize ( int_arsize[i] ),
1373 .s_axi4_arburst ( int_arburst[i] ),
1374 .s_axi4_arlock ( int_arlock[i] ),
1375 .s_axi4_arprot ( int_arprot[i] ),
1376 .s_axi4_arcache ( int_arcache[i] ),
1377 .s_axi4_aruser ( int_aruser[i] ),
1378 .m_axi4_arid ( m1_axi4_arid[i] ),
1379 .m_axi4_araddr ( m1_axi4_araddr[i] ),
1380 .m_axi4_arvalid ( m1_axi4_arvalid[i] ),
1381 .m_axi4_arready ( m1_axi4_arready[i] ),
1382 .m_axi4_arlen ( m1_axi4_arlen[i] ),
1383 .m_axi4_arsize ( m1_axi4_arsize[i] ),
1384 .m_axi4_arburst ( m1_axi4_arburst[i] ),
1385 .m_axi4_arlock ( m1_axi4_arlock[i] ),
1386 .m_axi4_arprot ( m1_axi4_arprot[i] ),
1387 .m_axi4_arcache ( ),
1388 .m_axi4_aruser ( m1_axi4_aruser[i] )
1389 );
1390
1391 // The AXCACHE signals are set according to burstiness and cache coherence or statically
1392 // when not connected to ACP on Zynq (implemented below).
1393 assign m1_read_is_burst[i] = (m1_axi4_arlen[i] != {8{1'b0}}) && (m1_axi4_arburst[i] != 2'b00);
1394 `ifdef EN_ACP
1395 always_comb begin
1396 if (m1_read_is_burst[i]) begin
1397 m1_axi4_arcache[i] = 4'b1011;
1398 end else begin
1399 m1_axi4_arcache[i] = 4'b1111;
1400 end
1401 end
1402 `else
1403 assign m1_axi4_arcache[i] = 4'b0011;
1404 `endif
1405
1406 // }}}
1407
1408 // Read Response channel (r) {{{
1409 /*
1410 * read response channel (r)
1411 *
1412 * ██████╗ ███████╗ █████╗ ██████╗ ██████╗ ███████╗███████╗██████╗
1413 * ██╔══██╗██╔════╝██╔══██╗██╔══██╗ ██╔══██╗██╔════╝██╔════╝██╔══██╗
1414 * ██████╔╝█████╗ ███████║██║ ██║ ██████╔╝█████╗ ███████╗██████╔╝
1415 * ██╔══██╗██╔══╝ ██╔══██║██║ ██║ ██╔══██╗██╔══╝ ╚════██║██╔═══╝
1416 * ██║ ██║███████╗██║ ██║██████╔╝ ██║ ██║███████╗███████║██║
1417 * ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝
1418 *
1419 */
1420 axi4_r_buffer
1421 #(
1422 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1423 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1424 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
1425 )
1426 u_r_buffer_m0
1427 (
1428 .axi4_aclk ( Clk_CI ),
1429 .axi4_arstn ( Rst_RBI ),
1430 .s_axi4_rid ( int_m0_rid[i] ),
1431 .s_axi4_rresp ( int_m0_rresp[i] ),
1432 .s_axi4_rdata ( int_m0_rdata[i] ),
1433 .s_axi4_rlast ( int_m0_rlast[i] ),
1434 .s_axi4_rvalid ( int_m0_rvalid[i] ),
1435 .s_axi4_ruser ( int_m0_ruser[i] ),
1436 .s_axi4_rready ( int_m0_rready[i] ),
1437 .m_axi4_rid ( m0_axi4_rid[i] ),
1438 .m_axi4_rresp ( m0_axi4_rresp[i] ),
1439 .m_axi4_rdata ( m0_axi4_rdata[i] ),
1440 .m_axi4_rlast ( m0_axi4_rlast[i] ),
1441 .m_axi4_rvalid ( m0_axi4_rvalid[i] ),
1442 .m_axi4_ruser ( m0_axi4_ruser[i] ),
1443 .m_axi4_rready ( m0_axi4_rready[i] )
1444 );
1445
1446 axi4_r_buffer
1447 #(
1448 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1449 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1450 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
1451 )
1452 u_r_buffer_m1
1453 (
1454 .axi4_aclk ( Clk_CI ),
1455 .axi4_arstn ( Rst_RBI ),
1456 .s_axi4_rid ( int_m1_rid[i] ),
1457 .s_axi4_rresp ( int_m1_rresp[i] ),
1458 .s_axi4_rdata ( int_m1_rdata[i] ),
1459 .s_axi4_rlast ( int_m1_rlast[i] ),
1460 .s_axi4_rvalid ( int_m1_rvalid[i] ),
1461 .s_axi4_ruser ( int_m1_ruser[i] ),
1462 .s_axi4_rready ( int_m1_rready[i] ),
1463 .m_axi4_rid ( m1_axi4_rid[i] ),
1464 .m_axi4_rresp ( m1_axi4_rresp[i] ),
1465 .m_axi4_rdata ( m1_axi4_rdata[i] ),
1466 .m_axi4_rlast ( m1_axi4_rlast[i] ),
1467 .m_axi4_rvalid ( m1_axi4_rvalid[i] ),
1468 .m_axi4_ruser ( m1_axi4_ruser[i] ),
1469 .m_axi4_rready ( m1_axi4_rready[i] )
1470 );
1471
1472 axi4_r_sender
1473 #(
1474 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1475 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1476 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
1477 )
1478 u_r_sender
1479 (
1480 .axi4_aclk ( Clk_CI ),
1481 .axi4_arstn ( Rst_RBI ),
1482 .drop_i ( lx_r_drop[i] ),
1483 .drop_len_i ( lx_len_drop[i] ),
1484 .done_o ( lx_r_done[i] ),
1485 .id_i ( lx_id_drop[i] ),
1486 .prefetch_i ( lx_prefetch_drop[i] ),
1487 .hit_i ( lx_hit_drop[i] ),
1488 .s_axi4_rid ( s_axi4_rid[i] ),
1489 .s_axi4_rresp ( s_axi4_rresp[i] ),
1490 .s_axi4_rdata ( s_axi4_rdata[i] ),
1491 .s_axi4_rlast ( s_axi4_rlast[i] ),
1492 .s_axi4_rvalid ( s_axi4_rvalid[i] ),
1493 .s_axi4_ruser ( s_axi4_ruser[i] ),
1494 .s_axi4_rready ( s_axi4_rready[i] ),
1495 .m_axi4_rid ( int_rid[i] ),
1496 .m_axi4_rresp ( int_rresp[i] ),
1497 .m_axi4_rdata ( int_rdata[i] ),
1498 .m_axi4_rlast ( int_rlast[i] ),
1499 .m_axi4_rvalid ( int_rvalid[i] ),
1500 .m_axi4_ruser ( int_ruser[i] ),
1501 .m_axi4_rready ( int_rready[i] )
1502 );
1503
1504 /*
1505 * Multiplexer to switch between the two output master ports on the read response(r) channel
1506 *
1507 * Do not perform read burst interleaving as the DMA does not support it. This means we can only
1508 * switch between the two masters upon sending rlast or when idle.
1509 *
1510 * However, if the downstream already performs burst interleaving, this cannot be undone here.
1511 * Also, the downstream may interleave a burst reponse with a single-beat transaction. In this
1512 * case, the FSM below falls out of the burst mode. To avoid it performing burst interleaving
1513 * after such an event, it gives priority to the master which received the last burst in case
1514 * both have a have a burst ready (rvalid).
1515 *
1516 * Order of priority:
1517 * 1. Ongoing burst transaction
1518 * 2. Single-beat transaction on Master 1.
1519 * 3. Single-beat transaction on Master 0.
1520 * 4. Burst transaction on master that received the last burst.
1521 */
1522 // Select signal
1523 always_ff @(posedge Clk_CI) begin
1524 if (Rst_RBI == 0) begin
1525 RRespSel_SP[i] <= 1'b0;
1526 end else begin
1527 RRespSel_SP[i] <= RRespSel_SN[i];
1528 end
1529 end
1530
1531 // FSM
1532 always_comb begin : RRespMuxFsm
1533 RRespMuxCtrl_SN[i] = RRespMuxCtrl_SP[i];
1534 RRespSel_SN[i] = RRespSel_SP[i];
1535
1536 RRespBurst_S[i] = 1'b0;
1537 RRespSelIm_S[i] = 1'b0;
1538
1539 unique case (RRespMuxCtrl_SP[i])
1540
1541 IDLE: begin
1542 // immediately forward single-beat transactions
1543 if (int_m1_rvalid[i] && int_m1_rlast[i])
1544 RRespSelIm_S[i] = 1'b1;
1545 else if (int_m0_rvalid[i] && int_m0_rlast[i])
1546 RRespSelIm_S[i] = 1'b0;
1547
1548 // bursts - they also start immediately
1549 else if (int_m1_rvalid[i] || int_m0_rvalid[i]) begin
1550 RRespMuxCtrl_SN[i] = BUSY;
1551
1552 // in case both are ready, continue with the master that had the last burst
1553 if (int_m1_rvalid[i] && int_m0_rvalid[i]) begin
1554 RRespSel_SN[i] = RRespSel_SP[i];
1555 RRespSelIm_S[i] = RRespSel_SP[i];
1556 end else if (int_m1_rvalid[i]) begin
1557 RRespSel_SN[i] = 1'b1;
1558 RRespSelIm_S[i] = 1'b1;
1559 end else begin
1560 RRespSel_SN[i] = 1'b0;
1561 RRespSelIm_S[i] = 1'b0;
1562 end
1563 end
1564 end
1565
1566 BUSY: begin
1567 RRespBurst_S[i] = 1'b1;
1568 // detect last handshake of currently ongoing transfer
1569 if (int_rvalid[i] && int_rready[i] && int_rlast[i])
1570 RRespMuxCtrl_SN[i] = IDLE;
1571 end
1572
1573 default: begin
1574 RRespMuxCtrl_SN[i] = IDLE;
1575 end
1576
1577 endcase
1578 end
1579
1580 // FSM state
1581 always_ff @(posedge Clk_CI) begin
1582 if (Rst_RBI == 0) begin
1583 RRespMuxCtrl_SP[i] <= IDLE;
1584 end else begin
1585 RRespMuxCtrl_SP[i] <= RRespMuxCtrl_SN[i];
1586 end
1587 end
1588
1589 // Actual multiplexer
1590 always_comb begin
1591 if ( (RRespBurst_S[i] && RRespSel_SP[i]) || (!RRespBurst_S[i] && RRespSelIm_S[i]) ) begin
1592 int_m0_rready[i] = 1'b0;
1593 int_m1_rready[i] = int_rready[i];
1594
1595 int_rid[i] = int_m1_rid[i];
1596 int_rresp[i] = int_m1_rresp[i];
1597 int_rdata[i] = int_m1_rdata[i];
1598 int_rlast[i] = int_m1_rlast[i];
1599 int_ruser[i] = int_m1_ruser[i];
1600 int_rvalid[i] = int_m1_rvalid[i];
1601 end else begin
1602 int_m0_rready[i] = int_rready[i];
1603 int_m1_rready[i] = 1'b0;
1604
1605 int_rid[i] = int_m0_rid[i];
1606 int_rresp[i] = int_m0_rresp[i];
1607 int_rdata[i] = int_m0_rdata[i];
1608 int_rlast[i] = int_m0_rlast[i];
1609 int_ruser[i] = int_m0_ruser[i];
1610 int_rvalid[i] = int_m0_rvalid[i];
1611 end
1612 end
1613
1614 end // BUF & SEND
1615
1616 // }}}
1617
1618 endgenerate // BUF & SEND }}}
1619
1620 // Log {{{
1621
1622 `ifdef RAB_AX_LOG_EN
1623 AxiBramLogger
1624 #(
1625 .AXI_ID_BITW ( AXI_ID_WIDTH ),
1626 .AXI_ADDR_BITW ( AXI_S_ADDR_WIDTH ),
1627 .NUM_LOG_ENTRIES ( `RAB_AX_LOG_ENTRIES )
1628 )
1629 u_aw_logger
1630 (
1631 .Clk_CI ( NonGatedClk_CI ),
1632 .TimestampClk_CI ( Clk_CI ),
1633 .Rst_RBI ( Rst_RBI ),
1634 .AxiValid_SI ( s_axi4_awvalid[1] ),
1635 .AxiReady_SI ( s_axi4_awready[1] ),
1636 .AxiId_DI ( s_axi4_awid[1] ),
1637 .AxiAddr_DI ( s_axi4_awaddr[1] ),
1638 .AxiLen_DI ( s_axi4_awlen[1] ),
1639 .Clear_SI ( AwLogClr_SI ),
1640 .LogEn_SI ( LogEn_SI ),
1641 .Full_SO ( int_aw_log_full ),
1642 .Ready_SO ( AwLogRdy_SO ),
1643 .Bram_PS ( AwBram_PS )
1644 );
1645
1646 AxiBramLogger
1647 #(
1648 .AXI_ID_BITW ( AXI_ID_WIDTH ),
1649 .AXI_ADDR_BITW ( AXI_S_ADDR_WIDTH ),
1650 .NUM_LOG_ENTRIES ( `RAB_AX_LOG_ENTRIES )
1651 )
1652 u_ar_logger
1653 (
1654 .Clk_CI ( NonGatedClk_CI ),
1655 .TimestampClk_CI ( Clk_CI ),
1656 .Rst_RBI ( Rst_RBI ),
1657 .AxiValid_SI ( s_axi4_arvalid[1] ),
1658 .AxiReady_SI ( s_axi4_arready[1] ),
1659 .AxiId_DI ( s_axi4_arid[1] ),
1660 .AxiAddr_DI ( s_axi4_araddr[1] ),
1661 .AxiLen_DI ( s_axi4_arlen[1] ),
1662 .Clear_SI ( ArLogClr_SI ),
1663 .LogEn_SI ( LogEn_SI ),
1664 .Full_SO ( int_ar_log_full ),
1665 .Ready_SO ( ArLogRdy_SO ),
1666 .Bram_PS ( ArBram_PS )
1667 );
1668 `endif
1669
1670 // }}}
1671
1672 // RAB Core {{{
1673 // ██████╗ █████╗ ██████╗ ██████╗ ██████╗ ██████╗ ███████╗
1674 // ██╔══██╗██╔══██╗██╔══██╗ ██╔════╝██╔═══██╗██╔══██╗██╔════╝
1675 // ██████╔╝███████║██████╔╝ ██║ ██║ ██║██████╔╝█████╗
1676 // ██╔══██╗██╔══██║██╔══██╗ ██║ ██║ ██║██╔══██╗██╔══╝
1677 // ██║ ██║██║ ██║██████╔╝ ╚██████╗╚██████╔╝██║ ██║███████╗
1678 // ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
1679 //
1680 /*
1681 * rab_core
1682 *
1683 * The rab core translates addresses. It has two ports, which can be used
1684 * independently, however they will compete for time internally, as lookups
1685 * are serialized.
1686 *
1687 * type is the read(0) or write(1) used to check the protection flags. If they
1688 * don't match an interrupt is created on the int_prot line.
1689 */
1690
1691 rab_core
1692 #(
1693 .N_PORTS ( N_PORTS ),
1694 .N_L2_SETS ( N_L2_SETS ),
1695 .N_L2_SET_ENTRIES ( N_L2_SET_ENTRIES ),
1696 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1697 .AXI_S_ADDR_WIDTH ( AXI_S_ADDR_WIDTH ),
1698 .AXI_M_ADDR_WIDTH ( AXI_M_ADDR_WIDTH ),
1699 .AXI_LITE_DATA_WIDTH ( AXI_LITE_DATA_WIDTH ),
1700 .AXI_LITE_ADDR_WIDTH ( AXI_LITE_ADDR_WIDTH ),
1701 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1702 .AXI_USER_WIDTH ( AXI_USER_WIDTH ),
1703 .MH_FIFO_DEPTH ( MH_FIFO_DEPTH )
1704 )
1705 u_rab_core
1706 (
1707 .Clk_CI ( Clk_CI ),
1708 .Rst_RBI ( Rst_RBI ),
1709
1710 // Config IF
1711 .s_axi_awaddr ( s_axi4lite_awaddr ),
1712 .s_axi_awvalid ( s_axi4lite_awvalid ),
1713 .s_axi_awready ( s_axi4lite_awready ),
1714 .s_axi_wdata ( s_axi4lite_wdata ),
1715 .s_axi_wstrb ( s_axi4lite_wstrb ),
1716 .s_axi_wvalid ( s_axi4lite_wvalid ),
1717 .s_axi_wready ( s_axi4lite_wready ),
1718 .s_axi_bresp ( s_axi4lite_bresp ),
1719 .s_axi_bvalid ( s_axi4lite_bvalid ),
1720 .s_axi_bready ( s_axi4lite_bready ),
1721 .s_axi_araddr ( s_axi4lite_araddr ),
1722 .s_axi_arvalid ( s_axi4lite_arvalid ),
1723 .s_axi_arready ( s_axi4lite_arready ),
1724 .s_axi_rready ( s_axi4lite_rready ),
1725 .s_axi_rdata ( s_axi4lite_rdata ),
1726 .s_axi_rresp ( s_axi4lite_rresp ),
1727 .s_axi_rvalid ( s_axi4lite_rvalid ),
1728
1729 // L1 miss info outputs -> L2 TLB arbitration
1730 .int_miss ( rab_miss ),
1731 .int_multi ( rab_multi ),
1732 .int_prot ( rab_prot ),
1733 .int_prefetch ( rab_prefetch ),
1734 .int_mhf_full ( int_mhf_full ),
1735
1736 // L1 transaction info outputs -> L2 TLB arbitration
1737 .int_axaddr_o ( L1OutAddr_D ),
1738 .int_axid_o ( L1OutId_D ),
1739 .int_axlen_o ( L1OutLen_D ),
1740 .int_axuser_o ( L1OutUser_D ),
1741
1742 // Write Req IF
1743 .port1_addr ( int_awaddr ),
1744 .port1_id ( int_awid ),
1745 .port1_len ( int_awlen ),
1746 .port1_size ( int_awsize ),
1747 .port1_addr_valid ( int_awvalid & ~aw_in_stall ), // avoid the FSM accepting new AW requests
1748 .port1_type ( {N_PORTS{1'b1}} ),
1749 .port1_user ( int_awuser ),
1750 .port1_sent ( int_wtrans_sent ), // signal done to L1 FSM
1751 .port1_out_addr ( int_wtrans_addr ),
1752 .port1_cache_coherent ( int_wtrans_cache_coherent ),
1753 .port1_accept ( int_wtrans_accept ),
1754 .port1_drop ( int_wtrans_drop ),
1755 .port1_miss ( int_wtrans_miss ),
1756
1757 // Read Req IF
1758 .port2_addr ( int_araddr ),
1759 .port2_id ( int_arid ),
1760 .port2_len ( int_arlen ),
1761 .port2_size ( int_arsize ),
1762 .port2_addr_valid ( int_arvalid ),
1763 .port2_type ( {N_PORTS{1'b0}} ),
1764 .port2_user ( int_aruser ),
1765 .port2_sent ( int_rtrans_sent ), // signal done to L1 FSM
1766 .port2_out_addr ( int_rtrans_addr ),
1767 .port2_cache_coherent ( int_rtrans_cache_coherent ),
1768 .port2_accept ( int_rtrans_accept ),
1769 .port2_drop ( int_rtrans_drop ),
1770 .port2_miss ( int_rtrans_miss ),
1771
1772 // L2 miss info inputs -> axi_rab_cfg
1773 .miss_l2_i ( L2Miss_S ),
1774 .miss_l2_addr_i ( L2OutInAddr_DP ),
1775 .miss_l2_id_i ( L2OutId_DP ),
1776 .miss_l2_user_i ( L2OutUser_DP ),
1777
1778 // L2 config outputs
1779 .wdata_l2_o ( L2CfgWData_D ),
1780 .waddr_l2_o ( L2CfgWAddr_D ),
1781 .wren_l2_o ( L2CfgWE_S )
1782 );
1783
1784 // }}}
1785
1786 // AX SPLITS {{{
1787 // █████╗ ██╗ ██╗ ███████╗██████╗ ██╗ ██╗████████╗
1788 // ██╔══██╗╚██╗██╔╝ ██╔════╝██╔══██╗██║ ██║╚══██╔══╝
1789 // ███████║ ╚███╔╝ ███████╗██████╔╝██║ ██║ ██║
1790 // ██╔══██║ ██╔██╗ ╚════██║██╔═══╝ ██║ ██║ ██║
1791 // ██║ ██║██╔╝ ██╗ ███████║██║ ███████╗██║ ██║
1792 // ╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝╚═╝ ╚══════╝╚═╝ ╚═╝
1793 //
1794 /**
1795 * Multiplex the two output master ports of the Read Address and Write Address (AR/AW) channels.
1796 *
1797 * Use the `int_xmaster_select` signal to route the signals to either Master 0 (to memory) or
1798 * Master 1 (to ACP). In case of an L1 miss: Route the signals to both masters. They shall be
1799 * saved until the L2 outputs are available.
1800 */
1801 generate for (i = 0; i < N_PORTS; i++) begin : AX_SPLIT
1802
1803 /*
1804 * When accepting L1 transactions, we must just do so on the selected master. Drop requests must
1805 * be performed on any one of the two masters. Save requests must be performed by both masters.
1806 */
1807 always_comb begin : AW_L1_SPLIT
1808
1809 // TLB handshake
1810 l1_m0_aw_accept[i] = 1'b0;
1811 l1_m1_aw_accept[i] = 1'b0;
1812 l1_m0_aw_drop[i] = 1'b0;
1813 l1_m1_aw_drop[i] = 1'b0;
1814 l1_m0_aw_save[i] = 1'b0;
1815 l1_m1_aw_save[i] = 1'b0;
1816
1817 l1_mx_aw_done[i] = 1'b0;
1818
1819 // AXI sender input handshake
1820 int_m0_awvalid[i] = 1'b0;
1821 int_m1_awvalid[i] = 1'b0;
1822 int_awready[i] = 1'b0;
1823
1824 // accept on selected master only
1825 if (l1_aw_accept[i]) begin
1826 if (int_wmaster_select[i]) begin
1827 l1_m1_aw_accept[i] = 1'b1;
1828 l1_mx_aw_done[i] = l1_m1_aw_done[i];
1829
1830 int_m1_awvalid[i] = int_awvalid[i];
1831 int_awready[i] = int_m1_awready[i];
1832
1833 end else begin
1834 l1_m0_aw_accept[i] = 1'b1;
1835 l1_mx_aw_done[i] = l1_m0_aw_done[i];
1836
1837 int_m0_awvalid[i] = int_awvalid[i];
1838 int_awready[i] = int_m0_awready[i];
1839 end
1840
1841 // drop on Master 0 only
1842 end else if (l1_aw_drop[i]) begin
1843 l1_m0_aw_drop[i] = 1'b1;
1844 l1_mx_aw_done[i] = l1_m0_aw_done[i];
1845
1846 int_m0_awvalid[i] = int_awvalid[i];
1847 int_awready[i] = l1_m0_aw_done[i];
1848
1849 // save on both masters
1850 end else if (l1_aw_save[i]) begin
1851 // split save
1852 l1_m0_aw_save[i] = ~l1_m0_aw_done_SP[i];
1853 l1_m1_aw_save[i] = ~l1_m1_aw_done_SP[i];
1854
1855 // combine done
1856 l1_mx_aw_done[i] = l1_m0_aw_done_SP[i] & l1_m1_aw_done_SP[i];
1857
1858 int_m0_awvalid[i] = int_awvalid[i];
1859 int_m1_awvalid[i] = int_awvalid[i];
1860 int_awready[i] = l1_mx_aw_done[i];
1861 end
1862 end
1863
1864 // signal back to handshake splitter
1865 assign l1_aw_done[i] = l1_mx_aw_done[i];
1866
1867 always_ff @(posedge Clk_CI) begin : L1_MX_AW_DONE_REG
1868 if (Rst_RBI == 0) begin
1869 l1_m0_aw_done_SP[i] <= 1'b0;
1870 l1_m1_aw_done_SP[i] <= 1'b0;
1871 end else if (l1_mx_aw_done[i]) begin
1872 l1_m0_aw_done_SP[i] <= 1'b0;
1873 l1_m1_aw_done_SP[i] <= 1'b0;
1874 end else begin
1875 l1_m0_aw_done_SP[i] <= l1_m0_aw_done_SP[i] | l1_m0_aw_done[i];
1876 l1_m1_aw_done_SP[i] <= l1_m1_aw_done_SP[i] | l1_m1_aw_done[i];
1877 end
1878 end
1879
1880 /*
1881 * When accepting L2 transactions, we must drop the corresponding transaction from the other
1882 * master to make it available again for save requests from L1_DROP_SAVE.
1883 */
1884 always_comb begin : AW_L2_SPLIT
1885
1886 l2_m0_aw_accept[i] = 1'b0;
1887 l2_m1_aw_accept[i] = 1'b0;
1888 l2_m0_aw_drop[i] = 1'b0;
1889 l2_m1_aw_drop[i] = 1'b0;
1890
1891 // de-assert request signals individually upon handshakes
1892 if (l2_aw_accept[i]) begin
1893 if (l2_master_select[i]) begin
1894 l2_m1_aw_accept[i] = ~l2_m1_aw_done_SP[i];
1895 l2_m0_aw_drop[i] = ~l2_m0_aw_done_SP[i];
1896
1897 end else begin
1898 l2_m0_aw_accept[i] = ~l2_m0_aw_done_SP[i];
1899 l2_m1_aw_drop[i] = ~l2_m1_aw_done_SP[i];
1900
1901 end
1902 end else begin
1903 l2_m0_aw_drop[i] = ~l2_m0_aw_done_SP[i] ? l2_aw_drop[i] : 1'b0;
1904 l2_m1_aw_drop[i] = ~l2_m1_aw_done_SP[i] ? l2_aw_drop[i] : 1'b0;
1905
1906 end
1907
1908 // combine done
1909 l2_mx_aw_done[i] = l2_m0_aw_done_SP[i] & l2_m1_aw_done_SP[i];
1910
1911 l2_aw_done[i] = l2_mx_aw_done[i];
1912 end
1913
1914 always_ff @(posedge Clk_CI) begin : L2_MX_AW_DONE_REG
1915 if (Rst_RBI == 0) begin
1916 l2_m0_aw_done_SP[i] <= 1'b0;
1917 l2_m1_aw_done_SP[i] <= 1'b0;
1918 end else if (l2_mx_aw_done[i]) begin
1919 l2_m0_aw_done_SP[i] <= 1'b0;
1920 l2_m1_aw_done_SP[i] <= 1'b0;
1921 end else begin
1922 l2_m0_aw_done_SP[i] <= l2_m0_aw_done_SP[i] | l2_m0_aw_done[i];
1923 l2_m1_aw_done_SP[i] <= l2_m1_aw_done_SP[i] | l2_m1_aw_done[i];
1924 end
1925 end
1926
1927 /*
1928 * When accepting L1 transactions, we must just do so on the selected master. Drop requests must
1929 * be performed on any one of the two masters. Save requests must be performed by both masters.
1930 */
1931 always_comb begin : AR_L1_SPLIT
1932
1933 // TLB handshake
1934 l1_m0_ar_accept[i] = 1'b0;
1935 l1_m1_ar_accept[i] = 1'b0;
1936 l1_m0_ar_drop[i] = 1'b0;
1937 l1_m1_ar_drop[i] = 1'b0;
1938 l1_m0_ar_save[i] = 1'b0;
1939 l1_m1_ar_save[i] = 1'b0;
1940
1941 l1_mx_ar_done[i] = 1'b0;
1942
1943 // AXI sender input handshake
1944 int_m0_arvalid[i] = 1'b0;
1945 int_m1_arvalid[i] = 1'b0;
1946 int_arready[i] = 1'b0;
1947
1948 // accept on selected master only
1949 if (l1_ar_accept[i]) begin
1950 if (int_rmaster_select[i]) begin
1951 l1_m1_ar_accept[i] = 1'b1;
1952 l1_mx_ar_done[i] = l1_m1_ar_done[i];
1953
1954 int_m1_arvalid[i] = int_arvalid[i];
1955 int_arready[i] = int_m1_arready[i];
1956
1957 end else begin
1958 l1_m0_ar_accept[i] = 1'b1;
1959 l1_mx_ar_done[i] = l1_m0_ar_done[i];
1960
1961 int_m0_arvalid[i] = int_arvalid[i];
1962 int_arready[i] = int_m0_arready[i];
1963 end
1964
1965 // drop on Master 0 only
1966 end else if (l1_ar_drop[i]) begin
1967 l1_m0_ar_drop[i] = 1'b1;
1968 l1_mx_ar_done[i] = l1_m0_ar_done[i];
1969
1970 int_m0_arvalid[i] = int_arvalid[i];
1971 int_arready[i] = l1_m0_ar_done[i];
1972
1973 // save on both masters
1974 end else if (l1_ar_save[i]) begin
1975 // split save
1976 l1_m0_ar_save[i] = ~l1_m0_ar_done_SP[i];
1977 l1_m1_ar_save[i] = ~l1_m1_ar_done_SP[i];
1978
1979 // combine done
1980 l1_mx_ar_done[i] = l1_m0_ar_done_SP[i] & l1_m1_ar_done_SP[i];
1981
1982 int_m0_arvalid[i] = int_arvalid[i];
1983 int_m1_arvalid[i] = int_arvalid[i];
1984 int_arready[i] = l1_mx_ar_done[i];
1985 end
1986 end
1987
1988 // signal back to handshake splitter
1989 assign l1_ar_done[i] = l1_mx_ar_done[i];
1990
1991 always_ff @(posedge Clk_CI) begin : L1_MX_AR_DONE_REG
1992 if (Rst_RBI == 0) begin
1993 l1_m0_ar_done_SP[i] <= 1'b0;
1994 l1_m1_ar_done_SP[i] <= 1'b0;
1995 end else if (l1_mx_ar_done[i]) begin
1996 l1_m0_ar_done_SP[i] <= 1'b0;
1997 l1_m1_ar_done_SP[i] <= 1'b0;
1998 end else begin
1999 l1_m0_ar_done_SP[i] <= l1_m0_ar_done_SP[i] | l1_m0_ar_done[i];
2000 l1_m1_ar_done_SP[i] <= l1_m1_ar_done_SP[i] | l1_m1_ar_done[i];
2001 end
2002 end
2003
2004 /*
2005 * When accepting L2 transactions, we must drop the corresponding transaction from the other
2006 * master to make it available again for save requests from L1_DROP_SAVE.
2007 */
2008 always_comb begin : AR_L2_SPLIT
2009
2010 l2_m0_ar_accept[i] = 1'b0;
2011 l2_m1_ar_accept[i] = 1'b0;
2012 l2_m0_ar_drop[i] = 1'b0;
2013 l2_m1_ar_drop[i] = 1'b0;
2014
2015 // de-assert request signals individually upon handshakes
2016 if (l2_ar_accept[i]) begin
2017 if (l2_master_select[i]) begin
2018 l2_m1_ar_accept[i] = ~l2_m1_ar_done_SP[i];
2019 l2_m0_ar_drop[i] = ~l2_m0_ar_done_SP[i];
2020
2021 end else begin
2022 l2_m0_ar_accept[i] = ~l2_m0_ar_done_SP[i];
2023 l2_m1_ar_drop[i] = ~l2_m1_ar_done_SP[i];
2024
2025 end
2026 end else if (l2_ar_drop[i]) begin
2027 l2_m0_ar_drop[i] = ~l2_m0_ar_done_SP[i] ? l2_ar_drop[i] : 1'b0;
2028 l2_m1_ar_drop[i] = ~l2_m1_ar_done_SP[i] ? l2_ar_drop[i] : 1'b0;
2029
2030 end
2031
2032 // combine done
2033 l2_mx_ar_done[i] = l2_m0_ar_done_SP[i] & l2_m1_ar_done_SP[i];
2034
2035 l2_ar_done[i] = l2_mx_ar_done[i];
2036 end
2037
2038 always_ff @(posedge Clk_CI) begin : L2_MX_AR_DONE_REG
2039 if (Rst_RBI == 0) begin
2040 l2_m0_ar_done_SP[i] <= 1'b0;
2041 l2_m1_ar_done_SP[i] <= 1'b0;
2042 end else if (l2_mx_ar_done[i]) begin
2043 l2_m0_ar_done_SP[i] <= 1'b0;
2044 l2_m1_ar_done_SP[i] <= 1'b0;
2045 end else begin
2046 l2_m0_ar_done_SP[i] <= l2_m0_ar_done_SP[i] | l2_m0_ar_done[i];
2047 l2_m1_ar_done_SP[i] <= l2_m1_ar_done_SP[i] | l2_m1_ar_done[i];
2048 end
2049 end
2050
2051 end // AX_SPLIT
2052 endgenerate // AX_SPLIT
2053
2054 // }}}
2055
2056 // HANDSHAKE SPLITS {{{
2057 // ██╗ ██╗███████╗ ███████╗██████╗ ██╗ ██╗████████╗
2058 // ██║ ██║██╔════╝ ██╔════╝██╔══██╗██║ ██║╚══██╔══╝
2059 // ███████║███████╗ ███████╗██████╔╝██║ ██║ ██║
2060 // ██╔══██║╚════██║ ╚════██║██╔═══╝ ██║ ██║ ██║
2061 // ██║ ██║███████║ ███████║██║ ███████╗██║ ██║
2062 // ╚═╝ ╚═╝╚══════╝ ╚══════╝╚═╝ ╚══════╝╚═╝ ╚═╝
2063 //
2064 /*
2065 * We need to perform combined handshakes with multiple AXI modules
2066 * upon transactions drops, accepts, saves etc. from two TLBs.
2067 */
2068 generate for (i = 0; i < N_PORTS; i++) begin : HANDSHAKE_SPLIT
2069
2070 assign l1_xw_accept[i] = int_wtrans_accept[i] & ~aw_out_stall[i];
2071 assign int_wtrans_sent[i] = l1_xw_done[i];
2072
2073 assign l1_ar_accept[i] = int_rtrans_accept[i];
2074 assign int_rtrans_sent[i] = l1_ar_done[i];
2075
2076 /*
2077 * L1 AW sender + W buffer handshake split
2078 */
2079 // forward
2080 assign l1_aw_accept[i] = l1_xw_accept[i] & ~l1_aw_done_SP[i];
2081 assign l1_w_accept[i] = l1_xw_accept[i] & ~l1_w_done_SP[i];
2082
2083 assign l1_aw_save[i] = l1_xw_save[i] & ~l1_aw_done_SP[i];
2084 assign l1_w_save[i] = l1_xw_save[i] & ~l1_w_done_SP[i];
2085
2086 assign l1_aw_drop[i] = l1_xw_drop[i] & ~l1_aw_done_SP[i];
2087 assign l1_w_drop[i] = l1_xw_drop[i] & ~l1_w_done_SP[i];
2088
2089 // backward
2090 assign l1_xw_done[i] = l1_aw_done_SP[i] & l1_w_done_SP[i];
2091
2092 always_ff @(posedge Clk_CI) begin : L1_XW_HS_SPLIT
2093 if (Rst_RBI == 0) begin
2094 l1_aw_done_SP[i] <= 1'b0;
2095 l1_w_done_SP[i] <= 1'b0;
2096 end else if (l1_xw_done[i]) begin
2097 l1_aw_done_SP[i] <= 1'b0;
2098 l1_w_done_SP[i] <= 1'b0;
2099 end else begin
2100 l1_aw_done_SP[i] <= l1_aw_done_SP[i] | l1_aw_done[i];
2101 l1_w_done_SP[i] <= l1_w_done_SP[i] | l1_w_done[i];
2102 end
2103 end
2104
2105 if (ENABLE_L2TLB[i] == 1) begin : L2_HS_SPLIT
2106
2107 /*
2108 * L1 AR sender + R sender handshake split
2109 *
2110 * AR and R do not need to be strictly in sync. We thus use separate handshakes.
2111 * But the handshake signals for the R sender are multiplexed with the those for
2112 * the L2. However, L2_ACCEPT_DROP_SAVE has always higher priority.
2113 */
2114 assign lx_r_drop[i] = l2_r_drop[i] | l1_r_drop[i];
2115 assign l1_r_done[i] = l2_r_drop[i] ? 1'b0 : lx_r_done[i];
2116 assign l2_r_done[i] = l2_r_drop[i] ? lx_r_done[i] : 1'b0;
2117
2118 /*
2119 * L2 AW sender + W buffer handshake split
2120 */
2121 // forward
2122 assign l2_aw_accept[i] = l2_xw_accept[i] & ~l2_aw_done_SP[i];
2123 assign l2_w_accept[i] = l2_xw_accept[i] & ~l2_w_done_SP[i];
2124
2125 assign l2_aw_drop[i] = l2_xw_drop[i] & ~l2_aw_done_SP[i];
2126 assign l2_w_drop[i] = l2_xw_drop[i] & ~l2_w_done_SP[i];
2127
2128 // backward
2129 assign l2_xw_done[i] = l2_aw_done_SP[i] & l2_w_done_SP[i];
2130
2131 always_ff @(posedge Clk_CI) begin : L2_XW_HS_SPLIT
2132 if (Rst_RBI == 0) begin
2133 l2_aw_done_SP[i] <= 1'b0;
2134 l2_w_done_SP[i] <= 1'b0;
2135 end else if (l2_xw_done[i]) begin
2136 l2_aw_done_SP[i] <= 1'b0;
2137 l2_w_done_SP[i] <= 1'b0;
2138 end else begin
2139 l2_aw_done_SP[i] <= l2_aw_done_SP[i] | l2_aw_done[i];
2140 l2_w_done_SP[i] <= l2_w_done_SP[i] | l2_w_done[i];
2141 end
2142 end
2143
2144 /*
2145 * L2 AR + R sender handshake split
2146 */
2147 // forward
2148 assign l2_ar_drop[i] = l2_xr_drop[i] & ~l2_ar_done_SP[i];
2149 assign l2_r_drop[i] = l2_xr_drop[i] & ~l2_r_done_SP[i];
2150
2151 // backward - make sure to always clear L2_XR_HS_SPLIT
2152 always_comb begin
2153 if (l2_xr_drop[i]) begin
2154 l2_xr_done[i] = l2_ar_done_SP[i] & l2_r_done_SP[i];
2155 end else begin
2156 l2_xr_done[i] = l2_ar_done_SP[i];
2157 end
2158 end
2159
2160 always_ff @(posedge Clk_CI) begin : L2_XR_HS_SPLIT
2161 if (Rst_RBI == 0) begin
2162 l2_ar_done_SP[i] <= 1'b0;
2163 l2_r_done_SP[i] <= 1'b0;
2164 end else if (l2_xr_done[i]) begin
2165 l2_ar_done_SP[i] <= 1'b0;
2166 l2_r_done_SP[i] <= 1'b0;
2167 end else begin
2168 l2_ar_done_SP[i] <= l2_ar_done_SP[i] | l2_ar_done[i];
2169 l2_r_done_SP[i] <= l2_r_done_SP[i] | l2_r_done[i];
2170 end
2171 end
2172
2173 end else begin // if (ENABLE_L2TLB[i] == 1)
2174
2175 assign lx_r_drop[i] = l1_r_drop[i];
2176 assign l1_r_done[i] = lx_r_done[i];
2177
2178 assign l2_aw_accept[i] = 1'b0;
2179 assign l2_w_accept[i] = 1'b0;
2180 assign l2_aw_drop[i] = 1'b0;
2181 assign l2_w_drop[i] = 1'b0;
2182 assign l2_xw_done[i] = 1'b0;
2183 assign l2_aw_done_SP[i] = 1'b0;
2184 assign l2_w_done_SP[i] = 1'b0;
2185
2186 assign l2_ar_accept[i] = 1'b0;
2187 assign l2_ar_drop[i] = 1'b0;
2188 assign l2_r_drop[i] = 1'b0;
2189 assign l2_xr_done[i] = 1'b0;
2190 assign l2_r_done[i] = 1'b0;
2191 assign l2_ar_done_SP[i] = 1'b0;
2192 assign l2_r_done_SP[i] = 1'b0;
2193
2194 end // if (ENABLE_L2TLB[i] == 1)
2195
2196 end // HANDSHAKE_SPLIT
2197 endgenerate // HANDSHAKE_SPLIT
2198
2199 // }}}
2200
2201 // L2 TLB {{{
2202 // ██╗ ██████╗ ████████╗██╗ ██████╗
2203 // ██║ ╚════██╗ ╚══██╔══╝██║ ██╔══██╗
2204 // ██║ █████╔╝ ██║ ██║ ██████╔╝
2205 // ██║ ██╔═══╝ ██║ ██║ ██╔══██╗
2206 // ███████╗███████╗ ██║ ███████╗██████╔╝
2207 // ╚══════╝╚══════╝ ╚═╝ ╚══════╝╚═════╝
2208 //
2209 /*
2210 * l2_tlb
2211 *
2212 * The L2 TLB translates addresses upon misses in the L1 TLB (rab_core).
2213 *
2214 * It supports one ongoing translation at a time. If an L1 miss occurs while the L2 is busy,
2215 * the L1 is stalled untill the L2 is available again.
2216 *
2217 */
2218 generate for (i = 0; i < N_PORTS; i++) begin : L2_TLB
2219 if (ENABLE_L2TLB[i] == 1) begin : L2_TLB
2220
2221 /*
2222 * L1 output selector
2223 */
2224 assign L1OutRwType_D[i] = int_wtrans_drop[i] ? 1'b1 : 1'b0;
2225 assign L1OutProt_D[i] = rab_prot[i];
2226 assign L1OutMulti_D[i] = rab_multi[i];
2227
2228 /*
2229 * L1 output control + L1_DROP_BUF, L2_IN_BUF management
2230 *
2231 * Forward the L1 drop request to AR/AW sender modules if
2232 * 1. the transactions needs to be dropped (L1 multi, prot, prefetch), or
2233 * 2. if a lookup in the L2 TLB is required (L1 miss) and the input buffer is not full.
2234 *
2235 * The AR/AW senders do not support more than 1 oustanding L1 miss. The push back towards
2236 * the upstream is realized by not accepting the save request (saving the L1 transaction)
2237 * in the senders as long as the L2 TLB is busy or has valid output. This ultimately
2238 * blocks the L1 TLB.
2239 *
2240 * Together with the AW drop/save, we also perform the W drop/save as AW and W need to
2241 * absolutely remain in order. In contrast, the R drop is performed
2242 */
2243 always_comb begin : L1_DROP_SAVE
2244
2245 l1_ar_drop[i] = 1'b0;
2246 l1_ar_save[i] = 1'b0;
2247 l1_xw_drop[i] = 1'b0;
2248 l1_xw_save[i] = 1'b0;
2249
2250 l1_id_drop[i] = L1OutId_D[i];
2251 l1_len_drop[i] = L1OutLen_D[i];
2252 l1_prefetch_drop[i] = rab_prefetch[i];
2253 l1_hit_drop[i] = 1'b1; // there are no drops for L1 misses
2254
2255 L1DropEn_S[i] = 1'b0;
2256 L2InEn_S[i] = 1'b0;
2257
2258 if ( rab_prot[i] | rab_multi[i] | rab_prefetch[i] ) begin
2259 // 1. Drop
2260 l1_ar_drop[i] = int_rtrans_drop[i] & ~L1DropValid_SP[i];
2261 l1_xw_drop[i] = int_wtrans_drop[i] & ~L1DropValid_SP[i];
2262
2263 // Store to L1_DROP_BUF upon handshake
2264 L1DropEn_S[i] = (l1_ar_drop[i] & l1_ar_done[i]) |
2265 (l1_xw_drop[i] & l1_xw_done[i]);
2266
2267 end else if ( rab_miss[i] ) begin
2268 // 2. Save - Make sure L2 is really available.
2269 l1_ar_save[i] = int_rtrans_drop[i] & ~L2Busy_S[i];
2270 l1_xw_save[i] = int_wtrans_drop[i] & ~L2Busy_S[i];
2271
2272 // Store to L2_IN_BUF upon handshake - triggers the L2 TLB
2273 L2InEn_S[i] = (l1_ar_save[i] & l1_ar_done[i]) |
2274 (l1_xw_save[i] & l1_xw_done[i]);
2275 end
2276 end
2277
2278 /*
2279 * L2 output control + L2_OUT_BUF management + R/B sender control + W buffer control
2280 *
2281 * Perform L1 R transaction drops unless the L2 output buffer holds valid data. The AXI specs
2282 * require the B response to be sent only after consuming/discarding the corresponding data
2283 * in the W channel. Thus, we only send L2 drop request to the W buffer here. The drop
2284 * request to the B sender is then sent by the W buffer autonomously.
2285 *
2286 * L1 AW/W drop requests are managed by L1_DROP_SAVE.
2287 */
2288 always_comb begin : L2_ACCEPT_DROP_SAVE
2289
2290 l2_ar_addr[i] = 'b0;
2291 l2_aw_addr[i] = 'b0;
2292 l2_ar_accept[i] = 1'b0;
2293 l2_xr_drop[i] = 1'b0;
2294 l2_xw_accept[i] = 1'b0;
2295 l2_xw_drop[i] = 1'b0;
2296
2297 l1_r_drop[i] = 1'b0;
2298
2299 lx_id_drop[i] = 'b0;
2300 lx_len_drop[i] = 'b0;
2301 lx_prefetch_drop[i] = 1'b0;
2302 lx_hit_drop[i] = 1'b0;
2303
2304 L1DropValid_SN[i] = L1DropValid_SP[i] | L1DropEn_S[i];
2305 L2OutValid_SN[i] = L2OutValid_SP[i];
2306 L2OutReady_S[i] = 1'b0;
2307 L2OutEn_S[i] = 1'b0;
2308
2309 L2Miss_S[i] = 1'b0;
2310 int_multi[i] = 1'b0;
2311 int_prot[i] = 1'b0;
2312
2313 if (L2OutValid_SP[i] == 1'b0) begin
2314
2315 // Drop L1 from R senders
2316 if (L1DropValid_SP[i] == 1'b1) begin
2317
2318 // Only perform the R sender drop here.
2319 if (~L1DropRwType_DP[i]) begin
2320
2321 l1_r_drop[i] = 1'b1;
2322 lx_id_drop[i] = L1DropId_DP[i];
2323 lx_len_drop[i] = L1DropLen_DP[i];
2324 lx_prefetch_drop[i] = L1DropPrefetch_S[i];
2325 lx_hit_drop[i] = 1'b1; // there are no drops for L1 misses
2326
2327 // Invalidate L1_DROP_BUF upon handshake
2328 if ( l1_r_drop[i] & l1_r_done[i] ) begin
2329
2330 L1DropValid_SN[i] = 1'b0;
2331 int_prot[i] = L1DropProt_DP[i];
2332 int_multi[i] = L1DropMulti_DP[i];
2333 end
2334
2335 end else begin
2336 // Invalidate L1_DROP_BUF
2337 L1DropValid_SN[i] = 1'b0;
2338 int_prot[i] = L1DropProt_DP[i];
2339 int_multi[i] = L1DropMulti_DP[i];
2340 end
2341 end
2342
2343 end else begin // L2_OUT_BUF has valid data
2344
2345 if ( L2OutHit_SP[i] & ~(L2OutPrefetch_S[i] | L2OutProt_SP[i] | L2OutMulti_SP[i]) ) begin
2346
2347 l2_ar_addr[i] = L2OutAddr_DP[i];
2348 l2_aw_addr[i] = L2OutAddr_DP[i];
2349
2350 l2_ar_accept[i] = L2OutRwType_DP[i] ? 1'b0 : 1'b1;
2351 l2_xw_accept[i] = L2OutRwType_DP[i] ? 1'b1 : 1'b0;
2352
2353 // Invalidate L2_OUT_BUF upon handshake
2354 L2OutValid_SN[i] = ~( (l2_ar_accept[i] & l2_ar_done[i]) |
2355 (l2_xw_accept[i] & l2_xw_done[i]) );
2356 end else begin
2357
2358 lx_id_drop[i] = L2OutId_DP[i];
2359 lx_len_drop[i] = L2OutLen_DP[i];
2360 lx_prefetch_drop[i] = L2OutPrefetch_S[i];
2361 lx_hit_drop[i] = L2OutHit_SP[i];
2362
2363 // The l2_xr_drop will also perform the handshake with the R sender
2364 l2_xr_drop[i] = L2OutRwType_DP[i] ? 1'b0 : 1'b1;
2365 l2_xw_drop[i] = L2OutRwType_DP[i] ? 1'b1 : 1'b0;
2366
2367 // Invalidate L1_DROP_BUF upon handshake
2368 if ( (l2_xr_drop[i] & l2_xr_done[i]) | (l2_xw_drop[i] & l2_xw_done[i]) ) begin
2369
2370 L2OutValid_SN[i] = 1'b0;
2371 L2Miss_S[i] = ~L2OutHit_SP[i];
2372 int_prot[i] = L2OutProt_SP[i];
2373 int_multi[i] = L2OutMulti_SP[i];
2374 end
2375 end
2376 end
2377
2378 // Only accept new L2 output after ongoing drops have finished.
2379 if ( (l2_xr_drop[i] == l2_xr_done[i]) &
2380 (l2_xw_drop[i] == l2_xw_done[i]) &
2381 (l1_r_drop[i] == l1_r_done[i] ) ) begin
2382 // Store to L2_OUT_BUF upon handshake with L2 TLB module
2383 if ( (L2OutValid_SP[i] == 1'b0) && (L2OutValid_S[i] == 1'b1) ) begin
2384 L2OutValid_SN[i] = 1'b1;
2385 L2OutReady_S[i] = 1'b1;
2386 L2OutEn_S[i] = 1'b1;
2387 end
2388 end
2389 end
2390
2391 /*
2392 * L1 drop buffer
2393 *
2394 * Used in case of multi, prot and prefetch hits in the L1 TLB.
2395 */
2396 always_ff @(posedge Clk_CI) begin : L1_DROP_BUF
2397 if (Rst_RBI == 0) begin
2398 L1DropProt_DP[i] <= 1'b0;
2399 L1DropMulti_DP[i] <= 1'b0;
2400 L1DropRwType_DP[i] <= 1'b0;
2401 L1DropUser_DP[i] <= 'b0;
2402 L1DropId_DP[i] <= 'b0;
2403 L1DropLen_DP[i] <= 'b0;
2404 L1DropAddr_DP[i] <= 'b0;
2405 end else if (L1DropEn_S[i] == 1'b1) begin
2406 L1DropProt_DP[i] <= L1OutProt_D[i] ;
2407 L1DropMulti_DP[i] <= L1OutMulti_D[i] ;
2408 L1DropRwType_DP[i] <= L1OutRwType_D[i];
2409 L1DropUser_DP[i] <= L1OutUser_D[i] ;
2410 L1DropId_DP[i] <= L1OutId_D[i] ;
2411 L1DropLen_DP[i] <= L1OutLen_D[i] ;
2412 L1DropAddr_DP[i] <= L1OutAddr_D[i] ;
2413 end
2414 end // always_ff @ (posedge Clk_CI)
2415
2416 /*
2417 * L2 input buffer
2418 *
2419 * Make sure there are no combinational paths between L1 TLB/inputs and L2 TLB.
2420 */
2421 always_ff @(posedge Clk_CI) begin : L2_IN_BUF
2422 if (Rst_RBI == 0) begin
2423 L2InRwType_DP[i] <= 1'b0;
2424 L2InUser_DP[i] <= 'b0;
2425 L2InId_DP[i] <= 'b0;
2426 L2InLen_DP[i] <= 'b0;
2427 L2InAddr_DP[i] <= 'b0;
2428 end else if (L2InEn_S[i] == 1'b1) begin
2429 L2InRwType_DP[i] <= L1OutRwType_D[i];
2430 L2InUser_DP[i] <= L1OutUser_D[i] ;
2431 L2InId_DP[i] <= L1OutId_D[i] ;
2432 L2InLen_DP[i] <= L1OutLen_D[i] ;
2433 L2InAddr_DP[i] <= L1OutAddr_D[i] ;
2434 end
2435 end // always_ff @ (posedge Clk_CI)
2436
2437 l2_tlb
2438 #(
2439 .AXI_S_ADDR_WIDTH ( AXI_S_ADDR_WIDTH ),
2440 .AXI_M_ADDR_WIDTH ( AXI_M_ADDR_WIDTH ),
2441 .AXI_LITE_DATA_WIDTH ( AXI_LITE_DATA_WIDTH ),
2442 .AXI_LITE_ADDR_WIDTH ( AXI_LITE_ADDR_WIDTH ),
2443 .N_SETS ( `RAB_L2_N_SETS ),
2444 .N_OFFSETS ( `RAB_L2_N_SET_ENTRIES/2/`RAB_L2_N_PAR_VA_RAMS ),
2445 .N_PAR_VA_RAMS ( `RAB_L2_N_PAR_VA_RAMS ),
2446 .HIT_OFFSET_STORE_WIDTH ( log2(`RAB_L2_N_SET_ENTRIES/2/`RAB_L2_N_PAR_VA_RAMS) )
2447 )
2448 u_l2_tlb
2449 (
2450 .clk_i ( Clk_CI ),
2451 .rst_ni ( Rst_RBI ),
2452
2453 // Config inputs
2454 .we_i ( L2CfgWE_S[i] ),
2455 .waddr_i ( L2CfgWAddr_D[i] ),
2456 .wdata_i ( L2CfgWData_D[i] ),
2457
2458 // Request input
2459 .start_i ( L2InEn_S[i] ),
2460 .busy_o ( L2Busy_S[i] ),
2461 .rw_type_i ( L2InRwType_DP[i] ),
2462 .in_addr_i ( L2InAddr_DP[i] ),
2463
2464 // Response output
2465 .out_ready_i ( L2OutReady_S[i] ),
2466 .out_valid_o ( L2OutValid_S[i] ),
2467 .hit_o ( L2OutHit_SN[i] ),
2468 .miss_o ( L2OutMiss_SN[i] ),
2469 .prot_o ( L2OutProt_SN[i] ),
2470 .multi_o ( L2OutMulti_SN[i] ),
2471 .cache_coherent_o ( L2OutCC_SN[i] ),
2472 .out_addr_o ( L2OutAddr_DN[i] )
2473 );
2474
2475 /*
2476 * L2 output buffer
2477 *
2478 * Make sure there are no combinational paths between L1 TLB/inputs and L2 TLB.
2479 */
2480 always_ff @(posedge Clk_CI) begin : L2_OUT_BUF
2481 if (Rst_RBI == 0) begin
2482 L2OutRwType_DP[i] <= 1'b0;
2483 L2OutUser_DP[i] <= 'b0;
2484 L2OutLen_DP[i] <= 'b0;
2485 L2OutId_DP[i] <= 'b0;
2486 L2OutInAddr_DP[i] <= 'b0;
2487
2488 L2OutHit_SP[i] <= 1'b0;
2489 L2OutMiss_SP[i] <= 1'b0;
2490 L2OutProt_SP[i] <= 1'b0;
2491 L2OutMulti_SP[i] <= 1'b0;
2492 L2OutCC_SP[i] <= 1'b0;
2493 L2OutAddr_DP[i] <= 'b0;
2494 end else if (L2OutEn_S[i] == 1'b1) begin
2495 L2OutRwType_DP[i] <= L2InRwType_DP[i];
2496 L2OutUser_DP[i] <= L2InUser_DP[i] ;
2497 L2OutLen_DP[i] <= L2InLen_DP[i] ;
2498 L2OutId_DP[i] <= L2InId_DP[i] ;
2499 L2OutInAddr_DP[i] <= L2InAddr_DP[i] ;
2500
2501 L2OutHit_SP[i] <= L2OutHit_SN[i] ;
2502 L2OutMiss_SP[i] <= L2OutMiss_SN[i] ;
2503 L2OutProt_SP[i] <= L2OutProt_SN[i] ;
2504 L2OutMulti_SP[i] <= L2OutMulti_SN[i];
2505 L2OutCC_SP[i] <= L2OutCC_SN[i] ;
2506 L2OutAddr_DP[i] <= L2OutAddr_DN[i] ;
2507 end
2508 end // always_ff @ (posedge Clk_CI)
2509
2510 always_ff @(posedge Clk_CI) begin : BUF_VALID
2511 if (Rst_RBI == 0) begin
2512 L1DropValid_SP[i] = 1'b0;
2513 L2OutValid_SP[i] = 1'b0;
2514 end else begin
2515 L1DropValid_SP[i] = L1DropValid_SN[i];
2516 L2OutValid_SP[i] = L2OutValid_SN[i];
2517 end
2518 end
2519
2520 always_comb begin : BUF_TO_PREFETCH
2521 // L1 Drop Buf
2522 if (L1DropUser_DP[i] == {AXI_USER_WIDTH{1'b1}})
2523 L1DropPrefetch_S[i] = 1'b1;
2524 else
2525 L1DropPrefetch_S[i] = 1'b0;
2526
2527 // L2 Out Buf
2528 if (L2OutUser_DP[i] == {AXI_USER_WIDTH{1'b1}})
2529 L2OutPrefetch_S[i] = 1'b1;
2530 else
2531 L2OutPrefetch_S[i] = 1'b0;
2532 end
2533
2534 assign l2_cache_coherent[i] = L2OutCC_SP[i];
2535 assign int_miss[i] = L2Miss_S[i];
2536
2537 end else begin : L2_TLB_STUB // if (ENABLE_L2TLB[i] == 1)
2538
2539 assign l1_ar_drop[i] = int_rtrans_drop[i];
2540 assign l1_r_drop[i] = int_rtrans_drop[i];
2541 assign l1_xw_drop[i] = int_wtrans_drop[i];
2542
2543 assign l1_ar_save[i] = 1'b0;
2544 assign l1_xw_save[i] = 1'b0;
2545 assign l2_xw_accept[i] = 1'b0;
2546 assign l2_xr_drop[i] = 1'b0;
2547 assign l2_xw_drop[i] = 1'b0;
2548
2549 assign l2_ar_addr[i] = 'b0;
2550 assign l2_aw_addr[i] = 'b0;
2551
2552 assign l1_id_drop[i] = int_wtrans_drop[i] ? int_awid[i] :
2553 int_rtrans_drop[i] ? int_arid[i] :
2554 '0;
2555 assign l1_len_drop[i] = int_wtrans_drop[i] ? int_awlen[i] :
2556 int_rtrans_drop[i] ? int_arlen[i] :
2557 '0;
2558 assign l1_prefetch_drop[i] = rab_prefetch[i];
2559 assign l1_hit_drop[i] = ~rab_miss[i];
2560
2561 assign lx_id_drop[i] = int_wtrans_drop[i] ? int_awid[i] :
2562 int_rtrans_drop[i] ? int_arid[i] :
2563 '0;
2564 assign lx_len_drop[i] = int_wtrans_drop[i] ? int_awlen[i] :
2565 int_rtrans_drop[i] ? int_arlen[i] :
2566 '0;
2567 assign lx_prefetch_drop[i] = rab_prefetch[i];
2568 assign lx_hit_drop[i] = ~rab_miss[i];
2569
2570 assign l2_cache_coherent[i] = 1'b0;
2571
2572 assign int_miss[i] = rab_miss[i];
2573 assign int_prot[i] = rab_prot[i];
2574 assign int_multi[i] = rab_multi[i];
2575
2576 // unused signals
2577 assign L2Miss_S[i] = 1'b0;
2578
2579 assign L1OutRwType_D[i] = 1'b0;
2580 assign L1OutProt_D[i] = 1'b0;
2581 assign L1OutMulti_D[i] = 1'b0;
2582
2583 assign L1DropRwType_DP[i] = 1'b0;
2584 assign L1DropUser_DP[i] = 'b0;
2585 assign L1DropId_DP[i] = 'b0;
2586 assign L1DropLen_DP[i] = 'b0;
2587 assign L1DropAddr_DP[i] = 'b0;
2588 assign L1DropProt_DP[i] = 1'b0;
2589 assign L1DropMulti_DP[i] = 1'b0;
2590
2591 assign L1DropEn_S[i] = 1'b0;
2592 assign L1DropPrefetch_S[i] = 1'b0;
2593 assign L1DropValid_SN[i] = 1'b0;
2594 assign L1DropValid_SP[i] = 1'b0;
2595
2596 assign L2InRwType_DP[i] = 1'b0;
2597 assign L2InUser_DP[i] = 'b0;
2598 assign L2InId_DP[i] = 'b0;
2599 assign L2InLen_DP[i] = 'b0;
2600 assign L2InAddr_DP[i] = 'b0;
2601
2602 assign L2InEn_S[i] = 1'b0;
2603
2604 assign L2OutHit_SN[i] = 1'b0;
2605 assign L2OutMiss_SN[i] = 1'b0;
2606 assign L2OutProt_SN[i] = 1'b0;
2607 assign L2OutMulti_SN[i] = 1'b0;
2608 assign L2OutCC_SN[i] = 1'b0;
2609 assign L2OutAddr_DN[i] = 'b0;
2610
2611 assign L2OutRwType_DP[i] = 1'b0;
2612 assign L2OutUser_DP[i] = 'b0;
2613 assign L2OutId_DP[i] = 'b0;
2614 assign L2OutLen_DP[i] = 'b0;
2615 assign L2OutInAddr_DP[i] = 'b0;
2616 assign L2OutHit_SP[i] = 1'b0;
2617 assign L2OutMiss_SP[i] = 1'b0;
2618 assign L2OutProt_SP[i] = 1'b0;
2619 assign L2OutMulti_SP[i] = 1'b0;
2620 assign L2OutCC_SP[i] = 1'b0;
2621 assign L2OutAddr_DP[i] = 'b0;
2622
2623 assign L2OutEn_S[i] = 1'b0;
2624 assign L2OutPrefetch_S[i] = 1'b0;
2625 assign L2Busy_S[i] = 1'b0;
2626 assign L2OutValid_S[i] = 1'b0;
2627 assign L2OutValid_SN[i] = 1'b0;
2628 assign L2OutValid_SP[i] = 1'b0;
2629 assign L2OutReady_S[i] = 1'b0;
2630
2631 end // !`ifdef ENABLE_L2TLB
2632 end // for (i = 0; i < N_PORTS; i++)
2633 endgenerate
2634
2635 // }}}
2636 """
2637 # endmodule
2638 #
2639 #
2640 # // vim: ts=2 sw=2 sts=2 et nosmartindent autoindent foldmethod=marker
2641 #
2642 #