mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 13:07:46 -04:00
Update google_riscv-dv to google/riscv-dv@6344e95 (#673)
Update code from upstream repository https://github.com/google/riscv- dv to revision 6344e951fef22b383551a85365ebb7d6aa74eb34 * fix incorrect initialization routine (Udi Jonnalagadda) * Add coverage for single precision floating (Part 1) (google/riscv- dv#488) (weicaiyang) * Add load/store shared memory test (google/riscv-dv#508) (taoliug) * Fix hart id assignment for load/store instruction stream (google/riscv-dv#507) (taoliug) Signed-off-by: Udi <udij@google.com>
This commit is contained in:
parent
753e76549d
commit
19173290e0
10 changed files with 266 additions and 21 deletions
2
vendor/google_riscv-dv.lock.hjson
vendored
2
vendor/google_riscv-dv.lock.hjson
vendored
|
@ -9,6 +9,6 @@
|
|||
upstream:
|
||||
{
|
||||
url: https://github.com/google/riscv-dv
|
||||
rev: 4583049cc2b3469ba9dea56b5e2d75809a89d8f3
|
||||
rev: 6344e951fef22b383551a85365ebb7d6aa74eb34
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
2
vendor/google_riscv-dv/src/riscv_defines.svh
vendored
2
vendor/google_riscv-dv/src/riscv_defines.svh
vendored
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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] {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue