Commit ba226a13 authored by Luca Valente's avatar Luca Valente Committed by Andreas Kurth
Browse files

axi_cdc: Modularize into source and destination side

Co-authored-by: default avatarAndreas Kurth <akurth@iis.ee.ethz.ch>
Co-authored-by: default avatarManuel Eggimann <meggimann@iis.ee.ethz.ch>
parent d0f3d1f9
Showing with 723 additions and 84 deletions
+723 -84
...@@ -55,6 +55,8 @@ artifacts: ...@@ -55,6 +55,8 @@ artifacts:
- src/axi_pkg.sv - src/axi_pkg.sv
- src/axi_intf.sv - src/axi_intf.sv
- src/axi_test.sv - src/axi_test.sv
- src/axi_cdc_dst.sv
- src/axi_cdc_src.sv
- src/axi_cdc.sv - src/axi_cdc.sv
- test/tb_axi_cdc.sv - test/tb_axi_cdc.sv
outputs: outputs:
......
...@@ -25,7 +25,8 @@ sources: ...@@ -25,7 +25,8 @@ sources:
# Level 2 # Level 2
- src/axi_atop_filter.sv - src/axi_atop_filter.sv
- src/axi_burst_splitter.sv - src/axi_burst_splitter.sv
- src/axi_cdc.sv - src/axi_cdc_dst.sv
- src/axi_cdc_src.sv
- src/axi_cut.sv - src/axi_cut.sv
- src/axi_delayer.sv - src/axi_delayer.sv
- src/axi_demux.sv - src/axi_demux.sv
...@@ -45,6 +46,7 @@ sources: ...@@ -45,6 +46,7 @@ sources:
- src/axi_mux.sv - src/axi_mux.sv
- src/axi_serializer.sv - src/axi_serializer.sv
# Level 3 # Level 3
- src/axi_cdc.sv
- src/axi_err_slv.sv - src/axi_err_slv.sv
- src/axi_dw_converter.sv - src/axi_dw_converter.sv
- src/axi_multicut.sv - src/axi_multicut.sv
......
...@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ...@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## Unreleased ## Unreleased
### Added ### Added
- Add source- and destination-clock-domain "halves" for the clock domain crossing (CDC):
`axi_cdc_src` and `axi_cdc_dst`. This is implemented by refactoring the `axi_cdc` module, so the
implementation is reused from the existing `axi_cdc` module. To avoid code duplication, `axi_cdc`
now instantiates an `axi_cdc_src` connected to an `axi_cdc_dst`.
### Changed ### Changed
- `axi_lite_to_apb`: Make pipeline registers on request and response path optional (can be enabled - `axi_lite_to_apb`: Make pipeline registers on request and response path optional (can be enabled
......
...@@ -17,7 +17,8 @@ filesets: ...@@ -17,7 +17,8 @@ filesets:
# Level 2 # Level 2
- src/axi_atop_filter.sv - src/axi_atop_filter.sv
- src/axi_burst_splitter.sv - src/axi_burst_splitter.sv
- src/axi_cdc.sv - src/axi_cdc_dst.sv
- src/axi_cdc_src.sv
- src/axi_cut.sv - src/axi_cut.sv
- src/axi_delayer.sv - src/axi_delayer.sv
- src/axi_demux.sv - src/axi_demux.sv
...@@ -37,6 +38,7 @@ filesets: ...@@ -37,6 +38,7 @@ filesets:
- src/axi_mux.sv - src/axi_mux.sv
- src/axi_serializer.sv - src/axi_serializer.sv
# Level 3 # Level 3
- src/axi_cdc.sv
- src/axi_err_slv.sv - src/axi_err_slv.sv
- src/axi_dw_converter.sv - src/axi_dw_converter.sv
- src/axi_multicut.sv - src/axi_multicut.sv
......
// Copyright (c) 20192-2020 ETH Zurich, University of Bologna // Copyright (c) 2019-2020 ETH Zurich, University of Bologna
// //
// Copyright and related rights are licensed under the Solderpad Hardware // Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in // License, Version 0.51 (the "License"); you may not use this file except in
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
// - Fabian Schuiki <fschuiki@iis.ee.ethz.ch> // - Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
// - Florian Zaruba <zarubaf@iis.ee.ethz.ch> // - Florian Zaruba <zarubaf@iis.ee.ethz.ch>
// - Wolfgang Roenninger <wroennin@iis.ee.ethz.ch> // - Wolfgang Roenninger <wroennin@iis.ee.ethz.ch>
// - Luca Valente <luca.valente2@unibo.it>
`include "axi/assign.svh" `include "axi/assign.svh"
...@@ -45,86 +46,80 @@ module axi_cdc #( ...@@ -45,86 +46,80 @@ module axi_cdc #(
input axi_resp_t dst_resp_i input axi_resp_t dst_resp_i
); );
cdc_fifo_gray #( aw_chan_t [2**LogDepth-1:0] async_data_aw_data;
// We need to cast to bits here because of some arbitrary bug in Synopsys. w_chan_t [2**LogDepth-1:0] async_data_w_data;
.WIDTH ( $bits(aw_chan_t) ), b_chan_t [2**LogDepth-1:0] async_data_b_data;
.LOG_DEPTH ( LogDepth ) ar_chan_t [2**LogDepth-1:0] async_data_ar_data;
) i_cdc_fifo_gray_aw ( r_chan_t [2**LogDepth-1:0] async_data_r_data;
.src_rst_ni, logic [LogDepth:0] async_data_aw_wptr, async_data_aw_rptr,
.src_clk_i, async_data_w_wptr, async_data_w_rptr,
.src_data_i ( src_req_i.aw ), async_data_b_wptr, async_data_b_rptr,
.src_valid_i ( src_req_i.aw_valid ), async_data_ar_wptr, async_data_ar_rptr,
.src_ready_o ( src_resp_o.aw_ready ), async_data_r_wptr, async_data_r_rptr;
.dst_rst_ni,
.dst_clk_i, axi_cdc_src #(
.dst_data_o ( dst_req_o.aw ), .aw_chan_t ( aw_chan_t ),
.dst_valid_o ( dst_req_o.aw_valid ), .w_chan_t ( w_chan_t ),
.dst_ready_i ( dst_resp_i.aw_ready ) .b_chan_t ( b_chan_t ),
); .ar_chan_t ( ar_chan_t ),
.r_chan_t ( r_chan_t ),
cdc_fifo_gray #( .axi_req_t ( axi_req_t ),
.WIDTH ( $bits(w_chan_t) ), .axi_resp_t ( axi_resp_t ),
.LOG_DEPTH ( LogDepth ) .LogDepth ( LogDepth )
) i_cdc_fifo_gray_w ( ) i_axi_cdc_src (
.src_rst_ni, .src_clk_i,
.src_clk_i, .src_rst_ni,
.src_data_i ( src_req_i.w ), .isolate_i ( 1'b0 ),
.src_valid_i ( src_req_i.w_valid ), .src_req_i,
.src_ready_o ( src_resp_o.w_ready ), .src_resp_o,
.dst_rst_ni, (* async *) .async_data_master_aw_data_o ( async_data_aw_data ),
.dst_clk_i, (* async *) .async_data_master_aw_wptr_o ( async_data_aw_wptr ),
.dst_data_o ( dst_req_o.w ), (* async *) .async_data_master_aw_rptr_i ( async_data_aw_rptr ),
.dst_valid_o ( dst_req_o.w_valid ), (* async *) .async_data_master_w_data_o ( async_data_w_data ),
.dst_ready_i ( dst_resp_i.w_ready ) (* async *) .async_data_master_w_wptr_o ( async_data_w_wptr ),
); (* async *) .async_data_master_w_rptr_i ( async_data_w_rptr ),
(* async *) .async_data_master_b_data_i ( async_data_b_data ),
cdc_fifo_gray #( (* async *) .async_data_master_b_wptr_i ( async_data_b_wptr ),
.WIDTH ( $bits(b_chan_t) ), (* async *) .async_data_master_b_rptr_o ( async_data_b_rptr ),
.LOG_DEPTH ( LogDepth ) (* async *) .async_data_master_ar_data_o ( async_data_ar_data ),
) i_cdc_fifo_gray_b ( (* async *) .async_data_master_ar_wptr_o ( async_data_ar_wptr ),
.src_rst_ni ( dst_rst_ni ), (* async *) .async_data_master_ar_rptr_i ( async_data_ar_rptr ),
.src_clk_i ( dst_clk_i ), (* async *) .async_data_master_r_data_i ( async_data_r_data ),
.src_data_i ( dst_resp_i.b ), (* async *) .async_data_master_r_wptr_i ( async_data_r_wptr ),
.src_valid_i ( dst_resp_i.b_valid ), (* async *) .async_data_master_r_rptr_o ( async_data_r_rptr )
.src_ready_o ( dst_req_o.b_ready ), );
.dst_rst_ni ( src_rst_ni ),
.dst_clk_i ( src_clk_i ), axi_cdc_dst #(
.dst_data_o ( src_resp_o.b ), .aw_chan_t ( aw_chan_t ),
.dst_valid_o ( src_resp_o.b_valid ), .w_chan_t ( w_chan_t ),
.dst_ready_i ( src_req_i.b_ready ) .b_chan_t ( b_chan_t ),
); .ar_chan_t ( ar_chan_t ),
.r_chan_t ( r_chan_t ),
cdc_fifo_gray #( .axi_req_t ( axi_req_t ),
.WIDTH ( $bits(ar_chan_t) ), .axi_resp_t ( axi_resp_t ),
.LOG_DEPTH ( LogDepth ) .LogDepth ( LogDepth )
) i_cdc_fifo_gray_ar ( ) i_axi_cdc_dst (
.src_rst_ni, .dst_clk_i,
.src_clk_i, .dst_rst_ni,
.src_data_i ( src_req_i.ar ), .isolate_i ( 1'b0 ),
.src_valid_i ( src_req_i.ar_valid ), .dst_req_o,
.src_ready_o ( src_resp_o.ar_ready ), .dst_resp_i,
.dst_rst_ni, (* async *) .async_data_slave_aw_wptr_i ( async_data_aw_wptr ),
.dst_clk_i, (* async *) .async_data_slave_aw_rptr_o ( async_data_aw_rptr ),
.dst_data_o ( dst_req_o.ar ), (* async *) .async_data_slave_aw_data_i ( async_data_aw_data ),
.dst_valid_o ( dst_req_o.ar_valid ), (* async *) .async_data_slave_w_wptr_i ( async_data_w_wptr ),
.dst_ready_i ( dst_resp_i.ar_ready ) (* async *) .async_data_slave_w_rptr_o ( async_data_w_rptr ),
); (* async *) .async_data_slave_w_data_i ( async_data_w_data ),
(* async *) .async_data_slave_b_wptr_o ( async_data_b_wptr ),
cdc_fifo_gray #( (* async *) .async_data_slave_b_rptr_i ( async_data_b_rptr ),
.WIDTH ( $bits(r_chan_t) ), (* async *) .async_data_slave_b_data_o ( async_data_b_data ),
.LOG_DEPTH ( LogDepth ) (* async *) .async_data_slave_ar_wptr_i ( async_data_ar_wptr ),
) i_cdc_fifo_gray_r ( (* async *) .async_data_slave_ar_rptr_o ( async_data_ar_rptr ),
.src_rst_ni ( dst_rst_ni ), (* async *) .async_data_slave_ar_data_i ( async_data_ar_data ),
.src_clk_i ( dst_clk_i ), (* async *) .async_data_slave_r_wptr_o ( async_data_r_wptr ),
.src_data_i ( dst_resp_i.r ), (* async *) .async_data_slave_r_rptr_i ( async_data_r_rptr ),
.src_valid_i ( dst_resp_i.r_valid ), (* async *) .async_data_slave_r_data_o ( async_data_r_data )
.src_ready_o ( dst_req_o.r_ready ), );
.dst_rst_ni ( src_rst_ni ),
.dst_clk_i ( src_clk_i ),
.dst_data_o ( src_resp_o.r ),
.dst_valid_o ( src_resp_o.r_valid ),
.dst_ready_i ( src_req_i.r_ready )
);
endmodule endmodule
......
// Copyright (c) 2019-2020 ETH Zurich, University of Bologna
//
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Authors:
// - Andreas Kurth <akurth@iis.ee.ethz.ch>
// - Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
// - Florian Zaruba <zarubaf@iis.ee.ethz.ch>
// - Luca Valente <luca.valente2@unibo.it>
`include "axi/assign.svh"
`include "axi/typedef.svh"
/// Destination-clock-domain half of the AXI CDC crossing.
///
/// For each of the five AXI channels, this module instantiates the source or destination half of
/// a CDC FIFO. IMPORTANT: For each AXI channel, you MUST properly constrain three paths through
/// the FIFO; see the header of `cdc_fifo_gray` for instructions.
module axi_cdc_dst #(
/// Depth of the FIFO crossing the clock domain, given as 2**LOG_DEPTH.
parameter int unsigned LogDepth = 1,
parameter type aw_chan_t = logic,
parameter type w_chan_t = logic,
parameter type b_chan_t = logic,
parameter type ar_chan_t = logic,
parameter type r_chan_t = logic,
parameter type axi_req_t = logic,
parameter type axi_resp_t = logic
) (
// asynchronous slave port
input aw_chan_t [2**LogDepth-1:0] async_data_slave_aw_data_i,
input logic [LogDepth:0] async_data_slave_aw_wptr_i,
output logic [LogDepth:0] async_data_slave_aw_rptr_o,
input w_chan_t [2**LogDepth-1:0] async_data_slave_w_data_i,
input logic [LogDepth:0] async_data_slave_w_wptr_i,
output logic [LogDepth:0] async_data_slave_w_rptr_o,
output b_chan_t [2**LogDepth-1:0] async_data_slave_b_data_o,
output logic [LogDepth:0] async_data_slave_b_wptr_o,
input logic [LogDepth:0] async_data_slave_b_rptr_i,
input ar_chan_t [2**LogDepth-1:0] async_data_slave_ar_data_i,
input logic [LogDepth:0] async_data_slave_ar_wptr_i,
output logic [LogDepth:0] async_data_slave_ar_rptr_o,
output r_chan_t [2**LogDepth-1:0] async_data_slave_r_data_o,
output logic [LogDepth:0] async_data_slave_r_wptr_o,
input logic [LogDepth:0] async_data_slave_r_rptr_i,
// synchronous master port - clocked by `dst_clk_i`
input logic dst_clk_i,
input logic dst_rst_ni,
input logic isolate_i,
output axi_req_t dst_req_o,
input axi_resp_t dst_resp_i
);
cdc_fifo_gray_dst #(
.T ( logic [$bits(aw_chan_t)-1:0] ),
.LOG_DEPTH ( LogDepth )
) i_cdc_fifo_gray_dst_aw (
.async_data_i ( async_data_slave_aw_data_i ),
.async_wptr_i ( async_data_slave_aw_wptr_i ),
.async_rptr_o ( async_data_slave_aw_rptr_o ),
.dst_clk_i,
.dst_rst_ni,
.dst_data_o ( dst_req_o.aw ),
.dst_valid_o ( dst_req_o.aw_valid ),
.dst_ready_i ( dst_resp_i.aw_ready & ~isolate_i )
);
cdc_fifo_gray_dst #(
.T ( logic [$bits(w_chan_t)-1:0] ),
.LOG_DEPTH ( LogDepth )
) i_cdc_fifo_gray_dst_w (
.async_data_i ( async_data_slave_w_data_i ),
.async_wptr_i ( async_data_slave_w_wptr_i ),
.async_rptr_o ( async_data_slave_w_rptr_o ),
.dst_clk_i,
.dst_rst_ni,
.dst_data_o ( dst_req_o.w ),
.dst_valid_o ( dst_req_o.w_valid ),
.dst_ready_i ( dst_resp_i.w_ready & ~isolate_i )
);
cdc_fifo_gray_src #(
.T ( logic [$bits(b_chan_t)-1:0] ),
.LOG_DEPTH ( LogDepth )
) i_cdc_fifo_gray_src_b (
.src_clk_i ( dst_clk_i ),
.src_rst_ni ( dst_rst_ni ),
.src_data_i ( dst_resp_i.b ),
.src_valid_i ( dst_resp_i.b_valid & ~isolate_i ),
.src_ready_o ( dst_req_o.b_ready ),
.async_data_o ( async_data_slave_b_data_o ),
.async_wptr_o ( async_data_slave_b_wptr_o ),
.async_rptr_i ( async_data_slave_b_rptr_i )
);
cdc_fifo_gray_dst #(
.T ( logic [$bits(ar_chan_t)-1:0] ),
.LOG_DEPTH ( LogDepth )
) i_cdc_fifo_gray_dst_ar (
.dst_clk_i,
.dst_rst_ni,
.dst_data_o ( dst_req_o.ar ),
.dst_valid_o ( dst_req_o.ar_valid ),
.dst_ready_i ( dst_resp_i.ar_ready & ~isolate_i ),
.async_data_i ( async_data_slave_ar_data_i ),
.async_wptr_i ( async_data_slave_ar_wptr_i ),
.async_rptr_o ( async_data_slave_ar_rptr_o )
);
cdc_fifo_gray_src #(
.T ( logic [$bits(r_chan_t)-1:0] ),
.LOG_DEPTH ( LogDepth )
) i_cdc_fifo_gray_src_r (
.src_clk_i ( dst_clk_i ),
.src_rst_ni ( dst_rst_ni ),
.src_data_i ( dst_resp_i.r ),
.src_valid_i ( dst_resp_i.r_valid & ~isolate_i ),
.src_ready_o ( dst_req_o.r_ready ),
.async_data_o ( async_data_slave_r_data_o ),
.async_wptr_o ( async_data_slave_r_wptr_o ),
.async_rptr_i ( async_data_slave_r_rptr_i )
);
endmodule
module axi_cdc_dst_intf #(
parameter int unsigned AXI_ID_WIDTH = 0,
parameter int unsigned AXI_ADDR_WIDTH = 0,
parameter int unsigned AXI_DATA_WIDTH = 0,
parameter int unsigned AXI_USER_WIDTH = 0,
/// Depth of the FIFO crossing the clock domain, given as 2**LOG_DEPTH.
parameter int unsigned LOG_DEPTH = 1
) (
// asynchronous slave port
AXI_BUS_ASYNC_GRAY.Slave src,
// synchronous master port - clocked by `dst_clk_i`
input logic dst_clk_i,
input logic dst_rst_ni,
AXI_BUS.Master dst
);
typedef logic [AXI_ID_WIDTH-1:0] id_t;
typedef logic [AXI_ADDR_WIDTH-1:0] addr_t;
typedef logic [AXI_DATA_WIDTH-1:0] data_t;
typedef logic [AXI_DATA_WIDTH/8-1:0] strb_t;
typedef logic [AXI_USER_WIDTH-1:0] user_t;
`AXI_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t, id_t, user_t)
`AXI_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t, user_t)
`AXI_TYPEDEF_B_CHAN_T(b_chan_t, id_t, user_t)
`AXI_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t, id_t, user_t)
`AXI_TYPEDEF_R_CHAN_T(r_chan_t, data_t, id_t, user_t)
`AXI_TYPEDEF_REQ_T(req_t, aw_chan_t, w_chan_t, ar_chan_t)
`AXI_TYPEDEF_RESP_T(resp_t, b_chan_t, r_chan_t)
req_t dst_req;
resp_t dst_resp;
axi_cdc_dst #(
.aw_chan_t ( aw_chan_t ),
.w_chan_t ( w_chan_t ),
.b_chan_t ( b_chan_t ),
.ar_chan_t ( ar_chan_t ),
.r_chan_t ( r_chan_t ),
.axi_req_t ( req_t ),
.axi_resp_t ( resp_t ),
.LogDepth ( LOG_DEPTH )
) i_axi_cdc_dst (
.async_data_slave_aw_data_i ( src.aw_data ),
.async_data_slave_aw_wptr_i ( src.aw_wptr ),
.async_data_slave_aw_rptr_o ( src.aw_rptr ),
.async_data_slave_w_data_i ( src.w_data ),
.async_data_slave_w_wptr_i ( src.w_wptr ),
.async_data_slave_w_rptr_o ( src.w_rptr ),
.async_data_slave_b_data_o ( src.b_data ),
.async_data_slave_b_wptr_o ( src.b_wptr ),
.async_data_slave_b_rptr_i ( src.b_rptr ),
.async_data_slave_ar_data_i ( src.ar_data ),
.async_data_slave_ar_wptr_i ( src.ar_wptr ),
.async_data_slave_ar_rptr_o ( src.ar_rptr ),
.async_data_slave_r_data_o ( src.r_data ),
.async_data_slave_r_wptr_o ( src.r_wptr ),
.async_data_slave_r_rptr_i ( src.r_rptr ),
.dst_clk_i,
.dst_rst_ni,
.dst_req_o ( dst_req ),
.dst_resp_i ( dst_resp )
);
`AXI_ASSIGN_FROM_REQ(dst, dst_req)
`AXI_ASSIGN_TO_RESP(dst_resp, dst)
endmodule
module axi_lite_cdc_dst_intf #(
parameter int unsigned AXI_ADDR_WIDTH = 0,
parameter int unsigned AXI_DATA_WIDTH = 0,
/// Depth of the FIFO crossing the clock domain, given as 2**LOG_DEPTH.
parameter int unsigned LOG_DEPTH = 1
) (
// asynchronous slave port
AXI_LITE_ASYNC_GRAY.Slave src,
// synchronous master port - clocked by `dst_clk_i`
input logic dst_clk_i,
input logic dst_rst_ni,
AXI_LITE.Master dst
);
typedef logic [AXI_ADDR_WIDTH-1:0] addr_t;
typedef logic [AXI_DATA_WIDTH-1:0] data_t;
typedef logic [AXI_DATA_WIDTH/8-1:0] strb_t;
`AXI_LITE_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t)
`AXI_LITE_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t)
`AXI_LITE_TYPEDEF_B_CHAN_T(b_chan_t)
`AXI_LITE_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t)
`AXI_LITE_TYPEDEF_R_CHAN_T(r_chan_t, data_t)
`AXI_LITE_TYPEDEF_REQ_T(req_t, aw_chan_t, w_chan_t, ar_chan_t)
`AXI_LITE_TYPEDEF_RESP_T(resp_t, b_chan_t, r_chan_t)
req_t dst_req;
resp_t dst_resp;
axi_cdc_dst #(
.aw_chan_t ( aw_chan_t ),
.w_chan_t ( w_chan_t ),
.b_chan_t ( b_chan_t ),
.ar_chan_t ( ar_chan_t ),
.r_chan_t ( r_chan_t ),
.axi_req_t ( req_t ),
.axi_resp_t ( resp_t ),
.LogDepth ( LOG_DEPTH )
) i_axi_cdc_dst (
.async_data_slave_aw_data_i ( src.aw_data ),
.async_data_slave_aw_wptr_i ( src.aw_wptr ),
.async_data_slave_aw_rptr_o ( src.aw_rptr ),
.async_data_slave_w_data_i ( src.w_data ),
.async_data_slave_w_wptr_i ( src.w_wptr ),
.async_data_slave_w_rptr_o ( src.w_rptr ),
.async_data_slave_b_data_o ( src.b_data ),
.async_data_slave_b_wptr_o ( src.b_wptr ),
.async_data_slave_b_rptr_i ( src.b_rptr ),
.async_data_slave_ar_data_i ( src.ar_data ),
.async_data_slave_ar_wptr_i ( src.ar_wptr ),
.async_data_slave_ar_rptr_o ( src.ar_rptr ),
.async_data_slave_r_data_o ( src.r_data ),
.async_data_slave_r_wptr_o ( src.r_wptr ),
.async_data_slave_r_rptr_i ( src.r_rptr ),
.dst_clk_i,
.dst_rst_ni,
.dst_req_o ( dst_req ),
.dst_resp_i ( dst_resp )
);
`AXI_LITE_ASSIGN_FROM_REQ(dst, dst_req)
`AXI_LITE_ASSIGN_TO_RESP(dst_resp, dst)
endmodule
// Copyright (c) 2019-2020 ETH Zurich, University of Bologna
//
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Authors:
// - Andreas Kurth <akurth@iis.ee.ethz.ch>
// - Fabian Schuiki <fschuiki@iis.ee.ethz.ch>
// - Florian Zaruba <zarubaf@iis.ee.ethz.ch>
// - Luca Valente <luca.valente2@unibo.it>
`include "axi/assign.svh"
`include "axi/typedef.svh"
/// Source-clock-domain half of the AXI CDC crossing.
///
/// For each of the five AXI channels, this module instantiates the source or destination half of
/// a CDC FIFO. IMPORTANT: For each AXI channel, you MUST properly constrain three paths through
/// the FIFO; see the header of `cdc_fifo_gray` for instructions.
module axi_cdc_src #(
/// Depth of the FIFO crossing the clock domain, given as 2**LOG_DEPTH.
parameter int unsigned LogDepth = 1,
parameter type aw_chan_t = logic,
parameter type w_chan_t = logic,
parameter type b_chan_t = logic,
parameter type ar_chan_t = logic,
parameter type r_chan_t = logic,
parameter type axi_req_t = logic,
parameter type axi_resp_t = logic
) (
// synchronous slave port - clocked by `src_clk_i`
input logic src_clk_i,
input logic src_rst_ni,
input logic isolate_i,
input axi_req_t src_req_i,
output axi_resp_t src_resp_o,
// asynchronous master port
output aw_chan_t [2**LogDepth-1:0] async_data_master_aw_data_o,
output logic [LogDepth:0] async_data_master_aw_wptr_o,
input logic [LogDepth:0] async_data_master_aw_rptr_i,
output w_chan_t [2**LogDepth-1:0] async_data_master_w_data_o,
output logic [LogDepth:0] async_data_master_w_wptr_o,
input logic [LogDepth:0] async_data_master_w_rptr_i,
input b_chan_t [2**LogDepth-1:0] async_data_master_b_data_i,
input logic [LogDepth:0] async_data_master_b_wptr_i,
output logic [LogDepth:0] async_data_master_b_rptr_o,
output ar_chan_t [2**LogDepth-1:0] async_data_master_ar_data_o,
output logic [LogDepth:0] async_data_master_ar_wptr_o,
input logic [LogDepth:0] async_data_master_ar_rptr_i,
input r_chan_t [2**LogDepth-1:0] async_data_master_r_data_i,
input logic [LogDepth:0] async_data_master_r_wptr_i,
output logic [LogDepth:0] async_data_master_r_rptr_o
);
cdc_fifo_gray_src #(
.T ( logic [$bits(aw_chan_t)-1:0] ),
.LOG_DEPTH ( LogDepth )
) i_cdc_fifo_gray_src_aw (
.src_clk_i,
.src_rst_ni,
.src_data_i ( src_req_i.aw ),
.src_valid_i ( src_req_i.aw_valid & ~isolate_i ),
.src_ready_o ( src_resp_o.aw_ready ),
.async_data_o ( async_data_master_aw_data_o ),
.async_wptr_o ( async_data_master_aw_wptr_o ),
.async_rptr_i ( async_data_master_aw_rptr_i )
);
cdc_fifo_gray_src #(
.T ( logic [$bits(w_chan_t)-1:0] ),
.LOG_DEPTH ( LogDepth )
) i_cdc_fifo_gray_src_w (
.src_clk_i,
.src_rst_ni,
.src_data_i ( src_req_i.w ),
.src_valid_i ( src_req_i.w_valid & ~isolate_i ),
.src_ready_o ( src_resp_o.w_ready ),
.async_data_o ( async_data_master_w_data_o ),
.async_wptr_o ( async_data_master_w_wptr_o ),
.async_rptr_i ( async_data_master_w_rptr_i )
);
cdc_fifo_gray_dst #(
.T ( logic [$bits(b_chan_t)-1:0] ),
.LOG_DEPTH ( LogDepth )
) i_cdc_fifo_gray_dst_b (
.dst_clk_i ( src_clk_i ),
.dst_rst_ni ( src_rst_ni ),
.dst_data_o ( src_resp_o.b ),
.dst_valid_o ( src_resp_o.b_valid ),
.dst_ready_i ( src_req_i.b_ready & ~isolate_i ),
.async_data_i ( async_data_master_b_data_i ),
.async_wptr_i ( async_data_master_b_wptr_i ),
.async_rptr_o ( async_data_master_b_rptr_o )
);
cdc_fifo_gray_src #(
.T ( logic [$bits(ar_chan_t)-1:0] ),
.LOG_DEPTH ( LogDepth )
) i_cdc_fifo_gray_src_ar (
.src_clk_i,
.src_rst_ni,
.src_data_i ( src_req_i.ar ),
.src_valid_i ( src_req_i.ar_valid & ~isolate_i ),
.src_ready_o ( src_resp_o.ar_ready ),
.async_data_o ( async_data_master_ar_data_o ),
.async_wptr_o ( async_data_master_ar_wptr_o ),
.async_rptr_i ( async_data_master_ar_rptr_i )
);
cdc_fifo_gray_dst #(
.T ( logic [$bits(r_chan_t)-1:0] ),
.LOG_DEPTH ( LogDepth )
) i_cdc_fifo_gray_dst_r (
.dst_clk_i ( src_clk_i ),
.dst_rst_ni ( src_rst_ni ),
.dst_data_o ( src_resp_o.r ),
.dst_valid_o ( src_resp_o.r_valid ),
.dst_ready_i ( src_req_i.r_ready & ~isolate_i ),
.async_data_i ( async_data_master_r_data_i ),
.async_wptr_i ( async_data_master_r_wptr_i ),
.async_rptr_o ( async_data_master_r_rptr_o )
);
endmodule
module axi_cdc_src_intf #(
parameter int unsigned AXI_ID_WIDTH = 0,
parameter int unsigned AXI_ADDR_WIDTH = 0,
parameter int unsigned AXI_DATA_WIDTH = 0,
parameter int unsigned AXI_USER_WIDTH = 0,
/// Depth of the FIFO crossing the clock domain, given as 2**LOG_DEPTH.
parameter int unsigned LOG_DEPTH = 1
) (
// synchronous slave port - clocked by `src_clk_i`
input logic src_clk_i,
input logic src_rst_ni,
AXI_BUS.Slave src,
// asynchronous master port
AXI_BUS_ASYNC_GRAY.Master dst
);
typedef logic [AXI_ID_WIDTH-1:0] id_t;
typedef logic [AXI_ADDR_WIDTH-1:0] addr_t;
typedef logic [AXI_DATA_WIDTH-1:0] data_t;
typedef logic [AXI_DATA_WIDTH/8-1:0] strb_t;
typedef logic [AXI_USER_WIDTH-1:0] user_t;
`AXI_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t, id_t, user_t)
`AXI_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t, user_t)
`AXI_TYPEDEF_B_CHAN_T(b_chan_t, id_t, user_t)
`AXI_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t, id_t, user_t)
`AXI_TYPEDEF_R_CHAN_T(r_chan_t, data_t, id_t, user_t)
`AXI_TYPEDEF_REQ_T(req_t, aw_chan_t, w_chan_t, ar_chan_t)
`AXI_TYPEDEF_RESP_T(resp_t, b_chan_t, r_chan_t)
req_t src_req;
resp_t src_resp;
`AXI_ASSIGN_TO_REQ(src_req, src)
`AXI_ASSIGN_FROM_RESP(src, src_resp)
axi_cdc_src #(
.aw_chan_t ( aw_chan_t ),
.w_chan_t ( w_chan_t ),
.b_chan_t ( b_chan_t ),
.ar_chan_t ( ar_chan_t ),
.r_chan_t ( r_chan_t ),
.axi_req_t ( req_t ),
.axi_resp_t ( resp_t ),
.LogDepth ( LOG_DEPTH )
) i_axi_cdc_src (
.src_clk_i,
.src_rst_ni,
.src_req_i ( src_req ),
.src_resp_o ( src_resp ),
.async_data_master_aw_data_o ( dst.aw_data ),
.async_data_master_aw_wptr_o ( dst.aw_wptr ),
.async_data_master_aw_rptr_i ( dst.aw_rptr ),
.async_data_master_w_data_o ( dst.w_data ),
.async_data_master_w_wptr_o ( dst.w_wptr ),
.async_data_master_w_rptr_i ( dst.w_rptr ),
.async_data_master_b_data_i ( dst.b_data ),
.async_data_master_b_wptr_i ( dst.b_wptr ),
.async_data_master_b_rptr_o ( dst.b_rptr ),
.async_data_master_ar_data_o ( dst.ar_data ),
.async_data_master_ar_wptr_o ( dst.ar_wptr ),
.async_data_master_ar_rptr_i ( dst.ar_rptr ),
.async_data_master_r_data_i ( dst.r_data ),
.async_data_master_r_wptr_i ( dst.r_wptr ),
.async_data_master_r_rptr_o ( dst.r_rptr )
);
endmodule
module axi_lite_cdc_src_intf #(
parameter int unsigned AXI_ADDR_WIDTH = 0,
parameter int unsigned AXI_DATA_WIDTH = 0,
/// Depth of the FIFO crossing the clock domain, given as 2**LOG_DEPTH.
parameter int unsigned LOG_DEPTH = 1
) (
// synchronous slave port - clocked by `src_clk_i`
input logic src_clk_i,
input logic src_rst_ni,
AXI_BUS.Slave src,
// asynchronous master port
AXI_LITE_ASYNC_GRAY.Master dst
);
typedef logic [AXI_ADDR_WIDTH-1:0] addr_t;
typedef logic [AXI_DATA_WIDTH-1:0] data_t;
typedef logic [AXI_DATA_WIDTH/8-1:0] strb_t;
`AXI_LITE_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t)
`AXI_LITE_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t)
`AXI_LITE_TYPEDEF_B_CHAN_T(b_chan_t)
`AXI_LITE_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t)
`AXI_LITE_TYPEDEF_R_CHAN_T(r_chan_t, data_t)
`AXI_LITE_TYPEDEF_REQ_T(req_t, aw_chan_t, w_chan_t, ar_chan_t)
`AXI_LITE_TYPEDEF_RESP_T(resp_t, b_chan_t, r_chan_t)
req_t src_req;
resp_t src_resp;
`AXI_LITE_ASSIGN_TO_REQ(src_req, src)
`AXI_LITE_ASSIGN_FROM_RESP(src, src_resp)
axi_cdc_src #(
.aw_chan_t ( aw_chan_t ),
.w_chan_t ( w_chan_t ),
.b_chan_t ( b_chan_t ),
.ar_chan_t ( ar_chan_t ),
.r_chan_t ( r_chan_t ),
.axi_req_t ( req_t ),
.axi_resp_t ( resp_t ),
.LogDepth ( LOG_DEPTH )
) i_axi_cdc_src (
.src_clk_i,
.src_rst_ni,
.src_req_o ( src_req ),
.src_resp_i ( src_resp ),
.async_data_master_aw_data_o ( dst.aw_data ),
.async_data_master_aw_wptr_o ( dst.aw_wptr ),
.async_data_master_aw_rptr_i ( dst.aw_rptr ),
.async_data_master_w_data_o ( dst.w_data ),
.async_data_master_w_wptr_o ( dst.w_wptr ),
.async_data_master_w_rptr_i ( dst.w_rptr ),
.async_data_master_b_data_i ( dst.b_data ),
.async_data_master_b_wptr_i ( dst.b_wptr ),
.async_data_master_b_rptr_o ( dst.b_rptr ),
.async_data_master_ar_data_o ( dst.ar_data ),
.async_data_master_ar_wptr_o ( dst.ar_wptr ),
.async_data_master_ar_rptr_i ( dst.ar_rptr ),
.async_data_master_r_data_i ( dst.r_data ),
.async_data_master_r_wptr_i ( dst.r_wptr ),
.async_data_master_r_rptr_o ( dst.r_rptr )
);
endmodule
...@@ -246,6 +246,7 @@ interface AXI_BUS_DV #( ...@@ -246,6 +246,7 @@ interface AXI_BUS_DV #(
endinterface endinterface
/// An asynchronous AXI4 interface. /// An asynchronous AXI4 interface.
interface AXI_BUS_ASYNC interface AXI_BUS_ASYNC
#( #(
...@@ -334,6 +335,59 @@ interface AXI_BUS_ASYNC ...@@ -334,6 +335,59 @@ interface AXI_BUS_ASYNC
endinterface endinterface
`include "axi/typedef.svh"
/// An asynchronous AXI4 interface for Gray CDCs.
interface AXI_BUS_ASYNC_GRAY #(
parameter int unsigned AXI_ADDR_WIDTH = 0,
parameter int unsigned AXI_DATA_WIDTH = 0,
parameter int unsigned AXI_ID_WIDTH = 0,
parameter int unsigned AXI_USER_WIDTH = 0,
parameter int unsigned LOG_DEPTH = 0
);
localparam int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8;
typedef logic [AXI_ID_WIDTH-1:0] id_t;
typedef logic [AXI_ADDR_WIDTH-1:0] addr_t;
typedef logic [AXI_DATA_WIDTH-1:0] data_t;
typedef logic [AXI_STRB_WIDTH-1:0] strb_t;
typedef logic [AXI_USER_WIDTH-1:0] user_t;
`AXI_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t, id_t, user_t)
`AXI_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t, user_t)
`AXI_TYPEDEF_B_CHAN_T(b_chan_t, id_t, user_t)
`AXI_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t, id_t, user_t)
`AXI_TYPEDEF_R_CHAN_T(r_chan_t, data_t, id_t, user_t)
aw_chan_t [2**LOG_DEPTH-1:0] aw_data;
w_chan_t [2**LOG_DEPTH-1:0] w_data;
b_chan_t [2**LOG_DEPTH-1:0] b_data;
ar_chan_t [2**LOG_DEPTH-1:0] ar_data;
r_chan_t [2**LOG_DEPTH-1:0] r_data;
logic [LOG_DEPTH:0] aw_wptr, aw_rptr,
w_wptr, w_rptr,
b_wptr, b_rptr,
ar_wptr, ar_rptr,
r_wptr, r_rptr;
modport Master (
output aw_data, aw_wptr, input aw_rptr,
output w_data, w_wptr, input w_rptr,
input b_data, b_wptr, output b_rptr,
output ar_data, ar_wptr, input ar_rptr,
input r_data, r_wptr, output r_rptr);
modport Slave (
input aw_data, aw_wptr, output aw_rptr,
input w_data, w_wptr, output w_rptr,
output b_data, b_wptr, input b_rptr,
input ar_data, ar_wptr, output ar_rptr,
output r_data, r_wptr, input r_rptr);
endinterface
/// An AXI4-Lite interface. /// An AXI4-Lite interface.
interface AXI_LITE #( interface AXI_LITE #(
parameter int unsigned AXI_ADDR_WIDTH = 0, parameter int unsigned AXI_ADDR_WIDTH = 0,
...@@ -389,6 +443,7 @@ interface AXI_LITE #( ...@@ -389,6 +443,7 @@ interface AXI_LITE #(
endinterface endinterface
/// A clocked AXI4-Lite interface for use in design verification. /// A clocked AXI4-Lite interface for use in design verification.
interface AXI_LITE_DV #( interface AXI_LITE_DV #(
parameter int unsigned AXI_ADDR_WIDTH = 0, parameter int unsigned AXI_ADDR_WIDTH = 0,
...@@ -445,3 +500,50 @@ interface AXI_LITE_DV #( ...@@ -445,3 +500,50 @@ interface AXI_LITE_DV #(
); );
endinterface endinterface
/// An asynchronous AXI4-Lite interface for Gray CDCs.
interface AXI_LITE_ASYNC_GRAY #(
parameter int unsigned AXI_ADDR_WIDTH = 0,
parameter int unsigned AXI_DATA_WIDTH = 0,
parameter int unsigned LOG_DEPTH = 0
);
localparam int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8;
typedef logic [AXI_ADDR_WIDTH-1:0] addr_t;
typedef logic [AXI_DATA_WIDTH-1:0] data_t;
typedef logic [AXI_STRB_WIDTH-1:0] strb_t;
`AXI_LITE_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t)
`AXI_LITE_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t)
`AXI_LITE_TYPEDEF_B_CHAN_T(b_chan_t)
`AXI_LITE_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t)
`AXI_LITE_TYPEDEF_R_CHAN_T(r_chan_t, data_t)
aw_chan_t [2**LOG_DEPTH-1:0] aw_data;
w_chan_t [2**LOG_DEPTH-1:0] w_data;
b_chan_t [2**LOG_DEPTH-1:0] b_data;
ar_chan_t [2**LOG_DEPTH-1:0] ar_data;
r_chan_t [2**LOG_DEPTH-1:0] r_data;
logic [LOG_DEPTH:0] aw_wptr, aw_rptr,
w_wptr, w_rptr,
b_wptr, b_rptr,
ar_wptr, ar_rptr,
r_wptr, r_rptr;
modport Master (
output aw_data, aw_wptr, input aw_rptr,
output w_data, w_wptr, input w_rptr,
input b_data, b_wptr, output b_rptr,
output ar_data, ar_wptr, input ar_rptr,
input r_data, r_wptr, output r_rptr);
modport Slave (
input aw_data, aw_wptr, output aw_rptr,
input w_data, w_wptr, output w_rptr,
output b_data, b_wptr, input b_rptr,
input ar_data, ar_wptr, output ar_rptr,
output r_data, r_wptr, input r_rptr);
endinterface
...@@ -16,7 +16,8 @@ axi: ...@@ -16,7 +16,8 @@ axi:
# Level 2 # Level 2
- src/axi_atop_filter.sv - src/axi_atop_filter.sv
- src/axi_burst_splitter.sv - src/axi_burst_splitter.sv
- src/axi_cdc.sv - src/axi_cdc_dst.sv
- src/axi_cdc_src.sv
- src/axi_cut.sv - src/axi_cut.sv
- src/axi_delayer.sv - src/axi_delayer.sv
- src/axi_demux.sv - src/axi_demux.sv
...@@ -36,6 +37,7 @@ axi: ...@@ -36,6 +37,7 @@ axi:
- src/axi_mux.sv - src/axi_mux.sv
- src/axi_serializer.sv - src/axi_serializer.sv
# Level 3 # Level 3
- src/axi_cdc.sv
- src/axi_err_slv.sv - src/axi_err_slv.sv
- src/axi_dw_converter.sv - src/axi_dw_converter.sv
- src/axi_multicut.sv - src/axi_multicut.sv
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment