Skip to content

Commit 2180118

Browse files
authored
Merge pull request #56 from pulp-platform/small-improvements
Small improvements to atop_filter, demux, id_prepend, and xbar
2 parents ef8c1e2 + cf3bca5 commit 2180118

File tree

5 files changed

+131
-27
lines changed

5 files changed

+131
-27
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
88
## Unreleased
99

1010
### Added
11+
- `axi_xbar_intf`: Add interface variant of crossbar.
1112

1213
### Changed
1314

1415
### Fixed
16+
- `axi_atop_filter`: Fix ModelSim warnings by adding `default` statement. The signal in the `case`
17+
has a single bit, and both values were correctly handled in synthesis. However, when starting
18+
simulation, the signal has an undefined value, and ModelSim threw warnings that this violated the
19+
`unique` condition.
20+
- `axi_demux`: Move `typedef` outside `generate` for compatibility with VCS.
21+
- `axi_id_prepend`:
22+
- Fix text of some assertion messages.
23+
- Fix case of prepending a single-bit ID.
1524
- `tb_axi_xbar`: Fix for localparam `AxiIdWidthSlaves` to be dependent on the number of masters.
1625

1726

src/axi_atop_filter.sv

+2
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ module axi_atop_filter #(
246246
end
247247
end
248248
end
249+
250+
default: r_state_d = R_FEEDTHROUGH;
249251
endcase
250252
end
251253
// Feed all signals on AR through.

src/axi_demux.sv

+13-12
Original file line numberDiff line numberDiff line change
@@ -51,24 +51,25 @@ module axi_demux #(
5151

5252
localparam int unsigned IdCounterWidth = $clog2(MaxTrans);
5353

54+
//--------------------------------------
55+
// Typedefs for the FIFOs / Queues
56+
//--------------------------------------
57+
typedef logic [AxiIdWidth-1:0] axi_id_t;
58+
typedef struct packed {
59+
aw_chan_t aw_chan;
60+
select_t aw_select;
61+
} aw_chan_select_t;
62+
typedef struct packed {
63+
ar_chan_t ar_chan;
64+
select_t ar_select;
65+
} ar_chan_select_t;
66+
5467
// pass through if only one master port
5568
if (NoMstPorts == 32'h1) begin : gen_no_demux
5669
assign mst_reqs_o[0] = slv_req_i;
5770
assign slv_resp_o = mst_resps_i;
5871
// other non degenerate cases
5972
end else begin : gen_demux
60-
//--------------------------------------
61-
// Typedefs for the Fifo's / Queues
62-
//--------------------------------------
63-
typedef logic [AxiIdWidth-1:0] axi_id_t;
64-
typedef struct packed {
65-
aw_chan_t aw_chan;
66-
select_t aw_select;
67-
} aw_chan_select_t;
68-
typedef struct packed {
69-
ar_chan_t ar_chan;
70-
select_t ar_select;
71-
} ar_chan_select_t;
7273

7374
//--------------------------------------
7475
//--------------------------------------

src/axi_id_prepend.sv

+20-15
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,22 @@ module axi_id_prepend #(
7676
);
7777

7878
// prepend the ID
79-
always_comb begin
80-
for (int unsigned i = 0; i < NoBus; i++) begin : gen_id_prepend
81-
mst_aw_chans_o[i] = slv_aw_chans_i[i];
82-
mst_aw_chans_o[i].id[AxiIdWidthSlvPort+:PreIdWidth] = pre_id_i;
83-
mst_ar_chans_o[i] = slv_ar_chans_i[i];
84-
mst_ar_chans_o[i].id[AxiIdWidthSlvPort+:PreIdWidth] = pre_id_i;
85-
// The ID is in the highest bits of the struct, so an assignment from a channel with a wide ID
86-
// to a channel with a shorter ID correctly cuts the prepended ID.
87-
slv_b_chans_o[i] = mst_b_chans_i[i];
88-
slv_r_chans_o[i] = mst_r_chans_i[i];
79+
for (genvar i = 0; i < NoBus; i++) begin : gen_id_prepend
80+
if (PreIdWidth == 0) begin : gen_no_prepend
81+
assign mst_aw_chans_o[i] = slv_aw_chans_i[i];
82+
assign mst_ar_chans_o[i] = slv_ar_chans_i[i];
83+
end else begin : gen_prepend
84+
always_comb begin
85+
mst_aw_chans_o[i] = slv_aw_chans_i[i];
86+
mst_ar_chans_o[i] = slv_ar_chans_i[i];
87+
mst_aw_chans_o[i].id = {pre_id_i, slv_aw_chans_i[i].id[AxiIdWidthSlvPort-1:0]};
88+
mst_ar_chans_o[i].id = {pre_id_i, slv_ar_chans_i[i].id[AxiIdWidthSlvPort-1:0]};
89+
end
8990
end
91+
// The ID is in the highest bits of the struct, so an assignment from a channel with a wide ID
92+
// to a channel with a shorter ID correctly cuts the prepended ID.
93+
assign slv_b_chans_o[i] = mst_b_chans_i[i];
94+
assign slv_r_chans_o[i] = mst_r_chans_i[i];
9095
end
9196

