1 # this file has been generated by sv2nmigen
3 from nmigen
import Signal
, Module
, Const
, Cat
, Elaboratable
6 class axi_rab_top(Elaboratable
):
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
160 def elaborate(self
, platform
=None):
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.
175 # // --=========================================================================--
177 # // █████╗ ██╗ ██╗██╗ ██████╗ █████╗ ██████╗ ████████╗ ██████╗ ██████╗
178 # // ██╔══██╗╚██╗██╔╝██║ ██╔══██╗██╔══██╗██╔══██╗ ╚══██╔══╝██╔═══██╗██╔══██╗
179 # // ███████║ ╚███╔╝ ██║ ██████╔╝███████║██████╔╝ ██║ ██║ ██║██████╔╝
180 # // ██╔══██║ ██╔██╗ ██║ ██╔══██╗██╔══██║██╔══██╗ ██║ ██║ ██║██╔═══╝
181 # // ██║ ██║██╔╝ ██╗██║ ██║ ██║██║ ██║██████╔╝ ██║ ╚██████╔╝██║
182 # // ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═════╝ ╚═╝
184 # // --=========================================================================--
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.
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.
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.
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.
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>
216 # //`include "pulp_soc_defines.sv"
218 # ////import CfMath::log2;
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
241 # input logic Clk_CI, // This clock may be gated.
242 # input logic NonGatedClk_CI,
243 # input logic Rst_RBI,
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
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
408 # output logic [1:0] s_axi4lite_bresp,
409 # output logic s_axi4lite_bvalid,
410 # input logic s_axi4lite_bready,
412 # input logic [AXI_LITE_ADDR_WIDTH-1:0] s_axi4lite_araddr,
413 # input logic s_axi4lite_arvalid,
414 # output logic s_axi4lite_arready,
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,
423 # //`ifdef RAB_AX_LOG_EN
424 # // BramPort.Slave ArBram_PS,
425 # // BramPort.Slave AwBram_PS,
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,
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,
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
459 // ███████╗██╗ ██████╗ ███╗ ██╗ █████╗ ██╗ ███████╗
460 // ██╔════╝██║██╔════╝ ████╗ ██║██╔══██╗██║ ██╔════╝
461 // ███████╗██║██║ ███╗██╔██╗ ██║███████║██║ ███████╗
462 // ╚════██║██║██║ ██║██║╚██╗██║██╔══██║██║ ╚════██║
463 // ███████║██║╚██████╔╝██║ ╚████║██║ ██║███████╗███████║
464 // ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝╚══════╝╚══════╝
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;
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;
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;
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;
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;
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;
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;
533 logic [N_PORTS-1:0] w_master_select;
535 // Internal master0 AXI4 lines. These connect the first master port to the
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;
542 logic [N_PORTS-1:0] int_m0_wvalid;
543 logic [N_PORTS-1:0] int_m0_wready;
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;
551 logic [N_PORTS-1:0] int_m0_arvalid;
552 logic [N_PORTS-1:0] int_m0_arready;
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;
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;
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;
580 // Internal master1 AXI4 lines. These connect the second master port to the
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;
587 logic [N_PORTS-1:0] int_m1_wvalid;
588 logic [N_PORTS-1:0] int_m1_wready;
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;
596 logic [N_PORTS-1:0] int_m1_arvalid;
597 logic [N_PORTS-1:0] int_m1_arready;
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;
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;
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;
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;
630 // Signals used to support L2 TLB
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;
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;
648 logic [N_PORTS-1:0] L1DropValid_SN, L1DropValid_SP;
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;
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;
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;
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;
678 logic [N_PORTS-1:0] L2Busy_S;
679 logic [N_PORTS-1:0] L2OutValid_S;
681 logic [N_PORTS-1:0] L2Miss_S;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
754 logic [N_PORTS-1:0] b_drop;
755 logic [N_PORTS-1:0] b_done;
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;
760 logic [N_PORTS-1:0] l2_cache_coherent;
761 logic [N_PORTS-1:0] l2_master_select;
763 logic [N_PORTS-1:0] aw_in_stall;
764 logic [N_PORTS-1:0] aw_out_stall;
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;
777 // Local parameters {{{
779 // Enable L2 for select ports
780 localparam integer ENABLE_L2TLB[N_PORTS-1:0] = `EN_L2TLB_ARRAY;
783 localparam integer HUM_BUFFER_DEPTH = (N_L2_SET_ENTRIES/2/`RAB_L2_N_PAR_VA_RAMS)+13;
787 // Derive `master_select` from cache coherency flag. {{{
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;
793 assign int_wmaster_select = '0;
794 assign int_rmaster_select = '0;
795 assign l2_master_select = '0;
800 // ██████╗ ██╗ ██╗███████╗ ██╗ ███████╗███████╗███╗ ██╗██████╗
801 // ██╔══██╗██║ ██║██╔════╝ ██║ ██╔════╝██╔════╝████╗ ██║██╔══██╗
802 // ██████╔╝██║ ██║█████╗ ████████╗ ███████╗█████╗ ██╔██╗ ██║██║ ██║
803 // ██╔══██╗██║ ██║██╔══╝ ██╔═██╔═╝ ╚════██║██╔══╝ ██║╚██╗██║██║ ██║
804 // ██████╔╝╚██████╔╝██║ ██████║ ███████║███████╗██║ ╚████║██████╔╝
805 // ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═══╝╚═════╝
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;
810 generate for (i = 0; i < N_PORTS; i++) begin : BUF_AND_SEND
812 // Write Address channel (aw) {{{
814 * write address channel (aw)
816 * ██╗ ██╗██████╗ ██╗████████╗███████╗ █████╗ ██████╗ ██████╗ ██████╗
817 * ██║ ██║██╔══██╗██║╚══██╔══╝██╔════╝ ██╔══██╗██╔══██╗██╔══██╗██╔══██╗
818 * ██║ █╗ ██║██████╔╝██║ ██║ █████╗ ███████║██║ ██║██║ ██║██████╔╝
819 * ██║███╗██║██╔══██╗██║ ██║ ██╔══╝ ██╔══██║██║ ██║██║ ██║██╔══██╗
820 * ╚███╔███╔╝██║ ██║██║ ██║ ███████╗ ██║ ██║██████╔╝██████╔╝██║ ██║
821 * ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═╝ ╚═╝
827 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
828 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
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] )
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] )
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] ),
905 .m_axi4_awregion ( m0_axi4_awregion[i] ),
906 .m_axi4_awqos ( m0_axi4_awqos[i] ),
907 .m_axi4_awuser ( m0_axi4_awuser[i] )
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);
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;
919 m0_axi4_awcache[i] = 4'b1111;
922 m0_axi4_awcache[i] = 4'b0011;
926 assign m0_axi4_awcache[i] = 4'b0011;
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] )
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] ),
972 .m_axi4_awregion ( m1_axi4_awregion[i] ),
973 .m_axi4_awqos ( m1_axi4_awqos[i] ),
974 .m_axi4_awuser ( m1_axi4_awuser[i] )
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);
982 if (m1_write_is_burst[i]) begin
983 m1_axi4_awcache[i] = 4'b1011;
985 m1_axi4_awcache[i] = 4'b1111;
989 assign m1_axi4_awcache[i] = 4'b0011;
994 // Write Data channel (w) {{{
996 * write data channel (w)
998 * ██╗ ██╗██████╗ ██╗████████╗███████╗ ██████╗ █████╗ ████████╗ █████╗
999 * ██║ ██║██╔══██╗██║╚══██╔══╝██╔════╝ ██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗
1000 * ██║ █╗ ██║██████╔╝██║ ██║ █████╗ ██║ ██║███████║ ██║ ███████║
1001 * ██║███╗██║██╔══██╗██║ ██║ ██╔══╝ ██║ ██║██╔══██║ ██║ ██╔══██║
1002 * ╚███╔███╔╝██║ ██║██║ ██║ ███████╗ ██████╔╝██║ ██║ ██║ ██║ ██║
1003 * ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
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 )
1016 .axi4_aclk ( Clk_CI ),
1017 .axi4_arstn ( Rst_RBI ),
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] ),
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] ),
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
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] ),
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] )
1069 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1070 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
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] )
1092 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1093 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
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] )
1115 * Multiplexer to switch between the two output master ports on the write data (w) channel
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];
1124 int_m0_wvalid[i] = 1'b0;
1125 int_m1_wvalid[i] = int_wvalid[i];
1126 int_wready[i] = int_m1_wready[i];
1132 // Write Response channel (b) {{{
1134 * write response channel (b)
1136 * ██╗ ██╗██████╗ ██╗████████╗███████╗ ██████╗ ███████╗███████╗██████╗
1137 * ██║ ██║██╔══██╗██║╚══██╔══╝██╔════╝ ██╔══██╗██╔════╝██╔════╝██╔══██╗
1138 * ██║ █╗ ██║██████╔╝██║ ██║ █████╗ ██████╔╝█████╗ ███████╗██████╔╝
1139 * ██║███╗██║██╔══██╗██║ ██║ ██╔══╝ ██╔══██╗██╔══╝ ╚════██║██╔═══╝
1140 * ╚███╔███╔╝██║ ██║██║ ██║ ███████╗ ██║ ██║███████╗███████║██║
1141 * ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝
1146 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1147 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
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] )
1167 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1168 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
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] )
1188 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1189 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
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] )
1213 * Multiplexer to switch between the two output master ports on the write response (b) channel
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];
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];
1227 int_m0_bready[i] = int_bready[i];
1228 int_m1_bready[i] = 1'b0;
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];
1239 // Read Address channel (ar) {{{
1241 * read address channel (ar)
1243 * ██████╗ ███████╗ █████╗ ██████╗ █████╗ ██████╗ ██████╗ ██████╗
1244 * ██╔══██╗██╔════╝██╔══██╗██╔══██╗ ██╔══██╗██╔══██╗██╔══██╗██╔══██╗
1245 * ██████╔╝█████╗ ███████║██║ ██║ ███████║██║ ██║██║ ██║██████╔╝
1246 * ██╔══██╗██╔══╝ ██╔══██║██║ ██║ ██╔══██║██║ ██║██║ ██║██╔══██╗
1247 * ██║ ██║███████╗██║ ██║██████╔╝ ██║ ██║██████╔╝██████╔╝██║ ██║
1248 * ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═╝ ╚═╝
1253 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1254 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
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] )
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] )
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] )
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);
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;
1337 m0_axi4_arcache[i] = 4'b1111;
1340 m0_axi4_arcache[i] = 4'b0011;
1344 assign m0_axi4_arcache[i] = 4'b0011;
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] )
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] )
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);
1396 if (m1_read_is_burst[i]) begin
1397 m1_axi4_arcache[i] = 4'b1011;
1399 m1_axi4_arcache[i] = 4'b1111;
1403 assign m1_axi4_arcache[i] = 4'b0011;
1408 // Read Response channel (r) {{{
1410 * read response channel (r)
1412 * ██████╗ ███████╗ █████╗ ██████╗ ██████╗ ███████╗███████╗██████╗
1413 * ██╔══██╗██╔════╝██╔══██╗██╔══██╗ ██╔══██╗██╔════╝██╔════╝██╔══██╗
1414 * ██████╔╝█████╗ ███████║██║ ██║ ██████╔╝█████╗ ███████╗██████╔╝
1415 * ██╔══██╗██╔══╝ ██╔══██║██║ ██║ ██╔══██╗██╔══╝ ╚════██║██╔═══╝
1416 * ██║ ██║███████╗██║ ██║██████╔╝ ██║ ██║███████╗███████║██║
1417 * ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝
1422 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1423 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1424 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
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] )
1448 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1449 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1450 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
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] )
1474 .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
1475 .AXI_ID_WIDTH ( AXI_ID_WIDTH ),
1476 .AXI_USER_WIDTH ( AXI_USER_WIDTH )
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] )
1505 * Multiplexer to switch between the two output master ports on the read response(r) channel
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.
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).
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.
1523 always_ff @(posedge Clk_CI) begin
1524 if (Rst_RBI == 0) begin
1525 RRespSel_SP[i] <= 1'b0;
1527 RRespSel_SP[i] <= RRespSel_SN[i];
1532 always_comb begin : RRespMuxFsm
1533 RRespMuxCtrl_SN[i] = RRespMuxCtrl_SP[i];
1534 RRespSel_SN[i] = RRespSel_SP[i];
1536 RRespBurst_S[i] = 1'b0;
1537 RRespSelIm_S[i] = 1'b0;
1539 unique case (RRespMuxCtrl_SP[i])
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;
1548 // bursts - they also start immediately
1549 else if (int_m1_rvalid[i] || int_m0_rvalid[i]) begin
1550 RRespMuxCtrl_SN[i] = BUSY;
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;
1560 RRespSel_SN[i] = 1'b0;
1561 RRespSelIm_S[i] = 1'b0;
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;
1574 RRespMuxCtrl_SN[i] = IDLE;
1581 always_ff @(posedge Clk_CI) begin
1582 if (Rst_RBI == 0) begin
1583 RRespMuxCtrl_SP[i] <= IDLE;
1585 RRespMuxCtrl_SP[i] <= RRespMuxCtrl_SN[i];
1589 // Actual multiplexer
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];
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];
1602 int_m0_rready[i] = int_rready[i];
1603 int_m1_rready[i] = 1'b0;
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];
1618 endgenerate // BUF & SEND }}}
1622 `ifdef RAB_AX_LOG_EN
1625 .AXI_ID_BITW ( AXI_ID_WIDTH ),
1626 .AXI_ADDR_BITW ( AXI_S_ADDR_WIDTH ),
1627 .NUM_LOG_ENTRIES ( `RAB_AX_LOG_ENTRIES )
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 )
1648 .AXI_ID_BITW ( AXI_ID_WIDTH ),
1649 .AXI_ADDR_BITW ( AXI_S_ADDR_WIDTH ),
1650 .NUM_LOG_ENTRIES ( `RAB_AX_LOG_ENTRIES )
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 )
1673 // ██████╗ █████╗ ██████╗ ██████╗ ██████╗ ██████╗ ███████╗
1674 // ██╔══██╗██╔══██╗██╔══██╗ ██╔════╝██╔═══██╗██╔══██╗██╔════╝
1675 // ██████╔╝███████║██████╔╝ ██║ ██║ ██║██████╔╝█████╗
1676 // ██╔══██╗██╔══██║██╔══██╗ ██║ ██║ ██║██╔══██╗██╔══╝
1677 // ██║ ██║██║ ██║██████╔╝ ╚██████╗╚██████╔╝██║ ██║███████╗
1678 // ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
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
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.
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 )
1708 .Rst_RBI ( Rst_RBI ),
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 ),
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 ),
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 ),
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 ),
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 ),
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 ),
1778 // L2 config outputs
1779 .wdata_l2_o ( L2CfgWData_D ),
1780 .waddr_l2_o ( L2CfgWAddr_D ),
1781 .wren_l2_o ( L2CfgWE_S )
1787 // █████╗ ██╗ ██╗ ███████╗██████╗ ██╗ ██╗████████╗
1788 // ██╔══██╗╚██╗██╔╝ ██╔════╝██╔══██╗██║ ██║╚══██╔══╝
1789 // ███████║ ╚███╔╝ ███████╗██████╔╝██║ ██║ ██║
1790 // ██╔══██║ ██╔██╗ ╚════██║██╔═══╝ ██║ ██║ ██║
1791 // ██║ ██║██╔╝ ██╗ ███████║██║ ███████╗██║ ██║
1792 // ╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝╚═╝ ╚══════╝╚═╝ ╚═╝
1795 * Multiplex the two output master ports of the Read Address and Write Address (AR/AW) channels.
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.
1801 generate for (i = 0; i < N_PORTS; i++) begin : AX_SPLIT
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.
1807 always_comb begin : AW_L1_SPLIT
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;
1817 l1_mx_aw_done[i] = 1'b0;
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;
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];
1830 int_m1_awvalid[i] = int_awvalid[i];
1831 int_awready[i] = int_m1_awready[i];
1834 l1_m0_aw_accept[i] = 1'b1;
1835 l1_mx_aw_done[i] = l1_m0_aw_done[i];
1837 int_m0_awvalid[i] = int_awvalid[i];
1838 int_awready[i] = int_m0_awready[i];
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];
1846 int_m0_awvalid[i] = int_awvalid[i];
1847 int_awready[i] = l1_m0_aw_done[i];
1849 // save on both masters
1850 end else if (l1_aw_save[i]) begin
1852 l1_m0_aw_save[i] = ~l1_m0_aw_done_SP[i];
1853 l1_m1_aw_save[i] = ~l1_m1_aw_done_SP[i];
1856 l1_mx_aw_done[i] = l1_m0_aw_done_SP[i] & l1_m1_aw_done_SP[i];
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];
1864 // signal back to handshake splitter
1865 assign l1_aw_done[i] = l1_mx_aw_done[i];
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;
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];
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.
1884 always_comb begin : AW_L2_SPLIT
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;
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];
1898 l2_m0_aw_accept[i] = ~l2_m0_aw_done_SP[i];
1899 l2_m1_aw_drop[i] = ~l2_m1_aw_done_SP[i];
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;
1909 l2_mx_aw_done[i] = l2_m0_aw_done_SP[i] & l2_m1_aw_done_SP[i];
1911 l2_aw_done[i] = l2_mx_aw_done[i];
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;
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];
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.
1931 always_comb begin : AR_L1_SPLIT
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;
1941 l1_mx_ar_done[i] = 1'b0;
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;
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];
1954 int_m1_arvalid[i] = int_arvalid[i];
1955 int_arready[i] = int_m1_arready[i];
1958 l1_m0_ar_accept[i] = 1'b1;
1959 l1_mx_ar_done[i] = l1_m0_ar_done[i];
1961 int_m0_arvalid[i] = int_arvalid[i];
1962 int_arready[i] = int_m0_arready[i];
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];
1970 int_m0_arvalid[i] = int_arvalid[i];
1971 int_arready[i] = l1_m0_ar_done[i];
1973 // save on both masters
1974 end else if (l1_ar_save[i]) begin
1976 l1_m0_ar_save[i] = ~l1_m0_ar_done_SP[i];
1977 l1_m1_ar_save[i] = ~l1_m1_ar_done_SP[i];
1980 l1_mx_ar_done[i] = l1_m0_ar_done_SP[i] & l1_m1_ar_done_SP[i];
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];
1988 // signal back to handshake splitter
1989 assign l1_ar_done[i] = l1_mx_ar_done[i];
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;
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];
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.
2008 always_comb begin : AR_L2_SPLIT
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;
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];
2022 l2_m0_ar_accept[i] = ~l2_m0_ar_done_SP[i];
2023 l2_m1_ar_drop[i] = ~l2_m1_ar_done_SP[i];
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;
2033 l2_mx_ar_done[i] = l2_m0_ar_done_SP[i] & l2_m1_ar_done_SP[i];
2035 l2_ar_done[i] = l2_mx_ar_done[i];
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;
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];
2052 endgenerate // AX_SPLIT
2056 // HANDSHAKE SPLITS {{{
2057 // ██╗ ██╗███████╗ ███████╗██████╗ ██╗ ██╗████████╗
2058 // ██║ ██║██╔════╝ ██╔════╝██╔══██╗██║ ██║╚══██╔══╝
2059 // ███████║███████╗ ███████╗██████╔╝██║ ██║ ██║
2060 // ██╔══██║╚════██║ ╚════██║██╔═══╝ ██║ ██║ ██║
2061 // ██║ ██║███████║ ███████║██║ ███████╗██║ ██║
2062 // ╚═╝ ╚═╝╚══════╝ ╚══════╝╚═╝ ╚══════╝╚═╝ ╚═╝
2065 * We need to perform combined handshakes with multiple AXI modules
2066 * upon transactions drops, accepts, saves etc. from two TLBs.
2068 generate for (i = 0; i < N_PORTS; i++) begin : HANDSHAKE_SPLIT
2070 assign l1_xw_accept[i] = int_wtrans_accept[i] & ~aw_out_stall[i];
2071 assign int_wtrans_sent[i] = l1_xw_done[i];
2073 assign l1_ar_accept[i] = int_rtrans_accept[i];
2074 assign int_rtrans_sent[i] = l1_ar_done[i];
2077 * L1 AW sender + W buffer handshake split
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];
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];
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];
2090 assign l1_xw_done[i] = l1_aw_done_SP[i] & l1_w_done_SP[i];
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;
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];
2105 if (ENABLE_L2TLB[i] == 1) begin : L2_HS_SPLIT
2108 * L1 AR sender + R sender handshake split
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.
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;
2119 * L2 AW sender + W buffer handshake split
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];
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];
2129 assign l2_xw_done[i] = l2_aw_done_SP[i] & l2_w_done_SP[i];
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;
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];
2145 * L2 AR + R sender handshake split
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];
2151 // backward - make sure to always clear L2_XR_HS_SPLIT
2153 if (l2_xr_drop[i]) begin
2154 l2_xr_done[i] = l2_ar_done_SP[i] & l2_r_done_SP[i];
2156 l2_xr_done[i] = l2_ar_done_SP[i];
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;
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];
2173 end else begin // if (ENABLE_L2TLB[i] == 1)
2175 assign lx_r_drop[i] = l1_r_drop[i];
2176 assign l1_r_done[i] = lx_r_done[i];
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;
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;
2194 end // if (ENABLE_L2TLB[i] == 1)
2196 end // HANDSHAKE_SPLIT
2197 endgenerate // HANDSHAKE_SPLIT
2202 // ██╗ ██████╗ ████████╗██╗ ██████╗
2203 // ██║ ╚════██╗ ╚══██╔══╝██║ ██╔══██╗
2204 // ██║ █████╔╝ ██║ ██║ ██████╔╝
2205 // ██║ ██╔═══╝ ██║ ██║ ██╔══██╗
2206 // ███████╗███████╗ ██║ ███████╗██████╔╝
2207 // ╚══════╝╚══════╝ ╚═╝ ╚══════╝╚═════╝
2212 * The L2 TLB translates addresses upon misses in the L1 TLB (rab_core).
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.
2218 generate for (i = 0; i < N_PORTS; i++) begin : L2_TLB
2219 if (ENABLE_L2TLB[i] == 1) begin : L2_TLB
2222 * L1 output selector
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];
2229 * L1 output control + L1_DROP_BUF, L2_IN_BUF management
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.
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.
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
2243 always_comb begin : L1_DROP_SAVE
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;
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
2255 L1DropEn_S[i] = 1'b0;
2258 if ( rab_prot[i] | rab_multi[i] | rab_prefetch[i] ) begin
2260 l1_ar_drop[i] = int_rtrans_drop[i] & ~L1DropValid_SP[i];
2261 l1_xw_drop[i] = int_wtrans_drop[i] & ~L1DropValid_SP[i];
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]);
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];
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]);
2279 * L2 output control + L2_OUT_BUF management + R/B sender control + W buffer control
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.
2286 * L1 AW/W drop requests are managed by L1_DROP_SAVE.
2288 always_comb begin : L2_ACCEPT_DROP_SAVE
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;
2297 l1_r_drop[i] = 1'b0;
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;
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;
2310 int_multi[i] = 1'b0;
2313 if (L2OutValid_SP[i] == 1'b0) begin
2315 // Drop L1 from R senders
2316 if (L1DropValid_SP[i] == 1'b1) begin
2318 // Only perform the R sender drop here.
2319 if (~L1DropRwType_DP[i]) begin
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
2327 // Invalidate L1_DROP_BUF upon handshake
2328 if ( l1_r_drop[i] & l1_r_done[i] ) begin
2330 L1DropValid_SN[i] = 1'b0;
2331 int_prot[i] = L1DropProt_DP[i];
2332 int_multi[i] = L1DropMulti_DP[i];
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];
2343 end else begin // L2_OUT_BUF has valid data
2345 if ( L2OutHit_SP[i] & ~(L2OutPrefetch_S[i] | L2OutProt_SP[i] | L2OutMulti_SP[i]) ) begin
2347 l2_ar_addr[i] = L2OutAddr_DP[i];
2348 l2_aw_addr[i] = L2OutAddr_DP[i];
2350 l2_ar_accept[i] = L2OutRwType_DP[i] ? 1'b0 : 1'b1;
2351 l2_xw_accept[i] = L2OutRwType_DP[i] ? 1'b1 : 1'b0;
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]) );
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];
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;
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
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];
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;
2394 * Used in case of multi, prot and prefetch hits in the L1 TLB.
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] ;
2414 end // always_ff @ (posedge Clk_CI)
2419 * Make sure there are no combinational paths between L1 TLB/inputs and L2 TLB.
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] ;
2435 end // always_ff @ (posedge Clk_CI)
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) )
2451 .rst_ni ( Rst_RBI ),
2454 .we_i ( L2CfgWE_S[i] ),
2455 .waddr_i ( L2CfgWAddr_D[i] ),
2456 .wdata_i ( L2CfgWData_D[i] ),
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] ),
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] )
2478 * Make sure there are no combinational paths between L1 TLB/inputs and L2 TLB.
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;
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] ;
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] ;
2508 end // always_ff @ (posedge Clk_CI)
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;
2515 L1DropValid_SP[i] = L1DropValid_SN[i];
2516 L2OutValid_SP[i] = L2OutValid_SN[i];
2520 always_comb begin : BUF_TO_PREFETCH
2522 if (L1DropUser_DP[i] == {AXI_USER_WIDTH{1'b1}})
2523 L1DropPrefetch_S[i] = 1'b1;
2525 L1DropPrefetch_S[i] = 1'b0;
2528 if (L2OutUser_DP[i] == {AXI_USER_WIDTH{1'b1}})
2529 L2OutPrefetch_S[i] = 1'b1;
2531 L2OutPrefetch_S[i] = 1'b0;
2534 assign l2_cache_coherent[i] = L2OutCC_SP[i];
2535 assign int_miss[i] = L2Miss_S[i];
2537 end else begin : L2_TLB_STUB // if (ENABLE_L2TLB[i] == 1)
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];
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;
2549 assign l2_ar_addr[i] = 'b0;
2550 assign l2_aw_addr[i] = 'b0;
2552 assign l1_id_drop[i] = int_wtrans_drop[i] ? int_awid[i] :
2553 int_rtrans_drop[i] ? int_arid[i] :
2555 assign l1_len_drop[i] = int_wtrans_drop[i] ? int_awlen[i] :
2556 int_rtrans_drop[i] ? int_arlen[i] :
2558 assign l1_prefetch_drop[i] = rab_prefetch[i];
2559 assign l1_hit_drop[i] = ~rab_miss[i];
2561 assign lx_id_drop[i] = int_wtrans_drop[i] ? int_awid[i] :
2562 int_rtrans_drop[i] ? int_arid[i] :
2564 assign lx_len_drop[i] = int_wtrans_drop[i] ? int_awlen[i] :
2565 int_rtrans_drop[i] ? int_arlen[i] :
2567 assign lx_prefetch_drop[i] = rab_prefetch[i];
2568 assign lx_hit_drop[i] = ~rab_miss[i];
2570 assign l2_cache_coherent[i] = 1'b0;
2572 assign int_miss[i] = rab_miss[i];
2573 assign int_prot[i] = rab_prot[i];
2574 assign int_multi[i] = rab_multi[i];
2577 assign L2Miss_S[i] = 1'b0;
2579 assign L1OutRwType_D[i] = 1'b0;
2580 assign L1OutProt_D[i] = 1'b0;
2581 assign L1OutMulti_D[i] = 1'b0;
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;
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;
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;
2602 assign L2InEn_S[i] = 1'b0;
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;
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;
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;
2631 end // !`ifdef ENABLE_L2TLB
2632 end // for (i = 0; i < N_PORTS; i++)
2640 # // vim: ts=2 sw=2 sts=2 et nosmartindent autoindent foldmethod=marker