[ibex/dv] Add clocking blocks to Ibex interfaces

This PR adds clocking blocks to all major Ibex interfaces and updates
all corresponding interface accesses to use these clocking blocks.

A few notes:

- `ibex_mem_intf` has two driver clocking blocks, one for host side and
  one for device side.
  This is because our Ibex testbench currently provides both host and
  device agents for both I/D interfaces (of course we only use the
  reactive device agents in the main testbench).
- `csr_if` and `dut_if` only have one clocking block each, as all
  signals in each will only be either sampled or driven, never both.
- Some utility tasks have been added to some interfaces to wait for a
  specified number of clock cycles.
This commit is contained in:
Udi 2020-06-18 17:25:48 -07:00 committed by udinator
parent 96cf24a41a
commit 1f26d93267
13 changed files with 241 additions and 137 deletions

View file

@ -2,10 +2,13 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
interface ibex_mem_intf#(parameter int ADDR_WIDTH = 32,
parameter int DATA_WIDTH = 32);
interface ibex_mem_intf#(
parameter int ADDR_WIDTH = 32,
parameter int DATA_WIDTH = 32
) (
input clk
);
logic clock;
logic reset;
logic request;
logic grant;
@ -17,4 +20,51 @@ interface ibex_mem_intf#(parameter int ADDR_WIDTH = 32,
logic [DATA_WIDTH-1:0] rdata;
logic error;
clocking host_driver_cb @(posedge clk);
input reset;
output request;
input grant;
output addr;
output we;
output be;
input rvalid;
output wdata;
input rdata;
input error;
endclocking
clocking device_driver_cb @(posedge clk);
input reset;
input request;
output grant;
input addr;
input we;
input be;
output rvalid;
input wdata;
output rdata;
output error;
endclocking
clocking monitor_cb @(posedge clk);
input reset;
input request;
input grant;
input addr;
input we;
input be;
input rvalid;
input wdata;
input rdata;
input error;
endclocking
task automatic wait_clks(input int num);
repeat (num) @(posedge clk);
endtask
task automatic wait_neg_clks(input int num);
repeat (num) @(negedge clk);
endtask
endinterface : ibex_mem_intf

View file

@ -31,11 +31,11 @@ class ibex_mem_intf_master_driver extends uvm_driver #(ibex_mem_intf_seq_item);
endtask : run_phase
virtual protected task get_and_drive();
@(negedge vif.reset);
@(negedge vif.host_driver_cb.reset);
forever begin
@(posedge vif.clock);
vif.wait_clks(1);
seq_item_port.get_next_item(req);
repeat(req.req_delay) @(posedge vif.clock);
vif.wait_clks(req.req_delay);
$cast(rsp, req.clone());
rsp.set_id_info(req);
drive_transfer(rsp);
@ -45,31 +45,31 @@ class ibex_mem_intf_master_driver extends uvm_driver #(ibex_mem_intf_seq_item);
virtual protected task reset_signals();
forever begin
@(posedge vif.reset);
vif.request <= 'h0;
vif.addr <= 'hz;
vif.wdata <= 'hz;
vif.be <= 'bz;
vif.we <= 'bz;
@(posedge vif.host_driver_cb.reset);
vif.host_driver_cb.request <= 'h0;
vif.host_driver_cb.addr <= 'hz;
vif.host_driver_cb.wdata <= 'hz;
vif.host_driver_cb.be <= 'bz;
vif.host_driver_cb.we <= 'bz;
end
endtask : reset_signals
virtual protected task drive_transfer (ibex_mem_intf_seq_item trans);
if (trans.req_delay > 0) begin
repeat(trans.req_delay) @(posedge vif.clock);
vif.wait_clks(trans.req_delay);
end
vif.request <= 1'b1;
vif.addr <= trans.addr;
vif.be <= trans.be;
vif.we <= trans.read_write;
vif.wdata <= trans.data;
wait(vif.grant === 1'b1);
@(posedge vif.clock);
vif.request <= 'h0;
vif.addr <= 'hz;
vif.wdata <= 'hz;
vif.be <= 'bz;
vif.we <= 'bz;
vif.host_driver_cb.request <= 1'b1;
vif.host_driver_cb.addr <= trans.addr;
vif.host_driver_cb.be <= trans.be;
vif.host_driver_cb.we <= trans.read_write;
vif.host_driver_cb.wdata <= trans.data;
wait (vif.host_driver_cb.grant === 1'b1);
vif.wait_clks(1);
vif.host_driver_cb.request <= 'h0;
vif.host_driver_cb.addr <= 'hz;
vif.host_driver_cb.wdata <= 'hz;
vif.host_driver_cb.be <= 'bz;
vif.host_driver_cb.we <= 'bz;
rdata_queue.put(trans);
endtask : drive_transfer
@ -77,10 +77,10 @@ class ibex_mem_intf_master_driver extends uvm_driver #(ibex_mem_intf_seq_item);
ibex_mem_intf_seq_item tr;
forever begin
rdata_queue.get(tr);
@(posedge vif.clock);
while(vif.rvalid !== 1'b1) @(posedge vif.clock);
vif.wait_clks(1);
while(vif.rvalid !== 1'b1) vif.wait_clks(1);
if(tr.read_write == READ)
tr.data = vif.rdata;
tr.data = vif.host_driver_cb.rdata;
seq_item_port.put_response(tr);
end
endtask : collect_response

View file

@ -28,12 +28,12 @@ class ibex_mem_intf_monitor extends uvm_monitor;
endfunction: build_phase
virtual task run_phase(uvm_phase phase);
wait(vif.reset === 1'b0);
wait (vif.monitor_cb.reset === 1'b0);
forever begin
fork : check_mem_intf
collect_address_phase();
collect_data_phase();
wait(vif.reset === 1'b1);
wait (vif.monitor_cb.reset === 1'b1);
join_any
// Will only reach this point when mid-test reset is asserted
disable check_mem_intf;
@ -45,21 +45,21 @@ class ibex_mem_intf_monitor extends uvm_monitor;
ibex_mem_intf_seq_item mailbox_result;
// Clear the mailbox of any content
while (collect_data_queue.try_get(mailbox_result));
wait(vif.reset === 1'b0);
wait (vif.monitor_cb.reset === 1'b0);
endtask
virtual protected task collect_address_phase();
ibex_mem_intf_seq_item trans_collected;
forever begin
trans_collected = ibex_mem_intf_seq_item::type_id::create("trans_collected");
while(!(vif.request && vif.grant)) @(posedge vif.clock);
trans_collected.addr = vif.addr;
trans_collected.be = vif.be;
while(!(vif.monitor_cb.request && vif.monitor_cb.grant)) vif.wait_clks(1);
trans_collected.addr = vif.monitor_cb.addr;
trans_collected.be = vif.monitor_cb.be;
`uvm_info(get_full_name(), $sformatf("Detect request with address: %0x",
trans_collected.addr), UVM_HIGH)
if(vif.we) begin
if(vif.monitor_cb.we) begin
trans_collected.read_write = WRITE;
trans_collected.data = vif.wdata;
trans_collected.data = vif.monitor_cb.wdata;
end else begin
trans_collected.read_write = READ;
end
@ -69,7 +69,7 @@ class ibex_mem_intf_monitor extends uvm_monitor;
item_collected_port.write(trans_collected);
else
collect_data_queue.put(trans_collected);
@(posedge vif.clock);
vif.wait_clks(1);
end
endtask : collect_address_phase
@ -78,9 +78,9 @@ class ibex_mem_intf_monitor extends uvm_monitor;
forever begin
collect_data_queue.get(trans_collected);
do
@(posedge vif.clock);
while(vif.rvalid === 0);
trans_collected.data = vif.rdata;
vif.wait_clks(1);
while(vif.monitor_cb.rvalid === 0);
trans_collected.data = vif.monitor_cb.rdata;
item_collected_port.write(trans_collected);
end
endtask : collect_data_phase

View file

@ -27,12 +27,12 @@ class ibex_mem_intf_slave_driver extends uvm_driver #(ibex_mem_intf_seq_item);
virtual task run_phase(uvm_phase phase);
reset_signals();
wait(vif.reset === 1'b0);
wait (vif.device_driver_cb.reset === 1'b0);
forever begin
fork : drive_stimulus
send_grant();
get_and_drive();
wait(vif.reset === 1'b1);
wait (vif.device_driver_cb.reset === 1'b1);
join_any
// Will only be reached after mid-test reset
disable drive_stimulus;
@ -52,26 +52,26 @@ class ibex_mem_intf_slave_driver extends uvm_driver #(ibex_mem_intf_seq_item);
end
end while (req != null);
reset_signals();
wait(vif.reset === 1'b0);
wait (vif.device_driver_cb.reset === 1'b0);
endtask
virtual protected task reset_signals();
vif.rvalid <= 1'b0;
vif.grant <= 1'b0;
vif.rdata <= 'b0;
vif.error <= 1'b0;
vif.device_driver_cb.rvalid <= 1'b0;
vif.device_driver_cb.grant <= 1'b0;
vif.device_driver_cb.rdata <= 'b0;
vif.device_driver_cb.error <= 1'b0;
endtask : reset_signals
virtual protected task get_and_drive();
wait(vif.reset === 1'b0);
wait (vif.device_driver_cb.reset === 1'b0);
fork
begin
forever begin
ibex_mem_intf_seq_item req, req_c;
@(posedge vif.clock);
vif.wait_clks(1);
seq_item_port.get_next_item(req);
$cast(req_c, req.clone());
if(~vif.reset) begin
if(~vif.device_driver_cb.reset) begin
rdata_queue.put(req_c);
end
seq_item_port.item_done();
@ -86,8 +86,8 @@ class ibex_mem_intf_slave_driver extends uvm_driver #(ibex_mem_intf_seq_item);
virtual protected task send_grant();
int gnt_delay;
forever begin
while(vif.request !== 1'b1) begin
@(negedge vif.clock);
while(vif.device_driver_cb.request !== 1'b1) begin
vif.wait_neg_clks(1);
end
if (!std::randomize(gnt_delay) with {
gnt_delay dist {
@ -98,11 +98,11 @@ class ibex_mem_intf_slave_driver extends uvm_driver #(ibex_mem_intf_seq_item);
}) begin
`uvm_fatal(`gfn, $sformatf("Cannot randomize grant"))
end
repeat(gnt_delay) @(negedge vif.clock);
if(~vif.reset) begin
vif.grant = 1'b1;
@(negedge vif.clock);
vif.grant = 1'b0;
vif.wait_neg_clks(gnt_delay);
if(~vif.device_driver_cb.reset) begin
vif.device_driver_cb.grant <= 1'b1;
vif.wait_neg_clks(1);
vif.device_driver_cb.grant <= 1'b0;
end
end
endtask : send_grant
@ -110,17 +110,17 @@ class ibex_mem_intf_slave_driver extends uvm_driver #(ibex_mem_intf_seq_item);
virtual protected task send_read_data();
ibex_mem_intf_seq_item tr;
forever begin
@(posedge vif.clock);
vif.rvalid <= 1'b0;
vif.rdata <= 'x;
vif.error <= 1'b0;
vif.wait_clks(1);
vif.device_driver_cb.rvalid <= 1'b0;
vif.device_driver_cb.rdata <= 'x;
vif.device_driver_cb.error <= 1'b0;
rdata_queue.get(tr);
if(vif.reset) continue;
repeat(tr.rvalid_delay) @(posedge vif.clock);
if(~vif.reset) begin
vif.rvalid <= 1'b1;
vif.error <= tr.error;
vif.rdata <= tr.data;
if(vif.device_driver_cb.reset) continue;
vif.wait_clks(tr.rvalid_delay);
if(~vif.device_driver_cb.reset) begin
vif.device_driver_cb.rvalid <= 1'b1;
vif.device_driver_cb.error <= tr.error;
vif.device_driver_cb.rdata <= tr.data;
end
end
endtask : send_read_data

View file

@ -2,12 +2,34 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
interface irq_if;
logic clock;
interface irq_if(input clk);
logic reset;
logic irq_software;
logic irq_timer;
logic irq_external;
logic [14:0] irq_fast;
logic irq_nm; // non-maskeable interrupt
clocking driver_cb @(posedge clk);
input reset;
output irq_software;
output irq_timer;
output irq_external;
output irq_fast;
output irq_nm;
endclocking
clocking monitor_cb @(posedge clk);
input reset;
input irq_software;
input irq_timer;
input irq_external;
input irq_fast;
input irq_nm;
endclocking
task automatic wait_clks(input int num);
repeat (num) @(posedge clk);
endtask
endinterface

View file

@ -22,7 +22,7 @@ class irq_master_driver extends uvm_driver #(irq_seq_item);
forever begin
fork : drive_irq
get_and_drive();
wait(vif.reset === 1'b1);
wait (vif.driver_cb.reset === 1'b1);
join_any
// Will only reach here on mid-test reset
disable drive_irq;
@ -43,7 +43,7 @@ class irq_master_driver extends uvm_driver #(irq_seq_item);
endtask
virtual protected task get_and_drive();
wait(vif.reset === 1'b0);
wait (vif.driver_cb.reset === 1'b0);
forever begin
seq_item_port.try_next_item(req);
if (req != null) begin
@ -52,30 +52,30 @@ class irq_master_driver extends uvm_driver #(irq_seq_item);
drive_seq_item(rsp);
seq_item_port.item_done(rsp);
end else begin
@(posedge vif.clock);
vif.wait_clks(1);
end
end
endtask : get_and_drive
virtual protected task reset_signals();
@(negedge vif.reset);
@(negedge vif.driver_cb.reset);
drive_reset_value();
endtask : reset_signals
virtual protected task drive_seq_item (irq_seq_item trans);
vif.irq_software <= trans.irq_software;
vif.irq_timer <= trans.irq_timer;
vif.irq_external <= trans.irq_external;
vif.irq_fast <= trans.irq_fast;
vif.irq_nm <= trans.irq_nm;
vif.driver_cb.irq_software <= trans.irq_software;
vif.driver_cb.irq_timer <= trans.irq_timer;
vif.driver_cb.irq_external <= trans.irq_external;
vif.driver_cb.irq_fast <= trans.irq_fast;
vif.driver_cb.irq_nm <= trans.irq_nm;
endtask : drive_seq_item
task drive_reset_value();
vif.irq_software <= '0;
vif.irq_timer <= '0;
vif.irq_external <= '0;
vif.irq_fast <= '0;
vif.irq_nm <= '0;
vif.driver_cb.irq_software <= '0;
vif.driver_cb.irq_timer <= '0;
vif.driver_cb.irq_external <= '0;
vif.driver_cb.irq_fast <= '0;
vif.driver_cb.irq_nm <= '0;
endtask : drive_reset_value
endclass : irq_master_driver

View file

@ -23,10 +23,10 @@ class irq_monitor extends uvm_monitor;
virtual task run_phase(uvm_phase phase);
forever begin
wait(vif.reset === 1'b0);
wait (vif.monitor_cb.reset === 1'b0);
fork : monitor_irq
collect_irq();
wait(vif.reset === 1'b1);
wait (vif.monitor_cb.reset === 1'b1);
join_any
// Will only reach here on mid-test reset
disable monitor_irq;
@ -46,19 +46,26 @@ class irq_monitor extends uvm_monitor;
bit[DATA_WIDTH-1:0] stored_irq_val = '0;
bit[DATA_WIDTH-1:0] current_irq = '0;
forever begin
current_irq = {vif.irq_nm, vif.irq_fast, 4'b0, vif.irq_external, 3'b0,
vif.irq_timer, 3'b0, vif.irq_software, 3'b0};
current_irq = {vif.monitor_cb.irq_nm,
vif.monitor_cb.irq_fast,
4'b0,
vif.monitor_cb.irq_external,
3'b0,
vif.monitor_cb.irq_timer,
3'b0,
vif.monitor_cb.irq_software,
3'b0};
if (current_irq !== stored_irq_val) begin
stored_irq_val = current_irq;
irq = irq_seq_item::type_id::create("irq");
irq.irq_software = vif.irq_software;
irq.irq_timer = vif.irq_timer;
irq.irq_external = vif.irq_external;
irq.irq_fast = vif.irq_fast;
irq.irq_nm = vif.irq_nm;
irq.irq_software = vif.monitor_cb.irq_software;
irq.irq_timer = vif.monitor_cb.irq_timer;
irq.irq_external = vif.monitor_cb.irq_external;
irq.irq_fast = vif.monitor_cb.irq_fast;
irq.irq_nm = vif.monitor_cb.irq_nm;
irq_port.write(irq);
end
@(posedge vif.clock);
vif.wait_clks(1);
end
endtask : collect_irq

View file

@ -9,4 +9,13 @@ interface core_ibex_csr_if(input logic clk);
logic [31:0] csr_wdata;
logic [31:0] csr_rdata;
ibex_pkg::csr_op_e csr_op;
clocking csr_cb @(posedge clk);
input csr_access;
input csr_addr;
input csr_wdata;
input csr_rdata;
input csr_op;
endclocking
endinterface

View file

@ -16,6 +16,20 @@ interface core_ibex_dut_probe_if(input logic clk);
logic debug_req;
ibex_pkg::priv_lvl_e priv_mode;
clocking dut_cb @(posedge clk);
output fetch_enable;
output debug_req;
input reset;
input illegal_instr;
input ecall;
input wfi;
input ebreak;
input dret;
input mret;
input core_sleep;
input priv_mode;
endclocking
initial begin
debug_req = 1'b0;
end

View file

@ -12,9 +12,9 @@ module core_ibex_tb_top;
logic fetch_enable;
clk_if ibex_clk_if(.clk(clk), .rst_n(rst_n));
irq_if irq_vif();
ibex_mem_intf data_mem_vif();
ibex_mem_intf instr_mem_vif();
irq_if irq_vif(.clk(clk));
ibex_mem_intf data_mem_vif(.clk(clk));
ibex_mem_intf instr_mem_vif(.clk(clk));
// DUT probe interface
@ -89,10 +89,8 @@ module core_ibex_tb_top;
);
// Data load/store vif connection
assign data_mem_vif.clock = clk;
assign data_mem_vif.reset = ~rst_n;
// Instruction fetch vif connnection
assign instr_mem_vif.clock = clk;
assign instr_mem_vif.reset = ~rst_n;
assign instr_mem_vif.we = 0;
assign instr_mem_vif.be = 0;
@ -118,7 +116,6 @@ module core_ibex_tb_top;
assign rvfi_if.mem_rdata = dut.rvfi_mem_rdata;
assign rvfi_if.mem_wdata = dut.rvfi_mem_wdata;
// Irq interface connections
assign irq_vif.clock = clk;
assign irq_vif.reset = ~rst_n;
// Dut_if interface connections
assign dut_if.ecall = dut.u_ibex_core.id_stage_i.controller_i.ecall_insn;

View file

@ -68,10 +68,10 @@ class core_ibex_base_test extends uvm_test;
enable_irq_seq = cfg.enable_irq_single_seq || cfg.enable_irq_multiple_seq;
phase.raise_objection(this);
run = phase;
dut_vif.fetch_enable = 1'b0;
dut_vif.dut_cb.fetch_enable <= 1'b0;
clk_vif.wait_clks(100);
load_binary_to_mem();
dut_vif.fetch_enable = 1'b1;
dut_vif.dut_cb.fetch_enable <= 1'b1;
send_stimulus();
wait_for_test_done();
phase.drop_objection(this);
@ -116,11 +116,11 @@ class core_ibex_base_test extends uvm_test;
virtual task wait_for_test_done();
fork
begin
wait (dut_vif.ecall === 1'b1);
wait (dut_vif.dut_cb.ecall === 1'b1);
vseq.stop();
`uvm_info(`gfn, "ECALL instruction is detected, test done", UVM_LOW)
// De-assert fetch enable to finish the test
dut_vif.fetch_enable = 1'b0;
dut_vif.dut_cb.fetch_enable <= 1'b0;
fork
check_perf_stats();
// Wait some time for the remaining instruction to finish

View file

@ -131,15 +131,15 @@ class debug_seq extends core_base_seq#(irq_seq_item);
if (!uvm_config_db#(virtual core_ibex_dut_probe_if)::get(null, "", "dut_if", dut_vif)) begin
`uvm_fatal(get_full_name(), "Cannot get dut_if")
end
dut_vif.debug_req <= 1'b0;
dut_vif.dut_cb.debug_req <= 1'b0;
super.body();
endtask
virtual task send_req();
`uvm_info(get_full_name(), "Sending debug request", UVM_HIGH)
dut_vif.debug_req <= 1'b1;
dut_vif.dut_cb.debug_req <= 1'b1;
clk_vif.wait_clks(50);
dut_vif.debug_req <= 1'b0;
dut_vif.dut_cb.debug_req <= 1'b0;
endtask
endclass

View file

@ -47,7 +47,7 @@ class core_ibex_reset_test extends core_ibex_base_test;
clk_vif.wait_clks($urandom_range(0, 50000));
fork
begin
dut_vif.fetch_enable = 1'b0;
dut_vif.dut_cb.fetch_enable <= 1'b0;
clk_vif.reset();
end
begin
@ -61,7 +61,7 @@ class core_ibex_reset_test extends core_ibex_base_test;
end
join
// Assert fetch_enable to have the core start executing from boot address
dut_vif.fetch_enable = 1'b1;
dut_vif.dut_cb.fetch_enable <= 1'b1;
end
endtask
@ -223,7 +223,7 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test;
end
check_next_core_status(HANDLING_IRQ, "Core did not jump to vectored interrupt handler", 750);
check_priv_mode(PRIV_LVL_M);
operating_mode = dut_vif.priv_mode;
operating_mode = dut_vif.dut_cb.priv_mode;
// check mstatus
wait_for_csr_write(CSR_MSTATUS, 500);
mstatus = signature_data;
@ -329,16 +329,16 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test;
begin
case (ret)
"dret": begin
wait (dut_vif.dret === 1'b1);
wait (dut_vif.dut_cb.dret === 1'b1);
end
"mret": begin
wait (dut_vif.mret === 1'b1);
wait (dut_vif.dut_cb.mret === 1'b1);
end
default: begin
`uvm_fatal(`gfn, $sformatf("Invalid xRET instruction %0s", ret))
end
endcase
wait (dut_vif.priv_mode === select_mode());
wait (dut_vif.dut_cb.priv_mode === select_mode());
end
begin : ret_timeout
clk_vif.wait_clks(timeout);
@ -352,7 +352,7 @@ class core_ibex_debug_intr_basic_test extends core_ibex_base_test;
endtask
virtual function void check_priv_mode(priv_lvl_e mode);
`DV_CHECK_EQ_FATAL(dut_vif.priv_mode, mode,
`DV_CHECK_EQ_FATAL(dut_vif.dut_cb.priv_mode, mode,
"Incorrect privilege mode")
endfunction
@ -397,7 +397,7 @@ class core_ibex_directed_test extends core_ibex_debug_intr_basic_test;
check_stimulus();
end : stimulus
begin
wait(dut_vif.ecall === 1'b1);
wait (dut_vif.dut_cb.ecall === 1'b1);
disable stimulus;
if (run.get_objection_count(this) > 1) begin
run.drop_objection(this);
@ -475,8 +475,8 @@ class core_ibex_irq_wfi_test extends core_ibex_directed_test;
virtual task check_stimulus();
forever begin
wait (dut_vif.wfi === 1'b1);
wait(dut_vif.core_sleep === 1'b1);
wait (dut_vif.dut_cb.wfi === 1'b1);
wait (dut_vif.dut_cb.core_sleep === 1'b1);
send_irq_stimulus();
end
endtask
@ -492,13 +492,15 @@ class core_ibex_irq_csr_test extends core_ibex_directed_test;
virtual task check_stimulus();
vseq.irq_raise_single_seq_h.max_delay = 0;
// wait for a write to mstatus - should be in init code
wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MSTATUS &&
csr_vif.csr_op != CSR_OP_READ);
wait (csr_vif.csr_cb.csr_access === 1'b1 &&
csr_vif.csr_cb.csr_addr === CSR_MSTATUS &&
csr_vif.csr_cb.csr_op != CSR_OP_READ);
// send interrupt immediately after detection
send_irq_stimulus();
// wait for a write to mie - should be in init code
wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MIE &&
csr_vif.csr_op != CSR_OP_READ);
wait (csr_vif.csr_cb.csr_access === 1'b1 &&
csr_vif.csr_cb.csr_addr === CSR_MIE &&
csr_vif.csr_cb.csr_op != CSR_OP_READ);
// send interrupt immediately after detection
send_irq_stimulus();
endtask
@ -562,7 +564,7 @@ class core_ibex_debug_in_irq_test extends core_ibex_directed_test;
send_debug_stimulus(operating_mode, "Core did not enter debug mode from interrupt handler");
end
begin
wait(dut_vif.dret == 1'b1);
wait (dut_vif.dut_cb.dret == 1'b1);
send_irq_stimulus_end();
end
join
@ -591,8 +593,9 @@ class core_ibex_nested_irq_test extends core_ibex_directed_test;
// Send nested interrupt after the checks of the first interrupt have finished
in_nested_trap = 1'b1;
// wait until we are setting mstatus.mie to 1'b1 to send the next set of interrupts
wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MSTATUS &&
csr_vif.csr_op != CSR_OP_READ);
wait (csr_vif.csr_cb.csr_access === 1'b1 &&
csr_vif.csr_cb.csr_addr === CSR_MSTATUS &&
csr_vif.csr_cb.csr_op != CSR_OP_READ);
send_irq_stimulus(1'b0);
vseq.irq_raise_seq_h.max_delay = initial_irq_delay;
in_nested_trap = 1'b0;
@ -611,8 +614,8 @@ class core_ibex_debug_wfi_test extends core_ibex_directed_test;
virtual task check_stimulus();
forever begin
wait (dut_vif.wfi === 1'b1);
wait (dut_vif.core_sleep === 1'b1);
wait (dut_vif.dut_cb.wfi === 1'b1);
wait (dut_vif.dut_cb.core_sleep === 1'b1);
clk_vif.wait_clks($urandom_range(100));
send_debug_stimulus(init_operating_mode, "Core did not jump into debug mode from WFI state");
end
@ -629,12 +632,14 @@ class core_ibex_debug_csr_test extends core_ibex_directed_test;
virtual task check_stimulus();
vseq.debug_seq_single_h.max_delay = 0;
// wait for a dummy write to mstatus in init code
wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MSTATUS &&
csr_vif.csr_op != CSR_OP_READ);
wait (csr_vif.csr_cb.csr_access === 1'b1 &&
csr_vif.csr_cb.csr_addr === CSR_MSTATUS &&
csr_vif.csr_cb.csr_op != CSR_OP_READ);
send_debug_stimulus(init_operating_mode, "Core did not trap to debug mode upon debug stimulus");
// wait for a dummy write to mie in the init code
wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MIE &&
csr_vif.csr_op != CSR_OP_READ);
wait (csr_vif.csr_cb.csr_access === 1'b1 &&
csr_vif.csr_cb.csr_addr === CSR_MIE &&
csr_vif.csr_cb.csr_op != CSR_OP_READ);
send_debug_stimulus(init_operating_mode, "Core did not trap to debug mode upon debug stimulus");
endtask
@ -648,7 +653,7 @@ class core_ibex_dret_test extends core_ibex_directed_test;
virtual task check_stimulus();
forever begin
wait (dut_vif.dret === 1'b1);
wait (dut_vif.dut_cb.dret === 1'b1);
check_illegal_insn("Core did not treat dret like illegal instruction");
end
endtask
@ -678,7 +683,7 @@ class core_ibex_debug_ebreak_test extends core_ibex_directed_test;
// capture the first write of dpc
wait_for_csr_write(CSR_DPC, 500);
dpc = signature_data;
wait (dut_vif.ebreak === 1'b1);
wait (dut_vif.dut_cb.ebreak === 1'b1);
// compare the second writes of dcsr and dpc against the captured values
wait_for_csr_write(CSR_DCSR, 1000);
`DV_CHECK_EQ_FATAL(dcsr, signature_data,
@ -713,7 +718,7 @@ class core_ibex_debug_ebreakmu_test extends core_ibex_directed_test;
check_dcsr_cause(DBG_CAUSE_HALTREQ);
wait_ret("dret", 5000);
forever begin
wait (dut_vif.ebreak === 1'b1);
wait (dut_vif.dut_cb.ebreak === 1'b1);
check_next_core_status(IN_DEBUG_MODE,
"Core did not enter debug mode after execution of ebreak", 2000);
check_priv_mode(PRIV_LVL_M);
@ -840,7 +845,7 @@ class core_ibex_mem_error_test extends core_ibex_directed_test;
exc_type = EXC_CAUSE_STORE_ACCESS_FAULT;
end
check_mcause(1'b0, exc_type);
wait (dut_vif.mret === 1'b1);
wait (dut_vif.dut_cb.mret === 1'b1);
`uvm_info(`gfn, "exiting mem fault checker", UVM_LOW)
endtask
@ -876,7 +881,7 @@ class core_ibex_mem_error_test extends core_ibex_directed_test;
"Core did not register correct memory fault type", 500);
exc_type = EXC_CAUSE_INSTR_ACCESS_FAULT;
check_mcause(1'b0, exc_type);
wait (dut_vif.mret === 1'b1);
wait (dut_vif.dut_cb.mret === 1'b1);
`uvm_info(`gfn, "exiting mem fault checker", UVM_LOW)
endtask
@ -891,7 +896,7 @@ class core_ibex_umode_tw_test extends core_ibex_directed_test;
virtual task check_stimulus();
bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] mcause;
forever begin
wait (dut_vif.wfi === 1'b1);
wait (dut_vif.dut_cb.wfi === 1'b1);
check_illegal_insn("Core did not treat U-mode WFI as illegal");
end
endtask
@ -907,9 +912,9 @@ class core_ibex_invalid_csr_test extends core_ibex_directed_test;
virtual task check_stimulus();
forever begin
// Wait for a CSR access
wait (csr_vif.csr_access == 1'b1);
wait (csr_vif.csr_cb.csr_access == 1'b1);
check_illegal_insn($sformatf("Core did not treat access to CSR 0x%0x from %0s as illegal",
csr_vif.csr_addr, init_operating_mode));
csr_vif.csr_cb.csr_addr, init_operating_mode));
end
endtask