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