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_trace.h - Functions for tracing signals and variables.
23
24  Author: Abhijit Ghosh, Synopsys, Inc.
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35
36 *****************************************************************************/
37
38/*****************************************************************************
39
40   Acknowledgement: The tracing mechanism is based on the tracing
41   mechanism developed at Infineon (formerly Siemens HL). Though this
42   code is somewhat different, the basics are identical to what was
43   originally contributed by Infineon.  The contribution of Infineon
44   in the development of this tracing technology is hereby
45   acknowledged.
46
47 *****************************************************************************/
48
49#ifndef SC_TRACE_H
50#define SC_TRACE_H
51
52#include <cstdio>
53
54#include "sysc/datatypes/int/sc_nbdefs.h"
55#include "sysc/kernel/sc_time.h"
56
57// Some forward declarations
58namespace sc_dt
59{
60    class sc_bit;
61    class sc_logic;
62    class sc_bv_base;
63    class sc_lv_base;
64    class sc_signed;
65    class sc_unsigned;
66    class sc_int_base;
67    class sc_uint_base;
68    class sc_fxval;
69    class sc_fxval_fast;
70    class sc_fxnum;
71    class sc_fxnum_fast;
72}
73
74namespace sc_core {
75
76class sc_time;
77
78template <class T> class sc_signal_in_if;
79
80
81// Base class for all kinds of trace files.
82
83class sc_trace_file
84{
85    friend class sc_simcontext;
86
87public:
88
89    // Constructor
90    sc_trace_file();
91
92    // All functions are pure virtual because they need to be defined by the
93    // particular tracing mechanism
94
95
96#define DECL_TRACE_METHOD_A(tp)                                               \
97    virtual void trace( const tp& object,                                     \
98			const std::string& name ) = 0;
99
100#define DECL_TRACE_METHOD_B(tp)                                               \
101    virtual void trace( const tp& object,                                     \
102			const std::string& name,                                     \
103			int width ) = 0;
104
105
106    DECL_TRACE_METHOD_A( bool )
107    DECL_TRACE_METHOD_A( sc_dt::sc_bit )
108    DECL_TRACE_METHOD_A( sc_dt::sc_logic )
109
110    DECL_TRACE_METHOD_B( unsigned char )
111    DECL_TRACE_METHOD_B( unsigned short )
112    DECL_TRACE_METHOD_B( unsigned int )
113    DECL_TRACE_METHOD_B( unsigned long )
114    DECL_TRACE_METHOD_B( char )
115    DECL_TRACE_METHOD_B( short )
116    DECL_TRACE_METHOD_B( int )
117    DECL_TRACE_METHOD_B( long )
118    DECL_TRACE_METHOD_B( sc_dt::int64 )
119    DECL_TRACE_METHOD_B( sc_dt::uint64 )
120
121    DECL_TRACE_METHOD_A( float )
122    DECL_TRACE_METHOD_A( double )
123    DECL_TRACE_METHOD_A( sc_dt::sc_int_base )
124    DECL_TRACE_METHOD_A( sc_dt::sc_uint_base )
125    DECL_TRACE_METHOD_A( sc_dt::sc_signed )
126    DECL_TRACE_METHOD_A( sc_dt::sc_unsigned )
127
128    DECL_TRACE_METHOD_A( sc_dt::sc_fxval )
129    DECL_TRACE_METHOD_A( sc_dt::sc_fxval_fast )
130    DECL_TRACE_METHOD_A( sc_dt::sc_fxnum )
131    DECL_TRACE_METHOD_A( sc_dt::sc_fxnum_fast )
132
133    DECL_TRACE_METHOD_A( sc_dt::sc_bv_base )
134    DECL_TRACE_METHOD_A( sc_dt::sc_lv_base )
135
136
137#undef DECL_TRACE_METHOD_A
138#undef DECL_TRACE_METHOD_B
139
140    // Trace an enumerated object - where possible output the enumeration
141    // literals in the trace file. Enum literals is a null terminated array
142    // of null terminated char* literal strings.
143    virtual void trace( const unsigned int& object,
144			const std::string& name,
145			const char** enum_literals ) = 0;
146
147    // Output a comment to the trace file
148    virtual void write_comment( const std::string& comment ) = 0;
149
150    // Set the amount of space before next column
151    // (For most formats this does nothing)
152    virtual void space( int n );
153
154    // Also trace transitions between delta cycles if flag is true.
155    virtual void delta_cycles( bool flag );
156
157    // Set time unit.
158    virtual void set_time_unit( double v, sc_time_unit tu )=0;
159
160protected:
161
162    // Write trace info for cycle
163    virtual void cycle( bool delta_cycle ) = 0;
164
165    // Flush results and close file
166    virtual ~sc_trace_file()
167	{ /* Intentionally blank */ }
168};
169
170/*****************************************************************************/
171
172// Now comes all the SystemC defined tracing functions.
173// We define two sc_trace() versions for scalar types; one where the object to
174// be traced is passed as a reference and the other where a pointer to the
175// tracing object is passed.
176
177#define DECL_TRACE_FUNC_REF_A(tp)     \
178void                                  \
179sc_trace( sc_trace_file* tf,          \
180	  const tp& object,               \
181	  const std::string& name );
182
183#define DECL_TRACE_FUNC_PTR_A(tp)     \
184void                                  \
185sc_trace( sc_trace_file* tf,          \
186	  const tp* object,               \
187	  const std::string& name );        \
188
189#define DECL_TRACE_FUNC_A(tp)         \
190DECL_TRACE_FUNC_REF_A(tp)             \
191DECL_TRACE_FUNC_PTR_A(tp)
192
193
194DECL_TRACE_FUNC_A( sc_dt::sc_bit )
195DECL_TRACE_FUNC_A( sc_dt::sc_logic )
196
197DECL_TRACE_FUNC_A( sc_dt::sc_int_base )
198DECL_TRACE_FUNC_A( sc_dt::sc_uint_base )
199DECL_TRACE_FUNC_A( sc_dt::sc_signed )
200DECL_TRACE_FUNC_A( sc_dt::sc_unsigned )
201
202DECL_TRACE_FUNC_REF_A( sc_dt::sc_bv_base )
203DECL_TRACE_FUNC_REF_A( sc_dt::sc_lv_base )
204
205
206#undef DECL_TRACE_FUNC_REF_A
207#undef DECL_TRACE_FUNC_PTR_A
208#undef DECL_TRACE_FUNC_A
209
210
211// ----------------------------------------------------------------------------
212
213#define DEFN_TRACE_FUNC_REF_A(tp)                                             \
214inline                                                                        \
215void                                                                          \
216sc_trace( sc_trace_file* tf, const tp& object, const std::string& name ) \
217{                                                                             \
218    if( tf ) {                                                                \
219	tf->trace( object, name );                                            \
220    }                                                                         \
221}
222
223#define DEFN_TRACE_FUNC_PTR_A(tp)                                             \
224inline                                                                        \
225void                                                                          \
226sc_trace( sc_trace_file* tf, const tp* object, const std::string& name ) \
227{                                                                             \
228    if( tf ) {                                                                \
229	tf->trace( *object, name );                                           \
230    }                                                                         \
231}
232
233#define DEFN_TRACE_FUNC_A(tp)                                                 \
234DEFN_TRACE_FUNC_REF_A(tp)                                                     \
235DEFN_TRACE_FUNC_PTR_A(tp)
236
237
238#define DEFN_TRACE_FUNC_REF_B(tp)                                             \
239inline                                                                        \
240void                                                                          \
241sc_trace( sc_trace_file* tf, const tp& object, const std::string& name,  \
242          int width = 8 * sizeof( tp ) )                                      \
243{                                                                             \
244    if( tf ) {                                                                \
245	tf->trace( object, name, width );                                     \
246    }                                                                         \
247}
248
249#define DEFN_TRACE_FUNC_PTR_B(tp)                                             \
250inline                                                                        \
251void                                                                          \
252sc_trace( sc_trace_file* tf, const tp* object, const std::string& name,  \
253          int width = 8 * sizeof( tp ) )                                      \
254{                                                                             \
255    if( tf ) {                                                                \
256	tf->trace( *object, name, width );                                    \
257    }                                                                         \
258}
259
260
261#define DEFN_TRACE_FUNC_B(tp)                                                 \
262DEFN_TRACE_FUNC_REF_B(tp)                                                     \
263DEFN_TRACE_FUNC_PTR_B(tp)
264
265
266DEFN_TRACE_FUNC_A( bool )
267DEFN_TRACE_FUNC_A( float )
268DEFN_TRACE_FUNC_A( double )
269
270DEFN_TRACE_FUNC_B( unsigned char )
271DEFN_TRACE_FUNC_B( unsigned short )
272DEFN_TRACE_FUNC_B( unsigned int )
273DEFN_TRACE_FUNC_B( unsigned long )
274DEFN_TRACE_FUNC_B( char )
275DEFN_TRACE_FUNC_B( short )
276DEFN_TRACE_FUNC_B( int )
277DEFN_TRACE_FUNC_B( long )
278DEFN_TRACE_FUNC_B( sc_dt::int64 )
279DEFN_TRACE_FUNC_B( sc_dt::uint64 )
280
281
282#undef DEFN_TRACE_FUNC_REF_A
283#undef DEFN_TRACE_FUNC_PTR_A
284#undef DEFN_TRACE_FUNC_A
285
286#undef DEFN_TRACE_FUNC_REF_B
287#undef DEFN_TRACE_FUNC_PTR_B
288#undef DEFN_TRACE_FUNC_B
289
290
291template <class T>
292inline
293void
294sc_trace( sc_trace_file* tf,
295	  const sc_signal_in_if<T>& object,
296	  const std::string& name )
297{
298    sc_trace( tf, object.read(), name );
299}
300
301template< class T >
302inline
303void
304sc_trace( sc_trace_file* tf,
305	  const sc_signal_in_if<T>& object,
306	  const char* name )
307{
308    sc_trace( tf, object.read(), name );
309}
310
311
312// specializations for signals of type char, short, int, long
313
314void sc_trace( sc_trace_file* tf,
315	       const sc_signal_in_if<char>& object,
316	       const std::string& name,
317	       int width );
318
319void sc_trace( sc_trace_file* tf,
320	       const sc_signal_in_if<short>& object,
321	       const std::string& name,
322	       int width );
323
324void sc_trace( sc_trace_file* tf,
325	       const sc_signal_in_if<int>& object,
326	       const std::string& name,
327	       int width );
328
329void sc_trace( sc_trace_file* tf,
330	       const sc_signal_in_if<long>& object,
331	       const std::string& name,
332	       int width );
333
334
335// 1. non-template function is better than template
336// 2. more-specialized template is better than less-specialized
337// 3. no partial specialization for template functions
338
339
340// Trace an enumerated object - where possible output the enumeration literals
341// in the trace file. Enum literals is a null terminated array of null
342// terminated char* literal strings.
343
344void
345sc_trace( sc_trace_file* tf,
346	  const unsigned int& object,
347	  const std::string& name,
348	  const char** enum_literals );
349
350
351// Dummy function for arbitrary types of value, does nothing
352
353extern void sc_trace( sc_trace_file* tf,
354		      const void* object,
355		      const std::string& name );
356
357
358// Turn on/off delta cycle tracing on trace file `tf'.
359// Default is to turn on delta cycle tracing.
360
361inline
362void
363sc_trace_delta_cycles( sc_trace_file* tf, bool on = true )
364{
365    if( tf ) tf->delta_cycles( on );
366}
367
368
369// Output a comment to the trace file
370
371inline
372void
373sc_write_comment( sc_trace_file* tf, const std::string& comment )
374{
375    if( tf ) tf->write_comment( comment );
376}
377
378
379// Equivalent of std::fprintf for trace files!
380
381void tprintf( sc_trace_file* tf,  const char* format, ... );
382
383// ----------------------------------------------------------------------------
384// Create VCD file
385extern sc_trace_file *sc_create_vcd_trace_file(const char* name);
386extern void sc_close_vcd_trace_file( sc_trace_file* tf );
387
388
389// ----------------------------------------------------------------------------
390// Create WIF file
391extern sc_trace_file *sc_create_wif_trace_file(const char *name);
392extern void sc_close_wif_trace_file( sc_trace_file* tf );
393
394} // namespace sc_core
395
396#endif // SC_TRACE_H
397// Taf
398