mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-20 04:07:36 -04:00
add UVM interrupt agent (#2309)
This commit is contained in:
parent
9900d5fd19
commit
2616d5e649
34 changed files with 1583 additions and 34 deletions
14
verif/env/uvme/cov/uvme_cva6_cov_model.sv
vendored
14
verif/env/uvme/cov/uvme_cva6_cov_model.sv
vendored
|
@ -37,6 +37,7 @@ class uvme_cva6_cov_model_c extends uvm_component;
|
|||
uvme_exception_cov_model_c exception_covg;
|
||||
uvme_axi_covg_c axi_covg;
|
||||
uvme_axi_ext_covg_c axi_ext_covg;
|
||||
uvme_interrupt_covg_c interrupt_covg;
|
||||
|
||||
//
|
||||
uvm_analysis_export#(uvma_clknrst_mon_trn_c) reset_export;
|
||||
|
@ -101,12 +102,13 @@ function void uvme_cva6_cov_model_c::build_phase(uvm_phase phase);
|
|||
`uvm_fatal("CNTXT", "Context handle is null")
|
||||
end
|
||||
|
||||
if (cfg.cov_cvxif_model_enabled) begin
|
||||
if (cfg.cvxif_cfg.cov_model_enabled) begin
|
||||
cvxif_covg = uvme_cvxif_covg_c::type_id::create("cvxif_covg", this);
|
||||
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "cvxif_covg", "cfg", cfg);
|
||||
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "cvxif_covg", "cntxt", cntxt);
|
||||
end
|
||||
|
||||
if (cfg.cov_isa_model_enabled) begin
|
||||
if (cfg.isacov_cfg.cov_model_enabled) begin
|
||||
isa_covg = uvme_isa_cov_model_c::type_id::create("isa_covg", this);
|
||||
illegal_covg = uvme_illegal_instr_cov_model_c::type_id::create("illegal_covg", this);
|
||||
exception_covg = uvme_exception_cov_model_c::type_id::create("exception_covg", this);
|
||||
|
@ -114,8 +116,6 @@ function void uvme_cva6_cov_model_c::build_phase(uvm_phase phase);
|
|||
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "illegal_covg", "cfg", cfg);
|
||||
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "exception_covg", "cfg", cfg);
|
||||
end
|
||||
|
||||
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "cvxif_covg", "cntxt", cntxt);
|
||||
|
||||
config_covg = uvme_cva6_config_covg_c::type_id::create("config_covg", this);
|
||||
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "config_covg", "cfg", cfg);
|
||||
|
@ -130,6 +130,12 @@ function void uvme_cva6_cov_model_c::build_phase(uvm_phase phase);
|
|||
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "axi_ext_covg", "cntxt", cntxt);
|
||||
end
|
||||
|
||||
if(cfg.interrupt_cfg.cov_model_enabled) begin
|
||||
interrupt_covg = uvme_interrupt_covg_c::type_id::create("interrupt_covg", this);
|
||||
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "interrupt_covg", "cfg", cfg);
|
||||
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "interrupt_covg", "cntxt", cntxt);
|
||||
end
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
function void uvme_cva6_cov_model_c::connect_phase(uvm_phase phase);
|
||||
|
|
126
verif/env/uvme/cov/uvme_interrupt_covg.sv
vendored
Normal file
126
verif/env/uvme/cov/uvme_interrupt_covg.sv
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
//
|
||||
// Copyright 2024 OpenHW Group
|
||||
// Copyright 2024 Thales
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
covergroup cg_interrupt(
|
||||
string name
|
||||
) with function sample (
|
||||
uvma_isacov_instr_c instr
|
||||
);
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
cp_interrupt: coverpoint instr.rvfi.name_csrs["mcause"].wdata {
|
||||
bins NO_INTERRUPT = {0} iff (!instr.trap);
|
||||
|
||||
bins MACHINE_MODE_EXTERNAL_INTERRUPT = {32'h8000000b} iff (instr.trap);
|
||||
bins MACHINE_MODE_SOFTWARE_INTERRUPT = {32'h80000003} iff (instr.trap);
|
||||
bins MACHINE_MODE_TIMER_INTERRUPT = {32'h80000007} iff (instr.trap);
|
||||
|
||||
}
|
||||
|
||||
cp_mstatus_mie: coverpoint instr.rvfi.name_csrs["mstatus"].wdata[3] {
|
||||
bins GLOBAL_INTERRUPT_ENABLE = {1'h1};
|
||||
}
|
||||
|
||||
cp_msie: coverpoint instr.rvfi.name_csrs["mie"].wdata[3] {
|
||||
bins MSIE = {1'h1};
|
||||
}
|
||||
|
||||
cp_mtie: coverpoint instr.rvfi.name_csrs["mie"].wdata[7] {
|
||||
bins MTIE = {1'h1};
|
||||
}
|
||||
|
||||
cp_meie: coverpoint instr.rvfi.name_csrs["mie"].wdata[11] {
|
||||
bins MEIE = {1'h1};
|
||||
}
|
||||
|
||||
cp_msip: coverpoint instr.rvfi.name_csrs["mip"].wdata[3] {
|
||||
bins MSIP = {1'h1};
|
||||
}
|
||||
|
||||
cp_mtip: coverpoint instr.rvfi.name_csrs["mip"].wdata[7] {
|
||||
bins MTIP = {1'h1};
|
||||
}
|
||||
|
||||
cp_meip: coverpoint instr.rvfi.name_csrs["mip"].wdata[11] {
|
||||
bins MEIP = {1'h1};
|
||||
}
|
||||
|
||||
endgroup : cg_interrupt
|
||||
|
||||
class uvme_interrupt_covg_c extends uvm_component;
|
||||
|
||||
/*
|
||||
* Class members
|
||||
*/
|
||||
// Objects
|
||||
uvme_cva6_cfg_c cfg ;
|
||||
uvme_cva6_cntxt_c cntxt ;
|
||||
|
||||
// TLM
|
||||
uvm_tlm_analysis_fifo#(uvma_isacov_mon_trn_c) mon_trn_fifo;
|
||||
|
||||
uvma_isacov_mon_trn_c mon_trn;
|
||||
|
||||
`uvm_component_utils(uvme_interrupt_covg_c)
|
||||
|
||||
//Interrupt Covergroup
|
||||
cg_interrupt interrupt_cg;
|
||||
|
||||
extern function new(string name = "interrupt_covg", uvm_component parent = null);
|
||||
extern function void build_phase(uvm_phase phase);
|
||||
extern task run_phase(uvm_phase phase);
|
||||
|
||||
endclass : uvme_interrupt_covg_c
|
||||
|
||||
function uvme_interrupt_covg_c::new(string name = "interrupt_covg", uvm_component parent = null);
|
||||
|
||||
super.new(name, parent);
|
||||
|
||||
endfunction : new
|
||||
|
||||
function void uvme_interrupt_covg_c::build_phase(uvm_phase phase);
|
||||
|
||||
super.build_phase(phase);
|
||||
|
||||
void'(uvm_config_db#(uvme_cva6_cfg_c)::get(this, "", "cfg", cfg));
|
||||
if (!cfg) begin
|
||||
`uvm_fatal("CFG", "Configuration handle is null")
|
||||
end
|
||||
|
||||
interrupt_cg = new("interrupt_cg");
|
||||
|
||||
mon_trn_fifo = new("mon_trn_fifo" , this);
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
task uvme_interrupt_covg_c::run_phase(uvm_phase phase);
|
||||
|
||||
super.run_phase(phase);
|
||||
|
||||
`uvm_info(get_type_name(), "The Interrupt env coverage model is running", UVM_LOW);
|
||||
|
||||
forever begin
|
||||
mon_trn_fifo.get(mon_trn);
|
||||
interrupt_cg.sample(mon_trn.instr);
|
||||
end
|
||||
|
||||
endtask : run_phase
|
||||
|
16
verif/env/uvme/uvma_interrupt/README.md
vendored
Normal file
16
verif/env/uvme/uvma_interrupt/README.md
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
Description of the interrupt agent.
|
||||
|
||||
- The interrupt agent supports mainly 3 modes:
|
||||
1 - The agent sends one interrupt request, then we deassert it.
|
||||
2 - The agent sends several interrupt requests at the same time, with the same size, then we deassert the interrupt requests.
|
||||
3 - The agent sends randomized interrupt requests.
|
||||
|
||||
- The interrupt agent has 2 type of delays in `uvma_interrupt_seq_item.sv`:
|
||||
1 - `irq_delay` is related to the delay between two interrupt request.
|
||||
2 - `irq_time` is related to the time the interrupt request could take.
|
||||
|
||||
- The interrupt agent sends requests asynchronously.
|
||||
|
||||
- To enable interrupt requests you should add the option `"+enable_interrupt"`.
|
||||
|
||||
- There is no mechanism to clear the interrupt requests (on going).
|
111
verif/env/uvme/uvma_interrupt/cov/uvma_interrupt_cov_model.sv
vendored
Normal file
111
verif/env/uvme/uvma_interrupt/cov/uvma_interrupt_cov_model.sv
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_COV_MODEL_SV__
|
||||
`define __UVMA_INTERRUPT_COV_MODEL_SV__
|
||||
|
||||
covergroup cg_interrupt(
|
||||
string name
|
||||
) with function
|
||||
sample(uvma_interrupt_seq_item_c req_item);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
cp_interrupt_req : coverpoint req_item.interrupt_valid;
|
||||
|
||||
endgroup: cg_interrupt
|
||||
|
||||
/**
|
||||
* Component encapsulating Interrupt functional coverage model.
|
||||
*/
|
||||
class uvma_interrupt_cov_model_c extends uvm_component;
|
||||
|
||||
// Objects
|
||||
uvma_interrupt_cfg_c cfg;
|
||||
uvma_interrupt_cntxt_c cntxt;
|
||||
|
||||
uvma_interrupt_seq_item_c req_item;
|
||||
|
||||
// TLM
|
||||
uvm_tlm_analysis_fifo#(uvma_interrupt_seq_item_c) seq_item_fifo;
|
||||
|
||||
|
||||
`uvm_component_utils_begin(uvma_interrupt_cov_model_c)
|
||||
`uvm_field_object(cfg , UVM_DEFAULT)
|
||||
`uvm_field_object(cntxt, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
cg_interrupt interrupt_cg;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvma_interrupt_cov_model", uvm_component parent=null);
|
||||
|
||||
/**
|
||||
* 1. Ensures cfg & cntxt handles are not null.
|
||||
* 2. Builds fifos.
|
||||
*/
|
||||
extern virtual function void build_phase(uvm_phase phase);
|
||||
|
||||
/**
|
||||
* Forks all sampling loops
|
||||
*/
|
||||
extern virtual task run_phase(uvm_phase phase);
|
||||
|
||||
endclass : uvma_interrupt_cov_model_c
|
||||
|
||||
|
||||
function uvma_interrupt_cov_model_c::new(string name="uvma_interrupt_cov_model", uvm_component parent=null);
|
||||
|
||||
super.new(name, parent);
|
||||
|
||||
endfunction : new
|
||||
|
||||
|
||||
function void uvma_interrupt_cov_model_c::build_phase(uvm_phase phase);
|
||||
|
||||
super.build_phase(phase);
|
||||
|
||||
void'(uvm_config_db#(uvma_interrupt_cfg_c)::get(this, "", "cfg", cfg));
|
||||
if (cfg == null) begin
|
||||
`uvm_fatal("CFG", "Configuration handle is null")
|
||||
end
|
||||
|
||||
void'(uvm_config_db#(uvma_interrupt_cntxt_c)::get(this, "", "cntxt", cntxt));
|
||||
if (cntxt == null) begin
|
||||
`uvm_fatal("CNTXT", "Context handle is null")
|
||||
end
|
||||
|
||||
interrupt_cg = new("interrupt_cg");
|
||||
|
||||
seq_item_fifo = new("seq_item_fifo", this);
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
|
||||
task uvma_interrupt_cov_model_c::run_phase(uvm_phase phase);
|
||||
|
||||
super.run_phase(phase);
|
||||
|
||||
if (cfg.enabled && cfg.cov_model_enabled) begin
|
||||
|
||||
// Sequence items
|
||||
forever begin
|
||||
seq_item_fifo.get(req_item);
|
||||
interrupt_cg.sample(req_item);
|
||||
end
|
||||
end
|
||||
|
||||
endtask : run_phase
|
||||
|
||||
|
||||
`endif // __UVMA_INTERRUPT_COV_MODEL_SV__
|
55
verif/env/uvme/uvma_interrupt/seq/uvma_interrupt_base_seq.sv
vendored
Normal file
55
verif/env/uvme/uvma_interrupt/seq/uvma_interrupt_base_seq.sv
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_BASE_SEQ_SV__
|
||||
`define __UVMA_INTERRUPT_BASE_SEQ_SV__
|
||||
|
||||
|
||||
/**
|
||||
* Abstract object from which all other Interrupt agent sequences must extend.
|
||||
* Subclasses must be run on Interrupt sequencer (uvma_interrupt_sqr_c) instance.
|
||||
*/
|
||||
class uvma_interrupt_base_seq_c extends uvm_sequence#(uvma_interrupt_seq_item_c);
|
||||
|
||||
`uvm_object_utils(uvma_interrupt_base_seq_c)
|
||||
`uvm_declare_p_sequencer(uvma_interrupt_sqr_c)
|
||||
|
||||
// Objects
|
||||
uvma_interrupt_cfg_c cfg;
|
||||
uvma_interrupt_cntxt_c cntxt;
|
||||
|
||||
uvma_interrupt_seq_item_c req_item;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvma_interrupt_base_seq");
|
||||
|
||||
/**
|
||||
* Assigns cfg and cntxt handles from p_sequencer.
|
||||
*/
|
||||
extern virtual task pre_start();
|
||||
|
||||
endclass : uvma_interrupt_base_seq_c
|
||||
|
||||
function uvma_interrupt_base_seq_c::new(string name="uvma_interrupt_base_seq");
|
||||
|
||||
super.new(name);
|
||||
|
||||
endfunction : new
|
||||
|
||||
task uvma_interrupt_base_seq_c::pre_start();
|
||||
|
||||
cfg = p_sequencer.cfg;
|
||||
cntxt = p_sequencer.cntxt;
|
||||
|
||||
endtask : pre_start
|
||||
|
||||
`endif // __UVMA_INTERRUPT_BASE_SEQ_SV__
|
60
verif/env/uvme/uvma_interrupt/seq/uvma_interrupt_seq.sv
vendored
Normal file
60
verif/env/uvme/uvma_interrupt/seq/uvma_interrupt_seq.sv
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_SEQ_SV__
|
||||
`define __UVMA_INTERRUPT_SEQ_SV__
|
||||
|
||||
|
||||
/**
|
||||
* Abstract object from which all other Interrupt agent sequences must extend.
|
||||
* Subclasses must be run on Interrupt sequencer (uvma_interrupt_sqr_c) instance.
|
||||
*/
|
||||
class uvma_interrupt_seq_c extends uvma_interrupt_base_seq_c;
|
||||
|
||||
`uvm_object_utils(uvma_interrupt_seq_c)
|
||||
`uvm_declare_p_sequencer(uvma_interrupt_sqr_c)
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvma_interrupt_seq");
|
||||
|
||||
extern virtual task body();
|
||||
|
||||
endclass : uvma_interrupt_seq_c
|
||||
|
||||
function uvma_interrupt_seq_c::new(string name="uvma_interrupt_seq");
|
||||
|
||||
super.new(name);
|
||||
|
||||
endfunction : new
|
||||
|
||||
task uvma_interrupt_seq_c::body();
|
||||
|
||||
forever begin
|
||||
req_item = uvma_interrupt_seq_item_c::type_id::create("req_item");
|
||||
|
||||
start_item(req_item);
|
||||
assert(req_item.randomize() with {
|
||||
if(!cfg.enable_interrupt){
|
||||
req_item.interrupt_valid == 'h0;
|
||||
}
|
||||
else {
|
||||
req_item.irq_cntrl != UVMA_INTERRUPT_RANDOMIZE;
|
||||
}
|
||||
})
|
||||
cfg.calc_random_req_latency();
|
||||
|
||||
finish_item(req_item);
|
||||
end
|
||||
|
||||
endtask : body
|
||||
|
||||
`endif // __UVMA_INTERRUPT_SEQ_SV__
|
66
verif/env/uvme/uvma_interrupt/seq/uvma_interrupt_seq_item.sv
vendored
Normal file
66
verif/env/uvme/uvma_interrupt/seq/uvma_interrupt_seq_item.sv
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_SEQ_ITEM_SV__
|
||||
`define __UVMA_INTERRUPT_SEQ_ITEM_SV__
|
||||
|
||||
|
||||
/**
|
||||
* Object created by Interrupt agent sequences extending uvma_interrupt_seq_base_c.
|
||||
*/
|
||||
class uvma_interrupt_seq_item_c extends uvml_trn_seq_item_c;
|
||||
|
||||
rand uvma_interrupt_cntrl_enum irq_cntrl;
|
||||
rand int unsigned irq_delay; // Delay before applying individual interrupt
|
||||
rand int unsigned irq_time; // How many cycles take an interrupt
|
||||
|
||||
rand bit[NUM_IRQ-1:0] interrupt_valid; //the valid interrupts for the core under test
|
||||
|
||||
`uvm_object_utils_begin(uvma_interrupt_seq_item_c)
|
||||
`uvm_field_enum(uvma_interrupt_cntrl_enum, irq_cntrl, UVM_DEFAULT)
|
||||
`uvm_field_int(irq_delay, UVM_DEFAULT)
|
||||
`uvm_field_int(irq_time, UVM_DEFAULT)
|
||||
`uvm_field_int(interrupt_valid, UVM_DEFAULT)
|
||||
`uvm_object_utils_end
|
||||
|
||||
|
||||
constraint default_irq_delay_c {
|
||||
irq_delay inside {[150:250]};
|
||||
}
|
||||
|
||||
constraint default_irq_time_c {
|
||||
irq_time inside {[5:10]};
|
||||
}
|
||||
|
||||
constraint irq_mode_c {
|
||||
|
||||
if (irq_cntrl == UVMA_INTERRUPT_ONE_BY_ONE) {
|
||||
$countones(interrupt_valid) == 1;
|
||||
}
|
||||
if (irq_cntrl == UVMA_INTERRUPT_MORE_THAN_ONE) {
|
||||
$countones(interrupt_valid) > 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvma_interrupt_seq_item");
|
||||
|
||||
endclass : uvma_interrupt_seq_item_c
|
||||
|
||||
function uvma_interrupt_seq_item_c::new(string name="uvma_interrupt_seq_item");
|
||||
|
||||
super.new(name);
|
||||
|
||||
endfunction : new
|
||||
|
||||
|
||||
`endif // __UVMA_INTERRUPT_SEQ_ITEM_SV__
|
182
verif/env/uvme/uvma_interrupt/uvma_interrupt_agent.sv
vendored
Normal file
182
verif/env/uvme/uvma_interrupt/uvma_interrupt_agent.sv
vendored
Normal file
|
@ -0,0 +1,182 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_AGENT_SV__
|
||||
`define __UVMA_INTERRUPT_AGENT_SV__
|
||||
|
||||
class uvma_interrupt_agent_c extends uvm_agent;
|
||||
|
||||
// Objects
|
||||
uvma_interrupt_cfg_c cfg;
|
||||
uvma_interrupt_cntxt_c cntxt;
|
||||
|
||||
// Components
|
||||
uvma_interrupt_mon_c monitor;
|
||||
uvma_interrupt_drv_c driver;
|
||||
uvma_interrupt_sqr_c sequencer;
|
||||
uvma_interrupt_cov_model_c cov_model;
|
||||
|
||||
`uvm_component_utils_begin(uvma_interrupt_agent_c)
|
||||
`uvm_field_object(cfg , UVM_DEFAULT)
|
||||
`uvm_field_object(cntxt, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvma_interrupt_agent", uvm_component parent=null);
|
||||
|
||||
/**
|
||||
* 1. Ensures cfg & cntxt handles are not null
|
||||
* 2. Builds all components
|
||||
*/
|
||||
extern virtual function void build_phase(uvm_phase phase);
|
||||
|
||||
/**
|
||||
* 1. Links agent's analysis ports to sub-components'
|
||||
* 2. Connects coverage models and loggers
|
||||
*/
|
||||
extern virtual function void connect_phase(uvm_phase phase);
|
||||
|
||||
/**
|
||||
* Uses uvm_config_db to retrieve cfg and hand out to sub-components.
|
||||
*/
|
||||
extern function void get_and_set_cfg();
|
||||
|
||||
/**
|
||||
* Uses uvm_config_db to retrieve cntxt and hand out to sub-components.
|
||||
*/
|
||||
extern function void get_and_set_cntxt();
|
||||
|
||||
/**
|
||||
* Uses uvm_config_db to retrieve the Virtual Interface (vif) associated with this
|
||||
* agent.
|
||||
*/
|
||||
extern function void retrieve_vif();
|
||||
|
||||
/**
|
||||
* Creates sub-components.
|
||||
*/
|
||||
extern function void create_components();
|
||||
|
||||
/**
|
||||
* Connects sequencer and driver's TLM port(s).
|
||||
*/
|
||||
extern function void connect_sequencer_and_driver();
|
||||
|
||||
/**
|
||||
* Connects coverage model to monitor and driver's analysis ports.
|
||||
*/
|
||||
extern function void connect_cov_model();
|
||||
|
||||
endclass : uvma_interrupt_agent_c
|
||||
|
||||
|
||||
function uvma_interrupt_agent_c::new(string name="uvma_interrupt_agent", uvm_component parent=null);
|
||||
|
||||
super.new(name, parent);
|
||||
|
||||
endfunction : new
|
||||
|
||||
|
||||
function void uvma_interrupt_agent_c::build_phase(uvm_phase phase);
|
||||
|
||||
super.build_phase(phase);
|
||||
|
||||
get_and_set_cfg ();
|
||||
get_and_set_cntxt();
|
||||
retrieve_vif ();
|
||||
create_components();
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
|
||||
function void uvma_interrupt_agent_c::connect_phase(uvm_phase phase);
|
||||
|
||||
super.connect_phase(phase);
|
||||
|
||||
connect_sequencer_and_driver();
|
||||
connect_cov_model();
|
||||
|
||||
endfunction: connect_phase
|
||||
|
||||
|
||||
function void uvma_interrupt_agent_c::get_and_set_cfg();
|
||||
|
||||
void'(uvm_config_db#(uvma_interrupt_cfg_c)::get(this, "", "cfg", cfg));
|
||||
if (cfg == null) begin
|
||||
`uvm_fatal("CFG", "Configuration handle is null")
|
||||
end
|
||||
else begin
|
||||
`uvm_info("CFG", $sformatf("Found configuration handle:\n%s", cfg.sprint()), UVM_DEBUG)
|
||||
uvm_config_db#(uvma_interrupt_cfg_c)::set(this, "*", "cfg", cfg);
|
||||
end
|
||||
|
||||
endfunction : get_and_set_cfg
|
||||
|
||||
|
||||
function void uvma_interrupt_agent_c::get_and_set_cntxt();
|
||||
|
||||
void'(uvm_config_db#(uvma_interrupt_cntxt_c)::get(this, "", "cntxt", cntxt));
|
||||
if (cntxt == null) begin
|
||||
`uvm_info("CNTXT", "Context handle is null; creating.", UVM_DEBUG)
|
||||
cntxt = uvma_interrupt_cntxt_c::type_id::create("cntxt");
|
||||
end
|
||||
uvm_config_db#(uvma_interrupt_cntxt_c)::set(this, "*", "cntxt", cntxt);
|
||||
|
||||
endfunction : get_and_set_cntxt
|
||||
|
||||
|
||||
function void uvma_interrupt_agent_c::retrieve_vif();
|
||||
|
||||
if (!uvm_config_db#(virtual uvma_interrupt_if)::get(this, "", "interrupt_vif", cntxt.interrupt_vif)) begin
|
||||
`uvm_fatal("VIF", $sformatf("Could not find vif handle of type %s in uvm_config_db", $typename(cntxt.interrupt_vif)))
|
||||
end
|
||||
else begin
|
||||
`uvm_info("VIF", $sformatf("Found vif handle of type %s in uvm_config_db", $typename(cntxt.interrupt_vif)), UVM_DEBUG)
|
||||
end
|
||||
|
||||
endfunction : retrieve_vif
|
||||
|
||||
|
||||
function void uvma_interrupt_agent_c::create_components();
|
||||
|
||||
monitor = uvma_interrupt_mon_c ::type_id::create("monitor" , this);
|
||||
if (cfg.is_active == UVM_ACTIVE) begin
|
||||
sequencer = uvma_interrupt_sqr_c ::type_id::create("sequencer" , this);
|
||||
driver = uvma_interrupt_drv_c ::type_id::create("driver" , this);
|
||||
end
|
||||
if (cfg.cov_model_enabled) begin
|
||||
cov_model = uvma_interrupt_cov_model_c ::type_id::create("cov_model" , this);
|
||||
end
|
||||
|
||||
endfunction : create_components
|
||||
|
||||
|
||||
function void uvma_interrupt_agent_c::connect_sequencer_and_driver();
|
||||
|
||||
if (cfg.is_active == UVM_ACTIVE) begin
|
||||
driver.seq_item_port.connect(sequencer.seq_item_export);
|
||||
end
|
||||
|
||||
endfunction : connect_sequencer_and_driver
|
||||
|
||||
|
||||
function void uvma_interrupt_agent_c::connect_cov_model();
|
||||
|
||||
if (cfg.cov_model_enabled) begin
|
||||
monitor.ap.connect(cov_model.seq_item_fifo.analysis_export);
|
||||
end
|
||||
|
||||
endfunction : connect_cov_model
|
||||
|
||||
|
||||
`endif // __UVMA_INTERRUPT_AGENT_SV__
|
115
verif/env/uvme/uvma_interrupt/uvma_interrupt_cfg.sv
vendored
Normal file
115
verif/env/uvme/uvma_interrupt/uvma_interrupt_cfg.sv
vendored
Normal file
|
@ -0,0 +1,115 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_CFG_SV__
|
||||
`define __UVMA_INTERRUPT_CFG_SV__
|
||||
|
||||
|
||||
class uvma_interrupt_cfg_c extends uvm_object;
|
||||
|
||||
// Common options
|
||||
rand bit enabled;
|
||||
rand uvm_active_passive_enum is_active;
|
||||
|
||||
rand bit cov_model_enabled;
|
||||
rand bit trn_log_enabled;
|
||||
|
||||
rand bit enable_interrupt;
|
||||
bit interrupt_plusarg_valid;
|
||||
|
||||
// Interrupt request latency modes
|
||||
rand uvma_interrupt_drv_req_enum drv_req_mode;
|
||||
rand int unsigned drv_req_fixed_latency;
|
||||
rand int unsigned drv_req_random_latency_min;
|
||||
rand int unsigned drv_req_random_latency_max;
|
||||
|
||||
`uvm_object_utils_begin(uvma_interrupt_cfg_c)
|
||||
`uvm_field_int ( enabled , UVM_DEFAULT)
|
||||
`uvm_field_enum(uvm_active_passive_enum, is_active , UVM_DEFAULT)
|
||||
`uvm_field_int ( cov_model_enabled , UVM_DEFAULT)
|
||||
`uvm_field_int ( trn_log_enabled , UVM_DEFAULT)
|
||||
`uvm_field_int ( enable_interrupt , UVM_DEFAULT)
|
||||
`uvm_field_int ( interrupt_plusarg_valid , UVM_DEFAULT)
|
||||
`uvm_field_enum(uvma_interrupt_drv_req_enum, drv_req_mode , UVM_DEFAULT)
|
||||
`uvm_field_int ( drv_req_fixed_latency , UVM_DEFAULT)
|
||||
`uvm_field_int ( drv_req_random_latency_min , UVM_DEFAULT)
|
||||
`uvm_field_int ( drv_req_random_latency_max , UVM_DEFAULT)
|
||||
`uvm_object_utils_end
|
||||
|
||||
|
||||
constraint defaults_cons {
|
||||
soft enabled == 1;
|
||||
soft is_active == UVM_PASSIVE;
|
||||
soft cov_model_enabled == 1;
|
||||
soft trn_log_enabled == 1;
|
||||
|
||||
}
|
||||
|
||||
constraint default_enable_irq_cons {
|
||||
soft enable_interrupt == 0;
|
||||
}
|
||||
|
||||
constraint default_drive_req_mode_cons {
|
||||
soft drv_req_mode == UVMA_INTERRUPT_DRV_REQ_MODE_FIXED_LATENCY;
|
||||
}
|
||||
|
||||
constraint default_fixed_req_latency_cons {
|
||||
soft drv_req_fixed_latency inside {[250:300]};
|
||||
}
|
||||
|
||||
constraint valid_random_req_latency_cons {
|
||||
drv_req_random_latency_min < drv_req_random_latency_max;
|
||||
}
|
||||
|
||||
constraint default_random_latency_cons {
|
||||
soft drv_req_random_latency_min inside {[50:100]};
|
||||
soft drv_req_random_latency_max inside {[150:200]};
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvma_interrupt_cfg");
|
||||
|
||||
/**
|
||||
* Calculate a new random gnt latency
|
||||
*/
|
||||
extern function int unsigned calc_random_req_latency();
|
||||
|
||||
endclass : uvma_interrupt_cfg_c
|
||||
|
||||
function uvma_interrupt_cfg_c::new(string name="uvma_interrupt_cfg");
|
||||
|
||||
super.new(name);
|
||||
|
||||
// Read plusargs for defaults
|
||||
if ($test$plusargs("enable_interrupt")) begin
|
||||
interrupt_plusarg_valid = 1;
|
||||
end
|
||||
|
||||
endfunction : new
|
||||
|
||||
function int unsigned uvma_interrupt_cfg_c::calc_random_req_latency();
|
||||
|
||||
int unsigned req_latency;
|
||||
|
||||
case (drv_req_mode)
|
||||
UVMA_INTERRUPT_DRV_REQ_MODE_CONSTANT : req_latency = 0;
|
||||
UVMA_INTERRUPT_DRV_REQ_MODE_FIXED_LATENCY : req_latency = drv_req_fixed_latency;
|
||||
UVMA_INTERRUPT_DRV_REQ_MODE_RANDOM_LATENCY: begin
|
||||
req_latency = $urandom_range(drv_req_random_latency_min, drv_req_random_latency_max);
|
||||
end
|
||||
endcase
|
||||
|
||||
return req_latency;
|
||||
|
||||
endfunction : calc_random_req_latency
|
||||
|
||||
`endif // __UVMA_INTERRUPT_CFG_SV__
|
68
verif/env/uvme/uvma_interrupt/uvma_interrupt_cntxt.sv
vendored
Normal file
68
verif/env/uvme/uvma_interrupt/uvma_interrupt_cntxt.sv
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_CNTXT_SV__
|
||||
`define __UVMA_INTERRUPT_CNTXT_SV__
|
||||
|
||||
|
||||
/**
|
||||
* Object encapsulating all state variables for all Interrupt agent
|
||||
* (uvma_interrupt_agent_c) components.
|
||||
*/
|
||||
class uvma_interrupt_cntxt_c extends uvm_object;
|
||||
|
||||
// Handle to agent interface
|
||||
virtual uvma_interrupt_if interrupt_vif;
|
||||
|
||||
// Events
|
||||
uvm_event sample_cfg_e;
|
||||
uvm_event sample_cntxt_e;
|
||||
|
||||
`uvm_object_utils_begin(uvma_interrupt_cntxt_c)
|
||||
`uvm_field_event(sample_cfg_e , UVM_DEFAULT)
|
||||
`uvm_field_event(sample_cntxt_e, UVM_DEFAULT)
|
||||
`uvm_object_utils_end
|
||||
|
||||
/**
|
||||
* Builds events.
|
||||
*/
|
||||
extern function new(string name="uvma_interrupt_cntxt");
|
||||
|
||||
/**
|
||||
* TODO Describe uvma_interrupt_cntxt_c::reset()
|
||||
*/
|
||||
extern function void reset();
|
||||
|
||||
endclass : uvma_interrupt_cntxt_c
|
||||
|
||||
|
||||
`pragma protect begin
|
||||
|
||||
|
||||
function uvma_interrupt_cntxt_c::new(string name="uvma_interrupt_cntxt");
|
||||
|
||||
super.new(name);
|
||||
|
||||
sample_cfg_e = new("sample_cfg_e" );
|
||||
sample_cntxt_e = new("sample_cntxt_e");
|
||||
|
||||
endfunction : new
|
||||
|
||||
function void uvma_interrupt_cntxt_c::reset();
|
||||
|
||||
// TODO Implement uvma_interrupt_cntxt_c::reset()
|
||||
|
||||
endfunction : reset
|
||||
|
||||
|
||||
`pragma protect end
|
||||
|
||||
|
||||
`endif // __UVMA_INTERRUPT_CNTXT_SV__
|
14
verif/env/uvme/uvma_interrupt/uvma_interrupt_constants.sv
vendored
Normal file
14
verif/env/uvme/uvma_interrupt/uvma_interrupt_constants.sv
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_CONSTANTS_SV__
|
||||
`define __UVMA_INTERRUPT_CONSTANTS_SV__
|
||||
|
||||
|
||||
`endif // __UVMA_INTERRUPT_CONSTANTS_SV__
|
165
verif/env/uvme/uvma_interrupt/uvma_interrupt_drv.sv
vendored
Normal file
165
verif/env/uvme/uvma_interrupt/uvma_interrupt_drv.sv
vendored
Normal file
|
@ -0,0 +1,165 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_DRV_SV__
|
||||
`define __UVMA_INTERRUPT_DRV_SV__
|
||||
|
||||
/**
|
||||
* Component driving interrupt virtual interface (uvma_interrupt_if).
|
||||
*/
|
||||
class uvma_interrupt_drv_c extends uvm_driver#(uvma_interrupt_seq_item_c);
|
||||
|
||||
// Objects
|
||||
uvma_interrupt_cfg_c cfg;
|
||||
uvma_interrupt_cntxt_c cntxt;
|
||||
|
||||
uvma_interrupt_seq_item_c req_item;
|
||||
|
||||
`uvm_component_utils_begin(uvma_interrupt_drv_c)
|
||||
`uvm_field_object(cfg , UVM_DEFAULT)
|
||||
`uvm_field_object(cntxt, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvma_interrupt_drv", uvm_component parent=null);
|
||||
|
||||
/**
|
||||
* 1. Ensures cfg & cntxt handles are not null.
|
||||
* 2. Builds ap.
|
||||
*/
|
||||
extern virtual function void build_phase(uvm_phase phase);
|
||||
|
||||
/**
|
||||
* Obtains the reqs from the sequence item port and calls drv_irq()
|
||||
*/
|
||||
extern virtual task run_phase(uvm_phase phase);
|
||||
|
||||
/**
|
||||
* Drives the virtual interface's (cntxt.interrupt_vif) signals using req's contents.
|
||||
*/
|
||||
extern task drv_irq(uvma_interrupt_seq_item_c req);
|
||||
|
||||
/**
|
||||
* Assert only one interrupt each time
|
||||
*/
|
||||
extern task assert_irq_one_by_one(uvma_interrupt_seq_item_c req);
|
||||
|
||||
/**
|
||||
* Assert one or more interrupt each time
|
||||
*/
|
||||
extern task assert_irq_more(uvma_interrupt_seq_item_c req);
|
||||
|
||||
/**
|
||||
* Randomize interrupt signal
|
||||
*/
|
||||
extern task assert_irq_randomize(uvma_interrupt_seq_item_c req);
|
||||
|
||||
endclass : uvma_interrupt_drv_c
|
||||
|
||||
function uvma_interrupt_drv_c::new(string name="uvma_interrupt_drv", uvm_component parent=null);
|
||||
|
||||
super.new(name, parent);
|
||||
|
||||
endfunction : new
|
||||
|
||||
|
||||
function void uvma_interrupt_drv_c::build_phase(uvm_phase phase);
|
||||
|
||||
super.build_phase(phase);
|
||||
|
||||
void'(uvm_config_db#(uvma_interrupt_cfg_c)::get(this, "", "cfg", cfg));
|
||||
if (cfg == null) begin
|
||||
`uvm_fatal("CFG", "Configuration handle is null")
|
||||
end
|
||||
uvm_config_db#(uvma_interrupt_cfg_c)::set(this, "*", "cfg", cfg);
|
||||
|
||||
void'(uvm_config_db#(uvma_interrupt_cntxt_c)::get(this, "", "cntxt", cntxt));
|
||||
if (cntxt == null) begin
|
||||
`uvm_fatal("CNTXT", "Context handle is null")
|
||||
end
|
||||
uvm_config_db#(uvma_interrupt_cntxt_c)::set(this, "*", "cntxt", cntxt);
|
||||
|
||||
req_item = uvma_interrupt_seq_item_c::type_id::create("req_item");
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
task uvma_interrupt_drv_c::run_phase(uvm_phase phase);
|
||||
|
||||
super.run_phase(phase);
|
||||
|
||||
//Initial the interface before the CPU start
|
||||
cntxt.interrupt_vif.irq <= 'h0;
|
||||
|
||||
if(!cfg.enable_interrupt) begin
|
||||
`uvm_warning(get_type_name(), "Driving Interrupt reqeust is disabled");
|
||||
return;
|
||||
end
|
||||
|
||||
forever begin
|
||||
|
||||
seq_item_port.get_next_item(req_item);
|
||||
drv_irq(req_item);
|
||||
seq_item_port.item_done();
|
||||
|
||||
end
|
||||
|
||||
endtask : run_phase
|
||||
|
||||
task uvma_interrupt_drv_c::drv_irq(uvma_interrupt_seq_item_c req);
|
||||
`uvm_info(get_type_name(), $sformatf("Driving:\n%s", req.sprint()), UVM_HIGH);
|
||||
|
||||
case (req.irq_cntrl)
|
||||
UVMA_INTERRUPT_ONE_BY_ONE: begin
|
||||
assert_irq_one_by_one(req);
|
||||
end
|
||||
UVMA_INTERRUPT_MORE_THAN_ONE: begin
|
||||
assert_irq_more(req);
|
||||
end
|
||||
UVMA_INTERRUPT_RANDOMIZE: begin
|
||||
assert_irq_randomize(req);
|
||||
end
|
||||
endcase
|
||||
|
||||
endtask : drv_irq
|
||||
|
||||
task uvma_interrupt_drv_c::assert_irq_one_by_one(uvma_interrupt_seq_item_c req);
|
||||
|
||||
#req.irq_delay;
|
||||
cntxt.interrupt_vif.irq <= req.interrupt_valid;
|
||||
`uvm_info(get_type_name(), $sformatf("Assert interrupt channel(s) %0b", req.interrupt_valid), UVM_HIGH)
|
||||
#req.irq_time;
|
||||
cntxt.interrupt_vif.irq <= 'h0;
|
||||
|
||||
endtask : assert_irq_one_by_one
|
||||
|
||||
task uvma_interrupt_drv_c::assert_irq_more(uvma_interrupt_seq_item_c req);
|
||||
|
||||
#req.irq_delay;
|
||||
cntxt.interrupt_vif.irq <= req.interrupt_valid;
|
||||
#req.irq_time;
|
||||
cntxt.interrupt_vif.irq <= 'h0;
|
||||
|
||||
endtask : assert_irq_more
|
||||
|
||||
task uvma_interrupt_drv_c::assert_irq_randomize(uvma_interrupt_seq_item_c req);
|
||||
|
||||
repeat(5) begin
|
||||
#req.irq_delay;
|
||||
cntxt.interrupt_vif.irq <= req.interrupt_valid;
|
||||
#req.irq_time;
|
||||
end
|
||||
|
||||
cntxt.interrupt_vif.irq <= 'h0;
|
||||
cfg.calc_random_req_latency();
|
||||
|
||||
endtask : assert_irq_randomize
|
||||
|
||||
`endif // __UVMA_INTERRUPT_DRV_SV__
|
28
verif/env/uvme/uvma_interrupt/uvma_interrupt_if.sv
vendored
Normal file
28
verif/env/uvme/uvma_interrupt/uvma_interrupt_if.sv
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_IF_SV__
|
||||
`define __UVMA_INTERRUPT_IF_SV__
|
||||
|
||||
|
||||
/**
|
||||
* Encapsulates all signals and clocking of Interrupt interface. Used by
|
||||
* monitor and driver.
|
||||
*/
|
||||
interface uvma_interrupt_if
|
||||
(
|
||||
);
|
||||
|
||||
logic [uvma_interrupt_pkg::NUM_IRQ-1:0] irq;
|
||||
|
||||
endinterface : uvma_interrupt_if
|
||||
|
||||
|
||||
`endif // __UVMA_INTERRUPT_IF_SV__
|
25
verif/env/uvme/uvma_interrupt/uvma_interrupt_macros.sv
vendored
Normal file
25
verif/env/uvme/uvma_interrupt/uvma_interrupt_macros.sv
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2020 OpenHW Group
|
||||
// Copyright 2020 Datum Technology Corporation
|
||||
// Copyright 2020 Silicon Labs, Inc.
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_MACROS_SV__
|
||||
`define __UVMA_INTERRUPT_MACROS_SV__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
`endif // __UVMA_INTERRUPT_MACROS_SV__
|
114
verif/env/uvme/uvma_interrupt/uvma_interrupt_mon.sv
vendored
Normal file
114
verif/env/uvme/uvma_interrupt/uvma_interrupt_mon.sv
vendored
Normal file
|
@ -0,0 +1,114 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_MON_SV__
|
||||
`define __UVMA_INTERRUPT_MON_SV__
|
||||
|
||||
class uvma_interrupt_mon_c extends uvm_monitor;
|
||||
|
||||
// Objects
|
||||
uvma_interrupt_cfg_c cfg;
|
||||
uvma_interrupt_cntxt_c cntxt;
|
||||
|
||||
`uvm_component_utils_begin(uvma_interrupt_mon_c)
|
||||
`uvm_field_object(cfg , UVM_DEFAULT)
|
||||
`uvm_field_object(cntxt, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
// TLM
|
||||
uvm_analysis_port #(uvma_interrupt_seq_item_c) ap;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvma_interrupt_mon", uvm_component parent=null);
|
||||
|
||||
/**
|
||||
* 1. Ensures cfg & cntxt handles are not null.
|
||||
* 2. Builds ap.
|
||||
*/
|
||||
extern virtual function void build_phase(uvm_phase phase);
|
||||
|
||||
/**
|
||||
* Oversees monitoring via monitor_clk() and monitor_reset() tasks in parallel
|
||||
* forks.
|
||||
*/
|
||||
extern virtual task run_phase(uvm_phase phase);
|
||||
|
||||
/**
|
||||
* Monitor interrupt
|
||||
*/
|
||||
extern virtual task mon_irq();
|
||||
|
||||
endclass : uvma_interrupt_mon_c
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
function uvma_interrupt_mon_c::new(string name = "uvma_interrupt_mon", uvm_component parent);
|
||||
super.new(name, parent);
|
||||
|
||||
endfunction
|
||||
|
||||
/**
|
||||
* 1. Ensures cfg & cntxt handles are not null.
|
||||
* 2. Builds ap.
|
||||
*/
|
||||
function void uvma_interrupt_mon_c::build_phase(uvm_phase phase);
|
||||
|
||||
super.build_phase(phase);
|
||||
|
||||
void'(uvm_config_db#(uvma_interrupt_cntxt_c)::get(this, "", "cntxt", cntxt));
|
||||
if (cntxt == null) begin
|
||||
`uvm_fatal("build_phase", "monitor cntxt class failed")
|
||||
end
|
||||
|
||||
void'(uvm_config_db#(uvma_interrupt_cfg_c)::get(this, "", "cfg", cfg));
|
||||
if (cfg == null) begin
|
||||
`uvm_fatal("CFG", "Configuration handle is null")
|
||||
end
|
||||
|
||||
ap = new("ap", this);
|
||||
|
||||
endfunction
|
||||
|
||||
/**
|
||||
* TODO Describe uvma_interrupt_mon_c::run_phase()
|
||||
*/
|
||||
task uvma_interrupt_mon_c::run_phase(uvm_phase phase);
|
||||
super.run_phase(phase);
|
||||
|
||||
fork
|
||||
begin
|
||||
mon_irq();
|
||||
end
|
||||
join_none
|
||||
|
||||
endtask: run_phase
|
||||
|
||||
/**
|
||||
* TODO Describe uvma_interrupt_mon_c::mon_post_reset()
|
||||
*/
|
||||
task uvma_interrupt_mon_c::mon_irq();
|
||||
|
||||
uvma_interrupt_seq_item_c irq_item;
|
||||
|
||||
while(1) begin
|
||||
@(cntxt.interrupt_vif.irq);
|
||||
|
||||
irq_item = uvma_interrupt_seq_item_c::type_id::create("irq_item");
|
||||
irq_item.interrupt_valid = cntxt.interrupt_vif.irq;
|
||||
`uvm_info(get_type_name(), $sformatf("monitor interrupt : %0d", irq_item.interrupt_valid), UVM_LOW)
|
||||
ap.write(irq_item);
|
||||
|
||||
end
|
||||
|
||||
endtask: mon_irq
|
||||
|
||||
`endif
|
17
verif/env/uvme/uvma_interrupt/uvma_interrupt_pkg.flist
vendored
Normal file
17
verif/env/uvme/uvma_interrupt/uvma_interrupt_pkg.flist
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
// Directories
|
||||
+incdir+${DV_UVMA_INTERRUPT_PATH}
|
||||
+incdir+${DV_UVMA_INTERRUPT_PATH}/cov
|
||||
+incdir+${DV_UVMA_INTERRUPT_PATH}/seq
|
||||
|
||||
// Files
|
||||
${DV_UVMA_INTERRUPT_PATH}/uvma_interrupt_pkg.sv
|
61
verif/env/uvme/uvma_interrupt/uvma_interrupt_pkg.sv
vendored
Normal file
61
verif/env/uvme/uvma_interrupt/uvma_interrupt_pkg.sv
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_PKG_SV__
|
||||
`define __UVMA_INTERRUPT_PKG_SV__
|
||||
|
||||
|
||||
// Pre-processor macros
|
||||
`include "uvm_macros.svh"
|
||||
`include "uvml_hrtbt_macros.sv"
|
||||
`include "uvma_interrupt_macros.sv"
|
||||
|
||||
/**
|
||||
* Encapsulates all the types needed for an UVM agent capable of driving and/or
|
||||
* monitoring Clock & Reset.
|
||||
*/
|
||||
|
||||
package uvma_interrupt_pkg;
|
||||
|
||||
import uvm_pkg ::*;
|
||||
import uvml_hrtbt_pkg::*;
|
||||
import uvml_trn_pkg ::*;
|
||||
import uvml_logs_pkg ::*;
|
||||
|
||||
parameter NUM_IRQ = 3;
|
||||
|
||||
// Constants / Structs / Enums
|
||||
`include "uvma_interrupt_constants.sv"
|
||||
`include "uvma_interrupt_tdefs.sv"
|
||||
|
||||
// Objects
|
||||
`include "uvma_interrupt_cfg.sv"
|
||||
`include "uvma_interrupt_cntxt.sv"
|
||||
|
||||
// High-level transactions
|
||||
`include "uvma_interrupt_seq_item.sv"
|
||||
|
||||
// Agent components
|
||||
`include "uvma_interrupt_cov_model.sv"
|
||||
`include "uvma_interrupt_mon.sv"
|
||||
`include "uvma_interrupt_drv.sv"
|
||||
`include "uvma_interrupt_sqr.sv"
|
||||
`include "uvma_interrupt_agent.sv"
|
||||
|
||||
// Sequences
|
||||
`include "uvma_interrupt_base_seq.sv"
|
||||
`include "uvma_interrupt_seq.sv"
|
||||
|
||||
endpackage : uvma_interrupt_pkg
|
||||
|
||||
// Interface(s) / Module(s) / Checker(s)
|
||||
`include "uvma_interrupt_if.sv"
|
||||
|
||||
`endif // __UVMA_INTERRUPT_PKG_SV__
|
77
verif/env/uvme/uvma_interrupt/uvma_interrupt_sqr.sv
vendored
Normal file
77
verif/env/uvme/uvma_interrupt/uvma_interrupt_sqr.sv
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
//
|
||||
// Copyright 2020 OpenHW Group
|
||||
// Copyright 2020 Datum Technology Corporation
|
||||
// Copyright 2020 Silicon Labs, Inc.
|
||||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_SQR_SV__
|
||||
`define __UVMA_INTERRUPT_SQR_SV__
|
||||
|
||||
|
||||
/**
|
||||
* Component running interrupt sequences extending uvma_interrupt_seq_base_c.
|
||||
* Provides sequence items for uvma_interrupt_drv_c.
|
||||
*/
|
||||
class uvma_interrupt_sqr_c extends uvm_sequencer#(uvma_interrupt_seq_item_c);
|
||||
|
||||
// Objects
|
||||
uvma_interrupt_cfg_c cfg;
|
||||
uvma_interrupt_cntxt_c cntxt;
|
||||
|
||||
// Analysis port to receive
|
||||
uvm_tlm_analysis_fifo #(uvma_interrupt_seq_item_c) mm_req_fifo;
|
||||
|
||||
`uvm_component_utils_begin(uvma_interrupt_sqr_c)
|
||||
`uvm_field_object(cfg , UVM_DEFAULT)
|
||||
`uvm_field_object(cntxt, UVM_DEFAULT)
|
||||
`uvm_component_utils_end
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvma_interrupt_sqr", uvm_component parent=null);
|
||||
|
||||
/**
|
||||
* Ensures cfg & cntxt handles are not null
|
||||
*/
|
||||
extern virtual function void build_phase(uvm_phase phase);
|
||||
|
||||
endclass : uvma_interrupt_sqr_c
|
||||
|
||||
|
||||
function uvma_interrupt_sqr_c::new(string name="uvma_interrupt_sqr", uvm_component parent=null);
|
||||
|
||||
super.new(name, parent);
|
||||
|
||||
endfunction : new
|
||||
|
||||
|
||||
function void uvma_interrupt_sqr_c::build_phase(uvm_phase phase);
|
||||
|
||||
super.build_phase(phase);
|
||||
|
||||
void'(uvm_config_db#(uvma_interrupt_cfg_c)::get(this, "", "cfg", cfg));
|
||||
if (cfg == null) begin
|
||||
`uvm_fatal("CFG", "Configuration handle is null")
|
||||
end
|
||||
|
||||
void'(uvm_config_db#(uvma_interrupt_cntxt_c)::get(this, "", "cntxt", cntxt));
|
||||
if (cntxt == null) begin
|
||||
`uvm_fatal("CNTXT", "Context handle is null")
|
||||
end
|
||||
|
||||
mm_req_fifo = new("mm_req_fifo", this);
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
|
||||
`endif // __UVMA_INTERRUPT_SQR_SV__
|
25
verif/env/uvme/uvma_interrupt/uvma_interrupt_tdefs.sv
vendored
Normal file
25
verif/env/uvme/uvma_interrupt/uvma_interrupt_tdefs.sv
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2024 Thales DIS SAS
|
||||
//
|
||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
//
|
||||
// Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
`ifndef __UVMA_INTERRUPT_TDEFS_SV__
|
||||
`define __UVMA_INTERRUPT_TDEFS_SV__
|
||||
|
||||
typedef enum {
|
||||
UVMA_INTERRUPT_ONE_BY_ONE,
|
||||
UVMA_INTERRUPT_MORE_THAN_ONE,
|
||||
UVMA_INTERRUPT_RANDOMIZE
|
||||
} uvma_interrupt_cntrl_enum;
|
||||
|
||||
typedef enum {
|
||||
UVMA_INTERRUPT_DRV_REQ_MODE_CONSTANT,
|
||||
UVMA_INTERRUPT_DRV_REQ_MODE_FIXED_LATENCY,
|
||||
UVMA_INTERRUPT_DRV_REQ_MODE_RANDOM_LATENCY
|
||||
} uvma_interrupt_drv_req_enum;
|
||||
|
||||
`endif // __UVMA_INTERRUPT_TDEFS_SV__
|
38
verif/env/uvme/uvme_cva6_cfg.sv
vendored
38
verif/env/uvme/uvme_cva6_cfg.sv
vendored
|
@ -34,8 +34,6 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
|||
rand bit scoreboard_enabled;
|
||||
rand bit tandem_enabled;
|
||||
rand bit cov_model_enabled;
|
||||
rand bit cov_cvxif_model_enabled;
|
||||
rand bit cov_isa_model_enabled;
|
||||
rand bit trn_log_enabled;
|
||||
rand int unsigned sys_clk_period;
|
||||
|
||||
|
@ -45,6 +43,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
|||
rand uvma_axi_cfg_c axi_cfg;
|
||||
rand uvma_rvfi_cfg_c#(ILEN,XLEN) rvfi_cfg;
|
||||
rand uvma_isacov_cfg_c isacov_cfg;
|
||||
rand uvma_interrupt_cfg_c interrupt_cfg;
|
||||
|
||||
// Zicond extension
|
||||
rand bit ext_zicond_supported;
|
||||
|
@ -84,6 +83,8 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
|||
|
||||
`uvm_field_object(isacov_cfg, UVM_DEFAULT)
|
||||
|
||||
`uvm_field_object(interrupt_cfg, UVM_DEFAULT)
|
||||
|
||||
`uvm_object_utils_end
|
||||
|
||||
|
||||
|
@ -185,11 +186,20 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
|||
(!dm_exception_addr_plusarg_valid) -> (dm_exception_addr == 'h0000_0000);
|
||||
}
|
||||
|
||||
constraint default_interrupt_cons {
|
||||
if (interrupt_cfg.interrupt_plusarg_valid) {
|
||||
interrupt_cfg.enable_interrupt == 'h1;
|
||||
}
|
||||
else
|
||||
interrupt_cfg.enable_interrupt == 'h0;
|
||||
}
|
||||
|
||||
constraint agent_cfg_cons {
|
||||
if (enabled) {
|
||||
clknrst_cfg.enabled == 1;
|
||||
isacov_cfg.enabled == 1;
|
||||
rvfi_cfg.enabled == 1;
|
||||
clknrst_cfg.enabled == 1;
|
||||
isacov_cfg.enabled == 1;
|
||||
rvfi_cfg.enabled == 1;
|
||||
interrupt_cfg.enabled == 1;
|
||||
}
|
||||
|
||||
isacov_cfg.seq_instr_group_x2_enabled == 1;
|
||||
|
@ -203,9 +213,10 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
|||
axi_cfg.rand_channel_delay_enabled == 0;
|
||||
|
||||
if (is_active == UVM_ACTIVE) {
|
||||
clknrst_cfg.is_active == UVM_ACTIVE;
|
||||
isacov_cfg.is_active == UVM_PASSIVE;
|
||||
rvfi_cfg.is_active == UVM_PASSIVE;
|
||||
clknrst_cfg.is_active == UVM_ACTIVE;
|
||||
isacov_cfg.is_active == UVM_PASSIVE;
|
||||
rvfi_cfg.is_active == UVM_PASSIVE;
|
||||
interrupt_cfg.is_active == UVM_ACTIVE;
|
||||
}
|
||||
|
||||
if (trn_log_enabled) {
|
||||
|
@ -216,12 +227,10 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
|||
}
|
||||
|
||||
if (cov_model_enabled) {
|
||||
cvxif_cfg.cov_model_enabled == 1;
|
||||
isacov_cfg.cov_model_enabled == 1;
|
||||
axi_cfg.cov_model_enabled == 1;
|
||||
//env coverage models
|
||||
cov_cvxif_model_enabled == 1;
|
||||
cov_isa_model_enabled == 1;
|
||||
cvxif_cfg.cov_model_enabled == 1;
|
||||
isacov_cfg.cov_model_enabled == 1;
|
||||
axi_cfg.cov_model_enabled == 1;
|
||||
interrupt_cfg.cov_model_enabled == 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -253,6 +262,7 @@ function uvme_cva6_cfg_c::new(string name="uvme_cva6_cfg");
|
|||
axi_cfg = uvma_axi_cfg_c::type_id::create("axi_cfg");
|
||||
rvfi_cfg = uvma_rvfi_cfg_c#(ILEN,XLEN)::type_id::create("rvfi_cfg");
|
||||
isacov_cfg = uvma_isacov_cfg_c::type_id::create("isacov_cfg");
|
||||
interrupt_cfg = uvma_interrupt_cfg_c::type_id::create("interrupt_cfg");
|
||||
|
||||
isacov_cfg.core_cfg = this;
|
||||
rvfi_cfg.core_cfg = this;
|
||||
|
|
3
verif/env/uvme/uvme_cva6_cntxt.sv
vendored
3
verif/env/uvme/uvme_cva6_cntxt.sv
vendored
|
@ -35,6 +35,7 @@ class uvme_cva6_cntxt_c extends uvm_object;
|
|||
uvma_axi_cntxt_c axi_cntxt;
|
||||
uvma_cva6_core_cntrl_cntxt_c core_cntrl_cntxt;
|
||||
uvma_rvfi_cntxt_c rvfi_cntxt;
|
||||
uvma_interrupt_cntxt_c interrupt_cntxt;
|
||||
|
||||
// Memory modelling
|
||||
rand uvml_mem_cva6 mem;
|
||||
|
@ -49,6 +50,7 @@ class uvme_cva6_cntxt_c extends uvm_object;
|
|||
`uvm_field_object(axi_cntxt, UVM_DEFAULT)
|
||||
`uvm_field_object(core_cntrl_cntxt, UVM_DEFAULT)
|
||||
`uvm_field_object(rvfi_cntxt, UVM_DEFAULT)
|
||||
`uvm_field_object(interrupt_cntxt, UVM_DEFAULT)
|
||||
`uvm_field_event(sample_cfg_e , UVM_DEFAULT)
|
||||
`uvm_field_event(sample_cntxt_e, UVM_DEFAULT)
|
||||
`uvm_field_object(mem, UVM_DEFAULT)
|
||||
|
@ -75,6 +77,7 @@ function uvme_cva6_cntxt_c::new(string name="uvme_cva6_cntxt");
|
|||
axi_cntxt = uvma_axi_cntxt_c::type_id::create("axi_cntxt");
|
||||
mem = uvml_mem_cva6::type_id::create("mem");
|
||||
rvfi_cntxt = uvma_rvfi_cntxt_c#()::type_id::create("rvfi_cntxt");
|
||||
interrupt_cntxt = uvma_interrupt_cntxt_c::type_id::create("interrupt_cntxt");
|
||||
|
||||
sample_cfg_e = new("sample_cfg_e" );
|
||||
sample_cntxt_e = new("sample_cntxt_e");
|
||||
|
|
22
verif/env/uvme/uvme_cva6_env.sv
vendored
22
verif/env/uvme/uvme_cva6_env.sv
vendored
|
@ -47,6 +47,7 @@ class uvme_cva6_env_c extends uvm_env;
|
|||
uvma_cva6_core_cntrl_agent_c core_cntrl_agent;
|
||||
uvma_rvfi_agent_c#(ILEN,XLEN) rvfi_agent;
|
||||
uvma_isacov_agent_c#(ILEN,XLEN) isacov_agent;
|
||||
uvma_interrupt_agent_c interrupt_agent;
|
||||
|
||||
// Handle to agent switch interface
|
||||
virtual uvmt_axi_switch_intf axi_switch_vif;
|
||||
|
@ -258,6 +259,8 @@ function void uvme_cva6_env_c::assign_cfg();
|
|||
uvm_config_db#(uvma_core_cntrl_cfg_c)::set(this, "*rvfi_scoreboard", "cfg", cfg);
|
||||
uvm_config_db#(uvma_core_cntrl_cfg_c)::set(this, "reference_model", "cfg", cfg);
|
||||
|
||||
uvm_config_db#(uvma_interrupt_cfg_c)::set(this, "*interrupt_agent", "cfg", cfg.interrupt_cfg);
|
||||
|
||||
endfunction: assign_cfg
|
||||
|
||||
|
||||
|
@ -267,6 +270,7 @@ function void uvme_cva6_env_c::assign_cntxt();
|
|||
uvm_config_db#(uvma_clknrst_cntxt_c)::set(this, "clknrst_agent", "cntxt", cntxt.clknrst_cntxt);
|
||||
uvm_config_db#(uvma_axi_cntxt_c)::set(this, "axi_agent", "cntxt", cntxt.axi_cntxt);
|
||||
uvm_config_db#(uvma_rvfi_cntxt_c)::set(this, "rvfi_agent", "cntxt", cntxt.rvfi_cntxt);
|
||||
uvm_config_db#(uvma_interrupt_cntxt_c)::set(this, "interrupt_agent", "cntxt", cntxt.interrupt_cntxt);
|
||||
|
||||
endfunction: assign_cntxt
|
||||
|
||||
|
@ -279,6 +283,7 @@ function void uvme_cva6_env_c::create_agents();
|
|||
core_cntrl_agent = uvma_cva6_core_cntrl_agent_c::type_id::create("core_cntrl_agent", this);
|
||||
rvfi_agent = uvma_rvfi_agent_c#(ILEN,XLEN)::type_id::create("rvfi_agent", this);
|
||||
isacov_agent = uvma_isacov_agent_c#(ILEN,XLEN)::type_id::create("isacov_agent", this);
|
||||
interrupt_agent = uvma_interrupt_agent_c::type_id::create("interrupt_agent", this);
|
||||
|
||||
endfunction: create_agents
|
||||
|
||||
|
@ -358,6 +363,7 @@ function void uvme_cva6_env_c::assemble_vsequencer();
|
|||
vsequencer.clknrst_sequencer = clknrst_agent.sequencer;
|
||||
vsequencer.cvxif_vsequencer = cvxif_agent.vsequencer;
|
||||
vsequencer.axi_vsequencer = axi_agent.vsequencer;
|
||||
vsequencer.interrupt_sequencer = interrupt_agent.sequencer;
|
||||
|
||||
endfunction: assemble_vsequencer
|
||||
|
||||
|
@ -379,15 +385,23 @@ task uvme_cva6_env_c::run_phase(uvm_phase phase);
|
|||
axi_vseq.start(axi_agent.vsequencer);
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
if(cfg.interrupt_cfg.is_active == UVM_ACTIVE) begin
|
||||
uvma_interrupt_seq_c interrupt_seq;
|
||||
interrupt_seq = uvma_interrupt_seq_c::type_id::create("interrupt_seq");
|
||||
interrupt_seq.start(interrupt_agent.sequencer);
|
||||
end
|
||||
end
|
||||
join_none
|
||||
endtask
|
||||
|
||||
function void uvme_cva6_env_c::connect_coverage_model();
|
||||
|
||||
if (cfg.cov_cvxif_model_enabled) begin
|
||||
if (cfg.cvxif_cfg.cov_model_enabled) begin
|
||||
cvxif_agent.monitor.req_ap.connect(cov_model.cvxif_covg.req_item_fifo.analysis_export);
|
||||
end
|
||||
if (cfg.cov_isa_model_enabled) begin
|
||||
if (cfg.isacov_cfg.cov_model_enabled) begin
|
||||
isacov_agent.monitor.ap.connect(cov_model.isa_covg.mon_trn_fifo.analysis_export);
|
||||
isacov_agent.monitor.ap.connect(cov_model.illegal_covg.mon_trn_fifo.analysis_export);
|
||||
isacov_agent.monitor.ap.connect(cov_model.exception_covg.mon_trn_fifo.analysis_export);
|
||||
|
@ -408,6 +422,10 @@ function void uvme_cva6_env_c::connect_coverage_model();
|
|||
axi_agent.monitor.m_axi_superset_write_req_packets_collected.connect(cov_model.axi_ext_covg.uvme_axi_cov_aw_req_fifo.analysis_export);
|
||||
end
|
||||
|
||||
if(cfg.interrupt_cfg.cov_model_enabled) begin
|
||||
isacov_agent.monitor.ap.connect(cov_model.interrupt_covg.mon_trn_fifo.analysis_export);
|
||||
end
|
||||
|
||||
endfunction: connect_coverage_model
|
||||
|
||||
`endif // __UVME_CVA6_ENV_SV__
|
||||
|
|
1
verif/env/uvme/uvme_cva6_pkg.flist
vendored
1
verif/env/uvme/uvme_cva6_pkg.flist
vendored
|
@ -22,6 +22,7 @@
|
|||
+incdir+${CVA6_UVME_PATH}/cov
|
||||
+incdir+${CVA6_UVME_PATH}/vseq
|
||||
+incdir+${CVA6_UVME_PATH}/cvxif_vseq
|
||||
+incdir+${CVA6_UVME_PATH}/uvma_interrupt
|
||||
|
||||
// Files
|
||||
${CVA6_UVME_PATH}/uvme_cva6_pkg.sv
|
||||
|
|
3
verif/env/uvme/uvme_cva6_pkg.sv
vendored
3
verif/env/uvme/uvme_cva6_pkg.sv
vendored
|
@ -54,7 +54,9 @@ package uvme_cva6_pkg;
|
|||
import uvmc_rvfi_scoreboard_pkg::*;
|
||||
import uvmc_rvfi_reference_model_pkg::*;
|
||||
import uvma_isacov_pkg::*;
|
||||
import uvma_interrupt_pkg::*;
|
||||
import config_pkg::*;
|
||||
|
||||
import "DPI-C" function void read_elf(input string filename);
|
||||
import "DPI-C" function byte get_section(output longint address, output longint len);
|
||||
import "DPI-C" context function void read_section_sv(input longint address, inout byte buffer[]);
|
||||
|
@ -102,6 +104,7 @@ package uvme_cva6_pkg;
|
|||
`include "uvme_isa_covg.sv"
|
||||
`include "uvme_illegal_instr_covg.sv"
|
||||
`include "uvme_exception_covg.sv"
|
||||
`include "uvme_interrupt_covg.sv"
|
||||
`include "uvme_cva6_config_covg.sv"
|
||||
`include "uvme_axi_covg.sv"
|
||||
`include "uvme_axi_ext_covg.sv"
|
||||
|
|
7
verif/env/uvme/uvme_cva6_vsqr.sv
vendored
7
verif/env/uvme/uvme_cva6_vsqr.sv
vendored
|
@ -35,9 +35,10 @@ class uvme_cva6_vsqr_c extends uvm_sequencer#(
|
|||
uvme_cva6_cntxt_c cntxt;
|
||||
|
||||
// Sequencer handles
|
||||
uvma_clknrst_sqr_c clknrst_sequencer;
|
||||
uvma_cvxif_vsqr_c cvxif_vsequencer;
|
||||
uvma_axi_vsqr_c axi_vsequencer;
|
||||
uvma_clknrst_sqr_c clknrst_sequencer;
|
||||
uvma_cvxif_vsqr_c cvxif_vsequencer;
|
||||
uvma_axi_vsqr_c axi_vsequencer;
|
||||
uvma_interrupt_sqr_c interrupt_sequencer;
|
||||
|
||||
|
||||
`uvm_component_utils_begin(uvme_cva6_vsqr_c)
|
||||
|
|
42
verif/regress/dv-interrupt-test.sh
Normal file
42
verif/regress/dv-interrupt-test.sh
Normal file
|
@ -0,0 +1,42 @@
|
|||
# Copyright 2023 Thales DIS
|
||||
#
|
||||
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
# You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
#
|
||||
# Original Author: Ayoub JALALI - Thales
|
||||
|
||||
if [ -n "$RISCV_ZCB" ]; then
|
||||
echo "Using RISCV_ZCB to support Zcb extension"
|
||||
RISCV=$RISCV_ZCB
|
||||
fi
|
||||
|
||||
if ! [ -n "$RISCV" ]; then
|
||||
echo "Error: RISCV variable undefined"
|
||||
return
|
||||
fi
|
||||
|
||||
# install the required tools
|
||||
source ./verif/regress/install-verilator.sh
|
||||
source ./verif/regress/install-spike.sh
|
||||
|
||||
source ./verif/sim/setup-env.sh
|
||||
|
||||
export cov=1 #enable the Code Coverage
|
||||
|
||||
if ! [ -n "$DV_TARGET" ]; then
|
||||
DV_TARGET=cv32a65x
|
||||
fi
|
||||
|
||||
if ! [ -n "$DV_SIMULATORS" ]; then
|
||||
DV_SIMULATORS=vcs-uvm,spike
|
||||
fi
|
||||
|
||||
cd verif/sim/
|
||||
cp ../env/corev-dv/custom/riscv_custom_instr_enum.sv ./dv/src/isa/custom/
|
||||
|
||||
python3 cva6.py --testlist=cva6_base_testlist.yaml --test riscv_interrupt_test --iss_yaml cva6.yaml --target $DV_TARGET -cs ../env/corev-dv/target/rv32imcb/ --mabi ilp32 --isa rv32imc --isa_extension="zba,zbb,zbc,zbs,zcb" --simulator_yaml ../env/corev-dv/simulator.yaml --iss=$DV_SIMULATORS --priv=m --issrun_opts="+enable_interrupt" -i 5 -bz 1 --iss_timeout 300
|
||||
python3 cva6.py --testlist=../tests/testlist_interrupt.yaml --test jump_to_zero --iss_yaml cva6.yaml --target $DV_TARGET -cs ../env/corev-dv/target/rv32imcb/ --mabi ilp32 --isa rv32imc --isa_extension="zba,zbb,zbc,zbs,zcb" --simulator_yaml ../env/corev-dv/simulator.yaml --iss=$DV_SIMULATORS --priv=m --issrun_opts="+enable_interrupt"
|
||||
|
||||
cd -
|
|
@ -164,7 +164,7 @@ export DV_UVMA_ISACOV_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_isacov
|
|||
export DV_UVMA_CLKNRST_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_clknrst
|
||||
export DV_UVMA_CVXIF_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_cvxif
|
||||
export DV_UVMA_AXI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_axi5
|
||||
export DV_UVMA_INTERRUPT_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_interrupt
|
||||
export DV_UVMA_INTERRUPT_PATH = $(DV_UVME_PATH)/uvma_interrupt
|
||||
export DV_UVMA_DEBUG_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_debug
|
||||
export DV_UVMA_OBI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_obi
|
||||
export DV_UVMC_RVFI_SCOREBOARD_PATH = $(CORE_V_VERIF)/lib/uvm_components/uvmc_rvfi_scoreboard/
|
||||
|
|
|
@ -730,3 +730,34 @@
|
|||
iterations: 2
|
||||
gen_test: cva6_instr_hazard_test_c
|
||||
rtl_test: core_base_test
|
||||
|
||||
- test: riscv_interrupt_test
|
||||
description: >
|
||||
Arithmetic instruction test, no load/store/branch instructions no compressed
|
||||
gcc_opts: >
|
||||
-static
|
||||
-mcmodel=medany
|
||||
-fvisibility=hidden
|
||||
-nostdlib
|
||||
-nostartfiles
|
||||
gen_opts: >
|
||||
+instr_cnt=500
|
||||
+num_of_sub_program=0
|
||||
+no_fence=1
|
||||
+no_data_page=1
|
||||
+enable_interrupt=1
|
||||
+enable_timer_irq=1
|
||||
+no_branch_jump=1
|
||||
+no_wfi=0
|
||||
+boot_mode=m
|
||||
+no_csr_instr=1
|
||||
+tvec_alignment=8
|
||||
+disable_compressed_instr=1
|
||||
+enable_zba_extension=1
|
||||
+enable_zbb_extension=1
|
||||
+enable_zbc_extension=1
|
||||
+enable_zbs_extension=1
|
||||
+enable_zcb_extension=1
|
||||
iterations: 2
|
||||
gen_test: cva6_instr_base_test_c
|
||||
rtl_test: core_base_test
|
||||
|
|
|
@ -58,6 +58,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
|||
output rvfi_csr_t rvfi_csr_o,
|
||||
input cvxif_pkg::cvxif_resp_t cvxif_resp,
|
||||
output cvxif_pkg::cvxif_req_t cvxif_req,
|
||||
input logic [2:0] irq_i,
|
||||
uvma_axi_intf axi_slave,
|
||||
uvmt_axi_switch_intf axi_switch_vif,
|
||||
uvmt_default_inputs_intf default_inputs_vif
|
||||
|
@ -81,19 +82,19 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
|||
.rvfi_probes_csr_t ( rvfi_probes_csr_t ),
|
||||
.rvfi_probes_t ( rvfi_probes_t )
|
||||
) i_cva6 (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.boot_addr_i ( boot_addr_i ),//Driving the boot_addr value from the core control agent
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.boot_addr_i ( boot_addr_i ),//Driving the boot_addr value from the core control agent
|
||||
.hart_id_i ( default_inputs_vif.hart_id ),
|
||||
.irq_i ( default_inputs_vif.irq ),
|
||||
.ipi_i ( default_inputs_vif.ipi ),
|
||||
.time_irq_i ( default_inputs_vif.time_irq ),
|
||||
.irq_i ( {1'b0, irq_i[0]} ),
|
||||
.ipi_i ( irq_i[1] ),
|
||||
.time_irq_i ( irq_i[2] ),
|
||||
.debug_req_i ( default_inputs_vif.debug_req ),
|
||||
.rvfi_probes_o ( rvfi_probes ),
|
||||
.cvxif_req_o ( cvxif_req ),
|
||||
.cvxif_resp_i ( cvxif_resp ),
|
||||
.noc_req_o ( axi_ariane_req ),
|
||||
.noc_resp_i ( axi_ariane_resp )
|
||||
.cvxif_req_o ( cvxif_req ),
|
||||
.cvxif_resp_i ( cvxif_resp ),
|
||||
.noc_req_o ( axi_ariane_req ),
|
||||
.noc_resp_i ( axi_ariane_resp )
|
||||
);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
-f ${DV_UVMA_ISACOV_PATH}/uvma_isacov_pkg.flist
|
||||
-f ${DV_UVMC_RVFI_REFERENCE_MODEL_PATH}/uvmc_rvfi_reference_model_pkg.flist
|
||||
-f ${DV_UVMC_RVFI_SCOREBOARD_PATH}/uvmc_rvfi_scoreboard_pkg.flist
|
||||
-f ${CVA6_UVME_PATH}/uvma_interrupt/uvma_interrupt_pkg.flist
|
||||
|
||||
// Environments
|
||||
-f ${CVA6_UVME_PATH}/uvme_cva6_pkg.flist
|
||||
|
|
|
@ -34,6 +34,7 @@ module uvmt_cva6_dut_wrap # (
|
|||
uvmt_axi_switch_intf axi_switch_vif,
|
||||
uvmt_default_inputs_intf default_inputs_vif,
|
||||
uvme_cva6_core_cntrl_if core_cntrl_if,
|
||||
uvma_interrupt_if interrupt_vif,
|
||||
output logic[31:0] tb_exit_o,
|
||||
output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o,
|
||||
output rvfi_csr_t rvfi_csr_o
|
||||
|
@ -60,6 +61,7 @@ module uvmt_cva6_dut_wrap # (
|
|||
.boot_addr_i ( boot_addr ),
|
||||
.cvxif_resp ( cvxif_if.cvxif_resp_o ),
|
||||
.cvxif_req ( cvxif_if.cvxif_req_i ),
|
||||
.irq_i ( interrupt_vif.irq ),
|
||||
.axi_slave ( axi_if ),
|
||||
.axi_switch_vif ( axi_switch_vif ),
|
||||
.default_inputs_vif ( default_inputs_vif ),
|
||||
|
|
|
@ -67,6 +67,11 @@ module uvmt_cva6_tb;
|
|||
.clk(clknrst_if.clk),
|
||||
.rst_n(clknrst_if.reset_n)
|
||||
);
|
||||
|
||||
uvma_interrupt_if
|
||||
interrupt_vif(
|
||||
);
|
||||
|
||||
uvmt_axi_switch_intf axi_switch_vif();
|
||||
uvme_cva6_core_cntrl_if core_cntrl_if();
|
||||
uvma_rvfi_instr_if #(
|
||||
|
@ -122,6 +127,7 @@ module uvmt_cva6_tb;
|
|||
.axi_switch_vif (axi_switch_vif),
|
||||
.default_inputs_vif (default_inputs_vif),
|
||||
.core_cntrl_if(core_cntrl_if),
|
||||
.interrupt_vif(interrupt_vif),
|
||||
.tb_exit_o(tb_exit_if.tb_exit_o),
|
||||
.rvfi_o(rvfi_if.rvfi_o),
|
||||
.rvfi_csr_o(rvfi_if.rvfi_csr_o)
|
||||
|
@ -370,6 +376,8 @@ module uvmt_cva6_tb;
|
|||
uvm_config_db#(virtual uvmt_axi_switch_intf )::set(.cntxt(null), .inst_name("*.env"), .field_name("axi_switch_vif"), .value(axi_switch_vif));
|
||||
uvm_config_db#(virtual uvmt_rvfi_if#( .CVA6Cfg(CVA6Cfg), .rvfi_instr_t(rvfi_instr_t), .rvfi_csr_t (rvfi_csr_t)))::set(.cntxt(null), .inst_name("*"), .field_name("rvfi_vif"), .value(rvfi_if));
|
||||
uvm_config_db#(virtual uvme_cva6_core_cntrl_if)::set(.cntxt(null), .inst_name("*"), .field_name("core_cntrl_vif"), .value(core_cntrl_if));
|
||||
uvm_config_db#(virtual uvma_interrupt_if)::set(.cntxt(null), .inst_name("*"), .field_name("interrupt_vif"), .value(interrupt_vif));
|
||||
|
||||
uvm_config_db#(virtual uvmt_tb_exit_if)::set(.cntxt(null), .inst_name("*"), .field_name("tb_exit_vif"), .value(tb_exit_if));
|
||||
|
||||
// DUT and ENV parameters
|
||||
|
|
65
verif/tests/custom/interrupt/jump_to_zero.S
Normal file
65
verif/tests/custom/interrupt/jump_to_zero.S
Normal file
|
@ -0,0 +1,65 @@
|
|||
# Copyright 2024 Thales DIS SAS
|
||||
#
|
||||
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
# You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||
#
|
||||
# Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
#*****************************************************************************
|
||||
# jump_to_zero.S
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
|
||||
.globl main
|
||||
main:
|
||||
# core of the test
|
||||
la t1, exception_handler
|
||||
csrw mtvec, t1 ## Load the address of the exception handler into MTVEC
|
||||
csrw 0x341, zero ## Writing Zero to MEPC CSR
|
||||
csrw 0x342, zero ## Writing Zero to MCAUSE CSR
|
||||
#End Handle exceptions
|
||||
|
||||
# enable interrupt in mie and mstatus
|
||||
li a1, 0x888
|
||||
csrw mie, a1
|
||||
csrr a2, mie
|
||||
li a1, 0x8
|
||||
csrw mstatus, a1
|
||||
csrr a2, mstatus
|
||||
|
||||
jump00:
|
||||
jal a1, jump00
|
||||
|
||||
jump01:
|
||||
c.j jump01
|
||||
|
||||
jump02:
|
||||
c.jal jump02
|
||||
|
||||
#End of test
|
||||
j test_done
|
||||
|
||||
test_done:
|
||||
li ra, 0
|
||||
slli ra, ra, 1
|
||||
addi ra, ra, 1
|
||||
sw ra, tohost, t5
|
||||
self_loop: j self_loop
|
||||
|
||||
.align 8
|
||||
exception_handler:
|
||||
# increment return address to skip instruction generating the exception
|
||||
# valid only if faulting instruction is not compressed (4-byte long)
|
||||
csrr s11, mepc
|
||||
lbu s5, 0(s11)
|
||||
li s9, 0x3
|
||||
and s5, s5, s9
|
||||
bne s5, s9, exception_handler_incr_mepc2
|
||||
addi s11, s11, 2
|
||||
exception_handler_incr_mepc2:
|
||||
addi s11, s11, 2
|
||||
csrw mepc, s11
|
||||
csrr t6, mepc
|
||||
mret
|
32
verif/tests/testlist_interrupt.yaml
Normal file
32
verif/tests/testlist_interrupt.yaml
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Copyright 2024 Thales DIS design services SAS
|
||||
#
|
||||
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||
# You may obtain a copy of the License at https:#solderpad.org/licenses/
|
||||
#
|
||||
# Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
|
||||
|
||||
# ================================================================================
|
||||
# Regression test list format
|
||||
# --------------------------------------------------------------------------------
|
||||
# test : Assembly test name
|
||||
# description : Description of this test
|
||||
# gen_opts : Instruction generator options
|
||||
# iterations : Number of iterations of this test
|
||||
# no_iss : Enable/disable ISS simulator (Optional)
|
||||
# gen_test : Test name used by the instruction generator
|
||||
# asm_tests : Path to directed, hand-coded assembly test file or directory
|
||||
# rtl_test : RTL simulation test name
|
||||
# cmp_opts : Compile options passed to the instruction generator
|
||||
# sim_opts : Simulation options passed to the instruction generator
|
||||
# no_post_compare : Enable/disable comparison of trace log and ISS log (Optional)
|
||||
# compare_opts : Options for the RTL & ISS trace comparison
|
||||
# gcc_opts : gcc compile options
|
||||
# --------------------------------------------------------------------------------
|
||||
|
||||
- test: jump_to_zero
|
||||
iterations: 1
|
||||
path_var: TESTS_PATH
|
||||
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld -lgcc"
|
||||
asm_tests: <path_var>/custom/interrupt/jump_to_zero.S
|
Loading…
Add table
Add a link
Reference in a new issue