Skip to content

Commit d7b7105

Browse files
committed
axi_mcast_demux_mapped: Allow multicast XBAR with NoMulticastRules == 0
1 parent 6544830 commit d7b7105

File tree

1 file changed

+32
-30
lines changed

1 file changed

+32
-30
lines changed

src/axi_mcast_demux_mapped.sv

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ module axi_mcast_demux_mapped #(
207207
// -----------------
208208

209209
// AW decoder inputs
210-
mask_rule_t [NoMulticastRules-1:0] multicast_rules;
211-
mask_rule_t default_rule;
210+
mask_rule_t [axi_pkg::iomsb(NoMulticastRules):0] multicast_rules;
211+
mask_rule_t default_rule;
212212

213213
// AW unicast decoder outputs
214214
idx_select_t dec_aw_unicast_select_idx;
@@ -228,16 +228,6 @@ module axi_mcast_demux_mapped #(
228228
addr_t [NoMstPortsExt-1:0] dec_aw_addr;
229229
addr_t [NoMstPortsExt-1:0] dec_aw_mask;
230230

231-
// Convert multicast rules to mask (NAPOT) form, see https://arxiv.org/pdf/2502.19215
232-
for (genvar i = 0; i < NoMulticastRules; i++) begin : g_multicast_rules
233-
assign multicast_rules[i].idx = addr_map_i[i].idx;
234-
assign multicast_rules[i].mask = addr_map_i[i].end_addr - addr_map_i[i].start_addr - 1;
235-
assign multicast_rules[i].addr = addr_map_i[i].start_addr;
236-
end
237-
assign default_rule.idx = default_mst_port_i.idx;
238-
assign default_rule.mask = default_mst_port_i.end_addr - default_mst_port_i.start_addr - 1;
239-
assign default_rule.addr = default_mst_port_i.start_addr;
240-
241231
// Address decoding for unicast requests
242232
addr_decode #(
243233
.NoIndices (NoMstPorts),
@@ -257,8 +247,26 @@ module axi_mcast_demux_mapped #(
257247
// Generate the output mask from the index
258248
assign dec_aw_unicast_select_mask = 1'b1 << dec_aw_unicast_select_idx;
259249

260-
// Address decoding for multicast requests
261-
if (NoMulticastRules > 0) begin : gen_multicast_decoding
250+
// If the address decoding doesn't produce any match, the request
251+
// is routed to the error slave, which lies at the highest index.
252+
mask_select_t select_error_slave;
253+
assign select_error_slave = 1'b1 << NoMstPorts;
254+
255+
// Disable multicast only if NoMulticastPorts == 0. In some instances you may want to
256+
// match the multicast decoder's default port, even if NoMulticastRules == 0.
257+
if (NoMulticastPorts > 0) begin : gen_multicast
258+
259+
// Convert multicast rules to mask (NAPOT) form, see https://arxiv.org/pdf/2502.19215
260+
for (genvar i = 0; i < NoMulticastRules; i++) begin : g_multicast_rules
261+
assign multicast_rules[i].idx = addr_map_i[i].idx;
262+
assign multicast_rules[i].mask = addr_map_i[i].end_addr - addr_map_i[i].start_addr - 1;
263+
assign multicast_rules[i].addr = addr_map_i[i].start_addr;
264+
end
265+
assign default_rule.idx = default_mst_port_i.idx;
266+
assign default_rule.mask = default_mst_port_i.end_addr - default_mst_port_i.start_addr - 1;
267+
assign default_rule.addr = default_mst_port_i.start_addr;
268+
269+
// Address decoding for multicast requests.
262270
multiaddr_decode #(
263271
.NoIndices (NoMulticastPorts),
264272
.NoRules (NoMulticastRules),
@@ -276,21 +284,8 @@ module axi_mcast_demux_mapped #(
276284
.en_default_idx_i (en_default_mst_port_i),
277285
.default_idx_i (default_rule)
278286
);
279-
end else begin : gen_no_multicast_decoding
280-
assign dec_aw_multicast_select_mask = '0;
281-
assign dec_aw_multicast_addr = '0;
282-
assign dec_aw_multicast_mask = '0;
283-
assign dec_aw_multicast_valid = '0;
284-
assign dec_aw_multicast_error = '0;
285-
end
286-
287-
// If the address decoding doesn't produce any match, the request
288-
// is routed to the error slave, which lies at the highest index.
289-
mask_select_t select_error_slave;
290-
assign select_error_slave = 1'b1 << NoMstPorts;
291287

292-
// Mux the multicast and unicast decoding outputs
293-
if (NoMulticastRules > 0) begin : gen_decoding_mux
288+
// Mux the multicast and unicast decoding outputs.
294289
always_comb begin
295290
dec_aw_select_mask = '0;
296291
dec_aw_addr = '0;
@@ -313,7 +308,14 @@ module axi_mcast_demux_mapped #(
313308
end
314309
end
315310
end
316-
end else begin
311+
312+
end else begin : gen_no_multicast
313+
assign dec_aw_multicast_select_mask = '0;
314+
assign dec_aw_multicast_addr = '0;
315+
assign dec_aw_multicast_mask = '0;
316+
assign dec_aw_multicast_valid = '0;
317+
assign dec_aw_multicast_error = '0;
318+
317319
assign dec_aw_addr = {'0, {NoMstPorts{slv_req_cut.aw.addr}}};
318320
assign dec_aw_mask = '0;
319321
assign dec_aw_select_mask = (dec_aw_unicast_error) ? select_error_slave :
@@ -396,7 +398,7 @@ module axi_mcast_demux_mapped #(
396398
i, addr_map_i[i].start_addr, size))
397399
end
398400
// Default rule is only converted to mask form if there are any other multicast rules
399-
if (NoMulticastRules > 0) begin : gen_multicast_default_rule_assertion
401+
if (NoMulticastPorts > 0) begin : gen_multicast_default_rule_assertion
400402
addr_t size;
401403
assign size = default_mst_port_i.end_addr - default_mst_port_i.start_addr;
402404
`ASSERT(DefaultRuleSize,

0 commit comments

Comments
 (0)