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