mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-24 22:07:43 -04:00
Update lowrisc_ip to lowRISC/opentitan@ca950b43a
Update code from upstream repository https://github.com/lowRISC/opentitan to revision ca950b43a0e9ef5013b8e2e5de765bc34fb59b74 Two updates to the Ibex code were required: * Adjust the prim_secded port names to match the changes in OpenTitan. * Replace `has_ral` in `ibex_icache_env_cfg.sv` and `ibex_icache_base_test.sv` with its newer equivalent, matching https://github.com/lowRISC/opentitan/pull/5932 and the additional updates in https://github.com/lowRISC/opentitan/pull/5951. Upstream changes include: * [prim_secded] Use _i/_o suffix for port names (Philipp Wagner) * [tl,dv] Allow bits to be set in responses regardless of mask (Rupert Swarbrick) * [push_pull agent] Driver code refactor (Srikrishna Iyer) * [dv/dvsim] Group failures per test in buckets (Guillermo Maturana) * [dv/uvmdvgen] Flag error for paths in block name (Guillermo Maturana) * [prim_fifo_async] Style fixes (Philipp Wagner) * Remove non-ASCII characters from SV code and meson.build (Rupert Swarbrick) * [dv/spi_device] Fix spi_device_csr_wr_with_rand_reset timeout issue (Cindy Chen) * [otp] Update to match latest foundry wrapper (Timothy Chen) * [flash] update to match latest foundry wrapper (Timothy Chen) * [top] Latest ast integration (Timothy Chen) * [lint] Strengthen Verible lint check to 100-character lines (Rupert Swarbrick) * [ prim ] Suppress unneeded assertion when clearing prim_packer_fifo (Martin Lueker-Boden) * [dv/otp_ctrl] Add coverage exclusions (Cindy Chen) * [dv/dvsim] Add "^Error:" as a run fail pattern. (Guillermo Maturana) * [dvsim] Fix column bug in DV summary report (Srikrishna Iyer) * [dvsim] Fix testplan test counts (Srikrishna Iyer) * [dvsim] Fix lowRISC/opentitan#6061 (Srikrishna Iyer) * [prim_clock_div] Update waiver (Michael Schaffner) * [fpv] dvsim script error (Cindy Chen) * [prim_otp] Update interface (Michael Schaffner) * [dvsim] update edacloudlauncher imports (Udi Jonnalagadda) * [dv/doc] Minor fix on dv_doc (Cindy Chen) * [dvsim] Scheduler updates - max_parallel, max_poll (Srikrishna Iyer) * [dvsim] Set `Deploy.job_name` more robustly (Srikrishna Iyer) * [prim] Make SECDED prim generation deterministic (Rupert Swarbrick) * [tool, xcel] Support dumpping the array of struct in shm/vcd (Tung Hoang) * [dv/otp_ctrl] OTP_CTRL DV doc (Cindy Chen) * [dv/dv_macros] Fix DV_PRINT_ARR_CONTENTS (Guillermo Maturana) * [prim_pad_attr/prim_flop_en] Add waiver files (Michael Schaffner) * [prim_usb_diff] Minor lint fix (Michael Schaffner) * [prim_clock_div] Update waiver file (Michael Schaffner) * [top] change prim_generic usage into prim (Timothy Chen) * [formal/conn] Support dvsim to publish regression result summary (Cindy Chen) * Add formatting changes from allow list (Rafal Kapuscik) * [prim] Add generic and Xilinx-specific xor2 primitives (Pirmin Vogel) * [prim] Add Width parameter to buffer primitives (Pirmin Vogel) * [prim] Add generic and Xilinx-specific enable-FF primitives (Pirmin Vogel) * [prim] Remove temporary workaround in parameter list related to primgen (Pirmin Vogel) * [dv/dvsim] Provides more context on some failures. (Guillermo Maturana) * [dvsim] Fix local run error. (Eunchan Kim) * [dv] Support multi-ral (part 4) (Weicai Yang) * [dv/dvsim] Adds failure bucketizer for triage. (Guillermo Maturana) * [lint/docs] Update ascentlint dvsim command in readme (Michael Schaffner) * [top] Various top level lint fixes (Timothy Chen) * [pinmux/padring] Wire up the pad attribute WARL behavior modules (Michael Schaffner) * [dv] Fix tl_error failure (Weicai Yang) * [pinout] Update flash test mode and voltage signals/pads (Michael Schaffner) * [pad_wrapper] Extend the generic and Xilinx pad wrapper models (Michael Schaffner) * [dv] Update scb for all blocks (Weicai Yang) * [dv] Support multi-ral (part 3) (Weicai Yang) * [prim_arbiter,lint] Tell Verilator to split variables for scheduling (Rupert Swarbrick) * [prim] Fix lint warnings, replace inline AscentLint waivers (Pirmin Vogel) * [dvsim] Scratch root default to $REPO_TOP/scratch (Srikrishna Iyer) * [dv] Update `process_tl_access` args for all blocks (Weicai Yang) * [dv] Support multi-ral (part 2) (Weicai Yang) * [formal] Clean up some formal warnings (Cindy Chen) * [topgen] Rework pinmux datastructure and templatize tops (Michael Schaffner) * [otp_ctrl] Several small lint fixes (Michael Schaffner) * [prim_fifo_async] Make async FIFO output zero when empty (Noah Moroze) * [flash] Improve flash ECC handling based on transasction attribute (Timothy Chen) * [dv] Remove toggle coverage excl for a_user/d_user (Weicai Yang) * [dvsim] Fix remaining comments from lowRISC/opentitan#5876 (Srikrishna Iyer) * [dv] Support multi-ral (part 1) (Weicai Yang) Signed-off-by: Philipp Wagner <phw@lowrisc.org>
This commit is contained in:
parent
8ef06de73d
commit
c7cb958f0d
107 changed files with 2699 additions and 1569 deletions
62
vendor/lowrisc_ip/dv/sv/csr_utils/csr_seq_lib.sv
vendored
62
vendor/lowrisc_ip/dv/sv/csr_utils/csr_seq_lib.sv
vendored
|
@ -23,10 +23,9 @@
|
|||
class csr_base_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
|
||||
`uvm_object_utils(csr_base_seq)
|
||||
|
||||
uvm_reg_block models[$];
|
||||
uvm_reg_block models[string];
|
||||
uvm_reg all_csrs[$];
|
||||
uvm_reg test_csrs[$];
|
||||
csr_excl_item m_csr_excl_item;
|
||||
|
||||
// By default, assume external checker (example, scoreboard) is turned off. If that is the case,
|
||||
// then writes are followed by call to predict function to update the mirrored value. Reads are
|
||||
|
@ -48,12 +47,6 @@ class csr_base_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
|
|||
|
||||
// create test_csrs list only if its empty
|
||||
if (test_csrs.size() == 0) set_csr_test_range();
|
||||
|
||||
// create dummy m_csr_excl_item if not supplied
|
||||
if (m_csr_excl_item == null) begin
|
||||
`uvm_info(`gtn, "m_csr_excl_item is null, creating a dummy one locally", UVM_LOW)
|
||||
m_csr_excl_item = csr_excl_item::type_id::create("m_csr_excl_item");
|
||||
end
|
||||
endtask
|
||||
|
||||
// post_start
|
||||
|
@ -63,10 +56,6 @@ class csr_base_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
|
|||
test_csrs.delete();
|
||||
endtask
|
||||
|
||||
function void set_csr_excl_item(csr_excl_item item);
|
||||
this.m_csr_excl_item = item;
|
||||
endfunction
|
||||
|
||||
// extract csrs and split and prune to a specified test_csr_chunk
|
||||
virtual function void set_csr_test_range();
|
||||
int start_idx;
|
||||
|
@ -112,6 +101,18 @@ class csr_base_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
|
|||
test_csrs.shuffle();
|
||||
endfunction
|
||||
|
||||
// check if this csr/fld is excluded from test based on the excl info in blk.csr_excl
|
||||
// TODO, consider to put excl info in dv_base_reg and dv_base_reg_field
|
||||
function bit is_excl(uvm_object obj,
|
||||
csr_excl_type_e csr_excl_type,
|
||||
csr_test_type_e csr_test_type);
|
||||
csr_excl_item csr_excl = get_excl_item(obj);
|
||||
if (csr_excl == null) begin
|
||||
return 0;
|
||||
end else begin
|
||||
return csr_excl.is_excl(obj, csr_excl_type, csr_test_type);
|
||||
end
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -131,7 +132,7 @@ class csr_hw_reset_seq extends csr_base_seq;
|
|||
uvm_reg_data_t compare_mask;
|
||||
|
||||
// check if parent block or register is excluded from init check
|
||||
if (m_csr_excl_item.is_excl(test_csrs[i], CsrExclInitCheck, CsrHwResetTest)) begin
|
||||
if (is_excl(test_csrs[i], CsrExclInitCheck, CsrHwResetTest)) begin
|
||||
`uvm_info(`gtn, $sformatf("Skipping register %0s due to CsrExclInitCheck exclusion",
|
||||
test_csrs[i].get_full_name()), UVM_MEDIUM)
|
||||
continue;
|
||||
|
@ -140,8 +141,7 @@ class csr_hw_reset_seq extends csr_base_seq;
|
|||
`uvm_info(`gtn, $sformatf("Verifying reset value of register %0s",
|
||||
test_csrs[i].get_full_name()), UVM_MEDIUM)
|
||||
|
||||
compare_mask = get_mask_excl_fields(test_csrs[i], CsrExclInitCheck, CsrHwResetTest,
|
||||
m_csr_excl_item);
|
||||
compare_mask = get_mask_excl_fields(test_csrs[i], CsrExclInitCheck, CsrHwResetTest);
|
||||
csr_rd_check(.ptr (test_csrs[i]),
|
||||
.blocking (0),
|
||||
.compare (!external_checker),
|
||||
|
@ -190,7 +190,7 @@ class csr_write_seq extends csr_base_seq;
|
|||
dv_base_reg dv_csr;
|
||||
bit backdoor;
|
||||
// check if parent block or register is excluded from write
|
||||
if (m_csr_excl_item.is_excl(test_csrs[i], CsrExclWrite, CsrHwResetTest)) begin
|
||||
if (is_excl(test_csrs[i], CsrExclWrite, CsrHwResetTest)) begin
|
||||
`uvm_info(`gtn, $sformatf("Skipping register %0s due to CsrExclWrite exclusion",
|
||||
test_csrs[i].get_full_name()), UVM_MEDIUM)
|
||||
continue;
|
||||
|
@ -200,7 +200,7 @@ class csr_write_seq extends csr_base_seq;
|
|||
test_csrs[i].get_full_name()), UVM_MEDIUM)
|
||||
|
||||
`DV_CHECK_STD_RANDOMIZE_FATAL(wdata)
|
||||
wdata &= get_mask_excl_fields(test_csrs[i], CsrExclWrite, CsrHwResetTest, m_csr_excl_item);
|
||||
wdata &= get_mask_excl_fields(test_csrs[i], CsrExclWrite, CsrHwResetTest);
|
||||
|
||||
`downcast(dv_csr, test_csrs[i])
|
||||
if (en_rand_backdoor_write && !dv_csr.get_is_ext_reg()) begin
|
||||
|
@ -234,7 +234,7 @@ class csr_rw_seq extends csr_base_seq;
|
|||
uvm_reg_field test_fields[$];
|
||||
|
||||
// check if parent block or register is excluded from write
|
||||
if (m_csr_excl_item.is_excl(test_csrs[i], CsrExclWrite, CsrRwTest)) begin
|
||||
if (is_excl(test_csrs[i], CsrExclWrite, CsrRwTest)) begin
|
||||
`uvm_info(`gtn, $sformatf("Skipping register %0s due to CsrExclWrite exclusion",
|
||||
test_csrs[i].get_full_name()), UVM_MEDIUM)
|
||||
continue;
|
||||
|
@ -244,7 +244,7 @@ class csr_rw_seq extends csr_base_seq;
|
|||
test_csrs[i].get_full_name()), UVM_MEDIUM)
|
||||
|
||||
`DV_CHECK_STD_RANDOMIZE_FATAL(wdata)
|
||||
wdata &= get_mask_excl_fields(test_csrs[i], CsrExclWrite, CsrRwTest, m_csr_excl_item);
|
||||
wdata &= get_mask_excl_fields(test_csrs[i], CsrExclWrite, CsrRwTest);
|
||||
|
||||
// if external checker is not enabled and writes are made non-blocking, then we need to
|
||||
// pre-predict so that the mirrored value will be updated. if we dont, then csr_rd_check task
|
||||
|
@ -258,8 +258,7 @@ class csr_rw_seq extends csr_base_seq;
|
|||
.compare(!external_checker),
|
||||
.compare_vs_ral(1),
|
||||
.csr_excl_type(CsrExclWriteCheck),
|
||||
.csr_test_type(CsrRwTest),
|
||||
.csr_excl_item(m_csr_excl_item));
|
||||
.csr_test_type(CsrRwTest));
|
||||
|
||||
wait_if_max_outstanding_accesses_reached();
|
||||
end
|
||||
|
@ -281,8 +280,8 @@ class csr_bit_bash_seq extends csr_base_seq;
|
|||
virtual task body();
|
||||
foreach (test_csrs[i]) begin
|
||||
// check if parent block or register is excluded from write
|
||||
if (m_csr_excl_item.is_excl(test_csrs[i], CsrExclWrite, CsrBitBashTest) ||
|
||||
m_csr_excl_item.is_excl(test_csrs[i], CsrExclWriteCheck, CsrBitBashTest)) begin
|
||||
if (is_excl(test_csrs[i], CsrExclWrite, CsrBitBashTest) ||
|
||||
is_excl(test_csrs[i], CsrExclWriteCheck, CsrBitBashTest)) begin
|
||||
`uvm_info(`gtn, $sformatf("Skipping register %0s due to CsrExclWrite/WriteCheck exclusion",
|
||||
test_csrs[i].get_full_name()), UVM_MEDIUM)
|
||||
continue;
|
||||
|
@ -323,15 +322,15 @@ class csr_bit_bash_seq extends csr_base_seq;
|
|||
endcase
|
||||
|
||||
// skip fields that are wr-excluded
|
||||
if (m_csr_excl_item.is_excl(fields[j], CsrExclWrite, CsrBitBashTest)) begin
|
||||
if (is_excl(fields[j], CsrExclWrite, CsrBitBashTest)) begin
|
||||
`uvm_info(`gtn, $sformatf("Skipping field %0s due to CsrExclWrite exclusion",
|
||||
fields[j].get_full_name()), UVM_MEDIUM)
|
||||
dc = 1;
|
||||
end
|
||||
|
||||
// ignore fields that are init or rd-excluded
|
||||
cmp = m_csr_excl_item.is_excl(fields[j], CsrExclInitCheck, CsrBitBashTest) ||
|
||||
m_csr_excl_item.is_excl(fields[j], CsrExclWriteCheck, CsrBitBashTest) ;
|
||||
cmp = is_excl(fields[j], CsrExclInitCheck, CsrBitBashTest) ||
|
||||
is_excl(fields[j], CsrExclWriteCheck, CsrBitBashTest) ;
|
||||
|
||||
// Any unused bits on the right side of the LSB?
|
||||
while (next_lsb < lsb) mode[next_lsb++] = "RO";
|
||||
|
@ -404,7 +403,7 @@ class csr_aliasing_seq extends csr_base_seq;
|
|||
uvm_reg_data_t wdata;
|
||||
|
||||
// check if parent block or register is excluded
|
||||
if (m_csr_excl_item.is_excl(test_csrs[i], CsrExclWrite, CsrAliasingTest)) begin
|
||||
if (is_excl(test_csrs[i], CsrExclWrite, CsrAliasingTest)) begin
|
||||
`uvm_info(`gtn, $sformatf("Skipping register %0s due to CsrExclWrite exclusion",
|
||||
test_csrs[i].get_full_name()), UVM_MEDIUM)
|
||||
continue;
|
||||
|
@ -414,7 +413,7 @@ class csr_aliasing_seq extends csr_base_seq;
|
|||
test_csrs[i].get_full_name()), UVM_MEDIUM)
|
||||
|
||||
`DV_CHECK_STD_RANDOMIZE_FATAL(wdata)
|
||||
wdata &= get_mask_excl_fields(test_csrs[i], CsrExclWrite, CsrAliasingTest, m_csr_excl_item);
|
||||
wdata &= get_mask_excl_fields(test_csrs[i], CsrExclWrite, CsrAliasingTest);
|
||||
csr_wr(.ptr(test_csrs[i]), .value(wdata), .blocking(0), .predict(!external_checker));
|
||||
|
||||
all_csrs.shuffle();
|
||||
|
@ -427,15 +426,14 @@ class csr_aliasing_seq extends csr_base_seq;
|
|||
uvm_reg_data_t compare_mask;
|
||||
|
||||
// check if parent block or register is excluded
|
||||
if (m_csr_excl_item.is_excl(all_csrs[j], CsrExclInitCheck, CsrAliasingTest) ||
|
||||
m_csr_excl_item.is_excl(all_csrs[j], CsrExclWriteCheck, CsrAliasingTest)) begin
|
||||
if (is_excl(all_csrs[j], CsrExclInitCheck, CsrAliasingTest) ||
|
||||
is_excl(all_csrs[j], CsrExclWriteCheck, CsrAliasingTest)) begin
|
||||
`uvm_info(`gtn, $sformatf("Skipping register %0s due to CsrExclInit/WriteCheck exclusion",
|
||||
all_csrs[j].get_full_name()), UVM_MEDIUM)
|
||||
continue;
|
||||
end
|
||||
|
||||
compare_mask = get_mask_excl_fields(all_csrs[j], CsrExclWriteCheck, CsrAliasingTest,
|
||||
m_csr_excl_item);
|
||||
compare_mask = get_mask_excl_fields(all_csrs[j], CsrExclWriteCheck, CsrAliasingTest);
|
||||
csr_rd_check(.ptr (all_csrs[j]),
|
||||
.blocking (0),
|
||||
.compare (!external_checker),
|
||||
|
|
|
@ -14,7 +14,7 @@ package csr_utils_pkg;
|
|||
|
||||
// local types and variables
|
||||
uint outstanding_accesses = 0;
|
||||
uint default_timeout_ns = 1_000_000; // 1ms
|
||||
uint default_timeout_ns = 2_000_000; // 2ms
|
||||
uint default_spinwait_timeout_ns = 10_000_000; // 10ms
|
||||
string msg_id = "csr_utils";
|
||||
bit default_csr_blocking = 1;
|
||||
|
@ -540,7 +540,7 @@ package csr_utils_pkg;
|
|||
input bit compare_vs_ral = 1,
|
||||
input csr_excl_type_e csr_excl_type = CsrNoExcl,
|
||||
input csr_test_type_e csr_test_type = CsrRwTest,
|
||||
input csr_excl_item csr_excl_item = null);
|
||||
input csr_excl_item csr_excl_item = get_excl_item(csr));
|
||||
uvm_reg_data_t compare_mask;
|
||||
|
||||
// Check if parent block or register is excluded from read-check
|
||||
|
@ -730,10 +730,12 @@ package csr_utils_pkg;
|
|||
function automatic uvm_reg_data_t get_mask_excl_fields(uvm_reg csr,
|
||||
csr_excl_type_e csr_excl_type,
|
||||
csr_test_type_e csr_test_type,
|
||||
csr_excl_item m_csr_excl_item);
|
||||
csr_excl_item m_csr_excl_item =
|
||||
get_excl_item(csr));
|
||||
uvm_reg_field flds[$];
|
||||
csr.get_fields(flds);
|
||||
get_mask_excl_fields = '1;
|
||||
|
||||
if (m_csr_excl_item != null) begin
|
||||
foreach (flds[i]) begin
|
||||
if (m_csr_excl_item.is_excl(flds[i], csr_excl_type, csr_test_type)) begin
|
||||
|
@ -746,6 +748,20 @@ package csr_utils_pkg;
|
|||
end
|
||||
endfunction
|
||||
|
||||
function automatic csr_excl_item get_excl_item(uvm_object ptr);
|
||||
csr_field_t csr_or_fld;
|
||||
dv_base_reg_block blk;
|
||||
|
||||
csr_or_fld = decode_csr_or_field(ptr);
|
||||
`downcast(blk, csr_or_fld.csr.get_parent(), , , msg_id)
|
||||
|
||||
// csr_excl is at the highest level of reg block
|
||||
while (blk.csr_excl == null) begin
|
||||
`downcast(blk, blk.get_parent(), , , msg_id)
|
||||
`DV_CHECK_NE_FATAL(blk, null, "", msg_id)
|
||||
end
|
||||
return blk.csr_excl;
|
||||
endfunction
|
||||
// sources
|
||||
`include "csr_seq_lib.sv"
|
||||
|
||||
|
|
|
@ -342,7 +342,7 @@ class dv_base_reg extends uvm_reg;
|
|||
string parent_name = this.get_parent().get_name();
|
||||
|
||||
// block level alert name is input alert name from hjson
|
||||
if (parent_name == "ral") return update_err_alert_name;
|
||||
if (get_parent().get_parent() == null) return update_err_alert_name;
|
||||
|
||||
// top-level alert name is ${block_name} + alert name from hjson
|
||||
return ($sformatf("%0s_%0s", parent_name, update_err_alert_name));
|
||||
|
@ -360,7 +360,7 @@ class dv_base_reg extends uvm_reg;
|
|||
string parent_name = this.get_parent().get_name();
|
||||
|
||||
// block level alert name is input alert name from hjson
|
||||
if (parent_name == "ral") return storage_err_alert_name;
|
||||
if (get_parent().get_parent() == null) return storage_err_alert_name;
|
||||
|
||||
// top-level alert name is ${block_name} + alert name from hjson
|
||||
return ($sformatf("%0s_%0s", parent_name, storage_err_alert_name));
|
||||
|
|
|
@ -20,6 +20,9 @@ class dv_base_agent_cfg extends uvm_object;
|
|||
// use for phase_ready_to_end to add additional delay after ok_to_end is set
|
||||
int ok_to_end_delay_ns = 1000;
|
||||
|
||||
// Indicates that the interface is under reset. The derived monitor detects and maintains it.
|
||||
bit in_reset;
|
||||
|
||||
`uvm_object_utils_begin(dv_base_agent_cfg)
|
||||
`uvm_field_int (is_active, UVM_DEFAULT)
|
||||
`uvm_field_int (en_cov, UVM_DEFAULT)
|
||||
|
|
33
vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env.sv
vendored
33
vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env.sv
vendored
|
@ -16,17 +16,42 @@ class dv_base_env #(type CFG_T = dv_base_env_cfg,
|
|||
`uvm_component_new
|
||||
|
||||
virtual function void build_phase(uvm_phase phase);
|
||||
string default_ral_name;
|
||||
super.build_phase(phase);
|
||||
// get dv_base_env_cfg object from uvm_config_db
|
||||
if (!uvm_config_db#(CFG_T)::get(this, "", "cfg", cfg)) begin
|
||||
`uvm_fatal(`gfn, $sformatf("failed to get %s from uvm_config_db", cfg.get_type_name()))
|
||||
end
|
||||
|
||||
// get vifs
|
||||
if (!uvm_config_db#(virtual clk_rst_if)::get(this, "", "clk_rst_vif", cfg.clk_rst_vif)) begin
|
||||
`uvm_fatal(get_full_name(), "failed to get clk_rst_if from uvm_config_db")
|
||||
// get vifs for RAL models
|
||||
if (cfg.ral_model_names.size > 0) begin
|
||||
default_ral_name = cfg.ral.get_type_name();
|
||||
foreach (cfg.ral_model_names[i]) begin
|
||||
string ral_name = cfg.ral_model_names[i];
|
||||
string if_name;
|
||||
|
||||
if (ral_name == default_ral_name) if_name = "clk_rst_vif";
|
||||
else if_name = {"clk_rst_vif_", ral_name};
|
||||
if (!uvm_config_db#(virtual clk_rst_if)::get(this, "", if_name,
|
||||
cfg.clk_rst_vifs[ral_name])) begin
|
||||
`uvm_fatal(`gfn, $sformatf("failed to get clk_rst_if for %0s from uvm_config_db", ral_name))
|
||||
end
|
||||
cfg.clk_rst_vifs[ral_name].set_freq_mhz(cfg.clk_freqs_mhz[ral_name]);
|
||||
end
|
||||
|
||||
// assign default clk_rst_vif
|
||||
`DV_CHECK_FATAL(cfg.clk_rst_vifs.exists(default_ral_name))
|
||||
cfg.clk_rst_vif = cfg.clk_rst_vifs[default_ral_name];
|
||||
end else begin
|
||||
// no RAL model, get the default clk_rst_vif for the block
|
||||
// such as xbar, it doesn't has ral model, but it also needs a default clk_rst_vif
|
||||
if (!uvm_config_db#(virtual clk_rst_if)::get(this, "", "clk_rst_vif", cfg.clk_rst_vif))
|
||||
begin
|
||||
`uvm_fatal(`gfn, "failed to get clk_rst_if from uvm_config_db")
|
||||
end
|
||||
cfg.clk_rst_vif.set_freq_mhz(cfg.clk_freq_mhz);
|
||||
end
|
||||
cfg.clk_rst_vif.set_freq_mhz(cfg.clk_freq_mhz);
|
||||
|
||||
|
||||
// create components
|
||||
if (cfg.en_cov) begin
|
||||
|
|
111
vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env_cfg.sv
vendored
111
vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_env_cfg.sv
vendored
|
@ -9,7 +9,7 @@ class dv_base_env_cfg #(type RAL_T = dv_base_reg_block) extends uvm_object;
|
|||
bit en_scb_tl_err_chk = 1;
|
||||
bit en_scb_mem_chk = 1;
|
||||
bit en_cov = 0; // Enable via plusarg, only if coverage collection is turned on.
|
||||
bit has_ral = 1;
|
||||
|
||||
bit under_reset = 0;
|
||||
bit is_initialized; // Indicates that the initialize() method has been called.
|
||||
|
||||
|
@ -29,20 +29,31 @@ class dv_base_env_cfg #(type RAL_T = dv_base_reg_block) extends uvm_object;
|
|||
|
||||
// reg model & q of valid csr addresses
|
||||
RAL_T ral;
|
||||
dv_base_reg_block ral_models[$];
|
||||
bit [bus_params_pkg::BUS_AW-1:0] csr_addrs[$];
|
||||
addr_range_t mem_ranges[$];
|
||||
dv_base_reg_block ral_models[string];
|
||||
// A queue of the names of RAL models that should be created in the `initialize` function
|
||||
// Related agents, adapters will be created in env as well as connecting them with scb
|
||||
// For example, if the IP has an additional RAL model named `ral1`, add it into the list as below
|
||||
// virtual function void initialize(bit [TL_AW-1:0] csr_base_addr = '1);
|
||||
// ral_model_names.push_back("ral1");
|
||||
// super.initialize(csr_base_addr);
|
||||
string ral_model_names[$] = {RAL_T::type_name};
|
||||
|
||||
bit [bus_params_pkg::BUS_AW-1:0] csr_addrs[string][$];
|
||||
addr_range_t mem_ranges[string][$];
|
||||
|
||||
// clk_rst_if & freq
|
||||
// clk_rst_vif and clk_freq_mhz are used for default clk/rst. If more than one RAL, the other
|
||||
// clk_rst_vif and clk_freq_mhz can be found from the associative arrays
|
||||
virtual clk_rst_if clk_rst_vif;
|
||||
virtual clk_rst_if clk_rst_vifs[string];
|
||||
rand clk_freq_mhz_e clk_freq_mhz;
|
||||
rand clk_freq_mhz_e clk_freqs_mhz[string];
|
||||
|
||||
`uvm_object_param_utils_begin(dv_base_env_cfg #(RAL_T))
|
||||
`uvm_field_int (is_active, UVM_DEFAULT)
|
||||
`uvm_field_int (en_scb, UVM_DEFAULT)
|
||||
`uvm_field_int (en_cov, UVM_DEFAULT)
|
||||
`uvm_field_int (zero_delays, UVM_DEFAULT)
|
||||
`uvm_field_enum (clk_freq_mhz_e, clk_freq_mhz, UVM_DEFAULT)
|
||||
`uvm_object_utils_end
|
||||
|
||||
`uvm_object_new
|
||||
|
@ -51,36 +62,22 @@ class dv_base_env_cfg #(type RAL_T = dv_base_reg_block) extends uvm_object;
|
|||
`DV_CHECK_FATAL(is_initialized, "Please invoke initialize() before randomizing this object.")
|
||||
endfunction
|
||||
|
||||
function void post_randomize();
|
||||
if (clk_freqs_mhz.size > 0) begin
|
||||
`DV_CHECK_FATAL(clk_freqs_mhz.exists(RAL_T::type_name))
|
||||
clk_freqs_mhz[RAL_T::type_name] = clk_freq_mhz;
|
||||
end
|
||||
endfunction
|
||||
|
||||
virtual function void initialize(bit [bus_params_pkg::BUS_AW-1:0] csr_base_addr = '1);
|
||||
is_initialized = 1'b1;
|
||||
|
||||
// build the ral model
|
||||
if (has_ral) begin
|
||||
uvm_reg_addr_t base_addr;
|
||||
create_ral_models(csr_base_addr);
|
||||
|
||||
ral = RAL_T::type_id::create("ral");
|
||||
|
||||
// Build the register block with an arbitrary base address (we choose 0). We'll change it
|
||||
// later.
|
||||
ral.build(.base_addr(0), .csr_excl(null));
|
||||
apply_ral_fixes();
|
||||
ral.lock_model();
|
||||
|
||||
// Now the model is locked, we know its layout. Set the base address for the register block.
|
||||
// The function internally picks a random one if we pass '1 to it, and performs an integrity
|
||||
// check on the set address.
|
||||
//
|
||||
// The definition of base_addr explicitly casts from a bus address to a uvm_reg_addr_t (to
|
||||
// correctly handle the case where a bus address is narrower than a uvm_reg_addr_t).
|
||||
base_addr = (&csr_base_addr ?
|
||||
{`UVM_REG_ADDR_WIDTH{1'b1}} :
|
||||
{{(`UVM_REG_ADDR_WIDTH - bus_params_pkg::BUS_AW){1'b0}}, csr_base_addr});
|
||||
ral.set_base_addr(base_addr);
|
||||
|
||||
// Get list of valid csr addresses (useful in seq to randomize addr as well as in scb checks)
|
||||
get_csr_addrs(ral, csr_addrs);
|
||||
get_mem_addr_ranges(ral, mem_ranges);
|
||||
ral_models.push_back(ral);
|
||||
// add items to clk_freqs_mhz before randomizing it
|
||||
foreach (ral_model_names[i]) begin
|
||||
clk_freqs_mhz[ral_model_names[i]] = ClkFreq24Mhz;
|
||||
end
|
||||
endfunction
|
||||
|
||||
|
@ -100,4 +97,58 @@ class dv_base_env_cfg #(type RAL_T = dv_base_reg_block) extends uvm_object;
|
|||
csr_utils_pkg::reset_deasserted();
|
||||
endfunction
|
||||
|
||||
virtual function void create_ral_models(bit [bus_params_pkg::BUS_AW-1:0] csr_base_addr = '1);
|
||||
foreach (ral_model_names[i]) begin
|
||||
string ral_name = ral_model_names[i];
|
||||
uvm_reg_addr_t base_addr;
|
||||
dv_base_reg_block reg_blk = create_ral_by_name(ral_name);
|
||||
|
||||
if (reg_blk.get_name() == RAL_T::type_name) `downcast(ral, reg_blk)
|
||||
|
||||
// Build the register block with an arbitrary base address (we choose 0). We'll change it
|
||||
// later.
|
||||
reg_blk.build(.base_addr(0), .csr_excl(null));
|
||||
apply_ral_fixes();
|
||||
reg_blk.lock_model();
|
||||
|
||||
// Now the model is locked, we know its layout. Set the base address for the register block.
|
||||
// The function internally picks a random one if we pass '1 to it, and performs an integrity
|
||||
// check on the set address.
|
||||
//
|
||||
// The definition of base_addr explicitly casts from a bus address to a uvm_reg_addr_t (to
|
||||
// correctly handle the case where a bus address is narrower than a uvm_reg_addr_t).
|
||||
base_addr = (&csr_base_addr ?
|
||||
{`UVM_REG_ADDR_WIDTH{1'b1}} :
|
||||
{{(`UVM_REG_ADDR_WIDTH - bus_params_pkg::BUS_AW){1'b0}}, csr_base_addr});
|
||||
reg_blk.set_base_addr(base_addr);
|
||||
|
||||
// Get list of valid csr addresses (useful in seq to randomize addr as well as in scb checks)
|
||||
get_csr_addrs(reg_blk, csr_addrs[ral_name]);
|
||||
get_mem_addr_ranges(reg_blk, mem_ranges[ral_name]);
|
||||
ral_models[ral_name] = reg_blk;
|
||||
end
|
||||
|
||||
if (ral_model_names.size > 0) begin
|
||||
`DV_CHECK_FATAL(ral_models.exists(RAL_T::type_name))
|
||||
end
|
||||
endfunction
|
||||
|
||||
virtual function dv_base_reg_block create_ral_by_name(string name);
|
||||
uvm_object obj;
|
||||
uvm_factory factory;
|
||||
dv_base_reg_block ral;
|
||||
|
||||
factory = uvm_factory::get();
|
||||
obj = factory.create_object_by_name(.requested_type_name(name), .name(name));
|
||||
if (obj == null) begin
|
||||
// print factory overrides to help debug
|
||||
factory.print();
|
||||
`uvm_fatal(msg_id, $sformatf("could not create %0s as a RAL model, see above for a list of \
|
||||
type/instance overrides", name))
|
||||
end
|
||||
if (!$cast(ral, obj)) begin
|
||||
`uvm_fatal(msg_id, $sformatf("cast failed - %0s is not a dv_base_reg_block", name))
|
||||
end
|
||||
return ral;
|
||||
endfunction
|
||||
endclass
|
||||
|
|
|
@ -50,9 +50,7 @@ class dv_base_scoreboard #(type RAL_T = dv_base_reg_block,
|
|||
|
||||
virtual function void reset(string kind = "HARD");
|
||||
// reset the ral model
|
||||
if (cfg.has_ral) begin
|
||||
foreach (cfg.ral_models[i]) cfg.ral_models[i].reset(kind);
|
||||
end
|
||||
foreach (cfg.ral_models[i]) cfg.ral_models[i].reset(kind);
|
||||
endfunction
|
||||
|
||||
virtual function void pre_abort();
|
||||
|
|
51
vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_vseq.sv
vendored
51
vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_vseq.sv
vendored
|
@ -86,8 +86,22 @@ class dv_base_vseq #(type RAL_T = dv_base_reg_block,
|
|||
|
||||
virtual task apply_reset(string kind = "HARD");
|
||||
if (kind == "HARD") begin
|
||||
cfg.clk_rst_vif.apply_reset();
|
||||
end
|
||||
if (cfg.clk_rst_vifs.size > 0) begin
|
||||
fork
|
||||
begin : isolation_fork
|
||||
foreach (cfg.clk_rst_vifs[i]) begin
|
||||
automatic string ral_name = i;
|
||||
fork
|
||||
cfg.clk_rst_vifs[ral_name].apply_reset();
|
||||
join_none
|
||||
end
|
||||
wait fork;
|
||||
end : isolation_fork
|
||||
join
|
||||
end else begin // no ral model and only has default clk_rst_vif
|
||||
cfg.clk_rst_vif.apply_reset();
|
||||
end
|
||||
end // if (kind == "HARD")
|
||||
endtask
|
||||
|
||||
virtual task wait_for_reset(string reset_kind = "HARD",
|
||||
|
@ -109,62 +123,37 @@ class dv_base_vseq #(type RAL_T = dv_base_reg_block,
|
|||
csr_utils_pkg::wait_no_outstanding_access();
|
||||
endtask
|
||||
|
||||
// function to add csr exclusions of the given type using the csr_excl_item item
|
||||
// arg csr_test_type: this the the type of csr test run - we may want additional exclusions
|
||||
// depending on what test seq we are running
|
||||
// arg csr_excl: this is the csr exclusion object that maintains the list of exclusions
|
||||
// the same object handle is to be passed to csr sequences in csr_seq_lib so that they can query
|
||||
// those exclusions
|
||||
virtual function void add_csr_exclusions(string csr_test_type,
|
||||
csr_excl_item csr_excl,
|
||||
string scope = "ral");
|
||||
`uvm_info(`gfn, "no exclusion item added from this function", UVM_DEBUG)
|
||||
endfunction
|
||||
|
||||
// TODO: temp support, can delete this once all IPs update their exclusion in hjson
|
||||
virtual function csr_excl_item add_and_return_csr_excl(string csr_test_type);
|
||||
add_csr_exclusions(csr_test_type, ral.csr_excl);
|
||||
ral.csr_excl.print_exclusions();
|
||||
return ral.csr_excl;
|
||||
endfunction
|
||||
|
||||
// wrapper task around run_csr_vseq - the purpose is to be able to call this directly for actual
|
||||
// csr tests (as opposed to higher level stress test that could also run csr seq as a fork by
|
||||
// calling run_csr_vseq(..) task)
|
||||
virtual task run_csr_vseq_wrapper(int num_times = 1);
|
||||
string csr_test_type;
|
||||
csr_excl_item csr_excl;
|
||||
|
||||
// env needs to have a ral instance
|
||||
`DV_CHECK_EQ_FATAL(cfg.has_ral, 1'b1)
|
||||
`DV_CHECK_GE_FATAL(cfg.ral_models.size(), 1)
|
||||
|
||||
// get csr_test_type from plusarg
|
||||
void'($value$plusargs("csr_%0s", csr_test_type));
|
||||
|
||||
// create csr exclusions before running the csr seq
|
||||
csr_excl = add_and_return_csr_excl(csr_test_type);
|
||||
|
||||
// run the csr seq
|
||||
for (int i = 1; i <= num_times; i++) begin
|
||||
`uvm_info(`gfn, $sformatf("running csr %0s vseq iteration %0d/%0d",
|
||||
csr_test_type, i, num_times), UVM_LOW)
|
||||
run_csr_vseq(.csr_test_type(csr_test_type), .csr_excl(csr_excl));
|
||||
run_csr_vseq(.csr_test_type(csr_test_type));
|
||||
end
|
||||
endtask
|
||||
|
||||
// capture the entire csr seq as a task that can be overridden if desired
|
||||
// arg csr_test_type: what csr test to run {hw_reset, rw, bit_bash, aliasing}
|
||||
// arg csr_excl: csr exclusion object - needs to be created and exclusions set before call
|
||||
// arg num_test_csrs:instead of testing the entire ral model or passing test chunk info via
|
||||
// plusarg, provide ability to set a random number of csrs to test from higher level sequence
|
||||
virtual task run_csr_vseq(string csr_test_type = "",
|
||||
csr_excl_item csr_excl = null,
|
||||
int num_test_csrs = 0,
|
||||
bit do_rand_wr_and_reset = 1);
|
||||
csr_base_seq m_csr_seq;
|
||||
|
||||
// env needs to have a ral instance
|
||||
`DV_CHECK_EQ_FATAL(cfg.has_ral, 1'b1)
|
||||
`DV_CHECK_GE_FATAL(cfg.ral_models.size(), 1)
|
||||
|
||||
// check which csr test type
|
||||
case (csr_test_type)
|
||||
|
@ -193,7 +182,6 @@ class dv_base_vseq #(type RAL_T = dv_base_reg_block,
|
|||
m_csr_write_seq.models = cfg.ral_models;
|
||||
m_csr_write_seq.external_checker = cfg.en_scb;
|
||||
m_csr_write_seq.en_rand_backdoor_write = 1'b1;
|
||||
m_csr_write_seq.set_csr_excl_item(csr_excl);
|
||||
m_csr_write_seq.start(null);
|
||||
|
||||
// run dut_shutdown before asserting reset
|
||||
|
@ -211,7 +199,6 @@ class dv_base_vseq #(type RAL_T = dv_base_reg_block,
|
|||
m_csr_seq.models = cfg.ral_models;
|
||||
m_csr_seq.external_checker = cfg.en_scb;
|
||||
m_csr_seq.num_test_csrs = num_test_csrs;
|
||||
m_csr_seq.set_csr_excl_item(csr_excl);
|
||||
m_csr_seq.start(null);
|
||||
endtask
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@
|
|||
`define DV_PRINT_ARR_CONTENTS(ARR_, V_=uvm_pkg::UVM_MEDIUM, ID_=`gfn) \
|
||||
begin \
|
||||
foreach (ARR_[i]) begin \
|
||||
`dv_info($sformatf("%s[%0d] = 0x%0d[0x%0h]", `"ARR_`", i, ARR_[i], ARR_[i]), V_, ID_) \
|
||||
`dv_info($sformatf("%s[%0d] = %0d (0x%0h)", `"ARR_`", i, ARR_[i], ARR_[i]), V_, ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
|
|
@ -18,8 +18,7 @@ package dv_test_status_pkg;
|
|||
$display(" | | __/\\__ \\ |_ | |_) | (_| \\__ \\__ \\ __/ (_| |_|");
|
||||
$display(" |_|\\___||___/\\__| | .__/ \\__,_|___/___/\\___|\\__,_(_)");
|
||||
$display(" |_| \n");
|
||||
end
|
||||
else begin
|
||||
end else begin
|
||||
$display("\nTEST FAILED CHECKS");
|
||||
$display(" _____ _ __ _ _ _ _ ");
|
||||
$display("|_ _|__ ___| |_ / _| __ _(_) | ___ __| | |");
|
||||
|
|
|
@ -74,8 +74,8 @@ class mem_model #(int AddrWidth = bus_params_pkg::BUS_AW,
|
|||
if (mask[0]) begin
|
||||
compare_byte(addr + i, byte_data);
|
||||
end else begin
|
||||
`DV_CHECK_EQ(byte_data, 0,
|
||||
$sformatf("addr 0x%0h masked data aren't 0, mask 0x%0h", addr, mask))
|
||||
// Nothing to do here: since this byte wasn't selected by the mask, there are no
|
||||
// requirements about what data came back.
|
||||
end
|
||||
act_data = act_data>> 8;
|
||||
mask = mask >> 1;
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
"^UVM_WARNING\\s[^:].*$",
|
||||
"^Assert failed: ",
|
||||
"^\\s*Offending '.*'",
|
||||
"^TEST FAILED (UVM_)?CHECKS$"]
|
||||
"^TEST FAILED (UVM_)?CHECKS$",
|
||||
"^Error:.*$"] // ISS errors
|
||||
|
||||
// Default TileLink widths
|
||||
tl_aw: 32
|
||||
|
|
|
@ -2,14 +2,18 @@
|
|||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Exclude below TL toggle coverage as these pins won't be changed in the comportable IPs
|
||||
// Exclude below TL toggle coverage as these pins won't be changed in the comportable IPs.
|
||||
|
||||
// Exclude alert_sender as it is fully verified in FPV. Note that user might also need to exclude
|
||||
// prim_diff_decode module, but it is not listed here because modules other than prim_alert_sender
|
||||
// might instantiate this prim_diff_decode as well.
|
||||
|
||||
INSTANCE: tb.dut
|
||||
Toggle tl_i.a_user.parity "logic tl_i.a_user.parity[7:0]"
|
||||
Toggle tl_i.a_user.parity_en "logic tl_i.a_user.parity_en"
|
||||
Toggle tl_i.a_user.rsvd1 "logic tl_i.a_user.rsvd1[6:0]"
|
||||
Toggle tl_o.d_opcode [1] "logic tl_o.d_opcode[2:0]"
|
||||
Toggle tl_o.d_opcode [2] "logic tl_o.d_opcode[2:0]"
|
||||
Toggle tl_o.d_param "logic tl_o.d_param[2:0]"
|
||||
Toggle tl_o.d_sink "logic tl_o.d_sink[0:0]"
|
||||
Toggle tl_o.d_user "logic tl_o.d_user[15:0]"
|
||||
Toggle tl_i.a_param "logic tl_i.a_param[2:0]"
|
||||
// TODO: revisit after issue #6089 is implemented
|
||||
ANNOTATION: "[EXTERNAL] alert_sender is fully verified by FPV testbench."
|
||||
MODULE:prim_alert_sender
|
||||
|
|
4
vendor/lowrisc_ip/dv/tools/waves.tcl
vendored
4
vendor/lowrisc_ip/dv/tools/waves.tcl
vendored
|
@ -110,7 +110,7 @@ proc wavedumpScope {scope fid {depth 0} {fsdb_flags "+all"} {probe_flags "-all"
|
|||
if {$depth == 0} {
|
||||
set depth "all"
|
||||
}
|
||||
probe "$scope" $probe_flags -depth $depth -shm
|
||||
probe "$scope" $probe_flags -depth $depth -memories -shm
|
||||
}
|
||||
|
||||
"vpd" {
|
||||
|
@ -124,7 +124,7 @@ proc wavedumpScope {scope fid {depth 0} {fsdb_flags "+all"} {probe_flags "-all"
|
|||
if {$depth == 0} {
|
||||
set depth "all"
|
||||
}
|
||||
probe "$scope" $probe_flags -depth $depth -vcd
|
||||
probe "$scope" $probe_flags -depth $depth -memories -vcd
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue