Skip to content

Commit c8feb74

Browse files
authored
Merge pull request #196 from pulp-platform/fix-xbar-single-master-port
axi_xbar: Fix signal width for single master port
2 parents 5380c5f + d24303f commit c8feb74

File tree

5 files changed

+83
-70
lines changed

5 files changed

+83
-70
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1212
### Changed
1313

1414
### Fixed
15+
- `axi_xbar`: Fix signal width for single master port. Before this fix, a crossbar instantiated
16+
with a single master port would contain arrays with incorrect dimensions.
1517

1618

1719
## 0.31.0 - 2021-12-07

scripts/run_vsim.sh

+10-5
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,16 @@ exec_test() {
160160
done
161161
;;
162162
axi_xbar)
163-
for Atop in 0 1; do
164-
for Exclusive in 0 1; do
165-
for UniqueIds in 0 1; do
166-
call_vsim tb_axi_xbar -gTbEnAtop=$Atop -gTbEnExcl=$Exclusive \
167-
-gTbUniqueIds=$UniqueIds
163+
for NumMst in 1 6; do
164+
for NumSlv in 1 8; do
165+
for Atop in 0 1; do
166+
for Exclusive in 0 1; do
167+
for UniqueIds in 0 1; do
168+
call_vsim tb_axi_xbar -gTbNumMst=$NumMst -gTbNumSlv=$NumSlv \
169+
-gTbEnAtop=$Atop -gTbEnExcl=$Exclusive \
170+
-gTbUniqueIds=$UniqueIds
171+
done
172+
done
168173
done
169174
done
170175
done

src/axi_xbar.sv

+29-25
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
// axi_xbar: Fully-connected AXI4+ATOP crossbar with an arbitrary number of slave and master ports.
1717
// See `doc/axi_xbar.md` for the documentation, including the definition of parameters and ports.
18-
module axi_xbar #(
18+
module axi_xbar
19+
import cf_math_pkg::idx_width;
20+
#(
1921
parameter axi_pkg::xbar_cfg_t Cfg = '0,
2022
parameter bit ATOPs = 1'b1,
2123
parameter type slv_aw_chan_t = logic,
@@ -33,21 +35,21 @@ module axi_xbar #(
3335
parameter type mst_resp_t = logic,
3436
parameter type rule_t = axi_pkg::xbar_rule_64_t
3537
) (
36-
input logic clk_i,
37-
input logic rst_ni,
38-
input logic test_i,
39-
input slv_req_t [Cfg.NoSlvPorts-1:0] slv_ports_req_i,
40-
output slv_resp_t [Cfg.NoSlvPorts-1:0] slv_ports_resp_o,
41-
output mst_req_t [Cfg.NoMstPorts-1:0] mst_ports_req_o,
42-
input mst_resp_t [Cfg.NoMstPorts-1:0] mst_ports_resp_i,
43-
input rule_t [Cfg.NoAddrRules-1:0] addr_map_i,
44-
input logic [Cfg.NoSlvPorts-1:0] en_default_mst_port_i,
45-
input logic [Cfg.NoSlvPorts-1:0][$clog2(Cfg.NoMstPorts)-1:0] default_mst_port_i
38+
input logic clk_i,
39+
input logic rst_ni,
40+
input logic test_i,
41+
input slv_req_t [Cfg.NoSlvPorts-1:0] slv_ports_req_i,
42+
output slv_resp_t [Cfg.NoSlvPorts-1:0] slv_ports_resp_o,
43+
output mst_req_t [Cfg.NoMstPorts-1:0] mst_ports_req_o,
44+
input mst_resp_t [Cfg.NoMstPorts-1:0] mst_ports_resp_i,
45+
input rule_t [Cfg.NoAddrRules-1:0] addr_map_i,
46+
input logic [Cfg.NoSlvPorts-1:0] en_default_mst_port_i,
47+
input logic [Cfg.NoSlvPorts-1:0][idx_width(Cfg.NoMstPorts)-1:0] default_mst_port_i
4648
);
4749

4850
typedef logic [Cfg.AxiAddrWidth-1:0] addr_t;
4951
// to account for the decoding error slave
50-
typedef logic [$clog2(Cfg.NoMstPorts + 1)-1:0] mst_port_idx_t;
52+
typedef logic [idx_width(Cfg.NoMstPorts + 1)-1:0] mst_port_idx_t;
5153

5254
// signals from the axi_demuxes, one index more for decode error
5355
slv_req_t [Cfg.NoSlvPorts-1:0][Cfg.NoMstPorts:0] slv_reqs;
@@ -61,10 +63,10 @@ module axi_xbar #(
6163
slv_resp_t [Cfg.NoMstPorts-1:0][Cfg.NoSlvPorts-1:0] mst_resps;
6264

6365
for (genvar i = 0; i < Cfg.NoSlvPorts; i++) begin : gen_slv_port_demux
64-
logic [$clog2(Cfg.NoMstPorts)-1:0] dec_aw, dec_ar;
65-
mst_port_idx_t slv_aw_select, slv_ar_select;
66-
logic dec_aw_valid, dec_aw_error;
67-
logic dec_ar_valid, dec_ar_error;
66+
logic [idx_width(Cfg.NoMstPorts)-1:0] dec_aw, dec_ar;
67+
mst_port_idx_t slv_aw_select, slv_ar_select;
68+
logic dec_aw_valid, dec_aw_error;
69+
logic dec_ar_valid, dec_ar_error;
6870

6971
addr_decode #(
7072
.NoIndices ( Cfg.NoMstPorts ),
@@ -239,19 +241,21 @@ endmodule
239241
`include "axi/assign.svh"
240242
`include "axi/typedef.svh"
241243

242-
module axi_xbar_intf #(
244+
module axi_xbar_intf
245+
import cf_math_pkg::idx_width;
246+
#(
243247
parameter int unsigned AXI_USER_WIDTH = 0,
244248
parameter axi_pkg::xbar_cfg_t Cfg = '0,
245249
parameter type rule_t = axi_pkg::xbar_rule_64_t
246250
) (
247-
input logic clk_i,
248-
input logic rst_ni,
249-
input logic test_i,
250-
AXI_BUS.Slave slv_ports [Cfg.NoSlvPorts-1:0],
251-
AXI_BUS.Master mst_ports [Cfg.NoMstPorts-1:0],
252-
input rule_t [Cfg.NoAddrRules-1:0] addr_map_i,
253-
input logic [Cfg.NoSlvPorts-1:0] en_default_mst_port_i,
254-
input logic [Cfg.NoSlvPorts-1:0][$clog2(Cfg.NoMstPorts)-1:0] default_mst_port_i
251+
input logic clk_i,
252+
input logic rst_ni,
253+
input logic test_i,
254+
AXI_BUS.Slave slv_ports [Cfg.NoSlvPorts-1:0],
255+
AXI_BUS.Master mst_ports [Cfg.NoMstPorts-1:0],
256+
input rule_t [Cfg.NoAddrRules-1:0] addr_map_i,
257+
input logic [Cfg.NoSlvPorts-1:0] en_default_mst_port_i,
258+
input logic [Cfg.NoSlvPorts-1:0][idx_width(Cfg.NoMstPorts)-1:0] default_mst_port_i
255259
);
256260

257261
localparam int unsigned AxiIdWidthMstPorts = Cfg.AxiIdWidthSlvPorts + $clog2(Cfg.NoSlvPorts);

test/tb_axi_xbar.sv

