Skip to content

Commit

Permalink
axi_mcast_xbar: Add option to multicast to default slave
Browse files Browse the repository at this point in the history
  • Loading branch information
colluca committed Nov 7, 2023
1 parent ffcbdb0 commit cb979cb
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 22 deletions.
61 changes: 41 additions & 20 deletions src/axi_mcast_demux.sv
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ module axi_mcast_demux #(
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 int unsigned NoMulticastRules = 32'd0,
parameter int unsigned NoMulticastPorts = 32'd0,
parameter int unsigned MaxMcastTrans = 32'd7,
parameter int unsigned McastToDefaultSlave = 1'b0,
// 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,
Expand Down Expand Up @@ -186,11 +187,13 @@ module axi_mcast_demux #(

// AW address decoder
mask_rule_t [NoMulticastRules-1:0] multicast_rules;
logic idx_decoder_en_default, mask_decoder_en_default;
decode_idx_t dec_aw_idx;
logic dec_aw_idx_valid, dec_aw_idx_error;
logic [NoMulticastPorts-1:0] dec_aw_select_partial;
logic [NoMulticastPorts-1:0] dec_aw_select_partial, dec_aw_select_mask;
aw_addr_t [NoMulticastPorts-1:0] dec_aw_addr, dec_aw_mask;
logic dec_aw_select_error;
logic dec_aw_valid, dec_aw_select_error;
logic [NoMstPorts-2:0] dec_aw_idx_mask;
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;
Expand Down Expand Up @@ -307,12 +310,12 @@ module axi_mcast_demux #(
.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)
.en_default_idx_i(idx_decoder_en_default),
.default_idx_i (default_mst_port_i)
);
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_valid = 0;
assign dec_aw_idx_error = (!McastToDefaultSlave) ? !en_default_mst_port_i : 1'b1;
assign dec_aw_idx = default_mst_port_i;
end

Expand All @@ -334,19 +337,37 @@ module axi_mcast_demux #(
.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)
.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_aw_valid),
.dec_error_o (dec_aw_select_error),
.en_default_idx_i(mask_decoder_en_default),
.default_idx_i (default_mst_port_i)
);

// 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;
// Enable default slave either on the regular address decoder or on the multi-address decoder.
// The multi-address decoder should be selected if the default slave can be a multicast target,
// whereas the regular address decoder should be selected when the default slave is not
// configured to be a multicast target (!McastToDefaultSlave).
assign idx_decoder_en_default = (!McastToDefaultSlave) && en_default_mst_port_i;
assign mask_decoder_en_default = McastToDefaultSlave && en_default_mst_port_i;

// Combine output from the two address decoders.
// Note: assumes the slaves targeted by multicast lie at the lower indices.
// The two address decoders use two disjoint address maps, so it is guaranteed that only one
// at a time has valid output. This is true so long as the default slave is not enabled. In
// this case, one address decoder might match the default slave while the other matches a
// regular rule. We must prevent this, and only select the default slave if the other decoder
// had no match.
// TODO
assign idx_decoder_default_valid = idx_decoder_en_default && !dec_aw_idx_valid && !dec_aw_valid;
assign dec_aw_idx_mask = (dec_aw_idx_valid || idx_decoder_default_valid) << dec_aw_idx;
assign dec_aw_select_mask = dec_aw_select_partial & ~{NoMulticastPorts{dec_aw_idx_valid}};
assign dec_aw_select = dec_aw_idx_mask | dec_aw_select_mask;

assign slv_aw_select_mask = (dec_aw_idx_error && dec_aw_select_error) ?
{1'b1, {(NoMstPorts-1){1'b0}}} : {1'b0, dec_aw_select};
Expand Down
5 changes: 3 additions & 2 deletions src/axi_mcast_xbar.sv
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ import cf_math_pkg::idx_width;
.SpillR ( Cfg.LatencyMode[5] ),
.rule_t ( rule_t ),
.NoAddrRules ( Cfg.NoAddrRules ),
.NoMulticastRules( Cfg.NoMulticastRules ),
.NoMulticastPorts( Cfg.NoMulticastPorts )
.NoMulticastRules ( Cfg.NoMulticastRules ),
.NoMulticastPorts ( Cfg.NoMulticastPorts ),
.McastToDefaultSlave( Cfg.McastToDefaultSlave )
) i_axi_demux (
.clk_i, // Clock
.rst_ni, // Asynchronous reset active low
Expand Down
2 changes: 2 additions & 0 deletions src/axi_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,8 @@ package axi_pkg;
/// Number of master ports of the crossbar which can be targets of a multicast request.
/// These are assumed to be connected at the lower indices.
int unsigned NoMulticastPorts;
/// Whether the default slave (if any) is considered for multicast requests.
bit McastToDefaultSlave;
} xbar_cfg_t;

/// Commonly used rule types for `axi_xbar` (64-bit addresses).
Expand Down

0 comments on commit cb979cb

Please sign in to comment.