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

Subversion Repositories uart2bus_testbench

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 HanySalah
//
2
// -------------------------------------------------------------
3
//    Copyright 2004-2009 Synopsys, Inc.
4
//    Copyright 2010-2011 Mentor Graphics Corporation
5
//    Copyright 2010 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
// Title: Memory Allocation Manager
27
//
28
// Manages the exclusive allocation of consecutive memory locations
29
// called ~regions~.
30
// The regions can subsequently be accessed like little memories of
31
// their own, without knowing in which memory or offset they are
32
// actually located.
33
//
34
// The memory allocation manager should be used by any
35
// application-level process
36
// that requires reserved space in the memory,
37
// such as DMA buffers.
38
//
39
// A region will remain reserved until it is explicitly released.
40
//
41
//------------------------------------------------------------------------------
42
 
43
 
44
`ifndef UVM_MEM_MAM__SV
45
`define UVM_MEM_MAM__SV
46
 
47
 
48
typedef class uvm_mem_mam_cfg;
49
typedef class uvm_mem_region;
50
typedef class uvm_mem_mam_policy;
51
 
52
typedef class uvm_mem;
53
 
54
 
55
//------------------------------------------------------------------------------
56
// CLASS: uvm_mem_mam
57
//------------------------------------------------------------------------------
58
// Memory allocation manager
59
//
60
// Memory allocation management utility class similar to C's malloc()
61
// and free().
62
// A single instance of this class is used to manage a single,
63
// contiguous address space.
64
//------------------------------------------------------------------------------
65
 
66
class uvm_mem_mam;
67
 
68
   //----------------------
69
   // Group: Initialization
70
   //----------------------
71
 
72
   // Type: alloc_mode_e
73
   //
74
   // Memory allocation mode
75
   //
76
   // Specifies how to allocate a memory region
77
   //
78
   // GREEDY   - Consume new, previously unallocated memory
79
   // THRIFTY  - Reused previously released memory as much as possible (not yet implemented)
80
   //
81
   typedef enum {GREEDY, THRIFTY} alloc_mode_e;
82
 
83
 
84
   // Type: locality_e
85
   //
86
   // Location of memory regions
87
   //
88
   // Specifies where to locate new memory regions
89
   //
90
   // BROAD    - Locate new regions randomly throughout the address space
91
   // NEARBY   - Locate new regions adjacent to existing regions
92
 
93
   typedef enum {BROAD, NEARBY}   locality_e;
94
 
95
 
96
 
97
   // Variable: default_alloc
98
   //
99
   // Region allocation policy
100
   //
101
   // This object is repeatedly randomized when allocating new regions.
102
   uvm_mem_mam_policy default_alloc;
103
 
104
 
105
   local uvm_mem memory;
106
   local uvm_mem_mam_cfg cfg;
107
   local uvm_mem_region in_use[$];
108
   local int for_each_idx = -1;
109
   local string fname;
110
   local int lineno;
111
 
112
 
113
   // Function: new
114
   //
115
   // Create a new manager instance
116
   //
117
   // Create an instance of a memory allocation manager
118
   // with the specified name and configuration.
119
   // This instance manages all memory region allocation within
120
   // the address range specified in the configuration descriptor.
121
   //
122
   // If a reference to a memory abstraction class is provided, the memory
123
   // locations within the regions can be accessed through the region
124
   // descriptor, using the  and
125
   //  methods.
126
   //
127
   extern function new(string name,
128
                       uvm_mem_mam_cfg cfg,
129
                       uvm_mem mem=null);
130
 
131
 
132
   // Function: reconfigure
133
   //
134
   // Reconfigure the manager
135
   //
136
   // Modify the maximum and minimum addresses of the address space managed by
137
   // the allocation manager, allocation mode, or locality.
138
   // The number of bytes per memory location cannot be modified
139
   // once an allocation manager has been constructed.
140
   // All currently allocated regions must fall within the new address space.
141
   //
142
   // Returns the previous configuration.
143
   //
144
   // if no new configuration is specified, simply returns the current
145
   // configuration.
146
   //
147
   extern function uvm_mem_mam_cfg reconfigure(uvm_mem_mam_cfg cfg = null);
148
 
149
 
150
   //-------------------------
151
   // Group: Memory Management
152
   //-------------------------
153
 
154
   // Function: reserve_region
155
   //
156
   // Reserve a specific memory region
157
   //
158
   // Reserve a memory region of the specified number of bytes
159
   // starting at the specified offset.
160
   // A descriptor of the reserved region is returned.
161
   // If the specified region cannot be reserved, ~null~ is returned.
162
   //
163
   // It may not be possible to reserve a region because
164
   // it overlaps with an already-allocated region or
165
   // it lies outside the address range managed
166
   // by the memory manager.
167
   //
168
   // Regions can be reserved to create "holes" in the managed address space.
169
   //
170
   extern function uvm_mem_region reserve_region(bit [63:0]   start_offset,
171
                                                 int unsigned n_bytes,
172
                                                 string       fname = "",
173
                                                 int          lineno = 0);
174
 
175
 
176
   // Function: request_region
177
   //
178
   // Request and reserve a memory region
179
   //
180
   // Request and reserve a memory region of the specified number
181
   // of bytes starting at a random location.
182
   // If an policy is specified, it is randomized to determine
183
   // the start offset of the region.
184
   // If no policy is specified, the policy found in
185
   // the  class property is randomized.
186
   //
187
   // A descriptor of the allocated region is returned.
188
   // If no region can be allocated, ~null~ is returned.
189
   //
190
   // It may not be possible to allocate a region because
191
   // there is no area in the memory with enough consecutive locations
192
   // to meet the size requirements or
193
   // because there is another contradiction when randomizing
194
   // the policy.
195
   //
196
   // If the memory allocation is configured to ~THRIFTY~ or ~NEARBY~,
197
   // a suitable region is first sought procedurally.
198
   //
199
   extern function uvm_mem_region request_region(int unsigned   n_bytes,
200
                                                 uvm_mem_mam_policy alloc = null,
201
                                                 string         fname = "",
202
                                                 int            lineno = 0);
203
 
204
 
205
   // Function: release_region
206
   //
207
   // Release the specified region
208
   //
209
   // Release a previously allocated memory region.
210
   // An error is issued if the
211
   // specified region has not been previously allocated or
212
   // is no longer allocated.
213
   //
214
   extern function void release_region(uvm_mem_region region);
215
 
216
 
217
   // Function: release_all_regions
218
   //
219
   // Forcibly release all allocated memory regions.
220
   //
221
   extern function void release_all_regions();
222
 
223
 
224
   //---------------------
225
   // Group: Introspection
226
   //---------------------
227
 
228
   // Function: convert2string
229
   //
230
   // Image of the state of the manager
231
   //
232
   // Create a human-readable description of the state of
233
   // the memory manager and the currently allocated regions.
234
   //
235
   extern function string convert2string();
236
 
237
 
238
   // Function: for_each
239
   //
240
   // Iterate over all currently allocated regions
241
   //
242
   // If reset is ~TRUE~, reset the iterator
243
   // and return the first allocated region.
244
   // Returns ~null~ when there are no additional allocated
245
   // regions to iterate on.
246
   //
247
   extern function uvm_mem_region for_each(bit reset = 0);
248
 
249
 
250
   // Function: get_memory
251
   //
252
   // Get the managed memory implementation
253
   //
254
   // Return the reference to the memory abstraction class
255
   // for the memory implementing
256
   // the locations managed by this instance of the allocation manager.
257
   // Returns ~null~ if no
258
   // memory abstraction class was specified at construction time.
259
   //
260
   extern function uvm_mem get_memory();
261
 
262
endclass: uvm_mem_mam
263
 
264
 
265
 
266
//------------------------------------------------------------------------------
267
// CLASS: uvm_mem_region
268
//------------------------------------------------------------------------------
269
// Allocated memory region descriptor
270
//
271
// Each instance of this class describes an allocated memory region.
272
// Instances of this class are created only by
273
// the memory manager, and returned by the
274
//  and 
275
// methods.
276
//------------------------------------------------------------------------------
277
 
278
class uvm_mem_region;
279
 
280
   /*local*/ bit [63:0] Xstart_offsetX;  // Can't be local since function
281
   /*local*/ bit [63:0] Xend_offsetX;    // calls not supported in constraints
282
 
283
   local int unsigned len;
284
   local int unsigned n_bytes;
285
   local uvm_mem_mam  parent;
286
   local string       fname;
287
   local int          lineno;
288
 
289
   /*local*/ uvm_vreg XvregX;
290
 
291
   extern /*local*/ function new(bit [63:0]   start_offset,
292
                                 bit [63:0]   end_offset,
293
                                 int unsigned len,
294
                                 int unsigned n_bytes,
295
                                 uvm_mem_mam      parent);
296
 
297
   // Function: get_start_offset
298
   //
299
   // Get the start offset of the region
300
   //
301
   // Return the address offset, within the memory,
302
   // where this memory region starts.
303
   //
304
   extern function bit [63:0] get_start_offset();
305
 
306
 
307
   // Function: get_end_offset
308
   //
309
   // Get the end offset of the region
310
   //
311
   // Return the address offset, within the memory,
312
   // where this memory region ends.
313
   //
314
   extern function bit [63:0] get_end_offset();
315
 
316
 
317
   // Function: get_len
318
   //
319
   // Size of the memory region
320
   //
321
   // Return the number of consecutive memory locations
322
   // (not necessarily bytes) in the allocated region.
323
   //
324
   extern function int unsigned get_len();
325
 
326
 
327
   // Function: get_n_bytes
328
   //
329
   // Number of bytes in the region
330
   //
331
   // Return the number of consecutive bytes in the allocated region.
332
   // If the managed memory contains more than one byte per address,
333
   // the number of bytes in an allocated region may
334
   // be greater than the number of requested or reserved bytes.
335
   //
336
   extern function int unsigned get_n_bytes();
337
 
338
 
339
   // Function: release_region
340
   //
341
   // Release this region
342
   //
343
   extern function void release_region();
344
 
345
 
346
   // Function: get_memory
347
   //
348
   // Get the memory where the region resides
349
   //
350
   // Return a reference to the memory abstraction class
351
   // for the memory implementing this allocated memory region.
352
   // Returns ~null~ if no memory abstraction class was specified
353
   // for the allocation manager that allocated this region.
354
   //
355
   extern function uvm_mem get_memory();
356
 
357
 
358
   // Function: get_virtual_registers
359
   //
360
   // Get the virtual register array in this region
361
   //
362
   // Return a reference to the virtual register array abstraction class
363
   // implemented in this region.
364
   // Returns ~null~ if the memory region is
365
   // not known to implement virtual registers.
366
   //
367
   extern function uvm_vreg get_virtual_registers();
368
 
369
 
370
   // Task: write
371
   //
372
   // Write to a memory location in the region.
373
   //
374
   // Write to the memory location that corresponds to the
375
   // specified ~offset~ within this region.
376
   // Requires that the memory abstraction class be associated with
377
   // the memory allocation manager that allocated this region.
378
   //
379
   // See  for more details.
380
   //
381
   extern task write(output uvm_status_e       status,
382
                     input  uvm_reg_addr_t     offset,
383
                     input  uvm_reg_data_t     value,
384
                     input  uvm_path_e         path   = UVM_DEFAULT_PATH,
385
                     input  uvm_reg_map        map    = null,
386
                     input  uvm_sequence_base  parent = null,
387
                     input  int                prior = -1,
388
                     input  uvm_object         extension = null,
389
                     input  string             fname = "",
390
                     input  int                lineno = 0);
391
 
392
 
393
   // Task: read
394
   //
395
   // Read from a memory location in the region.
396
   //
397
   // Read from the memory location that corresponds to the
398
   // specified ~offset~ within this region.
399
   // Requires that the memory abstraction class be associated with
400
   // the memory allocation manager that allocated this region.
401
   //
402
   // See  for more details.
403
   //
404
   extern task read(output uvm_status_e       status,
405
                    input  uvm_reg_addr_t     offset,
406
                    output uvm_reg_data_t     value,
407
                    input  uvm_path_e         path   = UVM_DEFAULT_PATH,
408
                    input  uvm_reg_map        map    = null,
409
                    input  uvm_sequence_base  parent = null,
410
                    input  int                prior = -1,
411
                    input  uvm_object         extension = null,
412
                    input  string             fname = "",
413
                    input  int                lineno = 0);
414
 
415
 
416
   // Task: burst_write
417
   //
418
   // Write to a set of memory location in the region.
419
   //
420
   // Write to the memory locations that corresponds to the
421
   // specified ~burst~ within this region.
422
   // Requires that the memory abstraction class be associated with
423
   // the memory allocation manager that allocated this region.
424
   //
425
   // See  for more details.
426
   //
427
   extern task burst_write(output uvm_status_e       status,
428
                           input  uvm_reg_addr_t     offset,
429
                           input  uvm_reg_data_t     value[],
430
                           input  uvm_path_e         path   = UVM_DEFAULT_PATH,
431
                           input  uvm_reg_map        map    = null,
432
                           input  uvm_sequence_base  parent = null,
433
                           input  int                prior  = -1,
434
                           input  uvm_object         extension = null,
435
                           input  string             fname  = "",
436
                           input  int                lineno = 0);
437
 
438
 
439
   // Task: burst_read
440
   //
441
   // Read from a set of memory location in the region.
442
   //
443
   // Read from the memory locations that corresponds to the
444
   // specified ~burst~ within this region.
445
   // Requires that the memory abstraction class be associated with
446
   // the memory allocation manager that allocated this region.
447
   //
448
   // See  for more details.
449
   //
450
   extern task burst_read(output uvm_status_e       status,
451
                          input  uvm_reg_addr_t     offset,
452
                          output uvm_reg_data_t     value[],
453
                          input  uvm_path_e         path   = UVM_DEFAULT_PATH,
454
                          input  uvm_reg_map        map    = null,
455
                          input  uvm_sequence_base  parent = null,
456
                          input  int                prior  = -1,
457
                          input  uvm_object         extension = null,
458
                          input  string             fname  = "",
459
                          input  int                lineno = 0);
460
 
461
 
462
   // Task: poke
463
   //
464
   // Deposit in a memory location in the region.
465
   //
466
   // Deposit the specified value in the memory location
467
   // that corresponds to the
468
   // specified ~offset~ within this region.
469
   // Requires that the memory abstraction class be associated with
470
   // the memory allocation manager that allocated this region.
471
   //
472
   // See  for more details.
473
   //
474
   extern task poke(output uvm_status_e       status,
475
                    input  uvm_reg_addr_t     offset,
476
                    input  uvm_reg_data_t     value,
477
                    input  uvm_sequence_base  parent = null,
478
                    input  uvm_object         extension = null,
479
                    input  string             fname = "",
480
                    input  int                lineno = 0);
481
 
482
 
483
   // Task: peek
484
   //
485
   // Sample a memory location in the region.
486
   //
487
   // Sample the memory location that corresponds to the
488
   // specified ~offset~ within this region.
489
   // Requires that the memory abstraction class be associated with
490
   // the memory allocation manager that allocated this region.
491
   //
492
   // See  for more details.
493
   //
494
   extern task peek(output uvm_status_e       status,
495
                    input  uvm_reg_addr_t     offset,
496
                    output uvm_reg_data_t     value,
497
                    input  uvm_sequence_base  parent = null,
498
                    input  uvm_object         extension = null,
499
                    input  string             fname = "",
500
                    input  int                lineno = 0);
501
 
502
 
503
   extern function string convert2string();
504
 
505
endclass
506
 
507
 
508
 
509
//------------------------------------------------------------------------------
510
// Class: uvm_mem_mam_policy
511
//------------------------------------------------------------------------------
512
//
513
// An instance of this class is randomized to determine
514
// the starting offset of a randomly allocated memory region.
515
// This class can be extended to provide additional constraints
516
// on the starting offset, such as word alignment or
517
// location of the region within a memory page.
518
// If a procedural region allocation policy is required,
519
// it can be implemented in the pre/post_randomize() method.
520
//------------------------------------------------------------------------------
521
 
522
class uvm_mem_mam_policy;
523
   // variable: len
524
   // Number of addresses required
525
   int unsigned len;
526
 
527
   // variable: start_offset
528
   // The starting offset of the region
529
   rand bit [63:0] start_offset;
530
 
531
   // variable: min_offset
532
   // Minimum address offset in the managed address space
533
   bit [63:0] min_offset;
534
 
535
   // variable: max_offset
536
   // Maximum address offset in the managed address space
537
   bit [63:0] max_offset;
538
 
539
   // variable: in_use
540
   // Regions already allocated in the managed address space
541
   uvm_mem_region in_use[$];
542
 
543
   constraint uvm_mem_mam_policy_valid {
544
      start_offset >= min_offset;
545
      start_offset <= max_offset - len + 1;
546
   }
547
 
548
   constraint uvm_mem_mam_policy_no_overlap {
549
      foreach (in_use[i]) {
550
         !(start_offset <= in_use[i].Xend_offsetX &&
551
           start_offset + len - 1 >= in_use[i].Xstart_offsetX);
552
      }
553
   }
554
 
555
endclass
556
 
557
 
558
 
559
//
560
// CLASS: uvm_mem_mam_cfg
561
// Specifies the memory managed by an instance of a  memory
562
// allocation manager class.
563
//
564
class uvm_mem_mam_cfg;
565
   // variable: n_bytes
566
   // Number of bytes in each memory location
567
   rand int unsigned n_bytes;
568
 
569
// FIXME start_offset and end_offset should be "longint unsigned" to match the memory addr types
570
   // variable: start_offset
571
   // Lowest address of managed space
572
   rand bit [63:0] start_offset;
573
 
574
   // variable: end_offset
575
   // Last address of managed space
576
   rand bit [63:0] end_offset;
577
 
578
   // variable: mode
579
   // Region allocation mode
580
   rand uvm_mem_mam::alloc_mode_e mode;
581
 
582
   // variable: locality
583
   // Region location mode
584
   rand uvm_mem_mam::locality_e   locality;
585
 
586
   constraint uvm_mem_mam_cfg_valid {
587
      end_offset > start_offset;
588
      n_bytes < 64;
589
   }
590
endclass
591
 
592
 
593
 
594
//------------------------------------------------------------------
595
//  Implementation
596
//------------------------------------------------------------------
597
 
598
function uvm_mem_region::new(bit [63:0] start_offset,
599
                             bit [63:0] end_offset,
600
                             int unsigned len,
601
                             int unsigned n_bytes,
602
                             uvm_mem_mam      parent);
603
   this.Xstart_offsetX = start_offset;
604
   this.Xend_offsetX   = end_offset;
605
   this.len            = len;
606
   this.n_bytes        = n_bytes;
607
   this.parent         = parent;
608
   this.XvregX         = null;
609
endfunction: new
610
 
611
 
612
function bit [63:0] uvm_mem_region::get_start_offset();
613
   return this.Xstart_offsetX;
614
endfunction: get_start_offset
615
 
616
 
617
function bit [63:0] uvm_mem_region::get_end_offset();
618
   return this.Xend_offsetX;
619
endfunction: get_end_offset
620
 
621
 
622
function int unsigned uvm_mem_region::get_len();
623
   return this.len;
624
endfunction: get_len
625
 
626
 
627
function int unsigned uvm_mem_region::get_n_bytes();
628
   return this.n_bytes;
629
endfunction: get_n_bytes
630
 
631
 
632
function string uvm_mem_region::convert2string();
633
   $sformat(convert2string, "['h%h:'h%h]",
634
            this.Xstart_offsetX, this.Xend_offsetX);
635
endfunction: convert2string
636
 
637
 
638
function void uvm_mem_region::release_region();
639
   this.parent.release_region(this);
640
endfunction
641
 
642
 
643
function uvm_mem uvm_mem_region::get_memory();
644
   return this.parent.get_memory();
645
endfunction: get_memory
646
 
647
 
648
function uvm_vreg uvm_mem_region::get_virtual_registers();
649
   return this.XvregX;
650
endfunction: get_virtual_registers
651
 
652
 
653
function uvm_mem_mam::new(string      name,
654
                      uvm_mem_mam_cfg cfg,
655
                      uvm_mem mem = null);
656
   this.cfg           = cfg;
657
   this.memory        = mem;
658
   this.default_alloc = new;
659
endfunction: new
660
 
661
 
662
function uvm_mem_mam_cfg uvm_mem_mam::reconfigure(uvm_mem_mam_cfg cfg = null);
663
   uvm_root top;
664
   uvm_coreservice_t cs;
665
   if (cfg == null)
666
     return this.cfg;
667
 
668
   cs = uvm_coreservice_t::get();
669
   top = cs.get_root();
670
 
671
   // Cannot reconfigure n_bytes
672
   if (cfg.n_bytes !== this.cfg.n_bytes) begin
673
      top.uvm_report_error("uvm_mem_mam",
674
                 $sformatf("Cannot reconfigure Memory Allocation Manager with a different number of bytes (%0d !== %0d)",
675
                           cfg.n_bytes, this.cfg.n_bytes), UVM_LOW);
676
      return this.cfg;
677
   end
678
 
679
   // All currently allocated regions must fall within the new space
680
   foreach (this.in_use[i]) begin
681
      if (this.in_use[i].get_start_offset() < cfg.start_offset ||
682
          this.in_use[i].get_end_offset() > cfg.end_offset) begin
683
         top.uvm_report_error("uvm_mem_mam",
684
                    $sformatf("Cannot reconfigure Memory Allocation Manager with a currently allocated region outside of the managed address range ([%0d:%0d] outside of [%0d:%0d])",
685
                              this.in_use[i].get_start_offset(),
686
                              this.in_use[i].get_end_offset(),
687
                              cfg.start_offset, cfg.end_offset), UVM_LOW);
688
         return this.cfg;
689
      end
690
   end
691
 
692
   reconfigure = this.cfg;
693
   this.cfg = cfg;
694
endfunction: reconfigure
695
 
696
 
697
function uvm_mem_region uvm_mem_mam::reserve_region(bit [63:0]   start_offset,
698
                                                int unsigned n_bytes,
699
                                                string       fname = "",
700
                                                int          lineno = 0);
701
   bit [63:0] end_offset;
702
   this.fname = fname;
703
   this.lineno = lineno;
704
   if (n_bytes == 0) begin
705
      `uvm_error("RegModel", "Cannot reserve 0 bytes");
706
      return null;
707
   end
708
 
709
   if (start_offset < this.cfg.start_offset) begin
710
      `uvm_error("RegModel", $sformatf("Cannot reserve before start of memory space: 'h%h < 'h%h",
711
                                     start_offset, this.cfg.start_offset));
712
      return null;
713
   end
714
 
715
   end_offset = start_offset + ((n_bytes-1) / this.cfg.n_bytes);
716
   n_bytes = (end_offset - start_offset + 1) * this.cfg.n_bytes;
717
 
718
   if (end_offset > this.cfg.end_offset) begin
719
      `uvm_error("RegModel", $sformatf("Cannot reserve past end of memory space: 'h%h > 'h%h",
720
                                     end_offset, this.cfg.end_offset));
721
      return null;
722
   end
723
 
724
    `uvm_info("RegModel",$sformatf("Attempting to reserve ['h%h:'h%h]...",
725
          start_offset, end_offset),UVM_MEDIUM)
726
 
727
 
728
 
729
 
730
   foreach (this.in_use[i]) begin
731
      if (start_offset <= this.in_use[i].get_end_offset() &&
732
          end_offset >= this.in_use[i].get_start_offset()) begin
733
         // Overlap!
734
         `uvm_error("RegModel", $sformatf("Cannot reserve ['h%h:'h%h] because it overlaps with %s",
735
                                        start_offset, end_offset,
736
                                        this.in_use[i].convert2string()));
737
         return null;
738
      end
739
 
740
      // Regions are stored in increasing start offset
741
      if (start_offset > this.in_use[i].get_start_offset()) begin
742
         reserve_region = new(start_offset, end_offset,
743
                              end_offset - start_offset + 1, n_bytes, this);
744
         this.in_use.insert(i, reserve_region);
745
         return reserve_region;
746
      end
747
   end
748
 
749
   reserve_region = new(start_offset, end_offset,
750
                        end_offset - start_offset + 1, n_bytes, this);
751
   this.in_use.push_back(reserve_region);
752
endfunction: reserve_region
753
 
754
 
755
function uvm_mem_region uvm_mem_mam::request_region(int unsigned      n_bytes,
756
                                                uvm_mem_mam_policy    alloc = null,
757
                                                string            fname = "",
758
                                                int               lineno = 0);
759
   this.fname = fname;
760
   this.lineno = lineno;
761
   if (alloc == null) alloc = this.default_alloc;
762
 
763
   alloc.len        = (n_bytes-1) / this.cfg.n_bytes + 1;
764
   alloc.min_offset = this.cfg.start_offset;
765
   alloc.max_offset = this.cfg.end_offset;
766
   alloc.in_use     = this.in_use;
767
 
768
   if (!alloc.randomize()) begin
769
      `uvm_error("RegModel", "Unable to randomize policy");
770
      return null;
771
   end
772
 
773
   return reserve_region(alloc.start_offset, n_bytes);
774
endfunction: request_region
775
 
776
 
777
function void uvm_mem_mam::release_region(uvm_mem_region region);
778
 
779
   if (region == null) return;
780
 
781
   foreach (this.in_use[i]) begin
782
      if (this.in_use[i] == region) begin
783
         this.in_use.delete(i);
784
         return;
785
      end
786
   end
787
   `uvm_error("RegModel", {"Attempting to release unallocated region\n",
788
                      region.convert2string()});
789
endfunction: release_region
790
 
791
 
792
function void uvm_mem_mam::release_all_regions();
793
  in_use.delete();
794
endfunction: release_all_regions
795
 
796
 
797
function string uvm_mem_mam::convert2string();
798
   convert2string = "Allocated memory regions:\n";
799
   foreach (this.in_use[i]) begin
800
      $sformat(convert2string, "%s   %s\n", convert2string,
801
               this.in_use[i].convert2string());
802
   end
803
endfunction: convert2string
804
 
805
 
806
function uvm_mem_region uvm_mem_mam::for_each(bit reset = 0);
807
   if (reset) this.for_each_idx = -1;
808
 
809
   this.for_each_idx++;
810
 
811
   if (this.for_each_idx >= this.in_use.size()) begin
812
      return null;
813
   end
814
 
815
   return this.in_use[this.for_each_idx];
816
endfunction: for_each
817
 
818
 
819
function uvm_mem uvm_mem_mam::get_memory();
820
   return this.memory;
821
endfunction: get_memory
822
 
823
 
824
task uvm_mem_region::write(output uvm_status_e       status,
825
                           input  uvm_reg_addr_t     offset,
826
                           input  uvm_reg_data_t     value,
827
                           input  uvm_path_e         path = UVM_DEFAULT_PATH,
828
                           input  uvm_reg_map        map    = null,
829
                           input  uvm_sequence_base  parent = null,
830
                           input  int                prior = -1,
831
                           input  uvm_object         extension = null,
832
                           input  string             fname = "",
833
                           input  int                lineno = 0);
834
 
835
   uvm_mem mem = this.parent.get_memory();
836
   this.fname = fname;
837
   this.lineno = lineno;
838
 
839
   if (mem == null) begin
840
      `uvm_error("RegModel", "Cannot use uvm_mem_region::write() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance");
841
      status = UVM_NOT_OK;
842
      return;
843
   end
844
 
845
   if (offset > this.len) begin
846
      `uvm_error("RegModel",
847
                 $sformatf("Attempting to write to an offset outside of the allocated region (%0d > %0d)",
848
                           offset, this.len));
849
      status = UVM_NOT_OK;
850
      return;
851
   end
852
 
853
   mem.write(status, offset + this.get_start_offset(), value,
854
            path, map, parent, prior, extension);
855
endtask: write
856
 
857
 
858
task uvm_mem_region::read(output uvm_status_e       status,
859
                          input  uvm_reg_addr_t     offset,
860
                          output uvm_reg_data_t     value,
861
                          input  uvm_path_e         path = UVM_DEFAULT_PATH,
862
                          input  uvm_reg_map        map    = null,
863
                          input  uvm_sequence_base  parent = null,
864
                          input  int                prior = -1,
865
                          input  uvm_object         extension = null,
866
                          input  string             fname = "",
867
                          input  int                lineno = 0);
868
   uvm_mem mem = this.parent.get_memory();
869
   this.fname = fname;
870
   this.lineno = lineno;
871
 
872
   if (mem == null) begin
873
      `uvm_error("RegModel", "Cannot use uvm_mem_region::read() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance");
874
      status = UVM_NOT_OK;
875
      return;
876
   end
877
 
878
   if (offset > this.len) begin
879
      `uvm_error("RegModel",
880
                 $sformatf("Attempting to read from an offset outside of the allocated region (%0d > %0d)",
881
                           offset, this.len));
882
      status = UVM_NOT_OK;
883
      return;
884
   end
885
 
886
   mem.read(status, offset + this.get_start_offset(), value,
887
            path, map, parent, prior, extension);
888
endtask: read
889
 
890
 
891
task uvm_mem_region::burst_write(output uvm_status_e       status,
892
                                 input  uvm_reg_addr_t     offset,
893
                                 input  uvm_reg_data_t     value[],
894
                                 input  uvm_path_e         path = UVM_DEFAULT_PATH,
895
                                 input  uvm_reg_map        map    = null,
896
                                 input  uvm_sequence_base  parent = null,
897
                                 input  int                prior = -1,
898
                                 input  uvm_object         extension = null,
899
                                 input  string             fname = "",
900
                                 input  int                lineno = 0);
901
   uvm_mem mem = this.parent.get_memory();
902
   this.fname = fname;
903
   this.lineno = lineno;
904
 
905
   if (mem == null) begin
906
      `uvm_error("RegModel", "Cannot use uvm_mem_region::burst_write() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance");
907
      status = UVM_NOT_OK;
908
      return;
909
   end
910
 
911
   if (offset + value.size() > this.len) begin
912
      `uvm_error("RegModel",
913
                 $sformatf("Attempting to burst-write to an offset outside of the allocated region (burst to [%0d:%0d] > mem_size %0d)",
914
                           offset,offset+value.size(),this.len))
915
      status = UVM_NOT_OK;
916
      return;
917
   end
918
 
919
   mem.burst_write(status, offset + get_start_offset(), value,
920
                   path, map, parent, prior, extension);
921
 
922
endtask: burst_write
923
 
924
 
925
task uvm_mem_region::burst_read(output uvm_status_e       status,
926
                                input  uvm_reg_addr_t     offset,
927
                                output uvm_reg_data_t     value[],
928
                                input  uvm_path_e         path = UVM_DEFAULT_PATH,
929
                                input  uvm_reg_map        map    = null,
930
                                input  uvm_sequence_base  parent = null,
931
                                input  int                prior = -1,
932
                                input  uvm_object         extension = null,
933
                                input  string             fname = "",
934
                                input  int                lineno = 0);
935
   uvm_mem mem = this.parent.get_memory();
936
   this.fname = fname;
937
   this.lineno = lineno;
938
 
939
   if (mem == null) begin
940
      `uvm_error("RegModel", "Cannot use uvm_mem_region::burst_read() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance");
941
      status = UVM_NOT_OK;
942
      return;
943
   end
944
 
945
   if (offset + value.size() > this.len) begin
946
      `uvm_error("RegModel",
947
                 $sformatf("Attempting to burst-read to an offset outside of the allocated region (burst to [%0d:%0d] > mem_size %0d)",
948
                           offset,offset+value.size(),this.len))
949
      status = UVM_NOT_OK;
950
      return;
951
   end
952
 
953
   mem.burst_read(status, offset + get_start_offset(), value,
954
                  path, map, parent, prior, extension);
955
 
956
endtask: burst_read
957
 
958
 
959
task uvm_mem_region::poke(output uvm_status_e       status,
960
                          input  uvm_reg_addr_t     offset,
961
                          input  uvm_reg_data_t     value,
962
                          input  uvm_sequence_base  parent = null,
963
                          input  uvm_object         extension = null,
964
                          input  string             fname = "",
965
                          input  int                lineno = 0);
966
   uvm_mem mem = this.parent.get_memory();
967
   this.fname = fname;
968
   this.lineno = lineno;
969
 
970
   if (mem == null) begin
971
      `uvm_error("RegModel", "Cannot use uvm_mem_region::poke() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance");
972
      status = UVM_NOT_OK;
973
      return;
974
   end
975
 
976
   if (offset > this.len) begin
977
      `uvm_error("RegModel",
978
                 $sformatf("Attempting to poke to an offset outside of the allocated region (%0d > %0d)",
979
                           offset, this.len));
980
      status = UVM_NOT_OK;
981
      return;
982
   end
983
 
984
   mem.poke(status, offset + this.get_start_offset(), value, "", parent, extension);
985
endtask: poke
986
 
987
 
988
task uvm_mem_region::peek(output uvm_status_e       status,
989
                          input  uvm_reg_addr_t     offset,
990
                          output uvm_reg_data_t     value,
991
                          input  uvm_sequence_base  parent = null,
992
                          input  uvm_object         extension = null,
993
                          input  string             fname = "",
994
                          input  int                lineno = 0);
995
   uvm_mem mem = this.parent.get_memory();
996
   this.fname = fname;
997
   this.lineno = lineno;
998
 
999
   if (mem == null) begin
1000
      `uvm_error("RegModel", "Cannot use uvm_mem_region::peek() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance");
1001
      status = UVM_NOT_OK;
1002
      return;
1003
   end
1004
 
1005
   if (offset > this.len) begin
1006
      `uvm_error("RegModel",
1007
                 $sformatf("Attempting to peek from an offset outside of the allocated region (%0d > %0d)",
1008
                           offset, this.len));
1009
      status = UVM_NOT_OK;
1010
      return;
1011
   end
1012
 
1013
   mem.peek(status, offset + this.get_start_offset(), value, "", parent, extension);
1014
endtask: peek
1015
 
1016
 
1017
`endif  // UVM_MEM_MAM__SV

powered by: WebSVN 2.1.0

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