VMM OpenSource - (expanded) sv/RAL/vmm_ral_vreg.sv

Expanded versions of source files are the output of the preprocessor. Lines subject to conditional compilation are not shown and all compiler pragmas have been stripped. Macros have been completely expanded.

sv/RAL/vmm_ral_vreg.sv unexpanded source

00001: // 
00002: // -------------------------------------------------------------
00003: //    Copyright 2004-2008 Synopsys, Inc.
00004: //    All Rights Reserved Worldwide
00005: // 
00006: //    Licensed under the Apache License, Version 2.0 (the
00007: //    "License"); you may not use this file except in
00008: //    compliance with the License.  You may obtain a copy of
00009: //    the License at
00010: // 
00011: //        http://www.apache.org/licenses/LICENSE-2.0
00012: // 
00013: //    Unless required by applicable law or agreed to in
00014: //    writing, software distributed under the License is
00015: //    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
00016: //    CONDITIONS OF ANY KIND, either express or implied.  See
00017: //    the License for the specific language governing
00018: //    permissions and limitations under the License.
00019: // -------------------------------------------------------------
00020: // 
00021: 
00022: 
00023: typedef class vmm_mam_region;
00024: typedef class vmm_mam;
00025: 
00026: 
00027: class vmm_ral_vreg_callbacks extends vmm_ral_callbacks;
00028: 
00029:    virtual task pre_write(vmm_ral_vreg                      rg,
00030:                           longint unsigned                  idx,
00031:                           ref bit [64-1:0] wdat,
00032:                           ref vmm_ral::path_e               path,
00033:                           ref string                        domain);
00034:    endtask: pre_write
00035: 
00036:    virtual task post_write(vmm_ral_vreg                  rg,
00037:                            longint unsigned              idx,
00038:                            bit [64-1:0] wdat,
00039:                            vmm_ral::path_e               path,
00040:                            string                        domain,
00041:                            ref vmm_rw::status_e          status);
00042:    endtask: post_write
00043: 
00044:    virtual task pre_read(vmm_ral_vreg         rg,
00045:                          longint unsigned     idx,
00046:                          ref vmm_ral::path_e  path,
00047:                          ref string           domain);
00048:    endtask: pre_read
00049: 
00050:    virtual task post_read(vmm_ral_vreg                      rg,
00051:                           longint unsigned                  idx,
00052:                           ref bit [64-1:0] rdat,
00053:                           input vmm_ral::path_e             path,
00054:                           input string                      domain,
00055:                           ref vmm_rw::status_e              status);
00056:    endtask: post_read
00057: endclass: vmm_ral_vreg_callbacks
00058: 
00059: 
00060: class vmm_ral_vreg;
00061:    static vmm_log log = new("RAL", "virtual register");
00062: 
00063:    local bit locked;
00064:    local vmm_ral_block parent;
00065:    local string name;
00066:    local int unsigned  n_bits;
00067:    local int unsigned  n_used_bits;
00068: 
00069:    local vmm_ral_vfield fields[$];   // Fields in LSB to MSB order
00070: 
00071:    local vmm_ral_vreg_callbacks callbacks[$];
00072: 
00073:    local vmm_ral_mem                   mem;     // Where is it implemented?
00074:    local bit [64-1:0] offset;  // Start of vreg[0]
00075:    local int unsigned                  incr;    // From start to start of next
00076:    local longint unsigned              size;    //number of vregs
00077:    local bit                           is_static;
00078: 
00079:    local vmm_mam_region   region;    // Not NULL if implemented via MAM
00080:   
00081:    local semaphore atomic;   // Field RMW operations must be atomic
00082: 
00083:    extern /*local*/ function new(vmm_ral_block                 parent,
00084:                                  string                        name,
00085:                                  int unsigned                  n_bits,
00086:                                  bit [64-1:0] offset = 0,
00087:                                  vmm_ral_mem                   mem    = null,
00088:                                  longint unsigned              size   = 0,
00089:                                  int unsigned                  incr   = 0);
00090: 
00091:    /*local*/ extern function void Xlock_modelX();
00092:    
00093:    /*local*/ extern function void register_field(vmm_ral_vfield field);
00094:    /*local*/ extern task XatomicX(bit on);
00095:    
00096:    extern function void reset(vmm_ral::reset_e kind = vmm_ral::HARD);
00097: 
00098:    extern virtual function string get_name();
00099:    extern virtual function string get_fullname();
00100:    extern virtual function vmm_ral_block get_block();
00101: 
00102:    extern virtual function bit implement(longint unsigned              n,
00103:                                          vmm_ral_mem                   mem    = null,
00104:                                          bit [64-1:0] offset = 0,
00105:                                          int unsigned                  incr   = 0);
00106:    extern virtual function vmm_mam_region allocate(longint unsigned n,
00107:                                                    vmm_mam          mam);
00108:    extern virtual function vmm_mam_region get_region();
00109:    extern virtual function void release_region();
00110: 
00111:    extern virtual function vmm_ral_mem get_memory();
00112:    extern virtual function int get_n_domains();
00113:    extern virtual function void get_domains(ref string domains[]);
00114:    extern virtual function vmm_ral::access_e get_access(string domain = "");
00115:    extern virtual function vmm_ral::access_e get_rights(string domain = "");
00116:    extern virtual function bit [64-1:0] get_offset_in_memory(longint unsigned idx);
00117: 
00118:    extern virtual function bit [64-1:0] get_address_in_system(longint unsigned idx,
00119:                                                                                string domain = "");
00120: 
00121:    extern virtual function int unsigned get_size();
00122:    extern virtual function int unsigned get_n_bytes();
00123:    extern virtual function int unsigned get_n_memlocs();
00124:    extern virtual function int unsigned get_incr();
00125: 
00126:    extern virtual function void display(string prefix = "",
00127:                                         string domain = "");
00128:    extern virtual function string psdisplay(string prefix = "",
00129:                                             string domain = "");
00130: 
00131:    extern virtual function void get_fields(ref vmm_ral_vfield fields[]);
00132:    extern virtual function vmm_ral_vfield get_field_by_name(string name);
00133: 
00134:    extern virtual task write(input  longint unsigned             idx,
00135:                              output vmm_rw::status_e             status,
00136:                              input  bit[64-1:0] value,
00137:                              input  vmm_ral::path_e              path = vmm_ral::DEFAULT,
00138:                              input  string                       domain = "",
00139:                              input  int                          data_id = -1,
00140:                              input  int                          scenario_id = -1,
00141:                              input  int                          stream_id = -1);
00142:    extern virtual task read(input  longint unsigned             idx,
00143:                             output vmm_rw::status_e             status,
00144:                             output bit[64-1:0] value,
00145:                             input  vmm_ral::path_e              path = vmm_ral::DEFAULT,
00146:                             input  string                       domain = "",
00147:                             input  int                          data_id = -1,
00148:                             input  int                          scenario_id = -1,
00149:                             input  int                          stream_id = -1);
00150:    extern virtual task poke(input  longint unsigned             idx,
00151:                             output vmm_rw::status_e             status,
00152:                             input  bit[64-1:0] value,
00153:                             input  int                          data_id = -1,
00154:                             input  int                          scenario_id = -1,
00155:                             input  int                          stream_id = -1);
00156:    extern virtual task peek(input  longint unsigned             idx,
00157:                             output vmm_rw::status_e             status,
00158:                             output bit[64-1:0] value,
00159:                             input  int                          data_id = -1,
00160:                             input  int                          scenario_id = -1,
00161:                             input  int                          stream_id = -1);
00162:   
00163:    extern function void prepend_callback(vmm_ral_vreg_callbacks cb);
00164:    extern function void append_callback(vmm_ral_vreg_callbacks cb);
00165:    extern function void unregister_callback(vmm_ral_vreg_callbacks cb);
00166: endclass: vmm_ral_vreg
00167: 
00168: 
00169: function vmm_ral_vreg::new(vmm_ral_block                 parent,
00170:                            string                        name,
00171:                            int unsigned                  n_bits,
00172:                            bit [64-1:0] offset = 0,
00173:                            vmm_ral_mem                   mem = null,
00174:                            longint unsigned              size = 0,
00175:                            int unsigned                  incr = 0);
00176:    this.locked    = 0;
00177: 
00178:    this.parent = parent;
00179:    this.parent.register_vreg(this);
00180:    this.name = name;
00181: 
00182:    if (n_bits == 0) begin
00183:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Virtual register \"%s\" cannot have 0 bits", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00184:       n_bits = 1;
00185:    end
00186:    if (n_bits > 64) begin
00187:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Virtual register \"%s\" cannot have more than %0d bits %0d", this.get_fullname(), 64, n_bits))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00188:       n_bits = 64;
00189:    end
00190:    this.n_bits = n_bits;
00191:    this.n_used_bits = 0;
00192: 
00193:    if (mem != null) begin
00194:       void'(this.implement(size, mem, offset, incr));
00195:       this.is_static = 1;
00196:    end
00197:    else begin
00198:       this.mem = null;
00199:       this.is_static = 0;
00200:    end
00201: 
00202:    this.atomic = new(1);
00203: endfunction: new
00204: 
00205: 
00206: function void vmm_ral_vreg::Xlock_modelX();
00207:    if (this.locked) return;
00208: 
00209:    this.locked = 1;
00210: endfunction: Xlock_modelX
00211: 
00212: 
00213: function void vmm_ral_vreg::register_field(vmm_ral_vfield field);
00214:    int offset;
00215:    int idx;
00216:    
00217:    if (this.locked) begin
00218:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text("Cannot add virtual field to locked virtual register model")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00219:       return;
00220:    end
00221: 
00222:    if (field == null) 
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin 
     :       void'(this.log.text("Attempting to register NULL virtual field")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00223: 
00224:    // Store fields in LSB to MSB order
00225:    offset = field.get_lsb_pos_in_register();
00226: 
00227:    idx = -1;
00228:    foreach (this.fields[i]) begin
00229:       if (offset < this.fields[i].get_lsb_pos_in_register()) begin
00230:          int j = i;
00231:          this.fields.insert(j, field);
00232:          idx = i;
00233:          break;
00234:       end
00235:    end
00236:    if (idx < 0) begin
00237:       this.fields.push_back(field);
00238:       idx = this.fields.size()-1;
00239:    end
00240: 
00241:    this.n_used_bits += field.get_n_bits();
00242:    
00243:    // Check if there are too many fields in the register
00244:    if (this.n_used_bits > this.n_bits) begin
00245:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Virtual fields use more bits %0d than available in virtual register \"%s\" %0d",
     :                                      this.n_used_bits, this.get_fullname(), this.n_bits))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00247:    end
00248: 
00249:    // Check if there are overlapping fields
00250:    if (idx > 0) begin
00251:       if (this.fields[idx-1].get_lsb_pos_in_register() +
00252:           this.fields[idx-1].get_n_bits() > offset) begin
00253:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Field %s overlaps field %s in virtual register \"%s\"",
     :                                         this.fields[idx-1].get_name(),
     :                                         field.get_name(),
     :                                         this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00257:       end
00258:    end
00259:    if (idx < this.fields.size()-1) begin
00260:       if (offset + field.get_n_bits() >
00261:           this.fields[idx+1].get_lsb_pos_in_register()) begin
00262:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Field %s overlaps field %s in virtual register \"%s\"",
     :                                         field.get_name(),
     :                                         this.fields[idx+1].get_name(),
     : 
     :                                         this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00267:       end
00268:    end
00269: endfunction: register_field
00270: 
00271: 
00272: task vmm_ral_vreg::XatomicX(bit on);
00273:    if (on) this.atomic.get(1);
00274:    else begin
00275:       // Maybe a key was put back in by a spurious call to reset()
00276:       void'(this.atomic.try_get(1));
00277:       this.atomic.put(1);
00278:    end
00279: endtask: XatomicX
00280: 
00281: 
00282: function void vmm_ral_vreg::reset(vmm_ral::reset_e kind = vmm_ral::HARD);
00283:    // Put back a key in the semaphore if it is checked out
00284:    // in case a thread was killed during an operation
00285:    void'(this.atomic.try_get(1));
00286:    this.atomic.put(1);
00287: endfunction: reset
00288: 
00289: 
00290: function string vmm_ral_vreg::get_name();
00291:    return this.name;
00292: endfunction: get_name
00293: 
00294: 
00295: function string vmm_ral_vreg::get_fullname();
00296:    vmm_ral_block blk;
00297: 
00298:    get_fullname = this.get_name();
00299: 
00300:    // Do not include top-level name in full name
00301:    blk = this.get_block();
00302:    if (blk == null) return get_fullname;
00303:    if (blk.get_parent() == null) return get_fullname;
00304: 
00305:    get_fullname = {this.parent.get_fullname(), ".", get_fullname};
00306: endfunction: get_fullname
00307: 
00308: 
00309: function vmm_ral_block vmm_ral_vreg::get_block();
00310:    get_block = this.parent;
00311: endfunction: get_block
00312: 
00313: 
00314: function bit vmm_ral_vreg::implement(longint unsigned              n,
00315:                                      vmm_ral_mem                   mem = null,
00316:                                      bit [64-1:0] offset = 0,
00317:                                      int unsigned                  incr = 0);
00318: 
00319:    vmm_mam_region mam_region;
00320: 
00321:    if(n < 1)
00322:    begin
00323:      
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Attempting to implement virtual register \"%s\" with a subscript less than one doesn't make sense",this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00324:       return 0;
00325:    end
00326: 
00327:    if (mem == null) begin
00328:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Attempting to implement virtual register \"%s\" using a NULL vmm_ral_mem reference", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00329:       return 0;
00330:    end
00331: 
00332:    if (this.is_static) begin
00333:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Virtual register \"%s\" is static and cannot be dynamically implemented", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00334:       return 0;
00335:    end
00336: 
00337:    if (mem.get_block() != this.parent) begin
00338:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Attempting to implement virtual register \"%s\" on memory \"%s\" in a different block",
     :                                      this.get_fullname(),
     :                                      mem.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00341:       return 0;
00342:    end
00343: 
00344:    begin
00345:       int min_incr = (this.get_n_bytes()-1) / mem.get_n_bytes() + 1;
00346:       if (incr == 0) incr = min_incr;
00347:       if (min_incr > incr) begin
00348:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Virtual register \"%s\" increment is too small %0d: Each virtual register requires at least %0d locations in memory \"%s\".",
     :                                         this.get_fullname(), incr,
     :                                         min_incr, mem.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00351:          return 0;
00352:       end
00353:    end
00354: 
00355:    // Is the memory big enough for ya?
00356:    if (offset + (n * incr) > mem.get_size()) begin
00357:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Given Offset for Virtual register \"%s[%0d]\" is too big for memory %s@'h%0h", this.get_fullname(), n, mem.get_fullname(), offset))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00358:       return 0;
00359:    end
00360: 
00361:    mam_region = mem.mam.reserve_region(offset,n*incr*mem.get_n_bytes());
00362: 
00363:    if (mam_region == null) begin
00364:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Could not allocate a memory region for virtual register \"%s\"", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00365:       return 0;
00366:    end
00367: 
00368:    if (this.mem != null) begin
00369:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Virtual register \"%s\" is being moved re-implemented from %s@'h%0h to %s@'h%0h",
     :                                      this.get_fullname(),
     :                                      this.mem.get_fullname(),
     :                                      this.offset,
     :                                      mem.get_fullname(), offset))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00374:       this.release_region();
00375:    end
00376: 
00377:    this.region = mam_region;
00378:    this.mem    = mem;
00379:    this.size   = n;
00380:    this.offset = offset;
00381:    this.incr   = incr;
00382:    this.mem.XvregsX.push_back(this);
00383: 
00384:    return 1;
00385: endfunction: implement
00386: 
00387: 
00388: function vmm_mam_region vmm_ral_vreg::allocate(longint unsigned n,
00389:                                                vmm_mam          mam);
00390: 
00391:    vmm_ral_mem mem;
00392: 
00393:    if(n < 1)
00394:    begin
00395:      
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Attempting to implement virtual register \"%s\" with a subscript less than one doesn't make sense",this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00396:       return null;
00397:    end
00398: 
00399:    if (mam == null) begin
00400:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Attempting to implement virtual register \"%s\" using a NULL vmm_mam reference", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00401:       return null;
00402:    end
00403: 
00404:    if (this.is_static) begin
00405:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Virtual register \"%s\" is static and cannot be dynamically allocated", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00406:       return null;
00407:    end
00408: 
00409:    mem = mam.get_memory();
00410:    if (mem.get_block() != this.parent) begin
00411:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Attempting to allocate virtual register \"%s\" on memory \"%s\" in a different block",
     :                                      this.get_fullname(),
     :                                      mem.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00414:       return null;
00415:    end
00416: 
00417:    begin
00418:       int min_incr = (this.get_n_bytes()-1) / mem.get_n_bytes() + 1;
00419:       if (incr == 0) incr = min_incr;
00420:       if (min_incr < incr) begin
00421:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Virtual register \"%s\" increment is too small %0d: Each virtual register requires at least %0d locations in memory \"%s\".",
     :                                         this.get_fullname(), incr,
     :                                         min_incr, mem.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00424:          return null;
00425:       end
00426:    end
00427: 
00428:    // Need memory at least of size num_vregs*sizeof(vreg) in bytes.
00429:    allocate = mam.request_region(n*incr*mem.get_n_bytes());
00430:    if (allocate == null) begin
00431:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Could not allocate a memory region for virtual register \"%s\"", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00432:       return null;
00433:    end
00434: 
00435:    if (this.mem != null) begin
00436:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Virtual register \"%s\" is being moved re-allocated from %s@'h%0h to %s@'h%0h",
     :                                      this.get_fullname(),
     :                                      this.mem.get_fullname(),
     :                                      this.offset,
     :                                      mem.get_fullname(),
     :                                      allocate.get_start_offset()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00442: 
00443:       this.release_region();
00444:    end
00445: 
00446:    this.region = allocate;
00447: 
00448:    this.mem    = mam.get_memory();
00449:    this.offset = allocate.get_start_offset();
00450:    this.size   = n;
00451:    this.incr   = incr;
00452: 
00453:    this.mem.XvregsX.push_back(this);
00454: endfunction: allocate
00455: 
00456: 
00457: function vmm_mam_region vmm_ral_vreg::get_region();
00458:    return this.region;
00459: endfunction: get_region
00460: 
00461: 
00462: function void vmm_ral_vreg::release_region();
00463:    if (this.is_static) begin
00464:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Virtual register \"%s\" is static and cannot be dynamically released", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00465:       return;
00466:    end
00467: 
00468:    if (this.mem != null) begin
00469:       foreach (this.mem.XvregsX[i]) begin
00470:          if (this.mem.XvregsX[i] == this) begin
00471:             this.mem.XvregsX.delete(i);
00472:             break;
00473:          end
00474:       end
00475:    end 
00476:    if (this.region != null) begin
00477:       this.region.release_region();
00478:    end
00479: 
00480:    this.region = null;
00481:    this.mem    = null;
00482:    this.size   = 0;
00483:    this.offset = 0;
00484: 
00485:    this.reset();
00486: endfunction: release_region
00487: 
00488: 
00489: function vmm_ral_mem vmm_ral_vreg::get_memory();
00490:    return this.mem;
00491: endfunction: get_memory
00492: 
00493: 
00494: function bit [64-1:0] vmm_ral_vreg::get_offset_in_memory(longint unsigned idx);
00495:    if (this.mem == null) begin
00496:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_offset_in_memory on unimplemented virtual register \"%s\"",
     :                                      this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00498:       return 0;
00499:    end
00500: 
00501:    return this.offset + idx * this.incr;
00502: endfunction
00503: 
00504: 
00505: function bit [64-1:0] vmm_ral_vreg::get_address_in_system(longint unsigned idx,
00506:                                                                            string domain = "");
00507:    if (this.mem == null) begin
00508:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot get address of of unimplemented virtual register \"%s\".", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00509:       return 0;
00510:    end
00511: 
00512:    return this.mem.get_address_in_system(this.get_offset_in_memory(idx),
00513:                                          domain);
00514: endfunction: get_address_in_system
00515: 
00516: 
00517: function int unsigned vmm_ral_vreg::get_size();
00518:    if (this.size == 0) begin
00519:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_size on unimplemented virtual register \"%s\"",
     :                                      this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00521:       return 0;
00522:    end
00523: 
00524:    return this.size;
00525: endfunction: get_size
00526: 
00527: 
00528: function int unsigned vmm_ral_vreg::get_n_bytes();
00529:    return ((this.n_bits-1) / 8) + 1;
00530: endfunction: get_n_bytes
00531: 
00532: 
00533: function int unsigned vmm_ral_vreg::get_n_memlocs();
00534:    if (this.mem == null) begin
00535:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_n_memlocs on unimplemented virtual register \"%s\"",
     :                                      this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00537:       return 0;
00538:    end
00539: 
00540:    return (this.get_n_bytes()-1) / this.mem.get_n_bytes() + 1;
00541: endfunction: get_n_memlocs
00542: 
00543: 
00544: function int unsigned vmm_ral_vreg::get_incr();
00545:    if (this.incr == 0) begin
00546:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_incr on unimplemented virtual register \"%s\"",
     :                                      this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00548:       return 0;
00549:    end
00550: 
00551:    return this.incr;
00552: endfunction: get_incr
00553: 
00554: 
00555: function int vmm_ral_vreg::get_n_domains();
00556:    if (this.mem == null) begin
00557:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_n_domains on unimplemented virtual register \"%s\"",
     :                                      this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00559:       return 0;
00560:    end
00561: 
00562:    get_n_domains = this.mem.get_n_domains();
00563: endfunction: get_n_domains
00564: 
00565: 
00566: function void vmm_ral_vreg::get_domains(ref string domains[]);
00567:    if (this.mem == null) begin
00568:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_domains on unimplemented virtual register \"%s\"",
     :                                      this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00570:       return;
00571:    end
00572: 
00573:    this.mem.get_domains(domains);
00574: endfunction: get_domains
00575: 
00576: 
00577: function vmm_ral::access_e vmm_ral_vreg::get_access(string domain = "");
00578:    if (this.mem == null) begin
00579:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_rights on unimplemented virtual register \"%s\"",
     :                                      this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00581:       return vmm_ral::RW;
00582:    end
00583: 
00584:    get_access = this.mem.get_access(domain);
00585: endfunction: get_access
00586: 
00587: 
00588: function vmm_ral::access_e vmm_ral_vreg::get_rights(string domain = "");
00589:    if (this.mem == null) begin
00590:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_rights on unimplemented virtual register \"%s\"",
     :                                      this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00592:       return vmm_ral::RW;
00593:    end
00594: 
00595:    get_rights = this.mem.get_rights(domain);
00596: endfunction: get_rights
00597: 
00598: 
00599: function void vmm_ral_vreg::display(string prefix = "",
00600:                                     string domain = "");
00601:    $write("%s\n", this.psdisplay(prefix, domain));
00602: endfunction: display
00603: 
00604: 
00605: function string vmm_ral_vreg::psdisplay(string prefix = "",
00606:                                        string domain = "");
00607:    $sformat(psdisplay, "%sVirtual register %s -- ", prefix,
00608:             this.get_fullname());
00609:    if (this.size == 0) $sformat(psdisplay, "%sunimplemented", psdisplay);
00610:    else begin
00611:       bit [64-1:0] addr0;
00612: 
00613:       addr0 = this.get_address_in_system(0, domain);
00614: 
00615:       $sformat(psdisplay, "%s[%0d] in %0s['h%0h+'h%0h] @'h%h+'h%h", psdisplay,
00616:                this.size, this.mem.get_fullname(), this.offset, this.incr, 
00617:                addr0, this.get_address_in_system(1, domain) - addr0);
00618:   end
00619:    foreach(this.fields[i]) begin
00620:       $sformat(psdisplay, "%s\n%s", psdisplay,
00621:                this.fields[i].psdisplay({prefix, "   "}));
00622:    end
00623: endfunction: psdisplay
00624: 
00625: 
00626: function void vmm_ral_vreg::get_fields(ref vmm_ral_vfield fields[]);
00627:    fields = new [this.fields.size()];
00628:    foreach(this.fields[i]) begin
00629:       fields[i] = this.fields[i];
00630:    end
00631: endfunction: get_fields
00632: 
00633: 
00634: function vmm_ral_vfield vmm_ral_vreg::get_field_by_name(string name);
00635:    foreach (this.fields[i]) begin
00636:       if (this.fields[i].get_name() == name) begin
00637:          return this.fields[i];
00638:       end
00639:    end
00640:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Unable to locate field \"%s\" in virtual register \"%s\".",
     :                                     name, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00642:    get_field_by_name = null;
00643: endfunction: get_field_by_name
00644: 
00645: 
00646: task vmm_ral_vreg::write(input  longint unsigned             idx,
00647:                          output vmm_rw::status_e             status,
00648:                          input  bit[64-1:0] value,
00649:                          input  vmm_ral::path_e              path = vmm_ral::DEFAULT,
00650:                          input  string                       domain = "",
00651:                          input  int                          data_id = -1,
00652:                          input  int                          scenario_id = -1,
00653:                          input  int                          stream_id = -1);
00654: 
00655:    bit [64-1:0] addr;
00656:    bit [64-1:0] tmp;
00657:    bit [64-1:0] msk;
00658:    int lsb;
00659: 
00660:    if (this.mem == null) begin
00661:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot write to unimplemented virtual register \"%s\".", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00662:       status = vmm_rw::ERROR;
00663:       return;
00664:    end
00665: 
00666:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00667: 
00668:    foreach (fields[i]) begin
00669:       vmm_ral_vfield f = fields[i];
00670:       
00671:       lsb = f.get_lsb_pos_in_register();
00672:       msk = ((1<<f.get_n_bits())-1) << lsb;
00673:       tmp = (value & msk) >> lsb;
00674:       foreach (f.XcbsX[j]) begin
00675:          vmm_ral_vfield_callbacks cb;
00676:          if (!$cast(cb, f.XcbsX[j])) continue;
00677:          cb.pre_write(f, idx, tmp, path, domain);
00678:       end
00679:       value = (value & ~msk) | (tmp << lsb);
00680:    end
00681:    
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_vreg_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.pre_write(this, idx, value, path, domain); 
     : end while (0);
00683: 
00684:    addr = this.offset + (idx * this.incr);
00685: 
00686:    lsb = 0;
00687:    status = vmm_rw::IS_OK;
00688:    for (int i = 0; i < this.get_n_memlocs(); i++) begin
00689:       vmm_rw::status_e s;
00690: 
00691:       msk = ((1<<(this.mem.get_n_bytes()*8))-1) << lsb;
00692:       tmp = (value & msk) >> lsb;
00693:       this.mem.write(s, addr + i, tmp,
00694:                      path, domain ,
00695:                      data_id, scenario_id, stream_id);
00696:       if (s != vmm_rw::IS_OK) status = s;
00697:       lsb += this.mem.get_n_bytes() * 8;
00698:    end
00699: 
00700:    foreach (fields[i]) begin
00701:       vmm_ral_vfield f = fields[i];
00702:       
00703:       lsb = f.get_lsb_pos_in_register();
00704:       msk = ((1<<f.get_n_bits())-1) << lsb;
00705:       tmp = (value & msk) >> lsb;
00706:       foreach (f.XcbsX[j]) begin
00707:          vmm_ral_vfield_callbacks cb;
00708:          if (!$cast(cb, f.XcbsX[j])) continue;
00709:          cb.post_write(f, idx, tmp, path, domain, status);
00710:       end
00711:       value = (value & ~msk) | (tmp << lsb);
00712:    end
00713:    
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_vreg_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.post_write(this, idx, value, path, domain, status); 
     : end while (0);
00715: 
00716:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Wrote virtual register \"%s\"[%0d] via %s with: 'h%h",
     :                                   this.get_fullname(), idx,
     :                                   (path == vmm_ral::BFM) ? "frontdoor" : "backdoor",
     :                                   value))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00720: 
00721: endtask: write
00722: 
00723: 
00724: task vmm_ral_vreg::read(input  longint unsigned             idx,
00725:                         output vmm_rw::status_e             status,
00726:                         output bit[64-1:0] value,
00727:                         input  vmm_ral::path_e              path = vmm_ral::DEFAULT,
00728:                         input  string                       domain = "",
00729:                         input  int                          data_id = -1,
00730:                         input  int                          scenario_id = -1,
00731:                         input  int                          stream_id = -1);
00732:    bit [64-1:0] addr;
00733:    bit [64-1:0] tmp;
00734:    bit [64-1:0] msk;
00735:    int lsb;
00736: 
00737:    if (this.mem == null) begin
00738:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot read from unimplemented virtual register \"%s\".", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00739:       status = vmm_rw::ERROR;
00740:       return;
00741:    end
00742: 
00743:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00744: 
00745:    foreach (fields[i]) begin
00746:       vmm_ral_vfield f = fields[i];
00747:       foreach (f.XcbsX[j]) begin
00748:          vmm_ral_vfield_callbacks cb;
00749:          if (!$cast(cb, f.XcbsX[j])) continue;
00750:          cb.pre_read(f, idx, path, domain);
00751:       end
00752:    end
00753:   
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_vreg_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.pre_read(this, idx, path, domain); 
     : end while (0);
00755: 
00756:    addr = this.offset + (idx * this.incr);
00757: 
00758:    lsb = 0;
00759:    value = 0;
00760:    status = vmm_rw::IS_OK;
00761:    for (int i = 0; i < this.get_n_memlocs(); i++) begin
00762:       vmm_rw::status_e s;
00763: 
00764:       this.mem.read(s, addr + i, tmp,
00765:                      path, domain ,
00766:                      data_id, scenario_id, stream_id);
00767:       if (s != vmm_rw::IS_OK) status = s;
00768: 
00769:       value |= tmp << lsb;
00770:       lsb += this.mem.get_n_bytes() * 8;
00771:    end
00772: 
00773:    foreach (fields[i]) begin
00774:       vmm_ral_vfield f = fields[i];
00775: 
00776:       lsb = f.get_lsb_pos_in_register();
00777: 
00778:       msk = ((1<<f.get_n_bits())-1) << lsb;
00779:       tmp = (value & msk) >> lsb;
00780: 
00781:       foreach (f.XcbsX[j]) begin
00782:          vmm_ral_vfield_callbacks cb;
00783:          if (!$cast(cb, f.XcbsX[j])) continue;
00784:          cb.post_read(f, idx, tmp, path, domain, status);
00785:       end
00786: 
00787:       value = (value & ~msk) | (tmp << lsb);
00788:    end
00789:    
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_vreg_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.post_read(this, idx, value, path, domain, status); 
     : end while (0);
00791: 
00792:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Read virtual register \"%s\"[%0d] via %s: 'h%h",
     :                                   this.get_fullname(), idx,
     :                                   (path == vmm_ral::BFM) ? "frontdoor" : "backdoor",
     :                                   value))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00796: endtask: read