9297
// assign the handshaking's and w channel
@@ -133,15 +138,15 @@ module axi_id_prepend #(
133138

134139
ar_id : assert final(
135140
mst_ar_chans_o[0].id[$bits(slv_ar_chans_i[0].id)-1:0] === slv_ar_chans_i[0].id)
136-
else $fatal (1, "Something with the AW channel ID prepending went wrong.");
141+
else $fatal (1, "Something with the AR channel ID prepending went wrong.");
137142
ar_addr : assert final(mst_ar_chans_o[0].addr === slv_ar_chans_i[0].addr)
138-
else $fatal (1, "Something with the AW channel ID prepending went wrong.");
143+
else $fatal (1, "Something with the AR channel ID prepending went wrong.");
139144
ar_len : assert final(mst_ar_chans_o[0].len === slv_ar_chans_i[0].len)
140-
else $fatal (1, "Something with the AW channel ID prepending went wrong.");
145+
else $fatal (1, "Something with the AR channel ID prepending went wrong.");
141146
ar_size : assert final(mst_ar_chans_o[0].size === slv_ar_chans_i[0].size)
142-
else $fatal (1, "Something with the AW channel ID prepending went wrong.");
147+
else $fatal (1, "Something with the AR channel ID prepending went wrong.");
143148
ar_qos : assert final(mst_ar_chans_o[0].qos === slv_ar_chans_i[0].qos)
144-
else $fatal (1, "Something with the AW channel ID prepending went wrong.");
149+
else $fatal (1, "Something with the AR channel ID prepending went wrong.");
145150

146151
r_id : assert final(mst_r_chans_i[0].id[$bits(slv_r_chans_o[0].id)-1:0] === slv_r_chans_o[0].id)
147152
else $fatal (1, "Something with the R channel ID stripping went wrong.");

src/axi_xbar.sv

+87
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,90 @@ module axi_xbar #(
220220
`endif
221221
// pragma translate_on
222222
endmodule
223+
224+
`include "axi/assign.svh"
225+
`include "axi/typedef.svh"
226+
227+
module axi_xbar_intf #(
228+
parameter int unsigned AXI_USER_WIDTH = 0,
229+
parameter axi_pkg::xbar_cfg_t Cfg = '0,
230+
parameter type rule_t = axi_pkg::xbar_rule_64_t
231+
) (
232+
input logic clk_i,
233+
input logic rst_ni,
234+
input logic test_i,
235+
AXI_BUS.Slave slv_ports [Cfg.NoSlvPorts-1:0],
236+
AXI_BUS.Master mst_ports [Cfg.NoMstPorts-1:0],
237+
input rule_t [Cfg.NoAddrRules-1:0] addr_map_i,
238+
input logic [Cfg.NoSlvPorts-1:0] en_default_mst_port_i,
239+
input logic [Cfg.NoSlvPorts-1:0][$clog2(Cfg.NoMstPorts)-1:0] default_mst_port_i
240+
);
241+
242+
localparam int unsigned AxiIdWidthMstPorts = Cfg.AxiIdWidthSlvPorts + $clog2(Cfg.NoSlvPorts);
243+
244+
typedef logic [AxiIdWidthMstPorts -1:0] id_mst_t;
245+
typedef logic [Cfg.AxiIdWidthSlvPorts -1:0] id_slv_t;
246+
typedef logic [Cfg.AxiAddrWidth -1:0] addr_t;
247+
typedef logic [Cfg.AxiDataWidth -1:0] data_t;
248+
typedef logic [Cfg.AxiDataWidth/8 -1:0] strb_t;
249+
typedef logic [AXI_USER_WIDTH -1:0] user_t;
250+
251+
`AXI_TYPEDEF_AW_CHAN_T ( mst_aw_chan_t, addr_t, id_mst_t, user_t)
252+
`AXI_TYPEDEF_AW_CHAN_T ( slv_aw_chan_t, addr_t, id_slv_t, user_t)
253+
`AXI_TYPEDEF_W_CHAN_T ( w_chan_t, data_t, strb_t, user_t)
254+
`AXI_TYPEDEF_B_CHAN_T ( mst_b_chan_t, id_mst_t, user_t)
255+
`AXI_TYPEDEF_B_CHAN_T ( slv_b_chan_t, id_slv_t, user_t)
256+
`AXI_TYPEDEF_AR_CHAN_T ( mst_ar_chan_t, addr_t, id_mst_t, user_t)
257+
`AXI_TYPEDEF_AR_CHAN_T ( slv_ar_chan_t, addr_t, id_slv_t, user_t)
258+
`AXI_TYPEDEF_R_CHAN_T ( mst_r_chan_t, data_t, id_mst_t, user_t)
259+
`AXI_TYPEDEF_R_CHAN_T ( slv_r_chan_t, data_t, id_slv_t, user_t)
260+
`AXI_TYPEDEF_REQ_T ( mst_req_t, mst_aw_chan_t, w_chan_t, mst_ar_chan_t)
261+
`AXI_TYPEDEF_REQ_T ( slv_req_t, slv_aw_chan_t, w_chan_t, slv_ar_chan_t)
262+
`AXI_TYPEDEF_RESP_T ( mst_resp_t, mst_b_chan_t, mst_r_chan_t)
263+
`AXI_TYPEDEF_RESP_T ( slv_resp_t, slv_b_chan_t, slv_r_chan_t)
264+
265+
mst_req_t [Cfg.NoMstPorts-1:0] mst_reqs;
266+
mst_resp_t [Cfg.NoMstPorts-1:0] mst_resps;
267+
slv_req_t [Cfg.NoSlvPorts-1:0] slv_reqs;
268+
slv_resp_t [Cfg.NoSlvPorts-1:0] slv_resps;
269+
270+
for (genvar i = 0; i < Cfg.NoMstPorts; i++) begin : gen_assign_mst
271+
`AXI_ASSIGN_FROM_REQ (mst_ports[i], mst_reqs[i] );
272+
`AXI_ASSIGN_TO_RESP (mst_resps[i], mst_ports[i]);
273+
end
274+
275+
for (genvar i = 0; i < Cfg.NoSlvPorts; i++) begin : gen_assign_slv
276+
`AXI_ASSIGN_TO_REQ (slv_reqs[i], slv_ports[i]);
277+
`AXI_ASSIGN_FROM_RESP (slv_ports[i], slv_resps[i]);
278+
end
279+
280+
axi_xbar #(
281+
.Cfg (Cfg),
282+
.slv_aw_chan_t ( slv_aw_chan_t ),
283+
.mst_aw_chan_t ( mst_aw_chan_t ),
284+
.w_chan_t ( w_chan_t ),
285+
.slv_b_chan_t ( slv_b_chan_t ),
286+
.mst_b_chan_t ( mst_b_chan_t ),
287+
.slv_ar_chan_t ( slv_ar_chan_t ),
288+
.mst_ar_chan_t ( mst_ar_chan_t ),
289+
.slv_r_chan_t ( slv_r_chan_t ),
290+
.mst_r_chan_t ( mst_r_chan_t ),
291+
.slv_req_t ( slv_req_t ),
292+
.slv_resp_t ( slv_resp_t ),
293+
.mst_req_t ( mst_req_t ),
294+
.mst_resp_t ( mst_resp_t ),
295+
.rule_t ( rule_t )
296+
) i_xbar (
297+
.clk_i,
298+
.rst_ni,
299+
.test_i,
300+
.slv_ports_req_i (slv_reqs ),
301+
.slv_ports_resp_o (slv_resps),
302+
.mst_ports_req_o (mst_reqs ),
303+
.mst_ports_resp_i (mst_resps),
304+
.addr_map_i,
305+
.en_default_mst_port_i,
306+
.default_mst_port_i
307+
);
308+
309+
endmodule

0 commit comments

Comments
 (0)