core-v-verif系列之lib<56>

UVM环境介绍
HEAD commitID: 1f968ef

// Copyright 2021 OpenHW Group
// Copyright 2021 Silicon Labs, Inc.
//
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://solderpad.org/licenses/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the 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.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0

`uvm_analysis_imp_decl(_rvfi_instr)

class uvma_isacov_mon_c#(int ILEN=DEFAULT_ILEN,
                         int XLEN=DEFAULT_XLEN) extends uvm_monitor;

  `uvm_component_param_utils(uvma_isacov_mon_c);

  uvma_isacov_cntxt_c                        cntxt;
  uvma_isacov_cfg_c                          cfg;
  uvm_analysis_port#(uvma_isacov_mon_trn_c)  ap;
  instr_name_t                               instr_name_lookup[string];

  // Analysis export to receive instructions from RVFI
  uvm_analysis_imp_rvfi_instr#(uvma_rvfi_instr_seq_item_c#(ILEN,XLEN), uvma_isacov_mon_c) rvfi_instr_imp;

  extern function new(string name = "uvma_isacov_mon", uvm_component parent = null);
  extern virtual function void build_phase(uvm_phase phase);

  /**
   * Convert enumeration from <instr_name_t> to match Spike disassembler
   */
  extern function string convert_instr_to_spike_name(string instr_name);

  /**
   * Analysis port write from RVFI instruction retirement monitor
   */
  extern virtual function void write_rvfi_instr(uvma_rvfi_instr_seq_item_c#(ILEN,XLEN) rvfi_instr);

endclass : uvma_isacov_mon_c


function uvma_isacov_mon_c::new(string name = "uvma_isacov_mon", uvm_component parent = null);

  super.new(name, parent);
  rvfi_instr_imp = new("rvfi_instr_imp", this);

endfunction : new


function void uvma_isacov_mon_c::build_phase(uvm_phase phase);

  instr_name_t in;

  super.build_phase(phase);

  void'(uvm_config_db#(uvma_isacov_cntxt_c)::get(this, "", "cntxt", cntxt));
  if (!cntxt) begin
    `uvm_fatal("CNTXT", "Context handle is null")
  end

  void'(uvm_config_db#(uvma_isacov_cfg_c)::get(this, "", "cfg", cfg));
  if (!cfg) begin
    `uvm_fatal("CFG", "Configuration handle is null")
  end

  ap = new("ap", this);

  dasm_set_config(32, "rv32imc", 0);

  // Use the enumerations in <instr_name_t> to setup the instr_name_lookup
  // convert the enums to lower-case and substitute underscore with . to match
  // Spike disassembler
  in = in.first;
  repeat(in.num) begin
    string instr_name_key = convert_instr_to_spike_name(in.name());

    `uvm_info("ISACOV", $sformatf("Converting: %s to %s", in.name(), instr_name_key), UVM_HIGH);
    instr_name_lookup[instr_name_key] = in;
    in = in.next;
  end

endfunction : build_phase

function string uvma_isacov_mon_c::convert_instr_to_spike_name(string instr_name);

  string spike_instr_name;

  foreach (instr_name[i]) begin
    string chr;

    chr = instr_name.substr(i,i).tolower();

    if (chr == "_") chr = ".";

    spike_instr_name = { spike_instr_name, chr };
  end

  return spike_instr_name;

endfunction : convert_instr_to_spike_name

function void uvma_isacov_mon_c::write_rvfi_instr(uvma_rvfi_instr_seq_item_c#(ILEN,XLEN) rvfi_instr);

  uvma_isacov_mon_trn_c mon_trn;
  string                instr_name;
  bit [63:0]            instr;

  mon_trn = uvma_isacov_mon_trn_c#(.ILEN(ILEN), .XLEN(XLEN))::type_id::create("mon_trn");
  mon_trn.instr = uvma_isacov_instr_c#(ILEN,XLEN)::type_id::create("mon_instr");
  mon_trn.instr.rvfi = rvfi_instr;

  // Mark trapped instructions from RVFI
  mon_trn.instr.trap = rvfi_instr.trap[0];
  mon_trn.instr.cause = rvfi_instr.trap >> 1;

  // Attempt to decode instruction with Spike DASM
  instr_name = dasm_name(rvfi_instr.insn);
  if (instr_name_lookup.exists(instr_name)) begin
    mon_trn.instr.name = instr_name_lookup[instr_name];
  end else begin
    // Undecodable instruction
    // Note that Spike can decode "everything" so if it doesn't map above, then it is an undecodable instruction
    // from OpenHW core-v-verif perspective so set to UNKNOWN
    mon_trn.instr.name = UNKNOWN;
  end

  `uvm_info("ISACOVMON", $sformatf("rvfi = 0x%08x %s", rvfi_instr.insn, instr_name), UVM_HIGH);

  mon_trn.instr.itype = get_instr_type(mon_trn.instr.name);
  mon_trn.instr.ext   = get_instr_ext(mon_trn.instr.name);
  mon_trn.instr.group = get_instr_group(mon_trn.instr.name, rvfi_instr.mem_addr);

  instr = $signed(rvfi_instr.insn);

  // Disassemble the instruction using Spike (via DPI)
  if (mon_trn.instr.ext == C_EXT || mon_trn.instr.ext == ZCE_EXT) begin
    mon_trn.instr.rs1     = dasm_rvc_rs1(instr);
    mon_trn.instr.rs2     = dasm_rvc_rs2(instr);
    mon_trn.instr.rd      = dasm_rvc_rd(instr);
    mon_trn.instr.c_rdrs1 = dasm_rvc_rd(instr);
    mon_trn.instr.c_rd    = mon_trn.instr.decode_rd_c(instr);
    mon_trn.instr.c_rs1   = mon_trn.instr.decode_rs1_c(instr);
    mon_trn.instr.c_rs2   = mon_trn.instr.decode_rs2_c(instr);
  end
  else begin
    mon_trn.instr.rs1  = dasm_rs1(instr);
    mon_trn.instr.rs2  = dasm_rs2(instr);
    mon_trn.instr.rd   = dasm_rd(instr);
    mon_trn.instr.immi = dasm_i_imm(instr);
    mon_trn.instr.imms = dasm_s_imm(instr);
    mon_trn.instr.immb = dasm_sb_imm(instr) >> 1;  // Because dasm gives [12:0], not [12: 1]
    mon_trn.instr.immu = dasm_u_imm(instr) >> 12;  // Because dasm gives [31:0], not [31:12]
    mon_trn.instr.immj = dasm_uj_imm(instr) >> 1;  // Because dasm gives [20:0], not [20: 1]
  end

  // Make instructions as illegal,
  // 1. If UNKNOWN (undecodable)
  if (mon_trn.instr.name == UNKNOWN)
    mon_trn.instr.illegal = 1;
  // 2. If a CSR instruction is not targeted to a valid CSR
  if (mon_trn.instr.group == CSR_GROUP) begin
    mon_trn.instr.csr_val = dasm_csr(instr);
    if (!$cast(mon_trn.instr.csr, mon_trn.instr.csr_val) ||
         cfg.core_cfg.unsupported_csr_mask[mon_trn.instr.csr_val]) begin
      mon_trn.instr.illegal = 1;
    end
  end
  // 3. Instruction is in unsupported extension
  if ((mon_trn.instr.ext == A_EXT && !cfg.core_cfg.ext_a_supported) ||
      (mon_trn.instr.ext == C_EXT && !cfg.core_cfg.ext_c_supported) ||
      (mon_trn.instr.ext == F_EXT && !cfg.core_cfg.ext_f_supported) ||
      (mon_trn.instr.ext == M_EXT && !cfg.core_cfg.ext_m_supported) ||
      (mon_trn.instr.ext == P_EXT && !cfg.core_cfg.ext_p_supported) ||
      (mon_trn.instr.ext == ZICSR_EXT && !cfg.core_cfg.ext_zicsr_supported) ||
      (mon_trn.instr.ext == ZIFENCEI_EXT && !cfg.core_cfg.ext_zifencei_supported) ||
      (mon_trn.instr.itype == ZBA_TYPE && !cfg.core_cfg.ext_zba_supported) ||
      (mon_trn.instr.itype == ZBB_TYPE && !cfg.core_cfg.ext_zbb_supported) ||
      (mon_trn.instr.itype == ZBC_TYPE && !cfg.core_cfg.ext_zbc_supported) ||
      (mon_trn.instr.itype == ZBS_TYPE && !cfg.core_cfg.ext_zbs_supported) ||
      (mon_trn.instr.itype == ZCB_TYPE && !cfg.core_cfg.ext_zcb_supported)) begin
    mon_trn.instr.illegal = 1;
  end
  // 4. Valid supported instruction with invalid operands
  if (mon_trn.instr.name == C_ADDI4SPN && mon_trn.instr.get_field_imm() == 0)
    mon_trn.instr.illegal = 1;

  // Set enumerations for each immediate value (if applicable)
  if (mon_trn.instr.itype == B_TYPE)
    mon_trn.instr.immb_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.immb, $bits(mon_trn.instr.immb), 1);

  if (mon_trn.instr.itype == S_TYPE)
    mon_trn.instr.imms_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.imms, $bits(mon_trn.instr.imms), 1);

  if (mon_trn.instr.itype == U_TYPE)
    mon_trn.instr.immu_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.immu, $bits(mon_trn.instr.immu), 0);

  if (mon_trn.instr.itype == I_TYPE)
    mon_trn.instr.immi_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.immi, $bits(mon_trn.instr.immi), immi_is_signed[mon_trn.instr.name]);

  if (mon_trn.instr.itype == J_TYPE)
    mon_trn.instr.immj_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.immj, $bits(mon_trn.instr.immj), 1);

  if (mon_trn.instr.itype == CI_TYPE) begin
    case (mon_trn.instr.name)
      C_ADDI:      mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 6, c_imm_is_signed[mon_trn.instr.name]);
      C_NOP:       mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 6, c_imm_is_signed[mon_trn.instr.name]);
      C_ADDI16SP:  mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 6, c_imm_is_signed[mon_trn.instr.name]);
      C_LWSP:      mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 6, c_imm_is_signed[mon_trn.instr.name]);
      C_SLLI:      mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 6, c_imm_is_signed[mon_trn.instr.name]);
      C_LI:        mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 6, c_imm_is_signed[mon_trn.instr.name]);
      C_LUI:       mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 6, c_imm_is_signed[mon_trn.instr.name]);
      default:     `uvm_fatal("ISACOV", $sformatf("unhandled CI instruction: %s", mon_trn.instr.name.name()))
    endcase
  end
  if (mon_trn.instr.itype == CSS_TYPE) begin
    case (mon_trn.instr.name)
      C_SWSP: mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 6, c_imm_is_signed[mon_trn.instr.name]);
      default:     `uvm_fatal("ISACOV", $sformatf("unhandled CSS instruction: %s", mon_trn.instr.name.name()))
    endcase
  end
  if (mon_trn.instr.itype == CIW_TYPE) begin
    case (mon_trn.instr.name)
      C_ADDI4SPN: mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 8, c_imm_is_signed[mon_trn.instr.name]);
      default:     `uvm_fatal("ISACOV", $sformatf("unhandled CIW instruction: %s", mon_trn.instr.name.name()))
    endcase
  end
  if (mon_trn.instr.itype == CL_TYPE) begin
    case (mon_trn.instr.name)
      C_LW: mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 5, c_imm_is_signed[mon_trn.instr.name]);
      default:     `uvm_fatal("ISACOV", $sformatf("unhandled CL instruction: %s", mon_trn.instr.name.name()))
    endcase
  end
  if (mon_trn.instr.itype == CS_TYPE) begin
    case (mon_trn.instr.name)
      C_SW: mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 5, c_imm_is_signed[mon_trn.instr.name]);
      default:     `uvm_fatal("ISACOV", $sformatf("unhandled CS instruction: %s", mon_trn.instr.name.name()))
    endcase
  end
  if (mon_trn.instr.itype == CB_TYPE) begin
    case (mon_trn.instr.name)
      C_BEQZ,
      C_BNEZ: mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 8, c_imm_is_signed[mon_trn.instr.name]);
      C_ANDI: mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 6, c_imm_is_signed[mon_trn.instr.name]);
      C_SRLI,
      C_SRAI: mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 6, c_imm_is_signed[mon_trn.instr.name]);
      default:     `uvm_fatal("ISACOV", $sformatf("unhandled CB instruction: %s", mon_trn.instr.name.name()))
    endcase
  end
  if (mon_trn.instr.itype == CJ_TYPE) begin
    case (mon_trn.instr.name)
      C_J,
      C_JAL: mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 11, c_imm_is_signed[mon_trn.instr.name]);
      default:     `uvm_fatal("ISACOV", $sformatf("unhandled CJ instruction: %s", mon_trn.instr.name.name()))
    endcase
  end
  if (mon_trn.instr.name inside {C_LBU, C_SB, C_LHU, C_SH, C_LH}) begin
    case (mon_trn.instr.name)
      C_LBU,
      C_SB: mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 2, c_imm_is_signed[mon_trn.instr.name]);
      C_LHU, C_SH,
      C_LH: mon_trn.instr.c_imm_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.get_field_imm(), 1, c_imm_is_signed[mon_trn.instr.name]);
      default:     `uvm_fatal("ISACOV", $sformatf("unhandled ZCB instruction: %s", mon_trn.instr.name.name()))
    endcase
  end

  mon_trn.instr.set_valid_flags();

  // Set enumerations for register values as reported from RVFI
  if (mon_trn.instr.rs1_valid) begin
    mon_trn.instr.rs1_value = rvfi_instr.rs1_rdata;
    mon_trn.instr.rs1_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.rs1_value, $bits(mon_trn.instr.rs1_value), rs1_is_signed[mon_trn.instr.name]);
  end
  if (mon_trn.instr.rs2_valid) begin
    mon_trn.instr.rs2_value = rvfi_instr.rs2_rdata;
    mon_trn.instr.rs2_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.rs2_value, $bits(mon_trn.instr.rs2_value), rs2_is_signed[mon_trn.instr.name]);
  end
  if (mon_trn.instr.rd_valid) begin
    mon_trn.instr.rd_value  = rvfi_instr.rd1_wdata;
    mon_trn.instr.rd_value_type = mon_trn.instr.get_instr_value_type(mon_trn.instr.rd_value, $bits(mon_trn.instr.rd_value), rd_is_signed[mon_trn.instr.name]);
  end

  // Write to analysis port
  ap.write(mon_trn);

endfunction : write_rvfi_instr



lib/uvm_agents/uvma_isacov/uvma_isacov_mon.sv

1. 简要介绍

该文件是ISACOV验证环境的监控器实现,主要功能包括:

  1. 接收RVFI指令流
  2. 解码指令信息
  3. 生成监控事务
  4. 分析指令合法性
  5. 通过TLM端口发送监控数据

2. 接口介绍

2.1 类定义
class uvma_isacov_mon_c#(int ILEN=DEFAULT_ILEN,
                         int XLEN=DEFAULT_XLEN) extends uvm_monitor;
  • 代码介绍:定义参数化监控器类,继承自UVM基础监控器类
  • 模板参数
    • ILEN:指令长度
    • XLEN:数据宽度
2.2 RVFI接口
uvm_analysis_imp_rvfi_instr#(uvma_rvfi_instr_seq_item_c#(ILEN,XLEN), uvma_isacov_mon_c) rvfi_instr_imp;
  • 代码介绍:定义RVFI指令分析端口
  • 功能:接收RISC-V Formal Interface指令流

3. 参数介绍

3.1 配置对象
uvma_isacov_cfg_c cfg;
  • 参数说明:存储验证配置
  • 获取方式:通过UVM配置数据库获取
3.2 上下文对象
uvma_isacov_cntxt_c cntxt;
  • 参数说明:存储运行时状态
  • 包含内容:虚拟接口和事件触发器

4. 模块实现介绍

4.1 build_phase实现
function void build_phase(uvm_phase phase);
   instr_name_t in;
   in = in.first;
   repeat(in.num) begin
      string instr_name_key = convert_instr_to_spike_name(in.name());
      instr_name_lookup[instr_name_key] = in;
      in = in.next;
   end
endfunction
  • 代码分析
    1. 初始化指令名称查找表
    2. 转换枚举名为Spike格式
    3. 建立名称到枚举的映射关系
4.2 RVFI指令处理
function void write_rvfi_instr(uvma_rvfi_instr_seq_item_c#(ILEN,XLEN) rvfi_instr);
   mon_trn.instr.name = instr_name_lookup[instr_name];
   mon_trn.instr.itype = get_instr_type(mon_trn.instr.name);
   mon_trn.instr.ext = get_instr_ext(mon_trn.instr.name);
endfunction
  • 代码分析
    1. 从RVFI指令创建监控事务
    2. 使用Spike反汇编器解码指令
    3. 设置指令类型和扩展信息
    4. 检查指令合法性

5. 总结

该监控器组件具有以下特点:

  1. 完整的UVM标准实现
  2. 强大的指令解码能力
  3. 灵活的配置管理
  4. 完善的合法性检查
  5. 可扩展的设计架构

作为验证环境的核心组件,它为指令集覆盖率验证提供了全面的监控能力,确保能够准确捕获和分析指令执行行为。

// Copyright 2020 OpenHW Group
// Copyright 2020 Datum Technology Corporation
// Copyright 2020 Silicon Labs, Inc.
//
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://solderpad.org/licenses/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the 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.


`ifndef __UVMA_ISACOV_TDEFS_SV__
`define __UVMA_ISACOV_TDEFS_SV__

typedef enum {
  A_EXT,
  B_EXT,
  C_EXT,
  F_EXT,
  I_EXT,
  M_EXT,
  P_EXT,
  Q_EXT,
  ZIFENCEI_EXT,
  ZICSR_EXT,
  ZCE_EXT
} instr_ext_t;

typedef enum {
   // Used for an opcode that cannot be decoded
  UNKNOWN,

  // 32I
  LUI, AUIPC, JAL, JALR,
  BEQ, BNE, BLT, BGE, BLTU, BGEU,
  LB, LH, LW, LBU, LHU, SB, SH, SW,
  ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI,
  ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND,
  FENCE, ECALL, EBREAK, DRET, MRET, WFI,

  // 32M
  MUL, MULH, MULHSU, MULHU,
  DIV, DIVU, REM, REMU,

  // 32C
  C_ADDI4SPN, C_LW, C_SW, C_NOP,
  C_ADDI, C_JAL, C_LI, C_ADDI16SP, C_LUI, C_SRLI, C_SRAI,
  C_ANDI, C_SUB, C_XOR, C_OR, C_AND, C_J, C_BEQZ, C_BNEZ,
  C_SLLI, C_LWSP, C_JR, C_MV, C_EBREAK, C_JALR, C_ADD, C_SWSP,

  // 32A
  LR_W, SC_W,
  AMOSWAP_W, AMOADD_W, AMOXOR_W, AMOAND_W,
  AMOOR_W, AMOMIN_W, AMOMAX_W, AMOMINU_W, AMOMAXU_W,

  // 32B
  SH1ADD, SH2ADD, SH3ADD,
  CLZ, CTZ, CPOP,
  MIN, MAX, MINU, MAXU,
  SEXT_B, SEXT_H, ZEXT_H,
  ANDN, ORN, XNOR, ROR, RORI, ROL,
  REV8, ORC_B,
  CLMUL, CLMULH, CLMULR,
  BSET, BSETI, BCLR, BCLRI, BINV, BINVI, BEXT, BEXTI,

  // Zicsr
  CSRRW, CSRRS, CSRRC,
  CSRRWI, CSRRSI, CSRRCI,

  // Zifencei
  FENCE_I,

  //Zcb
  C_LBU, C_LHU, C_LH,
  C_SB, C_SH,
  C_ZEXT_B, C_SEXT_B, C_ZEXT_H, C_SEXT_H,
  C_NOT, C_MUL

} instr_name_t;

typedef enum {
  // Used for non-decodable
  UNKNOWN_TYPE,

  // RV32 types
  R_TYPE,
  I_TYPE,
  S_TYPE,
  B_TYPE,
  U_TYPE,
  J_TYPE,

  CI_TYPE,
  CR_TYPE,
  CSS_TYPE,
  CIW_TYPE,
  CL_TYPE,
  CS_TYPE,
  CA_TYPE,
  CB_TYPE,
  CJ_TYPE,

  ZBA_TYPE,
  ZBB_TYPE,
  ZBC_TYPE,
  ZBS_TYPE,

  // CSR* instruction with rs1 operand
  CSR_TYPE,

  // CSR* instruction with immu operand
  CSRI_TYPE,

  // ZCB instructions
  ZCB_TYPE

} instr_type_t;

typedef enum {
  // Use for undecodable instructions
  UNKNOWN_GROUP,

  LOAD_GROUP,
  STORE_GROUP,
  MISALIGN_LOAD_GROUP,
  MISALIGN_STORE_GROUP,
  ALU_GROUP,
  BRANCH_GROUP,
  JUMP_GROUP,
  FENCE_GROUP,
  FENCE_I_GROUP,
  RET_GROUP,
  WFI_GROUP,
  CSR_GROUP,
  ENV_GROUP,
  MUL_GROUP,
  MULTI_MUL_GROUP,
  DIV_GROUP,
  ALOAD_GROUP,
  ASTORE_GROUP,
  AMEM_GROUP
} instr_group_t;

typedef enum bit[CSR_ADDR_WL-1:0] {
  USTATUS        = 'h000,
  UIE            = 'h004,
  UTVEC          = 'h005,
  USCRATCH       = 'h040,
  UEPC           = 'h041,
  UCAUSE         = 'h042,
  UTVAL          = 'h043,
  UIP            = 'h044,
  FFLAGS         = 'h001,
  FRM            = 'h002,
  FCSR           = 'h003,
  CYCLE          = 'hC00,
  TIME           = 'hC01,
  INSTRET        = 'hC02,
  HPMCOUNTER3    = 'hC03,
  HPMCOUNTER4    = 'hC04,
  HPMCOUNTER5    = 'hC05,
  HPMCOUNTER6    = 'hC06,
  HPMCOUNTER7    = 'hC07,
  HPMCOUNTER8    = 'hC08,
  HPMCOUNTER9    = 'hC09,
  HPMCOUNTER10   = 'hC0A,
  HPMCOUNTER11   = 'hC0B,
  HPMCOUNTER12   = 'hC0C,
  HPMCOUNTER13   = 'hC0D,
  HPMCOUNTER14   = 'hC0E,
  HPMCOUNTER15   = 'hC0F,
  HPMCOUNTER16   = 'hC10,
  HPMCOUNTER17   = 'hC11,
  HPMCOUNTER18   = 'hC12,
  HPMCOUNTER19   = 'hC13,
  HPMCOUNTER20   = 'hC14,
  HPMCOUNTER21   = 'hC15,
  HPMCOUNTER22   = 'hC16,
  HPMCOUNTER23   = 'hC17,
  HPMCOUNTER24   = 'hC18,
  HPMCOUNTER25   = 'hC19,
  HPMCOUNTER26   = 'hC1A,
  HPMCOUNTER27   = 'hC1B,
  HPMCOUNTER28   = 'hC1C,
  HPMCOUNTER29   = 'hC1D,
  HPMCOUNTER30   = 'hC1E,
  HPMCOUNTER31   = 'hC1F,
  CYCLEH         = 'hC80,
  TIMEH          = 'hC81,
  INSTRETH       = 'hC82,
  HPMCOUNTER3H   = 'hC83,
  HPMCOUNTER4H   = 'hC84,
  HPMCOUNTER5H   = 'hC85,
  HPMCOUNTER6H   = 'hC86,
  HPMCOUNTER7H   = 'hC87,
  HPMCOUNTER8H   = 'hC88,
  HPMCOUNTER9H   = 'hC89,
  HPMCOUNTER10H  = 'hC8A,
  HPMCOUNTER11H  = 'hC8B,
  HPMCOUNTER12H  = 'hC8C,
  HPMCOUNTER13H  = 'hC8D,
  HPMCOUNTER14H  = 'hC8E,
  HPMCOUNTER15H  = 'hC8F,
  HPMCOUNTER16H  = 'hC90,
  HPMCOUNTER17H  = 'hC91,
  HPMCOUNTER18H  = 'hC92,
  HPMCOUNTER19H  = 'hC93,
  HPMCOUNTER20H  = 'hC94,
  HPMCOUNTER21H  = 'hC95,
  HPMCOUNTER22H  = 'hC96,
  HPMCOUNTER23H  = 'hC97,
  HPMCOUNTER24H  = 'hC98,
  HPMCOUNTER25H  = 'hC99,
  HPMCOUNTER26H  = 'hC9A,
  HPMCOUNTER27H  = 'hC9B,
  HPMCOUNTER28H  = 'hC9C,
  HPMCOUNTER29H  = 'hC9D,
  HPMCOUNTER30H  = 'hC9E,
  HPMCOUNTER31H  = 'hC9F,
  SSTATUS        = 'h100,
  SEDELEG        = 'h102,
  SIDELEG        = 'h103,
  SIE            = 'h104,
  STVEC          = 'h105,
  SCOUNTEREN     = 'h106,
  SSCRATCH       = 'h140,
  SEPC           = 'h141,
  SCAUSE         = 'h142,
  STVAL          = 'h143,
  SIP            = 'h144,
  SATP           = 'h180,
  MVENDORID      = 'hF11,
  MARCHID        = 'hF12,
  MIMPID         = 'hF13,
  MHARTID        = 'hF14,
  MSTATUS        = 'h300,
  MISA           = 'h301,
  MEDELEG        = 'h302,
  MIDELEG        = 'h303,
  MIE            = 'h304,
  MTVEC          = 'h305,
  MCOUNTEREN     = 'h306,
  MENVCFG        = 'h30A,
  MSTATUSH       = 'h310,
  MENVCFGH       = 'h31A,
  MSCRATCH       = 'h340,
  MEPC           = 'h341,
  MCAUSE         = 'h342,
  MTVAL          = 'h343,
  MIP            = 'h344,
  MTINST         = 'h34A,
  MTVAL2         = 'h34B,
  PMPCFG0        = 'h3A0,
  PMPCFG1        = 'h3A1,
  PMPCFG2        = 'h3A2,
  PMPCFG3        = 'h3A3,
  PMPCFG4        = 'h3A4,
  PMPCFG5        = 'h3A5,
  PMPCFG6        = 'h3A6,
  PMPCFG7        = 'h3A7,
  PMPCFG8        = 'h3A8,
  PMPCFG9        = 'h3A9,
  PMPCFG10       = 'h3AA,
  PMPCFG11       = 'h3AB,
  PMPCFG12       = 'h3AC,
  PMPCFG13       = 'h3AD,
  PMPCFG14       = 'h3AE,
  PMPCFG15       = 'h3AF,
  PMPADDR0       = 'h3B0,
  PMPADDR1       = 'h3B1,
  PMPADDR2       = 'h3B2,
  PMPADDR3       = 'h3B3,
  PMPADDR4       = 'h3B4,
  PMPADDR5       = 'h3B5,
  PMPADDR6       = 'h3B6,
  PMPADDR7       = 'h3B7,
  PMPADDR8       = 'h3B8,
  PMPADDR9       = 'h3B9,
  PMPADDR10      = 'h3BA,
  PMPADDR11      = 'h3BB,
  PMPADDR12      = 'h3BC,
  PMPADDR13      = 'h3BD,
  PMPADDR14      = 'h3BE,
  PMPADDR15      = 'h3BF,
  PMPADDR16      = 'h3C0,
  PMPADDR17      = 'h3C1,
  PMPADDR18      = 'h3C2,
  PMPADDR19      = 'h3C3,
  PMPADDR20      = 'h3C4,
  PMPADDR21      = 'h3C5,
  PMPADDR22      = 'h3C6,
  PMPADDR23      = 'h3C7,
  PMPADDR24      = 'h3C8,
  PMPADDR25      = 'h3C9,
  PMPADDR26      = 'h3CA,
  PMPADDR27      = 'h3CB,
  PMPADDR28      = 'h3CC,
  PMPADDR29      = 'h3CD,
  PMPADDR30      = 'h3CE,
  PMPADDR31      = 'h3CF,
  PMPADDR32      = 'h3D0,
  PMPADDR33      = 'h3D1,
  PMPADDR34      = 'h3D2,
  PMPADDR35      = 'h3D3,
  PMPADDR36      = 'h3D4,
  PMPADDR37      = 'h3D5,
  PMPADDR38      = 'h3D6,
  PMPADDR39      = 'h3D7,
  PMPADDR40      = 'h3D8,
  PMPADDR41      = 'h3D9,
  PMPADDR42      = 'h3DA,
  PMPADDR43      = 'h3DB,
  PMPADDR44      = 'h3DC,
  PMPADDR45      = 'h3DD,
  PMPADDR46      = 'h3DE,
  PMPADDR47      = 'h3DF,
  PMPADDR48      = 'h3E0,
  PMPADDR49      = 'h3E1,
  PMPADDR50      = 'h3E2,
  PMPADDR51      = 'h3E3,
  PMPADDR52      = 'h3E4,
  PMPADDR53      = 'h3E5,
  PMPADDR54      = 'h3E6,
  PMPADDR55      = 'h3E7,
  PMPADDR56      = 'h3E8,
  PMPADDR57      = 'h3E9,
  PMPADDR58      = 'h3EA,
  PMPADDR59      = 'h3EB,
  PMPADDR60      = 'h3EC,
  PMPADDR61      = 'h3ED,
  PMPADDR62      = 'h3EE,
  PMPADDR63      = 'h3EF,
  MCYCLE         = 'hB00,
  MINSTRET       = 'hB02,
  MHPMCOUNTER3   = 'hB03,
  MHPMCOUNTER4   = 'hB04,
  MHPMCOUNTER5   = 'hB05,
  MHPMCOUNTER6   = 'hB06,
  MHPMCOUNTER7   = 'hB07,
  MHPMCOUNTER8   = 'hB08,
  MHPMCOUNTER9   = 'hB09,
  MHPMCOUNTER10  = 'hB0A,
  MHPMCOUNTER11  = 'hB0B,
  MHPMCOUNTER12  = 'hB0C,
  MHPMCOUNTER13  = 'hB0D,
  MHPMCOUNTER14  = 'hB0E,
  MHPMCOUNTER15  = 'hB0F,
  MHPMCOUNTER16  = 'hB10,
  MHPMCOUNTER17  = 'hB11,
  MHPMCOUNTER18  = 'hB12,
  MHPMCOUNTER19  = 'hB13,
  MHPMCOUNTER20  = 'hB14,
  MHPMCOUNTER21  = 'hB15,
  MHPMCOUNTER22  = 'hB16,
  MHPMCOUNTER23  = 'hB17,
  MHPMCOUNTER24  = 'hB18,
  MHPMCOUNTER25  = 'hB19,
  MHPMCOUNTER26  = 'hB1A,
  MHPMCOUNTER27  = 'hB1B,
  MHPMCOUNTER28  = 'hB1C,
  MHPMCOUNTER29  = 'hB1D,
  MHPMCOUNTER30  = 'hB1E,
  MHPMCOUNTER31  = 'hB1F,
  MCYCLEH        = 'hB80,
  MINSTRETH      = 'hB82,
  MHPMCOUNTER3H  = 'hB83,
  MHPMCOUNTER4H  = 'hB84,
  MHPMCOUNTER5H  = 'hB85,
  MHPMCOUNTER6H  = 'hB86,
  MHPMCOUNTER7H  = 'hB87,
  MHPMCOUNTER8H  = 'hB88,
  MHPMCOUNTER9H  = 'hB89,
  MHPMCOUNTER10H = 'hB8A,
  MHPMCOUNTER11H = 'hB8B,
  MHPMCOUNTER12H = 'hB8C,
  MHPMCOUNTER13H = 'hB8D,
  MHPMCOUNTER14H = 'hB8E,
  MHPMCOUNTER15H = 'hB8F,
  MHPMCOUNTER16H = 'hB90,
  MHPMCOUNTER17H = 'hB91,
  MHPMCOUNTER18H = 'hB92,
  MHPMCOUNTER19H = 'hB93,
  MHPMCOUNTER20H = 'hB94,
  MHPMCOUNTER21H = 'hB95,
  MHPMCOUNTER22H = 'hB96,
  MHPMCOUNTER23H = 'hB97,
  MHPMCOUNTER24H = 'hB98,
  MHPMCOUNTER25H = 'hB99,
  MHPMCOUNTER26H = 'hB9A,
  MHPMCOUNTER27H = 'hB9B,
  MHPMCOUNTER28H = 'hB9C,
  MHPMCOUNTER29H = 'hB9D,
  MHPMCOUNTER30H = 'hB9E,
  MHPMCOUNTER31H = 'hB9F,
  MCOUNTINHIBIT  = 'h320,
  MHPMEVENT3     = 'h323,
  MHPMEVENT4     = 'h324,
  MHPMEVENT5     = 'h325,
  MHPMEVENT6     = 'h326,
  MHPMEVENT7     = 'h327,
  MHPMEVENT8     = 'h328,
  MHPMEVENT9     = 'h329,
  MHPMEVENT10    = 'h32A,
  MHPMEVENT11    = 'h32B,
  MHPMEVENT12    = 'h32C,
  MHPMEVENT13    = 'h32D,
  MHPMEVENT14    = 'h32E,
  MHPMEVENT15    = 'h32F,
  MHPMEVENT16    = 'h330,
  MHPMEVENT17    = 'h331,
  MHPMEVENT18    = 'h332,
  MHPMEVENT19    = 'h333,
  MHPMEVENT20    = 'h334,
  MHPMEVENT21    = 'h335,
  MHPMEVENT22    = 'h336,
  MHPMEVENT23    = 'h337,
  MHPMEVENT24    = 'h338,
  MHPMEVENT25    = 'h339,
  MHPMEVENT26    = 'h33A,
  MHPMEVENT27    = 'h33B,
  MHPMEVENT28    = 'h33C,
  MHPMEVENT29    = 'h33D,
  MHPMEVENT30    = 'h33E,
  MHPMEVENT31    = 'h33F,
  MSECCFG        = 'h747,
  MSECCFGH       = 'h757,
  TSELECT        = 'h7A0,
  TDATA1         = 'h7A1,
  TDATA2         = 'h7A2,
  TDATA3         = 'h7A3,
  TINFO          = 'h7A4,
  MCONTEXT       = 'h7A8,
  SCONTEXT       = 'h7AA,
  DCSR           = 'h7B0,
  DPC            = 'h7B1,
  DSCRATCH0      = 'h7B2,
  DSCRATCH1      = 'h7B3,
  VSTART         = 'h008,
  VXSTAT         = 'h009,
  VXRM           = 'h00A,
  VL             = 'hC20,
  VTYPE          = 'hC21,
  VLENB          = 'hC22,
  MCONFIGPTR     = 'hF15
} instr_csr_t;

bit rs1_is_signed[instr_name_t] = '{
  MULH   : 1,
  MULHSU : 1,
  DIV    : 1,
  REM    : 1,
  ADDI   : 1,
  SLTI   : 1,
  SRA    : 1,
  ADD    : 1,
  SUB    : 1,
  SLT    : 1,
  C_ADDI : 1,
  C_ADDI16SP : 1,
  C_ADD  : 1,
  C_SUB  : 1,
  SH1ADD : 1,
  SH2ADD : 1,
  SH3ADD : 1,
  C_SEXT_B : 1,
  C_SEXT_H : 1,
  C_MUL : 1,
  default: 0
};

