1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_wif_trace.cpp - Implementation of WIF tracing.
23
24  Original Author - Abhijit Ghosh, Synopsys, Inc.
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
34  Description of Modification: - Replaced 'width' of sc_(u)int with their
35                                 'bitwidth()'.
36
37      Name, Affiliation, Date:
38  Description of Modification:
39
40 *****************************************************************************/
41
42/*****************************************************************************
43
44   Acknowledgement: The tracing mechanism is based on the tracing
45   mechanism developed at Infineon (formerly Siemens HL). Though this
46   code is somewhat different, and significantly enhanced, the basics
47   are identical to what was originally contributed by Infineon.  The
48   contribution of Infineon in the development of this tracing
49   technology is hereby acknowledged.
50
51 *****************************************************************************/
52
53/*****************************************************************************
54
55   Instead of creating the binary WIF format, we create the ASCII
56   WIF format which can be converted to the binary format using
57   a2wif (utility that comes with VSS from Synopsys). This way,
58   a user who does not have Synopsys VSS can still create WIF
59   files, but they can only be viewed by users who have VSS.
60
61 *****************************************************************************/
62
63
64#include <cstdlib>
65#include <vector>
66
67#define SC_DISABLE_API_VERSION_CHECK // for in-library sc_ver.h inclusion
68
69#include "sysc/kernel/sc_simcontext.h"
70#include "sysc/kernel/sc_ver.h"
71#include "sysc/datatypes/bit/sc_bit.h"
72#include "sysc/datatypes/bit/sc_logic.h"
73#include "sysc/datatypes/bit/sc_lv_base.h"
74#include "sysc/datatypes/int/sc_signed.h"
75#include "sysc/datatypes/int/sc_unsigned.h"
76#include "sysc/datatypes/int/sc_int_base.h"
77#include "sysc/datatypes/int/sc_uint_base.h"
78#include "sysc/datatypes/fx/fx.h"
79#include "sysc/tracing/sc_wif_trace.h"
80
81namespace sc_core {
82
83// Forward declarations for functions that come later in the file
84static char map_sc_logic_state_to_wif_state(char in_char);
85
86const char* wif_names[wif_trace_file::WIF_LAST] = {"BIT","MVL","real"};
87
88
89// ----------------------------------------------------------------------------
90//  CLASS : wif_trace
91//
92//  Base class for WIF traces.
93// ----------------------------------------------------------------------------
94
95class wif_trace
96{
97public:
98
99    wif_trace(const std::string& name_, const std::string& wif_name_);
100
101    // Needs to be pure virtual as has to be defined by the particular
102    // type being traced
103    virtual void write(FILE* f) = 0;
104
105    virtual void set_width();
106
107    // Comparison function needs to be pure virtual too
108    virtual bool changed() = 0;
109
110    // Got to declare this virtual as this will be overwritten
111    // by one base class
112    virtual void print_variable_declaration_line(FILE* f);
113
114    virtual ~wif_trace();
115
116    const std::string name;     // Name of the variable
117    const std::string wif_name; // Name of the variable in WIF file
118    const char* wif_type;     // WIF data type
119    int bit_width;
120};
121
122
123wif_trace::wif_trace(const std::string& name_,
124	const std::string& wif_name_)
125        : name(name_), wif_name(wif_name_), wif_type(0), bit_width(-1)
126{
127    /* Intentionally blank */
128}
129
130void
131wif_trace::print_variable_declaration_line( FILE* f )
132{
133    if( bit_width < 0 )
134    {
135        std::stringstream ss;
136        ss << "'" << name << "' has < 0 bits";
137        SC_REPORT_ERROR( SC_ID_TRACING_OBJECT_IGNORED_
138                       , ss.str().c_str() );
139        return;
140    }
141
142    std::fprintf( f, "declare  %s   \"%s\"  %s  ",
143                  wif_name.c_str(), name.c_str(), wif_type );
144
145    if( bit_width > 0 ) {
146        std::fprintf( f, "0 %d ", bit_width - 1 );
147    }
148    std::fprintf( f, "variable ;\n" );
149    std::fprintf( f, "start_trace %s ;\n", wif_name.c_str() );
150}
151
152void
153wif_trace::set_width()
154{
155    /* Intentionally Blank, should be defined for each type separately */
156}
157
158wif_trace::~wif_trace()
159{
160    /* Intentionally Blank */
161}
162
163// Classes for tracing individual data types
164
165/*****************************************************************************/
166
167class wif_uint64_trace: public wif_trace {
168public:
169    wif_uint64_trace(const sc_dt::uint64& object_,
170                const std::string& name_,
171                const std::string& wif_name_,
172                int width_);
173    void write(FILE* f);
174    bool changed();
175
176protected:
177    const sc_dt::uint64& object;
178    sc_dt::uint64 old_value;
179    sc_dt::uint64 mask;
180};
181
182
183wif_uint64_trace::wif_uint64_trace(const sc_dt::uint64& object_,
184                         const std::string& name_,
185                         const std::string& wif_name_,
186                         int width_)
187: wif_trace(name_, wif_name_), object(object_), old_value(object_),
188  mask(static_cast<sc_dt::uint64>(-1))
189{
190    bit_width = width_;
191    if (bit_width < (int)(sizeof(sc_dt::uint64)*BITS_PER_BYTE))
192        mask = ~(mask << bit_width);
193    wif_type = "BIT";
194}
195
196
197bool wif_uint64_trace::changed()
198{
199    return object != old_value;
200}
201
202
203void wif_uint64_trace::write(FILE* f)
204{
205    char buf[1000];
206    int bitindex;
207
208    // Check for overflow
209    if ((object & mask) != object)
210    {
211        for (bitindex = 0; bitindex < bit_width; bitindex++)
212        {
213            buf[bitindex]='0';
214        }
215    }
216    else
217    {
218        sc_dt::uint64 bit_mask = 1;
219        bit_mask = bit_mask << (bit_width-1);
220        for (bitindex = 0; bitindex < bit_width; bitindex++)
221        {
222            buf[bitindex] = (object & bit_mask)? '1' : '0';
223            bit_mask = bit_mask >> 1;
224        }
225    }
226    buf[bitindex] = '\0';
227    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
228    old_value = object;
229}
230
231/*****************************************************************************/
232
233class wif_int64_trace: public wif_trace {
234public:
235    wif_int64_trace(const sc_dt::int64& object_,
236                const std::string& name_,
237                const std::string& wif_name_,
238                int width_);
239    void write(FILE* f);
240    bool changed();
241
242protected:
243    const sc_dt::int64& object;
244    sc_dt::int64 old_value;
245    sc_dt::uint64 mask;
246};
247
248
249wif_int64_trace::wif_int64_trace(const sc_dt::int64& object_,
250                         const std::string& name_,
251                         const std::string& wif_name_,
252                         int width_)
253: wif_trace(name_, wif_name_), object(object_), old_value(object_),
254  mask(static_cast<sc_dt::uint64>(-1))
255{
256    bit_width = width_;
257    if (bit_width < (int)(sizeof(sc_dt::int64)*BITS_PER_BYTE))
258        mask = ~(mask << bit_width);
259    wif_type = "BIT";
260}
261
262
263bool wif_int64_trace::changed()
264{
265    return object != old_value;
266}
267
268
269void wif_int64_trace::write(FILE* f)
270{
271    char buf[1000];
272    int bitindex;
273
274    // Check for overflow
275    if ((object & mask) != (sc_dt::uint64)object)
276    {
277        for (bitindex = 0; bitindex < bit_width; bitindex++)
278        {
279            buf[bitindex]='0';
280        }
281    }
282    else
283    {
284        sc_dt::uint64 bit_mask = 1;
285        bit_mask = bit_mask << (bit_width-1);
286        for (bitindex = 0; bitindex < bit_width; bitindex++)
287        {
288            buf[bitindex] = (object & bit_mask)? '1' : '0';
289            bit_mask = bit_mask >> 1;
290        }
291    }
292    buf[bitindex] = '\0';
293    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
294    old_value = object;
295}
296
297/*****************************************************************************/
298
299class wif_bool_trace
300: public wif_trace
301{
302public:
303
304    wif_bool_trace( const bool& object_,
305		    const std::string& name_,
306		    const std::string& wif_name_ );
307    void write( FILE* f );
308    bool changed();
309
310protected:
311
312    const bool& object;
313    bool        old_value;
314};
315
316wif_bool_trace::wif_bool_trace( const bool& object_,
317				const std::string& name_,
318				const std::string& wif_name_ )
319: wif_trace( name_, wif_name_ ), object( object_ ), old_value( object_ )
320{
321    bit_width = 0;
322    wif_type = "BIT";
323}
324
325bool
326wif_bool_trace::changed()
327{
328    return object != old_value;
329}
330
331void
332wif_bool_trace::write( FILE* f )
333{
334    if( object == true ) {
335	std::fprintf( f, "assign %s \'1\' ;\n", wif_name.c_str() );
336    } else {
337	std::fprintf( f, "assign %s \'0\' ;\n", wif_name.c_str() );
338    }
339    old_value = object;
340}
341
342//*****************************************************************************
343
344class wif_sc_bit_trace : public wif_trace {
345public:
346    wif_sc_bit_trace(const sc_dt::sc_bit& object_,
347                     const std::string& name_,
348                     const std::string& wif_name_);
349    void write(FILE* f);
350    bool changed();
351
352protected:
353    const sc_dt::sc_bit& object;
354    sc_dt::sc_bit old_value;
355};
356
357wif_sc_bit_trace::wif_sc_bit_trace(const sc_dt::sc_bit& object_,
358				   const std::string& name_,
359				   const std::string& wif_name_)
360: wif_trace(name_, wif_name_), object(object_), old_value(object_)
361{
362    bit_width = 0;
363    wif_type = "BIT";
364}
365
366bool wif_sc_bit_trace::changed()
367{
368    return object != old_value;
369}
370
371void wif_sc_bit_trace::write(FILE* f)
372{
373    if (object == true) {
374        std::fprintf(f, "assign %s \'1\' ;\n", wif_name.c_str());
375    } else {
376	std::fprintf(f, "assign %s \'0\' ;\n", wif_name.c_str());
377    }
378    old_value = object;
379}
380
381/*****************************************************************************/
382
383class wif_sc_logic_trace: public wif_trace {
384public:
385    wif_sc_logic_trace(const sc_dt::sc_logic& object_,
386		       const std::string& name_,
387		       const std::string& wif_name_);
388    void write(FILE* f);
389    bool changed();
390
391protected:
392    const sc_dt::sc_logic& object;
393    sc_dt::sc_logic old_value;
394};
395
396
397wif_sc_logic_trace::wif_sc_logic_trace(const sc_dt::sc_logic& object_,
398				       const std::string& name_,
399				       const std::string& wif_name_)
400: wif_trace(name_, wif_name_), object(object_), old_value(object_)
401{
402    bit_width = 0;
403    wif_type = "MVL";
404}
405
406
407bool wif_sc_logic_trace::changed()
408{
409    return object != old_value;
410}
411
412
413void wif_sc_logic_trace::write(FILE* f)
414{
415    char wif_char;
416    std::fprintf(f, "assign %s \'", wif_name.c_str());
417    wif_char = map_sc_logic_state_to_wif_state(object.to_char());
418    std::fputc(wif_char, f);
419    std::fprintf(f,"\' ;\n");
420    old_value = object;
421}
422
423
424/*****************************************************************************/
425
426class wif_sc_unsigned_trace: public wif_trace {
427public:
428    wif_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,
429			  const std::string& name_,
430			  const std::string& wif_name_);
431    void write(FILE* f);
432    bool changed();
433    void set_width();
434
435protected:
436    const sc_dt::sc_unsigned& object;
437    sc_dt::sc_unsigned old_value;
438};
439
440
441wif_sc_unsigned_trace::wif_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,
442					     const std::string& name_,
443					     const std::string& wif_name_)
444: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
445{
446    old_value = object;
447    wif_type = "BIT";
448}
449
450bool wif_sc_unsigned_trace::changed()
451{
452    return object != old_value;
453}
454
455void wif_sc_unsigned_trace::write(FILE* f)
456{
457    static std::vector<char> buf(1024);
458    typedef std::vector<char>::size_type size_t;
459
460    if ( buf.size() < (size_t)object.length() ) {
461        size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1));
462        std::vector<char>( sz ).swap( buf ); // resize without copying values
463    }
464    char *buf_ptr = &buf[0];
465
466    for(int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
467        *buf_ptr++ = "01"[object[bitindex].to_bool()];
468    }
469    *buf_ptr = '\0';
470    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
471    old_value = object;
472}
473
474void wif_sc_unsigned_trace::set_width()
475{
476    bit_width = object.length();
477}
478
479
480/*****************************************************************************/
481
482class wif_sc_signed_trace: public wif_trace {
483public:
484    wif_sc_signed_trace(const sc_dt::sc_signed& object_,
485			const std::string& name_,
486			const std::string& wif_name_);
487    void write(FILE* f);
488    bool changed();
489    void set_width();
490
491protected:
492    const sc_dt::sc_signed& object;
493    sc_dt::sc_signed old_value;
494};
495
496
497wif_sc_signed_trace::wif_sc_signed_trace(const sc_dt::sc_signed& object_,
498					 const std::string& name_,
499					 const std::string& wif_name_)
500: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
501{
502    old_value = object;
503    wif_type = "BIT";
504}
505
506bool wif_sc_signed_trace::changed()
507{
508    return object != old_value;
509}
510
511void wif_sc_signed_trace::write(FILE* f)
512{
513    static std::vector<char> buf(1024);
514    typedef std::vector<char>::size_type size_t;
515
516    if ( buf.size() < (size_t)object.length() ) {
517        size_t sz = ( (size_t)object.length() + 4096 ) & (~(size_t)(4096-1));
518        std::vector<char>( sz ).swap( buf ); // resize without copying values
519    }
520    char *buf_ptr = &buf[0];
521
522    for(int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
523        *buf_ptr++ = "01"[object[bitindex].to_bool()];
524    }
525    *buf_ptr = '\0';
526
527    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
528    old_value = object;
529}
530
531void wif_sc_signed_trace::set_width()
532{
533    bit_width = object.length();
534}
535
536/*****************************************************************************/
537
538class wif_sc_uint_base_trace: public wif_trace {
539public:
540    wif_sc_uint_base_trace(const sc_dt::sc_uint_base& object_,
541			   const std::string& name_,
542			   const std::string& wif_name_);
543    void write(FILE* f);
544    bool changed();
545    void set_width();
546
547protected:
548    const sc_dt::sc_uint_base& object;
549    sc_dt::sc_uint_base old_value;
550};
551
552
553wif_sc_uint_base_trace::wif_sc_uint_base_trace(
554                                          const sc_dt::sc_uint_base& object_,
555					  const std::string& name_,
556					  const std::string& wif_name_)
557: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
558{
559    old_value = object;
560    wif_type = "BIT";
561}
562
563bool wif_sc_uint_base_trace::changed()
564{
565    return object != old_value;
566}
567
568void wif_sc_uint_base_trace::write(FILE* f)
569{
570    char buf[1000], *buf_ptr = buf;
571
572    int bitindex;
573    for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
574        *buf_ptr++ = "01"[object[bitindex].to_bool()];
575    }
576    *buf_ptr = '\0';
577    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
578    old_value = object;
579}
580
581void wif_sc_uint_base_trace::set_width()
582{
583    bit_width = object.length();
584}
585
586
587/*****************************************************************************/
588
589class wif_sc_int_base_trace: public wif_trace {
590public:
591    wif_sc_int_base_trace(const sc_dt::sc_int_base& object_,
592			  const std::string& name_,
593			  const std::string& wif_name_);
594    void write(FILE* f);
595    bool changed();
596    void set_width();
597
598protected:
599    const sc_dt::sc_int_base& object;
600    sc_dt::sc_int_base old_value;
601};
602
603
604wif_sc_int_base_trace::wif_sc_int_base_trace(const sc_dt::sc_int_base& object_,
605					     const std::string& name_,
606					     const std::string& wif_name_)
607: wif_trace(name_, wif_name_), object(object_), old_value(object_.length())
608{
609    old_value = object;
610    wif_type = "BIT";
611}
612
613bool wif_sc_int_base_trace::changed()
614{
615    return object != old_value;
616}
617
618void wif_sc_int_base_trace::write(FILE* f)
619{
620    char buf[1000], *buf_ptr = buf;
621
622    int bitindex;
623    for(bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
624        *buf_ptr++ = "01"[object[bitindex].to_bool()];
625    }
626    *buf_ptr = '\0';
627
628    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
629    old_value = object;
630}
631
632void wif_sc_int_base_trace::set_width()
633{
634    bit_width = object.length();
635}
636
637
638/*****************************************************************************/
639
640class wif_sc_fxval_trace: public wif_trace
641{
642public:
643
644    wif_sc_fxval_trace( const sc_dt::sc_fxval& object_,
645			const std::string& name_,
646			const std::string& wif_name_ );
647    void write( FILE* f );
648    bool changed();
649
650protected:
651
652    const sc_dt::sc_fxval& object;
653    sc_dt::sc_fxval old_value;
654
655};
656
657wif_sc_fxval_trace::wif_sc_fxval_trace( const sc_dt::sc_fxval& object_,
658				        const std::string& name_,
659					const std::string& wif_name_ )
660: wif_trace( name_, wif_name_ ), object( object_ ), old_value( object_ )
661{
662    bit_width = 0;
663    wif_type = "real";
664}
665
666bool
667wif_sc_fxval_trace::changed()
668{
669    return object != old_value;
670}
671
672void
673wif_sc_fxval_trace::write( FILE* f )
674{
675    std::fprintf( f, "assign  %s %f ; \n", wif_name.c_str(), object.to_double() );
676    old_value = object;
677}
678
679/*****************************************************************************/
680
681class wif_sc_fxval_fast_trace: public wif_trace
682{
683public:
684
685    wif_sc_fxval_fast_trace( const sc_dt::sc_fxval_fast& object_,
686			     const std::string& name_,
687			     const std::string& wif_name_ );
688    void write( FILE* f );
689    bool changed();
690
691protected:
692
693    const sc_dt::sc_fxval_fast& object;
694    sc_dt::sc_fxval_fast old_value;
695
696};
697
698wif_sc_fxval_fast_trace::wif_sc_fxval_fast_trace(
699                                const sc_dt::sc_fxval_fast& object_,
700				const std::string& name_,
701				const std::string& wif_name_ )
702: wif_trace(name_, wif_name_), object( object_ ), old_value( object_ )
703{
704    bit_width = 0;
705    wif_type = "real";
706}
707
708bool
709wif_sc_fxval_fast_trace::changed()
710{
711    return object != old_value;
712}
713
714void
715wif_sc_fxval_fast_trace::write( FILE* f )
716{
717    std::fprintf( f, "assign  %s %f ; \n", wif_name.c_str(), object.to_double() );
718    old_value = object;
719}
720
721/*****************************************************************************/
722
723class wif_sc_fxnum_trace: public wif_trace
724{
725public:
726
727    wif_sc_fxnum_trace( const sc_dt::sc_fxnum& object_,
728			const std::string& name_,
729			const std::string& wif_name_ );
730    void write( FILE* f );
731    bool changed();
732    void set_width();
733
734protected:
735
736    const sc_dt::sc_fxnum& object;
737    sc_dt::sc_fxnum old_value;
738
739};
740
741wif_sc_fxnum_trace::wif_sc_fxnum_trace( const sc_dt::sc_fxnum& object_,
742				        const std::string& name_,
743					const std::string& wif_name_ )
744: wif_trace( name_, wif_name_ ),
745  object( object_ ),
746  old_value( object_.m_params.type_params(),
747	     object_.m_params.enc(),
748	     object_.m_params.cast_switch(),
749	     0 )
750{
751    old_value = object;
752    wif_type = "BIT";
753}
754
755bool
756wif_sc_fxnum_trace::changed()
757{
758    return object != old_value;
759}
760
761void
762wif_sc_fxnum_trace::write( FILE* f )
763{
764    static std::vector<char> buf(1024);
765    typedef std::vector<char>::size_type size_t;
766
767    if ( buf.size() < (size_t)object.wl() ) {
768        size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1));
769        std::vector<char>( sz ).swap( buf ); // resize without copying values
770    }
771    char *buf_ptr = &buf[0];
772
773    for(int bitindex = object.wl() - 1; bitindex >= 0; --bitindex)
774    {
775        *buf_ptr ++ = "01"[object[bitindex]];
776    }
777    *buf_ptr = '\0';
778
779    std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
780    old_value = object;
781}
782
783void
784wif_sc_fxnum_trace::set_width()
785{
786    bit_width = object.wl();
787}
788
789/*****************************************************************************/
790
791class wif_sc_fxnum_fast_trace: public wif_trace
792{
793public:
794
795    wif_sc_fxnum_fast_trace( const sc_dt::sc_fxnum_fast& object_,
796			     const std::string& name_,
797			     const std::string& wif_name_ );
798    void write( FILE* f );
799    bool changed();
800    void set_width();
801
802protected:
803
804    const sc_dt::sc_fxnum_fast& object;
805    sc_dt::sc_fxnum_fast old_value;
806
807};
808
809wif_sc_fxnum_fast_trace::wif_sc_fxnum_fast_trace(
810				const sc_dt::sc_fxnum_fast& object_,
811				const std::string& name_,
812				const std::string& wif_name_ )
813: wif_trace( name_, wif_name_ ),
814  object( object_ ),
815  old_value( object_.m_params.type_params(),
816	     object_.m_params.enc(),
817	     object_.m_params.cast_switch(),
818	     0 )
819{
820    old_value = object;
821    wif_type = "BIT";
822}
823
824bool
825wif_sc_fxnum_fast_trace::changed()
826{
827    return object != old_value;
828}
829
830void
831wif_sc_fxnum_fast_trace::write( FILE* f )
832{
833    static std::vector<char> buf(1024);
834    typedef std::vector<char>::size_type size_t;
835
836    if ( buf.size() < (size_t)object.wl() ) {
837        size_t sz = ( (size_t)object.wl() + 4096 ) & (~(size_t)(4096-1));
838        std::vector<char>( sz ).swap( buf ); // resize without copying values
839    }
840    char *buf_ptr = &buf[0];
841
842    for(int bitindex = object.wl() - 1; bitindex >= 0; --bitindex)
843    {
844        *buf_ptr ++ = "01"[object[bitindex]];
845    }
846    *buf_ptr = '\0';
847
848    std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), &buf[0]);
849    old_value = object;
850}
851
852void
853wif_sc_fxnum_fast_trace::set_width()
854{
855    bit_width = object.wl();
856}
857
858
859/*****************************************************************************/
860
861class wif_unsigned_int_trace: public wif_trace {
862public:
863    wif_unsigned_int_trace(const unsigned& object_,
864			   const std::string& name_,
865			   const std::string& wif_name_, int width_);
866    void write(FILE* f);
867    bool changed();
868
869protected:
870    const unsigned& object;
871    unsigned old_value;
872    unsigned mask;
873};
874
875
876wif_unsigned_int_trace::wif_unsigned_int_trace(const unsigned& object_,
877					   const std::string& name_,
878					   const std::string& wif_name_,
879					   int width_)
880: wif_trace(name_, wif_name_), object(object_), old_value(object_),
881  mask(0xffffffff)
882{
883    bit_width = width_;
884    if (bit_width < 32) {
885        mask = ~(-1 << bit_width);
886    }
887
888    wif_type = "BIT";
889}
890
891
892bool wif_unsigned_int_trace::changed()
893{
894    return object != old_value;
895}
896
897
898void wif_unsigned_int_trace::write(FILE* f)
899{
900    char buf[1000];
901    int bitindex;
902
903    // Check for overflow
904    if ((object & mask) != object) {
905        for (bitindex = 0; bitindex < bit_width; bitindex++){
906            buf[bitindex] = '0';
907        }
908    }
909    else{
910        unsigned bit_mask = 1 << (bit_width-1);
911        for (bitindex = 0; bitindex < bit_width; bitindex++) {
912            buf[bitindex] = (object & bit_mask)? '1' : '0';
913            bit_mask = bit_mask >> 1;
914        }
915    }
916    buf[bitindex] = '\0';
917    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
918    old_value = object;
919}
920
921
922/*****************************************************************************/
923
924class wif_unsigned_short_trace: public wif_trace {
925public:
926    wif_unsigned_short_trace(const unsigned short& object_,
927			     const std::string& name_,
928			     const std::string& wif_name_,
929			     int width_);
930    void write(FILE* f);
931    bool changed();
932
933protected:
934    const unsigned short& object;
935    unsigned short old_value;
936    unsigned short mask;
937};
938
939
940wif_unsigned_short_trace::wif_unsigned_short_trace(
941	const unsigned short& object_,
942       const std::string& name_,
943       const std::string& wif_name_,
944       int width_)
945: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xffff)
946{
947    bit_width = width_;
948    if (bit_width < 16) {
949        mask = (unsigned short)~(-1 << bit_width);
950    }
951
952    wif_type = "BIT";
953}
954
955
956bool wif_unsigned_short_trace::changed()
957{
958    return object != old_value;
959}
960
961
962void wif_unsigned_short_trace::write(FILE* f)
963{
964    char buf[1000];
965    int bitindex;
966
967    // Check for overflow
968    if ((object & mask) != object) {
969        for (bitindex = 0; bitindex < bit_width; bitindex++){
970            buf[bitindex]='0';
971        }
972    }
973    else{
974        unsigned bit_mask = 1 << (bit_width-1);
975        for (bitindex = 0; bitindex < bit_width; bitindex++) {
976            buf[bitindex] = (object & bit_mask)? '1' : '0';
977            bit_mask = bit_mask >> 1;
978        }
979    }
980    buf[bitindex] = '\0';
981    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
982    old_value = object;
983}
984
985/*****************************************************************************/
986
987class wif_unsigned_char_trace: public wif_trace {
988public:
989    wif_unsigned_char_trace(const unsigned char& object_,
990			    const std::string& name_,
991			    const std::string& wif_name_,
992			    int width_);
993    void write(FILE* f);
994    bool changed();
995
996protected:
997    const unsigned char& object;
998    unsigned char old_value;
999    unsigned char mask;
1000};
1001
1002
1003wif_unsigned_char_trace::wif_unsigned_char_trace(const unsigned char& object_,
1004					 const std::string& name_,
1005					 const std::string& wif_name_,
1006					 int width_)
1007: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xff)
1008{
1009    bit_width = width_;
1010    if (bit_width < 8) {
1011        mask = (unsigned char)~(-1 << bit_width);
1012    }
1013
1014    wif_type = "BIT";
1015}
1016
1017
1018bool wif_unsigned_char_trace::changed()
1019{
1020    return object != old_value;
1021}
1022
1023
1024void wif_unsigned_char_trace::write(FILE* f)
1025{
1026    char buf[1000];
1027    int bitindex;
1028
1029    // Check for overflow
1030    if ((object & mask) != object) {
1031        for (bitindex = 0; bitindex < bit_width; bitindex++){
1032            buf[bitindex]='0';
1033        }
1034    }
1035    else{
1036        unsigned bit_mask = 1 << (bit_width-1);
1037        for (bitindex = 0; bitindex < bit_width; bitindex++) {
1038            buf[bitindex] = (object & bit_mask)? '1' : '0';
1039            bit_mask = bit_mask >> 1;
1040        }
1041    }
1042    buf[bitindex] = '\0';
1043    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
1044    old_value = object;
1045}
1046
1047/*****************************************************************************/
1048
1049class wif_unsigned_long_trace: public wif_trace {
1050public:
1051    wif_unsigned_long_trace(const unsigned long& object_,
1052			    const std::string& name_,
1053			    const std::string& wif_name_,
1054			    int width_);
1055    void write(FILE* f);
1056    bool changed();
1057
1058protected:
1059    const unsigned long& object;
1060    unsigned long old_value;
1061    unsigned long mask;
1062};
1063
1064
1065wif_unsigned_long_trace::wif_unsigned_long_trace(const unsigned long& object_,
1066					     const std::string& name_,
1067					     const std::string& wif_name_,
1068					     int width_)
1069: wif_trace(name_, wif_name_), object(object_), old_value(object_),
1070  mask((unsigned long)-1L)
1071{
1072    bit_width = width_;
1073    if (bit_width < (int)(sizeof(unsigned long)*BITS_PER_BYTE)) {
1074        mask = ~(-1L << bit_width);
1075    }
1076
1077    wif_type = "BIT";
1078}
1079
1080
1081bool wif_unsigned_long_trace::changed()
1082{
1083    return object != old_value;
1084}
1085
1086
1087void wif_unsigned_long_trace::write(FILE* f)
1088{
1089    char buf[1000];
1090    int bitindex;
1091
1092    // Check for overflow
1093    if ((object & mask) != object) {
1094        for (bitindex = 0; bitindex < bit_width; bitindex++){
1095            buf[bitindex]='0';
1096        }
1097    }
1098    else{
1099        unsigned long bit_mask = 1ul << (bit_width-1);
1100        for (bitindex = 0; bitindex < bit_width; bitindex++) {
1101            buf[bitindex] = (object & bit_mask)? '1' : '0';
1102            bit_mask = bit_mask >> 1;
1103        }
1104    }
1105    buf[bitindex] = '\0';
1106    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
1107    old_value = object;
1108}
1109
1110/*****************************************************************************/
1111
1112class wif_signed_int_trace: public wif_trace {
1113public:
1114    wif_signed_int_trace(const int& object_,
1115			 const std::string& name_,
1116			 const std::string& wif_name_,
1117			 int width_);
1118    void write(FILE* f);
1119    bool changed();
1120
1121protected:
1122    const int& object;
1123    int old_value;
1124    unsigned mask;
1125};
1126
1127
1128wif_signed_int_trace::wif_signed_int_trace(const signed& object_,
1129					   const std::string& name_,
1130					   const std::string& wif_name_,
1131					   int width_)
1132: wif_trace(name_, wif_name_), object(object_), old_value(object_),
1133  mask(0xffffffff)
1134{
1135    bit_width = width_;
1136    if (bit_width < 32) {
1137        mask = ~(-1 << bit_width);
1138    }
1139
1140    wif_type = "BIT";
1141}
1142
1143
1144bool wif_signed_int_trace::changed()
1145{
1146    return object != old_value;
1147}
1148
1149
1150void wif_signed_int_trace::write(FILE* f)
1151{
1152    char buf[1000];
1153    int bitindex;
1154
1155    // Check for overflow
1156    if (((unsigned) object & mask) != (unsigned) object) {
1157        for (bitindex = 0; bitindex < bit_width; bitindex++){
1158            buf[bitindex]='0';
1159        }
1160    }
1161    else{
1162        unsigned bit_mask = 1 << (bit_width-1);
1163        for (bitindex = 0; bitindex < bit_width; bitindex++) {
1164            buf[bitindex] = (object & bit_mask)? '1' : '0';
1165            bit_mask = bit_mask >> 1;
1166        }
1167    }
1168    buf[bitindex] = '\0';
1169    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
1170    old_value = object;
1171}
1172
1173/*****************************************************************************/
1174
1175class wif_signed_short_trace: public wif_trace {
1176public:
1177    wif_signed_short_trace(const short& object_,
1178			   const std::string& name_,
1179			   const std::string& wif_name_,
1180			   int width_);
1181    void write(FILE* f);
1182    bool changed();
1183
1184protected:
1185    const short& object;
1186    short old_value;
1187    unsigned short mask;
1188};
1189
1190
1191wif_signed_short_trace::wif_signed_short_trace(const short& object_,
1192					   const std::string& name_,
1193					   const std::string& wif_name_,
1194					   int width_)
1195: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xffff)
1196{
1197    bit_width = width_;
1198    if (bit_width < 16) {
1199        mask = (unsigned short)~(-1 << bit_width);
1200    }
1201
1202    wif_type = "BIT";
1203}
1204
1205
1206bool wif_signed_short_trace::changed()
1207{
1208    return object != old_value;
1209}
1210
1211
1212void wif_signed_short_trace::write(FILE* f)
1213{
1214    char buf[1000];
1215    int bitindex;
1216
1217    // Check for overflow
1218    if (((unsigned short) object & mask) != (unsigned short) object) {
1219        for (bitindex = 0; bitindex < bit_width; bitindex++){
1220            buf[bitindex]='0';
1221        }
1222    }
1223    else{
1224        unsigned bit_mask = 1 << (bit_width-1);
1225        for (bitindex = 0; bitindex < bit_width; bitindex++) {
1226            buf[bitindex] = (object & bit_mask)? '1' : '0';
1227            bit_mask = bit_mask >> 1;
1228        }
1229    }
1230    buf[bitindex] = '\0';
1231    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
1232    old_value = object;
1233}
1234
1235/*****************************************************************************/
1236
1237class wif_signed_char_trace: public wif_trace {
1238public:
1239    wif_signed_char_trace(const char& object_,
1240			  const std::string& name_,
1241			  const std::string& wif_name_,
1242			  int width_);
1243    void write(FILE* f);
1244    bool changed();
1245
1246protected:
1247    const char& object;
1248    char old_value;
1249    unsigned char mask;
1250};
1251
1252
1253wif_signed_char_trace::wif_signed_char_trace(const char& object_,
1254					     const std::string& name_,
1255					     const std::string& wif_name_,
1256					     int width_)
1257: wif_trace(name_, wif_name_), object(object_), old_value(object_), mask(0xff)
1258{
1259    bit_width = width_;
1260    if (bit_width < 8) {
1261        mask = (unsigned char)~(-1 << bit_width);
1262    }
1263
1264    wif_type = "BIT";
1265}
1266
1267
1268bool wif_signed_char_trace::changed()
1269{
1270    return object != old_value;
1271}
1272
1273
1274void wif_signed_char_trace::write(FILE* f)
1275{
1276    char buf[1000];
1277    int bitindex;
1278
1279    // Check for overflow
1280    if (((unsigned char) object & mask) != (unsigned char) object) {
1281        for (bitindex = 0; bitindex < bit_width; bitindex++){
1282            buf[bitindex]='0';
1283        }
1284    }
1285    else{
1286        unsigned bit_mask = 1 << (bit_width-1);
1287        for (bitindex = 0; bitindex < bit_width; bitindex++) {
1288            buf[bitindex] = (object & bit_mask)? '1' : '0';
1289            bit_mask = bit_mask >> 1;
1290        }
1291    }
1292    buf[bitindex] = '\0';
1293    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
1294    old_value = object;
1295}
1296
1297/*****************************************************************************/
1298
1299class wif_signed_long_trace: public wif_trace {
1300public:
1301    wif_signed_long_trace(const long& object_,
1302			  const std::string& name_,
1303			  const std::string& wif_name_,
1304			  int width_);
1305    void write(FILE* f);
1306    bool changed();
1307
1308protected:
1309    const long& object;
1310    long old_value;
1311    unsigned long mask;
1312};
1313
1314
1315wif_signed_long_trace::wif_signed_long_trace(const long& object_,
1316					     const std::string& name_,
1317					     const std::string& wif_name_,
1318					     int width_)
1319: wif_trace(name_, wif_name_), object(object_), old_value(object_),
1320  mask((unsigned long)-1L)
1321{
1322    bit_width = width_;
1323    if (bit_width < (int)(sizeof(long)*BITS_PER_BYTE)) {
1324        mask = ~(-1L << bit_width);
1325    }
1326
1327    wif_type = "BIT";
1328}
1329
1330
1331bool wif_signed_long_trace::changed()
1332{
1333    return object != old_value;
1334}
1335
1336
1337void wif_signed_long_trace::write(FILE* f)
1338{
1339    char buf[1000];
1340    int bitindex;
1341
1342    // Check for overflow
1343    if (((unsigned long) object & mask) != (unsigned long) object) {
1344        for (bitindex = 0; bitindex < bit_width; bitindex++){
1345            buf[bitindex]='0';
1346        }
1347    } else {
1348        unsigned long bit_mask = 1ul << (bit_width-1);
1349        for (bitindex = 0; bitindex < bit_width; bitindex++) {
1350            buf[bitindex] = (object & bit_mask)? '1' : '0';
1351            bit_mask = bit_mask >> 1;
1352        }
1353    }
1354    buf[bitindex] = '\0';
1355    std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), buf);
1356    old_value = object;
1357}
1358
1359
1360/*****************************************************************************/
1361
1362class wif_float_trace: public wif_trace {
1363public:
1364    wif_float_trace(const float& object_,
1365		    const std::string& name_,
1366		    const std::string& wif_name_);
1367    void write(FILE* f);
1368    bool changed();
1369
1370protected:
1371    const float& object;
1372    float old_value;
1373};
1374
1375wif_float_trace::wif_float_trace(const float& object_,
1376				 const std::string& name_,
1377				 const std::string& wif_name_)
1378: wif_trace(name_, wif_name_), object(object_), old_value(object_)
1379{
1380    bit_width = 0;
1381    wif_type = "real";
1382}
1383
1384bool wif_float_trace::changed()
1385{
1386    return object != old_value;
1387}
1388
1389void wif_float_trace::write(FILE* f)
1390{
1391    std::fprintf(f,"assign  %s %f ; \n", wif_name.c_str(), object);
1392    old_value = object;
1393}
1394
1395/*****************************************************************************/
1396
1397class wif_double_trace: public wif_trace {
1398public:
1399    wif_double_trace(const double& object_,
1400		     const std::string& name_,
1401		     const std::string& wif_name_);
1402    void write(FILE* f);
1403    bool changed();
1404
1405protected:
1406    const double& object;
1407    double old_value;
1408};
1409
1410wif_double_trace::wif_double_trace(const double& object_,
1411				   const std::string& name_,
1412				   const std::string& wif_name_)
1413: wif_trace(name_, wif_name_), object(object_), old_value(object_)
1414{
1415    bit_width = 0;
1416    wif_type = "real";
1417}
1418
1419bool wif_double_trace::changed()
1420{
1421    return object != old_value;
1422}
1423
1424void wif_double_trace::write(FILE* f)
1425{
1426    std::fprintf(f,"assign  %s %f ; \n", wif_name.c_str(), object);
1427    old_value = object;
1428}
1429
1430
1431/*****************************************************************************/
1432
1433class wif_enum_trace : public wif_trace {
1434public:
1435    wif_enum_trace(const unsigned& object_,
1436		   const std::string& name_,
1437		   const std::string& wif_name_,
1438		   const char** enum_literals);
1439    void write(FILE* f);
1440    bool changed();
1441    // Hides the definition of the same (virtual) function in wif_trace
1442    void print_variable_declaration_line(FILE* f);
1443
1444protected:
1445    const unsigned& object;
1446    unsigned old_value;
1447
1448    const char** literals;
1449    unsigned nliterals;
1450    std::string type_name;
1451
1452    ~wif_enum_trace();
1453};
1454
1455
1456wif_enum_trace::wif_enum_trace(const unsigned& object_,
1457			       const std::string& name_,
1458			       const std::string& wif_name_,
1459			       const char** enum_literals_)
1460: wif_trace(name_, wif_name_), object(object_), old_value(object_),
1461  literals(enum_literals_), nliterals(0), type_name(name_ + "__type__")
1462{
1463    // find number of enumeration literals - counting loop
1464    for (nliterals = 0; enum_literals_[nliterals]; nliterals++) continue;
1465
1466    bit_width = 0;
1467    wif_type = type_name.c_str();
1468}
1469
1470void wif_enum_trace::print_variable_declaration_line(FILE* f)
1471{
1472    std::fprintf(f, "type scalar \"%s\" enum ", wif_type);
1473
1474    for (unsigned i = 0; i < nliterals; i++)
1475      std::fprintf(f, "\"%s\", ", literals[i]);
1476    std::fprintf(f, "\"SC_WIF_UNDEF\" ;\n");
1477
1478    std::fprintf(f, "declare  %s   \"%s\"  \"%s\" ",
1479	    wif_name.c_str(), name.c_str(), wif_type);
1480    std::fprintf(f, "variable ;\n");
1481    std::fprintf(f, "start_trace %s ;\n", wif_name.c_str());
1482}
1483
1484bool wif_enum_trace::changed()
1485{
1486    return object != old_value;
1487}
1488
1489void wif_enum_trace::write(FILE* f)
1490{
1491    static bool warning_issued = false;
1492    const char* lit;
1493
1494    if (object >= nliterals) { // Note unsigned value is always greater than 0
1495        if (!warning_issued) {
1496            SC_REPORT_WARNING( SC_ID_TRACING_INVALID_ENUM_VALUE_
1497                             , name.c_str() );
1498            warning_issued = true;
1499        }
1500        lit = "SC_WIF_UNDEF";
1501    }
1502    else
1503    {
1504        lit = literals[object];
1505    }
1506    std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), lit );
1507    old_value = object;
1508}
1509
1510wif_enum_trace::~wif_enum_trace()
1511{
1512    /* Intentionally blank */
1513}
1514
1515
1516template <class T>
1517class wif_T_trace
1518: public wif_trace
1519{
1520public:
1521
1522    wif_T_trace( const T& object_,
1523		 const std::string& name_,
1524		 const std::string& wif_name_,
1525		 wif_trace_file::wif_enum type_ )
1526    : wif_trace( name_, wif_name_),
1527      object( object_ ),
1528      old_value( object_ )
1529    {  wif_type = wif_names[type_]; }
1530
1531    void write( FILE* f )
1532    {
1533       std::fprintf( f,
1534		"assign %s \"%s\" ;\n",
1535		wif_name.c_str(),
1536		object.to_string().c_str() );
1537       old_value = object;
1538    }
1539
1540    bool changed()
1541        { return !(object == old_value); }
1542
1543    void set_width()
1544        { bit_width = object.length(); }
1545
1546protected:
1547
1548    const T& object;
1549    T        old_value;
1550};
1551
1552typedef wif_T_trace<sc_dt::sc_bv_base> wif_sc_bv_trace;
1553typedef wif_T_trace<sc_dt::sc_lv_base> wif_sc_lv_trace;
1554
1555
1556//***********************************************************************
1557//           wif_trace_file functions
1558//***********************************************************************
1559
1560
1561wif_trace_file::wif_trace_file(const char * name)
1562  : sc_trace_file_base( name, "awif" )
1563  , wif_name_index(0)
1564  , previous_time_units_low(0)
1565  , previous_time_units_high(0)
1566  , previous_time(0.0)
1567  , traces()
1568{}
1569
1570
1571void wif_trace_file::do_initialize()
1572{
1573    char buf[2000];
1574
1575    // init
1576    std::fprintf(fp, "init ;\n\n");
1577
1578    //timescale:
1579    if     (timescale_unit == 1e-15) std::sprintf(buf,"0");
1580    else if(timescale_unit == 1e-14) std::sprintf(buf,"1");
1581    else if(timescale_unit == 1e-13) std::sprintf(buf,"2");
1582    else if(timescale_unit == 1e-12) std::sprintf(buf,"3");
1583    else if(timescale_unit == 1e-11) std::sprintf(buf,"4");
1584    else if(timescale_unit == 1e-10) std::sprintf(buf,"5");
1585    else if(timescale_unit == 1e-9)  std::sprintf(buf,"6");
1586    else if(timescale_unit == 1e-8)  std::sprintf(buf,"7");
1587    else if(timescale_unit == 1e-7)  std::sprintf(buf,"8");
1588    else if(timescale_unit == 1e-6)  std::sprintf(buf,"9");
1589    else if(timescale_unit == 1e-5)  std::sprintf(buf,"10");
1590    else if(timescale_unit == 1e-4)  std::sprintf(buf,"11");
1591    else if(timescale_unit == 1e-3)  std::sprintf(buf,"12");
1592    else if(timescale_unit == 1e-2)  std::sprintf(buf,"13");
1593    else if(timescale_unit == 1e-1)  std::sprintf(buf,"14");
1594    else if(timescale_unit == 1e0)   std::sprintf(buf,"15");
1595    else if(timescale_unit == 1e1)   std::sprintf(buf,"16");
1596    else if(timescale_unit == 1e2)   std::sprintf(buf,"17");
1597    std::fprintf(fp,"header  %s \"%s\" ;\n\n", buf, sc_version());
1598
1599    std::fprintf(fp, "comment \"ASCII WIF file produced on date:  %s\" ;\n"
1600                , localtime_string().c_str());
1601
1602    //version:
1603    std::fprintf(fp, "comment \"Created by %s\" ;\n", sc_version());
1604    //conversion info
1605    std::fprintf(fp, "comment \"Convert this file to binary WIF format using a2wif\" ;\n\n");
1606
1607    // Define the two types we need to represent bool and sc_logic
1608    std::fprintf(fp, "type scalar \"BIT\" enum '0', '1' ;\n");
1609    std::fprintf(fp, "type scalar \"MVL\" enum '0', '1', 'X', 'Z', '?' ;\n");
1610    std::fprintf(fp, "\n");
1611
1612    //variable definitions:
1613    int i;
1614    for (i = 0; i < (int)traces.size(); i++) {
1615        wif_trace* t = traces[i];
1616        t->set_width(); //needed for all vectors
1617        t->print_variable_declaration_line(fp);
1618    }
1619
1620    double inittime = sc_time_stamp().to_seconds();
1621    previous_time = inittime/timescale_unit;
1622
1623    // Dump all values at initial time
1624    std::sprintf(buf,
1625            "All initial values are dumped below at time "
1626            "%g sec = %g timescale units.",
1627            inittime,
1628            inittime/timescale_unit
1629            );
1630    write_comment(buf);
1631
1632    double_to_special_int64(inittime/timescale_unit,
1633			    &previous_time_units_high,
1634			    &previous_time_units_low );
1635
1636    for (i = 0; i < (int)traces.size(); i++) {
1637        wif_trace* t = traces[i];
1638        t->write(fp);
1639    }
1640}
1641
1642// ----------------------------------------------------------------------------
1643
1644#define DEFN_TRACE_METHOD(tp)                                                 \
1645void                                                                          \
1646wif_trace_file::trace( const tp& object_, const std::string& name_ )          \
1647{                                                                             \
1648    if( add_trace_check(name_) )                                              \
1649        traces.push_back( new wif_ ## tp ## _trace( object_,                  \
1650                                                    name_,                    \
1651                                                    obtain_name() ) );        \
1652}
1653
1654DEFN_TRACE_METHOD(bool)
1655DEFN_TRACE_METHOD(float)
1656DEFN_TRACE_METHOD(double)
1657
1658#undef DEFN_TRACE_METHOD
1659#define DEFN_TRACE_METHOD(tp)                                                 \
1660void                                                                          \
1661wif_trace_file::trace(const sc_dt::tp& object_, const std::string& name_)     \
1662{                                                                             \
1663    if( add_trace_check(name_) )                                              \
1664        traces.push_back( new wif_ ## tp ## _trace( object_,                  \
1665                                                    name_,                    \
1666                                                    obtain_name() ) );        \
1667}
1668
1669DEFN_TRACE_METHOD(sc_bit)
1670DEFN_TRACE_METHOD(sc_logic)
1671
1672DEFN_TRACE_METHOD(sc_signed)
1673DEFN_TRACE_METHOD(sc_unsigned)
1674DEFN_TRACE_METHOD(sc_int_base)
1675DEFN_TRACE_METHOD(sc_uint_base)
1676
1677DEFN_TRACE_METHOD(sc_fxval)
1678DEFN_TRACE_METHOD(sc_fxval_fast)
1679DEFN_TRACE_METHOD(sc_fxnum)
1680DEFN_TRACE_METHOD(sc_fxnum_fast)
1681
1682#undef DEFN_TRACE_METHOD
1683
1684
1685#define DEFN_TRACE_METHOD_SIGNED(tp)                                          \
1686void                                                                          \
1687wif_trace_file::trace( const tp&          object_,                            \
1688                       const std::string& name_,                              \
1689                       int                width_ )                            \
1690{                                                                             \
1691    if( add_trace_check(name_) )                                              \
1692        traces.push_back( new wif_signed_ ## tp ## _trace( object_,           \
1693                                                           name_,             \
1694                                                           obtain_name(),     \
1695                                                           width_ ) );        \
1696}
1697
1698#define DEFN_TRACE_METHOD_UNSIGNED(tp)                                        \
1699void                                                                          \
1700wif_trace_file::trace( const unsigned tp& object_,                            \
1701                       const std::string& name_,                              \
1702                       int                width_ )                            \
1703{                                                                             \
1704    if( add_trace_check(name_) )                                              \
1705        traces.push_back( new wif_unsigned_ ## tp ## _trace( object_,         \
1706                                                             name_,           \
1707                                                             obtain_name(),   \
1708                                                             width_ ) );      \
1709}
1710
1711DEFN_TRACE_METHOD_SIGNED(char)
1712DEFN_TRACE_METHOD_SIGNED(short)
1713DEFN_TRACE_METHOD_SIGNED(int)
1714DEFN_TRACE_METHOD_SIGNED(long)
1715
1716DEFN_TRACE_METHOD_UNSIGNED(char)
1717DEFN_TRACE_METHOD_UNSIGNED(short)
1718DEFN_TRACE_METHOD_UNSIGNED(int)
1719DEFN_TRACE_METHOD_UNSIGNED(long)
1720
1721#undef DEFN_TRACE_METHOD_SIGNED
1722#undef DEFN_TRACE_METHOD_UNSIGNED
1723
1724
1725#define DEFN_TRACE_METHOD_LONG_LONG(tp)                                       \
1726void                                                                          \
1727wif_trace_file::trace( const sc_dt::tp&   object_,                            \
1728                       const std::string& name_,                              \
1729                       int                width_ )                            \
1730{                                                                             \
1731    if( add_trace_check(name_) )                                              \
1732        traces.push_back( new wif_ ## tp ## _trace( object_,                  \
1733                                                    name_,                    \
1734                                                    obtain_name(),            \
1735                                                    width_ ) );               \
1736}
1737
1738DEFN_TRACE_METHOD_LONG_LONG(int64)
1739DEFN_TRACE_METHOD_LONG_LONG(uint64)
1740#undef DEFN_TRACE_METHOD_LONG_LONG
1741
1742void
1743wif_trace_file::trace( const unsigned& object_,
1744		       const std::string& name_,
1745		       const char** enum_literals_ )
1746{
1747    if( add_trace_check(name_) )
1748        traces.push_back( new wif_enum_trace( object_,
1749                                              name_,
1750                                              obtain_name(),
1751                                              enum_literals_ ) );
1752}
1753
1754void
1755wif_trace_file::trace( const sc_dt::sc_bv_base& object_,
1756    const std::string& name_ )
1757{
1758   traceT( object_, name_, WIF_BIT );
1759}
1760
1761void
1762wif_trace_file::trace( const sc_dt::sc_lv_base& object_,
1763    const std::string& name_ )
1764{
1765   traceT( object_, name_, WIF_MVL );
1766}
1767
1768
1769void
1770wif_trace_file::write_comment(const std::string& comment)
1771{
1772    if(!fp) open_fp();
1773    //no newline in comments allowed
1774    std::fprintf(fp, "comment \"%s\" ;\n", comment.c_str());
1775}
1776
1777
1778void
1779wif_trace_file::cycle(bool this_is_a_delta_cycle)
1780{
1781    unsigned now_units_high, now_units_low;
1782
1783    // Trace delta cycles only when enabled
1784    if (!delta_cycles() && this_is_a_delta_cycle) return;
1785
1786    // Check for initialization
1787    if( initialize() ) {
1788        return;
1789    };
1790
1791    // double now_units = sc_simulation_time() / timescale_unit;
1792    double now_units = sc_time_stamp().to_seconds() / timescale_unit;
1793
1794    double_to_special_int64(now_units, &now_units_high, &now_units_low );
1795
1796    // Now do the real stuff
1797    unsigned delta_units_high, delta_units_low;
1798    double diff_time;
1799    diff_time = now_units - previous_time;
1800    double_to_special_int64(diff_time, &delta_units_high, &delta_units_low);
1801    if (this_is_a_delta_cycle && (diff_time == 0.0))
1802	delta_units_low++; // Increment time for delta cycle simulation
1803    // Note that in the last statement above, we are assuming no more
1804    // than 2^32 delta cycles - seems realistic
1805
1806    bool time_printed = false;
1807    wif_trace* const* const l_traces = &traces[0];
1808    for (int i = 0; i < (int)traces.size(); i++) {
1809        wif_trace* t = l_traces[i];
1810        if(t->changed()){
1811            if(time_printed == false){
1812                if(delta_units_high){
1813                    std::fprintf(fp, "delta_time %u%09u ;\n", delta_units_high,
1814			    delta_units_low);
1815                }
1816                else{
1817                    std::fprintf(fp, "delta_time %u ;\n", delta_units_low);
1818                }
1819                time_printed = true;
1820            }
1821
1822	    // Write the variable
1823            t->write(fp);
1824        }
1825    }
1826
1827    if(time_printed) {
1828        std::fprintf(fp, "\n");     // Put another newline
1829	// We update previous_time_units only when we print time because
1830	// this field stores the previous time that was printed, not the
1831	// previous time this function was called
1832	previous_time_units_high = now_units_high;
1833	previous_time_units_low = now_units_low;
1834	previous_time = now_units;
1835    }
1836}
1837
1838#if 0
1839void
1840wif_trace_file::create_wif_name(std::string* ptr_to_str)
1841{
1842  obtain_name().swap(*ptr_to_str);
1843}
1844#endif
1845
1846// Create a WIF name for a variable
1847std::string
1848wif_trace_file::obtain_name()
1849{
1850    char buf[32];
1851    std::sprintf( buf, "O%d", wif_name_index ++ );
1852    return buf;
1853}
1854
1855wif_trace_file::~wif_trace_file()
1856{
1857    for( int i = 0; i < (int)traces.size(); i++ ) {
1858        wif_trace* t = traces[i];
1859        delete t;
1860    }
1861}
1862
1863// Map sc_logic values to values understandable by WIF
1864static char
1865map_sc_logic_state_to_wif_state(char in_char)
1866{
1867    char out_char;
1868
1869    switch(in_char){
1870        case 'U':
1871        case 'X':
1872        case 'W':
1873        case 'D':
1874            out_char = 'X';
1875            break;
1876        case '0':
1877        case 'L':
1878            out_char = '0';
1879            break;
1880        case  '1':
1881        case  'H':
1882            out_char = '1';
1883            break;
1884        case  'Z':
1885            out_char = 'Z';
1886            break;
1887        default:
1888            out_char = '?';
1889    }
1890    return out_char;
1891}
1892
1893// ----------------------------------------------------------------------------
1894
1895// Create the trace file
1896sc_trace_file*
1897sc_create_wif_trace_file(const char * name)
1898{
1899    sc_trace_file *tf = new wif_trace_file(name);
1900    return tf;
1901}
1902
1903
1904void
1905sc_close_wif_trace_file( sc_trace_file* tf )
1906{
1907    wif_trace_file* wif_tf = static_cast<wif_trace_file*>(tf);
1908    delete wif_tf;
1909}
1910
1911} // namespace sc_core
1912