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 \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 88 | if (T_) ; else 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 \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 97 | if ((ACT_) == (EXP_)) ; else 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 \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 107 | if ((ACT_) != (EXP_)) ; else 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 \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 117 | if ((ACT_) === (EXP_)) ; else 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 \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 127 | if ((ACT_) !== (EXP_)) ; else 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 \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 137 | if ((ACT_) < (EXP_)) ; else 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 \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 147 | if ((ACT_) > (EXP_)) ; else 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 \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 157 | if ((ACT_) <= (EXP_)) ; else 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 \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 167 | if ((ACT_) >= (EXP_)) ; else 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) \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 176 | begin \ |
| 177 | if ((ACT_) == (EXP_)) ; else begin \ |
| 178 | `dv_``SEV_($sformatf("Check failed \"%s\" == \"%s\" %s", ACT_, EXP_, MSG_), ID_) \ |
| 179 | end \ |
Srikrishna Iyer | 2e6b627 | 2020-10-14 11:01:17 -0700 | [diff] [blame] | 180 | end |
| 181 | `endif |
| 182 | |
| 183 | `ifndef DV_CHECK_STRNE |
| 184 | `define DV_CHECK_STRNE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 185 | begin \ |
| 186 | if ((ACT_) != (EXP_)) ; else begin \ |
| 187 | `dv_``SEV_($sformatf("Check failed \"%s\" != \"%s\" %s", ACT_, EXP_, MSG_), ID_) \ |
| 188 | end \ |
Srikrishna Iyer | 2e6b627 | 2020-10-14 11:01:17 -0700 | [diff] [blame] | 189 | end |
| 190 | `endif |
| 191 | |
Weicai Yang | 9dfff8f | 2022-09-21 23:18:39 -0700 | [diff] [blame] | 192 | `ifndef DV_CHECK_Q_EQ |
| 193 | `define DV_CHECK_Q_EQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \ |
| 194 | begin \ |
Srikrishna Iyer | 1901fcd | 2022-10-12 16:03:38 -0700 | [diff] [blame] | 195 | `DV_CHECK_EQ(ACT_.size(), EXP_.size(), MSG_, SEV_, ID_) \ |
| 196 | foreach (ACT_[i]) begin \ |
| 197 | `DV_CHECK_EQ(ACT_[i], EXP_[i], $sformatf("for i = %0d %s", i, MSG_), SEV_, ID_) \ |
Weicai Yang | 9dfff8f | 2022-09-21 23:18:39 -0700 | [diff] [blame] | 198 | end \ |
| 199 | end |
| 200 | `endif |
| 201 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 202 | // Fatal version of the checks |
| 203 | `ifndef DV_CHECK_FATAL |
| 204 | `define DV_CHECK_FATAL(T_, MSG_="", ID_=`gfn) \ |
| 205 | `DV_CHECK(T_, MSG_, fatal, ID_) |
| 206 | `endif |
| 207 | |
| 208 | `ifndef DV_CHECK_EQ_FATAL |
| 209 | `define DV_CHECK_EQ_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 210 | `DV_CHECK_EQ(ACT_, EXP_, MSG_, fatal, ID_) |
| 211 | `endif |
| 212 | |
| 213 | `ifndef DV_CHECK_NE_FATAL |
| 214 | `define DV_CHECK_NE_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 215 | `DV_CHECK_NE(ACT_, EXP_, MSG_, fatal, ID_) |
| 216 | `endif |
| 217 | |
| 218 | `ifndef DV_CHECK_LT_FATAL |
| 219 | `define DV_CHECK_LT_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 220 | `DV_CHECK_LT(ACT_, EXP_, MSG_, fatal, ID_) |
| 221 | `endif |
| 222 | |
| 223 | `ifndef DV_CHECK_GT_FATAL |
| 224 | `define DV_CHECK_GT_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 225 | `DV_CHECK_GT(ACT_, EXP_, MSG_, fatal, ID_) |
| 226 | `endif |
| 227 | |
| 228 | `ifndef DV_CHECK_LE_FATAL |
| 229 | `define DV_CHECK_LE_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 230 | `DV_CHECK_LE(ACT_, EXP_, MSG_, fatal, ID_) |
| 231 | `endif |
| 232 | |
| 233 | `ifndef DV_CHECK_GE_FATAL |
| 234 | `define DV_CHECK_GE_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 235 | `DV_CHECK_GE(ACT_, EXP_, MSG_, fatal, ID_) |
| 236 | `endif |
| 237 | |
Srikrishna Iyer | 2e6b627 | 2020-10-14 11:01:17 -0700 | [diff] [blame] | 238 | `ifndef DV_CHECK_STREQ_FATAL |
| 239 | `define DV_CHECK_STREQ_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 240 | `DV_CHECK_STREQ(ACT_, EXP_, MSG_, fatal, ID_) |
| 241 | `endif |
| 242 | |
| 243 | `ifndef DV_CHECK_STRNE_FATAL |
| 244 | `define DV_CHECK_STRNE_FATAL(ACT_, EXP_, MSG_="", ID_=`gfn) \ |
| 245 | `DV_CHECK_STRNE(ACT_, EXP_, MSG_, fatal, ID_) |
| 246 | `endif |
| 247 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 248 | // Shorthand for common foo.randomize() + fatal check |
| 249 | `ifndef DV_CHECK_RANDOMIZE_FATAL |
| 250 | `define DV_CHECK_RANDOMIZE_FATAL(VAR_, MSG_="Randomization failed!", ID_=`gfn) \ |
| 251 | `DV_CHECK_FATAL(VAR_.randomize(), MSG_, ID_) |
| 252 | `endif |
| 253 | |
| 254 | // Shorthand for common foo.randomize() with { } + fatal check |
| 255 | `ifndef DV_CHECK_RANDOMIZE_WITH_FATAL |
| 256 | `define DV_CHECK_RANDOMIZE_WITH_FATAL(VAR_, WITH_C_, MSG_="Randomization failed!", ID_=`gfn) \ |
| 257 | `DV_CHECK_FATAL(VAR_.randomize() with {WITH_C_}, MSG_, ID_) |
| 258 | `endif |
| 259 | |
| 260 | // Shorthand for common std::randomize(foo) + fatal check |
| 261 | `ifndef DV_CHECK_STD_RANDOMIZE_FATAL |
| 262 | `define DV_CHECK_STD_RANDOMIZE_FATAL(VAR_, MSG_="Randomization failed!", ID_=`gfn) \ |
| 263 | `DV_CHECK_FATAL(std::randomize(VAR_), MSG_, ID_) |
| 264 | `endif |
| 265 | |
| 266 | // Shorthand for common std::randomize(foo) with { } + fatal check |
| 267 | `ifndef DV_CHECK_STD_RANDOMIZE_WITH_FATAL |
Gaurang Chitroda | 556c3d7 | 2019-10-14 11:56:28 -0700 | [diff] [blame] | 268 | `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] | 269 | `DV_CHECK_FATAL(std::randomize(VAR_) with {WITH_C_}, MSG_, ID_) |
| 270 | `endif |
| 271 | |
Srikrishna Iyer | 17cf252 | 2020-09-29 07:41:19 -0700 | [diff] [blame] | 272 | // Shorthand for common cls_inst.randomize(member) + fatal check |
| 273 | // Randomizes a specific member of a class instance. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 274 | `ifndef DV_CHECK_MEMBER_RANDOMIZE_FATAL |
Srikrishna Iyer | 17cf252 | 2020-09-29 07:41:19 -0700 | [diff] [blame] | 275 | `define DV_CHECK_MEMBER_RANDOMIZE_FATAL(VAR_, CLS_INST_=this, MSG_="Randomization failed!", ID_=`gfn) \ |
| 276 | `DV_CHECK_FATAL(CLS_INST_.randomize(VAR_), MSG_, ID_) |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 277 | `endif |
| 278 | |
Srikrishna Iyer | 17cf252 | 2020-09-29 07:41:19 -0700 | [diff] [blame] | 279 | // Shorthand for common cls_inst.randomize(member) with { } + fatal check |
| 280 | // Randomizes a specific member of a class instance with inline constraints. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 281 | `ifndef DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL |
Srikrishna Iyer | 17cf252 | 2020-09-29 07:41:19 -0700 | [diff] [blame] | 282 | `define DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(VAR_, C_, CLS_INST_=this, MSG_="Randomization failed!", ID_=`gfn) \ |
| 283 | `DV_CHECK_FATAL(CLS_INST_.randomize(VAR_) with {C_}, MSG_, ID_) |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 284 | `endif |
| 285 | |
| 286 | // print static/dynamic 1d array or queue |
| 287 | `ifndef DV_PRINT_ARR_CONTENTS |
Srikrishna Iyer | 89790f8 | 2021-01-22 20:49:52 -0800 | [diff] [blame] | 288 | `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] | 289 | begin \ |
| 290 | foreach (ARR_[i]) begin \ |
Guillermo Maturana | dcee03a | 2021-04-16 14:52:24 -0700 | [diff] [blame] | 291 | `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] | 292 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 293 | end |
| 294 | `endif |
| 295 | |
| 296 | // print non-empty tlm fifos that were uncompared at end of test |
| 297 | `ifndef DV_EOT_PRINT_TLM_FIFO_CONTENTS |
| 298 | `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] | 299 | begin \ |
| 300 | while (!FIFO_.is_empty()) begin \ |
| 301 | TYP_ item; \ |
| 302 | void'(FIFO_.try_get(item)); \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 303 | `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"FIFO_`", item.sprint()), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 304 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 305 | end |
| 306 | `endif |
| 307 | |
| 308 | // print non-empty tlm fifos that were uncompared at end of test |
| 309 | `ifndef DV_EOT_PRINT_TLM_FIFO_ARR_CONTENTS |
| 310 | `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] | 311 | begin \ |
| 312 | foreach (FIFO_[i]) begin \ |
| 313 | while (!FIFO_[i].is_empty()) begin \ |
| 314 | TYP_ item; \ |
| 315 | void'(FIFO_[i].try_get(item)); \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 316 | `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] | 317 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 318 | end \ |
| 319 | end |
| 320 | `endif |
| 321 | |
| 322 | // print non-empty tlm fifos that were uncompared at end of test |
| 323 | `ifndef DV_EOT_PRINT_Q_CONTENTS |
| 324 | `define DV_EOT_PRINT_Q_CONTENTS(TYP_, Q_, SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 325 | begin \ |
| 326 | while (Q_.size() != 0) begin \ |
| 327 | TYP_ item = Q_.pop_front(); \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 328 | `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"Q_`", item.sprint()), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 329 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 330 | end |
| 331 | `endif |
| 332 | |
| 333 | // print non-empty tlm fifos that were uncompared at end of test |
| 334 | `ifndef DV_EOT_PRINT_Q_ARR_CONTENTS |
| 335 | `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] | 336 | begin \ |
| 337 | foreach (Q_[i]) begin \ |
| 338 | while (Q_[i].size() != 0) begin \ |
| 339 | TYP_ item = Q_[i].pop_front(); \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 340 | `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] | 341 | end \ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 342 | end \ |
| 343 | end |
| 344 | `endif |
| 345 | |
Rasmus Madsen | 1f2bfb7 | 2020-01-22 12:32:15 -0800 | [diff] [blame] | 346 | // check for non-empty mailbox and print items that were uncompared at end of test |
| 347 | `ifndef DV_EOT_PRINT_MAILBOX_CONTENTS |
| 348 | `define DV_EOT_PRINT_MAILBOX_CONTENTS(TYP_, MAILBOX_, SEV_=error, ID_=`gfn) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 349 | begin \ |
| 350 | while (MAILBOX_.num() != 0) begin \ |
| 351 | TYP_ item; \ |
| 352 | void'(MAILBOX_.try_get(item)); \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 353 | `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"MAILBOX_`", item.sprint()), ID_) \ |
Weicai Yang | 7dddad5 | 2020-04-08 14:03:37 -0700 | [diff] [blame] | 354 | end \ |
Rasmus Madsen | 1f2bfb7 | 2020-01-22 12:32:15 -0800 | [diff] [blame] | 355 | end |
| 356 | `endif |
| 357 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 358 | // get parity - implemented as a macro so that it can be invoked in constraints as well |
| 359 | `ifndef GET_PARITY |
| 360 | `define GET_PARITY(val, odd=0) (^val ^ odd) |
| 361 | `endif |
| 362 | |
Srikrishna Iyer | 134ab75 | 2020-09-29 08:07:57 -0700 | [diff] [blame] | 363 | // Wait a task or statement with exit condition |
| 364 | // 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] | 365 | // input WAIT_ need to be a statement. Here are some examples |
| 366 | // `DV_SPINWAIT(wait(...);, "Wait for ...") |
| 367 | // `DV_SPINWAIT( |
| 368 | // while (1) begin |
| 369 | // ... |
| 370 | // end) |
Weicai Yang | aa8ed45 | 2020-08-14 10:19:58 -0700 | [diff] [blame] | 371 | `ifndef DV_SPINWAIT_EXIT |
| 372 | `define DV_SPINWAIT_EXIT(WAIT_, EXIT_, MSG_ = "exit condition occurred!", ID_ =`gfn) \ |
| 373 | begin \ |
| 374 | fork begin \ |
| 375 | fork \ |
| 376 | begin \ |
| 377 | WAIT_ \ |
| 378 | end \ |
| 379 | begin \ |
| 380 | EXIT_ \ |
| 381 | if (MSG_ != "") begin \ |
Srikrishna Iyer | 89790f8 | 2021-01-22 20:49:52 -0800 | [diff] [blame] | 382 | `dv_info(MSG_, uvm_pkg::UVM_HIGH, ID_) \ |
Weicai Yang | aa8ed45 | 2020-08-14 10:19:58 -0700 | [diff] [blame] | 383 | end \ |
| 384 | end \ |
| 385 | join_any \ |
| 386 | disable fork; \ |
| 387 | end join \ |
| 388 | end |
| 389 | `endif |
Srikrishna Iyer | b7d0202 | 2020-09-29 07:46:30 -0700 | [diff] [blame] | 390 | |
Weicai Yang | 6f70c38 | 2022-08-25 15:18:58 -0700 | [diff] [blame] | 391 | // macro that waits for a given delay and then reports an error |
| 392 | `ifndef DV_WAIT_TIMEOUT |
| 393 | `define DV_WAIT_TIMEOUT(TIMEOUT_NS_, ID_ = `gfn, ERROR_MSG_ = "timeout occurred!", REPORT_FATAL_ = 1) \ |
| 394 | begin \ |
| 395 | #(TIMEOUT_NS_ * 1ns); \ |
| 396 | if (REPORT_FATAL_) `dv_fatal(ERROR_MSG_, ID_) \ |
| 397 | else `dv_error(ERROR_MSG_, ID_) \ |
| 398 | end |
| 399 | `endif |
| 400 | |
Srikrishna Iyer | 134ab75 | 2020-09-29 08:07:57 -0700 | [diff] [blame] | 401 | // wait a task or statement with timer watchdog |
| 402 | `ifndef DV_SPINWAIT |
| 403 | `define DV_SPINWAIT(WAIT_, MSG_ = "timeout occurred!", TIMEOUT_NS_ = default_spinwait_timeout_ns, ID_ =`gfn) \ |
Weicai Yang | 6f70c38 | 2022-08-25 15:18:58 -0700 | [diff] [blame] | 404 | `DV_SPINWAIT_EXIT(WAIT_, `DV_WAIT_TIMEOUT(TIMEOUT_NS_, ID_, MSG_);, "", ID_) |
Srikrishna Iyer | 134ab75 | 2020-09-29 08:07:57 -0700 | [diff] [blame] | 405 | `endif |
| 406 | |
Weicai Yang | 7ab0b78 | 2022-07-22 17:09:44 -0700 | [diff] [blame] | 407 | // a shorthand of `DV_SPINWAIT(wait(...)) |
| 408 | `ifndef DV_WAIT |
Weicai Yang | f4bf5a5 | 2022-07-22 17:10:33 -0700 | [diff] [blame] | 409 | `define DV_WAIT(WAIT_COND_, MSG_ = "wait timeout occurred!", TIMEOUT_NS_ = default_spinwait_timeout_ns, ID_ =`gfn) \ |
| 410 | `DV_SPINWAIT(wait (WAIT_COND_);, MSG_, TIMEOUT_NS_, ID_) |
Weicai Yang | 7ab0b78 | 2022-07-22 17:09:44 -0700 | [diff] [blame] | 411 | `endif |
| 412 | |
Srikrishna Iyer | b7d0202 | 2020-09-29 07:46:30 -0700 | [diff] [blame] | 413 | // Control assertions in the DUT. |
| 414 | // |
| 415 | // This macro is invoked in top level testbench that instantiates the DUT. It spawns off an initial |
| 416 | // block that forever waits for a resource of type bit named by the string arg ~LABEL_~ that |
| 417 | // can be set by any entity in the testbench. Based on the value set, it enables or disables the |
| 418 | // assertions at the hierarchy of the provided path. The entity setting the resource value invokes |
| 419 | // uvm_config_db#(bit)::set(...) and this macro calls the corresponding get. |
| 420 | // |
| 421 | // LABEL_ : Name of the assertion control resource bit (string). |
| 422 | // HIER_ : Path to the module within which the assertion is controlled. |
| 423 | // LEVELS_: Number of levels within the module to control the assertions. |
| 424 | // SCOPE_ : Hierarchical string path to the testbench where this macro is invoked, example: %m. |
| 425 | // ID_ : Identifier string used for UVM logs. |
| 426 | `ifndef DV_ASSERT_CTRL |
Srikrishna Iyer | aca5539 | 2021-10-16 02:22:01 -0700 | [diff] [blame] | 427 | `define DV_ASSERT_CTRL(LABEL_, HIER_, LEVELS_ = 0, SCOPE_ = "", ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | b7d0202 | 2020-09-29 07:46:30 -0700 | [diff] [blame] | 428 | initial begin \ |
| 429 | bit assert_en; \ |
| 430 | forever begin \ |
| 431 | uvm_config_db#(bit)::wait_modified(null, SCOPE_, LABEL_); \ |
| 432 | if (!uvm_config_db#(bit)::get(null, SCOPE_, LABEL_, assert_en)) begin \ |
| 433 | `uvm_fatal(ID_, $sformatf("Failed to get \"%0s\" from uvm_config_db", LABEL_)) \ |
| 434 | end \ |
| 435 | if (assert_en) begin \ |
| 436 | `uvm_info(ID_, $sformatf("Enabling assertions: %0s", `DV_STRINGIFY(HIER_)), UVM_LOW) \ |
| 437 | $asserton(LEVELS_, HIER_); \ |
| 438 | end else begin \ |
| 439 | `uvm_info(ID_, $sformatf("Disabling assertions: %0s", `DV_STRINGIFY(HIER_)), UVM_LOW) \ |
| 440 | $assertoff(LEVELS_, HIER_); \ |
Andreas Kurth | 51acfe4 | 2022-11-21 18:06:24 +0000 | [diff] [blame] | 441 | $assertkill(LEVELS_, HIER_); \ |
Srikrishna Iyer | b7d0202 | 2020-09-29 07:46:30 -0700 | [diff] [blame] | 442 | end \ |
| 443 | end \ |
| 444 | end |
| 445 | `endif |
| 446 | |
Srikrishna Iyer | 101c314 | 2021-11-24 13:15:48 -0800 | [diff] [blame] | 447 | // Retrieves a plusarg value representing an enum literal. |
| 448 | // |
| 449 | // The plusarg is parsed as a string, which needs to be converted into the enum literal whose name |
| 450 | // matches the string. This functionality is provided by the UVM helper function below. |
| 451 | // |
| 452 | // ENUM_: The enum type. |
| 453 | // VAR_: The enum variable to which the plusarg value will be set (must be declared already). |
| 454 | // PLUSARG_: the name of the plusarg (as raw text). This is typically the same as the enum variable. |
| 455 | // CHECK_EXISTS_: Throws a fatal error if the plusarg is not set. |
Weicai Yang | f11eeac | 2021-08-04 18:39:06 -0700 | [diff] [blame] | 456 | `ifndef DV_GET_ENUM_PLUSARG |
Weicai Yang | 7d0aafc | 2022-04-17 22:49:08 -0700 | [diff] [blame] | 457 | `define DV_GET_ENUM_PLUSARG(ENUM_, VAR_, PLUSARG_, CHECK_EXISTS_ = 0, ID_ = `gfn) \ |
Weicai Yang | f11eeac | 2021-08-04 18:39:06 -0700 | [diff] [blame] | 458 | begin \ |
| 459 | string str; \ |
| 460 | if ($value$plusargs("``PLUSARG_``=%0s", str)) begin \ |
Srikrishna Iyer | 101c314 | 2021-11-24 13:15:48 -0800 | [diff] [blame] | 461 | if (!uvm_enum_wrapper#(ENUM_)::from_name(str, VAR_)) begin \ |
| 462 | `uvm_fatal(ID_, $sformatf("Cannot find %s from enum ``ENUM_``", VAR_.name())) \ |
Weicai Yang | f11eeac | 2021-08-04 18:39:06 -0700 | [diff] [blame] | 463 | end \ |
Srikrishna Iyer | 101c314 | 2021-11-24 13:15:48 -0800 | [diff] [blame] | 464 | end else if (CHECK_EXISTS_) begin \ |
| 465 | `uvm_fatal(ID_, "Please pass the plusarg +``PLUSARG_``=<``ENUM_``-literal>") \ |
Weicai Yang | f11eeac | 2021-08-04 18:39:06 -0700 | [diff] [blame] | 466 | end \ |
| 467 | end |
| 468 | `endif |
| 469 | |
Cindy Chen | 274d0e0 | 2022-11-17 14:21:32 -0800 | [diff] [blame] | 470 | // Retrieves a queue of plusarg value from a string. |
| 471 | // |
| 472 | // The plusarg is parsed as a string, which needs to be converted into a queue of string which given delimiter. |
| 473 | // This functionality is provided by the UVM helper function below. |
| 474 | // |
| 475 | // QUEUE_: The queue of string to which the plusarg value will be set (must be declared already). |
| 476 | // PLUSARG_: the name of the plusarg (as raw text). This is typically the same as the enum variable. |
| 477 | // DELIMITER_: the delimiter that separate each item in the plusarg string value. |
| 478 | // CHECK_EXISTS_: Throws a fatal error if the plusarg is not set. |
| 479 | `ifndef DV_GET_QUEUE_PLUSARG |
| 480 | `define DV_GET_QUEUE_PLUSARG(QUEUE_, PLUSARG_, DELIMITER_ = ",", CHECK_EXISTS_ = 0, ID_ = `gfn) \ |
| 481 | begin \ |
| 482 | string str; \ |
| 483 | if ($value$plusargs("``PLUSARG_``=%0s", str)) begin \ |
| 484 | str_split(str, QUEUE_, DELIMITER_); \ |
| 485 | end else if (CHECK_EXISTS_) begin \ |
| 486 | `uvm_fatal(ID_, "Please pass the plusarg +``PLUSARG_``=<``ENUM_``-literal>") \ |
| 487 | end \ |
| 488 | end |
| 489 | `endif |
| 490 | |
Srikrishna Iyer | b7d0202 | 2020-09-29 07:46:30 -0700 | [diff] [blame] | 491 | // Enable / disable assertions at a module hierarchy identified by LABEL_. |
| 492 | // |
| 493 | // This goes in conjunction with `DV_ASSERT_CTRL() macro above, but is invoked in the entity that is |
| 494 | // sending the req to turn on / off the assertions. Note that that piece of code invoking this macro |
| 495 | // does not have the information on the actual hierarchical path to the module or the levels - this |
| 496 | // is 'wrapped' into the LABEL_ instead. DV user needs to uniquify the label sufficienly enough to |
| 497 | // reflect it. |
| 498 | // |
| 499 | // LABEL_ : Name of the assertion control resource bit (string). |
| 500 | // VALUE_ : Value of the control bit - 1 - enable assertions, 0 - disable assertions. |
| 501 | // SCOPE_ : Hierarchical string path to the testbench where this macro is invoked, example: %m. |
| 502 | `ifndef DV_ASSERT_CTRL_REQ |
| 503 | `define DV_ASSERT_CTRL_REQ(LABEL_, VALUE_, SCOPE_="") \ |
| 504 | begin \ |
| 505 | uvm_config_db#(bit)::set(null, SCOPE_, LABEL_, VALUE_); \ |
| 506 | end |
| 507 | `endif |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 508 | |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 509 | // Macros for logging (info, warning, error and fatal severities). |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 510 | // |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 511 | // 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] | 512 | // testbenches. We waive the lint requirement for these to be in uppercase, since they are |
| 513 | // UVM-adjacent. |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 514 | `ifdef UVM |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 515 | `ifndef dv_info |
| 516 | // verilog_lint: waive macro-name-style |
Srikrishna Iyer | 89790f8 | 2021-01-22 20:49:52 -0800 | [diff] [blame] | 517 | `define dv_info(MSG_, VERBOSITY_ = uvm_pkg::UVM_LOW, ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 518 | if (uvm_pkg::uvm_report_enabled(VERBOSITY_, uvm_pkg::UVM_INFO, ID_)) begin \ |
| 519 | uvm_pkg::uvm_report_info(ID_, MSG_, VERBOSITY_, `uvm_file, `uvm_line, "", 1); \ |
| 520 | end |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 521 | `endif |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 522 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 523 | `ifndef dv_warning |
| 524 | // verilog_lint: waive macro-name-style |
| 525 | `define dv_warning(MSG_, ID_ = $sformatf("%m")) \ |
| 526 | if (uvm_pkg::uvm_report_enabled(uvm_pkg::UVM_NONE, uvm_pkg::UVM_WARNING, ID_)) begin \ |
| 527 | uvm_pkg::uvm_report_warning(ID_, MSG_, uvm_pkg::UVM_NONE, `uvm_file, `uvm_line, "", 1); \ |
| 528 | end |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 529 | `endif |
| 530 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 531 | `ifndef dv_error |
| 532 | // verilog_lint: waive macro-name-style |
| 533 | `define dv_error(MSG_, ID_ = $sformatf("%m")) \ |
| 534 | if (uvm_pkg::uvm_report_enabled(uvm_pkg::UVM_NONE, uvm_pkg::UVM_ERROR, ID_)) begin \ |
| 535 | uvm_pkg::uvm_report_error(ID_, MSG_, uvm_pkg::UVM_NONE, `uvm_file, `uvm_line, "", 1); \ |
| 536 | end |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 537 | `endif |
| 538 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 539 | `ifndef dv_fatal |
| 540 | // verilog_lint: waive macro-name-style |
| 541 | `define dv_fatal(MSG_, ID_ = $sformatf("%m")) \ |
| 542 | if (uvm_pkg::uvm_report_enabled(uvm_pkg::UVM_NONE, uvm_pkg::UVM_FATAL, ID_)) begin \ |
| 543 | uvm_pkg::uvm_report_fatal(ID_, MSG_, uvm_pkg::UVM_NONE, `uvm_file, `uvm_line, "", 1); \ |
| 544 | end |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 545 | `endif |
| 546 | |
| 547 | `else // UVM |
| 548 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 549 | `ifndef dv_info |
| 550 | // verilog_lint: waive macro-name-style |
| 551 | `define dv_info(MSG_, VERBOSITY = DUMMY_, ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 552 | $display("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_); |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 553 | `endif |
| 554 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 555 | `ifndef dv_warning |
| 556 | // verilog_lint: waive macro-name-style |
| 557 | `define dv_warning(MSG_, ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 558 | $warning("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_); |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 559 | `endif |
| 560 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 561 | `ifndef dv_error |
| 562 | // verilog_lint: waive macro-name-style |
| 563 | `define dv_error(MSG_, ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 564 | $error("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_); |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 565 | `endif |
| 566 | |
Srikrishna Iyer | 4fc0b21 | 2020-12-03 18:02:09 -0800 | [diff] [blame] | 567 | `ifndef dv_fatal |
| 568 | // verilog_lint: waive macro-name-style |
| 569 | `define dv_fatal(MSG_, ID_ = $sformatf("%m")) \ |
Srikrishna Iyer | 75b5b85 | 2022-12-16 10:49:48 -0800 | [diff] [blame] | 570 | $fatal(1, "%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_); |
Srikrishna Iyer | fa54f39 | 2020-10-12 02:23:05 -0700 | [diff] [blame] | 571 | `endif |
Srikrishna Iyer | 5b626f5 | 2020-10-15 00:58:17 -0700 | [diff] [blame] | 572 | |
| 573 | `endif // UVM |
Weicai Yang | fc36219 | 2021-08-13 15:55:14 -0700 | [diff] [blame] | 574 | |
| 575 | // Macros for constrain clk with common frequencies |
Srikrishna Iyer | 335c225 | 2023-01-12 01:17:46 -0800 | [diff] [blame] | 576 | // |
| 577 | // Nominal clock frequency range is 24Mhz - 100Mhz and use higher weights on 24, 25, 48, 50, 100, |
Srikrishna Iyer | ce1490a | 2023-01-12 01:22:06 -0800 | [diff] [blame^] | 578 | // To mimic manufacturing conditions (when clocks are uncalibrated), we need to be able to go as |
Srikrishna Iyer | 335c225 | 2023-01-12 01:17:46 -0800 | [diff] [blame] | 579 | // low as 5MHz. |
Weicai Yang | fc36219 | 2021-08-13 15:55:14 -0700 | [diff] [blame] | 580 | `ifndef DV_COMMON_CLK_CONSTRAINT |
| 581 | `define DV_COMMON_CLK_CONSTRAINT(FREQ_) \ |
| 582 | FREQ_ dist { \ |
Srikrishna Iyer | 335c225 | 2023-01-12 01:17:46 -0800 | [diff] [blame] | 583 | [5:23] :/ 2, \ |
Weicai Yang | fc36219 | 2021-08-13 15:55:14 -0700 | [diff] [blame] | 584 | [24:25] :/ 2, \ |
| 585 | [26:47] :/ 1, \ |
| 586 | [48:50] :/ 2, \ |
| 587 | [51:95] :/ 1, \ |
| 588 | 96 :/ 1, \ |
| 589 | [97:99] :/ 1, \ |
| 590 | 100 :/ 1 \ |
| 591 | }; |
| 592 | `endif |
Srikrishna Iyer | 4c4b55d | 2022-03-29 23:08:47 -0700 | [diff] [blame] | 593 | |
| 594 | // Enables build-time randomization of fixed design constants. |
| 595 | // |
| 596 | // This is meant to be overridden externally by passing `+define+BUILD_SEED=<value>`. |
| 597 | `ifndef BUILD_SEED |
| 598 | `define BUILD_SEED 1 |
| 599 | `endif |
Srikrishna Iyer | 5e40007 | 2022-04-05 16:12:27 -0700 | [diff] [blame] | 600 | |
| 601 | // Max value out of 2 given expressions. |
| 602 | // |
| 603 | // Duplicate of dv_utils_pkg::max2() function, but this is better because |
| 604 | // it can consume different data types directly without the need for casting. |
| 605 | `ifndef DV_MAX2 |
| 606 | `define DV_MAX2(a, b) ((a) > (b) ? (a) : (b)) |
| 607 | `endif |
Srikrishna Iyer | a6ed153 | 2022-09-11 23:00:54 -0700 | [diff] [blame] | 608 | |
| 609 | // Creates a signal probe function to sample / force / release an internal signal. |
| 610 | // |
| 611 | // If there is a need to sample / force an internal signal, then it must be done in the testbench, |
| 612 | // or in an interface bound to the DUT. This macro creates a standardized signal probe function |
| 613 | // meant to be invoked an interface. The generated function can then be invoked in test sequences |
| 614 | // or other UVM classes. The macro takes 2 arguments - name of the function and the hierarchical |
| 615 | // path to the signal. If invoked in an interface which is bound to the DUT, the signal can be a |
| 616 | // partial hierarchical path within the DUT. The generated function accepts 2 arguments - the first |
| 617 | // indicates the probe action (sample, force or release) of type dv_utils_pkg::signal_probe_e. The |
| 618 | // second argument is the value to be forced. If sample action is chosen, then it returns the |
Srikrishna Iyer | c97881c | 2022-10-25 16:36:08 -0700 | [diff] [blame] | 619 | // sampled value (for other actions as well). |
Srikrishna Iyer | a6ed153 | 2022-09-11 23:00:54 -0700 | [diff] [blame] | 620 | // |
| 621 | // The suggested naming convention for the function is: |
| 622 | // signal_probe_<DUT_or_IP_block_name>_<signal_name> |
| 623 | // |
| 624 | // This macro must be invoked in an interface or module. |
| 625 | `ifndef DV_CREATE_SIGNAL_PROBE_FUNCTION |
Srikrishna Iyer | c97881c | 2022-10-25 16:36:08 -0700 | [diff] [blame] | 626 | `define DV_CREATE_SIGNAL_PROBE_FUNCTION(FUNC_NAME_, SIGNAL_PATH_, SIGNAL_WIDTH_ = uvm_pkg::UVM_HDL_MAX_WIDTH) \ |
| 627 | function static logic [SIGNAL_WIDTH_-1:0] FUNC_NAME_(dv_utils_pkg::signal_probe_e kind, \ |
| 628 | logic [SIGNAL_WIDTH_-1:0] value = '0); \ |
| 629 | case (kind) \ |
| 630 | dv_utils_pkg::SignalProbeSample: ; \ |
| 631 | dv_utils_pkg::SignalProbeForce: force SIGNAL_PATH_ = value; \ |
| 632 | dv_utils_pkg::SignalProbeRelease: release SIGNAL_PATH_; \ |
| 633 | default: `uvm_fatal(`"FUNC_NAME_`", $sformatf("Bad value: %0d", kind)) \ |
| 634 | endcase \ |
| 635 | return SIGNAL_PATH_; \ |
Srikrishna Iyer | a6ed153 | 2022-09-11 23:00:54 -0700 | [diff] [blame] | 636 | endfunction |
| 637 | `endif |