VMM OpenSource - (expanded) sv/perf/vmm_perf_analyzer.sv

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.

sv/perf/vmm_perf_analyzer.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 VMM_PERF_ANALYZER__SV
00025: 
00029: 
00030: class vmm_perf_data;
00031:    time start_time;
00032:    time end_time;
00033:    time resume_time;
00034:    time active_time = 0;
00035:    string more_data;
00036: 
00037:    bit  aborted;
00038: 
00039:    vmm_perf_tenure tenure;
00040: endclass: vmm_perf_data
00041: 
00042: 
00043: typedef class vmm_perf_analyzer;
00044: 
00045: 
00046: class vmm_perf_analyzer_callbacks;
00047:    virtual function void analyze_tenure(vmm_perf_analyzer analyzer,
00048:                                         vmm_perf_tenure   tenure,
00049:                                         ref time          start_time,
00050:                                         ref time          end_time,
00051:                                         ref time          active_time,
00052:                                         ref bit           aborted,
00053:                                         ref string        more_data,
00054:                                         ref bit           filtered);
00055:    endfunction
00056: endclass
00057: 
00058: 
00059: class vmm_perf_analyzer;
00060: 
00061:    typedef enum {SOFT, HARD} reset_e;
00062: 
00063:    vmm_log log;
00064: 
00065:    local int unsigned max_n_initiators;
00066:    local int unsigned max_n_targets;
00067:    local int unsigned max_n_concurrent;
00068: 
00069:    local int unsigned known_initiators[*];
00070:    local int unsigned known_targets[*];
00071: 
00072:    local vmm_perf_data active[$];
00073:    local vmm_perf_data suspended[$];
00074:    local vmm_perf_data completed[$];
00075: 
00076:    local vmm_sql_table sql_table;
00077:    local string        user_schema;
00078: 
00079:    local vmm_perf_analyzer_callbacks cbs[$];
00080: 
00081:    // For simple report
00082:    local time min_time;
00083:    local time max_time;
00084:    local time active_time;
00085:    local time min_abort_time;
00086:    local time max_abort_time;
00087:    local time abort_time;
00088:    local int  n;
00089: 
00090:    extern function new(string       name             = "",
00091:                        vmm_sql_db   sql_db,
00092:                        int unsigned max_n_initiators = 0,
00093:                        int unsigned max_n_targets    = 0,
00094:                        int unsigned max_n_concurrent = 1,
00095:                        string user_schema = "");
00096: 
00097:    extern virtual function time now();
00098: 
00099:    extern function void start_tenure(vmm_perf_tenure tenure);
00100:    extern function void suspend_tenure(vmm_perf_tenure tenure);
00101:    extern function void resume_tenure(vmm_perf_tenure tenure);
00102:    extern function void end_tenure(vmm_perf_tenure tenure,
00103:                                    string more_data = "");
00104:    extern function void abort_tenure(vmm_perf_tenure tenure,
00105:                                      string more_data = "");
00106:    extern function bit add_tenure(int      initiator_id = -1,
00107:                                   int      target_id    = -1,
00108:                                   time     start_time,
00109:                                   time     end_time,
00110:                                   vmm_data tr           = null,
00111:                                   time     active_time  = 0,
00112:                                   bit      aborted      = 0,
00113:                                   string   more_data    = "");
00114: 
00115:    extern virtual function string psdisplay(string prefix = "");
00116:    extern function void report(string name         = "",
00117:                                bit    brief        = 1);
00118: 
00119:    extern function vmm_sql_db get_db();
00120:    extern function void save_db();
00121:    extern function void save_db_txt(string name = "");
00122: 
00123:    extern function void reset(reset_e rst_typ = SOFT);
00124: 
00125:    extern function void append_callback(vmm_perf_analyzer_callbacks cb);
00126:    extern function void prepend_callback(vmm_perf_analyzer_callbacks cb);
00127:    extern function void unregister_callback(vmm_perf_analyzer_callbacks cb);
00128: endclass: vmm_perf_analyzer
00129: 
00130: function vmm_perf_analyzer::new(string       name,
00131:                                 vmm_sql_db   sql_db,
00132:                                 int unsigned max_n_initiators,
00133:                                 int unsigned max_n_targets,
00134:                                 int unsigned max_n_concurrent,
00135:                                 string user_schema);
00136:    string schema;
00137: 
00138:    this.log = new("Performance Analyzer", name);
00139: 
00140:    this.max_n_initiators = max_n_initiators;
00141:    this.max_n_targets = max_n_targets;
00142: 
00143:    this.max_n_concurrent = max_n_concurrent;
00144:    if (this.max_n_concurrent == 0) this.max_n_concurrent = (1<<31)-1;
00145: 
00146:    schema = "tenureID integer, initiatorID integer, targetID integer, start bigint, end bigint, active bigint, Abort tinyint";
00147:    this.user_schema = user_schema;
00148:    if (user_schema != "") schema = {schema, ", ", user_schema};
00149:    this.sql_table = sql_db.create_table(name, schema, 0);
00150: 
00151:    this.active_time = 0;
00152:    this.abort_time = 0;
00153:    this.max_time = 0;
00154:    this.min_time = '1;
00155:    this.max_abort_time = 0;
00156:    this.min_abort_time = '1;
00157:    this.n = 0;
00158: endfunction: new
00159: 
00160: 
00161: function time vmm_perf_analyzer::now();
00162:    return $time();
00163: endfunction: now
00164: 
00165: 
00166: function void vmm_perf_analyzer::start_tenure(vmm_perf_tenure tenure);
00167:    vmm_perf_data datum;
00168: 
00169:    if (tenure == null) begin
00170:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text("Attempting to start a NULL tenure")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00171:       return;
00172:    end
00173: 
00174:    foreach (this.active[i]) begin
00175:       if (this.active[i].tenure == tenure) 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({"Attempting to start an already-active tenure: ",
     :                                tenure.psdisplay()})); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00178:          return;
00179:       end
00180:    end
00181: 
00182:    if (this.max_n_initiators > 0) begin
00183:       if (!this.known_initiators.exists(tenure.get_initiator_id())) begin
00184:          this.known_initiators[tenure.get_initiator_id()] = 1;
00185:          if (this.known_initiators.num() > this.max_n_initiators) begin
00186:             
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Too many initiators: %0d > %0d",
     :                                            this.known_initiators.num(),
     :                                            this.max_n_initiators))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00189:          end
00190:       end
00191:    end
00192: 
00193:    if (this.max_n_targets > 0) begin
00194:       if (!this.known_targets.exists(tenure.get_initiator_id())) begin
00195:          this.known_targets[tenure.get_target_id()] = 1;
00196:          if (this.known_targets.num() > this.max_n_targets) begin
00197:             
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Too many targets: %0d > %0d",
     :                                            this.known_targets.num(),
     :                                            this.max_n_targets))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00200:          end
00201:       end
00202:    end
00203: 
00204:    datum = new;
00205:    datum.tenure = tenure;
00206: 
00207:    datum.start_time = this.now();
00208:    datum.resume_time = datum.start_time;
00209: 
00210:    this.active.push_back(datum);
00211: 
00212:    if (this.active.size() > this.max_n_concurrent) begin
00213:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Too many active tenures: %0d > %0d",
     :                                      this.active.size(), this.max_n_concurrent))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00215:       foreach (this.active[i]) begin
00216:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV, "", -1)) begin 
     :       void'(this.log.text(this.active[i].tenure.psdisplay("Active: "))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00217:       end
00218:    end
00219: endfunction: start_tenure
00220: 
00221: 
00222: function void vmm_perf_analyzer::suspend_tenure(vmm_perf_tenure tenure);
00223:    if (tenure == null) begin
00224:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text("Attempting to suspend a NULL tenure")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00225:       return;
00226:    end
00227: 
00228:    foreach (this.active[i]) begin
00229:       if (this.active[i].tenure == tenure) begin
00230:          vmm_perf_data datum = this.active[i];
00231: 
00232:          this.active.delete(i);
00233:          this.suspended.push_back(datum);
00234:          datum.active_time += this.now() - datum.resume_time;
00235: 
00236:          return;
00237:       end
00238:    end
00239: 
00240:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text({"Attempting to suspend a non-active tenure: ",
     :                          tenure.psdisplay()})); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00242: endfunction: suspend_tenure
00243: 
00244: 
00245: function void vmm_perf_analyzer::resume_tenure(vmm_perf_tenure tenure);
00246:    if (tenure == null) begin
00247:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text("Attempting to resume a NULL tenure")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00248:       return;
00249:    end
00250: 
00251:    foreach (this.suspended[i]) begin
00252:       if (this.suspended[i].tenure == tenure) begin
00253:          vmm_perf_data datum = this.suspended[i];
00254: 
00255:          this.suspended.delete(i);
00256:          this.active.push_back(datum);
00257: 
00258:          datum.resume_time = datum.start_time;
00259: 
00260:          if (this.active.size() > this.max_n_concurrent) begin
00261:             
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Too many active tenures: %0d > %0d",
     :                                            this.active.size(), this.max_n_concurrent))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00263:          end
00264:          return;
00265:       end
00266:    end
00267:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text({"Attempting to resume a non-suspended tenure: ",
     :                          tenure.psdisplay()})); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00269: endfunction: resume_tenure
00270: 
00271: 
00272: function void vmm_perf_analyzer::end_tenure(vmm_perf_tenure tenure, 
00273:                                             string          more_data);
00274:    if (tenure == null) begin
00275:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text("Attempting to end a NULL tenure")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00276:       return;
00277:    end
00278: 
00279:    foreach (this.active[i]) begin
00280:       if (this.active[i].tenure == tenure) begin
00281:          vmm_perf_data datum = this.active[i];
00282:          bit filtered = 0;
00283: 
00284:          this.active.delete(i);
00285: 
00286:          datum.end_time = this.now();
00287:          datum.active_time += this.now() - datum.resume_time;
00288:          datum.aborted = 0;
00289:          datum.more_data = more_data;
00290: 
00291:          foreach (this.cbs[i]) begin
00292:             this.cbs[i].analyze_tenure(this,
00293:                                        datum.tenure,
00294:                                        datum.start_time,
00295:                                        datum.end_time,
00296:                                        datum.active_time,
00297:                                        datum.aborted,
00298:                                        datum.more_data,
00299:                                        filtered);
00300:          end
00301: 
00302:          if (filtered) return;
00303: 
00304:          if (datum.end_time < datum.start_time) begin
00305:             
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Tenure modified with end time %0d < start time %0d", datum.end_time, datum.start_time))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00306:             return;
00307:          end
00308: 
00309:          if (datum.active_time > datum.end_time - datum.start_time) begin
00310:             
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Tenure modified with active time %0d > end time - start time %0d", datum.active_time, datum.end_time - datum.start_time))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00311:             return;
00312:          end
00313: 
00314:          this.completed.push_back(datum);
00315: 
00316:          this.active_time += datum.active_time;
00317:          if (this.min_time > datum.active_time) this.min_time = datum.active_time;
00318:          if (this.max_time < datum.active_time) this.max_time = datum.active_time;
00319:          this.n++;
00320: 
00321:          return;
00322:       end
00323:    end
00324: 
00325:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text({"Attempting to end a non-active tenure: ",
     :                          tenure.psdisplay()})); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00327: endfunction: end_tenure
00328: 
00329: 
00330: function void vmm_perf_analyzer::abort_tenure(vmm_perf_tenure tenure,
00331:                                               string          more_data);
00332:    if (tenure == null) begin
00333:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text("Attemtping to abort a NULL tenure")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00334:       return;
00335:    end
00336: 
00337:    foreach (this.active[i]) begin
00338:       if (this.active[i].tenure == tenure) begin
00339:          vmm_perf_data datum = this.active[i];
00340:          bit filtered = 0;
00341: 
00342:          this.active.delete(i);
00343: 
00344:          datum.end_time = this.now();
00345:          datum.active_time += this.now() - datum.resume_time;
00346:          datum.aborted = 1;
00347:          datum.more_data = more_data;
00348: 
00349:          foreach (this.cbs[i]) begin
00350:             this.cbs[i].analyze_tenure(this,
00351:                                        datum.tenure,
00352:                                        datum.start_time,
00353:                                        datum.end_time,
00354:                                        datum.active_time,
00355:                                        datum.aborted,
00356:                                        datum.more_data,
00357:                                        filtered);
00358:          end
00359: 
00360:          if (filtered) return;
00361: 
00362:          if (datum.end_time < datum.start_time) begin
00363:             
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Tenure modified with end time %0d < start time %0d", datum.end_time, datum.start_time))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00364:             return;
00365:          end
00366: 
00367:          if (datum.active_time > datum.end_time - datum.start_time) begin
00368:             
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Tenure modified with active time %0d > end time - start time %0d", datum.active_time, datum.end_time - datum.start_time))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00369:             return;
00370:          end
00371: 
00372:          this.completed.push_back(datum);
00373: 
00374:          this.active_time += datum.active_time;
00375:          if (this.min_time > datum.active_time) this.min_time = datum.active_time;
00376:          if (this.max_time < datum.active_time) this.max_time = datum.active_time;
00377: 
00378:          this.abort_time += datum.active_time;
00379:          if (this.min_abort_time > datum.active_time) this.min_abort_time = datum.active_time;
00380:          if (this.max_abort_time < datum.active_time) this.max_abort_time = datum.active_time;
00381:          this.n++;
00382: 
00383:          return;
00384:       end
00385:    end
00386: 
00387:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text({"Attempting to abort a non-active tenure: ",
     :                          tenure.psdisplay()})); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00389: endfunction: abort_tenure
00390: 
00391: 
00392: function bit vmm_perf_analyzer::add_tenure(int      initiator_id,
00393:                                            int      target_id,
00394:                                            time     start_time,
00395:                                            time     end_time,
00396:                                            vmm_data tr,
00397:                                            time     active_time,
00398:                                            bit      aborted,
00399:                                            string   more_data);
00400:    if (end_time < start_time) begin
00401:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Attempting to add tenure with end time %0d < start time %0d", end_time, start_time))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00402:       return 0;
00403:    end
00404: 
00405:    if (active_time > end_time - start_time) begin
00406:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Attempting to add tenure with active time %0d > end time - start time %0d", active_time, end_time - start_time))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00407:       return 0;
00408:    end
00409: 
00410:    if (active_time == 0) active_time = end_time - start_time;
00411: 
00412:    begin
00413:       vmm_perf_tenure tenure = new(initiator_id, target_id, tr);
00414:       bit             filtered = 0;
00415: 
00416:       foreach (this.cbs[i]) begin
00417:          this.cbs[i].analyze_tenure(this,
00418:                                     tenure,
00419:                                     start_time,
00420:                                     end_time,
00421:                                     active_time,
00422:                                     aborted,
00423:                                     more_data,
00424:                                     filtered);
00425:       end
00426: 
00427:       if (filtered) return 1;
00428: 
00429:       if (end_time < start_time) begin
00430:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Tenure modified with end time %0d < start time %0d", end_time, start_time))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00431:          return 0;
00432:       end
00433: 
00434:       if (active_time > end_time - start_time) begin
00435:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("Tenure modified with active time %0d > end time - start time %0d", active_time, end_time - start_time))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00436:          return 0;
00437:       end
00438: 
00439:       begin
00440:          vmm_perf_data   datum = new;
00441: 
00442:          datum.tenure      = tenure;
00443:          datum.start_time  = start_time;
00444:          datum.end_time    = end_time;
00445:          datum.active_time = active_time;
00446:          datum.aborted     = aborted;
00447:          datum.more_data   = more_data;
00448: 
00449:          this.completed.push_back(datum);
00450: 
00451:          this.active_time += datum.active_time;
00452:          if (this.min_time > datum.active_time) this.min_time = datum.active_time;
00453:          if (this.max_time < datum.active_time) this.max_time = datum.active_time;
00454: 
00455:          if (aborted) begin
00456:             this.abort_time += datum.active_time;
00457:             if (this.min_abort_time > datum.active_time) this.min_abort_time = datum.active_time;
00458:             if (this.max_abort_time < datum.active_time) this.max_abort_time = datum.active_time;
00459:          end
00460:          this.n++;
00461: 
00462:       end
00463:    end
00464: 
00465:    return 1;
00466: endfunction: add_tenure
00467: 
00468: 
00469: function string vmm_perf_analyzer::psdisplay(string prefix);
00470:    $sformat(psdisplay, "%s-- Performance Analyzer Status --", prefix);
00471:    $sformat(psdisplay, "%s\n%sMax init/targ/conc = %0d/%0d/%0d",
00472:             psdisplay, prefix, this.max_n_initiators, this.max_n_targets,
00473:             this.max_n_concurrent);
00474:    $sformat(psdisplay, "%s\n%sActive tenures:", psdisplay, prefix);
00475:    foreach (this.active[i]) begin
00476:       $sformat(psdisplay, "%s\n%s", psdisplay, this.active[i].tenure.psdisplay({prefix, "   "}));
00477:    end
00478:    $sformat(psdisplay, "%s\n%sSuspended tenures:", psdisplay, prefix);
00479:    foreach (this.suspended[i]) begin
00480:       $sformat(psdisplay, "%s\n%s", psdisplay, this.suspended[i].tenure.psdisplay({prefix, "   "}));
00481:    end
00482: endfunction: psdisplay
00483: 
00484: 
00485: function void vmm_perf_analyzer::report(string name,
00486:                                         bit    brief);
00487:    int fp = 32'h8000_0001; // STDOUT
00488: 
00489:    if (name != "") begin
00490:       fp = $fopen(name, "w");
00491:       if (!fp) begin
00492:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin 
     :       void'(this.log.text({"Unable to open ", name, " for writing."})); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00493:          return;
00494:       end
00495:    end
00496:    
00497:    $fwrite(fp, "\nPerformance Analysis Report for %s (based on %0d data points)\n", this.log.get_instance(), n);
00498:    $fwrite(fp, "====================================================================\n");
00499:    $fwrite(fp, "                            All Completed  |              Aborted\n");
00500: 
00501:    $fwrite(fp, "Min Tenure Duration: %d  | %d\n",
00502:            this.min_time, this.min_abort_time);
00503:    $fwrite(fp, "Avg Tenure Duration: %d  | %d\n",
00504:            this.active_time / n, this.abort_time / n);
00505:    $fwrite(fp, "Max Tenure Duration: %d  | %d\n",
00506:            this.max_time, this.max_abort_time);
00507:    $fwrite(fp, "Utilization        : %d%% | %d%%\n",
00508:            (this.active_time * 100) / this.now(),
00509:            (this.abort_time * 100) / this.now());
00510: 
00511:    if (name != "") begin
00512:       $fclose(fp);
00513:    end
00514: 
00515:    if (this.active.size() != 0 ||
00516:        this.suspended.size() != 0) begin
00517:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("There are %0d active/suspended tenures not included in the report",
     :                    this.active.size() + this.suspended.size()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00519:    end
00520: endfunction: report
00521: 
00522: function vmm_sql_db vmm_perf_analyzer::get_db();
00523:    return this.sql_table.get_db();
00524: endfunction: get_db
00525: 
00526: function void vmm_perf_analyzer::save_db();
00527:    foreach (this.completed[i]) begin
00528:       vmm_perf_data   datum  = this.completed[i];
00529:       vmm_perf_tenure tenure = datum.tenure;
00530:       string row;
00531: 
00532:       $sformat(row, "%0d,%0d,%0d,%0d,%0d,%0d,%b",
00533: 	       tenure.get_tenure_id(),
00534: 	       tenure.get_initiator_id(), 
00535: 	       tenure.get_target_id(),
00536: 	       datum.start_time, 
00537: 	       datum.end_time, 
00538: 	       datum.active_time, 
00539: 	       datum.aborted);
00540: 
00541:       if (this.user_schema != "") row = {row, ",", datum.more_data};
00542: 
00543:       this.sql_table.insert(row);
00544:    end
00545:    this.completed.delete();
00546: 
00547:    begin
00548:       vmm_sql_db sql_db = this.sql_table.get_db();
00549:       sql_db.commit();
00550:    end
00551: 
00552:    if (this.active.size() != 0 ||
00553:        this.suspended.size() != 0) begin
00554:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("There are %0d active/suspended tenures not included in the report",
     :                    this.active.size() + this.suspended.size()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00556:    end
00557: endfunction: save_db
00558: 
00559: function void vmm_perf_analyzer::save_db_txt(string name);
00560:    int fp;
00561: 
00562:    if (name == "") begin
00563:       name = {this.log.get_instance(), ".perf.db"};
00564:    end
00565:    
00566:    fp = $fopen(name, "w");
00567:    if (!fp) 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({"Unable to open ", name, " for writing."})); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while (0);
00569:       return;
00570:    end
00571: 
00572:    $fwrite("TenureID InitiatorID TargetID Start End Active Abort\n");
00573:    foreach (this.completed[i]) begin
00574:       vmm_perf_data   datum  = this.completed[i];
00575:       vmm_perf_tenure tenure = datum.tenure;
00576: 
00577:       $fwrite(fp, "%0d %0d %0d %0d %0d %0d %b\n", tenure.get_tenure_id(),
00578:               tenure.get_initiator_id(), tenure.get_target_id(),
00579:               datum.start_time, datum.end_time, datum.active_time, datum.aborted);
00580:    end
00581: 
00582:    $fclose(fp);
00583: 
00584:    if (this.active.size() != 0 ||
00585:        this.suspended.size() != 0) begin
00586:       
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text($psprintf("There are %0d active/suspended tenures not included in the DB",
     :                    this.active.size() + this.suspended.size()))); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00588:    end
00589: endfunction: save_db_txt
00590: 
00591: function void vmm_perf_analyzer::reset(reset_e rst_typ);
00592:    this.known_initiators.delete();
00593:    this.known_targets.delete();
00594:    this.active.delete();
00595:    this.completed.delete();
00596:    begin
00597:      vmm_sql_db sql_db = this.sql_table.get_db();
00598:      sql_db.statement(
00599:          $psprintf(
00600:              "DELETE FROM TABLE %s;",
00601:              this.sql_table.get_tblname)
00602:          );
00603:    end
00604: 
00605:    this.active_time = 0;
00606:    this.abort_time = 0;
00607:    this.max_time = 0;
00608:    this.min_time = '1;
00609:    this.max_abort_time = 0;
00610:    this.min_abort_time = '1;
00611:    this.n = 0;
00612: 
00613:    if (rst_typ == HARD) begin
00614:       this.cbs.delete();
00615:    end
00616: endfunction: reset
00617: 
00618: 
00619: function void vmm_perf_analyzer::append_callback(vmm_perf_analyzer_callbacks cb);
00620:    foreach (this.cbs[i]) begin
00621:       if (this.cbs[i] == cb) begin
00622:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text("Callback has already been registered")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00623:          return;
00624:       end
00625:    end
00626:    
00627:    // Append new callback
00628:    this.cbs.push_back(cb);
00629: endfunction: append_callback
00630: 
00631: 
00632: function void vmm_perf_analyzer::prepend_callback(vmm_perf_analyzer_callbacks cb);
00633:    foreach (this.cbs[i]) begin
00634:       if (this.cbs[i] == cb) begin
00635:          
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text("Callback has already been registered")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00636:          return;
00637:       end
00638:    end
00639:    
00640:    // Prepend new callback
00641:    this.cbs.push_front(cb);
00642: endfunction: prepend_callback
00643: 
00644: 
00645: function void vmm_perf_analyzer::unregister_callback(vmm_perf_analyzer_callbacks cb);
00646:    foreach (this.cbs[i]) begin
00647:       if (this.cbs[i] == cb) begin
00648:          int j = i;
00649:          // Unregister it
00650:          this.cbs.delete(j);
00651:          return;
00652:       end
00653:    end
00654: 
00655:    
     : do 
     :    /* synopsys translate_off */ 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin 
     :       void'(this.log.text("Callback was not registered")); 
     :       this.log.end_msg(); 
     :    end 
     :    /* synopsys translate_on */ 
     : while(0);
00656: endfunction: unregister_callback
00657: