VMM - RAL/vmm_ral_block_or_sys.sv

RAL/vmm_ral_block_or_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 virtual class vmm_ral_block_or_sys;
00024    static vmm_log log = new("RAL", "Block/Sys"); 
00025 
00026    vmm_ral::path_e default_access = vmm_ral::DEFAULT;
00027 
00028    protected static int unsigned __vmm_block_or_sys_id_factory = 0;
00029    local bit locked;
00030 
00031    local string name;
00032    local string typename;
00033 
00034    local string                        domains[];
00035    local string                        in_domains[]; // For each domain
00036    local int unsigned                  n_bytes[];    // For each domain
00037    local vmm_ral::endianness_e         endian[];     // For each domain
00038    local bit [`VMM_RAL_ADDR_WIDTH-1:0] base_addr[];  // For each domain
00039    local string                        constr[];     // Constraint blocks
00040 
00041    local vmm_ral_sys parent;
00042    protected vmm_ral_access ral_access;
00043 
00044    local bit no_cover;
00045    local bit cover_on;
00046 
00047    extern function new(vmm_ral_sys                   parent,
00048                        string                        block_or_sys,
00049                        string                        name,
00050                        string                        typename,
00051                        int unsigned                  n_bytes,
00052                        vmm_ral::endianness_e         endian,
00053                        bit [`VMM_RAL_ADDR_WIDTH-1:0] base_addr,
00054                        string                        domain = "",
00055                        bit                           cover_on = 1);
00056 
00057    /*local*/ extern virtual function void Xlock_modelX();
00058    /*local*/ extern function bit Xis_lockedX();
00059    /*local*/ extern virtual function void add_domain(int unsigned          n_bytes,
00060                                                      vmm_ral::endianness_e endian,
00061                                                      string                domain);
00062    /*local*/ extern virtual function void map_domain(string                        domain,
00063                                                      string                        in_domain,
00064                                                      bit [`VMM_RAL_ADDR_WIDTH-1:0] base_addr);
00065    /*local*/ extern virtual function void Xregister_ral_accessX(vmm_ral_access access);
00066    /*local*/ extern function void Xadd_constraintsX(string name);
00067    
00068    extern virtual function string get_name();
00069    extern virtual function string get_type();
00070    extern virtual function string get_fullname();
00071    extern function void get_domains(ref string names[]);
00072    extern virtual function vmm_ral_sys get_parent();
00073    extern virtual function bit [`VMM_RAL_ADDR_WIDTH-1:0] get_base_addr(string domain = "");
00074    extern virtual function int unsigned get_n_bytes(string domain = "");
00075    extern virtual function vmm_ral::endianness_e get_endian(string domain = "");
00076    extern virtual function vmm_ral::path_e get_default_access();
00077    extern virtual function string get_parent_domain(string domain = "");
00078    extern virtual function string get_external_domain(string domain = "");
00079 
00080    extern virtual function void display(string prefix = "",
00081                                         string domain = "");
00082    extern virtual function string psdisplay(string prefix = "",
00083                                             string domain = "");
00084 
00085    extern virtual function void get_fields(ref vmm_ral_field fields[],
00086                                            input string      domain = ""); 
00087    extern virtual function vmm_ral_field get_field_by_name(string name);
00088 
00089    extern virtual function void get_registers(ref vmm_ral_reg regs[],
00090                                               input string    domain = "");
00091    extern virtual function void get_virtual_registers(ref vmm_ral_vreg vregs[],
00092                                                       input string    domain = "");
00093    extern virtual function vmm_ral_reg get_reg_by_name(string name);
00094    extern virtual function vmm_ral_reg get_reg_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00095                                                          string                        domain = "");
00096 
00097    extern virtual function void get_memories(ref vmm_ral_mem mems[],
00098                                              input string    domain = "");
00099    extern virtual function vmm_ral_mem get_mem_by_name(string name);
00100    extern virtual function vmm_ral_mem get_mem_by_offset(bit [`VMM_RAL_ADDR_WIDTH-1:0] offset,
00101                                                          string                        domain = "");
00102 
00103    extern virtual function void get_constraints(ref string names[]);
00104 
00105    extern virtual function bit set_cover(bit is_on);
00106    extern virtual function bit is_cover_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    extern virtual task update(output vmm_rw::status_e status,
00112                               input  vmm_ral::path_e  path = vmm_ral::DEFAULT);
00113    extern virtual task mirror(output vmm_rw::status_e status,
00114                               input  vmm_ral::check_e check = vmm_ral::QUIET,
00115                               input  vmm_ral::path_e  path  = vmm_ral::DEFAULT);
00116    
00117    extern virtual task readmemh(string filename);
00118    extern virtual task writememh(string filename);
00119 
00120    extern function void prepend_callback(vmm_ral_callbacks cbs);
00121    extern function void append_callback(vmm_ral_callbacks cbs);
00122    extern function void unregister_callback(vmm_ral_callbacks cbs);
00123 
00124    extern protected function int get_domain_index(string domain);
00125 
00126    extern /*static*/ function vmm_ral_block_or_sys get_block_or_sys_by_ID(int unsigned id);
00127 endclass: vmm_ral_block_or_sys
00128    
00129 
00130 function vmm_ral_block_or_sys::new(vmm_ral_sys                   parent,
00131                                    string                        block_or_sys,
00132                                    string                        name,
00133                                    string                        typename,
00134                                    int unsigned                  n_bytes,
00135                                    vmm_ral::endianness_e         endian,
00136                                    bit [`VMM_RAL_ADDR_WIDTH-1:0] base_addr,
00137                                    string                        domain,
00138                                    bit                           cover_on);
00139    this.locked = 0;
00140 
00141    this.name = name;
00142    this.typename = typename;
00143    begin
00144       vmm_ral_block_or_sys p = parent;
00145       if (p == this) parent = null;
00146    end
00147    this.parent = parent;
00148 
00149    this.domains   = new [1]; this.domains[0]   = domain;
00150    this.in_domains= new [1]; this.in_domains[0]= "";
00151    this.n_bytes   = new [1]; this.n_bytes[0]   = n_bytes;
00152    this.endian    = new [1]; this.endian[0]    = endian;
00153    this.base_addr = new [1]; this.base_addr[0] = base_addr;
00154 
00155    this.cover_on = cover_on;
00156    this.no_cover = !cover_on;
00157 endfunction: new
00158 
00159 function void vmm_ral_block_or_sys::Xlock_modelX();
00160    this.locked = 1;
00161 endfunction: Xlock_modelX
00162 
00163 
00164 function bit vmm_ral_block_or_sys::Xis_lockedX();
00165    Xis_lockedX = this.locked;
00166 endfunction: Xis_lockedX
00167 
00168 
00169 function void vmm_ral_block_or_sys::add_domain(int unsigned          n_bytes,
00170                                                vmm_ral::endianness_e endian,
00171                                                string                domain);
00172    int n;
00173 
00174    if (this.locked) begin
00175       `vmm_error(this.log, "Cannot add domain to locked model");
00176       return;
00177    end
00178 
00179    n = this.domains.size();
00180    this.domains   = new [n+1] (this.domains);   this.domains[n]   = domain;
00181    this.in_domains= new [n+1] (this.in_domains);this.in_domains[n]= "";
00182    this.n_bytes   = new [n+1] (this.n_bytes);   this.n_bytes[n]   = n_bytes;
00183    this.endian    = new [n+1] (this.endian);    this.endian[n]    = endian;
00184    this.base_addr = new [n+1] (this.base_addr); this.base_addr[n] = 0;
00185 endfunction: add_domain
00186 
00187 
00188 function void vmm_ral_block_or_sys::map_domain(string                        domain,
00189                                                string                        in_domain,
00190                                                bit [`VMM_RAL_ADDR_WIDTH-1:0] base_addr);
00191    int n;
00192 
00193    n = this.get_domain_index(domain);
00194    if (n < 0) return;
00195 
00196    if (this.in_domains[n] != "") begin
00197       `vmm_error(this.log, $psprintf("Domain \"%s\" already mapped in domain \"%s\" @'h%h in %s",
00198                                      domain, in_domains[n], base_addr[n],
00199                                      this.get_fullname()));
00200       return;
00201    end
00202 
00203    this.in_domains[n] = in_domain;
00204    this.base_addr[n]  = base_addr;
00205 endfunction: map_domain
00206 
00207 
00208 function void vmm_ral_block_or_sys::Xadd_constraintsX(string name);
00209    int n;
00210 
00211    if (this.locked) begin
00212       `vmm_error(this.log, "Cannot add constraints to locked model");
00213       return;
00214    end
00215 
00216    // Check if the constraint block already exists
00217    foreach (this.constr[i]) begin
00218       if (this.constr[i] == name) begin
00219          `vmm_warning(this.log, $psprintf("Constraint \"%s\" already added",
00220                                           name));
00221          return;
00222       end
00223    end
00224 
00225    // Append the constraint name to the list
00226    n = this.constr.size();
00227    this.constr = new [n+1] (this.constr);
00228    this.constr[n] = name;
00229 endfunction: Xadd_constraintsX
00230 
00231 
00232 function string vmm_ral_block_or_sys::get_name();
00233    get_name = this.name;
00234 endfunction: get_name
00235 
00236 
00237 function string vmm_ral_block_or_sys::get_type();
00238    return this.typename;
00239 endfunction: get_type
00240 
00241 
00242 function string vmm_ral_block_or_sys::get_fullname();
00243    vmm_ral_block_or_sys bos;
00244 
00245    get_fullname = this.get_name();
00246 
00247    // Do not include top-level name in full name
00248    bos = this.get_parent();
00249    if (bos == null) return get_fullname;
00250    if (bos.get_parent() == null) return get_fullname;
00251 
00252    get_fullname = {this.parent.get_fullname(), ".", get_fullname};
00253 endfunction: get_fullname
00254 
00255 
00256 function void vmm_ral_block_or_sys::get_domains(ref string names[]);
00257    names = new [this.domains.size()] (this.domains);
00258 endfunction: get_domains
00259 
00260 
00261 function vmm_ral_sys vmm_ral_block_or_sys::get_parent();
00262    get_parent = this.parent;
00263 endfunction: get_parent
00264 
00265 
00266 function bit [`VMM_RAL_ADDR_WIDTH-1:0] vmm_ral_block_or_sys::get_base_addr(string domain);
00267    int i;
00268 
00269    i = this.get_domain_index(domain);
00270    if (i < 0) return 0;
00271    get_base_addr = this.base_addr[i];
00272 endfunction: get_base_addr
00273 
00274 
00275 function int unsigned vmm_ral_block_or_sys::get_n_bytes(string domain);
00276    int i;
00277 
00278    i = this.get_domain_index(domain);
00279    if (i < 0) return 0;
00280    get_n_bytes = this.n_bytes[i];
00281 endfunction: get_n_bytes
00282 
00283 
00284 function vmm_ral::endianness_e vmm_ral_block_or_sys::get_endian(string domain);
00285    int i;
00286 
00287    i = this.get_domain_index(domain);
00288    if (i < 0) return vmm_ral::LITTLE_ENDIAN;
00289    get_endian = this.endian[i];
00290 endfunction: get_endian
00291 
00292 
00293 function vmm_ral::path_e vmm_ral_block_or_sys::get_default_access();
00294    if (this.default_access != vmm_ral::DEFAULT) begin
00295       return this.default_access;
00296    end
00297 
00298    if (this.parent != null) begin
00299       return this.parent.get_default_access();
00300    end
00301 
00302    // Default access is defined by RAL access
00303    if (this.ral_access != null) begin
00304       get_default_access = this.ral_access.default_path;
00305    end
00306    else begin
00307       `vmm_fatal(log, $psprintf("RAL model for \"%s\" is not associated with a RAL access interface", this.get_fullname()));
00308       get_default_access = vmm_ral::BFM;
00309    end
00310 
00311    if (get_default_access == vmm_ral::DEFAULT) begin
00312       // Front door by default
00313       get_default_access = vmm_ral::BFM;
00314    end
00315 endfunction: get_default_access
00316 
00317 
00318 function string vmm_ral_block_or_sys::get_parent_domain(string domain);
00319    int i;
00320 
00321    // if this is the top-most block or system, there is no parent!
00322    if (this.parent == null) return domain;
00323 
00324    i = this.get_domain_index(domain);
00325    if (i < 0) return domain;
00326 
00327    return this.in_domains[i];
00328 endfunction: get_parent_domain
00329 
00330 
00331 function string vmm_ral_block_or_sys::get_external_domain(string domain);
00332    int i;
00333 
00334    // if this is the top-most block or system, there is no parent!
00335    if (this.parent == null) return domain;
00336 
00337    i = this.get_domain_index(domain);
00338    if (i < 0) return domain;
00339    return this.parent.get_external_domain(this.in_domains[i]);
00340 endfunction: get_external_domain
00341 
00342 
00343 function void vmm_ral_block_or_sys::display(string prefix,
00344                                             string domain);
00345    $write("%s\n", this.psdisplay(prefix, domain));
00346 endfunction: display
00347 
00348 
00349 function void vmm_ral_block_or_sys::get_constraints(ref string names[]);
00350    names = new [this.constr.size()] (this.constr);
00351 endfunction: get_constraints
00352 
00353 
00354 function bit vmm_ral_block_or_sys::set_cover(bit is_on);
00355    set_cover = this.cover_on;
00356 
00357    if (this.no_cover && is_on) begin
00358       `vmm_warning(this.log, $psprintf("Cannot turn cover ON in %s if constructed with coverage disabled", this.get_fullname()));
00359       return 0;
00360    end
00361 
00362    this.cover_on = is_on;
00363 endfunction: set_cover
00364 
00365 
00366 function bit vmm_ral_block_or_sys::is_cover_on();
00367    is_cover_on = this.cover_on;
00368 endfunction: is_cover_on
00369 
00370 
00371 function void vmm_ral_block_or_sys::prepend_callback(vmm_ral_callbacks cbs);
00372 endfunction: prepend_callback
00373 
00374 
00375 function void vmm_ral_block_or_sys::append_callback(vmm_ral_callbacks cbs);
00376 endfunction: append_callback
00377 
00378 
00379 function void vmm_ral_block_or_sys::unregister_callback(vmm_ral_callbacks cbs);
00380 endfunction: unregister_callback
00381 
00382 
00383 function int vmm_ral_block_or_sys::get_domain_index(string domain);
00384    // If the domain is "" and there is only one domain,
00385    // assume it is the one domain available to avoid
00386    // having to always have to specify domains
00387    if (domain == "" && this.domains.size() == 1) return 0;
00388 
00389    foreach (this.domains[i]) begin
00390       if (this.domains[i] == domain) return i;
00391    end
00392    `vmm_warning(this.log, $psprintf("Unknown domain name \"%s\" in %s.",
00393                                     domain, this.get_fullname()));
00394    return -1;
00395 endfunction: get_domain_index
00396 
00397 
00398 function vmm_ral_block_or_sys vmm_ral_block_or_sys::get_block_or_sys_by_ID(int unsigned id);
00399    vmm_ral_block blk;
00400    blk = blk.get_block_by_ID(id);
00401    if (blk != null) get_block_or_sys_by_ID = blk;
00402    else begin
00403       vmm_ral_sys sys;
00404       sys = sys.get_sys_by_ID(id);
00405       if (sys != null) get_block_or_sys_by_ID = sys;
00406       else get_block_or_sys_by_ID = null;
00407    end
00408 endfunction