diff --git a/vendor/google_riscv-dv.lock.hjson b/vendor/google_riscv-dv.lock.hjson index 6ed5f373..e89e5698 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: 0d2b5b7b8b1cdbce74d9e123a427052b12accd7b + rev: 80d429475138b4b94d863030246a06980c89889d } } diff --git a/vendor/google_riscv-dv/run.py b/vendor/google_riscv-dv/run.py index f0bbe278..c59c7f5d 100644 --- a/vendor/google_riscv-dv/run.py +++ b/vendor/google_riscv-dv/run.py @@ -240,6 +240,45 @@ def gcc_compile(test_list, output_dir, isa, mabi, opts): logging.debug(output) +def run_assembly(asm_test, iss_yaml, isa, mabi, iss): + """Run a directed assembly test with spike + + Args: + asm_tset : Assembly test file + iss_yaml : ISS configuration file in YAML format + isa : ISA variant passed to the ISS + mabi : MABI variant passed to GCC + iss : Instruction set simulators + """ + asm = asm_test + elf = asm_test + ".o" + binary = asm_test + ".bin" + log = asm_test + ".log" + logging.info("Compiling assembly test : %s" % asm) + # gcc comilation + cmd = ("%s -static -mcmodel=medany \ + -fvisibility=hidden -nostdlib \ + -nostartfiles %s \ + -I%s/user_extension \ + -T%s/scripts/link.ld -o %s " % \ + (get_env_var("RISCV_GCC"), asm, get_env_var("RISCV_DV_ROOT"), + get_env_var("RISCV_DV_ROOT"), elf)) + cmd += (" -march=%s" % isa) + cmd += (" -mabi=%s" % mabi) + logging.info("Compiling %s" % asm) + output = subprocess.check_output(cmd.split()) + # Convert the ELF to plain binary, used in RTL sim + logging.info("Converting to %s" % binary) + cmd = ("%s -O binary %s %s" % (get_env_var("RISCV_OBJCOPY"), elf, binary)) + output = subprocess.check_output(cmd.split()) + logging.debug(output) + base_cmd = parse_iss_yaml(iss, iss_yaml, isa) + logging.info("[%0s] Running ISS simulation: %s" % (iss, elf)) + cmd = get_iss_cmd(base_cmd, elf, log) + run_cmd(cmd, 20) + logging.info("[%0s] Running ISS simulation: %s ...done" % (iss, elf)) + + def iss_sim(test_list, output_dir, iss_list, iss_yaml, isa, timeout_s): """Run ISS simulation with the generated test program @@ -372,6 +411,8 @@ def setup_parser(): help="Path for the riscv_core_setting.sv") parser.add_argument("-ext", "--user_extension_dir", type=str, default="", help="Path for the user extension directory") + parser.add_argument("--asm_test", type=str, default="", + help="Directed assembly test") parser.set_defaults(co=False) parser.set_defaults(so=False) parser.set_defaults(verbose=False) @@ -398,6 +439,10 @@ def main(): if not args.testlist: args.testlist = cwd + "/yaml/testlist.yaml" + if args.asm_test != "": + run_assembly(args.asm_test, args.iss_yaml, args.isa, args.mabi, args.iss) + return + # Create output directory if args.o is None: output_dir = "out_" + str(date.today()) diff --git a/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv b/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv index f9471d74..b6ba06a6 100644 --- a/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv +++ b/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv @@ -314,7 +314,7 @@ class riscv_asm_program_gen extends uvm_object; // Generate the user stack section virtual function void gen_stack_section(); instr_stream.push_back(".pushsection .user_stack,\"aw\",@progbits;"); - instr_stream.push_back($sformatf(".align %0d", $clog2(XLEN))); + instr_stream.push_back(".align 12"); instr_stream.push_back("_user_stack_start:"); instr_stream.push_back($sformatf(".rept %0d", cfg.stack_len - 1)); instr_stream.push_back($sformatf(".%0dbyte 0x0", XLEN/8)); @@ -327,7 +327,7 @@ class riscv_asm_program_gen extends uvm_object; // The kernal stack is used to save user program context before executing exception handling virtual function void gen_kernel_stack_section(); instr_stream.push_back(".pushsection .kernel_stack,\"aw\",@progbits;"); - instr_stream.push_back($sformatf(".align %0d", $clog2(XLEN))); + instr_stream.push_back(".align 12"); instr_stream.push_back("_kernel_stack_start:"); instr_stream.push_back($sformatf(".rept %0d", cfg.kernel_stack_len - 1)); instr_stream.push_back($sformatf(".%0dbyte 0x0", XLEN/8)); @@ -636,6 +636,12 @@ class riscv_asm_program_gen extends uvm_object; gen_ecall_handler(); // Illegal instruction handler gen_illegal_instr_handler(); + // Instruction fault handler + gen_instr_fault_handler(); + // Load fault handler + gen_load_fault_handler(); + // Store fault handler + gen_store_fault_handler(); // Generate page table fault handling routine // Page table fault is always handled in machine mode, as virtual address translation may be // broken when page fault happens. @@ -707,11 +713,11 @@ class riscv_asm_program_gen extends uvm_object; "beq a1, a2, ecall_handler", // Page table fault or access fault conditions $sformatf("li a2, 0x%0x", INSTRUCTION_ACCESS_FAULT), - "beq a1, a2, 1f", + "beq a1, a2, instr_fault_handler", $sformatf("li a2, 0x%0x", LOAD_ACCESS_FAULT), - "beq a1, a2, 1f", + "beq a1, a2, load_fault_handler", $sformatf("li a2, 0x%0x", STORE_AMO_ACCESS_FAULT), - "beq a1, a2, 1f", + "beq a1, a2, store_fault_handler", $sformatf("li a2, 0x%0x", INSTRUCTION_PAGE_FAULT), "beq a1, a2, pt_fault_handler", $sformatf("li a2, 0x%0x", LOAD_PAGE_FAULT), @@ -827,6 +833,36 @@ class riscv_asm_program_gen extends uvm_object; gen_section("illegal_instr_handler", instr); endfunction + // TODO: handshake correct csr based on delegation + virtual function void gen_instr_fault_handler(); + string instr[$]; + gen_signature_handshake(instr, CORE_STATUS, INSTR_FAULT_EXCEPTION); + gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE)); + pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, instr); + instr.push_back("mret"); + gen_section("instr_fault_handler", instr); + endfunction + + // TODO: handshake correct csr based on delegation + virtual function void gen_load_fault_handler(); + string instr[$]; + gen_signature_handshake(instr, CORE_STATUS, LOAD_FAULT_EXCEPTION); + gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE)); + pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, instr); + instr.push_back("mret"); + gen_section("load_fault_handler", instr); + endfunction + + // TODO: handshake correct csr based on delegation + virtual function void gen_store_fault_handler(); + string instr[$]; + gen_signature_handshake(instr, CORE_STATUS, STORE_FAULT_EXCEPTION); + gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE)); + pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, instr); + instr.push_back("mret"); + gen_section("store_fault_handler", instr); + endfunction + //--------------------------------------------------------------------------------------- // Page table setup //--------------------------------------------------------------------------------------- diff --git a/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv b/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv index 482e5f9b..38358328 100644 --- a/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv +++ b/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv @@ -168,7 +168,7 @@ class riscv_jump_instr extends riscv_rand_instr_stream; riscv_instr_base instr[]; `DV_CHECK_RANDOMIZE_WITH_FATAL(jump, (use_jalr) -> (instr_name == JALR); - instr_name dist {JAL := 1, JALR := 1}; + instr_name dist {JAL := 1, JALR := 9}; rd == RA; rs1 == gpr; ) diff --git a/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv b/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv index bbc36384..9dba46f9 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv @@ -49,9 +49,9 @@ class riscv_instr_gen_config extends uvm_object; // Priviledged mode after boot rand privileged_mode_t init_privileged_mode; - rand bit[XLEN-1:0] mstatus, mie, - sstatus, sie, - ustatus, uie; + rand bit[XLEN-1:0] mstatus, mie, + sstatus, sie, + ustatus, uie; // Key fields in xSTATUS // Memory protection bits @@ -286,7 +286,7 @@ class riscv_instr_gen_config extends uvm_object; // You can modify this constraint if your ISS support different set of delegations constraint delegation_c { foreach(m_mode_exception_delegation[i]) { - if(!support_supervisor_mode) { + if(!support_supervisor_mode || no_delegation) { m_mode_exception_delegation[i] == 0; } if(!(i inside {INSTRUCTION_ADDRESS_MISALIGNED, BREAKPOINT, ECALL_UMODE, @@ -295,7 +295,7 @@ class riscv_instr_gen_config extends uvm_object; } } foreach(m_mode_interrupt_delegation[i]) { - if(!support_supervisor_mode) { + if(!support_supervisor_mode || no_delegation) { m_mode_interrupt_delegation[i] == 0; } if(!(i inside {S_SOFTWARE_INTR, S_TIMER_INTR, S_EXTERNAL_INTR})) { diff --git a/vendor/google_riscv-dv/src/riscv_privileged_common_seq.sv b/vendor/google_riscv-dv/src/riscv_privileged_common_seq.sv index 1798dc82..ce362535 100644 --- a/vendor/google_riscv-dv/src/riscv_privileged_common_seq.sv +++ b/vendor/google_riscv-dv/src/riscv_privileged_common_seq.sv @@ -55,10 +55,8 @@ class riscv_privileged_common_seq extends uvm_sequence; virtual function void setup_mmode_reg(privileged_mode_t mode, ref riscv_privil_reg regs[$]); mstatus = riscv_privil_reg::type_id::create("mstatus"); mstatus.init_reg(MSTATUS); - `uvm_info(`gfn, $sformatf("mstatus_val: 0x%0x", cfg.mstatus), UVM_LOW) mstatus.set_val({cfg.mstatus[XLEN-1:XLEN-21], cfg.mstatus_tvm, cfg.mstatus_mxr, cfg.mstatus_sum, cfg.mstatus_mprv, cfg.mstatus[16:0]}); - `DV_CHECK_RANDOMIZE_FATAL(mstatus, "cannot randomize mstatus"); if(XLEN==64) begin mstatus.set_field("UXL", 2'b10); mstatus.set_field("SXL", 2'b10); @@ -80,6 +78,7 @@ class riscv_privileged_common_seq extends uvm_sequence; mstatus.set_field("SIE", cfg.enable_interrupt); mstatus.set_field("UPIE", cfg.enable_interrupt); mstatus.set_field("UIE", riscv_instr_pkg::support_umode_trap); + `uvm_info(`gfn, $sformatf("mstatus_val: 0x%0x", mstatus.get_val()), UVM_LOW) regs.push_back(mstatus); // Enable external and timer interrupt if (MIE inside {implemented_csr}) begin diff --git a/vendor/google_riscv-dv/src/riscv_signature_pkg.sv b/vendor/google_riscv-dv/src/riscv_signature_pkg.sv index c213b242..3a4c4205 100644 --- a/vendor/google_riscv-dv/src/riscv_signature_pkg.sv +++ b/vendor/google_riscv-dv/src/riscv_signature_pkg.sv @@ -44,7 +44,10 @@ package riscv_signature_pkg; HANDLING_IRQ, FINISHED_IRQ, HANDLING_EXCEPTION, + INSTR_FAULT_EXCEPTION, ILLEGAL_INSTR_EXCEPTION, + LOAD_FAULT_EXCEPTION, + STORE_FAULT_EXCEPTION, EBREAK_EXCEPTION } core_status_t; diff --git a/vendor/google_riscv-dv/test/riscv_instr_base_test.sv b/vendor/google_riscv-dv/test/riscv_instr_base_test.sv index a4dfbb2d..40ca998c 100644 --- a/vendor/google_riscv-dv/test/riscv_instr_base_test.sv +++ b/vendor/google_riscv-dv/test/riscv_instr_base_test.sv @@ -97,13 +97,13 @@ class riscv_instr_base_test extends uvm_test; for(int i = 0; i < cfg.num_of_tests; i++) begin string test_name; randomize_cfg(); + cfg.build_instruction_template(); asm_gen = riscv_asm_program_gen::type_id::create("asm_gen"); get_directed_instr_stream_opts(); asm_gen.cfg = cfg; test_name = $sformatf("%0s_%0d.S", asm_file_name, i); apply_directed_instr(); `uvm_info(`gfn, "All directed instruction is applied", UVM_LOW) - cfg.build_instruction_template(); asm_gen.gen_program(); asm_gen.gen_test_file(test_name); end