Skip to content

Commit

Permalink
Merge pull request #2305 from XavierAubert/cv32e40p/dev_dd_W48a
Browse files Browse the repository at this point in the history
CV32E40Pv2 core-v-verif environment fixes and updates
  • Loading branch information
MikeOpenHWGroup committed Dec 12, 2023
2 parents f70c820 + 4143421 commit c98ff2a
Show file tree
Hide file tree
Showing 29 changed files with 400 additions and 230 deletions.
7 changes: 5 additions & 2 deletions bin/templates/regress_rmdb.j2
Expand Up @@ -208,8 +208,11 @@
<execScript launch="exec" usestderr="no">
<command> echo " TEST RUNCMD: (%t_cmd%) CHECK_SIM_RESULT={{regress_macros.yesorno(check_sim_results)}} COMP=0 CV_CORE={{project}} {{toolchain|upper}}=1 CFG=(%t_cfg%) TEST_CFG_FILE=(%t_test_cfg:%) SIMULATOR=(%t_simulator%) USE_ISS=(%t_iss:%) COV=(%t_cov:%) RUN_INDEX=(%t_iteration%) GEN_START_INDEX=(%t_iteration%) SEED=(%t_iteration%) {{regress_macros.cv_results(results_path)}} {{makeargs}} (%t_makearg%)"</command>
<command> echo " logfile: (%log_file%)"</command>
<command> echo " Here is the commend to reproduce the test locally: </command>
<command> echo " (%t_cmd%) CHECK_SIM_RESULT={{regress_macros.yesorno(check_sim_results)}} CV_CORE={{project}} {{toolchain|upper}}=1 CFG=(%t_cfg%) TEST_CFG_FILE=(%t_test_cfg:%) SIMULATOR=(%t_simulator%) USE_ISS=(%t_iss:%) COV=(%t_cov:%) SEED=(%t_iteration%) {{makeargs}} (%t_makearg%)</command>
<command> echo " RTL repo: CV_CORE_REPO : ${CV_CORE_REPO}"</command>
<command> echo " CV_CORE_BRANCH: ${CV_CORE_BRANCH}"</command>
<command> echo " CV_CORE_HASH : ${CV_CORE_HASH}"</command>
<command> echo " Here is the command to reproduce the test, using above RTL repo: "</command>
<command> echo " (%t_cmd%) CHECK_SIM_RESULT={{regress_macros.yesorno(check_sim_results)}} CV_CORE={{project}} {{toolchain|upper}}=1 CFG=(%t_cfg%) TEST_CFG_FILE=(%t_test_cfg:%) SIMULATOR=(%t_simulator%) USE_ISS=(%t_iss:%) COV=(%t_cov:%) SEED=(%t_iteration%) {{makeargs}} (%t_makearg%) "</command>
<command> cd (%t_abs_dir%) &amp;&amp; (%t_cmd%) CHECK_SIM_RESULT={{regress_macros.yesorno(check_sim_results)}} CHECK_SIM_LOG=(%log_file%) COMP=0 CV_CORE={{project}} {{toolchain|upper}}=1 CFG=(%t_cfg%) TEST_CFG_FILE=(%t_test_cfg:%) SIMULATOR=(%t_simulator%) USE_ISS=(%t_iss:%) COV=(%t_cov:%) RUN_INDEX=(%t_iteration%) GEN_START_INDEX=(%t_iteration%) SEED=(%t_iteration%) {{regress_macros.cv_results(results_path)}} {{makeargs}} (%t_makearg%)</command>
</execScript>
</runnable>
Expand Down
84 changes: 47 additions & 37 deletions cv32e40p/env/corev-dv/cv32e40p_asm_program_gen.sv
Expand Up @@ -365,9 +365,6 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;
// Restore user mode GPR value from kernel stack before return

// Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack
//pop_gpr_from_kernel_stack(status, scratch, cfg.mstatus_mprv,
// cfg.sp, cfg.tp, interrupt_handler_instr);

pop_regfile_from_kernel_stack(status, scratch, cfg.mstatus_mprv,
cfg.sp, cfg.tp, interrupt_handler_instr, corev_cfg);
// Emit fast interrupt handler since cv32e40p has hardware interrupt ack
Expand Down Expand Up @@ -526,8 +523,40 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;
instr_stream.push_back(str);
endfunction

// Override ECALL trap handler - gen_ecall_handler of corev-dv
// Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack
// With RV32X enabled, check for ecall instr on the last instr of hwloop
// If true, then
// (a) Set MEPC to first instr of hwloop body
// (b) Add logic to decrement the LPCOUNT
virtual function void gen_ecall_handler(int hart);
string instr[$];
cv32e40p_instr_gen_config corev_cfg;

`DV_CHECK_FATAL($cast(corev_cfg, cfg), "Could not cast cfg into corev_cfg")

if (riscv_instr_pkg::RV32X inside {riscv_instr_pkg::supported_isa}) begin
instr = {instr,
`COMMON_HWLOOP_EXC_HANDLING_CODE
};
end else begin
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
end
pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg);
instr.push_back("mret");
gen_section(get_label("ecall_handler", hart), instr);
endfunction : gen_ecall_handler

// Override Ebreak trap handler - gen_ebreak_handler
// Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack
// With RV32X enabled, check for ebreak instr on the last instr of hwloop
// If true, then
// (a) Set MEPC to first instr of hwloop body
// (b) Add logic to decrement the LPCOUNT
virtual function void gen_ebreak_handler(int hart);
string instr[$];
cv32e40p_instr_gen_config corev_cfg;
Expand All @@ -536,13 +565,18 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;

gen_signature_handshake(instr, CORE_STATUS, EBREAK_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], MEPC),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw 0x%0x, x%0d", MEPC, cfg.gpr[0])
};
if (riscv_instr_pkg::RV32X inside {riscv_instr_pkg::supported_isa}) begin
instr = {instr,
`COMMON_HWLOOP_EXC_HANDLING_CODE
};
end else begin
instr = {instr,
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], MEPC),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw 0x%0x, x%0d", MEPC, cfg.gpr[0])
};
end
// Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack
//pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg);
instr.push_back("mret");
gen_section(get_label("ebreak_handler", hart), instr);
Expand All @@ -551,8 +585,9 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;
// Override Illegal instruction handler - gen_illegal_instr_handler
// Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack
// With RV32X enabled, check for illegal instr on the last instr of hwloop
// If true, then set MEPC to first instr of hwloop instead of simply
// incrementing by 4.
// If true, then
// (a) Set MEPC to first instr of hwloop body
// (b) Add logic to decrement the LPCOUNT
virtual function void gen_illegal_instr_handler(int hart);
string instr[$];
cv32e40p_instr_gen_config corev_cfg;
Expand All @@ -563,28 +598,7 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
if (riscv_instr_pkg::RV32X inside {riscv_instr_pkg::supported_isa}) begin
instr = {instr,
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], LPCOUNT1),
$sformatf("li x%0d, 2", cfg.gpr[1]),
$sformatf("bge x%0d, x%0d, 1f", cfg.gpr[0], cfg.gpr[1]),
$sformatf("2: csrr x%0d, 0x%0x", cfg.gpr[0], LPCOUNT0),
$sformatf("li x%0d, 2", cfg.gpr[1]),
$sformatf("bge x%0d, x%0d, 3f", cfg.gpr[0], cfg.gpr[1]),
$sformatf("beqz x0, 4f"),
$sformatf("1: csrr x%0d, 0x%0x", cfg.gpr[0], MEPC),
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], LPEND1),
$sformatf("addi x%0d, x%0d, -4", cfg.gpr[1], cfg.gpr[1]),
$sformatf("bne x%0d, x%0d, 2b", cfg.gpr[0], cfg.gpr[1]),
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], LPSTART1),
$sformatf("beqz x0, 5f"),
$sformatf("3: csrr x%0d, 0x%0x", cfg.gpr[0], MEPC),
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], LPEND0),
$sformatf("addi x%0d, x%0d, -4", cfg.gpr[1], cfg.gpr[1]),
$sformatf("bne x%0d, x%0d, 4f", cfg.gpr[0], cfg.gpr[1]),
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], LPSTART0),
$sformatf("beqz x0, 5f"),
$sformatf("4: csrr x%0d, 0x%0x", cfg.gpr[0], MEPC),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("5: csrw 0x%0x, x%0d", MEPC, cfg.gpr[0])
`COMMON_HWLOOP_EXC_HANDLING_CODE
};
end else begin
instr = {instr,
Expand All @@ -594,7 +608,6 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;
};
end
// Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack
//pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg);
instr.push_back("mret");
gen_section(get_label("illegal_instr_handler", hart), instr);
Expand All @@ -616,7 +629,6 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;
instr);
end
// Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack
//pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg);
instr.push_back("mret");
gen_section(get_label("instr_fault_handler", hart), instr);
Expand All @@ -638,7 +650,6 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;
instr);
end
// Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack
//pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg);
instr.push_back("mret");
gen_section(get_label("load_fault_handler", hart), instr);
Expand All @@ -660,7 +671,6 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;
instr);
end
// Replace pop_gpr_from_kernel_stack with pop_regfile_from_kernel_stack
//pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
pop_regfile_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr, corev_cfg);
instr.push_back("mret");
gen_section(get_label("store_fault_handler", hart), instr);
Expand Down
2 changes: 1 addition & 1 deletion cv32e40p/env/corev-dv/cv32e40p_debug_rom_gen.sv
Expand Up @@ -115,7 +115,7 @@ class cv32e40p_debug_rom_gen extends riscv_debug_rom_gen;
format_section(debug_main);
gen_sub_program(hart, sub_program[hart], sub_program_name,
cfg.num_debug_sub_program, 1'b1, "debug_sub");
main_program[hart] = riscv_instr_sequence::type_id::create("debug_program");
main_program[hart] = cv32e40p_instr_sequence::type_id::create("debug_program");
main_program[hart].instr_cnt = cfg.debug_program_instr_cnt;
main_program[hart].is_debug_program = 1;
main_program[hart].cfg = cfg;
Expand Down
4 changes: 4 additions & 0 deletions cv32e40p/env/corev-dv/cv32e40p_illegal_instr.sv
Expand Up @@ -43,6 +43,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};
end
if (riscv_instr_pkg::RV32ZFINX inside {riscv_instr_pkg::supported_isa}) begin
legal_opcode = {legal_opcode, 7'b1000011, 7'b1000111, 7'b1001011,
7'b1001111, 7'b1010011};
Expand Down
6 changes: 6 additions & 0 deletions cv32e40p/env/corev-dv/cv32e40p_instr_sequence.sv
Expand Up @@ -175,6 +175,12 @@ class cv32e40p_instr_sequence extends riscv_instr_sequence;
instr_stream.instr_list[i].has_label = 1'b0;
end
end
// Remove all pulp store instructions inside debug_program
if(is_debug_program == 1) begin
if (instr_stream.instr_list[i].instr_name inside {CV_SB, CV_SH, CV_SW} ) begin
instr_stream.instr_list.delete(i);
end
end
i++;
end // while
`uvm_info(get_full_name(), "Finished post-processing instructions", UVM_HIGH)
Expand Down
66 changes: 65 additions & 1 deletion cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv
Expand Up @@ -27,6 +27,71 @@ package cv32e40p_instr_test_pkg;
import riscv_signature_pkg::*;
import corev_instr_test_pkg::*;


// MACRO for Common HWLOOP handling code for all the exception handlers
// Common handler code to ensure all handlers use same code.
// Description:
// Check for expection (ecall/ebreak/illegal) on the last hwloop body instr
// If true, then
// (a) Set MEPC to first instr of hwloop body
// (b) Add logic to decrement the LPCOUNT
`define COMMON_HWLOOP_EXC_HANDLING_CODE \
/* Check LPCOUNT1 >= 1 */ \
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], LPCOUNT1), \
$sformatf("li x%0d, 1", cfg.gpr[1]), \
$sformatf("bge x%0d, x%0d, 1f", cfg.gpr[0], cfg.gpr[1]), \
/* Check LPCOUNT0 >= 1 */ \
$sformatf("2: csrr x%0d, 0x%0x", cfg.gpr[0], LPCOUNT0), \
$sformatf("li x%0d, 1", cfg.gpr[1]), \
$sformatf("bge x%0d, x%0d, 3f", cfg.gpr[0], cfg.gpr[1]), \
/* Since both LPCOUNT0 & LPCOUNT1 equals 0 */ \
/* Nothing needs to be done for HWLOOPs and its CSRs */ \
$sformatf("beqz x0, 4f"), \
/* HWLOOP1 Handling */ \
/* Check for ILLEGAL being the LAST HWLOOP Body instr */ \
$sformatf("1: csrr x%0d, 0x%0x", cfg.gpr[0], MEPC), \
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], LPEND1), \
$sformatf("addi x%0d, x%0d, -4", cfg.gpr[1], cfg.gpr[1]), \
$sformatf("bne x%0d, x%0d, 2b", cfg.gpr[0], cfg.gpr[1]), \
/* Else, If equal this means the illegal instr was the last */ \
/* hwloop body instr, thus we handle the HWLOOP manually here */ \
/* First decrement lpcount CSR manually as CSR not updated in HW */ \
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], LPCOUNT1), \
$sformatf("addi x%0d, x%0d, -1", cfg.gpr[1], cfg.gpr[1]), \
$sformatf("cv.count 1, x%0d", cfg.gpr[1]), \
/* Check if the current LPCOUNT1 value == 0, if so, then MEPC=MEPC+4 */ \
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], LPCOUNT1), \
$sformatf("beqz x%0d, 4f", cfg.gpr[1]), \
/* Else LPCOUNT1 still >=1 and thus next, */ \
/* Set the next MEPC to LPSTART1 for next HWLOOP iteration */ \
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], LPSTART1), \
$sformatf("beqz x0, 5f"), \
/* HWLOOP0 Handling */ \
/* Check for ILLEGAL being the LAST HWLOOP Body instr */ \
$sformatf("3: csrr x%0d, 0x%0x", cfg.gpr[0], MEPC), \
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], LPEND0), \
$sformatf("addi x%0d, x%0d, -4", cfg.gpr[1], cfg.gpr[1]), \
$sformatf("bne x%0d, x%0d, 4f", cfg.gpr[0], cfg.gpr[1]), \
/* Else, If equal this means the illegal instr was the last */ \
/* hwloop body instr, thus we handle the HWLOOP manually here */ \
/* First decrement lpcount CSR manually as CSR not updated in HW */ \
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], LPCOUNT0), \
$sformatf("addi x%0d, x%0d, -1", cfg.gpr[1], cfg.gpr[1]), \
$sformatf("cv.count 0, x%0d", cfg.gpr[1]), \
/* Check if the current LPCOUNT0 value == 0, if so, then MEPC=MEPC+4 */ \
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[1], LPCOUNT0), \
$sformatf("beqz x%0d, 4f", cfg.gpr[1]), \
/* Else LPCOUNT0 still >=1 and thus next, */ \
/* Set the next MEPC to LPSTART0 for next HWLOOP iteration */ \
$sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], LPSTART0), \
$sformatf("beqz x0, 5f"), \
/* Default increment for MEPC by 4 */ \
$sformatf("4: csrr x%0d, 0x%0x", cfg.gpr[0], MEPC), \
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]), \
/* Write MEPC */ \
$sformatf("5: csrw 0x%0x, x%0d", MEPC, cfg.gpr[0])


`include "cv32e40p_instr_gen_config.sv"
// Instruction streams specific to CV32E40P
// `include "instr_lib/cv32e40p_load_store_instr_lib.sv"
Expand Down Expand Up @@ -407,5 +472,4 @@ package cv32e40p_instr_test_pkg;
end
endfunction


endpackage : cv32e40p_instr_test_pkg;

0 comments on commit c98ff2a

Please sign in to comment.