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

Subversion Repositories uart2bus_testbench

[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [reg/] [uvm_vreg_field.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 Mentor Graphics Corporation
5
//    All Rights Reserved Worldwide
6
//
7
//    Licensed under the Apache License, Version 2.0 (the
8
//    "License"); you may not use this file except in
9
//    compliance with the License.  You may obtain a copy of
10
//    the License at
11
//
12
//        http://www.apache.org/licenses/LICENSE-2.0
13
//
14
//    Unless required by applicable law or agreed to in
15
//    writing, software distributed under the License is
16
//    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17
//    CONDITIONS OF ANY KIND, either express or implied.  See
18
//    the License for the specific language governing
19
//    permissions and limitations under the License.
20
// -------------------------------------------------------------
21
//
22
 
23
 
24
//------------------------------------------------------------------------------
25
// Title: Virtual Register Field Classes
26
//
27
// This section defines the virtual field and callback classes.
28
//
29
// A virtual field is set of contiguous bits in one or more memory locations.
30
// The semantics and layout of virtual fields comes from
31
// an agreement between the software and the hardware,
32
// not any physical structures in the DUT.
33
//
34
//------------------------------------------------------------------------------
35
 
36
typedef class uvm_vreg_field_cbs;
37
 
38
 
39
//------------------------------------------------------------------------------
40
// Class: uvm_vreg_field
41
//
42
// Virtual field abstraction class
43
//
44
// A virtual field represents a set of adjacent bits that are
45
// logically implemented in consecutive memory locations.
46
//
47
//------------------------------------------------------------------------------
48
 
49
class uvm_vreg_field extends uvm_object;
50
 
51
   `uvm_object_utils(uvm_vreg_field)
52
   `uvm_register_cb(uvm_vreg_field, uvm_vreg_field_cbs)
53
 
54
   local uvm_vreg parent;
55
   local int unsigned lsb;
56
   local int unsigned size;
57
   local string fname;
58
   local int lineno;
59
   local bit read_in_progress;
60
   local bit write_in_progress;
61
 
62
 
63
   //
64
   // Group: initialization
65
   //
66
 
67
   //
68
   // Function: new
69
   // Create a new virtual field instance
70
   //
71
   // This method should not be used directly.
72
   // The uvm_vreg_field::type_id::create() method should be used instead.
73
   //
74
   extern function new(string name = "uvm_vreg_field");
75
 
76
   //
77
   // Function: configure
78
   // Instance-specific configuration
79
   //
80
   // Specify the ~parent~ virtual register of this virtual field, its
81
   // ~size~ in bits, and the position of its least-significant bit
82
   // within the virtual register relative to the least-significant bit
83
   // of the virtual register.
84
   //
85
   extern function void configure(uvm_vreg parent,
86
                                  int unsigned size,
87
                                  int unsigned lsb_pos);
88
 
89
 
90
   //
91
   // Group: Introspection
92
   //
93
 
94
   //
95
   // Function: get_name
96
   // Get the simple name
97
   //
98
   // Return the simple object name of this virtual field
99
   //
100
 
101
   //
102
   // Function: get_full_name
103
   // Get the hierarchical name
104
   //
105
   // Return the hierarchal name of this virtual field
106
   // The base of the hierarchical name is the root block.
107
   //
108
   extern virtual function string        get_full_name();
109
 
110
   //
111
   // FUNCTION: get_parent
112
   // Get the parent virtual register
113
   //
114
   extern virtual function uvm_vreg get_parent();
115
   extern virtual function uvm_vreg get_register();
116
 
117
   //
118
   // FUNCTION: get_lsb_pos_in_register
119
   // Return the position of the virtual field
120
   ///
121
   // Returns the index of the least significant bit of the virtual field
122
   // in the virtual register that instantiates it.
123
   // An offset of 0 indicates a field that is aligned with the
124
   // least-significant bit of the register.
125
   //
126
   extern virtual function int unsigned get_lsb_pos_in_register();
127
 
128
   //
129
   // FUNCTION: get_n_bits
130
   // Returns the width, in bits, of the virtual field.
131
   //
132
   extern virtual function int unsigned get_n_bits();
133
 
134
   //
135
   // FUNCTION: get_access
136
   // Returns the access policy of the virtual field register
137
   // when written and read via an address map.
138
   //
139
   // If the memory implementing the virtual field
140
   // is mapped in more than one address map,
141
   // an address ~map~ must be specified.
142
   // If access restrictions are present when accessing a memory
143
   // through the specified address map, the access mode returned
144
   // takes the access restrictions into account.
145
   // For example, a read-write memory accessed
146
   // through an address map with read-only restrictions would return "RO".
147
   //
148
   extern virtual function string get_access(uvm_reg_map map = null);
149
 
150
 
151
   //
152
   // Group: HDL Access
153
   //
154
 
155
   //
156
   // TASK: write
157
   // Write the specified value in a virtual field
158
   //
159
   // Write ~value~ in the DUT memory location(s) that implements
160
   // the virtual field that corresponds to this
161
   // abstraction class instance using the specified access
162
   // ~path~.
163
   //
164
   // If the memory implementing the virtual register array
165
   // containing this virtual field
166
   // is mapped in more than one address map,
167
   // an address ~map~ must be
168
   // specified if a physical access is used (front-door access).
169
   //
170
   // The operation is eventually mapped into
171
   // memory read-modify-write operations at the location
172
   // where the virtual register
173
   // specified by ~idx~ in the virtual register array is implemented.
174
   // If a backdoor is available for the memory implementing the
175
   // virtual field, it will be used for the memory-read operation.
176
   //
177
   extern virtual task write(input  longint unsigned   idx,
178
                             output uvm_status_e  status,
179
                             input  uvm_reg_data_t     value,
180
                             input  uvm_path_e    path = UVM_DEFAULT_PATH,
181
                             input  uvm_reg_map        map = null,
182
                             input  uvm_sequence_base  parent = null,
183
                             input  uvm_object         extension = null,
184
                             input  string             fname = "",
185
                             input  int                lineno = 0);
186
 
187
   //
188
   // TASK: read
189
   // Read the current value from a virtual field
190
   //
191
   // Read from the DUT memory location(s) that implements
192
   // the virtual field that corresponds to this
193
   // abstraction class instance using the specified access
194
   // ~path~, and return the readback ~value~.
195
   //
196
   // If the memory implementing the virtual register array
197
   // containing this virtual field
198
   // is mapped in more than one address map,
199
   // an address ~map~ must be
200
   // specified if a physical access is used (front-door access).
201
   //
202
   // The operation is eventually mapped into
203
   // memory read operations at the location(s)
204
   // where the virtual register
205
   // specified by ~idx~ in the virtual register array is implemented.
206
   //
207
   extern virtual task read(input  longint unsigned    idx,
208
                            output uvm_status_e   status,
209
                            output uvm_reg_data_t      value,
210
                            input  uvm_path_e     path = UVM_DEFAULT_PATH,
211
                            input  uvm_reg_map         map = null,
212
                            input  uvm_sequence_base   parent = null,
213
                            input  uvm_object          extension = null,
214
                            input  string              fname = "",
215
                            input  int                 lineno = 0);
216
 
217
 
218
   //
219
   // TASK: poke
220
   // Deposit the specified value in a virtual field
221
   //
222
   // Deposit ~value~ in the DUT memory location(s) that implements
223
   // the virtual field that corresponds to this
224
   // abstraction class instance using the specified access
225
   // ~path~.
226
   //
227
   // The operation is eventually mapped into
228
   // memory peek-modify-poke operations at the location
229
   // where the virtual register
230
   // specified by ~idx~ in the virtual register array is implemented.
231
   //
232
   extern virtual task poke(input  longint unsigned    idx,
233
                            output uvm_status_e   status,
234
                            input  uvm_reg_data_t      value,
235
                            input  uvm_sequence_base   parent = null,
236
                            input  uvm_object          extension = null,
237
                            input  string              fname = "",
238
                            input  int                 lineno = 0);
239
 
240
   //
241
   // TASK: peek
242
   // Sample the current value from a virtual field
243
   //
244
   // Sample from the DUT memory location(s) that implements
245
   // the virtual field that corresponds to this
246
   // abstraction class instance using the specified access
247
   // ~path~, and return the readback ~value~.
248
   //
249
   // If the memory implementing the virtual register array
250
   // containing this virtual field
251
   // is mapped in more than one address map,
252
   // an address ~map~ must be
253
   // specified if a physical access is used (front-door access).
254
   //
255
   // The operation is eventually mapped into
256
   // memory peek operations at the location(s)
257
   // where the virtual register
258
   // specified by ~idx~ in the virtual register array is implemented.
259
   //
260
   extern virtual task peek(input  longint unsigned    idx,
261
                            output uvm_status_e   status,
262
                            output uvm_reg_data_t      value,
263
                            input  uvm_sequence_base   parent = null,
264
                            input  uvm_object          extension = null,
265
                            input  string              fname = "",
266
                            input  int                 lineno = 0);
267
 
268
   //
269
   // Group: Callbacks
270
   //
271
 
272
 
273
   //
274
   // TASK: pre_write
275
   // Called before virtual field write.
276
   //
277
   // If the specified data value, access ~path~ or address ~map~ are modified,
278
   // the updated data value, access path or address map will be used
279
   // to perform the virtual register operation.
280
   //
281
   // The virtual field callback methods are invoked before the callback methods
282
   // on the containing virtual register.
283
   // The registered callback methods are invoked after the invocation
284
   // of this method.
285
   // The pre-write virtual register and field callbacks are executed
286
   // before the corresponding pre-write memory callbacks
287
   //
288
   virtual task pre_write(longint unsigned     idx,
289
                          ref uvm_reg_data_t   wdat,
290
                          ref uvm_path_e  path,
291
                          ref uvm_reg_map   map);
292
   endtask: pre_write
293
 
294
   //
295
   // TASK: post_write
296
   // Called after virtual field write
297
   //
298
   // If the specified ~status~ is modified,
299
   // the updated status will be
300
   // returned by the virtual register operation.
301
   //
302
   // The virtual field callback methods are invoked after the callback methods
303
   // on the containing virtual register.
304
   // The registered callback methods are invoked before the invocation
305
   // of this method.
306
   // The post-write virtual register and field callbacks are executed
307
   // after the corresponding post-write memory callbacks
308
   //
309
   virtual task post_write(longint unsigned       idx,
310
                           uvm_reg_data_t         wdat,
311
                           uvm_path_e        path,
312
                           uvm_reg_map         map,
313
                           ref uvm_status_e  status);
314
   endtask: post_write
315
 
316
   //
317
   // TASK: pre_read
318
   // Called before virtual field read.
319
   //
320
   // If the specified access ~path~ or address ~map~ are modified,
321
   // the updated access path or address map will be used to perform
322
   // the virtual register operation.
323
   //
324
   // The virtual field callback methods are invoked after the callback methods
325
   // on the containing virtual register.
326
   // The registered callback methods are invoked after the invocation
327
   // of this method.
328
   // The pre-read virtual register and field callbacks are executed
329
   // before the corresponding pre-read memory callbacks
330
   //
331
   virtual task pre_read(longint unsigned      idx,
332
                         ref uvm_path_e   path,
333
                         ref uvm_reg_map    map);
334
   endtask: pre_read
335
 
336
   //
337
   // TASK: post_read
338
   // Called after virtual field read.
339
   //
340
   // If the specified readback data ~rdat~ or ~status~ is modified,
341
   // the updated readback data or status will be
342
   // returned by the virtual register operation.
343
   //
344
   // The virtual field callback methods are invoked after the callback methods
345
   // on the containing virtual register.
346
   // The registered callback methods are invoked before the invocation
347
   // of this method.
348
   // The post-read virtual register and field callbacks are executed
349
   // after the corresponding post-read memory callbacks
350
   //
351
   virtual task post_read(longint unsigned       idx,
352
                          ref uvm_reg_data_t     rdat,
353
                          uvm_path_e        path,
354
                          uvm_reg_map         map,
355
                          ref uvm_status_e  status);
356
   endtask: post_read
357
 
358
 
359
   extern virtual function void do_print (uvm_printer printer);
360
   extern virtual function string convert2string;
361
   extern virtual function uvm_object clone();
362
   extern virtual function void do_copy   (uvm_object rhs);
363
   extern virtual function bit do_compare (uvm_object  rhs,
364
                                          uvm_comparer comparer);
365
   extern virtual function void do_pack (uvm_packer packer);
366
   extern virtual function void do_unpack (uvm_packer packer);
367
 
368
endclass: uvm_vreg_field
369
 
370
 
371
//------------------------------------------------------------------------------
372
// Class: uvm_vreg_field_cbs
373
//
374
// Pre/post read/write callback facade class
375
//
376
//------------------------------------------------------------------------------
377
 
378
class uvm_vreg_field_cbs extends uvm_callback;
379
   string fname;
380
   int    lineno;
381
 
382
   function new(string name = "uvm_vreg_field_cbs");
383
      super.new(name);
384
   endfunction
385
 
386
 
387
   //
388
   // Task: pre_write
389
   // Callback called before a write operation.
390
   //
391
   // The registered callback methods are invoked before the invocation
392
   // of the virtual register pre-write callbacks and
393
   // after the invocation of the  method.
394
   //
395
   // The written value ~wdat~, access ~path~ and address ~map~,
396
   // if modified, modifies the actual value, access path or address map
397
   // used in the register operation.
398
   //
399
   virtual task pre_write(uvm_vreg_field       field,
400
                          longint unsigned     idx,
401
                          ref uvm_reg_data_t   wdat,
402
                          ref uvm_path_e  path,
403
                          ref uvm_reg_map   map);
404
   endtask: pre_write
405
 
406
 
407
   //
408
   // TASK: post_write
409
   // Called after a write operation
410
   //
411
   // The registered callback methods are invoked after the invocation
412
   // of the virtual register post-write callbacks and
413
   // before the invocation of the  method.
414
   //
415
   // The ~status~ of the operation,
416
   // if modified, modifies the actual returned status.
417
   //
418
   virtual task post_write(uvm_vreg_field        field,
419
                           longint unsigned      idx,
420
                           uvm_reg_data_t        wdat,
421
                           uvm_path_e       path,
422
                           uvm_reg_map        map,
423
                           ref uvm_status_e status);
424
   endtask: post_write
425
 
426
 
427
   //
428
   // TASK: pre_read
429
   // Called before a virtual field read.
430
   //
431
   // The registered callback methods are invoked after the invocation
432
   // of the virtual register pre-read callbacks and
433
   // after the invocation of the  method.
434
   //
435
   // The access ~path~ and address ~map~,
436
   // if modified, modifies the actual access path or address map
437
   // used in the register operation.
438
   //
439
   virtual task pre_read(uvm_vreg_field        field,
440
                         longint unsigned      idx,
441
                         ref uvm_path_e   path,
442
                         ref uvm_reg_map    map);
443
   endtask: pre_read
444
 
445
 
446
   //
447
   // TASK: post_read
448
   // Called after a virtual field read.
449
   //
450
   // The registered callback methods are invoked after the invocation
451
   // of the virtual register post-read callbacks and
452
   // before the invocation of the  method.
453
   //
454
   // The readback value ~rdat~ and the ~status~ of the operation,
455
   // if modified, modifies the actual returned readback value and status.
456
   //
457
   virtual task post_read(uvm_vreg_field         field,
458
                          longint unsigned       idx,
459
                          ref uvm_reg_data_t     rdat,
460
                          uvm_path_e        path,
461
                          uvm_reg_map         map,
462
                          ref uvm_status_e  status);
463
   endtask: post_read
464
endclass: uvm_vreg_field_cbs
465
 
466
 
467
//
468
// Type: uvm_vreg_field_cb
469
// Convenience callback type declaration
470
//
471
// Use this declaration to register virtual field callbacks rather than
472
// the more verbose parameterized class
473
//
474
typedef uvm_callbacks#(uvm_vreg_field, uvm_vreg_field_cbs) uvm_vreg_field_cb;
475
 
476
//
477
// Type: uvm_vreg_field_cb_iter
478
// Convenience callback iterator type declaration
479
//
480
// Use this declaration to iterate over registered virtual field callbacks
481
// rather than the more verbose parameterized class
482
//
483
typedef uvm_callback_iter#(uvm_vreg_field, uvm_vreg_field_cbs) uvm_vreg_field_cb_iter;
484
 
485
 
486
 
487
 
488
function uvm_vreg_field::new(string name="uvm_vreg_field");
489
   super.new(name);
490
endfunction: new
491
 
492
function void uvm_vreg_field::configure(uvm_vreg  parent,
493
                                   int unsigned  size,
494
                                   int unsigned  lsb_pos);
495
   this.parent = parent;
496
   if (size == 0) begin
497
      `uvm_error("RegModel", $sformatf("Virtual field \"%s\" cannot have 0 bits", this.get_full_name()));
498
      size = 1;
499
   end
500
   if (size > `UVM_REG_DATA_WIDTH) begin
501
      `uvm_error("RegModel", $sformatf("Virtual field \"%s\" cannot have more than %0d bits",
502
                                     this.get_full_name(),
503
                                     `UVM_REG_DATA_WIDTH));
