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_rw.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: 00024: `define RVM_RW__SV 00025: 00027: 00030: `define VMM_RW_ADDR_WIDTH `VMM_RAL_ADDR_WIDTH : 00037: `define VMM_RW_DATA_WIDTH `VMM_RAL_DATA_WIDTH : 00042: 00043: 00044: class vmm_rw; 00045: typedef enum { 00046: READ, 00047: WRITE, 00048: EXPECT 00049: } kind_e; 00050: 00051: typedef enum { 00052: IS_OK, 00053: ERROR, 00054: RETRY 00055: } status_e; 00056: endclass: vmm_rw 00057: 00058: 00059: class vmm_rw_access extends vmm_data; 00060: static vmm_log log = new("vmm_rw_access", "class"); 00061: 00062: rand vmm_rw::kind_e kind; 00063: 00064: rand bit [64-1:0] addr; 00065: rand logic [64-1:0] data; 00066: rand int n_bits = 64; 00067: 00068: vmm_rw::status_e status; 00069: 00070: constraint valid_vmm_rw_access { 00071: n_bits > 0; 00072: n_bits < 64; 00073: } 00074: 00075: extern function new(); 00076: extern virtual function string psdisplay(string prefix = ""); 00077: endclass: vmm_rw_access 00078: : class vmm_rw_access_channel extends vmm_channel; : : function new(string name, : string inst, : int full = 1, : int empty = 0, : bit fill_as_bytes = 0); : super.new(name, inst, full, empty, fill_as_bytes); : endfunction: new : : function vmm_rw_access unput(int offset = -1); : $cast(unput, super.unput(offset)); : endfunction: unput : : task get(output vmm_rw_access obj, input int offset = 0); : vmm_data o; : super.get(o, offset); : $cast(obj, o); : endtask: get : : task peek(output vmm_rw_access obj, input int offset = 0); : vmm_data o; : super.peek(o, offset); : $cast(obj, o); : endtask: peek : : task activate(output vmm_rw_access obj, input int offset = 0); : vmm_data o; : super.activate(o, offset); : $cast(obj, o); : endtask: activate : : function vmm_rw_access active_slot(); : $cast(active_slot, super.active_slot()); : endfunction: active_slot : : function vmm_rw_access start(); : $cast(start, super.start()); : endfunction: start : : function vmm_rw_access complete(vmm_data status = null); : $cast(complete, super.complete(status)); : endfunction: complete : : function vmm_rw_access remove(); : $cast(remove, super.remove()); : endfunction: remove : : task tee(output vmm_rw_access obj); : vmm_data o; : super.tee(o); : $cast(obj, o); : endtask: tee : : function vmm_rw_access for_each(bit reset = 0); : $cast(for_each, super.for_each(reset)); : endfunction: for_each : endclass 00079: 00080: 00081: class vmm_rw_burst extends vmm_rw_access; 00082: rand int unsigned n_beats; 00083: rand bit [64-1:0] incr_addr; 00084: rand bit [64-1:0] max_addr; 00085: rand logic [64-1:0] data[]; 00086: vmm_data user_data; 00087: 00088: constraint vmm_rw_burst_valid { 00089: n_beats > 0; 00090: max_addr >= addr; 00091: if (kind == vmm_rw::WRITE || kind == vmm_rw::EXPECT) data.size() == n_beats; 00092: else data.size() == 0; 00093: } 00094: 00095: constraint reasonable { 00096: n_beats <= 1024; 00097: incr_addr inside {0, 1, 2, 4, 8, 16, 32}; 00098: } 00099: 00100: constraint linear { 00101: incr_addr == 1; 00102: max_addr == addr + n_beats - 1; 00103: } 00104: 00105: constraint fifo { 00106: incr_addr == 0; 00107: max_addr == addr; 00108: } 00109: 00110: constraint wrap { 00111: incr_addr > 0; 00112: max_addr < addr + (n_beats - 1)* incr_addr; 00113: } 00114: 00115: function new(); 00116: this.linear.constraint_mode(0); 00117: this.fifo.constraint_mode(0); 00118: this.wrap.constraint_mode(0); 00119: endfunction: new 00120: endclass: vmm_rw_burst 00121: 00122: 00123: typedef class vmm_rw_xactor; 00124: class vmm_rw_xactor_callbacks extends vmm_xactor_callbacks; 00125: virtual task pre_single(vmm_rw_xactor xactor, 00126: vmm_rw_access tr); 00127: endtask 00128: 00129: virtual task pre_burst(vmm_rw_xactor xactor, 00130: vmm_rw_burst tr); 00131: endtask 00132: 00133: virtual task post_single(vmm_rw_xactor xactor, 00134: vmm_rw_access tr); 00135: endtask 00136: 00137: virtual task post_burst(vmm_rw_xactor xactor, 00138: vmm_rw_burst tr); 00139: endtask 00140: endclass: vmm_rw_xactor_callbacks 00141: 00142: 00143: class vmm_rw_xactor extends vmm_xactor; 00144: typedef enum {BURST_DONE = 99990, 00145: SINGLE_DONE} notifications_e; 00146: 00147: vmm_rw_access_channel exec_chan; 00148: 00149: extern function new(string name, 00150: string instance, 00151: int stream_id = -1, 00152: vmm_rw_access_channel exec_chan = null); 00153: 00154: extern protected virtual task execute_single(vmm_rw_access tr); 00155: extern protected virtual task execute_burst(vmm_rw_burst tr); 00156: 00157: extern protected virtual task main(); 00158: extern function void reset_xactor(reset_e rst_typ = SOFT_RST); 00159: endclass: vmm_rw_xactor 00160: 00161: 00162: function vmm_rw_access::new(); 00163: super.new(this.log); 00164: endfunction: new 00165: 00166: function string vmm_rw_access::psdisplay(string prefix); 00167: string fmt; 00168: $sformat(fmt, "%0dh", this.n_bits); 00169: $sformat(psdisplay, {"%s%s @ 0x%h = %0d'h%", fmt, "\n"}, prefix, 00170: kind.name(), addr, n_bits, data); 00171: endfunction: psdisplay 00172: 00173: 00174: function vmm_rw_xactor::new(string name, 00175: string instance, 00176: int stream_id, 00177: vmm_rw_access_channel exec_chan); 00178: super.new(name, instance, stream_id); 00179: 00180: if (exec_chan == null) exec_chan = new({name, " Input Channel"}, instance); 00181: this.exec_chan = exec_chan; 00182: 00183: this.log.is_above(this.exec_chan.log); 00184: 00185: this.notify.configure(BURST_DONE); 00186: this.notify.configure(SINGLE_DONE); 00187: endfunction: new 00188: 00189: 00190: task vmm_rw_xactor::execute_single(vmm_rw_access tr); 00191: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin : void'(this.log.text("Undefined execute_single() method in vmm_rw_xactor extension")); : this.log.end_msg(); : end : while (0); 00192: endtask: execute_single 00193: 00194: 00195: task vmm_rw_xactor::execute_burst(vmm_rw_burst tr); 00196: bit [64-1:0] addr; 00197: int i; 00198: 00199: addr = tr.addr; 00200: i = 0; 00201: tr.status = vmm_rw::IS_OK; 00202: if (tr.kind == vmm_rw::READ) tr.data = new [tr.n_beats]; 00203: repeat (tr.n_beats) begin 00204: vmm_rw_access s = new; 00205: s.kind = tr.kind; 00206: s.addr = addr; 00207: if (s.kind != vmm_rw::READ) s.data = tr.data[i++]; 00208: this.execute_single(s); 00209: if (s.kind == vmm_rw::READ) tr.data[i++] = s.data; 00210: if (s.status != vmm_rw::IS_OK) begin 00211: tr.status = s.status; 00212: return; 00213: end 00214: 00215: addr += tr.incr_addr; 00216: if (addr > tr.max_addr) addr = addr - tr.max_addr + tr.addr; 00217: end 00218: tr.status = vmm_rw::IS_OK; 00219: endtask: execute_burst 00220: 00221: 00222: task vmm_rw_xactor::main(); 00223: vmm_rw_access tr; 00224: vmm_rw_burst br; 00225: 00226: fork 00227: super.main(); 00228: join_none 00229: 00230: forever begin 00231: this.wait_if_stopped_or_empty(this.exec_chan); 00232: 00233: this.exec_chan.activate(tr); 00234: this.exec_chan.start(); 00235: 00236: if ($cast(br, tr)) begin 00238: : : do foreach (this.callbacks[vmm_i]) begin : vmm_rw_xactor_callbacks cb; : if (!$cast(cb, this.callbacks[vmm_i])) continue; : : cb.pre_burst(this, br); : end while (0); 00239: this.execute_burst(br); 00241: : : do foreach (this.callbacks[vmm_i]) begin : vmm_rw_xactor_callbacks cb; : if (!$cast(cb, this.callbacks[vmm_i])) continue; : : cb.post_burst(this, br); : end while (0); 00242: this.notify.indicate(BURST_DONE, br); 00243: end 00244: else begin 00245: : : do foreach (this.callbacks[vmm_i]) begin : vmm_rw_xactor_callbacks cb; : if (!$cast(cb, this.callbacks[vmm_i])) continue; : : cb.pre_single(this, tr); : end while (0); 00246: this.execute_single(tr); 00248: : : do foreach (this.callbacks[vmm_i]) begin : vmm_rw_xactor_callbacks cb; : if (!$cast(cb, this.callbacks[vmm_i])) continue; : : cb.post_single(this, tr); : end while (0); 00249: this.notify.indicate(SINGLE_DONE, tr); 00250: end 00251: 00252: this.exec_chan.complete(); 00253: this.exec_chan.remove(); 00254: end 00255: endtask: main 00256: 00257: 00258: function void vmm_rw_xactor::reset_xactor(reset_e rst_typ); 00259: vmm_rw_access tr; 00260: 00261: super.reset_xactor(rst_typ); 00262: 00263: // Force a completion of the transaction to avoid 00264: // leaving the RAL model blocked 00265: tr = this.exec_chan.active_slot(); 00266: if (tr != null) begin 00267: tr.status = vmm_rw::RETRY; 00268: this.exec_chan.complete(); 00269: this.exec_chan.remove(); 00270: end 00271: this.exec_chan.flush(); 00272: endfunction: reset_xactor 00273: