VMM - RAL/vmm_ral_sys.sv

RAL/vmm_ral_sys.sv expanded 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_sys_domain;
00024    vmm_ral_block blocks[$];
00025    string        blk_domains[$];
00026    vmm_ral_sys   subsys[$];
00027    string        sys_domains[$];
00028 endclass
00029 
00030 class vmm_ral_sys extends vmm_ral_block_or_sys;
00031    local vmm_ral_sys_domain domains[];
00032    static local vmm_ral_sys __vmm_all_systems[*];  // Keeps track of all Systems in the RAL Model
00033    local int unsigned __vmm_sys_id = 0;
00034 
00035    extern function new(
00036                        vmm_ral_sys                   parent = null,
00037                        string                        name,
00038                        string                        typename,
00039                        int unsigned                  n_bytes,
00040                        vmm_ral::endianness_e         endian,
00041                        bit [`VMM_RAL_ADDR_WIDTH-1:0] base_addr = 0,
00042                        string                        domain    = "",
00043                        bit                           cover_on  = 1);
00044 
00045    /*local*/ extern virtual function void Xlock_modelX();
00046    /*local*/ extern virtual function void add_domain(int unsigned          n_bytes,
00047                                                      vmm_ral::endianness_e endian,
00048                                                      string                domain);
00049    /*local*/ extern function void register_block(vmm_ral_block                 block,
00050                                                  string                        domain = "",
00051                                                  string                        in_domain = "",
00052                                                  bit [`VMM_RAL_ADDR_WIDTH-1:0] base_addr);
00053    /*local*/ extern function void register_subsys(vmm_ral_sys                  subsys,
00054                                                   string                       domain = "",
00055                                                   string                       in_domain = "",
00056                                                   bit [`VMM_RAL_ADDR_WIDTH-1:0]base_addr);
00057    /*local*/ extern virtual function void Xregister_ral_accessX(vmm_ral_access access);
00058 
00059    extern virtual function string psdisplay(string prefix = "",
00060                                             string domain = "");
00061 
00062    extern virtual function void get_fields(ref vmm_ral_field fields[],
00063                                            input string      domain = ""); 
00064    extern virtual function void get_virtual_fields(ref vmm_ral_vfield fields[],
00065                                                    input string      domain = ""); 
00066    extern virtual function vmm_ral_field get_field_by_name(string name);
00067    extern virtual function vmm_ral_vfield get_virtual_field_by_name(string name);
00068 
00069    extern virtual function void get_registers(ref vmm_ral_reg regs[],
00070                                               input string    domain = "");
00071    extern virtual function void get_virtual_registers(ref vmm_ral_vreg vregs[],
00072                                                       input string    domain = "");
00073    extern virtual function vmm_ral_reg get_reg_by_name(string name);
00074    extern virtual function vmm_ral_vreg get_vreg_by_name(string name);
00075    extern virtual function vmm_ral_reg get_reg_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00076                                                          string                        domain = "");
00077    extern virtual function vmm_ral_vreg get_vreg_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00078                                                            string                        domain = "");
00079 
00080    extern virtual function void get_memories(ref vmm_ral_mem mems[],
00081                                              input string    domain = "");
00082    extern virtual function vmm_ral_mem get_mem_by_name(string name);
00083    extern virtual function vmm_ral_mem get_mem_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00084                                                          string                        domain = "");
00085 
00086    extern virtual function void get_blocks(ref vmm_ral_block blocks[],
00087                                            ref string        domains[],
00088                                            input string      domain = "");
00089    extern virtual function void get_all_blocks(ref vmm_ral_block blocks[],
00090                                                ref string        domains[],
00091                                                input string      domain = "");
00092    extern virtual function vmm_ral_block get_block_by_name(string name);  
00093    extern virtual function vmm_ral_block get_block_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00094                                                              string                        domain = ""); 
00095 
00096    extern virtual function void get_subsys(ref vmm_ral_sys subsys[],
00097                                            ref string      domains[],
00098                                            input string    domain = ""); 
00099    extern virtual function void get_all_subsys(ref vmm_ral_sys subsys[],
00100                                                ref string      domains[],
00101                                                input string    domain = ""); 
00102    extern virtual function vmm_ral_sys get_subsys_by_name(string name);  
00103    extern virtual function vmm_ral_sys get_subsys_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00104                                                             string                        domain = ""); 
00105      
00106    extern function bit set_cover(bit is_on);
00107 
00108    extern virtual function void reset(string           domain = "",
00109                                       vmm_ral::reset_e kind   = vmm_ral::HARD); 
00110    extern virtual function bit needs_update();
00111 
00112    extern virtual task update(output vmm_rw::status_e status,
00113                               input  vmm_ral::path_e  path = vmm_ral::DEFAULT);
00114    extern virtual task mirror(output vmm_rw::status_e status,
00115                               input  vmm_ral::check_e check = vmm_ral::	QUIET,
00116                               input  vmm_ral::path_e  path  = vmm_ral::DEFAULT);
00117    
00118    extern virtual task readmemh(string filename);
00119    extern virtual task writememh(string filename);
00120 
00121    extern function int unsigned get_sys_ID();
00122 
00123    extern /*static*/ function vmm_ral_sys get_sys_by_ID(int unsigned id);
00124 endclass: vmm_ral_sys
00125 
00126 
00127 function vmm_ral_sys::new(vmm_ral_sys                   parent,
00128                           string                        name,
00129                           string                        typename,
00130                           int unsigned                  n_bytes,
00131                           vmm_ral::endianness_e         endian,
00132                           bit [`VMM_RAL_ADDR_WIDTH-1:0] base_addr,
00133                           string                        domain,
00134                           bit                           cover_on);
00135    super.new(parent, "RAL System", name, typename,
00136              n_bytes, endian, base_addr, domain,
00137              cover_on);
00138 
00139    this.domains = new [1];
00140    this.domains[0] = new;
00141 
00142    // Initialize System ID
00143    this.__vmm_sys_id = ++this.__vmm_block_or_sys_id_factory;
00144    __vmm_all_systems[this.__vmm_sys_id] = this;
00145 endfunction: new
00146 
00147 
00148 function void vmm_ral_sys::Xlock_modelX();
00149    if (this.Xis_lockedX()) return;
00150 
00151    super.Xlock_modelX();
00152    foreach (this.domains[i]) begin
00153       foreach (this.domains[i].blocks[j]) begin
00154          this.domains[i].blocks[j].Xlock_modelX();
00155       end
00156       foreach (this.domains[i].subsys[j]) begin
00157          this.domains[i].subsys[j].Xlock_modelX();
00158       end
00159    end
00160 endfunction: Xlock_modelX
00161 
00162 
00163 function void vmm_ral_sys::add_domain(int unsigned          n_bytes,
00164                                       vmm_ral::endianness_e endian,
00165                                       string                domain);
00166    int n;
00167 
00168    super.add_domain(n_bytes, endian, domain);
00169 
00170    n = this.domains.size();
00171    this.domains    = new [n+1] (this.domains);
00172    this.domains[n] = new;
00173 endfunction: add_domain
00174 
00175 
00176 function void vmm_ral_sys::register_block(vmm_ral_block                 block,
00177                                           string                        domain,
00178                                           string                        in_domain,
00179                                           bit [`VMM_RAL_ADDR_WIDTH-1:0] base_addr);
00180    string doms[];
00181    vmm_ral_sys_domain dom;
00182 
00183    if (this.Xis_lockedX()) begin
00184       `vmm_error(this.log, "Cannot add block to locked system model");
00185       return;
00186    end
00187 
00188    block.get_domains(doms);
00189    foreach (doms[i]) begin
00190       if (doms[i] == domain) begin
00191          int j = this.get_domain_index(in_domain);
00192          if (j < 0) return;
00193 
00194          dom = this.domains[j];
00195          dom.blocks.push_back(block);
00196          dom.blk_domains.push_back(domain);
00197 
00198          begin
00199             int k;
00200             j = this.get_n_bytes(in_domain);
00201             k = block.get_n_bytes(domain);
00202             if (k > j) begin
00203                `vmm_warning(this.log, $psprintf("%0d-byte block %s.%s instantiated in %0d-byte system %s.%s",
00204                                                 k, block.get_name(), domain,
00205                                                 j, this.get_name(), in_domain));
00206             end
00207          end
00208 
00209          block.map_domain(domain, in_domain, base_addr);
00210 
00211          return;
00212       end
00213    end
00214 
00215    `vmm_error(this.log, $psprintf("Domain \"%s\" not found in block \"%s\".",
00216                                   domain, block.get_name()));
00217 endfunction: register_block
00218 
00219 
00220 function void vmm_ral_sys::register_subsys(vmm_ral_sys                   subsys,
00221                                            string                        domain,
00222                                            string                        in_domain,
00223                                            bit [`VMM_RAL_ADDR_WIDTH-1:0] base_addr);
00224    string doms[];
00225    vmm_ral_sys_domain dom;
00226    int i;
00227 
00228    if (this.Xis_lockedX()) begin
00229       `vmm_error(this.log, "Cannot add subsystem to locked system model");
00230       return;
00231    end
00232 
00233    subsys.get_domains(doms);
00234    foreach (doms[i]) begin
00235       if (doms[i] == domain) begin
00236          int j = this.get_domain_index(in_domain);
00237          if (j < 0) return;
00238 
00239          dom = this.domains[j];
00240          dom.subsys.push_back(subsys);
00241          dom.sys_domains.push_back(domain);
00242 
00243          begin
00244             int k;
00245             j = this.get_n_bytes(in_domain);
00246             k = subsys.get_n_bytes(domain);
00247             if (k > j) begin
00248                `vmm_warning(this.log, $psprintf("%0d-byte system %s.%s instantiated in %0d-byte system %s.%s",
00249                                                 k, subsys.get_name(), domain,
00250                                                 j, this.get_name(), in_domain));
00251             end
00252          end
00253 
00254          subsys.map_domain(domain, in_domain, base_addr);
00255 
00256          return;
00257       end
00258    end
00259 
00260    `vmm_error(this.log, $psprintf("Domain \"%s\" not found in system \"%s\".",
00261                                   domain, subsys.get_fullname()));
00262 endfunction: register_subsys
00263 
00264 
00265 function void vmm_ral_sys::Xregister_ral_accessX(vmm_ral_access access);
00266    // There can only be one RAL Access on a RAL model
00267    if (this.ral_access != null && this.ral_access != access) begin
00268       `vmm_fatal(this.log, $psprintf("System %s is already used by another RAL access instance", this.get_fullname()));
00269    end
00270    this.ral_access = access;
00271 
00272    // Register all sub-elements
00273    begin
00274       vmm_ral_sys sys[];
00275       vmm_ral_block blks[];
00276       string domains[];
00277 
00278       this.get_subsys(sys, domains);
00279       foreach (sys[i]) begin
00280          sys[i].Xregister_ral_accessX(access);
00281       end
00282 
00283       this.get_blocks(blks, domains);
00284       foreach (blks[i]) begin
00285          blks[i].Xregister_ral_accessX(access);
00286       end
00287    end
00288 endfunction: Xregister_ral_accessX
00289 
00290 
00291 function string vmm_ral_sys::psdisplay(string prefix,
00292                                        string domain);
00293    string image;
00294    string domains[];
00295    string blk_domains[];
00296    vmm_ral_sys sys[];
00297    vmm_ral_block blks[];
00298    bit         single_domain;
00299    vmm_ral::endianness_e endian;
00300 
00301    single_domain = 1;
00302    if (domain == "") begin
00303       this.get_domains(domains);
00304       if (domains.size() > 1) single_domain = 0;
00305    end
00306 
00307    if (single_domain) begin
00308       $sformat(image, "%sSystem %s", prefix, this.get_fullname());
00309       if (domain != "") $sformat(image, "%s.%s", image, domain);
00310       endian = this.get_endian(domain);
00311       $sformat(image, "%s -- %0d bytes (%s)", image,
00312                this.get_n_bytes(domain), endian.name());
00313 
00314       this.get_blocks(blks, blk_domains, domain);
00315       foreach (blks[i]) begin
00316          string img;
00317          img = blks[i].psdisplay({prefix, "   "}, blk_domains[i]);
00318          image = {image, "\n", img};
00319       end
00320 
00321       this.get_subsys(sys, blk_domains, domain);
00322       foreach (sys[i]) begin
00323          string img;
00324          img = sys[i].psdisplay({prefix, "   "}, blk_domains[i]);
00325          image = {image, "\n", img};
00326       end
00327    end
00328    else begin
00329       $sformat(image, "%sSystem %s", prefix, this.get_fullname());
00330       foreach (domains[i]) begin
00331          string img;
00332          endian = this.get_endian(domains[i]);
00333          $sformat(img, "%s   Domain \"%s\" -- %0d bytes (%s)",
00334                   prefix, domains[i],
00335                   this.get_n_bytes(domains[i]), endian.name());
00336          image = {image, "\n", img};
00337 
00338          this.get_blocks(blks, blk_domains, domains[i]);
00339          foreach (blks[j]) begin
00340             img = blks[j].psdisplay({prefix, "      "},
00341                                     blk_domains[j]);
00342             image = {image, "\n", img};
00343          end
00344 
00345          this.get_subsys(sys, blk_domains, domains[i]);
00346          foreach (sys[j]) begin
00347             img = sys[j].psdisplay({prefix, "      "},
00348                                    blk_domains[j]);
00349             image = {image, "\n", img};
00350          end
00351       end
00352    end
00353    return image;
00354 endfunction: psdisplay
00355 
00356 
00357 function void vmm_ral_sys::get_fields(ref vmm_ral_field fields[],
00358                                       input string      domain);
00359    int n;
00360    vmm_ral_block b[];
00361    string        d[];
00362    vmm_ral_field f[];
00363 
00364    this.get_all_blocks(b, d, domain);
00365    fields = new [0];
00366    foreach (b[i]) begin
00367       b[i].get_fields(f, d[i]);
00368       n = fields.size();
00369       fields = new [n + f.size()] (fields);
00370 
00371       foreach (f[j]) begin
00372          fields[n++] = f[j];
00373       end
00374    end
00375 endfunction: get_fields
00376 
00377 function void vmm_ral_sys::get_virtual_fields(ref vmm_ral_vfield fields[],
00378                                               input string      domain);
00379    int n;
00380    vmm_ral_block b[];
00381    string        d[];
00382    vmm_ral_vfield f[];
00383 
00384    this.get_all_blocks(b, d, domain);
00385    fields = new [0];
00386    foreach (b[i]) begin
00387       b[i].get_virtual_fields(f, d[i]);
00388       n = fields.size();
00389       fields = new [n + f.size()] (fields);
00390 
00391       foreach (f[j]) begin
00392          fields[n++] = f[j];
00393       end
00394    end
00395 endfunction: get_virtual_fields
00396 
00397 function vmm_ral_field vmm_ral_sys::get_field_by_name(string name);
00398    // Search the registers to find the first field of the specified name
00399    vmm_ral_reg r[];
00400 
00401    this.get_registers(r);
00402    foreach (r[i]) begin
00403       vmm_ral_field fields[];
00404       r[i].get_fields(fields);
00405       foreach (fields[j]) begin
00406          if (fields[j].get_name() == name) begin
00407             return fields[j];
00408          end
00409       end
00410    end
00411    `vmm_warning(this.log, $psprintf("Unable to locate field \"%s\" in system \"%s\".",
00412                                     name, this.get_fullname()));
00413    get_field_by_name = null;
00414 endfunction: get_field_by_name
00415 
00416 function vmm_ral_vfield vmm_ral_sys::get_virtual_field_by_name(string name);
00417    // Search the registers to find the first field of the specified name
00418    vmm_ral_vreg r[];
00419 
00420    this.get_virtual_registers(r);
00421    foreach (r[i]) begin
00422       vmm_ral_vfield fields[];
00423       r[i].get_fields(fields);
00424       foreach (fields[j]) begin
00425          if (fields[j].get_name() == name) begin
00426             return fields[j];
00427          end
00428       end
00429    end
00430    `vmm_warning(this.log, $psprintf("Unable to locate virtual field \"%s\" in system \"%s\".",
00431                                     name, this.get_fullname()));
00432    get_virtual_field_by_name = null;
00433 endfunction: get_virtual_field_by_name
00434 
00435 function void vmm_ral_sys::get_registers(ref vmm_ral_reg regs[],
00436                                          input string    domain);
00437    vmm_ral_block blks[];
00438    string        d[];
00439    
00440    regs = new [0];
00441 
00442    this.get_all_blocks(blks, d, domain);
00443    foreach (blks[i]) begin
00444       int n = regs.size();
00445       vmm_ral_reg rg[];
00446       
00447       blks[i].get_registers(rg, d[i]);
00448       regs = new [n + rg.size()] (regs);
00449 
00450       foreach (rg[j]) begin
00451          regs[n+j] = rg[j];
00452       end
00453    end
00454 endfunction: get_registers
00455 
00456 function void vmm_ral_sys::get_virtual_registers(ref vmm_ral_vreg vregs[],
00457                                                  input string    domain);
00458    vmm_ral_block blks[];
00459    string        d[];
00460    
00461    vregs = new [0];
00462 
00463    this.get_all_blocks(blks, d, domain);
00464    foreach (blks[i]) begin
00465       int n = vregs.size();
00466       vmm_ral_vreg rg[];
00467       
00468       blks[i].get_virtual_registers(rg, d[i]);
00469       vregs = new [n + rg.size()] (vregs);
00470 
00471       foreach (rg[j]) begin
00472          vregs[n+j] = rg[j];
00473       end
00474    end
00475 endfunction: get_virtual_registers
00476 
00477 function vmm_ral_reg vmm_ral_sys::get_reg_by_name(string name);
00478    // Search the registers to find the first of the specified name
00479    vmm_ral_reg r[];
00480 
00481    this.get_registers(r);
00482    foreach (r[i]) begin
00483       if (r[i].get_name() == name) begin
00484          return r[i];
00485       end
00486    end
00487    `vmm_warning(this.log, $psprintf("Unable to locate register \"%s\" in system \"%s\".",
00488                                     name, this.get_fullname()));
00489    get_reg_by_name = null;
00490 endfunction: get_reg_by_name
00491 
00492 function vmm_ral_vreg vmm_ral_sys::get_vreg_by_name(string name);
00493    // Search the registers to find the first of the specified name
00494    vmm_ral_vreg r[];
00495 
00496    this.get_virtual_registers(r);
00497    foreach (r[i]) begin
00498       if (r[i].get_name() == name) begin
00499          return r[i];
00500       end
00501    end
00502    `vmm_warning(this.log, $psprintf("Unable to locate virtual register \"%s\" in system \"%s\".",
00503                                     name, this.get_fullname()));
00504    get_vreg_by_name = null;
00505 endfunction: get_vreg_by_name
00506 
00507 function vmm_ral_reg vmm_ral_sys::get_reg_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00508                                                     string                        domain);
00509 endfunction: get_reg_by_offset
00510 
00511 function vmm_ral_vreg vmm_ral_sys::get_vreg_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00512                                                       string                        domain);
00513 endfunction: get_vreg_by_offset
00514                                                     
00515 function void vmm_ral_sys::get_memories(ref vmm_ral_mem mems[],
00516                                         input string    domain);
00517    vmm_ral_block blks[];
00518    string        d[];
00519    
00520    mems = new [0];
00521 
00522    this.get_all_blocks(blks, d, domain);
00523    foreach (blks[i]) begin
00524       integer n = mems.size();
00525       vmm_ral_mem mm[];
00526       
00527       blks[i].get_memories(mm, domain);
00528       mems = new [n + mm.size()] (mems);
00529 
00530       foreach (mm[j]) begin
00531          mems[n+j] = mm[j];
00532       end
00533    end
00534 endfunction: get_memories
00535 
00536 
00537 function vmm_ral_mem vmm_ral_sys::get_mem_by_name(string name);
00538    // Search the memories to find the first of the specified name
00539    vmm_ral_mem m[];
00540 
00541    this.get_memories(m);
00542    foreach (m[i]) begin
00543       if (m[i].get_name() == name) begin
00544          return m[i];
00545       end
00546    end
00547    `vmm_warning(this.log, $psprintf("Unable to locate memory \"%s\" in system \"%s\".",
00548                                     name, this.get_fullname()));
00549    get_mem_by_name = null;
00550 endfunction: get_mem_by_name
00551 
00552 
00553 function vmm_ral_mem vmm_ral_sys::get_mem_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00554                                                     string                        domain);
00555 endfunction: get_mem_by_offset
00556 
00557                                                     
00558 function void vmm_ral_sys::get_blocks(ref vmm_ral_block blocks[],
00559                                       ref string        domains[],
00560                                       input string      domain);
00561    if (domain == "" && this.domains.size() > 1) begin
00562       blocks = new [0];
00563       domains = new [0];
00564 
00565       foreach (this.domains[i]) begin
00566          int n = blocks.size();
00567       
00568          blocks  = new [n + this.domains[i].blocks.size()] (blocks);
00569          domains = new [n + this.domains[i].blocks.size()] (domains);
00570       
00571          foreach (this.domains[i].blocks[j]) begin
00572             blocks[n+j]  = this.domains[i].blocks[j];
00573             domains[n+j] = this.domains[i].blk_domains[j];
00574          end
00575       end
00576    end
00577    else begin
00578       vmm_ral_sys_domain dom;
00579       int i;
00580 
00581       i = this.get_domain_index(domain);
00582       if (i < 0) return;
00583 
00584       dom = this.domains[i];
00585       blocks = new [dom.blocks.size()];
00586       domains = new [dom.blocks.size()];
00587       
00588       foreach (dom.blocks[j]) begin
00589          blocks[j]  = dom.blocks[j];
00590          domains[j] = dom.blk_domains[j];
00591       end
00592    end
00593 endfunction: get_blocks
00594 
00595                              
00596 function void vmm_ral_sys::get_all_blocks(ref vmm_ral_block blocks[],
00597                                           ref string        domains[],
00598                                           input string      domain);
00599    vmm_ral_block blks[];
00600    vmm_ral_sys   sys[];
00601    string        doms[];
00602    string        subdoms[];
00603    
00604    this.get_blocks(blocks, domains, domain);
00605 
00606    this.get_all_subsys(sys, subdoms, domain);
00607    foreach (sys[i]) begin
00608       int n = blocks.size();
00609       
00610       sys[i].get_blocks(blks, doms, subdoms[i]);
00611       blocks  = new [n + blks.size()] (blocks);
00612       domains = new [n + blks.size()] (domains);
00613       
00614       foreach (blks[j]) begin
00615          blocks[n+j] = blks[j];
00616          domains[n+j] = doms[j];
00617       end
00618    end
00619 endfunction: get_all_blocks
00620 
00621                              
00622 function vmm_ral_block vmm_ral_sys::get_block_by_name(string name);
00623    vmm_ral_block blks[];
00624    string        d[];
00625 
00626    this.get_all_blocks(blks, d);
00627    foreach (blks[i]) begin
00628       if (blks[i].get_name() == name) begin
00629          return blks[i];
00630       end
00631    end
00632    `vmm_warning(this.log, $psprintf("Unable to locate block \"%s\" in system \"%s\".",
00633                                     name, this.get_fullname()));
00634    get_block_by_name = null;
00635 endfunction: get_block_by_name
00636 
00637 
00638 function vmm_ral_block vmm_ral_sys::get_block_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00639                                                         string                        domain);
00640 endfunction: get_block_by_offset
00641 
00642                                                         
00643 function void vmm_ral_sys::get_subsys(ref vmm_ral_sys subsys[],
00644                                       ref string      domains[],
00645                                       input string    domain);
00646    if (domain == "" && this.domains.size() > 1) begin
00647       subsys  = new [0];
00648       domains = new [0];
00649 
00650       foreach (this.domains[i]) begin
00651          int n = subsys.size();
00652       
00653          subsys  = new [n + this.domains[i].subsys.size()] (subsys);
00654          domains = new [n + this.domains[i].subsys.size()] (domains);
00655       
00656          foreach (this.domains[i].subsys[j]) begin
00657             subsys[n+j]  = this.domains[i].subsys[j];
00658             domains[n+j] = this.domains[i].sys_domains[j];
00659          end
00660       end
00661    end
00662    else begin
00663       vmm_ral_sys_domain dom;
00664       int i;
00665 
00666       i = this.get_domain_index(domain);
00667       if (i < 0) return;
00668 
00669       dom = this.domains[i];
00670       subsys = new [dom.subsys.size()];
00671       domains = new [dom.subsys.size()];
00672 
00673       foreach (dom.subsys[j]) begin
00674          subsys[j]  = dom.subsys[j];
00675          domains[j] = dom.sys_domains[j];
00676       end
00677    end
00678 endfunction: get_subsys
00679 
00680 
00681 function void vmm_ral_sys::get_all_subsys(ref vmm_ral_sys subsys[],
00682                                           ref string      domains[],
00683                                           input string    domain);
00684    vmm_ral_sys   sys[];
00685    string        subdoms[];
00686    vmm_ral_sys   ss[];
00687    string        doms[];
00688 
00689    subsys  = new [0];
00690    domains = new[0];
00691 
00692    this.get_subsys(sys, subdoms, domain);
00693 
00694    foreach (sys[i]) begin
00695       int n = subsys.size() + 1;
00696       
00697       sys[i].get_all_subsys(ss, doms, subdoms[i]);
00698       subsys  = new [n + ss.size()] (subsys);
00699       domains = new [n + ss.size()] (domains);
00700 
00701       subsys[n-1]  = sys[i];
00702       domains[n-1] = subdoms[i];
00703 
00704       foreach (ss[j]) begin
00705          subsys[n+j]  = ss[j];
00706          domains[n+j] = doms[j];
00707       end
00708    end
00709 endfunction: get_all_subsys
00710 
00711 
00712 function vmm_ral_sys vmm_ral_sys::get_subsys_by_name(string name);
00713    vmm_ral_sys subsys[];
00714    string      d[];
00715 
00716    this.get_all_subsys(subsys, d);
00717    foreach (subsys[i]) begin
00718       if (subsys[i].get_name() == name) begin
00719          return subsys[i];
00720       end
00721    end
00722    `vmm_warning(this.log, $psprintf("Unable to locate subsystem \"%s\" in system \"%s\".",
00723                                     name, this.get_fullname()));
00724    get_subsys_by_name = null;
00725 endfunction: get_subsys_by_name
00726 
00727 
00728 function vmm_ral_sys vmm_ral_sys::get_subsys_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00729                                                        string                        domain);
00730 endfunction: get_subsys_by_offset
00731 
00732                                                        
00733 function bit vmm_ral_sys::set_cover(bit is_on);
00734    set_cover = super.set_cover(is_on);
00735 
00736    if (is_on && !super.is_cover_on()) return set_cover;
00737 
00738    foreach (this.domains[i]) begin
00739       foreach (this.domains[i].blocks[j]) begin
00740          this.domains[i].blocks[j].set_cover(is_on);
00741       end
00742       foreach (this.domains[i].subsys[j]) begin
00743          this.domains[i].subsys[j].set_cover(is_on);
00744       end
00745    end
00746 endfunction: set_cover
00747 
00748 
00749 function void vmm_ral_sys::reset(string           domain,
00750                                  vmm_ral::reset_e kind);
00751    if (domain == "" && this.domains.size() > 1) begin
00752       foreach (this.domains[i]) begin
00753          foreach (this.domains[i].blocks[j]) begin
00754             this.domains[i].blocks[j].reset(this.domains[i].blk_domains[j],
00755                                             kind);
00756          end
00757          foreach (this.domains[i].subsys[j]) begin
00758             this.domains[i].subsys[j].reset(this.domains[i].sys_domains[j],
00759                                             kind);
00760          end
00761       end
00762    end
00763    else begin
00764       int i;
00765 
00766       i = this.get_domain_index(domain);
00767       if (i < 0) return;
00768 
00769       foreach (this.domains[i].blocks[j]) begin
00770          this.domains[i].blocks[j].reset(this.domains[i].blk_domains[j],
00771                                          kind);
00772       end
00773       foreach (this.domains[i].subsys[j]) begin
00774          this.domains[i].subsys[j].reset(this.domains[i].sys_domains[j],
00775                                          kind);
00776       end
00777    end
00778 endfunction: reset
00779 
00780 
00781 function bit vmm_ral_sys::needs_update();
00782    needs_update = 0;
00783    foreach (this.domains[i]) begin
00784       foreach (this.domains[i].blocks[j]) begin
00785          if (this.domains[i].blocks[j].needs_update()) begin
00786             return 1;
00787          end
00788       end
00789       foreach (this.domains[i].subsys[j]) begin
00790          if (this.domains[i].subsys[j].needs_update()) begin
00791             return 1;
00792          end
00793       end
00794    end
00795 endfunction: needs_update
00796 
00797 
00798 task vmm_ral_sys::update(output vmm_rw::status_e status,
00799                          input  vmm_ral::path_e  path);
00800    status = vmm_rw::IS_OK;
00801    foreach (this.domains[i]) begin
00802       foreach (this.domains[i].blocks[j]) begin
00803          this.domains[i].blocks[j].update(status, path);
00804          if (status != vmm_rw::IS_OK) return;
00805       end
00806       foreach (this.domains[i].subsys[j]) begin
00807          this.domains[i].subsys[j].update(status, path);
00808          if (status != vmm_rw::IS_OK) return;
00809       end
00810    end
00811 endtask: update
00812 
00813 
00814 task vmm_ral_sys::mirror(output vmm_rw::status_e status,
00815                          input  vmm_ral::check_e check,
00816                          input  vmm_ral::path_e  path);
00817    status = vmm_rw::IS_OK;
00818    foreach (this.domains[i]) begin
00819       foreach (this.domains[i].blocks[j]) begin
00820          this.domains[i].blocks[j].mirror(status, check, path);
00821          if (status != vmm_rw::IS_OK) return;
00822       end
00823       foreach (this.domains[i].subsys[j]) begin
00824          this.domains[i].subsys[j].mirror(status, check, path);
00825          if (status != vmm_rw::IS_OK) return;
00826       end
00827    end
00828 endtask: mirror
00829 
00830 
00831 task vmm_ral_sys::readmemh(string filename);
00832 endtask: readmemh
00833 
00834 
00835 task vmm_ral_sys::writememh(string filename);
00836 endtask: writememh
00837 
00838 
00839 function int unsigned vmm_ral_sys::get_sys_ID();
00840    get_sys_ID =  this.__vmm_sys_id;
00841 endfunction
00842 
00843 function vmm_ral_sys vmm_ral_sys::get_sys_by_ID(int unsigned id);
00844    if (__vmm_all_systems.exists(id)) get_sys_by_ID = __vmm_all_systems[id];
00845    else get_sys_by_ID = null;
00846 endfunction