VMM - (expanded) RAL/vmm_ral_mem.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.

RAL/vmm_ral_mem.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: function vmm_ral_mem::new(vmm_ral_block                 parent,
00024:                           string                        name,
00025:                           vmm_ral::access_e             access,
00026:                           longint unsigned              size,
00027:                           int unsigned                  n_bits,
00028:                           bit [64-1:0] base_addr,
00029:                           string                        domain,
00030:                           bit                           cover_on,
00031:                           bit [1:0]                     rights,
00032:                           bit                           unmapped);
00033: 
00034:    this.name = name;
00035:    this.locked = 0;
00036: 
00037:    if (n_bits == 0) begin
00038:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory \"%s\" cannot have 0 bits", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00039:       n_bits = 1;
00040:    end
00041:    if (n_bits > 64) begin
00042:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory \"%s\" cannot have more than %0d bits (%0d)", this.get_fullname(), 64, n_bits))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00043:       n_bits = 64;
00044:    end
00045:    if (access != vmm_ral::RW && access != vmm_ral::RO) begin
00047: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory %s can only be RW or RO",
     :                                      this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00048:       access = vmm_ral::RW;
00049:    end
00050: 
00051:    this.parent   = parent;
00052:    this.size     = size;
00053:    this.access   = access;
00054:    this.n_bits   = n_bits;
00055:    this.backdoor  = null;
00056: 
00057:    this.parent.register_mem(this);
00058:    this.add_domain(base_addr, domain, rights, unmapped);
00059: 
00060:    this.cover_on = cover_on;
00061:    this.no_cover = !cover_on;
00062: 
00063:    begin
00064:       vmm_mam_cfg cfg = new;
00065: 
00066:       cfg.n_bytes      = ((n_bits-1) / 8) + 1;
00067:       cfg.start_offset = 0;
00068:       cfg.end_offset   = size-1;
00069: 
00070:       cfg.mode     = vmm_mam::GREEDY;
00071:       cfg.locality = vmm_mam::BROAD;
00072: 
00073:       this.mam = new(this.get_fullname(), cfg, this);
00074:    end
00075: 
00076:    // Initialize Memory ID
00077:    this.__vmm_mem_id = ++this.__vmm_mem_id_factory;
00078:    __vmm_all_mems[this.__vmm_mem_id] = this;
00079: endfunction: new
00080: 
00081: 
00082: function void vmm_ral_mem::Xlock_modelX();
00083:    this.locked = 1;
00084: endfunction: Xlock_modelX
00085: 
00086: 
00087: function void vmm_ral_mem::add_domain(bit [64-1:0] base_addr,
00088:                                       string                        domain,
00089:                                       bit [1:0]                     rights,
00090:                                       bit                           unmapped);
00091:    vmm_ral::access_e acc;
00092: 
00093:    // Verify that this is a valid domain in the block
00094:    string domains[];
00095: 
00096:    if (this.locked) begin
00097:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Cannot add domain to locked memory %s", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00098:       return;
00099:    end
00100: 
00101:    case (rights)
00102:      2'b11: acc = vmm_ral::RW;
00103:      2'b10: acc = vmm_ral::RO;
00104:      2'b01: acc = vmm_ral::WO;
00105:      default:
00108: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory %s has no access rights in domain \"%s\"",
     :                             this.get_fullname(), domain))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00109:    endcase
00110: 
00111:    this.parent.get_domains(domains);
00112:    foreach(domains[i]) begin
00113:       if (domains[i] == domain) begin
00114:          automatic int n = this.offset_in_block.size();
00115:    
00116:          this.offset_in_block = new [n + 1] (this.offset_in_block);
00117:          this.offset_in_block[n] = (unmapped) ? 'X : base_addr;
00118:     
00119:          this.domains = new [n + 1] (this.domains);
00120:          this.domains[n] = domain;
00121: 
00122:          this.rights = new [n + 1] (this.rights);
00123:          this.rights[n] = acc;
00124: 
00125:          this.frontdoor = new [n + 1] (this.frontdoor);
00126:          this.frontdoor[n] = null;
00127:          return;
00128:       end
00129:    end
00131: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Domain \"%s\" not found in parent block %s of memory %s",
     :                                   domain, this.parent.get_name(), this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00132: endfunction: add_domain
00133: 
00134: 
00135: function void vmm_ral_mem::Xregister_ral_accessX(vmm_ral_access access);
00136:    // There can only be one RAL Access on a RAL model
00137:    if (this.ral_access != null && this.ral_access != access) begin
00138:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory %s is already used by another RAL access instance", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00139:    end
00140:    this.ral_access = access;
00141: endfunction: Xregister_ral_accessX
00142: 
00143: 
00144: function string vmm_ral_mem::get_name();
00145:    get_name = this.name;
00146: endfunction: get_name
00147: 
00148: 
00149: function string vmm_ral_mem::get_fullname();
00150:    vmm_ral_block blk;
00151: 
00152:    get_fullname = this.get_name();
00153: 
00154:    // Do not include top-level name in full name
00155:    blk = this.get_block();
00156:    if (blk == null) return get_fullname;
00157:    if (blk.get_parent() == null) return get_fullname;
00158: 
00159:    get_fullname = {this.parent.get_fullname(), ".", get_fullname};
00160: endfunction: get_fullname
00161: 
00162: 
00163: function int vmm_ral_mem::get_n_domains();
00164:    get_n_domains = this.domains.size();
00165: endfunction: get_n_domains
00166: 
00167: 
00168: function void vmm_ral_mem::get_domains(ref string domains[]);
00169:    domains = new [this.domains.size()] (this.domains);
00170: endfunction: get_domains
00171: 
00172: 
00173: function vmm_ral::access_e vmm_ral_mem::get_access(string domain);
00174:    get_access = this.access;
00175:    if (this.get_n_domains() == 1) return get_access;
00176: 
00177:    // Is the memory restricted in this domain?
00178:    case (this.get_rights(domain))
00179:      vmm_ral::RW:
00180:        // No restrictions
00181:        return get_access;
00182: 
00183:      vmm_ral::RO:
00184:        case (get_access)
00185:          vmm_ral::RW,
00186:          vmm_ral::RO: get_access = vmm_ral::RO;
00187: 
00188:          vmm_ral::WO: begin
00191: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("WO memory %s restricted to RO in domain \"%s\"",
     :                                  this.get_fullname(), domain))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00192:          end
00193: 
00194:          default:
00197: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Invalid memory %s access mode \"%s\"",
     :                                 this.get_fullname(), get_access.name()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00198:        endcase
00199: 
00200:      vmm_ral::WO:
00201:        case (get_access)
00202:          vmm_ral::RW,
00203:          vmm_ral::WO: get_access = vmm_ral::WO;
00204: 
00205:          vmm_ral::RO: begin
00208: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("RO memory %s restricted to WO in domain \"%s\"",
     :                                  this.get_fullname(), get_access.name(), domain))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00209:          end
00210: 
00211:          default:
00214: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Invalid memory %s access mode \"%s\"",
     :                                 this.get_fullname(), get_access.name()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00215:        endcase
00216: 
00217:      default:
00220: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Shared memory \"%s\" is not shared in domain \"%s\"",
     :                             this.get_fullname(), domain))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00221:    endcase
00222: endfunction: get_access
00223: 
00224: 
00225: function vmm_ral::access_e vmm_ral_mem::get_rights(string domain);
00226:    int i;
00227: 
00228:    // No right restrictions if not shared
00229:    if (this.domains.size() == 1) begin
00230:       return vmm_ral::RW;
00231:    end
00232: 
00233:    i = this.get_domain_index(domain);
00234:    if (i < 0) return vmm_ral::RW;
00235: 
00236:    get_rights = this.rights[i];
00237: endfunction: get_rights
00238: 
00239: 
00240: function void vmm_ral_mem::get_virtual_fields(ref vmm_ral_vfield fields[]);
00241:   vmm_ral_vfield vfields[];
00242: 
00243:   fields = new[0];
00244:   foreach (this.XvregsX[i]) begin
00245:     int n = fields.size();
00246:     this.XvregsX[i].get_fields(vfields);
00247:     fields = new[n + vfields.size()] (fields);
00248:     foreach(vfields[j]) begin
00249:       fields[n+j] = vfields[j];
00250:     end
00251:   end
00252: endfunction: get_virtual_fields
00253: 
00254: 
00255: // Return first occurrence of vfield matching name
00256: function vmm_ral_vfield vmm_ral_mem::get_virtual_field_by_name(string name);
00257:   vmm_ral_vfield vfields[];
00258: 
00259:   this.get_virtual_fields(vfields);
00260:   foreach (vfields[i]) begin
00261:     if (vfields[i].get_name() == name) return vfields[i];
00262:   end
00265: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Unable to find virtual field \"%s\" in memory %s.",
     :                          name, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00266:    return null;
00267: endfunction: get_virtual_field_by_name
00268: 
00269: 
00270: function void vmm_ral_mem::get_virtual_registers(ref vmm_ral_vreg regs[]);
00271:   regs = new[this.XvregsX.size()];
00272:   foreach (this.XvregsX[i]) begin
00273:      regs[i] = this.XvregsX[i];
00274:   end
00275: endfunction: get_virtual_registers
00276: 
00277: 
00278: function vmm_ral_vreg vmm_ral_mem::get_vreg_by_name(string name);
00279:   foreach (this.XvregsX[i]) begin
00280:     if (this.XvregsX[i].get_name() == name) return this.XvregsX[i];
00281:   end
00284: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Unable to find virtual register \"%s\" in memory %s.",
     :                          name, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00285: 
00286: endfunction: get_vreg_by_name
00287: 
00288: 
00289: function vmm_ral_vreg vmm_ral_mem::get_vreg_by_offset(bit [63:0] offset,
00290:                                                       string domain);
00291:    
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text("vmm_ral_mem::get_vreg_by_offset() not yet implemented")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00292:    return null;
00293: endfunction: get_vreg_by_offset
00294: 
00295: 
00296: function vmm_ral_block vmm_ral_mem::get_block();
00297:    get_block = this.parent;
00298: endfunction: get_block
00299: 
00300: 
00301: function bit [64-1:0] vmm_ral_mem::get_offset_in_block(bit [64-1:0] mem_addr,
00302:                                                                         string                        domain);
00303:    foreach (this.domains[i]) begin
00304:       if (this.domains[i] == domain) begin
00305:          if (this.offset_in_block[i] === 'x) begin
00306:             
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory \"%s\" is unmapped in domain \"%s\".", this.get_name(), domain))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00307:             return '0;
00308:          end
00309:          
00310:          return this.offset_in_block[i];
00311:       end
00312:    end
00314: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Unable to find offset within domain \"%s\" in memory %s.",
     :                                     domain, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00315:    get_offset_in_block = '1;
00316: endfunction: get_offset_in_block
00317: 
00318: 
00319: function bit [64-1:0] vmm_ral_mem::get_address_in_system(bit [64-1:0] mem_addr,
00320:                                                        string                                           domain);
00321:    bit [64-1:0] addr[];
00322:          
00323:    int i = this.get_domain_index(domain);
00324:    if (i < 0) return 0;
00325:          
00326:    if (this.ral_access == null) begin
00328: 
     : do 
     :    if (this.parent.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin 
     :       void'(this.parent.log.text("RAL model is not associated with an access transactor")); 
     :       this.parent.log.end_msg(); 
     :    end 
     : while (0);
00329:       return 0;
00330:    end
00331:          
00332:    if (this.offset_in_block[i] === 'x) begin
00333:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory \"%s\" is unmapped in domain \"%s\".", this.get_name(), this.domains[i]))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00334:       return '1;
00335:    end
00336:          
00337:    this.ral_access.Xget_physical_addressesX(this.offset_in_block[i],
00338:                                             mem_addr, this.get_n_bytes(),
00339:                                             this.parent,
00340:                                             this.domains[i],
00341:                                             addr);
00342: 
00343:    get_address_in_system = addr[0];
00344: endfunction: get_address_in_system
00345: 
00346: 
00347: function longint unsigned vmm_ral_mem::get_size();
00348:    get_size = this.size;
00349: endfunction: get_size
00350: 
00351: 
00352: function int unsigned vmm_ral_mem::get_n_bits();
00353:    get_n_bits = this.n_bits;
00354: endfunction: get_n_bits
00355: 
00356: 
00357: function int unsigned vmm_ral_mem::get_n_bytes();
00358:    get_n_bytes = (this.n_bits - 1) / 8 + 1;
00359: endfunction: get_n_bytes
00360: 
00361: 
00362: function void vmm_ral_mem::display(string prefix,
00363:                                    string domain);
00364:    $write("%s\n", this.psdisplay(prefix, domain));
00365: endfunction: display
00366: 
00367: 
00368: function string vmm_ral_mem::psdisplay(string prefix,
00369:                                        string domain);
00370:    $sformat(psdisplay, "%sMemory %s -- %0dx%0d bits @", prefix,
00371:             this.get_fullname(), this.get_size(), this.get_n_bits());
00372:    foreach (this.domains[i]) begin
00373:       if (this.domains[i] == domain) begin
00374:          if (this.offset_in_block[i] === 'x) begin
00375:             psdisplay = {psdisplay, "none"};
00376:          end
00377:          else begin
00378:             $sformat(psdisplay, "%s'h%h", psdisplay,
00379:                      this.get_address_in_system(0, domain));
00380:          end
00381:          break;
00382:       end
00383:    end
00384: endfunction: psdisplay
00385: 
00386: 
00387: function bit vmm_ral_mem::set_cover(bit is_on);
00388:    set_cover = this.cover_on;
00389: 
00390:    if (this.no_cover && is_on) begin
00391:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Cannot turn cover ON if constructed with coverage disabled in memory %s", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00392:       return 0;
00393:    end
00394: 
00395:    this.cover_on = is_on;
00396: endfunction: set_cover
00397: 
00398: 
00399: function bit vmm_ral_mem::is_cover_on();
00400:    is_cover_on = this.cover_on;
00401: endfunction: is_cover_on
00402: 
00403: 
00404: task vmm_ral_mem::init(output bit                           is_ok,
00405:                        input  init_e                        pattern,
00406:                        input  bit [64-1:0] data);
00407:    int incr;
00408:    is_ok = 0;
00409: 
00410:    if (this.backdoor == null) begin
00411:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("No backdoor available to initialize memory %s", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00412:       return;
00413:    end
00414: 
00415:    case (pattern)
00416:    UNKNOWNS:
00417:      begin
00418:         data = 'x;
00419:         incr = 0;
00420:      end
00421: 
00422:    ZEROES:
00423:      begin
00424:         data = '0;
00425:         incr = 0;
00426:      end
00427: 
00428:    ONES:
00429:      begin
00430:         data = '1;
00431:         incr = 0;
00432:      end
00433: 
00434:    VALUE:
00435:      begin
00436:         incr = 0;
00437:      end
00438: 
00439:    INCR:
00440:      begin
00441:         incr = 1;
00442:      end
00443: 
00444:    DECR:
00445:      begin
00446:         incr = -1;
00447:      end
00448:    endcase
00449: 
00450:    // ToDo...
00451: endtask:init
00452: 
00453: 
00454: task vmm_ral_mem::write(output vmm_rw::status_e              status,
00455:                         input  bit [64-1:0] mem_addr,
00456:                         input  bit [64-1:0] value,
00457:                         input  vmm_ral::path_e               path,
00458:                         input  string                        domain,
00459:                         input  int                           data_id,
00460:                         input  int                           scenario_id,
00461:                         input  int                           stream_id);
00462:    status = vmm_rw::ERROR;
00463:    
00464:    if (this.ral_access == null) begin
00465:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory %s not associated with RAL access object", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00466:       return;
00467:    end
00468:    
00469:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00470: 
00472: 
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_mem_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.pre_write(this, mem_addr, value, path, domain); 
     : end while (0);
00473: 
00474:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00475: 
00476:    if (path == vmm_ral::BACKDOOR &&
00477:        this.backdoor == null) begin
00478:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("No backdoor access available for memory \"%s\". Using frontdoor instead.", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00479:       path = vmm_ral::BFM;
00480:    end
00481: 
00482:    case (path)
00483:       
00484:       vmm_ral::BFM: begin
00485:          int di = this.get_domain_index(domain);
00486:          if (di < 0) return;
00487: 
00488:          if (this.frontdoor[di] != null) begin
00489:             this.frontdoor[di].write(status, mem_addr, value,
00490:                                      data_id, scenario_id, stream_id);
00491:          end
00492:          else begin
00493:             bit [64-1:0] addr[];
00494:             int w, j;
00495:             int n_bits;
00496:          
00497:             if (this.offset_in_block[di] === 'x) begin
00500: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory \"%s\" unmapped in domain \"%s\" does not have a user-defined frontdoor",
     :                                               this.get_name(),
     :                                               this.domains[di]))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00501:                return;
00502:             end
00503:          
00504:             w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00505:                                                          mem_addr,
00506:                                                          this.get_n_bytes(),
00507:                                                          this.parent,
00508:                                                          this.domains[di],
00509:                                                          addr);
00510:             j = 0;
00511:             n_bits = this.get_n_bits;
00512:             foreach (addr[i]) begin
00513:                bit [64-1:0] data;
00514:                data = value >> (j*8);
00515:                this.ral_access.write(status, addr[i], data,
00516:                                      (n_bits > w*8) ? w*8 : n_bits,
00517:                                      this.parent.get_external_domain(this.domains[di]),
00518:                                      data_id, scenario_id, stream_id);
00519:                if (status != vmm_rw::IS_OK) break;
00520:                j += w;
00521:                n_bits -= w * 8;
00522:             end
00523:          end
00524: 
00525:          if (this.cover_on) this.parent.XsampleX(this.offset_in_block[di], di);
00526:       end
00527:       
00528:       vmm_ral::BACKDOOR: begin
00529:          // Mimick front door access: Do not write read-only memories
00530:          if (this.get_access(domain) == vmm_ral::RW) begin
00531:             this.poke(status, mem_addr, value,
00532:                       data_id, scenario_id, stream_id);
00533:          end else status = vmm_rw::IS_OK;
00534:       end
00535:    endcase
00536: 
00538: 
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_mem_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.post_write(this, mem_addr, value, path, domain, status); 
     : end while (0);
00539: 
00543: 
     : do 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin 
     :       void'(this.log.text($psprintf("Wrote memory \"%s\"[%0d] via %s: with 'h%h",
     :                                   this.get_fullname(), mem_addr,
     :                                   (path == vmm_ral::BFM) ? "frontdoor" : "backdoor",
     :                                   value))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00544: endtask: write
00545: 
00546: 
00547: task vmm_ral_mem::read(output vmm_rw::status_e              status,
00548:                        input  bit [64-1:0] mem_addr,
00549:                        output bit [64-1:0] value,
00550:                        input  vmm_ral::path_e               path,
00551:                        input  string                        domain,
00552:                        input  int                           data_id,
00553:                        input  int                           scenario_id,
00554:                        input  int                           stream_id);
00555:    status = vmm_rw::ERROR;
00556:    
00557:    if (this.ral_access == null) begin
00558:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory %s not associated with RAL access object", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00559:       return;
00560:    end
00561:    
00562:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00563: 
00565: 
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_mem_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.pre_read(this, mem_addr, path, domain); 
     : end while (0);
00566: 
00567:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00568: 
00569:    if (path == vmm_ral::BACKDOOR &&
00570:        this.backdoor == null) begin
00571:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("No backdoor access available for memory \"%s\". Using frontdoor instead.", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00572:       path = vmm_ral::BFM;
00573:    end
00574: 
00575:    case (path)
00576:       
00577:       vmm_ral::BFM: begin
00578:          int di = this.get_domain_index(domain);
00579:          if (di < 0) return;
00580:          
00581:          if (this.frontdoor[di] != null) begin
00582:             this.frontdoor[di].read(status, mem_addr, value,
00583:                                    data_id, scenario_id, stream_id);
00584:          end
00585:          else begin
00586:             bit [64-1:0] addr[];
00587:             int w, j;
00588:             int n_bits;
00589:          
00590:             if (this.offset_in_block[di] === 'x) begin
00593: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory \"%s\" unmapped in domain \"%s\" does not have a user-defined frontdoor",
     :                                               this.get_name(),
     :                                               this.domains[di]))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00594:                return;
00595:             end
00596:          
00597:             w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00598:                                                          mem_addr,
00599:                                                          this.get_n_bytes(),
00600:                                                          this.parent,
00601:                                                          this.domains[di],
00602:                                                          addr);
00603:             j = 0;
00604:             n_bits = this.get_n_bits();
00605:             value = 0;
00606:             foreach (addr[i]) begin
00607:                bit [64-1:0] data;
00608:                this.ral_access.read(status, addr[i], data,
00609:                                     (n_bits > w*8) ? w*8 : n_bits,
00610:                                     this.parent.get_external_domain(this.domains[di]),
00611:                                     data_id, scenario_id, stream_id);
00612:                if (status != vmm_rw::IS_OK) break;
00613:                value |= (data & ((1 << (w*8)) - 1)) << (j*8);
00614:                j += w;
00615:                n_bits -= w * 8;
00616:             end
00617:          end
00618: 
00619:          if (this.cover_on) this.parent.XsampleX(this.offset_in_block[di], di);
00620:       end
00621:       
00622:       vmm_ral::BACKDOOR: begin
00623:          this.peek(status, mem_addr, value,
00624:                    data_id, scenario_id, stream_id);
00625:       end
00626:    endcase
00627: 
00629: 
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_mem_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.post_read(this, mem_addr, value, path, domain, status); 
     : end while (0);
00630: 
00634: 
     : do 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin 
     :       void'(this.log.text($psprintf("Read memory \"%s\"[%0d] via %s: 'h%h",
     :                                   this.get_fullname(), mem_addr,
     :                                   (path == vmm_ral::BFM) ? "frontdoor" : "backdoor",
     :                                   value))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00635: endtask: read
00636: 
00637: 
00638: function bit vmm_ral_mem::validate_burst(vmm_ral_mem_burst burst);
00639:    if (burst.start_offset >= this.get_size()) begin
00641: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Starting burst offset 'h%0h is greater than number of memory locations ('h%0h)",
     :                                      burst.start_offset, this.get_size()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00642:       return 0;
00643:    end
00644: 
00645:    if (burst.max_offset >= this.get_size()) begin
00647: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Maximum burst offset 'h%0h is greater than number of memory locations ('h%0h)",
     :                                      burst.max_offset, this.get_size()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00648:       return 0;
00649:    end
00650: 
00651:    if (burst.n_beats == 0) begin
00652:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text("Zero-length burst")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00653:       return 0;
00654:    end
00655: 
00656:    if (burst.start_offset > burst.max_offset) begin
00658: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Starting burst offset ('h%0h) greater than maximum burst offset ('h%0h)",
     :                                      burst.start_offset, burst.max_offset))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00659:       return 0;
00660:    end
00661: 
00662:    if (burst.n_beats > 1 &&
00663:        burst.start_offset + burst.incr_offset >= burst.max_offset) begin
00666: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("First burst offset increment 'h%0h+%0h is greater than maximum burst offset ('h%0h)",
     :                                      burst.start_offset, burst.incr_offset,
     :                                      burst.max_offset))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00667:       return 0;
00668:    end
00669: 
00670:    return 1;
00671: endfunction: validate_burst
00672: 
00673: 
00674: task vmm_ral_mem::burst_write(output vmm_rw::status_e              status,
00675:                               input  vmm_ral_mem_burst             burst,
00676:                               input  bit [64-1:0] value[],
00677:                               input  vmm_ral::path_e               path,
00678:                               input  string                        domain,
00679:                               input  int                           data_id,
00680:                               input  int                           scenario_id,
00681:                               input  int                           stream_id);
00682:    status = vmm_rw::ERROR;
00683: 
00684:    if (this.ral_access == null) begin
00685:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory %s not associated with RAL access object", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00686:       return;
00687:    end
00688:    
00689:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00690: 
00692: 
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_mem_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.pre_burst(this, vmm_rw::WRITE, burst, value, path, domain); 
     : end while (0);
00693: 
00694:    if (!this.validate_burst(burst)) return;
00695: 
00696:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00697: 
00698:    case (path)
00699:       
00700:       vmm_ral::BFM: begin
00701:          int di = this.get_domain_index(domain);
00702:          if (di < 0) return;
00703: 
00704:          if (this.frontdoor[di] != null) begin
00705:             this.frontdoor[di].burst_write(status, burst, value,
00706:                                            data_id, scenario_id, stream_id);
00707:          end
00708:          else begin
00709:             bit [64-1:0] addr[];
00710:             int w;
00711:             int n_bits;
00712:          
00713:             if (this.offset_in_block[di] === 'x) begin
00716: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory \"%s\" unmapped in domain \"%s\" does not have a user-defined frontdoor",
     :                                               this.get_name(),
     :                                               this.domains[di]))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00717:                return;
00718:             end
00719:          
00720:             w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00721:                                                          burst.start_offset,
00722:                                                          this.get_n_bytes(),
00723:                                                          this.parent,
00724:                                                          this.domains[di],
00725:                                                          addr);
00726:             n_bits = this.get_n_bits;
00727:             // Cannot burst memory through a narrower datapath
00728:             if (n_bits > w*8) begin
00730: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Cannot burst-write a %0d-bit memory through a narrower data path (%0d bytes)",
     :                                               n_bits, w))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00731:                return;
00732:             end
00733:             // Translate offsets into addresses
00734:             begin
00735:                bit [64-1:0] start, incr, max;
00736: 
00737:                start = addr[0];
00738: 
00739:                w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00740:                                                             burst.start_offset + burst.incr_offset,
00741:                                                             this.get_n_bytes(),
00742:                                                             this.parent,
00743:                                                             this.domains[di],
00744:                                                             addr);
00745:                incr = addr[0] - start;
00746: 
00747:                w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00748:                                                             burst.max_offset,
00749:                                                             this.get_n_bytes(),
00750:                                                             this.parent,
00751:                                                             this.domains[di],
00752:                                                             addr);
00753: 
00754:                max = addr[addr.size()-1];
00755: 
00756:                this.ral_access.burst_write(status, start, incr, max, value,
00757:                                            burst.user_data, n_bits,
00758:                                            this.parent.get_external_domain(this.domains[di]),
00759:                                            data_id, scenario_id, stream_id);
00760:             end
00761:          end
00762: 
00763:          if (this.cover_on) begin
00764:             bit [64-1:0] addr;
00765:             for (addr = burst.start_offset;
00766:                  addr <= burst.max_offset;
00767:                  addr += burst.incr_offset) begin
00768:                this.parent.XsampleX(this.offset_in_block[di] + addr, di);
00769:             end
00770:          end
00771:       end
00772:       
00773:       vmm_ral::BACKDOOR: begin
00774:          // Mimick front door access: Do not write read-only memories
00775:          if (this.get_access(domain) == vmm_ral::RW) begin
00776:             bit [64-1:0] addr;
00777:             addr = burst.start_offset;
00778:             foreach (value[i]) begin
00779:                this.poke(status, addr, value[i],
00780:                          data_id, scenario_id, stream_id);
00781:                if (status != vmm_rw::IS_OK) return;
00782:                addr += burst.incr_offset;
00783:                if (addr > burst.max_offset) begin
00784:                   addr -= (burst.max_offset - burst.start_offset - 1);
00785:                end
00786:             end
00787:          end
00788:          else status = vmm_rw::IS_OK;
00789:       end
00790:    endcase
00791: 
00794: 
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_mem_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.post_burst(this, vmm_rw::WRITE, burst, value,
     :                             path, domain, status); 
     : end while (0);
00795: endtask: burst_write
00796: 
00797: 
00798: task vmm_ral_mem::burst_read(output vmm_rw::status_e              status,
00799:                              input  vmm_ral_mem_burst             burst,
00800:                              output bit [64-1:0] value[],
00801:                              input  vmm_ral::path_e               path,
00802:                              input  string                        domain,
00803:                              input  int                           data_id,
00804:                              input  int                           scenario_id,
00805:                              input  int                           stream_id);
00806:    status = vmm_rw::ERROR;
00807: 
00808:    if (this.ral_access == null) begin
00809:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory %s not associated with RAL access object", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00810:       return;
00811:    end
00812:    
00813:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00814: 
00815:    begin
00816:       bit [64-1:0] junk[];
00817: 
00819: 
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_mem_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.pre_burst(this, vmm_rw::READ, burst, junk, path, domain); 
     : end while (0);
00820:    end
00821: 
00822:    if (!this.validate_burst(burst)) return;
00823: 
00824:    if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00825: 
00826:    case (path)
00827:       
00828:       vmm_ral::BFM: begin
00829:          int di = this.get_domain_index(domain);
00830:          if (di < 0) return;
00831:          
00832:          if (this.frontdoor[di] != null) begin
00833:             this.frontdoor[di].burst_read(status, burst, value,
00834:                                           data_id, scenario_id, stream_id);
00835:          end
00836:          else begin
00837:             bit [64-1:0] addr[];
00838:             int n_bits, w;
00839:          
00840:             if (this.offset_in_block[di] === 'x) begin
00843: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Memory \"%s\" unmapped in domain \"%s\" does not have a user-defined frontdoor",
     :                                               this.get_name(),
     :                                               this.domains[di]))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00844:                return;
