From 79a99e39e474be50b5dc9bb907c077f92e695718 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Tue, 15 Jul 2025 11:29:36 +0200 Subject: [PATCH 01/12] tb_axi_mcast_xbar_pkg: Report error when tests_conducted > tests_expected --- test/tb_axi_mcast_xbar_pkg.sv | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/tb_axi_mcast_xbar_pkg.sv b/test/tb_axi_mcast_xbar_pkg.sv index 7fe7bd520..16fc7ddfb 100644 --- a/test/tb_axi_mcast_xbar_pkg.sv +++ b/test/tb_axi_mcast_xbar_pkg.sv @@ -588,6 +588,9 @@ package tb_axi_mcast_xbar_pkg; if (tests_conducted < tests_expected) begin $error("Some of the expected tests were not conducted!"); end + if (tests_conducted > tests_expected) begin + $error("Conducted more than the expected tests!"); + end endtask : print_result endclass : axi_mcast_xbar_monitor endpackage From a317fac2c9ed2d69a7b8b328f40b25df892eef4a Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 26 May 2025 14:29:10 +0200 Subject: [PATCH 02/12] (feat) Introduce option to forward all collectiv operation to the default port independent of the address mapping * Add collectiv operation connectivity matrix * Decode the unicast and multicast seperatly --- src/axi_mcast_demux.sv | 214 ++++++++++++++++++++++------------------- src/axi_mcast_xbar.sv | 51 +++++----- 2 files changed, 143 insertions(+), 122 deletions(-) diff --git a/src/axi_mcast_demux.sv b/src/axi_mcast_demux.sv index d994ec325..96c863061 100644 --- a/src/axi_mcast_demux.sv +++ b/src/axi_mcast_demux.sv @@ -39,38 +39,38 @@ /// Beats on the B and R channel are multiplexed from the master ports to the slave port with /// a round-robin arbitration tree. module axi_mcast_demux #( - parameter int unsigned AxiIdWidth = 32'd0, - parameter bit AtopSupport = 1'b1, - parameter type aw_addr_t = logic, - parameter type aw_chan_t = logic, - parameter type w_chan_t = logic, - parameter type b_chan_t = logic, - parameter type ar_chan_t = logic, - parameter type r_chan_t = logic, - parameter type axi_req_t = logic, - parameter type axi_resp_t = logic, - parameter int unsigned NoMstPorts = 32'd0, + parameter int unsigned AxiIdWidth = 32'd0, + parameter bit AtopSupport = 1'b1, + parameter type aw_addr_t = logic, + parameter type aw_chan_t = logic, + parameter type w_chan_t = logic, + parameter type b_chan_t = logic, + parameter type ar_chan_t = logic, + parameter type r_chan_t = logic, + parameter type axi_req_t = logic, + parameter type axi_resp_t = logic, + parameter int unsigned NoMstPorts = 32'd0, /// Connectivity vector - parameter bit [NoMstPorts-1:0] Connectivity = '1, - parameter int unsigned MaxTrans = 32'd8, - parameter int unsigned AxiLookBits = 32'd3, - parameter bit UniqueIds = 1'b0, - parameter bit SpillAw = 1'b1, - parameter bit SpillW = 1'b0, - parameter bit SpillB = 1'b0, - parameter bit SpillAr = 1'b1, - parameter bit SpillR = 1'b0, - parameter type rule_t = logic, - parameter int unsigned NoAddrRules = 32'd0, - parameter int unsigned NoMulticastRules = 32'd0, - parameter int unsigned NoMulticastPorts = 32'd0, - parameter int unsigned MaxMcastTrans = 32'd7, + parameter bit [NoMstPorts-1:0] Connectivity = '1, + /// Collective Operation Connectivity (to mask certain outputs for coll operations) + parameter bit [NoMstPorts-1:0] CollectiveOpsConnectivity = '1, + parameter int unsigned MaxTrans = 32'd8, + parameter int unsigned AxiLookBits = 32'd3, + parameter bit UniqueIds = 1'b0, + parameter bit SpillAw = 1'b1, + parameter bit SpillW = 1'b0, + parameter bit SpillB = 1'b0, + parameter bit SpillAr = 1'b1, + parameter bit SpillR = 1'b0, + parameter type rule_t = logic, + parameter int unsigned NoAddrRules = 32'd0, + parameter int unsigned NoMulticastRules = 32'd0, + parameter int unsigned NoMulticastPorts = 32'd0, + parameter int unsigned MaxMcastTrans = 32'd7, // Dependent parameters, DO NOT OVERRIDE! - parameter int unsigned DecodeIdxWidth = ((NoMstPorts - 1) > 32'd1) ? $clog2(NoMstPorts - 1) : 32'd1, - parameter int unsigned IdxSelectWidth = (NoMstPorts > 32'd1) ? $clog2(NoMstPorts) : 32'd1, - parameter type decode_idx_t = logic [DecodeIdxWidth-1:0], - parameter type idx_select_t = logic [IdxSelectWidth-1:0], - parameter type mask_select_t = logic [NoMstPorts-1:0] + parameter int unsigned IdxSelectWidth = (NoMstPorts > 32'd1) ? $clog2(NoMstPorts) : 32'd1, + parameter type idx_select_t = logic [IdxSelectWidth-1:0], + parameter type mask_select_t = logic [NoMstPorts-1:0] ) ( input logic clk_i, input logic rst_ni, @@ -187,17 +187,24 @@ module axi_mcast_demux #( logic slv_aw_ready; // AW address decoder - mask_rule_t [NoMulticastRules-1:0] multicast_rules; - mask_rule_t default_rule; - decode_idx_t dec_aw_idx; - logic dec_aw_idx_valid, dec_aw_idx_error; - logic [NoMulticastPorts-1:0] dec_aw_select_partial; - aw_addr_t [NoMulticastPorts-1:0] dec_aw_addr, dec_aw_mask; - logic dec_aw_select_error; - logic [NoMstPorts-2:0] dec_aw_select; - aw_addr_t [NoMstPorts-1:0] slv_aw_addr, slv_aw_mask; - mask_select_t slv_aw_select_mask; - idx_select_t slv_aw_select; + mask_rule_t [NoMulticastRules-1:0] multicast_rules; + mask_rule_t default_rule; + + idx_select_t dec_aw_unicast_selected_idx; + logic [NoMstPorts-1:0] dec_aw_unicast_selected_out; + logic dec_aw_unicast_valid; + logic dec_aw_unicast_error; + + logic [NoMulticastPorts-1:0] dec_aw_multicast_selected_out; + aw_addr_t [NoMulticastPorts-1:0] dec_aw_multicast_addr; + aw_addr_t [NoMulticastPorts-1:0] dec_aw_multicast_mask; + logic dec_aw_multicast_valid; + logic dec_aw_multicast_error; + + aw_addr_t [NoMstPorts-1:0] slv_aw_addr; + aw_addr_t [NoMstPorts-1:0] slv_aw_mask; + mask_select_t slv_aw_select_mask; + idx_select_t slv_aw_select; // AW channel to slave ports logic [NoMstPorts-1:0] mst_aw_valids, mst_aw_readies; @@ -214,7 +221,6 @@ module axi_mcast_demux #( logic multicast_stall; mask_select_t multicast_select_q, multicast_select_d; mcast_cnt_t outstanding_mcast_cnt_q, outstanding_mcast_cnt_d; - logic [$clog2(NoMstPorts)+1-1:0] aw_select_popcount; logic accept_aw; logic mcast_aw_hs_in_progress; @@ -297,28 +303,6 @@ module axi_mcast_demux #( .data_o ( slv_aw_chan ) ); - if (NoMulticastRules != NoAddrRules) begin : g_aw_idx_decode - // Compare request against {start_addr, end_addr} rules - addr_decode #( - .NoIndices(NoMstPorts - 1), - .NoRules (NoAddrRules - NoMulticastRules), - .addr_t (aw_addr_t), - .rule_t (rule_t) - ) i_axi_aw_idx_decode ( - .addr_i (slv_aw_chan.addr), - .addr_map_i (addr_map_i[NoAddrRules-1:NoMulticastRules]), - .idx_o (dec_aw_idx), - .dec_valid_o (dec_aw_idx_valid), - .dec_error_o (dec_aw_idx_error), - .en_default_idx_i(1'b0), - .default_idx_i ('0) - ); - end else begin : g_no_aw_idx_decode - assign dec_aw_idx_valid = 1'b0; - assign dec_aw_idx_error = 1'b1; - assign dec_aw_idx = '0; - end - // Convert multicast rules to mask (NAPOT) form // - mask = {'0, {log2(end_addr - start_addr){1'b1}}} // - addr = start_addr / (end_addr - start_addr) @@ -333,36 +317,77 @@ module axi_mcast_demux #( assign default_rule.mask = default_mst_port_i.end_addr - default_mst_port_i.start_addr - 1; assign default_rule.addr = default_mst_port_i.start_addr; - // Compare request against {addr, mask} rules - multiaddr_decode #( - .NoIndices(NoMulticastPorts), - .NoRules(NoMulticastRules), - .addr_t (aw_addr_t), - .rule_t (mask_rule_t) - ) i_axi_aw_mask_decode ( - .addr_map_i (multicast_rules), - .addr_i (slv_aw_chan.addr), - .mask_i (slv_aw_chan.user.mcast), - .select_o (dec_aw_select_partial), - .addr_o (dec_aw_addr), - .mask_o (dec_aw_mask), - .dec_valid_o(), - .dec_error_o(dec_aw_select_error), - .en_default_idx_i(en_default_mst_port_i), - .default_idx_i (default_rule) + // Provide the address decoding for the unicast case + addr_decode #( + .NoIndices (NoMstPorts), + .NoRules (NoAddrRules), + .addr_t (aw_addr_t), + .rule_t (rule_t) + ) i_axi_aw_idx_unicast_decode ( + .addr_i (slv_aw_chan.addr), + .addr_map_i (addr_map_i), + .idx_o (dec_aw_unicast_selected_idx), + .dec_valid_o (dec_aw_unicast_valid), + .dec_error_o (dec_aw_unicast_error), + .en_default_idx_i (en_default_mst_port_i), + .default_idx_i (idx_select_t'(default_mst_port_i.idx)) ); - // Combine output from the two address decoders - // Note: assumes the slaves targeted by multicast lie at the lower indices - assign dec_aw_select = (dec_aw_idx_valid << dec_aw_idx) | dec_aw_select_partial; + // Generate the outmask from the idx + assign dec_aw_unicast_selected_out = (1'b1 << dec_aw_unicast_selected_idx); + + // Provide the address decoding for the multicast case + if (NoMulticastRules > 0) begin : gen_multicast_decoding + multiaddr_decode #( + .NoIndices (NoMulticastPorts), + .NoRules (NoMulticastRules), + .addr_t (aw_addr_t), + .rule_t (mask_rule_t) + ) i_axi_aw_multicast_decode ( + .addr_map_i (multicast_rules), + .addr_i (slv_aw_chan.addr), + .mask_i (slv_aw_chan.user.mcast), + .select_o (dec_aw_multicast_selected_out), + .addr_o (dec_aw_multicast_addr), + .mask_o (dec_aw_multicast_mask), + .dec_valid_o (dec_aw_multicast_valid), + .dec_error_o (dec_aw_multicast_error), + .en_default_idx_i (en_default_mst_port_i), + .default_idx_i (default_rule) + ); + end else begin + assign dec_aw_multicast_selected_out = '0; + assign dec_aw_multicast_addr = '0; + assign dec_aw_multicast_mask = '0; + assign dec_aw_multicast_valid = '0; + assign dec_aw_multicast_error = '0; + end - // Filter out messages on ports that are not connected, otherwise the error slave - // would respond with DECERR and, when merged with the other responses, this results - // in an error being returned to the master. - assign slv_aw_select_mask = (dec_aw_idx_error && dec_aw_select_error) ? - {1'b1, {(NoMstPorts-1){1'b0}}} : {1'b0, dec_aw_select & Connectivity}; - assign slv_aw_addr = {'0, {(NoMstPorts-NoMulticastPorts){slv_aw_chan.addr}}, dec_aw_addr}; - assign slv_aw_mask = {'0, dec_aw_mask}; + // Merge the signal between the multicast and the unicast + always_comb begin + // Set init values + slv_aw_select_mask = '0; + slv_aw_addr = '0; + slv_aw_mask = '0; + aw_is_multicast = '0; + + // decide if the aw request was unicast or multicast + if (slv_aw_chan.user.mcast == '0) begin : gen_unicast + aw_is_multicast = 1'b0; + slv_aw_select_mask = dec_aw_unicast_selected_out & Connectivity; + slv_aw_addr = {(NoMstPorts){slv_aw_chan.addr}}; + end else begin : gen_multicast + aw_is_multicast = 1'b1; + slv_aw_select_mask = {{(NoMstPorts-NoMulticastPorts){1'b0}}, dec_aw_multicast_selected_out} & CollectiveOpsConnectivity; + slv_aw_addr = {'0, {(NoMstPorts-NoMulticastPorts){slv_aw_chan.addr}}, dec_aw_multicast_addr}; + slv_aw_mask = {'0, dec_aw_multicast_mask}; + end + + // Overwrite the selection if we dedect an error > set the highest bit as these is the slave error + if (dec_aw_multicast_error && dec_aw_unicast_error) begin + slv_aw_select_mask = {1'b1, {(NoMstPorts-1){1'b0}}}; + end + end // Control of the AW handshake always_comb begin @@ -442,12 +467,6 @@ module axi_mcast_demux #( .bin (slv_aw_select) ); - // Popcount to identify multicast requests - popcount #(NoMstPorts) i_aw_select_popcount ( - .data_i (slv_aw_select_mask), - .popcount_o(aw_select_popcount) - ); - // While there can be multiple outstanding write transactions, i.e. // multiple AWs can be accepted before the corresponding Bs are returned, // in the case of multicast transactions this would require the need @@ -469,7 +488,6 @@ module axi_mcast_demux #( // We can slightly loosen this constraint, in the case of successive multicast // requests going to the same slaves. In this case, we don't need to buffer any // additional select signals. - assign aw_is_multicast = aw_select_popcount > 1; assign outstanding_multicast = outstanding_mcast_cnt_q != '0; assign multicast_stall = (outstanding_multicast && (slv_aw_select_mask != multicast_select_q)) || (aw_is_multicast && aw_any_outstanding_unicast_trx) || diff --git a/src/axi_mcast_xbar.sv b/src/axi_mcast_xbar.sv index 468768f33..16e3876ac 100644 --- a/src/axi_mcast_xbar.sv +++ b/src/axi_mcast_xbar.sv @@ -25,6 +25,8 @@ import cf_math_pkg::idx_width; parameter bit ATOPs = 1'b1, /// Connectivity matrix parameter bit [Cfg.NoSlvPorts-1:0][Cfg.NoMstPorts-1:0] Connectivity = '1, + /// Connectivity matrix for the collectiv operation + parameter bit [Cfg.NoSlvPorts-1:0][Cfg.NoMstPorts-1:0] CollectiveOpsConnectivity = '1, /// AXI4+ATOP AW channel struct type for the slave ports. parameter type slv_aw_chan_t = logic, /// AXI4+ATOP AW channel struct type for the master ports. @@ -141,30 +143,31 @@ import cf_math_pkg::idx_width; mst_port_idx_t'(Cfg.NoMstPorts) : mst_port_idx_t'(dec_ar_select); axi_mcast_demux #( - .AxiIdWidth ( Cfg.AxiIdWidthSlvPorts ), // ID Width - .AtopSupport ( ATOPs ), - .Connectivity ( Connectivity[i] ), - .aw_addr_t ( addr_t ), // AW Address Type - .aw_chan_t ( slv_aw_chan_t ), // AW Channel Type - .w_chan_t ( w_chan_t ), // W Channel Type - .b_chan_t ( slv_b_chan_t ), // B Channel Type - .ar_chan_t ( slv_ar_chan_t ), // AR Channel Type - .r_chan_t ( slv_r_chan_t ), // R Channel Type - .axi_req_t ( slv_req_t ), - .axi_resp_t ( slv_resp_t ), - .NoMstPorts ( Cfg.NoMstPorts + 1 ), - .MaxTrans ( Cfg.MaxMstTrans ), - .AxiLookBits ( Cfg.AxiIdUsedSlvPorts ), - .UniqueIds ( Cfg.UniqueIds ), - .SpillAw ( Cfg.LatencyMode[9] ), - .SpillW ( Cfg.LatencyMode[8] ), - .SpillB ( Cfg.LatencyMode[7] ), - .SpillAr ( Cfg.LatencyMode[6] ), - .SpillR ( Cfg.LatencyMode[5] ), - .rule_t ( rule_t ), - .NoAddrRules ( Cfg.NoAddrRules ), - .NoMulticastRules( Cfg.NoMulticastRules ), - .NoMulticastPorts( Cfg.NoMulticastPorts ) + .AxiIdWidth ( Cfg.AxiIdWidthSlvPorts ), // ID Width + .AtopSupport ( ATOPs ), + .Connectivity ( Connectivity[i] ), + .CollectiveOpsConnectivity( CollectiveOpsConnectivity[i]), + .aw_addr_t ( addr_t ), // AW Address Type + .aw_chan_t ( slv_aw_chan_t ), // AW Channel Type + .w_chan_t ( w_chan_t ), // W Channel Type + .b_chan_t ( slv_b_chan_t ), // B Channel Type + .ar_chan_t ( slv_ar_chan_t ), // AR Channel Type + .r_chan_t ( slv_r_chan_t ), // R Channel Type + .axi_req_t ( slv_req_t ), + .axi_resp_t ( slv_resp_t ), + .NoMstPorts ( Cfg.NoMstPorts + 1 ), + .MaxTrans ( Cfg.MaxMstTrans ), + .AxiLookBits ( Cfg.AxiIdUsedSlvPorts ), + .UniqueIds ( Cfg.UniqueIds ), + .SpillAw ( Cfg.LatencyMode[9] ), + .SpillW ( Cfg.LatencyMode[8] ), + .SpillB ( Cfg.LatencyMode[7] ), + .SpillAr ( Cfg.LatencyMode[6] ), + .SpillR ( Cfg.LatencyMode[5] ), + .rule_t ( rule_t ), + .NoAddrRules ( Cfg.NoAddrRules ), + .NoMulticastRules ( Cfg.NoMulticastRules ), + .NoMulticastPorts ( Cfg.NoMulticastPorts ) ) i_axi_demux ( .clk_i, // Clock .rst_ni, // Asynchronous reset active low From e6d1c1dd087c868ebfce156fdbd769ddb18cb31e Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Fri, 11 Jul 2025 12:19:01 +0200 Subject: [PATCH 03/12] axi_mcast_demux: Remove double space --- src/axi_mcast_demux.sv | 94 +++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/axi_mcast_demux.sv b/src/axi_mcast_demux.sv index 96c863061..bb07e5699 100644 --- a/src/axi_mcast_demux.sv +++ b/src/axi_mcast_demux.sv @@ -39,38 +39,38 @@ /// Beats on the B and R channel are multiplexed from the master ports to the slave port with /// a round-robin arbitration tree. module axi_mcast_demux #( - parameter int unsigned AxiIdWidth = 32'd0, - parameter bit AtopSupport = 1'b1, - parameter type aw_addr_t = logic, - parameter type aw_chan_t = logic, - parameter type w_chan_t = logic, - parameter type b_chan_t = logic, - parameter type ar_chan_t = logic, - parameter type r_chan_t = logic, - parameter type axi_req_t = logic, - parameter type axi_resp_t = logic, - parameter int unsigned NoMstPorts = 32'd0, + parameter int unsigned AxiIdWidth = 32'd0, + parameter bit AtopSupport = 1'b1, + parameter type aw_addr_t = logic, + parameter type aw_chan_t = logic, + parameter type w_chan_t = logic, + parameter type b_chan_t = logic, + parameter type ar_chan_t = logic, + parameter type r_chan_t = logic, + parameter type axi_req_t = logic, + parameter type axi_resp_t = logic, + parameter int unsigned NoMstPorts = 32'd0, /// Connectivity vector - parameter bit [NoMstPorts-1:0] Connectivity = '1, + parameter bit [NoMstPorts-1:0] Connectivity = '1, /// Collective Operation Connectivity (to mask certain outputs for coll operations) - parameter bit [NoMstPorts-1:0] CollectiveOpsConnectivity = '1, - parameter int unsigned MaxTrans = 32'd8, - parameter int unsigned AxiLookBits = 32'd3, - parameter bit UniqueIds = 1'b0, - parameter bit SpillAw = 1'b1, - parameter bit SpillW = 1'b0, - parameter bit SpillB = 1'b0, - parameter bit SpillAr = 1'b1, - parameter bit SpillR = 1'b0, - parameter type rule_t = logic, - parameter int unsigned NoAddrRules = 32'd0, - parameter int unsigned NoMulticastRules = 32'd0, - parameter int unsigned NoMulticastPorts = 32'd0, - parameter int unsigned MaxMcastTrans = 32'd7, + parameter bit [NoMstPorts-1:0] CollectiveOpsConnectivity = '1, + parameter int unsigned MaxTrans = 32'd8, + parameter int unsigned AxiLookBits = 32'd3, + parameter bit UniqueIds = 1'b0, + parameter bit SpillAw = 1'b1, + parameter bit SpillW = 1'b0, + parameter bit SpillB = 1'b0, + parameter bit SpillAr = 1'b1, + parameter bit SpillR = 1'b0, + parameter type rule_t = logic, + parameter int unsigned NoAddrRules = 32'd0, + parameter int unsigned NoMulticastRules = 32'd0, + parameter int unsigned NoMulticastPorts = 32'd0, + parameter int unsigned MaxMcastTrans = 32'd7, // Dependent parameters, DO NOT OVERRIDE! - parameter int unsigned IdxSelectWidth = (NoMstPorts > 32'd1) ? $clog2(NoMstPorts) : 32'd1, - parameter type idx_select_t = logic [IdxSelectWidth-1:0], - parameter type mask_select_t = logic [NoMstPorts-1:0] + parameter int unsigned IdxSelectWidth = (NoMstPorts > 32'd1) ? $clog2(NoMstPorts) : 32'd1, + parameter type idx_select_t = logic [IdxSelectWidth-1:0], + parameter type mask_select_t = logic [NoMstPorts-1:0] ) ( input logic clk_i, input logic rst_ni, @@ -187,24 +187,24 @@ module axi_mcast_demux #( logic slv_aw_ready; // AW address decoder - mask_rule_t [NoMulticastRules-1:0] multicast_rules; - mask_rule_t default_rule; - - idx_select_t dec_aw_unicast_selected_idx; - logic [NoMstPorts-1:0] dec_aw_unicast_selected_out; - logic dec_aw_unicast_valid; - logic dec_aw_unicast_error; - - logic [NoMulticastPorts-1:0] dec_aw_multicast_selected_out; - aw_addr_t [NoMulticastPorts-1:0] dec_aw_multicast_addr; - aw_addr_t [NoMulticastPorts-1:0] dec_aw_multicast_mask; - logic dec_aw_multicast_valid; - logic dec_aw_multicast_error; - - aw_addr_t [NoMstPorts-1:0] slv_aw_addr; - aw_addr_t [NoMstPorts-1:0] slv_aw_mask; - mask_select_t slv_aw_select_mask; - idx_select_t slv_aw_select; + mask_rule_t [NoMulticastRules-1:0] multicast_rules; + mask_rule_t default_rule; + + idx_select_t dec_aw_unicast_selected_idx; + logic [NoMstPorts-1:0] dec_aw_unicast_selected_out; + logic dec_aw_unicast_valid; + logic dec_aw_unicast_error; + + logic [NoMulticastPorts-1:0] dec_aw_multicast_selected_out; + aw_addr_t [NoMulticastPorts-1:0] dec_aw_multicast_addr; + aw_addr_t [NoMulticastPorts-1:0] dec_aw_multicast_mask; + logic dec_aw_multicast_valid; + logic dec_aw_multicast_error; + + aw_addr_t [NoMstPorts-1:0] slv_aw_addr; + aw_addr_t [NoMstPorts-1:0] slv_aw_mask; + mask_select_t slv_aw_select_mask; + idx_select_t slv_aw_select; // AW channel to slave ports logic [NoMstPorts-1:0] mst_aw_valids, mst_aw_readies; From e769b701b93e0f595fce1563f565d0c388ce0ba5 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Fri, 11 Jul 2025 12:29:24 +0200 Subject: [PATCH 04/12] axi_mcast_demux: Clean up comments and labels --- src/axi_mcast_demux.sv | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/axi_mcast_demux.sv b/src/axi_mcast_demux.sv index bb07e5699..41c7870eb 100644 --- a/src/axi_mcast_demux.sv +++ b/src/axi_mcast_demux.sv @@ -317,7 +317,7 @@ module axi_mcast_demux #( assign default_rule.mask = default_mst_port_i.end_addr - default_mst_port_i.start_addr - 1; assign default_rule.addr = default_mst_port_i.start_addr; - // Provide the address decoding for the unicast case + // Address decoding for unicast requests addr_decode #( .NoIndices (NoMstPorts), .NoRules (NoAddrRules), @@ -333,10 +333,10 @@ module axi_mcast_demux #( .default_idx_i (idx_select_t'(default_mst_port_i.idx)) ); - // Generate the outmask from the idx + // Generate the output mask from the index assign dec_aw_unicast_selected_out = (1'b1 << dec_aw_unicast_selected_idx); - // Provide the address decoding for the multicast case + // Address decoding for multicast requests if (NoMulticastRules > 0) begin : gen_multicast_decoding multiaddr_decode #( .NoIndices (NoMulticastPorts), @@ -355,7 +355,7 @@ module axi_mcast_demux #( .en_default_idx_i (en_default_mst_port_i), .default_idx_i (default_rule) ); - end else begin + end else begin : gen_no_multicast_decoding assign dec_aw_multicast_selected_out = '0; assign dec_aw_multicast_addr = '0; assign dec_aw_multicast_mask = '0; @@ -363,27 +363,25 @@ module axi_mcast_demux #( assign dec_aw_multicast_error = '0; end - // Merge the signal between the multicast and the unicast + // Mux the multicast and unicast decoding outputs always_comb begin - // Set init values slv_aw_select_mask = '0; slv_aw_addr = '0; slv_aw_mask = '0; aw_is_multicast = '0; - // decide if the aw request was unicast or multicast - if (slv_aw_chan.user.mcast == '0) begin : gen_unicast + if (slv_aw_chan.user.mcast == '0) begin aw_is_multicast = 1'b0; slv_aw_select_mask = dec_aw_unicast_selected_out & Connectivity; slv_aw_addr = {(NoMstPorts){slv_aw_chan.addr}}; - end else begin : gen_multicast + end else begin aw_is_multicast = 1'b1; slv_aw_select_mask = {{(NoMstPorts-NoMulticastPorts){1'b0}}, dec_aw_multicast_selected_out} & CollectiveOpsConnectivity; slv_aw_addr = {'0, {(NoMstPorts-NoMulticastPorts){slv_aw_chan.addr}}, dec_aw_multicast_addr}; slv_aw_mask = {'0, dec_aw_multicast_mask}; end - // Overwrite the selection if we dedect an error > set the highest bit as these is the slave error + // Overwrite the selection if we detect an error > set the highest bit as these is the slave error if (dec_aw_multicast_error && dec_aw_unicast_error) begin slv_aw_select_mask = {1'b1, {(NoMstPorts-1){1'b0}}}; end From 355d035a7a2f07886568625f88253e288ecd3071 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Fri, 11 Jul 2025 12:38:47 +0200 Subject: [PATCH 05/12] axi_mcast_demux: Correct error slave logic --- src/axi_mcast_demux.sv | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/axi_mcast_demux.sv b/src/axi_mcast_demux.sv index 41c7870eb..b1a2d6db8 100644 --- a/src/axi_mcast_demux.sv +++ b/src/axi_mcast_demux.sv @@ -363,6 +363,11 @@ module axi_mcast_demux #( assign dec_aw_multicast_error = '0; end + // If the address decoding doesn't produce any match, the request + // is routed to the error slave, which lies at the highest index. + mask_select_t select_error_slave; + assign select_error_slave = 1'b1 << (NoMstPorts - 1); + // Mux the multicast and unicast decoding outputs always_comb begin slv_aw_select_mask = '0; @@ -372,18 +377,21 @@ module axi_mcast_demux #( if (slv_aw_chan.user.mcast == '0) begin aw_is_multicast = 1'b0; - slv_aw_select_mask = dec_aw_unicast_selected_out & Connectivity; slv_aw_addr = {(NoMstPorts){slv_aw_chan.addr}}; + if (dec_aw_unicast_error) begin + slv_aw_select_mask = select_error_slave; + end else begin + slv_aw_select_mask = dec_aw_unicast_selected_out & Connectivity; + end end else begin aw_is_multicast = 1'b1; - slv_aw_select_mask = {{(NoMstPorts-NoMulticastPorts){1'b0}}, dec_aw_multicast_selected_out} & CollectiveOpsConnectivity; slv_aw_addr = {'0, {(NoMstPorts-NoMulticastPorts){slv_aw_chan.addr}}, dec_aw_multicast_addr}; slv_aw_mask = {'0, dec_aw_multicast_mask}; - end - - // Overwrite the selection if we detect an error > set the highest bit as these is the slave error - if (dec_aw_multicast_error && dec_aw_unicast_error) begin - slv_aw_select_mask = {1'b1, {(NoMstPorts-1){1'b0}}}; + if (dec_aw_multicast_error) begin + slv_aw_select_mask = select_error_slave; + end else begin + slv_aw_select_mask = {{(NoMstPorts-NoMulticastPorts){1'b0}}, dec_aw_multicast_selected_out} & CollectiveOpsConnectivity; + end end end From 8491e9b8f7d1dece519f30ff9180b1272003d1e0 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Fri, 11 Jul 2025 12:41:50 +0200 Subject: [PATCH 06/12] axi_mcast_demux: Clean up RTL --- src/axi_mcast_demux.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/axi_mcast_demux.sv b/src/axi_mcast_demux.sv index b1a2d6db8..5827b1885 100644 --- a/src/axi_mcast_demux.sv +++ b/src/axi_mcast_demux.sv @@ -377,7 +377,7 @@ module axi_mcast_demux #( if (slv_aw_chan.user.mcast == '0) begin aw_is_multicast = 1'b0; - slv_aw_addr = {(NoMstPorts){slv_aw_chan.addr}}; + slv_aw_addr = {NoMstPorts{slv_aw_chan.addr}}; if (dec_aw_unicast_error) begin slv_aw_select_mask = select_error_slave; end else begin @@ -390,7 +390,7 @@ module axi_mcast_demux #( if (dec_aw_multicast_error) begin slv_aw_select_mask = select_error_slave; end else begin - slv_aw_select_mask = {{(NoMstPorts-NoMulticastPorts){1'b0}}, dec_aw_multicast_selected_out} & CollectiveOpsConnectivity; + slv_aw_select_mask = {'0, dec_aw_multicast_selected_out} & CollectiveOpsConnectivity; end end end From 2091238c0ab4602e9261c8d708648840974daff9 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Fri, 11 Jul 2025 12:43:24 +0200 Subject: [PATCH 07/12] axi_mcast_xbar: Minor cleanup --- src/axi_mcast_xbar.sv | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/axi_mcast_xbar.sv b/src/axi_mcast_xbar.sv index 16e3876ac..d66503426 100644 --- a/src/axi_mcast_xbar.sv +++ b/src/axi_mcast_xbar.sv @@ -25,7 +25,7 @@ import cf_math_pkg::idx_width; parameter bit ATOPs = 1'b1, /// Connectivity matrix parameter bit [Cfg.NoSlvPorts-1:0][Cfg.NoMstPorts-1:0] Connectivity = '1, - /// Connectivity matrix for the collectiv operation + /// Connectivity matrix for collective operations parameter bit [Cfg.NoSlvPorts-1:0][Cfg.NoMstPorts-1:0] CollectiveOpsConnectivity = '1, /// AXI4+ATOP AW channel struct type for the slave ports. parameter type slv_aw_chan_t = logic, @@ -143,31 +143,31 @@ import cf_math_pkg::idx_width; mst_port_idx_t'(Cfg.NoMstPorts) : mst_port_idx_t'(dec_ar_select); axi_mcast_demux #( - .AxiIdWidth ( Cfg.AxiIdWidthSlvPorts ), // ID Width - .AtopSupport ( ATOPs ), - .Connectivity ( Connectivity[i] ), - .CollectiveOpsConnectivity( CollectiveOpsConnectivity[i]), - .aw_addr_t ( addr_t ), // AW Address Type - .aw_chan_t ( slv_aw_chan_t ), // AW Channel Type - .w_chan_t ( w_chan_t ), // W Channel Type - .b_chan_t ( slv_b_chan_t ), // B Channel Type - .ar_chan_t ( slv_ar_chan_t ), // AR Channel Type - .r_chan_t ( slv_r_chan_t ), // R Channel Type - .axi_req_t ( slv_req_t ), - .axi_resp_t ( slv_resp_t ), - .NoMstPorts ( Cfg.NoMstPorts + 1 ), - .MaxTrans ( Cfg.MaxMstTrans ), - .AxiLookBits ( Cfg.AxiIdUsedSlvPorts ), - .UniqueIds ( Cfg.UniqueIds ), - .SpillAw ( Cfg.LatencyMode[9] ), - .SpillW ( Cfg.LatencyMode[8] ), - .SpillB ( Cfg.LatencyMode[7] ), - .SpillAr ( Cfg.LatencyMode[6] ), - .SpillR ( Cfg.LatencyMode[5] ), - .rule_t ( rule_t ), - .NoAddrRules ( Cfg.NoAddrRules ), - .NoMulticastRules ( Cfg.NoMulticastRules ), - .NoMulticastPorts ( Cfg.NoMulticastPorts ) + .AxiIdWidth ( Cfg.AxiIdWidthSlvPorts ), // ID Width + .AtopSupport ( ATOPs ), + .Connectivity ( Connectivity[i] ), + .CollectiveOpsConnectivity( CollectiveOpsConnectivity[i] ), + .aw_addr_t ( addr_t ), // AW Address Type + .aw_chan_t ( slv_aw_chan_t ), // AW Channel Type + .w_chan_t ( w_chan_t ), // W Channel Type + .b_chan_t ( slv_b_chan_t ), // B Channel Type + .ar_chan_t ( slv_ar_chan_t ), // AR Channel Type + .r_chan_t ( slv_r_chan_t ), // R Channel Type + .axi_req_t ( slv_req_t ), + .axi_resp_t ( slv_resp_t ), + .NoMstPorts ( Cfg.NoMstPorts + 1 ), + .MaxTrans ( Cfg.MaxMstTrans ), + .AxiLookBits ( Cfg.AxiIdUsedSlvPorts ), + .UniqueIds ( Cfg.UniqueIds ), + .SpillAw ( Cfg.LatencyMode[9] ), + .SpillW ( Cfg.LatencyMode[8] ), + .SpillB ( Cfg.LatencyMode[7] ), + .SpillAr ( Cfg.LatencyMode[6] ), + .SpillR ( Cfg.LatencyMode[5] ), + .rule_t ( rule_t ), + .NoAddrRules ( Cfg.NoAddrRules ), + .NoMulticastRules ( Cfg.NoMulticastRules ), + .NoMulticastPorts ( Cfg.NoMulticastPorts ) ) i_axi_demux ( .clk_i, // Clock .rst_ni, // Asynchronous reset active low From d0f19861670aac17fd2019faf367d13e58966eda Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Tue, 15 Jul 2025 16:01:43 +0200 Subject: [PATCH 08/12] axi_mcast_xbar: Update `axi_mcast_xbar_intf` --- src/axi_mcast_xbar.sv | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/axi_mcast_xbar.sv b/src/axi_mcast_xbar.sv index d66503426..38832f2c9 100644 --- a/src/axi_mcast_xbar.sv +++ b/src/axi_mcast_xbar.sv @@ -333,11 +333,7 @@ import cf_math_pkg::idx_width; AXI_BUS.Master mst_ports [Cfg.NoMstPorts-1:0], input rule_t [Cfg.NoAddrRules-1:0] addr_map_i, input logic [Cfg.NoSlvPorts-1:0] en_default_mst_port_i, -`ifdef VCS - input logic [Cfg.NoSlvPorts-1:0][MstPortsIdxWidth-1:0] default_mst_port_i -`else - input logic [Cfg.NoSlvPorts-1:0][idx_width(Cfg.NoMstPorts)-1:0] default_mst_port_i -`endif + input rule_t [Cfg.NoSlvPorts-1:0] default_mst_port_i ); localparam int unsigned AxiIdWidthMstPorts = Cfg.AxiIdWidthSlvPorts + $clog2(Cfg.NoSlvPorts); From 27f435ee6a992654b78fc2b77329dfeb2e7d707e Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Tue, 15 Jul 2025 16:18:17 +0200 Subject: [PATCH 09/12] tb_axi_mcast_xbar_pkg: Update error slave logic --- test/tb_axi_mcast_xbar_pkg.sv | 99 ++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/test/tb_axi_mcast_xbar_pkg.sv b/test/tb_axi_mcast_xbar_pkg.sv index 16fc7ddfb..2c87712f1 100644 --- a/test/tb_axi_mcast_xbar_pkg.sv +++ b/test/tb_axi_mcast_xbar_pkg.sv @@ -187,57 +187,70 @@ package tb_axi_mcast_xbar_pkg; // Get address information from request aw_addr = masters_axi[i].aw_addr; aw_mcast = masters_axi[i].aw_user[AxiAddrWidth-1:0]; - for (int k = 0; k < AxiAddrWidth; k++) - aw_addr_masked[k] = aw_mcast[k] ? 1'bx : aw_addr[k]; - $display("Trying to match: %b", aw_addr_masked); - - // Compare request against each multicast rule. We look at the rules starting from the - // last ones. In case of multiple rules matching for the same slave, we want only - // the last rule to have effect - for (int j = (NoMulticastRules - 1); j >= 0; j--) begin - - // Convert address rule to mask (NAPOT) form - rule_mask = AddrMap[j].end_addr - AddrMap[j].start_addr - 1; - rule_addr = AddrMap[j].start_addr; + + // Set decode error by default, reset if a rule is matched in the following + decerr = 1; + + // When a mask is present, multicast rules are used, otherwise the unicast rules are used. + if (aw_mcast != '0) begin + + // Log masked address for (int k = 0; k < AxiAddrWidth; k++) - addrmap_masked[k] = rule_mask[k] ? 1'bx : rule_addr[k]; - $display("With slave %3d : %b", AddrMap[j].idx, addrmap_masked); - - // Request goes to the slave if all bits match, out of those which are neither masked - // in the request nor in the addrmap rule - if (&(~(aw_addr ^ rule_addr) | rule_mask | aw_mcast)) begin - int unsigned slave_idx = AddrMap[j].idx; - - // Only push the request if we haven't already matched it with a previous rule - // for the same slave - if (!matched_slaves[slave_idx]) begin - matched_slaves[slave_idx] = 1'b1; - to_slave_idx.push_back(slave_idx); - mask_to_slave.push_back(aw_mcast & rule_mask); - addr_to_slave.push_back((~aw_mcast & aw_addr) | (aw_mcast & rule_addr)); - $display(" Push mask : %32b", aw_mcast & rule_mask); - $display(" Push address : %32b", (~aw_mcast & aw_addr) | (aw_mcast & rule_addr)); + aw_addr_masked[k] = aw_mcast[k] ? 1'bx : aw_addr[k]; + $display("Trying to match: %b", aw_addr_masked); + + // Compare request against each multicast rule. We look at the rules starting from the + // last ones. In case of multiple rules matching for the same slave, we want only + // the last rule to have effect + for (int j = (NoMulticastRules - 1); j >= 0; j--) begin + + // Convert address rule to mask (NAPOT) form + rule_mask = AddrMap[j].end_addr - AddrMap[j].start_addr - 1; + rule_addr = AddrMap[j].start_addr; + for (int k = 0; k < AxiAddrWidth; k++) + addrmap_masked[k] = rule_mask[k] ? 1'bx : rule_addr[k]; + $display("With slave %3d : %b", AddrMap[j].idx, addrmap_masked); + + // Request goes to the slave if all bits match, out of those which are neither masked + // in the request nor in the addrmap rule + if (&(~(aw_addr ^ rule_addr) | rule_mask | aw_mcast)) begin + int unsigned slave_idx = AddrMap[j].idx; + decerr = 0; + + // Only push the request if we haven't already matched it with a previous rule + // for the same slave + if (!matched_slaves[slave_idx]) begin + matched_slaves[slave_idx] = 1'b1; + to_slave_idx.push_back(slave_idx); + mask_to_slave.push_back(aw_mcast & rule_mask); + addr_to_slave.push_back((~aw_mcast & aw_addr) | (aw_mcast & rule_addr)); + $display(" Push mask : %32b", aw_mcast & rule_mask); + $display(" Push address : %32b", (~aw_mcast & aw_addr) | (aw_mcast & rule_addr)); + end end end - end + + end else begin - // Compare request against each interval-form rule. We look at the rules starting from - // the last ones. We ignore the case of multiple rules matching for the same slave - // (as is the case in tb_mcast_xbar_pkg.sv) - $display("Trying to match: %x", aw_addr); - for (int j = (NoAddrRules - 1); j >= NoMulticastRules; j--) begin - $display("With slave %3d : [%x, %x)", AddrMap[j].idx, AddrMap[j].start_addr, AddrMap[j].end_addr); - if ((aw_addr >= AddrMap[j].start_addr) && - (aw_addr < AddrMap[j].end_addr)) begin - to_slave_idx.push_back(AddrMap[j].idx); - addr_to_slave.push_back(aw_addr); - mask_to_slave.push_back('0); - $display(" Push address : %x", aw_addr); + // Compare request against each interval-form rule. We look at the rules starting from + // the last ones. We ignore the case of multiple rules matching for the same slave + // (as is the case in tb_mcast_xbar_pkg.sv) + $display("Trying to match: %x", aw_addr); + for (int j = (NoAddrRules - 1); j >= 0; j--) begin + $display("With slave %3d : [%x, %x)", AddrMap[j].idx, AddrMap[j].start_addr, AddrMap[j].end_addr); + if ((aw_addr >= AddrMap[j].start_addr) && + (aw_addr < AddrMap[j].end_addr)) begin + decerr = 0; + to_slave_idx.push_back(AddrMap[j].idx); + addr_to_slave.push_back(aw_addr); + mask_to_slave.push_back('0); + $display(" Push address : %x", aw_addr); + end end + end num_slaves_matched = to_slave_idx.size(); - decerr = num_slaves_matched == 0; // send the exp aw beats down into the queues of the selected slaves // when no decerror From 57ae807dc902640090c99d7021926f12dd06c2c7 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Tue, 15 Jul 2025 16:18:53 +0200 Subject: [PATCH 10/12] tb_axi_mcast_xbar_pkg: Clean up logging --- test/tb_axi_mcast_xbar_pkg.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/tb_axi_mcast_xbar_pkg.sv b/test/tb_axi_mcast_xbar_pkg.sv index 2c87712f1..99b9695d2 100644 --- a/test/tb_axi_mcast_xbar_pkg.sv +++ b/test/tb_axi_mcast_xbar_pkg.sv @@ -334,6 +334,7 @@ package tb_axi_mcast_xbar_pkg; incr_conducted_tests(4); // push the required w beats into the right fifo + $display(" Expect %0d W beats.", slaves_axi[i].aw_len + 1); incr_expected_tests(slaves_axi[i].aw_len + 1); for (int unsigned j = 0; j <= slaves_axi[i].aw_len; j++) begin exp_slv_w = (j == slaves_axi[i].aw_len) ? @@ -440,7 +441,7 @@ package tb_axi_mcast_xbar_pkg; incr_expected_tests(1); end // push the required r beats into the right fifo - $display(" Expect R response, len: %0d.", masters_axi[i].ar_len); + $display(" Expect R response, len: %0d.", mst_axi_len); for (int unsigned j = 0; j <= mst_axi_len; j++) begin exp_mst_r = (j == mst_axi_len) ? '{mst_axi_id: mst_axi_id, last: 1'b1} : '{mst_axi_id: mst_axi_id, last: 1'b0}; From 83f975b7cee975948551d25152ac05c9765690f4 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Tue, 15 Jul 2025 15:58:21 +0200 Subject: [PATCH 11/12] axi_mcast_demux: Revert critical changes --- src/axi_mcast_demux.sv | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/axi_mcast_demux.sv b/src/axi_mcast_demux.sv index 5827b1885..4ac2fd809 100644 --- a/src/axi_mcast_demux.sv +++ b/src/axi_mcast_demux.sv @@ -221,6 +221,7 @@ module axi_mcast_demux #( logic multicast_stall; mask_select_t multicast_select_q, multicast_select_d; mcast_cnt_t outstanding_mcast_cnt_q, outstanding_mcast_cnt_d; + logic [$clog2(NoMstPorts)+1-1:0] aw_select_popcount; logic accept_aw; logic mcast_aw_hs_in_progress; @@ -373,10 +374,8 @@ module axi_mcast_demux #( slv_aw_select_mask = '0; slv_aw_addr = '0; slv_aw_mask = '0; - aw_is_multicast = '0; if (slv_aw_chan.user.mcast == '0) begin - aw_is_multicast = 1'b0; slv_aw_addr = {NoMstPorts{slv_aw_chan.addr}}; if (dec_aw_unicast_error) begin slv_aw_select_mask = select_error_slave; @@ -384,7 +383,6 @@ module axi_mcast_demux #( slv_aw_select_mask = dec_aw_unicast_selected_out & Connectivity; end end else begin - aw_is_multicast = 1'b1; slv_aw_addr = {'0, {(NoMstPorts-NoMulticastPorts){slv_aw_chan.addr}}, dec_aw_multicast_addr}; slv_aw_mask = {'0, dec_aw_multicast_mask}; if (dec_aw_multicast_error) begin @@ -473,6 +471,12 @@ module axi_mcast_demux #( .bin (slv_aw_select) ); + // Popcount to identify multicast requests + popcount #(NoMstPorts) i_aw_select_popcount ( + .data_i (slv_aw_select_mask), + .popcount_o(aw_select_popcount) + ); + // While there can be multiple outstanding write transactions, i.e. // multiple AWs can be accepted before the corresponding Bs are returned, // in the case of multicast transactions this would require the need @@ -494,6 +498,7 @@ module axi_mcast_demux #( // We can slightly loosen this constraint, in the case of successive multicast // requests going to the same slaves. In this case, we don't need to buffer any // additional select signals. + assign aw_is_multicast = aw_select_popcount > 1; assign outstanding_multicast = outstanding_mcast_cnt_q != '0; assign multicast_stall = (outstanding_multicast && (slv_aw_select_mask != multicast_select_q)) || (aw_is_multicast && aw_any_outstanding_unicast_trx) || From 54f34008a999441c5e94c95679f5c2aeb4fe32d8 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Tue, 15 Jul 2025 16:26:31 +0200 Subject: [PATCH 12/12] axi_mcast_demux: Rename `mcast` field in awuser to `collective_mask` --- src/axi_mcast_demux.sv | 12 ++++++------ src/axi_mcast_xbar.sv | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/axi_mcast_demux.sv b/src/axi_mcast_demux.sv index 4ac2fd809..6e3561acc 100644 --- a/src/axi_mcast_demux.sv +++ b/src/axi_mcast_demux.sv @@ -347,7 +347,7 @@ module axi_mcast_demux #( ) i_axi_aw_multicast_decode ( .addr_map_i (multicast_rules), .addr_i (slv_aw_chan.addr), - .mask_i (slv_aw_chan.user.mcast), + .mask_i (slv_aw_chan.user.collective_mask), .select_o (dec_aw_multicast_selected_out), .addr_o (dec_aw_multicast_addr), .mask_o (dec_aw_multicast_mask), @@ -375,7 +375,7 @@ module axi_mcast_demux #( slv_aw_addr = '0; slv_aw_mask = '0; - if (slv_aw_chan.user.mcast == '0) begin + if (slv_aw_chan.user.collective_mask == '0) begin slv_aw_addr = {NoMstPorts{slv_aw_chan.addr}}; if (dec_aw_unicast_error) begin slv_aw_select_mask = select_error_slave; @@ -918,10 +918,10 @@ module axi_mcast_demux #( for (int unsigned i = 0; i < NoMstPorts; i++) begin // AW channel - mst_reqs_o[i].aw = slv_aw_chan; - mst_reqs_o[i].aw.addr = slv_aw_addr[i]; - mst_reqs_o[i].aw.user.mcast = slv_aw_mask[i]; - mst_reqs_o[i].aw_valid = mst_aw_valids[i]; + mst_reqs_o[i].aw = slv_aw_chan; + mst_reqs_o[i].aw.addr = slv_aw_addr[i]; + mst_reqs_o[i].aw.user.collective_mask = slv_aw_mask[i]; + mst_reqs_o[i].aw_valid = mst_aw_valids[i]; // W channel mst_reqs_o[i].w = slv_w_chan; diff --git a/src/axi_mcast_xbar.sv b/src/axi_mcast_xbar.sv index 38832f2c9..242a47907 100644 --- a/src/axi_mcast_xbar.sv +++ b/src/axi_mcast_xbar.sv @@ -344,9 +344,9 @@ import cf_math_pkg::idx_width; typedef logic [Cfg.AxiDataWidth -1:0] data_t; typedef logic [Cfg.AxiDataWidth/8 -1:0] strb_t; typedef logic [AXI_USER_WIDTH -1:0] user_t; - // AW channel adds multicast mask to USER signals + // AW channel adds collective mask to USER signals typedef struct packed { - addr_t mcast; + addr_t collective_mask; } aw_user_t; `AXI_TYPEDEF_AW_CHAN_T(mst_aw_chan_t, addr_t, id_mst_t, aw_user_t)