mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 05:07:21 -04:00
AXI agent: Connect the the new AXI agent (#1817)
This commit is contained in:
parent
45ffb59980
commit
5e80c104c9
13 changed files with 771 additions and 57 deletions
269
verif/env/uvme/cov/uvme_axi_covg.sv
vendored
Normal file
269
verif/env/uvme/cov/uvme_axi_covg.sv
vendored
Normal file
|
@ -0,0 +1,269 @@
|
|||
// Copyright 2023 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: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com) – sub-contractor MU-Electronics for Thales group
|
||||
|
||||
|
||||
`ifndef __UVME_AXI_COVG_SV__
|
||||
`define __UVME_AXI_COVG_SV__
|
||||
|
||||
/*
|
||||
* Covergroups
|
||||
* Decalred at package-level to enable mutliple instances per monitor class (e.g. read/write)
|
||||
*/
|
||||
|
||||
covergroup cg_axi_w_channel(string name)
|
||||
with function sample(uvma_axi_transaction_c item, bit RVA);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
awready_to_valid: coverpoint (item.aw_delay) {
|
||||
bins dly[] = {[0:16]};
|
||||
}
|
||||
|
||||
wready_to_valid: coverpoint (item.w_data_trs[0].w_delay) {
|
||||
bins dly[] = {[0:16]};
|
||||
}
|
||||
|
||||
awsize: coverpoint (item.aw_size){
|
||||
bins size[] = {[0:3]};
|
||||
ignore_bins IGN_SIZE3 = {3} iff(uvme_cva6_pkg::XLEN == 32);
|
||||
}
|
||||
|
||||
awlock: coverpoint (item.aw_lock){
|
||||
bins lock[] = {[0:1]};
|
||||
ignore_bins IGN_EXCLUSIVE = {1} iff(!RVA);
|
||||
}
|
||||
|
||||
wstrb: coverpoint (item.w_data_trs[0].w_strb) {
|
||||
bins strb1 = {1};
|
||||
bins strb2 = {2};
|
||||
bins strb3 = {3};
|
||||
bins strb4 = {4};
|
||||
bins strb8 = {8};
|
||||
bins strb12 = {12};
|
||||
bins strb15 = {15};
|
||||
bins strb16 = {16};
|
||||
bins strb32 = {32};
|
||||
bins strb48 = {48};
|
||||
bins strb64 = {64};
|
||||
bins strb128 = {128};
|
||||
bins strb192 = {192};
|
||||
bins strb240 = {240};
|
||||
bins strb255 = {255};
|
||||
ignore_bins IGN_STRB255 = {255} iff(uvme_cva6_pkg::XLEN == 32);
|
||||
}
|
||||
|
||||
aw_axi_cross: cross awready_to_valid, wready_to_valid, awsize, awlock{
|
||||
illegal_bins ILLEGAL_BINS = binsof(awlock) intersect{1} &&
|
||||
binsof(awsize) intersect{[0:1]};
|
||||
ignore_bins IGN_CROSS = binsof(awsize) intersect{3} iff(uvme_cva6_pkg::XLEN == 32);
|
||||
}
|
||||
endgroup : cg_axi_w_channel
|
||||
|
||||
covergroup cg_axi_b_channel(string name)
|
||||
with function sample(uvma_axi_transaction_c item, bit RVA);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
bid: coverpoint (item.b_id){
|
||||
bins one = {[1:3]};
|
||||
illegal_bins ILLEGAL_BINS = {2};
|
||||
ignore_bins IGN_EXID = {3} iff(!RVA);
|
||||
}
|
||||
bresp: coverpoint (item.b_resp){
|
||||
bins zero = {0};
|
||||
bins one = {1};
|
||||
bins two = {2};
|
||||
bins three = {3};
|
||||
}
|
||||
|
||||
b_axi_cross: cross bid, bresp;
|
||||
endgroup : cg_axi_b_channel
|
||||
|
||||
covergroup cg_axi_ar_channel(string name)
|
||||
with function sample(uvma_axi_transaction_c item, bit RVA);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
arid: coverpoint (item.ar_id) {
|
||||
bins ID[] = {[0:1]};
|
||||
}
|
||||
|
||||
arlen: coverpoint (item.ar_len) {
|
||||
bins LEN[] = {[0:1]};
|
||||
}
|
||||
|
||||
arsize: coverpoint (item.ar_size) {
|
||||
bins SIZE[] = {[0:3]} iff(item.ar_len == 0);
|
||||
}
|
||||
|
||||
arready_to_valid: coverpoint (item.ar_delay) {
|
||||
bins dly[] = {[0:16]};
|
||||
}
|
||||
|
||||
arlock: coverpoint (item.ar_lock){
|
||||
bins lock[] = {[0:1]};
|
||||
ignore_bins IGN_EXCLUSIVE = {1} iff(!RVA);
|
||||
}
|
||||
|
||||
ar_axi_cross: cross arready_to_valid, arid, arlen;
|
||||
|
||||
ar_size_axi_cross: cross arready_to_valid, arid, arsize {
|
||||
illegal_bins ILLEGAL_BINS = binsof(arid) intersect{0} &&
|
||||
binsof(arsize) intersect{[0:2]};
|
||||
ignore_bins IGN_CROSS = binsof(arid) intersect{1} && binsof(arsize) intersect{3} iff(uvme_cva6_pkg::XLEN == 32);
|
||||
}
|
||||
|
||||
ar_lock_size_axi_cross: cross arready_to_valid, arlock, arsize{
|
||||
illegal_bins ILLEGAL_BINS = binsof(arlock) intersect{1} &&
|
||||
binsof(arsize) intersect{[0:1]};
|
||||
ignore_bins IGN_CROSS = binsof(arlock) intersect{0} && binsof(arsize) intersect{3} iff(uvme_cva6_pkg::XLEN == 32);
|
||||
}
|
||||
|
||||
endgroup : cg_axi_ar_channel
|
||||
|
||||
covergroup cg_axi_r_channel(string name)
|
||||
with function sample(uvma_axi_transaction_c item, int index, bit RVA);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
rid: coverpoint (item.r_data_trs[index].r_id) {
|
||||
bins ID[] = {[0:3]};
|
||||
illegal_bins ILLEGAL_BINS = {2};
|
||||
ignore_bins IGN_EXID = {3} iff(!RVA);
|
||||
}
|
||||
|
||||
rlast: coverpoint (item.r_data_trs[index].r_last);
|
||||
|
||||
rresp: coverpoint (item.r_data_trs[index].r_resp){
|
||||
bins zero = {0};
|
||||
bins one = {1};
|
||||
bins two = {2};
|
||||
bins three = {3};
|
||||
}
|
||||
|
||||
r_axi_cross: cross rid, rlast, rresp {
|
||||
illegal_bins ILLEGAL_BINS = binsof(rid) intersect{3} && binsof(rlast) intersect{0};
|
||||
}
|
||||
endgroup : cg_axi_r_channel
|
||||
|
||||
/**
|
||||
* Component encapsulating Open Bus Interface functional coverage model.
|
||||
*/
|
||||
class uvme_axi_covg_c extends uvm_component;
|
||||
|
||||
// Objects
|
||||
uvme_cva6_cntxt_c cntxt;
|
||||
uvme_cva6_cfg_c cfg;
|
||||
bit RVA;
|
||||
|
||||
// TLM
|
||||
uvm_tlm_analysis_fifo #(uvma_axi_transaction_c) uvme_axi_cov_resp_fifo;
|
||||
|
||||
// Covergroup instances
|
||||
cg_axi_w_channel w_axi_cg;
|
||||
cg_axi_b_channel b_axi_cg;
|
||||
cg_axi_ar_channel ar_axi_cg;
|
||||
cg_axi_r_channel r_axi_cg;
|
||||
|
||||
`uvm_component_utils_begin(uvme_axi_covg_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_axi_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 : uvme_axi_covg_c
|
||||
|
||||
|
||||
function uvme_axi_covg_c::new(string name="uvma_axi_cov_model", uvm_component parent=null);
|
||||
|
||||
super.new(name, parent);
|
||||
|
||||
endfunction : new
|
||||
|
||||
|
||||
// A significant chunk of the build_phase method is common between this
|
||||
// coverage model and the sequencer (uvma_obi_memory_sqr). This is
|
||||
// appropriate so the duplicated code has a lint waiver.
|
||||
//
|
||||
function void uvme_axi_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 == null) begin
|
||||
`uvm_fatal("cfg", "Context handle is null")
|
||||
end
|
||||
|
||||
void'(uvm_config_db#(uvme_cva6_cntxt_c)::get(this, "", "cntxt", cntxt));
|
||||
if (cntxt == null) begin
|
||||
`uvm_fatal("CNTXT", "Context handle is null")
|
||||
end
|
||||
|
||||
RVA = cfg.ext_a_supported;
|
||||
|
||||
uvme_axi_cov_resp_fifo = new("uvme_axi_cov_resp_fifo" , this);
|
||||
|
||||
w_axi_cg = new("w_axi_cg");
|
||||
b_axi_cg = new("b_axi_cg");
|
||||
ar_axi_cg = new("ar_axi_cg");
|
||||
r_axi_cg = new("r_axi_cg");
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
task uvme_axi_covg_c::run_phase(uvm_phase phase);
|
||||
|
||||
super.run_phase(phase);
|
||||
`uvm_info(get_type_name(), $sformatf("cov_model_enabled = %d", cfg.cov_model_enabled), UVM_HIGH)
|
||||
`uvm_info(get_type_name(), $sformatf("ATOMIC ENABLE = %d", RVA), UVM_HIGH)
|
||||
forever begin
|
||||
uvma_axi_transaction_c resp_item;
|
||||
|
||||
uvme_axi_cov_resp_fifo.get(resp_item);
|
||||
case (resp_item.access_type)
|
||||
UVMA_AXI_ACCESS_WRITE : begin
|
||||
|
||||
w_axi_cg.sample(resp_item, RVA);
|
||||
b_axi_cg.sample(resp_item, RVA);
|
||||
|
||||
end
|
||||
UVMA_AXI_ACCESS_READ : begin
|
||||
|
||||
ar_axi_cg.sample(resp_item, RVA);
|
||||
for(int i = 0; i <= resp_item.ar_len; i++) begin
|
||||
r_axi_cg.sample(resp_item, i, RVA);
|
||||
end
|
||||
|
||||
end
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
endtask : run_phase
|
||||
|
||||
`endif // __UVME_AXI_COVG_SV__
|
306
verif/env/uvme/cov/uvme_axi_ext_covg.sv
vendored
Normal file
306
verif/env/uvme/cov/uvme_axi_ext_covg.sv
vendored
Normal file
|
@ -0,0 +1,306 @@
|
|||
// Copyright 2023 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: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com) – sub-contractor MU-Electronics for Thales group
|
||||
|
||||
|
||||
`ifndef __UVME_AXI_EXT_COVG_SV__
|
||||
`define __UVME_AXI_EXT_COVG_SV__
|
||||
|
||||
/*
|
||||
* Covergroups
|
||||
* Decalred at package-level to enable mutliple instances per monitor class (e.g. read/write)
|
||||
*/
|
||||
|
||||
covergroup cg_axi_aw_order(string name)
|
||||
with function sample(uvma_axi_transaction_c item[], int t_b1_to_aw, int t_w1_to_aw, bit RVA);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
outstanding_resp: coverpoint (t_b1_to_aw < 0){
|
||||
bins normal = {0};
|
||||
bins outstanding = {1};
|
||||
}
|
||||
|
||||
awlock1: coverpoint (item[0].aw_lock){
|
||||
bins lock[] = {[0:1]};
|
||||
ignore_bins IGN_EXCLUSIVE = {1} iff(!RVA);
|
||||
}
|
||||
|
||||
awlock2: coverpoint (item[1].aw_lock){
|
||||
bins lock[] = {[0:1]};
|
||||
ignore_bins IGN_EXCLUSIVE = {1} iff(!RVA);
|
||||
}
|
||||
|
||||
aw_axi_cross: cross outstanding_resp, awlock1, awlock2;
|
||||
endgroup : cg_axi_aw_order
|
||||
|
||||
covergroup cg_axi_ar_order(string name)
|
||||
with function sample(uvma_axi_transaction_c item[], int t_r1_to_ar, int t_r1l_to_ar, int t_r1_to_r2, int t_r1l_to_r2l, bit RVA);
|
||||
|
||||
option.per_instance = 1;
|
||||
option.name = name;
|
||||
|
||||
outstanding_resp: coverpoint (t_r1_to_ar < 0){
|
||||
bins normal = {0};
|
||||
bins outstanding = {1};
|
||||
}
|
||||
|
||||
outstanding_last_resp: coverpoint (t_r1l_to_ar < 0 && t_r1_to_ar > 0){
|
||||
bins normal = {0};
|
||||
bins outstanding = {1};
|
||||
}
|
||||
|
||||
outoforder_resp_id0: coverpoint (t_r1_to_r2 < 0){
|
||||
bins normal = {0} iff(item[0].ar_id == 0);
|
||||
bins outoforder = {1} iff(item[0].ar_id == 0);
|
||||
}
|
||||
|
||||
outoforder_resp_id1: coverpoint (t_r1_to_r2 < 0){
|
||||
bins normal = {0} iff(item[0].ar_id == 1);
|
||||
bins outoforder = {1} iff(item[0].ar_id == 1);
|
||||
}
|
||||
|
||||
outoforder_last_resp_id0: coverpoint (t_r1l_to_r2l < 0){
|
||||
bins normal = {0} iff(item[0].ar_id == 0);
|
||||
bins outoforder = {1} iff(item[0].ar_id == 0);
|
||||
}
|
||||
|
||||
outoforder_last_resp_id1: coverpoint (t_r1l_to_r2l < 0){
|
||||
bins normal = {0} iff(item[0].ar_id == 1);
|
||||
bins outoforder = {1} iff(item[0].ar_id == 1);
|
||||
}
|
||||
|
||||
arid1: coverpoint (item[0].ar_id){
|
||||
bins id[] = {[0:1]};
|
||||
}
|
||||
|
||||
arlen1: coverpoint (item[0].ar_len){
|
||||
bins len[] = {[0:1]};
|
||||
}
|
||||
|
||||
arlock1: coverpoint (item[0].ar_lock){
|
||||
bins lock[] = {[0:1]};
|
||||
ignore_bins IGN_EXCLUSIVE = {1} iff(!RVA);
|
||||
}
|
||||
|
||||
arid2: coverpoint (item[1].ar_id){
|
||||
bins id[] = {[0:1]};
|
||||
}
|
||||
|
||||
arlen2: coverpoint (item[1].ar_len){
|
||||
bins len[] = {[0:1]};
|
||||
}
|
||||
|
||||
arlock2: coverpoint (item[1].ar_lock){
|
||||
bins lock[] = {[0:1]};
|
||||
ignore_bins IGN_EXCLUSIVE = {1} iff(!RVA);
|
||||
}
|
||||
|
||||
ar_axi_outstanding_cross: cross outstanding_resp, outstanding_last_resp, arid1, arlen1, arlock1, arid2, arlen2, arlock2{
|
||||
ignore_bins IGN_CROSS1 = binsof(outstanding_resp) intersect{1} &&
|
||||
binsof(outstanding_last_resp) intersect{1};
|
||||
}
|
||||
|
||||
aw_axi_outoforder_id0_cross: cross outoforder_resp_id0, outoforder_last_resp_id0, arlen1, arlock1, arlen2, arlock2{
|
||||
ignore_bins IGN_CROSS1 = binsof(outoforder_resp_id0) intersect{1} &&
|
||||
binsof(outoforder_last_resp_id0) intersect{0} &&
|
||||
binsof(arlen2) intersect{0};
|
||||
ignore_bins IGN_CROSS2 = binsof(outoforder_resp_id0) intersect{0} &&
|
||||
binsof(outoforder_last_resp_id0) intersect{1} &&
|
||||
binsof(arlen1) intersect{0};
|
||||
}
|
||||
|
||||
aw_axi_outoforder_id1_cross: cross outoforder_resp_id1, outoforder_last_resp_id1, arlen1, arlock1, arlen2, arlock2{
|
||||
ignore_bins IGN_CROSS1 = binsof(outoforder_resp_id1) intersect{1} &&
|
||||
binsof(outoforder_last_resp_id1) intersect{0} &&
|
||||
binsof(arlen2) intersect{0};
|
||||
ignore_bins IGN_CROSS2 = binsof(outoforder_resp_id1) intersect{0} &&
|
||||
binsof(outoforder_last_resp_id1) intersect{1} &&
|
||||
binsof(arlen1) intersect{0};
|
||||
}
|
||||
endgroup : cg_axi_ar_order
|
||||
|
||||
/**
|
||||
* Component encapsulating Open Bus Interface functional coverage model.
|
||||
*/
|
||||
class uvme_axi_ext_covg_c extends uvm_component;
|
||||
|
||||
// Objects
|
||||
uvme_cva6_cntxt_c cntxt;
|
||||
uvme_cva6_cfg_c cfg;
|
||||
bit RVA;
|
||||
|
||||
// Time between write transfer
|
||||
int t_b1_to_aw; // <0 (outstanding)
|
||||
int t_w1_to_aw; // <0 (outstanding)
|
||||
|
||||
// Time between read transfer
|
||||
int t_r1_to_ar; // <0 (outstanding)
|
||||
int t_r1l_to_ar; // <0 (outstanding)
|
||||
int t_r1_to_r2; // <0 (r2 run before r1)
|
||||
int t_r1l_to_r2l; // <0 (last r2 run before last r1)
|
||||
|
||||
// Covergroup instances
|
||||
cg_axi_aw_order aw_axi_order_cg;
|
||||
cg_axi_ar_order ar_axi_order_cg;
|
||||
|
||||
//
|
||||
uvma_axi_transaction_c aw_trs_fifo[];
|
||||
uvma_axi_transaction_c ar_trs_fifo[];
|
||||
|
||||
int order_resp;
|
||||
|
||||
// TLM
|
||||
uvm_tlm_analysis_fifo #(uvma_axi_transaction_c) uvme_axi_cov_fifo;
|
||||
|
||||
`uvm_component_utils_begin(uvme_axi_ext_covg_c)
|
||||
`uvm_component_utils_end
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvme_axi_ext_covg", 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);
|
||||
|
||||
/**
|
||||
* Forks all sampling loops
|
||||
*/
|
||||
extern virtual function int aw_time_operations();
|
||||
|
||||
/**
|
||||
* Forks all sampling loops
|
||||
*/
|
||||
extern virtual function int ar_time_operations();
|
||||
|
||||
endclass : uvme_axi_ext_covg_c
|
||||
|
||||
|
||||
function uvme_axi_ext_covg_c::new(string name="uvme_axi_ext_covg", uvm_component parent=null);
|
||||
|
||||
super.new(name, parent);
|
||||
|
||||
endfunction : new
|
||||
|
||||
function void uvme_axi_ext_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 == null) begin
|
||||
`uvm_fatal("cfg", "Context handle is null")
|
||||
end
|
||||
|
||||
void'(uvm_config_db#(uvme_cva6_cntxt_c)::get(this, "", "cntxt", cntxt));
|
||||
if (cntxt == null) begin
|
||||
`uvm_fatal("CNTXT", "Context handle is null")
|
||||
end
|
||||
|
||||
RVA = cfg.ext_a_supported;
|
||||
|
||||
aw_axi_order_cg = new("aw_axi_order_cg");
|
||||
ar_axi_order_cg = new("ar_axi_order_cg");
|
||||
|
||||
uvme_axi_cov_fifo = new("uvme_axi_cov_fifo" , this);
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
task uvme_axi_ext_covg_c::run_phase(uvm_phase phase);
|
||||
|
||||
super.run_phase(phase);
|
||||
forever begin
|
||||
uvma_axi_transaction_c resp_item;
|
||||
|
||||
uvme_axi_cov_fifo.get(resp_item);
|
||||
case (resp_item.access_type)
|
||||
|
||||
UVMA_AXI_ACCESS_WRITE : begin
|
||||
|
||||
aw_trs_fifo = new [aw_trs_fifo.size()+1] (aw_trs_fifo);
|
||||
aw_trs_fifo[aw_trs_fifo.size()-1] = new resp_item;
|
||||
if(aw_trs_fifo.size() == 2) begin
|
||||
order_resp = aw_time_operations();
|
||||
aw_axi_order_cg.sample(aw_trs_fifo, t_b1_to_aw, t_w1_to_aw, RVA);
|
||||
if(order_resp == 1) aw_trs_fifo[0] = new aw_trs_fifo[1];
|
||||
aw_trs_fifo = new [aw_trs_fifo.size()-1] (aw_trs_fifo);
|
||||
end
|
||||
|
||||
end
|
||||
UVMA_AXI_ACCESS_READ : begin
|
||||
|
||||
ar_trs_fifo = new [ar_trs_fifo.size()+1] (ar_trs_fifo);
|
||||
ar_trs_fifo[ar_trs_fifo.size()-1] = new resp_item;
|
||||
|
||||
if(ar_trs_fifo.size() == 2) begin
|
||||
|
||||
order_resp = ar_time_operations();
|
||||
ar_axi_order_cg.sample(ar_trs_fifo, t_r1_to_ar, t_r1l_to_ar, t_r1_to_r2, t_r1l_to_r2l, RVA);
|
||||
if(order_resp == 1) ar_trs_fifo[0] = new ar_trs_fifo[1];
|
||||
ar_trs_fifo = new [ar_trs_fifo.size()-1] (ar_trs_fifo);
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endtask : run_phase
|
||||
|
||||
function int uvme_axi_ext_covg_c::ar_time_operations();
|
||||
int order_resp = 1;
|
||||
uvma_axi_transaction_c axi_transaction;
|
||||
|
||||
if(ar_trs_fifo[0].ar_start_time > ar_trs_fifo[1].ar_start_time) begin
|
||||
|
||||
axi_transaction = new ar_trs_fifo[0];
|
||||
ar_trs_fifo[0] = new ar_trs_fifo[1];
|
||||
ar_trs_fifo[1] = new axi_transaction;
|
||||
order_resp = 0;
|
||||
|
||||
end
|
||||
|
||||
t_r1_to_ar = ar_trs_fifo[1].ar_start_time - ar_trs_fifo[0].r_data_trs[0].r_start_time;
|
||||
t_r1l_to_ar = ar_trs_fifo[1].ar_start_time - ar_trs_fifo[0].r_data_trs[ar_trs_fifo[0].r_data_trs.size()-1].r_start_time;
|
||||
t_r1_to_r2 = ar_trs_fifo[1].r_data_trs[0].r_start_time - ar_trs_fifo[0].r_data_trs[0].r_start_time;
|
||||
t_r1l_to_r2l = ar_trs_fifo[1].r_data_trs[ar_trs_fifo[1].r_data_trs.size()-1].r_start_time - ar_trs_fifo[0].r_data_trs[ar_trs_fifo[0].r_data_trs.size()-1].r_start_time;
|
||||
|
||||
return order_resp;
|
||||
|
||||
endfunction : ar_time_operations
|
||||
|
||||
function int uvme_axi_ext_covg_c::aw_time_operations();
|
||||
int order_resp = 1;
|
||||
uvma_axi_transaction_c axi_transaction;
|
||||
|
||||
if(aw_trs_fifo[0].aw_start_time > aw_trs_fifo[1].aw_start_time) begin
|
||||
|
||||
axi_transaction = new aw_trs_fifo[0];
|
||||
aw_trs_fifo[0] = new aw_trs_fifo[1];
|
||||
aw_trs_fifo[1] = new axi_transaction;
|
||||
order_resp = 0;
|
||||
|
||||
end
|
||||
|
||||
t_b1_to_aw = aw_trs_fifo[1].aw_start_time - aw_trs_fifo[0].b_start_time;
|
||||
t_w1_to_aw = aw_trs_fifo[1].aw_start_time - aw_trs_fifo[0].w_data_trs[0].w_start_time;
|
||||
|
||||
return order_resp;
|
||||
|
||||
endfunction : aw_time_operations
|
||||
|
||||
`endif // __UVME_AXI_EXT_COVG_SV__
|
11
verif/env/uvme/cov/uvme_cva6_cov_model.sv
vendored
11
verif/env/uvme/cov/uvme_cva6_cov_model.sv
vendored
|
@ -35,6 +35,8 @@ class uvme_cva6_cov_model_c extends uvm_component;
|
|||
uvme_cva6_config_covg_c config_covg;
|
||||
uvme_illegal_instr_cov_model_c illegal_covg;
|
||||
uvme_exception_cov_model_c exception_covg;
|
||||
uvme_axi_covg_c axi_covg;
|
||||
uvme_axi_ext_covg_c axi_ext_covg;
|
||||
|
||||
//
|
||||
uvm_analysis_export#(uvma_clknrst_mon_trn_c) reset_export;
|
||||
|
@ -119,6 +121,15 @@ function void uvme_cva6_cov_model_c::build_phase(uvm_phase phase);
|
|||
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "config_covg", "cfg", cfg);
|
||||
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "config_covg", "cntxt", cntxt);
|
||||
|
||||
if(cfg.axi_cfg.cov_model_enabled) begin
|
||||
axi_covg = uvme_axi_covg_c::type_id::create("axi_covg", this);
|
||||
axi_ext_covg = uvme_axi_ext_covg_c::type_id::create("axi_ext_covg", this);
|
||||
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "axi_covg", "cfg", cfg);
|
||||
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "axi_covg", "cntxt", cntxt);
|
||||
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "axi_ext_covg", "cfg", cfg);
|
||||
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "axi_ext_covg", "cntxt", cntxt);
|
||||
end
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
function void uvme_cva6_cov_model_c::connect_phase(uvm_phase phase);
|
||||
|
|
1
verif/env/uvme/uvme_cva6_cfg.sv
vendored
1
verif/env/uvme/uvme_cva6_cfg.sv
vendored
|
@ -194,6 +194,7 @@ 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;
|
||||
|
|
5
verif/env/uvme/uvme_cva6_env.sv
vendored
5
verif/env/uvme/uvme_cva6_env.sv
vendored
|
@ -381,6 +381,11 @@ function void uvme_cva6_env_c::connect_coverage_model();
|
|||
clknrst_agent.mon_ap.connect(cov_model.reset_export);
|
||||
rvfi_agent.rvfi_core_ap.connect(isacov_agent.monitor.rvfi_instr_imp);
|
||||
|
||||
if(cfg.axi_cfg.cov_model_enabled) begin
|
||||
axi_agent.vsequencer.synchronizer.uvma_sqr_trs_port.connect(cov_model.axi_covg.uvme_axi_cov_resp_fifo.analysis_export);
|
||||
axi_agent.vsequencer.synchronizer.uvma_sqr_trs_port.connect(cov_model.axi_ext_covg.uvme_axi_cov_fifo.analysis_export);
|
||||
end
|
||||
|
||||
endfunction: connect_coverage_model
|
||||
|
||||
`endif // __UVME_CVA6_ENV_SV__
|
||||
|
|
6
verif/env/uvme/uvme_cva6_pkg.sv
vendored
6
verif/env/uvme/uvme_cva6_pkg.sv
vendored
|
@ -51,6 +51,9 @@ package uvme_cva6_pkg;
|
|||
import uvmc_rvfi_scoreboard_pkg::*;
|
||||
import uvmc_rvfi_reference_model_pkg::*;
|
||||
import uvma_isacov_pkg::*;
|
||||
import "DPI-C" function 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[]);
|
||||
|
||||
// Default legal opcode and funct7 for RV32I instructions
|
||||
bit [6:0] legal_i_opcode[$] = '{7'b0000011,
|
||||
|
@ -96,12 +99,15 @@ package uvme_cva6_pkg;
|
|||
`include "uvme_illegal_instr_covg.sv"
|
||||
`include "uvme_exception_covg.sv"
|
||||
`include "uvme_cva6_config_covg.sv"
|
||||
`include "uvme_axi_covg.sv"
|
||||
`include "uvme_axi_ext_covg.sv"
|
||||
`include "uvme_cva6_cov_model.sv"
|
||||
`include "uvme_cva6_env.sv"
|
||||
|
||||
// Virtual sequences
|
||||
`include "uvme_cva6_base_vseq.sv"
|
||||
`include "uvme_cva6_reset_vseq.sv"
|
||||
`include "uvme_axi_fw_preload_seq.sv"
|
||||
// `include "uvme_cva6_interrupt_noise_vseq.sv"
|
||||
`include "uvme_cva6_vseq_lib.sv"
|
||||
|
||||
|
|
84
verif/env/uvme/vseq/uvme_axi_fw_preload_seq.sv
vendored
Normal file
84
verif/env/uvme/vseq/uvme_axi_fw_preload_seq.sv
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
// 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: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com) – sub-contractor MU-Electronics for Thales group
|
||||
|
||||
|
||||
`ifndef __UVME_AXI_FW_PRELOAD_SEQ_SV__
|
||||
`define __UVME_AXI_FW_PRELOAD_SEQ_SV__
|
||||
|
||||
|
||||
/**
|
||||
* Virtual sequence preloads the CVA6 memory.
|
||||
*/
|
||||
class uvme_axi_fw_preload_seq_c extends uvma_axi_fw_preload_seq_c;
|
||||
|
||||
uvml_mem_c mem;
|
||||
static uvm_cmdline_processor uvcl = uvm_cmdline_processor::get_inst();
|
||||
|
||||
bit[63:0] value;
|
||||
logic [7:0][7:0] mem_row;
|
||||
string binary = "";
|
||||
longint address;
|
||||
longint len;
|
||||
byte buffer[];
|
||||
|
||||
`uvm_object_utils(uvme_axi_fw_preload_seq_c)
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
extern function new(string name="uvma_axi_fw_preload_seq");
|
||||
|
||||
extern virtual task body();
|
||||
|
||||
endclass : uvme_axi_fw_preload_seq_c
|
||||
|
||||
function uvme_axi_fw_preload_seq_c::new(string name="uvma_axi_fw_preload_seq");
|
||||
|
||||
super.new(name);
|
||||
mem = uvml_mem_c::type_id::create("mem");
|
||||
mem.mem_default = MEM_DEFAULT_0;
|
||||
|
||||
endfunction : new
|
||||
|
||||
task uvme_axi_fw_preload_seq_c::body();
|
||||
|
||||
void'(uvcl.get_arg_value("+elf_file=", binary));
|
||||
|
||||
if (binary != "") begin
|
||||
void'(read_elf(binary));
|
||||
wait(p_sequencer.cntxt.axi_vi.clk);
|
||||
// while there are more sections to process
|
||||
while (get_section(address, len)) begin
|
||||
automatic int num_words0 = (len+7)/8;
|
||||
`uvm_info( "Core Test", $sformatf("Loading Address: %x, Length: %x", address, len), UVM_HIGH)
|
||||
buffer = new [num_words0*8];
|
||||
void'(read_section_sv(address, buffer));
|
||||
// preload memories
|
||||
// 64-bit
|
||||
for (int i = 0; i < num_words0; i++) begin
|
||||
mem_row = '0;
|
||||
for (int j = 0; j < 8; j++) begin
|
||||
mem_row[j] = buffer[i*8 + j];
|
||||
end
|
||||
mem.write(address + i*8 + 0, mem_row[0]);
|
||||
mem.write(address + i*8 + 1, mem_row[1]);
|
||||
mem.write(address + i*8 + 2, mem_row[2]);
|
||||
mem.write(address + i*8 + 3, mem_row[3]);
|
||||
mem.write(address + i*8 + 4, mem_row[4]);
|
||||
mem.write(address + i*8 + 5, mem_row[5]);
|
||||
mem.write(address + i*8 + 6, mem_row[6]);
|
||||
mem.write(address + i*8 + 7, mem_row[7]);
|
||||
end
|
||||
p_sequencer.cntxt.mem = mem;
|
||||
end
|
||||
end
|
||||
|
||||
endtask : body
|
||||
|
||||
`endif // __UVME_AXI_FW_PRELOAD_SEQ_SV__
|
|
@ -179,7 +179,7 @@ export DV_UVMA_RVFI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_rvfi
|
|||
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_axi
|
||||
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_DEBUG_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_debug
|
||||
export DV_UVMA_OBI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_obi
|
||||
|
|
|
@ -201,6 +201,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
|||
assign axi_slave.aw_prot = axi_ariane_req.aw.prot;
|
||||
assign axi_slave.aw_qos = axi_ariane_req.aw.qos;
|
||||
assign axi_slave.aw_region = axi_ariane_req.aw.region;
|
||||
assign axi_slave.aw_atop = axi_ariane_req.aw.atop;
|
||||
assign axi_slave.aw_user = 0;
|
||||
// W Channel
|
||||
assign axi_slave.w_data = axi_ariane_req.w.data;
|
||||
|
|
|
@ -5,48 +5,27 @@
|
|||
// 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: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com)
|
||||
// Original Author: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com) – sub-contractor MU-Electronics for Thales group
|
||||
|
||||
module uvmt_axi_assert (uvma_axi_intf.passive axi_assert, input bit clk, input rst_n);
|
||||
module uvmt_axi_assert (uvma_axi_intf axi_assert_if);
|
||||
|
||||
import uvm_pkg::*;
|
||||
|
||||
uvma_axi_assert axi_mix_assert(.axi_assert(axi_assert_if));
|
||||
|
||||
bind uvmt_axi_assert
|
||||
uvma_axi_aw_assert axi_aw_assert(.axi_assert(axi_assert),
|
||||
.clk(clk),
|
||||
.rst_n(rst_n)
|
||||
);
|
||||
uvma_axi_aw_assert axi_aw_assert(.axi_assert(axi_assert_if));
|
||||
|
||||
bind uvmt_axi_assert
|
||||
uvma_axi_ar_assert axi_ar_assert(.axi_assert(axi_assert),
|
||||
.clk(clk),
|
||||
.rst_n(rst_n)
|
||||
);
|
||||
uvma_axi_ar_assert axi_ar_assert(.axi_assert(axi_assert_if));
|
||||
|
||||
bind uvmt_axi_assert
|
||||
uvma_axi_w_assert axi_w_assert(.axi_assert(axi_assert),
|
||||
.clk(clk),
|
||||
.rst_n(rst_n)
|
||||
);
|
||||
uvma_axi_w_assert axi_w_assert(.axi_assert(axi_assert_if));
|
||||
|
||||
bind uvmt_axi_assert
|
||||
uvma_axi_r_assert axi_r_assert(.axi_assert(axi_assert),
|
||||
.clk(clk),
|
||||
.rst_n(rst_n)
|
||||
);
|
||||
uvma_axi_r_assert axi_r_assert(.axi_assert(axi_assert_if));
|
||||
|
||||
bind uvmt_axi_assert
|
||||
uvma_axi_b_assert axi_b_assert(.axi_assert(axi_assert),
|
||||
.clk(clk),
|
||||
.rst_n(rst_n)
|
||||
);
|
||||
uvma_axi_b_assert axi_b_assert(.axi_assert(axi_assert_if));
|
||||
|
||||
bind uvmt_axi_assert
|
||||
uvmt_cva6_axi_assert cva6_axi_assert(.axi_assert(axi_assert),
|
||||
.clk(clk),
|
||||
.rst_n(rst_n)
|
||||
);
|
||||
uvma_axi_amo_assert axi_amo_assert(.axi_assert(axi_assert_if));
|
||||
|
||||
uvmt_cva6_axi_assert cva6_axi_assert(.axi_assert_if(axi_assert_if));
|
||||
|
||||
|
||||
endmodule : uvmt_axi_assert
|
||||
|
|
|
@ -5,93 +5,98 @@
|
|||
// 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: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com)
|
||||
// Original Author: Alae Eddine EZ ZEJJARI (alae-eddine.ez-zejjari@external.thalesgroup.com) – sub-contractor MU-Electronics for Thales group
|
||||
|
||||
// *************************** AXI features supported by CVA6 ************************** //
|
||||
|
||||
module uvmt_cva6_axi_assert (uvma_axi_intf axi_assert, input bit clk, input rst_n);
|
||||
module uvmt_cva6_axi_assert (uvma_axi_intf axi_assert_if);
|
||||
|
||||
import uvm_pkg::*;
|
||||
|
||||
|
||||
//check if the CVA6 identify read transaction with an ID equal to 0 or 1
|
||||
property AXI4_CVA6_ARID;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_id == 0 || axi_assert.ar_id == 1;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.ar_valid |-> axi_assert_if.ar_id == 0 || axi_assert_if.ar_id == 1 || (axi_assert_if.ar_id == 3 && axi_assert_if.ar_lock == 1);
|
||||
endproperty
|
||||
|
||||
//check if the CVA6 identify write transaction with an ID equal to 0 or 1
|
||||
property AXI4_CVA6_AWID;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.aw_valid |-> axi_assert.aw_id == 1;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.aw_valid |-> axi_assert_if.aw_id == 1 || (axi_assert_if.aw_id == 3 && axi_assert_if.aw_atop != 0) || (axi_assert_if.aw_id == 3 && axi_assert_if.aw_lock == 1);
|
||||
endproperty
|
||||
|
||||
//Check if user-defined extension for read address channel is equal to 0b00
|
||||
property AXI4_CVA6_ARUSER;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_user == 0;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.ar_valid |-> axi_assert_if.ar_user == 0;
|
||||
endproperty
|
||||
|
||||
//Check if user-defined extension for write address channel is equal to 0b00
|
||||
property AXI4_CVA6_AWUSER;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.aw_valid |-> axi_assert.aw_user == 0;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.aw_valid |-> axi_assert_if.aw_user == 0;
|
||||
endproperty
|
||||
|
||||
//Check if Quality of Service identifier for write transaction is equal to 0b0000
|
||||
property AXI4_CVA6_AWQOS;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.aw_valid |-> axi_assert.aw_qos == 0;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.aw_valid |-> axi_assert_if.aw_qos == 0;
|
||||
endproperty
|
||||
|
||||
//Check if Quality of Service identifier for read transaction is equal to 0b0000
|
||||
property AXI4_CVA6_ARQOS;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_qos == 0;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.ar_valid |-> axi_assert_if.ar_qos == 0;
|
||||
endproperty
|
||||
|
||||
//Check if Region indicator for write transaction is equal to 0b0000
|
||||
property AXI4_CVA6_AWREGION;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.aw_valid |-> axi_assert.aw_region == 0;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.aw_valid |-> axi_assert_if.aw_region == 0;
|
||||
endproperty
|
||||
|
||||
//Check if Region indicator for read transaction is equal to 0b0000
|
||||
property AXI4_CVA6_ARREGION;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_region == 0;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.ar_valid |-> axi_assert_if.ar_region == 0;
|
||||
endproperty
|
||||
|
||||
//Check if AWCACHE is always equal to 0b0000
|
||||
property AXI4_CVA6_AWCACHE;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.aw_valid |-> axi_assert.aw_cache == 2;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.aw_valid |-> axi_assert_if.aw_cache == 2;
|
||||
endproperty
|
||||
|
||||
//Check if ARCACHE is always equal to 0b0000
|
||||
property AXI4_CVA6_ARCACHE;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_cache == 2;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.ar_valid |-> axi_assert_if.ar_cache == 2;
|
||||
endproperty
|
||||
|
||||
//Check if Protection attributes for write transaction always take the 0b000
|
||||
property AXI4_CVA6_AWPROT;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.aw_valid |-> axi_assert.aw_prot == 0;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.aw_valid |-> axi_assert_if.aw_prot == 0;
|
||||
endproperty
|
||||
|
||||
//Check if Protection attributes for read transaction always take the 0b000
|
||||
property AXI4_CVA6_ARPROT;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_prot == 0;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.ar_valid |-> axi_assert_if.ar_prot == 0;
|
||||
endproperty
|
||||
|
||||
//Check if all write transaction performed by CVA6 are of type INCR
|
||||
property AXI4_CVA6_AWBURST;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.aw_valid |-> axi_assert.aw_burst == 1;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.aw_valid |-> axi_assert_if.aw_burst == 1;
|
||||
endproperty
|
||||
|
||||
//Check if all read transaction performed by CVA6 are of type INCR
|
||||
property AXI4_CVA6_ARBURST;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_burst == 1;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.ar_valid |-> axi_assert_if.ar_burst == 1;
|
||||
endproperty
|
||||
|
||||
//Check if all write transaction performed by CVA6 are equal to 0
|
||||
property AXI4_CVA6_AWLEN;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.aw_valid |-> axi_assert.aw_len == 0;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.aw_valid |-> axi_assert_if.aw_len == 0;
|
||||
endproperty
|
||||
|
||||
//Check if all Read transaction performed by CVA6 are equal to 0 or 1
|
||||
property AXI4_CVA6_ARLEN;
|
||||
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_len == 0 || axi_assert.ar_len == 1;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.ar_valid |-> axi_assert_if.ar_len == 0 || axi_assert_if.ar_len == 1;
|
||||
endproperty
|
||||
|
||||
//Check if all Write transaction performed by CVA6 are of type Non atomic, AtomicLoad or AtomicSwap
|
||||
property AXI4_CVA6_AWATOP;
|
||||
@(posedge axi_assert_if.clk) disable iff (!axi_assert_if.rst_n) axi_assert_if.aw_valid |-> (axi_assert_if.aw_atop[5:4] == 0 || axi_assert_if.aw_atop[5:4] == 2 || axi_assert_if.aw_atop[5:4] == 3) && axi_assert_if.aw_atop[3] == 0;
|
||||
endproperty
|
||||
|
||||
/********************************************** Assert Property ******************************************************/
|
||||
|
@ -144,6 +149,9 @@ module uvmt_cva6_axi_assert (uvma_axi_intf axi_assert, input bit clk, input rst
|
|||
cva6_awlen : assert property (AXI4_CVA6_AWLEN)
|
||||
else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_CVA6_AWLEN");
|
||||
|
||||
cva6_awatop : assert property (AXI4_CVA6_AWATOP)
|
||||
else `uvm_error (" AXI4 protocol checks assertion ", "Violation of AXI4_CVA6_AWATOP");
|
||||
|
||||
/********************************************** Cover Property ******************************************************/
|
||||
|
||||
|
||||
|
@ -179,7 +187,7 @@ module uvmt_cva6_axi_assert (uvma_axi_intf axi_assert, input bit clk, input rst
|
|||
|
||||
cov_cva6_awlen : cover property(AXI4_CVA6_AWLEN);
|
||||
|
||||
|
||||
cov_cva6_awatop : cover property(AXI4_CVA6_AWATOP);
|
||||
|
||||
|
||||
endmodule : uvmt_cva6_axi_assert
|
||||
|
|
|
@ -88,7 +88,7 @@ module uvmt_cva6_tb;
|
|||
|
||||
uvma_rvfi_csr_if#(uvme_cva6_pkg::XLEN) rvfi_csr_if [RVFI_NRET-1:0]();
|
||||
|
||||
uvmt_default_inputs_intf default_inputs_vif();
|
||||
uvmt_default_inputs_intf default_inputs_vif();
|
||||
|
||||
//bind assertion module for cvxif interface
|
||||
bind uvmt_cva6_dut_wrap
|
||||
|
@ -98,10 +98,8 @@ module uvmt_cva6_tb;
|
|||
);
|
||||
//bind assertion module for axi interface
|
||||
bind uvmt_cva6_dut_wrap
|
||||
uvmt_axi_assert axi_assert(.axi_assert(axi_if.passive),
|
||||
.clk(clknrst_if.clk),
|
||||
.rst_n(clknrst_if.reset_n)
|
||||
);
|
||||
uvmt_axi_assert axi_assert(.axi_assert_if(axi_if));
|
||||
|
||||
// DUT Wrapper Interfaces
|
||||
uvmt_rvfi_if #(
|
||||
// RVFI
|
||||
|
@ -238,6 +236,14 @@ module uvmt_cva6_tb;
|
|||
// Specify time format for simulation (units_number, precision_number, suffix_string, minimum_field_width)
|
||||
$timeformat(-9, 3, " ns", 8);
|
||||
|
||||
axi_if.aw_assertion_enabled = 1;
|
||||
axi_if.w_assertion_enabled = 1;
|
||||
axi_if.b_assertion_enabled = 1;
|
||||
axi_if.ar_assertion_enabled = 1;
|
||||
axi_if.r_assertion_enabled = 1;
|
||||
axi_if.axi_assertion_enabled = 1;
|
||||
axi_if.axi_amo_assertion_enabled = 1;
|
||||
|
||||
// Add interfaces handles to uvm_config_db
|
||||
uvm_config_db#(virtual uvma_clknrst_if )::set(.cntxt(null), .inst_name("*.env.clknrst_agent"), .field_name("vif"), .value(clknrst_if));
|
||||
uvm_config_db#(virtual uvma_cvxif_intf )::set(.cntxt(null), .inst_name("*.env.cvxif_agent"), .field_name("vif"), .value(cvxif_if) );
|
||||
|
|
|
@ -40,6 +40,12 @@ class uvmt_cva6_base_test_c extends uvm_test;
|
|||
uvme_cva6_env_c env ;
|
||||
uvme_cva6_vsqr_c vsequencer;
|
||||
|
||||
typedef enum {
|
||||
UVMA_AXI_VERSION_1P1,
|
||||
UVMA_AXI_VERSION_1P2,
|
||||
UVMA_AXI_VERSION_1P3
|
||||
} uvma_axi_version_enum;
|
||||
|
||||
// Handles testbench interfaces
|
||||
virtual uvmt_rvfi_if rvfi_vif; // virtual peripheral status
|
||||
// virtual uvmt_cva6_core_cntrl_if core_cntrl_vif; // control inputs to the core
|
||||
|
@ -50,6 +56,8 @@ class uvmt_cva6_base_test_c extends uvm_test;
|
|||
// Variable can be modified from command line, to change the AXI agent mode
|
||||
int force_axi_mode = -1;
|
||||
|
||||
uvm_factory factory;
|
||||
|
||||
|
||||
`uvm_component_utils_begin(uvmt_cva6_base_test_c)
|
||||
`uvm_field_object(test_cfg , UVM_DEFAULT)
|
||||
|
@ -74,6 +82,16 @@ class uvmt_cva6_base_test_c extends uvm_test;
|
|||
soft test_cfg.tpt == NO_TEST_PROGRAM;
|
||||
}
|
||||
|
||||
constraint memory_region_cfg {
|
||||
env_cfg.axi_cfg.axi_region_enabled == 0;
|
||||
env_cfg.axi_cfg.axi_prot_enabled == 0;
|
||||
env_cfg.axi_cfg.m_addr_start == 64'h0;
|
||||
env_cfg.axi_cfg.m_addr_end == 64'h7fffffffffffffff;
|
||||
env_cfg.axi_cfg.m_num_part == 1;
|
||||
env_cfg.axi_cfg.m_part_st[0].axi_prot_type_access == 0;
|
||||
env_cfg.axi_cfg.m_part_st[0].m_type_access == 3;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 1. Replaces default report server with rs.
|
||||
|
@ -223,6 +241,26 @@ function void uvmt_cva6_base_test_c::build_phase(uvm_phase phase);
|
|||
create_env ();
|
||||
create_components();
|
||||
|
||||
`uvm_info("BASE TEST", $sformatf("AXI config version = %s", env_cfg.axi_cfg.version), UVM_LOW)
|
||||
|
||||
factory = uvm_factory::get();
|
||||
|
||||
case (env_cfg.axi_cfg.version)
|
||||
UVMA_AXI_VERSION_1P2 : begin
|
||||
factory.set_type_override_by_name("uvma_axi_synchronizer_c", "uvma_axi_ext_synchronizer_c");
|
||||
`uvm_info("BASE TEST", $sformatf("AXI EXT SYNCHRONIZER"), UVM_LOW)
|
||||
end
|
||||
UVMA_AXI_VERSION_1P3 : begin
|
||||
factory.set_type_override_by_name("uvma_axi_synchronizer_c", "uvma_axi_amo_synchronizer_c");
|
||||
`uvm_info("BASE TEST", $sformatf("AXI AMO SYNCHRONIZER"), UVM_LOW)
|
||||
end
|
||||
endcase
|
||||
|
||||
if(!env_cfg.axi_cfg.preload_mem) begin
|
||||
factory.set_type_override_by_name("uvma_axi_fw_preload_seq_c", "uvme_axi_fw_preload_seq_c");
|
||||
end
|
||||
|
||||
|
||||
endfunction : build_phase
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue