1 |
16 |
HanySalah |
//-----------------------------------------------------------------------------
|
2 |
|
|
// Copyright 2007-2011 Mentor Graphics Corporation
|
3 |
|
|
// Copyright 2007-2011 Cadence Design Systems, Inc.
|
4 |
|
|
// Copyright 2010 Synopsys, Inc.
|
5 |
|
|
// All Rights Reserved Worldwide
|
6 |
|
|
//
|
7 |
|
|
// Licensed under the Apache License, Version 2.0 (the
|
8 |
|
|
// "License"); you may not use this file except in
|
9 |
|
|
// compliance with the License. You may obtain a copy of
|
10 |
|
|
// the License at
|
11 |
|
|
//
|
12 |
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
13 |
|
|
//
|
14 |
|
|
// Unless required by applicable law or agreed to in
|
15 |
|
|
// writing, software distributed under the License is
|
16 |
|
|
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
17 |
|
|
// CONDITIONS OF ANY KIND, either express or implied. See
|
18 |
|
|
// the License for the specific language governing
|
19 |
|
|
// permissions and limitations under the License.
|
20 |
|
|
//-----------------------------------------------------------------------------
|
21 |
|
|
|
22 |
|
|
`ifndef UVM_CB_MACROS_SVH
|
23 |
|
|
`define UVM_CB_MACROS_SVH
|
24 |
|
|
|
25 |
|
|
|
26 |
|
|
//-----------------------------------------------------------------------------
|
27 |
|
|
// Title: Callback Macros
|
28 |
|
|
//
|
29 |
|
|
// These macros are used to register and execute callbacks extending
|
30 |
|
|
// from ~uvm_callbacks~.
|
31 |
|
|
//-----------------------------------------------------------------------------
|
32 |
|
|
|
33 |
|
|
//-----------------------------------------------------------------------------
|
34 |
|
|
// MACRO: `uvm_register_cb
|
35 |
|
|
//
|
36 |
|
|
//| `uvm_register_cb(T,CB)
|
37 |
|
|
//
|
38 |
|
|
// Registers the given ~CB~ callback type with the given ~T~ object type. If
|
39 |
|
|
// a type-callback pair is not registered then a warning is issued if an
|
40 |
|
|
// attempt is made to use the pair (add, delete, etc.).
|
41 |
|
|
//
|
42 |
|
|
// The registration will typically occur in the component that executes the
|
43 |
|
|
// given type of callback. For instance:
|
44 |
|
|
//
|
45 |
|
|
//| virtual class mycb extends uvm_callback;
|
46 |
|
|
//| virtual function void doit();
|
47 |
|
|
//| endclass
|
48 |
|
|
//|
|
49 |
|
|
//| class my_comp extends uvm_component;
|
50 |
|
|
//| `uvm_register_cb(my_comp,mycb)
|
51 |
|
|
//| ...
|
52 |
|
|
//| task run_phase(uvm_phase phase);
|
53 |
|
|
//| ...
|
54 |
|
|
//| `uvm_do_callbacks(my_comp, mycb, doit())
|
55 |
|
|
//| endtask
|
56 |
|
|
//| endclass
|
57 |
|
|
//-----------------------------------------------------------------------------
|
58 |
|
|
|
59 |
|
|
`define uvm_register_cb(T,CB) \
|
60 |
|
|
static local bit m_register_cb_``CB = uvm_callbacks#(T,CB)::m_register_pair(`"T`",`"CB`");
|
61 |
|
|
|
62 |
|
|
|
63 |
|
|
//-----------------------------------------------------------------------------
|
64 |
|
|
// MACRO: `uvm_set_super_type
|
65 |
|
|
//
|
66 |
|
|
//| `uvm_set_super_type(T,ST)
|
67 |
|
|
//
|
68 |
|
|
// Defines the super type of ~T~ to be ~ST~. This allows for derived class
|
69 |
|
|
// objects to inherit typewide callbacks that are registered with the base
|
70 |
|
|
// class.
|
71 |
|
|
//
|
72 |
|
|
// The registration will typically occur in the component that executes the
|
73 |
|
|
// given type of callback. For instance:
|
74 |
|
|
//
|
75 |
|
|
//| virtual class mycb extend uvm_callback;
|
76 |
|
|
//| virtual function void doit();
|
77 |
|
|
//| endclass
|
78 |
|
|
//|
|
79 |
|
|
//| class my_comp extends uvm_component;
|
80 |
|
|
//| `uvm_register_cb(my_comp,mycb)
|
81 |
|
|
//| ...
|
82 |
|
|
//| task run_phase(uvm_phase phase);
|
83 |
|
|
//| ...
|
84 |
|
|
//| `uvm_do_callbacks(my_comp, mycb, doit())
|
85 |
|
|
//| endtask
|
86 |
|
|
//| endclass
|
87 |
|
|
//|
|
88 |
|
|
//| class my_derived_comp extends my_comp;
|
89 |
|
|
//| `uvm_set_super_type(my_derived_comp,my_comp)
|
90 |
|
|
//| ...
|
91 |
|
|
//| task run_phase(uvm_phase phase);
|
92 |
|
|
//| ...
|
93 |
|
|
//| `uvm_do_callbacks(my_comp, mycb, doit())
|
94 |
|
|
//| endtask
|
95 |
|
|
//| endclass
|
96 |
|
|
//-----------------------------------------------------------------------------
|
97 |
|
|
|
98 |
|
|
`define uvm_set_super_type(T,ST) \
|
99 |
|
|
static local bit m_register_``T``ST = uvm_derived_callbacks#(T,ST)::register_super_type(`"T`",`"ST`");
|
100 |
|
|
|
101 |
|
|
|
102 |
|
|
//-----------------------------------------------------------------------------
|
103 |
|
|
// MACRO: `uvm_do_callbacks
|
104 |
|
|
//
|
105 |
|
|
//| `uvm_do_callbacks(T,CB,METHOD)
|
106 |
|
|
//
|
107 |
|
|
// Calls the given ~METHOD~ of all callbacks of type ~CB~ registered with
|
108 |
|
|
// the calling object (i.e. ~this~ object), which is or is based on type ~T~.
|
109 |
|
|
//
|
110 |
|
|
// This macro executes all of the callbacks associated with the calling
|
111 |
|
|
// object (i.e. ~this~ object). The macro takes three arguments:
|
112 |
|
|
//
|
113 |
|
|
// - CB is the class type of the callback objects to execute. The class
|
114 |
|
|
// type must have a function signature that matches the METHOD argument.
|
115 |
|
|
//
|
116 |
|
|
// - T is the type associated with the callback. Typically, an instance
|
117 |
|
|
// of type T is passed as one the arguments in the ~METHOD~ call.
|
118 |
|
|
//
|
119 |
|
|
// - METHOD is the method call to invoke, with all required arguments as
|
120 |
|
|
// if they were invoked directly.
|
121 |
|
|
//
|
122 |
|
|
// For example, given the following callback class definition:
|
123 |
|
|
//
|
124 |
|
|
//| virtual class mycb extends uvm_cb;
|
125 |
|
|
//| pure function void my_function (mycomp comp, int addr, int data);
|
126 |
|
|
//| endclass
|
127 |
|
|
//
|
128 |
|
|
// A component would invoke the macro as
|
129 |
|
|
//
|
130 |
|
|
//| task mycomp::run_phase(uvm_phase phase);
|
131 |
|
|
//| int curr_addr, curr_data;
|
132 |
|
|
//| ...
|
133 |
|
|
//| `uvm_do_callbacks(mycb, mycomp, my_function(this, curr_addr, curr_data))
|
134 |
|
|
//| ...
|
135 |
|
|
//| endtask
|
136 |
|
|
//-----------------------------------------------------------------------------
|
137 |
|
|
|
138 |
|
|
|
139 |
|
|
`define uvm_do_callbacks(T,CB,METHOD) \
|
140 |
|
|
`uvm_do_obj_callbacks(T,CB,this,METHOD)
|
141 |
|
|
|
142 |
|
|
|
143 |
|
|
//-----------------------------------------------------------------------------
|
144 |
|
|
// MACRO: `uvm_do_obj_callbacks
|
145 |
|
|
//
|
146 |
|
|
//| `uvm_do_obj_callbacks(T,CB,OBJ,METHOD)
|
147 |
|
|
//
|
148 |
|
|
// Calls the given ~METHOD~ of all callbacks based on type ~CB~ registered with
|
149 |
|
|
// the given object, ~OBJ~, which is or is based on type ~T~.
|
150 |
|
|
//
|
151 |
|
|
// This macro is identical to <`uvm_do_callbacks> macro,
|
152 |
|
|
// but it has an additional ~OBJ~ argument to allow the specification of an
|
153 |
|
|
// external object to associate the callback with. For example, if the
|
154 |
|
|
// callbacks are being applied in a sequence, ~OBJ~ could be specified
|
155 |
|
|
// as the associated sequencer or parent sequence.
|
156 |
|
|
//
|
157 |
|
|
//| ...
|
158 |
|
|
//| `uvm_do_callbacks(mycb, mycomp, seqr, my_function(seqr, curr_addr, curr_data))
|
159 |
|
|
//| ...
|
160 |
|
|
//-----------------------------------------------------------------------------
|
161 |
|
|
|
162 |
|
|
`define uvm_do_obj_callbacks(T,CB,OBJ,METHOD) \
|
163 |
|
|
begin \
|
164 |
|
|
uvm_callback_iter#(T,CB) iter = new(OBJ); \
|
165 |
|
|
CB cb = iter.first(); \
|
166 |
|
|
while(cb != null) begin \
|
167 |
|
|
`uvm_cb_trace_noobj(cb,$sformatf(`"Executing callback method 'METHOD' for callback %s (CB) from %s (T)`",cb.get_name(), OBJ.get_full_name())) \
|
168 |
|
|
cb.METHOD; \
|
169 |
|
|
cb = iter.next(); \
|
170 |
|
|
end \
|
171 |
|
|
end
|
172 |
|
|
|
173 |
|
|
|
174 |
|
|
|
175 |
|
|
|
176 |
|
|
//-----------------------------------------------------------------------------
|
177 |
|
|
// MACRO: `uvm_do_callbacks_exit_on
|
178 |
|
|
//
|
179 |
|
|
//| `uvm_do_callbacks_exit_on(T,CB,METHOD,VAL)
|
180 |
|
|
//
|
181 |
|
|
// Calls the given ~METHOD~ of all callbacks of type ~CB~ registered with
|
182 |
|
|
// the calling object (i.e. ~this~ object), which is or is based on type ~T~,
|
183 |
|
|
// returning upon the first callback returning the bit value given by ~VAL~.
|
184 |
|
|
//
|
185 |
|
|
// This macro executes all of the callbacks associated with the calling
|
186 |
|
|
// object (i.e. ~this~ object). The macro takes three arguments:
|
187 |
|
|
//
|
188 |
|
|
// - CB is the class type of the callback objects to execute. The class
|
189 |
|
|
// type must have a function signature that matches the METHOD argument.
|
190 |
|
|
//
|
191 |
|
|
// - T is the type associated with the callback. Typically, an instance
|
192 |
|
|
// of type T is passed as one the arguments in the ~METHOD~ call.
|
193 |
|
|
//
|
194 |
|
|
// - METHOD is the method call to invoke, with all required arguments as
|
195 |
|
|
// if they were invoked directly.
|
196 |
|
|
//
|
197 |
|
|
// - VAL, if 1, says return upon the first callback invocation that
|
198 |
|
|
// returns 1. If 0, says return upon the first callback invocation that
|
199 |
|
|
// returns 0.
|
200 |
|
|
//
|
201 |
|
|
// For example, given the following callback class definition:
|
202 |
|
|
//
|
203 |
|
|
//| virtual class mycb extends uvm_cb;
|
204 |
|
|
//| pure function bit drop_trans (mycomp comp, my_trans trans);
|
205 |
|
|
//| endclass
|
206 |
|
|
//
|
207 |
|
|
// A component would invoke the macro as
|
208 |
|
|
//
|
209 |
|
|
//| task mycomp::run_phase(uvm_phase phase);
|
210 |
|
|
//| my_trans trans;
|
211 |
|
|
//| forever begin
|
212 |
|
|
//| get_port.get(trans);
|
213 |
|
|
//| if(do_callbacks(trans) == 0)
|
214 |
|
|
//| uvm_report_info("DROPPED",{"trans dropped: %s",trans.convert2string()});
|
215 |
|
|
//| else
|
216 |
|
|
//| // execute transaction
|
217 |
|
|
//| end
|
218 |
|
|
//| endtask
|
219 |
|
|
//| function bit do_callbacks(my_trans);
|
220 |
|
|
//| // Returns 0 if drop happens and 1 otherwise
|
221 |
|
|
//| `uvm_do_callbacks_exit_on(mycomp, mycb, extobj, drop_trans(this,trans), 1)
|
222 |
|
|
//| endfunction
|
223 |
|
|
//
|
224 |
|
|
// Because this macro calls ~return~, its use is restricted to implementations
|
225 |
|
|
// of functions that return a ~bit~ value, as in the above example.
|
226 |
|
|
//
|
227 |
|
|
//-----------------------------------------------------------------------------
|
228 |
|
|
|
229 |
|
|
|
230 |
|
|
`define uvm_do_callbacks_exit_on(T,CB,METHOD,VAL) \
|
231 |
|
|
`uvm_do_obj_callbacks_exit_on(T,CB,this,METHOD,VAL) \
|
232 |
|
|
|
233 |
|
|
|
234 |
|
|
//-----------------------------------------------------------------------------
|
235 |
|
|
// MACRO: `uvm_do_obj_callbacks_exit_on
|
236 |
|
|
//
|
237 |
|
|
//| `uvm_do_obj_callbacks_exit_on(T,CB,OBJ,METHOD,VAL)
|
238 |
|
|
//
|
239 |
|
|
// Calls the given ~METHOD~ of all callbacks of type ~CB~ registered with
|
240 |
|
|
// the given object ~OBJ~, which must be or be based on type ~T~, and returns
|
241 |
|
|
// upon the first callback that returns the bit value given by ~VAL~. It is
|
242 |
|
|
// exactly the same as the <`uvm_do_callbacks_exit_on> but has a specific
|
243 |
|
|
// object instance (instead of the implicit this instance) as the third
|
244 |
|
|
// argument.
|
245 |
|
|
//
|
246 |
|
|
//| ...
|
247 |
|
|
//| // Exit if a callback returns a 1
|
248 |
|
|
//| `uvm_do_callbacks_exit_on(mycomp, mycb, seqr, drop_trans(seqr,trans), 1)
|
249 |
|
|
//| ...
|
250 |
|
|
//
|
251 |
|
|
// Because this macro calls ~return~, its use is restricted to implementations
|
252 |
|
|
// of functions that return a ~bit~ value, as in the above example.
|
253 |
|
|
//-----------------------------------------------------------------------------
|
254 |
|
|
|
255 |
|
|
`define uvm_do_obj_callbacks_exit_on(T,CB,OBJ,METHOD,VAL) \
|
256 |
|
|
begin \
|
257 |
|
|
uvm_callback_iter#(T,CB) iter = new(OBJ); \
|
258 |
|
|
CB cb = iter.first(); \
|
259 |
|
|
while(cb != null) begin \
|
260 |
|
|
if (cb.METHOD == VAL) begin \
|
261 |
|
|
`uvm_cb_trace_noobj(cb,$sformatf(`"Executed callback method 'METHOD' for callback %s (CB) from %s (T) : returned value VAL (other callbacks will be ignored)`",cb.get_name(), OBJ.get_full_name())) \
|
262 |
|
|
return VAL; \
|
263 |
|
|
end \
|
264 |
|
|
`uvm_cb_trace_noobj(cb,$sformatf(`"Executed callback method 'METHOD' for callback %s (CB) from %s (T) : did not return value VAL`",cb.get_name(), OBJ.get_full_name())) \
|
265 |
|
|
cb = iter.next(); \
|
266 |
|
|
end \
|
267 |
|
|
return 1-VAL; \
|
268 |
|
|
end
|
269 |
|
|
|
270 |
|
|
|
271 |
|
|
// The +define+UVM_CB_TRACE_ON setting will instrument the uvm library to emit
|
272 |
|
|
// messages with message id UVMCB_TRC and UVM_NONE verbosity
|
273 |
|
|
// notifing add,delete and execution of uvm callbacks. The instrumentation is off by default.
|
274 |
|
|
|
275 |
|
|
`ifdef UVM_CB_TRACE_ON
|
276 |
|
|
|
277 |
|
|
`define uvm_cb_trace(OBJ,CB,OPER) \
|
278 |
|
|
begin \
|
279 |
|
|
string msg; \
|
280 |
|
|
msg = (OBJ == null) ? "null" : $sformatf("%s (%s@%0d)", \
|
281 |
|
|
OBJ.get_full_name(), OBJ.get_type_name(), OBJ.get_inst_id()); \
|
282 |
|
|
`uvm_info("UVMCB_TRC", $sformatf("%s: callback %s (%s@%0d) : to object %s", \
|
283 |
|
|
OPER, CB.get_name(), CB.get_type_name(), CB.get_inst_id(), msg), UVM_NONE) \
|
284 |
|
|
end
|
285 |
|
|
|
286 |
|
|
`define uvm_cb_trace_noobj(CB,OPER) \
|
287 |
|
|
begin \
|
288 |
|
|
if(uvm_callbacks_base::m_tracing) \
|
289 |
|
|
`uvm_info("UVMCB_TRC", $sformatf("%s : callback %s (%s@%0d)" , \
|
290 |
|
|
OPER, CB.get_name(), CB.get_type_name(), CB.get_inst_id()), UVM_NONE) \
|
291 |
|
|
end
|
292 |
|
|
`else
|
293 |
|
|
|
294 |
|
|
`define uvm_cb_trace_noobj(CB,OPER) /* null */
|
295 |
|
|
`define uvm_cb_trace(OBJ,CB,OPER) /* null */
|
296 |
|
|
|
297 |
|
|
`endif
|
298 |
|
|
|
299 |
|
|
|
300 |
|
|
`endif
|