sc_wif_trace.cpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2006 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.4 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   sc_wif_trace.cpp - Implementation of WIF tracing.
00021 
00022   Original Author - Abhijit Ghosh, Synopsys, Inc.
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
00032   Description of Modification: - Replaced 'width' of sc_(u)int with their
00033                                  'bitwidth()'.
00034 
00035       Name, Affiliation, Date:
00036   Description of Modification:
00037 
00038  *****************************************************************************/
00039 
00040 /*****************************************************************************
00041 
00042    Acknowledgement: The tracing mechanism is based on the tracing
00043    mechanism developed at Infineon (formerly Siemens HL). Though this
00044    code is somewhat different, and significantly enhanced, the basics
00045    are identical to what was originally contributed by Infineon.  The
00046    contribution of Infineon in the development of this tracing
00047    technology is hereby acknowledged.
00048 
00049  *****************************************************************************/
00050 
00051 /*****************************************************************************
00052 
00053    Instead of creating the binary WIF format, we create the ASCII
00054    WIF format which can be converted to the binary format using
00055    a2wif (utility that comes with VSS from Synopsys). This way, 
00056    a user who does not have Synopsys VSS can still create WIF 
00057    files, but they can only be viewed by users who have VSS.
00058 
00059  *****************************************************************************/
00060 
00061 
00062 #include <assert.h>
00063 #include <time.h>
00064 #include <cstdlib>
00065 
00066 #include "sysc/kernel/sc_simcontext.h"
00067 #include "sysc/kernel/sc_ver.h"
00068 #include "sysc/datatypes/bit/sc_bit.h"
00069 #include "sysc/datatypes/bit/sc_logic.h"
00070 #include "sysc/datatypes/bit/sc_lv_base.h"
00071 #include "sysc/datatypes/int/sc_signed.h"
00072 #include "sysc/datatypes/int/sc_unsigned.h"
00073 #include "sysc/datatypes/int/sc_int_base.h"
00074 #include "sysc/datatypes/int/sc_uint_base.h"
00075 #include "sysc/datatypes/fx/fx.h"
00076 #include "sysc/tracing/sc_wif_trace.h"
00077 
00078 namespace sc_core {
00079 
00080 static bool running_regression = false;
00081 
00082 // Forward declarations for functions that come later in the file
00083 static char map_sc_logic_state_to_wif_state(char in_char);
00084 
00085 const char* wif_names[wif_trace_file::WIF_LAST] = {"BIT","MVL","real"};
00086 
00087 
00088 // ----------------------------------------------------------------------------
00089 //  CLASS : wif_trace
00090 //
00091 //  Base class for WIF traces.
00092 // ----------------------------------------------------------------------------
00093 
00094 class wif_trace
00095 {
00096 public:
00097 
00098     wif_trace(const std::string& name_, const std::string& wif_name_);
00099 
00100     // Needs to be pure virtual as has to be defined by the particular
00101     // type being traced
00102     virtual void write(FILE* f) = 0;
00103     
00104     virtual void set_width();
00105 
00106     // Comparison function needs to be pure virtual too
00107     virtual bool changed() = 0;
00108 
00109     // Got to declare this virtual as this will be overwritten
00110     // by one base class
00111     virtual void print_variable_declaration_line(FILE* f);
00112 
00113     virtual ~wif_trace();
00114 
00115     const std::string name;     // Name of the variable
00116     const std::string wif_name; // Name of the variable in WIF file
00117     const char* wif_type;     // WIF data type
00118     int bit_width; 
00119 };
00120 
00121 
00122 wif_trace::wif_trace(const std::string& name_, 
00123     const std::string& wif_name_)
00124         : name(name_), wif_name(wif_name_), bit_width(-1)
00125 {
00126     /* Intentionally blank */
00127 }
00128         
00129 void
00130 wif_trace::print_variable_declaration_line( FILE* f )
00131 {
00132     char buf[2000];
00133 
00134     if( bit_width < 0 ) {
00135         std::sprintf( buf, "Traced object \"%s\" has < 0 Bits, cannot be traced.",
00136           name.c_str() );
00137         put_error_message( buf, false );
00138     } else {
00139         std::fprintf( f, "declare  %s   \"%s\"  %s  ",
00140         wif_name.c_str(), name.c_str(), wif_type );
00141     if( bit_width > 0 ) {
00142         std::fprintf( f, "0 %d ", bit_width - 1 );
00143     }
00144     std::fprintf( f, "variable ;\n" );
00145     std::fprintf( f, "start_trace %s ;\n", wif_name.c_str() );
00146     }
00147 }
00148 
00149 void
00150 wif_trace::set_width()
00151 {
00152     /* Intentionally Blank, should be defined for each type separately */
00153 }
00154 
00155 wif_trace::~wif_trace()
00156 {
00157     /* Intentionally Blank */
00158 }
00159 
00160 // Classes for tracing individual data types
00161 
00162 /*****************************************************************************/
00163 
00164 class wif_uint64_trace: public wif_trace {
00165 public:
00166     wif_uint64_trace(const sc_dt::uint64& object_,
00167                 const std::string& name_,
00168                 const std::string& wif_name_,
00169                 int width_);
00170     void write(FILE* f);
00171     bool changed();
00172 
00173 protected:
00174     const sc_dt::uint64& object;
00175     sc_dt::uint64 old_value;
00176     sc_dt::uint64 mask; 
00177 };
00178 
00179 
00180 wif_uint64_trace::wif_uint64_trace(const sc_dt::uint64& object_,
00181                          const std::string& name_,
00182                          const std::string& wif_name_,
00183                          int width_) 
00184 : wif_trace(name_, wif_name_), object(object_)
00185 {
00186     bit_width = width_;
00187     mask = (sc_dt::uint64)-1;
00188     if (bit_width < 32) mask = ~(mask << bit_width);
00189     old_value = object;
00190     wif_type = "BIT";
00191 }
00192 
00193 
00194 bool wif_uint64_trace::changed()
00195 {
00196     return object != old_value;
00197 }
00198 
00199 
00200 void wif_uint64_trace::write(FILE* f)
00201 {
00202     char buf[1000];
00203     int bitindex;
00204 
00205     // Check for overflow
00206     if ((object & mask) != object) 
00207     {
00208         for (bitindex = 0; bitindex < bit_width; bitindex++)
00209         {
00210             buf[bitindex]='0';
00211         }
00212     }
00213     else
00214     {
00215         sc_dt::uint64 bit_mask = 1;
00216         bit_mask = bit_mask << (bit_width-1);
00217         for (bitindex = 0; bitindex < bit_width; bitindex++) 
00218         {
00219             buf[bitindex] = (object & bit_mask)? '1' : '0';
00220             bit_mask = bit_mask >> 1;
00221         }
00222     }
00223     buf[bitindex] = '\0';
00224     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
00225     old_value = object;
00226 }
00227 
00228 /*****************************************************************************/
00229 
00230 class wif_int64_trace: public wif_trace {
00231 public:
00232     wif_int64_trace(const sc_dt::int64& object_,
00233                 const std::string& name_,
00234                 const std::string& wif_name_,
00235                 int width_);
00236     void write(FILE* f);
00237     bool changed();
00238 
00239 protected:
00240     const sc_dt::int64& object;
00241     sc_dt::int64 old_value;
00242     sc_dt::uint64 mask; 
00243 };
00244 
00245 
00246 wif_int64_trace::wif_int64_trace(const sc_dt::int64& object_,
00247                          const std::string& name_,
00248                          const std::string& wif_name_,
00249                          int width_) 
00250 : wif_trace(name_, wif_name_), object(object_)
00251 {
00252     bit_width = width_;
00253     mask = (sc_dt::uint64)-1;
00254     if (bit_width < 32) mask = ~(mask << bit_width);
00255     old_value = object;
00256     wif_type = "BIT";
00257 }
00258 
00259 
00260 bool wif_int64_trace::changed()
00261 {
00262     return object != old_value;
00263 }
00264 
00265 
00266 void wif_int64_trace::write(FILE* f)
00267 {
00268     char buf[1000];
00269     int bitindex;
00270 
00271     // Check for overflow
00272     if ((object & mask) != (sc_dt::uint64)object) 
00273     {
00274         for (bitindex = 0; bitindex < bit_width; bitindex++)
00275         {
00276             buf[bitindex]='0';
00277         }
00278     }
00279     else
00280     {
00281         sc_dt::uint64 bit_mask = 1;
00282         bit_mask = bit_mask << (bit_width-1);
00283         for (bitindex = 0; bitindex < bit_width; bitindex++) 
00284         {
00285             buf[bitindex] = (object & bit_mask)? '1' : '0';
00286             bit_mask = bit_mask >> 1;
00287         }
00288     }
00289     buf[bitindex] = '\0';
00290     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
00291     old_value = object;
00292 }
00293 
00294 /*****************************************************************************/
00295 
00296 class wif_bool_trace
00297 : public wif_trace
00298 {
00299 public:
00300 
00301     wif_bool_trace( const bool& object_,
00302             const std::string& name_,
00303             const std::string& wif_name_ );
00304     void write( FILE* f );
00305     bool changed();
00306 
00307 protected:    
00308 
00309     const bool& object;
00310     bool        old_value;
00311 };
00312 
00313 wif_bool_trace::wif_bool_trace( const bool& object_,
00314                 const std::string& name_,
00315                 const std::string& wif_name_ )
00316 : wif_trace( name_, wif_name_ ),
00317   object( object_ )
00318 {
00319     bit_width = 0;
00320     old_value = object_;
00321     wif_type = "BIT";
00322 }
00323 
00324 bool
00325 wif_bool_trace::changed()
00326 {
00327     return object != old_value;
00328 }
00329 
00330 void
00331 wif_bool_trace::write( FILE* f )
00332 {
00333     if( object == true ) {
00334     std::fprintf( f, "assign %s \'1\' ;\n", wif_name.c_str() );
00335     } else {
00336     std::fprintf( f, "assign %s \'0\' ;\n", wif_name.c_str() );
00337     }
00338     old_value = object;
00339 }
00340 
00341 //*****************************************************************************
00342 
00343 class wif_sc_bit_trace : public wif_trace {
00344 public:
00345     wif_sc_bit_trace(const sc_dt::sc_bit& object_, 
00346                      const std::string& name_,
00347                      const std::string& wif_name_);
00348     void write(FILE* f);
00349     bool changed();
00350 
00351 protected:    
00352     const sc_dt::sc_bit& object;
00353     sc_dt::sc_bit old_value;
00354 };
00355 
00356 wif_sc_bit_trace::wif_sc_bit_trace(const sc_dt::sc_bit& object_,
00357                    const std::string& name_,
00358                    const std::string& wif_name_)
00359 : wif_trace(name_, wif_name_), object(object_)
00360 {
00361     bit_width = 0;
00362     old_value = object_;
00363     wif_type = "BIT";
00364 }
00365 
00366 bool wif_sc_bit_trace::changed()
00367 {
00368     return object != old_value;
00369 }
00370 
00371 void wif_sc_bit_trace::write(FILE* f)
00372 {
00373     if (object == true) {
00374         std::fprintf(f, "assign %s \'1\' ;\n", wif_name.c_str());
00375     } else {
00376     std::fprintf(f, "assign %s \'0\' ;\n", wif_name.c_str());
00377     }
00378     old_value = object;
00379 }
00380 
00381 /*****************************************************************************/
00382 
00383 class wif_sc_logic_trace: public wif_trace {
00384 public:
00385     wif_sc_logic_trace(const sc_dt::sc_logic& object_,
00386                const std::string& name_,
00387                const std::string& wif_name_);
00388     void write(FILE* f);
00389     bool changed();
00390 
00391 protected:    
00392     const sc_dt::sc_logic& object;
00393     sc_dt::sc_logic old_value;
00394 };
00395 
00396 
00397 wif_sc_logic_trace::wif_sc_logic_trace(const sc_dt::sc_logic& object_,
00398                        const std::string& name_,
00399                        const std::string& wif_name_) 
00400 : wif_trace(name_, wif_name_), object(object_)
00401 {
00402     bit_width = 0;
00403     old_value = object;
00404     wif_type = "MVL";
00405 }
00406 
00407 
00408 bool wif_sc_logic_trace::changed()
00409 {
00410     return object != old_value;
00411 }
00412 
00413 
00414 void wif_sc_logic_trace::write(FILE* f)
00415 {
00416     char wif_char;
00417     std::fprintf(f, "assign %s \'", wif_name.c_str());
00418     wif_char = map_sc_logic_state_to_wif_state(object.to_char());
00419     std::fputc(wif_char, f); 
00420     std::fprintf(f,"\' ;\n");
00421     old_value = object;
00422 }
00423 
00424 
00425 /*****************************************************************************/
00426 
00427 class wif_sc_unsigned_trace: public wif_trace {
00428 public:
00429     wif_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,
00430               const std::string& name_,
00431               const std::string& wif_name_);
00432     void write(FILE* f);
00433     bool changed();
00434     void set_width();
00435 
00436 protected:    
00437     const sc_dt::sc_unsigned& object;
00438     sc_dt::sc_unsigned old_value;
00439 };
00440 
00441 
00442 wif_sc_unsigned_trace::wif_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,
00443                          const std::string& name_,
00444                          const std::string& wif_name_) 
00445 : wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
00446 {
00447     old_value = object;
00448     wif_type = "BIT";
00449 }
00450 
00451 bool wif_sc_unsigned_trace::changed()
00452 {
00453     return object != old_value;
00454 }
00455 
00456 void wif_sc_unsigned_trace::write(FILE* f)
00457 {
00458     char buf[1000], *buf_ptr = buf;
00459 
00460     int bitindex;
00461     for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
00462         *buf_ptr++ = "01"[(object)[bitindex]];
00463     }
00464     *buf_ptr = '\0';
00465     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
00466     old_value = object;
00467 }
00468 
00469 void wif_sc_unsigned_trace::set_width()
00470 {
00471     bit_width = object.length();
00472 }
00473 
00474 
00475 /*****************************************************************************/
00476 
00477 class wif_sc_signed_trace: public wif_trace {
00478 public:
00479     wif_sc_signed_trace(const sc_dt::sc_signed& object_,
00480             const std::string& name_,
00481             const std::string& wif_name_);
00482     void write(FILE* f);
00483     bool changed();
00484     void set_width();
00485 
00486 protected:    
00487     const sc_dt::sc_signed& object;
00488     sc_dt::sc_signed old_value;
00489 };
00490 
00491 
00492 wif_sc_signed_trace::wif_sc_signed_trace(const sc_dt::sc_signed& object_,
00493                      const std::string& name_,
00494                      const std::string& wif_name_) 
00495 : wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
00496 {
00497     old_value = object;
00498     wif_type = "BIT";
00499 }
00500 
00501 bool wif_sc_signed_trace::changed()
00502 {
00503     return object != old_value;
00504 }
00505 
00506 void wif_sc_signed_trace::write(FILE* f)
00507 {
00508     char buf[1000], *buf_ptr = buf;
00509 
00510     int bitindex;
00511     for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
00512         *buf_ptr++ = "01"[(object)[bitindex]];
00513     }
00514     *buf_ptr = '\0';
00515 
00516     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
00517     old_value = object;
00518 }
00519 
00520 void wif_sc_signed_trace::set_width()
00521 {
00522     bit_width = object.length();
00523 }
00524 
00525 /*****************************************************************************/
00526 
00527 class wif_sc_uint_base_trace: public wif_trace {
00528 public:
00529     wif_sc_uint_base_trace(const sc_dt::sc_uint_base& object_,
00530                const std::string& name_,
00531                const std::string& wif_name_);
00532     void write(FILE* f);
00533     bool changed();
00534     void set_width();
00535 
00536 protected:    
00537     const sc_dt::sc_uint_base& object;
00538     sc_dt::sc_uint_base old_value;
00539 };
00540 
00541 
00542 wif_sc_uint_base_trace::wif_sc_uint_base_trace(
00543                                           const sc_dt::sc_uint_base& object_,
00544                       const std::string& name_,
00545                       const std::string& wif_name_)
00546 : wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
00547 {
00548     old_value = object;
00549     wif_type = "BIT";
00550 }
00551 
00552 bool wif_sc_uint_base_trace::changed()
00553 {
00554     return object != old_value;
00555 }
00556 
00557 void wif_sc_uint_base_trace::write(FILE* f)
00558 {
00559     char buf[1000], *buf_ptr = buf;
00560 
00561     int bitindex;
00562     for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
00563         *buf_ptr++ = "01"[(object)[bitindex]];
00564     }
00565     *buf_ptr = '\0';
00566     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
00567     old_value = object;
00568 }
00569 
00570 void wif_sc_uint_base_trace::set_width()
00571 {
00572     bit_width = object.length();
00573 }
00574 
00575 
00576 /*****************************************************************************/
00577 
00578 class wif_sc_int_base_trace: public wif_trace {
00579 public:
00580     wif_sc_int_base_trace(const sc_dt::sc_int_base& object_,
00581               const std::string& name_,
00582               const std::string& wif_name_);
00583     void write(FILE* f);
00584     bool changed();
00585     void set_width();
00586 
00587 protected:    
00588     const sc_dt::sc_int_base& object;
00589     sc_dt::sc_int_base old_value;
00590 };
00591 
00592 
00593 wif_sc_int_base_trace::wif_sc_int_base_trace(const sc_dt::sc_int_base& object_,
00594                          const std::string& name_,
00595                          const std::string& wif_name_) 
00596 : wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
00597 {
00598     old_value = object;
00599     wif_type = "BIT";
00600 }
00601 
00602 bool wif_sc_int_base_trace::changed()
00603 {
00604     return object != old_value;
00605 }
00606 
00607 void wif_sc_int_base_trace::write(FILE* f)
00608 {
00609     char buf[1000], *buf_ptr = buf;
00610 
00611     int bitindex;
00612     for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
00613         *buf_ptr++ = "01"[(object)[bitindex]];
00614     }
00615     *buf_ptr = '\0';
00616 
00617     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
00618     old_value = object;
00619 }
00620 
00621 void wif_sc_int_base_trace::set_width()
00622 {
00623     bit_width = object.length();
00624 }
00625 
00626 
00627 /*****************************************************************************/
00628 
00629 class wif_sc_fxval_trace: public wif_trace
00630 {
00631 public:
00632 
00633     wif_sc_fxval_trace( const sc_dt::sc_fxval& object_,
00634             const std::string& name_,
00635             const std::string& wif_name_ );
00636     void write( FILE* f );
00637     bool changed();
00638 
00639 protected:
00640 
00641     const sc_dt::sc_fxval& object;
00642     sc_dt::sc_fxval old_value;
00643 
00644 };
00645 
00646 wif_sc_fxval_trace::wif_sc_fxval_trace( const sc_dt::sc_fxval& object_,
00647                         const std::string& name_,
00648                     const std::string& wif_name_ )
00649 : wif_trace( name_, wif_name_ ),
00650   object( object_ )
00651 {
00652     bit_width = 0;
00653     old_value = object;
00654     wif_type = "real";
00655 }
00656 
00657 bool
00658 wif_sc_fxval_trace::changed()
00659 {
00660     return object != old_value;
00661 }
00662 
00663 void
00664 wif_sc_fxval_trace::write( FILE* f )
00665 {
00666     std::fprintf( f, "assign  %s %f ; \n", wif_name.c_str(), object.to_double() );
00667     old_value = object;
00668 }
00669 
00670 /*****************************************************************************/
00671 
00672 class wif_sc_fxval_fast_trace: public wif_trace
00673 {
00674 public:
00675 
00676     wif_sc_fxval_fast_trace( const sc_dt::sc_fxval_fast& object_,
00677                  const std::string& name_,
00678                  const std::string& wif_name_ );
00679     void write( FILE* f );
00680     bool changed();
00681 
00682 protected:
00683 
00684     const sc_dt::sc_fxval_fast& object;
00685     sc_dt::sc_fxval_fast old_value;
00686 
00687 };
00688 
00689 wif_sc_fxval_fast_trace::wif_sc_fxval_fast_trace( 
00690                                 const sc_dt::sc_fxval_fast& object_,
00691                 const std::string& name_,
00692                 const std::string& wif_name_ )
00693 : wif_trace( name_, wif_name_ ),
00694   object( object_ )
00695 {
00696     bit_width = 0;
00697     old_value = object;
00698     wif_type = "real";
00699 }
00700 
00701 bool
00702 wif_sc_fxval_fast_trace::changed()
00703 {
00704     return object != old_value;
00705 }
00706 
00707 void
00708 wif_sc_fxval_fast_trace::write( FILE* f )
00709 {
00710     std::fprintf( f, "assign  %s %f ; \n", wif_name.c_str(), object.to_double() );
00711     old_value = object;
00712 }
00713 
00714 /*****************************************************************************/
00715 
00716 class wif_sc_fxnum_trace: public wif_trace
00717 {
00718 public:
00719 
00720     wif_sc_fxnum_trace( const sc_dt::sc_fxnum& object_,
00721             const std::string& name_,
00722             const std::string& wif_name_ );
00723     void write( FILE* f );
00724     bool changed();
00725     void set_width();
00726 
00727 protected:
00728 
00729     const sc_dt::sc_fxnum& object;
00730     sc_dt::sc_fxnum old_value;
00731 
00732 };
00733 
00734 wif_sc_fxnum_trace::wif_sc_fxnum_trace( const sc_dt::sc_fxnum& object_,
00735                         const std::string& name_,
00736                     const std::string& wif_name_ )
00737 : wif_trace( name_, wif_name_ ),
00738   object( object_ ),
00739   old_value( object_.m_params.type_params(),
00740          object_.m_params.enc(),
00741          object_.m_params.cast_switch(),
00742          0 )
00743 {
00744     old_value = object;
00745     wif_type = "BIT";
00746 }
00747 
00748 bool
00749 wif_sc_fxnum_trace::changed()
00750 {
00751     return object != old_value;
00752 }
00753 
00754 void
00755 wif_sc_fxnum_trace::write( FILE* f )
00756 {
00757     char buf[1000], *buf_ptr = buf;
00758 
00759     int bitindex;
00760     for( bitindex = object.wl() - 1; bitindex >= 0; -- bitindex )
00761     {
00762         *buf_ptr ++ = "01"[(object)[bitindex]];
00763     }
00764     *buf_ptr = '\0';
00765 
00766     std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf );
00767     old_value = object;
00768 }
00769 
00770 void
00771 wif_sc_fxnum_trace::set_width()
00772 {
00773     bit_width = object.wl();
00774 }
00775 
00776 /*****************************************************************************/
00777 
00778 class wif_sc_fxnum_fast_trace: public wif_trace
00779 {
00780 public:
00781 
00782     wif_sc_fxnum_fast_trace( const sc_dt::sc_fxnum_fast& object_,
00783                  const std::string& name_,
00784                  const std::string& wif_name_ );
00785     void write( FILE* f );
00786     bool changed();
00787     void set_width();
00788 
00789 protected:
00790 
00791     const sc_dt::sc_fxnum_fast& object;
00792     sc_dt::sc_fxnum_fast old_value;
00793 
00794 };
00795 
00796 wif_sc_fxnum_fast_trace::wif_sc_fxnum_fast_trace( 
00797                 const sc_dt::sc_fxnum_fast& object_,
00798                 const std::string& name_,
00799                 const std::string& wif_name_ )
00800 : wif_trace( name_, wif_name_ ),
00801   object( object_ ),
00802   old_value( object_.m_params.type_params(),
00803          object_.m_params.enc(),
00804          object_.m_params.cast_switch(),
00805          0 )
00806 {
00807     old_value = object;
00808     wif_type = "BIT";
00809 }
00810 
00811 bool
00812 wif_sc_fxnum_fast_trace::changed()
00813 {
00814     return object != old_value;
00815 }
00816 
00817 void
00818 wif_sc_fxnum_fast_trace::write( FILE* f )
00819 {
00820     char buf[1000], *buf_ptr = buf;
00821 
00822     int bitindex;
00823     for( bitindex = object.wl() - 1; bitindex >= 0; -- bitindex )
00824     {
00825         *buf_ptr ++ = "01"[(object)[bitindex]];
00826     }
00827     *buf_ptr = '\0';
00828 
00829     std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf );
00830     old_value = object;
00831 }
00832 
00833 void
00834 wif_sc_fxnum_fast_trace::set_width()
00835 {
00836     bit_width = object.wl();
00837 }
00838 
00839 
00840 /*****************************************************************************/
00841 
00842 class wif_unsigned_int_trace: public wif_trace {
00843 public:
00844     wif_unsigned_int_trace(const unsigned& object_,
00845                const std::string& name_,
00846                const std::string& wif_name_, int width_);
00847     void write(FILE* f);
00848     bool changed();
00849 
00850 protected:
00851     const unsigned& object;
00852     unsigned old_value;
00853     unsigned mask; 
00854 };
00855 
00856 
00857 wif_unsigned_int_trace::wif_unsigned_int_trace(const unsigned& object_,
00858                        const std::string& name_,
00859                        const std::string& wif_name_,
00860                        int width_) 
00861 : wif_trace(name_, wif_name_), object(object_)
00862 {
00863     bit_width = width_;
00864     if (bit_width < 32) {
00865         mask = ~(-1 << bit_width);
00866     } else {
00867         mask = 0xffffffff;
00868     }
00869 
00870     old_value = object;
00871     wif_type = "BIT";
00872 }
00873 
00874 
00875 bool wif_unsigned_int_trace::changed()
00876 {
00877     return object != old_value;
00878 }
00879 
00880 
00881 void wif_unsigned_int_trace::write(FILE* f)
00882 {
00883     char buf[1000];
00884     int bitindex;
00885 
00886     // Check for overflow
00887     if ((object & mask) != object) {
00888         for (bitindex = 0; bitindex < bit_width; bitindex++){
00889             buf[bitindex] = '0';
00890         }
00891     }
00892     else{
00893         unsigned bit_mask = 1 << (bit_width-1);
00894         for (bitindex = 0; bitindex < bit_width; bitindex++) {
00895             buf[bitindex] = (object & bit_mask)? '1' : '0';
00896             bit_mask = bit_mask >> 1;
00897         }
00898     }
00899     buf[bitindex] = '\0';
00900     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
00901     old_value = object;
00902 }
00903 
00904 
00905 /*****************************************************************************/
00906 
00907 class wif_unsigned_short_trace: public wif_trace {
00908 public:
00909     wif_unsigned_short_trace(const unsigned short& object_,
00910                  const std::string& name_,
00911                  const std::string& wif_name_,
00912                  int width_);
00913     void write(FILE* f);
00914     bool changed();
00915 
00916 protected:
00917     const unsigned short& object;
00918     unsigned short old_value;
00919     unsigned short mask; 
00920 };
00921 
00922 
00923 wif_unsigned_short_trace::wif_unsigned_short_trace(
00924     const unsigned short& object_,
00925        const std::string& name_,
00926        const std::string& wif_name_,
00927        int width_) 
00928 : wif_trace(name_, wif_name_), object(object_)
00929 {
00930     bit_width = width_;
00931     if (bit_width < 16) {
00932         mask = ~(-1 << bit_width);
00933     } else {
00934         mask = 0xffff;
00935     }
00936 
00937     old_value = object;
00938     wif_type = "BIT";
00939 }
00940 
00941 
00942 bool wif_unsigned_short_trace::changed()
00943 {
00944     return object != old_value;
00945 }
00946 
00947 
00948 void wif_unsigned_short_trace::write(FILE* f)
00949 {
00950     char buf[1000];
00951     int bitindex;
00952 
00953     // Check for overflow
00954     if ((object & mask) != object) {
00955         for (bitindex = 0; bitindex < bit_width; bitindex++){
00956             buf[bitindex]='0';
00957         }
00958     }
00959     else{
00960         unsigned bit_mask = 1 << (bit_width-1);
00961         for (bitindex = 0; bitindex < bit_width; bitindex++) {
00962             buf[bitindex] = (object & bit_mask)? '1' : '0';
00963             bit_mask = bit_mask >> 1;
00964         }
00965     }
00966     buf[bitindex] = '\0';
00967     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
00968     old_value = object;
00969 }
00970 
00971 /*****************************************************************************/
00972 
00973 class wif_unsigned_char_trace: public wif_trace {
00974 public:
00975     wif_unsigned_char_trace(const unsigned char& object_,
00976                 const std::string& name_,
00977                 const std::string& wif_name_,
00978                 int width_);
00979     void write(FILE* f);
00980     bool changed();
00981 
00982 protected:
00983     const unsigned char& object;
00984     unsigned char old_value;
00985     unsigned char mask; 
00986 };
00987 
00988 
00989 wif_unsigned_char_trace::wif_unsigned_char_trace(const unsigned char& object_,
00990                      const std::string& name_,
00991                      const std::string& wif_name_,
00992                      int width_) 
00993 : wif_trace(name_, wif_name_), object(object_)
00994 {
00995     bit_width = width_;
00996     if (bit_width < 8) {
00997         mask = ~(-1 << bit_width);
00998     } else {
00999         mask = 0xff;
01000     }
01001 
01002     old_value = object;
01003     wif_type = "BIT";
01004 }
01005 
01006 
01007 bool wif_unsigned_char_trace::changed()
01008 {
01009     return object != old_value;
01010 }
01011 
01012 
01013 void wif_unsigned_char_trace::write(FILE* f)
01014 {
01015     char buf[1000];
01016     int bitindex;
01017 
01018     // Check for overflow
01019     if ((object & mask) != object) {
01020         for (bitindex = 0; bitindex < bit_width; bitindex++){
01021             buf[bitindex]='0';
01022         }
01023     }
01024     else{
01025         unsigned bit_mask = 1 << (bit_width-1);
01026         for (bitindex = 0; bitindex < bit_width; bitindex++) {
01027             buf[bitindex] = (object & bit_mask)? '1' : '0';
01028             bit_mask = bit_mask >> 1;
01029         }
01030     }
01031     buf[bitindex] = '\0';
01032     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
01033     old_value = object;
01034 }
01035 
01036 /*****************************************************************************/
01037 
01038 class wif_unsigned_long_trace: public wif_trace {
01039 public:
01040     wif_unsigned_long_trace(const unsigned long& object_,
01041                 const std::string& name_,
01042                 const std::string& wif_name_,
01043                 int width_);
01044     void write(FILE* f);
01045     bool changed();
01046 
01047 protected:
01048     const unsigned long& object;
01049     unsigned long old_value;
01050     unsigned long mask; 
01051 };
01052 
01053 
01054 wif_unsigned_long_trace::wif_unsigned_long_trace(const unsigned long& object_,
01055                          const std::string& name_,
01056                          const std::string& wif_name_,
01057                          int width_) 
01058 : wif_trace(name_, wif_name_), object(object_)
01059 {
01060     bit_width = width_;
01061     if (bit_width < 32) {
01062         mask = ~(-1 << bit_width);
01063     } else {
01064         mask = 0xffffffff;
01065     }
01066 
01067     old_value = object;
01068     wif_type = "BIT";
01069 }
01070 
01071 
01072 bool wif_unsigned_long_trace::changed()
01073 {
01074     return object != old_value;
01075 }
01076 
01077 
01078 void wif_unsigned_long_trace::write(FILE* f)
01079 {
01080     char buf[1000];
01081     int bitindex;
01082 
01083     // Check for overflow
01084     if ((object & mask) != object) {
01085         for (bitindex = 0; bitindex < bit_width; bitindex++){
01086             buf[bitindex]='0';
01087         }
01088     }
01089     else{
01090         unsigned bit_mask = 1 << (bit_width-1);
01091         for (bitindex = 0; bitindex < bit_width; bitindex++) {
01092             buf[bitindex] = (object & bit_mask)? '1' : '0';
01093             bit_mask = bit_mask >> 1;
01094         }
01095     }
01096     buf[bitindex] = '\0';
01097     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
01098     old_value = object;
01099 }
01100 
01101 /*****************************************************************************/
01102 
01103 class wif_signed_int_trace: public wif_trace {
01104 public:
01105     wif_signed_int_trace(const int& object_,
01106              const std::string& name_,
01107              const std::string& wif_name_,
01108              int width_);
01109     void write(FILE* f);
01110     bool changed();
01111 
01112 protected:
01113     const int& object;
01114     int old_value;
01115     unsigned mask; 
01116 };
01117 
01118 
01119 wif_signed_int_trace::wif_signed_int_trace(const signed& object_,
01120                        const std::string& name_,
01121                        const std::string& wif_name_,
01122                        int width_) 
01123 : wif_trace(name_, wif_name_), object(object_)
01124 {
01125     bit_width = width_;
01126     if (bit_width < 32) {
01127         mask = ~(-1 << bit_width);
01128     } else {
01129         mask = 0xffffffff;
01130     }
01131 
01132     old_value = object;
01133     wif_type = "BIT";
01134 }
01135 
01136 
01137 bool wif_signed_int_trace::changed()
01138 {
01139     return object != old_value;
01140 }
01141 
01142 
01143 void wif_signed_int_trace::write(FILE* f)
01144 {
01145     char buf[1000];
01146     int bitindex;
01147 
01148     // Check for overflow
01149     if (((unsigned) object & mask) != (unsigned) object) {
01150         for (bitindex = 0; bitindex < bit_width; bitindex++){
01151             buf[bitindex]='0';
01152         }
01153     }
01154     else{
01155         unsigned bit_mask = 1 << (bit_width-1);
01156         for (bitindex = 0; bitindex < bit_width; bitindex++) {
01157             buf[bitindex] = (object & bit_mask)? '1' : '0';
01158             bit_mask = bit_mask >> 1;
01159         }
01160     }
01161     buf[bitindex] = '\0';
01162     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
01163     old_value = object;
01164 }
01165 
01166 /*****************************************************************************/
01167 
01168 class wif_signed_short_trace: public wif_trace {
01169 public:
01170     wif_signed_short_trace(const short& object_,
01171                const std::string& name_,
01172                const std::string& wif_name_,
01173                int width_);
01174     void write(FILE* f);
01175     bool changed();
01176 
01177 protected:
01178     const short& object;
01179     short old_value;
01180     unsigned short mask; 
01181 };
01182 
01183 
01184 wif_signed_short_trace::wif_signed_short_trace(const short& object_,
01185                        const std::string& name_,
01186                        const std::string& wif_name_,
01187                        int width_) 
01188 : wif_trace(name_, wif_name_), object(object_)
01189 {
01190     bit_width = width_;
01191     if (bit_width < 16) {
01192         mask = ~(-1 << bit_width);
01193     } else {
01194         mask = 0xffff;
01195     }
01196 
01197     old_value = object;
01198     wif_type = "BIT";
01199 }
01200 
01201 
01202 bool wif_signed_short_trace::changed()
01203 {
01204     return object != old_value;
01205 }
01206 
01207 
01208 void wif_signed_short_trace::write(FILE* f)
01209 {
01210     char buf[1000];
01211     int bitindex;
01212 
01213     // Check for overflow
01214     if (((unsigned short) object & mask) != (unsigned short) object) {
01215         for (bitindex = 0; bitindex < bit_width; bitindex++){
01216             buf[bitindex]='0';
01217         }
01218     }
01219     else{
01220         unsigned bit_mask = 1 << (bit_width-1);
01221         for (bitindex = 0; bitindex < bit_width; bitindex++) {
01222             buf[bitindex] = (object & bit_mask)? '1' : '0';
01223             bit_mask = bit_mask >> 1;
01224         }
01225     }
01226     buf[bitindex] = '\0';
01227     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
01228     old_value = object;
01229 }
01230 
01231 /*****************************************************************************/
01232 
01233 class wif_signed_char_trace: public wif_trace {
01234 public:
01235     wif_signed_char_trace(const char& object_,
01236               const std::string& name_,
01237               const std::string& wif_name_,
01238               int width_);
01239     void write(FILE* f);
01240     bool changed();
01241 
01242 protected:
01243     const char& object;
01244     char old_value;
01245     unsigned char mask; 
01246 };
01247 
01248 
01249 wif_signed_char_trace::wif_signed_char_trace(const char& object_,
01250                          const std::string& name_,
01251                          const std::string& wif_name_,
01252                          int width_) 
01253 : wif_trace(name_, wif_name_), object(object_)
01254 {
01255     bit_width = width_;
01256     if (bit_width < 8) {
01257         mask = ~(-1 << bit_width);
01258     } else {
01259         mask = 0xff;
01260     }
01261 
01262     old_value = object;
01263     wif_type = "BIT";
01264 }
01265 
01266 
01267 bool wif_signed_char_trace::changed()
01268 {
01269     return object != old_value;
01270 }
01271 
01272 
01273 void wif_signed_char_trace::write(FILE* f)
01274 {
01275     char buf[1000];
01276     int bitindex;
01277 
01278     // Check for overflow
01279     if (((unsigned char) object & mask) != (unsigned char) object) {
01280         for (bitindex = 0; bitindex < bit_width; bitindex++){
01281             buf[bitindex]='0';
01282         }
01283     }
01284     else{
01285         unsigned bit_mask = 1 << (bit_width-1);
01286         for (bitindex = 0; bitindex < bit_width; bitindex++) {
01287             buf[bitindex] = (object & bit_mask)? '1' : '0';
01288             bit_mask = bit_mask >> 1;
01289         }
01290     }
01291     buf[bitindex] = '\0';
01292     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
01293     old_value = object;
01294 }
01295 
01296 /*****************************************************************************/
01297 
01298 class wif_signed_long_trace: public wif_trace {
01299 public:
01300     wif_signed_long_trace(const long& object_,
01301               const std::string& name_,
01302               const std::string& wif_name_,
01303               int width_);
01304     void write(FILE* f);
01305     bool changed();
01306 
01307 protected:
01308     const long& object;
01309     long old_value;
01310     unsigned long mask; 
01311 };
01312 
01313 
01314 wif_signed_long_trace::wif_signed_long_trace(const long& object_,
01315                          const std::string& name_,
01316                          const std::string& wif_name_,
01317                          int width_) 
01318 : wif_trace(name_, wif_name_), object(object_)
01319 {
01320     bit_width = width_;
01321     if (bit_width < 32) {
01322         mask = ~(-1 << bit_width);
01323     } else {
01324         mask = 0xffffffff;
01325     }
01326 
01327     old_value = object;
01328     wif_type = "BIT";
01329 }
01330 
01331 
01332 bool wif_signed_long_trace::changed()
01333 {
01334     return object != old_value;
01335 }
01336 
01337 
01338 void wif_signed_long_trace::write(FILE* f)
01339 {
01340     char buf[1000];
01341     int bitindex;
01342 
01343     // Check for overflow
01344     if (((unsigned long) object & mask) != (unsigned long) object) {
01345         for (bitindex = 0; bitindex < bit_width; bitindex++){
01346             buf[bitindex]='0';
01347         }
01348     } else {
01349         unsigned bit_mask = 1 << (bit_width-1);
01350         for (bitindex = 0; bitindex < bit_width; bitindex++) {
01351             buf[bitindex] = (object & bit_mask)? '1' : '0';
01352             bit_mask = bit_mask >> 1;
01353         }
01354     }
01355     buf[bitindex] = '\0';
01356     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf); 
01357     old_value = object;
01358 }
01359 
01360 
01361 /*****************************************************************************/
01362 
01363 class wif_float_trace: public wif_trace {
01364 public:
01365     wif_float_trace(const float& object_,
01366             const std::string& name_,
01367             const std::string& wif_name_);
01368     void write(FILE* f);
01369     bool changed();
01370 
01371 protected:    
01372     const float& object;
01373     float old_value;
01374 };
01375 
01376 wif_float_trace::wif_float_trace(const float& object_,
01377                  const std::string& name_,
01378                  const std::string& wif_name_)
01379 : wif_trace(name_, wif_name_), object(object_)
01380 {
01381     bit_width = 0;
01382     old_value = object;
01383     wif_type = "real";
01384 }
01385 
01386 bool wif_float_trace::changed()
01387 {
01388     return object != old_value;
01389 }
01390 
01391 void wif_float_trace::write(FILE* f)
01392 {
01393     std::fprintf(f,"assign  %s %f ; \n", wif_name.c_str(), object);
01394     old_value = object;
01395 }
01396 
01397 /*****************************************************************************/
01398 
01399 class wif_double_trace: public wif_trace {
01400 public:
01401     wif_double_trace(const double& object_,
01402              const std::string& name_,
01403              const std::string& wif_name_);
01404     void write(FILE* f);
01405     bool changed();
01406 
01407 protected:    
01408     const double& object;
01409     double old_value;
01410 };
01411 
01412 wif_double_trace::wif_double_trace(const double& object_,
01413                    const std::string& name_,
01414                    const std::string& wif_name_)
01415 : wif_trace(name_, wif_name_), object(object_)
01416 {
01417     bit_width = 0;
01418     old_value = object;
01419     wif_type = "real";
01420 }
01421 
01422 bool wif_double_trace::changed()
01423 {
01424     return object != old_value;
01425 }
01426 
01427 void wif_double_trace::write(FILE* f)
01428 {
01429     std::fprintf(f,"assign  %s %f ; \n", wif_name.c_str(), object);
01430     old_value = object;
01431 }
01432 
01433 
01434 /*****************************************************************************/
01435 
01436 class wif_enum_trace : public wif_trace {
01437 public:
01438     wif_enum_trace(const unsigned& object_,
01439            const std::string& name_,
01440            const std::string& wif_name_,
01441            const char** enum_literals);
01442     void write(FILE* f);
01443     bool changed();
01444     // Hides the definition of the same (virtual) function in wif_trace
01445     void print_variable_declaration_line(FILE* f);
01446 
01447 protected:
01448     const unsigned& object;
01449     unsigned old_value;
01450     
01451     const char** literals;
01452     unsigned nliterals;
01453     std::string type_name;
01454 
01455     ~wif_enum_trace();
01456 };
01457 
01458 
01459 wif_enum_trace::wif_enum_trace(const unsigned& object_,
01460                    const std::string& name_,
01461                    const std::string& wif_name_,
01462                    const char** enum_literals_) 
01463 : wif_trace(name_, wif_name_), object(object_), literals(enum_literals_)
01464 {
01465     // find number of enumeration literals - counting loop
01466     for (nliterals = 0; enum_literals_[nliterals]; nliterals++);
01467 
01468     bit_width = 0;
01469     old_value = object;
01470     type_name = name_ + "__type__";
01471     wif_type = type_name.c_str();
01472 }       
01473 
01474 void wif_enum_trace::print_variable_declaration_line(FILE* f)
01475 {
01476     std::fprintf(f, "type scalar \"%s\" enum ", wif_type);
01477 
01478     for (unsigned i = 0; i < nliterals; i++)
01479       std::fprintf(f, "\"%s\", ", literals[i]);
01480     std::fprintf(f, "\"SC_WIF_UNDEF\" ;\n");
01481 
01482     std::fprintf(f, "declare  %s   \"%s\"  \"%s\" ",
01483         wif_name.c_str(), name.c_str(), wif_type);
01484     std::fprintf(f, "variable ;\n");
01485     std::fprintf(f, "start_trace %s ;\n", wif_name.c_str());
01486 }
01487 
01488 bool wif_enum_trace::changed()
01489 {
01490     return object != old_value;
01491 }
01492 
01493 void wif_enum_trace::write(FILE* f)
01494 {
01495     char buf[2000];
01496     static bool warning_issued = false;
01497 
01498     if (object >= nliterals) { // Note unsigned value is always greater than 0
01499         if (!warning_issued) {
01500         std::sprintf(buf, "Tracing error: Value of enumerated type undefined");
01501         put_error_message(buf, false);
01502         warning_issued = true;
01503     }
01504     std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(),
01505         "SC_WIF_UNDEF");
01506     }
01507     else 
01508         std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(),
01509         literals[object]);
01510     old_value = object;
01511 }
01512 
01513 wif_enum_trace::~wif_enum_trace()
01514 {
01515     /* Intentionally blank */
01516 }
01517 
01518 
01519 template <class T>
01520 class wif_T_trace
01521 : public wif_trace
01522 {
01523 public:
01524 
01525     wif_T_trace( const T& object_,
01526          const std::string& name_,
01527          const std::string& wif_name_,
01528          wif_trace_file::wif_enum type_ )
01529     : wif_trace( name_, wif_name_),
01530       object( object_ ),
01531       old_value( object_ )
01532     {  wif_type = wif_names[type_]; }
01533 
01534     void write( FILE* f )
01535     {
01536        std::fprintf( f,
01537         "assign %s \"%s\" ;\n",
01538         wif_name.c_str(),
01539         object.to_string().c_str() );
01540        old_value = object;
01541     }
01542 
01543     bool changed()
01544         { return !(object == old_value); }
01545 
01546     void set_width()
01547         { bit_width = object.length(); }
01548 
01549 protected:
01550 
01551     const T& object;
01552     T        old_value;
01553 };
01554 
01555 typedef wif_T_trace<sc_dt::sc_bv_base> wif_sc_bv_trace;
01556 typedef wif_T_trace<sc_dt::sc_lv_base> wif_sc_lv_trace;
01557 
01558 
01559 //***********************************************************************
01560 //           wif_trace_file functions
01561 //***********************************************************************
01562 
01563 
01564 wif_trace_file::wif_trace_file(const char * name)
01565 {
01566     std::string file_name = name ;
01567     file_name += ".awif";
01568     fp = fopen(file_name.c_str(), "w");
01569     if (!fp) {
01570         std::string msg = 
01571         std::string("Cannot write trace file '") + file_name +
01572         "'";
01573     ::std::cerr << "FATAL: " << msg << "\n";
01574         exit(1);
01575     }
01576     trace_delta_cycles = false; // make it the default
01577     initialized = false;
01578     wif_name_index = 0;
01579 
01580     // default time step is the time resolution
01581     timescale_unit = sc_get_time_resolution().to_seconds();
01582 
01583     timescale_set_by_user = false;
01584 }
01585 
01586 
01587 void wif_trace_file::initialize()
01588 {
01589     char buf[2000];
01590 
01591     // init
01592     std::fprintf(fp, "init ;\n\n");
01593 
01594     //timescale:
01595     if     (timescale_unit == 1e-15) std::sprintf(buf,"0");
01596     else if(timescale_unit == 1e-14) std::sprintf(buf,"1");
01597     else if(timescale_unit == 1e-13) std::sprintf(buf,"2");
01598     else if(timescale_unit == 1e-12) std::sprintf(buf,"3");
01599     else if(timescale_unit == 1e-11) std::sprintf(buf,"4");
01600     else if(timescale_unit == 1e-10) std::sprintf(buf,"5");
01601     else if(timescale_unit == 1e-9)  std::sprintf(buf,"6");
01602     else if(timescale_unit == 1e-8)  std::sprintf(buf,"7");
01603     else if(timescale_unit == 1e-7)  std::sprintf(buf,"8");
01604     else if(timescale_unit == 1e-6)  std::sprintf(buf,"9");
01605     else if(timescale_unit == 1e-5)  std::sprintf(buf,"10");
01606     else if(timescale_unit == 1e-4)  std::sprintf(buf,"11");
01607     else if(timescale_unit == 1e-3)  std::sprintf(buf,"12");
01608     else if(timescale_unit == 1e-2)  std::sprintf(buf,"13");
01609     else if(timescale_unit == 1e-1)  std::sprintf(buf,"14");
01610     else if(timescale_unit == 1e0)   std::sprintf(buf,"15");
01611     else if(timescale_unit == 1e1)   std::sprintf(buf,"16");
01612     else if(timescale_unit == 1e2)   std::sprintf(buf,"17");
01613     std::fprintf(fp,"header  %s \"%s\" ;\n\n", buf, sc_version());
01614 
01615     //date:
01616     time_t long_time;
01617     time(&long_time);
01618     struct tm* p_tm;
01619     p_tm = localtime(&long_time);
01620     strftime(buf, 199, "%b %d, %Y       %H:%M:%S", p_tm);
01621     std::fprintf(fp, "comment \"ASCII WIF file produced on date:  %s\" ;\n", buf);
01622  
01623     //version:
01624     std::fprintf(fp, "comment \"Created by %s\" ;\n", sc_version());
01625     //conversion info
01626     std::fprintf(fp, "comment \"Convert this file to binary WIF format using a2wif\" ;\n\n");
01627 
01628 
01629     running_regression = ( getenv( "SYSTEMC_REGRESSION" ) != NULL );
01630     // Don't print message if running regression
01631     if( ! timescale_set_by_user && ! running_regression ) {
01632     ::std::cout << "WARNING: Default time step is used for WIF tracing." << ::std::endl;
01633     }
01634 
01635     // Define the two types we need to represent bool and sc_logic
01636     std::fprintf(fp, "type scalar \"BIT\" enum '0', '1' ;\n");
01637     std::fprintf(fp, "type scalar \"MVL\" enum '0', '1', 'X', 'Z', '?' ;\n");
01638     std::fprintf(fp, "\n");
01639 
01640     //variable definitions:
01641     int i;
01642     for (i = 0; i < (int)traces.size(); i++) {
01643         wif_trace* t = traces[i];
01644         t->set_width(); //needed for all vectors
01645         t->print_variable_declaration_line(fp);
01646     }
01647 
01648     double inittime = sc_time_stamp().to_seconds();
01649     previous_time = inittime/timescale_unit;
01650 
01651     // Dump all values at initial time
01652     std::sprintf(buf,
01653             "All initial values are dumped below at time "
01654             "%g sec = %g timescale units.",
01655             inittime,
01656             inittime/timescale_unit
01657             );
01658     write_comment(buf);
01659 
01660     double_to_special_int64(inittime/timescale_unit,
01661                 &previous_time_units_high,
01662                 &previous_time_units_low );
01663 
01664     for (i = 0; i < (int)traces.size(); i++) {
01665         wif_trace* t = traces[i];
01666         t->write(fp);
01667     }
01668 }
01669 
01670 // ----------------------------------------------------------------------------
01671 
01672 #define DEFN_TRACE_METHOD(tp)                                                 \
01673 void                                                                          \
01674 wif_trace_file::trace( const tp& object_, const std::string& name_ )     \
01675 {                                                                             \
01676     if( initialized ) {                                                       \
01677         put_error_message(                                                \
01678         "No traces can be added once simulation has started.\n"           \
01679             "To add traces, create a new wif trace file.", false );           \
01680     }                                                                         \
01681     std::string temp_wif_name;                                           \
01682     create_wif_name( &temp_wif_name );                                        \
01683     traces.push_back( new wif_ ## tp ## _trace( object_,                      \
01684                         name_,                        \
01685                         temp_wif_name ) );            \
01686 }
01687 
01688 DEFN_TRACE_METHOD(bool)
01689 DEFN_TRACE_METHOD(float)
01690 DEFN_TRACE_METHOD(double)
01691 
01692 #undef DEFN_TRACE_METHOD
01693 #define DEFN_TRACE_METHOD(tp)                                                 \
01694 void                                                                          \
01695 wif_trace_file::trace(const sc_dt::tp& object_, const std::string& name_)\
01696 {                                                                             \
01697     if( initialized ) {                                                       \
01698         put_error_message(                                                \
01699         "No traces can be added once simulation has started.\n"               \
01700             "To add traces, create a new wif trace file.", false );           \
01701     }                                                                         \
01702     std::string temp_wif_name;                                           \
01703     create_wif_name( &temp_wif_name );                                        \
01704     traces.push_back( new wif_ ## tp ## _trace( object_,                      \
01705                         name_,                        \
01706                         temp_wif_name ) );            \
01707 }
01708 
01709 DEFN_TRACE_METHOD(sc_bit)
01710 DEFN_TRACE_METHOD(sc_logic)
01711 
01712 DEFN_TRACE_METHOD(sc_signed)
01713 DEFN_TRACE_METHOD(sc_unsigned)
01714 DEFN_TRACE_METHOD(sc_int_base)
01715 DEFN_TRACE_METHOD(sc_uint_base)
01716 
01717 DEFN_TRACE_METHOD(sc_fxval)
01718 DEFN_TRACE_METHOD(sc_fxval_fast)
01719 DEFN_TRACE_METHOD(sc_fxnum)
01720 DEFN_TRACE_METHOD(sc_fxnum_fast)
01721 
01722 #undef DEFN_TRACE_METHOD
01723 
01724 
01725 #define DEFN_TRACE_METHOD_SIGNED(tp)                                          \
01726 void                                                                          \
01727 wif_trace_file::trace( const tp&        object_,                              \
01728                        const std::string& name_,                         \
01729                        int              width_ )                              \
01730 {                                                                             \
01731     if( initialized ) {                                                       \
01732         put_error_message(                                                \
01733         "No traces can be added once simulation has started.\n"           \
01734             "To add traces, create a new wif trace file.", false );           \
01735     }                                                                         \
01736     std::string temp_wif_name;                                           \
01737     create_wif_name( &temp_wif_name );                                        \
01738     traces.push_back( new wif_signed_ ## tp ## _trace( object_,               \
01739                                name_,                 \
01740                                temp_wif_name,         \
01741                                                        width_ ) );            \
01742 }
01743 
01744 #define DEFN_TRACE_METHOD_UNSIGNED(tp)                                        \
01745 void                                                                          \
01746 wif_trace_file::trace( const unsigned tp& object_,                            \
01747                        const std::string&   name_,                       \
01748                        int                width_ )                            \
01749 {                                                                             \
01750     if( initialized ) {                                                       \
01751         put_error_message(                                                \
01752         "No traces can be added once simulation has started.\n"           \
01753             "To add traces, create a new wif trace file.", false );           \
01754     }                                                                         \
01755     std::string temp_wif_name;                                           \
01756     create_wif_name( &temp_wif_name );                                        \
01757     traces.push_back( new wif_unsigned_ ## tp ## _trace( object_,             \
01758                                  name_,               \
01759                                  temp_wif_name,       \
01760                                                          width_ ) );          \
01761 }
01762 
01763 DEFN_TRACE_METHOD_SIGNED(char)
01764 DEFN_TRACE_METHOD_SIGNED(short)
01765 DEFN_TRACE_METHOD_SIGNED(int)
01766 DEFN_TRACE_METHOD_SIGNED(long)
01767 
01768 DEFN_TRACE_METHOD_UNSIGNED(char)
01769 DEFN_TRACE_METHOD_UNSIGNED(short)
01770 DEFN_TRACE_METHOD_UNSIGNED(int)
01771 DEFN_TRACE_METHOD_UNSIGNED(long)
01772 
01773 #undef DEFN_TRACE_METHOD_SIGNED
01774 #undef DEFN_TRACE_METHOD_UNSIGNED
01775 
01776 
01777 #define DEFN_TRACE_METHOD_LONG_LONG(tp)                                       \
01778 void                                                                          \
01779 wif_trace_file::trace( const sc_dt::tp& object_,                              \
01780                        const std::string&   name_,                       \
01781                        int                width_ )                            \
01782 {                                                                             \
01783     if( initialized ) {                                                       \
01784         put_error_message(                                                \
01785         "No traces can be added once simulation has started.\n"           \
01786             "To add traces, create a new wif trace file.", false );           \
01787     }                                                                         \
01788     std::string temp_wif_name;                                           \
01789     create_wif_name( &temp_wif_name );                                        \
01790     traces.push_back( new wif_ ## tp ## _trace( object_,                      \
01791                         name_,                        \
01792                         temp_wif_name,                \
01793                                                 width_ ) );                   \
01794 }
01795 
01796 DEFN_TRACE_METHOD_LONG_LONG(int64)
01797 DEFN_TRACE_METHOD_LONG_LONG(uint64)
01798 #undef DEFN_TRACE_METHOD_LONG_LONG
01799 
01800 void
01801 wif_trace_file::trace( const unsigned& object_,
01802                const std::string& name_,
01803                const char** enum_literals_ )
01804 {
01805     if( initialized ) {
01806         put_error_message(
01807         "No traces can be added once simulation has started.\n"
01808         "To add traces, create a new wif trace file.", false );
01809     }
01810     std::string temp_wif_name;
01811     create_wif_name( &temp_wif_name );
01812     traces.push_back( new wif_enum_trace( object_,
01813                       name_,
01814                       temp_wif_name,
01815                       enum_literals_ ) );
01816 }
01817 
01818 void
01819 wif_trace_file::trace( const sc_dt::sc_bv_base& object_, 
01820     const std::string& name_ )
01821 {
01822    traceT( object_, name_, WIF_BIT );
01823 }
01824 
01825 void
01826 wif_trace_file::trace( const sc_dt::sc_lv_base& object_, 
01827     const std::string& name_ )
01828 {
01829    traceT( object_, name_, WIF_MVL );
01830 }
01831 
01832 
01833 void
01834 wif_trace_file::write_comment(const std::string& comment)
01835 {
01836     //no newline in comments allowed
01837     std::fprintf(fp, "comment \"%s\" ;\n", comment.c_str());
01838 }
01839 
01840 
01841 void
01842 wif_trace_file::delta_cycles(bool flag)
01843 {
01844     trace_delta_cycles = flag;
01845 }
01846 
01847 void
01848 wif_trace_file::cycle(bool this_is_a_delta_cycle)
01849 {
01850     unsigned now_units_high, now_units_low;
01851 
01852     // Trace delta cycles only when enabled
01853     if (!trace_delta_cycles && this_is_a_delta_cycle) return;
01854 
01855     // Check for initialization
01856     if (!initialized) {
01857         initialize();
01858         initialized = true;
01859         return;
01860     };
01861 
01862     // double now_units = sc_simulation_time() / timescale_unit;
01863     double now_units = sc_time_stamp().to_seconds() / timescale_unit;
01864     
01865     double_to_special_int64(now_units, &now_units_high, &now_units_low );
01866 
01867     // Now do the real stuff
01868     unsigned delta_units_high, delta_units_low;
01869     double diff_time;
01870     diff_time = now_units - previous_time;
01871     double_to_special_int64(diff_time, &delta_units_high, &delta_units_low);
01872     if (this_is_a_delta_cycle && (diff_time == 0.0))
01873     delta_units_low++; // Increment time for delta cycle simulation
01874     // Note that in the last statement above, we are assuming no more
01875     // than 2^32 delta cycles - seems realistic
01876     
01877     bool time_printed = false;
01878     wif_trace* const* const l_traces = &traces[0];
01879     for (int i = 0; i < (int)traces.size(); i++) {
01880         wif_trace* t = l_traces[i];
01881         if(t->changed()){
01882             if(time_printed == false){
01883                 if(delta_units_high){
01884                     std::fprintf(fp, "delta_time %u%09u ;\n", delta_units_high,
01885                 delta_units_low);
01886                 }
01887                 else{ 
01888                     std::fprintf(fp, "delta_time %u ;\n", delta_units_low);
01889                 }
01890                 time_printed = true;
01891             }
01892 
01893         // Write the variable
01894             t->write(fp);
01895         }
01896     }
01897 
01898     if(time_printed) {
01899         std::fprintf(fp, "\n");     // Put another newline
01900     // We update previous_time_units only when we print time because
01901     // this field stores the previous time that was printed, not the
01902     // previous time this function was called
01903     previous_time_units_high = now_units_high;
01904     previous_time_units_low = now_units_low;
01905     previous_time = now_units;
01906     }
01907 }
01908 
01909 // Create a WIF name for a variable
01910 void
01911 wif_trace_file::create_wif_name(std::string* ptr_to_str)
01912 {
01913     char buf[50];
01914     std::sprintf(buf,"O%d", wif_name_index);
01915     *ptr_to_str = buf; 
01916     wif_name_index++;
01917 }
01918 
01919 std::string
01920 wif_trace_file::obtain_new_index()
01921 {
01922     char buf[32];
01923     std::sprintf( buf, "O%d", wif_name_index ++ );
01924     return std::string( buf );
01925 }
01926 
01927 // Cleanup and close trace file
01928 wif_trace_file::~wif_trace_file()
01929 {
01930     int i;
01931     for (i = 0; i < (int)traces.size(); i++) {
01932         wif_trace* t = traces[i];
01933         delete t;
01934     }
01935     fclose(fp);
01936 }
01937 
01938 // Map sc_logic values to values understandable by WIF
01939 static char
01940 map_sc_logic_state_to_wif_state(char in_char)
01941 {
01942     char out_char;
01943 
01944     switch(in_char){
01945         case 'U':
01946         case 'X': 
01947         case 'W':
01948         case 'D':
01949             out_char = 'X';
01950             break;
01951         case '0':
01952         case 'L':
01953             out_char = '0';
01954             break;
01955         case  '1':
01956         case  'H': 
01957             out_char = '1';
01958             break;
01959         case  'Z': 
01960             out_char = 'Z';
01961             break;
01962         default:
01963             out_char = '?';
01964     }
01965     return out_char;
01966 }
01967 
01968 
01969 #if 0
01970 // no output should be done directly to ::std::cout, cerr, etc.
01971 void
01972 put_error_message(const char* msg, bool just_warning)
01973 {
01974     if(just_warning){
01975     ::std::cout << "WIF Trace Warning:\n" << msg << "\n" << ::std::endl;
01976     }
01977     else{
01978     ::std::cout << "WIF Trace ERROR:\n" << msg << "\n" << ::std::endl;
01979     }
01980 }
01981 #endif // 0
01982 
01983 // Create the trace file
01984 sc_trace_file*
01985 sc_create_wif_trace_file(const char * name)
01986 {
01987     sc_trace_file *tf;
01988 
01989     tf = new wif_trace_file(name);
01990     sc_get_curr_simcontext()->add_trace_file(tf);
01991     return tf;
01992 }
01993 
01994 void
01995 sc_close_wif_trace_file( sc_trace_file* tf )
01996 {
01997     wif_trace_file* wif_tf = (wif_trace_file*)tf;
01998     delete wif_tf;
01999 }
02000 
02001 } // namespace sc_core

Generated on Wed Jan 21 15:32:10 2009 for SystemC by  doxygen 1.5.5