lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 1 | // Copyright lowRISC contributors. |
| 2 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| 3 | // SPDX-License-Identifier: Apache-2.0 |
| 4 | |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 5 | `ifdef UVM |
| 6 | `include "uvm_macros.svh" |
| 7 | `endif |
| 8 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 9 | // UVM speficic macros |
| 10 | `ifndef gfn |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 11 | `ifdef UVM |
Srikrishna Iyer | 94b35e5 | 2020-10-12 13:49:28 -0700 | [diff] [blame] | 12 | // verilog_lint: waive macro-name-style |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 13 | `define gfn get_full_name() |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 14 | `else |
| 15 | // verilog_lint: waive macro-name-style |
| 16 | `define gfn $sformatf("%m") |
| 17 | `endif |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 18 | `endif |
| 19 | |
| 20 | `ifndef gtn |
Srikrishna Iyer | 94b35e5 | 2020-10-12 13:49:28 -0700 | [diff] [blame] | 21 | // verilog_lint: waive macro-name-style |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 22 | `define gtn get_type_name() |
| 23 | `endif |
| 24 | |
| 25 | `ifndef gn |
Srikrishna Iyer | 94b35e5 | 2020-10-12 13:49:28 -0700 | [diff] [blame] | 26 | // verilog_lint: waive macro-name-style |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 27 | `define gn get_name() |
| 28 | `endif |
| 29 | |
| 30 | `ifndef gmv |
Srikrishna Iyer | 94b35e5 | 2020-10-12 13:49:28 -0700 | [diff] [blame] | 31 | // verilog_lint: waive macro-name-style |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 32 | `define gmv(csr) csr.get_mirrored_value() |
| 33 | `endif |
| 34 | |
| 35 | // cast base class obj holding extended class handle to extended class handle; |
| 36 | // throw error if cast fails |
| 37 | `ifndef downcast |
Srikrishna Iyer | 94b35e5 | 2020-10-12 13:49:28 -0700 | [diff] [blame] | 38 | // verilog_lint: waive macro-name-style |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 39 | `define downcast(EXT_, BASE_, MSG_="", SEV_=fatal, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 40 | begin \ |
| 41 | if (!$cast(EXT_, BASE_)) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 42 | `dv_``SEV_($sformatf({"Cast failed: base class variable %0s ", \ |
| 43 | "does not hold extended class %0s handle %s"}, \ |
| 44 | `"BASE_`", `"EXT_`", MSG_), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 45 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 46 | end |
| 47 | `endif |
| 48 | |
| 49 | // Note, UVM provides a macro `uvm_new_func -- which only applies to uvm_components |
| 50 | `ifndef uvm_object_new |
| 51 | `define uvm_object_new \ |
| 52 | function new (string name=""); \ |
| 53 | super.new(name); \ |
| 54 | endfunction : new |
| 55 | `endif |
| 56 | |
| 57 | `ifndef uvm_create_obj |
| 58 | `define uvm_create_obj(_type_name_, _inst_name_) \ |
| 59 | _inst_name_ = _type_name_::type_id::create(`"_inst_name_`"); |
| 60 | `endif |
| 61 | |
| 62 | `ifndef uvm_component_new |
| 63 | `define uvm_component_new \ |
| 64 | function new (string name="", uvm_component parent=null); \ |
| 65 | super.new(name, parent); \ |
| 66 | endfunction : new |
| 67 | `endif |
| 68 | |
| 69 | `ifndef uvm_create_comp |
| 70 | `define uvm_create_comp(_type_name_, _inst_name_) \ |
| 71 | _inst_name_ = _type_name_::type_id::create(`"_inst_name_`", this); |
| 72 | `endif |
| 73 | |
Srikrishna Iyer | b7d0202 | 2020-09-29 07:46:30 -0700 | [diff] [blame] | 74 | // Convert arbitrary text / expression to string. |
| 75 | `ifndef DV_STRINGIFY |
| 76 | `define DV_STRINGIFY(I_) `"I_`" |
| 77 | `endif |
| 78 | |
Weicai Yang | fbf2edc | 2021-09-27 15:31:08 -0700 | [diff] [blame^] | 79 | `ifndef DUT_HIER_STR |
| 80 | `define DUT_HIER_STR `DV_STRINGIFY(`DUT_HIER) |
| 81 | `endif |
| 82 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 83 | // Common check macros used by DV_CHECK error and fatal macros. |
| 84 | // Note: Should not be called by user code |
| 85 | `ifndef DV_CHECK |
| 86 | `define DV_CHECK(T_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 87 | begin \ |
| 88 | if (!(T_)) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 89 | `dv_``SEV_($sformatf("Check failed (%s) %s ", `"T_`", MSG_), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 90 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 91 | end |
| 92 | `endif |
| 93 | |
| 94 | `ifndef DV_CHECK_EQ |
| 95 | `define DV_CHECK_EQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 96 | begin \ |
Weicai Yang | 8c9b8d9 | 2020-10-19 17:47:03 -0700 | [diff] [blame] | 97 | if (!((ACT_) == (EXP_))) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 98 | `dv_``SEV_($sformatf("Check failed %s == %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \ |
| 99 | `"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 100 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 101 | end |
| 102 | `endif |
| 103 | |
| 104 | `ifndef DV_CHECK_NE |
| 105 | `define DV_CHECK_NE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 106 | begin \ |
Weicai Yang | 8c9b8d9 | 2020-10-19 17:47:03 -0700 | [diff] [blame] | 107 | if (!((ACT_) != (EXP_))) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 108 | `dv_``SEV_($sformatf("Check failed %s != %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \ |
| 109 | `"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 110 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 111 | end |
| 112 | `endif |
| 113 | |
| 114 | `ifndef DV_CHECK_CASE_EQ |
| 115 | `define DV_CHECK_CASE_EQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 116 | begin \ |
Weicai Yang | 8c9b8d9 | 2020-10-19 17:47:03 -0700 | [diff] [blame] | 117 | if (!((ACT_) === (EXP_))) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 118 | `dv_``SEV_($sformatf("Check failed %s === %s (0x%0h [%0b] vs 0x%0h [%0b]) %s", \ |
| 119 | `"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 120 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 121 | end |
| 122 | `endif |
| 123 | |
| 124 | `ifndef DV_CHECK_CASE_NE |
| 125 | `define DV_CHECK_CASE_NE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 126 | begin \ |
Weicai Yang | 8c9b8d9 | 2020-10-19 17:47:03 -0700 | [diff] [blame] | 127 | if (!((ACT_) !== (EXP_))) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 128 | `dv_``SEV_($sformatf("Check failed %s !== %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \ |
| 129 | `"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 130 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 131 | end |
| 132 | `endif |
| 133 | |
| 134 | `ifndef DV_CHECK_LT |
| 135 | `define DV_CHECK_LT(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 136 | begin \ |
Weicai Yang | 8c9b8d9 | 2020-10-19 17:47:03 -0700 | [diff] [blame] | 137 | if (!((ACT_) < (EXP_))) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 138 | `dv_``SEV_($sformatf("Check failed %s < %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \ |
| 139 | `"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 140 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 141 | end |
| 142 | `endif |
| 143 | |
| 144 | `ifndef DV_CHECK_GT |
| 145 | `define DV_CHECK_GT(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 146 | begin \ |
Weicai Yang | 8c9b8d9 | 2020-10-19 17:47:03 -0700 | [diff] [blame] | 147 | if (!((ACT_) > (EXP_))) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 148 | `dv_``SEV_($sformatf("Check failed %s > %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \ |
| 149 | `"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 150 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 151 | end |
| 152 | `endif |
| 153 | |
| 154 | `ifndef DV_CHECK_LE |
| 155 | `define DV_CHECK_LE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 156 | begin \ |
Weicai Yang | 8c9b8d9 | 2020-10-19 17:47:03 -0700 | [diff] [blame] | 157 | if (!((ACT_) <= (EXP_))) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 158 | `dv_``SEV_($sformatf("Check failed %s <= %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \ |
| 159 | `"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 160 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 161 | end |
| 162 | `endif |
| 163 | |
| 164 | `ifndef DV_CHECK_GE |
| 165 | `define DV_CHECK_GE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 166 | begin \ |
Weicai Yang | 8c9b8d9 | 2020-10-19 17:47:03 -0700 | [diff] [blame] | 167 | if (!((ACT_) >= (EXP_))) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 168 | `dv_``SEV_($sformatf("Check failed %s >= %s (%0d [0x%0h] vs %0d [0x%0h]) %s", \ |
| 169 | `"ACT_`", `"EXP_`", ACT_, ACT_, EXP_, EXP_, MSG_), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 170 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 171 | end |
| 172 | `endif |
| 173 | |
Srikrishna Iyer | 2e6b627 | 2020-10-14 11:01:17 -0700 | [diff] [blame] | 174 | `ifndef DV_CHECK_STREQ |
| 175 | `define DV_CHECK_STREQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 8c9b8d9 | 2020-10-19 17:47:03 -0700 | [diff] [blame] | 176 | if (!((ACT_) == (EXP_))) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 177 | `dv_``SEV_($sformatf("Check failed \"%s\" == \"%s\" %s", ACT_, EXP_, MSG_), ID_) \ |
Srikrishna Iyer | 2e6b627 | 2020-10-14 11:01:17 -0700 | [diff] [blame] | 178 | end |
| 179 | `endif |
| 180 | |
| 181 | `ifndef DV_CHECK_STRNE |
| 182 | `define DV_CHECK_STRNE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Weicai Yang | 8c9b8d9 | 2020-10-19 17:47:03 -0700 | [diff] [blame] | 183 | if (!((ACT_) != (EXP_))) begin \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 184 | `dv_``SEV_($sformatf("Check failed \"%s\" != \"%s\" %s", ACT_, EXP_, MSG_), ID_) \ |
Srikrishna Iyer | 2e6b627 | 2020-10-14 11:01:17 -0700 | [diff] [blame] | 185 | end |
| 186 | `endif |
| 187 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 188 | // Fatal version of the checks |
| 189 | `ifndef DV_CHECK_FATAL |
| 190 | `define DV_CHECK_FATAL(T_, MSG_="", ID_=`gfn) \ |
| 191 | `DV_CHECK(T_, MSG_, fatal, ID_) |
| 192 | `endif |
| 193 | |
| 194 | `ifndef DV_CHECK_EQ_FATAL |
| 195 | `define DV_CHECK_EQ_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 196 | `DV_CHECK_EQ(ACT_, EXP_, MSG_, fatal, ID_) |
| 197 | `endif |
| 198 | |
| 199 | `ifndef DV_CHECK_NE_FATAL |
| 200 | `define DV_CHECK_NE_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 201 | `DV_CHECK_NE(ACT_, EXP_, MSG_, fatal, ID_) |
| 202 | `endif |
| 203 | |
| 204 | `ifndef DV_CHECK_LT_FATAL |
| 205 | `define DV_CHECK_LT_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 206 | `DV_CHECK_LT(ACT_, EXP_, MSG_, fatal, ID_) |
| 207 | `endif |
| 208 | |
| 209 | `ifndef DV_CHECK_GT_FATAL |
| 210 | `define DV_CHECK_GT_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 211 | `DV_CHECK_GT(ACT_, EXP_, MSG_, fatal, ID_) |
| 212 | `endif |
| 213 | |
| 214 | `ifndef DV_CHECK_LE_FATAL |
| 215 | `define DV_CHECK_LE_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 216 | `DV_CHECK_LE(ACT_, EXP_, MSG_, fatal, ID_) |
| 217 | `endif |
| 218 | |
| 219 | `ifndef DV_CHECK_GE_FATAL |
| 220 | `define DV_CHECK_GE_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 221 | `DV_CHECK_GE(ACT_, EXP_, MSG_, fatal, ID_) |
| 222 | `endif |
| 223 | |
Srikrishna Iyer | 2e6b627 | 2020-10-14 11:01:17 -0700 | [diff] [blame] | 224 | `ifndef DV_CHECK_STREQ_FATAL |
| 225 | `define DV_CHECK_STREQ_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 226 | `DV_CHECK_STREQ(ACT_, EXP_, MSG_, fatal, ID_) |
| 227 | `endif |
| 228 | |
| 229 | `ifndef DV_CHECK_STRNE_FATAL |
| 230 | `define DV_CHECK_STRNE_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 231 | `DV_CHECK_STRNE(ACT_, EXP_, MSG_, fatal, ID_) |
| 232 | `endif |
| 233 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 234 | // Shorthand for common foo.randomize() + fatal check |
| 235 | `ifndef DV_CHECK_RANDOMIZE_FATAL |
| 236 | `define DV_CHECK_RANDOMIZE_FATAL(VAR_, MSG_="Randomization failed!", ID_=`gfn) \ |
| 237 | `DV_CHECK_FATAL(VAR_.randomize(), MSG_, ID_) |
| 238 | `endif |
| 239 | |
| 240 | // Shorthand for common foo.randomize() with { } + fatal check |
| 241 | `ifndef DV_CHECK_RANDOMIZE_WITH_FATAL |
| 242 | `define DV_CHECK_RANDOMIZE_WITH_FATAL(VAR_, WITH_C_, MSG_="Randomization failed!", ID_=`gfn) \ |
| 243 | `DV_CHECK_FATAL(VAR_.randomize() with {WITH_C_}, MSG_, ID_) |
| 244 | `endif |
| 245 | |
| 246 | // Shorthand for common std::randomize(foo) + fatal check |
| 247 | `ifndef DV_CHECK_STD_RANDOMIZE_FATAL |
| 248 | `define DV_CHECK_STD_RANDOMIZE_FATAL(VAR_, MSG_="Randomization failed!", ID_=`gfn) \ |
| 249 | `DV_CHECK_FATAL(std::randomize(VAR_), MSG_, ID_) |
| 250 | `endif |
| 251 | |
| 252 | // Shorthand for common std::randomize(foo) with { } + fatal check |
| 253 | `ifndef DV_CHECK_STD_RANDOMIZE_WITH_FATAL |
Gaurang Chitroda | 556c3d7 | 2019-10-14 11:56:28 -0700 | [diff] [blame] | 254 | `define DV_CHECK_STD_RANDOMIZE_WITH_FATAL(VAR_, WITH_C_, MSG_="Randomization failed!",ID_=`gfn) \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 255 | `DV_CHECK_FATAL(std::randomize(VAR_) with {WITH_C_}, MSG_, ID_) |
| 256 | `endif |
| 257 | |
Srikrishna Iyer | 17cf252 | 2020-09-29 07:41:19 -0700 | [diff] [blame] | 258 | // Shorthand for common cls_inst.randomize(member) + fatal check |
| 259 | // Randomizes a specific member of a class instance. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 260 | `ifndef DV_CHECK_MEMBER_RANDOMIZE_FATAL |
Srikrishna Iyer | 17cf252 | 2020-09-29 07:41:19 -0700 | [diff] [blame] | 261 | `define DV_CHECK_MEMBER_RANDOMIZE_FATAL(VAR_, CLS_INST_=this, MSG_="Randomization failed!", ID_=`gfn) \ |
| 262 | `DV_CHECK_FATAL(CLS_INST_.randomize(VAR_), MSG_, ID_) |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 263 | `endif |
| 264 | |
Srikrishna Iyer | 17cf252 | 2020-09-29 07:41:19 -0700 | [diff] [blame] | 265 | // Shorthand for common cls_inst.randomize(member) with { } + fatal check |
| 266 | // Randomizes a specific member of a class instance with inline constraints. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 267 | `ifndef DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL |
Srikrishna Iyer | 17cf252 | 2020-09-29 07:41:19 -0700 | [diff] [blame] | 268 | `define DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(VAR_, C_, CLS_INST_=this, MSG_="Randomization failed!", ID_=`gfn) \ |
| 269 | `DV_CHECK_FATAL(CLS_INST_.randomize(VAR_) with {C_}, MSG_, ID_) |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 270 | `endif |
| 271 | |
| 272 | // print static/dynamic 1d array or queue |
| 273 | `ifndef DV_PRINT_ARR_CONTENTS |
Srikrishna Iyer | 89790f8 | 2021-01-22 20:49:52 -0800 | [diff] [blame] | 274 | `define DV_PRINT_ARR_CONTENTS(ARR_, V_=uvm_pkg::UVM_MEDIUM, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 275 | begin \ |
| 276 | foreach (ARR_[i]) begin \ |
Guillermo Maturana | dcee03a | 2021-04-16 14:52:24 -0700 | [diff] [blame] | 277 | `dv_info($sformatf("%s[%0d] = %0d (0x%0h)", `"ARR_`", i, ARR_[i], ARR_[i]), V_, ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 278 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 279 | end |
| 280 | `endif |
| 281 | |
| 282 | // print non-empty tlm fifos that were uncompared at end of test |
| 283 | `ifndef DV_EOT_PRINT_TLM_FIFO_CONTENTS |
| 284 | `define DV_EOT_PRINT_TLM_FIFO_CONTENTS(TYP_, FIFO_, SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 285 | begin \ |
| 286 | while (!FIFO_.is_empty()) begin \ |
| 287 | TYP_ item; \ |
| 288 | void'(FIFO_.try_get(item)); \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 289 | `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"FIFO_`", item.sprint()), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 290 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 291 | end |
| 292 | `endif |
| 293 | |
| 294 | // print non-empty tlm fifos that were uncompared at end of test |
| 295 | `ifndef DV_EOT_PRINT_TLM_FIFO_ARR_CONTENTS |
| 296 | `define DV_EOT_PRINT_TLM_FIFO_ARR_CONTENTS(TYP_, FIFO_, SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 297 | begin \ |
| 298 | foreach (FIFO_[i]) begin \ |
| 299 | while (!FIFO_[i].is_empty()) begin \ |
| 300 | TYP_ item; \ |
| 301 | void'(FIFO_[i].try_get(item)); \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 302 | `dv_``SEV_($sformatf("%s[%0d] item uncompared:\n%s", `"FIFO_`", i, item.sprint()), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 303 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 304 | end \ |
| 305 | end |
| 306 | `endif |
| 307 | |
| 308 | // print non-empty tlm fifos that were uncompared at end of test |
| 309 | `ifndef DV_EOT_PRINT_Q_CONTENTS |
| 310 | `define DV_EOT_PRINT_Q_CONTENTS(TYP_, Q_, SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 311 | begin \ |
| 312 | while (Q_.size() != 0) begin \ |
| 313 | TYP_ item = Q_.pop_front(); \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 314 | `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"Q_`", item.sprint()), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 315 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 316 | end |
| 317 | `endif |
| 318 | |
| 319 | // print non-empty tlm fifos that were uncompared at end of test |
| 320 | `ifndef DV_EOT_PRINT_Q_ARR_CONTENTS |
| 321 | `define DV_EOT_PRINT_Q_ARR_CONTENTS(TYP_, Q_, SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 322 | begin \ |
| 323 | foreach (Q_[i]) begin \ |
| 324 | while (Q_[i].size() != 0) begin \ |
| 325 | TYP_ item = Q_[i].pop_front(); \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 326 | `dv_``SEV_($sformatf("%s[%0d] item uncompared:\n%s", `"Q_`", i, item.sprint()), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 327 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 328 | end \ |
| 329 | end |
| 330 | `endif |
| 331 | |
Rasmus Madsen | 1f2bfb7 | 2020-01-22 12:32:15 -0800 | [diff] [blame] | 332 | // check for non-empty mailbox and print items that were uncompared at end of test |
| 333 | `ifndef DV_EOT_PRINT_MAILBOX_CONTENTS |
| 334 | `define DV_EOT_PRINT_MAILBOX_CONTENTS(TYP_, MAILBOX_, SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 335 | begin \ |
| 336 | while (MAILBOX_.num() != 0) begin \ |
| 337 | TYP_ item; \ |
| 338 | void'(MAILBOX_.try_get(item)); \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 339 | `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"MAILBOX_`", item.sprint()), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 340 | end \ |
Rasmus Madsen | 1f2bfb7 | 2020-01-22 12:32:15 -0800 | [diff] [blame] | 341 | end |
| 342 | `endif |
| 343 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 344 | // get parity - implemented as a macro so that it can be invoked in constraints as well |
| 345 | `ifndef GET_PARITY |
| 346 | `define GET_PARITY(val, odd=0) (^val ^ odd) |
| 347 | `endif |
| 348 | |
Srikrishna Iyer | 134ab75 | 2020-09-29 08:07:57 -0700 | [diff] [blame] | 349 | // Wait a task or statement with exit condition |
| 350 | // Kill the thread when either the wait statement is completed or exit condition occurs |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 351 | // input WAIT_ need to be a statement. Here are some examples |
| 352 | // `DV_SPINWAIT(wait(...);, "Wait for ...") |
| 353 | // `DV_SPINWAIT( |
| 354 | // while (1) begin |
| 355 | // ... |
| 356 | // end) |
Weicai Yang | aa8ed45 | 2020-08-14 10:19:58 -0700 | [diff] [blame] | 357 | `ifndef DV_SPINWAIT_EXIT |
| 358 | `define DV_SPINWAIT_EXIT(WAIT_, EXIT_, MSG_ = "exit condition occurred!", ID_ =`gfn) \ |
| 359 | begin \ |
| 360 | fork begin \ |
| 361 | fork \ |
| 362 | begin \ |
| 363 | WAIT_ \ |
| 364 | end \ |
| 365 | begin \ |
| 366 | EXIT_ \ |
| 367 | if (MSG_ != "") begin \ |
Srikrishna Iyer | 89790f8 | 2021-01-22 20:49:52 -0800 | [diff] [blame] | 368 | `dv_info(MSG_, uvm_pkg::UVM_HIGH, ID_) \ |
Weicai Yang | aa8ed45 | 2020-08-14 10:19:58 -0700 | [diff] [blame] | 369 | end \ |
| 370 | end \ |
| 371 | join_any \ |
| 372 | disable fork; \ |
| 373 | end join \ |
| 374 | end |
| 375 | `endif |
Srikrishna Iyer | b7d0202 | 2020-09-29 07:46:30 -0700 | [diff] [blame] | 376 | |
Srikrishna Iyer | 134ab75 | 2020-09-29 08:07:57 -0700 | [diff] [blame] | 377 | // wait a task or statement with timer watchdog |
| 378 | `ifndef DV_SPINWAIT |
| 379 | `define DV_SPINWAIT(WAIT_, MSG_ = "timeout occurred!", TIMEOUT_NS_ = default_spinwait_timeout_ns, ID_ =`gfn) \ |
| 380 | `DV_SPINWAIT_EXIT(WAIT_, wait_timeout(TIMEOUT_NS_, ID_, MSG_);, "", ID_) |
| 381 | `endif |
| 382 | |
Srikrishna Iyer | b7d0202 | 2020-09-29 07:46:30 -0700 | [diff] [blame] | 383 | // Control assertions in the DUT. |
| 384 | // |
| 385 | // This macro is invoked in top level testbench that instantiates the DUT. It spawns off an initial |
| 386 | // block that forever waits for a resource of type bit named by the string arg ~LABEL_~ that |
| 387 | // can be set by any entity in the testbench. Based on the value set, it enables or disables the |
| 388 | // assertions at the hierarchy of the provided path. The entity setting the resource value invokes |
| 389 | // uvm_config_db#(bit)::set(...) and this macro calls the corresponding get. |
| 390 | // |
| 391 | // LABEL_ : Name of the assertion control resource bit (string). |
| 392 | // HIER_ : Path to the module within which the assertion is controlled. |
| 393 | // LEVELS_: Number of levels within the module to control the assertions. |
| 394 | // SCOPE_ : Hierarchical string path to the testbench where this macro is invoked, example: %m. |
| 395 | // ID_ : Identifier string used for UVM logs. |
| 396 | `ifndef DV_ASSERT_CTRL |
Srikrishna Iyer | aca5539 | 2021-10-16 02:22:01 -0700 | [diff] [blame] | 397 | `define DV_ASSERT_CTRL(LABEL_, HIER_, LEVELS_ = 0, SCOPE_ = "", ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | b7d0202 | 2020-09-29 07:46:30 -0700 | [diff] [blame] | 398 | initial begin \ |
| 399 | bit assert_en; \ |
| 400 | forever begin \ |
| 401 | uvm_config_db#(bit)::wait_modified(null, SCOPE_, LABEL_); \ |
| 402 | if (!uvm_config_db#(bit)::get(null, SCOPE_, LABEL_, assert_en)) begin \ |
| 403 | `uvm_fatal(ID_, $sformatf("Failed to get \"%0s\" from uvm_config_db", LABEL_)) \ |
| 404 | end \ |
| 405 | if (assert_en) begin \ |
| 406 | `uvm_info(ID_, $sformatf("Enabling assertions: %0s", `DV_STRINGIFY(HIER_)), UVM_LOW) \ |
| 407 | $asserton(LEVELS_, HIER_); \ |
| 408 | end else begin \ |
| 409 | `uvm_info(ID_, $sformatf("Disabling assertions: %0s", `DV_STRINGIFY(HIER_)), UVM_LOW) \ |
| 410 | $assertoff(LEVELS_, HIER_); \ |
| 411 | end \ |
| 412 | end \ |
| 413 | end |
| 414 | `endif |
| 415 | |
Weicai Yang | f11eeac | 2021-08-04 18:39:06 -0700 | [diff] [blame] | 416 | // This macro converts a string input from plusarg to an enum variable |
| 417 | // ENUM_: the name of enum type |
| 418 | // PLUSARG_: the name of the plusargs, which is also the name of the enum variable |
| 419 | // CHECK_EXIST_: set to 1, `$value$plusargs()` should return true |
| 420 | `ifndef DV_GET_ENUM_PLUSARG |
| 421 | `define DV_GET_ENUM_PLUSARG(ENUM_, PLUSARG_, CHECK_EXIST_ = 0, ID_ = `gfn) \ |
| 422 | begin \ |
| 423 | string str; \ |
| 424 | if ($value$plusargs("``PLUSARG_``=%0s", str)) begin \ |
| 425 | if (!uvm_enum_wrapper#(ENUM_)::from_name(str, PLUSARG_)) begin \ |
| 426 | `uvm_fatal(ID_, $sformatf("Cannot find %s from enum ``ENUM_``", PLUSARG_.name)) \ |
| 427 | end \ |
| 428 | end else if (CHECK_EXIST_) begin \ |
| 429 | `uvm_fatal(ID_, "Can't find plusargs ``PLUSARG_``") \ |
| 430 | end \ |
| 431 | end |
| 432 | `endif |
| 433 | |
Srikrishna Iyer | b7d0202 | 2020-09-29 07:46:30 -0700 | [diff] [blame] | 434 | // Enable / disable assertions at a module hierarchy identified by LABEL_. |
| 435 | // |
| 436 | // This goes in conjunction with `DV_ASSERT_CTRL() macro above, but is invoked in the entity that is |
| 437 | // sending the req to turn on / off the assertions. Note that that piece of code invoking this macro |
| 438 | // does not have the information on the actual hierarchical path to the module or the levels - this |
| 439 | // is 'wrapped' into the LABEL_ instead. DV user needs to uniquify the label sufficienly enough to |
| 440 | // reflect it. |
| 441 | // |
| 442 | // LABEL_ : Name of the assertion control resource bit (string). |
| 443 | // VALUE_ : Value of the control bit - 1 - enable assertions, 0 - disable assertions. |
| 444 | // SCOPE_ : Hierarchical string path to the testbench where this macro is invoked, example: %m. |
| 445 | `ifndef DV_ASSERT_CTRL_REQ |
| 446 | `define DV_ASSERT_CTRL_REQ(LABEL_, VALUE_, SCOPE_="") \ |
| 447 | begin \ |
| 448 | uvm_config_db#(bit)::set(null, SCOPE_, LABEL_, VALUE_); \ |
| 449 | end |
| 450 | `endif |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 451 | |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 452 | // Macros for logging (info, warning, error and fatal severities). |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 453 | // |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 454 | // These are meant to be invoked in modules and interfaces that are shared between DV and Verilator |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 455 | // testbenches. We waive the lint requirement for these to be in uppercase, since they are |
| 456 | // UVM-adjacent. |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 457 | `ifdef UVM |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 458 | `ifndef dv_info |
| 459 | // verilog_lint: waive macro-name-style |
Srikrishna Iyer | 89790f8 | 2021-01-22 20:49:52 -0800 | [diff] [blame] | 460 | `define dv_info(MSG_, VERBOSITY_ = uvm_pkg::UVM_LOW, ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 461 | if (uvm_pkg::uvm_report_enabled(VERBOSITY_, uvm_pkg::UVM_INFO, ID_)) begin \ |
| 462 | uvm_pkg::uvm_report_info(ID_, MSG_, VERBOSITY_, `uvm_file, `uvm_line, "", 1); \ |
| 463 | end |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 464 | `endif |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 465 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 466 | `ifndef dv_warning |
| 467 | // verilog_lint: waive macro-name-style |
| 468 | `define dv_warning(MSG_, ID_ = $sformatf("%m")) \ |
| 469 | if (uvm_pkg::uvm_report_enabled(uvm_pkg::UVM_NONE, uvm_pkg::UVM_WARNING, ID_)) begin \ |
| 470 | uvm_pkg::uvm_report_warning(ID_, MSG_, uvm_pkg::UVM_NONE, `uvm_file, `uvm_line, "", 1); \ |
| 471 | end |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 472 | `endif |
| 473 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 474 | `ifndef dv_error |
| 475 | // verilog_lint: waive macro-name-style |
| 476 | `define dv_error(MSG_, ID_ = $sformatf("%m")) \ |
| 477 | if (uvm_pkg::uvm_report_enabled(uvm_pkg::UVM_NONE, uvm_pkg::UVM_ERROR, ID_)) begin \ |
| 478 | uvm_pkg::uvm_report_error(ID_, MSG_, uvm_pkg::UVM_NONE, `uvm_file, `uvm_line, "", 1); \ |
| 479 | end |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 480 | `endif |
| 481 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 482 | `ifndef dv_fatal |
| 483 | // verilog_lint: waive macro-name-style |
| 484 | `define dv_fatal(MSG_, ID_ = $sformatf("%m")) \ |
| 485 | if (uvm_pkg::uvm_report_enabled(uvm_pkg::UVM_NONE, uvm_pkg::UVM_FATAL, ID_)) begin \ |
| 486 | uvm_pkg::uvm_report_fatal(ID_, MSG_, uvm_pkg::UVM_NONE, `uvm_file, `uvm_line, "", 1); \ |
| 487 | end |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 488 | `endif |
| 489 | |
| 490 | `else // UVM |
| 491 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 492 | `ifndef dv_info |
| 493 | // verilog_lint: waive macro-name-style |
| 494 | `define dv_info(MSG_, VERBOSITY = DUMMY_, ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 495 | $display("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_); |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 496 | `endif |
| 497 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 498 | `ifndef dv_warning |
| 499 | // verilog_lint: waive macro-name-style |
| 500 | `define dv_warning(MSG_, ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 501 | $warning("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_); |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 502 | `endif |
| 503 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 504 | `ifndef dv_error |
| 505 | // verilog_lint: waive macro-name-style |
| 506 | `define dv_error(MSG_, ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 507 | $error("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_); |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 508 | `endif |
| 509 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 510 | `ifndef dv_fatal |
| 511 | // verilog_lint: waive macro-name-style |
| 512 | `define dv_fatal(MSG_, ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 513 | $fatal("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_); |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 514 | `endif |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 515 | |
| 516 | `endif // UVM |
Weicai Yang | fc36219 | 2021-08-13 15:55:14 -0700 | [diff] [blame] | 517 | |
| 518 | // Macros for constrain clk with common frequencies |
| 519 | // constrain clock to run at 24Mhz - 100Mhz and use higher weights on 24, 25, 48, 50, 100 |
| 520 | `ifndef DV_COMMON_CLK_CONSTRAINT |
| 521 | `define DV_COMMON_CLK_CONSTRAINT(FREQ_) \ |
| 522 | FREQ_ dist { \ |
| 523 | [24:25] :/ 2, \ |
| 524 | [26:47] :/ 1, \ |
| 525 | [48:50] :/ 2, \ |
| 526 | [51:95] :/ 1, \ |
| 527 | 96 :/ 1, \ |
| 528 | [97:99] :/ 1, \ |
| 529 | 100 :/ 1 \ |
| 530 | }; |
| 531 | `endif |