From e4862ec32e7e6afe97c61a8ba73529f203db82cf Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Thu, 7 Dec 2023 12:18:20 +0100 Subject: [PATCH] axi_mcast_xbar: Add default port mechanism for multicast transactions --- src/axi_mcast_demux.sv | 28 +++++++++++++++++++++------- src/axi_mcast_xbar.sv | 21 +++++++-------------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/axi_mcast_demux.sv b/src/axi_mcast_demux.sv index a38780a1a..fe1713588 100644 --- a/src/axi_mcast_demux.sv +++ b/src/axi_mcast_demux.sv @@ -75,7 +75,7 @@ module axi_mcast_demux #( input logic test_i, input rule_t [NoAddrRules-1:0] addr_map_i, input logic en_default_mst_port_i, - input decode_idx_t default_mst_port_i, + input rule_t default_mst_port_i, // Slave Port input axi_req_t slv_req_i, input idx_select_t slv_ar_select_i, @@ -186,6 +186,7 @@ module axi_mcast_demux #( // 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; @@ -311,9 +312,9 @@ module axi_mcast_demux #( .default_idx_i ('0) ); end else begin : g_no_aw_idx_decode - assign dec_aw_idx_valid = en_default_mst_port_i & dec_aw_select_error; - assign dec_aw_idx_error = !en_default_mst_port_i; - assign dec_aw_idx = default_mst_port_i; + 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 @@ -326,6 +327,9 @@ module axi_mcast_demux #( assign multicast_rules[i].mask = addr_map_i[i].end_addr - addr_map_i[i].start_addr - 1; assign multicast_rules[i].addr = addr_map_i[i].start_addr; end + assign default_rule.idx = default_mst_port_i.idx; + 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 #( @@ -341,7 +345,9 @@ module axi_mcast_demux #( .addr_o (dec_aw_addr), .mask_o (dec_aw_mask), .dec_valid_o(), - .dec_error_o(dec_aw_select_error) + .dec_error_o(dec_aw_select_error), + .en_default_idx_i(en_default_mst_port_i), + .default_idx_i (default_rule) ); // Combine output from the two address decoders @@ -1115,8 +1121,12 @@ module axi_mcast_demux_intf #( input logic test_i, // Testmode enable input rule_t [NO_MST_PORTS-2:0] addr_map_i, input idx_select_t slv_ar_select_i, // has to be stable, when ar_valid + input logic en_default_mst_port_i, + input rule_t default_mst_port_i, AXI_BUS.Slave slv, // slave port - AXI_BUS.Master mst [NO_MST_PORTS-1:0] // master ports + AXI_BUS.Master mst [NO_MST_PORTS-1:0], // master ports + output logic [NO_MST_PORTS-1:0] mst_is_mcast_o, + output logic [NO_MST_PORTS-1:0] mst_aw_commit_o ); typedef logic [AXI_ID_WIDTH-1:0] id_t; @@ -1170,12 +1180,16 @@ module axi_mcast_demux_intf #( .rst_ni, // Asynchronous reset active low .test_i, // Testmode enable .addr_map_i ( addr_map_i ), + .en_default_mst_port_i ( en_default_mst_port_i ), + .default_mst_port_i ( default_mst_port_i ), // slave port .slv_req_i ( slv_req ), .slv_ar_select_i ( slv_ar_select_i ), .slv_resp_o ( slv_resp ), // master port .mst_reqs_o ( mst_req ), - .mst_resps_i ( mst_resp ) + .mst_resps_i ( mst_resp ), + .mst_is_mcast_o ( mst_is_mcast_o ), + .mst_aw_commit_o ( mst_aw_commit_o ) ); endmodule diff --git a/src/axi_mcast_xbar.sv b/src/axi_mcast_xbar.sv index 4195255be..1797adff8 100644 --- a/src/axi_mcast_xbar.sv +++ b/src/axi_mcast_xbar.sv @@ -82,17 +82,10 @@ import cf_math_pkg::idx_width; input rule_t [Cfg.NoAddrRules-1:0] addr_map_i, /// Enable default master port. input logic [Cfg.NoSlvPorts-1:0] en_default_mst_port_i, -`ifdef VCS - /// Enables a default master port for each slave port. When this is enabled unmapped - /// transactions get issued at the master port given by `default_mst_port_i`. - /// When not used, tie to `'0`. - input logic [Cfg.NoSlvPorts-1:0][MstPortsIdxWidth-1:0] default_mst_port_i -`else /// Enables a default master port for each slave port. When this is enabled unmapped /// transactions get issued at the master port given by `default_mst_port_i`. /// When not used, tie to `'0`. - 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 ); // Address type for individual address signals @@ -101,9 +94,13 @@ import cf_math_pkg::idx_width; `ifdef VCS localparam int unsigned MstPortsIdxWidthOne = (Cfg.NoMstPorts == 32'd1) ? 32'd1 : unsigned'($clog2(Cfg.NoMstPorts + 1)); + localparam int unsigned MstPortsIdxWidth = + (Cfg.NoMstPorts == 32'd1) ? 32'd1 : unsigned'($clog2(Cfg.NoMstPorts)); typedef logic [MstPortsIdxWidthOne-1:0] mst_port_idx_t; + typedef logic [MstPortsIdxWidth-1:0] mst_port_idx_m1_t; `else typedef logic [idx_width(Cfg.NoMstPorts + 1)-1:0] mst_port_idx_t; + typedef logic [idx_width(Cfg.NoMstPorts)-1:0] mst_port_idx_m1_t; `endif // signals from the axi_demuxes, one index more for decode error @@ -122,11 +119,7 @@ import cf_math_pkg::idx_width; slv_resp_t [Cfg.NoMstPorts-1:0][Cfg.NoSlvPorts-1:0] mst_resps; for (genvar i = 0; i < Cfg.NoSlvPorts; i++) begin : gen_slv_port_demux -`ifdef VCS - logic [MstPortsIdxWidth-1:0] dec_ar_select; -`else - logic [idx_width(Cfg.NoMstPorts)-1:0] dec_ar_select; -`endif + mst_port_idx_m1_t dec_ar_select; logic dec_ar_valid, dec_ar_error; mst_port_idx_t slv_ar_select; @@ -142,7 +135,7 @@ import cf_math_pkg::idx_width; .dec_valid_o ( dec_ar_valid ), .dec_error_o ( dec_ar_error ), .en_default_idx_i ( en_default_mst_port_i[i] ), - .default_idx_i ( default_mst_port_i[i] ) + .default_idx_i ( mst_port_idx_m1_t'(default_mst_port_i[i].idx) ) ); assign slv_ar_select = (dec_ar_error) ? mst_port_idx_t'(Cfg.NoMstPorts) : mst_port_idx_t'(dec_ar_select);