Add dsim support (#328)

This commit is contained in:
taoliug 2019-09-17 16:18:05 -07:00 committed by GitHub
parent 2ce4bfa150
commit e7123f1c2d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 94 additions and 54 deletions

View file

@ -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 \

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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

View file

@ -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();

View file

@ -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