diff --git a/cv32e40p/env/corev-dv/cv32e40p_illegal_instr.sv b/cv32e40p/env/corev-dv/cv32e40p_illegal_instr.sv index fdd361b4ba..e7a3459cd4 100644 --- a/cv32e40p/env/corev-dv/cv32e40p_illegal_instr.sv +++ b/cv32e40p/env/corev-dv/cv32e40p_illegal_instr.sv @@ -28,6 +28,37 @@ class cv32e40p_illegal_instr extends riscv_illegal_instr; + // override Default legal opcode for RV32C instructions + bit [2:0] legal_c00_opcode[$] = '{3'b000, + 3'b010, + 3'b011, + 3'b110, + 3'b111}; + bit [2:0] legal_c10_opcode[$] = '{3'b000, + 3'b010, + 3'b011, + 3'b100, + 3'b110, + 3'b111}; + + // replicate constraint here to enable constraint takes effect with local variables from this class + // when we use factory override to this class + constraint illegal_compressed_op_c { + if (exception == kIllegalCompressedOpcode) { + c_op != 2'b01; + if (legal_c00_opcode.size() == 8) { + c_op != 2'b00; + } else { + !(c_msb inside {legal_c00_opcode}); + } + if (legal_c10_opcode.size() == 8) { + c_op != 2'b10; + } else { + !(c_msb inside {legal_c10_opcode}); + } + } + } + constraint missing_csr_debug_regs_c { instr_bin[31:20] != 'h7A4; // TINFO instr_bin[31:20] != 'h7A5; // TCONTROL @@ -52,8 +83,10 @@ class cv32e40p_illegal_instr extends riscv_illegal_instr; function void cv32e40p_init(riscv_instr_gen_config cfg); this.cfg = cfg; if (riscv_instr_pkg::RV32FC inside {riscv_instr_pkg::supported_isa}) begin - legal_c00_opcode = {legal_c00_opcode, 3'b011, 3'b111}; - legal_c10_opcode = {legal_c10_opcode, 3'b011, 3'b111}; + if (!(3'b011 inside {legal_c00_opcode})) legal_c00_opcode = {legal_c00_opcode, 3'b011}; + if (!(3'b111 inside {legal_c00_opcode})) legal_c00_opcode = {legal_c00_opcode, 3'b111}; + if (!(3'b011 inside {legal_c10_opcode})) legal_c10_opcode = {legal_c10_opcode, 3'b011}; + if (!(3'b111 inside {legal_c10_opcode})) legal_c10_opcode = {legal_c10_opcode, 3'b111}; end if (riscv_instr_pkg::RV32ZFINX inside {riscv_instr_pkg::supported_isa}) begin legal_opcode = {legal_opcode, 7'b1000011, 7'b1000111, 7'b1001011, diff --git a/cv32e40p/tb/uvmt/uvmt_cv32e40p_tb_ifs.sv b/cv32e40p/tb/uvmt/uvmt_cv32e40p_tb_ifs.sv index b80269d40c..4c652d7dfa 100644 --- a/cv32e40p/tb/uvmt/uvmt_cv32e40p_tb_ifs.sv +++ b/cv32e40p/tb/uvmt/uvmt_cv32e40p_tb_ifs.sv @@ -600,23 +600,27 @@ interface uvmt_cv32e40p_cov_if // calculate each APU operation's current clock cycle number during execution for functional coverage use // input(s): apu_op, bit detect_apu_rvalid = 1; + bit is_apu_addr_phase = 0; always @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin clk_cycle_window = 0; curr_fpu_apu_op_if = 0; detect_apu_rvalid = 1; + is_apu_addr_phase = 0; end else begin assert (clk_cycle_window <= MAX_FP_XACT_CYCLE) else `uvm_error("uvmt_cv32e40p_cov_if", $sformatf("clk_cycle_window (%0d) > MAX_FP_XACT_CYCLE (%0d)", clk_cycle_window, MAX_FP_XACT_CYCLE)); - if (apu_req && apu_gnt && apu_rvalid_i && detect_apu_rvalid) begin : IS_0_CYC_FPU - clk_cycle_window = 0; - detect_apu_rvalid = 0; + if (apu_req && apu_gnt && apu_rvalid_i) begin : IS_0_CYC_FPU + clk_cycle_window = (is_apu_addr_phase) ? 1 : 0; // if b2b addr then 1 + detect_apu_rvalid = (is_apu_addr_phase) ? 0 : 1; // if b2b addr then 0 + is_apu_addr_phase = 1; curr_fpu_apu_op_if = apu_op; end - else if (apu_req && apu_gnt && !apu_rvalid_i && detect_apu_rvalid) begin : NOT_0_CYC_FPU + else if (apu_req && apu_gnt && !apu_rvalid_i) begin : NOT_0_CYC_FPU clk_cycle_window = 1; detect_apu_rvalid = 0; + is_apu_addr_phase = 1; curr_fpu_apu_op_if = apu_op; end else if (apu_busy && !apu_rvalid_i && !detect_apu_rvalid) begin : FPU_MULT_CYC @@ -624,9 +628,11 @@ interface uvmt_cv32e40p_cov_if clk_cycle_window += 1; end else if (apu_busy && apu_rvalid_i && !detect_apu_rvalid) begin : DONE_FPU_CYCLE + clk_cycle_window = 0; detect_apu_rvalid = 1; + is_apu_addr_phase = 0; end - else if (!apu_busy) begin + else if (!apu_busy && detect_apu_rvalid) begin clk_cycle_window = 0; end end