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_vfield.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_ral_vfield; 00024: class vmm_ral_vfield_callbacks extends vmm_ral_callbacks; 00025: 00026: virtual task pre_write(vmm_ral_vfield field, 00027: longint unsigned idx, 00028: ref bit [64-1:0] wdat, 00029: ref vmm_ral::path_e path, 00030: ref string domain); 00031: endtask: pre_write 00032: 00033: virtual task post_write(vmm_ral_vfield field, 00034: longint unsigned idx, 00035: bit [64-1:0] wdat, 00036: vmm_ral::path_e path, 00037: string domain, 00038: ref vmm_rw::status_e status); 00039: endtask: post_write 00040: 00041: virtual task pre_read(vmm_ral_vfield field, 00042: longint unsigned idx, 00043: ref vmm_ral::path_e path, 00044: ref string domain); 00045: endtask: pre_read 00046: 00047: virtual task post_read(vmm_ral_vfield field, 00048: longint unsigned idx, 00049: ref bit [64-1:0] rdat, 00050: vmm_ral::path_e path, 00051: string domain, 00052: ref vmm_rw::status_e status); 00053: endtask: post_read 00054: endclass: vmm_ral_vfield_callbacks 00055: 00056: 00057: class vmm_ral_vfield; 00058: static vmm_log log = new("RAL", "virtual field"); 00059: 00060: local string name; 00061: local vmm_ral_vreg parent; 00062: local int unsigned lsb; 00063: local int unsigned size; 00064: 00065: vmm_ral_vfield_callbacks XcbsX[$]; 00066: 00067: extern /*local*/ function new(vmm_ral_vreg parent, 00068: string name, 00069: int unsigned size, 00070: int unsigned lsb_pos); 00071: 00072: extern virtual function string get_name(); 00073: extern virtual function string get_fullname(); 00074: extern virtual function vmm_ral_vreg get_register(); 00075: extern virtual function int unsigned get_lsb_pos_in_register(); 00076: extern virtual function int unsigned get_n_bits(); 00077: 00078: extern virtual function vmm_ral::access_e get_access(string domain = ""); 00079: 00080: extern virtual function void display(string prefix = ""); 00081: extern virtual function string psdisplay(string prefix = ""); 00082: 00083: extern virtual task write(input longint unsigned idx, 00084: output vmm_rw::status_e status, 00085: input bit [64-1:0] value, 00086: input vmm_ral::path_e path = vmm_ral::DEFAULT, 00087: input string domain = "", 00088: input int data_id = -1, 00089: input int scenario_id =- 1, 00090: input int stream_id = -1); 00091: extern virtual task read(input longint unsigned idx, 00092: output vmm_rw::status_e status, 00093: output bit[64-1:0] value, 00094: input vmm_ral::path_e path = vmm_ral::DEFAULT, 00095: input string domain = "", 00096: input int data_id = -1, 00097: input int scenario_id = -1, 00098: input int stream_id = -1); 00099: 00100: extern virtual task poke(input longint unsigned idx, 00101: output vmm_rw::status_e status, 00102: input bit [64-1:0] value, 00103: input int data_id = -1, 00104: input int scenario_id =- 1, 00105: input int stream_id = -1); 00106: extern virtual task peek(input longint unsigned idx, 00107: output vmm_rw::status_e status, 00108: output bit[64-1:0] value, 00109: input int data_id = -1, 00110: input int scenario_id = -1, 00111: input int stream_id = -1); 00112: 00113: extern function void prepend_callback(vmm_ral_vfield_callbacks cb); 00114: extern function void append_callback(vmm_ral_vfield_callbacks cb); 00115: extern function void unregister_callback(vmm_ral_vfield_callbacks cb); 00116: endclass: vmm_ral_vfield 00117: 00118: 00119: function vmm_ral_vfield::new(vmm_ral_vreg parent, 00120: string name, 00121: int unsigned size, 00122: int unsigned lsb_pos); 00123: this.parent = parent; 00124: this.name = name; 00125: 00126: if (size == 0) begin 00127: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual field \"%s\" cannot have 0 bits", this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00128: size = 1; 00129: end 00130: if (size > 64) begin 00133: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Virtual field \"%s\" cannot have more than %0d bits", : this.get_fullname(), : 64))); : this.log.end_msg(); : end : while (0); 00134: size = 64; 00135: end 00136: 00137: this.size = size; 00138: this.lsb = lsb_pos; 00139: 00140: this.parent.register_field(this); 00141: endfunction: new 00142: 00143: 00144: function string vmm_ral_vfield::get_name(); 00145: get_name = this.name; 00146: endfunction: get_name 00147: 00148: 00149: function string vmm_ral_vfield::get_fullname(); 00150: get_fullname = {this.parent.get_fullname(), ".", this.name}; 00151: endfunction: get_fullname 00152: 00153: 00154: function vmm_ral_vreg vmm_ral_vfield::get_register(); 00155: get_register = this.parent; 00156: endfunction: get_register 00157: 00158: 00159: function int unsigned vmm_ral_vfield::get_lsb_pos_in_register(); 00160: get_lsb_pos_in_register = this.lsb; 00161: endfunction: get_lsb_pos_in_register 00162: 00163: 00164: function int unsigned vmm_ral_vfield::get_n_bits(); 00165: get_n_bits = this.size; 00166: endfunction: get_n_bits 00167: 00168: 00169: function vmm_ral::access_e vmm_ral_vfield::get_access(string domain); 00170: if (this.parent.get_memory() == null) begin 00172: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vfield::get_rights() on unimplemented virtual field \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00173: return vmm_ral::RW; 00174: end 00175: 00176: get_access = this.parent.get_access(domain); 00177: endfunction: get_access 00178: 00179: 00180: function void vmm_ral_vfield::display(string prefix); 00181: $write("%s\n", this.psdisplay(prefix)); 00182: endfunction: display 00183: 00184: 00185: function string vmm_ral_vfield::psdisplay(string prefix); 00186: $sformat(psdisplay, {"%s%s[%0d-%0d]"}, prefix, 00187: this.get_name(), 00188: this.get_lsb_pos_in_register() + this.get_n_bits() - 1, 00189: this.get_lsb_pos_in_register()); 00190: endfunction: psdisplay 00191: 00192: 00193: task vmm_ral_vfield::write(input longint unsigned idx, 00194: output vmm_rw::status_e status, 00195: input bit [64-1:0] value, 00196: input vmm_ral::path_e path, 00197: input string domain, 00198: input int data_id, 00199: input int scenario_id, 00200: input int stream_id); 00201: bit [64-1:0] tmp; 00202: bit [64-1:0] segval; 00203: bit [64-1:0] segoff; 00204: vmm_rw::status_e st; 00205: 00206: int flsb, fmsb, rmwbits; 00207: int segsiz, segn; 00208: vmm_ral_mem mem; 00209: vmm_ral::path_e rm_path; 00210: 00211: mem = this.parent.get_memory(); 00212: if (mem == null) begin 00214: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vfield::write() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00215: status = vmm_rw::ERROR; 00216: return; 00217: end 00218: 00219: if (path == vmm_ral::DEFAULT) begin 00220: vmm_ral_block blk = this.parent.get_block(); 00221: path = blk.get_default_access(); 00222: end 00223: 00224: status = vmm_rw::IS_OK; 00225: 00226: this.parent.XatomicX(1); 00227: 00228: if (value >> this.size) begin 00229: : do : if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin : void'(log.text($psprintf("Writing value 'h%h that is greater than field \"%s\" size (%0d bits)", value, this.get_fullname(), this.get_n_bits()))); : log.end_msg(); : end : while(0); 00230: value &= value & ((1<<this.size)-1); 00231: end 00232: tmp = 0; 00233: 00234: foreach (this.XcbsX[j]) begin 00235: vmm_ral_vfield_callbacks cb; 00236: if (!$cast(cb, this.XcbsX[j])) continue; 00237: cb.pre_write(this, idx, value, path, domain); 00238: end 00239: 00240: segsiz = mem.get_n_bytes() * 8; 00241: flsb = this.get_lsb_pos_in_register(); 00242: segoff = this.parent.get_offset_in_memory(idx) + (flsb / segsiz); 00243: 00244: // Favor backdoor read to frontdoor read for the RMW operation 00245: rm_path = vmm_ral::DEFAULT; 00246: if (mem.get_backdoor() != null) rm_path = vmm_ral::BACKDOOR; 00247: 00248: // Any bits on the LSB side we need to RMW? 00249: rmwbits = flsb % segsiz; 00250: 00251: // Total number of memory segment in this field 00252: segn = (rmwbits + this.get_n_bits() - 1) / segsiz + 1; 00253: 00254: if (rmwbits > 0) begin 00255: bit [64-1:0] segn; 00256: 00257: mem.read(st, segoff, tmp, rm_path, domain, 00258: data_id, scenario_id, stream_id); 00259: if (st != vmm_rw::IS_OK) begin 00262: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Unable to read LSB bits in %s[%0d] to for RMW cycle on virtual field %s.", : mem.get_fullname(), segoff, this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00263: status = vmm_rw::ERROR; 00264: this.parent.XatomicX(0); 00265: return; 00266: end 00267: 00268: value = (value << rmwbits) | (tmp & ((1<<rmwbits)-1)); 00269: end 00270: 00271: // Any bits on the MSB side we need to RMW? 00272: fmsb = rmwbits + this.get_n_bits() - 1; 00273: rmwbits = (fmsb+1) % segsiz; 00274: if (rmwbits > 0) begin 00275: if (segn > 0) begin 00276: mem.read(st, segoff + segn - 1, tmp, rm_path, domain, 00277: data_id, scenario_id, stream_id); 00278: if (st != vmm_rw::IS_OK) begin 00282: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Unable to read MSB bits in %s[%0d] to for RMW cycle on virtual field %s.", : mem.get_fullname(), segoff+segn-1, : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00283: status = vmm_rw::ERROR; 00284: this.parent.XatomicX(0); 00285: return; 00286: end 00287: end 00288: value |= (tmp & ~((1<<rmwbits)-1)) << ((segn-1)*segsiz); 00289: end 00290: 00291: // Now write each of the segments 00292: tmp = value; 00293: repeat (segn) begin 00294: mem.write(st, segoff, tmp, path, domain, 00295: data_id, scenario_id, stream_id); 00296: if (st != vmm_rw::IS_OK) status = vmm_rw::ERROR; 00297: 00298: segoff++; 00299: tmp = tmp >> segsiz; 00300: end 00301: 00302: foreach (this.XcbsX[j]) begin 00303: vmm_ral_vfield_callbacks cb; 00304: if (!$cast(cb, this.XcbsX[j])) continue; 00305: cb.post_write(this, idx, value, path, domain, status); 00306: end 00307: 00308: this.parent.XatomicX(0); 00309: 00313: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Wrote virtual field \"%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); 00314: 00315: endtask: write 00316: 00317: 00318: task vmm_ral_vfield::read(input longint unsigned idx, 00319: output vmm_rw::status_e status, 00320: output bit[64-1:0] value, 00321: input vmm_ral::path_e path, 00322: input string domain, 00323: input int data_id, 00324: input int scenario_id, 00325: input int stream_id); 00326: bit [64-1:0] tmp; 00327: bit [64-1:0] segval; 00328: bit [64-1:0] segoff; 00329: vmm_rw::status_e st; 00330: 00331: int flsb, lsb; 00332: int segsiz, segn; 00333: vmm_ral_mem mem; 00334: 00335: mem = this.parent.get_memory(); 00336: if (mem == null) begin 00338: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vfield::read() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00339: status = vmm_rw::ERROR; 00340: return; 00341: end 00342: 00343: if (path == vmm_ral::DEFAULT) begin 00344: vmm_ral_block blk = this.parent.get_block(); 00345: path = blk.get_default_access(); 00346: end 00347: 00348: status = vmm_rw::IS_OK; 00349: 00350: this.parent.XatomicX(1); 00351: 00352: value = 0; 00353: 00354: foreach (this.XcbsX[j]) begin 00355: vmm_ral_vfield_callbacks cb; 00356: if (!$cast(cb, this.XcbsX[j])) continue; 00357: cb.pre_read(this, idx, path, domain); 00358: end 00359: 00360: segsiz = mem.get_n_bytes() * 8; 00361: flsb = this.get_lsb_pos_in_register(); 00362: segoff = this.parent.get_offset_in_memory(idx) + (flsb / segsiz); 00363: lsb = flsb % segsiz; 00364: 00365: // Total number of memory segment in this field 00366: segn = (lsb + this.get_n_bits() - 1) / segsiz + 1; 00367: 00368: // Read each of the segments, MSB first 00369: segoff += segn - 1; 00370: repeat (segn) begin 00371: value = value << segsiz; 00372: 00373: mem.read(st, segoff, tmp, path, domain, 00374: data_id, scenario_id, stream_id); 00375: if (st != vmm_rw::IS_OK) status = vmm_rw::ERROR; 00376: 00377: segoff--; 00378: value |= tmp; 00379: end 00380: 00381: // Any bits on the LSB side we need to get rid of? 00382: value = value >> lsb; 00383: 00384: // Any bits on the MSB side we need to get rid of? 00385: value &= (1<<this.get_n_bits()) - 1; 00386: 00387: foreach (this.XcbsX[j]) begin 00388: vmm_ral_vfield_callbacks cb; 00389: if (!$cast(cb, this.XcbsX[j])) continue; 00390: cb.post_read(this, idx, value, path, domain, status); 00391: end 00392: 00393: this.parent.XatomicX(0); 00394: 00398: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Read virtual field \"%s\"[%0d] via %s: 'h%h", : this.get_fullname(), idx, : (path == vmm_ral::BFM) ? "frontdoor" : "backdoor", : value))); : this.log.end_msg(); : end : while (0); 00399: 00400: endtask: read 00401: 00402: 00403: task vmm_ral_vfield::poke(input longint unsigned idx, 00404: output vmm_rw::status_e status, 00405: input bit [64-1:0] value, 00406: input int data_id, 00407: input int scenario_id, 00408: input int stream_id); 00409: bit [64-1:0] tmp; 00410: bit [64-1:0] segval; 00411: bit [64-1:0] segoff; 00412: vmm_rw::status_e st; 00413: 00414: int flsb, fmsb, rmwbits; 00415: int segsiz, segn; 00416: vmm_ral_mem mem; 00417: vmm_ral::path_e rm_path; 00418: 00419: mem = this.parent.get_memory(); 00420: if (mem == null) begin 00422: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vfield::poke() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00423: status = vmm_rw::ERROR; 00424: return; 00425: end 00426: 00427: status = vmm_rw::IS_OK; 00428: 00429: this.parent.XatomicX(1); 00430: 00431: if (value >> this.size) begin 00432: : do : if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin : void'(log.text($psprintf("Writing value 'h%h that is greater than field \"%s\" size (%0d bits)", value, this.get_fullname(), this.get_n_bits()))); : log.end_msg(); : end : while(0); 00433: value &= value & ((1<<this.size)-1); 00434: end 00435: tmp = 0; 00436: 00437: segsiz = mem.get_n_bytes() * 8; 00438: flsb = this.get_lsb_pos_in_register(); 00439: segoff = this.parent.get_offset_in_memory(idx) + (flsb / segsiz); 00440: 00441: // Any bits on the LSB side we need to RMW? 00442: rmwbits = flsb % segsiz; 00443: 00444: // Total number of memory segment in this field 00445: segn = (rmwbits + this.get_n_bits() - 1) / segsiz + 1; 00446: 00447: if (rmwbits > 0) begin 00448: bit [64-1:0] segn; 00449: 00450: mem.peek(st, segoff, tmp, 00451: data_id, scenario_id, stream_id); 00452: if (st != vmm_rw::IS_OK) begin 00455: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Unable to read LSB bits in %s[%0d] to for RMW cycle on virtual field %s.", : mem.get_fullname(), segoff, this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00456: status = vmm_rw::ERROR; 00457: this.parent.XatomicX(0); 00458: return; 00459: end 00460: 00461: value = (value << rmwbits) | (tmp & ((1<<rmwbits)-1)); 00462: end 00463: 00464: // Any bits on the MSB side we need to RMW? 00465: fmsb = rmwbits + this.get_n_bits() - 1; 00466: rmwbits = (fmsb+1) % segsiz; 00467: if (rmwbits > 0) begin 00468: if (segn > 0) begin 00469: mem.peek(st, segoff + segn - 1, tmp, 00470: data_id, scenario_id, stream_id); 00471: if (st != vmm_rw::IS_OK) begin 00475: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Unable to read MSB bits in %s[%0d] to for RMW cycle on virtual field %s.", : mem.get_fullname(), segoff+segn-1, : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00476: status = vmm_rw::ERROR; 00477: this.parent.XatomicX(0); 00478: return; 00479: end 00480: end 00481: value |= (tmp & ~((1<<rmwbits)-1)) << ((segn-1)*segsiz); 00482: end 00483: 00484: // Now write each of the segments 00485: tmp = value; 00486: repeat (segn) begin 00487: mem.poke(st, segoff, tmp, 00488: data_id, scenario_id, stream_id); 00489: if (st != vmm_rw::IS_OK) status = vmm_rw::ERROR; 00490: 00491: segoff++; 00492: tmp = tmp >> segsiz; 00493: end 00494: 00495: this.parent.XatomicX(0); 00496: 00498: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Wrote virtual field \"%s\"[%0d] with: 'h%h", : this.get_fullname(), idx, value))); : this.log.end_msg(); : end : while (0); 00499: 00500: endtask: poke 00501: 00502: 00503: task vmm_ral_vfield::peek(input longint unsigned idx, 00504: output vmm_rw::status_e status, 00505: output bit[64-1:0] value, 00506: input int data_id, 00507: input int scenario_id, 00508: input int stream_id); 00509: bit [64-1:0] tmp; 00510: bit [64-1:0] segval; 00511: bit [64-1:0] segoff; 00512: vmm_rw::status_e st; 00513: 00514: int flsb, lsb; 00515: int segsiz, segn; 00516: vmm_ral_mem mem; 00517: 00518: mem = this.parent.get_memory(); 00519: if (mem == null) begin 00521: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("Cannot call vmm_ral_vfield::peek() on unimplemented virtual register \"%s\"", : this.get_fullname()))); : this.log.end_msg(); : end : while (0); 00522: status = vmm_rw::ERROR; 00523: return; 00524: end 00525: 00526: status = vmm_rw::IS_OK; 00527: 00528: this.parent.XatomicX(1); 00529: 00530: value = 0; 00531: 00532: segsiz = mem.get_n_bytes() * 8; 00533: flsb = this.get_lsb_pos_in_register(); 00534: segoff = this.parent.get_offset_in_memory(idx) + (flsb / segsiz); 00535: lsb = flsb % segsiz; 00536: 00537: // Total number of memory segment in this field 00538: segn = (lsb + this.get_n_bits() - 1) / segsiz + 1; 00539: 00540: // Read each of the segments, MSB first 00541: segoff += segn - 1; 00542: repeat (segn) begin 00543: value = value << segsiz; 00544: 00545: mem.peek(st, segoff, tmp, 00546: data_id, scenario_id, stream_id); 00547: if (st != vmm_rw::IS_OK) status = vmm_rw::ERROR; 00548: 00549: segoff--; 00550: value |= tmp; 00551: end 00552: 00553: // Any bits on the LSB side we need to get rid of? 00554: value = value >> lsb; 00555: 00556: // Any bits on the MSB side we need to get rid of? 00557: value &= (1<<this.get_n_bits()) - 1; 00558: 00559: this.parent.XatomicX(0); 00560: 00562: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Peeked virtual field \"%s\"[%0d]: 'h%h", : this.get_fullname(), idx, value))); : this.log.end_msg(); : end : while (0); 00563: 00564: endtask: peek 00565: 00566: 00567: function void vmm_ral_vfield::prepend_callback(vmm_ral_vfield_callbacks cb); 00568: foreach (this.XcbsX[i]) begin 00569: if (this.XcbsX[i] == cb) begin 00570: : 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 field \"%s\"", this.get_fullname()))); : this.log.end_msg(); : end : while(0); 00571: return; 00572: end 00573: end 00574: 00575: // Prepend new callback 00576: this.XcbsX.push_front(cb); 00577: endfunction: prepend_callback 00578: 00579: 00580: function void vmm_ral_vfield::append_callback(vmm_ral_vfield_callbacks cb); 00581: foreach (this.XcbsX[i]) begin 00582: if (this.XcbsX[i] == cb) begin 00583: : 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 field \"%s\"", this.get_fullname()))); : this.log.end_msg(); : end : while(0); 00584: return; 00585: end 00586: end 00587: 00588: // Append new callback 00589: this.XcbsX.push_back(cb); 00590: endfunction: append_callback 00591: 00592: 00593: function void vmm_ral_vfield::unregister_callback(vmm_ral_vfield_callbacks cb); 00594: foreach (this.XcbsX[i]) begin 00595: if (this.XcbsX[i] == cb) begin 00596: int j = i; 00597: // Unregister it 00598: this.XcbsX.delete(j); 00599: return; 00600: end 00601: end 00602: 00603: : 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 field \"%s\"", this.get_fullname()))); : this.log.end_msg(); : end : while(0); 00604: endfunction: unregister_callback