Skip to content

Commit

Permalink
axi_mcast_xbar: Add default port mechanism for multicast transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
colluca committed Dec 11, 2023
1 parent ffcbdb0 commit e89e3d1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 21 deletions.
28 changes: 21 additions & 7 deletions src/axi_mcast_demux.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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 #(
Expand All @@ -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
Expand Down Expand Up @@ -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 [NoMstPorts-1:0] mst_is_mcast_o,
output logic [NoMstPorts-1:0] mst_aw_commit_o
);

typedef logic [AXI_ID_WIDTH-1:0] id_t;
Expand Down Expand Up @@ -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
21 changes: 7 additions & 14 deletions src/axi_mcast_xbar.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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;

Expand All @@ -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);
Expand Down

0 comments on commit e89e3d1

Please sign in to comment.