summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/tracing
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/tracing')
-rw-r--r--ext/systemc/src/sysc/tracing/sc_trace.cpp217
-rw-r--r--ext/systemc/src/sysc/tracing/sc_trace.h397
-rw-r--r--ext/systemc/src/sysc/tracing/sc_trace_file_base.cpp273
-rw-r--r--ext/systemc/src/sysc/tracing/sc_trace_file_base.h140
-rw-r--r--ext/systemc/src/sysc/tracing/sc_tracing_ids.h79
-rw-r--r--ext/systemc/src/sysc/tracing/sc_vcd_trace.cpp2175
-rw-r--r--ext/systemc/src/sysc/tracing/sc_vcd_trace.h228
-rw-r--r--ext/systemc/src/sysc/tracing/sc_wif_trace.cpp1911
-rw-r--r--ext/systemc/src/sysc/tracing/sc_wif_trace.h222
9 files changed, 5642 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/tracing/sc_trace.cpp b/ext/systemc/src/sysc/tracing/sc_trace.cpp
new file mode 100644
index 000000000..09a2fa3b2
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_trace.cpp
@@ -0,0 +1,217 @@
+/*****************************************************************************
+
+ 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.cpp - Functions for tracing signals and variables.
+
+ Original 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.
+
+ *****************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "sysc/tracing/sc_trace.h"
+#include "sysc/tracing/sc_tracing_ids.h"
+#include "sysc/communication/sc_signal_ifs.h"
+#include "sysc/utils/sc_report.h"
+#include "sysc/utils/sc_utils_ids.h"
+
+namespace sc_core {
+
+// Trace file common functions.
+
+sc_trace_file::sc_trace_file()
+{
+ /* Intentionally blank */
+}
+
+void tprintf(sc_trace_file* tf, const char* format, ...)
+{
+ static char buffer[4096];
+ va_list ap;
+ va_start(ap, format);
+ (void) vsprintf(buffer, format, ap);
+ va_end(ap);
+ if (tf) tf->write_comment(buffer);
+}
+
+void sc_trace_file::space(int)
+{
+ /* Intentionally blank */
+}
+
+void sc_trace_file::delta_cycles(bool)
+{
+ /* Intentionally blank */
+}
+
+
+void
+sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<char>& object,
+ const std::string& name,
+ int width )
+{
+ if( tf ) {
+ tf->trace( object.read(), name, width );
+ }
+}
+
+void
+sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<short>& object,
+ const std::string& name,
+ int width )
+{
+ if( tf ) {
+ tf->trace( object.read(), name, width );
+ }
+}
+
+void
+sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<int>& object,
+ const std::string& name,
+ int width )
+{
+ if( tf ) {
+ tf->trace( object.read(), name, width );
+ }
+}
+
+void
+sc_trace( sc_trace_file* tf,
+ const sc_signal_in_if<long>& object,
+ const std::string& name,
+ int width )
+{
+ if( tf ) {
+ tf->trace( object.read(), name, width );
+ }
+}
+
+
+void
+sc_trace(sc_trace_file* /* not used */,
+ const void* /* not used */,
+ const std::string& name)
+{
+ SC_REPORT_WARNING( SC_ID_TRACING_OBJECT_IGNORED_, name.c_str() );
+}
+
+
+
+void double_to_special_int64(double in, unsigned* high, unsigned* low)
+{
+ double invar = in;
+ if(invar > 5e17) invar = 5e17; // Saturation limit
+ if(invar < 0.0) invar = 0.0;
+ invar += .5;
+ *high = (unsigned)(invar / 1e9);
+ double rest = invar - 1e9 * (*high);
+ if(rest < 0) *low = 0;
+ else *low = (unsigned)rest;
+}
+
+
+// ----------------------------------------------------------------------------
+
+#define DEFN_TRACE_FUNC_REF_A(tp) \
+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) \
+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)
+
+
+DEFN_TRACE_FUNC_A( sc_dt::sc_bit )
+DEFN_TRACE_FUNC_A( sc_dt::sc_logic )
+
+DEFN_TRACE_FUNC_A( sc_dt::sc_int_base )
+DEFN_TRACE_FUNC_A( sc_dt::sc_uint_base )
+DEFN_TRACE_FUNC_A( sc_dt::sc_signed )
+DEFN_TRACE_FUNC_A( sc_dt::sc_unsigned )
+
+DEFN_TRACE_FUNC_REF_A( sc_dt::sc_bv_base )
+DEFN_TRACE_FUNC_REF_A( sc_dt::sc_lv_base )
+
+
+#undef DEFN_TRACE_FUNC_REF_A
+#undef DEFN_TRACE_FUNC_PTR_A
+#undef DEFN_TRACE_FUNC_A
+
+
+void
+sc_trace( sc_trace_file* tf,
+ const unsigned int& object,
+ const std::string& name,
+ const char** enum_literals )
+{
+ static bool warn_sc_trace_literals=true;
+ if ( warn_sc_trace_literals )
+ {
+ warn_sc_trace_literals=false;
+ SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
+ "tracing of enumerated literals is deprecated" );
+ }
+
+ if( tf ) tf->trace( object, name, enum_literals );
+}
+
+} // namespace sc_core
+
+// Taf!
diff --git a/ext/systemc/src/sysc/tracing/sc_trace.h b/ext/systemc/src/sysc/tracing/sc_trace.h
new file mode 100644
index 000000000..256e430a7
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_trace.h
@@ -0,0 +1,397 @@
+/*****************************************************************************
+
+ 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
diff --git a/ext/systemc/src/sysc/tracing/sc_trace_file_base.cpp b/ext/systemc/src/sysc/tracing/sc_trace_file_base.cpp
new file mode 100644
index 000000000..4f4345468
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_trace_file_base.cpp
@@ -0,0 +1,273 @@
+/*****************************************************************************
+
+ 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_file_base.cpp - Shared internal tracing implementation
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-11-15
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Acknowledgement: The tracing mechanism is based on the tracing
+ mechanism developed at Infineon (formerly Siemens HL). Though this
+ code is somewhat different, and significantly enhanced, 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.
+
+ *****************************************************************************/
+
+#include <ctime>
+
+#include "sysc/tracing/sc_trace_file_base.h"
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_simcontext_int.h"
+
+#if SC_TRACING_PHASE_CALLBACKS_
+# include "sysc/kernel/sc_object_int.h"
+#endif
+
+namespace sc_core {
+
+bool sc_trace_file_base::tracing_initialized_ = false;
+
+
+sc_trace_file_base::sc_trace_file_base( const char* name, const char* extension )
+ : sc_trace_file()
+#if SC_TRACING_PHASE_CALLBACKS_
+ , sc_object( sc_gen_unique_name("$$$$kernel_tracefile$$$$") )
+#endif
+ , fp(0)
+ , timescale_unit()
+ , timescale_set_by_user(false)
+ , filename_()
+ , initialized_(false)
+ , trace_delta_cycles_(false)
+{
+ if( !name || !*name ) {
+ SC_REPORT_ERROR( SC_ID_TRACING_FOPEN_FAILED_, "no name given" );
+ return;
+ } else {
+ std::stringstream ss;
+ ss << name << "." << extension;
+ ss.str().swap( filename_ );
+ }
+
+#if SC_TRACING_PHASE_CALLBACKS_ == 1
+ // remove from hierarchy
+ sc_object::detach();
+ // register regular (non-delta) callbacks
+ sc_object::register_simulation_phase_callback(
+ // Note: Usually, one would expect to dump the initial values
+ // of the traced variables at the end of the initialization
+ // phase. The "non-callback" implementation dumps those
+ // values only after the first delta cycle, though.
+ // SC_END_OF_INITIALIZATION |
+ SC_BEFORE_TIMESTEP |
+ SC_PAUSED | SC_STOPPED
+ );
+#else // explicitly register with simcontext
+ sc_get_curr_simcontext()->add_trace_file( this );
+#endif
+}
+
+sc_trace_file_base::~sc_trace_file_base()
+{
+ if( fp )
+ fclose(fp);
+
+#if SC_TRACING_PHASE_CALLBACKS_ == 0
+ // unregister from simcontext
+ sc_get_curr_simcontext()->remove_trace_file( this );
+#endif
+}
+
+/*****************************************************************************/
+// simulation phase callback based trigger
+//
+// The tracing updates are triggered
+// (- at the end of the initialization phase [disabled for now])
+// - before an update of the simulation time
+// - before returning to sc_start (via sc_pause() or sc_stop())
+// - after an update phase (if delta cycles need to be traced)
+//
+#if SC_TRACING_PHASE_CALLBACKS_
+void
+sc_trace_file_base::simulation_phase_callback()
+{
+ // delta cycle is traced at the end of an update phase
+ cycle( simcontext()->get_status() == SC_END_OF_UPDATE );
+}
+#endif // SC_TRACING_PHASE_CALLBACKS_
+
+/*****************************************************************************/
+
+bool
+sc_trace_file_base::initialize()
+{
+ if( initialized_ )
+ return false;
+
+ initialized_ = true;
+
+ if( !tracing_initialized_ ) {
+ tracing_initialized_ = true;
+ bool running_regression = ( getenv( "SYSTEMC_REGRESSION" ) != NULL );
+
+ // hide some messages during regression
+ if( running_regression ) {
+ sc_report_handler::set_actions( SC_ID_TRACING_TIMESCALE_DEFAULT_
+ , SC_INFO, SC_DO_NOTHING );
+ sc_report_handler::set_actions( SC_ID_TRACING_VCD_DUPLICATE_TIME_
+ , SC_WARNING, SC_DO_NOTHING );
+ }
+ }
+
+ // open trace file
+ if(!fp) open_fp();
+
+ // setup timescale
+ if( !timescale_set_by_user )
+ {
+ timescale_unit = sc_get_time_resolution().to_seconds();
+
+ std::stringstream ss;
+ ss << sc_get_time_resolution() << " (" << filename_ << ")";
+ SC_REPORT_INFO( SC_ID_TRACING_TIMESCALE_DEFAULT_
+ , ss.str().c_str() );
+ }
+
+ // initialize derived tracing implementation class (VCD/WIF)
+ do_initialize();
+
+ return initialized_;
+}
+
+void
+sc_trace_file_base::open_fp()
+{
+ sc_assert( !fp );
+ fp = fopen( filename(), "w" );
+ if( !fp ) {
+ SC_REPORT_ERROR( SC_ID_TRACING_FOPEN_FAILED_, filename() );
+ std::terminate(); // can't recover from here
+ }
+}
+
+void
+sc_trace_file_base::delta_cycles( bool flag )
+{
+ trace_delta_cycles_ = flag;
+#if SC_TRACING_PHASE_CALLBACKS_
+ if( trace_delta_cycles_ ) {
+ sc_object::register_simulation_phase_callback( SC_END_OF_UPDATE );
+ } else {
+ sc_object::unregister_simulation_phase_callback( SC_END_OF_UPDATE );
+ }
+#endif
+}
+
+void
+sc_trace_file_base::set_time_unit( double v, sc_time_unit tu )
+{
+ if( initialized_ )
+ {
+ std::stringstream ss;
+ ss << filename_ << "\n"
+ "\tTimescale unit cannot be changed once tracing has begun.\n"
+ "\tTo change the scale, create a new trace file.";
+ SC_REPORT_ERROR( SC_ID_TRACING_ALREADY_INITIALIZED_
+ , ss.str().c_str() );
+ return;
+ }
+
+ switch ( tu )
+ {
+ case SC_FS: v = v * 1e-15; break;
+ case SC_PS: v = v * 1e-12; break;
+ case SC_NS: v = v * 1e-9; break;
+ case SC_US: v = v * 1e-6; break;
+ case SC_MS: v = v * 1e-3; break;
+ case SC_SEC: break;
+ default: {
+ std::stringstream ss;
+ ss << "unknown time unit:" << tu
+ << " (" << filename_ << ")";
+ SC_REPORT_WARNING( SC_ID_TRACING_TIMESCALE_UNIT_
+ , ss.str().c_str() );
+ }
+ }
+
+ timescale_set_by_user = true;
+ timescale_unit = v;
+
+ // EMIT ADVISORY MESSAGE ABOUT CHANGE IN TIME SCALE:
+ {
+ std::stringstream ss;
+ ss << sc_time( timescale_unit, SC_SEC )
+ << " (" << filename_ << ")";
+ SC_REPORT_INFO( SC_ID_TRACING_TIMESCALE_UNIT_, ss.str().c_str() );
+ }
+}
+
+bool
+sc_trace_file_base::add_trace_check( const std::string & name ) const
+{
+ if( !initialized_ ) return true;
+
+ std::stringstream ss;
+ ss << "sc_trace() failed:\n"
+ "\tNo traces can be added to "
+ "'" << filename_ << "'"
+ " once trace recording has started.\n"
+ "\tTo add tracing of '" << name << "', create a new trace file.";
+
+ SC_REPORT_ERROR( SC_ID_TRACING_ALREADY_INITIALIZED_
+ , ss.str().c_str() );
+ return false;
+}
+
+// obtain formatted time string
+std::string localtime_string()
+{
+ char buf[200];
+ time_t long_time;
+ time(&long_time);
+ struct tm* p_tm = localtime(&long_time);
+ strftime(buf, 199, "%b %d, %Y %H:%M:%S", p_tm);
+ return buf;
+}
+
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+// Taf!
diff --git a/ext/systemc/src/sysc/tracing/sc_trace_file_base.h b/ext/systemc/src/sysc/tracing/sc_trace_file_base.h
new file mode 100644
index 000000000..c0217266f
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_trace_file_base.h
@@ -0,0 +1,140 @@
+/*****************************************************************************
+
+ 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_file_base.h - Shared internal tracing implementation
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-11-15
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Acknowledgement: The tracing mechanism is based on the tracing
+ mechanism developed at Infineon (formerly Siemens HL). Though this
+ code is somewhat different, and significantly enhanced, 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_FILE_BASE_H_INCLUDED_
+#define SC_TRACE_FILE_BASE_H_INCLUDED_
+
+#include <cstdio>
+
+// use callback-based tracing implementation
+#if defined( SC_ENABLE_SIMULATION_PHASE_CALLBACKS_TRACING )
+# define SC_TRACING_PHASE_CALLBACKS_ 1
+# include "sysc/kernel/sc_object.h"
+#else
+# define SC_TRACING_PHASE_CALLBACKS_ 0
+#endif
+
+#include "sysc/tracing/sc_trace.h"
+#include "sysc/tracing/sc_tracing_ids.h"
+
+namespace sc_core {
+
+// shared implementation of trace files
+class sc_trace_file_base
+ : public sc_trace_file
+#if SC_TRACING_PHASE_CALLBACKS_
+ , private sc_object // to be used as callback target
+#endif
+{
+public:
+ const char* filename() const
+ { return filename_.c_str(); }
+
+ bool delta_cycles() const
+ { return trace_delta_cycles_; }
+
+ // Also trace transitions between delta cycles if flag is true.
+ virtual void delta_cycles(bool flag);
+
+ // set a user-define timescale unit for the trace file
+ virtual void set_time_unit( double v, sc_time_unit tu);
+
+protected:
+ sc_trace_file_base( const char* name, const char* extension );
+
+ // returns true, iff initialization has been performed
+ bool initialize();
+ // ensure that file has been opened (needed for early write_comment())
+ void open_fp();
+ // perform format specific initialization
+ virtual void do_initialize() = 0;
+
+ // returns true, if new trace objects can still be added
+ // (i.e. trace file is not yet initialized)
+ bool add_trace_check( const std::string& name ) const;
+
+ // Flush results and close file.
+ virtual ~sc_trace_file_base();
+
+#if SC_TRACING_PHASE_CALLBACKS_
+private:
+ virtual void simulation_phase_callback();
+#endif // SC_TRACING_PHASE_CALLBACKS_
+
+protected:
+ FILE* fp; // pointer to the trace file
+ double timescale_unit; // in seconds
+ bool timescale_set_by_user; // = true means set by user
+
+private:
+ std::string filename_; // name of the file (for reporting)
+ bool initialized_; // tracing started?
+ bool trace_delta_cycles_; // also trace delta transitions?
+
+ static bool tracing_initialized_; // shared setup of tracing implementation
+
+private: // disabled
+ sc_trace_file_base( const sc_trace_file_base& ) /* = delete */;
+ sc_trace_file_base& operator=( const sc_trace_file_base& ) /* = delete */;
+
+}; // class sc_trace_file_base
+
+// -----------------------------------------------------------------------
+
+// Convert double time to 64-bit integer
+
+void double_to_special_int64( double in, unsigned* high, unsigned* low );
+
+// obtain formatted time string
+std::string localtime_string();
+
+} // namespace sc_core
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+#endif // SC_TRACE_FILE_BASE_H_INCLUDED_
+// Taf!
diff --git a/ext/systemc/src/sysc/tracing/sc_tracing_ids.h b/ext/systemc/src/sysc/tracing/sc_tracing_ids.h
new file mode 100644
index 000000000..dacdb9451
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_tracing_ids.h
@@ -0,0 +1,79 @@
+/*****************************************************************************
+
+ 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_tracing_ids.h -- Report ids for the tracing code.
+
+ Original Author: Philipp A. Hartmann, OFFIS, 2013-11-17
+
+ CHANGE LOG AT END OF FILE
+ *****************************************************************************/
+
+#ifndef SC_TRACING_IDS_H
+#define SC_TRACING_IDS_H
+
+// ----------------------------------------------------------------------------
+// Report ids (tracing)
+//
+// Report ids in the range of 700-799.
+// ----------------------------------------------------------------------------
+
+#ifndef SC_DEFINE_MESSAGE
+#define SC_DEFINE_MESSAGE(id,unused1,unused2) \
+ namespace sc_core { extern const char id[]; }
+#endif
+
+SC_DEFINE_MESSAGE( SC_ID_TRACING_FOPEN_FAILED_, 701,
+ "cannot open tracefile for writing" )
+
+SC_DEFINE_MESSAGE( SC_ID_TRACING_TIMESCALE_DEFAULT_, 702,
+ "default timescale unit used for tracing" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_TIMESCALE_UNIT_, 703,
+ "tracing timescale unit set" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_VCD_DELTA_CYCLE_, 704,
+ "VCD delta cycle tracing with pseudo timesteps (1 unit)" )
+/* unused IDs 705-709 */
+SC_DEFINE_MESSAGE( SC_ID_TRACING_OBJECT_IGNORED_, 710,
+ "object cannot not be traced" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_OBJECT_NAME_FILTERED_, 711,
+ "traced object name filtered" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_INVALID_ENUM_VALUE_, 712,
+ "traced value of enumerated type undefined" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_VCD_DUPLICATE_TIME_, 713,
+ "multiple VCD tracing cycles with the same time detected" )
+SC_DEFINE_MESSAGE( SC_ID_TRACING_VCD_REVERSED_TIME_, 714,
+ "VCD tracing cycle with falling time detected" )
+/* unused IDs 715-719 */
+SC_DEFINE_MESSAGE( SC_ID_TRACING_ALREADY_INITIALIZED_, 720,
+ "sc_trace_file already initialized" )
+
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date:
+ Description of Modification:
+
+ *****************************************************************************/
+
+#endif // SC_TRACING_IDS_H
+// Taf!
diff --git a/ext/systemc/src/sysc/tracing/sc_vcd_trace.cpp b/ext/systemc/src/sysc/tracing/sc_vcd_trace.cpp
new file mode 100644
index 000000000..616d6274d
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_vcd_trace.cpp
@@ -0,0 +1,2175 @@
+/*****************************************************************************
+
+ 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_vcd_trace.cpp - Implementation of VCD tracing.
+
+ Original Author - Abhijit Ghosh, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Replaced 'width' of sc_(u)int with their
+ 'bitwidth()'.
+
+ 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, and significantly enhanced, 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.
+
+ *****************************************************************************/
+
+
+#include <cstdlib>
+#include <string.h>
+#include <vector>
+
+#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_ver.h"
+#include "sysc/datatypes/bit/sc_bit.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/fx/fx.h"
+#include "sysc/tracing/sc_vcd_trace.h"
+
+namespace sc_core {
+
+// Forward declarations for functions that come later in the file
+// Map sc_dt::sc_logic to printable VCD
+static char map_sc_logic_state_to_vcd_state(char in_char);
+
+// Remove name problems associated with [] in vcd names
+static void remove_vcd_name_problems(vcd_trace const* vcd, std::string& name);
+
+const char* vcd_types[vcd_trace_file::VCD_LAST]={"wire","real"};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : vcd_trace
+//
+// Base class for VCD traces.
+// ----------------------------------------------------------------------------
+
+class vcd_trace
+{
+public:
+
+ vcd_trace(const std::string& name_, const std::string& vcd_name_);
+
+ // Needs to be pure virtual as has to be defined by the particular
+ // type being traced
+ virtual void write(FILE* f) = 0;
+
+ virtual void set_width();
+
+ static const char* strip_leading_bits(const char* originalbuf);
+
+ // Comparison function needs to be pure virtual too
+ virtual bool changed() = 0;
+
+ // Make this virtual as some derived classes may overwrite
+ virtual void print_variable_declaration_line(FILE* f);
+
+ void compose_data_line(char* rawdata, char* compdata);
+ std::string compose_line(const std::string& data);
+
+ virtual ~vcd_trace();
+
+ const std::string name;
+ const std::string vcd_name;
+ const char* vcd_var_typ_name;
+ int bit_width;
+};
+
+
+vcd_trace::vcd_trace(const std::string& name_, const std::string& vcd_name_)
+: name(name_), vcd_name(vcd_name_), vcd_var_typ_name(0), bit_width(0)
+{
+ /* Intentionally blank */
+}
+
+void
+vcd_trace::compose_data_line(char* rawdata, char* compdata)
+{
+ sc_assert(rawdata != compdata);
+
+ if(bit_width == 0)
+ {
+ compdata[0] = '\0';
+ }
+ else
+ {
+ if(bit_width == 1)
+ {
+ compdata[0] = rawdata[0];
+ strcpy(&(compdata[1]), vcd_name.c_str());
+ }
+ else
+ {
+ const char* effective_begin = strip_leading_bits(rawdata);
+ std::sprintf(compdata, "b%s %s", effective_begin, vcd_name.c_str());
+ }
+ }
+}
+
+// same as above but not that ugly
+std::string
+vcd_trace::compose_line(const std::string& data)
+{
+ if(bit_width == 0)
+ return "";
+ if(bit_width == 1)
+ return data + vcd_name;
+ return std::string("b")+strip_leading_bits(data.c_str())+" "+vcd_name;
+}
+
+void
+vcd_trace::print_variable_declaration_line(FILE* f)
+{
+ char buf[2000];
+
+ if ( bit_width <= 0 )
+ {
+ std::stringstream ss;
+ ss << "'" << name << "' has 0 bits";
+ SC_REPORT_ERROR( SC_ID_TRACING_OBJECT_IGNORED_
+ , ss.str().c_str() );
+ return;
+ }
+
+ std::string namecopy = name;
+ remove_vcd_name_problems(this, namecopy);
+ if ( bit_width == 1 )
+ {
+ std::sprintf(buf, "$var %s % 3d %s %s $end\n",
+ vcd_var_typ_name,
+ bit_width,
+ vcd_name.c_str(),
+ namecopy.c_str());
+ }
+ else
+ {
+ std::sprintf(buf, "$var %s % 3d %s %s [%d:0] $end\n",
+ vcd_var_typ_name,
+ bit_width,
+ vcd_name.c_str(),
+ namecopy.c_str(),
+ bit_width-1);
+ }
+ std::fputs(buf, f);
+}
+
+void
+vcd_trace::set_width()
+{
+ /* Intentionally Blank, should be defined for each type separately */
+}
+
+const char*
+vcd_trace::strip_leading_bits(const char* originalbuf)
+{
+ //*********************************************************************
+ // - Remove multiple leading 0,z,x, and replace by only one
+ // - For example,
+ // b000z100 -> b0z100
+ // b00000xxx -> b0xxx
+ // b000 -> b0
+ // bzzzzz1 -> bz1
+ // bxxxz10 -> xz10
+ // - For leading 0's followed by 1, remove all leading 0's
+ // b0000010101 -> b10101
+
+ const char* position = originalbuf;
+
+ if( strlen(originalbuf) < 2 ||
+ (originalbuf[0] != 'z' && originalbuf[0] != 'x' &&
+ originalbuf[0] != '0' ))
+ return originalbuf;
+
+ char first_char = *position;
+ while(*position == first_char)
+ {
+ position++;
+ }
+
+ if(first_char == '0' && *position == '1')
+ return position;
+ // else
+ return position-1;
+}
+
+vcd_trace::~vcd_trace()
+{
+ /* Intentionally Blank */
+}
+
+
+template <class T>
+class vcd_T_trace : public vcd_trace
+{
+ public:
+
+ vcd_T_trace( const T& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ vcd_trace_file::vcd_enum type_ )
+ : vcd_trace( name_, vcd_name_ ),
+ object( object_ ),
+ old_value( object_ )
+ {
+ vcd_var_typ_name = vcd_types[type_];
+ }
+
+ void write( FILE* f )
+ {
+ std::fprintf( f, "%s", compose_line( object.to_string() ).c_str() );
+ old_value = object;
+ }
+
+ bool changed()
+ { return !(object == old_value); }
+
+ void set_width()
+ { bit_width = object.length(); }
+
+protected:
+
+ const T& object;
+ T old_value;
+};
+
+typedef vcd_T_trace<sc_dt::sc_bv_base> vcd_sc_bv_trace;
+typedef vcd_T_trace<sc_dt::sc_lv_base> vcd_sc_lv_trace;
+
+// Trace sc_dt::sc_bv_base (sc_dt::sc_bv)
+void
+vcd_trace_file::trace(
+ const sc_dt::sc_bv_base& object, const std::string& name)
+{
+ traceT(object,name);
+}
+
+// Trace sc_dt::sc_lv_base (sc_dt::sc_lv)
+void
+vcd_trace_file::trace(
+ const sc_dt::sc_lv_base& object, const std::string& name)
+{
+ traceT(object,name);
+}
+
+/*****************************************************************************/
+
+class vcd_bool_trace : public vcd_trace {
+public:
+ vcd_bool_trace(const bool& object_,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const bool& object;
+ bool old_value;
+};
+
+vcd_bool_trace::vcd_bool_trace(const bool& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_)
+{
+ vcd_var_typ_name = "wire";
+ bit_width = 1;
+}
+
+bool
+vcd_bool_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_bool_trace::write(FILE* f)
+{
+ if (object == true) std::fputc('1', f);
+ else std::fputc('0', f);
+
+ std::fprintf(f,"%s", vcd_name.c_str());
+
+ old_value = object;
+}
+
+//*****************************************************************************
+
+class vcd_sc_bit_trace : public vcd_trace {
+public:
+ vcd_sc_bit_trace(const sc_dt::sc_bit& , const std::string& ,
+ const std::string& );
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::sc_bit& object;
+ sc_dt::sc_bit old_value;
+};
+
+vcd_sc_bit_trace::vcd_sc_bit_trace( const sc_dt::sc_bit& object_,
+ const std::string& name,
+ const std::string& vcd_name)
+: vcd_trace(name, vcd_name), object( object_ ), old_value( object_ )
+{
+ vcd_var_typ_name = "wire";
+ bit_width = 1;
+}
+
+bool
+vcd_sc_bit_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_bit_trace::write(FILE* f)
+{
+ if (object == true) std::fputc('1', f);
+ else std::fputc('0', f);
+
+ std::fprintf(f,"%s", vcd_name.c_str());
+
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_sc_logic_trace : public vcd_trace {
+public:
+ vcd_sc_logic_trace(const sc_dt::sc_logic& object_,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::sc_logic& object;
+ sc_dt::sc_logic old_value;
+};
+
+
+vcd_sc_logic_trace::vcd_sc_logic_trace(const sc_dt::sc_logic& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_)
+{
+ vcd_var_typ_name = "wire";
+ bit_width = 1;
+}
+
+
+bool
+vcd_sc_logic_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void
+vcd_sc_logic_trace::write(FILE* f)
+{
+ char out_char;
+ out_char = map_sc_logic_state_to_vcd_state(object.to_char());
+ std::fputc(out_char, f);
+
+ std::fprintf(f,"%s", vcd_name.c_str());
+
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class vcd_sc_unsigned_trace : public vcd_trace {
+public:
+ vcd_sc_unsigned_trace(const sc_dt::sc_unsigned& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_unsigned& object;
+ sc_dt::sc_unsigned old_value;
+};
+
+
+vcd_sc_unsigned_trace::vcd_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length())
+// The last may look strange, but is correct
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_unsigned_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_unsigned_trace::write(FILE* f)
+{
+ static std::vector<char> compdata(1024), rawdata(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( compdata.size() < (size_t)object.length() ) {
+ size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( compdata ); // resize without copying values
+ std::vector<char>( sz ).swap( rawdata );
+ }
+ char *rawdata_ptr = &rawdata[0];
+
+ for (int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *rawdata_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line(&rawdata[0], &compdata[0]);
+
+ std::fputs(&compdata[0], f);
+ old_value = object;
+}
+
+void
+vcd_sc_unsigned_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class vcd_sc_signed_trace : public vcd_trace {
+public:
+ vcd_sc_signed_trace(const sc_dt::sc_signed& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_signed& object;
+ sc_dt::sc_signed old_value;
+};
+
+
+vcd_sc_signed_trace::vcd_sc_signed_trace(const sc_dt::sc_signed& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length())
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_signed_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_signed_trace::write(FILE* f)
+{
+ static std::vector<char> compdata(1024), rawdata(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( compdata.size() < (size_t)object.length() ) {
+ size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( compdata ); // resize without copying values
+ std::vector<char>( sz ).swap( rawdata );
+ }
+ char *rawdata_ptr = &rawdata[0];
+
+ for (int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *rawdata_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line(&rawdata[0], &compdata[0]);
+
+ std::fputs(&compdata[0], f);
+ old_value = object;
+}
+
+void
+vcd_sc_signed_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+/*****************************************************************************/
+
+class vcd_sc_uint_base_trace : public vcd_trace {
+public:
+ vcd_sc_uint_base_trace(const sc_dt::sc_uint_base& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_uint_base& object;
+ sc_dt::sc_uint_base old_value;
+};
+
+
+vcd_sc_uint_base_trace::vcd_sc_uint_base_trace(
+ const sc_dt::sc_uint_base& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length())
+// The last may look strange, but is correct
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_uint_base_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_uint_base_trace::write(FILE* f)
+{
+ char rawdata[1000], *rawdata_ptr = rawdata;
+ char compdata[1000];
+
+ int bitindex;
+ for (bitindex = object.length()-1; bitindex >= 0; --bitindex) {
+ *rawdata_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line(rawdata, compdata);
+
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+void
+vcd_sc_uint_base_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class vcd_sc_int_base_trace : public vcd_trace {
+public:
+ vcd_sc_int_base_trace(const sc_dt::sc_int_base& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_int_base& object;
+ sc_dt::sc_int_base old_value;
+};
+
+
+vcd_sc_int_base_trace::vcd_sc_int_base_trace(const sc_dt::sc_int_base& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length())
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_int_base_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_int_base_trace::write(FILE* f)
+{
+ char rawdata[1000], *rawdata_ptr = rawdata;
+ char compdata[1000];
+
+ int bitindex;
+ for (bitindex = object.length()-1; bitindex >= 0; --bitindex) {
+ *rawdata_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line(rawdata, compdata);
+
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+void
+vcd_sc_int_base_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class vcd_sc_fxval_trace : public vcd_trace
+{
+public:
+
+ vcd_sc_fxval_trace( const sc_dt::sc_fxval& object,
+ const std::string& name_,
+ const std::string& vcd_name_ );
+ void write( FILE* f );
+ bool changed();
+
+protected:
+
+ const sc_dt::sc_fxval& object;
+ sc_dt::sc_fxval old_value;
+
+};
+
+vcd_sc_fxval_trace::vcd_sc_fxval_trace( const sc_dt::sc_fxval& object_,
+ const std::string& name_,
+ const std::string& vcd_name_ )
+: vcd_trace( name_, vcd_name_ ),
+ object( object_ ), old_value( object_ )
+{
+ vcd_var_typ_name = "real";
+ bit_width = 1;
+}
+
+bool
+vcd_sc_fxval_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_fxval_trace::write( FILE* f )
+{
+ std::fprintf( f, "r%.16g %s", object.to_double(), vcd_name.c_str() );
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_sc_fxval_fast_trace : public vcd_trace
+{
+public:
+
+ vcd_sc_fxval_fast_trace( const sc_dt::sc_fxval_fast& object,
+ const std::string& name_,
+ const std::string& vcd_name_ );
+ void write( FILE* f );
+ bool changed();
+
+protected:
+
+ const sc_dt::sc_fxval_fast& object;
+ sc_dt::sc_fxval_fast old_value;
+
+};
+
+vcd_sc_fxval_fast_trace::vcd_sc_fxval_fast_trace(
+ const sc_dt::sc_fxval_fast& object_,
+ const std::string& name_,
+ const std::string& vcd_name_ )
+: vcd_trace( name_, vcd_name_ ),
+ object( object_ ), old_value( object_ )
+{
+ vcd_var_typ_name = "real";
+ bit_width = 1;
+}
+
+bool
+vcd_sc_fxval_fast_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_fxval_fast_trace::write( FILE* f )
+{
+ std::fprintf( f, "r%.16g %s", object.to_double(), vcd_name.c_str() );
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_sc_fxnum_trace : public vcd_trace
+{
+public:
+
+ vcd_sc_fxnum_trace( const sc_dt::sc_fxnum& object,
+ const std::string& name_,
+ const std::string& vcd_name_ );
+ void write( FILE* f );
+ bool changed();
+ void set_width();
+
+protected:
+
+ const sc_dt::sc_fxnum& object;
+ sc_dt::sc_fxnum old_value;
+
+};
+
+vcd_sc_fxnum_trace::vcd_sc_fxnum_trace( const sc_dt::sc_fxnum& object_,
+ const std::string& name_,
+ const std::string& vcd_name_ )
+: vcd_trace( name_, vcd_name_ ),
+ object( object_ ),
+ old_value( object_.m_params.type_params(),
+ object_.m_params.enc(),
+ object_.m_params.cast_switch(),
+ 0 )
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_fxnum_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_fxnum_trace::write( FILE* f )
+{
+ static std::vector<char> compdata(1024), rawdata(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( compdata.size() < (size_t)object.wl() ) {
+ size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( compdata ); // resize without copying values
+ std::vector<char>( sz ).swap( rawdata );
+ }
+ char *rawdata_ptr = &rawdata[0];
+
+ for(int bitindex = object.wl() - 1; bitindex >= 0; -- bitindex )
+ {
+ *rawdata_ptr ++ = "01"[object[bitindex]];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line( &rawdata[0], &compdata[0] );
+
+ std::fputs( &compdata[0], f );
+ old_value = object;
+}
+
+void
+vcd_sc_fxnum_trace::set_width()
+{
+ bit_width = object.wl();
+}
+
+/*****************************************************************************/
+
+class vcd_sc_fxnum_fast_trace : public vcd_trace
+{
+public:
+
+ vcd_sc_fxnum_fast_trace( const sc_dt::sc_fxnum_fast& object,
+ const std::string& name_,
+ const std::string& vcd_name_ );
+ void write( FILE* f );
+ bool changed();
+ void set_width();
+
+protected:
+
+ const sc_dt::sc_fxnum_fast& object;
+ sc_dt::sc_fxnum_fast old_value;
+
+};
+
+vcd_sc_fxnum_fast_trace::vcd_sc_fxnum_fast_trace(
+ const sc_dt::sc_fxnum_fast& object_,
+ const std::string& name_,
+ const std::string& vcd_name_ )
+: vcd_trace( name_, vcd_name_ ),
+ object( object_ ),
+ old_value( object_.m_params.type_params(),
+ object_.m_params.enc(),
+ object_.m_params.cast_switch(),
+ 0 )
+{
+ vcd_var_typ_name = "wire";
+ old_value = object;
+}
+
+bool
+vcd_sc_fxnum_fast_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+vcd_sc_fxnum_fast_trace::write( FILE* f )
+{
+ static std::vector<char> compdata(1024), rawdata(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( compdata.size() < (size_t)object.wl() ) {
+ size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( compdata ); // resize without copying values
+ std::vector<char>( sz ).swap( rawdata );
+ }
+ char *rawdata_ptr = &rawdata[0];
+
+ for(int bitindex = object.wl() - 1; bitindex >= 0; -- bitindex )
+ {
+ *rawdata_ptr ++ = "01"[object[bitindex]];
+ }
+ *rawdata_ptr = '\0';
+ compose_data_line( &rawdata[0], &compdata[0] );
+
+ std::fputs( &compdata[0], f );
+ old_value = object;
+}
+
+void
+vcd_sc_fxnum_fast_trace::set_width()
+{
+ bit_width = object.wl();
+}
+
+
+/*****************************************************************************/
+
+class vcd_unsigned_int_trace : public vcd_trace {
+public:
+ vcd_unsigned_int_trace(const unsigned& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned& object;
+ unsigned old_value;
+ unsigned mask;
+};
+
+
+vcd_unsigned_int_trace::vcd_unsigned_int_trace(
+ const unsigned& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value( object_ ),
+ mask((unsigned)-1)
+{
+ bit_width = width_;
+ if (bit_width < 32) mask = ~(-1 << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool
+vcd_unsigned_int_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void
+vcd_unsigned_int_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_unsigned_short_trace : public vcd_trace {
+public:
+ vcd_unsigned_short_trace(const unsigned short& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned short& object;
+ unsigned short old_value;
+ unsigned short mask;
+};
+
+
+vcd_unsigned_short_trace::vcd_unsigned_short_trace(
+ const unsigned short& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_), mask(0xffff)
+{
+ bit_width = width_;
+ if (bit_width < 16) mask = (unsigned short)~(-1 << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool
+vcd_unsigned_short_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void
+vcd_unsigned_short_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_unsigned_char_trace : public vcd_trace {
+public:
+ vcd_unsigned_char_trace(const unsigned char& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned char& object;
+ unsigned char old_value;
+ unsigned char mask;
+};
+
+
+vcd_unsigned_char_trace::vcd_unsigned_char_trace(
+ const unsigned char& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_), mask(0xff)
+{
+ bit_width = width_;
+ if (bit_width < 8) mask = (unsigned char)~(-1 << bit_width);
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_unsigned_char_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_unsigned_char_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_unsigned_long_trace : public vcd_trace {
+public:
+ vcd_unsigned_long_trace(const unsigned long& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned long& object;
+ unsigned long old_value;
+ unsigned long mask;
+};
+
+
+vcd_unsigned_long_trace::vcd_unsigned_long_trace(
+ const unsigned long& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask((unsigned long)-1)
+{
+ bit_width = width_;
+ if ( bit_width < (int)(sizeof(unsigned long)*8) )
+ mask = ~(-1L << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_unsigned_long_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_unsigned_long_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned long bit_mask = 1ul << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_signed_int_trace : public vcd_trace {
+public:
+ vcd_signed_int_trace(const int& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const int& object;
+ int old_value;
+ unsigned mask;
+};
+
+
+vcd_signed_int_trace::vcd_signed_int_trace(const signed& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask((unsigned)-1)
+{
+ bit_width = width_;
+ if (bit_width < 32) mask = ~(-1 << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_signed_int_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_signed_int_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned) object & mask) != (unsigned) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_signed_short_trace : public vcd_trace {
+public:
+ vcd_signed_short_trace(const short& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const short& object;
+ short old_value;
+ unsigned short mask;
+};
+
+
+vcd_signed_short_trace::vcd_signed_short_trace(
+ const short& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_), mask(0xffff)
+{
+ bit_width = width_;
+ if (bit_width < 16) mask = (unsigned short)~(-1 << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_signed_short_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_signed_short_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned short) object & mask) != (unsigned short) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_signed_char_trace : public vcd_trace {
+public:
+ vcd_signed_char_trace(const char& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const char& object;
+ char old_value;
+ unsigned char mask;
+};
+
+
+vcd_signed_char_trace::vcd_signed_char_trace(const char& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_), mask(0xff)
+{
+ bit_width = width_;
+ if (bit_width < 8) mask = (unsigned char)~(-1 << bit_width);
+
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_signed_char_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_signed_char_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned char) object & mask) != (unsigned char) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_int64_trace : public vcd_trace {
+public:
+ vcd_int64_trace(const sc_dt::int64& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::int64& object;
+ sc_dt::int64 old_value;
+ sc_dt::uint64 mask;
+};
+
+
+vcd_int64_trace::vcd_int64_trace(const sc_dt::int64& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask((sc_dt::uint64)-1)
+{
+ bit_width = width_;
+ if (bit_width < 64) mask = ~(mask << bit_width);
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_int64_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_int64_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((sc_dt::uint64) object & mask) != (sc_dt::uint64) object)
+ {
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else
+ {
+ sc_dt::uint64 bit_mask = 1;
+ bit_mask = bit_mask << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class vcd_uint64_trace : public vcd_trace {
+public:
+ vcd_uint64_trace(const sc_dt::uint64& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::uint64& object;
+ sc_dt::uint64 old_value;
+ sc_dt::uint64 mask;
+};
+
+
+vcd_uint64_trace::vcd_uint64_trace( const sc_dt::uint64& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask((sc_dt::uint64)-1)
+{
+ bit_width = width_;
+ if ( bit_width < 64 ) mask = ~(mask << bit_width);
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_uint64_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_uint64_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object)
+ {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else
+ {
+ sc_dt::uint64 bit_mask = 1;
+ bit_mask = bit_mask << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class vcd_signed_long_trace : public vcd_trace {
+public:
+ vcd_signed_long_trace(const long& object,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const long& object;
+ long old_value;
+ unsigned long mask;
+};
+
+
+vcd_signed_long_trace::vcd_signed_long_trace(const long& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ int width_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask((unsigned long)-1)
+{
+ bit_width = width_;
+ if ( bit_width < (int)(sizeof(long)*8) )
+ mask = ~(-1L << bit_width);
+ vcd_var_typ_name = "wire";
+}
+
+
+bool vcd_signed_long_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void vcd_signed_long_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned long) object & mask) != (unsigned long) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ }
+ else{
+ unsigned long bit_mask = 1ul << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class vcd_float_trace : public vcd_trace {
+public:
+ vcd_float_trace(const float& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const float& object;
+ float old_value;
+};
+
+vcd_float_trace::vcd_float_trace(const float& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_)
+{
+ vcd_var_typ_name = "real";
+ bit_width = 1;
+ old_value = object;
+}
+
+bool vcd_float_trace::changed()
+{
+ return object != old_value;
+}
+
+void vcd_float_trace::write(FILE* f)
+{
+ std::fprintf(f, "r%.16g %s", object, vcd_name.c_str());
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class vcd_double_trace : public vcd_trace {
+public:
+ vcd_double_trace(const double& object,
+ const std::string& name_,
+ const std::string& vcd_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const double& object;
+ double old_value;
+};
+
+vcd_double_trace::vcd_double_trace(const double& object_,
+ const std::string& name_,
+ const std::string& vcd_name_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_)
+{
+ vcd_var_typ_name = "real";
+ bit_width = 1;
+}
+
+bool vcd_double_trace::changed()
+{
+ return object != old_value;
+}
+
+void vcd_double_trace::write(FILE* f)
+{
+ std::fprintf(f, "r%.16g %s", object, vcd_name.c_str());
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class vcd_enum_trace : public vcd_trace {
+public:
+ vcd_enum_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ const char** enum_literals);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned& object;
+ unsigned old_value;
+ unsigned mask;
+ const char** literals;
+ unsigned nliterals;
+};
+
+
+vcd_enum_trace::vcd_enum_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& vcd_name_,
+ const char** enum_literals_)
+: vcd_trace(name_, vcd_name_), object(object_), old_value(object_),
+ mask(0xffffffff), literals(enum_literals_), nliterals(0)
+{
+ // find number of bits required to represent enumeration literal - counting loop
+ for (nliterals = 0; enum_literals_[nliterals]; nliterals++) continue;
+
+ // Figure out number of bits required to represent the number of literals
+ bit_width = 0;
+ unsigned shifted_maxindex = nliterals-1;
+ while(shifted_maxindex != 0){
+ shifted_maxindex >>= 1;
+ bit_width++;
+ }
+
+ // Set the mask
+ if (bit_width < 32) {
+ mask = ~(-1 << bit_width);
+ } else {
+ mask = 0xffffffff;
+ }
+
+ vcd_var_typ_name = "wire";
+}
+
+bool vcd_enum_trace::changed()
+{
+ return object != old_value;
+}
+
+void vcd_enum_trace::write(FILE* f)
+{
+ char rawdata[1000];
+ char compdata[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ rawdata[bitindex] = 'x';
+ }
+ } else {
+ unsigned long bit_mask = 1ul << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ rawdata[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ rawdata[bitindex] = '\0';
+ compose_data_line(rawdata, compdata);
+ std::fputs(compdata, f);
+ old_value = object;
+}
+
+
+/*****************************************************************************
+ vcd_trace_file functions
+ *****************************************************************************/
+
+vcd_trace_file::vcd_trace_file(const char *name)
+ : sc_trace_file_base( name, "vcd" )
+ , vcd_name_index(0)
+ , previous_time_units_low(0)
+ , previous_time_units_high(0)
+ , traces()
+{}
+
+
+void
+vcd_trace_file::do_initialize()
+{
+ char buf[2000];
+
+ //date:
+ std::fprintf(fp, "$date\n %s\n$end\n\n", localtime_string().c_str() );
+
+ //version:
+ std::fprintf(fp, "$version\n %s\n$end\n\n", sc_version());
+
+ //timescale:
+ static struct SC_TIMESCALE_TO_TEXT {
+ double unit;
+ const char* text;
+ } timescale_to_text [] = {
+ { sc_time(1, SC_FS).to_seconds(), "1 fs" },
+ { sc_time(10, SC_FS).to_seconds(), "10 fs" },
+ { sc_time(100, SC_FS).to_seconds(),"100 fs" },
+ { sc_time(1, SC_PS).to_seconds(), "1 ps" },
+ { sc_time(10, SC_PS).to_seconds(), "10 ps" },
+ { sc_time(100, SC_PS).to_seconds(),"100 ps" },
+ { sc_time(1, SC_NS).to_seconds(), "1 ns" },
+ { sc_time(10, SC_NS).to_seconds(), "10 ns" },
+ { sc_time(100, SC_NS).to_seconds(),"100 ns" },
+ { sc_time(1, SC_US).to_seconds(), "1 us" },
+ { sc_time(10, SC_US).to_seconds(), "10 us" },
+ { sc_time(100, SC_US).to_seconds(),"100 us" },
+ { sc_time(1, SC_MS).to_seconds(), "1 ms" },
+ { sc_time(10, SC_MS).to_seconds(), "10 ms" },
+ { sc_time(100, SC_MS).to_seconds(),"100 ms" },
+ { sc_time(1, SC_SEC).to_seconds(), "1 sec" },
+ { sc_time(10, SC_SEC).to_seconds(), "10 sec" },
+ { sc_time(100, SC_SEC).to_seconds(),"100 sec" }
+ };
+ static int timescale_to_text_n =
+ sizeof(timescale_to_text)/sizeof(SC_TIMESCALE_TO_TEXT);
+
+ for ( int time_i = 0; time_i < timescale_to_text_n; time_i++ )
+ {
+ if (timescale_unit == timescale_to_text[time_i].unit)
+ {
+ std::fprintf(fp,"$timescale\n %s\n$end\n\n",
+ timescale_to_text[time_i].text);
+ break;
+ }
+ }
+
+ // Create a dummy scope
+ std::fputs("$scope module SystemC $end\n", fp);
+
+ //variable definitions:
+ for (int i = 0; i < (int)traces.size(); i++) {
+ vcd_trace* t = traces[i];
+ t->set_width(); // needed for all vectors
+ t->print_variable_declaration_line(fp);
+ }
+
+ std::fputs("$upscope $end\n", fp);
+
+ std::fputs("$enddefinitions $end\n\n", fp);
+
+ // double inittime = sc_simulation_time();
+ double inittime = sc_time_stamp().to_seconds();
+
+ std::sprintf(buf,
+ "All initial values are dumped below at time "
+ "%g sec = %g timescale units.",
+ inittime, inittime/timescale_unit
+ );
+ write_comment(buf);
+
+ double_to_special_int64(inittime/timescale_unit,
+ &previous_time_units_high,
+ &previous_time_units_low );
+
+
+ std::fputs("$dumpvars\n",fp);
+ for (int i = 0; i < (int)traces.size(); i++) {
+ traces[i]->write(fp);
+ std::fputc('\n', fp);
+ }
+ std::fputs("$end\n\n", fp);
+}
+
+
+// ----------------------------------------------------------------------------
+
+#define DEFN_TRACE_METHOD(tp) \
+void \
+vcd_trace_file::trace(const tp& object_, const std::string& name_) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new vcd_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name() ) ); \
+}
+
+DEFN_TRACE_METHOD(bool)
+DEFN_TRACE_METHOD(float)
+DEFN_TRACE_METHOD(double)
+
+#undef DEFN_TRACE_METHOD
+#define DEFN_TRACE_METHOD(tp) \
+void \
+vcd_trace_file::trace(const sc_dt::tp& object_, const std::string& name_) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new vcd_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name() ) ); \
+}
+
+DEFN_TRACE_METHOD(sc_bit)
+DEFN_TRACE_METHOD(sc_logic)
+
+DEFN_TRACE_METHOD(sc_signed)
+DEFN_TRACE_METHOD(sc_unsigned)
+DEFN_TRACE_METHOD(sc_int_base)
+DEFN_TRACE_METHOD(sc_uint_base)
+
+DEFN_TRACE_METHOD(sc_fxval)
+DEFN_TRACE_METHOD(sc_fxval_fast)
+DEFN_TRACE_METHOD(sc_fxnum)
+DEFN_TRACE_METHOD(sc_fxnum_fast)
+
+#undef DEFN_TRACE_METHOD
+
+
+#define DEFN_TRACE_METHOD_SIGNED(tp) \
+void \
+vcd_trace_file::trace( const tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new vcd_signed_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+#define DEFN_TRACE_METHOD_UNSIGNED(tp) \
+void \
+vcd_trace_file::trace( const unsigned tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new vcd_unsigned_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+DEFN_TRACE_METHOD_SIGNED(char)
+DEFN_TRACE_METHOD_SIGNED(short)
+DEFN_TRACE_METHOD_SIGNED(int)
+DEFN_TRACE_METHOD_SIGNED(long)
+
+DEFN_TRACE_METHOD_UNSIGNED(char)
+DEFN_TRACE_METHOD_UNSIGNED(short)
+DEFN_TRACE_METHOD_UNSIGNED(int)
+DEFN_TRACE_METHOD_UNSIGNED(long)
+
+#undef DEFN_TRACE_METHOD_SIGNED
+#undef DEFN_TRACE_METHOD_UNSIGNED
+
+#define DEFN_TRACE_METHOD_LONG_LONG(tp) \
+void \
+vcd_trace_file::trace( const sc_dt::tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new vcd_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+DEFN_TRACE_METHOD_LONG_LONG(int64)
+DEFN_TRACE_METHOD_LONG_LONG(uint64)
+
+#undef DEFN_TRACE_METHOD_LONG_LONG
+
+void
+vcd_trace_file::trace( const unsigned& object_,
+ const std::string& name_,
+ const char** enum_literals_ )
+{
+ if( add_trace_check(name_) )
+ traces.push_back( new vcd_enum_trace( object_,
+ name_,
+ obtain_name(),
+ enum_literals_ ) );
+}
+
+
+void
+vcd_trace_file::write_comment(const std::string& comment)
+{
+ if(!fp) open_fp();
+ //no newline in comments allowed, as some viewers may crash
+ std::fputs("$comment\n", fp);
+ std::fputs(comment.c_str(), fp);
+ std::fputs("\n$end\n\n", fp);
+}
+
+void
+vcd_trace_file::cycle(bool this_is_a_delta_cycle)
+{
+ unsigned this_time_units_high, this_time_units_low;
+
+ // Just to make g++ shut up in the optimized mode
+ this_time_units_high = this_time_units_low = 0;
+
+ // Trace delta cycles only when enabled
+ if (!delta_cycles() && this_is_a_delta_cycle) return;
+
+ // Check for initialization
+ if( initialize() ) {
+ return;
+ };
+
+
+ double now_units = sc_time_stamp().to_seconds() / timescale_unit;
+ unsigned now_units_high, now_units_low;
+ double_to_special_int64(now_units, &now_units_high, &now_units_low );
+
+ bool now_later_than_previous_time = false;
+ if( (now_units_low > previous_time_units_low
+ && now_units_high == previous_time_units_high)
+ || now_units_high > previous_time_units_high){
+ now_later_than_previous_time = true;
+ }
+
+ bool now_equals_previous_time = false;
+ if(now_later_than_previous_time){
+ this_time_units_high = now_units_high;
+ this_time_units_low = now_units_low;
+ } else {
+ if( now_units_low == previous_time_units_low
+ && now_units_high == previous_time_units_high){
+ now_equals_previous_time = true;
+ this_time_units_high = now_units_high;
+ this_time_units_low = now_units_low;
+ }
+ }
+
+ // Since VCD does not understand 0 time progression, we have to fake
+ // delta cycles with progressing time by one unit
+ if(this_is_a_delta_cycle){
+ this_time_units_high = previous_time_units_high;
+ this_time_units_low = previous_time_units_low + 1;
+ if(this_time_units_low == 1000000000){
+ this_time_units_high++;
+ this_time_units_low=0;
+ }
+ static bool warned = false;
+ if(!warned){
+ SC_REPORT_INFO( SC_ID_TRACING_VCD_DELTA_CYCLE_
+ , sc_time( timescale_unit, SC_SEC )
+ .to_string().c_str() );
+ warned = true;
+ }
+ }
+
+
+ // Not a delta cycle and time has not progressed
+ if( ! this_is_a_delta_cycle && now_equals_previous_time &&
+ ( now_units_high != 0 || now_units_low != 0 ) ) {
+ // Don't print the message at time zero
+ static bool warned = false;
+ if( ! warned ) {
+ std::stringstream ss;
+ ss << "units count: " << now_units_low << "\n"
+ "\tWaveform viewers will only show the states of the last one.\n"
+ "\tUse `tracefile->set_time_unit(double, sc_time_unit);'"
+ " to increase the time resolution.";
+ SC_REPORT_WARNING( SC_ID_TRACING_VCD_DUPLICATE_TIME_
+ , ss.str().c_str() );
+ // warned = true;
+ }
+ }
+
+ // Not a delta cycle and time has gone backward
+ // This will happen with large number of delta cycles between two real
+ // advances of time
+ if(!this_is_a_delta_cycle && !now_equals_previous_time &&
+ !now_later_than_previous_time){
+ static bool warned = false;
+ if(!warned) {
+ std::stringstream ss;
+ ss << "units count ("
+ << previous_time_units_low << "->" << now_units_low << ")\n"
+ "\tThis can occur when delta cycling is activated."
+ " Cycles with falling time are not shown.\n"
+ "\tUse `tracefile->set_time_unit(double, sc_time_unit);'"
+ " to increase the time resolution.";
+ SC_REPORT_WARNING( SC_ID_TRACING_VCD_DUPLICATE_TIME_
+ , ss.str().c_str() );
+ // warned = true;
+ }
+ // Note that we don't set this_time_units_high/low to any value only
+ // in this case because we are not going to do any tracing. In the
+ // optimized mode, the compiler complains because of this. Therefore,
+ // we include the lines at the very beginning of this function to make
+ // the compiler shut up.
+ return;
+ }
+
+ // Now do the actual printing
+ bool time_printed = false;
+ vcd_trace* const* const l_traces = &traces[0];
+ for (int i = 0; i < (int)traces.size(); i++) {
+ vcd_trace* t = l_traces[i];
+ if(t->changed()){
+ if(time_printed == false){
+ char buf[200];
+ if(this_time_units_high){
+ std::sprintf(buf, "#%u%09u", this_time_units_high, this_time_units_low);
+ }
+ else{
+ std::sprintf(buf, "#%u", this_time_units_low);
+ }
+ std::fputs(buf, fp);
+ std::fputc('\n', fp);
+ time_printed = true;
+ }
+
+ // Write the variable
+ t->write(fp);
+ std::fputc('\n', fp);
+ }
+ }
+ // Put another newline after all values are printed
+ if(time_printed) std::fputc('\n', fp);
+
+ if(time_printed){
+ // We update previous_time_units only when we print time because
+ // this field stores the previous time that was printed, not the
+ // previous time this function was called
+ previous_time_units_high = this_time_units_high;
+ previous_time_units_low = this_time_units_low;
+ }
+}
+
+#if 0
+void
+vcd_trace_file::create_vcd_name(std::string* p_destination)
+{
+ obtain_name.swap( *p_destination );
+}
+#endif
+
+// Create a VCD name for a variable
+std::string
+vcd_trace_file::obtain_name()
+{
+ const char first_type_used = 'a';
+ const int used_types_count = 'z' - 'a' + 1;
+ int result;
+
+ result = vcd_name_index;
+ char char6 = (char)(vcd_name_index % used_types_count);
+
+ result = result / used_types_count;
+ char char5 = (char)(result % used_types_count);
+
+ result = result / used_types_count;
+ char char4 = (char)(result % used_types_count);
+
+ result = result / used_types_count;
+ char char3 = (char)(result % used_types_count);
+
+ result = result / used_types_count;
+ char char2 = (char)(result % used_types_count);
+
+ char buf[20];
+ std::sprintf(buf, "%c%c%c%c%c",
+ char2 + first_type_used,
+ char3 + first_type_used,
+ char4 + first_type_used,
+ char5 + first_type_used,
+ char6 + first_type_used);
+ vcd_name_index++;
+ return std::string(buf);
+}
+
+vcd_trace_file::~vcd_trace_file()
+{
+ for( int i = 0; i < (int)traces.size(); i++ ) {
+ vcd_trace* t = traces[i];
+ delete t;
+ }
+}
+
+
+// Functions specific to VCD tracing
+
+static char
+map_sc_logic_state_to_vcd_state(char in_char)
+{
+ char out_char;
+
+ switch(in_char){
+ case 'U':
+ case 'X':
+ case 'W':
+ case 'D':
+ out_char = 'x';
+ break;
+ case '0':
+ case 'L':
+ out_char = '0';
+ break;
+ case '1':
+ case 'H':
+ out_char = '1';
+ break;
+ case 'Z':
+ out_char = 'z';
+ break;
+ default:
+ out_char = '?';
+ }
+
+ return out_char;
+}
+
+
+
+
+static
+void
+remove_vcd_name_problems(vcd_trace const* vcd, std::string& name)
+{
+ static bool warned = false;
+ bool braces_removed = false;
+ for (unsigned int i = 0; i< name.length(); i++) {
+ if (name[i] == '[') {
+ name[i] = '(';
+ braces_removed = true;
+ }
+ else if (name[i] == ']') {
+ name[i] = ')';
+ braces_removed = true;
+ }
+ }
+
+ if(braces_removed && !warned){
+ std::stringstream ss;
+ ss << vcd->name << ":\n"
+ "\tTraced objects found with name containing [], which may be\n"
+ "\tinterpreted by the waveform viewer in unexpected ways.\n"
+ "\tSo the [] is automatically replaced by ().";
+
+ SC_REPORT_WARNING( SC_ID_TRACING_OBJECT_NAME_FILTERED_
+ , ss.str().c_str() );
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+sc_trace_file*
+sc_create_vcd_trace_file(const char * name)
+{
+ sc_trace_file * tf = new vcd_trace_file(name);
+ return tf;
+}
+
+void
+sc_close_vcd_trace_file( sc_trace_file* tf )
+{
+ vcd_trace_file* vcd_tf = static_cast<vcd_trace_file*>(tf);
+ delete vcd_tf;
+}
+
+} // namespace sc_core
diff --git a/ext/systemc/src/sysc/tracing/sc_vcd_trace.h b/ext/systemc/src/sysc/tracing/sc_vcd_trace.h
new file mode 100644
index 000000000..760949ffb
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_vcd_trace.h
@@ -0,0 +1,228 @@
+/*****************************************************************************
+
+ 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_vcd_trace.h - Implementation of VCD tracing.
+
+ Original 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, and significantly enhanced, 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_VCD_TRACE_H
+#define SC_VCD_TRACE_H
+
+#include "sysc/tracing/sc_trace_file_base.h"
+
+namespace sc_core {
+
+class vcd_trace; // defined in vcd_trace.cpp
+template<class T> class vcd_T_trace;
+
+
+// ----------------------------------------------------------------------------
+// CLASS : vcd_trace_file
+//
+// ...
+// ----------------------------------------------------------------------------
+
+class vcd_trace_file
+ : public sc_trace_file_base
+{
+public:
+
+ enum vcd_enum {VCD_WIRE=0, VCD_REAL=1, VCD_LAST};
+
+ // sc_set_vcd_time_unit is deprecated.
+#if 0 // deprecated
+ inline void sc_set_vcd_time_unit(int exponent10_seconds)
+ { set_time_unit(exponent10_seconds); }
+#endif
+
+ // Create a Vcd trace file.
+ // `Name' forms the base of the name to which `.vcd' is added.
+ vcd_trace_file(const char *name);
+
+ // Flush results and close file.
+ ~vcd_trace_file();
+
+protected:
+
+ // These are all virtual functions in sc_trace_file and
+ // they need to be defined here.
+
+ // Trace a boolean object (single bit)
+ void trace(const bool& object, const std::string& name);
+
+ // Trace a sc_bit object (single bit)
+ virtual void trace( const sc_dt::sc_bit& object,
+ const std::string& name);
+
+ // Trace a sc_logic object (single bit)
+ void trace(const sc_dt::sc_logic& object, const std::string& name);
+
+ // Trace an unsigned char with the given width
+ void trace(const unsigned char& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned short with the given width
+ void trace(const unsigned short& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned int with the given width
+ void trace(const unsigned int& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned long with the given width
+ void trace(const unsigned long& object, const std::string& name,
+ int width);
+
+ // Trace a signed char with the given width
+ void trace(const char& object, const std::string& name, int width);
+
+ // Trace a signed short with the given width
+ void trace(const short& object, const std::string& name, int width);
+
+ // Trace a signed int with the given width
+ void trace(const int& object, const std::string& name, int width);
+
+ // Trace a signed long with the given width
+ void trace(const long& object, const std::string& name, int width);
+
+ // Trace an int64 with a given width
+ void trace(const sc_dt::int64& object, const std::string& name,
+ int width);
+
+ // Trace a uint64 with a given width
+ void trace(const sc_dt::uint64& object, const std::string& name,
+ int width);
+
+ // Trace a float
+ void trace(const float& object, const std::string& name);
+
+ // Trace a double
+ void trace(const double& object, const std::string& name);
+
+ // Trace sc_dt::sc_uint_base
+ void trace (const sc_dt::sc_uint_base& object,
+ const std::string& name);
+
+ // Trace sc_dt::sc_int_base
+ void trace (const sc_dt::sc_int_base& object,
+ const std::string& name);
+
+ // Trace sc_dt::sc_unsigned
+ void trace (const sc_dt::sc_unsigned& object,
+ const std::string& name);
+
+ // Trace sc_dt::sc_signed
+ void trace (const sc_dt::sc_signed& object, const std::string& name);
+
+ // Trace sc_dt::sc_fxval
+ void trace( const sc_dt::sc_fxval& object, const std::string& name );
+
+ // Trace sc_dt::sc_fxval_fast
+ void trace( const sc_dt::sc_fxval_fast& object,
+ const std::string& name );
+
+ // Trace sc_dt::sc_fxnum
+ void trace( const sc_dt::sc_fxnum& object, const std::string& name );
+
+ // Trace sc_dt::sc_fxnum_fast
+ void trace( const sc_dt::sc_fxnum_fast& object,
+ const std::string& name );
+
+ template<class T>
+ void traceT(const T& object, const std::string& name,
+ vcd_enum type=VCD_WIRE)
+ {
+ if( add_trace_check(name) )
+ traces.push_back(new vcd_T_trace<T>( object, name
+ , obtain_name(),type) );
+ }
+
+ // Trace sc_dt::sc_bv_base (sc_dt::sc_bv)
+ virtual void trace(const sc_dt::sc_bv_base& object,
+ const std::string& name);
+
+ // Trace sc_dt::sc_lv_base (sc_dt::sc_lv)
+ virtual void trace(const sc_dt::sc_lv_base& object,
+ const std::string& name);
+ // 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 trace(const unsigned& object, const std::string& name,
+ const char** enum_literals);
+
+ // Output a comment to the trace file
+ void write_comment(const std::string& comment);
+
+ // Write trace info for cycle.
+ void cycle(bool delta_cycle);
+
+private:
+
+#if SC_TRACING_PHASE_CALLBACKS_
+ // avoid hidden overload warnings
+ virtual void trace( sc_trace_file* ) const { sc_assert(false); }
+#endif // SC_TRACING_PHASE_CALLBACKS_
+
+ // Initialize the VCD tracing
+ virtual void do_initialize();
+
+ unsigned vcd_name_index; // Number of variables traced
+
+ unsigned previous_time_units_low; // Previous time unit as 64-bit integer
+ unsigned previous_time_units_high;
+
+public:
+
+ // Array to store the variables traced
+ std::vector<vcd_trace*> traces;
+
+ // Create VCD names for each variable
+ std::string obtain_name();
+
+};
+
+} // namespace sc_core
+
+#endif // SC_VCD_TRACE_H
+// Taf!
diff --git a/ext/systemc/src/sysc/tracing/sc_wif_trace.cpp b/ext/systemc/src/sysc/tracing/sc_wif_trace.cpp
new file mode 100644
index 000000000..b2bacee7d
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_wif_trace.cpp
@@ -0,0 +1,1911 @@
+/*****************************************************************************
+
+ 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_wif_trace.cpp - Implementation of WIF tracing.
+
+ Original Author - Abhijit Ghosh, Synopsys, Inc.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ MODIFICATION LOG - modifiers, enter your name, affliation, date and
+ changes you are making here.
+
+ Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
+ Description of Modification: - Replaced 'width' of sc_(u)int with their
+ 'bitwidth()'.
+
+ 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, and significantly enhanced, 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.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Instead of creating the binary WIF format, we create the ASCII
+ WIF format which can be converted to the binary format using
+ a2wif (utility that comes with VSS from Synopsys). This way,
+ a user who does not have Synopsys VSS can still create WIF
+ files, but they can only be viewed by users who have VSS.
+
+ *****************************************************************************/
+
+
+#include <cstdlib>
+#include <vector>
+
+#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion
+
+#include "sysc/kernel/sc_simcontext.h"
+#include "sysc/kernel/sc_ver.h"
+#include "sysc/datatypes/bit/sc_bit.h"
+#include "sysc/datatypes/bit/sc_logic.h"
+#include "sysc/datatypes/bit/sc_lv_base.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/fx/fx.h"
+#include "sysc/tracing/sc_wif_trace.h"
+
+namespace sc_core {
+
+// Forward declarations for functions that come later in the file
+static char map_sc_logic_state_to_wif_state(char in_char);
+
+const char* wif_names[wif_trace_file::WIF_LAST] = {"BIT","MVL","real"};
+
+
+// ----------------------------------------------------------------------------
+// CLASS : wif_trace
+//
+// Base class for WIF traces.
+// ----------------------------------------------------------------------------
+
+class wif_trace
+{
+public:
+
+ wif_trace(const std::string& name_, const std::string& wif_name_);
+
+ // Needs to be pure virtual as has to be defined by the particular
+ // type being traced
+ virtual void write(FILE* f) = 0;
+
+ virtual void set_width();
+
+ // Comparison function needs to be pure virtual too
+ virtual bool changed() = 0;
+
+ // Got to declare this virtual as this will be overwritten
+ // by one base class
+ virtual void print_variable_declaration_line(FILE* f);
+
+ virtual ~wif_trace();
+
+ const std::string name; // Name of the variable
+ const std::string wif_name; // Name of the variable in WIF file
+ const char* wif_type; // WIF data type
+ int bit_width;
+};
+
+
+wif_trace::wif_trace(const std::string& name_,
+ const std::string& wif_name_)
+ : name(name_), wif_name(wif_name_), wif_type(0), bit_width(-1)
+{
+ /* Intentionally blank */
+}
+
+void
+wif_trace::print_variable_declaration_line( FILE* f )
+{
+ if( bit_width < 0 )
+ {
+ std::stringstream ss;
+ ss << "'" << name << "' has < 0 bits";
+ SC_REPORT_ERROR( SC_ID_TRACING_OBJECT_IGNORED_
+ , ss.str().c_str() );
+ return;
+ }
+
+ std::fprintf( f, "declare %s \"%s\" %s ",
+ wif_name.c_str(), name.c_str(), wif_type );
+
+ if( bit_width > 0 ) {
+ std::fprintf( f, "0 %d ", bit_width - 1 );
+ }
+ std::fprintf( f, "variable ;\n" );
+ std::fprintf( f, "start_trace %s ;\n", wif_name.c_str() );
+}
+
+void
+wif_trace::set_width()
+{
+ /* Intentionally Blank, should be defined for each type separately */
+}
+
+wif_trace::~wif_trace()
+{
+ /* Intentionally Blank */
+}
+
+// Classes for tracing individual data types
+
+/*****************************************************************************/
+
+class wif_uint64_trace: public wif_trace {
+public:
+ wif_uint64_trace(const sc_dt::uint64& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::uint64& object;
+ sc_dt::uint64 old_value;
+ sc_dt::uint64 mask;
+};
+
+
+wif_uint64_trace::wif_uint64_trace(const sc_dt::uint64& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask(static_cast<sc_dt::uint64>(-1))
+{
+ bit_width = width_;
+ if (bit_width < (int)(sizeof(sc_dt::uint64)*BITS_PER_BYTE))
+ mask = ~(mask << bit_width);
+ wif_type = "BIT";
+}
+
+
+bool wif_uint64_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_uint64_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object)
+ {
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ buf[bitindex]='0';
+ }
+ }
+ else
+ {
+ sc_dt::uint64 bit_mask = 1;
+ bit_mask = bit_mask << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_int64_trace: public wif_trace {
+public:
+ wif_int64_trace(const sc_dt::int64& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::int64& object;
+ sc_dt::int64 old_value;
+ sc_dt::uint64 mask;
+};
+
+
+wif_int64_trace::wif_int64_trace(const sc_dt::int64& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask(static_cast<sc_dt::uint64>(-1))
+{
+ bit_width = width_;
+ if (bit_width < (int)(sizeof(sc_dt::int64)*BITS_PER_BYTE))
+ mask = ~(mask << bit_width);
+ wif_type = "BIT";
+}
+
+
+bool wif_int64_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_int64_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != (sc_dt::uint64)object)
+ {
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ buf[bitindex]='0';
+ }
+ }
+ else
+ {
+ sc_dt::uint64 bit_mask = 1;
+ bit_mask = bit_mask << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++)
+ {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_bool_trace
+: public wif_trace
+{
+public:
+
+ wif_bool_trace( const bool& object_,
+ const std::string& name_,
+ const std::string& wif_name_ );
+ void write( FILE* f );
+ bool changed();
+
+protected:
+
+ const bool& object;
+ bool old_value;
+};
+
+wif_bool_trace::wif_bool_trace( const bool& object_,
+ const std::string& name_,
+ const std::string& wif_name_ )
+: wif_trace( name_, wif_name_ ), object( object_ ), old_value( object_ )
+{
+ bit_width = 0;
+ wif_type = "BIT";
+}
+
+bool
+wif_bool_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+wif_bool_trace::write( FILE* f )
+{
+ if( object == true ) {
+ std::fprintf( f, "assign %s \'1\' ;\n", wif_name.c_str() );
+ } else {
+ std::fprintf( f, "assign %s \'0\' ;\n", wif_name.c_str() );
+ }
+ old_value = object;
+}
+
+//*****************************************************************************
+
+class wif_sc_bit_trace : public wif_trace {
+public:
+ wif_sc_bit_trace(const sc_dt::sc_bit& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::sc_bit& object;
+ sc_dt::sc_bit old_value;
+};
+
+wif_sc_bit_trace::wif_sc_bit_trace(const sc_dt::sc_bit& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_)
+{
+ bit_width = 0;
+ wif_type = "BIT";
+}
+
+bool wif_sc_bit_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_sc_bit_trace::write(FILE* f)
+{
+ if (object == true) {
+ std::fprintf(f, "assign %s \'1\' ;\n", wif_name.c_str());
+ } else {
+ std::fprintf(f, "assign %s \'0\' ;\n", wif_name.c_str());
+ }
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_sc_logic_trace: public wif_trace {
+public:
+ wif_sc_logic_trace(const sc_dt::sc_logic& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const sc_dt::sc_logic& object;
+ sc_dt::sc_logic old_value;
+};
+
+
+wif_sc_logic_trace::wif_sc_logic_trace(const sc_dt::sc_logic& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_)
+{
+ bit_width = 0;
+ wif_type = "MVL";
+}
+
+
+bool wif_sc_logic_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_sc_logic_trace::write(FILE* f)
+{
+ char wif_char;
+ std::fprintf(f, "assign %s \'", wif_name.c_str());
+ wif_char = map_sc_logic_state_to_wif_state(object.to_char());
+ std::fputc(wif_char, f);
+ std::fprintf(f,"\' ;\n");
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class wif_sc_unsigned_trace: public wif_trace {
+public:
+ wif_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_unsigned& object;
+ sc_dt::sc_unsigned old_value;
+};
+
+
+wif_sc_unsigned_trace::wif_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool wif_sc_unsigned_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_sc_unsigned_trace::write(FILE* f)
+{
+ static std::vector<char> buf(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( buf.size() < (size_t)object.length() ) {
+ size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( buf ); // resize without copying values
+ }
+ char *buf_ptr = &buf[0];
+
+ for(int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *buf_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *buf_ptr = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
+ old_value = object;
+}
+
+void wif_sc_unsigned_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class wif_sc_signed_trace: public wif_trace {
+public:
+ wif_sc_signed_trace(const sc_dt::sc_signed& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_signed& object;
+ sc_dt::sc_signed old_value;
+};
+
+
+wif_sc_signed_trace::wif_sc_signed_trace(const sc_dt::sc_signed& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool wif_sc_signed_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_sc_signed_trace::write(FILE* f)
+{
+ static std::vector<char> buf(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( buf.size() < (size_t)object.length() ) {
+ size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( buf ); // resize without copying values
+ }
+ char *buf_ptr = &buf[0];
+
+ for(int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *buf_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *buf_ptr = '\0';
+
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
+ old_value = object;
+}
+
+void wif_sc_signed_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+/*****************************************************************************/
+
+class wif_sc_uint_base_trace: public wif_trace {
+public:
+ wif_sc_uint_base_trace(const sc_dt::sc_uint_base& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_uint_base& object;
+ sc_dt::sc_uint_base old_value;
+};
+
+
+wif_sc_uint_base_trace::wif_sc_uint_base_trace(
+ const sc_dt::sc_uint_base& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool wif_sc_uint_base_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_sc_uint_base_trace::write(FILE* f)
+{
+ char buf[1000], *buf_ptr = buf;
+
+ int bitindex;
+ for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *buf_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *buf_ptr = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+void wif_sc_uint_base_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class wif_sc_int_base_trace: public wif_trace {
+public:
+ wif_sc_int_base_trace(const sc_dt::sc_int_base& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+ void set_width();
+
+protected:
+ const sc_dt::sc_int_base& object;
+ sc_dt::sc_int_base old_value;
+};
+
+
+wif_sc_int_base_trace::wif_sc_int_base_trace(const sc_dt::sc_int_base& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool wif_sc_int_base_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_sc_int_base_trace::write(FILE* f)
+{
+ char buf[1000], *buf_ptr = buf;
+
+ int bitindex;
+ for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
+ *buf_ptr++ = "01"[object[bitindex].to_bool()];
+ }
+ *buf_ptr = '\0';
+
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+void wif_sc_int_base_trace::set_width()
+{
+ bit_width = object.length();
+}
+
+
+/*****************************************************************************/
+
+class wif_sc_fxval_trace: public wif_trace
+{
+public:
+
+ wif_sc_fxval_trace( const sc_dt::sc_fxval& object_,
+ const std::string& name_,
+ const std::string& wif_name_ );
+ void write( FILE* f );
+ bool changed();
+
+protected:
+
+ const sc_dt::sc_fxval& object;
+ sc_dt::sc_fxval old_value;
+
+};
+
+wif_sc_fxval_trace::wif_sc_fxval_trace( const sc_dt::sc_fxval& object_,
+ const std::string& name_,
+ const std::string& wif_name_ )
+: wif_trace( name_, wif_name_ ), object( object_ ), old_value( object_ )
+{
+ bit_width = 0;
+ wif_type = "real";
+}
+
+bool
+wif_sc_fxval_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+wif_sc_fxval_trace::write( FILE* f )
+{
+ std::fprintf( f, "assign %s %f ; \n", wif_name.c_str(), object.to_double() );
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_sc_fxval_fast_trace: public wif_trace
+{
+public:
+
+ wif_sc_fxval_fast_trace( const sc_dt::sc_fxval_fast& object_,
+ const std::string& name_,
+ const std::string& wif_name_ );
+ void write( FILE* f );
+ bool changed();
+
+protected:
+
+ const sc_dt::sc_fxval_fast& object;
+ sc_dt::sc_fxval_fast old_value;
+
+};
+
+wif_sc_fxval_fast_trace::wif_sc_fxval_fast_trace(
+ const sc_dt::sc_fxval_fast& object_,
+ const std::string& name_,
+ const std::string& wif_name_ )
+: wif_trace(name_, wif_name_), object( object_ ), old_value( object_ )
+{
+ bit_width = 0;
+ wif_type = "real";
+}
+
+bool
+wif_sc_fxval_fast_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+wif_sc_fxval_fast_trace::write( FILE* f )
+{
+ std::fprintf( f, "assign %s %f ; \n", wif_name.c_str(), object.to_double() );
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_sc_fxnum_trace: public wif_trace
+{
+public:
+
+ wif_sc_fxnum_trace( const sc_dt::sc_fxnum& object_,
+ const std::string& name_,
+ const std::string& wif_name_ );
+ void write( FILE* f );
+ bool changed();
+ void set_width();
+
+protected:
+
+ const sc_dt::sc_fxnum& object;
+ sc_dt::sc_fxnum old_value;
+
+};
+
+wif_sc_fxnum_trace::wif_sc_fxnum_trace( const sc_dt::sc_fxnum& object_,
+ const std::string& name_,
+ const std::string& wif_name_ )
+: wif_trace( name_, wif_name_ ),
+ object( object_ ),
+ old_value( object_.m_params.type_params(),
+ object_.m_params.enc(),
+ object_.m_params.cast_switch(),
+ 0 )
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool
+wif_sc_fxnum_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+wif_sc_fxnum_trace::write( FILE* f )
+{
+ static std::vector<char> buf(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( buf.size() < (size_t)object.wl() ) {
+ size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( buf ); // resize without copying values
+ }
+ char *buf_ptr = &buf[0];
+
+ for(int bitindex = object.wl() - 1; bitindex >= 0; --bitindex)
+ {
+ *buf_ptr ++ = "01"[object[bitindex]];
+ }
+ *buf_ptr = '\0';
+
+ std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
+ old_value = object;
+}
+
+void
+wif_sc_fxnum_trace::set_width()
+{
+ bit_width = object.wl();
+}
+
+/*****************************************************************************/
+
+class wif_sc_fxnum_fast_trace: public wif_trace
+{
+public:
+
+ wif_sc_fxnum_fast_trace( const sc_dt::sc_fxnum_fast& object_,
+ const std::string& name_,
+ const std::string& wif_name_ );
+ void write( FILE* f );
+ bool changed();
+ void set_width();
+
+protected:
+
+ const sc_dt::sc_fxnum_fast& object;
+ sc_dt::sc_fxnum_fast old_value;
+
+};
+
+wif_sc_fxnum_fast_trace::wif_sc_fxnum_fast_trace(
+ const sc_dt::sc_fxnum_fast& object_,
+ const std::string& name_,
+ const std::string& wif_name_ )
+: wif_trace( name_, wif_name_ ),
+ object( object_ ),
+ old_value( object_.m_params.type_params(),
+ object_.m_params.enc(),
+ object_.m_params.cast_switch(),
+ 0 )
+{
+ old_value = object;
+ wif_type = "BIT";
+}
+
+bool
+wif_sc_fxnum_fast_trace::changed()
+{
+ return object != old_value;
+}
+
+void
+wif_sc_fxnum_fast_trace::write( FILE* f )
+{
+ static std::vector<char> buf(1024);
+ typedef std::vector<char>::size_type size_t;
+
+ if ( buf.size() < (size_t)object.wl() ) {
+ size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1));
+ std::vector<char>( sz ).swap( buf ); // resize without copying values
+ }
+ char *buf_ptr = &buf[0];
+
+ for(int bitindex = object.wl() - 1; bitindex >= 0; --bitindex)
+ {
+ *buf_ptr ++ = "01"[object[bitindex]];
+ }
+ *buf_ptr = '\0';
+
+ std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
+ old_value = object;
+}
+
+void
+wif_sc_fxnum_fast_trace::set_width()
+{
+ bit_width = object.wl();
+}
+
+
+/*****************************************************************************/
+
+class wif_unsigned_int_trace: public wif_trace {
+public:
+ wif_unsigned_int_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_, int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned& object;
+ unsigned old_value;
+ unsigned mask;
+};
+
+
+wif_unsigned_int_trace::wif_unsigned_int_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask(0xffffffff)
+{
+ bit_width = width_;
+ if (bit_width < 32) {
+ mask = ~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_unsigned_int_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_unsigned_int_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex] = '0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class wif_unsigned_short_trace: public wif_trace {
+public:
+ wif_unsigned_short_trace(const unsigned short& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned short& object;
+ unsigned short old_value;
+ unsigned short mask;
+};
+
+
+wif_unsigned_short_trace::wif_unsigned_short_trace(
+ const unsigned short& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xffff)
+{
+ bit_width = width_;
+ if (bit_width < 16) {
+ mask = (unsigned short)~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_unsigned_short_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_unsigned_short_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_unsigned_char_trace: public wif_trace {
+public:
+ wif_unsigned_char_trace(const unsigned char& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned char& object;
+ unsigned char old_value;
+ unsigned char mask;
+};
+
+
+wif_unsigned_char_trace::wif_unsigned_char_trace(const unsigned char& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xff)
+{
+ bit_width = width_;
+ if (bit_width < 8) {
+ mask = (unsigned char)~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_unsigned_char_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_unsigned_char_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_unsigned_long_trace: public wif_trace {
+public:
+ wif_unsigned_long_trace(const unsigned long& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const unsigned long& object;
+ unsigned long old_value;
+ unsigned long mask;
+};
+
+
+wif_unsigned_long_trace::wif_unsigned_long_trace(const unsigned long& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask((unsigned long)-1L)
+{
+ bit_width = width_;
+ if (bit_width < (int)(sizeof(unsigned long)*BITS_PER_BYTE)) {
+ mask = ~(-1L << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_unsigned_long_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_unsigned_long_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if ((object & mask) != object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned long bit_mask = 1ul << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_signed_int_trace: public wif_trace {
+public:
+ wif_signed_int_trace(const int& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const int& object;
+ int old_value;
+ unsigned mask;
+};
+
+
+wif_signed_int_trace::wif_signed_int_trace(const signed& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask(0xffffffff)
+{
+ bit_width = width_;
+ if (bit_width < 32) {
+ mask = ~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_signed_int_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_signed_int_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned) object & mask) != (unsigned) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_signed_short_trace: public wif_trace {
+public:
+ wif_signed_short_trace(const short& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const short& object;
+ short old_value;
+ unsigned short mask;
+};
+
+
+wif_signed_short_trace::wif_signed_short_trace(const short& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xffff)
+{
+ bit_width = width_;
+ if (bit_width < 16) {
+ mask = (unsigned short)~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_signed_short_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_signed_short_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned short) object & mask) != (unsigned short) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_signed_char_trace: public wif_trace {
+public:
+ wif_signed_char_trace(const char& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const char& object;
+ char old_value;
+ unsigned char mask;
+};
+
+
+wif_signed_char_trace::wif_signed_char_trace(const char& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xff)
+{
+ bit_width = width_;
+ if (bit_width < 8) {
+ mask = (unsigned char)~(-1 << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_signed_char_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_signed_char_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned char) object & mask) != (unsigned char) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ }
+ else{
+ unsigned bit_mask = 1 << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_signed_long_trace: public wif_trace {
+public:
+ wif_signed_long_trace(const long& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const long& object;
+ long old_value;
+ unsigned long mask;
+};
+
+
+wif_signed_long_trace::wif_signed_long_trace(const long& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ int width_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ mask((unsigned long)-1L)
+{
+ bit_width = width_;
+ if (bit_width < (int)(sizeof(long)*BITS_PER_BYTE)) {
+ mask = ~(-1L << bit_width);
+ }
+
+ wif_type = "BIT";
+}
+
+
+bool wif_signed_long_trace::changed()
+{
+ return object != old_value;
+}
+
+
+void wif_signed_long_trace::write(FILE* f)
+{
+ char buf[1000];
+ int bitindex;
+
+ // Check for overflow
+ if (((unsigned long) object & mask) != (unsigned long) object) {
+ for (bitindex = 0; bitindex < bit_width; bitindex++){
+ buf[bitindex]='0';
+ }
+ } else {
+ unsigned long bit_mask = 1ul << (bit_width-1);
+ for (bitindex = 0; bitindex < bit_width; bitindex++) {
+ buf[bitindex] = (object & bit_mask)? '1' : '0';
+ bit_mask = bit_mask >> 1;
+ }
+ }
+ buf[bitindex] = '\0';
+ std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class wif_float_trace: public wif_trace {
+public:
+ wif_float_trace(const float& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const float& object;
+ float old_value;
+};
+
+wif_float_trace::wif_float_trace(const float& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_)
+{
+ bit_width = 0;
+ wif_type = "real";
+}
+
+bool wif_float_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_float_trace::write(FILE* f)
+{
+ std::fprintf(f,"assign %s %f ; \n", wif_name.c_str(), object);
+ old_value = object;
+}
+
+/*****************************************************************************/
+
+class wif_double_trace: public wif_trace {
+public:
+ wif_double_trace(const double& object_,
+ const std::string& name_,
+ const std::string& wif_name_);
+ void write(FILE* f);
+ bool changed();
+
+protected:
+ const double& object;
+ double old_value;
+};
+
+wif_double_trace::wif_double_trace(const double& object_,
+ const std::string& name_,
+ const std::string& wif_name_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_)
+{
+ bit_width = 0;
+ wif_type = "real";
+}
+
+bool wif_double_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_double_trace::write(FILE* f)
+{
+ std::fprintf(f,"assign %s %f ; \n", wif_name.c_str(), object);
+ old_value = object;
+}
+
+
+/*****************************************************************************/
+
+class wif_enum_trace : public wif_trace {
+public:
+ wif_enum_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ const char** enum_literals);
+ void write(FILE* f);
+ bool changed();
+ // Hides the definition of the same (virtual) function in wif_trace
+ void print_variable_declaration_line(FILE* f);
+
+protected:
+ const unsigned& object;
+ unsigned old_value;
+
+ const char** literals;
+ unsigned nliterals;
+ std::string type_name;
+
+ ~wif_enum_trace();
+};
+
+
+wif_enum_trace::wif_enum_trace(const unsigned& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ const char** enum_literals_)
+: wif_trace(name_, wif_name_), object(object_), old_value(object_),
+ literals(enum_literals_), nliterals(0), type_name(name_ + "__type__")
+{
+ // find number of enumeration literals - counting loop
+ for (nliterals = 0; enum_literals_[nliterals]; nliterals++) continue;
+
+ bit_width = 0;
+ wif_type = type_name.c_str();
+}
+
+void wif_enum_trace::print_variable_declaration_line(FILE* f)
+{
+ std::fprintf(f, "type scalar \"%s\" enum ", wif_type);
+
+ for (unsigned i = 0; i < nliterals; i++)
+ std::fprintf(f, "\"%s\", ", literals[i]);
+ std::fprintf(f, "\"SC_WIF_UNDEF\" ;\n");
+
+ std::fprintf(f, "declare %s \"%s\" \"%s\" ",
+ wif_name.c_str(), name.c_str(), wif_type);
+ std::fprintf(f, "variable ;\n");
+ std::fprintf(f, "start_trace %s ;\n", wif_name.c_str());
+}
+
+bool wif_enum_trace::changed()
+{
+ return object != old_value;
+}
+
+void wif_enum_trace::write(FILE* f)
+{
+ static bool warning_issued = false;
+ const char* lit;
+
+ if (object >= nliterals) { // Note unsigned value is always greater than 0
+ if (!warning_issued) {
+ SC_REPORT_WARNING( SC_ID_TRACING_INVALID_ENUM_VALUE_
+ , name.c_str() );
+ warning_issued = true;
+ }
+ lit = "SC_WIF_UNDEF";
+ }
+ else
+ {
+ lit = literals[object];
+ }
+ std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), lit );
+ old_value = object;
+}
+
+wif_enum_trace::~wif_enum_trace()
+{
+ /* Intentionally blank */
+}
+
+
+template <class T>
+class wif_T_trace
+: public wif_trace
+{
+public:
+
+ wif_T_trace( const T& object_,
+ const std::string& name_,
+ const std::string& wif_name_,
+ wif_trace_file::wif_enum type_ )
+ : wif_trace( name_, wif_name_),
+ object( object_ ),
+ old_value( object_ )
+ { wif_type = wif_names[type_]; }
+
+ void write( FILE* f )
+ {
+ std::fprintf( f,
+ "assign %s \"%s\" ;\n",
+ wif_name.c_str(),
+ object.to_string().c_str() );
+ old_value = object;
+ }
+
+ bool changed()
+ { return !(object == old_value); }
+
+ void set_width()
+ { bit_width = object.length(); }
+
+protected:
+
+ const T& object;
+ T old_value;
+};
+
+typedef wif_T_trace<sc_dt::sc_bv_base> wif_sc_bv_trace;
+typedef wif_T_trace<sc_dt::sc_lv_base> wif_sc_lv_trace;
+
+
+//***********************************************************************
+// wif_trace_file functions
+//***********************************************************************
+
+
+wif_trace_file::wif_trace_file(const char * name)
+ : sc_trace_file_base( name, "awif" )
+ , wif_name_index(0)
+ , previous_time_units_low(0)
+ , previous_time_units_high(0)
+ , previous_time(0.0)
+ , traces()
+{}
+
+
+void wif_trace_file::do_initialize()
+{
+ char buf[2000];
+
+ // init
+ std::fprintf(fp, "init ;\n\n");
+
+ //timescale:
+ if (timescale_unit == 1e-15) std::sprintf(buf,"0");
+ else if(timescale_unit == 1e-14) std::sprintf(buf,"1");
+ else if(timescale_unit == 1e-13) std::sprintf(buf,"2");
+ else if(timescale_unit == 1e-12) std::sprintf(buf,"3");
+ else if(timescale_unit == 1e-11) std::sprintf(buf,"4");
+ else if(timescale_unit == 1e-10) std::sprintf(buf,"5");
+ else if(timescale_unit == 1e-9) std::sprintf(buf,"6");
+ else if(timescale_unit == 1e-8) std::sprintf(buf,"7");
+ else if(timescale_unit == 1e-7) std::sprintf(buf,"8");
+ else if(timescale_unit == 1e-6) std::sprintf(buf,"9");
+ else if(timescale_unit == 1e-5) std::sprintf(buf,"10");
+ else if(timescale_unit == 1e-4) std::sprintf(buf,"11");
+ else if(timescale_unit == 1e-3) std::sprintf(buf,"12");
+ else if(timescale_unit == 1e-2) std::sprintf(buf,"13");
+ else if(timescale_unit == 1e-1) std::sprintf(buf,"14");
+ else if(timescale_unit == 1e0) std::sprintf(buf,"15");
+ else if(timescale_unit == 1e1) std::sprintf(buf,"16");
+ else if(timescale_unit == 1e2) std::sprintf(buf,"17");
+ std::fprintf(fp,"header %s \"%s\" ;\n\n", buf, sc_version());
+
+ std::fprintf(fp, "comment \"ASCII WIF file produced on date: %s\" ;\n"
+ , localtime_string().c_str());
+
+ //version:
+ std::fprintf(fp, "comment \"Created by %s\" ;\n", sc_version());
+ //conversion info
+ std::fprintf(fp, "comment \"Convert this file to binary WIF format using a2wif\" ;\n\n");
+
+ // Define the two types we need to represent bool and sc_logic
+ std::fprintf(fp, "type scalar \"BIT\" enum '0', '1' ;\n");
+ std::fprintf(fp, "type scalar \"MVL\" enum '0', '1', 'X', 'Z', '?' ;\n");
+ std::fprintf(fp, "\n");
+
+ //variable definitions:
+ int i;
+ for (i = 0; i < (int)traces.size(); i++) {
+ wif_trace* t = traces[i];
+ t->set_width(); //needed for all vectors
+ t->print_variable_declaration_line(fp);
+ }
+
+ double inittime = sc_time_stamp().to_seconds();
+ previous_time = inittime/timescale_unit;
+
+ // Dump all values at initial time
+ std::sprintf(buf,
+ "All initial values are dumped below at time "
+ "%g sec = %g timescale units.",
+ inittime,
+ inittime/timescale_unit
+ );
+ write_comment(buf);
+
+ double_to_special_int64(inittime/timescale_unit,
+ &previous_time_units_high,
+ &previous_time_units_low );
+
+ for (i = 0; i < (int)traces.size(); i++) {
+ wif_trace* t = traces[i];
+ t->write(fp);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+#define DEFN_TRACE_METHOD(tp) \
+void \
+wif_trace_file::trace( const tp& object_, const std::string& name_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new wif_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name() ) ); \
+}
+
+DEFN_TRACE_METHOD(bool)
+DEFN_TRACE_METHOD(float)
+DEFN_TRACE_METHOD(double)
+
+#undef DEFN_TRACE_METHOD
+#define DEFN_TRACE_METHOD(tp) \
+void \
+wif_trace_file::trace(const sc_dt::tp& object_, const std::string& name_) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new wif_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name() ) ); \
+}
+
+DEFN_TRACE_METHOD(sc_bit)
+DEFN_TRACE_METHOD(sc_logic)
+
+DEFN_TRACE_METHOD(sc_signed)
+DEFN_TRACE_METHOD(sc_unsigned)
+DEFN_TRACE_METHOD(sc_int_base)
+DEFN_TRACE_METHOD(sc_uint_base)
+
+DEFN_TRACE_METHOD(sc_fxval)
+DEFN_TRACE_METHOD(sc_fxval_fast)
+DEFN_TRACE_METHOD(sc_fxnum)
+DEFN_TRACE_METHOD(sc_fxnum_fast)
+
+#undef DEFN_TRACE_METHOD
+
+
+#define DEFN_TRACE_METHOD_SIGNED(tp) \
+void \
+wif_trace_file::trace( const tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new wif_signed_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+#define DEFN_TRACE_METHOD_UNSIGNED(tp) \
+void \
+wif_trace_file::trace( const unsigned tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new wif_unsigned_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+DEFN_TRACE_METHOD_SIGNED(char)
+DEFN_TRACE_METHOD_SIGNED(short)
+DEFN_TRACE_METHOD_SIGNED(int)
+DEFN_TRACE_METHOD_SIGNED(long)
+
+DEFN_TRACE_METHOD_UNSIGNED(char)
+DEFN_TRACE_METHOD_UNSIGNED(short)
+DEFN_TRACE_METHOD_UNSIGNED(int)
+DEFN_TRACE_METHOD_UNSIGNED(long)
+
+#undef DEFN_TRACE_METHOD_SIGNED
+#undef DEFN_TRACE_METHOD_UNSIGNED
+
+
+#define DEFN_TRACE_METHOD_LONG_LONG(tp) \
+void \
+wif_trace_file::trace( const sc_dt::tp& object_, \
+ const std::string& name_, \
+ int width_ ) \
+{ \
+ if( add_trace_check(name_) ) \
+ traces.push_back( new wif_ ## tp ## _trace( object_, \
+ name_, \
+ obtain_name(), \
+ width_ ) ); \
+}
+
+DEFN_TRACE_METHOD_LONG_LONG(int64)
+DEFN_TRACE_METHOD_LONG_LONG(uint64)
+#undef DEFN_TRACE_METHOD_LONG_LONG
+
+void
+wif_trace_file::trace( const unsigned& object_,
+ const std::string& name_,
+ const char** enum_literals_ )
+{
+ if( add_trace_check(name_) )
+ traces.push_back( new wif_enum_trace( object_,
+ name_,
+ obtain_name(),
+ enum_literals_ ) );
+}
+
+void
+wif_trace_file::trace( const sc_dt::sc_bv_base& object_,
+ const std::string& name_ )
+{
+ traceT( object_, name_, WIF_BIT );
+}
+
+void
+wif_trace_file::trace( const sc_dt::sc_lv_base& object_,
+ const std::string& name_ )
+{
+ traceT( object_, name_, WIF_MVL );
+}
+
+
+void
+wif_trace_file::write_comment(const std::string& comment)
+{
+ if(!fp) open_fp();
+ //no newline in comments allowed
+ std::fprintf(fp, "comment \"%s\" ;\n", comment.c_str());
+}
+
+
+void
+wif_trace_file::cycle(bool this_is_a_delta_cycle)
+{
+ unsigned now_units_high, now_units_low;
+
+ // Trace delta cycles only when enabled
+ if (!delta_cycles() && this_is_a_delta_cycle) return;
+
+ // Check for initialization
+ if( initialize() ) {
+ return;
+ };
+
+ // double now_units = sc_simulation_time() / timescale_unit;
+ double now_units = sc_time_stamp().to_seconds() / timescale_unit;
+
+ double_to_special_int64(now_units, &now_units_high, &now_units_low );
+
+ // Now do the real stuff
+ unsigned delta_units_high, delta_units_low;
+ double diff_time;
+ diff_time = now_units - previous_time;
+ double_to_special_int64(diff_time, &delta_units_high, &delta_units_low);
+ if (this_is_a_delta_cycle && (diff_time == 0.0))
+ delta_units_low++; // Increment time for delta cycle simulation
+ // Note that in the last statement above, we are assuming no more
+ // than 2^32 delta cycles - seems realistic
+
+ bool time_printed = false;
+ wif_trace* const* const l_traces = &traces[0];
+ for (int i = 0; i < (int)traces.size(); i++) {
+ wif_trace* t = l_traces[i];
+ if(t->changed()){
+ if(time_printed == false){
+ if(delta_units_high){
+ std::fprintf(fp, "delta_time %u%09u ;\n", delta_units_high,
+ delta_units_low);
+ }
+ else{
+ std::fprintf(fp, "delta_time %u ;\n", delta_units_low);
+ }
+ time_printed = true;
+ }
+
+ // Write the variable
+ t->write(fp);
+ }
+ }
+
+ if(time_printed) {
+ std::fprintf(fp, "\n"); // Put another newline
+ // We update previous_time_units only when we print time because
+ // this field stores the previous time that was printed, not the
+ // previous time this function was called
+ previous_time_units_high = now_units_high;
+ previous_time_units_low = now_units_low;
+ previous_time = now_units;
+ }
+}
+
+#if 0
+void
+wif_trace_file::create_wif_name(std::string* ptr_to_str)
+{
+ obtain_name().swap(*ptr_to_str);
+}
+#endif
+
+// Create a WIF name for a variable
+std::string
+wif_trace_file::obtain_name()
+{
+ char buf[32];
+ std::sprintf( buf, "O%d", wif_name_index ++ );
+ return buf;
+}
+
+wif_trace_file::~wif_trace_file()
+{
+ for( int i = 0; i < (int)traces.size(); i++ ) {
+ wif_trace* t = traces[i];
+ delete t;
+ }
+}
+
+// Map sc_logic values to values understandable by WIF
+static char
+map_sc_logic_state_to_wif_state(char in_char)
+{
+ char out_char;
+
+ switch(in_char){
+ case 'U':
+ case 'X':
+ case 'W':
+ case 'D':
+ out_char = 'X';
+ break;
+ case '0':
+ case 'L':
+ out_char = '0';
+ break;
+ case '1':
+ case 'H':
+ out_char = '1';
+ break;
+ case 'Z':
+ out_char = 'Z';
+ break;
+ default:
+ out_char = '?';
+ }
+ return out_char;
+}
+
+// ----------------------------------------------------------------------------
+
+// Create the trace file
+sc_trace_file*
+sc_create_wif_trace_file(const char * name)
+{
+ sc_trace_file *tf = new wif_trace_file(name);
+ return tf;
+}
+
+
+void
+sc_close_wif_trace_file( sc_trace_file* tf )
+{
+ wif_trace_file* wif_tf = static_cast<wif_trace_file*>(tf);
+ delete wif_tf;
+}
+
+} // namespace sc_core
diff --git a/ext/systemc/src/sysc/tracing/sc_wif_trace.h b/ext/systemc/src/sysc/tracing/sc_wif_trace.h
new file mode 100644
index 000000000..b4de46e1b
--- /dev/null
+++ b/ext/systemc/src/sysc/tracing/sc_wif_trace.h
@@ -0,0 +1,222 @@
+/*****************************************************************************
+
+ 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_wif_trace.h - Implementation of WIF tracing.
+
+ Original 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, and significantly enhanced, 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.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+ Instead of creating the binary WIF format, we create the ASCII
+ WIF format which can be converted to the binary format using
+ a2wif (utility that comes with VSS from Synopsys). This way,
+ a user who does not have Synopsys VSS can still create WIF
+ files, but the files can only be viewed by users who have VSS.
+
+ *****************************************************************************/
+
+#ifndef SC_WIF_TRACE_H
+#define SC_WIF_TRACE_H
+
+#include <cstdio>
+#include "sysc/datatypes/int/sc_nbdefs.h"
+#include "sysc/tracing/sc_trace_file_base.h"
+
+namespace sc_core {
+
+class wif_trace; // defined in wif_trace.cc
+template<class T> class wif_T_trace;
+
+class wif_trace_file
+ : public sc_trace_file_base
+{
+public:
+ enum wif_enum {WIF_BIT=0, WIF_MVL=1, WIF_REAL=2, WIF_LAST};
+
+ // Create a wif trace file.
+ // `Name' forms the base of the name to which `.awif' is added.
+ explicit wif_trace_file(const char *name);
+
+ ~wif_trace_file();
+
+protected:
+ // These are all virtual functions in sc_trace_file and
+ // they need to be defined here.
+
+ // Trace a boolean object (single bit)
+ void trace(const bool& object, const std::string& name);
+
+ // Trace a sc_bit object (single bit)
+ void trace(const sc_dt::sc_bit& object, const std::string& name);
+
+ // Trace a sc_logic object (single bit)
+ void trace(const sc_dt::sc_logic& object, const std::string& name);
+
+ // Trace an unsigned char with the given width
+ void trace(const unsigned char& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned short with the given width
+ void trace(const unsigned short& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned int with the given width
+ void trace(const unsigned int& object, const std::string& name,
+ int width);
+
+ // Trace an unsigned long with the given width
+ void trace(const unsigned long& object, const std::string& name,
+ int width);
+
+ // Trace a signed char with the given width
+ void trace(const char& object, const std::string& name, int width);
+
+ // Trace a signed short with the given width
+ void trace(const short& object, const std::string& name, int width);
+
+ // Trace a signed int with the given width
+ void trace(const int& object, const std::string& name, int width);
+
+ // Trace a signed long with the given width
+ void trace(const long& object, const std::string& name, int width);
+
+ // Trace a signed long long with the given width
+ void trace(const sc_dt::int64& object, const std::string& name,
+ int width);
+
+ // Trace an usigned long long with the given width
+ void trace(const sc_dt::uint64& object, const std::string& name,
+ int width);
+
+ // Trace a float
+ void trace(const float& object, const std::string& name);
+
+ // Trace a double
+ void trace(const double& object, const std::string& name);
+
+ // Trace sc_unsigned
+ void trace (const sc_dt::sc_unsigned& object,
+ const std::string& name);
+
+ // Trace sc_signed
+ void trace (const sc_dt::sc_signed& object,
+ const std::string& name);
+
+ // Trace sc_uint_base
+ void trace (const sc_dt::sc_uint_base& object,
+ const std::string& name);
+
+ // Trace sc_int_base
+ void trace (const sc_dt::sc_int_base& object, const std::string& name);
+
+ // Trace sc_fxval
+ void trace( const sc_dt::sc_fxval& object, const std::string& name );
+
+ // Trace sc_fxval_fast
+ void trace( const sc_dt::sc_fxval_fast& object,
+ const std::string& name );
+
+ // Trace sc_fxnum
+ void trace( const sc_dt::sc_fxnum& object, const std::string& name );
+
+ // Trace sc_fxnum_fast
+ void trace( const sc_dt::sc_fxnum_fast& object,
+ const std::string& name );
+
+ template<class T>
+ void traceT(const T& object, const std::string& name, wif_enum type)
+ {
+ if( add_trace_check(name) )
+ traces.push_back( new wif_T_trace<T>( object, name
+ , obtain_name(),type ) );
+ }
+
+ // Trace sc_bv_base (sc_bv)
+ virtual void trace( const sc_dt::sc_bv_base& object,
+ const std::string& name );
+
+ // Trace sc_lv_base (sc_lv)
+ virtual void trace( const sc_dt::sc_lv_base& object,
+ const std::string& name );
+
+ // 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 trace(const unsigned& object, const std::string& name,
+ const char** enum_literals);
+
+ // Output a comment to the trace file
+ void write_comment(const std::string& comment);
+
+ // Write trace info for cycle.
+ void cycle(bool delta_cycle);
+
+private:
+
+#if SC_TRACING_PHASE_CALLBACKS_
+ // avoid hidden overload warnings
+ virtual void trace( sc_trace_file* ) const { sc_assert(false); }
+#endif // SC_TRACING_PHASE_CALLBACKS_
+
+ // Initialize the tracing mechanism
+ virtual void do_initialize();
+
+ unsigned wif_name_index; // Number of variables traced
+
+ unsigned previous_time_units_low; // Previous time as 64 bit integer
+ unsigned previous_time_units_high;
+ double previous_time; // Previous time as a double
+
+public:
+ // Create wif names for each variable
+ std::string obtain_name();
+
+ // Array to store the variables traced
+ std::vector<wif_trace*> traces;
+};
+
+} // namespace sc_core
+
+#endif // SC_WIF_TRACE_H
+// Taf!