From 1e052a13e72974c1ef654516fe07f3db14f96665 Mon Sep 17 00:00:00 2001 From: dd-baoshan Date: Thu, 6 Jun 2024 10:17:54 +0800 Subject: [PATCH 1/2] Fix issue found in random tests Signed-off-by: dd-baoshan --- .../instr_lib/cv32e40p_instr_for_func_cvg_lib.sv | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_instr_for_func_cvg_lib.sv b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_instr_for_func_cvg_lib.sv index 7880da732a..6f23c5b197 100644 --- a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_instr_for_func_cvg_lib.sv +++ b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_instr_for_func_cvg_lib.sv @@ -207,14 +207,15 @@ class cv32e40p_xpulp_single_hwloop_stream_directed extends cv32e40p_xpulp_hwloop } constraint no_imm_hwloop_setup_instr_c { - use_loop_counti_inst[0] == 0; - use_loop_counti_inst[1] == 0; - use_loop_setupi_inst[0] == 0; - use_loop_setupi_inst[1] == 0; + foreach (use_loop_counti_inst[i]) { + use_loop_counti_inst[i] == 0; + use_loop_setupi_inst[i] == 0; + } } constraint num_hwloop_instr_c { solve use_loop_endi_inst before num_hwloop_instr; + solve num_hwloop_instr before num_fill_instr_loop_ctrl_to_loop_start; foreach (num_hwloop_instr[i]) { // the max setting of Uimm[11:0] is 4092 however the the hwloop start label is not immediately following after cv.endi, // there is randomize numberof instr inserted between cv.endi and hwloop start label we need to keep some buffer from @@ -224,7 +225,11 @@ class cv32e40p_xpulp_single_hwloop_stream_directed extends cv32e40p_xpulp_hwloop } else { num_hwloop_instr[i] dist { 3 := 1, 3074 := 5, 4092 := 1 }; } - num_fill_instr_loop_ctrl_to_loop_start[i] inside {[0:7]}; + if (num_hwloop_instr[i] > 4080) { + num_fill_instr_loop_ctrl_to_loop_start[i] == 0; + } else { + num_fill_instr_loop_ctrl_to_loop_start[i] inside {[0:7]}; + } } num_fill_instr_in_loop1_till_loop0_setup == 0; } From f04d58a090b05e4f20e678dad769cc2a849cefff Mon Sep 17 00:00:00 2001 From: dd-baoshan Date: Thu, 6 Jun 2024 11:18:06 +0800 Subject: [PATCH 2/2] Improve fregs init function and add error message for immediate assertions Signed-off-by: dd-baoshan --- .../instr_lib/cv32e40p_float_instr_lib.sv | 59 ++++++++++--------- .../cv32e40p_float_instr_lib_defines.sv | 7 ++- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib.sv b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib.sv index 9188d208a6..148935b514 100644 --- a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib.sv +++ b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib.sv @@ -75,6 +75,8 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; logic [31:0] csr_rm = $urandom_range(0,4); logic [31:0] csr_mstatus_fs = 0; // for clr_crs_fflags usage - end + + riscv_reg_t xreg_for_set_fpr = ZERO; rand int unsigned num_of_instr_per_stream; rand riscv_reg_t avail_gp_regs[][]; // regs for extension zfinx and f @@ -389,28 +391,29 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; virtual function void initialize_regs(); // set random value on all gpr/fpr registers prior directed stream // random fp value with mantissa not zeroes - if (init_gpr) begin : SET_GPR_RAND_VALUE - logic [31:0] i_imm; - for (int i=1; i<32; i++) begin - riscv_reg_t i_gpr = riscv_reg_t'(i); - // if (i_gpr inside {cfg.reserved_regs}) continue; - if (i == int'(cfg.sp)) continue; // do not alter stack pointer - if (i == int'(cfg.tp)) continue; // do not alter thread pointer - if (cfg.gen_debug_section) begin - if (i == int'(cfg_cv32e40p.dp)) continue; // do not alter debug pointer - end + logic [31:0] i_imm; + for (int i=1; i<32; i++) begin + riscv_reg_t i_gpr = riscv_reg_t'(i); + // if (i_gpr inside {cfg.reserved_regs}) continue; + if (i == int'(cfg.sp)) continue; // do not alter stack pointer + if (i == int'(cfg.tp)) continue; // do not alter thread pointer + if (cfg.gen_debug_section) begin + if (i == int'(cfg_cv32e40p.dp)) continue; // do not alter debug pointer + end + if (init_gpr) begin : SET_GPR_RAND_VALUE rand_fp_val(i_imm); `SET_GPR_VALUE(i_gpr,i_imm); end + if (xreg_for_set_fpr == ZERO) xreg_for_set_fpr = i_gpr; end - if (init_fpr) begin : SET_FPR_RAND_VALUE - logic [31:0] i_imm; - for (int i=0; i<32; i++) begin - riscv_fpr_t i_fpr = riscv_fpr_t'(i); + for (int i=0; i<32; i++) begin + riscv_fpr_t i_fpr = riscv_fpr_t'(i); + if (init_fpr) begin : SET_FPR_RAND_VALUE rand_fp_val(i_imm); - `SET_FPR_VALUE(i_fpr,i_imm); + `SET_FPR_VALUE(i_fpr,i_imm,xreg_for_set_fpr); end end + set_reserved_sp_addr(); set_csr_fm(gp_reg_scratch); endfunction : initialize_regs @@ -426,9 +429,9 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; bit select_fp_instr, include_fpc, rand_status; rand_status = std::randomize(select_fp_instr) with {select_fp_instr dist {0:=1, 1:=1};}; - assert(rand_status); + assert(rand_status) else begin `uvm_error(_header, $sformatf("assertion error")); end rand_status = std::randomize(include_fpc) with {include_fpc dist {0:=3, 1:=1};}; // less weight on fpc - assert(rand_status); + assert(rand_status) else begin `uvm_error(_header, $sformatf("assertion error")); end if (!use_same_instr_per_stream) include_instr.delete(); include_group.delete(); @@ -492,7 +495,7 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; exclude_instr = new[exclude_instr.size()+1] ({exclude_instr, prev_instr.instr_name}); end if (use_same_instr_per_stream && prev_instr != null) begin - assert (use_fp_only_for_directed_instr && use_same_instr_per_stream); + assert (use_fp_only_for_directed_instr && use_same_instr_per_stream) else begin `uvm_error(_header, $sformatf("assertion error")); end include_instr = new[1] ({prev_instr.instr_name}); end endfunction: update_next_instr_arg_list @@ -1025,7 +1028,7 @@ class cv32e40p_float_zfinx_base_instr_stream extends cv32e40p_base_instr_stream; logic [11:0] csr=12'h000, int idx=0 ); riscv_instr instr; - assert(instr_name != INVALID_INSTR); + assert(instr_name != INVALID_INSTR) else begin `uvm_error(_header, $sformatf("assertion error")); end instr = new riscv_instr::get_rand_instr( .include_instr({instr_name}) ); @@ -1298,8 +1301,8 @@ class cv32e40p_constraint_mc_fp_instr_stream extends cv32e40p_float_zfinx_base_i int rand_mc_latency = $urandom_range(0,mc_instr_latency); int loop_cnt = 0; - assert(!(instr == null && instr_zfinx == null && instr_f == null)); - assert(rand_mc_latency >= 0); + assert(!(instr == null && instr_zfinx == null && instr_f == null)) else begin `uvm_error(_header, $sformatf("assertion error")); end + assert(rand_mc_latency >= 0) else begin `uvm_error(_header, $sformatf("assertion error")); end while (!(loop_cnt == 100) && rand_mc_latency > 0) begin int p_rand_mc_latency = rand_mc_latency; @@ -1426,7 +1429,7 @@ class cv32e40p_fp_op_fwd_instr_stream extends cv32e40p_float_zfinx_base_instr_st en_clr_fflags_af_instr = 0; num_of_instr_per_block = 10; include_load_store_base_sp = 0; // exclude store instrs for this stream - assert (num_of_instr_per_block != 0 && num_of_instr_per_block%10 == 0); + assert (num_of_instr_per_block != 0 && num_of_instr_per_block%10 == 0) else begin `uvm_error(_header, $sformatf("assertion error")); end endfunction: pre_randomize virtual function void print_stream_setting(); @@ -1699,7 +1702,7 @@ class cv32e40p_fp_op_fwd_instr_w_loadstore_stream extends cv32e40p_float_zfinx_b riscv_fpr_t i_fs1 = (is_zfinx) ? FT0 : p_instr_f.fs1; - assert(!(p_instr_zfinx == null && p_instr_f == null)); + assert(!(p_instr_zfinx == null && p_instr_f == null)) else begin `uvm_error(_header, $sformatf("assertion error")); end `SET_GPR_VALUE(i_rd, v_rd); if (p_instr_zfinx != null) begin @@ -1719,8 +1722,8 @@ class cv32e40p_fp_op_fwd_instr_w_loadstore_stream extends cv32e40p_float_zfinx_b end else begin unique case (p_instr_f.instr_name) - FCVT_W_S, FCVT_WU_S : begin `SET_FPR_VALUE(i_fs1, F_POS_VAL1); end // rd(int) = fs1 - FMV_X_W : begin `SET_FPR_VALUE(i_fs1, F_NEG_ZERO_DIV2); end // rd(int) <- fs1 + FCVT_W_S, FCVT_WU_S : begin `SET_FPR_VALUE(i_fs1, F_POS_VAL1, xreg_for_set_fpr); end // rd(int) = fs1 + FMV_X_W : begin `SET_FPR_VALUE(i_fs1, F_NEG_ZERO_DIV2, xreg_for_set_fpr); end // rd(int) <- fs1 endcase end @@ -1876,7 +1879,7 @@ class cv32e40p_fp_op_fwd_instr_w_loadstore_stream extends cv32e40p_float_zfinx_b STORE, POST_INC_STORE : begin // S[B|H|WW], C_SW[SP], C_FSW[SP], CV_S[B|H|W] instr2.rs1 = (is_zfinx) ? instr_zfinx.rd : instr_f.rd; if (instr2.category == POST_INC_STORE && j != num_of_load_store_instr-1) begin // no special handle on last load/store - assert(instr2.has_rd); // rd here is rs3 in spec + assert(instr2.has_rd) else begin `uvm_error(_header, $sformatf("assertion error")); end // rd here is rs3 in spec instr2.rd = ZERO; // prevent post incr to update rs1 that target into code space end last_store_rs1 = instr2.rs1; has_store = 1; @@ -1890,7 +1893,7 @@ class cv32e40p_fp_op_fwd_instr_w_loadstore_stream extends cv32e40p_float_zfinx_b end if (instr2.has_rd) begin last_load_rd = instr2.rd; has_load_rd = 1; end if (instr2.category == POST_INC_LOAD && j != num_of_load_store_instr-1) begin // no special handle on last load/store - assert(instr2.has_rs2); + assert(instr2.has_rs2) else begin `uvm_error(_header, $sformatf("assertion error")); end instr2.rs2 = ZERO; // prevent post incr to update rs1 that target into code space end cnt = 0; @@ -2050,7 +2053,7 @@ class cv32e40p_mstatus_fs_stream extends cv32e40p_float_zfinx_base_instr_stream; if (idx == 0) loop_cnt++; else if (idx != 0 && idx%total_instr == 0) begin loop_cnt++; - assert (loop_cnt <= loop_cnt_limit); + assert (loop_cnt <= loop_cnt_limit) else begin `uvm_error(_header, $sformatf("assertion error")); end exclude_instr.delete(); csr_mstatus_fs = 32'd2; // Clean clr_csr_init_done = 0; // Update csrrw_val diff --git a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib_defines.sv b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib_defines.sv index f18e72c3db..6d5ecebe8c 100644 --- a/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib_defines.sv +++ b/cv32e40p/env/corev-dv/instr_lib/cv32e40p_float_instr_lib_defines.sv @@ -158,15 +158,16 @@ } // Overhead instruction to set fpr with specific value - `define SET_FPR_VALUE(FRD,IMM) \ + `define SET_FPR_VALUE(FRD,IMM,XREG) \ begin\ riscv_instr m_instr;\ riscv_pseudo_instr p_instr;\ riscv_floating_point_instr f_instr;\ + assert(``XREG`` != ZERO) else begin `uvm_error("SET_FPR_VALUE", $sformatf("XREG is %s", ``XREG``.name())); end \ p_instr = riscv_pseudo_instr::type_id::create("p_instr");\ `DV_CHECK_RANDOMIZE_WITH_FATAL(p_instr,\ pseudo_instr_name == LI;\ - rd == T2;\ + rd == ``XREG``;\ );\ p_instr.imm = ``IMM``;\ p_instr.update_imm_str();\ @@ -176,7 +177,7 @@ override_instr(\ .f_instr (f_instr),\ .fd (``FRD``),\ - .rs1 (T2)\ + .rs1 (``XREG``)\ );\ instr_list.push_back(f_instr);\ instr_list[$].comment = {instr_list[$].comment, $sformatf(`" [SET REG TO 32'h%8h] `", ``IMM``)};\