move unused directory out of src, to indicate "ignore completely"
[soc.git] / unused_please_ignore_completely / iommu / axi_rab / axi4_w_buffer.py
1 # this file has been generated by sv2nmigen
2 # // Copyright 2018 ETH Zurich and University of Bologna.
3 # // Copyright and related rights are licensed under the Solderpad Hardware
4 # // License, Version 0.51 (the "License"); you may not use this file except in
5 # // compliance with the License. You may obtain a copy of the License at
6 # // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
7 # // or agreed to in writing, software, hardware and materials distributed under
8 # // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 # // CONDITIONS OF ANY KIND, either express or implied. See the License for the
10 # // specific language governing permissions and limitations under the License.
11 from nmigen import Signal, Module, Const, Cat, Elaboratable
12
13
14 class axi4_w_buffer(Elaboratable):
15
16 def __init__(self):
17 self.axi4_aclk = Signal() # input
18 self.axi4_arstn = Signal() # input
19 self.l1_done_o = Signal() # output
20 self.l1_accept_i = Signal() # input
21 self.l1_save_i = Signal() # input
22 self.l1_drop_i = Signal() # input
23 self.l1_master_i = Signal() # input
24 self.l1_id_i = Signal(AXI_ID_WIDTH) # input
25 self.l1_len_i = Signal(8) # input
26 self.l1_prefetch_i = Signal() # input
27 self.l1_hit_i = Signal() # input
28 self.l2_done_o = Signal() # output
29 self.l2_accept_i = Signal() # input
30 self.l2_drop_i = Signal() # input
31 self.l2_master_i = Signal() # input
32 self.l2_id_i = Signal(AXI_ID_WIDTH) # input
33 self.l2_len_i = Signal(8) # input
34 self.l2_prefetch_i = Signal() # input
35 self.l2_hit_i = Signal() # input
36 self.master_select_o = Signal() # output
37 self.input_stall_o = Signal() # output
38 self.output_stall_o = Signal() # output
39 self.b_drop_o = Signal() # output
40 self.b_done_i = Signal() # input
41 self.id_o = Signal(AXI_ID_WIDTH) # output
42 self.prefetch_o = Signal() # output
43 self.hit_o = Signal() # output
44 self.s_axi4_wdata = Signal(AXI_DATA_WIDTH) # input
45 self.s_axi4_wvalid = Signal() # input
46 self.s_axi4_wready = Signal() # output
47 self.s_axi4_wstrb = Signal(1+ERROR p_expression_25) # input
48 self.s_axi4_wlast = Signal() # input
49 self.s_axi4_wuser = Signal(AXI_USER_WIDTH) # input
50 self.m_axi4_wdata = Signal(AXI_DATA_WIDTH) # output
51 self.m_axi4_wvalid = Signal() # output
52 self.m_axi4_wready = Signal() # input
53 self.m_axi4_wstrb = Signal(1+ERROR p_expression_25) # output
54 self.m_axi4_wlast = Signal() # output
55 self.m_axi4_wuser = Signal(AXI_USER_WIDTH) # output
56
57 def elaborate(self, platform=None):
58 m = Module()
59 return m
60
61
62 #
63 # //import CfMath::log2;
64 #
65 # module axi4_w_buffer
66 # #(
67 # parameter AXI_DATA_WIDTH = 32,
68 # parameter AXI_ID_WIDTH = 4,
69 # parameter AXI_USER_WIDTH = 4,
70 # parameter ENABLE_L2TLB = 0,
71 # parameter HUM_BUFFER_DEPTH = 16
72 # )
73 # (
74 # input logic axi4_aclk,
75 # input logic axi4_arstn,
76 #
77 # // L1 & L2 interfaces
78 # output logic l1_done_o,
79 # input logic l1_accept_i,
80 # input logic l1_save_i,
81 # input logic l1_drop_i,
82 # input logic l1_master_i,
83 # input logic [AXI_ID_WIDTH-1:0] l1_id_i,
84 # input logic [7:0] l1_len_i,
85 # input logic l1_prefetch_i,
86 # input logic l1_hit_i,
87 #
88 # output logic l2_done_o,
89 # input logic l2_accept_i,
90 # input logic l2_drop_i,
91 # input logic l2_master_i,
92 # input logic [AXI_ID_WIDTH-1:0] l2_id_i,
93 # input logic [7:0] l2_len_i,
94 # input logic l2_prefetch_i,
95 # input logic l2_hit_i,
96 #
97 # output logic master_select_o,
98 # output logic input_stall_o,
99 # output logic output_stall_o,
100 #
101 # // B sender interface
102 # output logic b_drop_o,
103 # input logic b_done_i,
104 # output logic [AXI_ID_WIDTH-1:0] id_o,
105 # output logic prefetch_o,
106 # output logic hit_o,
107 #
108 # // AXI W channel interfaces
109 # input logic [AXI_DATA_WIDTH-1:0] s_axi4_wdata,
110 # input logic s_axi4_wvalid,
111 # output logic s_axi4_wready,
112 # input logic [AXI_DATA_WIDTH/8-1:0] s_axi4_wstrb,
113 # input logic s_axi4_wlast,
114 # input logic [AXI_USER_WIDTH-1:0] s_axi4_wuser,
115 #
116 # output logic [AXI_DATA_WIDTH-1:0] m_axi4_wdata,
117 # output logic m_axi4_wvalid,
118 # input logic m_axi4_wready,
119 # output logic [AXI_DATA_WIDTH/8-1:0] m_axi4_wstrb,
120 # output logic m_axi4_wlast,
121 # output logic [AXI_USER_WIDTH-1:0] m_axi4_wuser
122 # );
123 #
124 """
125
126 localparam BUFFER_WIDTH = AXI_DATA_WIDTH+AXI_USER_WIDTH+AXI_DATA_WIDTH/8+1;
127
128 localparam INPUT_BUFFER_DEPTH = 4;
129 localparam L1_FIFO_DEPTH = 8;
130 localparam L2_FIFO_DEPTH = 4;
131
132 logic [AXI_DATA_WIDTH-1:0] axi4_wdata;
133 logic axi4_wvalid;
134 logic axi4_wready;
135 logic [AXI_DATA_WIDTH/8-1:0] axi4_wstrb;
136 logic axi4_wlast;
137 logic [AXI_USER_WIDTH-1:0] axi4_wuser;
138
139 logic l1_fifo_valid_out;
140 logic l1_fifo_ready_in;
141 logic l1_fifo_valid_in;
142 logic l1_fifo_ready_out;
143
144 logic l1_req;
145 logic l1_accept_cur, l1_save_cur, l1_drop_cur;
146 logic l1_master_cur;
147 logic [AXI_ID_WIDTH-1:0] l1_id_cur;
148 logic [7:0] l1_len_cur;
149 logic l1_hit_cur, l1_prefetch_cur;
150 logic l1_save_in, l1_save_out;
151 logic [log2(L1_FIFO_DEPTH)-1:0] n_l1_save_SP;
152
153 logic l2_fifo_valid_out;
154 logic l2_fifo_ready_in;
155 logic l2_fifo_valid_in;
156 logic l2_fifo_ready_out;
157
158 logic l2_req;
159 logic l2_accept_cur, l2_drop_cur;
160 logic l2_master_cur;
161 logic [AXI_ID_WIDTH-1:0] l2_id_cur;
162 logic [7:0] l2_len_cur;
163 logic l2_hit_cur, l2_prefetch_cur;
164
165 logic fifo_select, fifo_select_SN, fifo_select_SP;
166 logic w_done;
167 logic b_drop_set;
168
169 // HUM buffer signals
170 logic hum_buf_ready_out;
171 logic hum_buf_valid_in;
172 logic hum_buf_ready_in;
173 logic hum_buf_valid_out;
174 logic hum_buf_underfull;
175
176 logic [AXI_DATA_WIDTH-1:0] hum_buf_wdata;
177 logic [AXI_DATA_WIDTH/8-1:0] hum_buf_wstrb;
178 logic hum_buf_wlast;
179 logic [AXI_USER_WIDTH-1:0] hum_buf_wuser;
180
181 logic hum_buf_drop_req_SN, hum_buf_drop_req_SP;
182 logic [7:0] hum_buf_drop_len_SN, hum_buf_drop_len_SP;
183 logic hum_buf_almost_full;
184
185 logic stop_store;
186 logic wlast_in, wlast_out;
187 logic signed [3:0] n_wlast_SN, n_wlast_SP;
188 logic block_forwarding;
189
190 // Search FSM
191 typedef enum logic [3:0] {STORE, BYPASS,
192 WAIT_L1_BYPASS_YES, WAIT_L2_BYPASS_YES,
193 WAIT_L1_BYPASS_NO, WAIT_L2_BYPASS_NO,
194 FLUSH, DISCARD,
195 DISCARD_FINISH}
196 hum_buf_state_t;
197 hum_buf_state_t hum_buf_SP; // Present state
198 hum_buf_state_tbg hum_buf_SN; // Next State
199
200 axi_buffer_rab
201 #(
202 .DATA_WIDTH ( BUFFER_WIDTH ),
203 .BUFFER_DEPTH ( INPUT_BUFFER_DEPTH )
204 )
205 u_input_buf
206 (
207 .clk ( axi4_aclk ),
208 .rstn ( axi4_arstn ),
209 // Push
210 .data_in ( {s_axi4_wuser, s_axi4_wstrb, s_axi4_wdata, s_axi4_wlast} ),
211 .valid_in ( s_axi4_wvalid ),
212 .ready_out ( s_axi4_wready ),
213 // Pop
214 .data_out ( {axi4_wuser, axi4_wstrb, axi4_wdata, axi4_wlast} ),
215 .valid_out ( axi4_wvalid ),
216 .ready_in ( axi4_wready )
217 );
218
219 axi_buffer_rab
220 #(
221 .DATA_WIDTH ( 2+AXI_ID_WIDTH+8+4 ),
222 .BUFFER_DEPTH ( L1_FIFO_DEPTH )
223 )
224 u_l1_fifo
225 (
226 .clk ( axi4_aclk ),
227 .rstn ( axi4_arstn ),
228 // Push
229 .data_in ( {l1_prefetch_i, l1_hit_i, l1_id_i, l1_len_i, l1_master_i, l1_accept_i, l1_save_i, l1_drop_i} ),
230 .valid_in ( l1_fifo_valid_in ),
231 .ready_out ( l1_fifo_ready_out ),
232 // Pop
233 .data_out ( {l1_prefetch_cur, l1_hit_cur, l1_id_cur, l1_len_cur, l1_master_cur, l1_accept_cur, l1_save_cur, l1_drop_cur} ),
234 .valid_out ( l1_fifo_valid_out ),
235 .ready_in ( l1_fifo_ready_in )
236 );
237
238 // Push upon receiving new requests from the TLB.
239 assign l1_req = l1_accept_i | l1_save_i | l1_drop_i;
240 assign l1_fifo_valid_in = l1_req & l1_fifo_ready_out;
241
242 // Signal handshake
243 assign l1_done_o = l1_fifo_valid_in;
244 assign l2_done_o = l2_fifo_valid_in;
245
246 // Stall AW input of L1 TLB
247 assign input_stall_o = ~(l1_fifo_ready_out & l2_fifo_ready_out);
248
249 // Interface b_drop signals + handshake
250 always_comb begin
251 if (fifo_select == 1'b0) begin
252 prefetch_o = l1_prefetch_cur;
253 hit_o = l1_hit_cur;
254 id_o = l1_id_cur;
255
256 l1_fifo_ready_in = w_done | b_done_i;
257 l2_fifo_ready_in = 1'b0;
258 end else begin
259 prefetch_o = l2_prefetch_cur;
260 hit_o = l2_hit_cur;
261 id_o = l2_id_cur;
262
263 l1_fifo_ready_in = 1'b0;
264 l2_fifo_ready_in = w_done | b_done_i;
265 end
266 end
267
268 // Detect when an L1 transaction save request enters or exits the L1 FIFO.
269 assign l1_save_in = l1_fifo_valid_in & l1_save_i;
270 assign l1_save_out = l1_fifo_ready_in & l1_save_cur;
271
272 // Count the number of L1 transaction to save in the L1 FIFO.
273 always_ff @(posedge axi4_aclk or negedge axi4_arstn) begin
274 if (axi4_arstn == 0) begin
275 n_l1_save_SP <= '0;
276 end else if (l1_save_in ^ l1_save_out) begin
277 if (l1_save_in) begin
278 n_l1_save_SP <= n_l1_save_SP + 1'b1;
279 end else if (l1_save_out) begin
280 n_l1_save_SP <= n_l1_save_SP - 1'b1;
281 end
282 end
283 end
284
285 // Stall forwarding of AW L1 hits if:
286 // 1. The HUM buffer does not allow to be bypassed.
287 // 2. There are multiple L1 save requests in the FIFO, i.e., multiple L2 outputs pending.
288 assign output_stall_o = (n_l1_save_SP > 1) || (block_forwarding == 1'b1);
289
290 generate
291 if (ENABLE_L2TLB == 1) begin : HUM_BUFFER
292
293 axi_buffer_rab_bram
294 #(
295 .DATA_WIDTH ( BUFFER_WIDTH ),
296 .BUFFER_DEPTH ( HUM_BUFFER_DEPTH )
297 )
298 u_hum_buf
299 (
300 .clk ( axi4_aclk ),
301 .rstn ( axi4_arstn ),
302 // Push
303 .data_in ( {axi4_wuser, axi4_wstrb, axi4_wdata, axi4_wlast} ),
304 .valid_in ( hum_buf_valid_in ),
305 .ready_out ( hum_buf_ready_out ),
306 // Pop
307 .data_out ( {hum_buf_wuser, hum_buf_wstrb, hum_buf_wdata, hum_buf_wlast} ),
308 .valid_out ( hum_buf_valid_out ),
309 .ready_in ( hum_buf_ready_in ),
310 // Clear
311 .almost_full ( hum_buf_almost_full ),
312 .underfull ( hum_buf_underfull ),
313 .drop_req ( hum_buf_drop_req_SP ),
314 .drop_len ( hum_buf_drop_len_SP )
315 );
316
317 axi_buffer_rab
318 #(
319 .DATA_WIDTH ( 2+AXI_ID_WIDTH+8+3 ),
320 .BUFFER_DEPTH ( L2_FIFO_DEPTH )
321 )
322 u_l2_fifo
323 (
324 .clk ( axi4_aclk ),
325 .rstn ( axi4_arstn ),
326 // Push
327 .data_in ( {l2_prefetch_i, l2_hit_i, l2_id_i, l2_len_i, l2_master_i, l2_accept_i, l2_drop_i} ),
328 .valid_in ( l2_fifo_valid_in ),
329 .ready_out ( l2_fifo_ready_out ),
330 // Pop
331 .data_out ( {l2_prefetch_cur, l2_hit_cur, l2_id_cur, l2_len_cur, l2_master_cur, l2_accept_cur, l2_drop_cur} ),
332 .valid_out ( l2_fifo_valid_out ),
333 .ready_in ( l2_fifo_ready_in )
334 );
335
336 // Push upon receiving new result from TLB.
337 assign l2_req = l2_accept_i | l2_drop_i;
338 assign l2_fifo_valid_in = l2_req & l2_fifo_ready_out;
339
340 assign wlast_in = axi4_wlast & hum_buf_valid_in & hum_buf_ready_out;
341 assign wlast_out = hum_buf_wlast & hum_buf_valid_out & hum_buf_ready_in;
342
343 always_ff @(posedge axi4_aclk or negedge axi4_arstn) begin
344 if (axi4_arstn == 0) begin
345 fifo_select_SP <= 1'b0;
346 hum_buf_drop_len_SP <= 'b0;
347 hum_buf_drop_req_SP <= 1'b0;
348 hum_buf_SP <= STORE;
349 n_wlast_SP <= 'b0;
350 end else begin
351 fifo_select_SP <= fifo_select_SN;
352 hum_buf_drop_len_SP <= hum_buf_drop_len_SN;
353 hum_buf_drop_req_SP <= hum_buf_drop_req_SN;
354 hum_buf_SP <= hum_buf_SN;
355 n_wlast_SP <= n_wlast_SN;
356 end
357 end
358
359 always_comb begin
360 n_wlast_SN = n_wlast_SP;
361 if (hum_buf_drop_req_SP) begin // Happens exactly once per burst to be dropped.
362 n_wlast_SN -= 1;
363 end
364 if (wlast_in) begin
365 n_wlast_SN += 1;
366 end
367 if (wlast_out) begin
368 n_wlast_SN -= 1;
369 end
370 end
371
372 always_comb begin : HUM_BUFFER_FSM
373 hum_buf_SN = hum_buf_SP;
374
375 m_axi4_wlast = 1'b0;
376 m_axi4_wdata = 'b0;
377 m_axi4_wstrb = 'b0;
378 m_axi4_wuser = 'b0;
379
380 m_axi4_wvalid = 1'b0;
381 axi4_wready = 1'b0;
382
383 hum_buf_valid_in = 1'b0;
384 hum_buf_ready_in = 1'b0;
385
386 hum_buf_drop_req_SN = hum_buf_drop_req_SP;
387 hum_buf_drop_len_SN = hum_buf_drop_len_SP;
388 master_select_o = 1'b0;
389
390 w_done = 1'b0; // read from FIFO without handshake with B sender
391 b_drop_o = 1'b0; // send data from FIFO to B sender (with handshake)
392 fifo_select = 1'b0;
393
394 fifo_select_SN = fifo_select_SP;
395 stop_store = 1'b0;
396
397 block_forwarding = 1'b0;
398
399 unique case (hum_buf_SP)
400
401 STORE : begin
402 // Simply store the data in the buffer.
403 hum_buf_valid_in = axi4_wvalid & hum_buf_ready_out;
404 axi4_wready = hum_buf_ready_out;
405
406 // We have got a full burst in the HUM buffer, thus stop storing.
407 if (wlast_in & !hum_buf_underfull | (n_wlast_SP > $signed(0))) begin
408 hum_buf_SN = WAIT_L1_BYPASS_YES;
409
410 // The buffer is full, thus wait for decision.
411 end else if (~hum_buf_ready_out) begin
412 hum_buf_SN = WAIT_L1_BYPASS_NO;
413 end
414
415 // Avoid the forwarding of L1 hits until we know whether we can bypass.
416 if (l1_fifo_valid_out & l1_save_cur) begin
417 block_forwarding = 1'b1;
418 end
419 end
420
421 WAIT_L1_BYPASS_YES : begin
422 // Wait for orders from L1 TLB.
423 if (l1_fifo_valid_out) begin
424
425 // L1 hit - forward data from buffer
426 if (l1_accept_cur) begin
427 m_axi4_wlast = hum_buf_wlast;
428 m_axi4_wdata = hum_buf_wdata;
429 m_axi4_wstrb = hum_buf_wstrb;
430 m_axi4_wuser = hum_buf_wuser;
431
432 m_axi4_wvalid = hum_buf_valid_out;
433 hum_buf_ready_in = m_axi4_wready;
434
435 master_select_o = l1_master_cur;
436
437 // Detect last data beat.
438 if (wlast_out) begin
439 fifo_select = 1'b0;
440 w_done = 1'b1;
441 hum_buf_SN = STORE;
442 end
443
444 // L1 miss - wait for L2
445 end else if (l1_save_cur) begin
446 fifo_select = 1'b0;
447 w_done = 1'b1;
448 hum_buf_SN = WAIT_L2_BYPASS_YES;
449
450 // L1 prefetch, prot, multi - drop data
451 end else if (l1_drop_cur) begin
452 fifo_select_SN = 1'b0; // L1
453 hum_buf_drop_req_SN = 1'b1;
454 hum_buf_drop_len_SN = l1_len_cur;
455 hum_buf_SN = FLUSH;
456 end
457 end
458 end
459
460 WAIT_L2_BYPASS_YES : begin
461 // Wait for orders from L2 TLB.
462 if (l2_fifo_valid_out) begin
463
464 // L2 hit - forward data from buffer
465 if (l2_accept_cur) begin
466 m_axi4_wlast = hum_buf_wlast;
467 m_axi4_wdata = hum_buf_wdata;
468 m_axi4_wstrb = hum_buf_wstrb;
469 m_axi4_wuser = hum_buf_wuser;
470
471 m_axi4_wvalid = hum_buf_valid_out;
472 hum_buf_ready_in = m_axi4_wready;
473
474 master_select_o = l2_master_cur;
475
476 // Detect last data beat.
477 if (wlast_out) begin
478 fifo_select = 1'b1;
479 w_done = 1'b1;
480 hum_buf_SN = STORE;
481 end
482
483 // L2 miss/prefetch hit
484 end else if (l2_drop_cur) begin
485 fifo_select_SN = 1'b1; // L2
486 hum_buf_drop_req_SN = 1'b1;
487 hum_buf_drop_len_SN = l2_len_cur;
488 hum_buf_SN = FLUSH;
489 end
490
491 // While we wait for orders from L2 TLB, we can still drop and accept L1 transactions.
492 end else if (l1_fifo_valid_out) begin
493
494 // L1 hit
495 if (l1_accept_cur) begin
496 hum_buf_SN = BYPASS;
497
498 // L1 prefetch/prot/multi
499 end else if (l1_drop_cur) begin
500 hum_buf_SN = DISCARD;
501 end
502 end
503 end
504
505 FLUSH : begin
506 // Clear HUM buffer flush request.
507 hum_buf_drop_req_SN = 1'b0;
508
509 // perform handshake with B sender
510 fifo_select = fifo_select_SP;
511 b_drop_o = 1'b1;
512 if (b_done_i) begin
513 hum_buf_SN = STORE;
514 end
515 end
516
517 BYPASS : begin
518 // Forward one full transaction from input buffer.
519 m_axi4_wlast = axi4_wlast;
520 m_axi4_wdata = axi4_wdata;
521 m_axi4_wstrb = axi4_wstrb;
522 m_axi4_wuser = axi4_wuser;
523
524 m_axi4_wvalid = axi4_wvalid;
525 axi4_wready = m_axi4_wready;
526
527 master_select_o = l1_master_cur;
528
529 // We have got a full transaction.
530 if (axi4_wlast & axi4_wready & axi4_wvalid) begin
531 fifo_select = 1'b0;
532 w_done = 1'b1;
533 hum_buf_SN = WAIT_L2_BYPASS_YES;
534 end
535 end
536
537 DISCARD : begin
538 // Discard one full transaction from input buffer.
539 axi4_wready = 1'b1;
540
541 // We have got a full transaction.
542 if (axi4_wlast & axi4_wready & axi4_wvalid) begin
543 // Try to perform handshake with B sender.
544 fifo_select = 1'b0;
545 b_drop_o = 1'b1;
546 // We cannot wait here due to axi4_wready.
547 if (b_done_i) begin
548 hum_buf_SN = WAIT_L2_BYPASS_YES;
549 end else begin
550 hum_buf_SN = DISCARD_FINISH;
551 end
552 end
553 end
554
555 DISCARD_FINISH : begin
556 // Perform handshake with B sender.
557 fifo_select = 1'b0;
558 b_drop_o = 1'b1;
559 if (b_done_i) begin
560 hum_buf_SN = WAIT_L2_BYPASS_YES;
561 end
562 end
563
564 WAIT_L1_BYPASS_NO : begin
565 // Do not allow the forwarding of L1 hits.
566 block_forwarding = 1'b1;
567
568 // Wait for orders from L1 TLB.
569 if (l1_fifo_valid_out) begin
570
571 // L1 hit - forward data from/through HUM buffer and refill the buffer
572 if (l1_accept_cur) begin
573 // Forward data from HUM buffer.
574 m_axi4_wlast = hum_buf_wlast;
575 m_axi4_wdata = hum_buf_wdata;
576 m_axi4_wstrb = hum_buf_wstrb;
577 m_axi4_wuser = hum_buf_wuser;
578
579 m_axi4_wvalid = hum_buf_valid_out;
580 hum_buf_ready_in = m_axi4_wready;
581
582 master_select_o = l1_master_cur;
583
584 // Refill the HUM buffer. Stop when buffer full.
585 stop_store = ~hum_buf_ready_out;
586 hum_buf_valid_in = stop_store ? 1'b0 : axi4_wvalid ;
587 axi4_wready = stop_store ? 1'b0 : hum_buf_ready_out;
588
589 // Detect last data beat.
590 if (wlast_out) begin
591 fifo_select = 1'b0;
592 w_done = 1'b1;
593 if (~hum_buf_ready_out | hum_buf_almost_full) begin
594 hum_buf_SN = WAIT_L1_BYPASS_NO;
595 end else begin
596 hum_buf_SN = STORE;
597 end
598 end
599
600 // Allow the forwarding of L1 hits.
601 block_forwarding = 1'b0;
602
603 // L1 miss - wait for L2
604 end else if (l1_save_cur) begin
605 fifo_select = 1'b0;
606 w_done = 1'b1;
607 hum_buf_SN = WAIT_L2_BYPASS_NO;
608
609 // L1 prefetch, prot, multi - drop data
610 end else if (l1_drop_cur) begin
611 fifo_select_SN = 1'b0; // L1
612 hum_buf_drop_req_SN = 1'b1;
613 hum_buf_drop_len_SN = l1_len_cur;
614 hum_buf_SN = FLUSH;
615
616 // Allow the forwarding of L1 hits.
617 block_forwarding = 1'b0;
618 end
619 end
620 end
621
622 WAIT_L2_BYPASS_NO : begin
623 // Do not allow the forwarding of L1 hits.
624 block_forwarding = 1'b1;
625
626 // Wait for orders from L2 TLB.
627 if (l2_fifo_valid_out) begin
628
629 // L2 hit - forward first part from HUM buffer, rest from input buffer
630 if (l2_accept_cur) begin
631 // Forward data from HUM buffer.
632 m_axi4_wlast = hum_buf_wlast;
633 m_axi4_wdata = hum_buf_wdata;
634 m_axi4_wstrb = hum_buf_wstrb;
635 m_axi4_wuser = hum_buf_wuser;
636
637 m_axi4_wvalid = hum_buf_valid_out;
638 hum_buf_ready_in = m_axi4_wready;
639
640 master_select_o = l2_master_cur;
641
642 // Refill the HUM buffer. Stop when buffer full.
643 stop_store = ~hum_buf_ready_out;
644 hum_buf_valid_in = stop_store ? 1'b0 : axi4_wvalid ;
645 axi4_wready = stop_store ? 1'b0 : hum_buf_ready_out;
646
647 // Detect last data beat.
648 if (wlast_out) begin
649 fifo_select = 1'b1;
650 w_done = 1'b1;
651 if (~hum_buf_ready_out | hum_buf_almost_full) begin
652 hum_buf_SN = WAIT_L1_BYPASS_NO;
653 end else begin
654 hum_buf_SN = STORE;
655 end
656 end
657
658 // Allow the forwarding of L1 hits.
659 block_forwarding = 1'b0;
660
661 // L2 miss/prefetch hit - drop data
662 end else if (l2_drop_cur) begin
663 fifo_select_SN = 1'b1; // L2
664 hum_buf_drop_req_SN = 1'b1;
665 hum_buf_drop_len_SN = l2_len_cur;
666 hum_buf_SN = FLUSH;
667
668 // Allow the forwarding of L1 hits.
669 block_forwarding = 1'b0;
670 end
671 end
672 end
673
674
675 default: begin
676 hum_buf_SN = STORE;
677 end
678
679 endcase // hum_buf_SP
680 end // HUM_BUFFER_FSM
681
682 assign b_drop_set = 1'b0;
683
684 end else begin // HUM_BUFFER
685
686 // register to perform the handshake with B sender
687 always_ff @(posedge axi4_aclk or negedge axi4_arstn) begin
688 if (axi4_arstn == 0) begin
689 b_drop_o <= 1'b0;
690 end else if (b_done_i) begin
691 b_drop_o <= 1'b0;
692 end else if (b_drop_set) begin
693 b_drop_o <= 1'b1;;
694 end
695 end
696
697 always_comb begin : OUTPUT_CTRL
698
699 fifo_select = 1'b0;
700 w_done = 1'b0;
701 b_drop_set = 1'b0;
702
703 m_axi4_wlast = 1'b0;
704 m_axi4_wdata = 'b0;
705 m_axi4_wstrb = 'b0;
706 m_axi4_wuser = 'b0;
707
708 m_axi4_wvalid = 1'b0;
709 axi4_wready = 1'b0;
710
711 if (l1_fifo_valid_out) begin
712 // forward data
713 if (l1_accept_cur) begin
714 m_axi4_wlast = axi4_wlast;
715 m_axi4_wdata = axi4_wdata;
716 m_axi4_wstrb = axi4_wstrb;
717 m_axi4_wuser = axi4_wuser;
718
719 m_axi4_wvalid = axi4_wvalid;
720 axi4_wready = m_axi4_wready;
721
722 // Simply pop from FIFO upon last data beat.
723 w_done = axi4_wlast & axi4_wvalid & axi4_wready;
724
725 // discard entire burst
726 end else if (b_drop_o == 1'b0) begin
727 axi4_wready = 1'b1;
728
729 // Simply pop from FIFO upon last data beat. Perform handshake with B sender.
730 if (axi4_wlast & axi4_wvalid & axi4_wready)
731 b_drop_set = 1'b1;
732 end
733 end
734
735 end // OUTPUT_CTRL
736
737 assign master_select_o = l1_master_cur;
738 assign l2_fifo_ready_out = 1'b1;
739 assign block_forwarding = 1'b0;
740
741 // unused signals
742 assign hum_buf_ready_out = 1'b0;
743 assign hum_buf_valid_in = 1'b0;
744 assign hum_buf_ready_in = 1'b0;
745 assign hum_buf_valid_out = 1'b0;
746 assign hum_buf_wdata = 'b0;
747 assign hum_buf_wstrb = 'b0;
748 assign hum_buf_wlast = 1'b0;
749 assign hum_buf_wuser = 'b0;
750 assign hum_buf_drop_len_SN = 'b0;
751 assign hum_buf_drop_req_SN = 1'b0;
752 assign hum_buf_almost_full = 1'b0;
753
754 assign l2_fifo_valid_in = 1'b0;
755 assign l2_fifo_valid_out = 1'b0;
756 assign l2_prefetch_cur = 1'b0;
757 assign l2_hit_cur = 1'b0;
758 assign l2_id_cur = 'b0;
759 assign l2_len_cur = 'b0;
760 assign l2_master_cur = 1'b0;
761 assign l2_accept_cur = 1'b0;
762 assign l2_drop_cur = 1'b0;
763
764 assign l2_req = 1'b0;
765
766 assign fifo_select_SN = 1'b0;
767 assign fifo_select_SP = 1'b0;
768
769 assign stop_store = 1'b0;
770 assign n_wlast_SP = 'b0;
771 assign wlast_in = 1'b0;
772 assign wlast_out = 1'b0;
773
774 end // HUM_BUFFER
775
776 endgenerate
777 """