blob: 17c8e4bc7217a7e7f81cca3de1ef84b375c71e20 [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 \
88 if (!(T_)) 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 \
Weicai Yang8c9b8d92020-10-19 17:47:03 -070097 if (!((ACT_) == (EXP_))) 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 \
Weicai Yang8c9b8d92020-10-19 17:47:03 -0700107 if (!((ACT_) != (EXP_))) 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 \
Weicai Yang8c9b8d92020-10-19 17:47:03 -0700117 if (!((ACT_) === (EXP_))) 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 \
Weicai Yang8c9b8d92020-10-19 17:47:03 -0700127 if (!((ACT_) !== (EXP_))) 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 \
Weicai Yang8c9b8d92020-10-19 17:47:03 -0700137 if (!((ACT_) < (EXP_))) 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 \
Weicai Yang8c9b8d92020-10-19 17:47:03 -0700147 if (!((ACT_) > (EXP_))) 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 \
Weicai Yang8c9b8d92020-10-19 17:47:03 -0700157 if (!((ACT_) <= (EXP_))) 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 \
Weicai Yang8c9b8d92020-10-19 17:47:03 -0700167 if (!((ACT_) >= (EXP_))) 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) \
Weicai Yang8c9b8d92020-10-19 17:47:03 -0700176 if (!((ACT_) == (EXP_))) begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800177 `dv_``SEV_($sformatf("Check failed \"%s\" == \"%s\" %s", ACT_, EXP_, MSG_), ID_) \
Srikrishna Iyer2e6b6272020-10-14 11:01:17 -0700178 end
179`endif
180
181`ifndef DV_CHECK_STRNE
182 `define DV_CHECK_STRNE(ACT_, EXP_, MSG_="", SEV_=error, ID_=`gfn) \
Weicai Yang8c9b8d92020-10-19 17:47:03 -0700183 if (!((ACT_) != (EXP_))) begin \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800184 `dv_``SEV_($sformatf("Check failed \"%s\" != \"%s\" %s", ACT_, EXP_, MSG_), ID_) \
Srikrishna Iyer2e6b6272020-10-14 11:01:17 -0700185 end
186`endif
187
lowRISC Contributors802543a2019-08-31 12:12:56 +0100188// 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 Iyer2e6b6272020-10-14 11:01:17 -0700224`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 Contributors802543a2019-08-31 12:12:56 +0100234// 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 Chitroda556c3d72019-10-14 11:56:28 -0700254 `define DV_CHECK_STD_RANDOMIZE_WITH_FATAL(VAR_, WITH_C_, MSG_="Randomization failed!",ID_=`gfn) \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100255 `DV_CHECK_FATAL(std::randomize(VAR_) with {WITH_C_}, MSG_, ID_)
256`endif
257
Srikrishna Iyer17cf2522020-09-29 07:41:19 -0700258// Shorthand for common cls_inst.randomize(member) + fatal check
259// Randomizes a specific member of a class instance.
lowRISC Contributors802543a2019-08-31 12:12:56 +0100260`ifndef DV_CHECK_MEMBER_RANDOMIZE_FATAL
Srikrishna Iyer17cf2522020-09-29 07:41:19 -0700261 `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 Contributors802543a2019-08-31 12:12:56 +0100263`endif
264
Srikrishna Iyer17cf2522020-09-29 07:41:19 -0700265// Shorthand for common cls_inst.randomize(member) with { } + fatal check
266// Randomizes a specific member of a class instance with inline constraints.
lowRISC Contributors802543a2019-08-31 12:12:56 +0100267`ifndef DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL
Srikrishna Iyer17cf2522020-09-29 07:41:19 -0700268 `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 Contributors802543a2019-08-31 12:12:56 +0100270`endif
271
272// print static/dynamic 1d array or queue
273`ifndef DV_PRINT_ARR_CONTENTS
Srikrishna Iyer89790f82021-01-22 20:49:52 -0800274`define DV_PRINT_ARR_CONTENTS(ARR_, V_=uvm_pkg::UVM_MEDIUM, ID_=`gfn) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700275 begin \
276 foreach (ARR_[i]) begin \
Guillermo Maturanadcee03a2021-04-16 14:52:24 -0700277 `dv_info($sformatf("%s[%0d] = %0d (0x%0h)", `"ARR_`", i, ARR_[i], ARR_[i]), V_, ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700278 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100279 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 Yang7dddad52020-04-08 14:03:37 -0700285 begin \
286 while (!FIFO_.is_empty()) begin \
287 TYP_ item; \
288 void'(FIFO_.try_get(item)); \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800289 `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"FIFO_`", item.sprint()), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700290 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100291 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 Yang7dddad52020-04-08 14:03:37 -0700297 begin \
298 foreach (FIFO_[i]) begin \
299 while (!FIFO_[i].is_empty()) begin \
300 TYP_ item; \
301 void'(FIFO_[i].try_get(item)); \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800302 `dv_``SEV_($sformatf("%s[%0d] item uncompared:\n%s", `"FIFO_`", i, item.sprint()), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700303 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100304 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 Yang7dddad52020-04-08 14:03:37 -0700311 begin \
312 while (Q_.size() != 0) begin \
313 TYP_ item = Q_.pop_front(); \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800314 `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"Q_`", item.sprint()), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700315 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100316 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 Yang7dddad52020-04-08 14:03:37 -0700322 begin \
323 foreach (Q_[i]) begin \
324 while (Q_[i].size() != 0) begin \
325 TYP_ item = Q_[i].pop_front(); \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800326 `dv_``SEV_($sformatf("%s[%0d] item uncompared:\n%s", `"Q_`", i, item.sprint()), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700327 end \
lowRISC Contributors802543a2019-08-31 12:12:56 +0100328 end \
329 end
330`endif
331
Rasmus Madsen1f2bfb72020-01-22 12:32:15 -0800332// 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 Yang7dddad52020-04-08 14:03:37 -0700335 begin \
336 while (MAILBOX_.num() != 0) begin \
337 TYP_ item; \
338 void'(MAILBOX_.try_get(item)); \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800339 `dv_``SEV_($sformatf("%s item uncompared:\n%s", `"MAILBOX_`", item.sprint()), ID_) \
Weicai Yang7dddad52020-04-08 14:03:37 -0700340 end \
Rasmus Madsen1f2bfb72020-01-22 12:32:15 -0800341 end
342`endif
343
lowRISC Contributors802543a2019-08-31 12:12:56 +0100344// 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 Iyer134ab752020-09-29 08:07:57 -0700349// Wait a task or statement with exit condition
350// Kill the thread when either the wait statement is completed or exit condition occurs
lowRISC Contributors802543a2019-08-31 12:12:56 +0100351// 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 Yangaa8ed452020-08-14 10:19:58 -0700357`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 Iyer89790f82021-01-22 20:49:52 -0800368 `dv_info(MSG_, uvm_pkg::UVM_HIGH, ID_) \
Weicai Yangaa8ed452020-08-14 10:19:58 -0700369 end \
370 end \
371 join_any \
372 disable fork; \
373 end join \
374 end
375`endif
Srikrishna Iyerb7d02022020-09-29 07:46:30 -0700376
Srikrishna Iyer134ab752020-09-29 08:07:57 -0700377// 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 Iyerb7d02022020-09-29 07:46:30 -0700383// 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 Iyeraca55392021-10-16 02:22:01 -0700397`define DV_ASSERT_CTRL(LABEL_, HIER_, LEVELS_ = 0, SCOPE_ = "", ID_ = $sformatf("%m")) \
Srikrishna Iyerb7d02022020-09-29 07:46:30 -0700398 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 Yangf11eeac2021-08-04 18:39:06 -0700416// 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 Iyerb7d02022020-09-29 07:46:30 -0700434// 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 Iyerfa54f392020-10-12 02:23:05 -0700451
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700452// Macros for logging (info, warning, error and fatal severities).
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700453//
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700454// These are meant to be invoked in modules and interfaces that are shared between DV and Verilator
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800455// testbenches. We waive the lint requirement for these to be in uppercase, since they are
456// UVM-adjacent.
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700457`ifdef UVM
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800458`ifndef dv_info
459 // verilog_lint: waive macro-name-style
Srikrishna Iyer89790f82021-01-22 20:49:52 -0800460 `define dv_info(MSG_, VERBOSITY_ = uvm_pkg::UVM_LOW, ID_ = $sformatf("%m")) \
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800461 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 Iyerfa54f392020-10-12 02:23:05 -0700464`endif
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700465
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800466`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 Iyer5b626f52020-10-15 00:58:17 -0700472`endif
473
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800474`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 Iyer5b626f52020-10-15 00:58:17 -0700480`endif
481
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800482`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 Iyer5b626f52020-10-15 00:58:17 -0700488`endif
489
490`else // UVM
491
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800492`ifndef dv_info
493 // verilog_lint: waive macro-name-style
494 `define dv_info(MSG_, VERBOSITY = DUMMY_, ID_ = $sformatf("%m")) \
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700495 $display("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700496`endif
497
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800498`ifndef dv_warning
499 // verilog_lint: waive macro-name-style
500 `define dv_warning(MSG_, ID_ = $sformatf("%m")) \
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700501 $warning("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700502`endif
503
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800504`ifndef dv_error
505 // verilog_lint: waive macro-name-style
506 `define dv_error(MSG_, ID_ = $sformatf("%m")) \
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700507 $error("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700508`endif
509
Srikrishna Iyer4fc0b212020-12-03 18:02:09 -0800510`ifndef dv_fatal
511 // verilog_lint: waive macro-name-style
512 `define dv_fatal(MSG_, ID_ = $sformatf("%m")) \
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700513 $fatal("%0t: (%0s:%0d) [%0s] %0s", $time, `__FILE__, `__LINE__, ID_, MSG_);
Srikrishna Iyerfa54f392020-10-12 02:23:05 -0700514`endif
Srikrishna Iyer5b626f52020-10-15 00:58:17 -0700515
516`endif // UVM
Weicai Yangfc362192021-08-13 15:55:14 -0700517
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