+39-40
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,15 @@
2323
`include "axi/assign.svh"
2424

2525
module tb_axi_xbar #(
26-
parameter bit TbEnAtop = 1'b1, // enable atomic operations (ATOPs)
27-
parameter bit TbEnExcl = 1'b0, // enable exclusive accesses
28-
parameter bit TbUniqueIds = 1'b0 // restrict to only unique IDs
26+
parameter bit TbEnAtop = 1'b1, // enable atomic operations (ATOPs)
27+
parameter bit TbEnExcl = 1'b0, // enable exclusive accesses
28+
parameter bit TbUniqueIds = 1'b0, // restrict to only unique IDs
29+
parameter int unsigned TbNumMst = 32'd6, // how many AXI masters there are
30+
parameter int unsigned TbNumSlv = 32'd8 // how many AXI slaves there are
2931
);
30-
// Dut parameters
31-
localparam int unsigned NoMasters = 6; // How many Axi Masters there are
32-
localparam int unsigned NoSlaves = 8; // How many Axi Slaves there are
3332
// Random master no Transactions
34-
localparam int unsigned NoWrites = 125; // How many writes per master
35-
localparam int unsigned NoReads = 125; // How many reads per master
33+
localparam int unsigned NoWrites = 80; // How many writes per master
34+
localparam int unsigned NoReads = 80; // How many reads per master
3635
// timing parameters
3736
localparam time CyclTime = 10ns;
3837
localparam time ApplTime = 2ns;
@@ -41,15 +40,15 @@ module tb_axi_xbar #(
4140
// axi configuration
4241
localparam int unsigned AxiIdWidthMasters = 4;
4342
localparam int unsigned AxiIdUsed = 3; // Has to be <= AxiIdWidthMasters
44-
localparam int unsigned AxiIdWidthSlaves = AxiIdWidthMasters + $clog2(NoMasters);
43+
localparam int unsigned AxiIdWidthSlaves = AxiIdWidthMasters + $clog2(TbNumMst);
4544
localparam int unsigned AxiAddrWidth = 32; // Axi Address Width
4645
localparam int unsigned AxiDataWidth = 64; // Axi Data Width
4746
localparam int unsigned AxiStrbWidth = AxiDataWidth / 8;
4847
localparam int unsigned AxiUserWidth = 5;
4948
// in the bench can change this variables which are set here freely
5049
localparam axi_pkg::xbar_cfg_t xbar_cfg = '{
51-
NoSlvPorts: NoMasters,
52-
NoMstPorts: NoSlaves,
50+
NoSlvPorts: TbNumMst,
51+
NoMstPorts: TbNumSlv,
5352
MaxMstTrans: 10,
5453
MaxSlvTrans: 6,
5554
FallThrough: 1'b0,
@@ -86,14 +85,14 @@ module tb_axi_xbar #(
8685
`AXI_TYPEDEF_RESP_T(slv_resp_t, b_chan_slv_t, r_chan_slv_t)
8786

8887
localparam rule_t [xbar_cfg.NoAddrRules-1:0] AddrMap = '{
89-
'{idx: 32'd7, start_addr: 32'h0001_0000, end_addr: 32'h0001_1000},
90-
'{idx: 32'd6, start_addr: 32'h0000_9000, end_addr: 32'h0001_0000},
91-
'{idx: 32'd5, start_addr: 32'h0000_8000, end_addr: 32'h0000_9000},
92-
'{idx: 32'd4, start_addr: 32'h0000_7000, end_addr: 32'h0000_8000},
93-
'{idx: 32'd3, start_addr: 32'h0000_6300, end_addr: 32'h0000_7000},
94-
'{idx: 32'd2, start_addr: 32'h0000_4000, end_addr: 32'h0000_6300},
95-
'{idx: 32'd1, start_addr: 32'h0000_3000, end_addr: 32'h0000_4000},
96-
'{idx: 32'd0, start_addr: 32'h0000_0000, end_addr: 32'h0000_3000}
88+
'{idx: 32'd7 % TbNumSlv, start_addr: 32'h0001_0000, end_addr: 32'h0001_1000},
89+
'{idx: 32'd6 % TbNumSlv, start_addr: 32'h0000_9000, end_addr: 32'h0001_0000},
90+
'{idx: 32'd5 % TbNumSlv, start_addr: 32'h0000_8000, end_addr: 32'h0000_9000},
91+
'{idx: 32'd4 % TbNumSlv, start_addr: 32'h0000_7000, end_addr: 32'h0000_8000},
92+
'{idx: 32'd3 % TbNumSlv, start_addr: 32'h0000_6300, end_addr: 32'h0000_7000},
93+
'{idx: 32'd2 % TbNumSlv, start_addr: 32'h0000_4000, end_addr: 32'h0000_6300},
94+
'{idx: 32'd1 % TbNumSlv, start_addr: 32'h0000_3000, end_addr: 32'h0000_4000},
95+
'{idx: 32'd0 % TbNumSlv, start_addr: 32'h0000_0000, end_addr: 32'h0000_3000}
9796
};
9897

9998
typedef axi_test::axi_rand_master #(
@@ -129,15 +128,15 @@ module tb_axi_xbar #(
129128
logic clk;
130129
// DUT signals
131130
logic rst_n;
132-
logic [NoMasters-1:0] end_of_sim;
131+
logic [TbNumMst-1:0] end_of_sim;
133132

134133
// master structs
135-
mst_req_t [NoMasters-1:0] masters_req;
136-
mst_resp_t [NoMasters-1:0] masters_resp;
134+
mst_req_t [TbNumMst-1:0] masters_req;
135+
mst_resp_t [TbNumMst-1:0] masters_resp;
137136

138137
// slave structs
139-
slv_req_t [NoSlaves-1:0] slaves_req;
140-
slv_resp_t [NoSlaves-1:0] slaves_resp;
138+
slv_req_t [TbNumSlv-1:0] slaves_req;
139+
slv_resp_t [TbNumSlv-1:0] slaves_resp;
141140

142141
// -------------------------------
143142
// AXI Interfaces
@@ -147,20 +146,20 @@ module tb_axi_xbar #(
147146
.AXI_DATA_WIDTH ( AxiDataWidth ),
148147
.AXI_ID_WIDTH ( AxiIdWidthMasters ),
149148
.AXI_USER_WIDTH ( AxiUserWidth )
150-
) master [NoMasters-1:0] ();
149+
) master [TbNumMst-1:0] ();
151150
AXI_BUS_DV #(
152151
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
153152
.AXI_DATA_WIDTH ( AxiDataWidth ),
154153
.AXI_ID_WIDTH ( AxiIdWidthMasters ),
155154
.AXI_USER_WIDTH ( AxiUserWidth )
156-
) master_dv [NoMasters-1:0] (clk);
155+
) master_dv [TbNumMst-1:0] (clk);
157156
AXI_BUS_DV #(
158157
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
159158
.AXI_DATA_WIDTH ( AxiDataWidth ),
160159
.AXI_ID_WIDTH ( AxiIdWidthMasters ),
161160
.AXI_USER_WIDTH ( AxiUserWidth )
162-
) master_monitor_dv [NoMasters-1:0] (clk);
163-
for (genvar i = 0; i < NoMasters; i++) begin : gen_conn_dv_masters
161+
) master_monitor_dv [TbNumMst-1:0] (clk);
162+
for (genvar i = 0; i < TbNumMst; i++) begin : gen_conn_dv_masters
164163
`AXI_ASSIGN (master[i], master_dv[i])
165164
`AXI_ASSIGN_TO_REQ(masters_req[i], master[i])
166165
`AXI_ASSIGN_FROM_RESP(master[i], masters_resp[i])
@@ -171,20 +170,20 @@ module tb_axi_xbar #(
171170
.AXI_DATA_WIDTH ( AxiDataWidth ),
172171
.AXI_ID_WIDTH ( AxiIdWidthSlaves ),
173172
.AXI_USER_WIDTH ( AxiUserWidth )
174-
) slave [NoSlaves-1:0] ();
173+
) slave [TbNumSlv-1:0] ();
175174
AXI_BUS_DV #(
176175
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
177176
.AXI_DATA_WIDTH ( AxiDataWidth ),
178177
.AXI_ID_WIDTH ( AxiIdWidthSlaves ),
179178
.AXI_USER_WIDTH ( AxiUserWidth )
180-
) slave_dv [NoSlaves-1:0](clk);
179+
) slave_dv [TbNumSlv-1:0](clk);
181180
AXI_BUS_DV #(
182181
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
183182
.AXI_DATA_WIDTH ( AxiDataWidth ),
184183
.AXI_ID_WIDTH ( AxiIdWidthSlaves ),
185184
.AXI_USER_WIDTH ( AxiUserWidth )
186-
) slave_monitor_dv [NoSlaves-1:0](clk);
187-
for (genvar i = 0; i < NoSlaves; i++) begin : gen_conn_dv_slaves
185+
) slave_monitor_dv [TbNumSlv-1:0](clk);
186+
for (genvar i = 0; i < TbNumSlv; i++) begin : gen_conn_dv_slaves
188187
`AXI_ASSIGN(slave_dv[i], slave[i])
189188
`AXI_ASSIGN_FROM_REQ(slave[i], slaves_req[i])
190189
`AXI_ASSIGN_TO_RESP(slaves_resp[i], slave[i])
@@ -193,7 +192,7 @@ module tb_axi_xbar #(
193192
// AXI Rand Masters and Slaves
194193
// -------------------------------
195194
// Masters control simulation run time
196-
for (genvar i = 0; i < NoMasters; i++) begin : gen_rand_master
195+
for (genvar i = 0; i < TbNumMst; i++) begin : gen_rand_master
197196
static axi_rand_master_t axi_rand_master = new ( master_dv[i] );
198197
initial begin
199198
end_of_sim[i] <= 1'b0;
@@ -207,7 +206,7 @@ module tb_axi_xbar #(
207206
end
208207
end
209208

210-
for (genvar i = 0; i < NoSlaves; i++) begin : gen_rand_slave
209+
for (genvar i = 0; i < TbNumSlv; i++) begin : gen_rand_slave
211210
static axi_rand_slave_t axi_rand_slave = new( slave_dv[i] );
212211
initial begin
213212
axi_rand_slave.reset();
@@ -223,8 +222,8 @@ module tb_axi_xbar #(
223222
.AxiIdWidthMasters ( AxiIdWidthMasters ),
224223
.AxiIdWidthSlaves ( AxiIdWidthSlaves ),
225224
.AxiUserWidth ( AxiUserWidth ),
226-
.NoMasters ( NoMasters ),
227-
.NoSlaves ( NoSlaves ),
225+
.NoMasters ( TbNumMst ),
226+
.NoSlaves ( TbNumSlv ),
228227
.NoAddrRules ( xbar_cfg.NoAddrRules ),
229228
.rule_t ( rule_t ),
230229
.AddrMap ( AddrMap ),
@@ -273,7 +272,7 @@ module tb_axi_xbar #(
273272
);
274273

275274
// logger for master modules
276-
for (genvar i = 0; i < NoMasters; i++) begin : gen_master_logger
275+
for (genvar i = 0; i < TbNumMst; i++) begin : gen_master_logger
277276
axi_chan_logger #(
278277
.TestTime ( TestTime ), // Time after clock, where sampling happens
279278
.LoggerName( $sformatf("axi_logger_master_%0d", i)),
@@ -309,7 +308,7 @@ module tb_axi_xbar #(
309308
);
310309
end
311310
// logger for slave modules
312-
for (genvar i = 0; i < NoSlaves; i++) begin : gen_slave_logger
311+
for (genvar i = 0; i < TbNumSlv; i++) begin : gen_slave_logger
313312
axi_chan_logger #(
314313
.TestTime ( TestTime ), // Time after clock, where sampling happens
315314
.LoggerName( $sformatf("axi_logger_slave_%0d",i)),
@@ -346,7 +345,7 @@ module tb_axi_xbar #(
346345
end
347346

348347

349-
for (genvar i = 0; i < NoMasters; i++) begin : gen_connect_master_monitor
348+
for (genvar i = 0; i < TbNumMst; i++) begin : gen_connect_master_monitor
350349
assign master_monitor_dv[i].aw_id = master[i].aw_id ;
351350
assign master_monitor_dv[i].aw_addr = master[i].aw_addr ;
352351
assign master_monitor_dv[i].aw_len = master[i].aw_len ;
@@ -393,7 +392,7 @@ module tb_axi_xbar #(
393392
assign master_monitor_dv[i].r_valid = master[i].r_valid ;
394393
assign master_monitor_dv[i].r_ready = master[i].r_ready ;
395394
end
396-
for (genvar i = 0; i < NoSlaves; i++) begin : gen_connect_slave_monitor
395+
for (genvar i = 0; i < TbNumSlv; i++) begin : gen_connect_slave_monitor
397396
assign slave_monitor_dv[i].aw_id = slave[i].aw_id ;
398397
assign slave_monitor_dv[i].aw_addr = slave[i].aw_addr ;
399398
assign slave_monitor_dv[i].aw_len = slave[i].aw_len ;

test/tb_axi_xbar_pkg.sv

+3
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,9 @@ package tb_axi_xbar_pkg;
495495
if(tests_failed > 0) begin
496496
$error("Simulation encountered unexpected Transactions!!!!!!");
497497
end
498+
if(tests_conducted == 0) begin
499+
$error("Simulation did not conduct any tests!");
500+
end
498501
endtask : print_result
499502
endclass : axi_xbar_monitor
500503
endpackage

0 commit comments

Comments
 (0)