blob: f2e8af5940b73dc5c8bad35cda9f12be58f19a2a [file] [log] [blame]
lowRISC Contributors802543a2019-08-31 12:12:56 +01001// 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 Iyer5b626f52020-10-15 00:58:17 -07005`ifdef UVM
6 `include "uvm_macros.svh"
7`endif
8
lowRISC Contributors802543a2019-08-31 12:12:56 +01009// UVM speficic macros
10`ifndef gfn
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -080011`ifdef UVM
Srikrishna Iyer94b35e52020-10-12 13:49:28 -070012 // verilog_lint: waive macro-name-style
lowRISC Contributors802543a2019-08-31 12:12:56 +010013 `define gfn get_full_name()
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -080014`else
15 // verilog_lint: waive macro-name-style
16 `define gfn $sformatf("%m")
17`endif
lowRISC Contributors802543a2019-08-31 12:12:56 +010018`endif
19
20`ifndef gtn
Srikrishna Iyer94b35e52020-10-12 13:49:28 -070021 // verilog_lint: waive macro-name-style
lowRISC Contributors802543a2019-08-31 12:12:56 +010022 `define gtn get_type_name()
23`endif
24
25`ifndef gn
Srikrishna Iyer94b35e52020-10-12 13:49:28 -070026 // verilog_lint: waive macro-name-style
lowRISC Contributors802543a2019-08-31 12:12:56 +010027 `define gn get_name()
28`endif
29
30`ifndef gmv
Srikrishna Iyer94b35e52020-10-12 13:49:28 -070031 // verilog_lint: waive macro-name-style
lowRISC Contributors802543a2019-08-31 12:12:56 +010032 `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 Iyer94b35e52020-10-12 13:49:28 -070038 // verilog_lint: waive macro-name-style
lowRISC Contributors802543a2019-08-31 12:12:56 +010039 `define downcast(EXT_, BASE_, MSG_="", SEV_=fatal, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -070040 begin \
41 if (!$cast(EXT_, BASE_)) begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -080042 `dv_``SEV_($sformatf({"Cast failed: base class variable %0s ", \
43 "does not hold extended class %0s handle %s"}, \
44 `"BASE_`", `"EXT_`", MSG_), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -070045 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +010046 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 Iyerb7d02022020-09-29 07:46:30 -070074// Convert arbitrary text / expression to string.
75`ifndef DV_STRINGIFY
76 `define DV_STRINGIFY(I_) `"I_`"
77`endif
78
Weicai Yangfbf2edc2021-09-27 15:31:08 -070079`ifndef DUT_HIER_STR
80 `define DUT_HIER_STR `DV_STRINGIFY(`DUT_HIER)
81`endif
82
lowRISC Contributors802543a2019-08-31 12:12:56 +010083// 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 Yang7dddad52020-04-08 14:03:37 -070087 begin \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -070088 if (T_) ; else begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -080089 `dv_``SEV_($sformatf("Check failed (%s) %s ", `"T_`", MSG_), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -070090 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +010091 end
92`endif
93
94`ifndef DV_CHECK_EQ
95 `define DV_CHECK_EQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -070096 begin \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -070097 if ((ACT_) == (EXP_)) ; else begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -080098 `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 Yang7dddad52020-04-08 14:03:37 -0700100 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100101 end
102`endif
103
104`ifndef DV_CHECK_NE
105 `define DV_CHECK_NE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700106 begin \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -0700107 if ((ACT_) != (EXP_)) ; else begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800108 `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 Yang7dddad52020-04-08 14:03:37 -0700110 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100111 end
112`endif
113
114`ifndef DV_CHECK_CASE_EQ
115 `define DV_CHECK_CASE_EQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700116 begin \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -0700117 if ((ACT_) === (EXP_)) ; else begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800118 `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 Yang7dddad52020-04-08 14:03:37 -0700120 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100121 end
122`endif
123
124`ifndef DV_CHECK_CASE_NE
125 `define DV_CHECK_CASE_NE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700126 begin \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -0700127 if ((ACT_) !== (EXP_)) ; else begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800128 `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 Yang7dddad52020-04-08 14:03:37 -0700130 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100131 end
132`endif
133
134`ifndef DV_CHECK_LT
135 `define DV_CHECK_LT(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700136 begin \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -0700137 if ((ACT_) < (EXP_)) ; else begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800138 `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 Yang7dddad52020-04-08 14:03:37 -0700140 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100141 end
142`endif
143
144`ifndef DV_CHECK_GT
145 `define DV_CHECK_GT(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700146 begin \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -0700147 if ((ACT_) > (EXP_)) ; else begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800148 `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 Yang7dddad52020-04-08 14:03:37 -0700150 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100151 end
152`endif
153
154`ifndef DV_CHECK_LE
155 `define DV_CHECK_LE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700156 begin \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -0700157 if ((ACT_) <= (EXP_)) ; else begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800158 `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 Yang7dddad52020-04-08 14:03:37 -0700160 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100161 end
162`endif
163
164`ifndef DV_CHECK_GE
165 `define DV_CHECK_GE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700166 begin \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -0700167 if ((ACT_) >= (EXP_)) ; else begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800168 `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 Yang7dddad52020-04-08 14:03:37 -0700170 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100171 end
172`endif
173
Srikrishna Iyer2e6b6272020-10-14 11:01:17 -0700174`ifndef DV_CHECK_STREQ
175 `define DV_CHECK_STREQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -0700176 begin \
177 if ((ACT_) == (EXP_)) ; else begin \
178 `dv_``SEV_($sformatf("Check failed \"%s\" == \"%s\" %s", ACT_, EXP_, MSG_), ID_) \
179 end \
Srikrishna Iyer2e6b6272020-10-14 11:01:17 -0700180 end
181`endif
182
183`ifndef DV_CHECK_STRNE
184 `define DV_CHECK_STRNE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -0700185 begin \
186 if ((ACT_) != (EXP_)) ; else begin \
187 `dv_``SEV_($sformatf("Check failed \"%s\" != \"%s\" %s", ACT_, EXP_, MSG_), ID_) \
188 end \
Srikrishna Iyer2e6b6272020-10-14 11:01:17 -0700189 end
190`endif
191
Weicai Yang9dfff8f2022-09-21 23:18:39 -0700192`ifndef DV_CHECK_Q_EQ
193 `define DV_CHECK_Q_EQ(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
194 begin \
Srikrishna Iyer1901fcd2022-10-12 16:03:38 -0700195 `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 Yang9dfff8f2022-09-21 23:18:39 -0700198 end \
199 end
200`endif
201
lowRISC Contributors802543a2019-08-31 12:12:56 +0100202// 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 Iyer2e6b6272020-10-14 11:01:17 -0700238`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 Contributors802543a2019-08-31 12:12:56 +0100248// 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 Chitroda556c3d72019-10-14 11:56:28 -0700268 `define DV_CHECK_STD_RANDOMIZE_WITH_FATAL(VAR_, WITH_C_, MSG_="Randomization failed!",ID_=`gfn) \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100269 `DV_CHECK_FATAL(std::randomize(VAR_) with {WITH_C_}, MSG_, ID_)
270`endif
271
Srikrishna Iyer17cf2522020-09-29 07:41:19 -0700272// Shorthand for common cls_inst.randomize(member) + fatal check
273// Randomizes a specific member of a class instance.
lowRISC Contributors802543a2019-08-31 12:12:56 +0100274`ifndef DV_CHECK_MEMBER_RANDOMIZE_FATAL
Srikrishna Iyer17cf2522020-09-29 07:41:19 -0700275 `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 Contributors802543a2019-08-31 12:12:56 +0100277`endif
278
Srikrishna Iyer17cf2522020-09-29 07:41:19 -0700279// Shorthand for common cls_inst.randomize(member) with { } + fatal check
280// Randomizes a specific member of a class instance with inline constraints.
lowRISC Contributors802543a2019-08-31 12:12:56 +0100281`ifndef DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL
Srikrishna Iyer17cf2522020-09-29 07:41:19 -0700282 `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 Contributors802543a2019-08-31 12:12:56 +0100284`endif
285
286// print static/dynamic 1d array or queue
287`ifndef DV_PRINT_ARR_CONTENTS
Srikrishna Iyer89790f82021-01-22 20:49:52 -0800288`define DV_PRINT_ARR_CONTENTS(ARR_, V_=uvm_pkg::UVM_MEDIUM, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700289 begin \
290 foreach (ARR_[i]) begin \
Guillermo Maturanadcee03a2021-04-16 14:52:24 -0700291 `dv_info($sformatf("%s[%0d] = %0d (0x%0h)", `"ARR_`", i, ARR_[i], ARR_[i]), V_, ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700292 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100293 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 Yang7dddad52020-04-08 14:03:37 -0700299 begin \
300 while (!FIFO_.is_empty()) begin \
301 TYP_ item; \
302 void'(FIFO_.try_get(item)); \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800303 `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"FIFO_`", item.sprint()), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700304 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100305 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 Yang7dddad52020-04-08 14:03:37 -0700311 begin \
312 foreach (FIFO_[i]) begin \
313 while (!FIFO_[i].is_empty()) begin \
314 TYP_ item; \
315 void'(FIFO_[i].try_get(item)); \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800316 `dv_``SEV_($sformatf("%s[%0d] item uncompared:\n%s", `"FIFO_`", i, item.sprint()), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700317 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100318 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 Yang7dddad52020-04-08 14:03:37 -0700325 begin \
326 while (Q_.size() != 0) begin \
327 TYP_ item = Q_.pop_front(); \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800328 `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"Q_`", item.sprint()), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700329 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100330 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 Yang7dddad52020-04-08 14:03:37 -0700336 begin \
337 foreach (Q_[i]) begin \
338 while (Q_[i].size() != 0) begin \
339 TYP_ item = Q_[i].pop_front(); \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800340 `dv_``SEV_($sformatf("%s[%0d] item uncompared:\n%s", `"Q_`", i, item.sprint()), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700341 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100342 end \
343 end
344`endif
345
Rasmus Madsen1f2bfb72020-01-22 12:32:15 -0800346// 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 Yang7dddad52020-04-08 14:03:37 -0700349 begin \
350 while (MAILBOX_.num() != 0) begin \
351 TYP_ item; \
352 void'(MAILBOX_.try_get(item)); \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800353 `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"MAILBOX_`", item.sprint()), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700354 end \
Rasmus Madsen1f2bfb72020-01-22 12:32:15 -0800355 end
356`endif
357
lowRISC Contributors802543a2019-08-31 12:12:56 +0100358// 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 Iyer134ab752020-09-29 08:07:57 -0700363// Wait a task or statement with exit condition
364// Kill the thread when either the wait statement is completed or exit condition occurs
lowRISC Contributors802543a2019-08-31 12:12:56 +0100365// 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 Yangaa8ed452020-08-14 10:19:58 -0700371`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 Iyer89790f82021-01-22 20:49:52 -0800382 `dv_info(MSG_, uvm_pkg::UVM_HIGH, ID_) \
Weicai Yangaa8ed452020-08-14 10:19:58 -0700383 end \
384 end \
385 join_any \
386 disable fork; \
387 end join \
388 end
389`endif
Srikrishna Iyerb7d02022020-09-29 07:46:30 -0700390
Weicai Yang6f70c382022-08-25 15:18:58 -0700391// 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 Iyer134ab752020-09-29 08:07:57 -0700401// 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 Yang6f70c382022-08-25 15:18:58 -0700404 `DV_SPINWAIT_EXIT(WAIT_, `DV_WAIT_TIMEOUT(TIMEOUT_NS_, ID_, MSG_);, "", ID_)
Srikrishna Iyer134ab752020-09-29 08:07:57 -0700405`endif
406
Weicai Yang7ab0b782022-07-22 17:09:44 -0700407// a shorthand of `DV_SPINWAIT(wait(...))
408`ifndef DV_WAIT
Weicai Yangf4bf5a52022-07-22 17:10:33 -0700409`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 Yang7ab0b782022-07-22 17:09:44 -0700411`endif
412
Srikrishna Iyerb7d02022020-09-29 07:46:30 -0700413// 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 Iyeraca55392021-10-16 02:22:01 -0700427`define DV_ASSERT_CTRL(LABEL_, HIER_, LEVELS_ = 0, SCOPE_ = "", ID_ = $sformatf("%m")) \
Srikrishna Iyerb7d02022020-09-29 07:46:30 -0700428 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 Kurth51acfe42022-11-21 18:06:24 +0000441 $assertkill(LEVELS_, HIER_); \
Srikrishna Iyerb7d02022020-09-29 07:46:30 -0700442 end \
443 end \
444 end
445`endif
446
Srikrishna Iyer101c3142021-11-24 13:15:48 -0800447// 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 Yangf11eeac2021-08-04 18:39:06 -0700456`ifndef DV_GET_ENUM_PLUSARG
Weicai Yang7d0aafc2022-04-17 22:49:08 -0700457`define DV_GET_ENUM_PLUSARG(ENUM_, VAR_, PLUSARG_, CHECK_EXISTS_ = 0, ID_ = `gfn) \
Weicai Yangf11eeac2021-08-04 18:39:06 -0700458 begin \
459 string str; \
460 if ($value$plusargs("``PLUSARG_``=%0s", str)) begin \
Srikrishna Iyer101c3142021-11-24 13:15:48 -0800461 if (!uvm_enum_wrapper#(ENUM_)::from_name(str, VAR_)) begin \
462 `uvm_fatal(ID_, $sformatf("Cannot find %s from enum ``ENUM_``", VAR_.name())) \
Weicai Yangf11eeac2021-08-04 18:39:06 -0700463 end \
Srikrishna Iyer101c3142021-11-24 13:15:48 -0800464 end else if (CHECK_EXISTS_) begin \
465 `uvm_fatal(ID_, "Please pass the plusarg +``PLUSARG_``=<``ENUM_``-literal>") \
Weicai Yangf11eeac2021-08-04 18:39:06 -0700466 end \
467 end
468`endif
469
Cindy Chen274d0e02022-11-17 14:21:32 -0800470// 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 Iyerb7d02022020-09-29 07:46:30 -0700491// 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 Iyerfa54f392020-10-12 02:23:05 -0700508
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700509// Macros for logging (info, warning, error and fatal severities).
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700510//
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700511// These are meant to be invoked in modules and interfaces that are shared between DV and Verilator
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800512// testbenches. We waive the lint requirement for these to be in uppercase, since they are
513// UVM-adjacent.
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700514`ifdef UVM
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800515`ifndef dv_info
516 // verilog_lint: waive macro-name-style
Srikrishna Iyer89790f82021-01-22 20:49:52 -0800517 `define dv_info(MSG_, VERBOSITY_ = uvm_pkg::UVM_LOW, ID_ = $sformatf("%m")) \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800518 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 Iyerfa54f392020-10-12 02:23:05 -0700521`endif
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700522
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800523`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 Iyer5b626f52020-10-15 00:58:17 -0700529`endif
530
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800531`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 Iyer5b626f52020-10-15 00:58:17 -0700537`endif
538
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800539`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 Iyer5b626f52020-10-15 00:58:17 -0700545`endif
546
547`else // UVM
548
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800549`ifndef dv_info
550 // verilog_lint: waive macro-name-style
551 `define dv_info(MSG_, VERBOSITY = DUMMY_, ID_ = $sformatf("%m")) \
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700552 $display("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700553`endif
554
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800555`ifndef dv_warning
556 // verilog_lint: waive macro-name-style
557 `define dv_warning(MSG_, ID_ = $sformatf("%m")) \
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700558 $warning("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700559`endif
560
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800561`ifndef dv_error
562 // verilog_lint: waive macro-name-style
563 `define dv_error(MSG_, ID_ = $sformatf("%m")) \
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700564 $error("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700565`endif
566
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800567`ifndef dv_fatal
568 // verilog_lint: waive macro-name-style
569 `define dv_fatal(MSG_, ID_ = $sformatf("%m")) \
Srikrishna Iyer75b5b852022-12-16 10:49:48 -0800570 $fatal(1, "%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700571`endif
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700572
573`endif // UVM
Weicai Yangfc362192021-08-13 15:55:14 -0700574
575// Macros for constrain clk with common frequencies
Srikrishna Iyer335c2252023-01-12 01:17:46 -0800576//
577// Nominal clock frequency range is 24Mhz - 100Mhz and use higher weights on 24, 25, 48, 50, 100,
Srikrishna Iyerce1490a2023-01-12 01:22:06 -0800578// To mimic manufacturing conditions (when clocks are uncalibrated), we need to be able to go as
Srikrishna Iyer335c2252023-01-12 01:17:46 -0800579// low as 5MHz.
Weicai Yangfc362192021-08-13 15:55:14 -0700580`ifndef DV_COMMON_CLK_CONSTRAINT
581`define DV_COMMON_CLK_CONSTRAINT(FREQ_) \
582 FREQ_ dist { \
Srikrishna Iyer335c2252023-01-12 01:17:46 -0800583 [5:23] :/ 2, \
Weicai Yangfc362192021-08-13 15:55:14 -0700584 [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 Iyer4c4b55d2022-03-29 23:08:47 -0700593
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 Iyer5e400072022-04-05 16:12:27 -0700600
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 Iyera6ed1532022-09-11 23:00:54 -0700608
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 Iyerc97881c2022-10-25 16:36:08 -0700619// sampled value (for other actions as well).
Srikrishna Iyera6ed1532022-09-11 23:00:54 -0700620//
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 Iyerc97881c2022-10-25 16:36:08 -0700626`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 Iyera6ed1532022-09-11 23:00:54 -0700636 endfunction
637`endif