|
13 | 13 | // - Wolfgang Roenninger <[email protected]>
|
14 | 14 | // - Andreas Kurth <[email protected]>
|
15 | 15 |
|
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" |
31 | 17 | `include "common_cells/registers.svh"
|
32 | 18 |
|
| 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. |
33 | 40 | 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 |
37 | 60 | ) (
|
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 |
46 | 77 | );
|
| 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 | + |
47 | 179 | // plus 1 in clog for accouning no open transaction, plus one bit for atomic injection
|
48 | 180 | localparam int unsigned CounterWidth = $clog2(NumPending + 32'd1) + 32'd1;
|
49 | 181 | typedef logic [CounterWidth-1:0] cnt_t;
|
@@ -275,22 +407,26 @@ module axi_isolate #(
|
275 | 407 | // pragma translate_on
|
276 | 408 | endmodule
|
277 | 409 |
|
278 |
| -`include "axi/typedef.svh" |
279 | 410 | `include "axi/assign.svh"
|
280 | 411 |
|
| 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. |
281 | 415 | 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 |
287 | 423 | ) (
|
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 |
294 | 430 | );
|
295 | 431 | typedef logic [AXI_ID_WIDTH-1:0] id_t;
|
296 | 432 | typedef logic [AXI_ADDR_WIDTH-1:0] addr_t;
|
@@ -318,18 +454,24 @@ module axi_isolate_intf #(
|
318 | 454 | `AXI_ASSIGN_TO_RESP(mst_resp, mst)
|
319 | 455 |
|
320 | 456 | 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 ) |
324 | 466 | ) 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 |
333 | 475 | );
|
334 | 476 |
|
335 | 477 | // pragma translate_off
|
|
0 commit comments