Fix interrtup test (#189)

Update TB for the new interrupt interface
This commit is contained in:
taoliug 2019-07-24 11:46:18 -07:00 committed by GitHub
parent 0dee0ff1ec
commit 2bf1ab923a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 68 additions and 50 deletions

View file

@ -3,10 +3,11 @@
// SPDX-License-Identifier: Apache-2.0
interface irq_if;
logic clock;
logic reset;
logic irq_i;
logic [4:0] irq_id_i;
logic [4:0] irq_id_o;
logic irq_ack_o;
logic clock;
logic reset;
logic irq_software;
logic irq_timer;
logic irq_external;
logic [14:0] irq_fast;
logic irq_nm; // non-maskeable interrupt
endinterface

View file

@ -42,8 +42,7 @@ class irq_master_driver extends uvm_driver #(irq_seq_item);
virtual protected task reset_signals();
forever begin
@(posedge vif.reset);
vif.irq_i <= 'h0;
vif.irq_id_i <= 'hz;
drive_reset_value();
end
endtask : reset_signals
@ -51,16 +50,22 @@ class irq_master_driver extends uvm_driver #(irq_seq_item);
if (trans.delay > 0) begin
repeat(trans.delay) @(posedge vif.clock);
end
vif.irq_i <= 1'b1;
vif.irq_id_i <= trans.irq_id;
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;
@(posedge vif.clock);
while (vif.irq_ack_o !== 1'b1) begin
@(posedge vif.clock);
end
trans.irq_id_o = vif.irq_id_o;
vif.irq_i <= 'h0;
vif.irq_id_i <= 'hz;
drive_reset_value();
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;
endtask : drive_reset_value
endclass : irq_master_driver

View file

@ -28,12 +28,16 @@ class irq_monitor extends uvm_monitor;
virtual protected task collect_irq();
irq_seq_item irq;
forever begin
irq = irq_seq_item::type_id::create("irq");
while (vif.irq_i === 1'b0) @(posedge vif.clock);
irq.irq_id = vif.irq_id_i;
while (vif.irq_ack_o === 1'b0) @(posedge vif.clock);
irq.irq_id_o = vif.irq_id_o;
irq_port.write(irq);
if (|{vif.irq_software, vif.irq_timer, vif.irq_external,
vif.irq_fast, vif.irq_nm}) begin
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_port.write(irq);
end
@(posedge vif.clock);
end
endtask : collect_irq

View file

@ -4,14 +4,20 @@
class irq_seq_item extends uvm_sequence_item;
rand bit [4:0] irq_id;
rand bit [3:0] delay;
rand bit [4:0] irq_id_o;
rand bit irq_software;
rand bit irq_timer;
rand bit irq_external;
rand bit [14:0] irq_fast;
rand bit irq_nm;
rand int unsigned delay;
`uvm_object_utils_begin(irq_seq_item)
`uvm_field_int(irq_id, UVM_DEFAULT)
`uvm_field_int(irq_id_o, UVM_DEFAULT)
`uvm_field_int(delay, UVM_DEFAULT)
`uvm_field_int(irq_software, UVM_DEFAULT)
`uvm_field_int(irq_timer, UVM_DEFAULT)
`uvm_field_int(irq_external, UVM_DEFAULT)
`uvm_field_int(irq_fast, UVM_DEFAULT)
`uvm_field_int(irq_nm, UVM_DEFAULT)
`uvm_field_int(delay, UVM_DEFAULT)
`uvm_object_utils_end
`uvm_object_new

View file

@ -12,7 +12,7 @@ class ibex_asm_program_gen extends riscv_asm_program_gen;
`uvm_object_new
virtual function void gen_program_header();
// Override the cfg value, below field is not supported by ibex
// Override the cfg value, below fields are not supported by ibex
cfg.mstatus_mprv = 0;
cfg.mstatus_mxr = 0;
cfg.mstatus_sum = 0;
@ -28,28 +28,26 @@ class ibex_asm_program_gen extends riscv_asm_program_gen;
instr_stream.push_back(".endm");
instr_stream.push_back(".section .text.init");
instr_stream.push_back(".globl _start");
// 0x0 - 0xFF is reserved for trap/interrupt handling
instr_stream.push_back(".option norvc");
instr_stream.push_back("j mtvec_handler");
// 0x40 debug mode entry
instr_stream.push_back(".align 6");
// 0x0 - 0x4F is reserved for trap/interrupt handling
repeat (20) begin
instr_stream.push_back("j mtvec_handler");
end
// 0x50 debug mode entry
instr_stream.push_back("j debug_rom");
// 0x44 debug mode exception handler
// 0x54 debug mode exception handler
instr_stream.push_back("j debug_exception");
instr_stream.push_back(".option rvc");
// Align the start section to 0x80
instr_stream.push_back(".align 7");
instr_stream.push_back("_start: j _reset_entry");
// ibex reserves 0x84-0x8C for trap handling, redirect everything mtvec_handler
// 0x84 illegal instruction
instr_stream.push_back(".align 2");
instr_stream.push_back("j mtvec_handler");
// 0x88 ECALL instruction handler
instr_stream.push_back(".align 2");
instr_stream.push_back("j mtvec_handler");
// 0x8C LSU error
instr_stream.push_back(".align 2");
instr_stream.push_back("j mtvec_handler");
instr_stream.push_back(".option rvc");
// Starting point of the reset entry
instr_stream.push_back("_reset_entry:");
endfunction

View file

@ -12,10 +12,14 @@ module core_ibex_tb_top;
logic debug_req;
clk_if ibex_clk_if(.clk(clk));
irq_if irq_vif();
// DUT probe interface
core_ibex_dut_probe_if dut_if(.clk(clk));
// TODO(taliu) Resolve the tied-off ports
ibex_core_tracing #(.DmHaltAddr(`BOOT_ADDR + 'h40),
.DmExceptionAddr(`BOOT_ADDR + 'h44)
ibex_core_tracing #(.DmHaltAddr(`BOOT_ADDR + 'h50),
.DmExceptionAddr(`BOOT_ADDR + 'h54)
) dut (
.clk_i(clk),
.rst_ni(rst_n),
@ -24,12 +28,17 @@ module core_ibex_tb_top;
.cluster_id_i('0),
.boot_addr_i(`BOOT_ADDR), // align with spike boot address
.debug_req_i(debug_req),
.fetch_enable_i(fetch_enable)
.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),
.fetch_enable_i(dut_if.fetch_enable),
.debug_req_i(dut_if.debug_req)
);
ibex_mem_intf data_mem_vif();
ibex_mem_intf instr_mem_vif();
irq_if irq_vif();
initial begin
// Data load/store vif connection
@ -58,17 +67,10 @@ module core_ibex_tb_top;
// IRQ interface
force irq_vif.clock = clk;
force irq_vif.reset = ~rst_n;
force dut.irq_i = irq_vif.irq_i;
force dut.irq_id_i = irq_vif.irq_id_i;
force irq_vif.irq_ack_o = dut.irq_ack_o;
force irq_vif.irq_id_o = dut.irq_id_o;
end
// DUT probe interface
core_ibex_dut_probe_if dut_if(.clk(clk));
assign dut_if.ecall = dut.u_ibex_core.id_stage_i.ecall_insn_dec;
assign fetch_enable = dut_if.fetch_enable;
assign debug_req = dut_if.debug_req;
initial begin
uvm_config_db#(virtual clk_if)::set(null, "*", "clk_if", ibex_clk_if);

View file

@ -55,6 +55,7 @@ class core_base_seq #(type REQ = uvm_sequence_item) extends uvm_sequence#(REQ);
virtual task stop();
stop_seq = 1'b1;
`uvm_info(get_full_name(), "Stopping sequence", UVM_LOW)
wait (seq_finished == 1'b1);
endtask
@ -72,6 +73,7 @@ class irq_seq extends core_base_seq#(irq_seq_item);
start_item(irq);
`DV_CHECK_RANDOMIZE_FATAL(irq)
finish_item(irq);
get_response(irq);
endtask
endclass