<commit_before>/*
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, 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
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */

class riscv_instr extends uvm_object;

  // All derived instructions
  static bit                 instr_registry[riscv_instr_name_t];

  // Instruction list
  static riscv_instr_name_t  instr_names[$];

  // Categorized instruction list
  static riscv_instr_name_t  instr_group[riscv_instr_group_t][$];
  static riscv_instr_name_t  instr_category[riscv_instr_category_t][$];
  static riscv_instr_name_t  basic_instr[$];
  static riscv_instr         instr_template[riscv_instr_name_t];

  // Privileged CSR filter
  static privileged_reg_t    exclude_reg[];
  static privileged_reg_t    include_reg[];

  // Instruction attributes
  riscv_instr_group_t        group;
  riscv_instr_format_t       format;
  riscv_instr_category_t     category;
  riscv_instr_name_t         instr_name;
  imm_t                      imm_type;
  bit [4:0]                  imm_len;

  // Operands
  rand bit [11:0]            csr;
  rand riscv_reg_t           rs2;
  rand riscv_reg_t           rs1;
  rand riscv_reg_t           rd;
  rand bit [31:0]            imm;

  // Helper fields
  bit [31:0]                 imm_mask = 32'hFFFF_FFFF;
  bit                        is_branch_target;
  bit                        has_label = 1'b1;
  bit                        atomic = 0;
  bit                        branch_assigned;
  bit                        process_load_store = 1'b1;
  bit                        is_compressed;
  bit                        is_illegal_instr;
  bit                        is_hint_instr;
  bit                        is_floating_point;
  string                     imm_str;
  string                     comment;
  string                     label;
  bit                        is_local_numeric_label;
  int                        idx = -1;
  bit                        has_rs1 = 1'b1;
  bit                        has_rs2 = 1'b1;
  bit                        has_rd = 1'b1;
  bit                        has_imm = 1'b1;

  constraint imm_c {
    if (instr_name inside {SLLI, SRLI, SRAI, SLLIW, SRLIW, SRAIW}) {
      imm[11:5] == 0;
    }
  }

  constraint csr_c {
    if (category == CSR) {
      if (include_reg.size() > 0) {
        csr inside {include_reg};
      }
      if (exclude_reg.size() > 0) {
        !(csr inside {exclude_reg});
      }
    }
  }

  `uvm_object_utils(riscv_instr)
  `uvm_object_new

  static function bit register(riscv_instr_name_t instr_name);
    `uvm_info("riscv_instr", $sformatf("Registering %0s", instr_name.name()), UVM_LOW)
    instr_registry[instr_name] = 1;
    return 1;
  endfunction : register

  // Create the list of instructions based on the supported ISA extensions and configuration of the
  // generator.
  static function void create_instr_list(riscv_instr_gen_config cfg);
    instr_names.delete();
    instr_group.delete();
    instr_category.delete();
    foreach (instr_registry[instr_name]) begin
      riscv_instr instr_inst;
      instr_inst = create_instr(instr_name);
      instr_template[instr_name] = instr_inst;
      // C_JAL is RV32C only instruction
      if ((XLEN != 32) && (instr_name == C_JAL)) continue;
      if ((SP inside {cfg.reserved_regs}) && (instr_name inside {C_ADDI16SP})) begin
        continue;
      end
      if (!cfg.enable_sfence && instr_name == SFENCE_VMA) continue;
      if (cfg.no_fence && (instr_name inside {FENCE, FENCE_I, SFENCE_VMA})) continue;
      // TODO: gcc compile issue, support c.addi4spn later
      if (instr_name == C_ADDI4SPN) continue;
      if ((instr_inst.group inside {supported_isa}) &&
          !(cfg.disable_compressed_instr &&
            (instr_inst.group inside {RV32C, RV64C, RV32DC, RV32FC, RV128C})) &&
          !(!cfg.enable_floating_point &&
            (instr_inst.group inside {RV32F, RV64F, RV32D, RV64D}))) begin
        instr_category[instr_inst.category].push_back(instr_name);
        instr_group[instr_inst.group].push_back(instr_name);
        instr_names.push_back(instr_name);
      end
    end
    build_basic_instruction_list(cfg);
    create_csr_filter(cfg);
  endfunction : create_instr_list

  static function void create_csr_filter(riscv_instr_gen_config cfg);
    include_reg.delete();
    exclude_reg.delete();
    if (cfg.enable_illegal_csr_instruction) begin
      exclude_reg = implemented_csr;
    end else if (cfg.enable_access_invalid_csr_level) begin
      include_reg = cfg.invalid_priv_mode_csrs;
    end else begin
      // Use scratch register to avoid the side effect of modifying other privileged mode CSR.
      if (cfg.init_privileged_mode == MACHINE_MODE) begin
        include_reg = {MSCRATCH};
      end else if (cfg.init_privileged_mode == SUPERVISOR_MODE) begin
        include_reg = {SSCRATCH};
      end else begin
        include_reg = {USCRATCH};
      end
    end
  endfunction : create_csr_filter

  static function riscv_instr create_instr(riscv_instr_name_t instr_name);
    uvm_object obj;
    riscv_instr inst;
    string instr_class_name;
    uvm_coreservice_t coreservice = uvm_coreservice_t::get();
    uvm_factory factory = coreservice.get_factory();
    instr_class_name = {"riscv_", instr_name.name(), "_instr"};
    obj = factory.create_object_by_name(instr_class_name, "riscv_instr", instr_class_name);
    if (obj == null) begin
      `uvm_fatal("riscv_instr", $sformatf("Failed to create instr: %0s", instr_class_name))
    end
    if (!$cast(inst, obj)) begin
      `uvm_fatal("riscv_instr", $sformatf("Failed to cast instr: %0s", instr_class_name))
    end
    return inst;
  endfunction : create_instr

  static function void build_basic_instruction_list(riscv_instr_gen_config cfg);
    basic_instr = {instr_category[SHIFT], instr_category[ARITHMETIC],
                   instr_category[LOGICAL], instr_category[COMPARE]};
    if (!cfg.no_ebreak) begin
      basic_instr = {basic_instr, EBREAK};
      foreach (riscv_instr_pkg::supported_isa[i]) begin
        if (RV32C inside {riscv_instr_pkg::supported_isa[i]}) begin
          basic_instr = {basic_instr, C_EBREAK};
          break;
        end
      end
    end
    if (cfg.no_dret == 0) begin
      basic_instr = {basic_instr, DRET};
    end
    if (cfg.no_fence == 0) begin
      basic_instr = {basic_instr, instr_category[SYNCH]};
    end
    if ((cfg.no_csr_instr == 0) && (cfg.init_privileged_mode == MACHINE_MODE)) begin
      basic_instr = {basic_instr, instr_category[CSR]};
    end
    if (cfg.no_wfi == 0) begin
      basic_instr = {basic_instr, WFI};
    end
  endfunction : build_basic_instruction_list

  static function riscv_instr get_rand_instr(riscv_instr instr_h = null,
                                             riscv_instr_name_t include_instr[] = {},
                                             riscv_instr_name_t exclude_instr[] = {},
                                             riscv_instr_category_t include_category[] = {},
                                             riscv_instr_category_t exclude_category[] = {},
                                             riscv_instr_group_t include_group[] = {},
                                             riscv_instr_group_t exclude_group[] = {});
     int unsigned idx;
     riscv_instr_name_t name;
     riscv_instr_name_t allowed_instr[];
     riscv_instr_name_t disallowed_instr[];
     riscv_instr_category_t allowed_categories[];
     foreach (include_category[i]) begin<commit_msg>Attempt to fix qrun issue (#383)<commit_after>/*
 * Copyright 2019 Google LLC
 *
 * Licensed under the Apache License, 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
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */

class riscv_instr extends uvm_object;

  // All derived instructions
  static bit                 instr_registry[riscv_instr_name_t];

  // Instruction list
  static riscv_instr_name_t  instr_names[$];

  // Categorized instruction list
  static riscv_instr_name_t  instr_group[riscv_instr_group_t][$];
  static riscv_instr_name_t  instr_category[riscv_instr_category_t][$];
  static riscv_instr_name_t  basic_instr[$];
  static riscv_instr         instr_template[riscv_instr_name_t];

  // Privileged CSR filter
  static privileged_reg_t    exclude_reg[];
  static privileged_reg_t    include_reg[];

  // Instruction attributes
  riscv_instr_group_t        group;
  riscv_instr_format_t       format;
  riscv_instr_category_t     category;
  riscv_instr_name_t         instr_name;
  imm_t                      imm_type;
  bit [4:0]                  imm_len;

  // Operands
  rand bit [11:0]            csr;
  rand riscv_reg_t           rs2;
  rand riscv_reg_t           rs1;
  rand riscv_reg_t           rd;
  rand bit [31:0]            imm;

  // Helper fields
  bit [31:0]                 imm_mask = 32'hFFFF_FFFF;
  bit                        is_branch_target;
  bit                        has_label = 1'b1;
  bit                        atomic = 0;
  bit                        branch_assigned;
  bit                        process_load_store = 1'b1;
  bit                        is_compressed;
  bit                        is_illegal_instr;
  bit                        is_hint_instr;
  bit                        is_floating_point;
  string                     imm_str;
  string                     comment;
  string                     label;
  bit                        is_local_numeric_label;
  int                        idx = -1;
  bit                        has_rs1 = 1'b1;
  bit                        has_rs2 = 1'b1;
  bit                        has_rd = 1'b1;
  bit                        has_imm = 1'b1;

  constraint imm_c {
    if (instr_name inside {SLLI, SRLI, SRAI, SLLIW, SRLIW, SRAIW}) {
      imm[11:5] == 0;
    }
  }

  constraint csr_c {
    if (category == CSR) {
      if (include_reg.size() > 0) {
        csr inside {include_reg};
      }
      if (exclude_reg.size() > 0) {
        !(csr inside {exclude_reg});
      }
    }
  }

  `uvm_object_utils(riscv_instr)
  `uvm_object_new

  static function bit register(riscv_instr_name_t instr_name);
    `uvm_info("riscv_instr", $sformatf("Registering %0s", instr_name.name()), UVM_LOW)
    instr_registry[instr_name] = 1;
    return 1;
  endfunction : register

  // Create the list of instructions based on the supported ISA extensions and configuration of the
  // generator.
  static function void create_instr_list(riscv_instr_gen_config cfg);
    instr_names.delete();
    instr_group.delete();
    instr_category.delete();
    foreach (instr_registry[instr_name]) begin
      riscv_instr instr_inst;
      instr_inst = create_instr(instr_name);
      instr_template[instr_name] = instr_inst;
      // C_JAL is RV32C only instruction
      if ((XLEN != 32) && (instr_name == C_JAL)) continue;
      if ((SP inside {cfg.reserved_regs}) && (instr_name inside {C_ADDI16SP})) begin
        continue;
      end
      if (!cfg.enable_sfence && instr_name == SFENCE_VMA) continue;
      if (cfg.no_fence && (instr_name inside {FENCE, FENCE_I, SFENCE_VMA})) continue;
      // TODO: gcc compile issue, support c.addi4spn later
      if (instr_name == C_ADDI4SPN) continue;
      if ((instr_inst.group inside {supported_isa}) &&
          !(cfg.disable_compressed_instr &&
            (instr_inst.group inside {RV32C, RV64C, RV32DC, RV32FC, RV128C})) &&
          !(!cfg.enable_floating_point &&
            (instr_inst.group inside {RV32F, RV64F, RV32D, RV64D}))) begin
        instr_category[instr_inst.category].push_back(instr_name);
        instr_group[instr_inst.group].push_back(instr_name);
        instr_names.push_back(instr_name);
      end
    end
    build_basic_instruction_list(cfg);
    create_csr_filter(cfg);
  endfunction : create_instr_list

  static function void create_csr_filter(riscv_instr_gen_config cfg);
    include_reg.delete();
    exclude_reg.delete();
    if (cfg.enable_illegal_csr_instruction) begin
      exclude_reg = implemented_csr;
    end else if (cfg.enable_access_invalid_csr_level) begin
      include_reg = cfg.invalid_priv_mode_csrs;
    end else begin
      // Use scratch register to avoid the side effect of modifying other privileged mode CSR.
      if (cfg.init_privileged_mode == MACHINE_MODE) begin
        include_reg = {MSCRATCH};
      end else if (cfg.init_privileged_mode == SUPERVISOR_MODE) begin
        include_reg = {SSCRATCH};
      end else begin
        include_reg = {USCRATCH};
      end
    end
  endfunction : create_csr_filter

  static function riscv_instr create_instr(riscv_instr_name_t instr_name);
    uvm_object obj;
    riscv_instr inst;
    string instr_class_name;
    uvm_coreservice_t coreservice = uvm_coreservice_t::get();
    uvm_factory factory = coreservice.get_factory();
    instr_class_name = {"riscv_", instr_name.name(), "_instr"};
    obj = factory.create_object_by_name(instr_class_name, "riscv_instr", instr_class_name);
    if (obj == null) begin
      `uvm_fatal("riscv_instr", $sformatf("Failed to create instr: %0s", instr_class_name))
    end
    if (!$cast(inst, obj)) begin
      `uvm_fatal("riscv_instr", $sformatf("Failed to cast instr: %0s", instr_class_name))
    end
    return inst;
  endfunction : create_instr

  static function void build_basic_instruction_list(riscv_instr_gen_config cfg);
    basic_instr = {instr_category[SHIFT], instr_category[ARITHMETIC],
                   instr_category[LOGICAL], instr_category[COMPARE]};
    if (!cfg.no_ebreak) begin
      basic_instr = {basic_instr, EBREAK};
      foreach (riscv_instr_pkg::supported_isa[i]) begin
        if (RV32C inside {riscv_instr_pkg::supported_isa[i]}) begin
          basic_instr = {basic_instr, C_EBREAK};
          break;
        end
      end
    end
    if (cfg.no_dret == 0) begin
      basic_instr = {basic_instr, DRET};
    end
    if (cfg.no_fence == 0) begin
      basic_instr = {basic_instr, instr_category[SYNCH]};
    end
    if ((cfg.no_csr_instr == 0) && (cfg.init_privileged_mode == MACHINE_MODE)) begin
      basic_instr = {basic_instr, instr_category[CSR]};
    end
    if (cfg.no_wfi == 0) begin
      basic_instr = {basic_instr, WFI};
    end
  endfunction : build_basic_instruction_list

  static function riscv_instr get_rand_instr(riscv_instr instr_h = null,
                                             riscv_instr_name_t include_instr[$] = {},
                                             riscv_instr_name_t exclude_instr[$] = {},
                                             riscv_instr_category_t include_category[$] = {},
                                             riscv_instr_category_t exclude_category[$] = {},
                                             riscv_instr_group_t include_group[$] = {},
                                             riscv_instr_group_t exclude_group[$] = {});
     int unsigned idx;
     riscv_instr_name_t name;
     riscv_instr_name_t allowed_instr[];
     riscv_instr_name_t disallowed_instr[];
     riscv_instr_category_t allowed_categories[];
     foreach (include_category[i]) begin
{'fraction_non_alphanumeric': 0.08566025843050741, 'fraction_numerical': 0.010652379451623069, 'mean_word_length': 2.39017094017094, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3182414', 'n_tokens_mistral': 5069, 'n_tokens_neox': 4947, 'n_words': 1146}