From cf0c35990c18031d7cbcfbef2da1f8785e485d2d Mon Sep 17 00:00:00 2001 From: Harry Callahan Date: Tue, 26 Mar 2024 21:14:42 +0000 Subject: [PATCH] [dv,py] Tweak ISS linker arg construction for Xcelium The previous code here was a bit too hacky, so implement a solution that directly follows the suggestion in the Cadence support article. An example was also added to make it clear what this transformation is achieving. Additionally, cleanup some of the other code in the module, renaming for clarity and adding comments. Move some variable declarations around to be closer to their use. Add some more typehints. Signed-off-by: Harry Callahan --- dv/uvm/core_ibex/scripts/compile_tb.py | 87 +++++++++++++---------- dv/uvm/core_ibex/yaml/rtl_simulation.yaml | 2 +- 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/dv/uvm/core_ibex/scripts/compile_tb.py b/dv/uvm/core_ibex/scripts/compile_tb.py index 0e7387e2ef..c1844ad1a1 100755 --- a/dv/uvm/core_ibex/scripts/compile_tb.py +++ b/dv/uvm/core_ibex/scripts/compile_tb.py @@ -5,6 +5,7 @@ # SPDX-License-Identifier: Apache-2.0 import argparse +from typing import List import os import sys import subprocess @@ -19,23 +20,31 @@ logger = logging.getLogger(__name__) -def _get_iss_pkgconfig_flags(specifiers, iss_pc, simulator): +def _get_iss_pkgconfig_flags(specifiers: List[str], iss_pc: List[str], simulator: str) -> str: + flags = [] + # Seperate pkg-config calls for each specifier as combining them has been # observed misbehaving on CentOS 7 - _flags = ' '.join([subprocess.check_output( - args=(['pkg-config', s] + iss_pc), - universal_newlines=True,).strip() - for s in specifiers]) - - if simulator == 'xlm': - # See xcelium documentation for the -Wld syntax for passing - # flags to the linker. Passing -rpath, options is tricky - # because commas are parsed strangely between xrun and the xmsc - # tool, and its easy for the options to arrive malformed. Use - # the following hack to get it through. - if '-Wl' in _flags: # This should be in LDFLAGS only - _flags = "'-Xlinker {}'".format(_flags.replace('-Wl,', '')) - return _flags + for s in specifiers: + cmd = ['pkg-config', s] + iss_pc + args = subprocess.check_output(cmd, universal_newlines=True).strip() + + rpath_prefix = '-Wl,-rpath,' + if simulator == 'xlm' and args.startswith(rpath_prefix): + # https://support.cadence.com/apex/ArticleAttachmentPortal?id=a1Od0000000sdF8EAI + # See xcelium documentation for the -Wld syntax for passing + # user specified arguments to the C++ linker. + # Passing -rpath, options is tricky, so use the following workaround as + # suggested in the support article. + # INPUT: '-Wl,-rpath,/opt/spike/lib' + # OUTPUT: '-Wld,-Xlinker,-rpath,-Xlinker,/opt/spike/lib', + rpaths = (args[len(rpath_prefix):]).split(',') + xlinker_rpaths_str = ','.join((f"-Xlinker,{p}" for p in rpaths)) + args = f"-Wld,-Xlinker,-rpath,{xlinker_rpaths_str}" + + flags += [ args ] + + return " ".join(flags) def _main() -> int: @@ -55,40 +64,42 @@ def _main() -> int: md.dir_tb.mkdir(exist_ok=True, parents=True) md.tb_build_log = md.dir_tb/'compile_tb.log' - subst_vars_dict = { - 'core_ibex': md.ibex_dv_root, - 'tb_dir': md.dir_tb, - 'tb_build_log': md.tb_build_log, - 'cmp_opts': get_compile_opts(md.ibex_config, - md.simulator), - 'dir_shared_cov': (md.dir_shared_cov if md.cov else ''), - 'xlm_cov_cfg_file': f"{md.ot_xcelium_cov_scripts}/cover.ccf", - 'dut_cov_rtl_path': md.dut_cov_rtl_path - } - # Locate the spike .pc files to allow us to link against it when # building, riscv-fesvr isn't strictly required but the DV flow has been # observed to see build failures where it isn't present with CentOS 7. spike_iss_pc = ['riscv-riscv', 'riscv-disasm', 'riscv-fdt', 'riscv-fesvr'] - - iss_pkgconfig_dict = { - 'ISS_CFLAGS' : ['--cflags'], - 'ISS_LDFLAGS' : ['--libs-only-other'], - 'ISS_LIBS' : ['--libs-only-l', '--libs-only-L'], - } - md.envvar_PKG_CONFIG_PATH = dict(os.environ).get('PKG_CONFIG_PATH') try: subprocess.check_output(['pkg-config', '--exists'] + spike_iss_pc) except subprocess.CalledProcessError as err: raise RuntimeError( f'Failed to find {spike_iss_pc} pkg-config packages. ' f'Did you set the PKG_CONFIG_PATH correctly?') from err - subst_vars_dict.update( - {k: _get_iss_pkgconfig_flags(v, - spike_iss_pc, - md.simulator) - for k, v in iss_pkgconfig_dict.items()}) + + # Now call out to pkg-config to return the appropriate flags for compilation + # (The keys here are the substitution placeholders in rtl_simulation.yaml) + iss_pkgconfig_dict = { + 'ISS_CFLAGS' : ['--cflags'], + 'ISS_LDFLAGS' : ['--libs-only-other'], + 'ISS_LIBS' : ['--libs-only-l', '--libs-only-L'], + } + iss_cc_subst_vars_dict = \ + {k: _get_iss_pkgconfig_flags(v, spike_iss_pc, md.simulator) + for k, v in iss_pkgconfig_dict.items()} + + # Populate the entire set of variables to substitute in the templated + # compilation command, including the compiler flags for the ISS. + subst_vars_dict = { + 'core_ibex': md.ibex_dv_root, + 'tb_dir': md.dir_tb, + 'tb_build_log': md.tb_build_log, + 'cmp_opts': get_compile_opts(md.ibex_config, + md.simulator), + 'dir_shared_cov': (md.dir_shared_cov if md.cov else ''), + 'xlm_cov_cfg_file': f"{md.ot_xcelium_cov_scripts}/cover.ccf", + 'dut_cov_rtl_path': md.dut_cov_rtl_path + } + subst_vars_dict.update(iss_cc_subst_vars_dict) md.tb_build_stdout = md.dir_tb/'compile_tb_stdstreams.log' md.tb_build_cmds = riscvdv_interface.get_tool_cmds( diff --git a/dv/uvm/core_ibex/yaml/rtl_simulation.yaml b/dv/uvm/core_ibex/yaml/rtl_simulation.yaml index b7103463bb..965ad33394 100644 --- a/dv/uvm/core_ibex/yaml/rtl_simulation.yaml +++ b/dv/uvm/core_ibex/yaml/rtl_simulation.yaml @@ -256,7 +256,7 @@ - -Wld, + -lstdc++ sim: cmd: