Skip to content

Commit 4651f45

Browse files
committed
Import axi_sub code from caliptra-rtl
This commit imports 'axi_sub' code from caliptra-rtl repository. Caliptra-ref: a4582f5856136286d2389b1cfa8de2910a82fe5e Signed-off-by: Maciej Dudek <[email protected]>
1 parent c9aeb01 commit 4651f45

File tree

9 files changed

+1232
-20
lines changed

9 files changed

+1232
-20
lines changed

src/i3c.f

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,8 @@
1717
${CALIPTRA_ROOT}/src/libs/rtl/ahb_slv_sif.sv
1818
${CALIPTRA_ROOT}/src/axi/rtl/axi_pkg.sv
1919
${CALIPTRA_ROOT}/src/axi/rtl/axi_if.sv
20-
${CALIPTRA_ROOT}/src/axi/rtl/axi_sub_arb.sv
21-
${CALIPTRA_ROOT}/src/axi/rtl/axi_sub_rd.sv
22-
${CALIPTRA_ROOT}/src/axi/rtl/axi_sub.sv
2320
${CALIPTRA_ROOT}/src/axi/rtl/axi_addr.v
2421
${CALIPTRA_ROOT}/src/libs/rtl/skidbuffer.v
25-
${CALIPTRA_ROOT}/src/axi/rtl/axi_sub_wr.sv
2622
${I3C_ROOT_DIR}/src/libs/mem/prim_ram_1p_pkg.sv
2723
${I3C_ROOT_DIR}/src/libs/mem/prim_generic_ram_1p.sv
2824
${I3C_ROOT_DIR}/src/libs/mem/prim_ram_1p_adv.sv
@@ -36,6 +32,10 @@
3632
${I3C_ROOT_DIR}/src/phy/i3c_io.sv
3733
${I3C_ROOT_DIR}/src/csr/I3CCSR.sv
3834
${I3C_ROOT_DIR}/src/interrupt.sv
35+
${I3C_ROOT_DIR}/src/libs/axi_sub/axi_sub_arb.sv
36+
${I3C_ROOT_DIR}/src/libs/axi_sub/axi_sub_rd.sv
37+
${I3C_ROOT_DIR}/src/libs/axi_sub/axi_sub.sv
38+
${I3C_ROOT_DIR}/src/libs/axi_sub/axi_sub_wr.sv
3939
${I3C_ROOT_DIR}/src/hci/queues/read_queue.sv
4040
${I3C_ROOT_DIR}/src/hci/queues/write_queue.sv
4141
${I3C_ROOT_DIR}/src/hci/ahb_if.sv

src/libs/axi_sub/axi_sub.sv

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
//
16+
// -------------------------------------------------------------
17+
// AXI Subordinate
18+
// -------------------------------------------------------------
19+
// Description:
20+
// Subordinate to convert AXI protocol transactions into internal component accesses
21+
// Includes an arbiter to squash duplex AXI transactions into simplex component operations
22+
// May optionally include an Exclusive Access monitor (AxLOCK signal)
23+
//
24+
// Limitations:
25+
// - When multiple ID tracking is enabled, write responses are returned in the
26+
// same order they are received, regardless of ID.
27+
//
28+
// -------------------------------------------------------------
29+
30+
module axi_sub import axi_pkg::*; #(
31+
parameter AW = 32, // Address Width
32+
parameter DW = 32, // Data Width
33+
BC = DW/8, // Byte Count
34+
BW = $clog2(BC), // Byte count Width
35+
parameter UW = 32, // User Width
36+
parameter IW = 1, // ID Width
37+
ID_NUM = 1 << IW, // Don't override
38+
39+
parameter EX_EN = 0, // Enable exclusive access tracking w/ AxLOCK
40+
parameter C_LAT = 0 // Component latency in clock cycles from (dv&&!hld) -> rdata
41+
// Must be const per component
42+
// For registers, typically 0
43+
// For SRAM, 1 or more
44+
) (
45+
input clk,
46+
input rst_n,
47+
48+
// AXI INF
49+
axi_if.w_sub s_axi_w_if,
50+
axi_if.r_sub s_axi_r_if,
51+
52+
//COMPONENT INF
53+
output logic dv,
54+
output logic [AW-1:0] addr, // Byte address
55+
output logic write,
56+
output logic [UW-1:0] user,
57+
output logic [IW-1:0] id,
58+
output logic [DW-1:0] wdata, // Requires: Component dwidth == AXI dwidth
59+
output logic [BC-1:0] wstrb, // Requires: Component dwidth == AXI dwidth
60+
output logic [2:0] size,
61+
input logic [DW-1:0] rdata, // Requires: Component dwidth == AXI dwidth
62+
output logic last, // Asserted with final 'dv' of a burst
63+
input logic hld,
64+
input logic rd_err,
65+
input logic wr_err
66+
67+
);
68+
69+
// Exclusive Access Signals
70+
`ifdef CALIPTRA_AXI_SUB_EX_EN
71+
logic [ID_NUM-1:0] ex_clr;
72+
logic [ID_NUM-1:0] ex_active;
73+
struct packed {
74+
logic [AW-1:0] addr;
75+
logic [AW-1:0] addr_mask;
76+
} [ID_NUM-1:0] ex_ctx;
77+
`endif
78+
79+
//Read Subordinate INF
80+
logic r_dv;
81+
logic [AW-1:0] r_addr; // Byte address
82+
logic [UW-1:0] r_user;
83+
logic [IW-1:0] r_id;
84+
logic [2:0] r_size;
85+
logic r_last; // Asserted with final 'dv' of a burst
86+
logic r_hld;
87+
logic r_err;
88+
89+
logic [DW-1:0] r_rdata; // Requires: Component dwidth == AXI dwidth
90+
91+
//Write Subordinate INF
92+
logic w_dv;
93+
logic [AW-1:0] w_addr; // Byte address
94+
logic [UW-1:0] w_user;
95+
logic [IW-1:0] w_id;
96+
logic [DW-1:0] w_wdata; // Requires: Component dwidth == AXI dwidth
97+
logic [BC-1:0] w_wstrb; // Requires: Component dwidth == AXI dwidth
98+
logic [2:0] w_size;
99+
logic w_last; // Asserted with final 'dv' of a burst
100+
logic w_hld;
101+
logic w_err;
102+
103+
104+
axi_sub_wr #(
105+
.AW (AW ),
106+
.DW (DW ),
107+
.UW (UW ),
108+
.IW (IW )
109+
110+
) i_axi_sub_wr (
111+
.clk (clk ),
112+
.rst_n(rst_n),
113+
114+
// AXI INF
115+
.s_axi_if(s_axi_w_if),
116+
117+
// Exclusive Access Signals
118+
`ifdef CALIPTRA_AXI_SUB_EX_EN
119+
.ex_clr (ex_clr ),
120+
.ex_active(ex_active),
121+
.ex_ctx (ex_ctx ),
122+
`endif
123+
124+
//COMPONENT INF
125+
.dv (w_dv ),
126+
.addr (w_addr ),
127+
.user (w_user ),
128+
.id (w_id ),
129+
.wdata(w_wdata),
130+
.wstrb(w_wstrb),
131+
.wsize(w_size ),
132+
.last (w_last ),
133+
.hld (w_hld ),
134+
.err (w_err )
135+
136+
);
137+
138+
axi_sub_rd #(
139+
.AW(AW),
140+
.DW(DW),
141+
.UW(UW),
142+
.IW(IW),
143+
144+
.C_LAT(C_LAT)
145+
) i_axi_sub_rd (
146+
.clk (clk ),
147+
.rst_n(rst_n),
148+
149+
// AXI INF
150+
.s_axi_if(s_axi_r_if),
151+
152+
// Exclusive Access Signals
153+
`ifdef CALIPTRA_AXI_SUB_EX_EN
154+
.ex_clr (ex_clr ),
155+
.ex_active(ex_active),
156+
.ex_ctx (ex_ctx ),
157+
`endif
158+
159+
//COMPONENT INF
160+
.dv (r_dv ),
161+
.addr (r_addr ),
162+
.user (r_user ),
163+
.id (r_id ),
164+
.size (r_size ),
165+
.last (r_last ),
166+
.hld (r_hld ),
167+
.err (r_err ),
168+
169+
.rdata(r_rdata)
170+
);
171+
172+
axi_sub_arb #(
173+
.AW(AW),
174+
.DW(DW),
175+
.UW(UW),
176+
.IW(IW),
177+
178+
.C_LAT(C_LAT)
179+
) i_axi_sub_arb (
180+
.clk (clk ),
181+
.rst_n (rst_n ),
182+
183+
//Read Subordinate INF
184+
.r_dv (r_dv ),
185+
.r_addr (r_addr ),
186+
.r_user (r_user ),
187+
.r_id (r_id ),
188+
.r_last (r_last ),
189+
.r_size (r_size ),
190+
.r_hld (r_hld ),
191+
.r_err (r_err ),
192+
.r_rdata(r_rdata),
193+
194+
//Write Subordinate INF
195+
.w_dv (w_dv ),
196+
.w_addr (w_addr ),
197+
.w_user (w_user ),
198+
.w_id (w_id ),
199+
.w_wdata(w_wdata),
200+
.w_wstrb(w_wstrb),
201+
.w_size (w_size ),
202+
.w_last (w_last ),
203+
.w_hld (w_hld ),
204+
.w_err (w_err ),
205+
206+
//COMPONENT INF
207+
.dv (dv ),
208+
.addr (addr ),
209+
.write (write ),
210+
.user (user ),
211+
.id (id ),
212+
.wdata (wdata ),
213+
.wstrb (wstrb ),
214+
.size (size ),
215+
.last (last ),
216+
.hld (hld ),
217+
.rd_err (rd_err ),
218+
.wr_err (wr_err ),
219+
.rdata (rdata )
220+
);
221+
222+
endmodule

src/libs/axi_sub/axi_sub_arb.sv

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
16+
// -------------------------------------------------------------
17+
// AXI Subordinate Arbiter
18+
// -------------------------------------------------------------
19+
// Description:
20+
// Arbitrate between Reads and Writes coming from AXI subordinate modules.
21+
// Always give precedence to Writes.
22+
//
23+
// -------------------------------------------------------------
24+
25+
module axi_sub_arb import axi_pkg::*; #(
26+
parameter AW = 32, // Address Width
27+
parameter DW = 32, // Data Width
28+
BC = DW/8, // Byte Count
29+
BW = $clog2(BC), // Byte count Width
30+
parameter UW = 32, // User Width
31+
parameter IW = 1, // ID Width
32+
ID_NUM = 1 << IW, // Don't override
33+
34+
parameter C_LAT = 0 // Component latency in clock cycles from (dv&&!hld) -> rdata
35+
// Must be const per component
36+
// For registers, typically 0
37+
// For SRAM, 1 or more
38+
) (
39+
input clk,
40+
input rst_n,
41+
42+
//Read Subordinate INF
43+
input logic r_dv,
44+
input logic [AW-1:0] r_addr, // Byte address
45+
input logic [UW-1:0] r_user,
46+
input logic [IW-1:0] r_id,
47+
input logic [2:0] r_size,
48+
input logic r_last, // Asserted with final 'dv' of a burst
49+
output logic r_hld,
50+
output logic r_err,
51+
52+
output logic [DW-1:0] r_rdata, // Requires: Component dwidth == AXI dwidth
53+
54+
//Write Subordinate INF
55+
input logic w_dv,
56+
input logic [AW-1:0] w_addr, // Byte address
57+
input logic [UW-1:0] w_user,
58+
input logic [IW-1:0] w_id,
59+
input logic [DW-1:0] w_wdata, // Requires: Component dwidth == AXI dwidth
60+
input logic [BC-1:0] w_wstrb, // Requires: Component dwidth == AXI dwidth
61+
input logic [2:0] w_size,
62+
input logic w_last, // Asserted with final 'dv' of a burst
63+
output logic w_hld,
64+
output logic w_err,
65+
66+
//COMPONENT INF
67+
output logic dv,
68+
output logic [AW-1:0] addr, // Byte address
69+
output logic write,
70+
output logic [UW-1:0] user,
71+
output logic [IW-1:0] id,
72+
output logic [DW-1:0] wdata, // Requires: Component dwidth == AXI dwidth
73+
output logic [BC-1:0] wstrb, // Requires: Component dwidth == AXI dwidth
74+
output logic [2:0] size,
75+
output logic last, // Asserted with final 'dv' of a burst
76+
input logic hld,
77+
input logic rd_err, // Asserts with rdata for reads (when C_LAT > 0)
78+
input logic wr_err, // Asserts with dv for writes
79+
80+
input logic [DW-1:0] rdata // Requires: Component dwidth == AXI dwidth
81+
);
82+
83+
`include "caliptra_prim_assert.sv"
84+
85+
logic r_pri; // Priority to reads
86+
logic r_win;
87+
88+
// Switch priority to current arb winner so that priority persists
89+
// in case
90+
// a) it was granted during a hold
91+
// b) it was granted at start of multi-beat burst
92+
// Otherwise, always give priority to other channel at end of a burst
93+
// to arbitrate fairly
94+
always_ff@(posedge clk or negedge rst_n) begin
95+
if (!rst_n)
96+
r_pri <= 1'b0;
97+
// Toggle priority at end of burst
98+
else if (w_dv && !w_hld && w_last)
99+
r_pri <= 1'b1;
100+
else if (r_dv && !r_hld && r_last)
101+
r_pri <= 1'b0;
102+
// Keep priority when xfer is in progress
103+
else if (w_dv && !r_win)
104+
r_pri <= 1'b0;
105+
else if (r_dv && r_win)
106+
r_pri <= 1'b1;
107+
end
108+
109+
always_comb begin
110+
// case ({r_pri,r_dv,w_dv}) inside
111+
// 3'b000: r_win = 0;
112+
// 3'b001: r_win = 0;
113+
// 3'b010: r_win = 1;
114+
// 3'b011: r_win = 0;
115+
// 3'b100: r_win = 1;
116+
// 3'b101: r_win = 0;
117+
// 3'b110: r_win = 1;
118+
// 3'b111: r_win = 1;
119+
// endcase
120+
if (r_pri) r_win = r_dv || !w_dv;
121+
else r_win = r_dv && !w_dv;
122+
end
123+
124+
always_comb begin
125+
dv = r_dv || w_dv;
126+
addr = r_win ? r_addr : w_addr;
127+
write = r_win ? 0 : 1;
128+
user = r_win ? r_user : w_user;
129+
id = r_win ? r_id : w_id ;
130+
last = r_win ? r_last : w_last;
131+
size = r_win ? r_size : w_size;
132+
r_hld = hld || !r_win;
133+
w_hld = hld || r_win;
134+
r_err = rd_err;
135+
w_err = wr_err;
136+
wdata = w_wdata;
137+
wstrb = w_wstrb;
138+
r_rdata = rdata;
139+
end
140+
141+
`CALIPTRA_ASSERT_NEVER(AXI_SUB_ARB_CONFLICT, r_dv && !r_hld && w_dv && !w_hld, clk, !rst_n)
142+
143+
144+
endmodule

0 commit comments

Comments
 (0)