1
1
// SPDX-License-Identifier: Apache-2.0
2
+ `include " i3c_defines.svh"
2
3
3
4
module axi_adapter # (
4
5
localparam int unsigned CsrAddrWidth = 12,
@@ -7,7 +8,10 @@ module axi_adapter #(
7
8
parameter int unsigned AxiDataWidth = 64 ,
8
9
parameter int unsigned AxiAddrWidth = 32 ,
9
10
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
11
15
) (
12
16
input logic clk_i,
13
17
input logic rst_ni,
@@ -49,12 +53,17 @@ module axi_adapter #(
49
53
input logic wvalid_i,
50
54
output logic wready_o,
51
55
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,
54
58
output logic [AxiUserWidth- 1 : 0 ] buser_o,
55
59
output logic bvalid_o,
56
60
input logic bready_i,
57
61
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
+
58
67
// I3C SW CSR access interface
59
68
output logic s_cpuif_req,
60
69
output logic s_cpuif_req_is_wr,
@@ -75,6 +84,9 @@ module axi_adapter #(
75
84
localparam UpperAddrBits = LowerAddrBits + AxiCSRDataShift;
76
85
localparam ShiftWidth = $clog2 (CsrDataWidth);
77
86
87
+ logic rlegal;
88
+ logic wlegal;
89
+
78
90
axi_if # (
79
91
.AW (CsrAddrWidth),
80
92
.DW (AxiDataWidth),
@@ -85,6 +97,45 @@ module axi_adapter #(
85
97
.rst_n (rst_ni)
86
98
);
87
99
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
+
88
139
// AXI Read Channels
89
140
always_comb begin : axi_r
90
141
axi.arvalid = arvalid_i;
@@ -144,6 +195,7 @@ module axi_adapter #(
144
195
logic [AxiDataWidth- 1 : 0 ] i3c_req_rdata;
145
196
logic [AxiIdWidth- 1 : 0 ] i3c_req_id;
146
197
logic [AxiDataWidth- 1 : 0 ] i3c_req_user;
198
+ logic i3c_rd_err, i3c_wr_err;
147
199
148
200
// Instantiate AXI subordinate to component interface module
149
201
i3c_axi_sub # (
@@ -172,8 +224,8 @@ module axi_adapter #(
172
224
.rdata (i3c_req_rdata),
173
225
.last (i3c_req_last),
174
226
.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 )
177
229
);
178
230
179
231
genvar i;
@@ -183,14 +235,27 @@ module axi_adapter #(
183
235
end
184
236
end
185
237
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;
187
240
assign cpuif_no_ack = ~ s_cpuif_wr_ack & ~ s_cpuif_rd_ack;
188
241
189
242
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;
192
255
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;
194
259
s_cpuif_req_is_wr = i3c_req_write;
195
260
s_cpuif_addr = i3c_req_addr[CsrAddrWidth- 1 : 0 ];
196
261
end
@@ -212,9 +277,11 @@ module axi_adapter #(
212
277
213
278
always_ff @ (posedge clk_i or negedge rst_ni) begin
214
279
if (~ rst_ni) begin
215
- i3c_req_hld_ext <= '0 ;
280
+ wr_hld_ext <= 0 ;
281
+ rd_hld_ext <= 0 ;
216
282
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 ;
218
285
end
219
286
end
220
287
endmodule
0 commit comments