mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-24 13:57:19 -04:00
Update lowrisc_ip to lowRISC/opentitan@c277e3a8
Update code from upstream repository https://github.com/lowRISC/opentitan to revision 7e131447da6d5f3044666a17974e15df44f0328b Updates to Ibex code to match this import: * Include str_utils in the imported code. * List new source files in dv/uvm/core_ibex/ibex_dv.f * Update patches to resolve merge conflicts. * Update tb_cs_registers.cc and ibex_riscv_compliance.cc to match the new return code of simctrl.Exec(). Imported updates: * Do not require pyyaml >= 5.1 (Philipp Wagner) * [prim_edn_req] Forward fips signal to consumer (Pirmin Vogel) * [prim_edn_req] Use prim_sync_reqack_data primitive (Pirmin Vogel) * [prim_edn_req] De-assert EDN request if packer FIFO has data available (Pirmin Vogel) * [cleanup] Mass replace tabs with spaces (Srikrishna Iyer) * [lc_ctrl] Add script to generate the LC state based on the ECC poly (Michael Schaffner) * [dvsim] Use list for rsync command (Eunchan Kim) * [verilator] Only control the reset line when necessary (Rupert Swarbrick) * [dv/csr_utils] Add debug msg for UVM_NOT_OK err (Cindy Chen) * [dvsim] Add exclude hidden files when needed (Eunchan Kim) * [prim_sync_reqack] Add variant with associated data and optional data reg (Pirmin Vogel) * [DV, Xcelium] Fix for lowRISC/opentitan#4690 (Srikrishna Iyer) * [dvsim] Remote copy update (Srikrishna Iyer) * [prim_edn_req] Add EDN sync and packer gadget primitive (Michael Schaffner) * [prim] Add hamming code as ECC option (Timothy Chen) * [DV] Cleanup lint warnings with Verible lint (¨Srikrishna) * [prim_ram] Rearrange parity bit packing and fix wrong wmask settings (Michael Schaffner) * [lc_sync/lc_sender] Absorb flops within lc_sender (Michael Schaffner) * [prim_otp_pkg] Move prim interface constants into separate package (Michael Schaffner) * [sram_ctrl] Pull scr macro out of sram_ctrl (Michael Schaffner) * [top] Move alert handler to periphs and attach escalation clock to ibex (Michael Schaffner) * [prim_esc_rxtx/rv_core_ibex] Add default values and NMI synchronization (Michael Schaffner) * [dvsim] Fix regression publish result link with --remote switch (Cindy Chen) * [vendor/ibex] Remove duplicate check tool requirements files (Michael Schaffner) * [prim_ram_1p_scr] Fix sequencing bug in scrambling logic (Michael Schaffner) * [prim_ram*_adv] Qualify error output signals with rvalid (Michael Schaffner) * [dvsim] Fix purge not delete remote repo_top (Cindy Chen) * [lc/otp/alerts] Place size-only buffers on all multibit signals (Michael Schaffner) * [prim_buf] Add generic and Xilinx buffer primitive (Michael Schaffner) * [prim] Packer to add byte hint assertion (Eunchan Kim) * [dvsim] Logic to copy repo to scratch area (Srikrishna Iyer) * [dv/lc_ctrl] enable lc_ctrl alert_test (Cindy Chen) * [prim] documentation update for flash (Timothy Chen) * [flash_ctrl] Add additional interface support (Timothy Chen) * [dvsim] Fix publish report path (Weicai Yang) * [top_earlgrey] Instantiate LC controller in toplevel (Michael Schaffner) * [doc] Fix checklist items in V1 (Michael Schaffner) * [dv/csr_excl] Fix VCS warning (Cindy Chen) * [dv/doc] cleaned up checkist alignment (Rasmus Madsen) * [doc/dv] cleanup (Rasmus Madsen) * [dv/doc] updated dv_plan links to new location (Rasmus Madsen) * [dv/doc] changed testplan to dv_plan in markdown files (Rasmus Madsen) * [dv/doc] changed dv plan to dv doc (Rasmus Madsen) * Remove redundant ascentlint options (Olof Kindgren) * Add ascentlint default options for all cores depending on lint:common (Olof Kindgren) * [flash] documentation update (Timothy Chen) * [flash / top] Add info_sel to flash interface (Timothy Chen) * [otp] lci interface assertion related fix (Cindy Chen) * [dv/uvmdvgen] Add switch to auto-gen edn (Cindy Chen) * [util] Rejig how we load hjson configurations for dvsim.py (Rupert Swarbrick) * added changes required by sriyerg (Dawid Zimonczyk) * update riviera.hjson (Dawid Zimonczyk) * [flash_ctrl] Add high endurance region attribute (Timothy Chen) * Change VerilatorSimCtrl::Exec to handle --help properly (Rupert Swarbrick) * Simplify handling of exit_app in VerilatorSimCtrl::ParseCommandArgs (Rupert Swarbrick) * [sram_ctrl] Rtl lint fix (Michael Schaffner) * [keymgr] Add edn support (Timothy Chen) * [dv] Make width conversion explicit in dv_base_env_cfg::initialize (Rupert Swarbrick) * [dvsim] Allow dvsim.py to be run under Make (Rupert Swarbrick) * [dvsim[ rename revision_string to revision (Srikrishna Iyer) * [dvsim] Update log messages (Srikrishna Iyer) * [dvsim] fix for full verbosity (Srikrishna Iyer) * [dv] Fix Questa warning and remove unused var (Weicai Yang) * [dvsim] Add alias for --run-only (Weicai Yang) * [keymgr] Hook-up random compile time constants (Timothy Chen) * [dvsim] Add support for UVM_FULL over cmd line (Srikrishna Iyer) * [dv common] Enable DV macros in non-UVM components (Srikrishna Iyer) * [DVsim] Add support for Verilator (Srikrishna Iyer) * [DVSim] Fix how sw_images is treated (Srikrishna Iyer) * [DV common] Fixes in sim.mk for Verilator (Srikrishna Iyer) * [DV Common] Split DV test status reporting logic (Srikrishna Iyer) * [prim_arbiter_ppc] Fix lint error (Philipp Wagner) * [DV common] Factor `sim_tops` out of build_opts (Srikrishna Iyer) * [dvsim] run yapf to fix style (Weicai Yang) * [dv/common] VCS UNR flow (Weicai Yang) * [dv] Add get_max_offset function in dv_base_reg_block (Weicai Yang) * [otp_ctrl] Fix warnings from VCS (Cindy Chen) * [lint] Change unused_ waiver (Eunchan Kim) * [dv/alert_test] Add alert_test IP level automation test (Cindy Chen) * [DV] Update the was SW is built for DV (Srikrishna Iyer) * [dvsim] Replace `sw_test` with `sw_images` (Srikrishna Iyer) * [chip dv] Move sw build directory (Srikrishna Iyer) * [dv common] Update dv_utils to use str_utils_pkg (Srikrishna Iyer) * [DVSim] Method to add pre/post build/run steps (Srikrishna Iyer) Signed-off-by: Philipp Wagner <phw@lowrisc.org>
This commit is contained in:
parent
0199bbae66
commit
b1daf9e44e
112 changed files with 3412 additions and 1247 deletions
|
@ -72,7 +72,7 @@ interface pins_if #(
|
|||
endfunction
|
||||
|
||||
// make connections
|
||||
for (genvar i = 0; i < Width; i++) begin : each_pin
|
||||
for (genvar i = 0; i < Width; i++) begin : gen_each_pin
|
||||
`ifdef VERILATOR
|
||||
assign pins[i] = pins_oe[i] ? pins_o[i] :
|
||||
pins_pu[i] ? 1'b1 :
|
||||
|
@ -91,7 +91,7 @@ interface pins_if #(
|
|||
// between 'value to be driven out' and the external driver's value.
|
||||
assign pins[i] = pins_oe[i] ? pins_o[i] : 1'bz;
|
||||
`endif
|
||||
end
|
||||
end : gen_each_pin
|
||||
|
||||
endinterface
|
||||
`endif
|
||||
|
|
|
@ -213,7 +213,9 @@ package csr_utils_pkg;
|
|||
// when reset occurs, all items will be dropped immediately. This may end up getting
|
||||
// d_error = 1 from previous item on the bus. Skip checking it during reset
|
||||
if (check == UVM_CHECK && !under_reset) begin
|
||||
`DV_CHECK_EQ(status, UVM_IS_OK, "", error, msg_id)
|
||||
`DV_CHECK_EQ(status, UVM_IS_OK,
|
||||
$sformatf("trying to update csr %0s", csr.get_full_name()),
|
||||
error, msg_id)
|
||||
end
|
||||
decrement_outstanding_access();
|
||||
end
|
||||
|
@ -274,7 +276,9 @@ package csr_utils_pkg;
|
|||
csr.write(.status(status), .value(value), .path(path), .map(map), .prior(100));
|
||||
csr_post_write_sub(csr, en_shadow_wr);
|
||||
if (check == UVM_CHECK && !under_reset) begin
|
||||
`DV_CHECK_EQ(status, UVM_IS_OK, "", error, msg_id)
|
||||
`DV_CHECK_EQ(status, UVM_IS_OK,
|
||||
$sformatf("trying to write csr %0s", csr.get_full_name()),
|
||||
error, msg_id)
|
||||
end
|
||||
// Only update the predicted value if status is ok (otherwise the write isn't completed
|
||||
// successfully and the design shouldn't have accepted the written value)
|
||||
|
@ -397,7 +401,9 @@ package csr_utils_pkg;
|
|||
.prior(100));
|
||||
end
|
||||
if (check == UVM_CHECK && !under_reset) begin
|
||||
`DV_CHECK_EQ(status, UVM_IS_OK, "", error, msg_id)
|
||||
`DV_CHECK_EQ(status, UVM_IS_OK,
|
||||
$sformatf("trying to read csr/field %0s", ptr.get_full_name()),
|
||||
error, msg_id)
|
||||
end
|
||||
decrement_outstanding_access();
|
||||
end
|
||||
|
@ -630,7 +636,8 @@ package csr_utils_pkg;
|
|||
increment_outstanding_access();
|
||||
ptr.read(.status(status), .offset(offset), .value(data), .map(map), .prior(100));
|
||||
if (check == UVM_CHECK && !under_reset) begin
|
||||
`DV_CHECK_EQ(status, UVM_IS_OK, "", error, msg_id)
|
||||
`DV_CHECK_EQ(status, UVM_IS_OK,
|
||||
$sformatf("trying to read mem %0s", ptr.get_full_name()), error, msg_id)
|
||||
end
|
||||
decrement_outstanding_access();
|
||||
end
|
||||
|
@ -679,7 +686,9 @@ package csr_utils_pkg;
|
|||
increment_outstanding_access();
|
||||
ptr.write(.status(status), .offset(offset), .value(data), .map(map), .prior(100));
|
||||
if (check == UVM_CHECK && !under_reset) begin
|
||||
`DV_CHECK_EQ(status, UVM_IS_OK, "", error, msg_id)
|
||||
`DV_CHECK_EQ(status, UVM_IS_OK,
|
||||
$sformatf("trying to write mem %0s", ptr.get_full_name()),
|
||||
error, msg_id)
|
||||
end
|
||||
decrement_outstanding_access();
|
||||
end
|
||||
|
|
|
@ -27,10 +27,12 @@ class csr_excl_item extends uvm_object;
|
|||
csr_test_type_e csr_test_type = CsrAllTests);
|
||||
bit [2:0] val = CsrNoExcl;
|
||||
bit [NUM_CSR_TESTS-1:0] test = CsrInvalidTest;
|
||||
csr_excl_s csr_excl_item;
|
||||
|
||||
if (csr_test_type == CsrInvalidTest) begin
|
||||
`uvm_fatal(`gfn, $sformatf("add %s exclusion without a test", obj))
|
||||
end
|
||||
|
||||
if (!exclusions.exists(obj)) exclusions[obj] = '{default:CsrNoExcl};
|
||||
val = csr_excl_type | exclusions[obj].csr_excl_type;
|
||||
test = csr_test_type | exclusions[obj].csr_test_type;
|
||||
exclusions[obj].csr_excl_type = csr_excl_type_e'(val);
|
||||
|
|
|
@ -78,10 +78,8 @@ class dv_base_reg_block extends uvm_reg_block;
|
|||
// Use below to get the addr map size #3317
|
||||
// max2(biggest_reg_offset+reg_size, biggest_mem_offset+mem_size) and then round up to 2**N
|
||||
protected function void compute_addr_mask(uvm_reg_map map);
|
||||
uvm_reg_addr_t max_addr, max_offset;
|
||||
uvm_reg_addr_t max_offset;
|
||||
uvm_reg_block blocks[$];
|
||||
uvm_reg regs[$];
|
||||
uvm_mem mems[$];
|
||||
int unsigned alignment;
|
||||
|
||||
// TODO: assume IP only contains 1 reg block, find a better way to handle chip-level and IP
|
||||
|
@ -92,26 +90,7 @@ class dv_base_reg_block extends uvm_reg_block;
|
|||
return;
|
||||
end
|
||||
|
||||
get_registers(regs);
|
||||
get_memories(mems);
|
||||
`DV_CHECK_GT_FATAL(regs.size() + mems.size(), 0)
|
||||
|
||||
// Walk the known registers and memories, calculating the largest byte address visible. Note
|
||||
// that the get_offset() calls will return absolute addresses, including any base address in the
|
||||
// default register map.
|
||||
max_addr = 0;
|
||||
foreach (regs[i]) begin
|
||||
max_addr = max2(regs[i].get_offset(map) + regs[i].get_n_bytes() - 1, max_addr);
|
||||
end
|
||||
|
||||
foreach (mems[i]) begin
|
||||
uvm_reg_addr_t mem_size;
|
||||
mem_size = mems[i].get_offset(.map(map)) + mems[i].get_size() * mems[i].get_n_bytes() - 1;
|
||||
max_addr = max2(mem_size, max_addr);
|
||||
end
|
||||
|
||||
// Subtract the base address in the default register map to get the maximum relative offset.
|
||||
max_offset = max_addr - map.get_base_addr();
|
||||
max_offset = get_max_offset(map);
|
||||
|
||||
// Set alignment to be ceil(log2(biggest_offset))
|
||||
alignment = 0;
|
||||
|
@ -131,6 +110,35 @@ class dv_base_reg_block extends uvm_reg_block;
|
|||
`DV_CHECK_FATAL(addr_mask[map])
|
||||
endfunction
|
||||
|
||||
// Return the offset of the highest byte contained in either a register or a memory
|
||||
function uvm_reg_addr_t get_max_offset(uvm_reg_map map = null);
|
||||
uvm_reg_addr_t max_offset;
|
||||
uvm_reg regs[$];
|
||||
uvm_mem mems[$];
|
||||
|
||||
if (map == null) map = get_default_map();
|
||||
|
||||
get_registers(regs);
|
||||
get_memories(mems);
|
||||
`DV_CHECK_GT_FATAL(regs.size() + mems.size(), 0)
|
||||
|
||||
// Walk the known registers and memories, calculating the largest byte address visible. Note
|
||||
// that the get_offset() calls will return absolute addresses, including any base address in the
|
||||
// specified register map.
|
||||
max_offset = 0;
|
||||
foreach (regs[i]) begin
|
||||
max_offset = max2(regs[i].get_offset(map) + regs[i].get_n_bytes() - 1, max_offset);
|
||||
end
|
||||
|
||||
foreach (mems[i]) begin
|
||||
uvm_reg_addr_t mem_size;
|
||||
mem_size = mems[i].get_offset(.map(map)) + mems[i].get_size() * mems[i].get_n_bytes() - 1;
|
||||
max_offset = max2(mem_size, max_offset);
|
||||
end
|
||||
|
||||
return max_offset;
|
||||
endfunction
|
||||
|
||||
// Get the address mask. This should only be called after locking the model (because it depends on
|
||||
// the layout of registers and memories in the block).
|
||||
function uvm_reg_addr_t get_addr_mask(uvm_reg_map map = null);
|
||||
|
|
|
@ -41,6 +41,8 @@ class dv_base_env_cfg #(type RAL_T = dv_base_reg_block) extends uvm_object;
|
|||
`uvm_object_new
|
||||
|
||||
virtual function void initialize(bit [bus_params_pkg::BUS_AW-1:0] csr_base_addr = '1);
|
||||
import bus_params_pkg::*;
|
||||
|
||||
// build the ral model
|
||||
if (has_ral) begin
|
||||
uvm_reg_addr_t base_addr;
|
||||
|
@ -56,7 +58,13 @@ class dv_base_env_cfg #(type RAL_T = dv_base_reg_block) extends uvm_object;
|
|||
// 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.
|
||||
ral.set_base_addr(csr_base_addr);
|
||||
//
|
||||
// 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_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);
|
||||
|
|
124
vendor/lowrisc_ip/dv/sv/dv_utils/dv_macros.svh
vendored
124
vendor/lowrisc_ip/dv/sv/dv_utils/dv_macros.svh
vendored
|
@ -11,8 +11,13 @@
|
|||
|
||||
// UVM speficic macros
|
||||
`ifndef gfn
|
||||
`ifdef UVM
|
||||
// verilog_lint: waive macro-name-style
|
||||
`define gfn get_full_name()
|
||||
`else
|
||||
// verilog_lint: waive macro-name-style
|
||||
`define gfn $sformatf("%m")
|
||||
`endif
|
||||
`endif
|
||||
|
||||
`ifndef gtn
|
||||
|
@ -37,9 +42,9 @@
|
|||
`define downcast(EXT_, BASE_, MSG_="", SEV_=fatal, ID_=`gfn) \
|
||||
begin \
|
||||
if (!$cast(EXT_, BASE_)) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf({"Cast failed: base class variable %0s ", \
|
||||
"does not hold extended class %0s handle %s"}, \
|
||||
`"BASE_`", `"EXT_`", MSG_)) \
|
||||
`dv_``SEV_($sformatf({"Cast failed: base class variable %0s ", \
|
||||
"does not hold extended class %0s handle %s"}, \
|
||||
`"BASE_`", `"EXT_`", MSG_), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -80,7 +85,7 @@
|
|||
`define DV_CHECK(T_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
begin \
|
||||
if (!(T_)) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed (%s) %s ", `"T_`", MSG_)) \
|
||||
`dv_``SEV_($sformatf("Check failed (%s) %s ", `"T_`", MSG_), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -89,8 +94,8 @@
|
|||
`define DV_CHECK_EQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
begin \
|
||||
if (!((ACT_) == (EXP_))) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed %s == %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_)) \
|
||||
`dv_``SEV_($sformatf("Check failed %s == %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -99,8 +104,8 @@
|
|||
`define DV_CHECK_NE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
begin \
|
||||
if (!((ACT_) != (EXP_))) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed %s != %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_)) \
|
||||
`dv_``SEV_($sformatf("Check failed %s != %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -109,8 +114,8 @@
|
|||
`define DV_CHECK_CASE_EQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
begin \
|
||||
if (!((ACT_) === (EXP_))) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed %s === %s (0x%0h [%0b] vs 0x%0h [%0b]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_)) \
|
||||
`dv_``SEV_($sformatf("Check failed %s === %s (0x%0h [%0b] vs 0x%0h [%0b]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -119,8 +124,8 @@
|
|||
`define DV_CHECK_CASE_NE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
begin \
|
||||
if (!((ACT_) !== (EXP_))) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed %s !== %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_)) \
|
||||
`dv_``SEV_($sformatf("Check failed %s !== %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -129,8 +134,8 @@
|
|||
`define DV_CHECK_LT(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
begin \
|
||||
if (!((ACT_) < (EXP_))) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed %s < %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_)) \
|
||||
`dv_``SEV_($sformatf("Check failed %s < %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -139,8 +144,8 @@
|
|||
`define DV_CHECK_GT(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
begin \
|
||||
if (!((ACT_) > (EXP_))) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed %s > %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_)) \
|
||||
`dv_``SEV_($sformatf("Check failed %s > %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -149,8 +154,8 @@
|
|||
`define DV_CHECK_LE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
begin \
|
||||
if (!((ACT_) <= (EXP_))) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed %s <= %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_)) \
|
||||
`dv_``SEV_($sformatf("Check failed %s <= %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -159,8 +164,8 @@
|
|||
`define DV_CHECK_GE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
begin \
|
||||
if (!((ACT_) >= (EXP_))) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed %s >= %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_)) \
|
||||
`dv_``SEV_($sformatf("Check failed %s >= %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \
|
||||
`"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -168,14 +173,14 @@
|
|||
`ifndef DV_CHECK_STREQ
|
||||
`define DV_CHECK_STREQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
if (!((ACT_) == (EXP_))) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed \"%s\" == \"%s\" %s", ACT_, EXP_, MSG_)); \
|
||||
`dv_``SEV_($sformatf("Check failed \"%s\" == \"%s\" %s", ACT_, EXP_, MSG_), ID_) \
|
||||
end
|
||||
`endif
|
||||
|
||||
`ifndef DV_CHECK_STRNE
|
||||
`define DV_CHECK_STRNE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
|
||||
if (!((ACT_) != (EXP_))) begin \
|
||||
`uvm_``SEV_(ID_, $sformatf("Check failed \"%s\" != \"%s\" %s", ACT_, EXP_, MSG_)); \
|
||||
`dv_``SEV_($sformatf("Check failed \"%s\" != \"%s\" %s", ACT_, EXP_, MSG_), ID_) \
|
||||
end
|
||||
`endif
|
||||
|
||||
|
@ -268,7 +273,7 @@
|
|||
`define DV_PRINT_ARR_CONTENTS(ARR_, V_=UVM_MEDIUM, ID_=`gfn) \
|
||||
begin \
|
||||
foreach (ARR_[i]) begin \
|
||||
`uvm_info(ID_, $sformatf("%s[%0d] = 0x%0d[0x%0h]", `"ARR_`", i, ARR_[i], ARR_[i]), V_) \
|
||||
`dv_info($sformatf("%s[%0d] = 0x%0d[0x%0h]", `"ARR_`", i, ARR_[i], ARR_[i]), V_, ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -280,7 +285,7 @@
|
|||
while (!FIFO_.is_empty()) begin \
|
||||
TYP_ item; \
|
||||
void'(FIFO_.try_get(item)); \
|
||||
`uvm_``SEV_(ID_, $sformatf("%s item uncompared:\n%s", `"FIFO_`", item.sprint())) \
|
||||
`dv_``SEV_($sformatf("%s item uncompared:\n%s", `"FIFO_`", item.sprint()), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -293,7 +298,7 @@
|
|||
while (!FIFO_[i].is_empty()) begin \
|
||||
TYP_ item; \
|
||||
void'(FIFO_[i].try_get(item)); \
|
||||
`uvm_``SEV_(ID_, $sformatf("%s[%0d] item uncompared:\n%s", `"FIFO_`", i, item.sprint())) \
|
||||
`dv_``SEV_($sformatf("%s[%0d] item uncompared:\n%s", `"FIFO_`", i, item.sprint()), ID_) \
|
||||
end \
|
||||
end \
|
||||
end
|
||||
|
@ -305,7 +310,7 @@
|
|||
begin \
|
||||
while (Q_.size() != 0) begin \
|
||||
TYP_ item = Q_.pop_front(); \
|
||||
`uvm_``SEV_(ID_, $sformatf("%s item uncompared:\n%s", `"Q_`", item.sprint())) \
|
||||
`dv_``SEV_($sformatf("%s item uncompared:\n%s", `"Q_`", item.sprint()), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -317,7 +322,7 @@
|
|||
foreach (Q_[i]) begin \
|
||||
while (Q_[i].size() != 0) begin \
|
||||
TYP_ item = Q_[i].pop_front(); \
|
||||
`uvm_``SEV_(ID_, $sformatf("%s[%0d] item uncompared:\n%s", `"Q_`", i, item.sprint())) \
|
||||
`dv_``SEV_($sformatf("%s[%0d] item uncompared:\n%s", `"Q_`", i, item.sprint()), ID_) \
|
||||
end \
|
||||
end \
|
||||
end
|
||||
|
@ -330,7 +335,7 @@
|
|||
while (MAILBOX_.num() != 0) begin \
|
||||
TYP_ item; \
|
||||
void'(MAILBOX_.try_get(item)); \
|
||||
`uvm_``SEV_(ID_, $sformatf("%s item uncompared:\n%s", `"MAILBOX_`", item.sprint())) \
|
||||
`dv_``SEV_($sformatf("%s item uncompared:\n%s", `"MAILBOX_`", item.sprint()), ID_) \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
@ -359,7 +364,7 @@
|
|||
begin \
|
||||
EXIT_ \
|
||||
if (MSG_ != "") begin \
|
||||
`uvm_info(ID_, MSG_, UVM_HIGH) \
|
||||
`dv_info(MSG_, UVM_HIGH, ID_) \
|
||||
end \
|
||||
end \
|
||||
join_any \
|
||||
|
@ -428,47 +433,64 @@
|
|||
// Macros for logging (info, warning, error and fatal severities).
|
||||
//
|
||||
// These are meant to be invoked in modules and interfaces that are shared between DV and Verilator
|
||||
// testbenches.
|
||||
// testbenches. We waive the lint requirement for these to be in uppercase, since they are
|
||||
// UVM-adjacent.
|
||||
`ifdef UVM
|
||||
`ifndef DV_INFO
|
||||
`define DV_INFO(MSG_, VERBOSITY_ = UVM_LOW, ID_ = $sformatf("%m")) \
|
||||
`uvm_info(ID_, MSG_, VERBOSITY_)
|
||||
`ifndef dv_info
|
||||
// verilog_lint: waive macro-name-style
|
||||
`define dv_info(MSG_, VERBOSITY_ = UVM_LOW, ID_ = $sformatf("%m")) \
|
||||
if (uvm_pkg::uvm_report_enabled(VERBOSITY_, uvm_pkg::UVM_INFO, ID_)) begin \
|
||||
uvm_pkg::uvm_report_info(ID_, MSG_, VERBOSITY_, `uvm_file, `uvm_line, "", 1); \
|
||||
end
|
||||
`endif
|
||||
|
||||
`ifndef DV_WARNING
|
||||
`define DV_WARNING(MSG_, ID_ = $sformatf("%m")) \
|
||||
`uvm_warning(ID_, MSG_)
|
||||
`ifndef dv_warning
|
||||
// verilog_lint: waive macro-name-style
|
||||
`define dv_warning(MSG_, ID_ = $sformatf("%m")) \
|
||||
if (uvm_pkg::uvm_report_enabled(uvm_pkg::UVM_NONE, uvm_pkg::UVM_WARNING, ID_)) begin \
|
||||
uvm_pkg::uvm_report_warning(ID_, MSG_, uvm_pkg::UVM_NONE, `uvm_file, `uvm_line, "", 1); \
|
||||
end
|
||||
`endif
|
||||
|
||||
`ifndef DV_ERROR
|
||||
`define DV_ERROR(MSG_, ID_ = $sformatf("%m")) \
|
||||
`uvm_error(ID_, MSG_)
|
||||
`ifndef dv_error
|
||||
// verilog_lint: waive macro-name-style
|
||||
`define dv_error(MSG_, ID_ = $sformatf("%m")) \
|
||||
if (uvm_pkg::uvm_report_enabled(uvm_pkg::UVM_NONE, uvm_pkg::UVM_ERROR, ID_)) begin \
|
||||
uvm_pkg::uvm_report_error(ID_, MSG_, uvm_pkg::UVM_NONE, `uvm_file, `uvm_line, "", 1); \
|
||||
end
|
||||
`endif
|
||||
|
||||
`ifndef DV_FATAL
|
||||
`define DV_FATAL(MSG_, ID_ = $sformatf("%m")) \
|
||||
`uvm_fatal(ID_, MSG_)
|
||||
`ifndef dv_fatal
|
||||
// verilog_lint: waive macro-name-style
|
||||
`define dv_fatal(MSG_, ID_ = $sformatf("%m")) \
|
||||
if (uvm_pkg::uvm_report_enabled(uvm_pkg::UVM_NONE, uvm_pkg::UVM_FATAL, ID_)) begin \
|
||||
uvm_pkg::uvm_report_fatal(ID_, MSG_, uvm_pkg::UVM_NONE, `uvm_file, `uvm_line, "", 1); \
|
||||
end
|
||||
`endif
|
||||
|
||||
`else // UVM
|
||||
|
||||
`ifndef DV_INFO
|
||||
`define DV_INFO(MSG_, VERBOSITY = DUMMY_, ID_ = $sformatf("%m")) \
|
||||
`ifndef dv_info
|
||||
// verilog_lint: waive macro-name-style
|
||||
`define dv_info(MSG_, VERBOSITY = DUMMY_, ID_ = $sformatf("%m")) \
|
||||
$display("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
|
||||
`endif
|
||||
|
||||
`ifndef DV_WARNING
|
||||
`define DV_WARNING(MSG_, ID_ = $sformatf("%m")) \
|
||||
`ifndef dv_warning
|
||||
// verilog_lint: waive macro-name-style
|
||||
`define dv_warning(MSG_, ID_ = $sformatf("%m")) \
|
||||
$warning("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
|
||||
`endif
|
||||
|
||||
`ifndef DV_ERROR
|
||||
`define DV_ERROR(MSG_, ID_ = $sformatf("%m")) \
|
||||
`ifndef dv_error
|
||||
// verilog_lint: waive macro-name-style
|
||||
`define dv_error(MSG_, ID_ = $sformatf("%m")) \
|
||||
$error("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
|
||||
`endif
|
||||
|
||||
`ifndef DV_FATAL
|
||||
`define DV_FATAL(MSG_, ID_ = $sformatf("%m")) \
|
||||
`ifndef dv_fatal
|
||||
// verilog_lint: waive macro-name-style
|
||||
`define dv_fatal(MSG_, ID_ = $sformatf("%m")) \
|
||||
$fatal("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
|
||||
`endif
|
||||
|
||||
|
@ -511,7 +533,7 @@
|
|||
/* The #1 delay below allows any part of the tb to control the conditions first at t = 0. */ \
|
||||
#1; \
|
||||
if ((en_``__CG_NAME) || (__COND)) begin \
|
||||
`DV_INFO({"Creating covergroup ", `"__CG_NAME`"}, UVM_MEDIUM) \
|
||||
`dv_info({"Creating covergroup ", `"__CG_NAME`"}, UVM_MEDIUM) \
|
||||
__CG_NAME``_inst = new``__CG_ARGS; \
|
||||
end \
|
||||
end
|
||||
|
|
|
@ -33,24 +33,7 @@ class dv_report_server extends uvm_default_report_server;
|
|||
|
||||
// Print final test pass-fail - external tool can use this signature for test status
|
||||
// Treat UVM_WARNINGs as a sign of test failure since it could silently result in false pass
|
||||
if ((num_uvm_warning + num_uvm_error + num_uvm_fatal) == 0) begin
|
||||
$display("\nTEST PASSED CHECKS");
|
||||
$display(" _____ _ _ _ ");
|
||||
$display("|_ _|__ ___| |_ _ __ __ _ ___ ___ ___ __| | |");
|
||||
$display(" | |/ _ \\/ __| __| | '_ \\ / _` / __/ __|/ _ \\/ _` | |");
|
||||
$display(" | | __/\\__ \\ |_ | |_) | (_| \\__ \\__ \\ __/ (_| |_|");
|
||||
$display(" |_|\\___||___/\\__| | .__/ \\__,_|___/___/\\___|\\__,_(_)");
|
||||
$display(" |_| \n");
|
||||
end
|
||||
else begin
|
||||
$display("\nTEST FAILED CHECKS");
|
||||
$display(" _____ _ __ _ _ _ _ ");
|
||||
$display("|_ _|__ ___| |_ / _| __ _(_) | ___ __| | |");
|
||||
$display(" | |/ _ \\/ __| __| | |_ / _` | | |/ _ \\/ _` | |");
|
||||
$display(" | | __/\\__ \\ |_ | _| (_| | | | __/ (_| |_|");
|
||||
$display(" |_|\\___||___/\\__| |_| \\__,_|_|_|\\___|\\__,_(_)\n");
|
||||
end
|
||||
|
||||
dv_test_status_pkg::dv_test_status((num_uvm_warning + num_uvm_error + num_uvm_fatal) == 0);
|
||||
endfunction
|
||||
|
||||
// Override default messaging format to standard "pretty" format for all testbenches
|
||||
|
@ -69,7 +52,7 @@ class dv_report_server extends uvm_default_report_server;
|
|||
string file_line;
|
||||
|
||||
if (show_file_line && filename != "") begin
|
||||
if (!show_file_path) filename = get_no_hier_filename(filename);
|
||||
if (!show_file_path) filename = str_utils_pkg::str_path_basename(filename);
|
||||
file_line = $sformatf("(%0s:%0d) ", filename, line);
|
||||
end
|
||||
obj_name = {obj_name, ((obj_name != "") ? " " : "")};
|
||||
|
@ -79,12 +62,4 @@ class dv_report_server extends uvm_default_report_server;
|
|||
end
|
||||
endfunction
|
||||
|
||||
// get we don't really want the full path to the filename
|
||||
// this should be reasonably lightweight
|
||||
local function string get_no_hier_filename(string filename);
|
||||
int idx;
|
||||
for (idx = filename.len() - 1; idx >= 0; idx--) if (filename[idx] == "/") break;
|
||||
return (filename.substr(idx + 1, filename.len() - 1));
|
||||
endfunction
|
||||
|
||||
endclass
|
||||
|
|
17
vendor/lowrisc_ip/dv/sv/dv_utils/dv_test_status.core
vendored
Normal file
17
vendor/lowrisc_ip/dv/sv/dv_utils/dv_test_status.core
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
CAPI=2:
|
||||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
name: "lowrisc:dv:dv_test_status"
|
||||
description: "DV test status reporting utilities"
|
||||
|
||||
filesets:
|
||||
files_dv:
|
||||
files:
|
||||
- dv_test_status_pkg.sv
|
||||
file_type: systemVerilogSource
|
||||
|
||||
targets:
|
||||
default:
|
||||
filesets:
|
||||
- files_dv
|
32
vendor/lowrisc_ip/dv/sv/dv_utils/dv_test_status_pkg.sv
vendored
Normal file
32
vendor/lowrisc_ip/dv/sv/dv_utils/dv_test_status_pkg.sv
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package dv_test_status_pkg;
|
||||
|
||||
// Prints the test status signature & banner.
|
||||
//
|
||||
// This function takes a boolean arg indicating whether the test passed or failed and prints the
|
||||
// signature along with a banner. The signature can be used by external scripts to determine if
|
||||
// the test passed or failed.
|
||||
function automatic void dv_test_status(bit passed);
|
||||
if (passed) begin
|
||||
$display("\nTEST PASSED CHECKS");
|
||||
$display(" _____ _ _ _ ");
|
||||
$display("|_ _|__ ___| |_ _ __ __ _ ___ ___ ___ __| | |");
|
||||
$display(" | |/ _ \\/ __| __| | '_ \\ / _` / __/ __|/ _ \\/ _` | |");
|
||||
$display(" | | __/\\__ \\ |_ | |_) | (_| \\__ \\__ \\ __/ (_| |_|");
|
||||
$display(" |_|\\___||___/\\__| | .__/ \\__,_|___/___/\\___|\\__,_(_)");
|
||||
$display(" |_| \n");
|
||||
end
|
||||
else begin
|
||||
$display("\nTEST FAILED CHECKS");
|
||||
$display(" _____ _ __ _ _ _ _ ");
|
||||
$display("|_ _|__ ___| |_ / _| __ _(_) | ___ __| | |");
|
||||
$display(" | |/ _ \\/ __| __| | |_ / _` | | |/ _ \\/ _` | |");
|
||||
$display(" | | __/\\__ \\ |_ | _| (_| | | | __/ (_| |_|");
|
||||
$display(" |_|\\___||___/\\__| |_| \\__,_|_|_|\\___|\\__,_(_)\n");
|
||||
end
|
||||
endfunction
|
||||
|
||||
endpackage
|
|
@ -12,6 +12,8 @@ filesets:
|
|||
- lowrisc:dv:common_ifs
|
||||
- lowrisc:prim:assert:0.1
|
||||
- lowrisc:ibex:bus_params_pkg
|
||||
- lowrisc:dv:str_utils
|
||||
- lowrisc:dv:dv_test_status
|
||||
files:
|
||||
- dv_utils_pkg.sv
|
||||
- dv_report_server.sv: {is_include_file: true}
|
||||
|
|
|
@ -9,7 +9,9 @@ package dv_utils_pkg;
|
|||
|
||||
// macro includes
|
||||
`include "dv_macros.svh"
|
||||
`ifdef UVM
|
||||
`include "uvm_macros.svh"
|
||||
`endif
|
||||
|
||||
// common parameters used across all benches
|
||||
parameter int NUM_MAX_INTERRUPTS = 32;
|
||||
|
|
6
vendor/lowrisc_ip/dv/sv/str_utils/README.md
vendored
Normal file
6
vendor/lowrisc_ip/dv/sv/str_utils/README.md
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
# str_utils_pkg
|
||||
|
||||
This package provides some basic string and path manipulation utility functions that
|
||||
can be used across the project. It can be imported in non-UVM testbenches as
|
||||
well. Please see the package for the list of available functions and their
|
||||
descriptions.
|
19
vendor/lowrisc_ip/dv/sv/str_utils/str_utils.core
vendored
Normal file
19
vendor/lowrisc_ip/dv/sv/str_utils/str_utils.core
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
CAPI=2:
|
||||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
name: "lowrisc:dv:str_utils"
|
||||
description: "String manipulation utilities"
|
||||
|
||||
filesets:
|
||||
files_dv:
|
||||
depend:
|
||||
- lowrisc:dv:dv_macros
|
||||
files:
|
||||
- str_utils_pkg.sv
|
||||
file_type: systemVerilogSource
|
||||
|
||||
targets:
|
||||
default:
|
||||
filesets:
|
||||
- files_dv
|
174
vendor/lowrisc_ip/dv/sv/str_utils/str_utils_pkg.sv
vendored
Normal file
174
vendor/lowrisc_ip/dv/sv/str_utils/str_utils_pkg.sv
vendored
Normal file
|
@ -0,0 +1,174 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package str_utils_pkg;
|
||||
`include "dv_macros.svh"
|
||||
|
||||
// Returns 1 if string 's' has substring 'sub' within the given index range. 0 Otherwise.
|
||||
function automatic bit str_has_substr(string s, string sub, int range_lo = 0, int range_hi = -1);
|
||||
if (range_hi < 0 || range_hi >= s.len()) range_hi = s.len() - 1;
|
||||
for (int i = range_lo; i <= (range_hi - sub.len() + 1); i++) begin
|
||||
if (s.substr(i, i + sub.len() - 1) == sub) begin
|
||||
return 1;
|
||||
end
|
||||
end
|
||||
return 0;
|
||||
endfunction : str_has_substr
|
||||
|
||||
// Returns the index of first occurrence of string 'sub' within string 's''s given index range.
|
||||
// Returns -1 otherwise.
|
||||
function automatic int str_find(string s, string sub, int range_lo = 0, int range_hi = -1);
|
||||
if (range_hi < 0 || range_hi >= s.len()) range_hi = s.len() - 1;
|
||||
for (int i = range_lo; i <= (range_hi - sub.len() + 1); i++) begin
|
||||
if (s.substr(i, i + sub.len() - 1) == sub) begin
|
||||
return i;
|
||||
end
|
||||
end
|
||||
return -1;
|
||||
endfunction : str_find
|
||||
|
||||
// Returns the index of last occurrence of string 'sub' within string 's''s given index range.
|
||||
// Returns -1 otherwise.
|
||||
function automatic int str_rfind(string s, string sub, int range_lo = 0, int range_hi = -1);
|
||||
if (range_hi < 0 || range_hi >= s.len()) range_hi = s.len() - 1;
|
||||
for (int i = (range_hi - sub.len() + 1); i >= range_lo; i--) begin
|
||||
if (s.substr(i, i + sub.len() - 1) == sub) begin
|
||||
return i;
|
||||
end
|
||||
end
|
||||
return -1;
|
||||
endfunction : str_rfind
|
||||
|
||||
// Strips a given set of characters in string 's'.
|
||||
//
|
||||
// The set of characters to strip is provided as a string. If not set, all whitespace characters
|
||||
// are stripped by default. Stripping is done at both ends, unless the user turns off the
|
||||
// stripping from one of the ends.
|
||||
function automatic string str_strip(string s,
|
||||
string chars = " \t\n",
|
||||
bit lstrip = 1'b1,
|
||||
bit rstrip = 1'b1);
|
||||
byte chars_q[$];
|
||||
if (chars == "") return s;
|
||||
foreach (chars[i]) chars_q.push_back(chars.getc(i));
|
||||
|
||||
if (lstrip) begin
|
||||
int i = 0;
|
||||
while (s.getc(i) inside {chars_q}) i++;
|
||||
s = s.substr(i, s.len() - 1);
|
||||
end
|
||||
|
||||
if (rstrip) begin
|
||||
int i = s.len() - 1;
|
||||
while (s.getc(i) inside {chars_q}) i--;
|
||||
s = s.substr(0, i);
|
||||
end
|
||||
return s;
|
||||
endfunction : str_strip
|
||||
|
||||
// Splits the input `string` on the given single-character delimiter `delim`.
|
||||
//
|
||||
// The split tokens are pushed into the `result` queue. The whitespaces on each split token are
|
||||
// stripped by default, which can be turned off.
|
||||
// TODO: allow arbitrary length delimiter.
|
||||
function automatic void str_split(input string s,
|
||||
output string result[$],
|
||||
input byte delim = " ",
|
||||
input bit strip_whitespaces = 1'b1);
|
||||
string sub;
|
||||
bit in_quotes;
|
||||
result = {};
|
||||
foreach (s[i]) begin
|
||||
if (s[i] == "\"") begin
|
||||
in_quotes = !in_quotes;
|
||||
end
|
||||
if ((s.getc(i) == delim) && !in_quotes) begin
|
||||
if (strip_whitespaces) sub = str_strip(sub);
|
||||
if (sub != "") result.push_back(sub);
|
||||
sub = "";
|
||||
end else begin
|
||||
sub = {sub, s[i]};
|
||||
end
|
||||
if (i == s.len() - 1) begin
|
||||
if (strip_whitespaces) sub = str_strip(sub);
|
||||
if (sub != "") result.push_back(sub);
|
||||
end
|
||||
end
|
||||
endfunction : str_split
|
||||
|
||||
// Returns a string concatenated from the provided queue of strings 's'.
|
||||
//
|
||||
// The concatenation is performed using the 'delim' arg as the delimiter.
|
||||
function automatic string str_join(string s[$], string delim = " ");
|
||||
string str;
|
||||
foreach (s[i]) begin
|
||||
str = {str, s[i], delim};
|
||||
end
|
||||
if (str != "") begin
|
||||
str = str.substr(0, str.len() - delim.len() - 1);
|
||||
end
|
||||
return str;
|
||||
endfunction : str_join
|
||||
|
||||
// Converts a string to an array of bytes.
|
||||
function automatic void str_to_bytes(string s, output byte bytes[]);
|
||||
bytes = new[s.len()];
|
||||
foreach (bytes[i]) begin
|
||||
bytes[i] = s.getc(i);
|
||||
end
|
||||
endfunction : str_to_bytes
|
||||
|
||||
/************************/
|
||||
/* File path functions. */
|
||||
/************************/
|
||||
|
||||
// Returns the dirname of the file.
|
||||
//
|
||||
// Examples:
|
||||
// path/to/foo.bar => path/to
|
||||
// path/to/foo/bar => path/to/foo
|
||||
// path/to/foo/bar/ => path/to/foo
|
||||
// path/to/foo/bar/. => path/to/foo/bar
|
||||
// / => /
|
||||
function automatic string str_path_dirname(string filename);
|
||||
int idx;
|
||||
string dirname;
|
||||
|
||||
if (filename == "/") return filename;
|
||||
filename = str_strip(.s(filename), .chars("/"), .lstrip(1'b0));
|
||||
idx = str_rfind(.s(filename), .sub("/"));
|
||||
if (idx == -1) idx = filename.len();
|
||||
if (idx == 0) idx++;
|
||||
dirname = filename.substr(0, idx - 1);
|
||||
return dirname;
|
||||
endfunction : str_path_dirname
|
||||
|
||||
// Returns the basename of the file.
|
||||
//
|
||||
// Optionally, it takes a bit flag to drop the extension from the basename if desired.
|
||||
// Examples:
|
||||
// path/to/foo.bar => (foo.bar, foo)
|
||||
// path/to/foo/bar => (bar, bar)
|
||||
// path/to/foo/bar/ => (bar, bar)
|
||||
// path/to/foo/bar/. => (., .)
|
||||
// / => (/, /)
|
||||
function automatic string str_path_basename(string filename, bit drop_extn = 1'b0);
|
||||
int idx;
|
||||
string basename;
|
||||
|
||||
if (filename == "/") return filename;
|
||||
filename = str_strip(.s(filename), .chars("/"), .lstrip(1'b0));
|
||||
idx = str_rfind(.s(filename), .sub("/"));
|
||||
basename = filename.substr(idx + 1, filename.len() - 1);
|
||||
|
||||
if (basename == ".") return basename;
|
||||
if (drop_extn) begin
|
||||
idx = str_find(.s(basename), .sub("."));
|
||||
if (idx == -1) idx = basename.len();
|
||||
basename = basename.substr(0, idx - 1);
|
||||
end
|
||||
return basename;
|
||||
endfunction : str_path_basename
|
||||
|
||||
endpackage
|
|
@ -2,10 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
{
|
||||
flow: sim
|
||||
// Where to find DV code
|
||||
dv_root: "{proj_root}/vendor/lowrisc_ip/dv"
|
||||
|
||||
flow: sim
|
||||
flow_makefile: "{dv_root}/tools/dvsim/sim.mk"
|
||||
|
||||
import_cfgs: ["{proj_root}/dv/uvm/common_project_cfg.hjson",
|
||||
|
@ -17,7 +16,7 @@
|
|||
build_dir: "{scratch_path}/{build_mode}"
|
||||
run_dir_name: "{index}.{test}"
|
||||
run_dir: "{scratch_path}/{run_dir_name}/out"
|
||||
sw_build_dir: "{scratch_path}/sw"
|
||||
sw_build_dir: "{scratch_path}"
|
||||
sw_root_dir: "{proj_root}/sw"
|
||||
|
||||
// pass and fail patterns
|
||||
|
@ -41,6 +40,7 @@
|
|||
expand_uvm_verbosity_l: UVM_LOW
|
||||
expand_uvm_verbosity_m: UVM_MEDIUM
|
||||
expand_uvm_verbosity_h: UVM_HIGH
|
||||
expand_uvm_verbosity_f: UVM_FULL
|
||||
expand_uvm_verbosity_d: UVM_DEBUG
|
||||
|
||||
// Default simulation verbosity (l => UVM_LOW). Can be overridden by
|
||||
|
@ -53,12 +53,10 @@
|
|||
dut_instance: "{tb}.dut"
|
||||
|
||||
// Top level simulation entities.
|
||||
sim_tops: ["-top {tb}"]
|
||||
sim_tops: ["{tb}"]
|
||||
|
||||
// Default build and run opts
|
||||
build_opts: [// List multiple tops for the simulation
|
||||
"{sim_tops}",
|
||||
// Standard UVM defines
|
||||
build_opts: [// Standard UVM defines
|
||||
"+define+UVM",
|
||||
"+define+UVM_NO_DEPRECATED",
|
||||
"+define+UVM_REGEX_NO_DPI",
|
||||
|
@ -71,7 +69,7 @@
|
|||
|
||||
// Default list of things to export to shell
|
||||
exports: [
|
||||
{ TOOL_SRCS_DIR: "{tool_srcs_dir}" },
|
||||
{ dv_root: "{dv_root}" },
|
||||
{ SIMULATOR: "{tool}" },
|
||||
{ WAVES: "{waves}" },
|
||||
{ DUT_TOP: "{dut}" },
|
||||
|
@ -104,7 +102,7 @@
|
|||
// By default, two regressions are made available - "all" and "nightly". Both
|
||||
// run all available tests for the DUT. "nightly" enables coverage as well.
|
||||
// The 'tests' key is set to an empty list, which indicates "run everything".
|
||||
// Test sets can enable sim modes, which are a set of build_opts and run_opts
|
||||
// Regressions can enable sim modes, which are a set of build_opts and run_opts
|
||||
// that are grouped together. These are appended to the build modes used by the
|
||||
// tests.
|
||||
regressions: [
|
||||
|
@ -129,26 +127,20 @@
|
|||
}
|
||||
]
|
||||
|
||||
// Add waves.tcl to the set of sources to be copied over to
|
||||
// {tool_srcs_dir}. This can be sourced by the tool-specific TCL
|
||||
// script to set up wave dumping.
|
||||
tool_srcs: ["{dv_root}/tools/sim.tcl",
|
||||
"{dv_root}/tools/common.tcl",
|
||||
"{dv_root}/tools/waves.tcl"]
|
||||
|
||||
// Project defaults for VCS
|
||||
vcs_cov_cfg_file: "{{build_mode}_vcs_cov_cfg_file}"
|
||||
vcs_cov_excl_files: ["{tool_srcs_dir}/common_cov_excl.el"]
|
||||
vcs_unr_cfg_file: "{dv_root}/tools/vcs/unr.cfg"
|
||||
vcs_cov_excl_files: ["{dv_root}/tools/vcs/common_cov_excl.el"]
|
||||
|
||||
// Build-specific coverage cfg files for VCS.
|
||||
default_vcs_cov_cfg_file: "-cm_hier {tool_srcs_dir}/cover.cfg"
|
||||
cover_reg_top_vcs_cov_cfg_file: "-cm_hier {tool_srcs_dir}/cover_reg_top.cfg"
|
||||
default_vcs_cov_cfg_file: "-cm_hier {dv_root}/tools/vcs/cover.cfg"
|
||||
cover_reg_top_vcs_cov_cfg_file: "-cm_hier {dv_root}/tools/vcs/cover_reg_top.cfg"
|
||||
|
||||
// Project defaults for Xcelium
|
||||
// xcelium_cov_cfg_file: "{{build_mode}_xcelium_cov_cfg_file}"
|
||||
// xcelium_cov_refine_files: ["{tool_srcs_dir}/common_cov.vRefine"]
|
||||
// xcelium_cov_refine_files: ["{dv_root}/tools/xcelium/common_cov.vRefine"]
|
||||
|
||||
// Build-specific coverage cfg files for Xcelium.
|
||||
// default_xcelium_cov_cfg_file: "-covfile {tool_srcs_dir}/cover.ccf"
|
||||
// cover_reg_top_xcelium_cov_cfg_file: "-covfile {tool_srcs_dir}/cover_reg_top.ccf"
|
||||
// default_xcelium_cov_cfg_file: "-covfile {dv_root}/tools/xcelium/cover.ccf"
|
||||
// cover_reg_top_xcelium_cov_cfg_file: "-covfile {dv_root}/tools/xcelium/cover_reg_top.ccf"
|
||||
}
|
||||
|
|
18
vendor/lowrisc_ip/dv/tools/dvsim/dsim.hjson
vendored
18
vendor/lowrisc_ip/dv/tools/dvsim/dsim.hjson
vendored
|
@ -5,12 +5,6 @@
|
|||
build_cmd: "{job_prefix} dsim"
|
||||
run_cmd: "{job_prefix} dsim"
|
||||
|
||||
// Indicate the tool specific helper sources - these are copied over to the
|
||||
// {tool_srcs_dir} before running the simulation.
|
||||
// TODO, there is no dsim tool file, point to vcs for now to avoid error from script
|
||||
// tool_srcs: ["{dv_root}/tools/dsim/*"]
|
||||
|
||||
|
||||
build_opts: ["-work {build_dir}/dsim_out",
|
||||
"-genimage image",
|
||||
"-sv",
|
||||
|
@ -23,6 +17,8 @@
|
|||
"-c-opts -I{DSIM_HOME}/include",
|
||||
"-timescale 1ns/1ps",
|
||||
"-f {sv_flist}",
|
||||
// List multiple tops for the simulation. Prepend each top level with `-top`.
|
||||
"{eval_cmd} echo {sim_tops} | sed -E 's/(\\S+)/-top \\1/g'",
|
||||
"+incdir+{build_dir}",
|
||||
// Suppress following DSim errors and warnings:
|
||||
// EnumMustBePositive - UVM 1.2 violates this
|
||||
|
@ -57,13 +53,13 @@
|
|||
// Merging coverage.
|
||||
// "cov_db_dirs" is a special variable that appends all build directories in use.
|
||||
// It is constructed by the tool itself.
|
||||
cov_merge_dir: "{scratch_base_path}/cov_merge"
|
||||
cov_merge_dir: "{scratch_path}/cov_merge"
|
||||
cov_merge_db_dir: "{cov_merge_dir}/merged.vdb"
|
||||
cov_merge_cmd: "{job_prefix} urg"
|
||||
cov_merge_opts: []
|
||||
|
||||
// Generate coverage reports in text as well as html.
|
||||
cov_report_dir: "{scratch_base_path}/cov_report"
|
||||
cov_report_dir: "{scratch_path}/cov_report"
|
||||
cov_report_cmd: "{job_prefix} urg"
|
||||
cov_report_opts: []
|
||||
cov_report_txt: "{cov_report_dir}/dashboard.txt"
|
||||
|
@ -71,7 +67,7 @@
|
|||
|
||||
// Analyzing coverage - this is done by invoking --cov-analyze switch. It opens up the
|
||||
// GUI for visual analysis.
|
||||
cov_analyze_dir: "{scratch_base_path}/cov_analyze"
|
||||
cov_analyze_dir: "{scratch_path}/cov_analyze"
|
||||
cov_analyze_cmd: "{job_prefix} verdi"
|
||||
cov_analyze_opts: ["-cov",
|
||||
"-covdir {cov_merge_db_dir}",
|
||||
|
@ -89,8 +85,8 @@
|
|||
cov_metrics: ""
|
||||
|
||||
// pass and fail patterns
|
||||
build_fail_patterns: ["^Error-.*$"]
|
||||
run_fail_patterns: ["^Error-.*$"] // Null pointer error
|
||||
build_fail_patterns: ["^=E:"]
|
||||
run_fail_patterns: ["^=E:"]
|
||||
|
||||
// waveform
|
||||
probe_file: "dsim.probe"
|
||||
|
|
31
vendor/lowrisc_ip/dv/tools/dvsim/riviera.hjson
vendored
31
vendor/lowrisc_ip/dv/tools/dvsim/riviera.hjson
vendored
|
@ -5,14 +5,13 @@
|
|||
build_cmd: "vlib work && {job_prefix} vlog"
|
||||
run_cmd: "{job_prefix} vsim"
|
||||
|
||||
// Indicate the tool specific helper sources - these are copied over to the
|
||||
// {tool_srcs_dir} before running the simulation.
|
||||
tool_srcs: ["{dv_root}/tools/riviera/*"]
|
||||
|
||||
build_opts: ["-sv",
|
||||
"-timescale 1ns/1ps",
|
||||
"-uvmver 1.2",
|
||||
"-f {sv_flist}"]
|
||||
build_opts: ["-timescale 1ns/1ps",
|
||||
"+incdir+\"{RIVIERA_HOME}/vlib/uvm-1.2/src\"",
|
||||
"\"{RIVIERA_HOME}/vlib/uvm-1.2/src/uvm_pkg.sv\"",
|
||||
"-f {sv_flist}",
|
||||
// List multiple tops for the simulation. Prepend each top level with `-top`.
|
||||
"{eval_cmd} echo {sim_tops} | sed -E 's/(\\S+)/-top \\1/g'",
|
||||
]
|
||||
|
||||
run_opts: ["-sv_seed={seed}",
|
||||
"-c",
|
||||
|
@ -20,6 +19,7 @@
|
|||
"-lib {sv_flist_gen_dir}/work",
|
||||
"+UVM_TESTNAME={uvm_test}",
|
||||
"+UVM_TEST_SEQ={uvm_test_seq}",
|
||||
"-sv_lib \"{RIVIERA_HOME}/bin/uvm_1_2_dpi\"",
|
||||
"-do {run_script}"]
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
|||
supported_wave_formats: []
|
||||
|
||||
// Default tcl script used when running the sim. Override if needed.
|
||||
run_script: "{tool_srcs_dir}/riviera_run.do"
|
||||
run_script: "{dv_root}/tools/riviera/riviera_run.do"
|
||||
|
||||
// Coverage related.
|
||||
// TODO: These options have to be filled in.
|
||||
|
@ -41,20 +41,20 @@
|
|||
// Merging coverage.
|
||||
// "cov_db_dirs" is a special variable that appends all build directories in use.
|
||||
// It is constructed by the tool itself.
|
||||
cov_merge_dir: "{scratch_base_path}/cov_merge"
|
||||
cov_merge_dir: "{scratch_path}/cov_merge"
|
||||
cov_merge_db_dir: ""
|
||||
cov_merge_cmd: ""
|
||||
cov_merge_opts: []
|
||||
|
||||
// Generate covreage reports in text as well as html.
|
||||
cov_report_dir: "{scratch_base_path}/cov_report"
|
||||
cov_report_dir: "{scratch_path}/cov_report"
|
||||
cov_report_cmd: ""
|
||||
cov_report_opts: []
|
||||
cov_report_dashboard: ""
|
||||
|
||||
// Analyzing coverage - this is done by invoking --cov-analyze switch. It opens up the
|
||||
// GUI for visual analysis.
|
||||
cov_analyze_dir: "{scratch_base_path}/cov_analyze"
|
||||
cov_analyze_dir: "{scratch_path}/cov_analyze"
|
||||
cov_analyze_cmd: ""
|
||||
cov_analyze_opts: []
|
||||
|
||||
|
@ -86,5 +86,12 @@
|
|||
is_sim_mode: 1
|
||||
build_opts: []
|
||||
}
|
||||
// TODO: Add build and run options to enable zero delay loop detection.
|
||||
{
|
||||
name: riviera_loopdetect
|
||||
is_sim_mode: 1
|
||||
build_opts: []
|
||||
run_opts: []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
169
vendor/lowrisc_ip/dv/tools/dvsim/sim.mk
vendored
169
vendor/lowrisc_ip/dv/tools/dvsim/sim.mk
vendored
|
@ -4,108 +4,100 @@
|
|||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
LOCK_TOOL_SRCS_DIR ?= flock --timeout 3600 ${tool_srcs_dir} --command
|
||||
LOCK_SW_BUILD ?= flock --timeout 3600 ${sw_build_dir} --command
|
||||
LOCK_SW_BUILD_DIR ?= flock --timeout 3600 ${sw_build_dir} --command
|
||||
|
||||
all: build run
|
||||
|
||||
###############################
|
||||
## sim build and run targets ##
|
||||
###############################
|
||||
build: compile_result
|
||||
build: build_result
|
||||
|
||||
prep_tool_srcs:
|
||||
@echo "[make]: prep_tool_srcs"
|
||||
mkdir -p ${tool_srcs_dir}
|
||||
${LOCK_TOOL_SRCS_DIR} "cp -Ru ${tool_srcs} ${tool_srcs_dir}/."
|
||||
|
||||
pre_compile: prep_tool_srcs
|
||||
@echo "[make]: pre_compile"
|
||||
pre_build:
|
||||
@echo "[make]: pre_build"
|
||||
mkdir -p ${build_dir}
|
||||
ifneq (${pre_build_cmds},)
|
||||
cd ${build_dir} && ${pre_build_cmds}
|
||||
endif
|
||||
|
||||
gen_sv_flist: pre_compile
|
||||
gen_sv_flist: pre_build
|
||||
@echo "[make]: gen_sv_flist"
|
||||
ifneq (${sv_flist_gen_cmd},)
|
||||
cd ${build_dir} && ${sv_flist_gen_cmd} ${sv_flist_gen_opts}
|
||||
endif
|
||||
|
||||
compile: gen_sv_flist
|
||||
@echo "[make]: compile"
|
||||
do_build: gen_sv_flist
|
||||
@echo "[make]: build"
|
||||
cd ${sv_flist_gen_dir} && ${build_cmd} ${build_opts}
|
||||
|
||||
post_compile: compile
|
||||
@echo "[make]: post_compile"
|
||||
post_build: do_build
|
||||
@echo "[make]: post_build"
|
||||
ifneq (${post_build_cmds},)
|
||||
cd ${build_dir} && ${post_build_cmds}
|
||||
endif
|
||||
|
||||
compile_result: post_compile
|
||||
@echo "[make]: compile_result"
|
||||
build_result: post_build
|
||||
@echo "[make]: build_result"
|
||||
|
||||
run: run_result
|
||||
|
||||
pre_run: prep_tool_srcs
|
||||
pre_run:
|
||||
@echo "[make]: pre_run"
|
||||
mkdir -p ${run_dir}
|
||||
ifneq (${sw_test},)
|
||||
mkdir -p ${sw_build_dir}
|
||||
ifneq (${pre_run_cmds},)
|
||||
cd ${run_dir} && ${pre_run_cmds}
|
||||
endif
|
||||
|
||||
.ONESHELL:
|
||||
sw_build: pre_run
|
||||
@echo "[make]: sw_build"
|
||||
ifneq (${sw_test},)
|
||||
ifneq (${sw_images},)
|
||||
set -e
|
||||
mkdir -p ${sw_build_dir}
|
||||
# Initialize meson build system.
|
||||
${LOCK_SW_BUILD} "cd ${proj_root} && \
|
||||
${LOCK_SW_BUILD_DIR} "cd ${proj_root} && \
|
||||
BUILD_ROOT=${sw_build_dir} ${proj_root}/meson_init.sh"
|
||||
# Compile boot rom code and generate the image.
|
||||
${LOCK_SW_BUILD} "ninja -C ${sw_build_dir}/build-out \
|
||||
sw/device/boot_rom/boot_rom_export_${sw_build_device}"
|
||||
# Extract the boot rom logs.
|
||||
${proj_root}/util/device_sw_utils/extract_sw_logs.py \
|
||||
-e "${sw_build_dir}/build-out/sw/device/boot_rom/boot_rom_${sw_build_device}.elf" \
|
||||
-f .logs.fields -r .rodata .chip_info \
|
||||
-n "rom" -o "${run_dir}"
|
||||
# Copy over the boot rom image to the run_dir.
|
||||
cp ${sw_build_dir}/build-out/sw/device/boot_rom/boot_rom_${sw_build_device}.32.vmem \
|
||||
${run_dir}/rom.vmem
|
||||
cp ${sw_build_dir}/build-out/sw/device/boot_rom/boot_rom_${sw_build_device}.elf \
|
||||
${run_dir}/rom.elf
|
||||
|
||||
ifeq (${sw_test_is_prebuilt},1)
|
||||
# Copy over the sw test image and related sources to the run_dir.
|
||||
cp ${proj_root}/${sw_test}.64.vmem ${run_dir}/sw.vmem
|
||||
# Optionally, assume that ${sw_test}_logs.txt exists and copy over to the run_dir.
|
||||
# Ignore copy error if it actually doesn't exist. Likewise for ${sw_test}_rodata.txt.
|
||||
-cp ${proj_root}/${sw_test}_logs.txt ${run_dir}/sw_logs.txt
|
||||
-cp ${proj_root}/${sw_test}_rodata.txt ${run_dir}/sw_rodata.txt
|
||||
|
||||
else
|
||||
# Compile the sw test code and generate the image.
|
||||
${LOCK_SW_BUILD} "ninja -C ${sw_build_dir}/build-out \
|
||||
${sw_test}_export_${sw_build_device}"
|
||||
# Convert sw image to frame format
|
||||
# TODO only needed for loading sw image through SPI. Can enhance this later
|
||||
${LOCK_SW_BUILD} "ninja -C ${sw_build_dir}/build-out sw/host/spiflash/spiflash_export"
|
||||
${LOCK_SW_BUILD} "${sw_build_dir}/build-bin/sw/host/spiflash/spiflash --input \
|
||||
${sw_build_dir}/build-bin/${sw_test}_${sw_build_device}.bin \
|
||||
--dump-frames=${run_dir}/sw.frames.bin"
|
||||
${LOCK_SW_BUILD} "srec_cat ${run_dir}/sw.frames.bin --binary \
|
||||
--offset 0x0 --byte-swap 4 --fill 0xff -within ${run_dir}/sw.frames.bin -binary -range-pad 4 \
|
||||
--output ${run_dir}/sw.frames.vmem --vmem"
|
||||
# Extract the sw test logs.
|
||||
${proj_root}/util/device_sw_utils/extract_sw_logs.py \
|
||||
-e "${sw_build_dir}/build-out/${sw_test}_${sw_build_device}.elf" \
|
||||
-f .logs.fields -r .rodata \
|
||||
-n "sw" -o "${run_dir}"
|
||||
# Copy over the sw test image to the run_dir.
|
||||
cp ${sw_build_dir}/build-out/${sw_test}_${sw_build_device}.64.vmem ${run_dir}/sw.vmem
|
||||
cp ${sw_build_dir}/build-out/${sw_test}_${sw_build_device}.elf ${run_dir}/sw.elf
|
||||
# Loop through the list of sw_images and invoke meson on each item.
|
||||
# `sw_images` is a space-separated list of tests to be built into an image.
|
||||
# Optionally, each item in the list can have additional metadata / flags using
|
||||
# the delimiter ':'. The format is as follows:
|
||||
# <path-to-sw-test>:<index>:<flag1>:<flag2>
|
||||
#
|
||||
# If no delimiter is detected, then the full string is considered to be the
|
||||
# <path-to-sw-test>. If 1 delimiter is detected, then it must be <path-to-sw-
|
||||
# test> followed by <index>. The <flag> is considered optional.
|
||||
@for sw_image in ${sw_images}; do \
|
||||
image=`echo $$sw_image | cut -d: -f 1`; \
|
||||
index=`echo $$sw_image | cut -d: -f 2`; \
|
||||
flags=(`echo $$sw_image | cut -d: -f 3- --output-delimiter " "`); \
|
||||
if [[ -z $$image ]]; then \
|
||||
echo "ERROR: SW image \"$$sw_image\" is malformed."; \
|
||||
echo "Expected format: path-to-sw-test:index:optional-flags."; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
if [[ $${flags[@]} =~ "prebuilt" ]]; then \
|
||||
echo "SW image \"$$image\" is prebuilt - copying sources."; \
|
||||
target_dir=`dirname ${sw_build_dir}/build-bin/$$image`; \
|
||||
mkdir -p $$target_dir; \
|
||||
cp ${proj_root}/$$image* $$target_dir/.; \
|
||||
else \
|
||||
echo "Building SW image \"$$image\"."; \
|
||||
target="$$image""_export_${sw_build_device}"; \
|
||||
${LOCK_SW_BUILD_DIR} "ninja -C ${sw_build_dir}/build-out $$target"; \
|
||||
fi; \
|
||||
done;
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
|
||||
simulate: sw_build
|
||||
@echo "[make]: simulate"
|
||||
cd ${run_dir} && ${run_cmd} ${run_opts}
|
||||
|
||||
post_run: simulate
|
||||
@echo "[make]: post_run"
|
||||
ifneq (${post_run_cmds},)
|
||||
cd ${run_dir} && ${post_run_cmds}
|
||||
endif
|
||||
|
||||
run_result: post_run
|
||||
@echo "[make]: run_result"
|
||||
|
@ -119,29 +111,42 @@ debug_waves:
|
|||
############################
|
||||
## coverage rated targets ##
|
||||
############################
|
||||
cov_unr_build: gen_sv_flist
|
||||
@echo "[make]: cov_unr_build"
|
||||
cd ${sv_flist_gen_dir} && ${cov_unr_build_cmd} ${cov_unr_build_opts}
|
||||
|
||||
cov_unr: cov_unr_build
|
||||
@echo "[make]: cov_unr"
|
||||
cd ${sv_flist_gen_dir} && ${cov_unr_run_cmd} ${cov_unr_run_opts}
|
||||
|
||||
# Merge coverage if there are multiple builds.
|
||||
cov_merge:
|
||||
@echo "[make]: cov_merge"
|
||||
${cov_merge_cmd} ${cov_merge_opts}
|
||||
|
||||
# Open coverage tool to review and create report or exclusion file.
|
||||
cov_analyze: prep_tool_srcs
|
||||
@echo "[make]: cov_analyze"
|
||||
${cov_analyze_cmd} ${cov_analyze_opts}
|
||||
|
||||
# Generate coverage reports.
|
||||
cov_report:
|
||||
@echo "[make]: cov_report"
|
||||
${cov_report_cmd} ${cov_report_opts}
|
||||
|
||||
# Open coverage tool to review and create report or exclusion file.
|
||||
cov_analyze:
|
||||
@echo "[make]: cov_analyze"
|
||||
${cov_analyze_cmd} ${cov_analyze_opts}
|
||||
|
||||
.PHONY: build \
|
||||
run \
|
||||
reg \
|
||||
pre_compile \
|
||||
compile \
|
||||
post_compile \
|
||||
compile_result \
|
||||
pre_run \
|
||||
simulate \
|
||||
post_run \
|
||||
run_result
|
||||
pre_build \
|
||||
gen_sv_flist \
|
||||
do_build \
|
||||
post_build \
|
||||
build_result \
|
||||
run \
|
||||
pre_run \
|
||||
sw_build \
|
||||
simulate \
|
||||
post_run \
|
||||
run_result \
|
||||
debug_waves \
|
||||
cov_merge \
|
||||
cov_analyze \
|
||||
cov_report
|
||||
|
|
28
vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson
vendored
Normal file
28
vendor/lowrisc_ip/dv/tools/dvsim/testplans/alert_test_testplan.hjson
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
{
|
||||
entries: [
|
||||
{
|
||||
name: alert_test
|
||||
desc: '''
|
||||
Verify common `alert_test` CSR that allows SW to mock-inject alert requests.
|
||||
- Enable a random set of alert requests by writing random value to
|
||||
alert_test CSR.
|
||||
- Check each `alert_tx.alert_p` pin to verify that only the requested alerts
|
||||
are triggered.
|
||||
- During alert_handshakes, write `alert_test` CSR again to verify that:
|
||||
If `alert_test` writes to current ongoing alert handshake, the `alert_test`
|
||||
request will be ignored.
|
||||
If `alert_test` writes to current idle alert handshake, a new alert_handshake
|
||||
should be triggered.
|
||||
- Wait for the alert handshakes to finish and verify `alert_tx.alert_p` pins
|
||||
all sets back to 0.
|
||||
- Repeat the above steps a bunch of times.
|
||||
'''
|
||||
milestone: V2
|
||||
tests: ["{name}{intf}_alert_test"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
20
vendor/lowrisc_ip/dv/tools/dvsim/tests/alert_test.hjson
vendored
Normal file
20
vendor/lowrisc_ip/dv/tools/dvsim/tests/alert_test.hjson
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
{
|
||||
build_modes: [
|
||||
{
|
||||
name: cover_reg_top
|
||||
}
|
||||
]
|
||||
|
||||
tests: [
|
||||
{
|
||||
name: "{name}_alert_test"
|
||||
build_mode: "cover_reg_top"
|
||||
uvm_test_seq: "{name}_common_vseq"
|
||||
run_opts: ["+run_alert_test", "+en_scb=0"]
|
||||
reseed: 50
|
||||
}
|
||||
]
|
||||
}
|
55
vendor/lowrisc_ip/dv/tools/dvsim/vcs.hjson
vendored
55
vendor/lowrisc_ip/dv/tools/dvsim/vcs.hjson
vendored
|
@ -6,15 +6,13 @@
|
|||
build_ex: "{build_dir}/simv"
|
||||
run_cmd: "{job_prefix} {build_ex}"
|
||||
|
||||
// Indicate the tool specific helper sources - these are copied over to the
|
||||
// {tool_srcs_dir} before running the simulation.
|
||||
tool_srcs: ["{dv_root}/tools/vcs/*"]
|
||||
|
||||
build_opts: ["-sverilog -full64 -licqueue -kdb -ntb_opts uvm-1.2",
|
||||
"-timescale=1ns/1ps",
|
||||
"-Mdir={build_ex}.csrc",
|
||||
"-o {build_ex}",
|
||||
"-f {sv_flist}",
|
||||
// List multiple tops for the simulation. Prepend each top level with `-top`.
|
||||
"{eval_cmd} echo {sim_tops} | sed -E 's/(\\S+)/-top \\1/g'",
|
||||
"+incdir+{build_dir}",
|
||||
// Turn on warnings for non-void functions called with return values ignored
|
||||
"+warn=SV-NFIVC",
|
||||
|
@ -107,7 +105,7 @@
|
|||
supported_wave_formats: ["fsdb", "vpd"]
|
||||
|
||||
// Default tcl script used when running the sim. Override if needed.
|
||||
run_script: "{tool_srcs_dir}/sim.tcl"
|
||||
run_script: "{dv_root}/tools/sim.tcl"
|
||||
|
||||
// Coverage related.
|
||||
cov_db_dir: "{scratch_path}/coverage/{build_mode}.vdb"
|
||||
|
@ -120,7 +118,7 @@
|
|||
// Merging coverage.
|
||||
// "cov_db_dirs" is a special variable that appends all build directories in use.
|
||||
// It is constructed by the tool itself.
|
||||
cov_merge_dir: "{scratch_base_path}/cov_merge"
|
||||
cov_merge_dir: "{scratch_path}/cov_merge"
|
||||
cov_merge_db_dir: "{cov_merge_dir}/merged.vdb"
|
||||
cov_merge_cmd: "{job_prefix} urg"
|
||||
cov_merge_opts: ["-full64",
|
||||
|
@ -132,14 +130,11 @@
|
|||
"-parallel",
|
||||
"-parallel_split 20",
|
||||
// Use cov_db_dirs var for dir args; append -dir in front of each
|
||||
'''{eval_cmd} dirs=`echo {cov_db_dirs}`; dir_args=; \
|
||||
for d in $dirs; do dir_args="$dir_args -dir $d"; done; \
|
||||
echo $dir_args
|
||||
''',
|
||||
"{eval_cmd} echo {cov_db_dirs} | sed -E 's/(\\S+)/-dir \\1/g'",
|
||||
"-dbname {cov_merge_db_dir}"]
|
||||
|
||||
// Generate coverage reports in text as well as html.
|
||||
cov_report_dir: "{scratch_base_path}/cov_report"
|
||||
cov_report_dir: "{scratch_path}/cov_report"
|
||||
cov_report_cmd: "{job_prefix} urg"
|
||||
cov_report_opts: ["-full64",
|
||||
"+urg+lic+wait",
|
||||
|
@ -152,9 +147,43 @@
|
|||
cov_report_txt: "{cov_report_dir}/dashboard.txt"
|
||||
cov_report_page: "dashboard.html"
|
||||
|
||||
// UNR related.
|
||||
// All code coverage, assert isn't supported
|
||||
cov_unr_metrics: "line+cond+fsm+tgl+branch"
|
||||
cov_unr_dir: "{scratch_path}/cov_unr"
|
||||
|
||||
cov_unr_common_build_opts: ["-sverilog -full64 -licqueue -ntb_opts uvm-1.2",
|
||||
"-timescale=1ns/1ps"]
|
||||
|
||||
// Use recommended UUM (Unified usage model) 3 steps flow. The other flow defines macro
|
||||
// "SYNTHESIS", which we have used in design
|
||||
cov_unr_build_cmd: [// Step 1
|
||||
"{job_prefix} vlogan {cov_unr_common_build_opts} &&",
|
||||
// Step 2
|
||||
"{job_prefix} vlogan {cov_unr_common_build_opts}",
|
||||
// grep all defines from {build_opts} from step 2
|
||||
'''{eval_cmd} opts=`echo {build_opts}`; defines=; d=; \
|
||||
for o in $opts; \
|
||||
do \
|
||||
d=`echo $o | grep -o '+define+.*'`; \
|
||||
defines="$defines $d"; \
|
||||
done; \
|
||||
echo $defines
|
||||
''',
|
||||
"-f {sv_flist} &&",
|
||||
// Step 3
|
||||
"{job_prefix} vcs {cov_unr_common_build_opts}"]
|
||||
cov_unr_build_opts: ["-cm {cov_unr_metrics}",
|
||||
"{vcs_cov_cfg_file}",
|
||||
"-unr={vcs_unr_cfg_file}",
|
||||
"{dut}"]
|
||||
|
||||
cov_unr_run_cmd: ["{job_prefix} ./unrSimv"]
|
||||
cov_unr_run_opts: ["-unr"]
|
||||
|
||||
// Analyzing coverage - this is done by invoking --cov-analyze switch. It opens up the
|
||||
// GUI for visual analysis.
|
||||
cov_analyze_dir: "{scratch_base_path}/cov_analyze"
|
||||
cov_analyze_dir: "{scratch_path}/cov_analyze"
|
||||
cov_analyze_cmd: "{job_prefix} verdi"
|
||||
cov_analyze_opts: ["-cov",
|
||||
"-covdir {cov_merge_db_dir}",
|
||||
|
@ -228,7 +257,7 @@
|
|||
{
|
||||
name: vcs_xprop
|
||||
is_sim_mode: 1
|
||||
build_opts: ["-xprop={tool_srcs_dir}/xprop.cfg"]
|
||||
build_opts: ["-xprop={dv_root}/tools/vcs/xprop.cfg"]
|
||||
}
|
||||
{
|
||||
name: vcs_profile
|
||||
|
|
139
vendor/lowrisc_ip/dv/tools/dvsim/verilator.hjson
vendored
Normal file
139
vendor/lowrisc_ip/dv/tools/dvsim/verilator.hjson
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
{
|
||||
// Replicate settings from `common_sim_cfg.hjson`.
|
||||
//
|
||||
// Unfortunately, that file assumes that the tools are invoked natively as
|
||||
// opposed to via FuseSoC. Verilator is setup to be invoked via FuseSoC,
|
||||
// which causes FuseSoC to fail due to unknown {build_opts}. Hence, contents
|
||||
// from `common_sim_cfg.hjson` are replicated here as appropriate.
|
||||
// -- START --
|
||||
dv_root: "{proj_root}/hw/dv"
|
||||
flow: sim
|
||||
flow_makefile: "{dv_root}/tools/dvsim/sim.mk"
|
||||
|
||||
import_cfgs: ["{proj_root}/hw/data/common_project_cfg.hjson",
|
||||
"{dv_root}/tools/dvsim/common_modes.hjson",
|
||||
"{dv_root}/tools/dvsim/fusesoc.hjson",
|
||||
]
|
||||
|
||||
// Default directory structure for the output
|
||||
build_dir: "{scratch_path}/{build_mode}"
|
||||
run_dir_name: "{index}.{test}"
|
||||
run_dir: "{scratch_path}/{run_dir_name}/out"
|
||||
sw_build_dir: "{scratch_path}"
|
||||
sw_root_dir: "{proj_root}/sw"
|
||||
|
||||
regressions: [
|
||||
{
|
||||
name: smoke
|
||||
reseed: 1
|
||||
}
|
||||
{
|
||||
name: all
|
||||
}
|
||||
{
|
||||
name: all_once
|
||||
reseed: 1
|
||||
}
|
||||
{
|
||||
name: nightly
|
||||
}
|
||||
]
|
||||
// -- END --
|
||||
|
||||
build_cmd: "fusesoc {fusesoc_cores_root_dirs} run"
|
||||
ex_name: "{eval_cmd} echo \"{fusesoc_core}\" | cut -d: -f3"
|
||||
run_cmd: "{build_dir}/sim-verilator/V{ex_name}"
|
||||
|
||||
// TODO: Verilator has a few useful build switches. Need to figure out how to
|
||||
// pass them via FuseSoC.
|
||||
|
||||
build_opts: ["--flag=fileset_{design_level}",
|
||||
"--target=sim",
|
||||
"--build-root={build_dir}",
|
||||
"--setup",
|
||||
"--build",
|
||||
"{fusesoc_core}"
|
||||
// "--timescale 1ns/1ps",
|
||||
// Enable all assertions.
|
||||
// "--assert",
|
||||
// Flush streams immediately after all $displays.
|
||||
// "--autoflush",
|
||||
// Enable multi-threading.
|
||||
// "--threads 4",
|
||||
// Randomize all 2-state vars if driven to unknown 'X'.
|
||||
// "--x-assign unique",
|
||||
// "--x-initial unique",
|
||||
]
|
||||
|
||||
run_opts: [// Set random seed.
|
||||
// "+verilator+seed+{seed}",
|
||||
]
|
||||
|
||||
// Supported wave dumping formats (in order of preference).
|
||||
supported_wave_formats: ["fst"]
|
||||
|
||||
// Vars that need to exported to the env.
|
||||
exports: [
|
||||
]
|
||||
|
||||
// pass and fail patterns
|
||||
build_pass_patterns: []
|
||||
build_fail_patterns: [// Verilator compile error.
|
||||
"^%Error.*?:",
|
||||
// FuseSoC build error.
|
||||
"^ERROR:.*$",
|
||||
]
|
||||
run_pass_patterns: ["^TEST PASSED CHECKS$"]
|
||||
run_fail_patterns: [// $warning/error/fatal messages.
|
||||
"^\\[[0-9]+\\] %Warning.*?: ",
|
||||
"^\\[[0-9]+\\] %Error.*?: ",
|
||||
"^\\[[0-9]+\\] %Fatal.*?: ",
|
||||
// Ninja / SW compile failure.
|
||||
"^FAILED: ",
|
||||
" error: ",
|
||||
// Failure signature pattern.
|
||||
"^TEST FAILED CHECKS$"
|
||||
]
|
||||
|
||||
// Coverage related.
|
||||
cov_db_dir: ""
|
||||
cov_db_test_dir: ""
|
||||
|
||||
build_modes: [
|
||||
{
|
||||
name: verilator_waves
|
||||
is_sim_mode: 1
|
||||
// build_opts: ["--trace",
|
||||
// "--trace-fst"
|
||||
// "--trace-structs",
|
||||
// "--trace-params",
|
||||
// "-CFLAGS \"-DVM_TRACE_FMT_FST\"",
|
||||
// ]
|
||||
run_opts: ["--trace"]
|
||||
}
|
||||
// TODO: These need to be fine-tuned.
|
||||
{
|
||||
name: verilator_cov
|
||||
is_sim_mode: 1
|
||||
// build_opts: ["--coverage"]
|
||||
}
|
||||
{
|
||||
name: verilator_xprop
|
||||
is_sim_mode: 1
|
||||
}
|
||||
{
|
||||
name: verilator_profile
|
||||
is_sim_mode: 1
|
||||
// build_opts: ["--prof-cfuncs",
|
||||
// "--prof-threads",
|
||||
// ]
|
||||
}
|
||||
{
|
||||
name: verilator_loopdetect
|
||||
is_sim_mode: 1
|
||||
}
|
||||
]
|
||||
}
|
25
vendor/lowrisc_ip/dv/tools/dvsim/xcelium.hjson
vendored
25
vendor/lowrisc_ip/dv/tools/dvsim/xcelium.hjson
vendored
|
@ -5,10 +5,6 @@
|
|||
build_cmd: "{job_prefix} xrun"
|
||||
run_cmd: "{job_prefix} xrun"
|
||||
|
||||
// Indicate the tool specific helper sources - these are copied over to the
|
||||
// {tool_srcs_dir} before running the simulation.
|
||||
tool_srcs: ["{dv_root}/tools/xcelium/*"]
|
||||
|
||||
build_opts: ["-elaborate -64bit -access +r -sv",
|
||||
"-licqueue",
|
||||
// TODO: duplicate primitives between OT and Ibex #1231
|
||||
|
@ -18,6 +14,11 @@
|
|||
"-f {sv_flist}",
|
||||
"-uvmhome CDNS-1.2",
|
||||
"-xmlibdirname {build_dir}/xcelium.d",
|
||||
// List multiple tops for the simulation. Prepend each top level with `-top`.
|
||||
"{eval_cmd} echo {sim_tops} | sed -E 's/(\\S+)/-top \\1/g'",
|
||||
// Set the top level elaborated entity (snapshot name) correctly since there are
|
||||
// multiple tops.
|
||||
"-snapshot {tb}",
|
||||
// for uvm_hdl_* used by csr backdoor
|
||||
"-access +rw",
|
||||
// Use this to conditionally compile for Xcelium (example: LRM interpretations differ
|
||||
|
@ -33,7 +34,9 @@
|
|||
|
||||
run_opts: ["-input {run_script}",
|
||||
"-licqueue",
|
||||
"-64bit -xmlibdirname {build_dir}/xcelium.d -R",
|
||||
"-64bit -xmlibdirname {build_dir}/xcelium.d",
|
||||
// Use the same snapshot name set during the build step.
|
||||
"-r {tb}",
|
||||
"+SVSEED={seed}",
|
||||
"+UVM_TESTNAME={uvm_test}",
|
||||
"+UVM_TEST_SEQ={uvm_test_seq}",
|
||||
|
@ -63,7 +66,7 @@
|
|||
supported_wave_formats: ["shm", "fsdb", "vcd"]
|
||||
|
||||
// Default tcl script used when running the sim. Override if needed.
|
||||
run_script: "{tool_srcs_dir}/sim.tcl"
|
||||
run_script: "{dv_root}/tools/sim.tcl"
|
||||
|
||||
// Coverage related.
|
||||
// By default, collect all coverage metrics: block:expr:fsm:toggle:functional.
|
||||
|
@ -88,26 +91,26 @@
|
|||
|
||||
// Merging coverage.
|
||||
// It is constructed by the tool itself.
|
||||
cov_merge_dir: "{scratch_base_path}/cov_merge"
|
||||
cov_merge_dir: "{scratch_path}/cov_merge"
|
||||
cov_merge_db_dir: "{cov_merge_dir}/merged"
|
||||
cov_merge_cmd: "{job_prefix} imc"
|
||||
cov_merge_opts: ["-64bit",
|
||||
"-licqueue",
|
||||
"-exec {tool_srcs_dir}/cov_merge.tcl"]
|
||||
"-exec {dv_root}/tools/xcelium/cov_merge.tcl"]
|
||||
|
||||
// Generate covreage reports in text as well as html.
|
||||
cov_report_dir: "{scratch_base_path}/cov_report"
|
||||
cov_report_dir: "{scratch_path}/cov_report"
|
||||
cov_report_cmd: "{job_prefix} imc"
|
||||
cov_report_opts: ["-64bit",
|
||||
"-licqueue",
|
||||
"-exec {tool_srcs_dir}/cov_report.tcl",
|
||||
"-exec {dv_root}/tools/xcelium/cov_report.tcl",
|
||||
"{xcelium_cov_refine_files}"]
|
||||
cov_report_txt: "{cov_report_dir}/cov_report.txt"
|
||||
cov_report_page: "index.html"
|
||||
|
||||
// Analyzing coverage - this is done by invoking --cov-analyze switch. It opens up the
|
||||
// GUI for visual analysis.
|
||||
cov_analyze_dir: "{scratch_base_path}/cov_analyze"
|
||||
cov_analyze_dir: "{scratch_path}/cov_analyze"
|
||||
cov_analyze_cmd: "{job_prefix} imc"
|
||||
cov_analyze_opts: ["-gui",
|
||||
"-64bit",
|
||||
|
|
4
vendor/lowrisc_ip/dv/tools/ralgen/ralgen.py
vendored
4
vendor/lowrisc_ip/dv/tools/ralgen/ralgen.py
vendored
|
@ -99,9 +99,7 @@ def main():
|
|||
f.write("CAPI=2:\n")
|
||||
yaml.dump(ral_pkg_core_text,
|
||||
f,
|
||||
encoding="utf-8",
|
||||
default_flow_style=False,
|
||||
sort_keys=False)
|
||||
encoding="utf-8")
|
||||
print("RAL core file written to {}".format(ral_pkg_core_file))
|
||||
|
||||
|
||||
|
|
12
vendor/lowrisc_ip/dv/tools/sim.tcl
vendored
12
vendor/lowrisc_ip/dv/tools/sim.tcl
vendored
|
@ -6,16 +6,16 @@
|
|||
# VCS syntax: -ucli -do <this file>
|
||||
# Xcelium syntax: -input <this file>
|
||||
|
||||
set tool_srcs_dir ""
|
||||
if {[info exists ::env(TOOL_SRCS_DIR)]} {
|
||||
set tool_srcs_dir "$::env(TOOL_SRCS_DIR)"
|
||||
set dv_root ""
|
||||
if {[info exists ::env(dv_root)]} {
|
||||
set dv_root "$::env(dv_root)"
|
||||
} else {
|
||||
puts "ERROR: Script run without TOOL_SRCS_DIR environment variable."
|
||||
puts "ERROR: Script run without dv_root environment variable."
|
||||
quit
|
||||
}
|
||||
|
||||
source "${tool_srcs_dir}/common.tcl"
|
||||
source "${tool_srcs_dir}/waves.tcl"
|
||||
source "${dv_root}/tools/common.tcl"
|
||||
source "${dv_root}/tools/waves.tcl"
|
||||
|
||||
run
|
||||
quit
|
||||
|
|
23
vendor/lowrisc_ip/dv/tools/vcs/unr.cfg
vendored
Normal file
23
vendor/lowrisc_ip/dv/tools/vcs/unr.cfg
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
-covInput $SCRATCH_PATH/cov_merge/merged.vdb
|
||||
-covDUT $dut_instance
|
||||
|
||||
# Provide the clock specification
|
||||
-clock clk 100
|
||||
# Provide the reset specification: signal_name, active_value, num clk cycles reset to be active
|
||||
-reset rst_n 0 20
|
||||
|
||||
# Black box some of the modules
|
||||
# -blackBoxes -type design *
|
||||
|
||||
# Include common el file, so that it doesn't generate reviewed common exclusions
|
||||
-covEL $dv_root/tools/vcs/common_cov_excl.el
|
||||
|
||||
# Name of the generated exclusion file
|
||||
-save_exclusion $SCRATCH_PATH/cov_unr/unr_exclude.el
|
||||
|
||||
# Enables verbose reporting in addition to summary reporting.
|
||||
-verboseReport
|
|
@ -47,22 +47,17 @@ void VerilatorSimCtrl::SetTop(VerilatedToplevel *top, CData *sig_clk,
|
|||
flags_ = flags;
|
||||
}
|
||||
|
||||
int VerilatorSimCtrl::Exec(int argc, char **argv) {
|
||||
std::pair<int, bool> VerilatorSimCtrl::Exec(int argc, char **argv) {
|
||||
bool exit_app = false;
|
||||
if (!ParseCommandArgs(argc, argv, exit_app)) {
|
||||
return 1;
|
||||
}
|
||||
bool good_cmdline = ParseCommandArgs(argc, argv, exit_app);
|
||||
if (exit_app) {
|
||||
// Successful exit requested by command argument parsing
|
||||
return 0;
|
||||
return std::make_pair(good_cmdline ? 0 : 1, false);
|
||||
}
|
||||
|
||||
RunSimulation();
|
||||
|
||||
if (!WasSimulationSuccessful()) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
int retcode = WasSimulationSuccessful() ? 0 : 1;
|
||||
return std::make_pair(retcode, true);
|
||||
}
|
||||
|
||||
bool VerilatorSimCtrl::ParseCommandArgs(int argc, char **argv, bool &exit_app) {
|
||||
|
@ -88,6 +83,7 @@ bool VerilatorSimCtrl::ParseCommandArgs(int argc, char **argv, bool &exit_app) {
|
|||
if (!tracing_possible_) {
|
||||
std::cerr << "ERROR: Tracing has not been enabled at compile time."
|
||||
<< std::endl;
|
||||
exit_app = true;
|
||||
return false;
|
||||
}
|
||||
TraceOn();
|
||||
|
@ -101,6 +97,7 @@ bool VerilatorSimCtrl::ParseCommandArgs(int argc, char **argv, bool &exit_app) {
|
|||
break;
|
||||
case ':': // missing argument
|
||||
std::cerr << "ERROR: Missing argument." << std::endl << std::endl;
|
||||
exit_app = true;
|
||||
return false;
|
||||
case '?':
|
||||
default:;
|
||||
|
@ -115,6 +112,7 @@ bool VerilatorSimCtrl::ParseCommandArgs(int argc, char **argv, bool &exit_app) {
|
|||
// Parse arguments for all registered extensions
|
||||
for (auto it = extension_array_.begin(); it != extension_array_.end(); ++it) {
|
||||
if (!(*it)->ParseCLIArguments(argc, argv, exit_app)) {
|
||||
exit_app = true;
|
||||
return false;
|
||||
if (exit_app) {
|
||||
return true;
|
||||
|
@ -291,11 +289,16 @@ void VerilatorSimCtrl::Run() {
|
|||
time_begin_ = std::chrono::steady_clock::now();
|
||||
UnsetReset();
|
||||
Trace();
|
||||
|
||||
unsigned long start_reset_cycle_ = initial_reset_delay_cycles_;
|
||||
unsigned long end_reset_cycle_ = start_reset_cycle_ + reset_duration_cycles_;
|
||||
|
||||
while (1) {
|
||||
if (time_ / 2 >= initial_reset_delay_cycles_) {
|
||||
unsigned long cycle_ = time_ / 2;
|
||||
|
||||
if (cycle_ == start_reset_cycle_) {
|
||||
SetReset();
|
||||
}
|
||||
if (time_ / 2 >= reset_duration_cycles_ + initial_reset_delay_cycles_) {
|
||||
} else if (cycle_ == end_reset_cycle_) {
|
||||
UnsetReset();
|
||||
}
|
||||
|
||||
|
|
|
@ -49,15 +49,18 @@ class VerilatorSimCtrl {
|
|||
* 1. Parses a C-style set of command line arguments (see ParseCommandArgs())
|
||||
* 2. Runs the simulation (see RunSimulation())
|
||||
*
|
||||
* @return a main()-compatible process exit code: 0 for success, 1 in case
|
||||
* of an error.
|
||||
* @return a pair with main()-compatible process exit code (0 for success, 1
|
||||
* in case of an error) and a boolean flag telling the calling
|
||||
* function whether the simulation actually ran.
|
||||
*/
|
||||
int Exec(int argc, char **argv);
|
||||
std::pair<int, bool> Exec(int argc, char **argv);
|
||||
|
||||
/**
|
||||
* Parse command line arguments
|
||||
*
|
||||
* Process all recognized command-line arguments from argc/argv.
|
||||
* Process all recognized command-line arguments from argc/argv. If a command
|
||||
* line argument implies that we should exit immediately (like --help), sets
|
||||
* exit_app. On failure, sets exit_app as well as returning false.
|
||||
*
|
||||
* @param argc, argv Standard C command line arguments
|
||||
* @param exit_app Indicate that program should terminate
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue