summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/tracing
diff options
context:
space:
mode:
authorMatthias Jung <jungma@eit.uni-kl.de>2017-03-01 18:39:56 +0100
committerMatthias Jung <jungma@eit.uni-kl.de>2017-05-18 08:36:56 +0000
commitaa651c7f8321bf96fc88f9a17285225000a753ec (patch)
treeb13240008c970b47bd74a5007e68136155d272fc /ext/systemc/src/sysc/tracing
parent595e692de09e1b7cbc5f57ac01da299afc066fdd (diff)
downloadgem5-aa651c7f8321bf96fc88f9a17285225000a753ec.tar.xz
ext: Include SystemC 2.3.1 into gem5
In the past it happened several times that some changes in gem5 broke the SystemC coupling. Recently Accelera has changed the licence for SystemC from their own licence to Apache2.0, which is compatible with gem5. However, SystemC usually relies on the Boost library, but I was able to exchange the boost calls by c++11 alternatives. The recent SystemC version is placed into /ext and is integrated into gem5's build system. The goal is to integrate some SystemC tests for the CI in some following patches. Change-Id: I4b66ec806b5e3cffc1d7c85d3735ff4fa5b31fd0 Reviewed-on: https://gem5-review.googlesource.com/2240 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
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!