Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / unused_please_ignore_completely / iommu / axi_rab / axi_rab_cfg.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_cfg(Elaboratable):
7
8 def __init__(self):
9 self.Clk_CI = Signal() # input
10 self.Rst_RBI = Signal() # input
11 self.s_axi_awaddr = Signal(AXI_ADDR_WIDTH) # input
12 self.s_axi_awvalid = Signal() # input
13 self.s_axi_awready = Signal() # output
14 self.s_axi_wdata = Signal() # input
15 self.s_axi_wstrb = Signal(1+ERROR p_expression_25) # input
16 self.s_axi_wvalid = Signal() # input
17 self.s_axi_wready = Signal() # output
18 self.s_axi_bresp = Signal(2) # output
19 self.s_axi_bvalid = Signal() # output
20 self.s_axi_bready = Signal() # input
21 self.s_axi_araddr = Signal(AXI_ADDR_WIDTH) # input
22 self.s_axi_arvalid = Signal() # input
23 self.s_axi_arready = Signal() # output
24 self.s_axi_rdata = Signal(AXI_DATA_WIDTH) # output
25 self.s_axi_rresp = Signal(2) # output
26 self.s_axi_rvalid = Signal() # output
27 self.s_axi_rready = Signal() # input
28 self.L1Cfg_DO = Signal() # output
29 self.L1AllowMultiHit_SO = Signal() # output
30 self.MissAddr_DI = Signal(ADDR_WIDTH_VIRT) # input
31 self.MissMeta_DI = Signal(MISS_META_WIDTH) # input
32 self.Miss_SI = Signal() # input
33 self.MhFifoFull_SO = Signal() # output
34 self.wdata_l2 = Signal() # output
35 self.waddr_l2 = Signal() # output
36 self.wren_l2 = Signal(N_PORTS) # output
37
38 def elaborate(self, platform=None):
39 m = Module()
40 return m
41
42
43 # // Copyright 2018 ETH Zurich and University of Bologna.
44 # // Copyright and related rights are licensed under the Solderpad Hardware
45 # // License, Version 0.51 (the "License"); you may not use this file except in
46 # // compliance with the License. You may obtain a copy of the License at
47 # // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
48 # // or agreed to in writing, software, hardware and materials distributed under
49 # // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
50 # // CONDITIONS OF ANY KIND, either express or implied. See the License for the
51 # // specific language governing permissions and limitations under the License.
52 #
53 # // --=========================================================================--
54 # //
55 # // █████╗ ██╗ ██╗██╗ ██████╗ █████╗ ██████╗ ██████╗███████╗ ██████╗
56 # // ██╔══██╗╚██╗██╔╝██║ ██╔══██╗██╔══██╗██╔══██╗ ██╔════╝██╔════╝██╔════╝
57 # // ███████║ ╚███╔╝ ██║ ██████╔╝███████║██████╔╝ ██║ █████╗ ██║ ███╗
58 # // ██╔══██║ ██╔██╗ ██║ ██╔══██╗██╔══██║██╔══██╗ ██║ ██╔══╝ ██║ ██║
59 # // ██║ ██║██╔╝ ██╗██║ ██║ ██║██║ ██║██████╔╝ ╚██████╗██║ ╚██████╔╝
60 # // ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝╚═╝ ╚═════╝
61 # //
62 # //
63 # // Author: Pirmin Vogel - vogelpi@iis.ee.ethz.ch
64 # //
65 # // Purpose : AXI4-Lite configuration and miss handling interface for RAB
66 # //
67 # // --=========================================================================--
68 #
69 # //import CfMath::log2;
70 #
71 # module axi_rab_cfg
72 # #(
73 # parameter N_PORTS = 3,
74 # parameter N_REGS = 196,
75 # parameter N_L2_SETS = 32,
76 # parameter N_L2_SET_ENTRIES= 32,
77 # parameter ADDR_WIDTH_PHYS = 40,
78 # parameter ADDR_WIDTH_VIRT = 32,
79 # parameter N_FLAGS = 4,
80 # parameter AXI_DATA_WIDTH = 64,
81 # parameter AXI_ADDR_WIDTH = 32,
82 # parameter MISS_META_WIDTH = 10, // <= FIFO_WIDTH
83 # parameter MH_FIFO_DEPTH = 16
84 # )
85 # (
86 # input logic Clk_CI,
87 # input logic Rst_RBI,
88 #
89 # // AXI Lite interface
90 # input logic [AXI_ADDR_WIDTH-1:0] s_axi_awaddr,
91 # input logic s_axi_awvalid,
92 # output logic s_axi_awready,
93 # input logic [AXI_DATA_WIDTH/8-1:0][7:0] s_axi_wdata,
94 # input logic [AXI_DATA_WIDTH/8-1:0] s_axi_wstrb,
95 # input logic s_axi_wvalid,
96 # output logic s_axi_wready,
97 # output logic [1:0] s_axi_bresp,
98 # output logic s_axi_bvalid,
99 # input logic s_axi_bready,
100 # input logic [AXI_ADDR_WIDTH-1:0] s_axi_araddr,
101 # input logic s_axi_arvalid,
102 # output logic s_axi_arready,
103 # output logic [AXI_DATA_WIDTH-1:0] s_axi_rdata,
104 # output logic [1:0] s_axi_rresp,
105 # output logic s_axi_rvalid,
106 # input logic s_axi_rready,
107 #
108 # // Slice configuration
109 # output logic [N_REGS-1:0][63:0] L1Cfg_DO,
110 # output logic L1AllowMultiHit_SO,
111 #
112 # // Miss handling
113 # input logic [ADDR_WIDTH_VIRT-1:0] MissAddr_DI,
114 # input logic [MISS_META_WIDTH-1:0] MissMeta_DI,
115 # input logic Miss_SI,
116 # output logic MhFifoFull_SO,
117 #
118 # // L2 TLB
119 # output logic [N_PORTS-1:0] [AXI_DATA_WIDTH-1:0] wdata_l2,
120 # output logic [N_PORTS-1:0] [AXI_ADDR_WIDTH-1:0] waddr_l2,
121 # output logic [N_PORTS-1:0] wren_l2
122 # );
123 #
124 """ #docstring_begin
125
126 localparam ADDR_LSB = log2(64/8); // 64 even if the AXI Lite interface is 32,
127 // because RAB slices are 64 bit wide.
128 localparam ADDR_MSB = log2(N_REGS)+ADDR_LSB-1;
129
130 localparam L2SINGLE_AMAP_SIZE = 16'h4000; // Maximum 2048 TLB entries in L2
131
132 localparam integer N_L2_ENTRIES = N_L2_SETS * N_L2_SET_ENTRIES;
133
134 localparam logic [AXI_ADDR_WIDTH-1:0] L2_VA_MAX_ADDR = (N_L2_ENTRIES-1) << 2;
135
136 logic [AXI_DATA_WIDTH/8-1:0][7:0] L1Cfg_DP[N_REGS]; // [Byte][Bit]
137 genvar j;
138
139 // █████╗ ██╗ ██╗██╗██╗ ██╗ ██╗ ██╗████████╗███████╗
140 // ██╔══██╗╚██╗██╔╝██║██║ ██║ ██║ ██║╚══██╔══╝██╔════╝
141 // ███████║ ╚███╔╝ ██║███████║█████╗██║ ██║ ██║ █████╗
142 // ██╔══██║ ██╔██╗ ██║╚════██║╚════╝██║ ██║ ██║ ██╔══╝
143 // ██║ ██║██╔╝ ██╗██║ ██║ ███████╗██║ ██║ ███████╗
144 // ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚══════╝
145 //
146 logic [AXI_ADDR_WIDTH-1:0] awaddr_reg;
147 logic awaddr_done_rise;
148 logic awaddr_done_reg;
149 logic awaddr_done_reg_dly;
150
151 logic [AXI_DATA_WIDTH/8-1:0][7:0] wdata_reg;
152 logic [AXI_DATA_WIDTH/8-1:0] wstrb_reg;
153 logic wdata_done_rise;
154 logic wdata_done_reg;
155 logic wdata_done_reg_dly;
156
157 logic wresp_done_reg;
158 logic wresp_running_reg;
159
160 logic [AXI_ADDR_WIDTH-1:0] araddr_reg;
161 logic araddr_done_reg;
162
163 logic [AXI_DATA_WIDTH-1:0] rdata_reg;
164 logic rresp_done_reg;
165 logic rresp_running_reg;
166
167 logic awready;
168 logic wready;
169 logic bvalid;
170
171 logic arready;
172 logic rvalid;
173
174 logic wren;
175 logic wren_l1;
176
177 assign wren = ( wdata_done_rise & awaddr_done_reg ) | ( awaddr_done_rise & wdata_done_reg );
178 assign wdata_done_rise = wdata_done_reg & ~wdata_done_reg_dly;
179 assign awaddr_done_rise = awaddr_done_reg & ~awaddr_done_reg_dly;
180
181 // reg_dly
182 always @(posedge Clk_CI or negedge Rst_RBI)
183 begin
184 if (!Rst_RBI)
185 begin
186 wdata_done_reg_dly <= 1'b0;
187 awaddr_done_reg_dly <= 1'b0;
188 end
189 else
190 begin
191 wdata_done_reg_dly <= wdata_done_reg;
192 awaddr_done_reg_dly <= awaddr_done_reg;
193 end
194 end
195
196 // AW Channel
197 always @(posedge Clk_CI or negedge Rst_RBI)
198 begin
199 if (!Rst_RBI)
200 begin
201 awaddr_done_reg <= 1'b0;
202 awaddr_reg <= '0;
203 awready <= 1'b1;
204 end
205 else
206 begin
207 if (awready && s_axi_awvalid)
208 begin
209 awready <= 1'b0;
210 awaddr_done_reg <= 1'b1;
211 awaddr_reg <= s_axi_awaddr;
212 end
213 else if (awaddr_done_reg && wresp_done_reg)
214 begin
215 awready <= 1'b1;
216 awaddr_done_reg <= 1'b0;
217 end
218 end
219 end
220
221 // W Channel
222 always @(posedge Clk_CI or negedge Rst_RBI)
223 begin
224 if (!Rst_RBI)
225 begin
226 wdata_done_reg <= 1'b0;
227 wready <= 1'b1;
228 wdata_reg <= '0;
229 wstrb_reg <= '0;
230 end
231 else
232 begin
233 if (wready && s_axi_wvalid)
234 begin
235 wready <= 1'b0;
236 wdata_done_reg <= 1'b1;
237 wdata_reg <= s_axi_wdata;
238 wstrb_reg <= s_axi_wstrb;
239 end
240 else if (wdata_done_reg && wresp_done_reg)
241 begin
242 wready <= 1'b1;
243 wdata_done_reg <= 1'b0;
244 end
245 end
246 end
247
248 // B Channel
249 always @(posedge Clk_CI or negedge Rst_RBI)
250 begin
251 if (!Rst_RBI)
252 begin
253 bvalid <= 1'b0;
254 wresp_done_reg <= 1'b0;
255 wresp_running_reg <= 1'b0;
256 end
257 else
258 begin
259 if (awaddr_done_reg && wdata_done_reg && !wresp_done_reg)
260 begin
261 if (!wresp_running_reg)
262 begin
263 bvalid <= 1'b1;
264 wresp_running_reg <= 1'b1;
265 end
266 else if (s_axi_bready)
267 begin
268 bvalid <= 1'b0;
269 wresp_done_reg <= 1'b1;
270 wresp_running_reg <= 1'b0;
271 end
272 end
273 else
274 begin
275 bvalid <= 1'b0;
276 wresp_done_reg <= 1'b0;
277 wresp_running_reg <= 1'b0;
278 end
279 end
280 end
281
282 // AR Channel
283 always @(posedge Clk_CI or negedge Rst_RBI)
284 begin
285 if (!Rst_RBI)
286 begin
287 araddr_done_reg <= 1'b0;
288 arready <= 1'b1;
289 araddr_reg <= '0;
290 end
291 else
292 begin
293 if (arready && s_axi_arvalid)
294 begin
295 arready <= 1'b0;
296 araddr_done_reg <= 1'b1;
297 araddr_reg <= s_axi_araddr;
298 end
299 else if (araddr_done_reg && rresp_done_reg)
300 begin
301 arready <= 1'b1;
302 araddr_done_reg <= 1'b0;
303 end
304 end
305 end
306
307 // R Channel
308 always @(posedge Clk_CI or negedge Rst_RBI)
309 begin
310 if (!Rst_RBI)
311 begin
312 rresp_done_reg <= 1'b0;
313 rvalid <= 1'b0;
314 rresp_running_reg <= 1'b0;
315 end
316 else
317 begin
318 if (araddr_done_reg && !rresp_done_reg)
319 begin
320 if (!rresp_running_reg)
321 begin
322 rvalid <= 1'b1;
323 rresp_running_reg <= 1'b1;
324 end
325 else if (s_axi_rready)
326 begin
327 rvalid <= 1'b0;
328 rresp_done_reg <= 1'b1;
329 rresp_running_reg <= 1'b0;
330 end
331 end
332 else
333 begin
334 rvalid <= 1'b0;
335 rresp_done_reg <= 1'b0;
336 rresp_running_reg <= 1'b0;
337 end
338 end
339 end
340
341 // ██╗ ██╗ ██████╗███████╗ ██████╗ ██████╗ ███████╗ ██████╗
342 // ██║ ███║ ██╔════╝██╔════╝██╔════╝ ██╔══██╗██╔════╝██╔════╝
343 // ██║ ╚██║ ██║ █████╗ ██║ ███╗ ██████╔╝█████╗ ██║ ███╗
344 // ██║ ██║ ██║ ██╔══╝ ██║ ██║ ██╔══██╗██╔══╝ ██║ ██║
345 // ███████╗██║ ╚██████╗██║ ╚██████╔╝ ██║ ██║███████╗╚██████╔╝
346 // ╚══════╝╚═╝ ╚═════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝
347 //
348 assign wren_l1 = wren && (awaddr_reg < L2SINGLE_AMAP_SIZE);
349
350 always @( posedge Clk_CI or negedge Rst_RBI )
351 begin
352 var integer idx_reg, idx_byte;
353 if ( Rst_RBI == 1'b0 )
354 begin
355 for ( idx_reg = 0; idx_reg < N_REGS; idx_reg++ )
356 L1Cfg_DP[idx_reg] <= '0;
357 end
358 else if ( wren_l1 )
359 begin
360 if ( awaddr_reg[ADDR_LSB+1] == 1'b0 ) begin // VIRT_ADDR
361 for ( idx_byte = 0; idx_byte < AXI_DATA_WIDTH/8; idx_byte++ ) begin
362 if ( (idx_byte < ADDR_WIDTH_VIRT/8) ) begin
363 if ( wstrb_reg[idx_byte] ) begin
364 L1Cfg_DP[awaddr_reg[ADDR_MSB:ADDR_LSB]][idx_byte] <= wdata_reg[idx_byte];
365 end
366 end
367 else begin // Let synthesizer optimize away unused registers.
368 L1Cfg_DP[awaddr_reg[ADDR_MSB:ADDR_LSB]][idx_byte] <= '0;
369 end
370 end
371 end
372 else if ( awaddr_reg[ADDR_LSB+1:ADDR_LSB] == 2'b10 ) begin // PHYS_ADDR
373 for ( idx_byte = 0; idx_byte < AXI_DATA_WIDTH/8; idx_byte++ ) begin
374 if ( (idx_byte < ADDR_WIDTH_PHYS/8) ) begin
375 if ( wstrb_reg[idx_byte] ) begin
376 L1Cfg_DP[awaddr_reg[ADDR_MSB:ADDR_LSB]][idx_byte] <= wdata_reg[idx_byte];
377 end
378 end
379 else begin // Let synthesizer optimize away unused registers.
380 L1Cfg_DP[awaddr_reg[ADDR_MSB:ADDR_LSB]][idx_byte] <= '0;
381 end
382 end
383 end
384 else begin // ( awaddr_reg[ADDR_LSB+1:ADDR_LSB] == 2'b11 ) // FLAGS
385 for ( idx_byte = 0; idx_byte < AXI_DATA_WIDTH/8; idx_byte++ ) begin
386 if ( (idx_byte < 1) ) begin
387 if ( wstrb_reg[idx_byte] ) begin
388 L1Cfg_DP[awaddr_reg[ADDR_MSB:ADDR_LSB]][idx_byte] <= wdata_reg[idx_byte] & { {{8-N_FLAGS}{1'b0}}, {{N_FLAGS}{1'b1}} };
389 end
390 end
391 else begin // Let synthesizer optimize away unused registers.
392 L1Cfg_DP[awaddr_reg[ADDR_MSB:ADDR_LSB]][idx_byte] <= '0;
393 end
394 end
395 end
396 end
397 end // always @ ( posedge Clk_CI or negedge Rst_RBI )
398
399 generate
400 // Mask unused bits -> Synthesizer should optimize away unused registers
401 for( j=0; j<N_REGS; j++ ) begin
402 if ( j[1] == 1'b0 ) // VIRT_ADDR
403 assign L1Cfg_DO[j] = { {{64-ADDR_WIDTH_VIRT}{1'b0}},{ADDR_WIDTH_VIRT{1'b1}} } & L1Cfg_DP[j];
404 else if ( j[1:0] == 2'b10 ) // PHYS_ADDR
405 assign L1Cfg_DO[j] = { {{64-ADDR_WIDTH_PHYS}{1'b0}},{ADDR_WIDTH_PHYS{1'b1}} } & L1Cfg_DP[j];
406 else // if ( j[1:0] == 2'b11 ) // FLAGS
407 assign L1Cfg_DO[j] = { {{64-N_FLAGS}{1'b0}},{N_FLAGS{1'b1}} } & L1Cfg_DP[j];
408 end
409 endgenerate
410
411 always_comb
412 begin
413 if ( araddr_reg[ADDR_LSB-1] == 1'b1 ) // read upper 32 bit, for debugging over 32-bit interface
414 rdata_reg = { {32'h00000000},{L1Cfg_DO[araddr_reg[ADDR_MSB:ADDR_LSB]][63:32]} };
415 else
416 rdata_reg = L1Cfg_DO[araddr_reg[ADDR_MSB:ADDR_LSB]];
417 end
418
419 assign s_axi_awready = awready;
420 assign s_axi_wready = wready;
421
422 assign s_axi_bresp = 2'b00;
423 assign s_axi_bvalid = bvalid;
424
425 assign s_axi_arready = arready;
426 assign s_axi_rresp = 2'b00;
427 assign s_axi_rvalid = rvalid;
428
429 // ██╗ ██████╗ ██████╗███████╗ ██████╗
430 // ██║ ╚════██╗ ██╔════╝██╔════╝██╔════╝
431 // ██║ █████╔╝ ██║ █████╗ ██║ ███╗
432 // ██║ ██╔═══╝ ██║ ██╔══╝ ██║ ██║
433 // ███████╗███████╗ ╚██████╗██║ ╚██████╔╝
434 // ╚══════╝╚══════╝ ╚═════╝╚═╝ ╚═════╝
435 //
436 logic [N_PORTS-1:0] l2_addr_is_in_va_rams;
437 logic [N_PORTS-1:0] upper_word_is_written;
438 logic [N_PORTS-1:0] lower_word_is_written;
439 generate
440 for( j=0; j< N_PORTS; j++)
441 begin
442 if (AXI_DATA_WIDTH == 64) begin
443 assign l2_addr_is_in_va_rams[j] = (awaddr_reg >= (j+1)*L2SINGLE_AMAP_SIZE) && (awaddr_reg[log2(L2SINGLE_AMAP_SIZE)-1:0] <= L2_VA_MAX_ADDR);
444 assign upper_word_is_written[j] = (wstrb_reg[7:4] != 4'b0000);
445 assign lower_word_is_written[j] = (wstrb_reg[3:0] != 4'b0000);
446 end else begin
447 assign l2_addr_is_in_va_rams[j] = 1'b0;
448 assign upper_word_is_written[j] = 1'b0;
449 assign lower_word_is_written[j] = 1'b0;
450 end
451
452 always @( posedge Clk_CI or negedge Rst_RBI ) begin
453 var integer idx_byte, off_byte;
454 if ( Rst_RBI == 1'b0 )
455 begin
456 wren_l2[j] <= 1'b0;
457 wdata_l2[j] <= '0;
458 end
459 else if (wren)
460 begin
461 if ( (awaddr_reg >= (j+1)*L2SINGLE_AMAP_SIZE) && (awaddr_reg < (j+2)*L2SINGLE_AMAP_SIZE) && (|wstrb_reg) )
462 wren_l2[j] <= 1'b1;
463 if (AXI_DATA_WIDTH == 32) begin
464 for ( idx_byte = 0; idx_byte < AXI_DATA_WIDTH/8; idx_byte++ )
465 wdata_l2[j][idx_byte*8 +: 8] <= wdata_reg[idx_byte] & {8{wstrb_reg[idx_byte]}};
466 end
467 else if (AXI_DATA_WIDTH == 64) begin
468 if (lower_word_is_written[j] == 1'b1)
469 off_byte = 0;
470 else
471 off_byte = 4;
472 // always put the payload in the lower word and set upper word to 0
473 for ( idx_byte = 0; idx_byte < AXI_DATA_WIDTH/8/2; idx_byte++ )
474 wdata_l2[j][idx_byte*8 +: 8] <= wdata_reg[idx_byte+off_byte] & {8{wstrb_reg[idx_byte+off_byte]}};
475 wdata_l2[j][AXI_DATA_WIDTH-1:AXI_DATA_WIDTH/2] <= 'b0;
476 end
477 // pragma translate_off
478 else
479 $fatal(1, "Unsupported AXI_DATA_WIDTH!");
480 // pragma translate_on
481 end
482 else
483 wren_l2[j] <= '0;
484 end // always @ ( posedge Clk_CI or negedge Rst_RBI )
485
486 // Properly align the 32-bit word address when writing from 64-bit interface:
487 // Depending on the system, the incoming address is (non-)aligned to the 64-bit
488 // word when writing the upper 32-bit word.
489 always_comb begin
490 waddr_l2[j] = (awaddr_reg -(j+1)*L2SINGLE_AMAP_SIZE)/4;
491 if (wren_l2[j]) begin
492 if (AXI_DATA_WIDTH == 64) begin
493 if (upper_word_is_written[j] == 1'b1) begin
494 // address must be non-aligned
495 waddr_l2[j][0] = 1'b1;
496 end
497 end
498 // pragma translate_off
499 else if (AXI_DATA_WIDTH != 32) begin
500 $fatal(1, "Unsupported AXI_DATA_WIDTH!");
501 end
502 // pragma translate_on
503 end
504 end
505
506 // Assert that only one 32-bit word is ever written at a time to VA RAMs on 64-bit data
507 // systems.
508 // pragma translate_off
509 always_ff @ (posedge Clk_CI) begin
510 if (AXI_DATA_WIDTH == 64) begin
511 if (l2_addr_is_in_va_rams[j]) begin
512 if (upper_word_is_written[j]) begin
513 assert (!lower_word_is_written[j])
514 else $error("Unsupported write across two 32-bit words to VA RAMs!");
515 end
516 else if (lower_word_is_written[j]) begin
517 assert (!upper_word_is_written[j])
518 else $error("Unsupported write across two 32-bit words to VA RAMs!");
519 end
520 end
521 end
522 end
523 // pragma translate_on
524
525 end // for (j=0; j< N_PORTS; j++)
526 endgenerate
527
528 // ███╗ ███╗██╗ ██╗ ███████╗██╗███████╗ ██████╗ ███████╗
529 // ████╗ ████║██║ ██║ ██╔════╝██║██╔════╝██╔═══██╗██╔════╝
530 // ██╔████╔██║███████║ █████╗ ██║█████╗ ██║ ██║███████╗
531 // ██║╚██╔╝██║██╔══██║ ██╔══╝ ██║██╔══╝ ██║ ██║╚════██║
532 // ██║ ╚═╝ ██║██║ ██║ ██║ ██║██║ ╚██████╔╝███████║
533 // ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═════╝ ╚══════╝
534 //
535 logic [ADDR_WIDTH_VIRT-1:0] AddrFifoDin_D;
536 logic AddrFifoWen_S;
537 logic AddrFifoRen_S;
538 logic [ADDR_WIDTH_VIRT-1:0] AddrFifoDout_D;
539 logic AddrFifoFull_S;
540 logic AddrFifoEmpty_S;
541 logic AddrFifoEmpty_SB;
542 logic AddrFifoFull_SB;
543
544 logic [MISS_META_WIDTH-1:0] MetaFifoDin_D;
545 logic MetaFifoWen_S;
546 logic MetaFifoRen_S;
547 logic [MISS_META_WIDTH-1:0] MetaFifoDout_D;
548 logic MetaFifoFull_S;
549 logic MetaFifoEmpty_S;
550 logic MetaFifoEmpty_SB;
551 logic MetaFifoFull_SB;
552
553 logic FifosDisabled_S;
554 logic ConfRegWen_S;
555 logic [1:0] ConfReg_DN;
556 logic [1:0] ConfReg_DP;
557
558 logic [AXI_DATA_WIDTH-1:0] wdata_reg_vec;
559
560 assign FifosDisabled_S = ConfReg_DP[0];
561 assign L1AllowMultiHit_SO = ConfReg_DP[1];
562
563 assign AddrFifoEmpty_S = ~AddrFifoEmpty_SB;
564 assign MetaFifoEmpty_S = ~MetaFifoEmpty_SB;
565
566 assign AddrFifoFull_S = ~AddrFifoFull_SB;
567 assign MetaFifoFull_S = ~MetaFifoFull_SB;
568
569 assign MhFifoFull_SO = (AddrFifoWen_S & AddrFifoFull_S) | (MetaFifoWen_S & MetaFifoFull_S);
570
571 generate
572 for ( j=0; j<AXI_DATA_WIDTH/8; j++ )
573 assign wdata_reg_vec[(j+1)*8-1:j*8] = wdata_reg[j];
574 endgenerate
575
576 // write address FIFO
577 always_comb
578 begin
579 AddrFifoWen_S = 1'b0;
580 AddrFifoDin_D = 'b0;
581 if ( (Miss_SI == 1'b1) && (FifosDisabled_S == 1'b0) ) // register a new miss
582 begin
583 AddrFifoWen_S = 1'b1;
584 AddrFifoDin_D = MissAddr_DI;
585 end
586 else if ( (wren_l1 == 1'b1) && (awaddr_reg[ADDR_MSB:0] == 'b0) && (FifosDisabled_S == 1'b0)) // write request from AXI interface
587 begin
588 AddrFifoWen_S = 1'b1;
589 AddrFifoDin_D = wdata_reg_vec[ADDR_WIDTH_VIRT-1:0];
590 end
591 end
592
593 // write meta FIFO
594 always_comb
595 begin
596 MetaFifoWen_S = 1'b0;
597 MetaFifoDin_D = 'b0;
598 if ( (Miss_SI == 1'b1) && (FifosDisabled_S == 1'b0) ) // register a new miss
599 begin
600 MetaFifoWen_S = 1'b1;
601 MetaFifoDin_D[MISS_META_WIDTH-1:0] = MissMeta_DI;
602 end
603 else if ( (wren_l1 == 1'b1) && (awaddr_reg[ADDR_MSB:0] == 4'h8) && (FifosDisabled_S == 1'b0) ) // write request from AXI interface
604 begin
605 MetaFifoWen_S = 1'b1;
606 MetaFifoDin_D = wdata_reg_vec[MISS_META_WIDTH-1:0];
607 end
608 end
609
610 // write configuration register
611 always_comb
612 begin
613 ConfRegWen_S = 1'b0;
614 ConfReg_DN = 1'b0;
615 if ( (wren_l1 == 1'b1) && (awaddr_reg[ADDR_MSB:0] == 8'h10) ) // write request from AXI interface
616 begin
617 ConfRegWen_S = 1'b1;
618 ConfReg_DN = wdata_reg_vec[$high(ConfReg_DN):0];
619 end
620 end
621
622 // AXI read data
623 always_comb
624 begin
625 s_axi_rdata = rdata_reg; // read L1 config
626 AddrFifoRen_S = 1'b0;
627 MetaFifoRen_S = 1'b0;
628 if ( rvalid == 1'b1 )
629 begin
630 // read address FIFO
631 if ( araddr_reg[ADDR_MSB:0] == 'b0 )
632 begin
633 s_axi_rdata = {AXI_DATA_WIDTH{1'b0}};
634 s_axi_rdata[ADDR_WIDTH_VIRT-1:0] = AddrFifoDout_D;
635 if ( AddrFifoEmpty_S == 1'b0 )
636 AddrFifoRen_S = 1'b1;
637 end
638 // read meta FIFO
639 else if ( araddr_reg[ADDR_MSB:0] == 4'h8 )
640 begin
641 s_axi_rdata = {AXI_DATA_WIDTH{1'b0}};
642 s_axi_rdata[31] = MetaFifoEmpty_S;
643 s_axi_rdata[MISS_META_WIDTH-1:0] = MetaFifoDout_D;
644 if ( MetaFifoEmpty_S == 1'b0 )
645 MetaFifoRen_S = 1'b1;
646 end
647 // read configuration register
648 else if ( araddr_reg[ADDR_MSB:0] == 8'h10 )
649 begin
650 s_axi_rdata = {AXI_DATA_WIDTH{1'b0}};
651 s_axi_rdata[$high(ConfReg_DP):0] = ConfReg_DP;
652 end
653 end // if ( rvalid == 1'b1 )
654 end // always_comb begin
655
656 // configuration register
657 always_ff @(posedge Clk_CI or negedge Rst_RBI) begin
658 if (Rst_RBI == 1'b0)
659 begin
660 ConfReg_DP <= 'b0;
661 end
662 else if (ConfRegWen_S == 1'b1)
663 begin
664 ConfReg_DP <= ConfReg_DN;
665 end
666 end
667
668 generic_fifo
669 #(
670 .DATA_WIDTH ( ADDR_WIDTH_VIRT ),
671 .DATA_DEPTH ( MH_FIFO_DEPTH )
672 )
673 fifo_addr_i
674 (
675 .clk ( Clk_CI ),
676 .rst_n ( Rst_RBI ),
677 .data_i ( AddrFifoDin_D ),
678 .valid_i ( AddrFifoWen_S & AddrFifoFull_SB ),
679 .grant_o ( AddrFifoFull_SB ),
680 .data_o ( AddrFifoDout_D ),
681 .valid_o ( AddrFifoEmpty_SB ),
682 .grant_i ( AddrFifoRen_S ),
683 .test_mode_i ( 1'b0 )
684 );
685
686 generic_fifo
687 #(
688 .DATA_WIDTH ( MISS_META_WIDTH ),
689 .DATA_DEPTH ( MH_FIFO_DEPTH )
690 )
691 fifo_meta_i
692 (
693 .clk ( Clk_CI ),
694 .rst_n ( Rst_RBI ),
695 .data_i ( MetaFifoDin_D ),
696 .valid_i ( MetaFifoWen_S & MetaFifoFull_SB ),
697 .grant_o ( MetaFifoFull_SB ),
698 .data_o ( MetaFifoDout_D ),
699 .valid_o ( MetaFifoEmpty_SB ),
700 .grant_i ( MetaFifoRen_S ),
701 .test_mode_i ( 1'b0 )
702 );
703 """
704 #
705 # endmodule
706 #
707 #