// //------------------------------------------------------------------------------ // Copyright 2012 AMD // Copyright 2007-2018 Cadence Design Systems, Inc. // Copyright 2014-2018 Cisco Systems, Inc. // Copyright 2014 Intel Corporation // Copyright 2020 Marvell International Ltd. // Copyright 2007-2018 Mentor Graphics Corporation // Copyright 2013-2020 NVIDIA Corporation // Copyright 2018 Qualcomm, Inc. // Copyright 2014 Semifore // Copyright 2018 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 or the specific language governing // permissions and limitations under the License. //------------------------------------------------------------------------------ typedef class m_uvm_printer_knobs; typedef class uvm_printer_element; typedef class uvm_structure_proxy; // File: uvm_printer // @uvm-ieee 1800.2-2020 auto 16.2.1 virtual class uvm_printer extends uvm_policy; `uvm_object_abstract_utils(uvm_printer) extern function new(string name="") ; bit m_flushed ; // 0 = needs flush, 1 = flushed since last use //config values from set_* accessors are stored in knobs local m_uvm_printer_knobs knobs ; protected function m_uvm_printer_knobs get_knobs() ; return knobs; endfunction // Group -- NODOCS -- Methods for printer usage // These functions are called from , or they are called // directly on any data to get formatted printing. extern static function void set_default(uvm_printer printer) ; extern static function uvm_printer get_default() ; // Function -- NODOCS -- print_field // // Prints an integral field (up to 4096 bits). // // name - The name of the field. // value - The value of the field. // size - The number of bits of the field (maximum is 4096). // radix - The radix to use for printing. The printer knob for radix is used // if no radix is specified. // scope_separator - is used to find the leaf name since many printers only // print the leaf name of a field. Typical values for the separator // are . (dot) or [ (open bracket). // @uvm-ieee 1800.2-2020 auto 16.2.3.8 extern virtual function void print_field (string name, uvm_bitstream_t value, int size, uvm_radix_enum radix=UVM_NORADIX, byte scope_separator=".", string type_name=""); // @uvm-ieee 1800.2-2020 auto 16.2.3.9 extern virtual function void print_field_int (string name, uvm_integral_t value, int size, uvm_radix_enum radix=UVM_NORADIX, byte scope_separator=".", string type_name=""); // Function -- NODOCS -- print_object // // Prints an object. Whether the object is recursed depends on a variety of // knobs, such as the depth knob; if the current depth is at or below the // depth setting, then the object is not recursed. // // By default, the children of are printed. To turn this // behavior off, you must set the bit to 0 for // the specific children you do not want automatically printed. // @uvm-ieee 1800.2-2020 auto 16.2.3.1 extern virtual function void print_object (string name, uvm_object value, byte scope_separator="."); extern virtual function void print_object_header (string name, uvm_object value, byte scope_separator="."); // Function -- NODOCS -- print_string // // Prints a string field. // @uvm-ieee 1800.2-2020 auto 16.2.3.10 extern virtual function void print_string (string name, string value, byte scope_separator="."); uvm_policy::recursion_state_e m_recur_states[uvm_object][uvm_recursion_policy_enum /*recursion*/] ; // @uvm-ieee 1800.2-2020 auto 16.2.3.2 extern virtual function uvm_policy::recursion_state_e object_printed ( uvm_object value, uvm_recursion_policy_enum recursion); // Function -- NODOCS -- print_time // // Prints a time value. name is the name of the field, and value is the // value to print. // // The print is subject to the ~$timeformat~ system task for formatting time // values. // @uvm-ieee 1800.2-2020 auto 16.2.3.11 extern virtual function void print_time (string name, time value, byte scope_separator="."); // Function -- NODOCS -- print_real // // Prints a real field. // @uvm-ieee 1800.2-2020 auto 16.2.3.12 extern virtual function void print_real (string name, real value, byte scope_separator="."); // Function -- NODOCS -- print_generic // // Prints a field having the given ~name~, ~type_name~, ~size~, and ~value~. // @uvm-ieee 1800.2-2020 auto 16.2.3.3 extern virtual function void print_generic (string name, string type_name, int size, string value, byte scope_separator="."); // @uvm-ieee 1800.2-2020 auto 16.2.3.4 extern virtual function void print_generic_element (string name, string type_name, string size, string value); // Group -- NODOCS -- Methods for printer subtyping // Function -- NODOCS -- emit // // Emits a string representing the contents of an object // in a format defined by an extension of this object. extern virtual function string emit (); extern virtual function void flush (); // @uvm-ieee 1800.2-2020 auto 16.2.5.1 extern virtual function void set_name_enabled (bit enabled); // @uvm-ieee 1800.2-2020 auto 16.2.5.1 extern virtual function bit get_name_enabled (); // @uvm-ieee 1800.2-2020 auto 16.2.5.2 extern virtual function void set_type_name_enabled (bit enabled); // @uvm-ieee 1800.2-2020 auto 16.2.5.2 extern virtual function bit get_type_name_enabled (); // @uvm-ieee 1800.2-2020 auto 16.2.5.3 extern virtual function void set_size_enabled (bit enabled); // @uvm-ieee 1800.2-2020 auto 16.2.5.3 extern virtual function bit get_size_enabled (); // @uvm-ieee 1800.2-2020 auto 16.2.5.4 extern virtual function void set_id_enabled (bit enabled); // @uvm-ieee 1800.2-2020 auto 16.2.5.4 extern virtual function bit get_id_enabled (); // @uvm-ieee 1800.2-2020 auto 16.2.5.5 extern virtual function void set_radix_enabled (bit enabled); // @uvm-ieee 1800.2-2020 auto 16.2.5.5 extern virtual function bit get_radix_enabled (); // @uvm-ieee 1800.2-2020 auto 16.2.5.6 extern virtual function void set_radix_string (uvm_radix_enum radix, string prefix); // @uvm-ieee 1800.2-2020 auto 16.2.5.6 extern virtual function string get_radix_string (uvm_radix_enum radix); // @uvm-ieee 1800.2-2020 auto 16.2.5.7 extern virtual function void set_default_radix (uvm_radix_enum radix); // @uvm-ieee 1800.2-2020 auto 16.2.5.7 extern virtual function uvm_radix_enum get_default_radix (); // @uvm-ieee 1800.2-2020 auto 16.2.5.8 extern virtual function void set_root_enabled (bit enabled); // @uvm-ieee 1800.2-2020 auto 16.2.5.8 extern virtual function bit get_root_enabled (); // @uvm-ieee 1800.2-2020 auto 16.2.5.9 extern virtual function void set_recursion_policy (uvm_recursion_policy_enum policy); // @uvm-ieee 1800.2-2020 auto 16.2.5.9 extern virtual function uvm_recursion_policy_enum get_recursion_policy (); // @uvm-ieee 1800.2-2020 auto 16.2.5.10 extern virtual function void set_max_depth (int depth); // @uvm-ieee 1800.2-2020 auto 16.2.5.10 extern virtual function int get_max_depth (); // @uvm-ieee 1800.2-2020 auto 16.2.5.11 extern virtual function void set_file (UVM_FILE fl); // @uvm-ieee 1800.2-2020 auto 16.2.5.11 extern virtual function UVM_FILE get_file (); // @uvm-ieee 1800.2-2020 auto 16.2.5.12 extern virtual function void set_line_prefix (string prefix); // @uvm-ieee 1800.2-2020 auto 16.2.5.12 extern virtual function string get_line_prefix (); // @uvm-ieee 1800.2-2020 auto 16.2.6 extern virtual function void set_begin_elements (int elements = 5); // @uvm-ieee 1800.2-2020 auto 16.2.6 extern virtual function int get_begin_elements (); // @uvm-ieee 1800.2-2020 auto 16.2.6 extern virtual function void set_end_elements (int elements = 5); // @uvm-ieee 1800.2-2020 auto 16.2.6 extern virtual function int get_end_elements (); local uvm_printer_element m_element_stack[$] ; protected function int m_get_stack_size(); return m_element_stack.size(); endfunction // @uvm-ieee 1800.2-2020 auto 16.2.7.1 extern protected virtual function uvm_printer_element get_bottom_element (); // @uvm-ieee 1800.2-2020 auto 16.2.7.2 extern protected virtual function uvm_printer_element get_top_element (); // @uvm-ieee 1800.2-2020 auto 16.2.7.3 extern virtual function void push_element ( string name, string type_name, string size, string value="" ); // @uvm-ieee 1800.2-2020 auto 16.2.7.4 extern virtual function void pop_element (); // return an element from the recycled stack if available or a new one otherwise extern function uvm_printer_element get_unused_element() ; // store element instances that have been created but are not currently on the stack uvm_printer_element m_recycled_elements[$]; // Function -- NODOCS -- print_array_header // // Prints the header of an array. This function is called before each // individual element is printed. is called to mark the // completion of array printing. // @uvm-ieee 1800.2-2020 auto 16.2.3.5 extern virtual function void print_array_header(string name, int size, string arraytype="array", byte scope_separator="."); // Function -- NODOCS -- print_array_range // // Prints a range using ellipses for values. This method is used when honoring // the array knobs for partial printing of large arrays, // and . // // This function should be called after begin_elements have been printed // and before end_elements have been printed. // @uvm-ieee 1800.2-2020 auto 16.2.3.6 extern virtual function void print_array_range (int min, int max); // Function -- NODOCS -- print_array_footer // // Prints the header of a footer. This function marks the end of an array // print. Generally, there is no output associated with the array footer, but // this method let's the printer know that the array printing is complete. // @uvm-ieee 1800.2-2020 auto 16.2.3.7 extern virtual function void print_array_footer (int size = 0); // Utility methods extern function bit istop (); extern function string index_string (int index, string name=""); string m_string; endclass // @uvm-ieee 1800.2-2020 auto 16.2.8.1 class uvm_printer_element extends uvm_object; // @uvm-ieee 1800.2-2020 auto 16.2.8.2.1 extern function new (string name=""); // @uvm-ieee 1800.2-2020 auto 16.2.8.2.2 extern virtual function void set (string element_name = "", string element_type_name = "", string element_size = "", string element_value = "" ); // @uvm-ieee 1800.2-2020 auto 16.2.8.2.3 extern virtual function void set_element_name (string element_name); // @uvm-ieee 1800.2-2020 auto 16.2.8.2.3 extern virtual function string get_element_name (); // @uvm-ieee 1800.2-2020 auto 16.2.8.2.4 extern virtual function void set_element_type_name (string element_type_name); // @uvm-ieee 1800.2-2020 auto 16.2.8.2.4 extern virtual function string get_element_type_name (); // @uvm-ieee 1800.2-2020 auto 16.2.8.2.5 extern virtual function void set_element_size (string element_size); // @uvm-ieee 1800.2-2020 auto 16.2.8.2.5 extern virtual function string get_element_size (); // @uvm-ieee 1800.2-2020 auto 16.2.8.2.6 extern virtual function void set_element_value (string element_value); // @uvm-ieee 1800.2-2020 auto 16.2.8.2.6 extern virtual function string get_element_value (); extern function void add_child(uvm_printer_element child) ; extern function void get_children(ref uvm_printer_element children[$], input bit recurse) ; extern function void clear_children() ; local string m_name ; local string m_type_name ; local string m_size ; local string m_value ; local uvm_printer_element m_children[$] ; endclass // @uvm-ieee 1800.2-2020 auto 16.2.9.1 class uvm_printer_element_proxy extends uvm_structure_proxy#(uvm_printer_element); // @uvm-ieee 1800.2-2020 auto 16.2.9.2.1 extern function new (string name=""); // @uvm-ieee 1800.2-2020 auto 16.2.9.2.2 extern virtual function void get_immediate_children(uvm_printer_element s, ref uvm_printer_element children[$]); endclass : uvm_printer_element_proxy //------------------------------------------------------------------------------ // // Class: uvm_table_printer // // The table printer prints output in a tabular format. // // The following shows sample output from the table printer. // //| --------------------------------------------------- //| Name Type Size Value //| --------------------------------------------------- //| c1 container - @1013 //| d1 mydata - @1022 //| v1 integral 32 'hcb8f1c97 //| e1 enum 32 THREE //| str string 2 hi //| value integral 12 'h2d //| --------------------------------------------------- // //------------------------------------------------------------------------------ // // @uvm-accellera The details of this API are specific to the Accellera implementation, and are not being considered for contribution to 1800.2 // @uvm-ieee 1800.2-2020 auto 16.2.10.1 class uvm_table_printer extends uvm_printer; // @uvm-ieee 1800.2-2020 auto 16.2.10.2.2 `uvm_object_utils(uvm_table_printer) // @uvm-ieee 1800.2-2020 auto 16.2.10.2.1 extern function new(string name=""); // Function -- NODOCS -- emit // // Formats the collected information from prior calls to ~print_*~ // into table format. // extern virtual function string emit(); extern virtual function string m_emit_element(uvm_printer_element element, int unsigned level); local static uvm_table_printer m_default_table_printer ; local static string m_space ; // @uvm-ieee 1800.2-2020 auto 16.2.10.2.3 extern static function void set_default(uvm_table_printer printer) ; // @uvm-ieee 1800.2-2020 auto 16.2.10.2.4 extern static function uvm_table_printer get_default() ; // @uvm-ieee 1800.2-2020 auto 16.2.10.3 extern virtual function void set_indent(int indent) ; // @uvm-ieee 1800.2-2020 auto 16.2.10.3 extern virtual function int get_indent() ; extern virtual function void flush() ; // Variables- m_max_* // // holds max size of each column, so table columns can be resized dynamically protected int m_max_name=4; protected int m_max_type=4; protected int m_max_size=4; protected int m_max_value=5; extern virtual function void pop_element(); endclass //------------------------------------------------------------------------------ // // Class: uvm_tree_printer // // By overriding various methods of the super class, // the tree printer prints output in a tree format. // // The following shows sample output from the tree printer. // //| c1: (container@1013) { //| d1: (mydata@1022) { //| v1: 'hcb8f1c97 //| e1: THREE //| str: hi //| } //| value: 'h2d //| } // //------------------------------------------------------------------------------ // @uvm-ieee 1800.2-2020 auto 16.2.11.1 class uvm_tree_printer extends uvm_printer; protected string m_newline = "\n"; protected string m_linefeed ; // @uvm-ieee 1800.2-2020 auto 16.2.11.2.2 `uvm_object_utils(uvm_tree_printer) // Variable -- NODOCS -- new // // Creates a new instance of ~uvm_tree_printer~. // @uvm-ieee 1800.2-2020 auto 16.2.11.2.1 extern function new(string name=""); local static uvm_tree_printer m_default_tree_printer ; // @uvm-ieee 1800.2-2020 auto 16.2.11.2.3 extern static function void set_default(uvm_tree_printer printer) ; // @uvm-ieee 1800.2-2020 auto 16.2.11.2.4 extern static function uvm_tree_printer get_default() ; // @uvm-ieee 1800.2-2020 auto 16.2.11.3.1 extern virtual function void set_indent(int indent) ; // @uvm-ieee 1800.2-2020 auto 16.2.11.3.1 extern virtual function int get_indent() ; // @uvm-ieee 1800.2-2020 auto 16.2.11.3.2 extern virtual function void set_separators(string separators) ; // @uvm-ieee 1800.2-2020 auto 16.2.11.3.2 extern virtual function string get_separators() ; extern virtual function void flush() ; // @uvm-ieee 1800.2-2020 auto 16.2.4.1 extern virtual function string emit(); extern virtual function string m_emit_element(uvm_printer_element element, int unsigned level); endclass //------------------------------------------------------------------------------ // // Class: uvm_line_printer // // The line printer prints output in a line format. // // The following shows sample output from the line printer. // //| c1: (container@1013) { d1: (mydata@1022) { v1: 'hcb8f1c97 e1: THREE str: hi } value: 'h2d } //------------------------------------------------------------------------------ // @uvm-ieee 1800.2-2020 auto 16.2.12.1 class uvm_line_printer extends uvm_tree_printer; // @uvm-ieee 1800.2-2020 auto 16.2.12.2.2 `uvm_object_utils(uvm_line_printer) // Variable -- NODOCS -- new // // Creates a new instance of ~uvm_line_printer~. It differs from the // only in that the output contains no line-feeds // and indentation. // @uvm-ieee 1800.2-2020 auto 16.2.12.2.1 // @uvm-ieee 1800.2-2020 auto 16.2.2.1 extern function new(string name=""); local static uvm_line_printer m_default_line_printer ; // @uvm-ieee 1800.2-2020 auto 16.2.12.2.3 // @uvm-ieee 1800.2-2020 auto 16.2.2.2 extern static function void set_default(uvm_line_printer printer) ; // @uvm-ieee 1800.2-2020 auto 16.2.12.2.4 // @uvm-ieee 1800.2-2020 auto 16.2.2.3 extern static function uvm_line_printer get_default() ; // @uvm-ieee 1800.2-2020 auto 16.2.12.3 extern virtual function void set_separators(string separators) ; // @uvm-ieee 1800.2-2020 auto 16.2.12.3 extern virtual function string get_separators() ; // @uvm-ieee 1800.2-2020 auto 16.2.4.2 extern virtual function void flush() ; endclass //------------------------------------------------------------------------------ // // Class -- NODOCS -- m_uvm_printer_knobs // // The ~m_uvm_printer_knobs~ class defines the printer settings available to all // printer subtypes. // //------------------------------------------------------------------------------ class m_uvm_printer_knobs; // Variable -- NODOCS -- identifier // // Indicates whether should print the identifier. This is useful // in cases where you just want the values of an object, but no identifiers. bit identifier = 1; // Variable -- NODOCS -- type_name // // Controls whether to print a field's type name. bit type_name = 1; // Variable -- NODOCS -- size // // Controls whether to print a field's size. bit size = 1; // Variable -- NODOCS -- depth // // Indicates how deep to recurse when printing objects. // A depth of -1 means to print everything. int depth = -1; // Variable -- NODOCS -- reference // // Controls whether to print a unique reference ID for object handles. // The behavior of this knob is simulator-dependent. bit reference = 1; // Variable -- NODOCS -- begin_elements // // Defines the number of elements at the head of a list to print. // Use -1 for no max. int begin_elements = 5; // Variable -- NODOCS -- end_elements // // This defines the number of elements at the end of a list that // should be printed. int end_elements = 5; // Variable -- NODOCS -- prefix // // Specifies the string prepended to each output line string prefix = ""; // Variable -- NODOCS -- indent // // This knob specifies the number of spaces to use for level indentation. // The default level indentation is two spaces. int indent = 2; // Variable -- NODOCS -- show_root // // This setting indicates whether or not the initial object that is printed // (when current depth is 0) prints the full path name. By default, the first // object is treated like all other objects and only the leaf name is printed. bit show_root = 0; // Variable -- NODOCS -- mcd // // This is a file descriptor, or multi-channel descriptor, that specifies // where the print output should be directed. // // By default, the output goes to the standard output of the simulator. int mcd = UVM_STDOUT; // Variable -- NODOCS -- separator // // For tree printers only, determines the opening and closing // separators used for nested objects. string separator = "{}"; // Variable -- NODOCS -- show_radix // // Indicates whether the radix string ('h, and so on) should be prepended to // an integral value when one is printed. bit show_radix = 1; // Variable -- NODOCS -- default_radix // // This knob sets the default radix to use for integral values when no radix // enum is explicitly supplied to the or // methods. uvm_radix_enum default_radix = UVM_HEX; // Variable -- NODOCS -- dec_radix // // This string should be prepended to the value of an integral type when a // radix of is used for the radix of the integral object. // // When a negative number is printed, the radix is not printed since only // signed decimal values can print as negative. string dec_radix = "'d"; // Variable -- NODOCS -- bin_radix // // This string should be prepended to the value of an integral type when a // radix of is used for the radix of the integral object. string bin_radix = "'b"; // Variable -- NODOCS -- oct_radix // // This string should be prepended to the value of an integral type when a // radix of is used for the radix of the integral object. string oct_radix = "'o"; // Variable -- NODOCS -- unsigned_radix // // This is the string which should be prepended to the value of an integral // type when a radix of is used for the radix of the integral // object. string unsigned_radix = "'d"; // Variable -- NODOCS -- hex_radix // // This string should be prepended to the value of an integral type when a // radix of is used for the radix of the integral object. string hex_radix = "'h"; uvm_recursion_policy_enum recursion_policy ; endclass //------------------------------------------------------------------------------ // IMPLEMENTATION //------------------------------------------------------------------------------ function uvm_printer::new(string name=""); super.new(name); knobs = new ; flush(); endfunction function void uvm_printer::set_default(uvm_printer printer) ; uvm_coreservice_t coreservice ; coreservice = uvm_coreservice_t::get() ; coreservice.set_default_printer(printer) ; endfunction function uvm_printer uvm_printer::get_default() ; uvm_coreservice_t coreservice ; coreservice = uvm_coreservice_t::get() ; return coreservice.get_default_printer() ; endfunction // print_field // --------- function void uvm_printer::print_field (string name, uvm_bitstream_t value, int size, uvm_radix_enum radix=UVM_NORADIX, byte scope_separator=".", string type_name=""); string sz_str, val_str; if(type_name == "") begin if(radix == UVM_TIME) type_name ="time"; else if(radix == UVM_STRING) type_name ="string"; else type_name ="integral"; end sz_str.itoa(size); if(radix == UVM_NORADIX) radix = get_default_radix(); val_str = uvm_bitstream_to_string (value, size, radix, get_radix_string(radix)); name = uvm_leaf_scope(name,scope_separator); push_element(name,type_name,sz_str,val_str); pop_element() ; endfunction // print_field_int // --------- function void uvm_printer::print_field_int (string name, uvm_integral_t value, int size, uvm_radix_enum radix=UVM_NORADIX, byte scope_separator=".", string type_name=""); string sz_str, val_str; if(type_name == "") begin if(radix == UVM_TIME) type_name ="time"; else if(radix == UVM_STRING) type_name ="string"; else type_name ="integral"; end sz_str.itoa(size); if(radix == UVM_NORADIX) radix = get_default_radix(); val_str = uvm_integral_to_string (value, size, radix, get_radix_string(radix)); name = uvm_leaf_scope(name,scope_separator); push_element(name,type_name,sz_str,val_str); pop_element() ; endfunction // emit // ---- function string uvm_printer::emit (); `uvm_error("NO_OVERRIDE","emit() method not overridden in printer subtype") return ""; endfunction function void uvm_printer::flush (); // recycle all elements that were on the stack uvm_printer_element element = get_bottom_element() ; uvm_printer_element all_descendent_elements[$] ; element = get_bottom_element() ; if (element != null) begin element.get_children(all_descendent_elements,1) ; //recursive foreach (all_descendent_elements[i]) begin m_recycled_elements.push_back(all_descendent_elements[i]) ; all_descendent_elements[i].clear_children() ; end element.clear_children(); m_recycled_elements.push_back(element) ; // now delete the stack m_element_stack.delete() ; end m_recur_states.delete(); m_flushed = 1 ; endfunction function void uvm_printer::set_name_enabled (bit enabled); knobs.identifier = enabled ; endfunction function bit uvm_printer::get_name_enabled (); return knobs.identifier ; endfunction function void uvm_printer::set_type_name_enabled (bit enabled); knobs.type_name = enabled ; endfunction function bit uvm_printer::get_type_name_enabled (); return knobs.type_name ; endfunction function void uvm_printer::set_size_enabled (bit enabled); knobs.size = enabled ; endfunction function bit uvm_printer::get_size_enabled (); return knobs.size ; endfunction function void uvm_printer::set_id_enabled (bit enabled); knobs.reference = enabled ; endfunction function bit uvm_printer::get_id_enabled (); return knobs.reference ; endfunction function void uvm_printer::set_radix_enabled (bit enabled); knobs.show_radix = enabled ; endfunction function bit uvm_printer::get_radix_enabled (); return knobs.show_radix ; endfunction function void uvm_printer::set_radix_string (uvm_radix_enum radix, string prefix); if (radix == UVM_DEC) knobs.dec_radix = prefix ; else if (radix == UVM_BIN) knobs.bin_radix = prefix ; else if (radix == UVM_OCT) knobs.oct_radix = prefix ; else if (radix == UVM_UNSIGNED) knobs.unsigned_radix = prefix ; else if (radix == UVM_HEX) knobs.hex_radix = prefix ; else `uvm_warning("PRINTER_UNKNOWN_RADIX",$sformatf("set_radix_string called with unsupported radix %s",radix)) endfunction function string uvm_printer::get_radix_string (uvm_radix_enum radix); if (radix == UVM_DEC) return knobs.dec_radix ; else if (radix == UVM_BIN) return knobs.bin_radix ; else if (radix == UVM_OCT) return knobs.oct_radix ; else if (radix == UVM_UNSIGNED) return knobs.unsigned_radix ; else if (radix == UVM_HEX) return knobs.hex_radix ; else return ""; endfunction function void uvm_printer::set_default_radix (uvm_radix_enum radix); knobs.default_radix = radix ; endfunction function uvm_radix_enum uvm_printer::get_default_radix (); return knobs.default_radix ; endfunction function void uvm_printer::set_root_enabled (bit enabled); knobs.show_root = enabled ; endfunction function bit uvm_printer::get_root_enabled (); return knobs.show_root ; endfunction function void uvm_printer::set_recursion_policy (uvm_recursion_policy_enum policy); knobs.recursion_policy = policy ; endfunction function uvm_recursion_policy_enum uvm_printer::get_recursion_policy (); return knobs.recursion_policy ; endfunction function void uvm_printer::set_max_depth (int depth); knobs.depth = depth ; endfunction function int uvm_printer::get_max_depth (); return knobs.depth ; endfunction function void uvm_printer::set_file (UVM_FILE fl); knobs.mcd = fl ; endfunction function UVM_FILE uvm_printer::get_file (); return knobs.mcd ; endfunction function void uvm_printer::set_line_prefix (string prefix); knobs.prefix = prefix ; endfunction function string uvm_printer::get_line_prefix (); return knobs.prefix ; endfunction function void uvm_printer::set_begin_elements (int elements = 5); knobs.begin_elements = elements ; endfunction function int uvm_printer::get_begin_elements (); return knobs.begin_elements ; endfunction function void uvm_printer::set_end_elements (int elements = 5); knobs.end_elements = elements ; endfunction function int uvm_printer::get_end_elements (); return knobs.end_elements ; endfunction function uvm_printer_element uvm_printer::get_bottom_element (); if (m_element_stack.size() > 0) return m_element_stack[0] ; else return null ; endfunction function uvm_printer_element uvm_printer::get_top_element (); if (m_element_stack.size() > 0) return m_element_stack[$] ; else return null ; endfunction function uvm_printer_element_proxy::new (string name=""); super.new(name) ; endfunction function void uvm_printer_element_proxy::get_immediate_children(uvm_printer_element s, ref uvm_printer_element children[$]); s.get_children(children,0) ; endfunction function void uvm_printer::push_element ( string name, string type_name, string size, string value=""); uvm_printer_element element ; uvm_printer_element parent ; element = get_unused_element() ; parent = get_top_element() ; element.set(name,type_name,size,value); if (parent != null) parent.add_child(element) ; m_element_stack.push_back(element) ; endfunction function void uvm_printer::pop_element (); if (m_element_stack.size() > 1) begin void'(m_element_stack.pop_back()); end endfunction function uvm_printer_element uvm_printer::get_unused_element() ; uvm_printer_element element ; if (m_recycled_elements.size() > 0) begin element = m_recycled_elements.pop_back() ; end else begin element = new() ; end return element ; endfunction // print_array_header // ------------------ function void uvm_printer::print_array_header (string name, int size, string arraytype="array", byte scope_separator="."); push_element(name,arraytype,$sformatf("%0d",size),"-"); endfunction // print_array_footer // ------------------ function void uvm_printer::print_array_footer (int size=0); pop_element() ; endfunction // print_array_range // ----------------- function void uvm_printer::print_array_range(int min, int max); string tmpstr; if(min == -1 && max == -1) return; if(min == -1) min = max; if(max == -1) max = min; if(max < min) return; print_generic_element("...", "...", "...", "..."); endfunction // print_object_header // ------------------- function void uvm_printer::print_object_header (string name, uvm_object value, byte scope_separator="."); if(name == "") name = ""; push_element(name, (value != null) ? value.get_type_name() : "object", "-", get_id_enabled() ? uvm_object_value_str(value) : "-"); endfunction // print_object // ------------ function void uvm_printer::print_object (string name, uvm_object value, byte scope_separator="."); uvm_component comp, child_comp; uvm_field_op field_op ; uvm_recursion_policy_enum recursion_policy; recursion_policy = get_recursion_policy(); if ((value == null) || (recursion_policy == UVM_REFERENCE) || (get_max_depth() == get_active_object_depth())) begin print_object_header(name,value,scope_separator); // calls push_element pop_element(); end else begin push_active_object(value); m_recur_states[value][recursion_policy] = uvm_policy::STARTED ; print_object_header(name,value,scope_separator); // calls push_element field_op = uvm_field_op::m_get_available_op() ; field_op.set(UVM_PRINT,this,null); value.do_execute_op(field_op); if (field_op.user_hook_enabled()) value.do_print(this); field_op.m_recycle(); pop_element() ; // matches push in print_object_header m_recur_states[value][recursion_policy] = uvm_policy::FINISHED ; void'(pop_active_object()); end endfunction // istop // ----- function bit uvm_printer::istop (); return (get_active_object_depth() == 0); endfunction // print_generic // ------------- function void uvm_printer::print_generic (string name, string type_name, int size, string value, byte scope_separator="."); push_element(name, type_name, (size == -2 ? "..." : $sformatf("%0d",size)), value); pop_element(); endfunction function void uvm_printer::print_generic_element (string name, string type_name, string size, string value); push_element(name,type_name,size,value); pop_element() ; endfunction // print_time // ---------- function void uvm_printer::print_time (string name, time value, byte scope_separator="."); print_field_int(name, value, 64, UVM_TIME, scope_separator); endfunction // print_string // ------------ function void uvm_printer::print_string (string name, string value, byte scope_separator="."); push_element(name, "string", $sformatf("%0d",value.len()), (value == "" ? "\"\"" : value)); pop_element() ; endfunction function uvm_policy::recursion_state_e uvm_printer::object_printed (uvm_object value, uvm_recursion_policy_enum recursion); if (!m_recur_states.exists(value)) return NEVER ; if (!m_recur_states[value].exists(recursion)) return NEVER ; else return m_recur_states[value][recursion] ; endfunction // print_real // ---------- function void uvm_printer::print_real (string name, real value, byte scope_separator="."); push_element(name,"real","64",$sformatf("%f",value)); pop_element() ; endfunction // index_string // ------------ function string uvm_printer::index_string(int index, string name=""); index_string.itoa(index); index_string = { name, "[", index_string, "]" }; endfunction //------------------------------------------------------------------------------ // Class- uvm_printer_element //------------------------------------------------------------------------------ function uvm_printer_element::new (string name = ""); super.new(name) ; endfunction function void uvm_printer_element::set (string element_name = "", string element_type_name = "", string element_size = "", string element_value = "" ); m_name = element_name ; m_type_name = element_type_name ; m_size = element_size ; m_value = element_value ; endfunction function void uvm_printer_element::set_element_name (string element_name); m_name = element_name ; endfunction function string uvm_printer_element::get_element_name (); return m_name ; endfunction function void uvm_printer_element::set_element_type_name (string element_type_name); m_type_name = element_type_name ; endfunction function string uvm_printer_element::get_element_type_name (); return m_type_name ; endfunction function void uvm_printer_element::set_element_size (string element_size); m_size = element_size ; endfunction function string uvm_printer_element::get_element_size (); return m_size ; endfunction function void uvm_printer_element::set_element_value (string element_value); m_value = element_value ; endfunction function string uvm_printer_element::get_element_value (); return m_value ; endfunction function void uvm_printer_element::add_child(uvm_printer_element child) ; m_children.push_back(child) ; endfunction function void uvm_printer_element::get_children(ref uvm_printer_element children[$], input bit recurse) ; foreach (m_children[i]) begin children.push_back(m_children[i]) ; if (recurse) begin m_children[i].get_children(children,1) ; end end endfunction function void uvm_printer_element::clear_children() ; m_children.delete() ; endfunction //------------------------------------------------------------------------------ // Class- uvm_table_printer //------------------------------------------------------------------------------ // new // --- function uvm_table_printer::new(string name=""); super.new(name); endfunction function void uvm_table_printer::pop_element(); int name_len; int level ; uvm_printer_element popped ; string name_str ; string type_name_str ; string size_str ; string value_str ; popped = get_top_element() ; level = m_get_stack_size() - 1 ; name_str = popped.get_element_name() ; type_name_str = popped.get_element_type_name() ; size_str = popped.get_element_size() ; value_str = popped.get_element_value() ; if ((name_str.len() + (get_indent() * level)) > m_max_name) m_max_name = (name_str.len() + (get_indent() * level)); if (type_name_str.len() > m_max_type) m_max_type = type_name_str.len(); if (size_str.len() > m_max_size) m_max_size = size_str.len(); if (value_str.len() > m_max_value) m_max_value = value_str.len(); super.pop_element() ; endfunction // emit // ---- function string uvm_table_printer::emit(); string s; string user_format; static string dash; // = "---------------------------------------------------------------------------------------------------"; string dashes; string linefeed; if (!m_flushed) begin `uvm_error("UVM/PRINT/NO_FLUSH","printer emit() method called twice without intervening uvm_printer::flush()") end else m_flushed = 0 ; linefeed = {"\n", get_line_prefix()}; begin int q[5]; int m; int qq[$]; q = '{m_max_name,m_max_type,m_max_size,m_max_value,100}; qq = q.max; m = qq[0]; if(dash.len() 0) && (value_str[0] == "@")) // is an object w/ id_enabled() on result = {result,"(",element.get_element_type_name(),value_str,") "}; else if (get_type_name_enabled() && (element.get_element_type_name() != "" || element.get_element_type_name() != "-" || element.get_element_type_name() != "...")) result = {result,"(",element.get_element_type_name(),") "}; // Size if (get_size_enabled()) begin if (element.get_element_size() != "" || element.get_element_size() != "-") result = {result,"(",element.get_element_size(),") "}; end if (element_children.size() > 0) begin result = {result, string'(separators[0]), m_linefeed}; end else result = {result, value_str, " ", m_linefeed}; //process all children (if any) of this element foreach (element_children[i]) begin result = {result, m_emit_element(element_children[i],level+1)} ; end //if there were children, add the closing separator if (element_children.size() > 0) begin result = {result, indent_str, string'(separators[1]), m_linefeed}; end end return result ; endfunction : m_emit_element function void uvm_table_printer::set_default(uvm_table_printer printer) ; m_default_table_printer = printer ; endfunction function uvm_table_printer uvm_table_printer::get_default() ; if (m_default_table_printer == null) begin m_default_table_printer = new("uvm_default_table_printer") ; end return m_default_table_printer ; endfunction function void uvm_table_printer::set_indent(int indent) ; m_uvm_printer_knobs _knobs = get_knobs(); _knobs.indent = indent ; endfunction function int uvm_table_printer::get_indent() ; m_uvm_printer_knobs _knobs = get_knobs(); return _knobs.indent ; endfunction function void uvm_table_printer::flush() ; super.flush() ; m_max_name=4; m_max_type=4; m_max_size=4; m_max_value=5; //set_indent(2) ; // LRM says to include this call endfunction function void uvm_tree_printer::set_default(uvm_tree_printer printer) ; m_default_tree_printer = printer ; endfunction function uvm_tree_printer uvm_tree_printer::get_default() ; if (m_default_tree_printer == null) begin m_default_tree_printer = new("uvm_default_tree_printer") ; end return m_default_tree_printer ; endfunction function uvm_line_printer::new(string name="") ; super.new(name); m_newline = " "; set_indent(0); endfunction function void uvm_line_printer::set_default(uvm_line_printer printer) ; m_default_line_printer = printer ; endfunction function uvm_line_printer uvm_line_printer::get_default() ; if (m_default_line_printer == null) begin m_default_line_printer = new("uvm_default_line_printer") ; end return m_default_line_printer ; endfunction function void uvm_line_printer::set_separators(string separators) ; m_uvm_printer_knobs _knobs = get_knobs(); if (separators.len() < 2) begin `uvm_error("UVM/PRINT/SHORT_SEP",$sformatf("Bad call: set_separators(%s) (Argument must have at least 2 characters)",separators)) end _knobs.separator = separators ; endfunction function string uvm_line_printer::get_separators() ; m_uvm_printer_knobs _knobs = get_knobs(); return _knobs.separator ; endfunction function void uvm_line_printer::flush() ; super.flush() ; //set_indent(0); // LRM says to include this call //set_separators("{}"); // LRM says to include this call endfunction