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

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [reg/] [uvm_reg_block.svh] - Blame information for rev 16

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//
2
// -------------------------------------------------------------
3
//    Copyright 2004-2011 Synopsys, Inc.
4
//    Copyright 2010-2011 Mentor Graphics Corporation
5
//    Copyright 2010-2011 Cadence Design Systems, Inc.
6
//    All Rights Reserved Worldwide
7
//
8
//    Licensed under the Apache License, Version 2.0 (the
9
//    "License"); you may not use this file except in
10
//    compliance with the License.  You may obtain a copy of
11
//    the License at
12
//
13
//        http://www.apache.org/licenses/LICENSE-2.0
14
//
15
//    Unless required by applicable law or agreed to in
16
//    writing, software distributed under the License is
17
//    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
18
//    CONDITIONS OF ANY KIND, either express or implied.  See
19
//    the License for the specific language governing
20
//    permissions and limitations under the License.
21
// -------------------------------------------------------------
22
//
23
 
24
 
25
 
26
//------------------------------------------------------------------------
27
// Class: uvm_reg_block
28
//
29
// Block abstraction base class
30
//
31
// A block represents a design hierarchy. It can contain registers,
32
// register files, memories and sub-blocks.
33
//
34
// A block has one or more address maps, each corresponding to a physical
35
// interface on the block.
36
//
37
//------------------------------------------------------------------------
38
virtual class uvm_reg_block extends uvm_object;
39
 
40
   local uvm_reg_block  parent;
41
 
42
   local static bit     m_roots[uvm_reg_block];
43
   local int unsigned   blks[uvm_reg_block];
44
   local int unsigned   regs[uvm_reg];
45
   local int unsigned   vregs[uvm_vreg];
46
   local int unsigned   mems[uvm_mem];
47
   local bit            maps[uvm_reg_map];
48
 
49
   // Variable: default_path
50
   // Default access path for the registers and memories in this block.
51
   uvm_path_e      default_path = UVM_DEFAULT_PATH;
52
 
53
   local string         default_hdl_path = "RTL";
54
   local uvm_reg_backdoor backdoor;
55
   local uvm_object_string_pool #(uvm_queue #(string)) hdl_paths_pool;
56
   local string         root_hdl_paths[string];
57
 
58
   local bit            locked;
59
 
60
   local int            has_cover;
61
   local int            cover_on;
62
   local string         fname;
63
   local int            lineno;
64
 
65
   local static int id;
66
 
67
   //----------------------
68
   // Group: Initialization
69
   //----------------------
70
 
71
   // Function: new
72
   //
73
   // Create a new instance and type-specific configuration
74
   //
75
   // Creates an instance of a block abstraction class with the specified
76
   // name.
77
   //
78
   // ~has_coverage~ specifies which functional coverage models are present in
79
   // the extension of the block abstraction class.
80
   // Multiple functional coverage models may be specified by adding their
81
   // symbolic names, as defined by the  type.
82
   //
83
   extern function new(string name="", int has_coverage=UVM_NO_COVERAGE);
84
 
85
 
86
   // Function: configure
87
   //
88
   // Instance-specific configuration
89
   //
90
   // Specify the parent block of this block.
91
   // A block without parent is a root block.
92
   //
93
   // If the block file corresponds to a hierarchical RTL structure,
94
   // its contribution to the HDL path is specified as the ~hdl_path~.
95
   // Otherwise, the block does not correspond to a hierarchical RTL
96
   // structure (e.g. it is physically flattened) and does not contribute
97
   // to the hierarchical HDL path of any contained registers or memories.
98
   //
99
   extern function void configure(uvm_reg_block parent=null,
100
                                  string hdl_path="");
101
 
102
 
103
   // Function: create_map
104
   //
105
   // Create an address map in this block
106
   //
107
   // Create an address map with the specified ~name~, then
108
   // configures it with the following properties.
109
   //
110
   // base_addr - the base address for the map. All registers, memories,
111
   //             and sub-blocks within the map will be at offsets to this
112
   //             address
113
   //
114
   // n_bytes   - the byte-width of the bus on which this map is used
115
   //
116
   // endian    - the endian format. See  for possible
117
   //             values
118
   //
119
   // byte_addressing - specifies whether consecutive addresses refer are 1 byte
120
   //             apart (TRUE) or ~n_bytes~ apart (FALSE). Default is TRUE.
121
   //
122
   //| APB = create_map("APB", 0, 1, UVM_LITTLE_ENDIAN, 1);
123
   //
124
   extern virtual function uvm_reg_map create_map(string name,
125
                                                  uvm_reg_addr_t base_addr,
126
                                                  int unsigned n_bytes,
127
                                                  uvm_endianness_e endian,
128
                                                  bit byte_addressing = 1);
129
 
130
 
131
   // Function: check_data_width
132
   //
133
   // Check that the specified data width (in bits) is less than
134
   // or equal to the value of `UVM_REG_DATA_WIDTH
135
   //
136
   // This method is designed to be called by a static initializer
137
   //
138
   //| class my_blk extends uvm_reg_block;
139
   //|   local static bit m_data_width = check_data_width(356);
140
   //|   ...
141
   //| endclass
142
   //
143
   extern protected static function bit check_data_width(int unsigned width);
144
 
145
 
146
 
147
   // Function: set_default_map
148
   //
149
   // Defines the default address map
150
   //
151
   // Set the specified address map as the  for this
152
   // block. The address map must be a map of this address block.
153
   //
154
   extern function void set_default_map (uvm_reg_map map);
155
 
156
 
157
   // Variable: default_map
158
   //
159
   // Default address map
160
   //
161
   // Default address map for this block, to be used when no
162
   // address map is specified for a register operation and that
163
   // register is accessible from more than one address map.
164
   //
165
   // It is also the implicit address map for a block with a single,
166
   // unnamed address map because it has only one physical interface.
167
   //
168
   uvm_reg_map default_map;
169
 
170
   extern function uvm_reg_map get_default_map ();
171
 
172
   extern virtual function void set_parent(uvm_reg_block parent);
173
 
174
   /*local*/ extern function void add_block (uvm_reg_block blk);
175
   /*local*/ extern function void add_map   (uvm_reg_map map);
176
   /*local*/ extern function void add_reg   (uvm_reg  rg);
177
   /*local*/ extern function void add_vreg  (uvm_vreg vreg);
178
   /*local*/ extern function void add_mem   (uvm_mem  mem);
179
 
180
 
181
   // Function: lock_model
182
   //
183
   // Lock a model and build the address map.
184
   //
185
   // Recursively lock an entire register model
186
   // and build the address maps to enable the
187
   //  and
188
   //  methods.
189
   //
190
   // Once locked, no further structural changes,
191
   // such as adding registers or memories,
192
   // can be made.
193
   //
194
   // It is not possible to unlock a model.
195
   //
196
   extern virtual function void lock_model();
197
 
198
 
199
   // Function: is_locked
200
   //
201
   // Return TRUE if the model is locked.
202
   //
203
   extern function bit is_locked();
204
 
205
 
206
   //---------------------
207
   // Group: Introspection
208
   //---------------------
209
 
210
 
211
   // Function: get_name
212
   //
213
   // Get the simple name
214
   //
215
   // Return the simple object name of this block.
216
   //
217
 
218
 
219
   // Function: get_full_name
220
   //
221
   // Get the hierarchical name
222
   //
223
   // Return the hierarchal name of this block.
224
   // The base of the hierarchical name is the root block.
225
   //
226
   extern virtual function string get_full_name();
227
 
228
 
229
   // Function: get_parent
230
   //
231
   // Get the parent block
232
   //
233
   // If this a top-level block, returns ~null~.
234
   //
235
   extern virtual function uvm_reg_block get_parent();
236
 
237
 
238
   // Function: get_root_blocks
239
   //
240
   // Get the all root blocks
241
   //
242
   // Returns an array of all root blocks in the simulation.
243
   //
244
   extern static  function void get_root_blocks(ref uvm_reg_block blks[$]);
245
 
246
 
247
   // Function: find_blocks
248
   //
249
   // Find the blocks whose hierarchical names match the
250
   // specified ~name~ glob.
251
   // If a ~root~ block is specified, the name of the blocks are
252
   // relative to that block, otherwise they are absolute.
253
   //
254
   // Returns the number of blocks found.
255
   //
256
   extern static function int find_blocks(input string        name,
257
                                          ref   uvm_reg_block blks[$],
258
                                          input uvm_reg_block root = null,
259
                                          input uvm_object    accessor = null);
260
 
261
 
262
   // Function: find_block
263
   //
264
   // Find the first block whose hierarchical names match the
265
   // specified ~name~ glob.
266
   // If a ~root~ block is specified, the name of the blocks are
267
   // relative to that block, otherwise they are absolute.
268
   //
269
   // Returns the first block found or ~null~ otherwise.
270
   // A warning is issued if more than one block is found.
271
   //
272
   extern static function uvm_reg_block find_block(input string        name,
273
                                                   input uvm_reg_block root = null,
274
                                                   input uvm_object    accessor = null);
275
 
276
 
277
   // Function: get_blocks
278
   //
279
   // Get the sub-blocks
280
   //
281
   // Get the blocks instantiated in this blocks.
282
   // If ~hier~ is TRUE, recursively includes any sub-blocks.
283
   //
284
   extern virtual function void get_blocks (ref uvm_reg_block  blks[$],
285
                                            input uvm_hier_e hier=UVM_HIER);
286
 
287
 
288
   // Function: get_maps
289
   //
290
   // Get the address maps
291
   //
292
   // Get the address maps instantiated in this block.
293
   //
294
   extern virtual function void get_maps (ref uvm_reg_map maps[$]);
295
 
296
 
297
   // Function: get_registers
298
   //
299
   // Get the registers
300
   //
301
   // Get the registers instantiated in this block.
302
   // If ~hier~ is TRUE, recursively includes the registers
303
   // in the sub-blocks.
304
   //
305
   // Note that registers may be located in different and/or multiple
306
   // address maps. To get the registers in a specific address map,
307
   // use the  method.
308
   //
309
   extern virtual function void get_registers (ref uvm_reg regs[$],
310
                                               input uvm_hier_e hier=UVM_HIER);
311
 
312
 
313
   // Function: get_fields
314
   //
315
   // Get the fields
316
   //
317
   // Get the fields in the registers instantiated in this block.
318
   // If ~hier~ is TRUE, recursively includes the fields of the registers
319
   // in the sub-blocks.
320
   //
321
   extern virtual function void get_fields (ref uvm_reg_field  fields[$],
322
                                            input uvm_hier_e hier=UVM_HIER);
323
 
324
 
325
   // Function: get_memories
326
   //
327
   // Get the memories
328
   //
329
   // Get the memories instantiated in this block.
330
   // If ~hier~ is TRUE, recursively includes the memories
331
   // in the sub-blocks.
332
   //
333
   // Note that memories may be located in different and/or multiple
334
   // address maps. To get the memories in a specific address map,
335
   // use the  method.
336
   //
337
   extern virtual function void get_memories (ref uvm_mem mems[$],
338
                                              input uvm_hier_e hier=UVM_HIER);
339
 
340
 
341
   // Function: get_virtual_registers
342
   //
343
   // Get the virtual registers
344
   //
345
   // Get the virtual registers instantiated in this block.
346
   // If ~hier~ is TRUE, recursively includes the virtual registers
347
   // in the sub-blocks.
348
   //
349
   extern virtual function void get_virtual_registers(ref uvm_vreg regs[$],
350
                                                input uvm_hier_e hier=UVM_HIER);
351
 
352
 
353
   // Function: get_virtual_fields
354
   //
355
   // Get the virtual fields
356
   //
357
   // Get the virtual fields from the virtual registers instantiated
358
   // in this block.
359
   // If ~hier~ is TRUE, recursively includes the virtual fields
360
   // in the virtual registers in the sub-blocks.
361
   //
362
   extern virtual function void get_virtual_fields (ref uvm_vreg_field fields[$],
363
                                                 input uvm_hier_e hier=UVM_HIER);
364
 
365
 
366
   // Function: get_block_by_name
367
   //
368
   // Finds a sub-block with the specified simple name.
369
   //
370
   // The name is the simple name of the block, not a hierarchical name.
371
   // relative to this block.
372
   // If no block with that name is found in this block, the sub-blocks
373
   // are searched for a block of that name and the first one to be found
374
   // is returned.
375
   //
376
   // If no blocks are found, returns ~null~.
377
   //
378
   extern virtual function uvm_reg_block get_block_by_name (string name);
379
 
380
 
381
   // Function: get_map_by_name
382
   //
383
   // Finds an address map with the specified simple name.
384
   //
385
   // The name is the simple name of the address map, not a hierarchical name.
386
   // relative to this block.
387
   // If no map with that name is found in this block, the sub-blocks
388
   // are searched for a map of that name and the first one to be found
389
   // is returned.
390
   //
391
   // If no address maps are found, returns ~null~.
392
   //
393
   extern virtual function uvm_reg_map get_map_by_name (string name);
394
 
395
 
396
   // Function: get_reg_by_name
397
   //
398
   // Finds a register with the specified simple name.
399
   //
400
   // The name is the simple name of the register, not a hierarchical name.
401
   // relative to this block.
402
   // If no register with that name is found in this block, the sub-blocks
403
   // are searched for a register of that name and the first one to be found
404
   // is returned.
405
   //
406
   // If no registers are found, returns ~null~.
407
   //
408
   extern virtual function uvm_reg get_reg_by_name (string name);
409
 
410
 
411
   // Function: get_field_by_name
412
   //
413
   // Finds a field with the specified simple name.
414
   //
415
   // The name is the simple name of the field, not a hierarchical name.
416
   // relative to this block.
417
   // If no field with that name is found in this block, the sub-blocks
418
   // are searched for a field of that name and the first one to be found
419
   // is returned.
420
   //
421
   // If no fields are found, returns ~null~.
422
   //
423
   extern virtual function uvm_reg_field get_field_by_name (string name);
424
 
425
 
426
   // Function: get_mem_by_name
427
   //
428
   // Finds a memory with the specified simple name.
429
   //
430
   // The name is the simple name of the memory, not a hierarchical name.
431
   // relative to this block.
432
   // If no memory with that name is found in this block, the sub-blocks
433
   // are searched for a memory of that name and the first one to be found
434
   // is returned.
435
   //
436
   // If no memories are found, returns ~null~.
437
   //
438
   extern virtual function uvm_mem get_mem_by_name (string name);
439
 
440
 
441
   // Function: get_vreg_by_name
442
   //
443
   // Finds a virtual register with the specified simple name.
444
   //
445
   // The name is the simple name of the virtual register,
446
   // not a hierarchical name.
447
   // relative to this block.
448
   // If no virtual register with that name is found in this block,
449
   // the sub-blocks are searched for a virtual register of that name
450
   // and the first one to be found is returned.
451
   //
452
   // If no virtual registers are found, returns ~null~.
453
   //
454
   extern virtual function uvm_vreg get_vreg_by_name (string name);
455
 
456
 
457
   // Function: get_vfield_by_name
458
   //
459
   // Finds a virtual field with the specified simple name.
460
   //
461
   // The name is the simple name of the virtual field,
462
   // not a hierarchical name.
463
   // relative to this block.
464
   // If no virtual field with that name is found in this block,
465
   // the sub-blocks are searched for a virtual field of that name
466
   // and the first one to be found is returned.
467
   //
468
   // If no virtual fields are found, returns ~null~.
469
   //
470
   extern virtual function uvm_vreg_field get_vfield_by_name (string name);
471
 
472
 
473
   //----------------
474
   // Group: Coverage
475
   //----------------
476
 
477
 
478
   // Function: build_coverage
479
   //
480
   // Check if all of the specified coverage model must be built.
481
   //
482
   // Check which of the specified coverage model must be built
483
   // in this instance of the block abstraction class,
484
   // as specified by calls to .
485
   //
486
   // Models are specified by adding the symbolic value of individual
487
   // coverage model as defined in .
488
   // Returns the sum of all coverage models to be built in the
489
   // block model.
490
   //
491
   extern protected function uvm_reg_cvr_t build_coverage(uvm_reg_cvr_t models);
492
 
493
 
494
   // Function: add_coverage
495
   //
496
   // Specify that additional coverage models are available.
497
   //
498
   // Add the specified coverage model to the coverage models
499
   // available in this class.
500
   // Models are specified by adding the symbolic value of individual
501
   // coverage model as defined in .
502
   //
503
   // This method shall be called only in the constructor of
504
   // subsequently derived classes.
505
   //
506
   extern virtual protected function void add_coverage(uvm_reg_cvr_t models);
507
 
508
 
509
   // Function: has_coverage
510
   //
511
   // Check if block has coverage model(s)
512
   //
513
   // Returns TRUE if the block abstraction class contains a coverage model
514
   // for all of the models specified.
515
   // Models are specified by adding the symbolic value of individual
516
   // coverage model as defined in .
517
   //
518
   extern virtual function bit has_coverage(uvm_reg_cvr_t models);
519
 
520
 
521
   // Function: set_coverage
522
   //
523
   // Turns on coverage measurement.
524
   //
525
   // Turns the collection of functional coverage measurements on or off
526
   // for this block and all blocks, registers, fields and memories within it.
527
   // The functional coverage measurement is turned on for every
528
   // coverage model specified using  symbolic
529
   // identifiers.
530
   // Multiple functional coverage models can be specified by adding
531
   // the functional coverage model identifiers.
532
   // All other functional coverage models are turned off.
533
   // Returns the sum of all functional
534
   // coverage models whose measurements were previously on.
535
   //
536
   // This method can only control the measurement of functional
537
   // coverage models that are present in the various abstraction classes,
538
   // then enabled during construction.
539
   // See the  method to identify
540
   // the available functional coverage models.
541
   //
542
   extern virtual function uvm_reg_cvr_t set_coverage(uvm_reg_cvr_t is_on);
543
 
544
 
545
   // Function: get_coverage
546
   //
547
   // Check if coverage measurement is on.
548
   //
549
   // Returns TRUE if measurement for all of the specified functional
550
   // coverage models are currently on.
551
   // Multiple functional coverage models can be specified by adding the
552
   // functional coverage model identifiers.
553
   //
554
   // See  for more details.
555
   //
556
   extern virtual function bit get_coverage(uvm_reg_cvr_t is_on = UVM_CVR_ALL);
557
 
558
 
559
   // Function: sample
560
   //
561
   // Functional coverage measurement method
562
   //
563
   // This method is invoked by the block abstraction class
564
   // whenever an address within one of its address map
565
   // is successfully read or written.
566
   // The specified offset is the offset within the block,
567
   // not an absolute address.
568
   //
569
   // Empty by default, this method may be extended by the
570
   // abstraction class generator to perform the required sampling
571
   // in any provided functional coverage model.
572
   //
573
   protected virtual function void  sample(uvm_reg_addr_t offset,
574
                                           bit            is_read,
575
                                           uvm_reg_map    map);
576
   endfunction
577
 
578
 
579
   // Function: sample_values
580
   //
581
   // Functional coverage measurement method for field values
582
   //
583
   // This method is invoked by the user
584
   // or by the  method of the parent block
585
   // to trigger the sampling
586
   // of the current field values in the
587
   // block-level functional coverage model.
588
   // It recursively invokes the 
589
   // and  methods
590
   // in the blocks and registers in this block.
591
   //
592
   // This method may be extended by the
593
   // abstraction class generator to perform the required sampling
594
   // in any provided field-value functional coverage model.
595
   // If this method is extended, it MUST call super.sample_values().
596
   //
597
   extern virtual function void sample_values();
598
 
599
   /*local*/ extern function void XsampleX(uvm_reg_addr_t addr,
600
                                           bit            is_read,
601
                                           uvm_reg_map    map);
602
 
603
 
604
   //--------------
605
   // Group: Access
606
   //--------------
607
 
608
   // Function: get_default_path
609
   //
610
   // Default access path
611
   //
612
   // Returns the default access path for this block.
613
   //
614
   extern virtual function uvm_path_e get_default_path();
615
 
616
 
617
   // Function: reset
618
   //
619
   // Reset the mirror for this block.
620
   //
621
   // Sets the mirror value of all registers in the block and sub-blocks
622
   // to the reset value corresponding to the specified reset event.
623
   // See  for more details.
624
   // Does not actually set the value of the registers in the design,
625
   // only the values mirrored in their corresponding mirror.
626
   //
627
   extern virtual function void reset(string kind = "HARD");
628
 
629
 
630
   // Function: needs_update
631
   //
632
   // Check if DUT registers need to be written
633
   //
634
   // If a mirror value has been modified in the abstraction model
635
   // without actually updating the actual register
636
   // (either through randomization or via the  method,
637
   // the mirror and state of the registers are outdated.
638
   // The corresponding registers in the DUT need to be updated.
639
   //
640
   // This method returns TRUE if the state of at least one register in
641
   // the block or sub-blocks needs to be updated to match the mirrored
642
   // values.
643
   // The mirror values, or actual content of registers, are not modified.
644
   // For additional information, see  method.
645
   //
646
   extern virtual function bit needs_update();
647
 
648
 
649
   // Task: update
650
   //
651
   // Batch update of register.
652
   //
653
   // Using the minimum number of write operations, updates the registers
654
   // in the design to match the mirrored values in this block and sub-blocks.
655
   // The update can be performed using the physical
656
   // interfaces (front-door access) or back-door accesses.
657
   // This method performs the reverse operation of .
658
   //
659
   extern virtual task update(output uvm_status_e       status,
660
                              input  uvm_path_e         path = UVM_DEFAULT_PATH,
661
                              input  uvm_sequence_base  parent = null,
662
                              input  int                prior = -1,
663
                              input  uvm_object         extension = null,
664
                              input  string             fname = "",
665
                              input  int                lineno = 0);
666
 
667
 
668
   // Task: mirror
669
   //
670
   // Update the mirrored values
671
   //
672
   // Read all of the registers in this block and sub-blocks and update their
673
   // mirror values to match their corresponding values in the design.
674
   // The mirroring can be performed using the physical interfaces
675
   // (front-door access) or back-door accesses.
676
   // If the ~check~ argument is specified as ,
677
   // an error message is issued if the current mirrored value
678
   // does not match the actual value in the design.
679
   // This method performs the reverse operation of .
680
   //
681
   extern virtual task mirror(output uvm_status_e       status,
682
                              input  uvm_check_e        check = UVM_NO_CHECK,
683
                              input  uvm_path_e         path  = UVM_DEFAULT_PATH,
684
                              input  uvm_sequence_base  parent = null,
685
                              input  int                prior = -1,
686
                              input  uvm_object         extension = null,
687
                              input  string             fname = "",
688
                              input  int                lineno = 0);
689
 
690
 
691
   // Task: write_reg_by_name
692
   //
693
   // Write the named register
694
   //
695
   // Equivalent to  followed by 
696
   //
697
   extern virtual task write_reg_by_name(
698
                              output uvm_status_e        status,
699
                              input  string              name,
700
                              input  uvm_reg_data_t      data,
701
                              input  uvm_path_e     path = UVM_DEFAULT_PATH,
702
                              input  uvm_reg_map         map = null,
703
                              input  uvm_sequence_base   parent = null,
704
                              input  int                 prior = -1,
705
                              input  uvm_object          extension = null,
706
                              input  string              fname = "",
707
                              input  int                 lineno = 0);
708
 
709
 
710
   // Task: read_reg_by_name
711
   //
712
   // Read the named register
713
   //
714
   // Equivalent to  followed by 
715
   //
716
   extern virtual task read_reg_by_name(
717
                              output uvm_status_e       status,
718
                              input  string             name,
719
                              output uvm_reg_data_t     data,
720
                              input  uvm_path_e    path = UVM_DEFAULT_PATH,
721
                              input  uvm_reg_map        map = null,
722
                              input  uvm_sequence_base  parent = null,
723
                              input  int                prior = -1,
724
                              input  uvm_object         extension = null,
725
                              input  string             fname = "",
726
                              input  int                lineno = 0);
727
 
728
 
729
   // Task: write_mem_by_name
730
   //
731
   // Write the named memory
732
   //
733
   // Equivalent to  followed by 
734
   //
735
   extern virtual task write_mem_by_name(
736
                              output uvm_status_e       status,
737
                              input  string             name,
738
                              input  uvm_reg_addr_t     offset,
739
                              input  uvm_reg_data_t     data,
740
                              input  uvm_path_e    path = UVM_DEFAULT_PATH,
741
                              input  uvm_reg_map        map = null,
742
                              input  uvm_sequence_base  parent = null,
743
                              input  int                prior = -1,
744
                              input  uvm_object         extension = null,
745
                              input  string             fname = "",
746
                              input  int                lineno = 0);
747
 
748
 
749
   // Task: read_mem_by_name
750
   //
751
   // Read the named memory
752
   //
753
   // Equivalent to  followed by 
754
   //
755
   extern virtual task read_mem_by_name(
756
                              output uvm_status_e       status,
757
                              input  string             name,
758
                              input  uvm_reg_addr_t     offset,
759
                              output uvm_reg_data_t     data,
760
                              input  uvm_path_e    path = UVM_DEFAULT_PATH,
761
                              input  uvm_reg_map        map = null,
762
                              input  uvm_sequence_base  parent = null,
763
                              input  int                prior = -1,
764
                              input  uvm_object         extension = null,
765
                              input  string             fname = "",
766
                              input  int                lineno = 0);
767
 
768
 
769
   extern virtual task readmemh(string filename);
770
   extern virtual task writememh(string filename);
771
 
772
 
773
 
774
   //----------------
775
   // Group: Backdoor
776
   //----------------
777
 
778
   // Function: get_backdoor
779
   //
780
   // Get the user-defined backdoor for all registers in this block
781
   //
782
   // Return the user-defined backdoor for all register in this
783
   // block and all sub-blocks -- unless overridden by a backdoor set
784
   // in a lower-level block or in the register itself.
785
   //
786
   // If ~inherited~ is TRUE, returns the backdoor of the parent block
787
   // if none have been specified for this block.
788
   //
789
   extern function uvm_reg_backdoor get_backdoor(bit inherited = 1);
790
 
791
 
792
   // Function: set_backdoor
793
   //
794
   // Set the user-defined backdoor for all registers in this block
795
   //
796
   // Defines the backdoor mechanism for all registers instantiated
797
   // in this block and sub-blocks, unless overridden by a definition
798
   // in a lower-level block or register.
799
   //
800
   extern function void set_backdoor (uvm_reg_backdoor bkdr,
801
                                      string fname = "",
802
                                      int lineno = 0);
803
 
804
 
805
   // Function:  clear_hdl_path
806
   //
807
   // Delete HDL paths
808
   //
809
   // Remove any previously specified HDL path to the block instance
810
   // for the specified design abstraction.
811
   //
812
   extern function void clear_hdl_path (string kind = "RTL");
813
 
814
 
815
   // Function:  add_hdl_path
816
   //
817
   // Add an HDL path
818
   //
819
   // Add the specified HDL path to the block instance for the specified
820
   // design abstraction. This method may be called more than once for the
821
   // same design abstraction if the block is physically duplicated
822
   // in the design abstraction
823
   //
824
   extern function void add_hdl_path (string path, string kind = "RTL");
825
 
826
 
827
   // Function:   has_hdl_path
828
   //
829
   // Check if a HDL path is specified
830
   //
831
   // Returns TRUE if the block instance has a HDL path defined for the
832
   // specified design abstraction. If no design abstraction is specified,
833
   // uses the default design abstraction specified for this block or
834
   // the nearest block ancestor with a specified default design abstraction.
835
   //
836
   extern function bit has_hdl_path (string kind = "");
837
 
838
 
839
   // Function:  get_hdl_path
840
   //
841
   // Get the incremental HDL path(s)
842
   //
843
   // Returns the HDL path(s) defined for the specified design abstraction
844
   // in the block instance.
845
   // Returns only the component of the HDL paths that corresponds to
846
   // the block, not a full hierarchical path
847
   //
848
   // If no design abstraction is specified, the default design abstraction
849
   // for this block is used.
850
   //
851
   extern function void get_hdl_path (ref string paths[$], input string kind = "");
852
 
853
 
854
   // Function:  get_full_hdl_path
855
   //
856
   // Get the full hierarchical HDL path(s)
857
   //
858
   // Returns the full hierarchical HDL path(s) defined for the specified
859
   // design abstraction in the block instance.
860
   // There may be more than one path returned even
861
   // if only one path was defined for the block instance, if any of the
862
   // parent components have more than one path defined for the same design
863
   // abstraction
864
   //
865
   // If no design abstraction is specified, the default design abstraction
866
   // for each ancestor block is used to get each incremental path.
867
   //
868
   extern function void get_full_hdl_path (ref string paths[$],
869
                                           input string kind = "",
870
                                           string separator = ".");
871
 
872
 
873
   // Function: set_default_hdl_path
874
   //
875
   // Set the default design abstraction
876
   //
877
   // Set the default design abstraction for this block instance.
878
   //
879
   extern function void   set_default_hdl_path (string kind);
880
 
881
 
882
   // Function:  get_default_hdl_path
883
   //
884
   // Get the default design abstraction
885
   //
886
   // Returns the default design abstraction for this block instance.
887
   // If a default design abstraction has not been explicitly set for this
888
   // block instance, returns the default design abstraction for the
889
   // nearest block ancestor.
890
   // Returns "" if no default design abstraction has been specified.
891
   //
892
   extern function string get_default_hdl_path ();
893
 
894
 
895
   // Function: set_hdl_path_root
896
   //
897
   // Specify a root HDL path
898
   //
899
   // Set the specified path as the absolute HDL path to the block instance
900
   // for the specified design abstraction.
901
   // This absolute root path is prepended to all hierarchical paths
902
   // under this block. The HDL path of any ancestor block is ignored.
903
   // This method overrides any incremental path for the
904
   // same design abstraction specified using .
905
   //
906
   extern function void set_hdl_path_root (string path, string kind = "RTL");
907
 
908
 
909
   // Function: is_hdl_path_root
910
   //
911
   // Check if this block has an absolute path
912
   //
913
   // Returns TRUE if an absolute HDL path to the block instance
914
   // for the specified design abstraction has been defined.
915
   // If no design abstraction is specified, the default design abstraction
916
   // for this block is used.
917
   //
918
   extern function bit is_hdl_path_root (string kind = "");
919
 
920
 
921
   extern virtual function void   do_print      (uvm_printer printer);
922
   extern virtual function void   do_copy       (uvm_object rhs);
923
   extern virtual function bit    do_compare    (uvm_object  rhs,
924
                                                 uvm_comparer comparer);
925
   extern virtual function void   do_pack       (uvm_packer packer);
926
   extern virtual function void   do_unpack     (uvm_packer packer);
927
   extern virtual function string convert2string ();
928
   extern virtual function uvm_object clone();
929
 
930
   extern local function void Xinit_address_mapsX();
931
 
932
endclass: uvm_reg_block
933
 
934
//------------------------------------------------------------------------
935
 
936
 
937
//---------------
938
// Initialization
939
//---------------
940
 
941
// check_data_width
942
 
943
function bit uvm_reg_block::check_data_width(int unsigned width);
944
   if (width <= $bits(uvm_reg_data_t)) return 1;
945
 
946
   `uvm_fatal("RegModel", $sformatf("Register model requires that UVM_REG_DATA_WIDTH be defined as %0d or greater. Currently defined as %0d", width, `UVM_REG_DATA_WIDTH))
947
 
948
   return 0;
949
endfunction
950
 
951
 
952
// new
953
 
954
function uvm_reg_block::new(string name="", int has_coverage=UVM_NO_COVERAGE);
955
   super.new(name);
956
   hdl_paths_pool = new("hdl_paths");
957
   this.has_cover = has_coverage;
958
   // Root block until registered with a parent
959
   m_roots[this] = 0;
960
endfunction: new
961
 
962
 
963
// configure
964
 
965
function void uvm_reg_block::configure(uvm_reg_block parent=null, string hdl_path="");
966
  this.parent = parent;
967
  if (parent != null)
968
    this.parent.add_block(this);
969
  add_hdl_path(hdl_path);
970
 
971
  uvm_resource_db#(uvm_reg_block)::set("uvm_reg::*", get_full_name(), this);
972
endfunction
973
 
974
 
975
// add_block
976
 
977
function void uvm_reg_block::add_block (uvm_reg_block blk);
978
   if (this.is_locked()) begin
979
      `uvm_error("RegModel", "Cannot add subblock to locked block model");
980
      return;
981
   end
982
   if (this.blks.exists(blk)) begin
983
      `uvm_error("RegModel", {"Subblock '",blk.get_name(),
984
         "' has already been registered with block '",get_name(),"'"})
985
       return;
986
   end
987
   blks[blk] = id++;
988
   if (m_roots.exists(blk)) m_roots.delete(blk);
989
endfunction
990
 
991
 
992
// add_reg
993
 
994
function void uvm_reg_block::add_reg(uvm_reg rg);
995
   if (this.is_locked()) begin
996
      `uvm_error("RegModel", "Cannot add register to locked block model");
997
      return;
998
   end
999
 
1000
   if (this.regs.exists(rg)) begin
1001
      `uvm_error("RegModel", {"Register '",rg.get_name(),
1002
         "' has already been registered with block '",get_name(),"'"})
1003
       return;
1004
   end
1005
 
1006
   regs[rg] = id++;
1007
endfunction: add_reg
1008
 
1009
 
1010
// add_vreg
1011
 
1012
function void uvm_reg_block::add_vreg(uvm_vreg vreg);
1013
   if (this.is_locked()) begin
1014
      `uvm_error("RegModel", "Cannot add virtual register to locked block model");
1015
      return;
1016
   end
1017
 
1018
   if (this.vregs.exists(vreg)) begin
1019
      `uvm_error("RegModel", {"Virtual register '",vreg.get_name(),
1020
         "' has already been registered with block '",get_name(),"'"})
1021
       return;
1022
   end
1023
   vregs[vreg] = id++;
1024
endfunction: add_vreg
1025
 
1026
 
1027
// add_mem
1028
 
1029
function void uvm_reg_block::add_mem(uvm_mem mem);
1030
   if (this.is_locked()) begin
1031
      `uvm_error("RegModel", "Cannot add memory to locked block model");
1032
      return;
1033
   end
1034
 
1035
   if (this.mems.exists(mem)) begin
1036
      `uvm_error("RegModel", {"Memory '",mem.get_name(),
1037
         "' has already been registered with block '",get_name(),"'"})
1038
       return;
1039
   end
1040
   mems[mem] = id++;
1041
endfunction: add_mem
1042
 
1043
 
1044
// set_parent
1045
 
1046
function void uvm_reg_block::set_parent(uvm_reg_block parent);
1047
  if (this != parent)
1048
    this.parent = parent;
1049
endfunction
1050
 
1051
 
1052
// is_locked
1053
 
1054
function bit uvm_reg_block::is_locked();
1055
   return this.locked;
1056
endfunction: is_locked
1057
 
1058
 
1059
// lock_model
1060
 
1061
function void uvm_reg_block::lock_model();
1062
 
1063
   if (is_locked())
1064
     return;
1065
 
1066
   locked = 1;
1067
 
1068
   foreach (regs[rg_]) begin
1069
      uvm_reg rg = rg_;
1070
      rg.Xlock_modelX();
1071
   end
1072
 
1073
   foreach (mems[mem_]) begin
1074
      uvm_mem mem = mem_;
1075
      mem.Xlock_modelX();
1076
   end
1077
 
1078
   foreach (blks[blk_]) begin
1079
      uvm_reg_block blk=blk_;
1080
      blk.lock_model();
1081
   end
1082
 
1083
   if (this.parent == null) begin
1084
      int max_size = uvm_reg::get_max_size();
1085
 
1086
      if (uvm_reg_field::get_max_size() > max_size)
1087
         max_size = uvm_reg_field::get_max_size();
1088
 
1089
      if (uvm_mem::get_max_size() > max_size)
1090
         max_size = uvm_mem::get_max_size();
1091
 
1092
      if (max_size > `UVM_REG_DATA_WIDTH) begin
1093
         `uvm_fatal("RegModel", $sformatf("Register model requires that UVM_REG_DATA_WIDTH be defined as %0d or greater. Currently defined as %0d", max_size, `UVM_REG_DATA_WIDTH))
1094
      end
1095
 
1096
      Xinit_address_mapsX();
1097
 
1098
      // Check that root register models have unique names
1099
 
1100
      // Has this name has been checked before?
1101
      if (m_roots[this] != 1) begin
1102
         int n;
1103
 
1104
         foreach (m_roots[_blk]) begin
1105
            uvm_reg_block blk = _blk;
1106
 
1107
            if (blk.get_name() == get_name()) begin
1108
               m_roots[blk] = 1;
1109
               n++;
1110
            end
1111
         end
1112
 
1113
         if (n > 1) begin
1114
            `uvm_error("UVM/REG/DUPLROOT",
1115
                       $sformatf("There are %0d root register models named \"%s\". The names of the root register models have to be unique",
1116
                                 n, get_name()))
1117
         end
1118
      end
1119
   end
1120
 
1121
endfunction: lock_model
1122
 
1123
 
1124
 
1125
//--------------------------
1126
// Get Hierarchical Elements
1127
//--------------------------
1128
 
1129
function string uvm_reg_block::get_full_name();
1130
   if (parent == null)
1131
     return get_name();
1132
 
1133
   return {parent.get_full_name(), ".", get_name()};
1134
 
1135
endfunction: get_full_name
1136
 
1137
 
1138
// get_fields
1139
 
1140
function void uvm_reg_block::get_fields(ref uvm_reg_field fields[$],
1141
                                        input uvm_hier_e hier=UVM_HIER);
1142
 
1143
   foreach (regs[rg_]) begin
1144
     uvm_reg rg = rg_;
1145
     rg.get_fields(fields);
1146
   end
1147
 
1148
   if (hier == UVM_HIER)
1149
     foreach (blks[blk_])
1150
     begin
1151
       uvm_reg_block blk = blk_;
1152
       blk.get_fields(fields);
1153
     end
1154
 
1155
endfunction: get_fields
1156
 
1157
 
1158
// get_virtual_fields
1159
 
1160
function void uvm_reg_block::get_virtual_fields(ref uvm_vreg_field fields[$],
1161
                                                input uvm_hier_e hier=UVM_HIER);
1162
 
1163
   foreach (vregs[vreg_]) begin
1164
     uvm_vreg vreg = vreg_;
1165
     vreg.get_fields(fields);
1166
   end
1167
 
1168
   if (hier == UVM_HIER)
1169
     foreach (blks[blk_]) begin
1170
       uvm_reg_block blk = blk_;
1171
       blk.get_virtual_fields(fields);
1172
     end
1173
endfunction: get_virtual_fields
1174
 
1175
 
1176
// get_registers
1177
 
1178
function void uvm_reg_block::get_registers(ref uvm_reg regs[$],
1179
                                           input uvm_hier_e hier=UVM_HIER);
1180
   foreach (this.regs[rg])
1181
     regs.push_back(rg);
1182
 
1183
   if (hier == UVM_HIER)
1184
     foreach (blks[blk_]) begin
1185
       uvm_reg_block blk = blk_;
1186
       blk.get_registers(regs);
1187
     end
1188
endfunction: get_registers
1189
 
1190
 
1191
// get_virtual_registers
1192
 
1193
function void uvm_reg_block::get_virtual_registers(ref uvm_vreg regs[$],
1194
                                                   input uvm_hier_e hier=UVM_HIER);
1195
 
1196
   foreach (vregs[rg])
1197
     regs.push_back(rg);
1198
 
1199
   if (hier == UVM_HIER)
1200
     foreach (blks[blk_]) begin
1201
       uvm_reg_block blk = blk_;
1202
       blk.get_virtual_registers(regs);
1203
     end
1204
endfunction: get_virtual_registers
1205
 
1206
 
1207
// get_memories
1208
 
1209
function void uvm_reg_block::get_memories(ref uvm_mem mems[$],
1210
                                          input uvm_hier_e hier=UVM_HIER);
1211
 
1212
   foreach (this.mems[mem_]) begin
1213
     uvm_mem mem = mem_;
1214
     mems.push_back(mem);
1215
   end
1216
 
1217
   if (hier == UVM_HIER)
1218
     foreach (blks[blk_]) begin
1219
       uvm_reg_block blk = blk_;
1220
       blk.get_memories(mems);
1221
     end
1222
 
1223
endfunction: get_memories
1224
 
1225
 
1226
// get_blocks
1227
 
1228
function void uvm_reg_block::get_blocks(ref uvm_reg_block blks[$],
1229
                                        input uvm_hier_e hier=UVM_HIER);
1230
 
1231
   foreach (this.blks[blk_]) begin
1232
     uvm_reg_block blk = blk_;
1233
     blks.push_back(blk);
1234
     if (hier == UVM_HIER)
1235
       blk.get_blocks(blks);
1236
   end
1237
 
1238
endfunction: get_blocks
1239
 
1240
 
1241
// get_root_blocks
1242
 
1243
function void uvm_reg_block::get_root_blocks(ref uvm_reg_block blks[$]);
1244
 
1245
   foreach (m_roots[blk]) begin
1246
      blks.push_back(blk);
1247
   end
1248
 
1249
endfunction: get_root_blocks
1250
 
1251
 
1252
// find_blocks
1253
 
1254
function int uvm_reg_block::find_blocks(input string        name,
1255
                                        ref   uvm_reg_block blks[$],
1256
                                        input uvm_reg_block root = null,
1257
                                        input uvm_object    accessor = null);
1258
 
1259
   uvm_resource_pool rpl = uvm_resource_pool::get();
1260
   uvm_resource_types::rsrc_q_t rs;
1261
 
1262
   blks.delete();
1263
 
1264
   if (root != null) name = {root.get_full_name(), ".", name};
1265
 
1266
   rs = rpl.lookup_regex(name, "uvm_reg::");
1267
   for (int i = 0; i < rs.size(); i++) begin
1268
      uvm_resource#(uvm_reg_block) blk;
1269
      if (!$cast(blk, rs.get(i))) continue;
1270
      blks.push_back(blk.read(accessor));
1271
   end
1272
 
1273
   return blks.size();
1274
endfunction
1275
 
1276
 
1277
// find_blocks
1278
 
1279
function uvm_reg_block uvm_reg_block::find_block(input string        name,
1280
                                                 input uvm_reg_block root = null,
1281
                                                 input uvm_object    accessor = null);
1282
 
1283
   uvm_reg_block blks[$];
1284
   if (!find_blocks(name, blks, root, accessor))
1285
      return null;
1286
 
1287
   if (blks.size() > 1) begin
1288
      `uvm_warning("MRTH1BLK",
1289
                   {"More than one block matched the name \"", name, "\"."})
1290
   end
1291
 
1292
 
1293
   return blks[0];
1294
endfunction
1295
 
1296
 
1297
// get_maps
1298
 
1299
function void uvm_reg_block::get_maps(ref uvm_reg_map maps[$]);
1300
 
1301
   foreach (this.maps[map])
1302
     maps.push_back(map);
1303
 
1304
endfunction
1305
 
1306
 
1307
// get_parent
1308
 
1309
function uvm_reg_block uvm_reg_block::get_parent();
1310
   get_parent = this.parent;
1311
endfunction: get_parent
1312
 
1313
 
1314
//------------
1315
// Get-By-Name
1316
//------------
1317
 
1318
// get_block_by_name
1319
 
1320
function uvm_reg_block uvm_reg_block::get_block_by_name(string name);
1321
 
1322
   if (get_name() == name)
1323
     return this;
1324
 
1325
   foreach (blks[blk_]) begin
1326
     uvm_reg_block blk = blk_;
1327
 
1328
     if (blk.get_name() == name)
1329
       return blk;
1330
   end
1331
 
1332
   foreach (blks[blk_]) begin
1333
      uvm_reg_block blk = blk_;
1334
      uvm_reg_block subblks[$];
1335
      blk_.get_blocks(subblks, UVM_HIER);
1336
 
1337
      foreach (subblks[j])
1338
         if (subblks[j].get_name() == name)
1339
            return subblks[j];
1340
   end
1341
 
1342
   `uvm_warning("RegModel", {"Unable to locate block '",name,
1343
                "' in block '",get_full_name(),"'"})
1344
   return null;
1345
 
1346
endfunction: get_block_by_name
1347
 
1348
 
1349
// get_reg_by_name
1350
 
1351
function uvm_reg uvm_reg_block::get_reg_by_name(string name);
1352
 
1353
   foreach (regs[rg_]) begin
1354
     uvm_reg rg = rg_;
1355
     if (rg.get_name() == name)
1356
       return rg;
1357
   end
1358
 
1359
   foreach (blks[blk_]) begin
1360
      uvm_reg_block blk = blk_;
1361
      uvm_reg subregs[$];
1362
      blk_.get_registers(subregs, UVM_HIER);
1363
 
1364
      foreach (subregs[j])
1365
         if (subregs[j].get_name() == name)
1366
            return subregs[j];
1367
   end
1368
 
1369
   `uvm_warning("RegModel", {"Unable to locate register '",name,
1370
                "' in block '",get_full_name(),"'"})
1371
   return null;
1372
 
1373
endfunction: get_reg_by_name
1374
 
1375
 
1376
// get_vreg_by_name
1377
 
1378
function uvm_vreg uvm_reg_block::get_vreg_by_name(string name);
1379
 
1380
   foreach (vregs[rg_]) begin
1381
     uvm_vreg rg = rg_;
1382
     if (rg.get_name() == name)
1383
       return rg;
1384
   end
1385
 
1386
   foreach (blks[blk_]) begin
1387
      uvm_reg_block blk = blk_;
1388
      uvm_vreg subvregs[$];
1389
      blk_.get_virtual_registers(subvregs, UVM_HIER);
1390
 
1391
      foreach (subvregs[j])
1392
         if (subvregs[j].get_name() == name)
1393
            return subvregs[j];
1394
   end
1395
 
1396
   `uvm_warning("RegModel", {"Unable to locate virtual register '",name,
1397
                "' in block '",get_full_name(),"'"})
1398
   return null;
1399
 
1400
endfunction: get_vreg_by_name
1401
 
1402
 
1403
// get_mem_by_name
1404
 
1405
function uvm_mem uvm_reg_block::get_mem_by_name(string name);
1406
 
1407
   foreach (mems[mem_]) begin
1408
     uvm_mem mem = mem_;
1409
     if (mem.get_name() == name)
1410
       return mem;
1411
   end
1412
 
1413
   foreach (blks[blk_]) begin
1414
      uvm_reg_block blk = blk_;
1415
      uvm_mem submems[$];
1416
      blk_.get_memories(submems, UVM_HIER);
1417
 
1418
      foreach (submems[j])
1419
         if (submems[j].get_name() == name)
1420
            return submems[j];
1421
   end
1422
 
1423
   `uvm_warning("RegModel", {"Unable to locate memory '",name,
1424
                "' in block '",get_full_name(),"'"})
1425
   return null;
1426
 
1427
endfunction: get_mem_by_name
1428
 
1429
 
1430
// get_field_by_name
1431
 
1432
function uvm_reg_field uvm_reg_block::get_field_by_name(string name);
1433
 
1434
   foreach (regs[rg_]) begin
1435
      uvm_reg rg = rg_;
1436
      uvm_reg_field fields[$];
1437
 
1438
      rg.get_fields(fields);
1439
      foreach (fields[i])
1440
        if (fields[i].get_name() == name)
1441
          return fields[i];
1442
   end
1443
 
1444
   foreach (blks[blk_]) begin
1445
      uvm_reg_block blk = blk_;
1446
      uvm_reg subregs[$];
1447
      blk_.get_registers(subregs, UVM_HIER);
1448
 
1449
      foreach (subregs[j]) begin
1450
         uvm_reg_field fields[$];
1451
         subregs[j].get_fields(fields);
1452
         foreach (fields[i])
1453
            if (fields[i].get_name() == name)
1454
               return fields[i];
1455
      end
1456
   end
1457
 
1458
   `uvm_warning("RegModel", {"Unable to locate field '",name,
1459
                "' in block '",get_full_name(),"'"})
1460
 
1461
   return null;
1462
 
1463
endfunction: get_field_by_name
1464
 
1465
 
1466
// get_vfield_by_name
1467
 
1468
function uvm_vreg_field uvm_reg_block::get_vfield_by_name(string name);
1469
 
1470
   foreach (vregs[rg_]) begin
1471
      uvm_vreg rg =rg_;
1472
      uvm_vreg_field fields[$];
1473
 
1474
      rg.get_fields(fields);
1475
      foreach (fields[i])
1476
        if (fields[i].get_name() == name)
1477
          return fields[i];
1478
   end
1479
 
1480
   foreach (blks[blk_]) begin
1481
      uvm_reg_block blk = blk_;
1482
      uvm_vreg subvregs[$];
1483
      blk_.get_virtual_registers(subvregs, UVM_HIER);
1484
 
1485
      foreach (subvregs[j]) begin
1486
         uvm_vreg_field fields[$];
1487
         subvregs[j].get_fields(fields);
1488
         foreach (fields[i])
1489
            if (fields[i].get_name() == name)
1490
               return fields[i];
1491
      end
1492
   end
1493
 
1494
   `uvm_warning("RegModel", {"Unable to locate virtual field '",name,
1495
                "' in block '",get_full_name(),"'"})
1496
 
1497
   return null;
1498
 
1499
endfunction: get_vfield_by_name
1500
 
1501
 
1502
 
1503
//-------------
1504
// Coverage API
1505
//-------------
1506
 
1507
// set_coverage
1508
 
1509
function uvm_reg_cvr_t uvm_reg_block::set_coverage(uvm_reg_cvr_t is_on);
1510
   this.cover_on = this.has_cover & is_on;
1511
 
1512
   foreach (regs[rg_]) begin
1513
     uvm_reg rg = rg_;
1514
     void'(rg.set_coverage(is_on));
1515
   end
1516
 
1517
   foreach (mems[mem_]) begin
1518
     uvm_mem mem = mem_;
1519
     void'(mem.set_coverage(is_on));
1520
   end
1521
 
1522
   foreach (blks[blk_]) begin
1523
     uvm_reg_block blk = blk_;
1524
     void'(blk.set_coverage(is_on));
1525
   end
1526
 
1527
   return this.cover_on;
1528
endfunction: set_coverage
1529
 
1530
 
1531
// sample_values
1532
 
1533
function void uvm_reg_block::sample_values();
1534
   foreach (regs[rg_]) begin
1535
      uvm_reg rg = rg_;
1536
      rg.sample_values();
1537
   end
1538
 
1539
   foreach (blks[blk_]) begin
1540
      uvm_reg_block blk = blk_;
1541
      blk.sample_values();
1542
   end
1543
endfunction
1544
 
1545
 
1546
// XsampleX
1547
 
1548
function void uvm_reg_block::XsampleX(uvm_reg_addr_t addr,
1549
                                      bit            is_read,
1550
                                      uvm_reg_map    map);
1551
   sample(addr, is_read, map);
1552
   if (parent != null) begin
1553
      // ToDo: Call XsampleX in the parent block
1554
      //       with the offset and map within that block's context
1555
   end
1556
endfunction
1557
 
1558
 
1559
function uvm_reg_cvr_t uvm_reg_block::build_coverage(uvm_reg_cvr_t models);
1560
   build_coverage = UVM_NO_COVERAGE;
1561
   void'(uvm_reg_cvr_rsrc_db::read_by_name({"uvm_reg::", get_full_name()},
1562
                                           "include_coverage",
1563
                                           build_coverage, this));
1564
   return build_coverage & models;
1565
endfunction: build_coverage
1566
 
1567
 
1568
// add_coverage
1569
 
1570
function void uvm_reg_block::add_coverage(uvm_reg_cvr_t models);
1571
   this.has_cover |= models;
1572
endfunction: add_coverage
1573
 
1574
 
1575
// has_coverage
1576
 
1577
function bit uvm_reg_block::has_coverage(uvm_reg_cvr_t models);
1578
   return ((this.has_cover & models) == models);
1579
endfunction: has_coverage
1580
 
1581
 
1582
// get_coverage
1583
 
1584
function bit uvm_reg_block::get_coverage(uvm_reg_cvr_t is_on = UVM_CVR_ALL);
1585
   if (this.has_coverage(is_on) == 0) return 0;
1586
   return ((this.cover_on & is_on) == is_on);
1587
endfunction: get_coverage
1588
 
1589
 
1590
//----------------
1591
// Run-Time Access
1592
//----------------
1593
 
1594
 
1595
// reset
1596
 
1597
function void uvm_reg_block::reset(string kind = "HARD");
1598
 
1599
   foreach (regs[rg_]) begin
1600
     uvm_reg rg = rg_;
1601
     rg.reset(kind);
1602
   end
1603
 
1604
   foreach (blks[blk_]) begin
1605
     uvm_reg_block blk = blk_;
1606
     blk.reset(kind);
1607
   end
1608
endfunction
1609
 
1610
 
1611
// needs_update
1612
 
1613
function bit uvm_reg_block::needs_update();
1614
   needs_update = 0;
1615
 
1616
   foreach (regs[rg_]) begin
1617
     uvm_reg rg = rg_;
1618
     if (rg.needs_update())
1619
       return 1;
1620
   end
1621
   foreach (blks[blk_]) begin
1622
     uvm_reg_block blk =blk_;
1623
     if (blk.needs_update())
1624
       return 1;
1625
   end
1626
endfunction: needs_update
1627
 
1628
 
1629
// update
1630
 
1631
task uvm_reg_block::update(output uvm_status_e  status,
1632
                           input  uvm_path_e    path = UVM_DEFAULT_PATH,
1633
                           input  uvm_sequence_base  parent = null,
1634
                           input  int                prior = -1,
1635
                           input  uvm_object         extension = null,
1636
                           input  string             fname = "",
1637
                           input  int                lineno = 0);
1638
   status = UVM_IS_OK;
1639
 
1640
   if (!needs_update()) begin
1641
     `uvm_info("RegModel", $sformatf("%s:%0d - RegModel block %s does not need updating",
1642
                    fname, lineno, this.get_name()), UVM_HIGH);
1643
      return;
1644
   end
1645
 
1646
   `uvm_info("RegModel", $sformatf("%s:%0d - Updating model block %s with %s path",
1647
                    fname, lineno, this.get_name(), path.name ), UVM_HIGH);
1648
 
1649
   foreach (regs[rg_]) begin
1650
      uvm_reg rg = rg_;
1651
      if (rg.needs_update()) begin
1652
         rg.update(status, path, null, parent, prior, extension);
1653
         if (status != UVM_IS_OK && status != UVM_HAS_X) begin;
1654
           `uvm_error("RegModel", $sformatf("Register \"%s\" could not be updated",
1655
                                        rg.get_full_name()));
1656
           return;
1657
         end
1658
      end
1659
   end
1660
 
1661
   foreach (blks[blk_]) begin
1662
     uvm_reg_block blk = blk_;
1663
     blk.update(status,path,parent,prior,extension,fname,lineno);
1664
   end
1665
endtask: update
1666
 
1667
 
1668
// mirror
1669
 
1670
task uvm_reg_block::mirror(output uvm_status_e       status,
1671
                           input  uvm_check_e        check = UVM_NO_CHECK,
1672
                           input  uvm_path_e         path = UVM_DEFAULT_PATH,
1673
                           input  uvm_sequence_base  parent = null,
1674
                           input  int                prior = -1,
1675
                           input  uvm_object         extension = null,
1676
                           input  string             fname = "",
1677
                           input  int                lineno = 0);
1678
   uvm_status_e final_status = UVM_IS_OK;
1679
 
1680
   foreach (regs[rg_]) begin
1681
      uvm_reg rg = rg_;
1682
      rg.mirror(status, check, path, null,
1683
                parent, prior, extension, fname, lineno);
1684
      if (status != UVM_IS_OK && status != UVM_HAS_X) begin;
1685
         final_status = status;
1686
      end
1687
   end
1688
 
1689
   foreach (blks[blk_]) begin
1690
      uvm_reg_block blk = blk_;
1691
 
1692
      blk.mirror(status, check, path, parent, prior, extension, fname, lineno);
1693
      if (status != UVM_IS_OK && status != UVM_HAS_X) begin;
1694
         final_status = status;
1695
      end
1696
   end
1697
 
1698
endtask: mirror
1699
 
1700
 
1701
// write_reg_by_name
1702
 
1703
task uvm_reg_block::write_reg_by_name(output uvm_status_e   status,
1704
                                      input  string              name,
1705
                                      input  uvm_reg_data_t      data,
1706
                                      input  uvm_path_e     path = UVM_DEFAULT_PATH,
1707
                                      input  uvm_reg_map      map = null,
1708
                                      input  uvm_sequence_base   parent = null,
1709
                                      input  int                 prior = -1,
1710
                                      input  uvm_object          extension = null,
1711
                                      input  string              fname = "",
1712
                                      input  int                 lineno = 0);
1713
   uvm_reg rg;
1714
   this.fname = fname;
1715
   this.lineno = lineno;
1716
 
1717
   status = UVM_NOT_OK;
1718
   rg = this.get_reg_by_name(name);
1719
   if (rg != null)
1720
     rg.write(status, data, path, map, parent, prior, extension);
1721
 
1722
endtask: write_reg_by_name
1723
 
1724
 
1725
// read_reg_by_name
1726
 
1727
task uvm_reg_block::read_reg_by_name(output uvm_status_e  status,
1728
                                     input  string             name,
1729
                                     output uvm_reg_data_t     data,
1730
                                     input  uvm_path_e    path = UVM_DEFAULT_PATH,
1731
                                     input  uvm_reg_map     map = null,
1732
                                     input  uvm_sequence_base  parent = null,
1733
                                     input  int                prior = -1,
1734
                                     input  uvm_object         extension = null,
1735
                                     input  string             fname = "",
1736
                                     input  int                lineno = 0);
1737
   uvm_reg rg;
1738
   this.fname = fname;
1739
   this.lineno = lineno;
1740
 
1741
   status = UVM_NOT_OK;
1742
   rg = this.get_reg_by_name(name);
1743
   if (rg != null)
1744
     rg.read(status, data, path, map, parent, prior, extension);
1745
endtask: read_reg_by_name
1746
 
1747
 
1748
// write_mem_by_name
1749
 
1750
task uvm_reg_block::write_mem_by_name(output uvm_status_e  status,
1751
                                          input  string             name,
1752
                                          input  uvm_reg_addr_t     offset,
1753
                                          input  uvm_reg_data_t     data,
1754
                                          input  uvm_path_e    path = UVM_DEFAULT_PATH,
1755
                                          input  uvm_reg_map     map = null,
1756
                                          input  uvm_sequence_base  parent = null,
1757
                                          input  int                prior = -1,
1758
                                          input  uvm_object         extension = null,
1759
                                          input  string             fname = "",
1760
                                          input  int                lineno = 0);
1761
   uvm_mem mem;
1762
   this.fname = fname;
1763
   this.lineno = lineno;
1764
 
1765
   status = UVM_NOT_OK;
1766
   mem = get_mem_by_name(name);
1767
   if (mem != null)
1768
     mem.write(status, offset, data, path, map, parent, prior, extension);
1769
endtask: write_mem_by_name
1770
 
1771
 
1772
// read_mem_by_name
1773
 
1774
task uvm_reg_block::read_mem_by_name(output uvm_status_e  status,
1775
                                         input  string             name,
1776
                                         input  uvm_reg_addr_t     offset,
1777
                                         output uvm_reg_data_t     data,
1778
                                         input  uvm_path_e    path = UVM_DEFAULT_PATH,
1779
                                         input  uvm_reg_map     map = null,
1780
                                         input  uvm_sequence_base  parent = null,
1781
                                         input  int                prior = -1,
1782
                                         input  uvm_object         extension = null,
1783
                                         input  string             fname = "",
1784
                                         input  int                lineno = 0);
1785
   uvm_mem mem;
1786
   this.fname = fname;
1787
   this.lineno = lineno;
1788
 
1789
   status = UVM_NOT_OK;
1790
   mem = get_mem_by_name(name);
1791
   if (mem != null)
1792
     mem.read(status, offset, data, path, map, parent, prior, extension);
1793
endtask: read_mem_by_name
1794
 
1795
 
1796
// readmemh
1797
 
1798
task uvm_reg_block::readmemh(string filename);
1799
   // TODO
1800
endtask: readmemh
1801
 
1802
 
1803
// writememh
1804
 
1805
task uvm_reg_block::writememh(string filename);
1806
   // TODO
1807
endtask: writememh
1808
 
1809
 
1810
//---------------
1811
// Map Management
1812
//---------------
1813
 
1814
// create_map
1815
 
1816
function uvm_reg_map uvm_reg_block::create_map(string name,
1817
                                               uvm_reg_addr_t base_addr,
1818
                                               int unsigned n_bytes,
1819
                                               uvm_endianness_e endian,
1820
                                               bit byte_addressing=1);
1821
 
1822
   uvm_reg_map  map;
1823
 
1824
   if (this.locked) begin
1825
      `uvm_error("RegModel", "Cannot add map to locked model");
1826
      return null;
1827
   end
1828
 
1829
   map = uvm_reg_map::type_id::create(name,,this.get_full_name());
1830
   map.configure(this,base_addr,n_bytes,endian,byte_addressing);
1831
 
1832
   this.maps[map] = 1;
1833
   if (maps.num() == 1)
1834
     default_map = map;
1835
 
1836
   return map;
1837
endfunction
1838
 
1839
 
1840
// add_map
1841
 
1842
function void uvm_reg_block::add_map(uvm_reg_map map);
1843
 
1844
   if (this.locked) begin
1845
      `uvm_error("RegModel", "Cannot add map to locked model");
1846
      return;
1847
   end
1848
 
1849
   if (this.maps.exists(map)) begin
1850
      `uvm_error("RegModel", {"Map '",map.get_name(),
1851
                 "' already exists in '",get_full_name(),"'"})
1852
      return;
1853
   end
1854
 
1855
   this.maps[map] = 1;
1856
   if (maps.num() == 1)
1857
     default_map = map;
1858
 
1859
endfunction: add_map
1860
 
1861
 
1862
// get_map_by_name
1863
 
1864
function uvm_reg_map uvm_reg_block::get_map_by_name(string name);
1865
   uvm_reg_map maps[$];
1866
 
1867
   this.get_maps(maps);
1868
 
1869
   foreach (maps[i])
1870
     if (maps[i].get_name() == name)
1871
       return maps[i];
1872
 
1873
   foreach (maps[i]) begin
1874
      uvm_reg_map submaps[$];
1875
      maps[i].get_submaps(submaps, UVM_HIER);
1876
 
1877
      foreach (submaps[j])
1878
         if (submaps[j].get_name() == name)
1879
            return submaps[j];
1880
   end
1881
 
1882
 
1883
   `uvm_warning("RegModel", {"Map with name '",name,"' does not exist in block"})
1884
   return null;
1885
endfunction
1886
 
1887
 
1888
// set_default_map
1889
 
1890
function void uvm_reg_block::set_default_map(uvm_reg_map map);
1891
  if (!maps.exists(map))
1892
   `uvm_warning("RegModel", {"Map '",map.get_full_name(),"' does not exist in block"})
1893
  default_map = map;
1894
endfunction
1895
 
1896
 
1897
// get_default_map
1898
 
1899
function uvm_reg_map uvm_reg_block::get_default_map();
1900
  return default_map;
1901
endfunction
1902
 
1903
 
1904
// get_default_path
1905
 
1906
function uvm_path_e uvm_reg_block::get_default_path();
1907
 
1908
   if (this.default_path != UVM_DEFAULT_PATH)
1909
      return this.default_path;
1910
 
1911
   if (this.parent != null)
1912
      return this.parent.get_default_path();
1913
 
1914
   return UVM_FRONTDOOR;
1915
 
1916
endfunction
1917
 
1918
 
1919
// Xinit_address_mapsX
1920
 
1921
function void uvm_reg_block::Xinit_address_mapsX();
1922
   foreach (maps[map_]) begin
1923
      uvm_reg_map map = map_;
1924
      map.Xinit_address_mapX();
1925
   end
1926
      //map.Xverify_map_configX();
1927
endfunction
1928
 
1929
 
1930
//----------------
1931
// Group- Backdoor
1932
//----------------
1933
 
1934
// set_backdoor
1935
 
1936
function void uvm_reg_block::set_backdoor(uvm_reg_backdoor bkdr,
1937
                                          string               fname = "",
1938
                                          int                  lineno = 0);
1939
   bkdr.fname = fname;
1940
   bkdr.lineno = lineno;
1941
   if (this.backdoor != null &&
1942
       this.backdoor.has_update_threads()) begin
1943
      `uvm_warning("RegModel", "Previous register backdoor still has update threads running. Backdoors with active mirroring should only be set before simulation starts.");
1944
   end
1945
   this.backdoor = bkdr;
1946
endfunction: set_backdoor
1947
 
1948
 
1949
// get_backdoor
1950
 
1951
function uvm_reg_backdoor uvm_reg_block::get_backdoor(bit inherited = 1);
1952
   if (backdoor == null && inherited) begin
1953
     uvm_reg_block blk = get_parent();
1954
     while (blk != null) begin
1955
       uvm_reg_backdoor bkdr = blk.get_backdoor();
1956
       if (bkdr != null)
1957
         return bkdr;
1958
       blk = blk.get_parent();
1959
     end
1960
   end
1961
   return this.backdoor;
1962
endfunction: get_backdoor
1963
 
1964
 
1965
 
1966
// clear_hdl_path
1967
 
1968
function void uvm_reg_block::clear_hdl_path(string kind = "RTL");
1969
 
1970
  if (kind == "ALL") begin
1971
    hdl_paths_pool = new("hdl_paths");
1972
    return;
1973
  end
1974
 
1975
  if (kind == "")
1976
    kind = get_default_hdl_path();
1977
 
1978
  if (!hdl_paths_pool.exists(kind)) begin
1979
    `uvm_warning("RegModel",{"Unknown HDL Abstraction '",kind,"'"})
1980
    return;
1981
  end
1982
 
1983
  hdl_paths_pool.delete(kind);
1984
endfunction
1985
 
1986
 
1987
// add_hdl_path
1988
 
1989
function void uvm_reg_block::add_hdl_path(string path, string kind = "RTL");
1990
 
1991
  uvm_queue #(string) paths;
1992
 
1993
  paths = hdl_paths_pool.get(kind);
1994
 
1995
  paths.push_back(path);
1996
 
1997
endfunction
1998
 
1999
 
2000
// has_hdl_path
2001
 
2002
function bit  uvm_reg_block::has_hdl_path(string kind = "");
2003
  if (kind == "") begin
2004
    kind = get_default_hdl_path();
2005
  end
2006
  return hdl_paths_pool.exists(kind);
2007
endfunction
2008
 
2009
 
2010
// get_hdl_path
2011
 
2012
function void uvm_reg_block::get_hdl_path(ref string paths[$], input string kind = "");
2013
 
2014
  uvm_queue #(string) hdl_paths;
2015
 
2016
  if (kind == "")
2017
    kind = get_default_hdl_path();
2018
 
2019
  if (!has_hdl_path(kind)) begin
2020
    `uvm_error("RegModel",{"Block does not have hdl path defined for abstraction '",kind,"'"})
2021
    return;
2022
  end
2023
 
2024
  hdl_paths = hdl_paths_pool.get(kind);
2025
 
2026
  for (int i=0; i
2027
    paths.push_back(hdl_paths.get(i));
2028
 
2029
endfunction
2030
 
2031
 
2032
// get_full_hdl_path
2033
 
2034
function void uvm_reg_block::get_full_hdl_path(ref string paths[$],
2035
                                               input string kind = "",
2036
                                               string separator = ".");
2037
 
2038
   if (kind == "")
2039
      kind = get_default_hdl_path();
2040
 
2041
   paths.delete();
2042
   if (is_hdl_path_root(kind)) begin
2043
      if (root_hdl_paths[kind] != "")
2044
         paths.push_back(root_hdl_paths[kind]);
2045
      return;
2046
   end
2047
 
2048
   if (!has_hdl_path(kind)) begin
2049
      `uvm_error("RegModel",{"Block does not have hdl path defined for abstraction '",kind,"'"})
2050
      return;
2051
   end
2052
 
2053
   begin
2054
      uvm_queue #(string) hdl_paths = hdl_paths_pool.get(kind);
2055
      string parent_paths[$];
2056
 
2057
      if (parent != null)
2058
         parent.get_full_hdl_path(parent_paths, kind, separator);
2059
 
2060
      for (int i=0; i
2061
         string hdl_path = hdl_paths.get(i);
2062
 
2063
         if (parent_paths.size() == 0) begin
2064
            if (hdl_path != "")
2065
               paths.push_back(hdl_path);
2066
 
2067
            continue;
2068
         end
2069
 
2070
         foreach (parent_paths[j])  begin
2071
            if (hdl_path == "")
2072
               paths.push_back(parent_paths[j]);
2073
            else
2074
               paths.push_back({ parent_paths[j], separator, hdl_path });
2075
         end
2076
      end
2077
   end
2078
 
2079
endfunction
2080
 
2081
 
2082
// get_default_hdl_path
2083
 
2084
function string uvm_reg_block::get_default_hdl_path();
2085
  if (default_hdl_path == "" && parent != null)
2086
    return parent.get_default_hdl_path();
2087
  return default_hdl_path;
2088
endfunction
2089
 
2090
 
2091
// set_default_hdl_path
2092
 
2093
function void uvm_reg_block::set_default_hdl_path(string kind);
2094
 
2095
  if (kind == "") begin
2096
    if (parent == null) begin
2097
      `uvm_error("RegModel",{"Block has no parent. ",
2098
           "Must specify a valid HDL abstraction (kind)"})
2099
    end
2100
    kind = parent.get_default_hdl_path();
2101
  end
2102
 
2103
  default_hdl_path = kind;
2104
endfunction
2105
 
2106
 
2107
// set_hdl_path_root
2108
 
2109
function void uvm_reg_block::set_hdl_path_root (string path, string kind = "RTL");
2110
  if (kind == "")
2111
    kind = get_default_hdl_path();
2112
 
2113
  root_hdl_paths[kind] = path;
2114
endfunction
2115
 
2116
 
2117
// is_hdl_path_root
2118
 
2119
function bit  uvm_reg_block::is_hdl_path_root (string kind = "");
2120
  if (kind == "")
2121
    kind = get_default_hdl_path();
2122
 
2123
  return root_hdl_paths.exists(kind);
2124
endfunction
2125
 
2126
 
2127
//----------------------------------
2128
// Group- Basic Object Operations
2129
//----------------------------------
2130
 
2131
// do_print
2132
function void uvm_reg_block::do_print (uvm_printer printer);
2133
  super.do_print(printer);
2134
 
2135
  foreach(blks[i]) begin
2136
     uvm_reg_block b = i;
2137
     uvm_object obj = b;
2138
     printer.print_object(obj.get_name(), obj);
2139
  end
2140
 
2141
  foreach(regs[i]) begin
2142
     uvm_reg r = i;
2143
     uvm_object obj = r;
2144
     printer.print_object(obj.get_name(), obj);
2145
  end
2146
 
2147
  foreach(vregs[i]) begin
2148
     uvm_vreg r = i;
2149
     uvm_object obj = r;
2150
     printer.print_object(obj.get_name(), obj);
2151
  end
2152
 
2153
  foreach(mems[i]) begin
2154
     uvm_mem m = i;
2155
     uvm_object obj = m;
2156
     printer.print_object(obj.get_name(), obj);
2157
  end
2158
 
2159
  foreach(maps[i]) begin
2160
     uvm_reg_map m = i;
2161
     uvm_object obj = m;
2162
     printer.print_object(obj.get_name(), obj);
2163
  end
2164
 
2165
endfunction
2166
 
2167
 
2168
 
2169
// clone
2170
 
2171
function uvm_object uvm_reg_block::clone();
2172
  `uvm_fatal("RegModel","RegModel blocks cannot be cloned")
2173
  return null;
2174
endfunction
2175
 
2176
// do_copy
2177
 
2178
function void uvm_reg_block::do_copy(uvm_object rhs);
2179
  `uvm_fatal("RegModel","RegModel blocks cannot be copied")
2180
endfunction
2181
 
2182
 
2183
// do_compare
2184
 
2185
function bit uvm_reg_block::do_compare (uvm_object  rhs,
2186
                                        uvm_comparer comparer);
2187
  `uvm_warning("RegModel","RegModel blocks cannot be compared")
2188
  return 0;
2189
endfunction
2190
 
2191
 
2192
// do_pack
2193
 
2194
function void uvm_reg_block::do_pack (uvm_packer packer);
2195
  `uvm_warning("RegModel","RegModel blocks cannot be packed")
2196
endfunction
2197
 
2198
 
2199
// do_unpack
2200
 
2201
function void uvm_reg_block::do_unpack (uvm_packer packer);
2202
  `uvm_warning("RegModel","RegModel blocks cannot be unpacked")
2203
endfunction
2204
 
2205
 
2206
// convert2string
2207
 
2208
function string uvm_reg_block::convert2string();
2209
   string image;
2210
   string maps[];
2211
   string blk_maps[];
2212
   bit         single_map;
2213
   uvm_endianness_e endian;
2214
   string prefix = "  ";
2215
 
2216
`ifdef TODO
2217
   single_map = 1;
2218
   if (map == "") begin
2219
      this.get_maps(maps);
2220
      if (maps.size() > 1) single_map = 0;
2221
   end
2222
 
2223
   if (single_map) begin
2224
      $sformat(image, "%sBlock %s", prefix, this.get_full_name());
2225
 
2226
      if (map != "")
2227
        $sformat(image, "%s.%s", image, map);
2228
 
2229
      endian = this.get_endian(map);
2230
 
2231
      $sformat(image, "%s -- %0d bytes (%s)", image,
2232
               this.get_n_bytes(map), endian.name());
2233
 
2234
      foreach (blks[i]) begin
2235
         string img;
2236
         img = blks[i].convert2string({prefix, "   "}, blk_maps[i]);
2237
         image = {image, "\n", img};
2238
      end
2239
 
2240
   end
2241
   else begin
2242
      $sformat(image, "%Block %s", prefix, this.get_full_name());
2243
      foreach (maps[i]) begin
2244
         string img;
2245
         endian = this.get_endian(maps[i]);
2246
         $sformat(img, "%s   Map \"%s\" -- %0d bytes (%s)",
2247
                  prefix, maps[i],
2248
                  this.get_n_bytes(maps[i]), endian.name());
2249
         image = {image, "\n", img};
2250
 
2251
         this.get_blocks(blks, blk_maps, maps[i]);
2252
         foreach (blks[j]) begin
2253
            img = blks[j].convert2string({prefix, "      "},
2254
                                    blk_maps[j]);
2255
            image = {image, "\n", img};
2256
         end
2257
 
2258
         this.get_subsys(sys, blk_maps, maps[i]);
2259
         foreach (sys[j]) begin
2260
            img = sys[j].convert2string({prefix, "      "},
2261
                                   blk_maps[j]);
2262
            image = {image, "\n", img};
2263
         end
2264
      end
2265
   end
2266
`endif
2267
   return image;
2268
endfunction: convert2string
2269
 
2270
 
2271
 

powered by: WebSVN 2.1.0

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