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: class vmm_ral_access extends vmm_xactor;
00024: vmm_ral::path_e default_path = vmm_ral::BFM; // Cannot be "DEFAULT"
00025:
00026: protected vmm_ral_block_or_sys model;
00027:
00028: protected vmm_rw_xactor rw_exec[string]; // One per domain
00029:
00030: extern function new();
00031:
00032: extern function void set_model(vmm_ral_block_or_sys model);
00033: extern function vmm_ral_block_or_sys get_model();
00034: extern function void add_xactor(vmm_rw_xactor xact,
00035: string domain = "");
00036:
00037: extern task write(output vmm_rw::status_e status,
00038: input bit [64-1:0] addr,
00039: input bit [64-1:0] data,
00040: input int n_bits = 64,
00041: input string domain = "",
00042: input int data_id = -1,
00043: input int scenario_id = -1,
00044: input int stream_id = -1);
00045:
00046: extern task read(output vmm_rw::status_e status,
00047: input bit [64-1:0] addr,
00048: output bit [64-1:0] data,
00049: input int n_bits = 64,
00050: input string domain = "",
00051: input int data_id = -1,
00052: input int scenario_id = -1,
00053: input int stream_id = -1);
00054:
00055: extern task burst_write(output vmm_rw::status_e status,
00056: input bit [64-1:0] start,
00057: input bit [64-1:0] incr,
00058: input bit [64-1:0] max,
00059: input bit [64-1:0] data[],
00060: input vmm_data user = null,
00061: input int n_bits = 64,
00062: input string domain = "",
00063: input int data_id = -1,
00064: input int scenario_id = -1,
00065: input int stream_id = -1);
00066:
00067: extern task burst_read(output vmm_rw::status_e status,
00068: input bit [64-1:0] start,
00069: input bit [64-1:0] incr,
00070: input bit [64-1:0] max,
00071: input int n_beats,
00072: output bit [64-1:0] data[],
00073: input vmm_data user = null,
00074: input int n_bits = 64,
00075: input string domain = "",
00076: input int data_id = -1,
00077: input int scenario_id = -1,
00078: input int stream_id = -1);
00079:
00080: extern virtual function bit set_by_name(input string name,
00081: input bit [64-1:0] value);
00082: extern virtual function bit get_by_name(input string name,
00083: output bit [64-1:0] value);
00084:
00085: extern task write_by_name(output vmm_rw::status_e status,
00086: input string name,
00087: input bit [64-1:0] data,
00088: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00089: input string domain = "",
00090: input int data_id = -1,
00091: input int scenario_id = -1,
00092: input int stream_id = -1);
00093:
00094: extern task read_by_name(output vmm_rw::status_e status,
00095: input string name,
00096: output bit [64-1:0] data,
00097: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00098: input string domain = "",
00099: input int data_id = -1,
00100: input int scenario_id = -1,
00101: input int stream_id = -1);
00102:
00103: extern task write_mem_by_name(output vmm_rw::status_e status,
00104: input string name,
00105: input bit [64-1:0] offset,
00106: input bit [64-1:0] data,
00107: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00108: input string domain = "",
00109: input int data_id = -1,
00110: input int scenario_id = -1,
00111: input int stream_id = -1);
00112:
00113: extern task read_mem_by_name(output vmm_rw::status_e status,
00114: input string name,
00115: input bit [64-1:0] offset,
00116: output bit [64-1:0] data,
00117: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00118: input string domain = "",
00119: input int data_id = -1,
00120: input int scenario_id = -1,
00121: input int stream_id = -1);
00122:
00123: /*local*/ extern function int
00124: Xget_physical_addressesX(bit [64-1:0] base_addr,
00125: bit [64-1:0] mem_offset,
00126: int unsigned n_bytes,
00127: vmm_ral_block_or_sys in_block,
00128: string domain,
00129: ref bit [64-1:0] addr[]);
00130: endclass: vmm_ral_access
00131:
00132:
00133: function vmm_ral_access::new();
00134: super.new("RVM RAL Access", "Main");
00135: endfunction: new
00136:
00137:
00138: function void vmm_ral_access::set_model(vmm_ral_block_or_sys model);
00139: if (this.model != null) begin
00140:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("A RAL abstraction model has already been associated with this RAL access interface"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00141: return;
00142: end
00143:
00144: this.model = model;
00145:
00146: // Register this RAL access object with the RAL model
00147: model.Xregister_ral_accessX(this);
00148: endfunction: set_model
00149:
00150:
00151: function vmm_ral_block_or_sys vmm_ral_access::get_model();
00152: get_model = this.model;
00153: endfunction: get_model
00154:
00155:
00156: function void vmm_ral_access::add_xactor(vmm_rw_xactor xact,
00157: string domain = "");
00158: if (this.model == null) begin
00159:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("A RAL abstraction model has not yet been associated with this RAL access interface"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00160: return;
00161: end
00162:
00163: // Check if the specified domain matches a domain in the model
00164: begin
00165: string domains[];
00166: bit found = 0;
00167:
00168: model.get_domains(domains);
00169: foreach (domains[i]) begin
00170: if (domains[i] == domain) begin
00171: found = 1;
00172: break;
00173: end
00174: end
00175: if (!found) begin
00176:
: 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\" does not exist in RAL model",
: domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00178: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin
00179: string msg;
00180: void'(this.log.text($psprintf("Domain \"%s\" does not exist in RAL model \"%s\"",
00181: domain, this.model.get_name())));
00182: msg = "Available domains are:";
00183: foreach (domains[i]) begin
00184: $sformat(msg, "%s \"%s\"", msg, domains[i]);
00185: end
00186: void'(this.log.text(msg));
00187: this.log.end_msg();
00188: end
00189: return;
00190: end
00191: end
00192:
00193: if (this.rw_exec.exists(domain)) begin
00194:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Transactor for domain \"%s\" already exists",
: domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00196: end
00197: else begin
00198: this.rw_exec[domain] = xact;
00199:
00200: // Make sure transactor is started
00201: xact.start_xactor();
00202: end
00203: endfunction: add_xactor
00204:
00205:
00206: task vmm_ral_access::write(output vmm_rw::status_e status,
00207: input bit [64-1:0] addr,
00208: input bit [64-1:0] data,
00209: input int n_bits = 64,
00210: input string domain = "",
00211: input int data_id = -1,
00212: input int scenario_id = -1,
00213: input int stream_id = -1);
00214: status = vmm_rw::ERROR;
00215:
00216: if (!this.rw_exec.exists(domain)) begin
00217:
: 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 transactor available to physically access domain \"%s\".",
: domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00219: return;
00220: end
00221:
00222:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Writing 'h%h at 'h%h via domain \"%s\"...",
: data, addr, domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00224:
00225: begin
00226: vmm_rw_access rw = new;
00227:
00228: rw.data_id = data_id;
00229: rw.scenario_id = scenario_id;
00230: rw.stream_id = stream_id;
00231:
00232: rw.kind = vmm_rw::WRITE;
00233: rw.addr = addr;
00234: rw.data = data;
00235: rw.n_bits = n_bits;
00236: this.rw_exec[domain].exec_chan.put(rw);
00237:
00238: status = rw.status;
00239: end
00240: endtask: write
00241:
00242:
00243: task vmm_ral_access::read(output vmm_rw::status_e status,
00244: input bit [64-1:0] addr,
00245: output bit [64-1:0] data,
00246: input int n_bits = 64,
00247: input string domain = "",
00248: input int data_id = -1,
00249: input int scenario_id = -1,
00250: input int stream_id = -1);
00251: status = vmm_rw::ERROR;
00252:
00253: if (!this.rw_exec.exists(domain)) begin
00254:
: 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 transactor available to physically access domain \"%s\".",
: domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00256: return;
00257: end
00258:
00259: begin
00260: vmm_rw_access rw = new;
00261:
00262: rw.data_id = data_id;
00263: rw.scenario_id = scenario_id;
00264: rw.stream_id = stream_id;
00265:
00266: rw.kind = vmm_rw::READ;
00267: rw.addr = addr;
00268: rw.n_bits = n_bits;
00269: this.rw_exec[domain].exec_chan.put(rw);
00270:
00271: data = rw.data;
00272: status = rw.status;
00273: end
00274:
00275:
: 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 'h%h from 'h%h via domain \"%s\"...",
: data, addr, domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00277:
00278: endtask: read
00279:
00280:
00281: task vmm_ral_access::burst_write(output vmm_rw::status_e status,
00282: input bit [64-1:0] start,
00283: input bit [64-1:0] incr,
00284: input bit [64-1:0] max,
00285: input bit [64-1:0] data[],
00286: input vmm_data user = null,
00287: input int n_bits = 64,
00288: input string domain = "",
00289: input int data_id = -1,
00290: input int scenario_id = -1,
00291: input int stream_id = -1);
00292: status = vmm_rw::ERROR;
00293:
00294: if (!this.rw_exec.exists(domain)) begin
00295:
: 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 transactor available to physically access domain \"%s\".",
: domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00297: return;
00298: end
00299:
00300: begin
00301: vmm_rw_burst rw = new;
00302:
00303: rw.data_id = data_id;
00304: rw.scenario_id = scenario_id;
00305: rw.stream_id = stream_id;
00306:
00307: rw.kind = vmm_rw::WRITE;
00308: rw.addr = start;
00309: rw.incr_addr = incr;
00310: rw.max_addr = max;
00311: rw.n_beats = data.size();
00312: rw.n_bits = n_bits;
00313: rw.user_data = user;
00314:
00315: rw.data = new [rw.n_beats];
00316: foreach (data[i]) rw.data[i] = data[i];
00317:
00318: this.rw_exec[domain].exec_chan.put(rw);
00319:
00320: status = rw.status;
00321: end
00322:
00323:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Burst-wrote %0d data from ['h%h+'h%h %%'h%h] via domain \"%s\"...",
: data.size(), start, incr, max, domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00325:
00326: endtask: burst_write
00327:
00328:
00329: task vmm_ral_access::burst_read(output vmm_rw::status_e status,
00330: input bit [64-1:0] start,
00331: input bit [64-1:0] incr,
00332: input bit [64-1:0] max,
00333: input int n_beats,
00334: output bit [64-1:0] data[],
00335: input vmm_data user = null,
00336: input int n_bits = 64,
00337: input string domain = "",
00338: input int data_id = -1,
00339: input int scenario_id = -1,
00340: input int stream_id = -1);
00341: status = vmm_rw::ERROR;
00342:
00343: if (!this.rw_exec.exists(domain)) begin
00344:
: 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 transactor available to physically access domain \"%s\".",
: domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00346: return;
00347: end
00348:
00349: begin
00350: vmm_rw_burst rw = new;
00351:
00352: rw.data_id = data_id;
00353: rw.scenario_id = scenario_id;
00354: rw.stream_id = stream_id;
00355:
00356: rw.kind = vmm_rw::READ;
00357: rw.addr = start;
00358: rw.incr_addr = incr;
00359: rw.max_addr = max;
00360: rw.n_beats = n_beats;
00361: rw.n_bits = n_bits;
00362: rw.user_data = user;
00363:
00364: this.rw_exec[domain].exec_chan.put(rw);
00365:
00366: data = new [rw.data.size()];
00367: foreach (data[i]) data[i] = rw.data[i];
00368: status = rw.status;
00369: end
00370:
00371:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Burst-read %0d data from ['h%h+'h%h %%'h%h] via domain \"%s\"...",
: data.size(), start, incr, max, domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00373:
00374: endtask: burst_read
00375:
00376:
00377: function bit vmm_ral_access::set_by_name(string name,
00378: bit [64-1:0] value);
00379: vmm_ral_reg rg;
00380:
00381: set_by_name = 0;
00382: rg = this.model.get_reg_by_name(name);
00383: if (rg == null) return 0;
00384:
00385: rg.set(value);
00386: set_by_name = 1;
00387: endfunction: set_by_name
00388:
00389:
00390: function bit vmm_ral_access::get_by_name(input string name,
00391: output bit [64-1:0] value);
00392: vmm_ral_reg rg;
00393:
00394: get_by_name = 0;
00395: rg = this.model.get_reg_by_name(name);
00396: if (rg == null) return 0;
00397:
00398: value = rg.get();
00399: get_by_name = 1;
00400: endfunction: get_by_name
00401:
00402:
00403: task vmm_ral_access::write_by_name(output vmm_rw::status_e status,
00404: input string name,
00405: input bit [64-1:0] data,
00406: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00407: input string domain = "",
00408: input int data_id = -1,
00409: input int scenario_id = -1,
00410: input int stream_id = -1);
00411: vmm_ral_reg rg;
00412:
00413: status = vmm_rw::ERROR;
00414: rg = this.model.get_reg_by_name(name);
00415: if (rg == null) return;
00416:
00417: rg.write(status, data, path, domain, data_id, scenario_id, stream_id);
00418: endtask: write_by_name
00419:
00420:
00421: task vmm_ral_access::read_by_name(output vmm_rw::status_e status,
00422: input string name,
00423: output bit [64-1:0] data,
00424: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00425: input string domain = "",
00426: input int data_id = -1,
00427: input int scenario_id = -1,
00428: input int stream_id = -1);
00429: vmm_ral_reg rg;
00430:
00431: status = vmm_rw::ERROR;
00432: rg = this.model.get_reg_by_name(name);
00433: if (rg == null) return;
00434:
00435: rg.read(status, data, path, domain, data_id, scenario_id, stream_id);
00436: endtask: read_by_name
00437:
00438:
00439: task vmm_ral_access::write_mem_by_name(output vmm_rw::status_e status,
00440: input string name,
00441: input bit [64-1:0] offset,
00442: input bit [64-1:0] data,
00443: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00444: input string domain = "",
00445: input int data_id = -1,
00446: input int scenario_id = -1,
00447: input int stream_id =-1);
00448: vmm_ral_mem mem;
00449:
00450: status = vmm_rw::ERROR;
00451: mem = this.model.get_mem_by_name(name);
00452: if (mem == null) return;
00453:
00454: mem.write(status, offset, data, path, domain, data_id, scenario_id, stream_id);
00455: endtask: write_mem_by_name
00456:
00457:
00458: task vmm_ral_access::read_mem_by_name(output vmm_rw::status_e status,
00459: input string name,
00460: input bit [64-1:0] offset,
00461: output bit [64-1:0] data,
00462: input vmm_ral::path_e path = vmm_ral::DEFAULT,
00463: input string domain = "",
00464: input int data_id = -1,
00465: input int scenario_id = -1,
00466: input int stream_id = -1);
00467: vmm_ral_mem mem;
00468:
00469: status = vmm_rw::ERROR;
00470: mem = this.model.get_mem_by_name(name);
00471: if (mem == null) return;
00472:
00473: mem.read(status, offset, data, path, domain, data_id, scenario_id, stream_id);
00474: endtask: read_mem_by_name
00475:
00476:
00477: //
00478: // Identify the sequence of addresses that must be accessed physically
00479: // to access the specified number of bytes at the specified address
00480: // within the specified block or system. Returns the number of bytes
00481: // of valid data in each access.
00482: //
00483: // Returns a list of address in little endian order, with the granularity
00484: // of the top-level system
00485: //
00486: // A register is specified as a base address with mem_indx == 0.
00487: // A location within a memory is specified as an index from a base address.
00488: //
00489: function int vmm_ral_access::Xget_physical_addressesX(bit [64-1:0] base_addr,
00490: bit [64-1:0] mem_offset,
00491: int unsigned n_bytes,
00492: vmm_ral_block_or_sys in_block,
00493: string domain,
00494: ref bit [64-1:0] addr[]);
00495: int bus_width = in_block.get_n_bytes(domain);
00496: bit [64-1:0] local_addr[];
00497: vmm_ral_block_or_sys parent = in_block.get_parent();
00498:
00499: addr = new [0];
00500:
00501: if (n_bytes <= 0) begin
00502:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Cannot access %0d bytes. Must be greater than 0",
: n_bytes)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00504: return 0;
00505: end
00506:
00507: // First, identify the addresses within the block/system
00508: if (n_bytes <= bus_width) begin
00509: local_addr = new [1];
00510: local_addr[0] = base_addr + mem_offset;
00511: end else begin
00512: int n;
00513:
00514: n = ((n_bytes-1) / bus_width) + 1;
00515: local_addr = new [n];
00516:
00517: base_addr = base_addr + mem_offset * n;
00518:
00519: case (in_block.get_endian(domain))
00520: vmm_ral::LITTLE_ENDIAN: begin
00521: foreach (local_addr[i]) begin
00522: local_addr[i] = base_addr + i;
00523: end
00524: end
00525: vmm_ral::BIG_ENDIAN: begin
00526: foreach (local_addr[i]) begin
00527: n--;
00528: local_addr[i] = base_addr + n;
00529: end
00530: end
00531: vmm_ral::LITTLE_FIFO: begin
00532: foreach (local_addr[i]) begin
00533: local_addr[i] = base_addr;
00534: end
00535: end
00536: vmm_ral::BIG_FIFO: begin
00537: foreach (local_addr[i]) begin
00538: local_addr[i] = base_addr;
00539: end
00540: end
00541: default: begin
00542:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Block has no specified endianness. Cannot access %0d bytes register via its %0d byte \"%s\" interface",
: n_bytes, in_block.get_n_bytes(domain), domain)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00544: end
00545: endcase
00546: end
00547:
00548:
00549: // Then translate these addresses in the parent's space
00550: if (parent == null) begin
00551: // This is the top-most system/block!
00552: addr = new [local_addr.size()] (local_addr);
00553: end else begin
00554: bit [64-1:0] sys_addr[];
00555: bit [64-1:0] base_addr;
00556: string up_domain;
00557: int w, k;
00558:
00559: up_domain = in_block.get_parent_domain(domain);
00560:
00561: // Scale the consecutive local address in the system's granularity
00562: if (bus_width < parent.get_n_bytes(up_domain)) k = 1;
00563: else k = ((bus_width-1) / parent.get_n_bytes(up_domain)) + 1;
00564:
00565: base_addr = in_block.get_base_addr(domain);
00566: foreach (local_addr[i]) begin
00567: int n = addr.size();
00568:
00569: w = this.Xget_physical_addressesX(base_addr + local_addr[i] * k, 0,
00570: bus_width, parent, up_domain,
00571: sys_addr);
00572:
00573: addr = new [n + sys_addr.size()] (addr);
00574: foreach (sys_addr[j]) begin
00575: addr[n+j] = sys_addr[j];
00576: end
00577: end
00578: // The width of each access is the minimum of this block or the system's width
00579: if (w < bus_width) bus_width = w;
00580: end
00581:
00582: Xget_physical_addressesX = bus_width;
00583: endfunction: Xget_physical_addressesX