504
      size = `UVM_REG_DATA_WIDTH;
505
   end
506
 
507
   this.size   = size;
508
   this.lsb    = lsb_pos;
509
 
510
   this.parent.add_field(this);
511
endfunction: configure
512
 
513
 
514
 
515
function string uvm_vreg_field::get_full_name();
516
   get_full_name = {this.parent.get_full_name(), ".", this.get_name()};
517
endfunction: get_full_name
518
 
519
 
520
function uvm_vreg uvm_vreg_field::get_register();
521
   get_register = this.parent;
522
endfunction: get_register
523
 
524
 
525
function uvm_vreg uvm_vreg_field::get_parent();
526
   get_parent = this.parent;
527
endfunction: get_parent
528
 
529
 
530
 
531
function int unsigned uvm_vreg_field::get_lsb_pos_in_register();
532
   get_lsb_pos_in_register = this.lsb;
533
endfunction: get_lsb_pos_in_register
534
 
535
 
536
function int unsigned uvm_vreg_field::get_n_bits();
537
   get_n_bits = this.size;
538
endfunction: get_n_bits
539
 
540
 
541
function string uvm_vreg_field::get_access(uvm_reg_map map = null);
542
   if (this.parent.get_memory() == null) begin
543
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg_field::get_rights() on unimplemented virtual field \"%s\"",
544
                                     this.get_full_name()));
545
      return "RW";
546
   end
547
 
548
   return this.parent.get_access(map);
549
endfunction: get_access
550
 
551
 
552
task uvm_vreg_field::write(input  longint unsigned    idx,
553
                           output uvm_status_e   status,
554
                           input  uvm_reg_data_t      value,
555
                           input  uvm_path_e     path = UVM_DEFAULT_PATH,
556
                           input  uvm_reg_map      map = null,
557
                           input  uvm_sequence_base   parent = null,
558
                           input  uvm_object          extension = null,
559
                           input  string              fname = "",
560
                           input  int                 lineno = 0);
561
   uvm_reg_data_t  tmp;
562
   uvm_reg_data_t  segval;
563
   uvm_reg_addr_t  segoff;
564
   uvm_status_e st;
565
 
566
   int flsb, fmsb, rmwbits;
567
   int segsiz, segn;
568
   uvm_mem    mem;
569
   uvm_path_e rm_path;
570
 
571
   uvm_vreg_field_cb_iter cbs = new(this);
572
 
573
   this.fname = fname;
574
   this.lineno = lineno;
575
 
576
   write_in_progress = 1'b1;
577
   mem = this.parent.get_memory();
578
   if (mem == null) begin
579
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg_field::write() on unimplemented virtual register \"%s\"",
580
                                     this.get_full_name()));
581
      status = UVM_NOT_OK;
582
      return;
583
   end
584
 
585
   if (path == UVM_DEFAULT_PATH) begin
586
      uvm_reg_block blk = this.parent.get_block();
587
      path = blk.get_default_path();
588
   end
589
 
590
   status = UVM_IS_OK;
591
 
592
   this.parent.XatomicX(1);
593
 
594
   if (value >> this.size) begin
595
      `uvm_warning("RegModel", $sformatf("Writing value 'h%h that is greater than field \"%s\" size (%0d bits)", value, this.get_full_name(), this.get_n_bits()));
596
      value &= value & ((1<
597
   end
598
   tmp = 0;
599
 
600
   this.pre_write(idx, value, path, map);
601
   for (uvm_vreg_field_cbs cb = cbs.first(); cb != null;
602
        cb = cbs.next()) begin
603
      cb.fname = this.fname;
604
      cb.lineno = this.lineno;
605
      cb.pre_write(this, idx, value, path, map);
606
   end
607
 
608
   segsiz = mem.get_n_bytes() * 8;
609
   flsb    = this.get_lsb_pos_in_register();
610
   segoff  = this.parent.get_offset_in_memory(idx) + (flsb / segsiz);
611
 
612
   // Favor backdoor read to frontdoor read for the RMW operation
613
   rm_path = UVM_DEFAULT_PATH;
614
   if (mem.get_backdoor() != null) rm_path = UVM_BACKDOOR;
615
 
616
   // Any bits on the LSB side we need to RMW?
617
   rmwbits = flsb % segsiz;
618
 
619
   // Total number of memory segment in this field
620
   segn = (rmwbits + this.get_n_bits() - 1) / segsiz + 1;
621
 
622
   if (rmwbits > 0) begin
623
      uvm_reg_addr_t  segn;
624
 
625
      mem.read(st, segoff, tmp, rm_path, map, parent, , extension, fname, lineno);
626
      if (st != UVM_IS_OK && st != UVM_HAS_X) begin
627
         `uvm_error("RegModel",
628
                    $sformatf("Unable to read LSB bits in %s[%0d] to for RMW cycle on virtual field %s.",
629
                              mem.get_full_name(), segoff, this.get_full_name()));
630
         status = UVM_NOT_OK;
631
         this.parent.XatomicX(0);
632
         return;
633
      end
634
 
635
      value = (value << rmwbits) | (tmp & ((1<
636
   end
637
 
638
   // Any bits on the MSB side we need to RMW?
639
   fmsb = rmwbits + this.get_n_bits() - 1;
640
   rmwbits = (fmsb+1) % segsiz;
641
   if (rmwbits > 0) begin
642
      if (segn > 0) begin
643
         mem.read(st, segoff + segn - 1, tmp, rm_path, map, parent,, extension, fname, lineno);
644
         if (st != UVM_IS_OK && st != UVM_HAS_X) begin
645
            `uvm_error("RegModel",
646
                       $sformatf("Unable to read MSB bits in %s[%0d] to for RMW cycle on virtual field %s.",
647
                                 mem.get_full_name(), segoff+segn-1,
648
                                 this.get_full_name()));
649
            status = UVM_NOT_OK;
650
            this.parent.XatomicX(0);
651
            return;
652
         end
653
      end
654
      value |= (tmp & ~((1<
655
   end
656
 
657
   // Now write each of the segments
658
   tmp = value;
659
   repeat (segn) begin
660
      mem.write(st, segoff, tmp, path, map, parent,, extension, fname, lineno);
661
      if (st != UVM_IS_OK && st != UVM_HAS_X) status = UVM_NOT_OK;
662
 
663
      segoff++;
664
      tmp = tmp >> segsiz;
665
   end
666
 
667
   this.post_write(idx, value, path, map, status);
668
   for (uvm_vreg_field_cbs cb = cbs.first(); cb != null;
669
        cb = cbs.next()) begin
670
      cb.fname = this.fname;
671
      cb.lineno = this.lineno;
672
      cb.post_write(this, idx, value, path, map, status);
673
   end
674
 
675
   this.parent.XatomicX(0);
676
 
677
 
678
   `uvm_info("RegModel", $sformatf("Wrote virtual field \"%s\"[%0d] via %s with: 'h%h",
679
                              this.get_full_name(), idx,
680
                              (path == UVM_FRONTDOOR) ? "frontdoor" : "backdoor",
681
                              value),UVM_MEDIUM);
682
 
683
   write_in_progress = 1'b0;
684
   this.fname = "";
685
   this.lineno = 0;
686
endtask: write
687
 
688
 
689
task uvm_vreg_field::read(input longint unsigned     idx,
690
                          output uvm_status_e   status,
691
                          output uvm_reg_data_t      value,
692
                          input  uvm_path_e     path = UVM_DEFAULT_PATH,
693
                          input  uvm_reg_map      map = null,
694
                          input  uvm_sequence_base   parent = null,
695
                          input  uvm_object          extension = null,
696
                          input  string              fname = "",
697
                          input  int                 lineno = 0);
698
   uvm_reg_data_t  tmp;
699
   uvm_reg_data_t  segval;
700
   uvm_reg_addr_t  segoff;
701
   uvm_status_e st;
702
 
703
   int flsb, lsb;
704
   int segsiz, segn;
705
   uvm_mem    mem;
706
 
707
   uvm_vreg_field_cb_iter cbs = new(this);
708
 
709
   this.fname = fname;
710
   this.lineno = lineno;
711
 
712
   read_in_progress = 1'b1;
713
   mem = this.parent.get_memory();
714
   if (mem == null) begin
715
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg_field::read() on unimplemented virtual register \"%s\"",
716
                                     this.get_full_name()));
717
      status = UVM_NOT_OK;
718
      return;
719
   end
720
 
721
   if (path == UVM_DEFAULT_PATH) begin
722
      uvm_reg_block blk = this.parent.get_block();
723
      path = blk.get_default_path();
724
   end
725
 
726
   status = UVM_IS_OK;
727
 
728
   this.parent.XatomicX(1);
729
 
730
   value = 0;
731
 
732
   this.pre_read(idx, path, map);
733
   for (uvm_vreg_field_cbs cb = cbs.first(); cb != null;
734
        cb = cbs.next()) begin
735
      cb.fname = this.fname;
736
      cb.lineno = this.lineno;
737
      cb.pre_read(this, idx, path, map);
738
   end
739
 
740
   segsiz = mem.get_n_bytes() * 8;
741
   flsb    = this.get_lsb_pos_in_register();
742
   segoff  = this.parent.get_offset_in_memory(idx) + (flsb / segsiz);
743
   lsb = flsb % segsiz;
744
 
745
   // Total number of memory segment in this field
746
   segn = (lsb + this.get_n_bits() - 1) / segsiz + 1;
747
 
748
   // Read each of the segments, MSB first
749
   segoff += segn - 1;
750
   repeat (segn) begin
751
      value = value << segsiz;
752
 
753
      mem.read(st, segoff, tmp, path, map, parent, , extension, fname, lineno);
754
      if (st != UVM_IS_OK && st != UVM_HAS_X) status = UVM_NOT_OK;
755
 
756
      segoff--;
757
      value |= tmp;
758
   end
759
 
760
   // Any bits on the LSB side we need to get rid of?
761
   value = value >> lsb;
762
 
763
   // Any bits on the MSB side we need to get rid of?
764
   value &= (1<
765
 
766
   this.post_read(idx, value, path, map, status);
767
   for (uvm_vreg_field_cbs cb = cbs.first(); cb != null;
768
        cb = cbs.next()) begin
769
      cb.fname = this.fname;
770
      cb.lineno = this.lineno;
771
      cb.post_read(this, idx, value, path, map, status);
772
   end
773
 
774
   this.parent.XatomicX(0);
775
 
776
   `uvm_info("RegModel", $sformatf("Read virtual field \"%s\"[%0d] via %s: 'h%h",
777
                              this.get_full_name(), idx,
778
                              (path == UVM_FRONTDOOR) ? "frontdoor" : "backdoor",
779
                              value),UVM_MEDIUM);
780
 
781
 
782
   read_in_progress = 1'b0;
783
   this.fname = "";
784
   this.lineno = 0;
785
endtask: read
786
 
787
 
788
task uvm_vreg_field::poke(input  longint unsigned  idx,
789
                          output uvm_status_e status,
790
                          input  uvm_reg_data_t    value,
791
                          input  uvm_sequence_base parent = null,
792
                          input  uvm_object        extension = null,
793
                          input  string            fname = "",
794
                          input  int               lineno = 0);
795
   uvm_reg_data_t  tmp;
796
   uvm_reg_data_t  segval;
797
   uvm_reg_addr_t  segoff;
798
   uvm_status_e st;
799
 
800
   int flsb, fmsb, rmwbits;
801
   int segsiz, segn;
802
   uvm_mem    mem;
803
   uvm_path_e rm_path;
804
   this.fname = fname;
805
   this.lineno = lineno;
806
 
807
   mem = this.parent.get_memory();
808
   if (mem == null) begin
809
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg_field::poke() on unimplemented virtual register \"%s\"",
810
                                     this.get_full_name()));
811
      status = UVM_NOT_OK;
812
      return;
813
   end
814
 
815
   status = UVM_IS_OK;
816
 
817
   this.parent.XatomicX(1);
818
 
819
   if (value >> this.size) begin
820
      `uvm_warning("RegModel", $sformatf("Writing value 'h%h that is greater than field \"%s\" size (%0d bits)", value, this.get_full_name(), this.get_n_bits()));
821
      value &= value & ((1<
822
   end
823
   tmp = 0;
824
 
825
   segsiz = mem.get_n_bytes() * 8;
826
   flsb    = this.get_lsb_pos_in_register();
827
   segoff  = this.parent.get_offset_in_memory(idx) + (flsb / segsiz);
828
 
829
   // Any bits on the LSB side we need to RMW?
830
   rmwbits = flsb % segsiz;
831
 
832
   // Total number of memory segment in this field
833
   segn = (rmwbits + this.get_n_bits() - 1) / segsiz + 1;
834
 
835
   if (rmwbits > 0) begin
836
      uvm_reg_addr_t  segn;
837
 
838
      mem.peek(st, segoff, tmp, "", parent, extension, fname, lineno);
839
      if (st != UVM_IS_OK && st != UVM_HAS_X) begin
840
         `uvm_error("RegModel",
841
                    $sformatf("Unable to read LSB bits in %s[%0d] to for RMW cycle on virtual field %s.",
842
                              mem.get_full_name(), segoff, this.get_full_name()));
843
         status = UVM_NOT_OK;
844
         this.parent.XatomicX(0);
845
         return;
846
      end
847
 
848
      value = (value << rmwbits) | (tmp & ((1<
849
   end
850
 
851
   // Any bits on the MSB side we need to RMW?
852
   fmsb = rmwbits + this.get_n_bits() - 1;
853
   rmwbits = (fmsb+1) % segsiz;
854
   if (rmwbits > 0) begin
855
      if (segn > 0) begin
856
         mem.peek(st, segoff + segn - 1, tmp, "", parent, extension, fname, lineno);
857
         if (st != UVM_IS_OK && st != UVM_HAS_X) begin
858
            `uvm_error("RegModel",
859
                       $sformatf("Unable to read MSB bits in %s[%0d] to for RMW cycle on virtual field %s.",
860
                                 mem.get_full_name(), segoff+segn-1,
861
                                 this.get_full_name()));
862
            status = UVM_NOT_OK;
863
            this.parent.XatomicX(0);
864
            return;
865
         end
866
      end
867
      value |= (tmp & ~((1<
868
   end
869
 
870
   // Now write each of the segments
871
   tmp = value;
872
   repeat (segn) begin
873
      mem.poke(st, segoff, tmp, "", parent, extension, fname, lineno);
874
      if (st != UVM_IS_OK && st != UVM_HAS_X) status = UVM_NOT_OK;
875
 
876
      segoff++;
877
      tmp = tmp >> segsiz;
878
   end
879
 
880
   this.parent.XatomicX(0);
881
 
882
   `uvm_info("RegModel", $sformatf("Wrote virtual field \"%s\"[%0d] with: 'h%h",
883
                              this.get_full_name(), idx, value),UVM_MEDIUM);
884
 
885
   this.fname = "";
886
   this.lineno = 0;
887
endtask: poke
888
 
889
 
890
task uvm_vreg_field::peek(input  longint unsigned  idx,
891
                          output uvm_status_e status,
892
                          output uvm_reg_data_t    value,
893
                          input  uvm_sequence_base parent = null,
894
                          input  uvm_object        extension = null,
895
                          input  string            fname = "",
896
                          input  int               lineno = 0);
897
   uvm_reg_data_t  tmp;
898
   uvm_reg_data_t  segval;
899
   uvm_reg_addr_t  segoff;
900
   uvm_status_e st;
901
 
902
   int flsb, lsb;
903
   int segsiz, segn;
904
   uvm_mem    mem;
905
   this.fname = fname;
906
   this.lineno = lineno;
907
 
908
   mem = this.parent.get_memory();
909
   if (mem == null) begin
910
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg_field::peek() on unimplemented virtual register \"%s\"",
911
                                     this.get_full_name()));
912
      status = UVM_NOT_OK;
913
      return;
914
   end
915
 
916
   status = UVM_IS_OK;
917
 
918
   this.parent.XatomicX(1);
919
 
920
   value = 0;
921
 
922
   segsiz = mem.get_n_bytes() * 8;
923
   flsb    = this.get_lsb_pos_in_register();
924
   segoff  = this.parent.get_offset_in_memory(idx) + (flsb / segsiz);
925
   lsb = flsb % segsiz;
926
 
927
   // Total number of memory segment in this field
928
   segn = (lsb + this.get_n_bits() - 1) / segsiz + 1;
929
 
930
   // Read each of the segments, MSB first
931
   segoff += segn - 1;
932
   repeat (segn) begin
933
      value = value << segsiz;
934
 
935
      mem.peek(st, segoff, tmp, "", parent, extension, fname, lineno);
936
 
937
      if (st != UVM_IS_OK && st != UVM_HAS_X) status = UVM_NOT_OK;
938
 
939
      segoff--;
940
      value |= tmp;
941
   end
942
 
943
   // Any bits on the LSB side we need to get rid of?
944
   value = value >> lsb;
945
 
946
   // Any bits on the MSB side we need to get rid of?
947
   value &= (1<
948
 
949
   this.parent.XatomicX(0);
950
 
951
   `uvm_info("RegModel", $sformatf("Peeked virtual field \"%s\"[%0d]: 'h%h", this.get_full_name(), idx, value),UVM_MEDIUM);
952
 
953
   this.fname = "";
954
   this.lineno = 0;
955
endtask: peek
956
 
957
 
958
function void uvm_vreg_field::do_print (uvm_printer printer);
959
  super.do_print(printer);
960
  printer.print_generic("initiator", parent.get_type_name(), -1, convert2string());
961
endfunction
962
 
963
function string uvm_vreg_field::convert2string();
964
   string res_str;
965
   string t_str;
966
   bit with_debug_info = 1'b0;
967
   $sformat(convert2string, {"%s[%0d-%0d]"},
968
            this.get_name(),
969
            this.get_lsb_pos_in_register() + this.get_n_bits() - 1,
970
            this.get_lsb_pos_in_register());
971
   if (read_in_progress == 1'b1) begin
972
      if (fname != "" && lineno != 0)
973
         $sformat(res_str, "%s:%0d ",fname, lineno);
974
      convert2string = {convert2string, "\n", res_str, "currently executing read method"};
975
   end
976
   if ( write_in_progress == 1'b1) begin
977
      if (fname != "" && lineno != 0)
978
         $sformat(res_str, "%s:%0d ",fname, lineno);
979
      convert2string = {convert2string, "\n", res_str, "currently executing write method"};
980
   end
981
 
982
endfunction
983
 
984
//TODO - add fatal messages
985
 
986
function uvm_object uvm_vreg_field::clone();
987
  return null;
988
endfunction
989
 
990
function void uvm_vreg_field::do_copy   (uvm_object rhs);
991
endfunction
992
 
993
function bit uvm_vreg_field::do_compare (uvm_object  rhs,
994
                                        uvm_comparer comparer);
995
  return 0;
996
endfunction
997
 
998
function void uvm_vreg_field::do_pack (uvm_packer packer);
999
endfunction
1000
 
1001
function void uvm_vreg_field::do_unpack (uvm_packer packer);
1002
endfunction
1003
 
1004
 

powered by: WebSVN 2.1.0

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