// //----------------------------------------------------------------------------- // Copyright 2007-2011 Mentor Graphics Corporation // Copyright 2007-2011 Cadence Design Systems, Inc. // Copyright 2010 Synopsys, Inc. // All Rights Reserved Worldwide // // Licensed under the Apache License, Version 2.0 (the // "License"); you may not use this file except in // compliance with the License. You may obtain a copy of // the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in // writing, software distributed under the License is // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See // the License for the specific language governing // permissions and limitations under the License. //----------------------------------------------------------------------------- //------------------------------------------------------------------------------ // // CLASS: uvm_recorder // // The uvm_recorder class provides a policy object for recording . // The policies determine how recording should be done. // // A default recorder instance, , is used when the // is called without specifying a recorder. // //------------------------------------------------------------------------------ class uvm_recorder extends uvm_object; `uvm_object_utils(uvm_recorder) int recording_depth; UVM_FILE file; string filename = "tr_db.log"; // Variable: tr_handle // // This is an integral handle to a transaction object. Its use is vendor // specific. // // A handle of 0 indicates there is no active transaction object. integer tr_handle = 0; // Variable: default_radix // // This is the default radix setting if is called without // a radix. uvm_radix_enum default_radix = UVM_HEX; // Variable: physical // // This bit provides a filtering mechanism for fields. // // The and physical settings allow an object to distinguish between // two different classes of fields. // // It is up to you, in the method, to test the // setting of this field if you want to use the physical trait as a filter. bit physical = 1; // Variable: abstract // // This bit provides a filtering mechanism for fields. // // The abstract and physical settings allow an object to distinguish between // two different classes of fields. // // It is up to you, in the method, to test the // setting of this field if you want to use the abstract trait as a filter. bit abstract = 1; // Variable: identifier // // This bit is used to specify whether or not an object's reference should be // recorded when the object is recorded. bit identifier = 1; // Variable: recursion_policy // // Sets the recursion policy for recording objects. // // The default policy is deep (which means to recurse an object). uvm_recursion_policy_enum policy = UVM_DEFAULT_POLICY; function new(string name = "uvm_recorder"); super.new(name); endfunction // Function: get_type_name // // Returns type name of the recorder. Subtypes must override this method // to enable the <`uvm_record_field> macro. // //| virtual function string get_type_name() // Function: record_field // // Records an integral field (less than or equal to 4096 bits). ~name~ is the // name of the field. // // ~value~ is the value of the field to record. ~size~ is the number of bits // of the field which apply. ~radix~ is the to use. virtual function void record_field (string name, uvm_bitstream_t value, int size, uvm_radix_enum radix=UVM_NORADIX); if(tr_handle==0) return; scope.set_arg(name); if(!radix) radix = default_radix; set_attribute(tr_handle, scope.get(), value, radix, size); endfunction // Function: record_field_real // // Records an real field. ~value~ is the value of the field to record. virtual function void record_field_real (string name, real value); bit[63:0] ival = $realtobits(value); if(tr_handle==0) return; scope.set_arg(name); set_attribute(tr_handle, scope.get(), ival, UVM_REAL, 64); endfunction // Function: record_object // // Records an object field. ~name~ is the name of the recorded field. // // This method uses the to determine whether or not to // recurse into the object. virtual function void record_object (string name, uvm_object value); int v; string str; if(identifier) begin if(value != null) begin $swrite(str, "%0d", value.get_inst_id()); v = str.atoi(); end scope.set_arg(name); set_attribute(tr_handle, scope.get(), v, UVM_DEC, 32); end if(policy != UVM_REFERENCE) begin if(value!=null) begin if(value.__m_uvm_status_container.cycle_check.exists(value)) return; value.__m_uvm_status_container.cycle_check[value] = 1; scope.down(name); value.record(this); scope.up(); value.__m_uvm_status_container.cycle_check.delete(value); end end endfunction // Function: record_string // // Records a string field. ~name~ is the name of the recorded field. virtual function void record_string (string name, string value); scope.set_arg(name); set_attribute(tr_handle, scope.get(), uvm_string_to_bits(value), UVM_STRING, 8*value.len()); endfunction // Function: record_time // // Records a time value. ~name~ is the name to record to the database. virtual function void record_time (string name, time value); scope.set_arg(name); set_attribute(tr_handle, scope.get(), value, UVM_TIME, 64); endfunction // Function: record_generic // // Records the ~name~-~value~ pair, where ~value~ has been converted // to a string. For example: // //| recorder.record_generic("myvar",$sformatf("%0d",myvar)); virtual function void record_generic (string name, string value); scope.set_arg(name); set_attribute(tr_handle, scope.get(), uvm_string_to_bits(value), UVM_STRING, 8*value.len()); endfunction uvm_scope_stack scope = new; //------------------------------ // Group- Vendor-Independent API //------------------------------ // UVM provides only a text-based default implementation. // Vendors provide subtype implementations and overwrite the // handle. // Function- open_file // // Opens the file in the property and assigns to the // file descriptor . // virtual function bit open_file(); if (file == 0) file = $fopen(filename); return (file > 0); endfunction static bit m_handles[int]; static int handle; // Function- create_stream // // virtual function integer create_stream (string name, string t, string scope); if (open_file()) begin m_handles[++handle] = 1; $fdisplay(file," CREATE_STREAM @%0t {NAME:%s T:%s SCOPE:%s STREAM:%0d}",$time,name,t,scope,handle); return handle; end return 0; endfunction // Function- m_set_attribute // // virtual function void m_set_attribute (integer txh, string nm, string value); if (open_file()) $fdisplay(file," SET_ATTR @%0t {TXH:%0d NAME:%s VALUE:%s}", $time,txh,nm,value); endfunction // Function- set_attribute // // virtual function void set_attribute (integer txh, string nm, logic [1023:0] value, uvm_radix_enum radix, integer numbits=1024); if (open_file()) $fdisplay(file," SET_ATTR @%0t {TXH:%0d NAME:%s VALUE:%0d RADIX:%s BITS=%0d}", $time,txh, nm, (value & ((1<