VMM OpenSource - (expanded) sv/RAL/vmm_ral_reg.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_reg.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: class vmm_ral_reg_callbacks extends vmm_ral_callbacks;
00024: 
00025:    virtual task pre_write(vmm_ral_reg                       rg,
00026:                           ref bit [64-1:0] wdat,
00027:                           ref vmm_ral::path_e               path,
00028:                           ref string                        domain);
00029:    endtask: pre_write
00030: 
00031:    virtual task post_write(vmm_ral_reg                   rg,
00032:                            bit [64-1:0] wdat,
00033:                            vmm_ral::path_e               path,
00034:                            string                        domain,
00035:                            ref vmm_rw::status_e          status);
00036:    endtask: post_write
00037: 
00038:    virtual task pre_read(vmm_ral_reg          rg,
00039:                          ref vmm_ral::path_e  path,
00040:                          ref string           domain);
00041:    endtask: pre_read
00042: 
00043:    virtual task post_read(vmm_ral_reg                       rg,
00044:                           ref bit [64-1:0] rdat,
00045:                           input vmm_ral::path_e             path,
00046:                           input string                      domain,
00047:                           ref vmm_rw::status_e              status);
00048:    endtask: post_read
00049: endclass: vmm_ral_reg_callbacks
00050: 
00051: 
00052: virtual class vmm_ral_reg_frontdoor;
00053:    static vmm_log log = new("vmm_ral_reg_frontdoor", "class");
00054:    
00055:    extern virtual task write(output vmm_rw::status_e              status,
00056:                              input  bit [64-1:0] data,
00057:                              input  int                           data_id = -1,
00058:                              input  int                           scenario_id = -1,
00059:                              input  int                           stream_id = -1);
00060:    extern virtual task read(output vmm_rw::status_e              status,
00061:                             output bit [64-1:0] data,
00062:                             input  int                           data_id = -1,
00063:                             input  int                           scenario_id = -1,
00064:                             input  int                           stream_id = -1);
00065: endclass: vmm_ral_reg_frontdoor
00066: 
00067: 
00068: 
00069: class vmm_ral_reg;
00070:    static vmm_log log = new("RAL", "register");
00071: 
00072:    static vmm_ral_reg all_regs[int]; // Keeps track of all registers in the RAL Model
00073:    static local int unsigned reg_id_factory = 0;
00074:    local int unsigned reg_id = 0;
00075:    local bit locked;
00076:    local vmm_ral_block parent;
00077:    local string name;
00078:    local int unsigned  n_bits;
00079:    local int unsigned  n_used_bits;
00080: 
00081:    local logic [64-1:0] offset_in_block[];
00082:    local string                          domains[];
00083:    local vmm_ral::access_e               rights[];
00084: 
00085:    local vmm_ral_field fields[$];   // Fields in LSB to MSB order
00086:    local string        constr[];
00087:    local event         value_change;
00088: 
00089:    local vmm_ral_access        ral_access;
00090:    local vmm_ral_reg_frontdoor frontdoor[];
00091:    local vmm_ral_reg_backdoor  backdoor;
00092: 
00093:    local vmm_ral_reg_callbacks callbacks[$];
00094: 
00095:    local string attributes[string];
00096: 
00097:    local int has_cover;
00098:    local int cover_on;
00099: 
00100:    local semaphore atomic;
00101: 
00102:    /*local*/ bit Xis_busyX;
00103:    /*local*/ bit Xis_locked_by_fieldX;
00104: 
00105:    extern function new(vmm_ral_block                 parent,
00106:                        string                        name,
00107:                        int unsigned                  n_bits,
00108:                        bit [64-1:0] offset,
00109:                        string                        domain = "",
00110:                        int                           cover_on = vmm_ral::NO_COVERAGE,
00111:                        bit [1:0]                     rights = 2'b11,
00112:                        bit                           unmapped = 0,
00113:                        int                           has_cover = vmm_ral::NO_COVERAGE);
00114: 
00115:    /*local*/ extern function void Xlock_modelX();
00116:    /*local*/ extern function void add_domain(bit [64-1:0] offset,
00117:                                              string                        domain,
00118:                                              bit [1:0]                     rights,
00119:                                              bit                           unmapped = 0);
00120:    
00121:    local virtual function void domain_coverage(string domain,
00122:                                                bit    rights,
00123:                                                int    idx);
00124:    endfunction
00125:    
00126:    /*local*/ extern function void register_field(vmm_ral_field field);
00127:    /*local*/ extern function void Xregister_ral_accessX(vmm_ral_access access);
00128:    /*local*/ extern function void Xadd_constraintsX(string name);
00129:    /*local*/ extern task XatomicX(bit on);
00130:    /*local*/ extern task XwriteX(output vmm_rw::status_e             status,
00131:                                  input  bit[64-1:0] value,
00132:                                  input  vmm_ral::path_e              path,
00133:                                  input  string                       domain,
00134:                                  input  int                          data_id,
00135:                                  input  int                          scenario_id,
00136:                                  input  int                          stream_id);
00137:    /*local*/ extern task XreadX(output vmm_rw::status_e             status,
00138:                                 output bit[64-1:0] value,
00139:                                 input  vmm_ral::path_e              path,
00140:                                 input  string                       domain,
00141:                                 input  int                          data_id,
00142:                                 input  int                          scenario_id,
00143:                                 input  int                          stream_id);
00144:    
00145:    extern virtual function string get_name();
00146:    extern virtual function string get_fullname();
00147:    extern virtual function int get_n_domains();
00148:    extern virtual function void get_domains(ref string domains[]);
00149:    extern virtual function vmm_ral::access_e get_rights(string domain = "");
00150:    extern virtual function vmm_ral_block get_block();
00151:    extern virtual function bit [64-1:0] get_offset_in_block(string domain = ""); 
00152:    extern virtual function bit [64-1:0] get_address_in_system(string domain = "");
00153:    extern virtual function int unsigned get_n_bytes();
00154:    extern virtual function void get_constraints(ref string names[]);
00155: 
00156:    extern virtual function void display(string prefix = "",
00157:                                         string domain = "");
00158:    extern virtual function string psdisplay(string prefix = "",
00159:                                             string domain = "");
00160: 
00161:    extern virtual function void get_fields(ref vmm_ral_field fields[]);
00162:    extern virtual function vmm_ral_field get_field_by_name(string name);
00163: 
00164:    extern virtual function void set_attribute(string name,
00165:                                               string value);
00166:    extern virtual function string get_attribute(string name,
00167:                                                 bit inherited = 1);
00168:    extern virtual function void get_all_attributes(ref string names[],
00169:                                                    input bit inherited = 1);
00170: 
00171:    extern virtual function bit can_cover(int models);
00172:    extern virtual function int set_cover(int is_on);
00173:    extern virtual function bit is_cover_on(int is_on);
00174: 
00175:    extern local virtual function void XforceX(bit [64-1:0] value,
00176:                                               vmm_ral::path_e               path,
00177:                                               string                        domain);
00178:    extern local virtual function void XwroteX(bit [64-1:0] value,
00179:                                               vmm_ral::path_e               path,
00180:                                               string                        domain);
00181:    extern virtual function void set(bit [64-1:0] value);
00182:    extern virtual function bit predict(bit [64-1:0] value);
00183:    extern virtual function bit[64-1:0] get();
00184:    extern virtual function void reset(vmm_ral::reset_e kind = vmm_ral::HARD);
00185:    extern virtual function logic [64-1:0]
00186:                     get_reset(vmm_ral::reset_e kind = vmm_ral::HARD);
00187:    extern virtual function bit needs_update(); 
00188:  
00189:    extern virtual task update(output vmm_rw::status_e status,
00190:                               input  vmm_ral::path_e  path = vmm_ral::DEFAULT,
00191:                               input  string           domain = "");
00192:    extern virtual task write(output vmm_rw::status_e             status,
00193:                              input  bit[64-1:0] value,
00194:                              input  vmm_ral::path_e              path = vmm_ral::DEFAULT,
00195:                              input  string                       domain = "",
00196:                              input  int                          data_id = -1,
00197:                              input  int                          scenario_id = -1,
00198:                              input  int                          stream_id = -1);
00199:    extern virtual task read(output vmm_rw::status_e             status,
00200:                             output bit[64-1:0] value,
00201:                             input  vmm_ral::path_e              path = vmm_ral::DEFAULT,
00202:                             input  string                       domain = "",
00203:                             input  int                          data_id = -1,
00204:                             input  int                          scenario_id = -1,
00205:                             input  int                          stream_id = -1);
00206:    extern virtual task poke(output vmm_rw::status_e             status,
00207:                             input  bit[64-1:0] value,
00208:                             input  int                          data_id = -1,
00209:                             input  int                          scenario_id = -1,
00210:                             input  int                          stream_id = -1);
00211:    extern virtual task peek(output vmm_rw::status_e             status,
00212:                             output bit[64-1:0] value,
00213:                             input  int                          data_id = -1,
00214:                             input  int                          scenario_id = -1,
00215:                             input  int                          stream_id = -1);
00216:    extern virtual task mirror(output vmm_rw::status_e status,
00217:                               input vmm_ral::check_e  check  = vmm_ral::QUIET,
00218:                               input vmm_ral::path_e   path = vmm_ral::DEFAULT,
00219:                               input string            domain = "");
00220:   
00221:    extern function void set_frontdoor(vmm_ral_reg_frontdoor ftdr,
00222:                                       string                domain = "");
00223:    extern function vmm_ral_reg_frontdoor get_frontdoor(string domain = "");
00224:    extern function void set_backdoor(vmm_ral_reg_backdoor bkdr);
00225:    extern function vmm_ral_reg_backdoor get_backdoor();
00226: 
00227:    extern function void prepend_callback(vmm_ral_reg_callbacks cb);
00228:    extern function void append_callback(vmm_ral_reg_callbacks cb);
00229:    extern function void unregister_callback(vmm_ral_reg_callbacks cb);
00230: 
00231:    extern local function int get_domain_index(string domain);
00232:    extern virtual local function void sample(bit [64-1:0] data,
00233:                                              bit                           is_read,
00234:                                              int                           domain);
00235: 
00236:    extern function int unsigned get_reg_ID();
00237: endclass: vmm_ral_reg
00238: 
00239: 
00240: function vmm_ral_reg::new(vmm_ral_block                 parent,
00241:                           string                        name,
00242:                           int unsigned                  n_bits,
00243:                           bit [64-1:0] offset,
00244:                           string                        domain = "",
00245:                           int                           cover_on = vmm_ral::NO_COVERAGE,
00246:                           bit [1:0]                     rights = 2'b11,
00247:                           bit                           unmapped = 0,
00248:                           int                           has_cover = vmm_ral::NO_COVERAGE);
00249:    this.locked = 0;
00250: 
00251:    this.parent = parent;
00252:    this.parent.register_reg(this);
00253: 
00254:    this.name = name;
00255:    this.has_cover = has_cover;
00256:    this.cover_on = vmm_ral::NO_COVERAGE;
00257:    void'(this.set_cover(cover_on));
00258: 
00259:    if (n_bits == 0) begin
00260:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" cannot have 0 bits", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00261:       n_bits = 1;
00262:    end
00263:    if (n_bits > 64) begin
00264:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" cannot have more than %0d bits %0d", this.get_name(), 64, n_bits))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00265:       n_bits = 64;
00266:    end
00267:    this.n_bits = n_bits;
00268:    this.n_used_bits = 0;
00269:    this.add_domain(offset, domain, rights, unmapped);
00270: 
00271:    this.atomic = new(1);
00272: 
00273:    this.Xis_busyX = 0;
00274:    this.Xis_locked_by_fieldX = 1'b0;
00275:    // Initialize Register ID
00276:    this.reg_id = ++this.reg_id_factory;
00277:    all_regs[this.reg_id] = this;
00278: endfunction: new
00279: 
00280: 
00281: function void vmm_ral_reg::Xlock_modelX();
00282:    int idx;
00283:    string fullname;
00284: 
00285:    if (this.locked) return;
00286: 
00287:    this.locked = 1;
00288: 
00289: endfunction: Xlock_modelX
00290: 
00291: 
00292: function void vmm_ral_reg::add_domain(bit [64-1:0] offset,
00293:                                       string                        domain,
00294:                                       bit [1:0]                     rights,
00295:                                       bit                           unmapped = 0);
00296:    // Verify that this is a valid domain in the block
00297:    string domains[];
00298:    vmm_ral::access_e acc;
00299: 
00300:    if (this.locked) begin
00301:       
     : 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 domain to locked register model")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00302:       return;
00303:    end
00304: 
00305:    case (rights)
00306:      2'b11: acc = vmm_ral::RW;
00307:      2'b10: acc = vmm_ral::RO;
00308:      2'b01: acc = vmm_ral::WO;
00309:      default:
00310:        
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" has no access rights in domain \"%s\"",
     :                             this.get_name(), domain))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00313:    endcase
00314: 
00315:    this.parent.get_domains(domains);
00316:    foreach(domains[i]) begin
00317:       if (domains[i] == domain) begin
00318:          automatic int n = this.offset_in_block.size();
00319:    
00320:          this.offset_in_block = new [n + 1] (this.offset_in_block);
00321:          this.offset_in_block[n] = (unmapped) ? 'x : offset;
00322:     
00323:          this.domains = new [n + 1] (this.domains);
00324:          this.domains[n] = domain;
00325: 
00326:          this.rights = new [n + 1] (this.rights);
00327:          this.rights[n] = acc;
00328: 
00329:          this.frontdoor = new [n + 1] (this.frontdoor);
00330:          this.frontdoor[n] = null;
00331: 
00332:          this.domain_coverage(domain, rights, n);
00333:          return;
00334:       end
00335:    end
00336:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Domain \"%s\" not found in parent block %s of register \"%s\"",
     :                                   domain, this.parent.get_name(), this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00338: endfunction: add_domain
00339: 
00340: 
00341: function void vmm_ral_reg::register_field(vmm_ral_field field);
00342:    int offset;
00343:    int idx;
00344:    
00345:    if (this.locked) begin
00346:       
     : 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 field to locked register model")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00347:       return;
