diff --git a/vendor/google_riscv-dv.lock.hjson b/vendor/google_riscv-dv.lock.hjson index 21ded156..bb3ff738 100644 --- a/vendor/google_riscv-dv.lock.hjson +++ b/vendor/google_riscv-dv.lock.hjson @@ -9,6 +9,6 @@ upstream: { url: https://github.com/google/riscv-dv - rev: 4583049cc2b3469ba9dea56b5e2d75809a89d8f3 + rev: 6344e951fef22b383551a85365ebb7d6aa74eb34 } } diff --git a/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv b/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv index ae18ede0..223728c0 100644 --- a/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv +++ b/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv @@ -386,10 +386,6 @@ class riscv_asm_program_gen extends uvm_object; // Init stack pointer to point to the end of the user stack str = {indent, $sformatf("la x%0d, %0suser_stack_end", cfg.sp, hart_prefix(hart))}; instr_stream.push_back(str); - if (support_pmp) begin - str = {indent, "j main"}; - instr_stream.push_back(str); - end if (cfg.enable_floating_point) begin init_floating_point_gpr(); end @@ -398,6 +394,10 @@ class riscv_asm_program_gen extends uvm_object; end core_is_initialized(); gen_dummy_csr_write(); // TODO add a way to disable xStatus read + if (support_pmp) begin + str = {indent, "j main"}; + instr_stream.push_back(str); + end endfunction // Setup MISA based on supported extensions diff --git a/vendor/google_riscv-dv/src/riscv_defines.svh b/vendor/google_riscv-dv/src/riscv_defines.svh index e423f76e..b584ff28 100644 --- a/vendor/google_riscv-dv/src/riscv_defines.svh +++ b/vendor/google_riscv-dv/src/riscv_defines.svh @@ -90,7 +90,7 @@ `INSTR_BODY(instr_n, instr_format, instr_category, instr_group, imm_tp) // Vector arithmetic instruction -`define DEFINE_VA_INSTR(instr_n, instr_format, instr_category, instr_group, vav = {}, imm_tp = IMM) \ +`define DEFINE_VA_INSTR(instr_n, instr_format, instr_category, instr_group, vav = {}, imm_tp = IMM)\ class riscv_``instr_n``_instr extends riscv_vector_instr; \ `VA_INSTR_BODY(instr_n, instr_format, instr_category, instr_group, vav, imm_tp) diff --git a/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv b/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv index 64984ffe..3dfba5dc 100644 --- a/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv +++ b/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv @@ -44,13 +44,16 @@ endclass class riscv_mem_access_stream extends riscv_directed_instr_stream; int max_data_page_id; + bit load_store_shared_memory; mem_region_t data_page[$]; `uvm_object_utils(riscv_mem_access_stream) `uvm_object_new function void pre_randomize(); - if(kernel_mode) begin + if (load_store_shared_memory) begin + data_page = cfg.amo_region; + end else if(kernel_mode) begin data_page = cfg.s_mem_region; end else begin data_page = cfg.mem_region; @@ -64,11 +67,14 @@ class riscv_mem_access_stream extends riscv_directed_instr_stream; la_instr = riscv_pseudo_instr::type_id::create("la_instr"); la_instr.pseudo_instr_name = LA; la_instr.rd = gpr; - if(kernel_mode) begin - la_instr.imm_str = $sformatf("%0s%s+%0d", + if (load_store_shared_memory) begin + la_instr.imm_str = $sformatf("%0s+%0d", cfg.amo_region[id].name, base); + + end else if(kernel_mode) begin + la_instr.imm_str = $sformatf("%0s%0s+%0d", hart_prefix(hart), cfg.s_mem_region[id].name, base); end else begin - la_instr.imm_str = $sformatf("%0s%s+%0d", + la_instr.imm_str = $sformatf("%0s%0s+%0d", hart_prefix(hart), cfg.mem_region[id].name, base); end instr_list.push_front(la_instr); @@ -187,8 +193,7 @@ class riscv_jump_instr extends riscv_directed_instr_stream; end jump.has_label = 1'b1; jump.label = "1"; - jump.comment = $sformatf("%s jump %0s -> %0s", - hart_prefix(hart), label, target_program_label); + jump.comment = $sformatf("jump %0s -> %0s", label, target_program_label); branch.imm_str = "1f"; branch.comment = "branch to jump instr"; branch.branch_assigned = 1'b1; diff --git a/vendor/google_riscv-dv/src/riscv_instr_cov_item.sv b/vendor/google_riscv-dv/src/riscv_instr_cov_item.sv index 703a966a..abcab925 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_cov_item.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_cov_item.sv @@ -23,8 +23,13 @@ class riscv_instr_cov_item extends riscv_instr; rand bit [XLEN-1:0] rs1_value; rand bit [XLEN-1:0] rs2_value; rand bit [XLEN-1:0] rd_value; + rand riscv_fpr_t fs1; + rand riscv_fpr_t fs2; + rand riscv_fpr_t fs3; + rand riscv_fpr_t fd; rand bit [XLEN-1:0] fs1_value; rand bit [XLEN-1:0] fs2_value; + rand bit [XLEN-1:0] fs3_value; rand bit [XLEN-1:0] fd_value; bit [31:0] binary; bit [XLEN-1:0] pc; @@ -37,8 +42,12 @@ class riscv_instr_cov_item extends riscv_instr; div_result_e div_result; operand_sign_e rs1_sign; operand_sign_e rs2_sign; + operand_sign_e fs1_sign; + operand_sign_e fs2_sign; + operand_sign_e fs3_sign; operand_sign_e imm_sign; operand_sign_e rd_sign; + operand_sign_e fd_sign; hazard_e gpr_hazard; hazard_e lsu_hazard; special_val_e rs1_special_val; @@ -59,6 +68,10 @@ class riscv_instr_cov_item extends riscv_instr; rs1_sign = get_operand_sign(rs1_value); rs2_sign = get_operand_sign(rs2_value); rd_sign = get_operand_sign(rd_value); + fs1_sign = get_operand_sign(fs1_value); + fs2_sign = get_operand_sign(fs2_value); + fs3_sign = get_operand_sign(fs2_value); + fd_sign = get_operand_sign(fd_value); imm_sign = get_imm_sign(imm); rs1_special_val = get_operand_special_val(rs1_value); rd_special_val = get_operand_special_val(rd_value); diff --git a/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv b/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv index 72fef81d..b0db34ed 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv @@ -216,6 +216,47 @@ `INSTR_CG_BEGIN(INSTR_NAME) \ cp_imm_sign : coverpoint instr.imm_sign; +// TODO, will handle special value later +// single-precision floating point special values coverpoint +`define FP_SPECIAL_VALUES_CP(VAR, NAME) \ + cp_fp_special_values_on_``NAME`` : coverpoint VAR { \ + bins infinity[] = {32'h7f80_0000, 32'hff80_0000}; \ + bins largest[] = {32'h7f7f_ffff, 32'hff7f_ffff}; \ + bins zeros[] = {32'h0000_0000, 32'h1000_0000}; \ + bins NaN[] = {32'h7fc0_0000, 32'h7f80_0000}; \ + } + +`define FP_R_INSTR_CG_BEGIN(INSTR_NAME) \ + `INSTR_CG_BEGIN(INSTR_NAME) \ + cp_fs1 : coverpoint instr.fs1; \ + cp_fs2 : coverpoint instr.fs2; \ + cp_fd : coverpoint instr.fd; \ + cp_fs1_sign : coverpoint instr.fs1_sign; \ + cp_fs2_sign : coverpoint instr.fs2_sign; \ + cp_fd_sign : coverpoint instr.fd_sign; \ + `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \ + +`define FP_R4_INSTR_CG_BEGIN(INSTR_NAME) \ + `INSTR_CG_BEGIN(INSTR_NAME) \ + cp_fs1 : coverpoint instr.fs1; \ + cp_fs2 : coverpoint instr.fs2; \ + cp_fs3 : coverpoint instr.fs3; \ + cp_fd : coverpoint instr.fd; \ + cp_fs1_sign : coverpoint instr.fs1_sign; \ + cp_fs2_sign : coverpoint instr.fs2_sign; \ + cp_fs3_sign : coverpoint instr.fs3_sign; \ + cp_fd_sign : coverpoint instr.fd_sign; \ + cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fs3_sign, cp_fd_sign; \ + `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \ + +`define FSQRT_INSTR_CG_BEGIN(INSTR_NAME) \ + `INSTR_CG_BEGIN(INSTR_NAME) \ + cp_fs1 : coverpoint instr.fs1; \ + cp_fd : coverpoint instr.fd; \ + cp_fs1_sign : coverpoint instr.fs1_sign; \ + cp_fd_sign : coverpoint instr.fd_sign; \ + `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \ + `define CG_END endgroup `define CG_SELECTOR_BEGIN(CG_ISA) \ @@ -446,6 +487,73 @@ class riscv_instr_cover_group; cp_ras : cross cp_rs1_link, cp_rd_link; `CG_END + // floating instructions + `INSTR_CG_BEGIN(flw) + cp_rs1 : coverpoint instr.rs1 { + `DV(ignore_bins zero = {ZERO};) + } + cp_fd : coverpoint instr.fd; + cp_imm_sign : coverpoint instr.imm_sign; + `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) + `DV(cp_lsu_hazard : coverpoint instr.lsu_hazard { + bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; + }) + `CG_END + + `INSTR_CG_BEGIN(fsw) + cp_rs1 : coverpoint instr.rs1 { + `DV(ignore_bins zero = {ZERO};) + } + cp_fs2 : coverpoint instr.fs2; + cp_imm_sign : coverpoint instr.imm_sign; + `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard { + bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; + }) + `DV(cp_lsu_hazard : coverpoint instr.lsu_hazard { + bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; + }) + `CG_END + + `FP_R_INSTR_CG_BEGIN(fadd_s) + cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fd_sign; + `CG_END + + `FP_R_INSTR_CG_BEGIN(fsub_s) + cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fd_sign; + `CG_END + + `FP_R_INSTR_CG_BEGIN(fmul_s) + cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign; + `CG_END + + `FP_R_INSTR_CG_BEGIN(fdiv_s) + cp_div_result: coverpoint instr.div_result; + cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign; + `CG_END + + `FSQRT_INSTR_CG_BEGIN(fsqrt_s) + `CG_END + + `FP_R_INSTR_CG_BEGIN(fmin_s) + cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign; + `CG_END + + `FP_R_INSTR_CG_BEGIN(fmax_s) + cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign; + `CG_END + + `FP_R4_INSTR_CG_BEGIN(fmadd_s) + `CG_END + + `FP_R4_INSTR_CG_BEGIN(fnmadd_s) + `CG_END + + `FP_R4_INSTR_CG_BEGIN(fmsub_s) + `CG_END + + `FP_R4_INSTR_CG_BEGIN(fnmsub_s) + `CG_END + // CSR instructions `CSR_INSTR_CG_BEGIN(csrrw) cp_rs1 : coverpoint instr.rs1; @@ -901,6 +1009,13 @@ class riscv_instr_cover_group; cp_mpp : coverpoint val[12:11]; endgroup + covergroup fcsr_cg with function sample(bit [XLEN-1:0] val); + cp_fflags : coverpoint val[4:0]; + cp_frm : coverpoint val[7:5] { + ignore_bins invalid = {3'b101, 3'b110}; + } + endgroup + `VECTOR_INCLUDE("riscv_instr_cover_group_inc_cg_add.sv") function new(riscv_instr_gen_config cfg); @@ -1089,6 +1204,22 @@ class riscv_instr_cover_group; c_addw_cg = new(); `CG_SELECTOR_END + `CG_SELECTOR_BEGIN(RV32F) + flw_cg = new(); + fsw_cg = new(); + fadd_s_cg = new(); + fsub_s_cg = new(); + fmul_s_cg = new(); + fdiv_s_cg = new(); + fsqrt_s_cg = new(); + fmin_s_cg = new(); + fmax_s_cg = new(); + fmadd_s_cg = new(); + fnmadd_s_cg = new(); + fmsub_s_cg = new(); + fnmsub_s_cg = new(); + `CG_SELECTOR_END + // Ignore the exception which cannot be covered when running with ISS if (iss_mode) begin int i; @@ -1111,6 +1242,7 @@ class riscv_instr_cover_group; mcause_exception_cg = new(); mcause_interrupt_cg = new(); mstatus_m_cg = new(); + fcsr_cg = new(); end if (!cfg.disable_compressed_instr) begin mepc_alignment_cg = new(); @@ -1242,6 +1374,19 @@ class riscv_instr_cover_group; C_SUBW : `SAMPLE(c_subw_cg, instr) C_ADDW : `SAMPLE(c_addw_cg, instr) C_ADDIW : `SAMPLE(c_addiw_cg, instr) + FLW : `SAMPLE(flw_cg, instr) + FSW : `SAMPLE(fsw_cg, instr) + FADD_S : `SAMPLE(fadd_s_cg, instr) + FSUB_S : `SAMPLE(fsub_s_cg, instr) + FMUL_S : `SAMPLE(fmul_s_cg, instr) + FDIV_S : `SAMPLE(fdiv_s_cg, instr) + FSQRT_S : `SAMPLE(fsqrt_s_cg, instr) + FMIN_S : `SAMPLE(fmin_s_cg, instr) + FMAX_S : `SAMPLE(fmax_s_cg, instr) + FMADD_S : `SAMPLE(fmadd_s_cg, instr) + FNMADD_S : `SAMPLE(fnmadd_s_cg, instr) + FMSUB_S : `SAMPLE(fmsub_s_cg, instr) + FNMSUB_S : `SAMPLE(fnmsub_s_cg, instr) `VECTOR_INCLUDE("riscv_instr_cover_group_inc_cg_sample.sv") default: begin if (instr.group == RV32I) begin @@ -1280,6 +1425,9 @@ class riscv_instr_cover_group; MSTATUS: begin `SAMPLE(mstatus_m_cg, instr.rd_value); end + FCSR: begin + `SAMPLE(fcsr_cg, instr.rd_value); + end endcase end if (instr_cnt > 1) begin diff --git a/vendor/google_riscv-dv/src/riscv_instr_pkg.sv b/vendor/google_riscv-dv/src/riscv_instr_pkg.sv index 3a06a714..e2556daa 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_pkg.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_pkg.sv @@ -511,8 +511,8 @@ package riscv_instr_pkg; } riscv_reg_t; typedef enum bit [4:0] { - F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, - F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31 + FT0, FT1, FT2, FT3, FT4, FT5, FT6, FT7, FS0, FS1, FA0, FA1, FA2, FA3, FA4, FA5, + FA6, FA7, FS2, FS3, FS4, FS5, FS6, FS7, FS8, FS9, FS10, FS11, FT8, FT9, FT10, FT11 } riscv_fpr_t; typedef enum bit [4:0] { diff --git a/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv b/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv index 235178ab..94c771e0 100644 --- a/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv +++ b/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv @@ -42,7 +42,7 @@ class riscv_load_store_base_instr_stream extends riscv_mem_access_stream; constraint sp_rnd_order_c { solve use_sp_as_rs1 before rs1_reg; } - + constraint sp_c { use_sp_as_rs1 dist {1 := 1, 0 := 2}; if (use_sp_as_rs1) { @@ -245,6 +245,20 @@ class riscv_load_store_stress_instr_stream extends riscv_load_store_base_instr_s endclass + +// Back to back load/store instructions +class riscv_load_store_shared_mem_stream extends riscv_load_store_stress_instr_stream; + + `uvm_object_utils(riscv_load_store_shared_mem_stream) + `uvm_object_new + + function void pre_randomize(); + load_store_shared_memory = 1; + super.pre_randomize(); + endfunction + +endclass + // Random load/store sequence // A random mix of load/store instructions and other instructions class riscv_load_store_rand_instr_stream extends riscv_load_store_base_instr_stream; @@ -374,6 +388,7 @@ class riscv_multi_page_load_store_instr_stream extends riscv_mem_access_stream; load_store_instr_stream[i].min_instr_cnt = 5; load_store_instr_stream[i].max_instr_cnt = 10; load_store_instr_stream[i].cfg = cfg; + load_store_instr_stream[i].hart = hart; load_store_instr_stream[i].sp_c.constraint_mode(0); // Make sure each load/store sequence doesn't override the rs1 of other sequences. foreach(rs1_reg[j]) begin diff --git a/vendor/google_riscv-dv/target/multi_harts/testlist.yaml b/vendor/google_riscv-dv/target/multi_harts/testlist.yaml index c491ae7c..d4ab0bd1 100644 --- a/vendor/google_riscv-dv/target/multi_harts/testlist.yaml +++ b/vendor/google_riscv-dv/target/multi_harts/testlist.yaml @@ -54,6 +54,18 @@ rtl_test: core_base_test +- test: riscv_load_store_shared_mem_test + description: > + Multi-harts load/store from shared memory regions + iterations: 2 + gen_test: riscv_rand_instr_test + gen_opts: > + +instr_cnt=5000 + +num_of_sub_program=5 + +directed_instr_0=riscv_load_store_shared_mem_stream,10 + rtl_test: core_base_test + + - test: riscv_amo_test description: > RISC-V atomic instruction extension test diff --git a/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv b/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv index cfbb3184..668df7e2 100644 --- a/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv +++ b/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv @@ -3,6 +3,7 @@ class riscv_instr_cov_test extends uvm_test; typedef uvm_enum_wrapper#(riscv_instr_name_t) instr_enum; typedef uvm_enum_wrapper#(riscv_reg_t) gpr_enum; + typedef uvm_enum_wrapper#(riscv_fpr_t) fpr_enum; typedef uvm_enum_wrapper#(privileged_reg_t) preg_enum; riscv_instr_gen_config cfg; @@ -136,7 +137,8 @@ class riscv_instr_cov_test extends uvm_test; if (instr_enum::from_name(process_instr_name(trace["instr"]), instr_name)) begin if (riscv_instr::instr_template.exists(instr_name)) begin instr.copy(riscv_instr::instr_template[instr_name]); - if (instr.group inside {RV32I, RV32M, RV32C, RV64I, RV64M, RV64C}) begin + if (instr.group inside {RV32I, RV32M, RV32C, RV64I, RV64M, RV64C, + RV32F}) begin assign_trace_info_to_instr(instr); end instr.pre_sample(); @@ -169,6 +171,8 @@ class riscv_instr_cov_test extends uvm_test; get_val(operands[1], instr.imm); end I_FORMAT: begin + // TODO, support I_FORMAT floating point later + if (instr.group == RV32F) return; `DV_CHECK_FATAL(operands.size() == 3, trace["instr_str"]) if(instr.category == LOAD) begin // load rd, imm(rs1) @@ -194,8 +198,10 @@ class riscv_instr_cov_test extends uvm_test; `DV_CHECK_FATAL(operands.size() == 3) if(instr.category == STORE) begin // sw rs2,imm(rs1) - instr.rs2 = get_gpr(operands[0]); - instr.rs2_value = get_gpr_state(operands[0]); + update_instr_reg_by_abi_name(operands[0], // FSW rs2 is fp + instr.rs2, instr.rs2_value, + instr.fs2, instr.fs2_value); + instr.rs1 = get_gpr(operands[2]); instr.rs1_value = get_gpr_state(operands[2]); get_val(operands[1], instr.imm); @@ -209,7 +215,8 @@ class riscv_instr_cov_test extends uvm_test; end end R_FORMAT: begin - `DV_CHECK_FATAL(operands.size() == 3) + if (!instr.instr_name inside {FCLASS_S, FCLASS_D}) `DV_CHECK_FATAL(operands.size() == 3) + else `DV_CHECK_FATAL(operands.size() == 2) if(instr.category == CSR) begin // csrrw rd, csr, rs1 if (preg_enum::from_name(operands[1].toupper(), preg)) begin @@ -219,6 +226,16 @@ class riscv_instr_cov_test extends uvm_test; end instr.rs1 = get_gpr(operands[2]); instr.rs1_value = get_gpr_state(operands[2]); + end + else if (instr.group inside {RV32F, RV64F, RV32D, RV64D}) begin + // fs1 + instr.fs1 = get_fpr(operands[1]); + instr.fs1_value = get_gpr_state(operands[1]); + // fs2 + if (!instr.instr_name inside {FCLASS_S, FCLASS_D}) begin + instr.fs2 = get_fpr(operands[2]); + instr.fs2_value = get_gpr_state(operands[2]); + end end else begin // add rd, rs1, rs2 instr.rs1 = get_gpr(operands[1]); @@ -227,6 +244,15 @@ class riscv_instr_cov_test extends uvm_test; instr.rs2_value = get_gpr_state(operands[2]); end end + R4_FORMAT: begin + `DV_CHECK_FATAL(operands.size() == 4) + instr.fs1 = get_fpr(operands[1]); + instr.fs1_value = get_gpr_state(operands[1]); + instr.fs2 = get_fpr(operands[2]); + instr.fs2_value = get_gpr_state(operands[2]); + instr.fs3 = get_fpr(operands[3]); + instr.fs3_value = get_gpr_state(operands[3]); + end CI_FORMAT, CIW_FORMAT: begin if (instr.instr_name == C_ADDI16SP) begin get_val(operands[1], instr.imm); @@ -303,8 +329,7 @@ class riscv_instr_cov_test extends uvm_test; `uvm_fatal(`gfn, $sformatf("Illegal gpr update format: %0s", gpr_update[i])) end get_val(pair[1], gpr_state[pair[0]], .hex(1)); - instr.rd = get_gpr(pair[0]); - instr.rd_value = get_gpr_state(pair[0]); + update_instr_reg_by_abi_name(pair[0], instr.rd, instr.rd_value, instr.fd, instr.fd_value); end endfunction : assign_trace_info_to_instr @@ -315,6 +340,13 @@ class riscv_instr_cov_test extends uvm_test; end endfunction : get_gpr + function riscv_fpr_t get_fpr(input string str); + str = str.toupper(); + if (!fpr_enum::from_name(str, get_fpr)) begin + `uvm_fatal(`gfn, $sformatf("Cannot convert %0s to FPR", str)) + end + endfunction : get_fpr + function bit [XLEN-1:0] get_gpr_state(string name); if (name inside {"zero", "x0"}) begin return 0; @@ -347,6 +379,26 @@ class riscv_instr_cov_test extends uvm_test; `uvm_info(`gfn, $sformatf("imm:%0s -> 0x%0x/%0d", str, val, $signed(val)), UVM_FULL) endfunction : get_val + function bit is_fp_reg(input string str); + riscv_fpr_t tmp; + str = str.toupper(); + return fpr_enum::from_name(str, tmp); + endfunction : is_fp_reg + + function void update_instr_reg_by_abi_name(string abi_name, + ref riscv_reg_t rs, + ref bit [XLEN-1:0] rs_value, + ref riscv_fpr_t fs, + ref bit [XLEN-1:0] fs_value); + if (is_fp_reg(abi_name)) begin + fs = get_fpr(abi_name); + fs_value = get_gpr_state(abi_name); + end else begin + rs = get_gpr(abi_name); + rs_value = get_gpr_state(abi_name); + end + endfunction : update_instr_reg_by_abi_name + function string process_instr_name(string instr_name); instr_name = instr_name.toupper(); foreach (instr_name[i]) begin