Skip to content

Commit 55e641c

Browse files
authored
Merge pull request #214 from pulp-platform/snitch-patches
Import patches from the Snitch repository
2 parents f80d53d + 43133d0 commit 55e641c

File tree

8 files changed

+428
-80
lines changed

8 files changed

+428
-80
lines changed

CHANGELOG.md

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

1010
### Added
11+
- `axi_demux` and `axi_isolate`: Add parameter `AtopSupport` to optionally disable the support for
12+
atomic operations (ATOPs). This parameter defaults to `1'b1`, i.e., ATOPs are supported.
13+
Therefore, this change is backward-compatible.
14+
- `axi_isolate`: Add parameter `TerminateTransaction` to optionally respond to transactions during
15+
isolation. This parameter defaults to `1'b0`, i.e., transactions do not get responses.
16+
Therefore, this change is backward-compatible.
17+
- `axi_xbar`: Add `Connectivity` parameter to enable the implementation of partially-connected
18+
crossbars. This parameter defaults to `'1`, i.e., every slave port is connected to every master
19+
port. Therefore, this change is backward-compatible.
20+
- `axi_test`: Add monitor class `axi_monitor`.
21+
- `axi_test::axi_driver`: Add monitor tasks.
1122

1223
### Changed
24+
- `axi_isolate`: Add parameters for the address, data, ID, and user signal width. This is required
25+
for the implementation of the `TerminateTransaction` parameter (see *Added* section). This change
26+
is **backward-incompatible** for all instances of `axi_isolate` outside this repository. Users
27+
must update all instances of `axi_isolate` in their code. The interface variant is not affected
28+
and remains backward-compatible.
1329

1430
### Fixed
1531

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.33.2-dev
1+
0.34.0-dev

axi.core

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CAPI=2:
22

3-
name : pulp-platform.org::axi:0.33.2-dev
3+
name : pulp-platform.org::axi:0.34.0-dev
44

55
filesets:
66
rtl:

src/axi_demux.sv

+9-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// - Wolfgang Roenninger <[email protected]>
1313
// - Andreas Kurth <[email protected]>
1414

15+
`include "common_cells/assertions.svh"
1516
`include "common_cells/registers.svh"
1617

1718
`ifdef QUESTA
@@ -24,6 +25,7 @@
2425
// See `doc/axi_demux.md` for the documentation, including the definition of parameters and ports.
2526
module axi_demux #(
2627
parameter int unsigned AxiIdWidth = 32'd0,
28+
parameter bit AtopSupport = 1'b1,
2729
parameter type aw_chan_t = logic,
2830
parameter type w_chan_t = logic,
2931
parameter type b_chan_t = logic,
@@ -205,12 +207,14 @@ module axi_demux #(
205207
slv_aw_ready = 1'b1;
206208
lock_aw_valid_d = 1'b0;
207209
load_aw_lock = 1'b1;
208-
atop_inject = slv_aw_chan_select.aw_chan.atop[5]; // inject the ATOP if necessary
210+
// inject the ATOP if necessary
211+
atop_inject = slv_aw_chan_select.aw_chan.atop[5] & AtopSupport;
209212
end
210213
end else begin
211214
// Process can start handling a transaction if its `i_aw_id_counter` and `w_fifo` have
212-
// space in them. Further check if we could inject something on the AR channel.
213-
if (!aw_id_cnt_full && !w_fifo_full && !ar_id_cnt_full) begin
215+
// space in them. Further check if we could inject something on the AR channel (only if
216+
// ATOPs are supported).
217+
if (!aw_id_cnt_full && !w_fifo_full && (!ar_id_cnt_full || !AtopSupport)) begin
214218
// there is a valid AW vector make the id lookup and go further, if it passes
215219
if (slv_aw_valid && (!aw_select_occupied ||
216220
(slv_aw_chan_select.aw_select == lookup_aw_select))) begin
@@ -221,7 +225,7 @@ module axi_demux #(
221225
// on AW transaction
222226
if (aw_ready) begin
223227
slv_aw_ready = 1'b1;
224-
atop_inject = slv_aw_chan_select.aw_chan.atop[5];
228+
atop_inject = slv_aw_chan_select.aw_chan.atop[5] & AtopSupport;
225229
// no AW transaction this cycle, lock the decision
226230
end else begin
227231
lock_aw_valid_d = 1'b1;
@@ -574,6 +578,7 @@ module axi_demux #(
574578
internal_aw_select: assert property( @(posedge clk_i)
575579
(aw_valid |-> slv_aw_chan_select.aw_select < NoMstPorts))
576580
else $fatal(1, "slv_aw_chan_select.aw_select illegal while aw_valid.");
581+
`ASSUME(NoAtopAllowed, !AtopSupport && slv_req_i.aw_valid |-> slv_req_i.aw.atop == '0)
577582
`endif
578583
`endif
579584
// pragma translate_on

src/axi_isolate.sv

+191-49
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,169 @@
1313
// - Wolfgang Roenninger <[email protected]>
1414
// - Andreas Kurth <[email protected]>
1515

16-
// Description:
17-
//
18-
// This module can isolate the AXI4+ATOPs bus on the master port from the slave port. When the
19-
// isolation is not active, the two ports are directly connected.
20-
//
21-
// This module counts how many open transactions are currently in flight on the read and write
22-
// channels. It is further capable of tracking the amount of open atomic transactions with read
23-
// responses.
24-
//
25-
// The isolation interface has two signals: `isolate_i` and `isolated_o`. When `isolate_i` is
26-
// asserted, all open transactions are gracefully terminated. When no transactions are in flight
27-
// anymore, the `isolated_o` output is asserted. As long as `isolated_o` is asserted, all output
28-
// signals in `mst_req_o` are silenced to `'0`. When isolated, new transactions initiated on the
29-
// slave port are stalled until the isolation is terminated by deasserting `isolate_i`.
30-
16+
`include "axi/typedef.svh"
3117
`include "common_cells/registers.svh"
3218

19+
/// This module can isolate the AXI4+ATOPs bus on the master port from the slave port. When the
20+
/// isolation is not active, the two ports are directly connected.
21+
///
22+
/// This module counts how many open transactions are currently in flight on the read and write
23+
/// channels. It is further capable of tracking the amount of open atomic transactions with read
24+
/// responses.
25+
///
26+
/// The isolation interface has two signals: `isolate_i` and `isolated_o`. When `isolate_i` is
27+
/// asserted, all open transactions are gracefully terminated. When no transactions are in flight
28+
/// anymore, the `isolated_o` output is asserted. As long as `isolated_o` is asserted, all output
29+
/// signals in `mst_req_o` are silenced to `'0`. When isolated, new transactions initiated on the
30+
/// slave port are stalled until the isolation is terminated by deasserting `isolate_i`.
31+
///
32+
/// ## Response
33+
///
34+
/// If the `TerminateTransaction` parameter is set to `1'b1`, the module will return response errors
35+
/// in case there is an incoming transaction while the module isolates. The data returned on the
36+
/// bus is `1501A7ED` (hexspeak for isolated).
37+
///
38+
/// If `TerminateTransaction` is set to `1'b0`, the transaction will block indefinitely until the
39+
/// module is de-isolated again.
3340
module axi_isolate #(
34-
parameter int unsigned NumPending = 32'd16, // Number of pending requests per channel
35-
parameter type axi_req_t = logic, // AXI request struct definition
36-
parameter type axi_resp_t = logic // AXI response struct definition
41+
/// Maximum number of pending requests per channel
42+
parameter int unsigned NumPending = 32'd16,
43+
/// Gracefully terminate all incoming transactions in case of isolation by returning proper error
44+
/// responses.
45+
parameter bit TerminateTransaction = 1'b0,
46+
/// Support atomic operations (ATOPs)
47+
parameter bit AtopSupport = 1'b1,
48+
/// Address width of all AXI4+ATOP ports
49+
parameter int unsigned AxiAddrWidth = 32'd0,
50+
/// Data width of all AXI4+ATOP ports
51+
parameter int unsigned AxiDataWidth = 32'd0,
52+
/// ID width of all AXI4+ATOP ports
53+
parameter int unsigned AxiIdWidth = 32'd0,
54+
/// User signal width of all AXI4+ATOP ports
55+
parameter int unsigned AxiUserWidth = 32'd0,
56+
/// Request struct type of all AXI4+ATOP ports
57+
parameter type axi_req_t = logic,
58+
/// Response struct type of all AXI4+ATOP ports
59+
parameter type axi_resp_t = logic
3760
) (
38-
input logic clk_i, // clock
39-
input logic rst_ni, // reset
40-
input axi_req_t slv_req_i, // slave port request struct
41-
output axi_resp_t slv_resp_o, // slave port response struct
42-
output axi_req_t mst_req_o, // master port request struct
43-
input axi_resp_t mst_resp_i, // master port response struct
44-
input logic isolate_i, // isolate master port from slave port
45-
output logic isolated_o // master port is isolated from slave port
61+
/// Rising-edge clock of all ports
62+
input logic clk_i,
63+
/// Asynchronous reset, active low
64+
input logic rst_ni,
65+
/// Slave port request
66+
input axi_req_t slv_req_i,
67+
/// Slave port response
68+
output axi_resp_t slv_resp_o,
69+
/// Master port request
70+
output axi_req_t mst_req_o,
71+
/// Master port response
72+
input axi_resp_t mst_resp_i,
73+
/// Isolate master port from slave port
74+
input logic isolate_i,
75+
/// Master port is isolated from slave port
76+
output logic isolated_o
4677
);
78+
79+
typedef logic [AxiIdWidth-1:0] id_t;
80+
typedef logic [AxiAddrWidth-1:0] addr_t;
81+
typedef logic [AxiDataWidth-1:0] data_t;
82+
typedef logic [AxiDataWidth/8-1:0] strb_t;
83+
typedef logic [AxiUserWidth-1:0] user_t;
84+
85+
`AXI_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t, id_t, user_t)
86+
`AXI_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t, user_t)
87+
`AXI_TYPEDEF_B_CHAN_T(b_chan_t, id_t, user_t)
88+
`AXI_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t, id_t, user_t)
89+
`AXI_TYPEDEF_R_CHAN_T(r_chan_t, data_t, id_t, user_t)
90+
91+
axi_req_t [1:0] demux_req;
92+
axi_resp_t [1:0] demux_rsp;
93+
94+
if (TerminateTransaction) begin
95+
axi_demux #(
96+
.AxiIdWidth ( AxiIdWidth ),
97+
.AtopSupport ( AtopSupport ),
98+
.aw_chan_t ( aw_chan_t ),
99+
.w_chan_t ( w_chan_t ),
100+
.b_chan_t ( b_chan_t ),
101+
.ar_chan_t ( ar_chan_t ),
102+
.r_chan_t ( r_chan_t ),
103+
.axi_req_t ( axi_req_t ),
104+
.axi_resp_t ( axi_resp_t ),
105+
.NoMstPorts ( 2 ),
106+
.MaxTrans ( NumPending ),
107+
// We don't need many bits here as the common case will be to go for the pass-through.
108+
.AxiLookBits ( 1 ),
109+
.UniqueIds ( 1'b0 ),
110+
.FallThrough ( 1'b1 ),
111+
.SpillAw ( 1'b0 ),
112+
.SpillW ( 1'b0 ),
113+
.SpillB ( 1'b0 ),
114+
.SpillAr ( 1'b0 ),
115+
.SpillR ( 1'b0 )
116+
) i_axi_demux (
117+
.clk_i,
118+
.rst_ni,
119+
.test_i ( 1'b0 ),
120+
.slv_req_i,
121+
.slv_aw_select_i ( isolated_o ),
122+
.slv_ar_select_i ( isolated_o ),
123+
.slv_resp_o,
124+
.mst_reqs_o ( demux_req ),
125+
.mst_resps_i ( demux_rsp )
126+
);
127+
128+
axi_err_slv #(
129+
.AxiIdWidth ( AxiIdWidth ),
130+
.axi_req_t ( axi_req_t ),
131+
.axi_resp_t ( axi_resp_t ),
132+
.Resp ( axi_pkg::RESP_DECERR ),
133+
.RespData ( 'h1501A7ED ),
134+
.ATOPs ( AtopSupport ),
135+
.MaxTrans ( 1 )
136+
) i_axi_err_slv (
137+
.clk_i,
138+
.rst_ni,
139+
.test_i ( 1'b0 ),
140+
.slv_req_i ( demux_req[1] ),
141+
.slv_resp_o ( demux_rsp[1] )
142+
);
143+
end else begin
144+
assign demux_req[0] = slv_req_i;
145+
assign slv_resp_o = demux_rsp[0];
146+
end
147+
148+
axi_isolate_inner #(
149+
.NumPending ( NumPending ),
150+
.axi_req_t ( axi_req_t ),
151+
.axi_resp_t ( axi_resp_t )
152+
) i_axi_isolate (
153+
.clk_i,
154+
.rst_ni,
155+
.slv_req_i ( demux_req[0] ),
156+
.slv_resp_o ( demux_rsp[0] ),
157+
.mst_req_o,
158+
.mst_resp_i,
159+
.isolate_i,
160+
.isolated_o
161+
);
162+
endmodule
163+
164+
module axi_isolate_inner #(
165+
parameter int unsigned NumPending = 32'd16,
166+
parameter type axi_req_t = logic,
167+
parameter type axi_resp_t = logic
168+
) (
169+
input logic clk_i,
170+
input logic rst_ni,
171+
input axi_req_t slv_req_i,
172+
output axi_resp_t slv_resp_o,
173+
output axi_req_t mst_req_o,
174+
input axi_resp_t mst_resp_i,
175+
input logic isolate_i,
176+
output logic isolated_o
177+
);
178+
47179
// plus 1 in clog for accouning no open transaction, plus one bit for atomic injection
48180
localparam int unsigned CounterWidth = $clog2(NumPending + 32'd1) + 32'd1;
49181
typedef logic [CounterWidth-1:0] cnt_t;
@@ -275,22 +407,26 @@ module axi_isolate #(
275407
// pragma translate_on
276408
endmodule
277409

278-
`include "axi/typedef.svh"
279410
`include "axi/assign.svh"
280411

412+
/// Interface variant of [`axi_isolate`](module.axi_isolate).
413+
///
414+
/// See the documentation of the main module for the definition of ports and parameters.
281415
module axi_isolate_intf #(
282-
parameter int unsigned NUM_PENDING = 32'd16, // Number of pending requests
283-
parameter int unsigned AXI_ID_WIDTH = 32'd0, // AXI ID width
284-
parameter int unsigned AXI_ADDR_WIDTH = 32'd0, // AXI address width
285-
parameter int unsigned AXI_DATA_WIDTH = 32'd0, // AXI data width
286-
parameter int unsigned AXI_USER_WIDTH = 32'd0 // AXI user width
416+
parameter int unsigned NUM_PENDING = 32'd16,
417+
parameter bit TERMINATE_TRANSACTION = 1'b0,
418+
parameter bit ATOP_SUPPORT = 1'b1,
419+
parameter int unsigned AXI_ID_WIDTH = 32'd0,
420+
parameter int unsigned AXI_ADDR_WIDTH = 32'd0,
421+
parameter int unsigned AXI_DATA_WIDTH = 32'd0,
422+
parameter int unsigned AXI_USER_WIDTH = 32'd0
287423
) (
288-
input logic clk_i, // clock
289-
input logic rst_ni, // asynchronous reset active low
290-
AXI_BUS.Slave slv, // slave port
291-
AXI_BUS.Master mst, // master port
292-
input logic isolate_i, // isolate master port from slave port
293-
output logic isolated_o // master port is isolated from slave port
424+
input logic clk_i,
425+
input logic rst_ni,
426+
AXI_BUS.Slave slv,
427+
AXI_BUS.Master mst,
428+
input logic isolate_i,
429+
output logic isolated_o
294430
);
295431
typedef logic [AXI_ID_WIDTH-1:0] id_t;
296432
typedef logic [AXI_ADDR_WIDTH-1:0] addr_t;
@@ -318,18 +454,24 @@ module axi_isolate_intf #(
318454
`AXI_ASSIGN_TO_RESP(mst_resp, mst)
319455

