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)
This commit is contained in:
udinator 2019-09-24 13:55:03 -07:00 committed by GitHub
parent 1e8381bfa1
commit 83178c69f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 183 additions and 48 deletions

View file

@ -9,6 +9,6 @@
upstream:
{
url: https://github.com/google/riscv-dv
rev: 44505927a70a6234b996d15f2e51bd1e2632b68e
rev: e3e1e308cfc3d718aeb94bb3463371979d9a31ae
}
}

View file

@ -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']:

View file

@ -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));
}
}

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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