From 6a6fdcc77fcdbb190e70cb910e5c8ac7d210fbfe Mon Sep 17 00:00:00 2001 From: bluew Date: Sat, 19 Feb 2022 10:11:33 +0100 Subject: [PATCH] axi_xbar: Work around constant function calls for VCS VCS seems to be unable to handle constant function calls whose argument is a `struct` passed into a module as `parameter`. `axi_xbar` became prone to this problem with commit d24303f0df9. This commit works around the problem by calling a system function instead of a constant function. --- CHANGELOG.md | 2 ++ src/axi_xbar.sv | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 188bba62f..c73665f1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `axi_id_remap`: Improve compatibility with Verilator by excluding `assert`s for that tool. - `axi_lite_demux`: Improve compatibility with VCS (issue #187 reported for `axi_demux`, which was fixed in v0.29.2). +- `axi_xbar`: Improve compatibility with VCS by adding VCS-specific code that does not use constant + function calls (#208). ## 0.32.0 - 2022-01-25 diff --git a/src/axi_xbar.sv b/src/axi_xbar.sv index 6124d90a7..acb45f0ac 100644 --- a/src/axi_xbar.sv +++ b/src/axi_xbar.sv @@ -34,6 +34,10 @@ import cf_math_pkg::idx_width; parameter type mst_req_t = logic, parameter type mst_resp_t = logic, 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 ) ( input logic clk_i, input logic rst_ni, @@ -44,12 +48,22 @@ import cf_math_pkg::idx_width; input mst_resp_t [Cfg.NoMstPorts-1:0] mst_ports_resp_i, input rule_t [Cfg.NoAddrRules-1:0] addr_map_i, input logic [Cfg.NoSlvPorts-1:0] en_default_mst_port_i, +`ifdef VCS + input logic [Cfg.NoSlvPorts-1:0][MstPortsIdxWidth-1:0] default_mst_port_i +`else input logic [Cfg.NoSlvPorts-1:0][idx_width(Cfg.NoMstPorts)-1:0] default_mst_port_i +`endif ); typedef logic [Cfg.AxiAddrWidth-1:0] addr_t; // to account for the decoding error slave +`ifdef VCS + localparam int unsigned MstPortsIdxWidthOne = + (Cfg.NoMstPorts == 32'd1) ? 32'd1 : unsigned'($clog2(Cfg.NoMstPorts + 1)); + typedef logic [MstPortsIdxWidthOne-1:0] mst_port_idx_t; +`else typedef logic [idx_width(Cfg.NoMstPorts + 1)-1:0] mst_port_idx_t; +`endif // signals from the axi_demuxes, one index more for decode error slv_req_t [Cfg.NoSlvPorts-1:0][Cfg.NoMstPorts:0] slv_reqs; @@ -63,7 +77,11 @@ import cf_math_pkg::idx_width; slv_resp_t [Cfg.NoMstPorts-1:0][Cfg.NoSlvPorts-1:0] mst_resps; for (genvar i = 0; i < Cfg.NoSlvPorts; i++) begin : gen_slv_port_demux +`ifdef VCS + logic [MstPortsIdxWidth-1:0] dec_aw, dec_ar; +`else logic [idx_width(Cfg.NoMstPorts)-1:0] dec_aw, dec_ar; +`endif mst_port_idx_t slv_aw_select, slv_ar_select; logic dec_aw_valid, dec_aw_error; logic dec_ar_valid, dec_ar_error; @@ -247,6 +265,10 @@ import cf_math_pkg::idx_width; parameter int unsigned AXI_USER_WIDTH = 0, parameter axi_pkg::xbar_cfg_t Cfg = '0, 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 ) ( input logic clk_i, input logic rst_ni, @@ -255,7 +277,11 @@ import cf_math_pkg::idx_width; AXI_BUS.Master mst_ports [Cfg.NoMstPorts-1:0], input rule_t [Cfg.NoAddrRules-1:0] addr_map_i, input logic [Cfg.NoSlvPorts-1:0] en_default_mst_port_i, +`ifdef VCS + input logic [Cfg.NoSlvPorts-1:0][MstPortsIdxWidth-1:0] default_mst_port_i +`else input logic [Cfg.NoSlvPorts-1:0][idx_width(Cfg.NoMstPorts)-1:0] default_mst_port_i +`endif ); localparam int unsigned AxiIdWidthMstPorts = Cfg.AxiIdWidthSlvPorts + $clog2(Cfg.NoSlvPorts);