320456
axi_isolate #(
321-
.NumPending ( NUM_PENDING ), // Number of pending requests per channel
322-
.axi_req_t ( axi_req_t ), // AXI request struct definition
323-
.axi_resp_t ( axi_resp_t ) // AXI response struct definition
457+
.NumPending ( NUM_PENDING ),
458+
.TerminateTransaction ( TERMINATE_TRANSACTION ),
459+
.AtopSupport ( ATOP_SUPPORT ),
460+
.AxiAddrWidth ( AXI_ADDR_WIDTH ),
461+
.AxiDataWidth ( AXI_DATA_WIDTH ),
462+
.AxiIdWidth ( AXI_ID_WIDTH ),
463+
.AxiUserWidth ( AXI_USER_WIDTH ),
464+
.axi_req_t ( axi_req_t ),
465+
.axi_resp_t ( axi_resp_t )
324466
) i_axi_isolate (
325-
.clk_i, // clock
326-
.rst_ni, // reset
327-
.slv_req_i ( slv_req ), // slave port request struct
328-
.slv_resp_o ( slv_resp ), // slave port response struct
329-
.mst_req_o ( mst_req ), // master port request struct
330-
.mst_resp_i ( mst_resp ), // master port response struct
331-
.isolate_i, // isolate master port from slave port
332-
.isolated_o // master port is isolated from slave port
467+
.clk_i,
468+
.rst_ni,
469+
.slv_req_i ( slv_req ),
470+
.slv_resp_o ( slv_resp ),
471+
.mst_req_o ( mst_req ),
472+
.mst_resp_i ( mst_resp ),
473+
.isolate_i,
474+
.isolated_o
333475
);
334476

335477
// pragma translate_off

0 commit comments

Comments
 (0)