OBI Agent and assertions integration for fetch bus (#2257)

This commit is contained in:
Anouar 2024-06-14 10:13:15 +01:00 committed by JeanRochCoulon
parent b59a0d1766
commit 45c05de3af
14 changed files with 391 additions and 3 deletions

View file

@ -43,6 +43,8 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
// Agent cfg handles
rand uvma_clknrst_cfg_c clknrst_cfg;
rand uvma_axi_cfg_c axi_cfg;
rand uvma_obi_memory_cfg_c obi_memory_instr_cfg;
//rand uvma_obi_memory_cfg_c obi_memory_data_cfg;
rand uvma_rvfi_cfg_c#(ILEN,XLEN) rvfi_cfg;
rand uvma_isacov_cfg_c isacov_cfg;
rand uvma_interrupt_cfg_c interrupt_cfg;
@ -66,6 +68,9 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
// Software interrupt supported
rand bit sw_int_supported;
//OBI stall gnt and rvalid
rand bit zero_stall_sim;
`uvm_object_utils_begin(uvme_cva6_cfg_c)
`uvm_field_int ( enabled , UVM_DEFAULT )
`uvm_field_enum(uvm_active_passive_enum, is_active , UVM_DEFAULT )
@ -87,6 +92,10 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
`uvm_field_object(axi_cfg, UVM_DEFAULT)
`uvm_field_object(obi_memory_instr_cfg, UVM_DEFAULT)
// TODO:`uvm_field_object(obi_memory_data_cfg, UVM_DEFAULT)
`uvm_field_object(rvfi_cfg, UVM_DEFAULT)
`uvm_field_object(isacov_cfg, UVM_DEFAULT)
@ -169,6 +178,36 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
}
}
constraint obi_zero_stall_sim_dist_cons {
//zero_stall_sim dist { 0 :/ 2, 1 :/ 1}; // TODO: Randomize
zero_stall_sim == 0;
}
constraint zero_stall_sim_cons {
if (zero_stall_sim) {
obi_memory_instr_cfg.drv_slv_gnt_mode == UVMA_OBI_MEMORY_DRV_SLV_GNT_MODE_CONSTANT;
obi_memory_instr_cfg.drv_slv_rvalid_mode == UVMA_OBI_MEMORY_DRV_SLV_RVALID_MODE_CONSTANT;
//obi_memory_data_cfg.drv_slv_gnt_mode == UVMA_OBI_MEMORY_DRV_SLV_GNT_MODE_CONSTANT;
//obi_memory_data_cfg.drv_slv_rvalid_mode == UVMA_OBI_MEMORY_DRV_SLV_RVALID_MODE_CONSTANT;
}
}
// TODO FIX
//constraint max_data_zero_instr_stall_sim_cons {
//if (max_data_zero_instr_stall) {
//obi_memory_instr_cfg.drv_slv_gnt_mode == UVMA_OBI_MEMORY_DRV_SLV_GNT_MODE_CONSTANT;
//obi_memory_instr_cfg.drv_slv_rvalid_mode == UVMA_OBI_MEMORY_DRV_SLV_RVALID_MODE_CONSTANT;
//obi_memory_data_cfg.drv_slv_gnt_mode == UVMA_OBI_MEMORY_DRV_SLV_GNT_MODE_RANDOM_LATENCY;
//obi_memory_data_cfg.drv_slv_gnt_random_latency_min == 0;
//obi_memory_data_cfg.drv_slv_gnt_random_latency_max == 8;
//obi_memory_data_cfg.drv_slv_rvalid_mode == UVMA_OBI_MEMORY_DRV_SLV_RVALID_MODE_RANDOM_LATENCY;
//obi_memory_data_cfg.drv_slv_rvalid_random_latency_min == 0;
//obi_memory_data_cfg.drv_slv_rvalid_random_latency_max == 8;
//}
//}
constraint agent_cfg_cons {
if (enabled) {
clknrst_cfg.enabled == 1;
@ -188,21 +227,51 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
axi_cfg.zero_delay_mode == 1;
axi_cfg.disable_trs_randomization == 1;
obi_memory_instr_cfg.drv_mode == UVMA_OBI_MEMORY_MODE_SLV;
obi_memory_instr_cfg.version == UVMA_OBI_MEMORY_VERSION_1P2;
obi_memory_instr_cfg.auser_width == RTLCVA6Cfg.ObiFetchbusCfg.OptionalCfg.AUserWidth;
obi_memory_instr_cfg.wuser_width == RTLCVA6Cfg.ObiFetchbusCfg.OptionalCfg.WUserWidth;
obi_memory_instr_cfg.ruser_width == RTLCVA6Cfg.ObiFetchbusCfg.OptionalCfg.RUserWidth;
obi_memory_instr_cfg.addr_width == RTLCVA6Cfg.ObiFetchbusCfg.AddrWidth ;
obi_memory_instr_cfg.data_width == RTLCVA6Cfg.ObiFetchbusCfg.DataWidth ;
obi_memory_instr_cfg.id_width == RTLCVA6Cfg.ObiFetchbusCfg.IdWidth ;
obi_memory_instr_cfg.achk_width == RTLCVA6Cfg.ObiFetchbusCfg.OptionalCfg.AChkWidth ;
obi_memory_instr_cfg.rchk_width == RTLCVA6Cfg.ObiFetchbusCfg.OptionalCfg.RChkWidth ;
soft obi_memory_instr_cfg.drv_slv_gnt_random_latency_max <= 2;
soft obi_memory_instr_cfg.drv_slv_gnt_fixed_latency <= 2;
soft obi_memory_instr_cfg.drv_slv_rvalid_random_latency_max <= 3;
soft obi_memory_instr_cfg.drv_slv_rvalid_fixed_latency <= 3;
// TODO: obi_memory_data_cfg ...
if (is_active == UVM_ACTIVE) {
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 (RTLCVA6Cfg.PipelineOnly) {
obi_memory_instr_cfg.is_active == UVM_ACTIVE;
//TODO :obi_memory_data_cfg.is_active == UVM_ACTIVE;
} else {
obi_memory_instr_cfg.is_active == UVM_PASSIVE;
//TODO :obi_memory_data_cfg.is_active == UVM_PASSIVE;
}
}
if (trn_log_enabled) {
clknrst_cfg.trn_log_enabled == 0;
axi_cfg.trn_log_enabled == 1;
obi_memory_instr_cfg.trn_log_enabled == 1;
//obi_memory_data_cfg.trn_log_enabled == 1;
rvfi_cfg.trn_log_enabled == 1;
isacov_cfg.trn_log_enabled == 1;
} else {
clknrst_cfg.trn_log_enabled == 0;
axi_cfg.trn_log_enabled == 0;
obi_memory_instr_cfg.trn_log_enabled == 0;
//obi_memory_data_cfg.trn_log_enabled == 0;
rvfi_cfg.trn_log_enabled == 0;
isacov_cfg.trn_log_enabled == 0;
}
@ -210,10 +279,14 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
if (cov_model_enabled) {
isacov_cfg.cov_model_enabled == 1;
axi_cfg.cov_model_enabled == 1;
obi_memory_instr_cfg.cov_model_enabled == 1;
//obi_memory_data_cfg.cov_model_enabled == 1; //TODO
interrupt_cfg.cov_model_enabled == 1;
} else {
isacov_cfg.cov_model_enabled == 0;
axi_cfg.cov_model_enabled == 0;
obi_memory_instr_cfg.cov_model_enabled == 0;
//obi_memory_data_cfg.cov_model_enabled == 1; //TODO
interrupt_cfg.cov_model_enabled == 0;
}
@ -250,6 +323,8 @@ function uvme_cva6_cfg_c::new(string name="uvme_cva6_cfg");
clknrst_cfg = uvma_clknrst_cfg_c::type_id::create("clknrst_cfg");
axi_cfg = uvma_axi_cfg_c::type_id::create("axi_cfg");
obi_memory_instr_cfg = uvma_obi_memory_cfg_c::type_id::create("obi_memory_instr_cfg");
// TODO:obi_memory_data_cfg = uvma_obi_memory_cfg_c::type_id::create("obi_memory_data_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");

View file

@ -30,15 +30,18 @@ class uvme_cva6_cntxt_c extends uvm_object;
typedef uvml_mem_c#(cva6_config_pkg::CVA6ConfigAxiAddrWidth) uvml_mem_cva6;
// Agent context handles
uvma_clknrst_cntxt_c clknrst_cntxt;
uvma_axi_cntxt_c axi_cntxt;
uvma_clknrst_cntxt_c clknrst_cntxt;
uvma_axi_cntxt_c axi_cntxt;
uvma_obi_memory_cntxt_c obi_memory_instr_cntxt;
//TODO :uvma_obi_memory_cntxt_c obi_memory_data_cntxt;
uvma_cva6_core_cntrl_cntxt_c core_cntrl_cntxt;
uvma_rvfi_cntxt_c rvfi_cntxt;
uvma_interrupt_cntxt_c interrupt_cntxt;
uvma_cvxif_cntxt_c cvxif_cntxt;
// Memory modelling
rand uvml_mem_cva6 mem;
rand uvml_mem_cva6 mem;
rand uvml_mem_c mem_obi;
// Handle to debug_req interface
virtual uvma_debug_if debug_vif;
@ -51,6 +54,8 @@ class uvme_cva6_cntxt_c extends uvm_object;
`uvm_object_utils_begin(uvme_cva6_cntxt_c)
`uvm_field_object(clknrst_cntxt, UVM_DEFAULT)
`uvm_field_object(axi_cntxt, UVM_DEFAULT)
`uvm_field_object(obi_memory_instr_cntxt, UVM_DEFAULT)
//TODO :`uvm_field_object(obi_memory_data_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)
@ -58,10 +63,12 @@ class uvme_cva6_cntxt_c extends uvm_object;
`uvm_field_event(sample_cfg_e , UVM_DEFAULT)
`uvm_field_event(sample_cntxt_e, UVM_DEFAULT)
`uvm_field_object(mem, UVM_DEFAULT)
`uvm_field_object(mem_obi, UVM_DEFAULT)
`uvm_object_utils_end
constraint mem_cfg_cons {
mem.mem_default == MEM_DEFAULT_0;
mem_obi.mem_default == MEM_DEFAULT_0;
}
/**
@ -79,6 +86,8 @@ function uvme_cva6_cntxt_c::new(string name="uvme_cva6_cntxt");
clknrst_cntxt = uvma_clknrst_cntxt_c::type_id::create("clknrst_cntxt");
core_cntrl_cntxt = uvma_cva6_core_cntrl_cntxt_c::type_id::create("core_cntrl_cntxt");
axi_cntxt = uvma_axi_cntxt_c::type_id::create("axi_cntxt");
obi_memory_instr_cntxt = uvma_obi_memory_cntxt_c::type_id::create("obi_memory_instr_cntxt");
// TODO:obi_memory_data_cntxt = uvma_obi_memory_cntxt_c::type_id::create("obi_memory_data_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");
@ -88,6 +97,7 @@ function uvme_cva6_cntxt_c::new(string name="uvme_cva6_cntxt");
sample_cntxt_e = new("sample_cntxt_e");
mem.mem_default = MEM_DEFAULT_0;
mem_obi.mem_default = MEM_DEFAULT_0;
endfunction : new

View file

@ -43,6 +43,8 @@ class uvme_cva6_env_c extends uvm_env;
// Agents
uvma_clknrst_agent_c clknrst_agent;
uvma_axi_agent_c axi_agent;
uvma_obi_memory_agent_c obi_memory_instr_agent;
// TODO: uvma_obi_memory_agent_c obi_memory_data_agent;
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;
@ -174,6 +176,10 @@ function void uvme_cva6_env_c::build_phase(uvm_phase phase);
end
cntxt.axi_cntxt.mem = cntxt.mem;
if (RTLCVA6Cfg.PipelineOnly) begin
cntxt.obi_memory_instr_cntxt.mem = cntxt.mem_obi;
// TODO:cntxt.obi_memory_data_cntxt.mem = cntxt.mem_obi;
end
cntxt.interrupt_cntxt.mem = cntxt.mem;
// get irq_addr ack from CVA6 UVM env
cfg.interrupt_cfg.irq_addr = cfg.get_irq_addr();
@ -246,6 +252,10 @@ function void uvme_cva6_env_c::assign_cfg();
uvm_config_db#(uvma_axi_cfg_c)::set(this, "*axi_agent", "cfg", cfg.axi_cfg);
uvm_config_db#(uvma_obi_memory_cfg_c)::set(this, "obi_memory_instr_agent", "cfg", cfg.obi_memory_instr_cfg);
// TODO:uvm_config_db#(uvma_obi_memory_cfg_c)::set(this, "obi_memory_data_agent", "cfg", cfg.obi_memory_data_cfg);
uvm_config_db#(uvma_core_cntrl_cfg_c)::set(this, "core_cntrl_agent", "cfg", cfg);
uvm_config_db#(uvma_rvfi_cfg_c#(ILEN,XLEN))::set(this, "*rvfi_agent", "cfg", cfg.rvfi_cfg);
@ -267,6 +277,8 @@ function void uvme_cva6_env_c::assign_cntxt();
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "*", "cntxt", 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_obi_memory_cntxt_c)::set(this, "obi_memory_instr_agent", "cntxt", cntxt.obi_memory_instr_cntxt);
//uvm_config_db#(uvma_obi_memory_cntxt_c)::set(this, "obi_memory_data_agent", "cntxt", cntxt.obi_memory_data_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);
uvm_config_db#(uvma_cvxif_cntxt_c)::set(this, "cvxif_agent", "cntxt", cntxt.cvxif_cntxt);
@ -278,6 +290,8 @@ function void uvme_cva6_env_c::create_agents();
clknrst_agent = uvma_clknrst_agent_c::type_id::create("clknrst_agent", this);
axi_agent = uvma_axi_agent_c::type_id::create("axi_agent", this);
obi_memory_instr_agent = uvma_obi_memory_agent_c::type_id::create("obi_memory_instr_agent", this);
// TODO:obi_memory_data_agent = uvma_obi_memory_agent_c::type_id::create("obi_memory_data_agent", this);
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);
@ -372,6 +386,8 @@ function void uvme_cva6_env_c::assemble_vsequencer();
vsequencer.clknrst_sequencer = clknrst_agent.sequencer;
vsequencer.axi_vsequencer = axi_agent.vsequencer;
vsequencer.interrupt_sequencer = interrupt_agent.sequencer;
vsequencer.obi_memory_instr_sequencer = obi_memory_instr_agent.sequencer;
// TODO: vsequencer.obi_memory_data_sequencer = obi_memory_data_agent.sequencer;
vsequencer.cvxif_vsequencer = cvxif_agent.vsequencer;
endfunction: assemble_vsequencer
@ -379,6 +395,10 @@ endfunction: assemble_vsequencer
task uvme_cva6_env_c::run_phase(uvm_phase phase);
uvma_obi_memory_fw_preload_seq_c fw_preload_seq;
uvma_obi_memory_slv_seq_c instr_slv_seq;
// uvma_obi_memory_slv_seq_c data_slv_seq;
fork
begin
@ -402,6 +422,26 @@ task uvme_cva6_env_c::run_phase(uvm_phase phase);
cvxif_vseq = uvme_cvxif_vseq_c::type_id::create("cvxif_vseq");
cvxif_vseq.start(cvxif_agent.vsequencer);
end
begin : spawn_obi_instr_fw_preload_thread
if(cfg.obi_memory_instr_cfg.is_active == UVM_ACTIVE) begin
fw_preload_seq = uvma_obi_memory_fw_preload_seq_c::type_id::create("fw_preload_seq");
if (!fw_preload_seq.randomize()) begin
`uvm_fatal("FWPRELOAD", "Randomize failed");
end
fw_preload_seq.start(obi_memory_instr_agent.sequencer);
end
end
begin : obi_instr_slv_thread
if(cfg.obi_memory_instr_cfg.is_active == UVM_ACTIVE) begin
instr_slv_seq = uvma_obi_memory_slv_seq_c::type_id::create("instr_slv_seq");
if (!instr_slv_seq.randomize()) begin
`uvm_fatal("INSTRSLVSEQ", "Randomize failed");
end
instr_slv_seq.start(obi_memory_instr_agent.sequencer);
end
end
join_none
endtask

View file

@ -47,6 +47,7 @@ package uvme_cva6_pkg;
import uvml_trn_pkg ::*;
import uvma_clknrst_pkg::*;
import uvma_axi_pkg::*;
import uvma_obi_memory_pkg::*;
import uvml_mem_pkg ::*;
import uvma_core_cntrl_pkg::*;
import uvma_rvfi_pkg::*;
@ -119,6 +120,8 @@ package uvme_cva6_pkg;
`include "uvme_cva6_base_vseq.sv"
`include "uvme_cva6_reset_vseq.sv"
`include "uvme_axi_fw_preload_seq.sv"
`include "uvme_obi_fw_preload_seq.sv"
`include "uvme_obi_slv_seq.sv"
// `include "uvme_cva6_interrupt_noise_vseq.sv"
`include "uvme_cva6_vseq_lib.sv"

View file

@ -39,6 +39,8 @@ class uvme_cva6_vsqr_c extends uvm_sequencer#(
uvma_axi_vsqr_c axi_vsequencer;
uvma_interrupt_sqr_c interrupt_sequencer;
uvma_cvxif_vsqr_c cvxif_vsequencer;
uvma_obi_memory_sqr_c obi_memory_instr_sequencer;
// TODO:uvma_obi_memory_sqr_c obi_memory_instr_sequencer;
`uvm_component_utils_begin(uvme_cva6_vsqr_c)

View file

@ -0,0 +1,81 @@
// 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_OBI_FW_PRELOAD_SEQ_SV__
`define __UVME_OBI_FW_PRELOAD_SEQ_SV__
/**
* Virtual sequence preloads the CVA6 memory.
*/
class uvme_obi_fw_preload_seq_c extends uvma_obi_memory_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_obi_fw_preload_seq_c)
/**
* Default constructor.
*/
extern function new(string name="uvma_obi_fw_preload_seq");
extern virtual task body();
endclass : uvme_obi_fw_preload_seq_c
function uvme_obi_fw_preload_seq_c::new(string name="uvma_obi_fw_preload_seq");
super.new(name);
endfunction : new
task uvme_obi_fw_preload_seq_c::body();
void'(uvcl.get_arg_value("+elf_file=", binary));
if (binary != "") begin
read_elf(binary);
wait(p_sequencer.cntxt.vif.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];
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
p_sequencer.cntxt.mem.write(address + i*8 + 0, mem_row[0]);
p_sequencer.cntxt.mem.write(address + i*8 + 1, mem_row[1]);
p_sequencer.cntxt.mem.write(address + i*8 + 2, mem_row[2]);
p_sequencer.cntxt.mem.write(address + i*8 + 3, mem_row[3]);
p_sequencer.cntxt.mem.write(address + i*8 + 4, mem_row[4]);
p_sequencer.cntxt.mem.write(address + i*8 + 5, mem_row[5]);
p_sequencer.cntxt.mem.write(address + i*8 + 6, mem_row[6]);
p_sequencer.cntxt.mem.write(address + i*8 + 7, mem_row[7]);
end
end
end
endtask : body
`endif // __UVME_OBI_FW_PRELOAD_SEQ_SV__

78
verif/env/uvme/vseq/uvme_obi_slv_seq.sv vendored Normal file
View file

@ -0,0 +1,78 @@
//
// Copyright 2021 OpenHW Group
// Copyright 2021 Datum Technology Corporation
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may
// not use this file except in compliance with the License, or, at your option,
// the Apache License version 2.0. You may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work
// 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 __UVME_OBI_SLV_SEQ_SV__
`define __UVME_OBI_SLV_SEQ_SV__
/**
* Virtual sequence implementing the cva6 virtual peripherals.
*/
class uvme_obi_slv_seq_c extends uvma_obi_memory_slv_seq_c;
`uvm_object_utils_begin(uvme_obi_slv_seq_c)
`uvm_object_utils_end
function new(string name="uvme_obi_slv_seq_c");
super.new(name);
endfunction : new
task do_mem_operation(ref uvma_obi_memory_mon_trn_c mon_req);
bit [31:0] word_aligned_addr;
uvma_obi_memory_slv_seq_item_c slv_rsp;
`uvm_create(slv_rsp)
slv_rsp.orig_trn = mon_req;
slv_rsp.access_type = mon_req.access_type;
word_aligned_addr = { mon_req.address[31:3], 3'h0 };
`uvm_info("SLV_SEQ", $sformatf("Performing operation:\n%s", mon_req.sprint()), UVM_HIGH)
if (mon_req.access_type == UVMA_OBI_MEMORY_ACCESS_WRITE) begin
if (mon_req.be[7]) cntxt.mem.write(word_aligned_addr+7, mon_req.data[63:56]);
if (mon_req.be[6]) cntxt.mem.write(word_aligned_addr+6, mon_req.data[55:48]);
if (mon_req.be[5]) cntxt.mem.write(word_aligned_addr+5, mon_req.data[47:40]);
if (mon_req.be[4]) cntxt.mem.write(word_aligned_addr+4, mon_req.data[39:32]);
if (mon_req.be[3]) cntxt.mem.write(word_aligned_addr+3, mon_req.data[31:24]);
if (mon_req.be[2]) cntxt.mem.write(word_aligned_addr+2, mon_req.data[23:16]);
if (mon_req.be[1]) cntxt.mem.write(word_aligned_addr+1, mon_req.data[15:08]);
if (mon_req.be[0]) cntxt.mem.write(word_aligned_addr+0, mon_req.data[07:00]);
end
else begin
if (mon_req.be[7]) slv_rsp.rdata[63:56] = cntxt.mem.read(word_aligned_addr+7);
if (mon_req.be[6]) slv_rsp.rdata[55:48] = cntxt.mem.read(word_aligned_addr+6);
if (mon_req.be[5]) slv_rsp.rdata[47:40] = cntxt.mem.read(word_aligned_addr+5);
if (mon_req.be[4]) slv_rsp.rdata[39:32] = cntxt.mem.read(word_aligned_addr+4);
if (mon_req.be[3]) slv_rsp.rdata[31:24] = cntxt.mem.read(word_aligned_addr+3);
if (mon_req.be[2]) slv_rsp.rdata[23:16] = cntxt.mem.read(word_aligned_addr+2);
if (mon_req.be[1]) slv_rsp.rdata[15:08] = cntxt.mem.read(word_aligned_addr+1);
if (mon_req.be[0]) slv_rsp.rdata[07:00] = cntxt.mem.read(word_aligned_addr+0);
end
add_r_fields(mon_req, slv_rsp);
slv_rsp.set_sequencer(p_sequencer);
`uvm_send(slv_rsp)
endtask : do_mem_operation
endclass : uvme_obi_slv_seq_c
`endif // __UVME_OBI_SLV_SEQ_SV__

View file

@ -171,6 +171,7 @@ export DV_UVML_TRN_PATH = $(CORE_V_VERIF)/lib/uvm_libs/uvml_trn
export DV_UVML_MEM_PATH = $(CORE_V_VERIF)/lib/uvm_libs/uvml_mem
export DV_UVML_LOGS_PATH = $(CORE_V_VERIF)/lib/uvm_libs/uvml_logs
export DV_UVML_SB_PATH = $(CORE_V_VERIF)/lib/uvm_libs/uvml_sb
export DV_UVMA_OBI_MEMORY_PATH= $(CORE_V_VERIF)/lib/uvm_agents/uvma_obi_memory
export CV_CORE_PKG = $(CORE_V_VERIF)/core-v-cores/$(CV_CORE_LC)
export DESIGN_RTL_DIR = $(CV_CORE_PKG)/rtl

View file

@ -76,6 +76,7 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
uvma_debug_if debug_if,
uvma_axi_intf axi_slave,
uvma_cvxif_intf cvxif_if,
uvma_obi_memory_if obi_fetch_slave,
uvmt_axi_switch_intf axi_switch_vif,
uvmt_default_inputs_intf default_inputs_vif
);
@ -256,6 +257,66 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
assign cvxif_if.commit_req = cvxif_req.commit;
assign cvxif_if.result_ready = cvxif_req.result_ready;
//Obi Interface
if (CVA6Cfg.PipelineOnly) begin
assign obi_fetch_slave.req = i_cva6.obi_fetch_req_if_cache.req;
assign obi_fetch_slave.addr = i_cva6.obi_fetch_req_if_cache.a.addr;
assign obi_fetch_slave.we = i_cva6.obi_fetch_req_if_cache.a.we;
assign obi_fetch_slave.be = i_cva6.obi_fetch_req_if_cache.a.be;
assign obi_fetch_slave.wdata = i_cva6.obi_fetch_req_if_cache.a.wdata;
assign obi_fetch_slave.auser = i_cva6.obi_fetch_req_if_cache.a.a_optional.auser;
assign obi_fetch_slave.wuser = i_cva6.obi_fetch_req_if_cache.a.a_optional.wuser;
assign obi_fetch_slave.aid = i_cva6.obi_fetch_req_if_cache.a.aid;
assign obi_fetch_slave.atop = i_cva6.obi_fetch_req_if_cache.a.a_optional.atop;
assign obi_fetch_slave.memtype = i_cva6.obi_fetch_req_if_cache.a.a_optional.memtype;
assign obi_fetch_slave.prot = i_cva6.obi_fetch_req_if_cache.a.a_optional.prot;
assign obi_fetch_slave.reqpar = i_cva6.obi_fetch_req_if_cache.reqpar;
assign obi_fetch_slave.achk = i_cva6.obi_fetch_req_if_cache.a.a_optional.achk;
assign obi_fetch_slave.rready = i_cva6.obi_fetch_req_if_cache.rready;
assign obi_fetch_slave.rreadypar = i_cva6.obi_fetch_req_if_cache.rreadypar;
assign i_cva6.obi_fetch_rsp_cache_if.gnt = obi_fetch_slave.gnt;
assign i_cva6.obi_fetch_rsp_cache_if.gntpar = obi_fetch_slave.gntpar;
assign i_cva6.obi_fetch_rsp_cache_if.rvalid = obi_fetch_slave.rvalid;
assign i_cva6.obi_fetch_rsp_cache_if.r.rdata = obi_fetch_slave.rdata;
assign i_cva6.obi_fetch_rsp_cache_if.r.err = obi_fetch_slave.err;
assign i_cva6.obi_fetch_rsp_cache_if.r.r_optional.ruser = obi_fetch_slave.ruser;
assign i_cva6.obi_fetch_rsp_cache_if.r.rid = obi_fetch_slave.rid;
assign i_cva6.obi_fetch_rsp_cache_if.r.r_optional.exokay = obi_fetch_slave.exokay;
assign i_cva6.obi_fetch_rsp_cache_if.rvalidpar = obi_fetch_slave.rvalidpar;
assign i_cva6.obi_fetch_rsp_cache_if.r.r_optional.rchk = obi_fetch_slave.rchk;
initial begin // TODO: workaround, need to emulate with OBI agent
force i_cva6.fetch_dreq_cache_if.ready = 1;
force i_cva6.fetch_dreq_cache_if.invalid_data = 0;
end
end else begin //OBI in PASSIVE mode
assign obi_fetch_slave.req = i_cva6.obi_fetch_req_if_cache.req;
assign obi_fetch_slave.addr = i_cva6.obi_fetch_req_if_cache.a.addr;
assign obi_fetch_slave.we = i_cva6.obi_fetch_req_if_cache.a.we;
assign obi_fetch_slave.be = i_cva6.obi_fetch_req_if_cache.a.be;
assign obi_fetch_slave.wdata = i_cva6.obi_fetch_req_if_cache.a.wdata;
assign obi_fetch_slave.auser = i_cva6.obi_fetch_req_if_cache.a.a_optional.auser;
assign obi_fetch_slave.wuser = i_cva6.obi_fetch_req_if_cache.a.a_optional.wuser;
assign obi_fetch_slave.aid = i_cva6.obi_fetch_req_if_cache.a.aid;
assign obi_fetch_slave.atop = i_cva6.obi_fetch_req_if_cache.a.a_optional.atop;
assign obi_fetch_slave.memtype = i_cva6.obi_fetch_req_if_cache.a.a_optional.memtype;
assign obi_fetch_slave.prot = i_cva6.obi_fetch_req_if_cache.a.a_optional.prot;
assign obi_fetch_slave.reqpar = i_cva6.obi_fetch_req_if_cache.reqpar;
assign obi_fetch_slave.achk = i_cva6.obi_fetch_req_if_cache.a.a_optional.achk;
assign obi_fetch_slave.rready = i_cva6.obi_fetch_req_if_cache.rready;
assign obi_fetch_slave.rreadypar = i_cva6.obi_fetch_req_if_cache.rreadypar;
assign obi_fetch_slave.gnt = i_cva6.obi_fetch_rsp_cache_if.gnt;
assign obi_fetch_slave.gntpar = i_cva6.obi_fetch_rsp_cache_if.gntpar;
assign obi_fetch_slave.rvalid = i_cva6.obi_fetch_rsp_cache_if.rvalid;
assign obi_fetch_slave.rdata = i_cva6.obi_fetch_rsp_cache_if.r.rdata;
assign obi_fetch_slave.err = i_cva6.obi_fetch_rsp_cache_if.r.err;
assign obi_fetch_slave.ruser = i_cva6.obi_fetch_rsp_cache_if.r.r_optional.ruser;
assign obi_fetch_slave.rid = i_cva6.obi_fetch_rsp_cache_if.r.rid;
assign obi_fetch_slave.exokay = i_cva6.obi_fetch_rsp_cache_if.r.r_optional.exokay;
assign obi_fetch_slave.rvalidpar = i_cva6.obi_fetch_rsp_cache_if.rvalidpar;
assign obi_fetch_slave.rchk = i_cva6.obi_fetch_rsp_cache_if.r.r_optional.rchk;
end
///assign obi_fetch_slave.mid = i_cva6.obi_fetch_rsp_cache_if.a.a_optional.mid;
///assign obi_fetch_slave.dbg = i_cva6.obi_fetch_rsp_cache_if.a.a_optional.dbg;
AXI_BUS #(

View file

@ -33,6 +33,17 @@
-f ${DV_UVMC_RVFI_SCOREBOARD_PATH}/uvmc_rvfi_scoreboard_pkg.flist
-f ${CVA6_UVME_PATH}/uvma_interrupt/uvma_interrupt_pkg.flist
+define+UVMA_OBI_MEMORY_AUSER_DEFAULT_WIDTH=64 // Width of the auser signal.
+define+UVMA_OBI_MEMORY_WUSER_DEFAULT_WIDTH=64 // Width of the wuser signal.
+define+UVMA_OBI_MEMORY_RUSER_DEFAULT_WIDTH=64 // Width of the ruser signal.
+define+UVMA_OBI_MEMORY_ADDR_DEFAULT_WIDTH=32 // Width of the addr signal.
+define+UVMA_OBI_MEMORY_DATA_DEFAULT_WIDTH=64 // Width of the rdata and wdata signals. be width is DATA_WIDTH / 8. Valid DATA_WIDTH settings are 32 and 64.
+define+UVMA_OBI_MEMORY_ID_DEFAULT_WIDTH=10 // Width of the aid and rid signals.
+define+UVMA_OBI_MEMORY_ACHK_DEFAULT_WIDTH=10 // Width of the achk signal.
+define+UVMA_OBI_MEMORY_RCHK_DEFAULT_WIDTH=10 // Width of the rchk signal.
-f ${DV_UVMA_OBI_MEMORY_PATH}/src/uvma_obi_memory_pkg.flist
// Environments
-f ${CVA6_UVME_PATH}/uvme_cva6_pkg.flist

View file

@ -30,6 +30,7 @@ module uvmt_cva6_dut_wrap # (
(
uvma_clknrst_if clknrst_if,
uvma_axi_intf axi_if,
uvma_obi_memory_if obi_fetch_if,
uvmt_axi_switch_intf axi_switch_vif,
uvmt_default_inputs_intf default_inputs_vif,
uvme_cva6_core_cntrl_if core_cntrl_if,
@ -64,6 +65,7 @@ module uvmt_cva6_dut_wrap # (
.debug_if ( debug_if ),
.axi_slave ( axi_if ),
.cvxif_if ( cvxif_vif ),
.obi_fetch_slave ( obi_fetch_if ),
.axi_switch_vif ( axi_switch_vif ),
.default_inputs_vif ( default_inputs_vif ),
.tb_exit_o ( tb_exit_o ),

View file

@ -30,6 +30,7 @@
`include "uvmt_axi_switch_intf.sv"
`include "uvmt_default_inputs_intf.sv"
`include "uvma_axi_intf.sv"
`include "uvma_obi_memory_if.sv"
/**
* Encapsulates all the types and test cases for the verification of an

View file

@ -75,6 +75,25 @@ module uvmt_cva6_tb;
.reset_n(clknrst_if.reset_n)
);
//OBI in monitor mode
uvma_obi_memory_if obi_fetch_if (
.clk(clknrst_if.clk),
.reset_n(clknrst_if.reset_n)
);
//bind assertion module for obi interface
bind uvmt_cva6_dut_wrap uvma_obi_memory_assert_if_wrp #(
.AUSER_WIDTH(CVA6Cfg.ObiFetchbusCfg.OptionalCfg.AUserWidth),
.WUSER_WIDTH(CVA6Cfg.ObiFetchbusCfg.OptionalCfg.WUserWidth),
.RUSER_WIDTH(CVA6Cfg.ObiFetchbusCfg.OptionalCfg.RUserWidth),
.ADDR_WIDTH(CVA6Cfg.ObiFetchbusCfg.AddrWidth),
.DATA_WIDTH(CVA6Cfg.ObiFetchbusCfg.DataWidth),
.ID_WIDTH(CVA6Cfg.ObiFetchbusCfg.IdWidth),
.ACHK_WIDTH(CVA6Cfg.ObiFetchbusCfg.OptionalCfg.AChkWidth),
.RCHK_WIDTH(CVA6Cfg.ObiFetchbusCfg.OptionalCfg.RChkWidth),
.IS_1P2(1)) obi_fetch_assert(.obi(obi_fetch_if));
uvmt_axi_switch_intf axi_switch_vif();
uvme_cva6_core_cntrl_if core_cntrl_if();
uvma_rvfi_instr_if #(
@ -127,6 +146,7 @@ module uvmt_cva6_tb;
.clknrst_if(clknrst_if),
.debug_if(debug_if),
.axi_if (axi_if),
.obi_fetch_if (obi_fetch_if),
.axi_switch_vif (axi_switch_vif),
.default_inputs_vif (default_inputs_vif),
.core_cntrl_if(core_cntrl_if),
@ -395,6 +415,7 @@ module uvmt_cva6_tb;
uvm_config_db#(virtual uvma_cvxif_intf)::set(.cntxt(null), .inst_name("*"), .field_name("vif"), .value(cvxif_vif));
uvm_config_db#(virtual uvmt_tb_exit_if)::set(.cntxt(null), .inst_name("*"), .field_name("tb_exit_vif"), .value(tb_exit_if));
uvm_config_db#(virtual uvma_obi_memory_if)::set(.cntxt(null), .inst_name("*obi_memory_instr_agent"), .field_name("vif"), .value(obi_fetch_if));
// DUT and ENV parameters
uvm_config_db#(int)::set(.cntxt(null), .inst_name("*"), .field_name("ENV_PARAM_INSTR_ADDR_WIDTH"), .value(ENV_PARAM_INSTR_ADDR_WIDTH) );

View file

@ -263,6 +263,8 @@ function void uvmt_cva6_base_test_c::build_phase(uvm_phase phase);
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");
factory.set_type_override_by_name("uvma_obi_memory_fw_preload_seq_c", "uvme_obi_fw_preload_seq_c");
factory.set_type_override_by_name("uvma_obi_memory_slv_seq_c", "uvme_obi_slv_seq_c");
end
endfunction : build_phase