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:
Philipp Wagner 2021-01-07 15:10:23 +00:00 committed by Philipp Wagner
parent 0199bbae66
commit b1daf9e44e
112 changed files with 3412 additions and 1247 deletions

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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

View 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

View 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

View file

@ -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}

View file

@ -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;

View 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.

View 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

View 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

View file

@ -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"
}

View file

@ -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"

View file

@ -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: []
}
]
}

View file

@ -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

View 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"]
}
]
}

View 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
}
]
}

View file

@ -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

View 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
}
]
}

View file

@ -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",

View file

@ -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))

View file

@ -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
View 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

View file

@ -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();
}

View file

@ -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