00348:    end
00349: 
00350:    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 field")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00351: 
00352:    // Store fields in LSB to MSB order
00353:    offset = field.get_lsb_pos_in_register();
00354: 
00355:    idx = -1;
00356:    foreach (this.fields[i]) begin
00357:       if (offset < this.fields[i].get_lsb_pos_in_register()) begin
00358:          int j = i;
00359:          this.fields.insert(j, field);
00360:          idx = i;
00361:          break;
00362:       end
00363:    end
00364:    if (idx < 0) begin
00365:       this.fields.push_back(field);
00366:       idx = this.fields.size()-1;
00367:    end
00368: 
00369:    this.n_used_bits += field.get_n_bits();
00370:    
00371:    // Check if there are too many fields in the register
00372:    if (this.n_used_bits > this.n_bits) begin
00373:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Fields use more bits %0d than available in register \"%s\" %0d",
     :                                      this.n_used_bits, this.get_name(), this.n_bits))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00375:    end
00376: 
00377:    // Check if there are overlapping fields
00378:    if (idx > 0) begin
00379:       if (this.fields[idx-1].get_lsb_pos_in_register() +
00380:           this.fields[idx-1].get_n_bits() > offset) begin
00381:          
     : 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 register \"%s\"",
     :                                         this.fields[idx-1].get_name(),
     :                                         field.get_name(), this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00384:       end
00385:    end
00386:    if (idx < this.fields.size()-1) begin
00387:       if (offset + field.get_n_bits() >
00388:           this.fields[idx+1].get_lsb_pos_in_register()) begin
00389:          
     : 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 register \"%s\"",
     :                                         field.get_name(),
     :                                         this.fields[idx+1].get_name(),
     : 
     :                                       this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00394:       end
00395:    end
00396: endfunction: register_field
00397: 
00398: 
00399: function void vmm_ral_reg::Xregister_ral_accessX(vmm_ral_access access);
00400:    // There can only be one RAL Access on a RAL model
00401:    if (this.ral_access != null && this.ral_access != access) begin
00402:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" is already used by another RAL access instance", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00403:    end
00404:    this.ral_access = access;
00405: endfunction: Xregister_ral_accessX
00406: 
00407: 
00408: function void vmm_ral_reg::Xadd_constraintsX(string name);
00409:    int n;
00410: 
00411:    if (this.locked) begin
00412:       
     : 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 constraints to locked register model")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00413:       return;
00414:    end
00415: 
00416:    // Check if the constraint block already exists
00417:    foreach (this.constr[i]) begin
00418:       if (this.constr[i] == name) begin
00419:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Constraint \"%s\" already added",
     :                                           name))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00421:          return;
00422:       end
00423:    end
00424: 
00425:    // Append the constraint name to the list
00426:    n = this.constr.size();
00427:    this.constr = new [n+1] (this.constr);
00428:    this.constr[n] = name;
00429: endfunction: Xadd_constraintsX
00430: 
00431: 
00432: task vmm_ral_reg::XatomicX(bit on);
00433:    if (on) this.atomic.get(1);
00434:    else begin
00435:       // Maybe a key was put back in by a spurious call to reset()
00436:       void'(this.atomic.try_get(1));
00437:       this.atomic.put(1);
00438:    end
00439: endtask: XatomicX
00440: 
00441: 
00442: function string vmm_ral_reg::get_name();
00443:    get_name = this.name;
00444: endfunction: get_name
00445: 
00446: 
00447: function string vmm_ral_reg::get_fullname();
00448:    vmm_ral_block blk;
00449: 
00450:    get_fullname = this.get_name();
00451: 
00452:    // Do not include top-level name in full name
00453:    blk = this.get_block();
00454:    if (blk == null) return get_fullname;
00455:    if (blk.get_parent() == null) return get_fullname;
00456: 
00457:    get_fullname = {this.parent.get_fullname(), ".", get_fullname};
00458: endfunction: get_fullname
00459: 
00460: 
00461: function int vmm_ral_reg::get_n_domains();
00462:    get_n_domains = this.domains.size();
00463: endfunction: get_n_domains
00464: 
00465: 
00466: function void vmm_ral_reg::get_domains(ref string domains[]);
00467:    domains = new [this.domains.size()] (this.domains);
00468: endfunction: get_domains
00469: 
00470: 
00471: function vmm_ral::access_e vmm_ral_reg::get_rights(string domain = "");
00472:    int i;
00473: 
00474:    // No right restrictions if not shared
00475:    if (this.domains.size() == 1) begin
00476:       return vmm_ral::RW;
00477:    end
00478: 
00479:    i = this.get_domain_index(domain);
00480:    if (i < 0) return vmm_ral::RW;
00481: 
00482:    get_rights = this.rights[i];
00483: endfunction: get_rights
00484: 
00485: 
00486: function vmm_ral_block vmm_ral_reg::get_block();
00487:    get_block = this.parent;
00488: endfunction: get_block
00489: 
00490: 
00491: function bit [64-1:0] vmm_ral_reg::get_offset_in_block(string domain = "");
00492:    foreach (this.domains[i]) begin
00493:       if (this.domains[i] == domain) begin
00494:          if (this.offset_in_block[i] === 'x) begin
00495:             
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" is unmapped in domain \"%s\".", this.get_name(), domain))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00496:             return '0;
00497:          end
00498:          
00499:          return this.offset_in_block[i];
00500:       end
00501:    end
00502:    
     : 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 find offset within domain \"%s\" in register \"%s\".",
     :                                     domain, this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00504:    get_offset_in_block = '1;
00505: endfunction: get_offset_in_block
00506: 
00507: 
00508: function bit [64-1:0] vmm_ral_reg::get_address_in_system(string domain = "");
00509:    bit [64-1:0] addr[];
00510:          
00511:    int i = this.get_domain_index(domain);
00512:    if (i < 0) return 0;
00513: 
00514:    if (this.ral_access == null) begin
00515:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.parent.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin 
     :       void'(this.parent.log.text("RAL model is not associated with an access transactor")); 
     :       this.parent.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00517:       return 0;