00845:             end
00846:          
00847:             w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00848:                                                          burst.start_offset,
00849:                                                          this.get_n_bytes(),
00850:                                                          this.parent,
00851:                                                          this.domains[di],
00852:                                                          addr);
00853:             n_bits = this.get_n_bits();
00854:             // Cannot burst memory through a narrower datapath
00855:             if (n_bits > w*8) begin
00857: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Cannot burst-write a %0d-bit memory through a narrower data path (%0d bytes)",
     :                                               n_bits, w))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00858:                return;
00859:             end
00860:             // Translate the offset-based burst into address-based burst
00861:             begin
00862:                bit [64-1:0] start, incr, max;
00863: 
00864:                start = addr[0];
00865: 
00866:                w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00867:                                                             burst.start_offset + burst.incr_offset,
00868:                                                             this.get_n_bytes(),
00869:                                                             this.parent,
00870:                                                             this.domains[di],
00871:                                                             addr);
00872:                incr = addr[0] - start;
00873: 
00874:                w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00875:                                                             burst.max_offset,
00876:                                                             this.get_n_bytes(),
00877:                                                             this.parent,
00878:                                                             this.domains[di],
00879:                                                             addr);
00880: 
00881:                max = addr[addr.size()-1];
00882: 
00883:                this.ral_access.burst_read(status, start, incr, max,
00884:                                           burst.n_beats, value,
00885:                                           burst.user_data, n_bits,
00886:                                           this.parent.get_external_domain(this.domains[di]),
00887:                                           data_id, scenario_id, stream_id);
00888:             end
00889:          end
00890: 
00891:          if (this.cover_on) begin
00892:             bit [64-1:0] addr;
00893:             for (addr = burst.start_offset;
00894:                  addr <= burst.max_offset;
00895:                  addr += burst.incr_offset) begin
00896:                this.parent.XsampleX(this.offset_in_block[di] + addr, di);
00897:             end
00898:          end
00899:       end
00900:       
00901:       vmm_ral::BACKDOOR: begin
00902:          bit [64-1:0] addr;
00903:          value = new [burst.n_beats];
00904:          addr = burst.start_offset;
00905:          foreach (value[i]) begin
00906:             this.peek(status, addr, value[i],
00907:                       data_id, scenario_id, stream_id);
00908:             if (status != vmm_rw::IS_OK) return;
00909:             addr += burst.incr_offset;
00910:             if (addr > burst.max_offset) begin
00911:                addr -= (burst.max_offset - burst.start_offset - 1);
00912:             end
00913:          end
00914:       end
00915:    endcase
00916: 
00919: 
     : 
     : do foreach (this.callbacks[vmm_i]) begin 
     :    vmm_ral_mem_callbacks cb; 
     :    if (!$cast(cb, this.callbacks[vmm_i])) continue; 
     :  
     :    cb.post_burst(this, vmm_rw::READ, burst, value,
     :                             path, domain, status); 
     : end while (0);
00920: endtask: burst_read
00921: 
00922: 
00923: task vmm_ral_mem::poke(output vmm_rw::status_e              status,
00924:                        input  bit [64-1:0] mem_addr,
00925:                        input  bit [64-1:0] value,
00926:                        input  int                           data_id,
00927:                        input  int                           scenario_id,
00928:                        input  int                           stream_id);
00929:    if (this.backdoor == null) begin
00930:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("No backdoor access available in memory %s", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00931:       status = vmm_rw::ERROR;
00932:       return;
00933:    end
00934:    this.backdoor.write(status, mem_addr, value, data_id, scenario_id, stream_id);
00935: 
00937: 
     : do 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin 
     :       void'(this.log.text($psprintf("Poked memory \"%s\"[%0d] with: 'h%h",
     :                                   this.get_fullname(), mem_addr, value))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00938: endtask: poke
00939: 
00940: 
00941: task vmm_ral_mem::peek(output vmm_rw::status_e              status,
00942:                        input  bit [64-1:0] mem_addr,
00943:                        output bit [64-1:0] value,
00944:                        input  int                           data_id,
00945:                        input  int                           scenario_id,
00946:                        input  int                           stream_id);
00947:    if (this.backdoor == null) begin
00948:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("No backdoor access available in memory %s", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00949:       status = vmm_rw::ERROR;
00950:       return;
00951:    end
00952:    this.backdoor.read(status, mem_addr, value, data_id, scenario_id, stream_id);
00953: 
00955: 
     : do 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin 
     :       void'(this.log.text($psprintf("Peeked memory \"%s\"[%0d]: 'h%h",
     :                                   this.get_fullname(), mem_addr, value))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00956: endtask: peek
00957: 
00958: 
00959: task vmm_ral_mem::readmemh(string filename);
00960: endtask: readmemh
00961: 
00962: 
00963: task vmm_ral_mem::writememh(string filename);
00964: endtask: writememh
00965: 
00966: 
00967: function void vmm_ral_mem::set_frontdoor(vmm_ral_mem_frontdoor ftdr,
00968:                                          string                domain);
00969:    foreach(this.domains[i]) begin
00970:       if (this.domains[i] == domain) begin
00971:          this.frontdoor[i] = ftdr;
00972:          return;
00973:       end
00974:    end
00975:    
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Domain \"%s\" not found in memory %s", domain, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00976: endfunction: set_frontdoor
00977: 
00978: 
00979: function vmm_ral_mem_frontdoor vmm_ral_mem::get_frontdoor(string domain);
00980:    foreach(this.domains[i]) begin
00981:       if (this.domains[i] == domain) begin
00982:          return this.frontdoor[i];
00983:       end
00984:    end
00985:    
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Domain \"%s\" not found in memory %s", domain, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00986: endfunction: get_frontdoor
00987: 
00988: 
00989: function void vmm_ral_mem::set_backdoor(vmm_ral_mem_backdoor bkdr);
00990:    this.backdoor = bkdr;
00991: endfunction: set_backdoor
00992: 
00993: 
00994: function vmm_ral_mem_backdoor vmm_ral_mem::get_backdoor();
00995:    get_backdoor = this.backdoor;
00996: endfunction: get_backdoor
00997: 
00998: 
00999: function void vmm_ral_mem::prepend_callback(vmm_ral_mem_callbacks cb);
01000:    foreach (this.callbacks[i]) begin
01001:       if (this.callbacks[i] == cb) begin
01002:          
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Callback has already been registered with memory %s", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
01003:          return;
01004:       end
01005:    end
01006:    
01007:    // Prepend new callback
01008:    this.callbacks.push_front(cb);
01009: endfunction: prepend_callback
01010: 
01011: 
01012: function void vmm_ral_mem::append_callback(vmm_ral_mem_callbacks cb);
01013:    foreach (this.callbacks[i]) begin
01014:       if (this.callbacks[i] == cb) begin
01015:          
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Callback has already been registered with memory %s", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
01016:          return;
01017:       end
01018:    end
01019:    
01020:    // Append new callback
01021:    this.callbacks.push_back(cb);
01022: endfunction: append_callback
01023: 
01024: 
01025: function void vmm_ral_mem::unregister_callback(vmm_ral_mem_callbacks cb);
01026:    foreach (this.callbacks[i]) begin
01027:       if (this.callbacks[i] == cb) begin
01028:          int j = i;
01029:          // Unregister it
01030:          this.callbacks.delete(j);
01031:          return;
01032:       end
01033:    end
01034: 
01035: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Callback was not registered with memory %s", this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
01036: endfunction: unregister_callback
01037: 
01038: 
01039: function int vmm_ral_mem::get_domain_index(string domain);
01040:    // If the domain is "" and there is only one domain,
01041:    // assume it is the one domain available to avoid
01042:    // having to always have to specify domains
01043:    if (domain == "" && this.domains.size() == 1) return 0;
01044: 
01045:    foreach (this.domains[i]) begin
01046:       if (this.domains[i] == domain) return i;
01047:    end
01048:    
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Unknown domain name \"%s\" in memory %s.", domain, this.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
01049:    return -1;
01050: endfunction: get_domain_index
01051: 
01052: 
01053: task vmm_ral_mem_frontdoor::write(output vmm_rw::status_e              status,
01054:                                   input  bit [64-1:0] offset,
01055:                                   input  bit [64-1:0] data,
01056:                                   input  int                           data_id,
01057:                                   input  int                           scenario_id,
01058:                                   input  int                           stream_id);
01059:    
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin 
     :       void'(this.log.text("vmm_ral_mem_frontdoor::write() method has not been overloaded")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
01060: endtask: write
01061: 
01062: 
01063: task vmm_ral_mem_frontdoor::read(output vmm_rw::status_e              status,
01064:                                  input  bit [64-1:0] offset,
01065:                                  output bit [64-1:0] data,
01066:                                  input  int                           data_id,
01067:                                  input  int                           scenario_id,
01068:                                  input  int                           stream_id);
01069:    
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin 
     :       void'(this.log.text("vmm_ral_mem_frontdoor::read() method has not been overloaded")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
01070: endtask: read
01071: 
01072: 
01073: function int unsigned vmm_ral_mem::get_mem_ID();
01074:    get_mem_ID =  this.__vmm_mem_id;
01075: endfunction
01076: 
01077: function vmm_ral_mem vmm_ral_mem::get_mem_by_ID(int unsigned id);
01078:    if (__vmm_all_mems.exists(id)) get_mem_by_ID = __vmm_all_mems[id];
01079:    else get_mem_by_ID = null;
01080: endfunction