From c7c87abea3a514d7e5879ab3db4c2119d93c920e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Mon, 29 Jun 2020 13:21:51 +0200 Subject: [PATCH 01/18] tb_axi_xbar: Add parameters, make more configurable for ci --- test/tb_axi_xbar.sv | 283 +++++++++++++++++++++++++------------------- 1 file changed, 159 insertions(+), 124 deletions(-) diff --git a/test/tb_axi_xbar.sv b/test/tb_axi_xbar.sv index d8d75900d..db7ef0235 100644 --- a/test/tb_axi_xbar.sv +++ b/test/tb_axi_xbar.sv @@ -9,6 +9,7 @@ // specific language governing permissions and limitations under the License. // // Authors: +// - Wolfgang Roenninger // - Florian Zaruba // - Andreas Kurth @@ -22,51 +23,68 @@ `include "axi/typedef.svh" `include "axi/assign.svh" +/// Testbench for the module `axi_xbar`. module tb_axi_xbar #( - parameter bit TbEnAtop = 1'b1, // enable atomic operations (ATOPs) - parameter bit TbEnExcl = 1'b0, // enable exclusive accesses - parameter bit TbUniqueIds = 1'b0, // restrict to only unique IDs - parameter int unsigned TbNumMst = 32'd6, // how many AXI masters there are - parameter int unsigned TbNumSlv = 32'd8 // how many AXI slaves there are + /// Number of AXI masters connected to the xbar. (Number of slave ports) + parameter int unsigned TbNumMasters = 32'd6, + /// Number of AXI slaves connected to the xbar. (Number of master ports) + parameter int unsigned TbNumSlaves = 32'd8, + /// Number of write transactions per master. + parameter int unsigned TbNumWrites = 32'd1000, + /// Number of read transactions per master. + parameter int unsigned TbNumReads = 32'd1000, + /// AXI4+ATOP ID wisth of the masters connected to the slave ports of the DUT. + /// The ID width of the salves is calulated depending on the xbar configuration. + parameter int unsigned TbAxiIdWidthMasters = 32'd4, + /// The used ID width of the DUT. + /// Has to be `TbAxiIdWidthMasters >= TbAxiIdUsed`. + parameter int unsigned TbAxiIdUsed = 32'd3, + /// Data width of the AXI channels. + parameter int unsigned TbAxiDataWidth = 32'd64, + /// Pipeline stages in the xbar itself. (Between Demux and mux) + parameter int unsigned TbPipeline = 32'd1, + /// Enable ATOP generation + parameter bit TbEnAtop = 1'b1, + /// Enable exclusive accesses + parameter bit TbEnExcl = 1'b0, + /// Restrict to only unique IDs + parameter bit TbUniqueIds = 1'b0 + ); - // Random master no Transactions - localparam int unsigned NoWrites = 80; // How many writes per master - localparam int unsigned NoReads = 80; // How many reads per master - // timing parameters + + // TB timing parameters localparam time CyclTime = 10ns; localparam time ApplTime = 2ns; localparam time TestTime = 8ns; - // axi configuration - localparam int unsigned AxiIdWidthMasters = 4; - localparam int unsigned AxiIdUsed = 3; // Has to be <= AxiIdWidthMasters - localparam int unsigned AxiIdWidthSlaves = AxiIdWidthMasters + $clog2(TbNumMst); - localparam int unsigned AxiAddrWidth = 32; // Axi Address Width - localparam int unsigned AxiDataWidth = 64; // Axi Data Width - localparam int unsigned AxiStrbWidth = AxiDataWidth / 8; - localparam int unsigned AxiUserWidth = 5; - // in the bench can change this variables which are set here freely + // AXI configuration which is automatically derived. + localparam int unsigned TbAxiIdWidthSlaves = TbAxiIdWidthMasters + $clog2(TbNumMasters); + localparam int unsigned TbAxiAddrWidth = 32'd32; + localparam int unsigned TbAxiStrbWidth = TbAxiDataWidth / 8; + localparam int unsigned TbAxiUserWidth = 5; + // In the bench can change this variables which are set here freely, localparam axi_pkg::xbar_cfg_t xbar_cfg = '{ - NoSlvPorts: TbNumMst, - NoMstPorts: TbNumSlv, + NoSlvPorts: TbNumMasters, + NoMstPorts: TbNumSlaves, MaxMstTrans: 10, MaxSlvTrans: 6, FallThrough: 1'b0, LatencyMode: axi_pkg::CUT_ALL_AX, - AxiIdWidthSlvPorts: AxiIdWidthMasters, - AxiIdUsedSlvPorts: AxiIdUsed, + PipelineStages: TbPipeline, + AxiIdWidthSlvPorts: TbAxiIdWidthMasters, + AxiIdUsedSlvPorts: TbAxiIdUsed, UniqueIds: TbUniqueIds, - AxiAddrWidth: AxiAddrWidth, - AxiDataWidth: AxiDataWidth, - NoAddrRules: 8 + AxiAddrWidth: TbAxiAddrWidth, + AxiDataWidth: TbAxiDataWidth, + NoAddrRules: TbNumSlaves }; - typedef logic [AxiIdWidthMasters-1:0] id_mst_t; - typedef logic [AxiIdWidthSlaves-1:0] id_slv_t; - typedef logic [AxiAddrWidth-1:0] addr_t; - typedef axi_pkg::xbar_rule_32_t rule_t; // Has to be the same width as axi addr - typedef logic [AxiDataWidth-1:0] data_t; - typedef logic [AxiStrbWidth-1:0] strb_t; - typedef logic [AxiUserWidth-1:0] user_t; + typedef logic [TbAxiIdWidthMasters-1:0] id_mst_t; + typedef logic [TbAxiIdWidthSlaves-1:0] id_slv_t; + typedef logic [TbAxiAddrWidth-1:0] addr_t; + typedef axi_pkg::xbar_rule_32_t rule_t; // Has to be the same width as axi addr + typedef logic [TbAxiDataWidth-1:0] data_t; + typedef logic [TbAxiStrbWidth-1:0] strb_t; + typedef logic [TbAxiUserWidth-1:0] user_t; `AXI_TYPEDEF_AW_CHAN_T(aw_chan_mst_t, addr_t, id_mst_t, user_t) `AXI_TYPEDEF_AW_CHAN_T(aw_chan_slv_t, addr_t, id_slv_t, user_t) @@ -84,42 +102,45 @@ module tb_axi_xbar #( `AXI_TYPEDEF_REQ_T(slv_req_t, aw_chan_slv_t, w_chan_t, ar_chan_slv_t) `AXI_TYPEDEF_RESP_T(slv_resp_t, b_chan_slv_t, r_chan_slv_t) - localparam rule_t [xbar_cfg.NoAddrRules-1:0] AddrMap = '{ - '{idx: 32'd7 % TbNumSlv, start_addr: 32'h0001_0000, end_addr: 32'h0001_1000}, - '{idx: 32'd6 % TbNumSlv, start_addr: 32'h0000_9000, end_addr: 32'h0001_0000}, - '{idx: 32'd5 % TbNumSlv, start_addr: 32'h0000_8000, end_addr: 32'h0000_9000}, - '{idx: 32'd4 % TbNumSlv, start_addr: 32'h0000_7000, end_addr: 32'h0000_8000}, - '{idx: 32'd3 % TbNumSlv, start_addr: 32'h0000_6300, end_addr: 32'h0000_7000}, - '{idx: 32'd2 % TbNumSlv, start_addr: 32'h0000_4000, end_addr: 32'h0000_6300}, - '{idx: 32'd1 % TbNumSlv, start_addr: 32'h0000_3000, end_addr: 32'h0000_4000}, - '{idx: 32'd0 % TbNumSlv, start_addr: 32'h0000_0000, end_addr: 32'h0000_3000} - }; + // Each slave has its own address range: + localparam rule_t [xbar_cfg.NoAddrRules-1:0] AddrMap = addr_map_gen(); + + function rule_t [xbar_cfg.NoAddrRules-1:0] addr_map_gen (); + for (int unsigned i = 0; i < xbar_cfg.NoAddrRules; i++) begin + addr_map_gen[i] = rule_t'{ + idx: unsigned'(i), + start_addr: i * 32'h0000_2000, + end_addr: (i+1) * 32'h0000_2000, + default: '0 + }; + end + endfunction typedef axi_test::axi_rand_master #( // AXI interface parameters - .AW ( AxiAddrWidth ), - .DW ( AxiDataWidth ), - .IW ( AxiIdWidthMasters ), - .UW ( AxiUserWidth ), + .AW ( TbAxiAddrWidth ), + .DW ( TbAxiDataWidth ), + .IW ( TbAxiIdWidthMasters ), + .UW ( TbAxiUserWidth ), // Stimuli application and test time - .TA ( ApplTime ), - .TT ( TestTime ), + .TA ( ApplTime ), + .TT ( TestTime ), // Maximum number of read and write transactions in flight - .MAX_READ_TXNS ( 20 ), - .MAX_WRITE_TXNS ( 20 ), - .AXI_EXCLS ( TbEnExcl ), - .AXI_ATOPS ( TbEnAtop ), + .MAX_READ_TXNS ( 20 ), + .MAX_WRITE_TXNS ( 20 ), + .AXI_EXCLS ( TbEnExcl ), + .AXI_ATOPS ( TbEnAtop ), .UNIQUE_IDS ( TbUniqueIds ) ) axi_rand_master_t; typedef axi_test::axi_rand_slave #( // AXI interface parameters - .AW ( AxiAddrWidth ), - .DW ( AxiDataWidth ), - .IW ( AxiIdWidthSlaves ), - .UW ( AxiUserWidth ), + .AW ( TbAxiAddrWidth ), + .DW ( TbAxiDataWidth ), + .IW ( TbAxiIdWidthSlaves ), + .UW ( TbAxiUserWidth ), // Stimuli application and test time - .TA ( ApplTime ), - .TT ( TestTime ) + .TA ( ApplTime ), + .TT ( TestTime ) ) axi_rand_slave_t; // ------------- @@ -128,72 +149,72 @@ module tb_axi_xbar #( logic clk; // DUT signals logic rst_n; - logic [TbNumMst-1:0] end_of_sim; + logic [TbNumMasters-1:0] end_of_sim; // master structs - mst_req_t [TbNumMst-1:0] masters_req; - mst_resp_t [TbNumMst-1:0] masters_resp; + mst_req_t [TbNumMasters-1:0] masters_req; + mst_resp_t [TbNumMasters-1:0] masters_resp; // slave structs - slv_req_t [TbNumSlv-1:0] slaves_req; - slv_resp_t [TbNumSlv-1:0] slaves_resp; + slv_req_t [TbNumSlaves-1:0] slaves_req; + slv_resp_t [TbNumSlaves-1:0] slaves_resp; // ------------------------------- // AXI Interfaces // ------------------------------- AXI_BUS #( - .AXI_ADDR_WIDTH ( AxiAddrWidth ), - .AXI_DATA_WIDTH ( AxiDataWidth ), - .AXI_ID_WIDTH ( AxiIdWidthMasters ), - .AXI_USER_WIDTH ( AxiUserWidth ) - ) master [TbNumMst-1:0] (); + .AXI_ADDR_WIDTH ( TbAxiAddrWidth ), + .AXI_DATA_WIDTH ( TbAxiDataWidth ), + .AXI_ID_WIDTH ( TbAxiIdWidthMasters ), + .AXI_USER_WIDTH ( TbAxiUserWidth ) + ) master [TbNumMasters-1:0] (); AXI_BUS_DV #( - .AXI_ADDR_WIDTH ( AxiAddrWidth ), - .AXI_DATA_WIDTH ( AxiDataWidth ), - .AXI_ID_WIDTH ( AxiIdWidthMasters ), - .AXI_USER_WIDTH ( AxiUserWidth ) - ) master_dv [TbNumMst-1:0] (clk); + .AXI_ADDR_WIDTH ( TbAxiAddrWidth ), + .AXI_DATA_WIDTH ( TbAxiDataWidth ), + .AXI_ID_WIDTH ( TbAxiIdWidthMasters ), + .AXI_USER_WIDTH ( TbAxiUserWidth ) + ) master_dv [TbNumMasters-1:0] (clk); AXI_BUS_DV #( - .AXI_ADDR_WIDTH ( AxiAddrWidth ), - .AXI_DATA_WIDTH ( AxiDataWidth ), - .AXI_ID_WIDTH ( AxiIdWidthMasters ), - .AXI_USER_WIDTH ( AxiUserWidth ) - ) master_monitor_dv [TbNumMst-1:0] (clk); - for (genvar i = 0; i < TbNumMst; i++) begin : gen_conn_dv_masters + .AXI_ADDR_WIDTH ( TbAxiAddrWidth ), + .AXI_DATA_WIDTH ( TbAxiDataWidth ), + .AXI_ID_WIDTH ( TbAxiIdWidthMasters ), + .AXI_USER_WIDTH ( TbAxiUserWidth ) + ) master_monitor_dv [TbNumMasters-1:0] (clk); + for (genvar i = 0; i < TbNumMasters; i++) begin : gen_conn_dv_masters `AXI_ASSIGN (master[i], master_dv[i]) `AXI_ASSIGN_TO_REQ(masters_req[i], master[i]) - `AXI_ASSIGN_TO_RESP(masters_resp[i], master[i]) + `AXI_ASSIGN_FROM_RESP(master[i], masters_resp[i]) end AXI_BUS #( - .AXI_ADDR_WIDTH ( AxiAddrWidth ), - .AXI_DATA_WIDTH ( AxiDataWidth ), - .AXI_ID_WIDTH ( AxiIdWidthSlaves ), - .AXI_USER_WIDTH ( AxiUserWidth ) - ) slave [TbNumSlv-1:0] (); + .AXI_ADDR_WIDTH ( TbAxiAddrWidth ), + .AXI_DATA_WIDTH ( TbAxiDataWidth ), + .AXI_ID_WIDTH ( TbAxiIdWidthSlaves ), + .AXI_USER_WIDTH ( TbAxiUserWidth ) + ) slave [TbNumSlaves-1:0] (); AXI_BUS_DV #( - .AXI_ADDR_WIDTH ( AxiAddrWidth ), - .AXI_DATA_WIDTH ( AxiDataWidth ), - .AXI_ID_WIDTH ( AxiIdWidthSlaves ), - .AXI_USER_WIDTH ( AxiUserWidth ) - ) slave_dv [TbNumSlv-1:0](clk); + .AXI_ADDR_WIDTH ( TbAxiAddrWidth ), + .AXI_DATA_WIDTH ( TbAxiDataWidth ), + .AXI_ID_WIDTH ( TbAxiIdWidthSlaves ), + .AXI_USER_WIDTH ( TbAxiUserWidth ) + ) slave_dv [TbNumSlaves-1:0](clk); AXI_BUS_DV #( - .AXI_ADDR_WIDTH ( AxiAddrWidth ), - .AXI_DATA_WIDTH ( AxiDataWidth ), - .AXI_ID_WIDTH ( AxiIdWidthSlaves ), - .AXI_USER_WIDTH ( AxiUserWidth ) - ) slave_monitor_dv [TbNumSlv-1:0](clk); - for (genvar i = 0; i < TbNumSlv; i++) begin : gen_conn_dv_slaves + .AXI_ADDR_WIDTH ( TbAxiAddrWidth ), + .AXI_DATA_WIDTH ( TbAxiDataWidth ), + .AXI_ID_WIDTH ( TbAxiIdWidthSlaves ), + .AXI_USER_WIDTH ( TbAxiUserWidth ) + ) slave_monitor_dv [TbNumSlaves-1:0](clk); + for (genvar i = 0; i < TbNumSlaves; i++) begin : gen_conn_dv_slaves `AXI_ASSIGN(slave_dv[i], slave[i]) - `AXI_ASSIGN_TO_REQ(slaves_req[i], slave[i]) + `AXI_ASSIGN_FROM_REQ(slave[i], slaves_req[i]) `AXI_ASSIGN_TO_RESP(slaves_resp[i], slave[i]) end // ------------------------------- // AXI Rand Masters and Slaves // ------------------------------- // Masters control simulation run time - axi_rand_master_t axi_rand_master [TbNumMst]; - for (genvar i = 0; i < TbNumMst; i++) begin : gen_rand_master + axi_rand_master_t axi_rand_master [TbNumMasters]; + for (genvar i = 0; i < TbNumMasters; i++) begin : gen_rand_master initial begin axi_rand_master[i] = new( master_dv[i] ); end_of_sim[i] <= 1'b0; @@ -202,13 +223,13 @@ module tb_axi_xbar #( axi_pkg::DEVICE_NONBUFFERABLE); axi_rand_master[i].reset(); @(posedge rst_n); - axi_rand_master[i].run(NoReads, NoWrites); + axi_rand_master.run(TbNumReads, TbNumWrites); end_of_sim[i] <= 1'b1; end end axi_rand_slave_t axi_rand_slave [TbNumSlv]; - for (genvar i = 0; i < TbNumSlv; i++) begin : gen_rand_slave + for (genvar i = 0; i < TbNumSlaves; i++) begin : gen_rand_slave initial begin axi_rand_slave[i] = new( slave_dv[i] ); axi_rand_slave[i].reset(); @@ -219,13 +240,13 @@ module tb_axi_xbar #( initial begin : proc_monitor static tb_axi_xbar_pkg::axi_xbar_monitor #( - .AxiAddrWidth ( AxiAddrWidth ), - .AxiDataWidth ( AxiDataWidth ), - .AxiIdWidthMasters ( AxiIdWidthMasters ), - .AxiIdWidthSlaves ( AxiIdWidthSlaves ), - .AxiUserWidth ( AxiUserWidth ), - .NoMasters ( TbNumMst ), - .NoSlaves ( TbNumSlv ), + .AxiAddrWidth ( TbAxiAddrWidth ), + .AxiDataWidth ( TbAxiDataWidth ), + .AxiIdWidthMasters ( TbAxiIdWidthMasters ), + .AxiIdWidthSlaves ( TbAxiIdWidthSlaves ), + .AxiUserWidth ( TbAxiUserWidth ), + .NoMasters ( TbNumMasters ), + .NoSlaves ( TbNumSlaves ), .NoAddrRules ( xbar_cfg.NoAddrRules ), .rule_t ( rule_t ), .AddrMap ( AddrMap ), @@ -258,23 +279,37 @@ module tb_axi_xbar #( //----------------------------------- // DUT //----------------------------------- - axi_xbar_intf #( - .AXI_USER_WIDTH ( AxiUserWidth ), - .Cfg ( xbar_cfg ), - .rule_t ( rule_t ) + axi_xbar #( + .Cfg ( xbar_cfg ), + .slv_aw_chan_t( aw_chan_mst_t ), + .mst_aw_chan_t( aw_chan_slv_t ), + .w_chan_t ( w_chan_t ), + .slv_b_chan_t ( b_chan_mst_t ), + .mst_b_chan_t ( b_chan_slv_t ), + .slv_ar_chan_t( ar_chan_mst_t ), + .mst_ar_chan_t( ar_chan_slv_t ), + .slv_r_chan_t ( r_chan_mst_t ), + .mst_r_chan_t ( r_chan_slv_t ), + .slv_req_t ( mst_req_t ), + .slv_resp_t ( mst_resp_t ), + .mst_req_t ( slv_req_t ), + .mst_resp_t ( slv_resp_t ), + .rule_t ( rule_t ) ) i_xbar_dut ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .test_i ( 1'b0 ), - .slv_ports ( master ), - .mst_ports ( slave ), - .addr_map_i ( AddrMap ), - .en_default_mst_port_i ( '0 ), - .default_mst_port_i ( '0 ) + .clk_i ( clk ), + .rst_ni ( rst_n ), + .test_i ( 1'b0 ), + .slv_ports_req_i ( masters_req ), + .slv_ports_resp_o ( masters_resp ), + .mst_ports_req_o ( slaves_req ), + .mst_ports_resp_i ( slaves_resp ), + .addr_map_i ( AddrMap ), + .en_default_mst_port_i ( '0 ), + .default_mst_port_i ( '0 ) ); // logger for master modules - for (genvar i = 0; i < TbNumMst; i++) begin : gen_master_logger + for (genvar i = 0; i < TbNumMasters; i++) begin : gen_master_logger axi_chan_logger #( .TestTime ( TestTime ), // Time after clock, where sampling happens .LoggerName( $sformatf("axi_logger_master_%0d", i)), @@ -310,7 +345,7 @@ module tb_axi_xbar #( ); end // logger for slave modules - for (genvar i = 0; i < TbNumSlv; i++) begin : gen_slave_logger + for (genvar i = 0; i < TbNumSlaves; i++) begin : gen_slave_logger axi_chan_logger #( .TestTime ( TestTime ), // Time after clock, where sampling happens .LoggerName( $sformatf("axi_logger_slave_%0d",i)), @@ -347,7 +382,7 @@ module tb_axi_xbar #( end - for (genvar i = 0; i < TbNumMst; i++) begin : gen_connect_master_monitor + for (genvar i = 0; i < TbNumMasters; i++) begin : gen_connect_master_monitor assign master_monitor_dv[i].aw_id = master[i].aw_id ; assign master_monitor_dv[i].aw_addr = master[i].aw_addr ; assign master_monitor_dv[i].aw_len = master[i].aw_len ; @@ -394,7 +429,7 @@ module tb_axi_xbar #( assign master_monitor_dv[i].r_valid = master[i].r_valid ; assign master_monitor_dv[i].r_ready = master[i].r_ready ; end - for (genvar i = 0; i < TbNumSlv; i++) begin : gen_connect_slave_monitor + for (genvar i = 0; i < TbNumSlaves; i++) begin : gen_connect_slave_monitor assign slave_monitor_dv[i].aw_id = slave[i].aw_id ; assign slave_monitor_dv[i].aw_addr = slave[i].aw_addr ; assign slave_monitor_dv[i].aw_len = slave[i].aw_len ; From 10d815c34b877277ddb5b46bfc45876e482c9d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Mon, 29 Jun 2020 13:28:53 +0200 Subject: [PATCH 02/18] axi_demux: Remove W select FIFO, add counter and register --- CHANGELOG.md | 5 +++++ src/axi_demux.sv | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae12b1c2c..97402a3be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -323,6 +323,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `axi_test::rand_axi_lite_slave` and `axi_test::rand_axi_lite_master`: Change type of address and data width parameters (`AW` and `DW`) from `int` to `int unsigned`. Same rationale as for `AXI_BUS` (et al.) above. +- `axi_demux`: Remove FIFO between AW and W channel, is now a register plus counter. + Prevents AWs to be emmitted downstream to a different master port as long as Ws + are still in flight to another. This prevents deadlock, if there is stalling + downstream. + ### Fixed - `axi_demux`: Break combinatorial simulation loop. diff --git a/src/axi_demux.sv b/src/axi_demux.sv index 184e9b23c..9e05406da 100644 --- a/src/axi_demux.sv +++ b/src/axi_demux.sv @@ -817,7 +817,6 @@ module axi_demux_intf #( parameter int unsigned MAX_TRANS = 32'd8, parameter int unsigned AXI_LOOK_BITS = 32'd3, parameter bit UNIQUE_IDS = 1'b0, - parameter bit FALL_THROUGH = 1'b0, parameter bit SPILL_AW = 1'b1, parameter bit SPILL_W = 1'b0, parameter bit SPILL_B = 1'b0, From 3076c142686acaed4ba5671d952f30f1691d8bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Mon, 29 Jun 2020 13:34:41 +0200 Subject: [PATCH 03/18] axi_xbar: Add pipeline stages in cross --- CHANGELOG.md | 3 ++- src/axi_pkg.sv | 1 + src/axi_xbar.sv | 19 +++++++++++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97402a3be..7f7791662 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -327,7 +327,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. Prevents AWs to be emmitted downstream to a different master port as long as Ws are still in flight to another. This prevents deadlock, if there is stalling downstream. - +- `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` + in the crossed connections in the xbar between the demuxes and muxes. ### Fixed - `axi_demux`: Break combinatorial simulation loop. diff --git a/src/axi_pkg.sv b/src/axi_pkg.sv index 92ede558c..0820dd708 100644 --- a/src/axi_pkg.sv +++ b/src/axi_pkg.sv @@ -399,6 +399,7 @@ package axi_pkg; int unsigned MaxSlvTrans; bit FallThrough; xbar_latency_e LatencyMode; + int unsigned PipelineStages; int unsigned AxiIdWidthSlvPorts; int unsigned AxiIdUsedSlvPorts; bit UniqueIds; diff --git a/src/axi_xbar.sv b/src/axi_xbar.sv index 0971ef6f5..7fd4f537d 100644 --- a/src/axi_xbar.sv +++ b/src/axi_xbar.sv @@ -204,8 +204,23 @@ import cf_math_pkg::idx_width; for (genvar i = 0; i < Cfg.NoSlvPorts; i++) begin : gen_xbar_slv_cross for (genvar j = 0; j < Cfg.NoMstPorts; j++) begin : gen_xbar_mst_cross if (Connectivity[i][j]) begin : gen_connection - assign mst_reqs[j][i] = slv_reqs[i][j]; - assign slv_resps[i][j] = mst_resps[j][i]; + axi_multicut #( + .NoCuts ( Cfg.PipelineStages ), + .aw_chan_t ( slv_aw_chan_t ), + .w_chan_t ( w_chan_t ), + .b_chan_t ( slv_b_chan_t ), + .ar_chan_t ( slv_ar_chan_t ), + .r_chan_t ( slv_r_chan_t ), + .req_t ( slv_req_t ), + .resp_t ( slv_resp_t ) + ) i_axi_multicut_xbar_pipeline ( + .clk_i, + .rst_ni, + .slv_req_i ( slv_reqs[i][j] ), + .slv_resp_o ( slv_resps[i][j] ), + .mst_req_o ( mst_reqs[j][i] ), + .mst_resp_i ( mst_resps[j][i] ) + ); end else begin : gen_no_connection assign mst_reqs[j][i] = '0; From 78f29996ace21682a4ad5145ddf67717c2e03fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Mon, 29 Jun 2020 13:35:42 +0200 Subject: [PATCH 04/18] scripts:run_vsim: Add parametized axi_xbar simulation call --- scripts/run_vsim.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/scripts/run_vsim.sh b/scripts/run_vsim.sh index 3737ba5d3..66a6b745f 100755 --- a/scripts/run_vsim.sh +++ b/scripts/run_vsim.sh @@ -202,6 +202,29 @@ exec_test() { done done ;; + axi_xbar) + for GEN_ATOP in 0 1; do + for NUM_MST in 1 2 4 6; do + for NUM_SLV in 2 7 9; do + for MST_ID_USE in 3 5; do + MST_ID=5 + for DATA_WIDTH in 64 256; do + for PIPE in 0 1; do + call_vsim tb_axi_xbar -t 1ns -voptargs="+acc" \ + -gTbNumMasters=$NUM_MST \ + -gTbNumSlaves=$NUM_SLV \ + -gTbAxiIdWidthMasters=$MST_ID \ + -gTbAxiIdUsed=$MST_ID_USE \ + -gTbAxiDataWidth=$DATA_WIDTH \ + -gTbPipeline=$PIPE \ + -gTbEnAtop=$GEN_ATOP + done + done + done + done + done + done + ;; *) call_vsim tb_$1 -t 1ns -coverage -voptargs="+acc +cover=bcesfx" ;; From 67df42ebfd5854382e13adbd01591c2fc1cd973d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Mon, 29 Jun 2020 13:48:20 +0200 Subject: [PATCH 05/18] axi_pkg: Add documentation for xbar_cfg_t --- CHANGELOG.md | 1 + src/axi_pkg.sv | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f7791662..7ce215fc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -329,6 +329,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. downstream. - `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` in the crossed connections in the xbar between the demuxes and muxes. +- `axi_pkg`: Add documentation to `xbar_cfg_t`. ### Fixed - `axi_demux`: Break combinatorial simulation loop. diff --git a/src/axi_pkg.sv b/src/axi_pkg.sv index 0820dd708..7ef3bbcd7 100644 --- a/src/axi_pkg.sv +++ b/src/axi_pkg.sv @@ -393,18 +393,44 @@ package axi_pkg; /// Configuration for `axi_xbar`. typedef struct packed { + /// Number of slave ports of the crossbar. + /// This many master modules are connected to it. int unsigned NoSlvPorts; + /// Number of master ports of the crossbar. + /// This many slave modules are connected to it. int unsigned NoMstPorts; + /// Maximum number of open transactions each master connected to the crossbar can have in + /// flight at the same time. int unsigned MaxMstTrans; + /// Maximum number of open transactions each slave connected to the crossbar can have in + /// flight at the same time. int unsigned MaxSlvTrans; + /// Determine if the internal FIFOs of the crossbar are instantiated in fallthrough mode. + /// 0: No fallthrough + /// 1: Fallthrough bit FallThrough; + /// The Latency mode of the xbar. This determines if the channels on the ports have + /// a spill register instantiated. + /// Example configurations are provided with the enum `xbar_latency_e`. xbar_latency_e LatencyMode; + /// This is the number of `axi_multicut` stages instantiated in the line cross of the channels. + /// Having multiple stages can potentially add a large number of FFs! int unsigned PipelineStages; + /// AXI ID width of the salve ports. The ID width of the master ports is determined + /// Automatically. See `axi_mux` for details. int unsigned AxiIdWidthSlvPorts; + /// The used ID portion to determine if a different salve is used for the same ID. + /// See `axi_demux` for details. int unsigned AxiIdUsedSlvPorts; + /// Are IDs unique? bit UniqueIds; + /// AXI4+ATOP address field width. int unsigned AxiAddrWidth; + /// AXI4+ATOP data field width. int unsigned AxiDataWidth; + /// The number of address rules defined for routing of the transactions. + /// Each master port can have multiple rules, should have however at least one. + /// If a transaction can not be routed the xbar will answer with an `axi_pkg::RESP_DECERR`. int unsigned NoAddrRules; } xbar_cfg_t; From 18d2a4fea5556487eec66aba5369254d0d46d0d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Tue, 30 Jun 2020 14:24:23 +0200 Subject: [PATCH 06/18] axi_xbar: Tone down runtime of ci --- scripts/run_vsim.sh | 4 ++-- test/tb_axi_xbar.sv | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/run_vsim.sh b/scripts/run_vsim.sh index 66a6b745f..7a14b428a 100755 --- a/scripts/run_vsim.sh +++ b/scripts/run_vsim.sh @@ -204,8 +204,8 @@ exec_test() { ;; axi_xbar) for GEN_ATOP in 0 1; do - for NUM_MST in 1 2 4 6; do - for NUM_SLV in 2 7 9; do + for NUM_MST in 1 6; do + for NUM_SLV in 2 9; do for MST_ID_USE in 3 5; do MST_ID=5 for DATA_WIDTH in 64 256; do diff --git a/test/tb_axi_xbar.sv b/test/tb_axi_xbar.sv index db7ef0235..8261e5216 100644 --- a/test/tb_axi_xbar.sv +++ b/test/tb_axi_xbar.sv @@ -30,12 +30,12 @@ module tb_axi_xbar #( /// Number of AXI slaves connected to the xbar. (Number of master ports) parameter int unsigned TbNumSlaves = 32'd8, /// Number of write transactions per master. - parameter int unsigned TbNumWrites = 32'd1000, + parameter int unsigned TbNumWrites = 32'd100, /// Number of read transactions per master. - parameter int unsigned TbNumReads = 32'd1000, + parameter int unsigned TbNumReads = 32'd100, /// AXI4+ATOP ID wisth of the masters connected to the slave ports of the DUT. /// The ID width of the salves is calulated depending on the xbar configuration. - parameter int unsigned TbAxiIdWidthMasters = 32'd4, + parameter int unsigned TbAxiIdWidthMasters = 32'd5, /// The used ID width of the DUT. /// Has to be `TbAxiIdWidthMasters >= TbAxiIdUsed`. parameter int unsigned TbAxiIdUsed = 32'd3, From a5dce2119c9cfd82f160c8e8403993ae637b88c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Thu, 2 Jul 2020 09:52:45 +0200 Subject: [PATCH 07/18] CHANGELOG: Format xbar pipeline additions --- CHANGELOG.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ce215fc9..2d40aa47b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -323,12 +323,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `axi_test::rand_axi_lite_slave` and `axi_test::rand_axi_lite_master`: Change type of address and data width parameters (`AW` and `DW`) from `int` to `int unsigned`. Same rationale as for `AXI_BUS` (et al.) above. -- `axi_demux`: Remove FIFO between AW and W channel, is now a register plus counter. - Prevents AWs to be emmitted downstream to a different master port as long as Ws - are still in flight to another. This prevents deadlock, if there is stalling - downstream. -- `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` - in the crossed connections in the xbar between the demuxes and muxes. +- `axi_demux`: Replace FIFO between AW and W channel by a register plus a counter. This prevents + AWs from being issued to one master port while Ws from another burst are ongoing to another + master port. This is required to prevents deadlocks due to circular waits downstream. +- `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` + in the crossed connections in the xbar between the demuxes and muxes. - `axi_pkg`: Add documentation to `xbar_cfg_t`. ### Fixed From f689d32d0e3c687d758e1432655285c7031027ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Thu, 2 Jul 2020 10:12:18 +0200 Subject: [PATCH 08/18] axi_demux: Remove docstring flag from comments --- src/axi_demux.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/axi_demux.sv b/src/axi_demux.sv index 9e05406da..fc061ff09 100644 --- a/src/axi_demux.sv +++ b/src/axi_demux.sv @@ -289,10 +289,10 @@ module axi_demux #( if (!aw_id_cnt_full && (w_open != {IdCounterWidth{1'b1}}) && (!(ar_id_cnt_full && slv_aw_chan.atop[axi_pkg::ATOP_R_RESP]) || !AtopSupport)) begin - /// There is a valid AW vector make the id lookup and go further, if it passes. - /// Also stall if previous transmitted AWs still have active W's in flight. - /// This prevents deadlocking of the W channel. The counters are there for the - /// Handling of the B responses. + // There is a valid AW vector make the id lookup and go further, if it passes. + // Also stall if previous transmitted AWs still have active W's in flight. + // This prevents deadlocking of the W channel. The counters are there for the + // Handling of the B responses. if (slv_aw_valid && ((w_open == '0) || (w_select == slv_aw_select)) && (!aw_select_occupied || (slv_aw_select == lookup_aw_select))) begin From 696acdb61ab68eb5ac4d2a404fa4dc7ab03a67f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Fri, 4 Dec 2020 15:37:40 +0100 Subject: [PATCH 09/18] axi_xbar: Add port/param documentation --- src/axi_xbar.sv | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/axi_xbar.sv b/src/axi_xbar.sv index 7fd4f537d..bffa890fe 100644 --- a/src/axi_xbar.sv +++ b/src/axi_xbar.sv @@ -13,45 +13,88 @@ // - Andreas Kurth // - Florian Zaruba -// axi_xbar: Fully-connected AXI4+ATOP crossbar with an arbitrary number of slave and master ports. -// See `doc/axi_xbar.md` for the documentation, including the definition of parameters and ports. +/// axi_xbar: Fully-connected AXI4+ATOP crossbar with an arbitrary number of slave and master ports. +/// See `doc/axi_xbar.md` for the documentation, including the definition of parameters and ports. module axi_xbar import cf_math_pkg::idx_width; #( + /// Configuration struct for the crossbar see `axi_pkg` for fields and definitions. parameter axi_pkg::xbar_cfg_t Cfg = '0, + /// Enable atomic operations support. parameter bit ATOPs = 1'b1, + /// Connectivity matrix parameter bit [Cfg.NoSlvPorts-1:0][Cfg.NoMstPorts-1:0] Connectivity = '1, + /// AXI4+ATOP AW channel struct type for the slave ports. parameter type slv_aw_chan_t = logic, + /// AXI4+ATOP AW channel struct type for the master ports. parameter type mst_aw_chan_t = logic, + /// AXI4+ATOP W channel struct type for all ports. parameter type w_chan_t = logic, + /// AXI4+ATOP B channel struct type for the slave ports. parameter type slv_b_chan_t = logic, + /// AXI4+ATOP B channel struct type for the master ports. parameter type mst_b_chan_t = logic, + /// AXI4+ATOP AR channel struct type for the slave ports. parameter type slv_ar_chan_t = logic, + /// AXI4+ATOP AR channel struct type for the master ports. parameter type mst_ar_chan_t = logic, + /// AXI4+ATOP R channel struct type for the slave ports. parameter type slv_r_chan_t = logic, + /// AXI4+ATOP R channel struct type for the master ports. parameter type mst_r_chan_t = logic, + /// AXI4+ATOP request struct type for the slave ports. parameter type slv_req_t = logic, + /// AXI4+ATOP response struct type for the slave ports. parameter type slv_resp_t = logic, + /// AXI4+ATOP request struct type for the master ports. parameter type mst_req_t = logic, + /// AXI4+ATOP response struct type for the master ports parameter type mst_resp_t = logic, + /// Address rule type for the address decoders from `common_cells:addr_decode`. + /// Example types are provided in `axi_pkg`. + /// Required struct fields: + /// ``` + /// typedef struct packed { + /// int unsigned idx; + /// axi_addr_t start_addr; + /// axi_addr_t end_addr; + /// } rule_t; + /// ``` parameter type rule_t = axi_pkg::xbar_rule_64_t `ifdef VCS , localparam int unsigned MstPortsIdxWidth = (Cfg.NoMstPorts == 32'd1) ? 32'd1 : unsigned'($clog2(Cfg.NoMstPorts)) `endif ) ( + /// Clock, positive edge triggered. input logic clk_i, + /// Asynchronous reset, active low. input logic rst_ni, + /// Testmode enable, active high. input logic test_i, + /// AXI4+ATOP requests to the slave ports. input slv_req_t [Cfg.NoSlvPorts-1:0] slv_ports_req_i, + /// AXI4+ATOP responses of the slave ports. output slv_resp_t [Cfg.NoSlvPorts-1:0] slv_ports_resp_o, + /// AXI4+ATOP requests of the master ports. output mst_req_t [Cfg.NoMstPorts-1:0] mst_ports_req_o, + /// AXI4+ATOP responses to the master ports. input mst_resp_t [Cfg.NoMstPorts-1:0] mst_ports_resp_i, + /// Address map array input for the crossbar. This map is global for the whole module. + /// It is used for routing the transactions to the respective master ports. + /// Each master port can have multiple different rules. input rule_t [Cfg.NoAddrRules-1:0] addr_map_i, + /// Enable default master port. input logic [Cfg.NoSlvPorts-1:0] en_default_mst_port_i, `ifdef VCS + /// Enables a default master port for each slave port. When this is enabled unmapped + /// transactions get issued at the master port given by `default_mst_port_i`. + /// When not used, tie to `'0`. input logic [Cfg.NoSlvPorts-1:0][MstPortsIdxWidth-1:0] default_mst_port_i `else + /// Enables a default master port for each slave port. When this is enabled unmapped + /// transactions get issued at the master port given by `default_mst_port_i`. + /// When not used, tie to `'0`. input logic [Cfg.NoSlvPorts-1:0][idx_width(Cfg.NoMstPorts)-1:0] default_mst_port_i `endif ); From b556516d7e13dd9240278eaeb766da4a9e381cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Mon, 29 Jun 2020 13:21:51 +0200 Subject: [PATCH 10/18] tb_axi_xbar: Add parameters, make more configurable for ci --- test/tb_axi_xbar.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/tb_axi_xbar.sv b/test/tb_axi_xbar.sv index 8261e5216..6055864f9 100644 --- a/test/tb_axi_xbar.sv +++ b/test/tb_axi_xbar.sv @@ -30,9 +30,9 @@ module tb_axi_xbar #( /// Number of AXI slaves connected to the xbar. (Number of master ports) parameter int unsigned TbNumSlaves = 32'd8, /// Number of write transactions per master. - parameter int unsigned TbNumWrites = 32'd100, + parameter int unsigned TbNumWrites = 32'd200, /// Number of read transactions per master. - parameter int unsigned TbNumReads = 32'd100, + parameter int unsigned TbNumReads = 32'd200, /// AXI4+ATOP ID wisth of the masters connected to the slave ports of the DUT. /// The ID width of the salves is calulated depending on the xbar configuration. parameter int unsigned TbAxiIdWidthMasters = 32'd5, From bd41988c13d32faad00dd33ac1315717805cdb57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Mon, 29 Jun 2020 13:34:41 +0200 Subject: [PATCH 11/18] axi_xbar: Add pipeline stages in cross --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d40aa47b..9b2ce0f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -329,6 +329,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` in the crossed connections in the xbar between the demuxes and muxes. - `axi_pkg`: Add documentation to `xbar_cfg_t`. +- `axi_demux`: Remove FIFO between AW and W channel, is now a register plus counter. + Prevents AWs to be emmitted downstream to a different master port as long as Ws + are still in flight to another. This prevents deadlock, if there is stalling + downstream. +- `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` + in the crossed connections in the xbar between the demuxes and muxes. ### Fixed - `axi_demux`: Break combinatorial simulation loop. From ba318e9dc074fa00a937c47ed6a49a1ad521d997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Mon, 29 Jun 2020 13:48:20 +0200 Subject: [PATCH 12/18] axi_pkg: Add documentation for xbar_cfg_t --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b2ce0f71..37b087e6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -335,6 +335,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. downstream. - `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` in the crossed connections in the xbar between the demuxes and muxes. +- `axi_pkg`: Add documentation to `xbar_cfg_t`. ### Fixed - `axi_demux`: Break combinatorial simulation loop. From da5d955910e10af8809621274d9592fb3934aa77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Thu, 2 Jul 2020 09:52:45 +0200 Subject: [PATCH 13/18] CHANGELOG: Format xbar pipeline additions --- CHANGELOG.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37b087e6e..2d40aa47b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -329,13 +329,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` in the crossed connections in the xbar between the demuxes and muxes. - `axi_pkg`: Add documentation to `xbar_cfg_t`. -- `axi_demux`: Remove FIFO between AW and W channel, is now a register plus counter. - Prevents AWs to be emmitted downstream to a different master port as long as Ws - are still in flight to another. This prevents deadlock, if there is stalling - downstream. -- `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` - in the crossed connections in the xbar between the demuxes and muxes. -- `axi_pkg`: Add documentation to `xbar_cfg_t`. ### Fixed - `axi_demux`: Break combinatorial simulation loop. From 522c2adc89e9c022495858208c93048399cf9485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20R=C3=B6nninger?= Date: Thu, 2 Jul 2020 13:08:14 +0200 Subject: [PATCH 14/18] axi_xbar: Add suggestions from PR xbar_pipeline --- src/axi_xbar.sv | 3 ++- test/tb_axi_xbar.sv | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/axi_xbar.sv b/src/axi_xbar.sv index bffa890fe..95b27ff2c 100644 --- a/src/axi_xbar.sv +++ b/src/axi_xbar.sv @@ -99,7 +99,8 @@ import cf_math_pkg::idx_width; `endif ); - typedef logic [Cfg.AxiAddrWidth-1:0] addr_t; + // Address tpye for inidvidual address signals + typedef logic [Cfg.AxiAddrWidth-1:0] addr_t; // to account for the decoding error slave `ifdef VCS localparam int unsigned MstPortsIdxWidthOne = diff --git a/test/tb_axi_xbar.sv b/test/tb_axi_xbar.sv index 6055864f9..d83db6e73 100644 --- a/test/tb_axi_xbar.sv +++ b/test/tb_axi_xbar.sv @@ -33,15 +33,15 @@ module tb_axi_xbar #( parameter int unsigned TbNumWrites = 32'd200, /// Number of read transactions per master. parameter int unsigned TbNumReads = 32'd200, - /// AXI4+ATOP ID wisth of the masters connected to the slave ports of the DUT. - /// The ID width of the salves is calulated depending on the xbar configuration. + /// AXI4+ATOP ID width of the masters connected to the slave ports of the DUT. + /// The ID width of the slaves is calculated depending on the xbar configuration. parameter int unsigned TbAxiIdWidthMasters = 32'd5, /// The used ID width of the DUT. /// Has to be `TbAxiIdWidthMasters >= TbAxiIdUsed`. parameter int unsigned TbAxiIdUsed = 32'd3, /// Data width of the AXI channels. parameter int unsigned TbAxiDataWidth = 32'd64, - /// Pipeline stages in the xbar itself. (Between Demux and mux) + /// Pipeline stages in the xbar itself (between demux and mux). parameter int unsigned TbPipeline = 32'd1, /// Enable ATOP generation parameter bit TbEnAtop = 1'b1, From 3379f5af433aa062038e981e63a3fc72d30dd9ed Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Fri, 30 Sep 2022 13:37:53 +0200 Subject: [PATCH 15/18] axi_xbar: Various fixes --- src/axi_xbar.sv | 16 ++++++++-------- test/tb_axi_xbar.sv | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/axi_xbar.sv b/src/axi_xbar.sv index 95b27ff2c..52769a66c 100644 --- a/src/axi_xbar.sv +++ b/src/axi_xbar.sv @@ -249,14 +249,14 @@ import cf_math_pkg::idx_width; for (genvar j = 0; j < Cfg.NoMstPorts; j++) begin : gen_xbar_mst_cross if (Connectivity[i][j]) begin : gen_connection axi_multicut #( - .NoCuts ( Cfg.PipelineStages ), - .aw_chan_t ( slv_aw_chan_t ), - .w_chan_t ( w_chan_t ), - .b_chan_t ( slv_b_chan_t ), - .ar_chan_t ( slv_ar_chan_t ), - .r_chan_t ( slv_r_chan_t ), - .req_t ( slv_req_t ), - .resp_t ( slv_resp_t ) + .NoCuts ( Cfg.PipelineStages ), + .aw_chan_t ( slv_aw_chan_t ), + .w_chan_t ( w_chan_t ), + .b_chan_t ( slv_b_chan_t ), + .ar_chan_t ( slv_ar_chan_t ), + .r_chan_t ( slv_r_chan_t ), + .axi_req_t ( slv_req_t ), + .axi_resp_t ( slv_resp_t ) ) i_axi_multicut_xbar_pipeline ( .clk_i, .rst_ni, diff --git a/test/tb_axi_xbar.sv b/test/tb_axi_xbar.sv index d83db6e73..b182e9185 100644 --- a/test/tb_axi_xbar.sv +++ b/test/tb_axi_xbar.sv @@ -223,12 +223,12 @@ module tb_axi_xbar #( axi_pkg::DEVICE_NONBUFFERABLE); axi_rand_master[i].reset(); @(posedge rst_n); - axi_rand_master.run(TbNumReads, TbNumWrites); + axi_rand_master[i].run(TbNumReads, TbNumWrites); end_of_sim[i] <= 1'b1; end end - axi_rand_slave_t axi_rand_slave [TbNumSlv]; + axi_rand_slave_t axi_rand_slave [TbNumSlaves]; for (genvar i = 0; i < TbNumSlaves; i++) begin : gen_rand_slave initial begin axi_rand_slave[i] = new( slave_dv[i] ); From e4b5fb56e3ad461104e10ac2a6ad84d935e21bef Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Fri, 30 Sep 2022 13:55:44 +0200 Subject: [PATCH 16/18] changelog: Update changelog with xbar changes --- CHANGELOG.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d40aa47b..6301e4c8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add `axi_channel_compare.sv`: Non-synthesizable module comparing two AXI channels of the same type ### Changed -- `axi_demux`: Replace write FIFO (`w_fifo`) with a write credit counter. +- `axi_demux`: Replace FIFO between AW and W channel by a register plus a counter. This prevents + AWs from being issued to one master port while Ws from another burst are ongoing to another + master port. This is required to prevents deadlocks due to circular waits downstream. +- `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` + in the crossed connections in the xbar between the demuxes and muxes. +- `axi_pkg`: Add documentation to `xbar_cfg_t`. ### Fixed @@ -323,12 +328,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `axi_test::rand_axi_lite_slave` and `axi_test::rand_axi_lite_master`: Change type of address and data width parameters (`AW` and `DW`) from `int` to `int unsigned`. Same rationale as for `AXI_BUS` (et al.) above. -- `axi_demux`: Replace FIFO between AW and W channel by a register plus a counter. This prevents - AWs from being issued to one master port while Ws from another burst are ongoing to another - master port. This is required to prevents deadlocks due to circular waits downstream. -- `axi_xbar`: Add parameter `PipelineStages` to `axi_pkg::xbar_cfg_t`. This adds `axi_multicuts` - in the crossed connections in the xbar between the demuxes and muxes. -- `axi_pkg`: Add documentation to `xbar_cfg_t`. ### Fixed - `axi_demux`: Break combinatorial simulation loop. From 07cd725c7c047c0bd0c78f3f668fd4d588944832 Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Thu, 6 Oct 2022 14:14:36 +0200 Subject: [PATCH 17/18] tb_xbar: Use the interface version of the xbar again --- test/tb_axi_xbar.sv | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/test/tb_axi_xbar.sv b/test/tb_axi_xbar.sv index b182e9185..6056be919 100644 --- a/test/tb_axi_xbar.sv +++ b/test/tb_axi_xbar.sv @@ -183,7 +183,7 @@ module tb_axi_xbar #( for (genvar i = 0; i < TbNumMasters; i++) begin : gen_conn_dv_masters `AXI_ASSIGN (master[i], master_dv[i]) `AXI_ASSIGN_TO_REQ(masters_req[i], master[i]) - `AXI_ASSIGN_FROM_RESP(master[i], masters_resp[i]) + `AXI_ASSIGN_TO_RESP(masters_resp[i], master[i]) end AXI_BUS #( @@ -206,7 +206,7 @@ module tb_axi_xbar #( ) slave_monitor_dv [TbNumSlaves-1:0](clk); for (genvar i = 0; i < TbNumSlaves; i++) begin : gen_conn_dv_slaves `AXI_ASSIGN(slave_dv[i], slave[i]) - `AXI_ASSIGN_FROM_REQ(slave[i], slaves_req[i]) + `AXI_ASSIGN_TO_REQ(slaves_req[i], slave[i]) `AXI_ASSIGN_TO_RESP(slaves_resp[i], slave[i]) end // ------------------------------- @@ -279,33 +279,19 @@ module tb_axi_xbar #( //----------------------------------- // DUT //----------------------------------- - axi_xbar #( - .Cfg ( xbar_cfg ), - .slv_aw_chan_t( aw_chan_mst_t ), - .mst_aw_chan_t( aw_chan_slv_t ), - .w_chan_t ( w_chan_t ), - .slv_b_chan_t ( b_chan_mst_t ), - .mst_b_chan_t ( b_chan_slv_t ), - .slv_ar_chan_t( ar_chan_mst_t ), - .mst_ar_chan_t( ar_chan_slv_t ), - .slv_r_chan_t ( r_chan_mst_t ), - .mst_r_chan_t ( r_chan_slv_t ), - .slv_req_t ( mst_req_t ), - .slv_resp_t ( mst_resp_t ), - .mst_req_t ( slv_req_t ), - .mst_resp_t ( slv_resp_t ), - .rule_t ( rule_t ) + axi_xbar_intf #( + .AXI_USER_WIDTH ( TbAxiUserWidth ), + .Cfg ( xbar_cfg ), + .rule_t ( rule_t ) ) i_xbar_dut ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .test_i ( 1'b0 ), - .slv_ports_req_i ( masters_req ), - .slv_ports_resp_o ( masters_resp ), - .mst_ports_req_o ( slaves_req ), - .mst_ports_resp_i ( slaves_resp ), - .addr_map_i ( AddrMap ), - .en_default_mst_port_i ( '0 ), - .default_mst_port_i ( '0 ) + .clk_i ( clk ), + .rst_ni ( rst_n ), + .test_i ( 1'b0 ), + .slv_ports ( master ), + .mst_ports ( slave ), + .addr_map_i ( AddrMap ), + .en_default_mst_port_i ( '0 ), + .default_mst_port_i ( '0 ) ); // logger for master modules From 66e5200ca8e22576e9c15a3b9deab0197c0dd95e Mon Sep 17 00:00:00 2001 From: Thomas Benz Date: Thu, 6 Oct 2022 14:15:07 +0200 Subject: [PATCH 18/18] sim: Correctly set the parameter overwrite --- scripts/run_vsim.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_vsim.sh b/scripts/run_vsim.sh index 7a14b428a..ad1312415 100755 --- a/scripts/run_vsim.sh +++ b/scripts/run_vsim.sh @@ -172,7 +172,7 @@ exec_test() { for Atop in 0 1; do for Exclusive in 0 1; do for UniqueIds in 0 1; do - call_vsim tb_axi_xbar -gTbNumMst=$NumMst -gTbNumSlv=$NumSlv \ + call_vsim tb_axi_xbar -gTbNumMasters=$NumMst -gTbNumSlaves=$NumSlv \ -gTbEnAtop=$Atop -gTbEnExcl=$Exclusive \ -gTbUniqueIds=$UniqueIds done