Skip to content

Commit 30ffbea

Browse files
wkkunakgugala
authored andcommitted
Add AXI ID filtering
Signed-off-by: Wiktoria Kuna <[email protected]>
1 parent 6b51f83 commit 30ffbea

File tree

24 files changed

+1303
-26
lines changed

24 files changed

+1303
-26
lines changed

i3c_core_configs.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ axi:
4646
FrontendBusDataWidth: 32
4747
FrontendBusUserWidth: 32
4848
FrontendBusIdWidth: 8
49+
FrontendBusIdFiltering: False
50+
NumPrivIds: 4
4951
DisableInputFF: True
5052

5153
axi_ff:
@@ -62,4 +64,6 @@ axi_ff:
6264
FrontendBusDataWidth: 32
6365
FrontendBusUserWidth: 32
6466
FrontendBusIdWidth: 8
67+
FrontendBusIdFiltering: False
68+
NumPrivIds: 4
6569
DisableInputFF: False

src/hci/axi_adapter.sv

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// SPDX-License-Identifier: Apache-2.0
2+
`include "i3c_defines.svh"
23

34
module axi_adapter #(
45
localparam int unsigned CsrAddrWidth = 12,
@@ -7,7 +8,10 @@ module axi_adapter #(
78
parameter int unsigned AxiDataWidth = 64,
89
parameter int unsigned AxiAddrWidth = 32,
910
parameter int unsigned AxiUserWidth = 32,
10-
parameter int unsigned AxiIdWidth = 2
11+
parameter int unsigned AxiIdWidth = 8
12+
`ifdef AXI_ID_FILTERING,
13+
parameter int unsigned NumPrivIds = 4
14+
`endif
1115
) (
1216
input logic clk_i,
1317
input logic rst_ni,
@@ -49,12 +53,17 @@ module axi_adapter #(
4953
input logic wvalid_i,
5054
output logic wready_o,
5155

52-
output logic [ 1:0] bresp_o,
53-
output logic [AxiIdWidth-1:0] bid_o,
56+
output logic [ 1:0] bresp_o,
57+
output logic [ AxiIdWidth-1:0] bid_o,
5458
output logic [AxiUserWidth-1:0] buser_o,
5559
output logic bvalid_o,
5660
input logic bready_i,
5761

62+
`ifdef AXI_ID_FILTERING
63+
input logic disable_id_filtering_i,
64+
input logic [AxiIdWidth-1:0] priv_ids_i[NumPrivIds],
65+
`endif
66+
5867
// I3C SW CSR access interface
5968
output logic s_cpuif_req,
6069
output logic s_cpuif_req_is_wr,
@@ -75,6 +84,9 @@ module axi_adapter #(
7584
localparam UpperAddrBits = LowerAddrBits + AxiCSRDataShift;
7685
localparam ShiftWidth = $clog2(CsrDataWidth);
7786

87+
logic rlegal;
88+
logic wlegal;
89+
7890
axi_if #(
7991
.AW(CsrAddrWidth),
8092
.DW(AxiDataWidth),
@@ -85,6 +97,45 @@ module axi_adapter #(
8597
.rst_n(rst_ni)
8698
);
8799

100+
`ifdef AXI_ID_FILTERING
101+
logic [NumPrivIds-1:0] rsel;
102+
logic [NumPrivIds-1:0] wsel;
103+
104+
always_ff @(posedge clk_i or negedge rst_ni) begin : axi_id_filter
105+
if (!rst_ni) begin
106+
rlegal <= '0;
107+
wlegal <= '0;
108+
end else begin
109+
if (arready_o && arvalid_i) begin
110+
rlegal <= disable_id_filtering_i | (|rsel);
111+
end
112+
113+
if (awready_o && awvalid_i) begin
114+
wlegal <= disable_id_filtering_i | (|wsel);
115+
end
116+
end
117+
end
118+
119+
genvar j;
120+
for (j = 0; j < NumPrivIds; j = j + 1) begin : g_match_id
121+
always_comb begin
122+
if (!rst_ni) begin
123+
rsel[j] = '0;
124+
wsel[j] = '0;
125+
end else begin
126+
rsel[j] = arid_i == priv_ids_i[j];
127+
wsel[j] = awid_i == priv_ids_i[j];
128+
end
129+
end
130+
end
131+
132+
`else
133+
always_comb begin
134+
rlegal = 1'b1;
135+
wlegal = 1'b1;
136+
end
137+
`endif
138+
88139
// AXI Read Channels
89140
always_comb begin : axi_r
90141
axi.arvalid = arvalid_i;
@@ -144,6 +195,7 @@ module axi_adapter #(
144195
logic [AxiDataWidth-1:0] i3c_req_rdata;
145196
logic [AxiIdWidth-1:0] i3c_req_id;
146197
logic [AxiDataWidth-1:0] i3c_req_user;
198+
logic i3c_rd_err, i3c_wr_err;
147199

148200
// Instantiate AXI subordinate to component interface module
149201
i3c_axi_sub #(
@@ -172,8 +224,8 @@ module axi_adapter #(
172224
.rdata(i3c_req_rdata),
173225
.last(i3c_req_last),
174226
.hld(i3c_req_hld),
175-
.rd_err(s_cpuif_rd_err),
176-
.wr_err(s_cpuif_wr_err)
227+
.rd_err(i3c_rd_err),
228+
.wr_err(i3c_wr_err)
177229
);
178230

179231
genvar i;
@@ -183,14 +235,27 @@ module axi_adapter #(
183235
end
184236
end
185237

186-
logic cpuif_no_ack;
238+
logic cpuif_no_ack, wr_hld, rd_hld;
239+
logic wr_hld_ext, rd_hld_ext, rd_req, wr_req, rd_req_legal, wr_req_legal;
187240
assign cpuif_no_ack = ~s_cpuif_wr_ack & ~s_cpuif_rd_ack;
188241

189242
always_comb begin : axi_2_i3c_comp
190-
cpuif_req_stall = i3c_req_write ? s_cpuif_req_stall_wr : s_cpuif_req_stall_rd;
191-
i3c_req_hld = (i3c_req_dv | cpuif_req_stall | i3c_req_hld_ext) & cpuif_no_ack;
243+
rd_req = i3c_req_dv & !i3c_req_write;
244+
wr_req = i3c_req_dv & i3c_req_write;
245+
// Operation is legal if ID of the request is on 'priv_ids_i'
246+
rd_req_legal = rd_req & rlegal;
247+
wr_req_legal = wr_req & wlegal;
248+
249+
rd_hld = (rd_req_legal | rd_hld_ext | s_cpuif_req_stall_rd) & cpuif_no_ack;
250+
wr_hld = (wr_req_legal | wr_hld_ext | s_cpuif_req_stall_wr) & cpuif_no_ack;
251+
252+
// Raise an error only when `hld` is deasserted
253+
i3c_rd_err = ((rd_req & !rlegal) | s_cpuif_rd_err) & !wr_hld;
254+
i3c_wr_err = ((wr_req & !wlegal) | s_cpuif_wr_err) & !rd_hld;
192255

193-
s_cpuif_req = i3c_req_dv & ~i3c_req_hld_ext;
256+
i3c_req_hld_ext = wr_hld_ext | rd_hld_ext;
257+
i3c_req_hld = wr_hld | rd_hld;
258+
s_cpuif_req = (wr_req_legal | rd_req_legal) & ~i3c_req_hld_ext;
194259
s_cpuif_req_is_wr = i3c_req_write;
195260
s_cpuif_addr = i3c_req_addr[CsrAddrWidth-1:0];
196261
end
@@ -212,9 +277,11 @@ module axi_adapter #(
212277

213278
always_ff @(posedge clk_i or negedge rst_ni) begin
214279
if (~rst_ni) begin
215-
i3c_req_hld_ext <= '0;
280+
wr_hld_ext <= 0;
281+
rd_hld_ext <= 0;
216282
end else begin
217-
i3c_req_hld_ext <= cpuif_no_ack ? i3c_req_dv : 1'b0;
283+
wr_hld_ext <= cpuif_no_ack ? wr_req_legal : 1'b0;
284+
rd_hld_ext <= cpuif_no_ack ? rd_req_legal : 1'b0;
218285
end
219286
end
220287
endmodule

src/i3c.sv

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ module i3c
3333
parameter int unsigned AxiAddrWidth = `AXI_ADDR_WIDTH,
3434
parameter int unsigned AxiUserWidth = `AXI_USER_WIDTH,
3535
parameter int unsigned AxiIdWidth = `AXI_ID_WIDTH,
36+
`ifdef AXI_ID_FILTERING
37+
parameter int unsigned NumPrivIds = `NUM_PRIV_IDS,
38+
`endif
3639
`endif
3740
parameter int unsigned DatAw = i3c_pkg::DatAw,
3841
parameter int unsigned DctAw = i3c_pkg::DctAw,
@@ -168,12 +171,16 @@ module i3c
168171
input logic wvalid_i,
169172
output logic wready_o,
170173

171-
output logic [ 1:0] bresp_o,
172-
output logic [AxiIdWidth-1:0] bid_o,
174+
output logic [ 1:0] bresp_o,
175+
output logic [ AxiIdWidth-1:0] bid_o,
173176
output logic [AxiUserWidth-1:0] buser_o,
174177
output logic bvalid_o,
175178
input logic bready_i,
176-
179+
`ifdef AXI_ID_FILTERING
180+
// ID Filtering
181+
input logic disable_id_filtering_i,
182+
input logic [AxiIdWidth-1:0] priv_ids_i [NumPrivIds],
183+
`endif
177184
`endif
178185

179186
// I3C bus IO
@@ -396,6 +403,10 @@ module i3c
396403
.AxiAddrWidth(AxiAddrWidth),
397404
.AxiUserWidth(AxiUserWidth),
398405
.AxiIdWidth (AxiIdWidth)
406+
`ifdef AXI_ID_FILTERING
407+
,
408+
.NumPrivIds(NumPrivIds)
409+
`endif
399410
) i3c_axi_if (
400411
.clk_i (clk_i),
401412
.rst_ni(rst_ni),
@@ -443,6 +454,11 @@ module i3c
443454
.bready_i(bready_i),
444455
.buser_o(buser_o),
445456

457+
`ifdef AXI_ID_FILTERING
458+
.disable_id_filtering_i(disable_id_filtering_i),
459+
.priv_ids_i(priv_ids_i),
460+
`endif
461+
446462
// I3C SW CSR access interface
447463
.s_cpuif_req(s_cpuif_req),
448464
.s_cpuif_req_is_wr(s_cpuif_req_is_wr),

src/i3c_defines.svh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
`define AXI_DATA_WIDTH 32
1818
`define AXI_USER_WIDTH 32
1919
`define AXI_ID_WIDTH 8
20+
`define NUM_PRIV_IDS 4
2021
`define DISABLE_INPUT_FF 1
2122

2223
`endif // I3C_CONFIG

src/i3c_wrapper.sv

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ module i3c_wrapper #(
1010
parameter int unsigned AxiAddrWidth = `AXI_ADDR_WIDTH,
1111
parameter int unsigned AxiUserWidth = `AXI_USER_WIDTH,
1212
parameter int unsigned AxiIdWidth = `AXI_ID_WIDTH,
13+
`ifdef AXI_ID_FILTERING
14+
parameter int unsigned NumPrivIds = `NUM_PRIV_IDS,
15+
`endif
1316
`endif
1417
parameter int unsigned DatAw = i3c_pkg::DatAw,
1518
parameter int unsigned DctAw = i3c_pkg::DctAw,
@@ -94,6 +97,10 @@ module i3c_wrapper #(
9497
output logic bvalid_o,
9598
input logic bready_i,
9699

100+
`ifdef AXI_ID_FILTERING
101+
input logic disable_id_filtering_i,
102+
input logic [AxiIdWidth-1:0] priv_ids_i [NumPrivIds],
103+
`endif
97104
`endif
98105

99106
// digital I3C input and output signals are exposed for the purpose of simulation
@@ -144,6 +151,9 @@ module i3c_wrapper #(
144151
.AxiAddrWidth(AxiAddrWidth),
145152
.AxiUserWidth(AxiUserWidth),
146153
.AxiIdWidth(AxiIdWidth),
154+
`endif
155+
`ifdef AXI_ID_FILTERING
156+
.NumPrivIds(NumPrivIds),
147157
`endif
148158
.CsrDataWidth(CsrDataWidth),
149159
.CsrAddrWidth(CsrAddrWidth),
@@ -210,6 +220,11 @@ module i3c_wrapper #(
210220
.bvalid_o(bvalid_o),
211221
.bready_i(bready_i),
212222
.buser_o(buser_o),
223+
224+
`ifdef AXI_ID_FILTERING
225+
.disable_id_filtering_i(disable_id_filtering_i),
226+
.priv_ids_i(priv_ids_i),
227+
`endif
213228
`endif
214229

215230
.i3c_scl_i (scl_io2phy),

testbench/tb.sv

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ module tb ();
1616
localparam int unsigned AxiAddrWidth = `AXI_ADDR_WIDTH;
1717
localparam int unsigned AxiUserWidth = `AXI_USER_WIDTH;
1818
localparam int unsigned AxiIdWidth = `AXI_ID_WIDTH;
19+
`ifdef AXI_ID_FILTERING
20+
localparam int unsigned NumPrivIds = `NUM_PRIV_IDS;
21+
`endif
1922
`endif
2023

2124
localparam int unsigned DatAw = i3c_pkg::DatAw;
@@ -83,6 +86,11 @@ logic rst_n;
8386
logic [AxiIdWidth-1:0] bid;
8487
logic bvalid;
8588
logic bready;
89+
90+
`ifdef AXI_ID_FILTERING
91+
logic disable_id_filtering_i;
92+
logic [AxiIdWidth-1:0] priv_ids_i [NumPrivIds];
93+
`endif
8694
`endif
8795

8896
// I3C Bus signals
@@ -101,6 +109,9 @@ i3c_wrapper #(
101109
.AxiAddrWidth(AxiAddrWidth),
102110
.AxiUserWidth(AxiUserWidth),
103111
.AxiIdWidth(AxiIdWidth),
112+
`ifdef AXI_ID_FILTERING
113+
.NumPrivIds(NumPrivIds),
114+
`endif
104115
`endif
105116
.DatAw(DatAw),
106117
.DctAw(DctAw),
@@ -161,6 +172,11 @@ i3c_wrapper #(
161172
.bid_o(bid),
162173
.bvalid_o(bvalid),
163174
.bready_i(bready),
175+
176+
`ifdef AXI_ID_FILTERING
177+
.disable_id_filtering_i(disable_id_filtering_i),
178+
.priv_ids_i(priv_ids_i),
179+
`endif
164180
`endif
165181

166182
.scl_i(bus_scl),

tools/i3c_config/i3c_core_config.schema.json

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@
9292
"minimum": 0,
9393
"maximum": 128
9494
},
95+
"FrontendBusIdFiltering": {
96+
"description": "Enable AXI ID filtering logic.",
97+
"type": "boolean"
98+
},
99+
"NumPrivIds": {
100+
"description": "Number of privileged AXI IDs.",
101+
"type": "integer"
102+
},
95103
"DisableInputFF": {
96104
"description": "Disable input synchronization flip-flops on SDA and SCL lines.",
97105
"type": "boolean"
@@ -111,11 +119,19 @@
111119
},
112120
"FrontendBusIdWidth": {
113121
"type": "integer"
122+
},
123+
"NumPrivIds": {
124+
"type": "integer"
125+
},
126+
"FrontendBusIdFiltering": {
127+
"type": "boolean"
114128
}
115129
},
116130
"required": [
117131
"FrontendBusUserWidth",
118-
"FrontendBusIdWidth"
132+
"FrontendBusIdWidth",
133+
"NumPrivIds",
134+
"FrontendBusIdFiltering"
119135
]
120136
},
121137
"else": {
@@ -138,7 +154,21 @@
138154
"FrontendBusIdWidth"
139155
]
140156
}
157+
},
158+
{
159+
"not": {
160+
"required": [
161+
"NumPrivIds"
162+
]
163+
}
164+
},
165+
{
166+
"not": {
167+
"required": [
168+
"FrontendBusIdFiltering"
169+
]
170+
}
141171
}
142172
]
143173
}
144-
}
174+
}

verification/cocotb/block/ahb_if/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ override PLUSARGS := $(strip +FrontendBusInterface=AHB $(PLUSARGS))
1414

1515
MODULE ?= $(subst $(space),$(comma),$(subst .py,,$(TEST_FILES)))
1616
TOPLEVEL = ahb_if_wrapper
17+
CFG_NAME = ahb
1718

1819
VERILOG_SOURCES = \
1920
$(CALIPTRA_ROOT)/src/libs/rtl/ahb_defines_pkg.sv \

verification/cocotb/block/axi_adapter/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ VERILOG_SOURCES = \
3131
$(SRC_DIR)/csr/I3CCSR_pkg.sv \
3232
$(SRC_DIR)/csr/I3CCSR.sv \
3333
$(SRC_DIR)/hci/axi_adapter.sv \
34-
$(TEST_DIR)/axi_adapter_wrapper.sv
34+
$(TEST_DIR)/../lib_adapter/axi_adapter_wrapper.sv
3535

3636
include $(TEST_DIR)/../block_common.mk

0 commit comments

Comments
 (0)