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_vreg.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: typedef class vmm_mam_region; 00024: typedef class vmm_mam; 00025: 00026: 00027: class vmm_ral_vreg_callbacks extends vmm_ral_callbacks; 00028: 00029: virtual task pre_write(vmm_ral_vreg rg, 00030: longint unsigned idx, 00031: ref bit [64-1:0] wdat, 00032: ref vmm_ral::path_e path, 00033: ref string domain); 00034: endtask: pre_write 00035: 00036: virtual task post_write(vmm_ral_vreg rg, 00037: longint unsigned idx, 00038: bit [64-1:0] wdat, 00039: vmm_ral::path_e path, 00040: string domain, 00041: ref vmm_rw::status_e status); 00042: endtask: post_write 00043: 00044: virtual task pre_read(vmm_ral_vreg rg, 00045: longint unsigned idx, 00046: ref vmm_ral::path_e path, 00047: ref string domain); 00048: endtask: pre_read 00049: 00050: virtual task post_read(vmm_ral_vreg rg, 00051: longint unsigned idx, 00052: ref bit [64-1:0] rdat, 00053: input vmm_ral::path_e path, 00054: input string domain, 00055: ref vmm_rw::status_e status); 00056: endtask: post_read 00057: endclass: vmm_ral_vreg_callbacks 00058: 00059: 00060: class vmm_ral_vreg; 00061: static vmm_log log = new("RAL", "virtual register"); 00062: 00063: local bit locked; 00064: local vmm_ral_block parent; 00065: local string name; 00066: local int unsigned n_bits; 00067: local int unsigned n_used_bits; 00068: 00069: local vmm_ral_vfield fields[$]; // Fields in LSB to MSB order 00070: 00071: local vmm_ral_vreg_callbacks callbacks[$]; 00072: 00073: local vmm_ral_mem mem; // Where is it implemented? 00074: local bit [64-1:0] offset; // Start of vreg[0] 00075: local int unsigned incr; // From start to start of next 00076: local longint unsigned size; //number of vregs 00077: local bit is_static; 00078: 00079: local vmm_mam_region region; // Not NULL if implemented via MAM 00080: 00081: local semaphore atomic; // Field RMW operations must be atomic 00082: 00083: extern /*local*/ function new(vmm_ral_block parent, 00084: string name, 00085: int unsigned n_bits, 00086: bit [64-1:0] offset = 0, 00087: vmm_ral_mem mem = null, 00088: longint unsigned size = 0, 00089: int unsigned incr = 0); 00090: 00091: /*local*/ extern function void Xlock_modelX(); 00092: 00093: /*local*/ extern function void register_field(vmm_ral_vfield field); 00094: /*local*/ extern task XatomicX(bit on); 00095: 00096: extern function void reset(vmm_ral::reset_e kind = vmm_ral::HARD); 00097: 00098: extern virtual function string get_name(); 00099: extern virtual function string get_fullname(); 00100: extern virtual function vmm_ral_block get_block(); 00101: 00102: extern virtual function bit implement(longint unsigned n, 00103: vmm_ral_mem mem = null, 00104: bit [64-1:0] offset = 0, 00105: int unsigned incr = 0); 00106: extern virtual function vmm_mam_region allocate(longint unsigned n, 00107: vmm_mam mam); 00108: extern virtual function vmm_mam_region get_region(); 00109: extern virtual function void release_region(); 00110: 00111: extern virtual function vmm_ral_mem get_memory(); 00112: extern virtual function int get_n_domains(); 00113: extern virtual function void get_domains(ref string domains[]); 00114: extern virtual function vmm_ral::access_e get_access(string domain = ""); 00115: extern virtual function vmm_ral::access_e get_rights(string domain = ""); 00116: extern virtual function bit [64-1:0] get_offset_in_memory(longint unsigned idx); 00117: 00118: extern virtual function bit [64-1:0] get_address_in_system(longint unsigned idx, 00119: string domain = ""); 00120: 00121: extern virtual function int unsigned get_size(); 00122: extern virtual function int unsigned get_n_bytes(); 00123: extern virtual function int unsigned get_n_memlocs(); 00124: extern virtual function int unsigned get_incr(); 00125: 00126: extern virtual function void display(string prefix = "", 00127: string domain = ""); 00128: extern virtual function string psdisplay(string prefix = "", 00129: string domain = ""); 00130: 00131: extern virtual function void get_fields(ref vmm_ral_vfield fields[]); 00132: extern virtual function vmm_ral_vfield get_field_by_name(string name); 00133: 00134: extern virtual task write(input longint unsigned idx, 00135: output vmm_rw::status_e status, 00136: input bit[64-1:0] value, 00137: input vmm_ral::path_e path = vmm_ral::DEFAULT, 00138: input string domain = "", 00139: input int data_id = -1, 00140: input int scenario_id = -1, 00141: input int stream_id = -1); 00142: extern virtual task read(input longint unsigned idx, 00143: output vmm_rw::status_e status, 00144: output bit[64-1:0] value, 00145: input vmm_ral::path_e path = vmm_ral::DEFAULT, 00146: input string domain = "", 00147: input int data_id = -1, 00148: input int scenario_id = -1, 00149: input int stream_id = -1); 00150: extern virtual task poke(input longint unsigned idx, 00151: output vmm_rw::status_e status, 00152: input bit[64-1:0] value, 00153: input int data_id = -1, 00154: input int scenario_id = -1, 00155: input int stream_id = -1); 00156: extern virtual task peek(input longint unsigned idx, 00157: output vmm_rw::status_e status, 00158: output bit[64-1:0] value, 00159: input int data_id = -1, 00160: input int scenario_id = -1, 00161: input int stream_id = -1); 00162: 00163: extern function void prepend_callback(vmm_ral_vreg_callbacks cb); 00164: extern function void append_callback(vmm_ral_vreg_callbacks cb); 00165: extern function void unregister_callback(vmm_ral_vreg_callbacks cb); 00166: endclass: vmm_ral_vreg 00167: 00168: 00169: function vmm_ral_vreg::new(vmm_ral_block parent, 00170: string name, 00171: int unsigned n_bits, 00172: bit [64-1:0] offset, 00173: vmm_ral_mem mem, 00174: longint unsigned size, 00175: int unsigned incr); 00176: this.locked = 0; 00177: 00178: this.parent = parent; 00179: this.parent.register_vreg(this); 00180: this.name = name; 00181: 00182: if (n_bits == 0) begin 00183: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual register \"%s\" cannot have 0 bits", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00184: n_bits = 1; 00185: end 00186: if (n_bits > 64) begin 00187: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual register \"%s\" cannot have more than %0d bits (%0d)", this.get_fullname(), 64, n_bits))); : this.log.end_msg(); : end : while (0); 00188: n_bits = 64; 00189: end 00190: this.n_bits = n_bits; 00191: this.n_used_bits = 0; 00192: 00193: if (mem != null) begin 00194: this.implement(size, mem, offset, incr); 00195: this.is_static = 1; 00196: end 00197: else begin 00198: this.mem = null; 00199: this.is_static = 0; 00200: end 00201: 00202: this.atomic = new(1); 00203: endfunction: new 00204: 00205: 00206: function void vmm_ral_vreg::Xlock_modelX(); 00207: if (this.locked) return; 00208: 00209: this.locked = 1; 00210: endfunction: Xlock_modelX 00211: 00212: 00213: function void vmm_ral_vreg::register_field(vmm_ral_vfield field); 00214: int offset; 00215: int idx; 00216: 00217: if (this.locked) begin 00218: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text("Cannot add virtual field to locked virtual register model")); : this.log.end_msg(); : end : while (0); 00219: return; 00220: end 00221: 00222: 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 virtual field")); : this.log.end_msg(); : end : while (0); 00223: 00224: // Store fields in LSB to MSB order 00225: offset = field.get_lsb_pos_in_register(); 00226: 00227: idx = -1; 00228: foreach (this.fields[i]) begin 00229: if (offset < this.fields[i].get_lsb_pos_in_register()) begin 00230: int j = i; 00231: this.fields.insert(j, field); 00232: idx = i; 00233: break; 00234: end 00235: end 00236: if (idx < 0) begin 00237: this.fields.push_back(field); 00238: idx = this.fields.size()-1; 00239: end 00240: 00241: this.n_used_bits += field.get_n_bits(); 00242: 00243: // Check if there are too many fields in the register 00244: if (this.n_used_bits > this.n_bits) begin 00246: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual fields use more bits (%0d) than available in virtual register \"%s\" (%0d)", : this.n_used_bits, this.get_fullname(), this.n_bits))); : this.log.end_msg(); : end : while (0); 00247: end 00248: 00249: // Check if there are overlapping fields 00250: if (idx > 0) begin 00251: if (this.fields[idx-1].get_lsb_pos_in_register() + 00252: this.fields[idx-1].get_n_bits() > offset) begin 00256: : 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 virtual register \"%s\"", : this.fields[idx-1].get_name(), : field.get_name(), : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00257: end 00258: end 00259: if (idx < this.fields.size()-1) begin 00260: if (offset + field.get_n_bits() > 00261: this.fields[idx+1].get_lsb_pos_in_register()) begin 00266: : 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 virtual register \"%s\"", : field.get_name(), : this.fields[idx+1].get_name(), : : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00267: end 00268: end 00269: endfunction: register_field 00270: 00271: 00272: task vmm_ral_vreg::XatomicX(bit on); 00273: if (on) this.atomic.get(1); 00274: else begin 00275: // Maybe a key was put back in by a spurious call to reset() 00276: this.atomic.try_get(1); 00277: this.atomic.put(1); 00278: end 00279: endtask: XatomicX 00280: 00281: 00282: function void vmm_ral_vreg::reset(vmm_ral::reset_e kind); 00283: // Put back a key in the semaphore if it is checked out 00284: // in case a thread was killed during an operation 00285: this.atomic.try_get(1); 00286: this.atomic.put(1); 00287: endfunction: reset 00288: 00289: 00290: function string vmm_ral_vreg::get_name(); 00291: return this.name; 00292: endfunction: get_name 00293: 00294: 00295: function string vmm_ral_vreg::get_fullname(); 00296: vmm_ral_block blk; 00297: 00298: get_fullname = this.get_name(); 00299: 00300: // Do not include top-level name in full name 00301: blk = this.get_block(); 00302: if (blk == null) return get_fullname; 00303: if (blk.get_parent() == null) return get_fullname; 00304: 00305: get_fullname = {this.parent.get_fullname(), ".", get_fullname}; 00306: endfunction: get_fullname 00307: 00308: 00309: function vmm_ral_block vmm_ral_vreg::get_block(); 00310: get_block = this.parent; 00311: endfunction: get_block 00312: 00313: 00314: function bit vmm_ral_vreg::implement(longint unsigned n, 00315: vmm_ral_mem mem, 00316: bit [64-1:0] offset, 00317: int unsigned incr); 00318: if (mem == null) begin 00319: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Attempting to implement virtual register \"%s\" using a NULL vmm_ral_mem reference", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00320: return 0; 00321: end 00322: 00323: if (this.is_static) begin 00324: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual register \"%s\" is static and cannot be dynamically implemented", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00325: return 0; 00326: end 00327: 00328: if (mem.get_block() != this.parent) begin 00331: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Attempting to implement virtual register \"%s\" on memory \"%s\" in a different block", : this.get_fullname(), : mem.get_fullname()))); : this.log.end_msg(); : end : while (0); 00332: return 0; 00333: end 00334: 00335: begin 00336: int min_incr = (this.get_n_bytes()-1) / mem.get_n_bytes() + 1; 00337: if (incr == 0) incr = min_incr; 00338: if (min_incr > incr) begin 00341: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual register \"%s\" increment is too small (%0d): Each virtual register requires at least %0d locations in memory \"%s\".", : this.get_fullname(), incr, : min_incr, mem.get_fullname()))); : this.log.end_msg(); : end : while (0); 00342: return 0; 00343: end 00344: end 00345: 00346: // Is the memory big enough for ya? 00347: if (offset + (n * incr) > mem.get_size()) begin 00348: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual register \"%s[%0d]\" is too big for memory %s@'h%0h", this.get_fullname(), n, mem.get_fullname(), offset))); : this.log.end_msg(); : end : while (0); 00349: return 0; 00350: end 00351: 00352: if (this.mem != null) begin 00357: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Virtual register \"%s\" is being moved re-implemented from %s@'h%0h to %s@'h%0h", : this.get_fullname(), : this.mem.get_fullname(), : this.offset, : mem.get_fullname(), offset))); : this.log.end_msg(); : end : while (0); 00358: this.release_region(); 00359: end 00360: 00361: this.mem = mem; 00362: this.size = n; 00363: this.offset = offset; 00364: this.incr = incr; 00365: this.mem.XvregsX.push_back(this); 00366: 00367: return 1; 00368: endfunction: implement 00369: 00370: 00371: function vmm_mam_region vmm_ral_vreg::allocate(longint unsigned n, 00372: vmm_mam mam); 00373: 00374: vmm_ral_mem mem; 00375: 00376: if (mam == null) begin 00377: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Attempting to implement virtual register \"%s\" using a NULL vmm_mam reference", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00378: return null; 00379: end 00380: 00381: if (this.is_static) begin 00382: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual register \"%s\" is static and cannot be dynamically allocated", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00383: return null; 00384: end 00385: 00386: mem = mam.get_memory(); 00387: if (mem.get_block() != this.parent) begin 00390: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Attempting to allocate virtual register \"%s\" on memory \"%s\" in a different block", : this.get_fullname(), : mem.get_fullname()))); : this.log.end_msg(); : end : while (0); 00391: return null; 00392: end 00393: 00394: begin 00395: int min_incr = (this.get_n_bytes()-1) / mem.get_n_bytes() + 1; 00396: if (incr == 0) incr = min_incr; 00397: if (min_incr < incr) begin 00400: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual register \"%s\" increment is too small (%0d): Each virtual register requires at least %0d locations in memory \"%s\".", : this.get_fullname(), incr, : min_incr, mem.get_fullname()))); : this.log.end_msg(); : end : while (0); 00401: return null; 00402: end 00403: end 00404: 00405: // Need memory at least of size num_vregs*sizeof(vreg) in bytes. 00406: allocate = mam.request_region(n*incr*mem.get_n_bytes()); 00407: if (allocate == null) begin 00408: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Could not allocate a memory region for virtual register \"%s\"", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00409: return null; 00410: end 00411: 00412: if (this.mem != null) begin 00418: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Virtual register \"%s\" is being moved re-allocated from %s@'h%0h to %s@'h%0h", : this.get_fullname(), : this.mem.get_fullname(), : this.offset, : mem.get_fullname(), : allocate.get_start_offset()))); : this.log.end_msg(); : end : while (0); 00419: 00420: this.release_region(); 00421: end 00422: 00423: this.region = allocate; 00424: 00425: this.mem = mam.get_memory(); 00426: this.offset = allocate.get_start_offset(); 00427: this.size = n; 00428: this.incr = incr; 00429: 00430: this.mem.XvregsX.push_back(this); 00431: endfunction: allocate 00432: 00433: 00434: function vmm_mam_region vmm_ral_vreg::get_region(); 00435: return this.region; 00436: endfunction: get_region 00437: 00438: 00439: function void vmm_ral_vreg::release_region(); 00440: if (this.is_static) begin 00441: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual register \"%s\" is static and cannot be dynamically released", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00442: return; 00443: end 00444: 00445: if (this.mem != null) begin 00446: foreach (this.mem.XvregsX[i]) begin 00447: if (this.mem.XvregsX[i] == this) begin 00448: this.mem.XvregsX.delete(i); 00449: break; 00450: end 00451: end 00452: end 00453: if (this.region != null) begin 00454: this.region.release_region(); 00455: end 00456: 00457: this.region = null; 00458: this.mem = null; 00459: this.size = 0; 00460: this.offset = 0; 00461: 00462: this.reset(); 00463: endfunction: release_region 00464: 00465: 00466: function vmm_ral_mem vmm_ral_vreg::get_memory(); 00467: return this.mem; 00468: endfunction: get_memory 00469: 00470: 00471: function bit [64-1:0] vmm_ral_vreg::get_offset_in_memory(longint unsigned idx); 00472: if (this.mem == null) begin 00474: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_offset_in_memory() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00475: return 0; 00476: end 00477: 00478: return this.offset + idx * this.incr; 00479: endfunction 00480: 00481: 00482: function bit [64-1:0] vmm_ral_vreg::get_address_in_system(longint unsigned idx, 00483: string domain); 00484: if (this.mem == null) begin 00485: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot get address of of unimplemented virtual register \"%s\".", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00486: return 0; 00487: end 00488: 00489: return this.mem.get_address_in_system(this.get_offset_in_memory(idx), 00490: domain); 00491: endfunction: get_address_in_system 00492: 00493: 00494: function int unsigned vmm_ral_vreg::get_size(); 00495: if (this.size == 0) begin 00497: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_size() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00498: return 0; 00499: end 00500: 00501: return this.size; 00502: endfunction: get_size 00503: 00504: 00505: function int unsigned vmm_ral_vreg::get_n_bytes(); 00506: return ((this.n_bits-1) / 8) + 1; 00507: endfunction: get_n_bytes 00508: 00509: 00510: function int unsigned vmm_ral_vreg::get_n_memlocs(); 00511: if (this.mem == null) begin 00513: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_n_memlocs() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00514: return 0; 00515: end 00516: 00517: return (this.get_n_bytes()-1) / this.mem.get_n_bytes() + 1; 00518: endfunction: get_n_memlocs 00519: 00520: 00521: function int unsigned vmm_ral_vreg::get_incr(); 00522: if (this.incr == 0) begin 00524: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_incr() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00525: return 0; 00526: end 00527: 00528: return this.incr; 00529: endfunction: get_incr 00530: 00531: 00532: function int vmm_ral_vreg::get_n_domains(); 00533: if (this.mem == null) begin 00535: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_n_domains() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00536: return 0; 00537: end 00538: 00539: get_n_domains = this.mem.get_n_domains(); 00540: endfunction: get_n_domains 00541: 00542: 00543: function void vmm_ral_vreg::get_domains(ref string domains[]); 00544: if (this.mem == null) begin 00546: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_domains() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00547: return; 00548: end 00549: 00550: this.mem.get_domains(domains); 00551: endfunction: get_domains 00552: 00553: 00554: function vmm_ral::access_e vmm_ral_vreg::get_access(string domain); 00555: if (this.mem == null) begin 00557: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_rights() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00558: return vmm_ral::RW; 00559: end 00560: 00561: get_access = this.mem.get_access(domain); 00562: endfunction: get_access 00563: 00564: 00565: function vmm_ral::access_e vmm_ral_vreg::get_rights(string domain); 00566: if (this.mem == null) begin 00568: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vreg::get_rights() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00569: return vmm_ral::RW; 00570: end 00571: 00572: get_rights = this.mem.get_rights(domain); 00573: endfunction: get_rights 00574: 00575: 00576: function void vmm_ral_vreg::display(string prefix, 00577: string domain); 00578: $write("%s\n", this.psdisplay(prefix, domain)); 00579: endfunction: display 00580: 00581: 00582: function string vmm_ral_vreg::psdisplay(string prefix, 00583: string domain); 00584: $sformat(psdisplay, "%sVirtual register %s -- ", prefix, 00585: this.get_fullname()); 00586: if (this.size == 0) $sformat(psdisplay, "%sunimplemented", psdisplay); 00587: else begin 00588: bit [64-1:0] addr0; 00589: 00590: addr0 = this.get_address_in_system(0, domain); 00591: 00592: $sformat(psdisplay, "%s[%0d] in %0s['h%0h+'h%0h] @'h%h+'h%h", psdisplay, 00593: this.size, this.mem.get_fullname(), this.offset, this.incr, 00594: addr0, this.get_address_in_system(1, domain) - addr0); 00595: end 00596: foreach(this.fields[i]) begin 00597: $sformat(psdisplay, "%s\n%s", psdisplay, 00598: this.fields[i].psdisplay({prefix, " "})); 00599: end 00600: endfunction: psdisplay 00601: 00602: 00603: function void vmm_ral_vreg::get_fields(ref vmm_ral_vfield fields[]); 00604: fields = new [this.fields.size()]; 00605: foreach(this.fields[i]) begin 00606: fields[i] = this.fields[i]; 00607: end 00608: endfunction: get_fields 00609: 00610: 00611: function vmm_ral_vfield vmm_ral_vreg::get_field_by_name(string name); 00612: foreach (this.fields[i]) begin 00613: if (this.fields[i].get_name() == name) begin 00614: return this.fields[i]; 00615: end 00616: end 00618: : 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 virtual register \"%s\".", : name, this.get_fullname()))); : this.log.end_msg(); : end : while(0); 00619: get_field_by_name = null; 00620: endfunction: get_field_by_name 00621: 00622: 00623: task vmm_ral_vreg::write(input longint unsigned idx, 00624: output vmm_rw::status_e status, 00625: input bit[64-1:0] value, 00626: input vmm_ral::path_e path, 00627: input string domain, 00628: input int data_id, 00629: input int scenario_id, 00630: input int stream_id); 00631: 00632: bit [64-1:0] addr; 00633: bit [64-1:0] tmp; 00634: bit [64-1:0] msk; 00635: int lsb; 00636: 00637: if (this.mem == null) begin 00638: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot write to unimplemented virtual register \"%s\".", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00639: status = vmm_rw::ERROR; 00640: return; 00641: end 00642: 00643: if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access(); 00644: 00645: foreach (fields[i]) begin 00646: vmm_ral_vfield f = fields[i]; 00647: 00648: lsb = f.get_lsb_pos_in_register(); 00649: msk = ((1<<f.get_n_bits())-1) << lsb; 00650: tmp = (value & msk) >> lsb; 00651: foreach (f.XcbsX[j]) begin 00652: vmm_ral_vfield_callbacks cb; 00653: if (!$cast(cb, f.XcbsX[j])) continue; 00654: cb.pre_write(f, idx, tmp, path, domain); 00655: end 00656: value = (value & ~msk) | (tmp << lsb); 00657: end 00659: : : do foreach (this.callbacks[vmm_i]) begin : vmm_ral_vreg_callbacks cb; : if (!$cast(cb, this.callbacks[vmm_i])) continue; : : cb.pre_write(this, idx, value, path, domain); : end while (0); 00660: 00661: addr = this.offset + (idx * this.incr); 00662: 00663: lsb = 0; 00664: status = vmm_rw::IS_OK; 00665: for (int i = 0; i < this.get_n_memlocs(); i++) begin 00666: vmm_rw::status_e s; 00667: 00668: msk = ((1<<(this.mem.get_n_bytes()*8))-1) << lsb; 00669: tmp = (value & msk) >> lsb; 00670: this.mem.write(s, addr + i, tmp, 00671: path, domain , 00672: data_id, scenario_id, stream_id); 00673: if (s != vmm_rw::IS_OK) status = s; 00674: lsb += this.mem.get_n_bytes() * 8; 00675: end 00676: 00677: foreach (fields[i]) begin 00678: vmm_ral_vfield f = fields[i]; 00679: 00680: lsb = f.get_lsb_pos_in_register(); 00681: msk = ((1<<f.get_n_bits())-1) << lsb; 00682: tmp = (value & msk) >> lsb; 00683: foreach (f.XcbsX[j]) begin 00684: vmm_ral_vfield_callbacks cb; 00685: if (!$cast(cb, f.XcbsX[j])) continue; 00686: cb.post_write(f, idx, tmp, path, domain, status); 00687: end 00688: value = (value & ~msk) | (tmp << lsb); 00689: end 00691: : : do foreach (this.callbacks[vmm_i]) begin : vmm_ral_vreg_callbacks cb; : if (!$cast(cb, this.callbacks[vmm_i])) continue; : : cb.post_write(this, idx, value, path, domain, status); : end while (0); 00692: 00696: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Wrote virtual register \"%s\"[%0d] via %s with: 'h%h", : this.get_fullname(), idx, : (path == vmm_ral::BFM) ? "frontdoor" : "backdoor", : value))); : this.log.end_msg(); : end : while (0); 00697: 00698: endtask: write 00699: 00700: 00701: task vmm_ral_vreg::read(input longint unsigned idx, 00702: output vmm_rw::status_e status, 00703: output bit[64-1:0] value, 00704: input vmm_ral::path_e path, 00705: input string domain, 00706: input int data_id, 00707: input int scenario_id, 00708: input int stream_id); 00709: bit [64-1:0] addr; 00710: bit [64-1:0] tmp; 00711: bit [64-1:0] msk; 00712: int lsb; 00713: 00714: if (this.mem == null) begin 00715: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot read from unimplemented virtual register \"%s\".", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00716: status = vmm_rw::ERROR; 00717: return; 00718: end 00719: 00720: if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access(); 00721: 00722: foreach (fields[i]) begin 00723: vmm_ral_vfield f = fields[i]; 00724: foreach (f.XcbsX[j]) begin 00725: vmm_ral_vfield_callbacks cb; 00726: if (!$cast(cb, f.XcbsX[j])) continue; 00727: cb.pre_read(f, idx, path, domain); 00728: end 00729: end 00731: : : do foreach (this.callbacks[vmm_i]) begin : vmm_ral_vreg_callbacks cb; : if (!$cast(cb, this.callbacks[vmm_i])) continue; : : cb.pre_read(this, idx, path, domain); : end while (0); 00732: 00733: addr = this.offset + (idx * this.incr); 00734: 00735: lsb = 0; 00736: value = 0; 00737: status = vmm_rw::IS_OK; 00738: for (int i = 0; i < this.get_n_memlocs(); i++) begin 00739: vmm_rw::status_e s; 00740: 00741: this.mem.read(s, addr + i, tmp, 00742: path, domain , 00743: data_id, scenario_id, stream_id); 00744: if (s != vmm_rw::IS_OK) status = s; 00745: 00746: value |= tmp << lsb; 00747: lsb += this.mem.get_n_bytes() * 8; 00748: end 00749: 00750: foreach (fields[i]) begin 00751: vmm_ral_vfield f = fields[i]; 00752: 00753: lsb = f.get_lsb_pos_in_register(); 00754: 00755: msk = ((1<<f.get_n_bits())-1) << lsb; 00756: tmp = (value & msk) >> lsb; 00757: 00758: foreach (f.XcbsX[j]) begin 00759: vmm_ral_vfield_callbacks cb; 00760: if (!$cast(cb, f.XcbsX[j])) continue; 00761: cb.post_read(f, idx, tmp, path, domain, status); 00762: end 00763: 00764: value = (value & ~msk) | (tmp << lsb); 00765: end 00767: : : do foreach (this.callbacks[vmm_i]) begin : vmm_ral_vreg_callbacks cb; : if (!$cast(cb, this.callbacks[vmm_i])) continue; : : cb.post_read(this, idx, value, path, domain, status); : end while (0); 00768: 00772: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Read virtual register \"%s\"[%0d] via %s: 'h%h", : this.get_fullname(), idx, : (path == vmm_ral::BFM) ? "frontdoor" : "backdoor", : value))); : this.log.end_msg(); : end : while (0); 00773: endtask: read 00774: 00775: 00776: task vmm_ral_vreg::poke(input longint unsigned idx, 00777: output vmm_rw::status_e status, 00778: input bit[64-1:0] value, 00779: input int data_id, 00780: input int scenario_id, 00781: input int stream_id); 00782: bit [64-1:0] addr; 00783: bit [64-1:0] tmp; 00784: bit [64-1:0] msk; 00785: int lsb; 00786: 00787: if (this.mem == null) begin 00788: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot poke in unimplemented virtual register \"%s\".", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00789: status = vmm_rw::ERROR; 00790: return; 00791: end 00792: 00793: addr = this.offset + (idx * this.incr); 00794: 00795: lsb = 0; 00796: status = vmm_rw::IS_OK; 00797: for (int i = 0; i < this.get_n_memlocs(); i++) begin 00798: vmm_rw::status_e s; 00799: 00800: msk = ((1<<(this.mem.get_n_bytes() * 8))-1) << lsb; 00801: tmp = (value & msk) >> lsb; 00802: 00803: this.mem.poke(status, addr + i, tmp, 00804: data_id, scenario_id, stream_id); 00805: if (s != vmm_rw::IS_OK) status = s; 00806: 00807: lsb += this.mem.get_n_bytes() * 8; 00808: end 00809: 00811: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Poked virtual register \"%s\"[%0d] with: 'h%h", : this.get_fullname(), idx, value))); : this.log.end_msg(); : end : while (0); 00812: 00813: endtask: poke 00814: 00815: 00816: task vmm_ral_vreg::peek(input longint unsigned idx, 00817: output vmm_rw::status_e status, 00818: output bit[64-1:0] value, 00819: input int data_id, 00820: input int scenario_id, 00821: input int stream_id); 00822: bit [64-1:0] addr; 00823: bit [64-1:0] tmp; 00824: bit [64-1:0] msk; 00825: int lsb; 00826: 00827: if (this.mem == null) begin 00828: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot peek in from unimplemented virtual register \"%s\".", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00829: status = vmm_rw::ERROR; 00830: return; 00831: end 00832: 00833: addr = this.offset + (idx * this.incr); 00834: 00835: lsb = 0; 00836: value = 0; 00837: status = vmm_rw::IS_OK; 00838: for (int i = 0; i < this.get_n_memlocs(); i++) begin 00839: vmm_rw::status_e s; 00840: 00841: this.mem.peek(status, addr + i, tmp, 00842: data_id, scenario_id, stream_id); 00843: if (s != vmm_rw::IS_OK) status = s; 00844: 00845: value |= tmp << lsb; 00846: lsb += this.mem.get_n_bytes() * 8; 00847: end 00848: 00850: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Peeked virtual register \"%s\"[%0d]: 'h%h", : this.get_fullname(), idx, value))); : this.log.end_msg(); : end : while (0); 00851: 00852: endtask: peek 00853: 00854: 00855: function void vmm_ral_vreg::prepend_callback(vmm_ral_vreg_callbacks cb); 00856: foreach (this.callbacks[i]) begin 00857: if (this.callbacks[i] == cb) begin 00858: : 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 virtual register \"%s\"", this.get_fullname()))); : this.log.end_msg(); : end : while(0); 00859: return; 00860: end 00861: end 00862: 00863: // Prepend new callback 00864: this.callbacks.push_front(cb); 00865: endfunction: prepend_callback 00866: 00867: 00868: function void vmm_ral_vreg::append_callback(vmm_ral_vreg_callbacks cb); 00869: foreach (this.callbacks[i]) begin 00870: if (this.callbacks[i] == cb) begin 00871: : 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 virtual register \"%s\"", this.get_fullname()))); : this.log.end_msg(); : end : while(0); 00872: return; 00873: end 00874: end 00875: 00876: // Append new callback 00877: this.callbacks.push_back(cb); 00878: endfunction: append_callback 00879: 00880: 00881: function void vmm_ral_vreg::unregister_callback(vmm_ral_vreg_callbacks cb); 00882: foreach (this.callbacks[i]) begin 00883: if (this.callbacks[i] == cb) begin 00884: int j = i; 00885: // Unregister it 00886: this.callbacks.delete(j); 00887: return; 00888: end 00889: end 00890: 00891: : 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 virtual register \"%s\"", this.get_fullname()))); : this.log.end_msg(); : end : while(0); 00892: endfunction: unregister_callback