00797: 
00798: 
00799: task vmm_ral_vreg::poke(input longint unsigned              idx,
00800:                         output vmm_rw::status_e             status,
00801:                         input  bit[64-1:0] value,
00802:                         input  int                          data_id = -1,
00803:                         input  int                          scenario_id = -1,
00804:                         input  int                          stream_id = -1);
00805:    bit [64-1:0] addr;
00806:    bit [64-1:0] tmp;
00807:    bit [64-1:0] msk;
00808:    int lsb;
00809: 
00810:    if (this.mem == null) begin
00811:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot poke in unimplemented virtual register \"%s\".", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00812:       status = vmm_rw::ERROR;
00813:       return;
00814:    end
00815: 
00816:    addr = this.offset + (idx * this.incr);
00817: 
00818:    lsb = 0;
00819:    status = vmm_rw::IS_OK;
00820:    for (int i = 0; i < this.get_n_memlocs(); i++) begin
00821:       vmm_rw::status_e s;
00822: 
00823:       msk = ((1<<(this.mem.get_n_bytes() * 8))-1) << lsb;
00824:       tmp = (value & msk) >> lsb;
00825: 
00826:       this.mem.poke(status, addr + i, tmp,
00827:                     data_id, scenario_id, stream_id);
00828:       if (s != vmm_rw::IS_OK) status = s;
00829: 
00830:       lsb += this.mem.get_n_bytes() * 8;
00831:    end
00832: 
00833:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Poked virtual register \"%s\"[%0d] with: 'h%h",
     :                                   this.get_fullname(), idx, value))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00835: 
00836: endtask: poke
00837: 
00838: 
00839: task vmm_ral_vreg::peek(input longint unsigned              idx,
00840:                         output vmm_rw::status_e             status,
00841:                         output bit[64-1:0] value,
00842:                         input  int                          data_id = -1,
00843:                         input  int                          scenario_id = -1,
00844:                         input  int                          stream_id = -1);
00845:    bit [64-1:0] addr;
00846:    bit [64-1:0] tmp;
00847:    bit [64-1:0] msk;
00848:    int lsb;
00849: 
00850:    if (this.mem == null) begin
00851:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Cannot peek in from unimplemented virtual register \"%s\".", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00852:       status = vmm_rw::ERROR;
00853:       return;
00854:    end
00855: 
00856:    addr = this.offset + (idx * this.incr);
00857: 
00858:    lsb = 0;
00859:    value = 0;
00860:    status = vmm_rw::IS_OK;
00861:    for (int i = 0; i < this.get_n_memlocs(); i++) begin
00862:       vmm_rw::status_e s;
00863: 
00864:       this.mem.peek(status, addr + i, tmp,
00865:                     data_id, scenario_id, stream_id);
00866:       if (s != vmm_rw::IS_OK) status = s;
00867: 
00868:       value |= tmp << lsb;
00869:       lsb += this.mem.get_n_bytes() * 8;
00870:    end
00871: 
00872:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Peeked virtual register \"%s\"[%0d]: 'h%h",
     :                                   this.get_fullname(), idx, value))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00874: 
00875: endtask: peek
00876: 
00877: 
00878: function void vmm_ral_vreg::prepend_callback(vmm_ral_vreg_callbacks cb);
00879:    foreach (this.callbacks[i]) begin
00880:       if (this.callbacks[i] == cb) begin
00881:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Callback has already been registered with virtual register \"%s\"", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00882:          return;
00883:       end
00884:    end
00885:    
00886:    // Prepend new callback
00887:    this.callbacks.push_front(cb);
00888: endfunction: prepend_callback
00889: 
00890: 
00891: function void vmm_ral_vreg::append_callback(vmm_ral_vreg_callbacks cb);
00892:    foreach (this.callbacks[i]) begin
00893:       if (this.callbacks[i] == cb) begin
00894:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Callback has already been registered with virtual register \"%s\"", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00895:          return;
00896:       end
00897:    end
00898:    
00899:    // Append new callback
00900:    this.callbacks.push_back(cb);
00901: endfunction: append_callback
00902: 
00903: 
00904: function void vmm_ral_vreg::unregister_callback(vmm_ral_vreg_callbacks cb);
00905:    foreach (this.callbacks[i]) begin
00906:       if (this.callbacks[i] == cb) begin
00907:          int j = i;
00908:          // Unregister it
00909:          this.callbacks.delete(j);
00910:          return;
00911:       end
00912:    end
00913: 
00914:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Callback was not registered with virtual register \"%s\"", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00915: endfunction: unregister_callback