diff --git a/dv/uvm/core_ibex/scripts/ibex_cmd.py b/dv/uvm/core_ibex/scripts/ibex_cmd.py index 0d8c5346e2..c4ec6f25e7 100644 --- a/dv/uvm/core_ibex/scripts/ibex_cmd.py +++ b/dv/uvm/core_ibex/scripts/ibex_cmd.py @@ -91,13 +91,27 @@ def get_config(cfg_name: str) -> Config: return parse_config(cfg_name, yaml_path) +def _rv32zc_isa_parts(rv32zc: str) -> list[str]: + mapping = { + 'ibex_pkg::RV32Zca': ['zicsr', 'zifencei', 'zca'], + 'ibex_pkg::RV32ZcaZcb': ['zicsr', 'zifencei', 'zca', 'zcb'], + 'ibex_pkg::RV32ZcaZcmp': ['zicsr', 'zifencei', 'zca', 'zcmp'], + 'ibex_pkg::RV32ZcaZcbZcmp': ['zicsr', 'zifencei', 'zca', 'zcb', 'zcmp'], + } + part = mapping.get(rv32zc) + if part is None: + raise ValueError(f'Unknown RV32ZC value ({rv32zc}) in config YAML') + return part + + def get_isas_for_config(cfg: Config) -> Tuple[str, str]: """Get ISA and ISS_ISA keys for the given Ibex config.""" # NOTE: This logic should match the code in the get_isa_string() function # in core_ibex/tests/core_ibex_base_test.sv: keep them in sync! has_multiplier = cfg.rv32m != 'ibex_pkg::RV32MNone' - base_isa = 'rv32{}{}c'.format('e' if cfg.rv32e else 'i', - 'm' if has_multiplier else '') + + base_isa = 'rv32{}{}'.format('e' if cfg.rv32e else 'i', + 'm' if has_multiplier else '') bitmanip_mapping = { 'ibex_pkg::RV32BNone': [], @@ -113,9 +127,12 @@ def get_isas_for_config(cfg: Config) -> Tuple[str, str]: raise ValueError(f'Unknown RV32B value ({cfg.rv32b}) in config YAML') has_bitmanip = cfg.rv32b != 'ibex_pkg::RV32BNone' - toolchain_isa = base_isa + ('b' if has_bitmanip else '') + # Keep the toolchain ISA using the legacy C extension spelling, but build + # the ISS ISA from the explicit RV32ZC subset below. + toolchain_isa = base_isa + 'c' + ('b' if has_bitmanip else '') + iss_isa = '_'.join([base_isa] + _rv32zc_isa_parts(cfg.rv32zc) + bitmanip_isa) - return (toolchain_isa, '_'.join([base_isa] + bitmanip_isa)) + return (toolchain_isa, iss_isa) _TestEntry = Dict[str, object] diff --git a/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv b/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv index a2658d1239..0e13f4ab7e 100644 --- a/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv +++ b/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv @@ -52,6 +52,10 @@ module core_ibex_tb_top; `define IBEX_CFG_RegFile ibex_pkg::RegFileFF `endif + `ifndef IBEX_CFG_RV32ZC + `define IBEX_CFG_RV32ZC ibex_pkg::RV32ZcaZcbZcmp + `endif + // Ibex Parameters parameter bit PMPEnable = 1'b0; parameter int unsigned PMPGranularity = 0; @@ -62,6 +66,7 @@ module core_ibex_tb_top; parameter ibex_pkg::rv32m_e RV32M = `IBEX_CFG_RV32M; parameter ibex_pkg::rv32b_e RV32B = `IBEX_CFG_RV32B; parameter ibex_pkg::regfile_e RegFile = `IBEX_CFG_RegFile; + parameter ibex_pkg::rv32zc_e RV32ZC = `IBEX_CFG_RV32ZC; parameter bit BranchTargetALU = 1'b0; parameter bit WritebackStage = 1'b0; parameter bit ICache = 1'b0; @@ -103,6 +108,7 @@ module core_ibex_tb_top; .RV32E (RV32E ), .RV32M (RV32M ), .RV32B (RV32B ), + .RV32ZC (RV32ZC ), .RegFile (RegFile ), .BranchTargetALU (BranchTargetALU ), .WritebackStage (WritebackStage ), @@ -370,6 +376,7 @@ module core_ibex_tb_top; uvm_config_db#(bit)::set(null, "*", "RV32E", RV32E); uvm_config_db#(ibex_pkg::rv32m_e)::set(null, "*", "RV32M", RV32M); uvm_config_db#(ibex_pkg::rv32b_e)::set(null, "*", "RV32B", RV32B); + uvm_config_db#(ibex_pkg::rv32zc_e)::set(null, "*", "RV32ZC", RV32ZC); if (PMPEnable) begin uvm_config_db#(bit [31:0])::set(null, "*", "PMPNumRegions", PMPNumRegions); diff --git a/dv/uvm/core_ibex/tests/core_ibex_base_test.sv b/dv/uvm/core_ibex/tests/core_ibex_base_test.sv index 47847ad671..7782961a1a 100644 --- a/dv/uvm/core_ibex/tests/core_ibex_base_test.sv +++ b/dv/uvm/core_ibex/tests/core_ibex_base_test.sv @@ -47,12 +47,26 @@ class core_ibex_base_test extends uvm_test; irq_collected_port = new("irq_collected_port_test", this); endfunction + function automatic string rv32zc_isa_suffix(rv32zc_e rv32zc); + case (rv32zc) + RV32Zca: return "_zicsr_zifencei_zca"; + RV32ZcaZcb: return "_zicsr_zifencei_zca_zcb"; + RV32ZcaZcmp: return "_zicsr_zifencei_zca_zcmp"; + RV32ZcaZcbZcmp: return "_zicsr_zifencei_zca_zcb_zcmp"; + default: begin + `uvm_fatal(`gfn, $sformatf("Unknown RV32ZC value: %0d", rv32zc)) + return ""; + end + endcase + endfunction + // NOTE: This logic should match the code in the get_isas_for_config() function in - // core_ibex/scripts/scripts_lib.py: keep them in sync! + // core_ibex/scripts/ibex_cmd.py: keep them in sync! function string get_isa_string(); bit RV32E; rv32m_e RV32M; rv32b_e RV32B; + rv32zc_e RV32ZC; string isa; if (!uvm_config_db#(bit)::get(null, "", "RV32E", RV32E)) begin @@ -64,12 +78,16 @@ class core_ibex_base_test extends uvm_test; if (!uvm_config_db#(rv32b_e)::get(null, "", "RV32B", RV32B)) begin `uvm_fatal(`gfn, "Cannot get RV32B parameter") end + if (!uvm_config_db#(rv32zc_e)::get(null, "", "RV32ZC", RV32ZC)) begin + `uvm_fatal(`gfn, "Cannot get RV32ZC parameter") + end // Construct the right ISA string for the cosimulator by looking at top-level testbench // parameters. isa = {"rv32", RV32E ? "e" : "i"}; if (RV32M != RV32MNone) isa = {isa, "m"}; - isa = {isa, "c"}; + isa = {isa, rv32zc_isa_suffix(RV32ZC)}; + case (RV32B) RV32BNone: ;