00518:    end
00519:          
00520:    if (this.offset_in_block[i] === 'x) begin
00521:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" is unmapped in domain \"%s\".", this.get_name(), this.domains[i]))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00522:       return '1;
00523:    end
00524:          
00525:    void'(this.ral_access.Xget_physical_addressesX(this.offset_in_block[i],
00526:                                                   0, this.get_n_bytes(),
00527:                                                   this.parent, this.domains[i],
00528:                                                   addr));
00529: 
00530:    get_address_in_system = addr[addr.size()-1];
00531: 
00532:    // Make sure to return the lower address as Xget_physical_addressesX()
00533:    // returns the address in little-endian sequence.
00534:    if (addr[0] < get_address_in_system) get_address_in_system = addr[0];
00535: endfunction: get_address_in_system
00536: 
00537: 
00538: function int unsigned vmm_ral_reg::get_n_bytes();
00539:    get_n_bytes = ((this.n_bits-1) / 8) + 1;
00540: endfunction: get_n_bytes
00541: 
00542: 
00543: function void vmm_ral_reg::display(string prefix = "",
00544:                                    string domain = "");
00545:    $write("%s\n", this.psdisplay(prefix, domain));
00546: endfunction: display
00547: 
00548: 
00549: function string vmm_ral_reg::psdisplay(string prefix = "",
00550:                                        string domain = "");
00551:    $sformat(psdisplay, "%sRegister %s -- %0d bytes @", prefix,
00552:             this.get_fullname(), this.get_n_bytes());
00553:    foreach (this.domains[i]) begin
00554:       if (this.domains[i] == domain) begin
00555:          if (this.offset_in_block[i] === 'x) begin
00556:             psdisplay = {psdisplay, "none"};
00557:          end
00558:          else begin
00559:             $sformat(psdisplay, "%s'h%h", psdisplay,
00560:                      this.get_address_in_system(domain));
00561:          end
00562:          break;
00563:       end
00564:    end
00565:    if (this.attributes.num() > 0) begin
00566:       string name;
00567:       this.attributes.first(name);
00568:       psdisplay = {psdisplay, "\n", prefix, "Attributes:"};
00569:       do begin
00570:          $sformat(psdisplay, " %s=\"%s\"", name, this.attributes[name]);
00571:       end while (this.attributes.next(name));
00572:    end
00573:    foreach(this.fields[i]) begin
00574:       $sformat(psdisplay, "%s\n%s", psdisplay,
00575:                this.fields[i].psdisplay({prefix, "   "}));
00576:    end
00577: endfunction: psdisplay
00578: 
00579: 
00580: function void vmm_ral_reg::get_fields(ref vmm_ral_field fields[]);
00581:    fields = new [this.fields.size()];
00582:    foreach(this.fields[i]) begin
00583:       fields[i] = this.fields[i];
00584:    end
00585: endfunction: get_fields
00586: 
00587: 
00588: function vmm_ral_field vmm_ral_reg::get_field_by_name(string name);
00589:    foreach (this.fields[i]) begin
00590:       if (this.fields[i].get_name() == name) begin
00591:          return this.fields[i];
00592:       end
00593:    end
00594:    
     : 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 register \"%s\".",
     :                                     name, this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00596:    get_field_by_name = null;
00597: endfunction: get_field_by_name
00598: 
00599: 
00600: function void vmm_ral_reg::get_constraints(ref string names[]);
00601:    names = new [this.constr.size()] (this.constr);
00602: endfunction: get_constraints
00603: 
00604: 
00605: function void vmm_ral_reg::set_attribute(string name,
00606:                                          string value);
00607:    if (name == "") begin
00608:       
     : 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 set anonymous attribute \"\" in register \"%s\". Please specify an attribute name.",
     :                                        name, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00610:       return;
00611:    end
00612: 
00613:    if (this.attributes.exists(name)) begin
00614:       if (value != "") begin
00615:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Redefining attributed \"%s\" in register \"%s\" to \"%s\".",
     :                                           name, this.get_fullname(), value))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00617:          this.attributes[name] = value;
00618:       end
00619:       else begin
00620:          this.attributes.delete(name);
00621:       end
00622:       return;
00623:    end
00624: 
00625:    if (value == "") begin
00626:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Attempting to delete non-existent attribute \"%s\" in register \"%s\".",
     :                                        name, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00628:       return;
00629:    end
00630: 
00631:    this.attributes[name] = value;
00632: endfunction: set_attribute
00633: 
00634: 
00635: function string vmm_ral_reg::get_attribute(string name,
00636:                                            bit inherited = 1);
00637:    if (this.attributes.exists(name)) begin
00638:       return this.attributes[name];
00639:    end
00640: 
00641:    if (inherited) return this.parent.get_attribute(name);
00642: 
00643:    return "";
00644: endfunction: get_attribute
00645: 
00646: 
00647: function void vmm_ral_reg::get_all_attributes(ref string names[],
00648:                                               input bit inherited = 1);
00649:    string tmp[];
00650:    string name;
00651:    bit    ok;
00652:    int    i;
00653: 
00654:    if (inherited) this.parent.get_all_attributes(tmp);
00655: 
00656:    i = tmp.size();
00657:    tmp = new [tmp.size() + this.attributes.num()] (tmp);
00658: 
00659:    ok = this.attributes.first(name);
00660:    while (ok) begin
00661:       int found = 0;
00662:       foreach (tmp[j]) begin
00663:          if (tmp[j] == name) begin
00664:             found = 1;
00665:             break;
00666:          end
00667:       end
00668:       if (!found) tmp[i++] = name;
00669:       ok = this.attributes.next(name);
00670:    end
00671:    names = new [i] (tmp);
00672: endfunction: get_all_attributes
00673: 
00674: 
00675: function bit vmm_ral_reg::can_cover(int models);
00676:    return ((this.has_cover & models) == models);
00677: endfunction: can_cover
00678: 
00679: 
00680: function int vmm_ral_reg::set_cover(int is_on);
00681:    if (is_on == vmm_ral::NO_COVERAGE) begin
00682:       this.cover_on = is_on;
00683:       return this.cover_on;
00684:    end
00685: 
00686:    if ((this.has_cover & is_on) == 0) begin
00687:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" - Cannot turn ON any coverage becasue the corresponding coverage model was not generated.", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00688:       return this.cover_on;
00689:    end
00690: 
00691:    if (is_on & vmm_ral::REG_BITS) begin
00692:       if (this.has_cover & vmm_ral::REG_BITS) begin
00693:           this.cover_on |= vmm_ral::REG_BITS;
00694:       end else begin
00695:           
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" - Cannot turn ON Register Bit coverage becasue the corresponding coverage model was not generated.", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00696:       end
00697:    end
00698: 
00699:    if (is_on & vmm_ral::FIELD_VALS) begin
00700:       if (this.has_cover & vmm_ral::FIELD_VALS) begin
00701:           this.cover_on |= vmm_ral::FIELD_VALS;
00702:       end else begin
00703:           
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" - Cannot turn ON Field Value coverage becasue the corresponding coverage model was not generated.", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00704:       end
00705:    end
00706: 
00707:    if (is_on & vmm_ral::ADDR_MAP) begin
00708:       if (this.has_cover & vmm_ral::ADDR_MAP) begin
00709:           this.cover_on |= vmm_ral::ADDR_MAP;
00710:       end else begin
00711:           
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" - Cannot turn ON Address Map coverage becasue the corresponding coverage model was not generated.", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00712:       end
00713:    end
00714: 
00715:    set_cover = this.cover_on;
00716: endfunction: set_cover
00717: 
00718: 
00719: function bit vmm_ral_reg::is_cover_on(int is_on);
00720:    if (this.can_cover(is_on) == 0) return 0;
00721:    return ((this.cover_on & is_on) == is_on);
00722: endfunction: is_cover_on
00723: 
00724: 
00725: function void vmm_ral_reg::XforceX(bit [64-1:0] value,
00726:                                    vmm_ral::path_e               path,
00727:                                    string                        domain);
00728:    // Fields are stored in LSB or MSB order
00729:    foreach (this.fields[i]) begin
00730:       this.fields[i].XforceX(value >> this.fields[i].get_lsb_pos_in_register(),
00731:                              path, domain);
00732:    end
00733: endfunction: XforceX
00734: 
00735: 
00736: function void vmm_ral_reg::XwroteX(bit [64-1:0] value,
00737:                                    vmm_ral::path_e               path,
00738:                                    string                        domain);
00739:    int j, w;
00740: 
00741:    // Fields are stored in LSB or MSB order
00742:    foreach (this.fields[i]) begin
00743:       j = this.fields[i].get_lsb_pos_in_register();
00744:       w = this.fields[i].get_n_bits();
00745:       this.fields[i].XwroteX((value >> j) & ((1 << w) - 1), path, domain);
00746:    end
00747: endfunction: XwroteX
00748: 
00749: 
00750: function void vmm_ral_reg::set(bit [64-1:0] value);
00751:    // Split the value into the individual fields
00752:    int j, w;
00753: 
00754:    // Fields are stored in LSB or MSB order
00755:    foreach (this.fields[i]) begin
00756:       j = this.fields[i].get_lsb_pos_in_register();
00757:       w = this.fields[i].get_n_bits();
00758:       this.fields[i].set((value >> j) & ((1 << w) - 1));
00759:    end
00760: endfunction: set
00761: 
00762: 
00763: function bit vmm_ral_reg::predict(bit [64-1:0] value);
00764:    if (this.Xis_busyX) begin
00765:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Trying to predict value of register \"%s\" while it is being accessed",
     :                                        this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00767:       return 0;
00768:    end
00769:    
00770:    predict = 1;
00771:    
00772:    // Fields are stored in LSB or MSB order
00773:    foreach (this.fields[i]) begin
00774:       predict &= this.fields[i].predict(value >> this.fields[i].get_lsb_pos_in_register());
00775:    end
00776: endfunction: predict
00777: 
00778: 
00779: function bit[64-1:0] vmm_ral_reg::get();
00780:    // Concatenate the value of the individual fields
00781:    // to form the register value
00782:    int j, w;
00783: 
00784:    get = 0;
00785:    
00786:    // Fields are stored in LSB or MSB order
00787:    foreach (this.fields[i]) begin
00788:       j = this.fields[i].get_lsb_pos_in_register();
00789:       get |= this.fields[i].get() << j;
00790:    end
00791: endfunction: get
00792: 
00793: 
00794: function logic [64-1:0]
00795:    vmm_ral_reg::get_reset(vmm_ral::reset_e kind = vmm_ral::HARD);
00796:    // Concatenate the value of the individual fields
00797:    // to form the register value
00798:    int j, w;
00799: 
00800:    get_reset = 0;
00801:    
00802:    // Fields are stored in LSB or MSB order
00803:    foreach (this.fields[i]) begin
00804:       j = this.fields[i].get_lsb_pos_in_register();
00805:       get_reset |= this.fields[i].get_reset(kind) << j;
00806:    end
00807: endfunction: get_reset
00808: 
00809: 
00810: function void vmm_ral_reg::reset(vmm_ral::reset_e kind = vmm_ral::HARD);
00811:    foreach (this.fields[i]) begin
00812:       this.fields[i].reset(kind);
00813:    end
00814:    // Put back a key in the semaphore if it is checked out
00815:    // in case a thread was killed during an operation
00816:    void'(this.atomic.try_get(1));
00817:    this.atomic.put(1);
00818: endfunction: reset
00819: 
00820: 
00821: function bit vmm_ral_reg::needs_update();
00822:    needs_update = 0;
00823:    foreach (this.fields[i]) begin
00824:       if (this.fields[i].needs_update()) begin
00825:          return 1;
00826:       end
00827:    end
00828: endfunction: needs_update
00829: 
00830: 
00831: task vmm_ral_reg::update(output vmm_rw::status_e status,
00832:                          input  vmm_ral::path_e  path = vmm_ral::DEFAULT,
00833:                          input  string           domain = "");
00834:    bit [64-1:0] upd;
00835:    int j;
00836: 
00837:    if (this.parent.Xis_powered_downX) begin
00838:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register %s cannot be accessed when its parent block is powered down", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00839:       return;
00840:    end
00841: 
00842:    status = vmm_rw::IS_OK;
00843:    if (!this.needs_update()) return;
00844: 
00845:    this.XatomicX(1);
00846: 
00847:    // Concatenate the write-to-update values from each field
00848:    // Fields are stored in LSB or MSB order
00849:    upd = 0;
00850:    foreach (this.fields[i]) begin
00851:       j = this.fields[i].get_lsb_pos_in_register();
00852:       upd |= this.fields[i].XupdX() << j;
00853:    end
00854: 
00855:    this.XwriteX(status, upd, path, domain, -1, -1, -1);
00856: 
00857:    this.XatomicX(0);
00858: endtask: update
00859: 
00860: 
00861: task vmm_ral_reg::write(output vmm_rw::status_e             status,
00862:                         input  bit[64-1:0] value,
00863:                         input  vmm_ral::path_e              path = vmm_ral::DEFAULT,
00864:                         input  string                       domain = "",
00865:                         input  int                          data_id = -1,
00866:                         input  int                          scenario_id = -1,
00867:                         input  int                          stream_id = -1);
00868:    if (this.parent.Xis_powered_downX) begin
00869:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register %s cannot be accessed when its parent block is powered down", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00870:       return;
00871:    end
00872: 
00873:    this.XatomicX(1);
00874:    this.XwriteX(status, value, path, domain, data_id, scenario_id, stream_id);
00875:    this.XatomicX(0);
00876: endtask: write
00877: 
00878: 
00879: task vmm_ral_reg::XwriteX(output vmm_rw::status_e             status,
00880:                           input  bit[64-1:0] value,
00881:                           input  vmm_ral::path_e              path,
00882:                           input  string                       domain,
00883:                           input  int                          data_id,
00884:                           input  int                          scenario_id,
00885:                           input  int                          stream_id);
00886:    status = vmm_rw::ERROR;
00887:    
00888:    if (this.ral_access == null) begin
00889:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" not associated with RAL access object", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00890:       return;
00891:    end
00892:    
00893:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00894: 
00895:    begin
00896:       bit [64-1:0] tmp;
00897:       bit [64-1:0] msk;
00898:       int lsb;
00899: 
00900:       foreach (fields[i]) begin
00901:          vmm_ral_field f = fields[i];
00902: 
00903:          lsb = f.get_lsb_pos_in_register();
00904: 
00905:          msk = ((1<<f.get_n_bits())-1) << lsb;
00906:          tmp = (value & msk) >> lsb;
00907: 
00908:          foreach (f.XcbsX[j]) begin
00909:             vmm_ral_field_callbacks cb;
00910:             if (!$cast(cb, f.XcbsX[j])) continue;
00911:             cb.pre_write(f, tmp, path, domain);
00912:          end
00913: 
00914:          value = (value & ~msk) | (tmp << lsb);
00915:       end
00916:    end
00917:    
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_reg_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.pre_write(this, value, path, domain); 
     : end while (0);
00919: 
00920:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00921: 
00922:    if (path == vmm_ral::BACKDOOR &&
00923:        this.backdoor == null) begin
00924:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("No backdoor access available for register \"%s\". Using frontdoor instead.", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00925:       path = vmm_ral::BFM;
00926:    end
00927: 
00928:    case (path)
00929:       
00930:       vmm_ral::BFM: begin
00931:          int di = this.get_domain_index(domain);
00932:          if (di < 0) return;
00933:          
00934:          this.Xis_busyX = 1;
00935: 
00936:          if (this.frontdoor[di] != null) begin
00937:             this.frontdoor[di].write(status, value,
00938:                                      data_id, scenario_id, stream_id);
00939:          end
00940:          else begin
00941:             bit [64-1:0] addr[];
00942:             int w, j;
00943:             int n_bits;
00944: 
00945:             if (this.offset_in_block[di] === 'x) begin
00946:                
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" unmapped in domain \"%s\" does not have a user-defined frontdoor",
     :                                               this.get_name(),
     :                                               this.domains[di]))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00949:                return;
00950:             end
00951: 
00952:             w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00953:                                                          0, this.get_n_bytes(),
00954:                                                          this.parent,
00955:                                                          this.domains[di],
00956:                                                          addr);
00957:             j = 0;
00958:             n_bits = this.get_n_bytes() * 8;
00959:             foreach (addr[i]) begin
00960:                bit [64-1:0] data;
00961:                data = value >> (j*8);
00962:                this.ral_access.write(status, addr[i], data,
00963:                                      (n_bits > w*8) ? w*8 : n_bits,
00964:                                      this.parent.get_external_domain(this.domains[di]),
00965:                                      data_id, scenario_id, stream_id);
00966:                if (status != vmm_rw::IS_OK) return;
00967:                j += w;
00968:                n_bits -= w * 8;
00969:             end
00970:          end
00971: 
00972:          if (this.cover_on) begin
00973:             this.sample(value, 0, di);
00974:             this.parent.XsampleX(this.offset_in_block[di], di);
00975:          end
00976: 
00977:          this.Xis_busyX = 0;
00978: 
00979:          this.XwroteX(value, path, domain);
00980:       end
00981:       
00982:       vmm_ral::BACKDOOR: begin
00983:          bit [64-1:0] reg_val;
00984:          bit [64-1:0] final_val;
00985: 
00986:          // Mimick the final value after a physical read
00987:          this.backdoor.read(status, reg_val,
00988:                             data_id, scenario_id, stream_id);
00989:          if (status != vmm_rw::IS_OK) return;
00990: 
00991:          begin
00992:             int j, w;
00993: 
00994:             // Fields are stored in LSB or MSB order
00995:             final_val = '0;
00996:             foreach (this.fields[i]) begin
00997:                bit [64-1:0] field_val;
00998:                j = this.fields[i].get_lsb_pos_in_register();
00999:                w = this.fields[i].get_n_bits();
01000:                field_val = this.fields[i].XpredictX((reg_val >> j) & ((1 << w) - 1),
01001:                                                     (value >> j) & ((1 << w) - 1),
01002:                                                     domain);
01003:                final_val |= field_val << j;
01004:             end
01005:          end
01006:          this.backdoor.write(status, final_val, data_id, scenario_id, stream_id);
01007:          this.XwroteX(final_val, path, "-");
01008:       end
01009:    endcase
01010: 
01011:    begin
01012:       bit [64-1:0] tmp;
01013:       bit [64-1:0] msk;
01014:       int lsb;
01015: 
01016:       value = this.get();
01017: 
01018:       foreach (fields[i]) begin
01019:          vmm_ral_field f = fields[i];
01020: 
01021:          lsb = f.get_lsb_pos_in_register();
01022: 
01023:          msk = ((1<<f.get_n_bits())-1) << lsb;
01024:          tmp = (value & msk) >> lsb;
01025: 
01026:          foreach (f.XcbsX[j]) begin
01027:             vmm_ral_field_callbacks cb;
01028:             if (!$cast(cb, f.XcbsX[j])) continue;
01029:             cb.post_write(f, tmp, path, domain, status);
01030:          end
01031:       end
01032:    end
01033: 
01034:    
     : 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 register \"%s\" via %s with: 'h%h",
     :                                   this.get_fullname(),
     :                                   (path == vmm_ral::BFM) ? "frontdoor" : "backdoor",
     :                                   value))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01038: 
01039:    
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_reg_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.post_write(this, value, path, domain, status); 
     : end while (0);
01041: endtask: XwriteX
01042: 
01043: 
01044: task vmm_ral_reg::read(output vmm_rw::status_e             status,
01045:                        output bit[64-1:0] value,
01046:                        input  vmm_ral::path_e              path = vmm_ral::DEFAULT,
01047:                        input  string                       domain = "",
01048:                        input  int                          data_id = -1,
01049:                        input  int                          scenario_id = -1,
01050:                        input  int                          stream_id = -1);
01051:    if (this.parent.Xis_powered_downX) begin
01052:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register %s cannot be accessed when its parent block is powered down", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01053:       return;
01054:    end
01055: 
01056:    this.XatomicX(1);
01057:    this.XreadX(status, value, path, domain, data_id, scenario_id, stream_id);
01058:    this.XatomicX(0);
01059: endtask: read
01060: 
01061: 
01062: task vmm_ral_reg::XreadX(output vmm_rw::status_e             status,
01063:                          output bit[64-1:0] value,
01064:                          input  vmm_ral::path_e              path,
01065:                          input  string                       domain,
01066:                          input  int                          data_id,
01067:                          input  int                          scenario_id,
01068:                          input  int                          stream_id);
01069:    status = vmm_rw::ERROR;
01070:    
01071:    if (this.ral_access == null) begin
01072:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" not associated with RAL access object", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01073:       return;
01074:    end
01075:    
01076:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
01077: 
01078:    foreach (fields[i]) begin
01079:       vmm_ral_field f = fields[i];
01080: 
01081:       foreach (f.XcbsX[j]) begin
01082:          vmm_ral_field_callbacks cb;
01083:          if (!$cast(cb, f.XcbsX[j])) continue;
01084:          cb.pre_read(f, path, domain);
01085:       end
01086:    end
01087:    
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_reg_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.pre_read(this, path, domain); 
     : end while (0);
01089: 
01090:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
01091: 
01092:    if (path == vmm_ral::BACKDOOR &&
01093:        this.backdoor == null) begin
01094:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("No backdoor access available for register \"%s\". Using frontdoor instead.", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
01095:       path = vmm_ral::BFM;
01096:    end
01097: 
01098:    case (path)
01099:       
01100:       vmm_ral::BFM: begin
01101:          int di = this.get_domain_index(domain);
01102:          if (di < 0) return;
01103:          
01104:          this.Xis_busyX = 1;
01105: 
01106:          if (this.frontdoor[di] != null) begin
01107:             this.frontdoor[di].read(status, value,
01108:                                    data_id, scenario_id, stream_id);
01109:          end
01110:          else begin
01111:             bit [64-1:0] addr[];
01112:             int w, j;
01113:             int n_bits;
01114:          
01115:             if (this.offset_in_block[di] === 'x) begin
01116:                
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" unmapped in domain \"%s\" does not have a user-defined frontdoor",
     :                                               this.get_name(),
     :                                               this.domains[di]))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01119:                return;
01120:             end
01121:          
01122:             w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
01123:                                                          0, this.get_n_bytes(),
01124:                                                          this.parent,
01125:                                                          this.domains[di],
01126:                                                          addr);
01127:             j = 0;
01128:             n_bits = this.get_n_bytes() * 8;
01129:             value = 0;
01130:             foreach (addr[i]) begin
01131:                bit [64-1:0] data;
01132:                this.ral_access.read(status, addr[i], data,
01133:                                     (n_bits > w*8) ? w*8 : n_bits,
01134:                                     this.parent.get_external_domain(this.domains[di]),
01135:                                     data_id, scenario_id, stream_id);
01136:                if (status != vmm_rw::IS_OK) return;
01137:                value |= (data & ((1 << (w*8)) - 1)) << (j*8);
01138:                j += w;
01139:                n_bits -= w * 8;
01140:             end
01141:          end
01142: 
01143:          if (this.cover_on) begin
01144:             this.sample(value, 1, di);
01145:             this.parent.XsampleX(this.offset_in_block[di], di);
01146:          end
01147: 
01148:          this.Xis_busyX = 0;
01149: 
01150:          this.XforceX(value, path, domain);
01151:       end
01152:       
01153:       vmm_ral::BACKDOOR: begin
01154:          bit [64-1:0] final_val;
01155: 
01156:          this.backdoor.read(status, value, data_id, scenario_id, stream_id);
01157:          final_val = value;
01158: 
01159:          // Need to clear RC fields and mask WO fields
01160:          if (status == vmm_rw::IS_OK) begin
01161:             bit [64-1:0] wo_mask = 0;
01162: 
01163:             foreach (this.fields[i]) begin
01164:                vmm_ral::access_e acc = this.fields[i].get_access("BaCkDoOr");
01165:                if (acc == vmm_ral::RC) begin
01166:                   final_val &= ~(((1<<this.fields[i].get_n_bits())-1) << this.fields[i].get_lsb_pos_in_register());
01167:                end
01168:                else if (acc == vmm_ral::WO) begin
01169:                   wo_mask |= ((1<<this.fields[i].get_n_bits())-1) << this.fields[i].get_lsb_pos_in_register();
01170:                end
01171:             end
01172: 
01173:             if (final_val != value) begin
01174:                this.backdoor.write(status, final_val,
01175:                                    data_id, scenario_id, stream_id);
01176:             end
01177: 
01178:             value &= ~wo_mask;
01179:             this.XforceX(final_val, path, "-");
01180:          end
01181:       end
01182:    endcase
01183: 
01184: 
01185:    begin
01186:       bit [64-1:0] tmp;
01187:       bit [64-1:0] msk;
01188:       int lsb;
01189: 
01190:       foreach (fields[i]) begin
01191:          vmm_ral_field f = fields[i];
01192: 
01193:          lsb = f.get_lsb_pos_in_register();
01194: 
01195:          msk = ((1<<f.get_n_bits())-1) << lsb;
01196:          tmp = (value & msk) >> lsb;
01197: 
01198:          foreach (f.XcbsX[j]) begin
01199:             vmm_ral_field_callbacks cb;
01200:             if (!$cast(cb, f.XcbsX[j])) continue;
01201:             cb.post_read(f, tmp, path, domain, status);
01202:          end
01203: 
01204:          value = (value & ~msk) | (tmp << lsb);
01205:       end
01206:    end
01207: 
01208:    
     : 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 register \"%s\" via %s: 'h%h",
     :                                   this.get_fullname(),
     :                                   (path == vmm_ral::BFM) ? "frontdoor" : "backdoor",
     :                                   value))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01212: 
01213:    
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_reg_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.post_read(this, value, path, domain, status); 
     : end while (0);
01215: endtask: XreadX
01216: 
01217: 
01218: task vmm_ral_reg::poke(output vmm_rw::status_e             status,
01219:                        input  bit[64-1:0] value,
01220:                        input  int                          data_id = -1,
01221:                        input  int                          scenario_id = -1,
01222:                        input  int                          stream_id = -1);
01223:    if (this.parent.Xis_powered_downX) begin
01224:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register %s cannot be accessed when its parent block is powered down", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01225:       return;
01226:    end
01227: 
01228:    if(!this.Xis_locked_by_fieldX)
01229:      this.XatomicX(1);
01230: 
01231:    if (this.backdoor == null) begin
01232:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("No backdoor access available to poke register \"%s\"", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01233:       status = vmm_rw::ERROR;
01234:       if(!this.Xis_locked_by_fieldX)
01235:         this.XatomicX(0);
01236:       return;
01237:    end
01238: 
01239:    this.backdoor.write(status, value, data_id, scenario_id, stream_id);
01240: 
01241:    
     : 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 register \"%s\" with: 'h%h",
     :                                   this.get_fullname(), value))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01243: 
01244:    this.XforceX(value, vmm_ral::BACKDOOR, "-");
01245:    if(!this.Xis_locked_by_fieldX)
01246:      this.XatomicX(0);
01247: endtask: poke
01248: 
01249: 
01250: task vmm_ral_reg::peek(output vmm_rw::status_e             status,
01251:                        output bit[64-1:0] value,
01252:                        input  int                          data_id = -1,
01253:                        input  int                          scenario_id = -1,
01254:                        input  int                          stream_id = -1);
01255:    if (this.parent.Xis_powered_downX) begin
01256:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register %s cannot be accessed when its parent block is powered down", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01257:       return;
01258:    end
01259: 
01260:    if(!this.Xis_locked_by_fieldX)
01261:      this.XatomicX(1);
01262:    if (this.backdoor == null) begin
01263:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("No backdoor access available peek register \"%s\"", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01264:       status = vmm_rw::ERROR;
01265:       if(!this.Xis_locked_by_fieldX)
01266:         this.XatomicX(0);
01267:       return;
01268:    end
01269:    this.backdoor.read(status, value, data_id, scenario_id, stream_id);
01270: 
01271:    
     : 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 register \"%s\": 'h%h",
     :                                   this.get_fullname(), value))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01273: 