bit rs2_is_signed[instr_name_t] = '{
  MULH   : 1,
  DIV    : 1,
  REM    : 1,
  ADD    : 1,
  SUB    : 1,
  SLT    : 1,
  C_ADD  : 1,
  C_SUB  : 1,
  SH1ADD : 1,
  SH2ADD : 1,
  SH3ADD : 1,
  C_MUL  : 1,
  default: 0
};

bit immi_is_signed[instr_name_t] = '{
  JALR   : 1,
  LB     : 1,
  LH     : 1,
  LW     : 1,
  LBU    : 1,
  LHU    : 1,
  SLTI   : 1,
  SLTIU  : 1,
  XORI   : 1,
  ORI    : 1,
  ANDI   : 1,
  ADDI   : 1,
  SLLI   : 0,
  SRLI   : 0,
  SRAI   : 0,
  default: 0
};

bit c_imm_is_signed[instr_name_t] = '{
  C_ADDI:  1,
  C_ADDI16SP: 1,
  C_ANDI:  1,
  C_BEQZ:  1,
  C_BNEZ:  1,
  C_J:     1,
  C_JAL:   1,
  C_LI:    1,
  C_LUI:   1,
  C_NOP:   1,
  default: 0
};

bit c_imm_is_nonzero[instr_name_t] = '{
  C_ADDI4SPN:1,
  C_NOP:   1,
  C_ADDI:  1,
  C_ADDI16SP:1,
  C_LUI:   1,
  C_SRLI:  1,
  C_SRAI:  1,
  C_SLLI:  1,
  default: 0
};

bit rd_is_signed[instr_name_t] = '{
  MULH   : 1,
  MULHSU : 1,
  DIV    : 1,
  REM    : 1,
  LH     : 1,
  LB     : 1,
  ADD    : 1,
  SRA    : 1,
  SUB    : 1,
  ADDI   : 1,
  C_ADDI : 1,
  C_ADDI16SP: 1,
  C_ADD  : 1,
  C_SUB  : 1,
  SH1ADD : 1,
  SH2ADD : 1,
  SH3ADD : 1,
  C_LH   : 1,
  C_MUL  : 1,
  default: 0
};

bit c_has_rs1[instr_name_t] = '{
  C_LW   : 1,
  C_SW   : 1,
  C_ADDI : 1,
  C_ADDI16SP:1,
  C_SRLI : 1,
  C_SRAI : 1,
  C_ANDI : 1,
  C_SUB  : 1,
  C_XOR  : 1,
  C_OR   : 1,
  C_AND  : 1,
  C_BEQZ : 1,
  C_BNEZ : 1,
  C_SLLI : 1,
  C_JR   : 1,
  C_JALR : 1,
  C_ADD  : 1,
  C_LBU  : 1,
  C_SB   : 1,
  C_SH   : 1,
  C_LHU  : 1,
  C_LH   : 1,
  C_ZEXT_B  : 1,
  C_SEXT_B  : 1,
  C_ZEXT_H  : 1,
  C_SEXT_H  : 1,
  C_NOT  : 1,
  C_MUL  : 1,
  default: 0
};

typedef enum {
  ZERO,     // For signed and unsigned values
  NON_ZERO, // For unsigned values
  POSITIVE, // For signed values
  NEGATIVE  // For signed values
} instr_value_t;  // TODO:ropeders should be "value_type_t"?

// Package level methods to map instruction to extension
function instr_ext_t get_instr_ext(instr_name_t name);
  if (name inside
    {
      LUI, AUIPC, JAL, JALR,
      BEQ, BNE, BLT, BGE, BLTU, BGEU,
      LB, LH, LW, LBU, LHU, SB, SH, SW,
      ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI,
      ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND,
      FENCE, ECALL, EBREAK, DRET, MRET, WFI
    })
    return I_EXT;

  if (name inside
    {
      MUL, MULH, MULHSU, MULHU,
      DIV, DIVU, REM, REMU
    })
    return M_EXT;

  if (name inside
    {
      C_ADDI4SPN, C_LW, C_SW, C_NOP,
      C_ADDI, C_JAL, C_LI, C_ADDI16SP, C_LUI, C_SRLI, C_SRAI,
      C_ANDI, C_SUB, C_XOR, C_OR, C_AND, C_J, C_BEQZ, C_BNEZ,
      C_SLLI, C_LWSP, C_JR, C_MV, C_EBREAK, C_JALR, C_ADD, C_SWSP
    })
    return C_EXT;

  if (name inside
    {
      LR_W, SC_W,
      AMOSWAP_W, AMOADD_W, AMOXOR_W, AMOAND_W,
      AMOOR_W, AMOMIN_W, AMOMAX_W, AMOMINU_W, AMOMAXU_W
    })
    return A_EXT;

  if (name inside
    {
      SH1ADD, SH2ADD, SH3ADD,
      CLZ, CTZ, CPOP,
      MIN, MAX, MINU, MAXU,
      SEXT_B, SEXT_H, ZEXT_H,
      ANDN, ORN, XNOR, ROR, RORI, ROL,
      REV8, ORC_B,
      CLMUL, CLMULH, CLMULR,
      BSET, BSETI, BCLR, BCLRI, BINV, BINVI, BEXT, BEXTI
    })
    return B_EXT;

  if (name inside
    {
      CSRRW, CSRRS, CSRRC,
      CSRRWI, CSRRSI, CSRRCI
    })
    return ZICSR_EXT;

  if (name inside
    {
      FENCE_I
    })
    return ZIFENCEI_EXT;

  if (name inside
    {
      C_LBU, C_LHU, C_LH,
      C_SB, C_SH, C_ZEXT_B,
      C_SEXT_B, C_ZEXT_H, C_SEXT_H,
      C_NOT, C_MUL
    })
    return ZCE_EXT;

endfunction : get_instr_ext


// Package level methods to map instruction to type
function instr_type_t get_instr_type(instr_name_t name);
  static instr_name_t itypes[] = '{
    LB, LH, LW, LBU, LHU,
    ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI,
    JALR
    };
  static instr_name_t rtypes[] = '{
    // I-ext
    ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND,
    // M-ext
    MUL, MULH, MULHSU, MULHU, DIV, DIVU, REM, REMU,
    // A-ext
    LR_W, SC_W, AMOSWAP_W, AMOADD_W, AMOXOR_W, AMOAND_W,
    AMOOR_W, AMOMIN_W, AMOMAX_W, AMOMINU_W, AMOMAXU_W
    };

  if (name inside {rtypes})
    return R_TYPE;

  if (name inside {itypes})
    return I_TYPE;

  if (name inside {C_ADDI,C_ADDI16SP,C_LWSP,C_LI,C_LUI,C_SLLI,C_NOP})
    return CI_TYPE;

  if (name inside {C_SWSP})
    return CSS_TYPE;

  if (name inside {C_MV, C_ADD, C_JR, C_JALR})
    return CR_TYPE;

  if (name inside {C_ADDI4SPN})
    return CIW_TYPE;

  if (name inside {C_LW})
    return CL_TYPE;

  if (name inside {C_SW})
    return CS_TYPE;

  if (name inside {C_AND, C_OR, C_XOR, C_SUB})
    return CA_TYPE;

  if (name inside {C_BEQZ, C_BNEZ, C_ANDI, C_SRAI, C_SRLI})
    return CB_TYPE;

  if (name inside {C_J, C_JAL})
    return CJ_TYPE;

  if (name inside {SB,SH,SW})
    return S_TYPE;

  if (name inside {BEQ,BNE,BLT,BGE,BLTU,BGEU})
    return B_TYPE;

  if (name inside {LUI,AUIPC})
    return U_TYPE;

  if (name inside {JAL})
    return J_TYPE;

  if (name inside {CSRRW,CSRRS,CSRRC})
    return CSR_TYPE;

  if (name inside {CSRRWI,CSRRSI,CSRRCI})
    return CSRI_TYPE;

  if (name inside {SH1ADD,SH2ADD,SH3ADD})
    return ZBA_TYPE;

  if (name inside {CLZ,CTZ,CPOP,MIN,MINU,MAX,MAXU,
                   SEXT_B,SEXT_H,ZEXT_H,ANDN,ORN,XNOR,
                   ROL,ROR,RORI,REV8,ORC_B})
    return ZBB_TYPE;

  if (name inside {CLMUL,CLMULH,CLMULR})
    return ZBC_TYPE;

  if (name inside {BSET,BSETI,BCLR,BCLRI,
                   BINV,BINVI,BEXT,BEXTI})
    return ZBS_TYPE;

  if (name inside {JAL})
    return J_TYPE;

  if (name inside {C_LBU,C_LHU,C_LH,
                   C_SB,C_SH,C_ZEXT_B,
                   C_SEXT_B,C_ZEXT_H,C_SEXT_H,
                   C_NOT, C_MUL})
    return ZCB_TYPE;

  return UNKNOWN_TYPE;
endfunction : get_instr_type

// Package level methods to map instruction to type
function instr_group_t get_instr_group(instr_name_t name, bit[DEFAULT_XLEN-1:0] mem_addr);

  if (name inside {UNKNOWN})
    return UNKNOWN_GROUP;

  if (name inside {LB,LH,LW,LBU,C_LBU,C_LHU,C_LH,LHU,C_LW,C_LWSP}) begin
    if (name inside {LH, LHU, C_LH, C_LHU} && mem_addr[0])
      return MISALIGN_LOAD_GROUP;

    if (name inside {LW, C_LW, C_LWSP} && mem_addr[1:0])
      return MISALIGN_LOAD_GROUP;

    return LOAD_GROUP;
  end

  if (name inside {SB,SH,SW,C_SB,C_SH,C_SW,C_SWSP}) begin
    if (name inside {SH,C_SH} && mem_addr[0])
      return MISALIGN_STORE_GROUP;

    if (name inside {SW, C_SW, C_SWSP} && mem_addr[1:0])
      return MISALIGN_STORE_GROUP;

    return STORE_GROUP;
  end

  if (name inside {SLL,SLLI,SRL,SRLI,SRA,SRAI,
                   ADD,ADDI,SUB,LUI,AUIPC,
                   XOR,XORI,OR,ORI,AND,ANDI,
                   SLT,SLTI,SLTU,SLTIU,
                   C_ADD,C_ADDI,C_ADDI16SP,
                   C_LI,C_LUI,C_MV,C_NOP,
                   C_XOR,C_SRLI,C_AND,C_ANDI,C_OR,
                   C_SUB,C_ADDI4SPN,C_SLLI,C_SRAI,
                   SH1ADD, SH2ADD, SH3ADD,
                   CLZ, CTZ, CPOP,
                   MIN, MAX, MINU, MAXU,
                   SEXT_B, SEXT_H, ZEXT_H,
                   C_SEXT_B, C_SEXT_H, C_ZEXT_B,
                   C_ZEXT_H, C_NOT,
                   ANDN, ORN, XNOR, ROR, RORI, ROL,
                   REV8, ORC_B,
                   CLMUL, CLMULH, CLMULR,
                   BSET, BSETI, BCLR, BCLRI, BINV, BINVI, BEXT, BEXTI})
    return ALU_GROUP;

  if (name inside {BEQ,BNE,BLT,BGE,BLTU,BGEU,
                   C_BEQZ,C_BNEZ})
    return BRANCH_GROUP;

  if (name inside {JAL,JALR,
                   C_J,C_JR,C_JAL,C_JALR})
    return JUMP_GROUP;

  if (name inside {FENCE})
    return FENCE_GROUP;

  if (name inside {FENCE_I})
    return FENCE_I_GROUP;

  if (name inside {ECALL, EBREAK, C_EBREAK})
    return ENV_GROUP;

  if (name inside {DRET, MRET})
    return RET_GROUP;

  if (name inside {WFI})
    return WFI_GROUP;

  if (name inside {CSRRW,CSRRS,CSRRC,CSRRWI,CSRRSI,CSRRCI})
    return CSR_GROUP;

  if (name inside {MUL,C_MUL})
    return MUL_GROUP;

  if (name inside {MULH,MULHSU,MULHU})
    return MULTI_MUL_GROUP;

  if (name inside {DIV,DIVU,REM,REMU})
    return DIV_GROUP;

  if (name inside {LR_W})
    return ALOAD_GROUP;

  if (name inside {SC_W})
    return ASTORE_GROUP;

  if (name inside {AMOSWAP_W,AMOADD_W,AMOXOR_W,AMOAND_W,
                   AMOOR_W,AMOMIN_W,AMOMAX_W,AMOMINU_W,AMOMAXU_W})
    return AMEM_GROUP;

  `uvm_fatal("ISACOV", $sformatf("Called get_instr_group with unmapped type: %s", name.name()));
endfunction : get_instr_group


`endif // __UVMA_ISACOV_TDEFS_SV__

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值