diff --git a/dv/cosim/spike_cosim.cc b/dv/cosim/spike_cosim.cc index c4eda95a16..daa400709b 100644 --- a/dv/cosim/spike_cosim.cc +++ b/dv/cosim/spike_cosim.cc @@ -331,7 +331,7 @@ bool SpikeCosim::check_retired_instr(uint32_t write_reg, std::stringstream err_str; err_str << "PC mismatch, DUT retired : " << std::hex << dut_pc << " , but the ISS retired: " << std::hex - << processor->get_state()->last_inst_pc; + << (processor->get_state()->last_inst_pc & 0xffffffff); errors.emplace_back(err_str.str()); return false; } diff --git a/dv/uvm/core_ibex/riscv_dv_extension/ibex_directed_instr_lib.sv b/dv/uvm/core_ibex/riscv_dv_extension/ibex_directed_instr_lib.sv index aeebfd0ef5..8dd96e18a4 100644 --- a/dv/uvm/core_ibex/riscv_dv_extension/ibex_directed_instr_lib.sv +++ b/dv/uvm/core_ibex/riscv_dv_extension/ibex_directed_instr_lib.sv @@ -79,7 +79,7 @@ class ibex_rand_mseccfg_stream extends riscv_directed_instr_stream; csrrw_instr = riscv_instr::get_instr(CSRRWI); csrrw_instr.atomic = 1'b0; csrrw_instr.csr = MSECCFG; - csrrw_instr.rd = '0; + csrrw_instr.rd = ZERO; // Randomize between 3'b000 and 3'b111 to hit every combination of RLB/MMWP/MML bits. csrrw_instr.imm_str = $sformatf("0x%0x", $urandom_range(7,0)); instr_list = {csrrw_instr}; @@ -159,7 +159,7 @@ class ibex_rand_cpuctrlsts_stream extends riscv_directed_instr_stream; instrs[3] = riscv_instr::get_instr(CSRRW); instrs[3].atomic = 1'b0; instrs[3].csr = 12'h7c0; - instrs[3].rd = '0; + instrs[3].rd = ZERO; instrs[3].rs1 = cfg.gpr[0]; instr_list = instrs; @@ -191,7 +191,7 @@ class ibex_valid_na4_stream extends riscv_directed_instr_stream; cfg_csrrw_instr.atomic = 1'b1; cfg_csrrw_instr.has_label = 1'b0; cfg_csrrw_instr.csr = PMPCFG0; - cfg_csrrw_instr.rd = '0; + cfg_csrrw_instr.rd = ZERO; cfg_csrrw_instr.imm_str = $sformatf("%0d", $urandom_range(16,23)); // Use a label to use it for setting pmpaddr CSR. @@ -222,7 +222,7 @@ class ibex_valid_na4_stream extends riscv_directed_instr_stream; addr_csrrw_instr.atomic = 1'b1; addr_csrrw_instr.csr = PMPADDR0; addr_csrrw_instr.rs1 = cfg.gpr[1]; - addr_csrrw_instr.rd = '0; + addr_csrrw_instr.rd = ZERO; instr_list = {cfg_csrrw_instr, nop_instr, la_instr, srli_instr, addr_csrrw_instr}; endfunction @@ -395,7 +395,7 @@ class ibex_make_pmp_region_exec_stream extends riscv_directed_instr_stream; instrs[5] = riscv_instr::get_instr(CSRRW); instrs[5].atomic = 1'b0; instrs[5].csr = PMPCFG0 + pmpcfg_num; - instrs[5].rd = '0; + instrs[5].rd = ZERO; instrs[5].rs1 = cfg.gpr[2]; // Immediately read back what we wrote, to check it has been dealt with correctly (i.e. write @@ -404,7 +404,7 @@ class ibex_make_pmp_region_exec_stream extends riscv_directed_instr_stream; instrs[6].atomic = 1'b0; instrs[6].csr = PMPCFG0 + pmpcfg_num; instrs[6].rd = cfg.gpr[0]; - instrs[6].rs1 = 0; + instrs[6].rs1 = ZERO; instr_list = instrs; diff --git a/dv/uvm/core_ibex/riscv_dv_extension/riscv_core_setting.tpl.sv b/dv/uvm/core_ibex/riscv_dv_extension/riscv_core_setting.tpl.sv index 15b1e697c9..fff0a1af17 100644 --- a/dv/uvm/core_ibex/riscv_dv_extension/riscv_core_setting.tpl.sv +++ b/dv/uvm/core_ibex/riscv_dv_extension/riscv_core_setting.tpl.sv @@ -131,8 +131,8 @@ const privileged_reg_t implemented_csr[] = { MTVAL, // Machine bad address or instruction MIE, // Machine interrupt enable MIP, // Machine interrupt pending - 12'h7c0, // CPU Control and Status (Ibex Specific) - 12'h7c1, // Secure Seed (Ibex Specific) + CPUCTRLSTS, // CPU Control and Status (Ibex Specific) + SECURESEED, // Secure Seed (Ibex Specific) MCYCLE, // Machine cycle counter (lower 32 bits) MCYCLEH, // Machine cycle counter (upper 32 bits) //MINSTRET, // Machine instructions retired counter (lower 32 bits) diff --git a/dv/uvm/core_ibex/scripts/run_instr_gen.py b/dv/uvm/core_ibex/scripts/run_instr_gen.py index 2dedd676bc..23d5325137 100755 --- a/dv/uvm/core_ibex/scripts/run_instr_gen.py +++ b/dv/uvm/core_ibex/scripts/run_instr_gen.py @@ -65,6 +65,11 @@ def reloc_word(simulator: str, # For Xcelium, the build directory gets passed as the # "-xmlibdirpath" argument. (placeholder_dir, build_dir) + ], + 'dsim': [ + # DSim build path + (os.path.join(placeholder_dir, 'dsim'), + os.path.join(build_dir, 'dsim')) ] } always_relocs = [ diff --git a/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv b/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv index 4f7f4b19c7..ba65f4a2f6 100644 --- a/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv +++ b/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv @@ -326,6 +326,7 @@ module core_ibex_tb_top; initial begin // Drive the clock and reset lines. Reset everything and start the clock at the beginning of // time + #0; // needed for dsim ibex_clk_if.set_active(); fork ibex_clk_if.apply_reset(.reset_width_clks (100)); diff --git a/dv/uvm/core_ibex/tests/core_ibex_base_test.sv b/dv/uvm/core_ibex/tests/core_ibex_base_test.sv index abf8ff766e..47847ad671 100644 --- a/dv/uvm/core_ibex/tests/core_ibex_base_test.sv +++ b/dv/uvm/core_ibex/tests/core_ibex_base_test.sv @@ -27,8 +27,8 @@ class core_ibex_base_test extends uvm_test; // code, the test will wait for the specified number of cycles before starting stimulus // sequences (irq and debug) int unsigned stimulus_delay = 800; - bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] signature_data_q[$]; - bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] signature_data; + bit[ibex_mem_intf_pkg::DATA_WIDTH-1:0] signature_data_q[$]; + bit[ibex_mem_intf_pkg::DATA_WIDTH-1:0] signature_data; uvm_tlm_analysis_fifo #(ibex_mem_intf_seq_item) item_collected_port; uvm_tlm_analysis_fifo #(ibex_mem_intf_seq_item) test_done_port; uvm_tlm_analysis_fifo #(irq_seq_item) irq_collected_port; @@ -402,7 +402,7 @@ class core_ibex_base_test extends uvm_test; virtual task wait_for_mem_txn( - input bit [ibex_mem_intf_agent_pkg::ADDR_WIDTH-1:0] ref_addr, + input bit [ibex_mem_intf_pkg::ADDR_WIDTH-1:0] ref_addr, input signature_type_t ref_type, input uvm_tlm_analysis_fifo #(ibex_mem_intf_seq_item) txn_port = item_collected_port ); diff --git a/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv b/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv index 526dfbd552..f7b0d8aaf3 100644 --- a/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv +++ b/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv @@ -755,17 +755,17 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test; `uvm_component_utils(core_ibex_debug_intr_basic_test) `uvm_component_new - bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] core_init_mstatus; - bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] core_init_mie; + bit [ibex_mem_intf_pkg::DATA_WIDTH-1:0] core_init_mstatus; + bit [ibex_mem_intf_pkg::DATA_WIDTH-1:0] core_init_mie; priv_lvl_e init_operating_mode; priv_lvl_e operating_mode; bit [$clog2(irq_agent_pkg::DATA_WIDTH)-1:0] irq_id; irq_seq_item irq_txn; bit [irq_agent_pkg::DATA_WIDTH-1:0] irq; - bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] mstatus; - bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] mcause; - bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] mip; - bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] mie; + bit [ibex_mem_intf_pkg::DATA_WIDTH-1:0] mstatus; + bit [ibex_mem_intf_pkg::DATA_WIDTH-1:0] mcause; + bit [ibex_mem_intf_pkg::DATA_WIDTH-1:0] mip; + bit [ibex_mem_intf_pkg::DATA_WIDTH-1:0] mie; bit in_nested_trap; virtual task send_stimulus(); @@ -966,14 +966,14 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test; return have_irq; endfunction - virtual task check_mcause(bit irq_or_exc, bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-2:0] cause); - bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] mcause; + virtual task check_mcause(bit irq_or_exc, bit[ibex_mem_intf_pkg::DATA_WIDTH-2:0] cause); + bit[ibex_mem_intf_pkg::DATA_WIDTH-1:0] mcause; wait_for_csr_write(CSR_MCAUSE, 10000); mcause = signature_data; `uvm_info(`gfn, $sformatf("mcause: 0x%0x", mcause), UVM_LOW) - `DV_CHECK_EQ_FATAL(mcause[ibex_mem_intf_agent_pkg::DATA_WIDTH-1], irq_or_exc, + `DV_CHECK_EQ_FATAL(mcause[ibex_mem_intf_pkg::DATA_WIDTH-1], irq_or_exc, $sformatf("mcause.interrupt is not set to 0x%0x", irq_or_exc)) - `DV_CHECK_EQ_FATAL(mcause[ibex_mem_intf_agent_pkg::DATA_WIDTH-2:0], cause, + `DV_CHECK_EQ_FATAL(mcause[ibex_mem_intf_pkg::DATA_WIDTH-2:0], cause, "mcause.exception_code is encoding the wrong exception type") endtask @@ -1161,7 +1161,7 @@ class core_ibex_directed_test extends core_ibex_debug_intr_basic_test; // currently in the ID stage against the global seen_instr[$] queue. // If we've seen the same type of instruction before, return 0, otherwise add it to the // seen_instr[$] queue and return 1. - virtual function bit decode_instr(bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] instr); + virtual function bit decode_instr(bit [ibex_mem_intf_pkg::DATA_WIDTH-1:0] instr); ibex_pkg::opcode_e opcode; bit [2:0] funct3; bit [6:0] funct7; @@ -1670,8 +1670,8 @@ class core_ibex_debug_ebreak_test extends core_ibex_directed_test; `uvm_component_utils(core_ibex_debug_ebreak_test) `uvm_component_new - bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] dpc; - bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] dcsr; + bit[ibex_mem_intf_pkg::DATA_WIDTH-1:0] dpc; + bit[ibex_mem_intf_pkg::DATA_WIDTH-1:0] dcsr; virtual task check_stimulus(); forever begin @@ -1885,7 +1885,7 @@ class core_ibex_umode_tw_test extends core_ibex_directed_test; `uvm_component_new virtual task check_stimulus(); - bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] mcause; + bit [ibex_mem_intf_pkg::DATA_WIDTH-1:0] mcause; forever begin wait (dut_vif.dut_cb.wfi === 1'b1); check_illegal_insn("Core did not treat U-mode WFI as illegal"); diff --git a/dv/uvm/core_ibex/tests/core_ibex_vseq.sv b/dv/uvm/core_ibex/tests/core_ibex_vseq.sv index 0e54aa1cea..0809d4da30 100644 --- a/dv/uvm/core_ibex/tests/core_ibex_vseq.sv +++ b/dv/uvm/core_ibex/tests/core_ibex_vseq.sv @@ -19,7 +19,7 @@ class core_ibex_vseq extends uvm_sequence; debug_seq debug_seq_single_h; fetch_enable_seq fetch_enable_seq_h; core_ibex_env_cfg cfg; - bit[ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] data; + bit[ibex_mem_intf_pkg::DATA_WIDTH-1:0] data; `uvm_object_utils(core_ibex_vseq) `uvm_declare_p_sequencer(core_ibex_vseqr) diff --git a/dv/uvm/core_ibex/yaml/rtl_simulation.yaml b/dv/uvm/core_ibex/yaml/rtl_simulation.yaml index d937d10610..d62b84c6fa 100644 --- a/dv/uvm/core_ibex/yaml/rtl_simulation.yaml +++ b/dv/uvm/core_ibex/yaml/rtl_simulation.yaml @@ -129,7 +129,7 @@ ############################################################ - tool: dsim - env_var: DSIM,DSIM_LIB_PATH + env_var: DSIM,DSIM_LIB_PATH,IBEX_ROOT compile: cmd: - >- @@ -142,11 +142,21 @@ $UVM_HOME/src/uvm_pkg.sv +define+UVM +define+DSIM + +define+UVM_REGEX_NO_DPI +acc+rwb -f /ibex_dv_defines.f -f /ibex_dv.f -l - -suppress EnumMustBePositive" + -suppress EnumMustBePositive + + + # dsim does not link image.so with ISS_LDFLAGS and ISS_LIBS, so symbols are missing + # so we need to re-link image.so with the linker flags and libraries + - gcc -shared -Bsymbolic -o /image.so @/obj/objfiles -lstdc++ + cosim_opts: >- + -f /ibex_dv_cosim_dpi.f + -ld-opts ' -lstdc++' + -c-opts ' -lstdc++ -I/dv/cosim' sim: cmd: - >- diff --git a/rtl/ibex_core.sv b/rtl/ibex_core.sv index 6700244559..b5ff81acec 100644 --- a/rtl/ibex_core.sv +++ b/rtl/ibex_core.sv @@ -1591,9 +1591,28 @@ module ibex_core import ibex_pkg::*; #( rvfi_ext_stage_debug_req[i+1] <= '0; rvfi_ext_stage_debug_mode[i] <= '0; rvfi_ext_stage_mcycle[i] <= '0; - rvfi_ext_stage_mhpmcounters[i] <= '{10{'0}}; - rvfi_ext_stage_mhpmcountersh[i] <= '{10{'0}}; rvfi_ext_stage_ic_scr_key_valid[i] <= '0; + // DSim does not properly support array assignment in for loop, so unroll + rvfi_ext_stage_mhpmcounters[i][0] <= '0; + rvfi_ext_stage_mhpmcountersh[i][0] <= '0; + rvfi_ext_stage_mhpmcounters[i][1] <= '0; + rvfi_ext_stage_mhpmcountersh[i][1] <= '0; + rvfi_ext_stage_mhpmcounters[i][2] <= '0; + rvfi_ext_stage_mhpmcountersh[i][2] <= '0; + rvfi_ext_stage_mhpmcounters[i][3] <= '0; + rvfi_ext_stage_mhpmcountersh[i][3] <= '0; + rvfi_ext_stage_mhpmcounters[i][4] <= '0; + rvfi_ext_stage_mhpmcountersh[i][4] <= '0; + rvfi_ext_stage_mhpmcounters[i][5] <= '0; + rvfi_ext_stage_mhpmcountersh[i][5] <= '0; + rvfi_ext_stage_mhpmcounters[i][6] <= '0; + rvfi_ext_stage_mhpmcountersh[i][6] <= '0; + rvfi_ext_stage_mhpmcounters[i][7] <= '0; + rvfi_ext_stage_mhpmcountersh[i][7] <= '0; + rvfi_ext_stage_mhpmcounters[i][8] <= '0; + rvfi_ext_stage_mhpmcountersh[i][8] <= '0; + rvfi_ext_stage_mhpmcounters[i][9] <= '0; + rvfi_ext_stage_mhpmcountersh[i][9] <= '0; end else begin rvfi_stage_valid[i] <= rvfi_stage_valid_d[i]; @@ -1624,12 +1643,27 @@ module ibex_core import ibex_pkg::*; #( rvfi_ext_stage_debug_mode[i] <= debug_mode; rvfi_ext_stage_mcycle[i] <= cs_registers_i.mcycle_counter_i.counter_val_o; rvfi_ext_stage_ic_scr_key_valid[i] <= cs_registers_i.cpuctrlsts_ic_scr_key_valid_q; - // This is done this way because SystemVerilog does not support looping through - // gen_cntrs[k] within a for loop. - for (int k=0; k < 10; k++) begin - rvfi_ext_stage_mhpmcounters[i][k] <= cs_registers_i.mhpmcounter[k+3][31:0]; - rvfi_ext_stage_mhpmcountersh[i][k] <= cs_registers_i.mhpmcounter[k+3][63:32]; - end + // DSim does not properly support array assignment in for loop, so unroll + rvfi_ext_stage_mhpmcounters[i][0] <= cs_registers_i.mhpmcounter[3][31:0]; + rvfi_ext_stage_mhpmcountersh[i][0] <= cs_registers_i.mhpmcounter[3][63:32]; + rvfi_ext_stage_mhpmcounters[i][1] <= cs_registers_i.mhpmcounter[4][31:0]; + rvfi_ext_stage_mhpmcountersh[i][1] <= cs_registers_i.mhpmcounter[4][63:32]; + rvfi_ext_stage_mhpmcounters[i][2] <= cs_registers_i.mhpmcounter[5][31:0]; + rvfi_ext_stage_mhpmcountersh[i][2] <= cs_registers_i.mhpmcounter[5][63:32]; + rvfi_ext_stage_mhpmcounters[i][3] <= cs_registers_i.mhpmcounter[6][31:0]; + rvfi_ext_stage_mhpmcountersh[i][3] <= cs_registers_i.mhpmcounter[6][63:32]; + rvfi_ext_stage_mhpmcounters[i][4] <= cs_registers_i.mhpmcounter[7][31:0]; + rvfi_ext_stage_mhpmcountersh[i][4] <= cs_registers_i.mhpmcounter[7][63:32]; + rvfi_ext_stage_mhpmcounters[i][5] <= cs_registers_i.mhpmcounter[8][31:0]; + rvfi_ext_stage_mhpmcountersh[i][5] <= cs_registers_i.mhpmcounter[8][63:32]; + rvfi_ext_stage_mhpmcounters[i][6] <= cs_registers_i.mhpmcounter[9][31:0]; + rvfi_ext_stage_mhpmcountersh[i][6] <= cs_registers_i.mhpmcounter[9][63:32]; + rvfi_ext_stage_mhpmcounters[i][7] <= cs_registers_i.mhpmcounter[10][31:0]; + rvfi_ext_stage_mhpmcountersh[i][7] <= cs_registers_i.mhpmcounter[10][63:32]; + rvfi_ext_stage_mhpmcounters[i][8] <= cs_registers_i.mhpmcounter[11][31:0]; + rvfi_ext_stage_mhpmcountersh[i][8] <= cs_registers_i.mhpmcounter[11][63:32]; + rvfi_ext_stage_mhpmcounters[i][9] <= cs_registers_i.mhpmcounter[12][31:0]; + rvfi_ext_stage_mhpmcountersh[i][9] <= cs_registers_i.mhpmcounter[12][63:32]; end // Some of the rvfi_ext_* signals are used to provide an interrupt notification (signalled diff --git a/util/ibex_config.py b/util/ibex_config.py index 8f653a836c..092316fd85 100755 --- a/util/ibex_config.py +++ b/util/ibex_config.py @@ -271,11 +271,11 @@ def main(): lambda p, v: [], lambda d, v: ['+define+' + d + '=' + v], '/'), SimOpts('xlm_opts', 'Xcelium compile', - lambda p, v: ['-defparam', p + '=' + v], + lambda p, v: ['-defparam', p + '=' + v], lambda d, v: ['-define', d + '=' + v], '.'), - SimOpts('dsim_compile_opts', 'DSim compile', - lambda p, v: ['+define+' + p + '=' + v], - lambda d, v: [], '/'), + SimOpts('dsim_opts', 'DSim compile', + lambda p, v: ['-defparam', p + '=' + v], + lambda d, v: ['+define+' + d + '=' + v], '.'), ] argparser = argparse.ArgumentParser(description=( diff --git a/vendor/google_riscv-dv/euvm/riscv/gen/riscv_instr_pkg.d b/vendor/google_riscv-dv/euvm/riscv/gen/riscv_instr_pkg.d index b92879570d..0ff7bcdbcc 100644 --- a/vendor/google_riscv-dv/euvm/riscv/gen/riscv_instr_pkg.d +++ b/vendor/google_riscv-dv/euvm/riscv/gen/riscv_instr_pkg.d @@ -1102,7 +1102,10 @@ enum privileged_reg_t: ushort { // 12'b VXRM = 0x00A, // Fixed point rounding mode VL = 0xC20, // Vector length VTYPE = 0xC21, // Vector data type register - VLENB = 0xC22 // VLEN/8 (vector register length in bytes) + VLENB = 0xC22, // VLEN/8 (vector register length in bytes) + // Ibex Registers + CPUCTRLSTS = 0x7C0, // CPU Control and Status (Ibex Specific) + SECURESEED = 0x7C1 // Secure Seed (Ibex Specific) } enum privileged_reg_fld_t: ubyte { diff --git a/vendor/google_riscv-dv/src/riscv_instr_pkg.sv b/vendor/google_riscv-dv/src/riscv_instr_pkg.sv index 96207667a4..12f248b74e 100644 --- a/vendor/google_riscv-dv/src/riscv_instr_pkg.sv +++ b/vendor/google_riscv-dv/src/riscv_instr_pkg.sv @@ -1097,7 +1097,10 @@ package riscv_instr_pkg; VXRM = 'h00A, // Fixed point rounding mode VL = 'hC20, // Vector length VTYPE = 'hC21, // Vector data type register - VLENB = 'hC22 // VLEN/8 (vector register length in bytes) + VLENB = 'hC22, // VLEN/8 (vector register length in bytes) + // Ibex Registers + CPUCTRLSTS = 'h7C0, // CPU Control and Status (Ibex Specific) + SECURESEED = 'h7C1 // Secure Seed (Ibex Specific) } privileged_reg_t; typedef enum bit [5:0] {