| /***************************************************************************** |
| |
| Licensed to Accellera Systems Initiative Inc. (Accellera) under one or |
| more contributor license agreements. See the NOTICE file distributed |
| with this work for additional information regarding copyright ownership. |
| Accellera licenses this file to you 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. |
| |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| |
| sc_trace.h - Functions for tracing signals and variables. |
| |
| Author: Abhijit Ghosh, Synopsys, Inc. |
| |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| |
| MODIFICATION LOG - modifiers, enter your name, affiliation, date and |
| changes you are making here. |
| |
| Name, Affiliation, Date: |
| Description of Modification: |
| |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| |
| Acknowledgement: The tracing mechanism is based on the tracing |
| mechanism developed at Infineon (formerly Siemens HL). Though this |
| code is somewhat different, the basics are identical to what was |
| originally contributed by Infineon. The contribution of Infineon |
| in the development of this tracing technology is hereby |
| acknowledged. |
| |
| *****************************************************************************/ |
| |
| #ifndef SC_TRACE_H |
| #define SC_TRACE_H |
| |
| #include <cstdio> |
| |
| #include "sysc/datatypes/int/sc_nbdefs.h" |
| #include "sysc/kernel/sc_time.h" |
| |
| // Some forward declarations |
| namespace sc_dt |
| { |
| class sc_bit; |
| class sc_logic; |
| class sc_bv_base; |
| class sc_lv_base; |
| class sc_signed; |
| class sc_unsigned; |
| class sc_int_base; |
| class sc_uint_base; |
| class sc_fxval; |
| class sc_fxval_fast; |
| class sc_fxnum; |
| class sc_fxnum_fast; |
| } |
| |
| namespace sc_core { |
| |
| class sc_time; |
| |
| template <class T> class sc_signal_in_if; |
| |
| |
| // Base class for all kinds of trace files. |
| |
| class sc_trace_file |
| { |
| friend class sc_simcontext; |
| |
| public: |
| |
| // Constructor |
| sc_trace_file(); |
| |
| // All functions are pure virtual because they need to be defined by the |
| // particular tracing mechanism |
| |
| |
| #define DECL_TRACE_METHOD_A(tp) \ |
| virtual void trace( const tp& object, \ |
| const std::string& name ) = 0; |
| |
| #define DECL_TRACE_METHOD_B(tp) \ |
| virtual void trace( const tp& object, \ |
| const std::string& name, \ |
| int width ) = 0; |
| |
| |
| DECL_TRACE_METHOD_A( bool ) |
| DECL_TRACE_METHOD_A( sc_dt::sc_bit ) |
| DECL_TRACE_METHOD_A( sc_dt::sc_logic ) |
| |
| DECL_TRACE_METHOD_B( unsigned char ) |
| DECL_TRACE_METHOD_B( unsigned short ) |
| DECL_TRACE_METHOD_B( unsigned int ) |
| DECL_TRACE_METHOD_B( unsigned long ) |
| DECL_TRACE_METHOD_B( char ) |
| DECL_TRACE_METHOD_B( short ) |
| DECL_TRACE_METHOD_B( int ) |
| DECL_TRACE_METHOD_B( long ) |
| DECL_TRACE_METHOD_B( sc_dt::int64 ) |
| DECL_TRACE_METHOD_B( sc_dt::uint64 ) |
| |
| DECL_TRACE_METHOD_A( float ) |
| DECL_TRACE_METHOD_A( double ) |
| DECL_TRACE_METHOD_A( sc_dt::sc_int_base ) |
| DECL_TRACE_METHOD_A( sc_dt::sc_uint_base ) |
| DECL_TRACE_METHOD_A( sc_dt::sc_signed ) |
| DECL_TRACE_METHOD_A( sc_dt::sc_unsigned ) |
| |
| DECL_TRACE_METHOD_A( sc_dt::sc_fxval ) |
| DECL_TRACE_METHOD_A( sc_dt::sc_fxval_fast ) |
| DECL_TRACE_METHOD_A( sc_dt::sc_fxnum ) |
| DECL_TRACE_METHOD_A( sc_dt::sc_fxnum_fast ) |
| |
| DECL_TRACE_METHOD_A( sc_dt::sc_bv_base ) |
| DECL_TRACE_METHOD_A( sc_dt::sc_lv_base ) |
| |
| |
| #undef DECL_TRACE_METHOD_A |
| #undef DECL_TRACE_METHOD_B |
| |
| // Trace an enumerated object - where possible output the enumeration |
| // literals in the trace file. Enum literals is a null terminated array |
| // of null terminated char* literal strings. |
| virtual void trace( const unsigned int& object, |
| const std::string& name, |
| const char** enum_literals ) = 0; |
| |
| // Output a comment to the trace file |
| virtual void write_comment( const std::string& comment ) = 0; |
| |
| // Set the amount of space before next column |
| // (For most formats this does nothing) |
| virtual void space( int n ); |
| |
| // Also trace transitions between delta cycles if flag is true. |
| virtual void delta_cycles( bool flag ); |
| |
| // Set time unit. |
| virtual void set_time_unit( double v, sc_time_unit tu )=0; |
| |
| protected: |
| |
| // Write trace info for cycle |
| virtual void cycle( bool delta_cycle ) = 0; |
| |
| // Flush results and close file |
| virtual ~sc_trace_file() |
| { /* Intentionally blank */ } |
| }; |
| |
| /*****************************************************************************/ |
| |
| // Now comes all the SystemC defined tracing functions. |
| // We define two sc_trace() versions for scalar types; one where the object to |
| // be traced is passed as a reference and the other where a pointer to the |
| // tracing object is passed. |
| |
| #define DECL_TRACE_FUNC_REF_A(tp) \ |
| void \ |
| sc_trace( sc_trace_file* tf, \ |
| const tp& object, \ |
| const std::string& name ); |
| |
| #define DECL_TRACE_FUNC_PTR_A(tp) \ |
| void \ |
| sc_trace( sc_trace_file* tf, \ |
| const tp* object, \ |
| const std::string& name ); \ |
| |
| #define DECL_TRACE_FUNC_A(tp) \ |
| DECL_TRACE_FUNC_REF_A(tp) \ |
| DECL_TRACE_FUNC_PTR_A(tp) |
| |
| |
| DECL_TRACE_FUNC_A( sc_dt::sc_bit ) |
| DECL_TRACE_FUNC_A( sc_dt::sc_logic ) |
| |
| DECL_TRACE_FUNC_A( sc_dt::sc_int_base ) |
| DECL_TRACE_FUNC_A( sc_dt::sc_uint_base ) |
| DECL_TRACE_FUNC_A( sc_dt::sc_signed ) |
| DECL_TRACE_FUNC_A( sc_dt::sc_unsigned ) |
| |
| DECL_TRACE_FUNC_REF_A( sc_dt::sc_bv_base ) |
| DECL_TRACE_FUNC_REF_A( sc_dt::sc_lv_base ) |
| |
| |
| #undef DECL_TRACE_FUNC_REF_A |
| #undef DECL_TRACE_FUNC_PTR_A |
| #undef DECL_TRACE_FUNC_A |
| |
| |
| // ---------------------------------------------------------------------------- |
| |
| #define DEFN_TRACE_FUNC_REF_A(tp) \ |
| inline \ |
| void \ |
| sc_trace( sc_trace_file* tf, const tp& object, const std::string& name ) \ |
| { \ |
| if( tf ) { \ |
| tf->trace( object, name ); \ |
| } \ |
| } |
| |
| #define DEFN_TRACE_FUNC_PTR_A(tp) \ |
| inline \ |
| void \ |
| sc_trace( sc_trace_file* tf, const tp* object, const std::string& name ) \ |
| { \ |
| if( tf ) { \ |
| tf->trace( *object, name ); \ |
| } \ |
| } |
| |
| #define DEFN_TRACE_FUNC_A(tp) \ |
| DEFN_TRACE_FUNC_REF_A(tp) \ |
| DEFN_TRACE_FUNC_PTR_A(tp) |
| |
| |
| #define DEFN_TRACE_FUNC_REF_B(tp) \ |
| inline \ |
| void \ |
| sc_trace( sc_trace_file* tf, const tp& object, const std::string& name, \ |
| int width = 8 * sizeof( tp ) ) \ |
| { \ |
| if( tf ) { \ |
| tf->trace( object, name, width ); \ |
| } \ |
| } |
| |
| #define DEFN_TRACE_FUNC_PTR_B(tp) \ |
| inline \ |
| void \ |
| sc_trace( sc_trace_file* tf, const tp* object, const std::string& name, \ |
| int width = 8 * sizeof( tp ) ) \ |
| { \ |
| if( tf ) { \ |
| tf->trace( *object, name, width ); \ |
| } \ |
| } |
| |
| |
| #define DEFN_TRACE_FUNC_B(tp) \ |
| DEFN_TRACE_FUNC_REF_B(tp) \ |
| DEFN_TRACE_FUNC_PTR_B(tp) |
| |
| |
| DEFN_TRACE_FUNC_A( bool ) |
| DEFN_TRACE_FUNC_A( float ) |
| DEFN_TRACE_FUNC_A( double ) |
| |
| DEFN_TRACE_FUNC_B( unsigned char ) |
| DEFN_TRACE_FUNC_B( unsigned short ) |
| DEFN_TRACE_FUNC_B( unsigned int ) |
| DEFN_TRACE_FUNC_B( unsigned long ) |
| DEFN_TRACE_FUNC_B( char ) |
| DEFN_TRACE_FUNC_B( short ) |
| DEFN_TRACE_FUNC_B( int ) |
| DEFN_TRACE_FUNC_B( long ) |
| DEFN_TRACE_FUNC_B( sc_dt::int64 ) |
| DEFN_TRACE_FUNC_B( sc_dt::uint64 ) |
| |
| |
| #undef DEFN_TRACE_FUNC_REF_A |
| #undef DEFN_TRACE_FUNC_PTR_A |
| #undef DEFN_TRACE_FUNC_A |
| |
| #undef DEFN_TRACE_FUNC_REF_B |
| #undef DEFN_TRACE_FUNC_PTR_B |
| #undef DEFN_TRACE_FUNC_B |
| |
| |
| template <class T> |
| inline |
| void |
| sc_trace( sc_trace_file* tf, |
| const sc_signal_in_if<T>& object, |
| const std::string& name ) |
| { |
| sc_trace( tf, object.read(), name ); |
| } |
| |
| template< class T > |
| inline |
| void |
| sc_trace( sc_trace_file* tf, |
| const sc_signal_in_if<T>& object, |
| const char* name ) |
| { |
| sc_trace( tf, object.read(), name ); |
| } |
| |
| |
| // specializations for signals of type char, short, int, long |
| |
| void sc_trace( sc_trace_file* tf, |
| const sc_signal_in_if<char>& object, |
| const std::string& name, |
| int width ); |
| |
| void sc_trace( sc_trace_file* tf, |
| const sc_signal_in_if<short>& object, |
| const std::string& name, |
| int width ); |
| |
| void sc_trace( sc_trace_file* tf, |
| const sc_signal_in_if<int>& object, |
| const std::string& name, |
| int width ); |
| |
| void sc_trace( sc_trace_file* tf, |
| const sc_signal_in_if<long>& object, |
| const std::string& name, |
| int width ); |
| |
| |
| // 1. non-template function is better than template |
| // 2. more-specialized template is better than less-specialized |
| // 3. no partial specialization for template functions |
| |
| |
| // Trace an enumerated object - where possible output the enumeration literals |
| // in the trace file. Enum literals is a null terminated array of null |
| // terminated char* literal strings. |
| |
| void |
| sc_trace( sc_trace_file* tf, |
| const unsigned int& object, |
| const std::string& name, |
| const char** enum_literals ); |
| |
| |
| // Dummy function for arbitrary types of value, does nothing |
| |
| extern void sc_trace( sc_trace_file* tf, |
| const void* object, |
| const std::string& name ); |
| |
| |
| // Turn on/off delta cycle tracing on trace file `tf'. |
| // Default is to turn on delta cycle tracing. |
| |
| inline |
| void |
| sc_trace_delta_cycles( sc_trace_file* tf, bool on = true ) |
| { |
| if( tf ) tf->delta_cycles( on ); |
| } |
| |
| |
| // Output a comment to the trace file |
| |
| inline |
| void |
| sc_write_comment( sc_trace_file* tf, const std::string& comment ) |
| { |
| if( tf ) tf->write_comment( comment ); |
| } |
| |
| |
| // Equivalent of std::fprintf for trace files! |
| |
| void tprintf( sc_trace_file* tf, const char* format, ... ); |
| |
| // ---------------------------------------------------------------------------- |
| // Create VCD file |
| extern sc_trace_file *sc_create_vcd_trace_file(const char* name); |
| extern void sc_close_vcd_trace_file( sc_trace_file* tf ); |
| |
| |
| // ---------------------------------------------------------------------------- |
| // Create WIF file |
| extern sc_trace_file *sc_create_wif_trace_file(const char *name); |
| extern void sc_close_wif_trace_file( sc_trace_file* tf ); |
| |
| } // namespace sc_core |
| |
| #endif // SC_TRACE_H |
| // Taf |