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.
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: function vmm_ral_mem::new(vmm_ral_block parent,
00024: string name,
00025: vmm_ral::access_e access,
00026: longint unsigned size,
00027: int unsigned n_bits,
00028: bit [64-1:0] base_addr,
00029: string domain = "",
00030: int cover_on = vmm_ral::NO_COVERAGE,
00031: bit [1:0] rights = 2'b11,
00032: bit unmapped = 0,
00033: int has_cover = vmm_ral::NO_COVERAGE);
00034:
00035: this.name = name;
00036: this.locked = 0;
00037:
00038: if (n_bits == 0) begin
00039:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory \"%s\" cannot have 0 bits", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00040: n_bits = 1;
00041: end
00042: if (n_bits > 64) begin
00043:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory \"%s\" cannot have more than %0d bits %0d", this.get_fullname(), 64, n_bits)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00044: n_bits = 64;
00045: end
00046: if (access != vmm_ral::RW && access != vmm_ral::RO) begin
00047:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s can only be RW or RO",
: this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00049: access = vmm_ral::RW;
00050: end
00051:
00052: this.parent = parent;
00053: this.size = size;
00054: this.access = access;
00055: this.n_bits = n_bits;
00056: this.backdoor = null;
00057:
00058: this.parent.register_mem(this);
00059: this.add_domain(base_addr, domain, rights, unmapped);
00060:
00061: this.is_powered_down = 0;
00062:
00063: this.has_cover = has_cover;
00064: this.cover_on = vmm_ral::NO_COVERAGE;
00065: void'(this.set_cover(cover_on));
00066:
00067: begin
00068: vmm_mam_cfg cfg = new;
00069:
00070: cfg.n_bytes = ((n_bits-1) / 8) + 1;
00071: cfg.start_offset = 0;
00072: cfg.end_offset = size-1;
00073:
00074: cfg.mode = vmm_mam::GREEDY;
00075: cfg.locality = vmm_mam::BROAD;
00076:
00077: this.mam = new(this.get_fullname(), cfg, this);
00078: end
00079:
00080: // Initialize Memory ID
00081: this.mem_id = ++this.mem_id_factory;
00082: all_mems[this.mem_id] = this;
00083: endfunction: new
00084:
00085:
00086: function void vmm_ral_mem::Xlock_modelX();
00087: this.locked = 1;
00088: endfunction: Xlock_modelX
00089:
00090:
00091: function void vmm_ral_mem::add_domain(bit [64-1:0] base_addr,
00092: string domain,
00093: bit [1:0] rights,
00094: bit unmapped = 0);
00095: vmm_ral::access_e acc;
00096:
00097: // Verify that this is a valid domain in the block
00098: string domains[];
00099:
00100: if (this.locked) begin
00101:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Cannot add domain to locked memory %s", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00102: return;
00103: end
00104:
00105: case (rights)
00106: 2'b11: acc = vmm_ral::RW;
00107: 2'b10: acc = vmm_ral::RO;
00108: 2'b01: acc = vmm_ral::WO;
00109: default:
00110:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s has no access rights in domain \"%s\"",
: this.get_fullname(), domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00113: endcase
00114:
00115: this.parent.get_domains(domains);
00116: foreach(domains[i]) begin
00117: if (domains[i] == domain) begin
00118: automatic int n = this.offset_in_block.size();
00119:
00120: this.offset_in_block = new [n + 1] (this.offset_in_block);
00121: this.offset_in_block[n] = (unmapped) ? 'X : base_addr;
00122:
00123: this.domains = new [n + 1] (this.domains);
00124: this.domains[n] = domain;
00125:
00126: this.rights = new [n + 1] (this.rights);
00127: this.rights[n] = acc;
00128:
00129: this.frontdoor = new [n + 1] (this.frontdoor);
00130: this.frontdoor[n] = null;
00131: return;
00132: end
00133: end
00134:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Domain \"%s\" not found in parent block %s of memory %s",
: domain, this.parent.get_name(), this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00136: endfunction: add_domain
00137:
00138:
00139: function void vmm_ral_mem::Xregister_ral_accessX(vmm_ral_access access);
00140: // There can only be one RAL Access on a RAL model
00141: if (this.ral_access != null && this.ral_access != access) begin
00142:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s is already used by another RAL access instance", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00143: end
00144: this.ral_access = access;
00145: endfunction: Xregister_ral_accessX
00146:
00147:
00148: function string vmm_ral_mem::get_name();
00149: get_name = this.name;
00150: endfunction: get_name
00151:
00152:
00153: function string vmm_ral_mem::get_fullname();
00154: vmm_ral_block blk;
00155:
00156: get_fullname = this.get_name();
00157:
00158: // Do not include top-level name in full name
00159: blk = this.get_block();
00160: if (blk == null) return get_fullname;
00161: if (blk.get_parent() == null) return get_fullname;
00162:
00163: get_fullname = {this.parent.get_fullname(), ".", get_fullname};
00164: endfunction: get_fullname
00165:
00166:
00167: function int vmm_ral_mem::get_n_domains();
00168: get_n_domains = this.domains.size();
00169: endfunction: get_n_domains
00170:
00171:
00172: function void vmm_ral_mem::get_domains(ref string domains[]);
00173: domains = new [this.domains.size()] (this.domains);
00174: endfunction: get_domains
00175:
00176:
00177: function vmm_ral::access_e vmm_ral_mem::get_access(string domain = "");
00178: get_access = this.access;
00179: if (this.get_n_domains() == 1) return get_access;
00180:
00181: // Is the memory restricted in this domain?
00182: case (this.get_rights(domain))
00183: vmm_ral::RW:
00184: // No restrictions
00185: return get_access;
00186:
00187: vmm_ral::RO:
00188: case (get_access)
00189: vmm_ral::RW,
00190: vmm_ral::RO: get_access = vmm_ral::RO;
00191:
00192: vmm_ral::WO: begin
00193:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("WO memory %s restricted to RO in domain \"%s\"",
: this.get_fullname(), domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00196: end
00197:
00198: default:
00199:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Invalid memory %s access mode \"%s\"",
: this.get_fullname(), get_access.name())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00202: endcase
00203:
00204: vmm_ral::WO:
00205: case (get_access)
00206: vmm_ral::RW,
00207: vmm_ral::WO: get_access = vmm_ral::WO;
00208:
00209: vmm_ral::RO: begin
00210:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("RO memory %s restricted to WO in domain \"%s\"",
: this.get_fullname(), get_access.name(), domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00213: end
00214:
00215: default:
00216:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Invalid memory %s access mode \"%s\"",
: this.get_fullname(), get_access.name())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00219: endcase
00220:
00221: default:
00222:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Shared memory \"%s\" is not shared in domain \"%s\"",
: this.get_fullname(), domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00225: endcase
00226: endfunction: get_access
00227:
00228:
00229: function vmm_ral::access_e vmm_ral_mem::get_rights(string domain = "");
00230: int i;
00231:
00232: // No right restrictions if not shared
00233: if (this.domains.size() == 1) begin
00234: return vmm_ral::RW;
00235: end
00236:
00237: i = this.get_domain_index(domain);
00238: if (i < 0) return vmm_ral::RW;
00239:
00240: get_rights = this.rights[i];
00241: endfunction: get_rights
00242:
00243:
00244: function void vmm_ral_mem::get_virtual_fields(ref vmm_ral_vfield fields[]);
00245: vmm_ral_vfield vfields[];
00246:
00247: fields = new[0];
00248: foreach (this.XvregsX[i]) begin
00249: int n = fields.size();
00250: this.XvregsX[i].get_fields(vfields);
00251: fields = new[n + vfields.size()] (fields);
00252: foreach(vfields[j]) begin
00253: fields[n+j] = vfields[j];
00254: end
00255: end
00256: endfunction: get_virtual_fields
00257:
00258:
00259: // Return first occurrence of vfield matching name
00260: function vmm_ral_vfield vmm_ral_mem::get_virtual_field_by_name(string name);
00261: vmm_ral_vfield vfields[];
00262:
00263: this.get_virtual_fields(vfields);
00264: foreach (vfields[i]) begin
00265: if (vfields[i].get_name() == name) return vfields[i];
00266: end
00267:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Unable to find virtual field \"%s\" in memory %s.",
: name, this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00270: return null;
00271: endfunction: get_virtual_field_by_name
00272:
00273:
00274: function void vmm_ral_mem::get_virtual_registers(ref vmm_ral_vreg regs[]);
00275: regs = new[this.XvregsX.size()];
00276: foreach (this.XvregsX[i]) begin
00277: regs[i] = this.XvregsX[i];
00278: end
00279: endfunction: get_virtual_registers
00280:
00281:
00282: function vmm_ral_vreg vmm_ral_mem::get_vreg_by_name(string name);
00283: foreach (this.XvregsX[i]) begin
00284: if (this.XvregsX[i].get_name() == name) return this.XvregsX[i];
00285: end
00286:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Unable to find virtual register \"%s\" in memory %s.",
: name, this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00289:
00290: endfunction: get_vreg_by_name
00291:
00292:
00293: function vmm_ral_vreg vmm_ral_mem::get_vreg_by_offset(bit [63:0] offset,
00294: string domain = "");
00295:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("vmm_ral_mem::get_vreg_by_offset not yet implemented"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00296: return null;
00297: endfunction: get_vreg_by_offset
00298:
00299:
00300: function vmm_ral_block vmm_ral_mem::get_block();
00301: get_block = this.parent;
00302: endfunction: get_block
00303:
00304:
00305: function bit [64-1:0] vmm_ral_mem::get_offset_in_block(bit [64-1:0] mem_addr = 0,
00306: string domain = "");
00307: foreach (this.domains[i]) begin
00308: if (this.domains[i] == domain) begin
00309: if (this.offset_in_block[i] === 'x) begin
00310:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory \"%s\" is unmapped in domain \"%s\".", this.get_name(), domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00311: return '0;
00312: end
00313:
00314: return this.offset_in_block[i];
00315: end
00316: end
00317:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Unable to find offset within domain \"%s\" in memory %s.",
: domain, this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00319: get_offset_in_block = '1;
00320: endfunction: get_offset_in_block
00321:
00322:
00323: function bit [64-1:0] vmm_ral_mem::get_address_in_system(bit [64-1:0] mem_addr = 0,
00324: string domain = "");
00325: bit [64-1:0] addr[];
00326:
00327: int i = this.get_domain_index(domain);
00328: if (i < 0) return 0;
00329:
00330: if (this.ral_access == null) begin
00331:
: do
: /* synopsys translate_off */
: if (this.parent.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin
: void'(this.parent.log.text("RAL model is not associated with an access transactor"));
: this.parent.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00333: return 0;
00334: end
00335:
00336: if (this.offset_in_block[i] === 'x) begin
00337:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory \"%s\" is unmapped in domain \"%s\".", this.get_name(), this.domains[i])));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00338: return '1;
00339: end
00340:
00341: void'(this.ral_access.Xget_physical_addressesX(this.offset_in_block[i],
00342: mem_addr, this.get_n_bytes(),
00343: this.parent,
00344: this.domains[i],
00345: addr));
00346:
00347: get_address_in_system = addr[0];
00348: endfunction: get_address_in_system
00349:
00350:
00351: function longint unsigned vmm_ral_mem::get_size();
00352: get_size = this.size;
00353: endfunction: get_size
00354:
00355:
00356: function int unsigned vmm_ral_mem::get_n_bits();
00357: get_n_bits = this.n_bits;
00358: endfunction: get_n_bits
00359:
00360:
00361: function int unsigned vmm_ral_mem::get_n_bytes();
00362: get_n_bytes = (this.n_bits - 1) / 8 + 1;
00363: endfunction: get_n_bytes
00364:
00365:
00366: function void vmm_ral_mem::display(string prefix = "",
00367: string domain = "");
00368: $write("%s\n", this.psdisplay(prefix, domain));
00369: endfunction: display
00370:
00371:
00372: function string vmm_ral_mem::psdisplay(string prefix = "",
00373: string domain = "");
00374: $sformat(psdisplay, "%sMemory %s -- %0dx%0d bits @", prefix,
00375: this.get_fullname(), this.get_size(), this.get_n_bits());
00376: foreach (this.domains[i]) begin
00377: if (this.domains[i] == domain) begin
00378: if (this.offset_in_block[i] === 'x) begin
00379: psdisplay = {psdisplay, "none"};
00380: end
00381: else begin
00382: $sformat(psdisplay, "%s'h%h", psdisplay,
00383: this.get_address_in_system(0, domain));
00384: end
00385: break;
00386: end
00387: end
00388: endfunction: psdisplay
00389:
00390:
00391: function void vmm_ral_mem::set_attribute(string name,
00392: string value);
00393: if (name == "") begin
00394:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Cannot set anonymous attribute \"\" in memory \"%s\". Please specify an attribute name.",
: name, this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00396: return;
00397: end
00398:
00399: if (this.attributes.exists(name)) begin
00400: if (value != "") begin
00401:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Redefining attributed \"%s\" in memory \"%s\" to \"%s\".",
: name, this.get_fullname(), value)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00403: this.attributes[name] = value;
00404: end
00405: else begin
00406: this.attributes.delete(name);
00407: end
00408: return;
00409: end
00410:
00411: if (value == "") begin
00412:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Attempting to delete non-existent attribute \"%s\" in memory \"%s\".",
: name, this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00414: return;
00415: end
00416:
00417: this.attributes[name] = value;
00418: endfunction: set_attribute
00419:
00420:
00421: function string vmm_ral_mem::get_attribute(string name,
00422: bit inherited = 1);
00423: if (this.attributes.exists(name)) begin
00424: return this.attributes[name];
00425: end
00426:
00427: if (inherited) return this.parent.get_attribute(name);
00428:
00429: return "";
00430: endfunction: get_attribute
00431:
00432:
00433: function void vmm_ral_mem::get_all_attributes(ref string names[],
00434: input bit inherited = 1);
00435: string tmp[];
00436: string name;
00437: bit ok;
00438: int i;
00439:
00440: if (inherited) this.parent.get_all_attributes(tmp);
00441:
00442: i = tmp.size();
00443: tmp = new [tmp.size() + this.attributes.num()] (tmp);
00444:
00445: ok = this.attributes.first(name);
00446: while (ok) begin
00447: int found = 0;
00448: foreach (tmp[j]) begin
00449: if (tmp[j] == name) begin
00450: found = 1;
00451: break;
00452: end
00453: end
00454: if (!found) tmp[i++] = name;
00455: ok = this.attributes.next(name);
00456: end
00457: names = new [i] (tmp);
00458: endfunction: get_all_attributes
00459:
00460:
00461: function void vmm_ral_mem::power_down();
00462: this.is_powered_down = 1;
00463: endfunction: power_down
00464:
00465:
00466: function void vmm_ral_mem::power_up();
00467: this.is_powered_down = 0;
00468: endfunction: power_up
00469:
00470:
00471: function bit vmm_ral_mem::can_cover(int models);
00472: return ((this.has_cover & models) == models);
00473: endfunction: can_cover
00474:
00475:
00476: function int vmm_ral_mem::set_cover(int is_on);
00477: if (is_on == vmm_ral::NO_COVERAGE) begin
00478: this.cover_on = is_on;
00479: return this.cover_on;
00480: end
00481:
00482: if (is_on & vmm_ral::ADDR_MAP) begin
00483: if (this.has_cover & vmm_ral::ADDR_MAP) begin
00484: this.cover_on |= vmm_ral::ADDR_MAP;
00485: end else begin
00486:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("\"%s\" - Cannot turn ON Address Map coverage becasue the corresponding coverage model was not generated.", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00487: end
00488: end else begin
00489: return this.cover_on;
00490: end
00491:
00492: set_cover = this.cover_on;
00493: endfunction: set_cover
00494:
00495:
00496: function bit vmm_ral_mem::is_cover_on(int is_on);
00497: if (this.can_cover(is_on) == 0) return 0;
00498: return ((this.cover_on & is_on) == is_on);
00499: endfunction: is_cover_on
00500:
00501:
00502: task vmm_ral_mem::init(output bit is_ok,
00503: input init_e pattern,
00504: input bit [64-1:0] data);
00505: int incr;
00506: is_ok = 0;
00507:
00508: if (this.backdoor == null) begin
00509:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("No backdoor available to initialize memory %s", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00510: return;
00511: end
00512:
00513: case (pattern)
00514: UNKNOWNS:
00515: begin
00516: data = 'x;
00517: incr = 0;
00518: end
00519:
00520: ZEROES:
00521: begin
00522: data = '0;
00523: incr = 0;
00524: end
00525:
00526: ONES:
00527: begin
00528: data = '1;
00529: incr = 0;
00530: end
00531:
00532: VALUE:
00533: begin
00534: incr = 0;
00535: end
00536:
00537: INCR:
00538: begin
00539: incr = 1;
00540: end
00541:
00542: DECR:
00543: begin
00544: incr = -1;
00545: end
00546: endcase
00547:
00548: // ToDo...
00549: endtask:init
00550:
00551:
00552: task vmm_ral_mem::write(output vmm_rw::status_e status,
00553: input bit [64-1:0] mem_addr,
00554: input bit [64-1:0] value,
00555: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00556: input string domain = "",
00557: input int data_id = -1,
00558: input int scenario_id = -1,
00559: input int stream_id = -1);
00560: status = vmm_rw::ERROR;
00561:
00562: if (this.ral_access == null) begin
00563:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s not associated with RAL access object", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00564: return;
00565: end
00566:
00567: if (this.is_powered_down) begin
00568:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s cannot be accessed when it is powered down", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00569: return;
00570: end
00571:
00572: if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00573:
00574:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_ral_mem_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.pre_write(this, mem_addr, value, path, domain);
: end while (0);
00576:
00577: if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00578:
00579: if (path == vmm_ral::BACKDOOR &&
00580: this.backdoor == null) begin
00581:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("No backdoor access available for memory \"%s\". Using frontdoor instead.", this.get_name())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00582: path = vmm_ral::BFM;
00583: end
00584:
00585: case (path)
00586:
00587: vmm_ral::BFM: begin
00588: int di = this.get_domain_index(domain);
00589: if (di < 0) return;
00590:
00591: if (this.frontdoor[di] != null) begin
00592: this.frontdoor[di].write(status, mem_addr, value,
00593: data_id, scenario_id, stream_id);
00594: end
00595: else begin
00596: bit [64-1:0] addr[];
00597: int w, j;
00598: int n_bits;
00599:
00600: if (this.offset_in_block[di] === 'x) begin
00601:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory \"%s\" unmapped in domain \"%s\" does not have a user-defined frontdoor",
: this.get_name(),
: this.domains[di])));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00604: return;
00605: end
00606:
00607: w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00608: mem_addr,
00609: this.get_n_bytes(),
00610: this.parent,
00611: this.domains[di],
00612: addr);
00613: j = 0;
00614: n_bits = this.get_n_bits;
00615: foreach (addr[i]) begin
00616: bit [64-1:0] data;
00617: data = value >> (j*8);
00618: this.ral_access.write(status, addr[i], data,
00619: (n_bits > w*8) ? w*8 : n_bits,
00620: this.parent.get_external_domain(this.domains[di]),
00621: data_id, scenario_id, stream_id);
00622: if (status != vmm_rw::IS_OK) break;
00623: j += w;
00624: n_bits -= w * 8;
00625: end
00626: end
00627:
00628: if (this.cover_on)
00629: this.parent.XsampleX(this.offset_in_block[di] +
00630: mem_addr * (((this.get_n_bytes()-1)/this.parent.get_n_bytes(domain))+1), di);
00631: end
00632:
00633: vmm_ral::BACKDOOR: begin
00634: // Mimick front door access: Do not write read-only memories
00635: if (this.get_access(domain) == vmm_ral::RW) begin
00636: this.poke(status, mem_addr, value,
00637: data_id, scenario_id, stream_id);
00638: end else status = vmm_rw::IS_OK;
00639: end
00640: endcase
00641:
00642:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_ral_mem_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.post_write(this, mem_addr, value, path, domain, status);
: end while (0);
00644:
00645:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Wrote memory \"%s\"[%0d] via %s: with 'h%h",
: this.get_fullname(), mem_addr,
: (path == vmm_ral::BFM) ? "frontdoor" : "backdoor",
: value)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00649: endtask: write
00650:
00651:
00652: task vmm_ral_mem::read(output vmm_rw::status_e status,
00653: input bit [64-1:0] mem_addr,
00654: output bit [64-1:0] value,
00655: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00656: input string domain = "",
00657: input int data_id = -1,
00658: input int scenario_id = -1,
00659: input int stream_id = -1);
00660: status = vmm_rw::ERROR;
00661:
00662: if (this.ral_access == null) begin
00663:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s not associated with RAL access object", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00664: return;
00665: end
00666:
00667: if (this.is_powered_down) begin
00668:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s cannot be accessed when it is powered down", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00669: return;
00670: end
00671:
00672: if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00673:
00674:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_ral_mem_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.pre_read(this, mem_addr, path, domain);
: end while (0);
00676:
00677: if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00678:
00679: if (path == vmm_ral::BACKDOOR &&
00680: this.backdoor == null) begin
00681:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("No backdoor access available for memory \"%s\". Using frontdoor instead.", this.get_name())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00682: path = vmm_ral::BFM;
00683: end
00684:
00685: case (path)
00686:
00687: vmm_ral::BFM: begin
00688: int di = this.get_domain_index(domain);
00689: if (di < 0) return;
00690:
00691: if (this.frontdoor[di] != null) begin
00692: this.frontdoor[di].read(status, mem_addr, value,
00693: data_id, scenario_id, stream_id);
00694: end
00695: else begin
00696: bit [64-1:0] addr[];
00697: int w, j;
00698: int n_bits;
00699:
00700: if (this.offset_in_block[di] === 'x) begin
00701:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory \"%s\" unmapped in domain \"%s\" does not have a user-defined frontdoor",
: this.get_name(),
: this.domains[di])));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00704: return;
00705: end
00706:
00707: w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00708: mem_addr,
00709: this.get_n_bytes(),
00710: this.parent,
00711: this.domains[di],
00712: addr);
00713: j = 0;
00714: n_bits = this.get_n_bits();
00715: value = 0;
00716: foreach (addr[i]) begin
00717: bit [64-1:0] data;
00718: this.ral_access.read(status, addr[i], data,
00719: (n_bits > w*8) ? w*8 : n_bits,
00720: this.parent.get_external_domain(this.domains[di]),
00721: data_id, scenario_id, stream_id);
00722: if (status != vmm_rw::IS_OK) break;
00723: value |= (data & ((1 << (w*8)) - 1)) << (j*8);
00724: j += w;
00725: n_bits -= w * 8;
00726: end
00727: end
00728:
00729: if (this.cover_on)
00730: this.parent.XsampleX(this.offset_in_block[di] +
00731: mem_addr * (((this.get_n_bytes()-1)/this.parent.get_n_bytes(domain))+1), di);
00732: end
00733:
00734: vmm_ral::BACKDOOR: begin
00735: this.peek(status, mem_addr, value,
00736: data_id, scenario_id, stream_id);
00737: end
00738: endcase
00739:
00740:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_ral_mem_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.post_read(this, mem_addr, value, path, domain, status);
: end while (0);
00742:
00743:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Read memory \"%s\"[%0d] via %s: 'h%h",
: this.get_fullname(), mem_addr,
: (path == vmm_ral::BFM) ? "frontdoor" : "backdoor",
: value)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00747: endtask: read
00748:
00749:
00750: function bit vmm_ral_mem::validate_burst(vmm_ral_mem_burst burst);
00751: if (burst.start_offset >= this.get_size()) begin
00752:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Starting burst offset 'h%0h is greater than number of memory locations 'h%0h",
: burst.start_offset, this.get_size())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00754: return 0;
00755: end
00756:
00757: if (burst.max_offset >= this.get_size()) begin
00758:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Maximum burst offset 'h%0h is greater than number of memory locations 'h%0h",
: burst.max_offset, this.get_size())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00760: return 0;
00761: end
00762:
00763: if (burst.n_beats == 0) begin
00764:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("Zero-length burst"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00765: return 0;
00766: end
00767:
00768: if (burst.start_offset > burst.max_offset) begin
00769:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Starting burst offset 'h%0h greater than maximum burst offset 'h%0h",
: burst.start_offset, burst.max_offset)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00771: return 0;
00772: end
00773:
00774: if (burst.n_beats > 1 &&
00775: burst.start_offset + burst.incr_offset >= burst.max_offset) begin
00776:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("First burst offset increment 'h%0h+%0h is greater than maximum burst offset 'h%0h",
: burst.start_offset, burst.incr_offset,
: burst.max_offset)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00779: return 0;
00780: end
00781:
00782: return 1;
00783: endfunction: validate_burst
00784:
00785:
00786: task vmm_ral_mem::burst_write(output vmm_rw::status_e status,
00787: input vmm_ral_mem_burst burst,
00788: input bit [64-1:0] value[],
00789: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00790: input string domain = "",
00791: input int data_id = -1,
00792: input int scenario_id = -1,
00793: input int stream_id = -1);
00794: status = vmm_rw::ERROR;
00795:
00796: if (this.ral_access == null) begin
00797:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s not associated with RAL access object", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00798: return;
00799: end
00800:
00801: if (this.is_powered_down) begin
00802:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s cannot be accessed when it is powered down", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00803: return;
00804: end
00805:
00806: if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00807:
00808:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_ral_mem_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.pre_burst(this, vmm_rw::WRITE, burst, value, path, domain);
: end while (0);
00810:
00811: if (!this.validate_burst(burst)) return;
00812:
00813: if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00814:
00815: case (path)
00816:
00817: vmm_ral::BFM: begin
00818: int di = this.get_domain_index(domain);
00819: if (di < 0) return;
00820:
00821: if (this.frontdoor[di] != null) begin
00822: this.frontdoor[di].burst_write(status, burst, value,
00823: data_id, scenario_id, stream_id);
00824: end
00825: else begin
00826: bit [64-1:0] addr[];
00827: int w;
00828: int n_bits;
00829:
00830: if (this.offset_in_block[di] === 'x) begin
00831:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory \"%s\" unmapped in domain \"%s\" does not have a user-defined frontdoor",
: this.get_name(),
: this.domains[di])));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00834: return;
00835: end
00836:
00837: w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00838: burst.start_offset,
00839: this.get_n_bytes(),
00840: this.parent,
00841: this.domains[di],
00842: addr);
00843: n_bits = this.get_n_bits;
00844: // Cannot burst memory through a narrower datapath
00845: if (n_bits > w*8) begin
00846:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Cannot burst-write a %0d-bit memory through a narrower data path %0d bytes",
: n_bits, w)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00848: return;
00849: end
00850: // Translate offsets into addresses
00851: begin
00852: bit [64-1:0] start, incr, max;
00853:
00854: start = addr[0];
00855:
00856: w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00857: burst.start_offset + burst.incr_offset,
00858: this.get_n_bytes(),
00859: this.parent,
00860: this.domains[di],
00861: addr);
00862: incr = addr[0] - start;
00863:
00864: w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00865: burst.max_offset,
00866: this.get_n_bytes(),
00867: this.parent,
00868: this.domains[di],
00869: addr);
00870:
00871: max = addr[addr.size()-1];
00872:
00873: this.ral_access.burst_write(status, start, incr, max, value,
00874: burst.user_data, n_bits,
00875: this.parent.get_external_domain(this.domains[di]),
00876: data_id, scenario_id, stream_id);
00877: end
00878: end
00879:
00880: if (this.cover_on) begin
00881: bit [64-1:0] addr;
00882: for (addr = burst.start_offset;
00883: addr <= burst.max_offset;
00884: addr += burst.incr_offset) begin
00885: this.parent.XsampleX(this.offset_in_block[di] + addr, di);
00886: end
00887: end
00888: end
00889:
00890: vmm_ral::BACKDOOR: begin
00891: // Mimick front door access: Do not write read-only memories
00892: if (this.get_access(domain) == vmm_ral::RW) begin
00893: bit [64-1:0] addr;
00894: addr = burst.start_offset;
00895: foreach (value[i]) begin
00896: this.poke(status, addr, value[i],
00897: data_id, scenario_id, stream_id);
00898: if (status != vmm_rw::IS_OK) return;
00899: addr += burst.incr_offset;
00900: if (addr > burst.max_offset) begin
00901: addr -= (burst.max_offset - burst.start_offset - 1);
00902: end
00903: end
00904: end
00905: else status = vmm_rw::IS_OK;
00906: end
00907: endcase
00908:
00909:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_ral_mem_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.post_burst(this, vmm_rw::WRITE, burst, value,
: path, domain, status);
: end while (0);
00912: endtask: burst_write
00913:
00914:
00915: task vmm_ral_mem::burst_read(output vmm_rw::status_e status,
00916: input vmm_ral_mem_burst burst,
00917: output bit [64-1:0] value[],
00918: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00919: input string domain = "",
00920: input int data_id = -1,
00921: input int scenario_id = -1,
00922: input int stream_id = -1);
00923: status = vmm_rw::ERROR;
00924:
00925: if (this.ral_access == null) begin
00926:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s not associated with RAL access object", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00927: return;
00928: end
00929:
00930: if (this.is_powered_down) begin
00931:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s cannot be accessed when it is powered down", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00932: return;
00933: end
00934:
00935: if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
00936:
00937: begin
00938: bit [64-1:0] junk[];
00939:
00940:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_ral_mem_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.pre_burst(this, vmm_rw::READ, burst, junk, path, domain);
: end while (0);
00942: end
00943:
00944: if (!this.validate_burst(burst)) return;
00945:
00946: if (path == vmm_ral::DEFAULT) path = this.parent.get_default_access();
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: if (this.frontdoor[di] != null) begin
00955: this.frontdoor[di].burst_read(status, burst, value,
00956: data_id, scenario_id, stream_id);
00957: end
00958: else begin
00959: bit [64-1:0] addr[];
00960: int n_bits, w;
00961:
00962: if (this.offset_in_block[di] === 'x) begin
00963:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory \"%s\" unmapped in domain \"%s\" does not have a user-defined frontdoor",
: this.get_name(),
: this.domains[di])));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00966: return;
00967: end
00968:
00969: w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00970: burst.start_offset,
00971: this.get_n_bytes(),
00972: this.parent,
00973: this.domains[di],
00974: addr);
00975: n_bits = this.get_n_bits();
00976: // Cannot burst memory through a narrower datapath
00977: if (n_bits > w*8) begin
00978:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Cannot burst-write a %0d-bit memory through a narrower data path %0d bytes",
: n_bits, w)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00980: return;
00981: end
00982: // Translate the offset-based burst into address-based burst
00983: begin
00984: bit [64-1:0] start, incr, max;
00985:
00986: start = addr[0];
00987:
00988: w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00989: burst.start_offset + burst.incr_offset,
00990: this.get_n_bytes(),
00991: this.parent,
00992: this.domains[di],
00993: addr);
00994: incr = addr[0] - start;
00995:
00996: w = this.ral_access.Xget_physical_addressesX(this.offset_in_block[di],
00997: burst.max_offset,
00998: this.get_n_bytes(),
00999: this.parent,
01000: this.domains[di],
01001: addr);
01002:
01003: max = addr[addr.size()-1];
01004:
01005: this.ral_access.burst_read(status, start, incr, max,
01006: burst.n_beats, value,
01007: burst.user_data, n_bits,
01008: this.parent.get_external_domain(this.domains[di]),
01009: data_id, scenario_id, stream_id);
01010: end
01011: end
01012:
01013: if (this.cover_on) begin
01014: bit [64-1:0] addr;
01015: for (addr = burst.start_offset;
01016: addr <= burst.max_offset;
01017: addr += burst.incr_offset) begin
01018: this.parent.XsampleX(this.offset_in_block[di] + addr, di);
01019: end
01020: end
01021: end
01022:
01023: vmm_ral::BACKDOOR: begin
01024: bit [64-1:0] addr;
01025: value = new [burst.n_beats];
01026: addr = burst.start_offset;
01027: foreach (value[i]) begin
01028: this.peek(status, addr, value[i],
01029: data_id, scenario_id, stream_id);
01030: if (status != vmm_rw::IS_OK) return;
01031: addr += burst.incr_offset;
01032: if (addr > burst.max_offset) begin
01033: addr -= (burst.max_offset - burst.start_offset - 1);
01034: end
01035: end
01036: end
01037: endcase
01038:
01039:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_ral_mem_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.post_burst(this, vmm_rw::READ, burst, value,
: path, domain, status);
: end while (0);
01042: endtask: burst_read
01043:
01044:
01045: task vmm_ral_mem::poke(output vmm_rw::status_e status,
01046: input bit [64-1:0] mem_addr,
01047: input bit [64-1:0] value,
01048: input int data_id = -1,
01049: input int scenario_id = -1,
01050: input int stream_id = -1);
01051: if (this.backdoor == null) begin
01052:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("No backdoor access available in memory %s", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01053: status = vmm_rw::ERROR;
01054: return;
01055: end
01056: if (this.is_powered_down) begin
01057:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s cannot be accessed when it is powered down", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01058: return;
01059: end
01060:
01061: this.backdoor.write(status, mem_addr, value, data_id, scenario_id, stream_id);
01062:
01063:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Poked memory \"%s\"[%0d] with: 'h%h",
: this.get_fullname(), mem_addr, value)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01065: endtask: poke
01066:
01067:
01068: task vmm_ral_mem::peek(output vmm_rw::status_e status,
01069: input bit [64-1:0] mem_addr,
01070: output bit [64-1:0] value,
01071: input int data_id = -1,
01072: input int scenario_id = -1,
01073: input int stream_id = -1);
01074: if (this.backdoor == null) begin
01075:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("No backdoor access available in memory %s", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01076: status = vmm_rw::ERROR;
01077: return;
01078: end
01079: if (this.is_powered_down) begin
01080:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Memory %s cannot be accessed when it is powered down", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01081: return;
01082: end
01083:
01084: this.backdoor.read(status, mem_addr, value, data_id, scenario_id, stream_id);
01085:
01086:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Peeked memory \"%s\"[%0d]: 'h%h",
: this.get_fullname(), mem_addr, value)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01088: endtask: peek
01089:
01090:
01091: task vmm_ral_mem::readmemh(string filename);
01092: endtask: readmemh
01093:
01094:
01095: task vmm_ral_mem::writememh(string filename);
01096: endtask: writememh
01097:
01098:
01099: function void vmm_ral_mem::set_frontdoor(vmm_ral_mem_frontdoor ftdr,
01100: string domain = "");
01101: foreach(this.domains[i]) begin
01102: if (this.domains[i] == domain) begin
01103: this.frontdoor[i] = ftdr;
01104: return;
01105: end
01106: end
01107:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Domain \"%s\" not found in memory %s", domain, this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01108: endfunction: set_frontdoor
01109:
01110:
01111: function vmm_ral_mem_frontdoor vmm_ral_mem::get_frontdoor(string domain = "");
01112: foreach(this.domains[i]) begin
01113: if (this.domains[i] == domain) begin
01114: return this.frontdoor[i];
01115: end
01116: end
01117:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Domain \"%s\" not found in memory %s", domain, this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01118: endfunction: get_frontdoor
01119:
01120:
01121: function void vmm_ral_mem::set_backdoor(vmm_ral_mem_backdoor bkdr);
01122: this.backdoor = bkdr;
01123: endfunction: set_backdoor
01124:
01125:
01126: function vmm_ral_mem_backdoor vmm_ral_mem::get_backdoor();
01127: get_backdoor = this.backdoor;
01128: endfunction: get_backdoor
01129:
01130:
01131: function void vmm_ral_mem::prepend_callback(vmm_ral_mem_callbacks cb);
01132: foreach (this.callbacks[i]) begin
01133: if (this.callbacks[i] == cb) begin
01134:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Callback has already been registered with memory %s", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
01135: return;
01136: end
01137: end
01138:
01139: // Prepend new callback
01140: this.callbacks.push_front(cb);
01141: endfunction: prepend_callback
01142:
01143:
01144: function void vmm_ral_mem::append_callback(vmm_ral_mem_callbacks cb);
01145: foreach (this.callbacks[i]) begin
01146: if (this.callbacks[i] == cb) begin
01147:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Callback has already been registered with memory %s", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
01148: return;
01149: end
01150: end
01151:
01152: // Append new callback
01153: this.callbacks.push_back(cb);
01154: endfunction: append_callback
01155:
01156:
01157: function void vmm_ral_mem::unregister_callback(vmm_ral_mem_callbacks cb);
01158: foreach (this.callbacks[i]) begin
01159: if (this.callbacks[i] == cb) begin
01160: int j = i;
01161: // Unregister it
01162: this.callbacks.delete(j);
01163: return;
01164: end
01165: end
01166:
01167:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Callback was not registered with memory %s", this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
01168: endfunction: unregister_callback
01169:
01170:
01171: function int vmm_ral_mem::get_domain_index(string domain);
01172: // If the domain is "" and there is only one domain,
01173: // assume it is the one domain available to avoid
01174: // having to always have to specify domains
01175: if (domain == "" && this.domains.size() == 1) return 0;
01176:
01177: foreach (this.domains[i]) begin
01178: if (this.domains[i] == domain) return i;
01179: end
01180:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Unknown domain name \"%s\" in memory %s.", domain, this.get_fullname())));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
01181: return -1;
01182: endfunction: get_domain_index
01183:
01184:
01185: task vmm_ral_mem_frontdoor::write(output vmm_rw::status_e status,
01186: input bit [64-1:0] offset,
01187: input bit [64-1:0] data,
01188: input int data_id = -1,
01189: input int scenario_id = -1,
01190: input int stream_id = -1);
01191:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin
: void'(this.log.text("vmm_ral_mem_frontdoor::write method has not been overloaded"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01192: endtask: write
01193:
01194:
01195: task vmm_ral_mem_frontdoor::read(output vmm_rw::status_e status,
01196: input bit [64-1:0] offset,
01197: output bit [64-1:0] data,
01198: input int data_id = -1,
01199: input int scenario_id = -1,
01200: input int stream_id = -1);
01201:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin
: void'(this.log.text("vmm_ral_mem_frontdoor::read method has not been overloaded"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01202: endtask: read
01203:
01204: task vmm_ral_mem_frontdoor::burst_write(output vmm_rw::status_e status,
01205: input vmm_ral_mem_burst burst,
01206: input bit [64-1:0] data[],
01207: input int data_id = -1,
01208: input int scenario_id = -1,
01209: input int stream_id = -1);
01210:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin
: void'(this.log.text("vmm_ral_mem_frontdoor::burst_write method has not been overloaded"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01211: endtask
01212:
01213: task vmm_ral_mem_frontdoor::burst_read(output vmm_rw::status_e status,
01214: input vmm_ral_mem_burst burst,
01215: output bit [64-1:0] data[],
01216: input int data_id = -1,
01217: input int scenario_id = -1,
01218: input int stream_id = -1);
01219:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin
: void'(this.log.text("vmm_ral_mem_frontdoor::burst_read method has not been overloaded"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01220: endtask
01221:
01222:
01223: function int unsigned vmm_ral_mem::get_mem_ID();
01224: get_mem_ID = this.mem_id;
01225: endfunction
01226:
01227: function vmm_ral_mem vmm_ral_get_mem_by_ID(int unsigned id);
01228: vmm_ral_mem m;
01229: if (m.all_mems.exists(id))
01230: vmm_ral_get_mem_by_ID = m.all_mems[id];
01231: else vmm_ral_get_mem_by_ID = null;
01232: endfunction