From 83178c69f9393b707fb57d9ff1afdb7ab4d78eae Mon Sep 17 00:00:00 2001 From: udinator Date: Tue, 24 Sep 2019 13:55:03 -0700 Subject: [PATCH] Update google_riscv-dv to google/riscv-dv@e3e1e30 (#349) Update code from upstream repository https://github.com/google/riscv- dv to revision e3e1e308cfc3d718aeb94bb3463371979d9a31ae * Disable full trace in the run script (google/riscv-dv#180) (taoliug) * Fix spike logging issue (google/riscv-dv#179) (taoliug) * Add functional coverage for HINT instructions (google/riscv-dv#177) (taoliug) * Add functional coverage for various hazard conditions (google/riscv- dv#176) (taoliug) --- vendor/google_riscv-dv.lock.hjson | 2 +- .../scripts/spike_log_to_trace_csv.py | 7 +- .../src/riscv_illegal_instr.sv | 13 +- .../src/riscv_instr_cov_item.sv | 38 ++++ .../src/riscv_instr_cover_group.sv | 163 +++++++++++++----- vendor/google_riscv-dv/src/riscv_instr_pkg.sv | 7 + .../test/riscv_instr_cov_test.sv | 1 + 7 files changed, 183 insertions(+), 48 deletions(-) diff --git a/vendor/google_riscv-dv.lock.hjson b/vendor/google_riscv-dv.lock.hjson index 78d8f179..036e7aa8 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: 44505927a70a6234b996d15f2e51bd1e2632b68e + rev: e3e1e308cfc3d718aeb94bb3463371979d9a31ae } } diff --git a/vendor/google_riscv-dv/scripts/spike_log_to_trace_csv.py b/vendor/google_riscv-dv/scripts/spike_log_to_trace_csv.py index 06362aea..a64c2044 100644 --- a/vendor/google_riscv-dv/scripts/spike_log_to_trace_csv.py +++ b/vendor/google_riscv-dv/scripts/spike_log_to_trace_csv.py @@ -39,7 +39,7 @@ HEX_RE = re.compile(r"^0x") LOGGER = logging.getLogger() -def process_spike_sim_log(spike_log, csv, full_trace = 1): +def process_spike_sim_log(spike_log, csv, full_trace = 0): """Process SPIKE simulation log. Extract instruction and affected register information from spike simulation @@ -50,7 +50,7 @@ def process_spike_sim_log(spike_log, csv, full_trace = 1): spike_instr = "" # Remove all the init spike boot instructions - cmd = ("sed -i '/3 0x0000000000001010/,$!d' %s" % spike_log) + cmd = ("sed -i '/core.*0x0000000000001010/,$!d' %s" % spike_log) os.system(cmd) # Remove all instructions after ecall (end of program excecution) cmd = ("sed -i '/ecall/q' %s" % spike_log) @@ -363,7 +363,8 @@ def assign_operand(trace, operands, gpr): trace.rd = 'zero' trace.rd_val = '0' trace.rs1 = operands[0] - trace.rs1_val = gpr[trace.rs1] + if trace.rs1 in gpr: + trace.rs1_val = gpr[trace.rs1] elif trace.instr in ['li']: trace.instr = 'li' elif trace.instr[0:2] in ['lr', 'am', 'sc']: diff --git a/vendor/google_riscv-dv/src/riscv_illegal_instr.sv b/vendor/google_riscv-dv/src/riscv_illegal_instr.sv index 7107908e..b476433f 100644 --- a/vendor/google_riscv-dv/src/riscv_illegal_instr.sv +++ b/vendor/google_riscv-dv/src/riscv_illegal_instr.sv @@ -111,12 +111,23 @@ class riscv_illegal_instr extends uvm_object; constraint hint_instr_c { if (exception == kHintInstr) { + // C.ADDI ((c_msb == 3'b000) && (c_op == 2'b01) && ({instr_bin[12], instr_bin[6:2]} == 6'b0)) || + // C.LI ((c_msb == 3'b010) && (c_op == 2'b01) && (instr_bin[11:7] == 5'b0)) || + // C.SRAI64, C.SRLI64 + ((c_msb == 3'b100) && (c_op == 2'b01) && (instr_bin[12:11] == 2'b00) && + (instr_bin[6:2] == 5'b0)) || // C.LUI ((c_msb == 3'b011) && (c_op == 2'b01) && (instr_bin[11:7] == 5'b0) && ({instr_bin[12], instr_bin[6:2]} != 6'b0)) || - ((c_msb == 3'b100) && (c_op == 2'b10) && (instr_bin[12:7] == 6'b0) && + // C.SLLI + ((c_msb == 3'b000) && (c_op == 2'b10) && (instr_bin[11:7] == 5'b0)) || + // C.SLLI64 + ((c_msb == 3'b000) && (c_op == 2'b10) && (instr_bin[11:7] != 5'b0) && !instr_bin[12] && + (instr_bin[6:2] == 0)) || + // C.ADD + ((c_msb == 3'b100) && (c_op == 2'b10) && (instr_bin[11:7] == 5'b0) && instr_bin[12] && (instr_bin[6:2] != 0)); } } 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 0eb3a053..064e00c5 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_cov_item.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_cov_item.sv @@ -19,6 +19,7 @@ class riscv_instr_cov_item extends riscv_instr_base; rand bit [XLEN-1:0] rs1_value; rand bit [XLEN-1:0] rs2_value; rand bit [XLEN-1:0] rd_value; + bit [31:0] binary; bit [XLEN-1:0] pc; bit [XLEN-1:0] mem_addr; @@ -30,6 +31,8 @@ class riscv_instr_cov_item extends riscv_instr_base; operand_sign_e rs2_sign; operand_sign_e imm_sign; operand_sign_e rd_sign; + hazard_e gpr_hazard; + hazard_e lsu_hazard; special_val_e rs1_special_val; special_val_e rs2_special_val; special_val_e rd_special_val; @@ -184,6 +187,41 @@ class riscv_instr_cov_item extends riscv_instr_base; return DIFFERENT; endfunction + function void check_hazard_condition(riscv_instr_cov_item pre_instr); + riscv_reg_t gpr; + if (pre_instr.has_rd) begin + if ((has_rs1 && (rs1 == pre_instr.rd)) || (has_rs2 && (rs2 == pre_instr.rd))) begin + gpr_hazard = RAW_HAZARD; + end else if (has_rd && (rd == pre_instr.rd)) begin + gpr_hazard = WAW_HAZARD; + end else if (has_rd && ((pre_instr.has_rs1 && (pre_instr.rs1 == rd)) || + (pre_instr.has_rs2 && (pre_instr.rs2 == rd)))) begin + gpr_hazard = WAR_HAZARD; + end else begin + gpr_hazard = NO_HAZARD; + end + end + if (category == LOAD) begin + if ((pre_instr.category == STORE) && (pre_instr.mem_addr == mem_addr)) begin + lsu_hazard = RAW_HAZARD; + end else begin + lsu_hazard = NO_HAZARD; + end + end + if (category == STORE) begin + if ((pre_instr.category == STORE) && (pre_instr.mem_addr == mem_addr)) begin + lsu_hazard = WAW_HAZARD; + end else if ((pre_instr.category == LOAD) && (pre_instr.mem_addr == mem_addr)) begin + lsu_hazard = WAR_HAZARD; + end else begin + lsu_hazard = NO_HAZARD; + end + end + `uvm_info(`gfn, $sformatf("Pre:%0s, Cur:%0s, Hazard: %0s/%0s", + pre_instr.convert2asm(), this.convert2asm(), + gpr_hazard.name(), lsu_hazard.name()), UVM_FULL) + endfunction + virtual function void sample_cov(); pre_sample(); endfunction 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 d14589ef..5ac78ec2 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv @@ -3,86 +3,114 @@ `define R_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ - cp_rs1 : coverpoint instr.rs1; \ - cp_rs2 : coverpoint instr.rs2; \ - cp_rd : coverpoint instr.rd; \ - cp_rs1_sign : coverpoint instr.rs1_sign; \ - cp_rs2_sign : coverpoint instr.rs2_sign; \ - cp_rd_sign : coverpoint instr.rd_sign; + cp_rs1 : coverpoint instr.rs1; \ + cp_rs2 : coverpoint instr.rs2; \ + cp_rd : coverpoint instr.rd; \ + cp_rs1_sign : coverpoint instr.rs1_sign; \ + cp_rs2_sign : coverpoint instr.rs2_sign; \ + cp_rd_sign : coverpoint instr.rd_sign; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard; \ `define CMP_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ - cp_rs1 : coverpoint instr.rs1; \ - cp_rd : coverpoint instr.rd; \ - cp_rs1_sign : coverpoint instr.rs1_sign; \ - cp_result : coverpoint instr.rd_value[0]; + cp_rs1 : coverpoint instr.rs1; \ + cp_rd : coverpoint instr.rd; \ + cp_rs1_sign : coverpoint instr.rs1_sign; \ + cp_result : coverpoint instr.rd_value[0]; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard; \ `define SB_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ - cp_rs1 : coverpoint instr.rs1; \ - cp_rs2 : coverpoint instr.rs2; \ - cp_rs1_sign : coverpoint instr.rs1_sign; \ - cp_rs2_sign : coverpoint instr.rs2_sign; \ - cp_imm_sign : coverpoint instr.imm_sign; \ - cp_branch_hit : coverpoint instr.branch_hit; \ - cp_sign_cross : cross cp_rs1_sign, cp_rs2_sign, cp_imm_sign; + cp_rs1 : coverpoint instr.rs1; \ + cp_rs2 : coverpoint instr.rs2; \ + cp_rs1_sign : coverpoint instr.rs1_sign; \ + cp_rs2_sign : coverpoint instr.rs2_sign; \ + cp_imm_sign : coverpoint instr.imm_sign; \ + cp_branch_hit : coverpoint instr.branch_hit; \ + cp_sign_cross : cross cp_rs1_sign, cp_rs2_sign, cp_imm_sign; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard { \ + bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \ + } `define STORE_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ - cp_rs1 : coverpoint instr.rs1; \ - cp_rs2 : coverpoint instr.rs2; \ - cp_imm_sign : coverpoint instr.imm_sign; \ + cp_rs1 : coverpoint instr.rs1; \ + cp_rs2 : coverpoint instr.rs2; \ + cp_imm_sign : coverpoint instr.imm_sign; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard { \ + bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \ + } \ + cp_lsu_harzard : coverpoint instr.lsu_hazard { \ + bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \ + } `define LOAD_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ - cp_rs1 : coverpoint instr.rs1; \ - cp_rd : coverpoint instr.rd; \ - cp_imm_sign : coverpoint instr.imm_sign; \ + cp_rs1 : coverpoint instr.rs1; \ + cp_rd : coverpoint instr.rd; \ + cp_imm_sign : coverpoint instr.imm_sign; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard; \ + cp_lsu_harzard : coverpoint instr.lsu_hazard { \ + bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \ + } `define I_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ - cp_rs1 : coverpoint instr.rs1; \ - cp_rd : coverpoint instr.rd; \ - cp_rs1_sign : coverpoint instr.rs1_sign; \ - cp_rd_sign : coverpoint instr.rd_sign; \ - cp_imm_sign : coverpoint instr.imm_sign; + cp_rs1 : coverpoint instr.rs1; \ + cp_rd : coverpoint instr.rd; \ + cp_rs1_sign : coverpoint instr.rs1_sign; \ + cp_rd_sign : coverpoint instr.rd_sign; \ + cp_imm_sign : coverpoint instr.imm_sign; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard; `define U_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ - cp_rd : coverpoint instr.rd; \ - cp_rd_sign : coverpoint instr.rd_sign; \ - cp_imm_sign : coverpoint instr.imm_sign; + cp_rd : coverpoint instr.rd; \ + cp_rd_sign : coverpoint instr.rd_sign; \ + cp_imm_sign : coverpoint instr.imm_sign; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard; `define CSR_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ - cp_csr : coverpoint instr.csr { \ + cp_csr : coverpoint instr.csr { \ bins csr[] = cp_csr with (is_implemented_csr(item)); \ } \ - cp_rs1 : coverpoint instr.rs1; \ - cp_rd : coverpoint instr.rd; + cp_rs1 : coverpoint instr.rs1; \ + cp_rd : coverpoint instr.rd; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard; `define CR_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ - cp_rs2 : coverpoint instr.rs2; \ - cp_rd : coverpoint instr.rd; \ - cp_rs2_sign : coverpoint instr.rs2_sign; + cp_rs2 : coverpoint instr.rs2; \ + cp_rd : coverpoint instr.rd; \ + cp_rs2_sign : coverpoint instr.rs2_sign; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard; `define CI_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ cp_rd : coverpoint instr.rd; \ - cp_imm_sign : coverpoint instr.imm_sign; + cp_imm_sign : coverpoint instr.imm_sign; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard { \ + bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \ + } `define CSS_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ cp_rs2 : coverpoint instr.rs2; \ cp_imm_sign : coverpoint instr.imm_sign; \ - cp_rs2_sign : coverpoint instr.rs2_sign; + cp_rs2_sign : coverpoint instr.rs2_sign; \ + cp_gpr_harzard : coverpoint instr.gpr_hazard { \ + bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \ + } `define CIW_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ cp_imm_sign : coverpoint instr.imm_sign; \ cp_rd : coverpoint instr.rd { \ bins gpr[] = cp_rd with (is_compressed_gpr(riscv_reg_t'(item))); \ + } \ + cp_gpr_harzard : coverpoint instr.gpr_hazard { \ + bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \ } `define CL_INSTR_CG_BEGIN(INSTR_NAME) \ @@ -93,6 +121,10 @@ } \ cp_rd : coverpoint instr.rd { \ bins gpr[] = cp_rd with (is_compressed_gpr(riscv_reg_t'(item))); \ + } \ + cp_gpr_harzard : coverpoint instr.gpr_hazard; \ + cp_lsu_harzard : coverpoint instr.lsu_hazard { \ + bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \ } `define CS_INSTR_CG_BEGIN(INSTR_NAME) \ @@ -103,13 +135,23 @@ } \ cp_rs2 : coverpoint instr.rs2 { \ bins gpr[] = cp_rs2 with (is_compressed_gpr(riscv_reg_t'(item))); \ + } \ + cp_gpr_harzard : coverpoint instr.gpr_hazard { \ + bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \ + } \ + cp_lsu_harzard : coverpoint instr.lsu_hazard { \ + bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \ } + `define CB_INSTR_CG_BEGIN(INSTR_NAME) \ `INSTR_CG_BEGIN(INSTR_NAME) \ cp_imm_sign : coverpoint instr.imm_sign; \ cp_rs1 : coverpoint instr.rs1 { \ bins gpr[] = cp_rs1 with (is_compressed_gpr(riscv_reg_t'(item))); \ + } \ + cp_gpr_harzard : coverpoint instr.gpr_hazard { \ + bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \ } `define CJ_INSTR_CG_BEGIN(INSTR_NAME) \ @@ -122,8 +164,8 @@ class riscv_instr_cover_group#(privileged_reg_t implemented_pcsr[] = riscv_instr_pkg::implemented_csr); riscv_instr_gen_config cfg; - riscv_instr_name_t instr_name; - riscv_instr_name_t pre_instr_name; + riscv_instr_cov_item cur_instr; + riscv_instr_cov_item pre_instr; riscv_instr_name_t instr_list[$]; int unsigned instr_cnt; int unsigned branch_instr_cnt; @@ -520,6 +562,32 @@ class riscv_instr_cover_group#(privileged_reg_t implemented_pcsr[] = `CR_INSTR_CG_BEGIN(c_addw) `CG_END + `INSTR_CG_BEGIN(hint) + cp_hint : coverpoint instr.binary[15:0] { + wildcard bins addi = {16'b0000_1xxx_x000_0001, + 16'b0000_x1xx_x000_0001, + 16'b0000_xx1x_x000_0001, + 16'b0000_xxx1_x000_0001, + 16'b0000_xxxx_1000_0001}; + wildcard bins li = {16'b010x_0000_0xxx_xx01}; + wildcard bins lui = {16'b011x_0000_0xxx_xx01}; + wildcard bins srli64 = {16'b1000_00xx_x000_0001}; + wildcard bins srai64 = {16'b1000_01xx_x000_0001}; + wildcard bins slli = {16'b000x_0000_0xxx_xx10}; + wildcard bins slli64 = {16'b0000_xxxx_x000_0010}; + wildcard bins mv = {16'b1000_0000_01xx_xx10, + 16'b1000_0000_0x1x_xx10, + 16'b1000_0000_0xx1_xx10, + 16'b1000_0000_0xxx_1x10, + 16'b1000_0000_0xxx_x110}; + wildcard bins add = {16'b1001_0000_01xx_xx10, + 16'b1001_0000_0x1x_xx10, + 16'b1001_0000_0xx1_xx10, + 16'b1001_0000_0xxx_1x10, + 16'b1001_0000_0xxx_x110}; + } + `CG_END + // Branch hit history covergroup branch_hit_history_cg; coverpoint branch_hit_history; @@ -549,7 +617,10 @@ class riscv_instr_cover_group#(privileged_reg_t implemented_pcsr[] = function new(riscv_instr_gen_config cfg); this.cfg = cfg; + cur_instr = riscv_instr_cov_item::type_id::create("cur_instr"); + pre_instr = riscv_instr_cov_item::type_id::create("pre_instr"); build_instr_list(); + hint_cg = new(); // RV32I instruction functional coverage instantiation add_cg = new(); sub_cg = new(); @@ -663,9 +734,13 @@ class riscv_instr_cover_group#(privileged_reg_t implemented_pcsr[] = endfunction function void sample(riscv_instr_cov_item instr); - pre_instr_name = instr_name; - instr_name = instr.instr_name; instr_cnt += 1; + if (instr_cnt > 1) begin + instr.check_hazard_condition(pre_instr); + end + if (instr.binary[1:0] != 2'b11) begin + hint_cg.sample(instr); + end case (instr.instr_name) ADD : add_cg.sample(instr); SUB : sub_cg.sample(instr); @@ -775,6 +850,8 @@ class riscv_instr_cover_group#(privileged_reg_t implemented_pcsr[] = if (instr_cnt > 1) begin // instr_trans_cg.sample(); end + pre_instr.copy_base_instr(instr); + pre_instr.mem_addr = instr.mem_addr; endfunction // Check if the privileged CSR is implemented diff --git a/vendor/google_riscv-dv/src/riscv_instr_pkg.sv b/vendor/google_riscv-dv/src/riscv_instr_pkg.sv index f67edc81..187ffd28 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_pkg.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_pkg.sv @@ -685,6 +685,13 @@ package riscv_instr_pkg; MISA_EXT_Z } misa_ext_t; + typedef enum bit [1:0] { + NO_HAZARD, + RAW_HAZARD, + WAR_HAZARD, + WAW_HAZARD + } hazard_e; + `include "riscv_core_setting.sv" typedef bit [15:0] program_id_t; 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 5436c5ce..0f77567a 100644 --- a/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv +++ b/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv @@ -122,6 +122,7 @@ class riscv_instr_cov_test extends uvm_test; riscv_reg_t gpr; privileged_reg_t preg; get_val(trace["addr"], instr.pc); + get_val(trace["binary"], instr.binary); instr.trace = trace["instr_str"]; if (instr.instr_name inside {ECALL, EBREAK, FENCE, FENCE_I, NOP, C_NOP, WFI, MRET, C_EBREAK}) begin