01274:    this.XforceX(value, vmm_ral::BACKDOOR, "-");
01275: 
01276:    if(!this.Xis_locked_by_fieldX)
01277:      this.XatomicX(0);
01278: endtask: peek
01279: 
01280: 
01281: task vmm_ral_reg::mirror(output vmm_rw::status_e  status,
01282:                          input  vmm_ral::check_e  check = vmm_ral::QUIET,
01283:                          input  vmm_ral::path_e   path = vmm_ral::DEFAULT,
01284:                          input  string            domain = "");
01285:    bit [64-1:0] v;
01286:    bit [64-1:0] exp;
01287: 
01288:    if (this.parent.Xis_powered_downX) begin
01289:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register %s cannot be accessed when its parent block is powered down", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01290:       return;
01291:    end
01292: 
01293:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
01294: 
01295:    this.XatomicX(1);
01296: 
01297:    if (path == vmm_ral::BACKDOOR && this.backdoor != null) begin
01298:       domain = "BaCkDoOr";
01299:    end
01300: 
01301:    // Remember what we think the value is before it gets updated
01302:    if (check == vmm_ral::VERB) begin
01303:       exp = this.get();
01304:       // Any WO field will readback as 0's
01305:       foreach(this.fields[i]) begin
01306:          if (this.fields[i].get_access(domain) == vmm_ral::WO) begin
01307:             exp &= ~(((1 << this.fields[i].get_n_bits())-1)
01308:                      << this.fields[i].get_lsb_pos_in_register());
01309:          end
01310:       end
01311:    end
01312: 
01313:    this.XreadX(status, v, path, domain, -1, -1, -1);
01314: 
01315:    if (status != vmm_rw::IS_OK) begin
01316:       this.XatomicX(0);
01317:       return;
01318:    end
01319: 
01320:    if (check == vmm_ral::VERB) begin
01321:       // Check that our idea of the register value matches
01322:       // what we just read from the DUT, minus the don't care fields
01323:       bit [64-1:0] dc = 0;
01324: 
01325:       foreach(this.fields[i]) begin
01326:          vmm_ral::access_e acc = this.fields[i].get_access(domain);
01327:          if (acc == vmm_ral::DC) begin
01328:             dc |= ((1 << this.fields[i].get_n_bits())-1)
01329:                   << this.fields[i].get_lsb_pos_in_register();
01330:          end
01331:          else if (acc == vmm_ral::WO) begin
01332:             // WO fields will always read-back as 0
01333:             exp &= ~(((1 << this.fields[i].get_n_bits())-1)
01334:                      << this.fields[i].get_lsb_pos_in_register());
01335:          end
01336:       end
01337: 
01338:       if ((v|dc) !== (exp|dc)) begin
01339:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Register \"%s\" value read from DUT 0x%h does not match mirrored value 0x%h",
     :                                         this.get_name(), v, (exp ^ ('x & dc))))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01341:       end
01342:    end
01343: 
01344:    this.XatomicX(0);
01345: endtask: mirror
01346: 
01347: 
01348: function void vmm_ral_reg::set_frontdoor(vmm_ral_reg_frontdoor ftdr,
01349:                                          string                domain = "");
01350:    foreach(this.domains[i]) begin
01351:       if (this.domains[i] == domain) begin
01352:          this.frontdoor[i] = ftdr;
01353:          return;
01354:       end
01355:    end
01356:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Domain \"%s\" not found in register %s", domain, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01357: endfunction: set_frontdoor
01358: 
01359: 
01360: function vmm_ral_reg_frontdoor vmm_ral_reg::get_frontdoor(string domain = "");
01361:    foreach(this.domains[i]) begin
01362:       if (this.domains[i] == domain) begin
01363:          return this.frontdoor[i];
01364:       end
01365:    end
01366:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Domain \"%s\" not found in register %s", domain, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01367: endfunction: get_frontdoor
01368: 
01369: 
01370: function void vmm_ral_reg::set_backdoor(vmm_ral_reg_backdoor bkdr);
01371:    this.backdoor = bkdr;
01372: endfunction: set_backdoor
01373: 
01374: 
01375: function vmm_ral_reg_backdoor vmm_ral_reg::get_backdoor();
01376:    get_backdoor = this.backdoor;
01377: endfunction: get_backdoor
01378: 
01379: 
01380: function void vmm_ral_reg::prepend_callback(vmm_ral_reg_callbacks cb);
01381:    foreach (this.callbacks[i]) begin
01382:       if (this.callbacks[i] == cb) begin
01383:          
     : 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 register \"%s\"", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
01384:          return;
01385:       end
01386:    end
01387:    
01388:    // Prepend new callback
01389:    this.callbacks.push_front(cb);
01390: endfunction: prepend_callback
01391: 
01392: 
01393: function void vmm_ral_reg::append_callback(vmm_ral_reg_callbacks cb);
01394:    foreach (this.callbacks[i]) begin
01395:       if (this.callbacks[i] == cb) begin
01396:          
     : 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 register \"%s\"", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
01397:          return;
01398:       end
01399:    end
01400:    
01401:    // Append new callback
01402:    this.callbacks.push_back(cb);
01403: endfunction: append_callback
01404: 
01405: 
01406: function void vmm_ral_reg::unregister_callback(vmm_ral_reg_callbacks cb);
01407:    foreach (this.callbacks[i]) begin
01408:       if (this.callbacks[i] == cb) begin
01409:          int j = i;
01410:          // Unregister it
01411:          this.callbacks.delete(j);
01412:          return;
01413:       end
01414:    end
01415: 
01416:    
     : 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 register \"%s\"", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
01417: endfunction: unregister_callback
01418: 
01419: 
01420: function int vmm_ral_reg::get_domain_index(string domain);
01421:    // If the domain is "" and there is only one domain,
01422:    // assume it is the one domain available to avoid
01423:    // having to always have to specify domains
01424:    if (domain == "" && this.domains.size() == 1) return 0;
01425: 
01426:    foreach (this.domains[i]) begin
01427:       if (this.domains[i] == domain) return i;
01428:    end
01429:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Unknown domain name \"%s\" in register \"%s\".", domain, this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
01430:    return -1;
01431: endfunction: get_domain_index
01432: 
01433: 
01434: task vmm_ral_reg_frontdoor::write(output vmm_rw::status_e              status,
01435:                                   input  bit [64-1:0] data,
01436:                                   input  int                           data_id,
01437:                                   input  int                           scenario_id,
01438:                                   input  int                           stream_id);
01439:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin 
     :       void'(this.log.text("vmm_ral_reg_frontdoor::write method has not been overloaded")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01440: endtask: write
01441: 
01442: 
01443: task vmm_ral_reg_frontdoor::read(output vmm_rw::status_e              status,
01444:                                  output bit [64-1:0] data,
01445:                                  input  int                           data_id,
01446:                                  input  int                           scenario_id,
01447:                                  input  int                           stream_id);
01448:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin 
     :       void'(this.log.text("vmm_ral_reg_frontdoor::read method has not been overloaded")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
01449: endtask: read
01450: 
01451: 
01452: function void vmm_ral_reg::sample(bit [64-1:0] data,
01453:                                   bit                           is_read,
01454:                                   int                           domain);
01455:    // Nothing to do in this base class
01456: endfunction
01457: 
01458: 
01459: function int unsigned vmm_ral_reg::get_reg_ID();
01460:    get_reg_ID =  this.reg_id;
01461: endfunction
01462: 
01463: function vmm_ral_reg vmm_ral_get_reg_by_ID(int unsigned id);
01464:    vmm_ral_reg rg;
01465:    if (rg.all_regs.exists(id)) 
01466:       vmm_ral_get_reg_by_ID = rg.all_regs[id];
01467:    else vmm_ral_get_reg_by_ID = null;
01468: endfunction
01469: