OpenCores
URL https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [base/] [uvm_factory.svh] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//
2
//------------------------------------------------------------------------------
3
//   Copyright 2007-2011 Mentor Graphics Corporation
4
//   Copyright 2007-2011 Cadence Design Systems, Inc.
5
//   Copyright 2010-2011 Synopsys, Inc.
6
//   Copyright 2013      NVIDIA Corporation
7
//   Copyright 2013      Verilab, Inc.
8
//   All Rights Reserved Worldwide
9
//
10
//   Licensed under the Apache License, Version 2.0 (the
11
//   "License"); you may not use this file except in
12
//   compliance with the License.  You may obtain a copy of
13
//   the License at
14
//
15
//       http://www.apache.org/licenses/LICENSE-2.0
16
//
17
//   Unless required by applicable law or agreed to in
18
//   writing, software distributed under the License is
19
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
20
//   CONDITIONS OF ANY KIND, either express or implied.  See
21
//   the License for the specific language governing
22
//   permissions and limitations under the License.
23
//------------------------------------------------------------------------------
24
 
25
 
26
typedef class uvm_object;
27
typedef class uvm_component;
28
typedef class uvm_object_wrapper;
29
typedef class uvm_factory_override;
30
 
31
//Instance overrides by requested type lookup
32
class uvm_factory_queue_class;
33
  uvm_factory_override queue[$];
34
endclass
35
 
36
//------------------------------------------------------------------------------
37
// Title: UVM Factory
38
//
39
// This page covers the classes that define the UVM factory facility.
40
//------------------------------------------------------------------------------
41
 
42
 
43
//------------------------------------------------------------------------------
44
//
45
// CLASS: uvm_factory
46
//
47
//------------------------------------------------------------------------------
48
//
49
// As the name implies, uvm_factory is used to manufacture (create) UVM objects
50
// and components. Object and component types are registered
51
// with the factory using lightweight proxies to the actual objects and
52
// components being created. The  and
53
//  class are used to proxy 
54
// and .
55
//
56
// The factory provides both name-based and type-based interfaces.
57
//
58
// type-based - The type-based interface is far less prone to errors in usage.
59
//   When errors do occur, they are caught at compile-time.
60
//
61
// name-based - The name-based interface is dominated
62
//   by string arguments that can be misspelled and provided in the wrong order.
63
//   Errors in name-based requests might only be caught at the time of the call,
64
//   if at all. Further, the name-based interface is not portable across
65
//   simulators when used with parameterized classes.
66
//
67
//
68
// The ~uvm_factory~ is an abstract class which declares many of its methods
69
// as ~pure virtual~.  The UVM uses the  class
70
// as its default factory implementation.
71
//
72
// See  section for details on configuring and using the factory.
73
//
74
 
75
virtual class uvm_factory;
76
 
77
  // Group: Retrieving the factory
78
 
79
 
80
  // Function: get
81
  // Static accessor for 
82
  //
83
  // The static accessor is provided as a convenience wrapper
84
  // around retrieving the factory via the 
85
  // method.
86
  //
87
  // | // Using the uvm_coreservice_t:
88
  // | uvm_coreservice_t cs;
89
  // | uvm_factory f;
90
  // | cs = uvm_coreservice_t::get();
91
  // | f = cs.get_factory();
92
  //
93
  // | // Not using the uvm_coreservice_t:
94
  // | uvm_factory f;
95
  // | f = uvm_factory::get();
96
  //
97
  static function uvm_factory get();
98
                uvm_coreservice_t s;
99
                s = uvm_coreservice_t::get();
100
                return s.get_factory();
101
  endfunction
102
 
103
  // Group: Registering Types
104
 
105
  // Function: register
106
  //
107
  // Registers the given proxy object, ~obj~, with the factory. The proxy object
108
  // is a lightweight substitute for the component or object it represents. When
109
  // the factory needs to create an object of a given type, it calls the proxy's
110
  // create_object or create_component method to do so.
111
  //
112
  // When doing name-based operations, the factory calls the proxy's
113
  // ~get_type_name~ method to match against the ~requested_type_name~ argument in
114
  // subsequent calls to  and .
115
  // If the proxy object's ~get_type_name~ method returns the empty string,
116
  // name-based lookup is effectively disabled.
117
 
118
  pure virtual function void register (uvm_object_wrapper obj);
119
 
120
 
121
  // Group: Type & Instance Overrides
122
 
123
  // Function: set_inst_override_by_type
124
 
125
  pure virtual function
126
      void set_inst_override_by_type (uvm_object_wrapper original_type,
127
                                      uvm_object_wrapper override_type,
128
                                      string full_inst_path);
129
 
130
  // Function: set_inst_override_by_name
131
  //
132
  // Configures the factory to create an object of the override's type whenever
133
  // a request is made to create an object of the original type using a context
134
  // that matches ~full_inst_path~. The original type is typically a super class
135
  // of the override type.
136
  //
137
  // When overriding by type, the ~original_type~ and ~override_type~ are
138
  // handles to the types' proxy objects. Preregistration is not required.
139
  //
140
  // When overriding by name, the ~original_type_name~ typically refers to a
141
  // preregistered type in the factory. It may, however, be any arbitrary
142
  // string. Future calls to any of the ~create_*~ methods with the same string
143
  // and matching instance path will produce the type represented by
144
  // ~override_type_name~, which must be preregistered with the factory.
145
  //
146
  // The ~full_inst_path~ is matched against the concatenation of
147
  // {~parent_inst_path~, ".", ~name~} provided in future create requests. The
148
  // ~full_inst_path~ may include wildcards (* and ?) such that a single
149
  // instance override can be applied in multiple contexts. A ~full_inst_path~
150
  // of "*" is effectively a type override, as it will match all contexts.
151
  //
152
  // When the factory processes instance overrides, the instance queue is
153
  // processed in order of override registrations, and the first override
154
  // match prevails. Thus, more specific overrides should be registered
155
  // first, followed by more general overrides.
156
 
157
  pure virtual function
158
      void set_inst_override_by_name (string original_type_name,
159
                                      string override_type_name,
160
                                      string full_inst_path);
161
 
162
 
163
  // Function: set_type_override_by_type
164
 
165
  pure virtual function
166
      void set_type_override_by_type (uvm_object_wrapper original_type,
167
                                      uvm_object_wrapper override_type,
168
                                      bit replace=1);
169
 
170
  // Function: set_type_override_by_name
171
  //
172
  // Configures the factory to create an object of the override's type whenever
173
  // a request is made to create an object of the original type, provided no
174
  // instance override applies. The original type is typically a super class of
175
  // the override type.
176
  //
177
  // When overriding by type, the ~original_type~ and ~override_type~ are
178
  // handles to the types' proxy objects. Preregistration is not required.
179
  //
180
  // When overriding by name, the ~original_type_name~ typically refers to a
181
  // preregistered type in the factory. It may, however, be any arbitrary
182
  // string. Future calls to any of the ~create_*~ methods with the same string
183
  // and matching instance path will produce the type represented by
184
  // ~override_type_name~, which must be preregistered with the factory.
185
  //
186
  // When ~replace~ is 1, a previous override on ~original_type_name~ is
187
  // replaced, otherwise a previous override, if any, remains intact.
188
 
189
  pure virtual function
190
      void set_type_override_by_name (string original_type_name,
191
                                      string override_type_name,
192
                                      bit replace=1);
193
 
194
 
195
  // Group: Creation
196
 
197
  // Function: create_object_by_type
198
 
199
  pure virtual function
200
      uvm_object    create_object_by_type    (uvm_object_wrapper requested_type,
201
                                              string parent_inst_path="",
202
                                              string name="");
203
 
204
  // Function: create_component_by_type
205
 
206
  pure virtual function
207
      uvm_component create_component_by_type (uvm_object_wrapper requested_type,
208
                                              string parent_inst_path="",
209
                                              string name,
210
                                              uvm_component parent);
211
 
212
  // Function: create_object_by_name
213
 
214
  pure virtual function
215
      uvm_object    create_object_by_name    (string requested_type_name,
216
                                              string parent_inst_path="",
217
                                              string name="");
218
 
219
  // Function: create_component_by_name
220
  //
221
  // Creates and returns a component or object of the requested type, which may
222
  // be specified by type or by name. A requested component must be derived
223
  // from the  base class, and a requested object must be derived
224
  // from the  base class.
225
  //
226
  // When requesting by type, the ~requested_type~ is a handle to the type's
227
  // proxy object. Preregistration is not required.
228
  //
229
  // When requesting by name, the ~request_type_name~ is a string representing
230
  // the requested type, which must have been registered with the factory with
231
  // that name prior to the request. If the factory does not recognize the
232
  // ~requested_type_name~, an error is produced and a ~null~ handle returned.
233
  //
234
  // If the optional ~parent_inst_path~ is provided, then the concatenation,
235
  // {~parent_inst_path~, ".",~name~}, forms an instance path (context) that
236
  // is used to search for an instance override. The ~parent_inst_path~ is
237
  // typically obtained by calling the  on the
238
  // parent.
239
  //
240
  // If no instance override is found, the factory then searches for a type
241
  // override.
242
  //
243
  // Once the final override is found, an instance of that component or object
244
  // is returned in place of the requested type. New components will have the
245
  // given ~name~ and ~parent~. New objects will have the given ~name~, if
246
  // provided.
247
  //
248
  // Override searches are recursively applied, with instance overrides taking
249
  // precedence over type overrides. If ~foo~ overrides ~bar~, and ~xyz~
250
  // overrides ~foo~, then a request for ~bar~ will produce ~xyz~. Recursive
251
  // loops will result in an error, in which case the type returned will be
252
  // that which formed the loop. Using the previous example, if ~bar~
253
  // overrides ~xyz~, then ~bar~ is returned after the error is issued.
254
 
255
  pure virtual function
256
      uvm_component create_component_by_name (string requested_type_name,
257
                                              string parent_inst_path="",
258
                                              string name,
259
                                              uvm_component parent);
260
 
261
  // Group: Debug
262
 
263
  // Function: debug_create_by_type
264
 
265
  pure virtual function
266
      void debug_create_by_type (uvm_object_wrapper requested_type,
267
                                 string parent_inst_path="",
268
                                 string name="");
269
 
270
  // Function: debug_create_by_name
271
  //
272
  // These methods perform the same search algorithm as the ~create_*~ methods,
273
  // but they do not create new objects. Instead, they provide detailed
274
  // information about what type of object it would return, listing each
275
  // override that was applied to arrive at the result. Interpretation of the
276
  // arguments are exactly as with the ~create_*~ methods.
277
 
278
  pure virtual function
279
      void debug_create_by_name (string requested_type_name,
280
                                 string parent_inst_path="",
281
                                 string name="");
282
 
283
 
284
  // Function: find_override_by_type
285
 
286
  pure virtual function
287
      uvm_object_wrapper find_override_by_type (uvm_object_wrapper requested_type,
288
                                                string full_inst_path);
289
 
290
  // Function: find_override_by_name
291
  //
292
  // These methods return the proxy to the object that would be created given
293
  // the arguments. The ~full_inst_path~ is typically derived from the parent's
294
  // instance path and the leaf name of the object to be created, i.e.
295
  // { parent.get_full_name(), ".", name }.
296
 
297
  pure virtual function
298
      uvm_object_wrapper find_override_by_name (string requested_type_name,
299
                                                string full_inst_path);
300
 
301
  // Function: find_wrapper_by_name
302
  //
303
  // This method returns the  associated with a given
304
  // ~type_name~.
305
  pure virtual
306
    function uvm_object_wrapper find_wrapper_by_name            (string type_name);
307
 
308
  // Function: print
309
  //
310
  // Prints the state of the uvm_factory, including registered types, instance
311
  // overrides, and type overrides.
312
  //
313
  // When ~all_types~ is 0, only type and instance overrides are displayed. When
314
  // ~all_types~ is 1 (default), all registered user-defined types are printed as
315
  // well, provided they have names associated with them. When ~all_types~ is 2,
316
  // the UVM types (prefixed with uvm_) are included in the list of registered
317
  // types.
318
 
319
  pure  virtual function void print (int all_types=1);
320
endclass
321
 
322
//------------------------------------------------------------------------------
323
//
324
// CLASS: uvm_default_factory
325
//
326
//------------------------------------------------------------------------------
327
//
328
// Default implementation of the UVM factory.
329
 
330
class uvm_default_factory extends uvm_factory;
331
 
332
  // Group: Registering Types
333
 
334
  // Function: register
335
  //
336
  // Registers the given proxy object, ~obj~, with the factory.
337
 
338
  extern virtual function void register (uvm_object_wrapper obj);
339
 
340
 
341
  // Group: Type & Instance Overrides
342
 
343
  // Function: set_inst_override_by_type
344
 
345
  extern virtual function
346
      void set_inst_override_by_type (uvm_object_wrapper original_type,
347
                                      uvm_object_wrapper override_type,
348
                                      string full_inst_path);
349
 
350
  // Function: set_inst_override_by_name
351
  //
352
  // Configures the factory to create an object of the override's type whenever
353
  // a request is made to create an object of the original type using a context
354
  // that matches ~full_inst_path~.
355
  extern virtual function
356
      void set_inst_override_by_name (string original_type_name,
357
                                      string override_type_name,
358
                                      string full_inst_path);
359
 
360
 
361
  // Function: set_type_override_by_type
362
 
363
  extern virtual function
364
      void set_type_override_by_type (uvm_object_wrapper original_type,
365
                                      uvm_object_wrapper override_type,
366
                                      bit replace=1);
367
 
368
  // Function: set_type_override_by_name
369
  //
370
  // Configures the factory to create an object of the override's type whenever
371
  // a request is made to create an object of the original type, provided no
372
  // instance override applies.
373
 
374
  extern virtual function
375
      void set_type_override_by_name (string original_type_name,
376
                                      string override_type_name,
377
                                      bit replace=1);
378
 
379
 
380
  // Group: Creation
381
 
382
  // Function: create_object_by_type
383
 
384
  extern virtual function
385
      uvm_object    create_object_by_type    (uvm_object_wrapper requested_type,
386
                                              string parent_inst_path="",
387
                                              string name="");
388
 
389
  // Function: create_component_by_type
390
 
391
  extern virtual function
392
      uvm_component create_component_by_type (uvm_object_wrapper requested_type,
393
                                              string parent_inst_path="",
394
                                              string name,
395
                                              uvm_component parent);
396
 
397
  // Function: create_object_by_name
398
 
399
  extern virtual function
400
      uvm_object    create_object_by_name    (string requested_type_name,
401
                                              string parent_inst_path="",
402
                                              string name="");
403
 
404
  // Function: create_component_by_name
405
  //
406
  // Creates and returns a component or object of the requested type, which may
407
  // be specified by type or by name.
408
 
409
  extern virtual function
410
      uvm_component create_component_by_name (string requested_type_name,
411
                                              string parent_inst_path="",
412
                                              string name,
413
                                              uvm_component parent);
414
 
415
  // Group: Debug
416
 
417
  // Function: debug_create_by_type
418
 
419
  extern virtual function
420
      void debug_create_by_type (uvm_object_wrapper requested_type,
421
                                 string parent_inst_path="",
422
                                 string name="");
423
 
424
  // Function: debug_create_by_name
425
  //
426
  // These methods perform the same search algorithm as the ~create_*~ methods,
427
  // but they do not create new objects.
428
  extern virtual function
429
      void debug_create_by_name (string requested_type_name,
430
                                 string parent_inst_path="",
431
                                 string name="");
432
 
433
 
434
  // Function: find_override_by_type
435
 
436
  extern virtual function
437
      uvm_object_wrapper find_override_by_type (uvm_object_wrapper requested_type,
438
                                                string full_inst_path);
439
 
440
  // Function: find_override_by_name
441
  //
442
  // These methods return the proxy to the object that would be created given
443
  // the arguments.
444
 
445
  extern virtual function
446
      uvm_object_wrapper find_override_by_name (string requested_type_name,
447
                                                string full_inst_path);
448
 
449
  extern virtual
450
    function uvm_object_wrapper find_wrapper_by_name            (string type_name);
451
 
452
  // Function: print
453
  //
454
  // Prints the state of the uvm_factory, including registered types, instance
455
  // overrides, and type overrides.
456
  //
457
  extern  virtual function void print (int all_types=1);
458
 
459
 
460
  //----------------------------------------------------------------------------
461
  // PRIVATE MEMBERS
462
 
463
  extern protected
464
      function void  m_debug_create (string requested_type_name,
465
                                     uvm_object_wrapper requested_type,
466
                                     string parent_inst_path,
467
                                     string name);
468
 
469
  extern protected
470
      function void  m_debug_display(string requested_type_name,
471
                                     uvm_object_wrapper result,
472
                                     string full_inst_path);
473
 
474
  protected bit                  m_types[uvm_object_wrapper];
475
  protected bit                  m_lookup_strs[string];
476
  protected uvm_object_wrapper   m_type_names[string];
477
 
478
  protected uvm_factory_override m_type_overrides[$];
479
 
480
  protected uvm_factory_queue_class m_inst_override_queues[uvm_object_wrapper];
481
  protected uvm_factory_queue_class m_inst_override_name_queues[string];
482
  protected uvm_factory_override    m_wildcard_inst_overrides[$];
483
 
484
  local uvm_factory_override     m_override_info[$];
485
  local static bit m_debug_pass;
486
 
487
  extern function bit m_has_wildcard(string nm);
488
 
489
  extern function bit check_inst_override_exists
490
                                      (uvm_object_wrapper original_type,
491
                                       uvm_object_wrapper override_type,
492
                                       string full_inst_path);
493
 
494
endclass
495
 
496
 
497
//------------------------------------------------------------------------------
498
//
499
// Group: Usage
500
//
501
// Using the factory involves three basic operations
502
//
503
// 1 - Registering objects and components types with the factory
504
// 2 - Designing components to use the factory to create objects or components
505
// 3 - Configuring the factory with type and instance overrides, both within and
506
//     outside components
507
//
508
// We'll briefly cover each of these steps here. More reference information can
509
// be found at , ,
510
// , .
511
//
512
// 1 -- Registering objects and component types with the factory:
513
//
514
// When defining  and -based classes, simply invoke
515
// the appropriate macro. Use of macros are required to ensure portability
516
// across different vendors' simulators.
517
//
518
// Objects that are not parameterized are declared as
519
//
520
//|  class packet extends uvm_object;
521
//|    `uvm_object_utils(packet)
522
//|  endclass
523
//|
524
//|  class packetD extends packet;
525
//|    `uvm_object_utils(packetD)
526
//|  endclass
527
//
528
// Objects that are parameterized are declared as
529
//
530
//|  class packet #(type T=int, int WIDTH=32) extends uvm_object;
531
//|    `uvm_object_param_utils(packet #(T,WIDTH))
532
//|   endclass
533
//
534
// Components that are not parameterized are declared as
535
//
536
//|  class comp extends uvm_component;
537
//|    `uvm_component_utils(comp)
538
//|  endclass
539
//
540
// Components that are parameterized are declared as
541
//
542
//|  class comp #(type T=int, int WIDTH=32) extends uvm_component;
543
//|    `uvm_component_param_utils(comp #(T,WIDTH))
544
//|  endclass
545
//
546
// The `uvm_*_utils macros for simple, non-parameterized classes will register
547
// the type with the factory and define the get_type, get_type_name, and create
548
// virtual methods inherited from . It will also define a static
549
// type_name variable in the class, which will allow you to determine the type
550
// without having to allocate an instance.
551
//
552
// The `uvm_*_param_utils macros for parameterized classes differ from
553
// `uvm_*_utils classes in the following ways:
554
//
555
// - The ~get_type_name~ method and static type_name variable are not defined. You
556
//   will need to implement these manually.
557
//
558
// - A type name is not associated with the type when registering with the
559
//   factory, so the factory's *_by_name operations will not work with
560
//   parameterized classes.
561
//
562
// - The factory's , , and 
563
//   methods, which depend on type names to convey information, will list
564
//   parameterized types as ''.
565
//
566
// It is worth noting that environments that exclusively use the type-based
567
// factory methods (*_by_type) do not require type registration. The factory's
568
// type-based methods will register the types involved "on the fly," when first
569
// used. However, registering with the `uvm_*_utils macros enables name-based
570
// factory usage and implements some useful utility functions.
571
//
572
//
573
// 2 -- Designing components that defer creation to the factory:
574
//
575
// Having registered your objects and components with the factory, you can now
576
// make requests for new objects and components via the factory. Using the factory
577
// instead of allocating them directly (via new) allows different objects to be
578
// substituted for the original without modifying the requesting class. The
579
// following code defines a driver class that is parameterized.
580
//
581
//|  class driverB #(type T=uvm_object) extends uvm_driver;
582
//|
583
//|    // parameterized classes must use the _param_utils version
584
//|    `uvm_component_param_utils(driverB #(T))
585
//|
586
//|    // our packet type; this can be overridden via the factory
587
//|    T pkt;
588
//|
589
//|    // standard component constructor
590
//|    function new(string name, uvm_component parent=null);
591
//|      super.new(name,parent);
592
//|    endfunction
593
//|
594
//|    // get_type_name not implemented by macro for parameterized classes
595
//|    const static string type_name = {"driverB #(",T::type_name,")"};
596
//|    virtual function string get_type_name();
597
//|      return type_name;
598
//|    endfunction
599
//|
600
//|    // using the factory allows pkt overrides from outside the class
601
//|    virtual function void build_phase(uvm_phase phase);
602
//|      pkt = packet::type_id::create("pkt",this);
603
//|    endfunction
604
//|
605
//|    // print the packet so we can confirm its type when printing
606
//|    virtual function void do_print(uvm_printer printer);
607
//|      printer.print_object("pkt",pkt);
608
//|    endfunction
609
//|
610
//|  endclass
611
//
612
// For purposes of illustrating type and instance overrides, we define two
613
// subtypes of the ~driverB~ class. The subtypes are also parameterized, so
614
// we must again provide an implementation for ,
615
// which we recommend writing in terms of a static string constant.
616
//
617
//|  class driverD1 #(type T=uvm_object) extends driverB #(T);
618
//|
619
//|    `uvm_component_param_utils(driverD1 #(T))
620
//|
621
//|    function new(string name, uvm_component parent=null);
622
//|      super.new(name,parent);
623
//|    endfunction
624
//|
625
//|    const static string type_name = {"driverD1 #(",T::type_name,")"};
626
//|    virtual function string get_type_name();
627
//|      ...return type_name;
628
//|    endfunction
629
//|
630
//|  endclass
631
//|
632
//|  class driverD2 #(type T=uvm_object) extends driverB #(T);
633
//|
634
//|    `uvm_component_param_utils(driverD2 #(T))
635
//|
636
//|    function new(string name, uvm_component parent=null);
637
//|      super.new(name,parent);
638
//|    endfunction
639
//|
640
//|    const static string type_name = {"driverD2 #(",T::type_name,")"};
641
//|    virtual function string get_type_name();
642
//|      return type_name;
643
//|    endfunction
644
//|
645
//|  endclass
646
//|
647
//|  // typedef some specializations for convenience
648
//|  typedef driverB  #(packet) B_driver;   // the base driver
649
//|  typedef driverD1 #(packet) D1_driver;  // a derived driver
650
//|  typedef driverD2 #(packet) D2_driver;  // another derived driver
651
//
652
// Next, we'll define a agent component, which requires a utils macro for
653
// non-parameterized types. Before creating the drivers using the factory, we
654
// override ~driver0~'s packet type to be ~packetD~.
655
//
656
//|  class agent extends uvm_agent;
657
//|
658
//|    `uvm_component_utils(agent)
659
//|    ...
660
//|    B_driver driver0;
661
//|    B_driver driver1;
662
//|
663
//|    function new(string name, uvm_component parent=null);
664
//|      super.new(name,parent);
665
//|    endfunction
666
//|
667
//|    virtual function void build_phase(uvm_phase phase);
668
//|
669
//|      // override the packet type for driver0 and below
670
//|      packet::type_id::set_inst_override(packetD::get_type(),"driver0.*");
671
//|
672
//|      // create using the factory; actual driver types may be different
673
//|      driver0 = B_driver::type_id::create("driver0",this);
674
//|      driver1 = B_driver::type_id::create("driver1",this);
675
//|
676
//|    endfunction
677
//|
678
//|  endclass
679
//
680
// Finally we define an environment class, also not parameterized. Its ~build_phase~
681
// method shows three methods for setting an instance override on a grandchild
682
// component with relative path name, ~agent1.driver1~, all equivalent.
683
//
684
//|  class env extends uvm_env;
685
//|
686
//|    `uvm_component_utils(env)
687
//|
688
//|    agent agent0;
689
//|    agent agent1;
690
//|
691
//|    function new(string name, uvm_component parent=null);
692
//|      super.new(name,parent);
693
//|    endfunction
694
//|
695
//|    virtual function void build_phase(uvm_phase phase);
696
//|
697
//|      // three methods to set an instance override for agent1.driver1
698
//|      // - via component convenience method...
699
//|      set_inst_override_by_type("agent1.driver1",
700
//|                                B_driver::get_type(),
701
//|                                D2_driver::get_type());
702
//|
703
//|      // - via the component's proxy (same approach as create)...
704
//|      B_driver::type_id::set_inst_override(D2_driver::get_type(),
705
//|                                           "agent1.driver1",this);
706
//|
707
//|      // - via a direct call to a factory method...
708
//|      factory.set_inst_override_by_type(B_driver::get_type(),
709
//|                                        D2_driver::get_type(),
710
//|                                        {get_full_name(),".agent1.driver1"});
711
//|
712
//|      // create agents using the factory; actual agent types may be different
713
//|      agent0 = agent::type_id::create("agent0",this);
714
//|      agent1 = agent::type_id::create("agent1",this);
715
//|
716
//|    endfunction
717
//|
718
//|    // at end_of_elaboration, print topology and factory state to verify
719
//|    virtual function void end_of_elaboration_phase(uvm_phase phase);
720
//|      uvm_top.print_topology();
721
//|    endfunction
722
//|
723
//|    virtual task run_phase(uvm_phase phase);
724
//|      #100 global_stop_request();
725
//|    endfunction
726
//|
727
//|  endclass
728
//
729
//
730
// 3 -- Configuring the factory with type and instance overrides:
731
//
732
// In the previous step, we demonstrated setting instance overrides and creating
733
// components using the factory within component classes. Here, we will
734
// demonstrate setting overrides from outside components, as when initializing
735
// the environment prior to running the test.
736
//
737
//|  module top;
738
//|
739
//|    env env0;
740
//|
741
//|    initial begin
742
//|
743
//|      // Being registered first, the following overrides take precedence
744
//|      // over any overrides made within env0's construction & build.
745
//|
746
//|      // Replace all base drivers with derived drivers...
747
//|      B_driver::type_id::set_type_override(D_driver::get_type());
748
//|
749
//|      // ...except for agent0.driver0, whose type remains a base driver.
750
//|      //     (Both methods below have the equivalent result.)
751
//|
752
//|      // - via the component's proxy (preferred)
753
//|      B_driver::type_id::set_inst_override(B_driver::get_type(),
754
//|                                           "env0.agent0.driver0");
755
//|
756
//|      // - via a direct call to a factory method
757
//|      factory.set_inst_override_by_type(B_driver::get_type(),
758
//|                                        B_driver::get_type(),
759
//|                                    {get_full_name(),"env0.agent0.driver0"});
760
//|
761
//|      // now, create the environment; our factory configuration will
762
//|      // govern what topology gets created
763
//|      env0 = new("env0");
764
//|
765
//|      // run the test (will execute build phase)
766
//|      run_test();
767
//|
768
//|    end
769
//|
770
//|  endmodule
771
//
772
// When the above example is run, the resulting topology (displayed via a call to
773
//  in env's  method)
774
// is similar to the following:
775
//
776
//| # UVM_INFO @ 0 [RNTST] Running test ...
777
//| # UVM_INFO @ 0 [UVMTOP] UVM testbench topology:
778
//| # ----------------------------------------------------------------------
779
//| # Name                     Type                Size                Value
780
//| # ----------------------------------------------------------------------
781
//| # env0                     env                 -                  env0@2
782
//| #   agent0                 agent               -                agent0@4
783
//| #     driver0              driverB #(packet)   -               driver0@8
784
//| #       pkt                packet              -                  pkt@21
785
//| #     driver1              driverD #(packet)   -              driver1@14
786
//| #       pkt                packet              -                  pkt@23
787
//| #   agent1                 agent               -                agent1@6
788
//| #     driver0              driverD #(packet)   -              driver0@24
789
//| #       pkt                packet              -                  pkt@37
790
//| #     driver1              driverD2 #(packet)  -              driver1@30
791
//| #       pkt                packet              -                  pkt@39
792
//| # ----------------------------------------------------------------------
793
//
794
//------------------------------------------------------------------------------
795
 
796
 
797
//------------------------------------------------------------------------------
798
//
799
// CLASS: uvm_object_wrapper
800
//
801
// The uvm_object_wrapper provides an abstract interface for creating object and
802
// component proxies. Instances of these lightweight proxies, representing every
803
// -based and -based object available in the test
804
// environment, are registered with the . When the factory is
805
// called upon to create an object or component, it finds and delegates the
806
// request to the appropriate proxy.
807
//
808
//------------------------------------------------------------------------------
809
 
810
virtual class uvm_object_wrapper;
811
 
812
  // Function: create_object
813
  //
814
  // Creates a new object with the optional ~name~.
815
  // An object proxy (e.g., ) implements this
816
  // method to create an object of a specific type, T.
817
 
818
  virtual function uvm_object create_object (string name="");
819
    return null;
820
  endfunction
821
 
822
 
823
  // Function: create_component
824
  //
825
  // Creates a new component, passing to its constructor the given ~name~ and
826
  // ~parent~. A component proxy (e.g. )
827
  // implements this method to create a component of a specific type, T.
828
 
829
  virtual function uvm_component create_component (string name,
830
                                                   uvm_component parent);
831
    return null;
832
  endfunction
833
 
834
 
835
  // Function: get_type_name
836
  //
837
  // Derived classes implement this method to return the type name of the object
838
  // created by  or . The factory uses this
839
  // name when matching against the requested type in name-based lookups.
840
 
841
  pure virtual function string get_type_name();
842
 
843
endclass
844
 
845
 
846
//------------------------------------------------------------------------------
847
//
848
// CLASS- uvm_factory_override
849
//
850
// Internal class.
851
//------------------------------------------------------------------------------
852
 
853
class uvm_factory_override;
854
  string full_inst_path;
855
  string orig_type_name;
856
  string ovrd_type_name;
857
  bit selected;
858
  int unsigned used;
859
  uvm_object_wrapper orig_type;
860
  uvm_object_wrapper ovrd_type;
861
  function new (string full_inst_path="",
862
                string orig_type_name="",
863
                uvm_object_wrapper orig_type=null,
864
                uvm_object_wrapper ovrd_type);
865
    if (ovrd_type == null) begin
866
      uvm_report_fatal ("NULLWR", "Attempting to register a null override object with the factory", UVM_NONE);
867
    end
868
    this.full_inst_path= full_inst_path;
869
    this.orig_type_name = orig_type == null ? orig_type_name : orig_type.get_type_name();
870
    this.orig_type      = orig_type;
871
    this.ovrd_type_name = ovrd_type.get_type_name();
872
    this.ovrd_type      = ovrd_type;
873
  endfunction
874
endclass
875
 
876
 
877
//-----------------------------------------------------------------------------
878
// IMPLEMENTATION
879
//-----------------------------------------------------------------------------
880
 
881
// register
882
// --------
883
 
884
function void uvm_default_factory::register (uvm_object_wrapper obj);
885
 
886
  if (obj == null) begin
887
    uvm_report_fatal ("NULLWR", "Attempting to register a null object with the factory", UVM_NONE);
888
  end
889
  if (obj.get_type_name() != "" && obj.get_type_name() != "") begin
890
    if (m_type_names.exists(obj.get_type_name()))
891
      uvm_report_warning("TPRGED", {"Type name '",obj.get_type_name(),
892
        "' already registered with factory. No string-based lookup ",
893
        "support for multiple types with the same type name."}, UVM_NONE);
894
    else
895
      m_type_names[obj.get_type_name()] = obj;
896
  end
897
 
898
  if (m_types.exists(obj)) begin
899
    if (obj.get_type_name() != "" && obj.get_type_name() != "")
900
      uvm_report_warning("TPRGED", {"Object type '",obj.get_type_name(),
901
                         "' already registered with factory. "}, UVM_NONE);
902
  end
903
  else begin
904
    m_types[obj] = 1;
905
    // If a named override happens before the type is registered, need to copy
906
    // the override queue.
907
    // Note:Registration occurs via static initialization, which occurs ahead of
908
    // procedural (e.g. initial) blocks. There should not be any preexisting overrides.
909
    if(m_inst_override_name_queues.exists(obj.get_type_name())) begin
910
       m_inst_override_queues[obj] = new;
911
       m_inst_override_queues[obj].queue = m_inst_override_name_queues[obj.get_type_name()].queue;
912
       m_inst_override_name_queues.delete(obj.get_type_name());
913
    end
914
    if(m_wildcard_inst_overrides.size()) begin
915
       if(! m_inst_override_queues.exists(obj))
916
            m_inst_override_queues[obj] = new;
917
       foreach (m_wildcard_inst_overrides[i]) begin
918
         if(uvm_is_match( m_wildcard_inst_overrides[i].orig_type_name, obj.get_type_name()))
919
            m_inst_override_queues[obj].queue.push_back(m_wildcard_inst_overrides[i]);
920
       end
921
    end
922
 
923
  end
924
 
925
endfunction
926
 
927
 
928
// set_type_override_by_type
929
// -------------------------
930
 
931
function void uvm_default_factory::set_type_override_by_type (uvm_object_wrapper original_type,
932
                                                      uvm_object_wrapper override_type,
933
                                                      bit replace=1);
934
  bit replaced;
935
 
936
  // check that old and new are not the same
937
  if (original_type == override_type) begin
938
    if (original_type.get_type_name() == "" || original_type.get_type_name() == "")
939
      uvm_report_warning("TYPDUP", {"Original and override type ",
940
                                    "arguments are identical"}, UVM_NONE);
941
    else
942
      uvm_report_warning("TYPDUP", {"Original and override type ",
943
                                    "arguments are identical: ",
944
                                    original_type.get_type_name()}, UVM_NONE);
945
  end
946
 
947
  // register the types if not already done so, for the benefit of string-based lookup
948
  if (!m_types.exists(original_type))
949
    register(original_type);
950
 
951
  if (!m_types.exists(override_type))
952
    register(override_type);
953
 
954
 
955
  // check for existing type override
956
  foreach (m_type_overrides[index]) begin
957
    if (m_type_overrides[index].orig_type == original_type ||
958
        (m_type_overrides[index].orig_type_name != "" &&
959
         m_type_overrides[index].orig_type_name != "" &&
960
         m_type_overrides[index].orig_type_name == original_type.get_type_name())) begin
961
      string msg;
962
      msg = {"Original object type '",original_type.get_type_name(),
963
             "' already registered to produce '",
964
             m_type_overrides[index].ovrd_type_name,"'"};
965
      if (!replace) begin
966
        msg = {msg, ".  Set 'replace' argument to replace the existing entry."};
967
        uvm_report_info("TPREGD", msg, UVM_MEDIUM);
968
        return;
969
      end
970
      msg = {msg, ".  Replacing with override to produce type '",
971
                  override_type.get_type_name(),"'."};
972
      uvm_report_info("TPREGR", msg, UVM_MEDIUM);
973
      replaced = 1;
974
      m_type_overrides[index].orig_type = original_type;
975
      m_type_overrides[index].orig_type_name = original_type.get_type_name();
976
      m_type_overrides[index].ovrd_type = override_type;
977
      m_type_overrides[index].ovrd_type_name = override_type.get_type_name();
978
    end
979
  end
980
 
981
  // make a new entry
982
  if (!replaced) begin
983
    uvm_factory_override override;
984
    override = new(.orig_type(original_type),
985
                   .orig_type_name(original_type.get_type_name()),
986
                   .full_inst_path("*"),
987
                   .ovrd_type(override_type));
988
 
989
    m_type_overrides.push_back(override);
990
  end
991
 
992
endfunction
993
 
994
 
995
// set_type_override_by_name
996
// -------------------------
997
 
998
function void uvm_default_factory::set_type_override_by_name (string original_type_name,
999
                                                      string override_type_name,
1000
                                                      bit replace=1);
1001
  bit replaced;
1002
 
1003
  uvm_object_wrapper original_type;
1004
  uvm_object_wrapper override_type;
1005
 
1006
  if(m_type_names.exists(original_type_name))
1007
    original_type = m_type_names[original_type_name];
1008
 
1009
  if(m_type_names.exists(override_type_name))
1010
    override_type = m_type_names[override_type_name];
1011
 
1012
  // check that type is registered with the factory
1013
  if (override_type == null) begin
1014
      uvm_report_error("TYPNTF", {"Cannot register override for original type '",
1015
      original_type_name,"' because the override type '",
1016
      override_type_name, "' is not registered with the factory."}, UVM_NONE);
1017
    return;
1018
  end
1019
 
1020
  // check that old and new are not the same
1021
  if (original_type_name == override_type_name) begin
1022
      uvm_report_warning("TYPDUP", {"Requested and actual type name ",
1023
      " arguments are identical: ",original_type_name,". Ignoring this override."}, UVM_NONE);
1024
    return;
1025
  end
1026
 
1027
  foreach (m_type_overrides[index]) begin
1028
    if (m_type_overrides[index].orig_type_name == original_type_name) begin
1029
      if (!replace) begin
1030
        uvm_report_info("TPREGD", {"Original type '",original_type_name,
1031
          "' already registered to produce '",m_type_overrides[index].ovrd_type_name,
1032
          "'.  Set 'replace' argument to replace the existing entry."}, UVM_MEDIUM);
1033
        return;
1034
      end
1035
      uvm_report_info("TPREGR", {"Original object type '",original_type_name,
1036
        "' already registered to produce '",m_type_overrides[index].ovrd_type_name,
1037
        "'.  Replacing with override to produce type '",override_type_name,"'."}, UVM_MEDIUM);
1038
      replaced = 1;
1039
      m_type_overrides[index].ovrd_type = override_type;
1040
      m_type_overrides[index].ovrd_type_name = override_type_name;
1041
    end
1042
  end
1043
 
1044
  if (original_type == null)
1045
    m_lookup_strs[original_type_name] = 1;
1046
 
1047
  if (!replaced) begin
1048
    uvm_factory_override override;
1049
    override = new(.orig_type(original_type),
1050
                   .orig_type_name(original_type_name),
1051
                   .full_inst_path("*"),
1052
                   .ovrd_type(override_type));
1053
 
1054
    m_type_overrides.push_back(override);
1055
//    m_type_names[original_type_name] = override.ovrd_type;
1056
  end
1057
 
1058
endfunction
1059
 
1060
 
1061
// check_inst_override_exists
1062
// --------------------------
1063
function bit uvm_default_factory::check_inst_override_exists (uvm_object_wrapper original_type,
1064
                                      uvm_object_wrapper override_type,
1065
                                      string full_inst_path);
1066
  uvm_factory_override override;
1067
  uvm_factory_queue_class qc;
1068
 
1069
  if (m_inst_override_queues.exists(original_type))
1070
    qc = m_inst_override_queues[original_type];
1071
  else
1072
    return 0;
1073
 
1074
  for (int index=0; index
1075
 
1076
    override = qc.queue[index];
1077
    if (override.full_inst_path == full_inst_path &&
1078
        override.orig_type == original_type &&
1079
        override.ovrd_type == override_type &&
1080
        override.orig_type_name == original_type.get_type_name()) begin
1081
    uvm_report_info("DUPOVRD",{"Instance override for '",
1082
       original_type.get_type_name(),"' already exists: override type '",
1083
       override_type.get_type_name(),"' with full_inst_path '",
1084
       full_inst_path,"'"},UVM_HIGH);
1085
      return 1;
1086
    end
1087
  end
1088
  return 0;
1089
endfunction
1090
 
1091
// set_inst_override_by_type
1092
// -------------------------
1093
 
1094
function void uvm_default_factory::set_inst_override_by_type (uvm_object_wrapper original_type,
1095
                                                      uvm_object_wrapper override_type,
1096
                                                      string full_inst_path);
1097
 
1098
  uvm_factory_override override;
1099
 
1100
  // register the types if not already done so
1101
  if (!m_types.exists(original_type))
1102
    register(original_type);
1103
 
1104
  if (!m_types.exists(override_type))
1105
    register(override_type);
1106
 
1107
  if (check_inst_override_exists(original_type,override_type,full_inst_path))
1108
    return;
1109
 
1110
  if(!m_inst_override_queues.exists(original_type))
1111
    m_inst_override_queues[original_type] = new;
1112
 
1113
  override = new(.full_inst_path(full_inst_path),
1114
                 .orig_type(original_type),
1115
                 .orig_type_name(original_type.get_type_name()),
1116
                 .ovrd_type(override_type));
1117
 
1118
 
1119
  m_inst_override_queues[original_type].queue.push_back(override);
1120
 
1121
endfunction
1122
 
1123
 
1124
// set_inst_override_by_name
1125
// -------------------------
1126
 
1127
function void uvm_default_factory::set_inst_override_by_name (string original_type_name,
1128
                                                      string override_type_name,
1129
                                                      string full_inst_path);
1130
 
1131
  uvm_factory_override override;
1132
  uvm_object_wrapper original_type;
1133
  uvm_object_wrapper override_type;
1134
 
1135
  if(m_type_names.exists(original_type_name))
1136
    original_type = m_type_names[original_type_name];
1137
 
1138
  if(m_type_names.exists(override_type_name))
1139
    override_type = m_type_names[override_type_name];
1140
 
1141
  // check that type is registered with the factory
1142
  if (override_type == null) begin
1143
    uvm_report_error("TYPNTF", {"Cannot register instance override with type name '",
1144
    original_type_name,"' and instance path '",full_inst_path,"' because the type it's supposed ",
1145
    "to produce, '",override_type_name,"', is not registered with the factory."}, UVM_NONE);
1146
    return;
1147
  end
1148
 
1149
  if (original_type == null)
1150
      m_lookup_strs[original_type_name] = 1;
1151
 
1152
  override = new(.full_inst_path(full_inst_path),
1153
                 .orig_type(original_type),
1154
                 .orig_type_name(original_type_name),
1155
                 .ovrd_type(override_type));
1156
 
1157
  if(original_type != null) begin
1158
    if (check_inst_override_exists(original_type,override_type,full_inst_path))
1159
      return;
1160
    if(!m_inst_override_queues.exists(original_type))
1161
      m_inst_override_queues[original_type] = new;
1162
    m_inst_override_queues[original_type].queue.push_back(override);
1163
  end
1164
  else begin
1165
    if(m_has_wildcard(original_type_name)) begin
1166
       foreach(m_type_names[i]) begin
1167
         if(uvm_is_match(original_type_name,i)) begin
1168
           this.set_inst_override_by_name(i, override_type_name, full_inst_path);
1169
         end
1170
       end
1171
       m_wildcard_inst_overrides.push_back(override);
1172
    end
1173
    else begin
1174
      if(!m_inst_override_name_queues.exists(original_type_name))
1175
        m_inst_override_name_queues[original_type_name] = new;
1176
      m_inst_override_name_queues[original_type_name].queue.push_back(override);
1177
    end
1178
  end
1179
 
1180
endfunction
1181
 
1182
function bit uvm_default_factory::m_has_wildcard(string nm);
1183
  foreach (nm[i])
1184
    if(nm[i] == "*" || nm[i] == "?") return 1;
1185
  return 0;
1186
endfunction
1187
 
1188
// create_object_by_name
1189
// ---------------------
1190
 
1191
function uvm_object uvm_default_factory::create_object_by_name (string requested_type_name,
1192
                                                        string parent_inst_path="",
1193
                                                        string name="");
1194
 
1195
  uvm_object_wrapper wrapper;
1196
  string inst_path;
1197
 
1198
  if (parent_inst_path == "")
1199
    inst_path = name;
1200
  else if (name != "")
1201
    inst_path = {parent_inst_path,".",name};
1202
  else
1203
    inst_path = parent_inst_path;
1204
 
1205
  m_override_info.delete();
1206
 
1207
  wrapper = find_override_by_name(requested_type_name, inst_path);
1208
 
1209
  // if no override exists, try to use requested_type_name directly
1210
  if (wrapper==null) begin
1211
    if(!m_type_names.exists(requested_type_name)) begin
1212
      uvm_report_warning("BDTYP",{"Cannot create an object of type '",
1213
      requested_type_name,"' because it is not registered with the factory."}, UVM_NONE);
1214
      return null;
1215
    end
1216
    wrapper = m_type_names[requested_type_name];
1217
  end
1218
 
1219
  return wrapper.create_object(name);
1220
 
1221
endfunction
1222
 
1223
 
1224
// create_object_by_type
1225
// ---------------------
1226
 
1227
function uvm_object uvm_default_factory::create_object_by_type (uvm_object_wrapper requested_type,
1228
                                                        string parent_inst_path="",
1229
                                                        string name="");
1230
 
1231
  string full_inst_path;
1232
 
1233
  if (parent_inst_path == "")
1234
    full_inst_path = name;
1235
  else if (name != "")
1236
    full_inst_path = {parent_inst_path,".",name};
1237
  else
1238
    full_inst_path = parent_inst_path;
1239
 
1240
  m_override_info.delete();
1241
 
1242
  requested_type = find_override_by_type(requested_type, full_inst_path);
1243
 
1244
  return requested_type.create_object(name);
1245
 
1246
endfunction
1247
 
1248
 
1249
// create_component_by_name
1250
// ------------------------
1251
 
1252
function uvm_component uvm_default_factory::create_component_by_name (string requested_type_name,
1253
                                                              string parent_inst_path="",
1254
                                                              string name,
1255
                                                              uvm_component parent);
1256
  uvm_object_wrapper wrapper;
1257
  string inst_path;
1258
 
1259
  if (parent_inst_path == "")
1260
    inst_path = name;
1261
  else if (name != "")
1262
    inst_path = {parent_inst_path,".",name};
1263
  else
1264
    inst_path = parent_inst_path;
1265
 
1266
  m_override_info.delete();
1267
 
1268
  wrapper = find_override_by_name(requested_type_name, inst_path);
1269
 
1270
  // if no override exists, try to use requested_type_name directly
1271
  if (wrapper == null) begin
1272
    if(!m_type_names.exists(requested_type_name)) begin
1273
      uvm_report_warning("BDTYP",{"Cannot create a component of type '",
1274
      requested_type_name,"' because it is not registered with the factory."}, UVM_NONE);
1275
      return null;
1276
    end
1277
    wrapper = m_type_names[requested_type_name];
1278
  end
1279
 
1280
  return wrapper.create_component(name, parent);
1281
 
1282
endfunction
1283
 
1284
 
1285
// create_component_by_type
1286
// ------------------------
1287
 
1288
function uvm_component uvm_default_factory::create_component_by_type (uvm_object_wrapper requested_type,
1289
                                                            string parent_inst_path="",
1290
                                                            string name,
1291
                                                            uvm_component parent);
1292
  string full_inst_path;
1293
 
1294
  if (parent_inst_path == "")
1295
    full_inst_path = name;
1296
  else if (name != "")
1297
    full_inst_path = {parent_inst_path,".",name};
1298
  else
1299
    full_inst_path = parent_inst_path;
1300
 
1301
  m_override_info.delete();
1302
 
1303
  requested_type = find_override_by_type(requested_type, full_inst_path);
1304
 
1305
  return requested_type.create_component(name, parent);
1306
 
1307
endfunction
1308
 
1309
 
1310
 
1311
// find_wrapper_by_name
1312
// ------------
1313
 
1314
function uvm_object_wrapper uvm_default_factory::find_wrapper_by_name(string type_name);
1315
 
1316
  if (m_type_names.exists(type_name))
1317
    return m_type_names[type_name];
1318
 
1319
  uvm_report_warning("UnknownTypeName", {"find_wrapper_by_name: Type name '",type_name,
1320
      "' not registered with the factory."}, UVM_NONE);
1321
 
1322
endfunction
1323
 
1324
 
1325
// find_override_by_name
1326
// ---------------------
1327
 
1328
function uvm_object_wrapper uvm_default_factory::find_override_by_name (string requested_type_name,
1329
                                                                string full_inst_path);
1330
  uvm_object_wrapper rtype;
1331
  uvm_factory_queue_class qc;
1332
  uvm_factory_override lindex;
1333
 
1334
  uvm_object_wrapper override;
1335
 
1336
  if (m_type_names.exists(requested_type_name))
1337
    rtype = m_type_names[requested_type_name];
1338
 
1339
/***
1340
  if(rtype == null) begin
1341
    if(requested_type_name != "") begin
1342
      uvm_report_warning("TYPNTF", {"Requested type name ",
1343
         requested_type_name, " is not registered with the factory. The instance override to ",
1344
         full_inst_path, " is ignored"}, UVM_NONE);
1345
    end
1346
    m_lookup_strs[requested_type_name] = 1;
1347
    return null;
1348
  end
1349
***/
1350
 
1351
  if (full_inst_path != "") begin
1352
    if(rtype == null) begin
1353
      if(m_inst_override_name_queues.exists(requested_type_name))
1354
        qc = m_inst_override_name_queues[requested_type_name];
1355
    end
1356
    else begin
1357
      if(m_inst_override_queues.exists(rtype))
1358
        qc = m_inst_override_queues[rtype];
1359
    end
1360
    if(qc != null)
1361
      for(int index = 0; index
1362
        if (uvm_is_match(qc.queue[index].orig_type_name, requested_type_name) &&
1363
            uvm_is_match(qc.queue[index].full_inst_path, full_inst_path)) begin
1364
          m_override_info.push_back(qc.queue[index]);
1365
          if (m_debug_pass) begin
1366
            if (override == null) begin
1367
              override = qc.queue[index].ovrd_type;
1368
              qc.queue[index].selected = 1;
1369
              lindex=qc.queue[index];
1370
            end
1371
          end
1372
          else begin
1373
                qc.queue[index].used++;
1374
            if (qc.queue[index].ovrd_type.get_type_name() == requested_type_name)
1375
              return qc.queue[index].ovrd_type;
1376
            else
1377
              return find_override_by_type(qc.queue[index].ovrd_type,full_inst_path);
1378
          end
1379
        end
1380
      end
1381
  end
1382
 
1383
  if(rtype != null && !m_inst_override_queues.exists(rtype) && m_wildcard_inst_overrides.size()) begin
1384
     m_inst_override_queues[rtype] = new;
1385
     foreach (m_wildcard_inst_overrides[i]) begin
1386
       if(uvm_is_match(m_wildcard_inst_overrides[i].orig_type_name, requested_type_name))
1387
         m_inst_override_queues[rtype].queue.push_back(m_wildcard_inst_overrides[i]);
1388
     end
1389
  end
1390
 
1391
  // type override - exact match
1392
  foreach (m_type_overrides[index])
1393
    if (m_type_overrides[index].orig_type_name == requested_type_name) begin
1394
      m_override_info.push_back(m_type_overrides[index]);
1395
      if (m_debug_pass) begin
1396
        if (override == null) begin
1397
          override = m_type_overrides[index].ovrd_type;
1398
          m_type_overrides[index].selected = 1;
1399
          lindex=m_type_overrides[index];
1400
        end
1401
      end
1402
      else begin
1403
            m_type_overrides[index].used++;
1404
        return find_override_by_type(m_type_overrides[index].ovrd_type,full_inst_path);
1405
      end
1406
    end
1407
 
1408
 
1409
  if (m_debug_pass && override != null) begin
1410
        lindex.used++;
1411
    return find_override_by_type(override, full_inst_path);
1412
  end
1413
 
1414
  // No override found
1415
  return null;
1416
 
1417
 
1418
endfunction
1419
 
1420
 
1421
// find_override_by_type
1422
// ---------------------
1423
 
1424
function uvm_object_wrapper uvm_default_factory::find_override_by_type(uvm_object_wrapper requested_type,
1425
                                                               string full_inst_path);
1426
 
1427
  uvm_object_wrapper override;
1428
  uvm_factory_override lindex;
1429
 
1430
  uvm_factory_queue_class qc;
1431
  qc = m_inst_override_queues.exists(requested_type) ?
1432
       m_inst_override_queues[requested_type] : null;
1433
 
1434
  foreach (m_override_info[index]) begin
1435
    if ( //index != m_override_info.size()-1 &&
1436
       m_override_info[index].orig_type == requested_type) begin
1437
      uvm_report_error("OVRDLOOP", "Recursive loop detected while finding override.", UVM_NONE);
1438
      if (!m_debug_pass)
1439
        debug_create_by_type (requested_type, full_inst_path);
1440
 
1441
          m_override_info[index].used++;
1442
      return requested_type;
1443
    end
1444
  end
1445
 
1446
  // inst override; return first match; takes precedence over type overrides
1447
  if (full_inst_path != "" && qc != null)
1448
    for (int index = 0; index < qc.queue.size(); ++index) begin
1449
      if ((qc.queue[index].orig_type == requested_type ||
1450
           (qc.queue[index].orig_type_name != "" &&
1451
            qc.queue[index].orig_type_name != "" &&
1452
            qc.queue[index].orig_type_name == requested_type.get_type_name())) &&
1453
          uvm_is_match(qc.queue[index].full_inst_path, full_inst_path)) begin
1454
        m_override_info.push_back(qc.queue[index]);
1455
        if (m_debug_pass) begin
1456
          if (override == null) begin
1457
            override = qc.queue[index].ovrd_type;
1458
            qc.queue[index].selected = 1;
1459
            lindex=qc.queue[index];
1460
          end
1461
        end
1462
        else begin
1463
              qc.queue[index].used++;
1464
          if (qc.queue[index].ovrd_type == requested_type)
1465
            return requested_type;
1466
          else
1467
            return find_override_by_type(qc.queue[index].ovrd_type,full_inst_path);
1468
        end
1469
      end
1470
    end
1471
 
1472
  // type override - exact match
1473
  foreach (m_type_overrides[index]) begin
1474
    if (m_type_overrides[index].orig_type == requested_type ||
1475
        (m_type_overrides[index].orig_type_name != "" &&
1476
         m_type_overrides[index].orig_type_name != "" &&
1477
         requested_type != null &&
1478
         m_type_overrides[index].orig_type_name == requested_type.get_type_name())) begin
1479
      m_override_info.push_back(m_type_overrides[index]);
1480
      if (m_debug_pass) begin
1481
        if (override == null) begin
1482
          override = m_type_overrides[index].ovrd_type;
1483
          m_type_overrides[index].selected = 1;
1484
          lindex=m_type_overrides[index];
1485
        end
1486
      end
1487
      else begin
1488
            m_type_overrides[index].used++;
1489
        if (m_type_overrides[index].ovrd_type == requested_type)
1490
          return requested_type;
1491
        else
1492
          return find_override_by_type(m_type_overrides[index].ovrd_type,full_inst_path);
1493
      end
1494
    end
1495
  end
1496
 
1497
  // type override with wildcard match
1498
  //foreach (m_type_overrides[index])
1499
  //  if (uvm_is_match(index,requested_type.get_type_name())) begin
1500
  //    m_override_info.push_back(m_inst_overrides[index]);
1501
  //    return find_override_by_type(m_type_overrides[index],full_inst_path);
1502
  //  end
1503
 
1504
  if (m_debug_pass && override != null) begin
1505
    lindex.used++;
1506
    if (override == requested_type) begin
1507
      return requested_type;
1508
    end
1509
    else
1510
      return find_override_by_type(override,full_inst_path);
1511
  end
1512
 
1513
  return requested_type;
1514
 
1515
endfunction
1516
 
1517
 
1518
// print
1519
// -----
1520
 
1521
function void uvm_default_factory::print (int all_types=1);
1522
 
1523
  string key;
1524
  uvm_factory_queue_class sorted_override_queues[string];
1525
  string qs[$];
1526
 
1527
  string tmp;
1528
  int id;
1529
  uvm_object_wrapper obj;
1530
 
1531
  //sort the override queues
1532
  foreach (m_inst_override_queues[i]) begin
1533
    obj = i;
1534
    tmp = obj.get_type_name();
1535
    if(tmp == "") $swrite(tmp, "__unnamed_id_%0d", id++);
1536
    sorted_override_queues[tmp] = m_inst_override_queues[i];
1537
 
1538
  end
1539
  foreach (m_inst_override_name_queues[i]) begin
1540
    sorted_override_queues[i] = m_inst_override_name_queues[i];
1541
  end
1542
 
1543
  qs.push_back("\n#### Factory Configuration (*)\n\n");
1544
 
1545
  // print instance overrides
1546
  if(!m_type_overrides.size() && !sorted_override_queues.num())
1547
    qs.push_back("  No instance or type overrides are registered with this factory\n");
1548
  else begin
1549
    int max1,max2,max3;
1550
    string dash = "---------------------------------------------------------------------------------------------------";
1551
    string space= "                                                                                                   ";
1552
 
1553
    // print instance overrides
1554
    if(!sorted_override_queues.num())
1555
      qs.push_back("No instance overrides are registered with this factory\n");
1556
    else begin
1557
      foreach(sorted_override_queues[j]) begin
1558
        uvm_factory_queue_class qc;
1559
        qc = sorted_override_queues[j];
1560
        for (int i=0; i
1561
          if (qc.queue[i].orig_type_name.len() > max1)
1562
            max1=qc.queue[i].orig_type_name.len();
1563
          if (qc.queue[i].full_inst_path.len() > max2)
1564
            max2=qc.queue[i].full_inst_path.len();
1565
          if (qc.queue[i].ovrd_type_name.len() > max3)
1566
            max3=qc.queue[i].ovrd_type_name.len();
1567
        end
1568
      end
1569
      if (max1 < 14) max1 = 14;
1570
      if (max2 < 13) max2 = 13;
1571
      if (max3 < 13) max3 = 13;
1572
 
1573
      qs.push_back("Instance Overrides:\n\n");
1574
      qs.push_back($sformatf("  %0s%0s  %0s%0s  %0s%0s\n","Requested Type",space.substr(1,max1-14),
1575
                                          "Override Path", space.substr(1,max2-13),
1576
                                          "Override Type", space.substr(1,max3-13)));
1577
      qs.push_back($sformatf("  %0s  %0s  %0s\n",dash.substr(1,max1),
1578
                                 dash.substr(1,max2),
1579
                                 dash.substr(1,max3)));
1580
 
1581
      foreach(sorted_override_queues[j]) begin
1582
        uvm_factory_queue_class qc;
1583
        qc = sorted_override_queues[j];
1584
        for (int i=0; i
1585
          qs.push_back($sformatf("  %0s%0s  %0s%0s",qc.queue[i].orig_type_name,
1586
                 space.substr(1,max1-qc.queue[i].orig_type_name.len()),
1587
                 qc.queue[i].full_inst_path,
1588
                 space.substr(1,max2-qc.queue[i].full_inst_path.len())));
1589
          qs.push_back($sformatf("  %0s\n",     qc.queue[i].ovrd_type_name));
1590
        end
1591
      end
1592
    end
1593
 
1594
    // print type overrides
1595
    if (!m_type_overrides.size())
1596
      qs.push_back("\nNo type overrides are registered with this factory\n");
1597
    else begin
1598
      // Resize for type overrides
1599
      if (max1 < 14) max1 = 14;
1600
      if (max2 < 13) max2 = 13;
1601
      if (max3 < 13) max3 = 13;
1602
 
1603
      foreach (m_type_overrides[i]) begin
1604
        if (m_type_overrides[i].orig_type_name.len() > max1)
1605
          max1=m_type_overrides[i].orig_type_name.len();
1606
        if (m_type_overrides[i].ovrd_type_name.len() > max2)
1607
          max2=m_type_overrides[i].ovrd_type_name.len();
1608
      end
1609
      if (max1 < 14) max1 = 14;
1610
      if (max2 < 13) max2 = 13;
1611
      qs.push_back("\nType Overrides:\n\n");
1612
      qs.push_back($sformatf("  %0s%0s  %0s%0s\n","Requested Type",space.substr(1,max1-14),
1613
                                  "Override Type", space.substr(1,max2-13)));
1614
      qs.push_back($sformatf("  %0s  %0s\n",dash.substr(1,max1),
1615
                            dash.substr(1,max2)));
1616
      foreach (m_type_overrides[index])
1617
        qs.push_back($sformatf("  %0s%0s  %0s\n",
1618
                 m_type_overrides[index].orig_type_name,
1619
                 space.substr(1,max1-m_type_overrides[index].orig_type_name.len()),
1620
                 m_type_overrides[index].ovrd_type_name));
1621
    end
1622
  end
1623
 
1624
  // print all registered types, if all_types >= 1
1625
  if (all_types >= 1 && m_type_names.first(key)) begin
1626
    bit banner;
1627
    qs.push_back($sformatf("\nAll types registered with the factory: %0d total\n",m_types.num()));
1628
    do begin
1629
      // filter out uvm_ classes (if all_types<2) and non-types (lookup strings)
1630
      if (!(all_types < 2 && uvm_is_match("uvm_*",
1631
           m_type_names[key].get_type_name())) &&
1632
           key == m_type_names[key].get_type_name()) begin
1633
        if (!banner) begin
1634
          qs.push_back("  Type Name\n");
1635
          qs.push_back("  ---------\n");
1636
          banner=1;
1637
        end
1638
        qs.push_back($sformatf("  %s\n", m_type_names[key].get_type_name()));
1639
      end
1640
    end while(m_type_names.next(key));
1641
  end
1642
 
1643
  qs.push_back("(*) Types with no associated type name will be printed as \n\n####\n\n");
1644
 
1645
  `uvm_info("UVM/FACTORY/PRINT",`UVM_STRING_QUEUE_STREAMING_PACK(qs),UVM_NONE)
1646
 
1647
endfunction
1648
 
1649
 
1650
// debug_create_by_name
1651
// --------------------
1652
 
1653
function void  uvm_default_factory::debug_create_by_name (string requested_type_name,
1654
                                                  string parent_inst_path="",
1655
                                                  string name="");
1656
  m_debug_create(requested_type_name, null, parent_inst_path, name);
1657
endfunction
1658
 
1659
 
1660
// debug_create_by_type
1661
// --------------------
1662
 
1663
function void  uvm_default_factory::debug_create_by_type (uvm_object_wrapper requested_type,
1664
                                                  string parent_inst_path="",
1665
                                                  string name="");
1666
  m_debug_create("", requested_type, parent_inst_path, name);
1667
endfunction
1668
 
1669
 
1670
// m_debug_create
1671
// --------------
1672
 
1673
function void  uvm_default_factory::m_debug_create (string requested_type_name,
1674
                                            uvm_object_wrapper requested_type,
1675
                                            string parent_inst_path,
1676
                                            string name);
1677
 
1678
  string full_inst_path;
1679
  uvm_object_wrapper result;
1680
 
1681
  if (parent_inst_path == "")
1682
    full_inst_path = name;
1683
  else if (name != "")
1684
    full_inst_path = {parent_inst_path,".",name};
1685
  else
1686
    full_inst_path = parent_inst_path;
1687
 
1688
  m_override_info.delete();
1689
 
1690
  if (requested_type == null) begin
1691
    if (!m_type_names.exists(requested_type_name) &&
1692
      !m_lookup_strs.exists(requested_type_name)) begin
1693
      uvm_report_warning("Factory Warning", {"The factory does not recognize '",
1694
        requested_type_name,"' as a registered type."}, UVM_NONE);
1695
      return;
1696
    end
1697
    m_debug_pass = 1;
1698
 
1699
    result = find_override_by_name(requested_type_name,full_inst_path);
1700
  end
1701
  else begin
1702
    m_debug_pass = 1;
1703
    if (!m_types.exists(requested_type))
1704
      register(requested_type);
1705
    result = find_override_by_type(requested_type,full_inst_path);
1706
    if (requested_type_name == "")
1707
      requested_type_name = requested_type.get_type_name();
1708
  end
1709
 
1710
  m_debug_display(requested_type_name, result, full_inst_path);
1711
  m_debug_pass = 0;
1712
 
1713
  foreach (m_override_info[index])
1714
    m_override_info[index].selected = 0;
1715
 
1716
endfunction
1717
 
1718
 
1719
// m_debug_display
1720
// ---------------
1721
 
1722
function void  uvm_default_factory::m_debug_display (string requested_type_name,
1723
                                             uvm_object_wrapper result,
1724
                                             string full_inst_path);
1725
 
1726
  int    max1,max2,max3;
1727
  string dash = "---------------------------------------------------------------------------------------------------";
1728
  string space= "                                                                                                   ";
1729
  string qs[$];
1730
 
1731
  qs.push_back("\n#### Factory Override Information (*)\n\n");
1732
  qs.push_back(
1733
        $sformatf("Given a request for an object of type '%s' with an instance\npath of '%s' the factory encountered\n\n",
1734
                requested_type_name,full_inst_path));
1735
 
1736
  if (m_override_info.size() == 0)
1737
    qs.push_back("no relevant overrides.\n\n");
1738
  else begin
1739
 
1740
    qs.push_back("the following relevant overrides. An 'x' next to a match indicates a\nmatch that was ignored.\n\n");
1741
 
1742
    foreach (m_override_info[i]) begin
1743
      if (m_override_info[i].orig_type_name.len() > max1)
1744
        max1=m_override_info[i].orig_type_name.len();
1745
      if (m_override_info[i].full_inst_path.len() > max2)
1746
        max2=m_override_info[i].full_inst_path.len();
1747
      if (m_override_info[i].ovrd_type_name.len() > max3)
1748
        max3=m_override_info[i].ovrd_type_name.len();
1749
    end
1750
 
1751
    if (max1 < 13) max1 = 13;
1752
    if (max2 < 13) max2 = 13;
1753
    if (max3 < 13) max3 = 13;
1754
 
1755
    qs.push_back($sformatf("Original Type%0s  Instance Path%0s  Override Type%0s\n",
1756
        space.substr(1,max1-13),space.substr(1,max2-13),space.substr(1,max3-13)));
1757
 
1758
    qs.push_back($sformatf("  %0s  %0s  %0s\n",dash.substr(1,max1),
1759
                               dash.substr(1,max2),
1760
                               dash.substr(1,max3)));
1761
 
1762
    foreach (m_override_info[i]) begin
1763
      qs.push_back($sformatf("%s%0s%0s\n",
1764
             m_override_info[i].selected ? "  " : "x ",
1765
             m_override_info[i].orig_type_name,
1766
             space.substr(1,max1-m_override_info[i].orig_type_name.len())));
1767
      qs.push_back($sformatf("  %0s%0s", m_override_info[i].full_inst_path,
1768
             space.substr(1,max2-m_override_info[i].full_inst_path.len())));
1769
      qs.push_back($sformatf("  %0s%0s", m_override_info[i].ovrd_type_name,
1770
             space.substr(1,max3-m_override_info[i].ovrd_type_name.len())));
1771
      if (m_override_info[i].full_inst_path == "*")
1772
        qs.push_back("  ");
1773
      else
1774
        qs.push_back("\n");
1775
    end
1776
    qs.push_back("\n");
1777
  end
1778
 
1779
 
1780
  qs.push_back("Result:\n\n");
1781
  qs.push_back($sformatf("  The factory will produce an object of type '%0s'\n",
1782
           result == null ? requested_type_name : result.get_type_name()));
1783
 
1784
  qs.push_back("\n(*) Types with no associated type name will be printed as \n\n####\n\n");
1785
 
1786
  `uvm_info("UVM/FACTORY/DUMP",`UVM_STRING_QUEUE_STREAMING_PACK(qs),UVM_NONE)
1787
endfunction
1788
 
1789
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.