@@ -44,6 +44,12 @@ module axi_mux #(
44
44
parameter int unsigned NoSlvPorts = 32'd0 , // Number of slave ports
45
45
// Maximum number of outstanding transactions per write
46
46
parameter int unsigned MaxWTrans = 32'd8 ,
47
+ // Enable ACE support (ACE)
48
+ parameter bit Ace = 1'b0 ,
49
+ // Maximum number of outstanding transactions per B channel (ACE)
50
+ parameter int unsigned AceMaxBTrans = 32'd8 ,
51
+ // Maximum number of outstanding transactions per R channel (ACE)
52
+ parameter int unsigned AceMaxRTrans = 32'd8 ,
47
53
// If enabled, this multiplexer is purely combinatorial
48
54
parameter bit FallThrough = 1'b0 ,
49
55
// add spill register on write master ports, adds a cycle latency on write channels
@@ -52,7 +58,9 @@ module axi_mux #(
52
58
parameter bit SpillB = 1'b0 ,
53
59
// add spill register on read master ports, adds a cycle latency on read channels
54
60
parameter bit SpillAr = 1'b1 ,
55
- parameter bit SpillR = 1'b0
61
+ parameter bit SpillR = 1'b0 ,
62
+ // add registers on xACK ports, add a cycle latency on acknowledgment signals (ACE)
63
+ parameter bit AceRegAck = 1'b0
56
64
) (
57
65
input logic clk_i, // Clock
58
66
input logic rst_ni, // Asynchronous reset active low
@@ -135,6 +143,22 @@ module axi_mux #(
135
143
.ready_i ( slv_reqs_i[0 ].r_ready ),
136
144
.data_o ( slv_resps_o[0 ].r )
137
145
);
146
+ if (Ace) begin : gen_ace
147
+ if (AceRegAck) begin : gen_xack_regs
148
+ always_ff @ (posedge clk_i or negedge rst_ni) begin
149
+ if (! rst_ni) begin
150
+ mst_req_o.rack <= 1'b0 ;
151
+ mst_req_o.wack <= 1'b0 ;
152
+ end else begin
153
+ mst_req_o.rack <= slv_reqs_i[0 ].rack;
154
+ mst_req_o.wack <= slv_reqs_i[0 ].wack;
155
+ end
156
+ end
157
+ end else begin : gen_no_xack_reg
158
+ assign mst_req_o.rack = slv_reqs_i[0 ].rack;
159
+ assign mst_req_o.wack = slv_reqs_i[0 ].wack;
160
+ end
161
+ end
138
162
// Validate parameters.
139
163
// pragma translate_off
140
164
`ASSERT_INIT (CorrectIdWidthSlvAw, $bits (slv_reqs_i[0 ].aw.id) == SlvAxiIDWidth)
@@ -192,7 +216,7 @@ module axi_mux #(
192
216
193
217
// B channel spill reg
194
218
mst_b_chan_t mst_b_chan;
195
- logic mst_b_valid;
219
+ logic mst_b_valid, mst_b_ready ;
196
220
197
221
// AR channel for when spill is enabled
198
222
mst_ar_chan_t mst_ar_chan;
@@ -203,7 +227,10 @@ module axi_mux #(
203
227
204
228
// R channel spill reg
205
229
mst_r_chan_t mst_r_chan;
206
- logic mst_r_valid;
230
+ logic mst_r_valid, mst_r_ready;
231
+
232
+ // xACK FIFOs
233
+ logic rack_fifo_full, wack_fifo_full;
207
234
208
235
// --------------------------------------
209
236
// ID prepend for all slave ports
@@ -387,7 +414,8 @@ module axi_mux #(
387
414
assign slv_b_chans = { NoSlvPorts{ mst_b_chan}} ;
388
415
// control B channel handshake
389
416
assign switch_b_id = mst_b_chan.id[SlvAxiIDWidth+ : MstIdxBits];
390
- assign slv_b_valids = (mst_b_valid) ? (1 << switch_b_id) : '0 ;
417
+ assign slv_b_valids = (mst_b_valid && ! wack_fifo_full) ? (1 << switch_b_id) : '0 ;
418
+ assign mst_b_ready = slv_b_readies[switch_b_id] && ! wack_fifo_full;
391
419
392
420
spill_register # (
393
421
.T ( mst_b_chan_t ),
@@ -399,7 +427,7 @@ module axi_mux #(
399
427
.ready_o ( mst_req_o.b_ready ),
400
428
.data_i ( mst_resp_i.b ),
401
429
.valid_o ( mst_b_valid ),
402
- .ready_i ( slv_b_readies[switch_b_id] ),
430
+ .ready_i ( mst_b_ready ),
403
431
.data_o ( mst_b_chan )
404
432
);
405
433
@@ -446,7 +474,8 @@ module axi_mux #(
446
474
assign slv_r_chans = { NoSlvPorts{ mst_r_chan}} ;
447
475
// R channel handshake control
448
476
assign switch_r_id = mst_r_chan.id[SlvAxiIDWidth+ : MstIdxBits];
449
- assign slv_r_valids = (mst_r_valid) ? (1 << switch_r_id) : '0 ;
477
+ assign slv_r_valids = (mst_r_valid && ! rack_fifo_full) ? (1 << switch_r_id) : '0 ;
478
+ assign mst_r_ready = slv_r_readies[switch_r_id] && ! rack_fifo_full;
450
479
451
480
spill_register # (
452
481
.T ( mst_r_chan_t ),
@@ -458,9 +487,72 @@ module axi_mux #(
458
487
.ready_o ( mst_req_o.r_ready ),
459
488
.data_i ( mst_resp_i.r ),
460
489
.valid_o ( mst_r_valid ),
461
- .ready_i ( slv_r_readies[switch_r_id] ),
490
+ .ready_i ( mst_r_ready ),
462
491
.data_o ( mst_r_chan )
463
492
);
493
+
494
+ // --------------------------------------
495
+ // xACKs signals (ACE)
496
+ // --------------------------------------
497
+
498
+ if (Ace) begin : gen_ace
499
+
500
+ switch_id_t switch_wack_id, switch_rack_id;
501
+
502
+ fifo_v3 # (
503
+ .FALL_THROUGH (1'b0 ),
504
+ .DEPTH (AceMaxBTrans),
505
+ .dtype (switch_id_t)
506
+ ) i_switch_b_fifo (
507
+ .clk_i,
508
+ .rst_ni,
509
+ .flush_i (1'b0 ),
510
+ .testmode_i (1'b0 ),
511
+ .full_o (wack_fifo_full),
512
+ .empty_o (),
513
+ .usage_o (),
514
+ .data_i (switch_b_id),
515
+ .push_i (mst_resp_i.b_valid && mst_req_o.b_ready),
516
+ .data_o (switch_wack_id),
517
+ .pop_i (mst_req_o.wack)
518
+ );
519
+
520
+ fifo_v3 # (
521
+ .FALL_THROUGH (1'b0 ),
522
+ .DEPTH (AceMaxRTrans),
523
+ .dtype (switch_id_t)
524
+ ) i_switch_r_fifo (
525
+ .clk_i,
526
+ .rst_ni,
527
+ .flush_i (1'b0 ),
528
+ .testmode_i (1'b0 ),
529
+ .full_o (rack_fifo_full),
530
+ .empty_o (),
531
+ .usage_o (),
532
+ .data_i (switch_r_id),
533
+ .push_i (mst_resp_i.r_valid && mst_req_o.r_ready && mst_resp_i.r.last),
534
+ .data_o (switch_rack_id),
535
+ .pop_i (mst_req_o.rack)
536
+ );
537
+
538
+ if (AceRegAck) begin : gen_xack_regs
539
+ always_ff @ (posedge clk_i or negedge rst_ni) begin
540
+ if (! rst_ni) begin
541
+ mst_req_o.rack <= 1'b0 ;
542
+ mst_req_o.wack <= 1'b0 ;
543
+ end else begin
544
+ mst_req_o.rack <= slv_reqs_i[switch_wack_id].wack;
545
+ mst_req_o.wack <= slv_reqs_i[switch_rack_id].rack;
546
+ end
547
+ end
548
+ end else begin : gen_no_xack_reg
549
+ assign mst_req_o.wack = slv_reqs_i[switch_wack_id].wack;
550
+ assign mst_req_o.rack = slv_reqs_i[switch_rack_id].rack;
551
+ end
552
+ end else begin : gen_no_ace
553
+ assign rack_fifo_full = 1'b0 ;
554
+ assign wack_fifo_full = 1'b0 ;
555
+ end
464
556
end
465
557
466
558
// pragma translate_off
0 commit comments