mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
Add dsim support (#328)
This commit is contained in:
parent
2ce4bfa150
commit
e7123f1c2d
9 changed files with 94 additions and 54 deletions
|
@ -75,6 +75,7 @@ CSR_OPTS=--csr_yaml=${CSR_FILE} \
|
|||
--lsf_cmd="${LSF_CMD}" \
|
||||
--core_setting_dir=${DV_DIR}/riscv_dv_extension \
|
||||
--user_extension_dir=${DV_DIR}/riscv_dv_extension \
|
||||
--simulator=${SIMULATOR} \
|
||||
${COMMON_OPTS} \
|
||||
${CSR_OPTS} \
|
||||
--sim_opts="+uvm_set_type_override=riscv_asm_program_gen,ibex_asm_program_gen \
|
||||
|
|
|
@ -61,16 +61,19 @@ class ibex_mem_intf_slave_driver extends uvm_driver #(ibex_mem_intf_seq_item);
|
|||
virtual protected task send_grant();
|
||||
int gnt_delay;
|
||||
forever begin
|
||||
vif.grant = 1'b1;
|
||||
while(vif.request !== 1'b1) begin
|
||||
@(negedge vif.clock);
|
||||
end
|
||||
std::randomize(gnt_delay) with {
|
||||
if (!std::randomize(gnt_delay) with {
|
||||
gnt_delay dist {
|
||||
min_grant_delay :/ 1,
|
||||
[min_grant_delay+1 : max_grant_delay-1] :/ 1,
|
||||
max_grant_delay :/ 1
|
||||
};
|
||||
};
|
||||
}) begin
|
||||
`uvm_fatal(`gfn, $sformatf("Cannot randomize grant"))
|
||||
end
|
||||
repeat(gnt_delay) @(negedge vif.clock);
|
||||
if(~vif.reset) begin
|
||||
vif.grant = 1'b1;
|
||||
|
|
|
@ -25,7 +25,7 @@ class ibex_mem_intf_slave_seq extends uvm_sequence #(ibex_mem_intf_seq_item);
|
|||
bit [ADDR_WIDTH-1:0] aligned_addr;
|
||||
p_sequencer.addr_ph_port.get(item);
|
||||
req = ibex_mem_intf_seq_item::type_id::create("req");
|
||||
req.randomize() with {
|
||||
if (!req.randomize() with {
|
||||
addr == item.addr;
|
||||
read_write == item.read_write;
|
||||
data == item.data;
|
||||
|
@ -36,7 +36,9 @@ class ibex_mem_intf_slave_seq extends uvm_sequence #(ibex_mem_intf_seq_item);
|
|||
[max_rvalid_delay/2 : max_rvalid_delay-1] :/ 1,
|
||||
max_rvalid_delay :/ 1
|
||||
};
|
||||
};
|
||||
}) begin
|
||||
`uvm_fatal(`gfn, "Cannot randomize slave request")
|
||||
end
|
||||
aligned_addr = {req.addr[DATA_WIDTH-1:2], 2'b0};
|
||||
if(req.read_write == READ) begin : READ_block
|
||||
req.data = m_mem.read(aligned_addr);
|
||||
|
|
|
@ -23,7 +23,7 @@ class mem_model#(Addr_width = 32, Data_width = 32) extends uvm_object;
|
|||
$sformatf("Read Mem : Addr[0x%0h], Data[0x%0h]", addr, data), UVM_HIGH)
|
||||
end
|
||||
else begin
|
||||
std::randomize(data);
|
||||
void'(std::randomize(data));
|
||||
`uvm_error(get_full_name(), $sformatf("read to uninitialzed addr 0x%0h", addr))
|
||||
end
|
||||
return data;
|
||||
|
|
|
@ -89,13 +89,22 @@ def get_simulator_cmd(simulator, simulator_yaml, en_cov, en_wave):
|
|||
logging.info("Found matching simulator: %s" % entry['tool'])
|
||||
compile_cmd = entry['compile']['cmd']
|
||||
for i in range(len(compile_cmd)):
|
||||
compile_cmd[i] = process_cmd("<cov_opts>", compile_cmd[i],
|
||||
entry['compile']['cov_opts'], en_cov)
|
||||
compile_cmd[i] = process_cmd("<wave_opts>", compile_cmd[i],
|
||||
entry['compile']['wave_opts'], en_wave)
|
||||
if 'cov_opts' in entry['compile']:
|
||||
compile_cmd[i] = process_cmd("<cov_opts>", compile_cmd[i],
|
||||
entry['compile']['cov_opts'], en_cov)
|
||||
if 'wave_opts' in entry['compile']:
|
||||
compile_cmd[i] = process_cmd("<wave_opts>", compile_cmd[i],
|
||||
entry['compile']['wave_opts'], en_wave)
|
||||
sim_cmd = entry['sim']['cmd']
|
||||
sim_cmd = process_cmd("<cov_opts>", sim_cmd, entry['sim']['cov_opts'], en_cov)
|
||||
sim_cmd = process_cmd("<wave_opts>", sim_cmd, entry['sim']['wave_opts'], en_wave)
|
||||
if 'cov_opts' in entry['sim']:
|
||||
sim_cmd = process_cmd("<cov_opts>", sim_cmd, entry['sim']['cov_opts'], en_cov)
|
||||
if 'wave_opts' in entry['sim']:
|
||||
sim_cmd = process_cmd("<wave_opts>", sim_cmd, entry['sim']['wave_opts'], en_wave)
|
||||
if 'env_var' in entry:
|
||||
for env_var in entry['env_var'].split(','):
|
||||
for i in range(len(compile_cmd)):
|
||||
compile_cmd[i] = re.sub("<"+env_var+">", get_env_var(env_var), compile_cmd[i])
|
||||
sim_cmd = re.sub("<"+env_var+">", get_env_var(env_var), sim_cmd)
|
||||
return compile_cmd, sim_cmd
|
||||
logging.info("Cannot find RTL simulator %0s" % simulator)
|
||||
sys.exit(1)
|
||||
|
|
|
@ -5,14 +5,17 @@
|
|||
module core_ibex_tb_top;
|
||||
|
||||
import uvm_pkg::*;
|
||||
import core_ibex_test_pkg::*;
|
||||
|
||||
logic clk;
|
||||
logic rst_n;
|
||||
logic fetch_enable;
|
||||
logic debug_req;
|
||||
|
||||
clk_if ibex_clk_if(.clk(clk));
|
||||
irq_if irq_vif();
|
||||
clk_if ibex_clk_if(.clk(clk));
|
||||
irq_if irq_vif();
|
||||
ibex_mem_intf data_mem_vif();
|
||||
ibex_mem_intf instr_mem_vif();
|
||||
|
||||
|
||||
// DUT probe interface
|
||||
core_ibex_dut_probe_if dut_if(.clk(clk));
|
||||
|
@ -25,44 +28,41 @@ module core_ibex_tb_top;
|
|||
.test_en_i(1'b1),
|
||||
.hart_id_i(32'b0),
|
||||
.boot_addr_i(`BOOT_ADDR), // align with spike boot address
|
||||
.debug_req_i(debug_req),
|
||||
.irq_software_i(irq_if.irq_software),
|
||||
.irq_timer_i(irq_if.irq_timer),
|
||||
.irq_external_i(irq_if.irq_external),
|
||||
.irq_fast_i(irq_if.irq_fast),
|
||||
.irq_nm_i(irq_if.irq_nm),
|
||||
.irq_software_i(irq_vif.irq_software),
|
||||
.irq_timer_i(irq_vif.irq_timer),
|
||||
.irq_external_i(irq_vif.irq_external),
|
||||
.irq_fast_i(irq_vif.irq_fast),
|
||||
.irq_nm_i(irq_vif.irq_nm),
|
||||
.fetch_enable_i(dut_if.fetch_enable),
|
||||
.debug_req_i(dut_if.debug_req)
|
||||
.debug_req_i(dut_if.debug_req),
|
||||
.data_gnt_i(data_mem_vif.grant),
|
||||
.data_rvalid_i(data_mem_vif.rvalid),
|
||||
.data_rdata_i(data_mem_vif.rdata),
|
||||
.data_err_i(0),
|
||||
.instr_gnt_i(instr_mem_vif.grant),
|
||||
.instr_rvalid_i(instr_mem_vif.rvalid),
|
||||
.instr_rdata_i(instr_mem_vif.rdata),
|
||||
.instr_err_i(0)
|
||||
);
|
||||
|
||||
ibex_mem_intf data_mem_vif();
|
||||
ibex_mem_intf instr_mem_vif();
|
||||
// Data load/store vif connection
|
||||
assign data_mem_vif.clock = clk;
|
||||
assign data_mem_vif.reset = ~rst_n;
|
||||
assign data_mem_vif.request = dut.data_req_o;
|
||||
assign data_mem_vif.we = dut.data_we_o;
|
||||
assign data_mem_vif.be = dut.data_be_o;
|
||||
assign data_mem_vif.addr = dut.data_addr_o;
|
||||
assign data_mem_vif.wdata = dut.data_wdata_o;
|
||||
// Instruction fetch vif connnection
|
||||
assign instr_mem_vif.clock = clk;
|
||||
assign instr_mem_vif.reset = ~rst_n;
|
||||
assign instr_mem_vif.request = dut.instr_req_o;
|
||||
assign instr_mem_vif.we = 0;
|
||||
assign instr_mem_vif.be = 0;
|
||||
assign instr_mem_vif.wdata = 0;
|
||||
assign instr_mem_vif.addr = dut.instr_addr_o;
|
||||
|
||||
initial begin
|
||||
// Data load/store vif connection
|
||||
force data_mem_vif.clock = clk;
|
||||
force data_mem_vif.reset = ~rst_n;
|
||||
force data_mem_vif.request = dut.data_req_o;
|
||||
force dut.data_gnt_i = data_mem_vif.grant;
|
||||
force dut.data_rvalid_i = data_mem_vif.rvalid;
|
||||
force data_mem_vif.we = dut.data_we_o;
|
||||
force data_mem_vif.be = dut.data_be_o;
|
||||
force data_mem_vif.addr = dut.data_addr_o;
|
||||
force data_mem_vif.wdata = dut.data_wdata_o;
|
||||
force dut.data_rdata_i = data_mem_vif.rdata;
|
||||
force dut.data_err_i = 0; // TODO(taliu) Support interface error
|
||||
// Instruction fetch vif connnection
|
||||
force instr_mem_vif.clock = clk;
|
||||
force instr_mem_vif.reset = ~rst_n;
|
||||
force instr_mem_vif.request = dut.instr_req_o;
|
||||
force dut.instr_gnt_i = instr_mem_vif.grant;
|
||||
force instr_mem_vif.we = 0;
|
||||
force instr_mem_vif.be = 0;
|
||||
force instr_mem_vif.wdata = 0;
|
||||
force dut.instr_rvalid_i = instr_mem_vif.rvalid;
|
||||
force instr_mem_vif.addr = dut.instr_addr_o;
|
||||
force dut.instr_rdata_i = instr_mem_vif.rdata;
|
||||
force dut.instr_err_i = 0; // TODO(taliu) Support interface error
|
||||
// IRQ interface
|
||||
force irq_vif.clock = clk;
|
||||
force irq_vif.reset = ~rst_n;
|
||||
|
|
|
@ -169,7 +169,7 @@ class core_ibex_base_test extends uvm_test;
|
|||
|
||||
// Gets the next CORE_STATUS signature write and compares it against the provided core_status
|
||||
// type, throws uvm_error on mismatch
|
||||
virtual task check_next_core_status(core_status_t core_status, string error_msg="");
|
||||
virtual task check_next_core_status(core_status_t core_status, string error_msg = "");
|
||||
wait_for_mem_txn(cfg.signature_addr, CORE_STATUS);
|
||||
signature_data = signature_data_q.pop_front();
|
||||
if (signature_data != core_status) begin
|
||||
|
|
|
@ -298,7 +298,8 @@ class core_ibex_dret_test extends core_ibex_directed_test;
|
|||
check_next_core_status(HANDLING_EXCEPTION, "Core did not jump to vectored exception handler");
|
||||
// The core will receive an illegal instruction handshake after jumping from the vectored trap
|
||||
// handler to the illegal instruction exception handler
|
||||
check_next_core_status(ILLEGAL_INSTR_EXCEPTION, "Core did not treat dret like illegal instruction");
|
||||
check_next_core_status(ILLEGAL_INSTR_EXCEPTION,
|
||||
"Core did not treat dret like illegal instruction");
|
||||
end
|
||||
endtask
|
||||
|
||||
|
@ -317,7 +318,8 @@ class core_ibex_debug_ebreak_test extends core_ibex_directed_test;
|
|||
forever begin
|
||||
wait (dut_vif.ebreak === 1'b1);
|
||||
check_next_core_status(HANDLING_EXCEPTION, "Core did not jump to exception handler");
|
||||
check_next_core_status(EBREAK_EXCEPTION, "Core did not jump from exception handler to ebreak handler");
|
||||
check_next_core_status(EBREAK_EXCEPTION,
|
||||
"Core did not jump from exception handler to ebreak handler");
|
||||
wait (dut_vif.mret === 1'b1);
|
||||
// Want to wait until after the ebreak handler has finished to send debug stimulus, to avoid
|
||||
// nested trap scenarios
|
||||
|
@ -335,9 +337,11 @@ class core_ibex_debug_ebreak_test extends core_ibex_directed_test;
|
|||
wait (dut_vif.ebreak === 1'b1);
|
||||
// compare the second writes of dcsr and dpc against the captured values
|
||||
wait_for_csr_write(CSR_DCSR);
|
||||
`DV_CHECK_EQ_FATAL(dcsr, signature_data, "ebreak inside the debug rom has changed the value of DCSR")
|
||||
`DV_CHECK_EQ_FATAL(dcsr, signature_data,
|
||||
"ebreak inside the debug rom has changed the value of DCSR")
|
||||
wait_for_csr_write(CSR_DPC);
|
||||
`DV_CHECK_EQ_FATAL(dpc, signature_data, "ebreak inside the debug rom has changed the value of DPC")
|
||||
`DV_CHECK_EQ_FATAL(dpc, signature_data,
|
||||
"ebreak inside the debug rom has changed the value of DPC")
|
||||
wait (dut_vif.dret === 1'b1);
|
||||
end
|
||||
endtask
|
||||
|
@ -353,7 +357,8 @@ class core_ibex_debug_ebreakm_test extends core_ibex_directed_test;
|
|||
virtual task check_stimulus();
|
||||
// send a single debug request after core initialization to configure dcsr
|
||||
vseq.start_debug_single_seq();
|
||||
check_next_core_status(IN_DEBUG_MODE, "Core did not enter debug mode after debug_req stimulus");
|
||||
check_next_core_status(IN_DEBUG_MODE,
|
||||
"Core did not enter debug mode after debug_req stimulus");
|
||||
// Read dcsr and verify the appropriate ebreak(m/s/u) bit has been set based on the prv field,
|
||||
// as well as the cause field
|
||||
wait_for_csr_write(CSR_DCSR);
|
||||
|
@ -362,7 +367,8 @@ class core_ibex_debug_ebreakm_test extends core_ibex_directed_test;
|
|||
wait (dut_vif.dret === 1'b1);
|
||||
forever begin
|
||||
wait (dut_vif.ebreak === 1'b1);
|
||||
check_next_core_status(IN_DEBUG_MODE, "Core did not enter debug mode after execution of ebreak");
|
||||
check_next_core_status(IN_DEBUG_MODE,
|
||||
"Core did not enter debug mode after execution of ebreak");
|
||||
// Read dcsr and verify the appropriate ebreak(m/s/u) bit has been set based on the prv field
|
||||
wait_for_csr_write(CSR_DCSR);
|
||||
check_dcsr_ebreak();
|
||||
|
|
|
@ -45,3 +45,22 @@
|
|||
-cm_name test_<seed>
|
||||
wave_opts: >
|
||||
-ucli -do <cwd>/vcs.tcl
|
||||
|
||||
- tool: dsim
|
||||
env_var: DSIM,DSIM_LIB_PATH
|
||||
compile:
|
||||
cmd:
|
||||
- "mkdir -p <out>/dsim"
|
||||
- "<DSIM> -sv -work <out>/dsim
|
||||
-genimage image
|
||||
+incdir+$UVM_HOME/src
|
||||
$UVM_HOME/src/uvm_pkg.sv
|
||||
+define+DSIM
|
||||
+acc+rwb
|
||||
-f ibex_dv.f
|
||||
-l <out>/dsim/compile.log"
|
||||
sim:
|
||||
cmd: >
|
||||
<DSIM> <sim_opts> -sv_seed <seed> -pli_lib <DSIM_LIB_PATH>/libuvm_dpi.so +acc+rwb -image image -work <out>/dsim <wave_opts>
|
||||
wave_opts: >
|
||||
-waves waves.vcd
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue