#include <sc_vcd_trace.h>
Public 型 | |
enum | vcd_enum { VCD_WIRE = 0, VCD_REAL = 1, VCD_LAST } |
Public メソッド | |
void | sc_set_vcd_time_unit (int exponent10_seconds) |
vcd_trace_file (const char *name) | |
~vcd_trace_file () | |
std::string | obtain_name () |
Public 変数 | |
std::vector< vcd_trace * > | traces |
Protected メソッド | |
void | trace (const bool &object, const std::string &name) |
virtual void | trace (const sc_dt::sc_bit &object, const std::string &name) |
void | trace (const sc_dt::sc_logic &object, const std::string &name) |
void | trace (const unsigned char &object, const std::string &name, int width) |
void | trace (const unsigned short &object, const std::string &name, int width) |
void | trace (const unsigned int &object, const std::string &name, int width) |
void | trace (const unsigned long &object, const std::string &name, int width) |
void | trace (const char &object, const std::string &name, int width) |
void | trace (const short &object, const std::string &name, int width) |
void | trace (const int &object, const std::string &name, int width) |
void | trace (const long &object, const std::string &name, int width) |
void | trace (const sc_dt::int64 &object, const std::string &name, int width) |
void | trace (const sc_dt::uint64 &object, const std::string &name, int width) |
void | trace (const float &object, const std::string &name) |
void | trace (const double &object, const std::string &name) |
void | trace (const sc_dt::sc_uint_base &object, const std::string &name) |
void | trace (const sc_dt::sc_int_base &object, const std::string &name) |
void | trace (const sc_dt::sc_unsigned &object, const std::string &name) |
void | trace (const sc_dt::sc_signed &object, const std::string &name) |
void | trace (const sc_dt::sc_fxval &object, const std::string &name) |
void | trace (const sc_dt::sc_fxval_fast &object, const std::string &name) |
void | trace (const sc_dt::sc_fxnum &object, const std::string &name) |
void | trace (const sc_dt::sc_fxnum_fast &object, const std::string &name) |
template<class T> | |
void | traceT (const T &object, const std::string &name, vcd_enum type=VCD_WIRE) |
virtual void | trace (const sc_dt::sc_bv_base &object, const std::string &name) |
virtual void | trace (const sc_dt::sc_lv_base &object, const std::string &name) |
void | trace (const unsigned &object, const std::string &name, const char **enum_literals) |
void | write_comment (const std::string &comment) |
void | delta_cycles (bool flag) |
void | cycle (bool delta_cycle) |
Private メソッド | |
void | initialize () |
void | create_vcd_name (std::string *p_destination) |
Private 変数 | |
FILE * | fp |
bool | trace_delta_cycles |
unsigned | vcd_name_index |
unsigned | previous_time_units_low |
unsigned | previous_time_units_high |
sc_vcd_trace.h の 66 行で定義されています。
sc_core::vcd_trace_file::vcd_trace_file | ( | const char * | name | ) |
sc_vcd_trace.cpp の 1710 行で定義されています。
01711 { 01712 std::string file_name = name ; 01713 file_name += ".vcd"; 01714 fp = fopen(file_name.c_str(), "w"); 01715 if (!fp) { 01716 std::string msg = std::string("Cannot write trace file '") + 01717 file_name + "'"; 01718 ::std::cerr << "FATAL: " << msg << "\n"; 01719 exit(1); 01720 } 01721 trace_delta_cycles = false; // Make this the default 01722 initialized = false; 01723 vcd_name_index = 0; 01724 01725 // default time step is the time resolution 01726 timescale_unit = sc_get_time_resolution().to_seconds(); 01727 01728 timescale_set_by_user = false; 01729 }
sc_core::vcd_trace_file::~vcd_trace_file | ( | ) |
sc_vcd_trace.cpp の 2184 行で定義されています。
02185 { 02186 int i; 02187 for (i = 0; i < (int)traces.size(); i++) { 02188 vcd_trace* t = traces[i]; 02189 delete t; 02190 } 02191 fclose(fp); 02192 }
void sc_core::vcd_trace_file::sc_set_vcd_time_unit | ( | int | exponent10_seconds | ) | [inline] |
void sc_core::vcd_trace_file::trace | ( | const bool & | object, | |
const std::string & | name | |||
) | [protected] |
virtual void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_bit & | object, | |
const std::string & | name | |||
) | [protected, virtual] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_logic & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const unsigned char & | object, | |
const std::string & | name, | |||
int | width | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const unsigned short & | object, | |
const std::string & | name, | |||
int | width | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const unsigned int & | object, | |
const std::string & | name, | |||
int | width | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const unsigned long & | object, | |
const std::string & | name, | |||
int | width | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const char & | object, | |
const std::string & | name, | |||
int | width | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const short & | object, | |
const std::string & | name, | |||
int | width | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const int & | object, | |
const std::string & | name, | |||
int | width | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const long & | object, | |
const std::string & | name, | |||
int | width | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::int64 & | object, | |
const std::string & | name, | |||
int | width | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::uint64 & | object, | |
const std::string & | name, | |||
int | width | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const float & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const double & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_uint_base & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_int_base & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_unsigned & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_signed & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_fxval & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_fxval_fast & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_fxnum & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_fxnum_fast & | object, | |
const std::string & | name | |||
) | [protected] |
void sc_core::vcd_trace_file::traceT | ( | const T & | object, | |
const std::string & | name, | |||
vcd_enum | type = VCD_WIRE | |||
) | [inline, protected] |
sc_vcd_trace.h の 170 行で定義されています。
00172 { 00173 if(initialized) 00174 put_error_message("No traces can be added once simulation has" 00175 " started.\nTo add traces, create a new vcd trace file.", false); 00176 else 00177 traces.push_back(new vcd_T_trace<T>(object, name, obtain_name(),type)); 00178 }
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_bv_base & | object, | |
const std::string & | name | |||
) | [protected, virtual] |
void sc_core::vcd_trace_file::trace | ( | const sc_dt::sc_lv_base & | object, | |
const std::string & | name | |||
) | [protected, virtual] |
void sc_core::vcd_trace_file::trace | ( | const unsigned & | object, | |
const std::string & | name, | |||
const char ** | enum_literals | |||
) | [protected] |
sc_vcd_trace.cpp の 1961 行で定義されています。
01964 { 01965 if( initialized ) { 01966 put_error_message( 01967 "No traces can be added once simulation has started.\n" 01968 "To add traces, create a new vcd trace file.", false ); 01969 } 01970 std::string temp_vcd_name; 01971 create_vcd_name( &temp_vcd_name ); 01972 traces.push_back( new vcd_enum_trace( object_, 01973 name_, 01974 temp_vcd_name, 01975 enum_literals_ ) ); 01976 }
void sc_core::vcd_trace_file::write_comment | ( | const std::string & | comment | ) | [protected, virtual] |
sc_core::sc_trace_fileを実装しています。
sc_vcd_trace.cpp の 1980 行で定義されています。
01981 { 01982 //no newline in comments allowed, as some viewers may crash 01983 std::fputs("$comment\n", fp); 01984 std::fputs(comment.c_str(), fp); 01985 std::fputs("\n$end\n\n", fp); 01986 }
void sc_core::vcd_trace_file::delta_cycles | ( | bool | flag | ) | [protected, virtual] |
sc_core::sc_trace_fileを再定義しています。
sc_vcd_trace.cpp の 1989 行で定義されています。
01990 { 01991 trace_delta_cycles = flag; 01992 }
void sc_core::vcd_trace_file::cycle | ( | bool | delta_cycle | ) | [protected, virtual] |
sc_core::sc_trace_fileを実装しています。
sc_vcd_trace.cpp の 1995 行で定義されています。
01996 { 01997 char message[4000]; 01998 unsigned this_time_units_high, this_time_units_low; 01999 02000 // Just to make g++ shut up in the optimized mode 02001 this_time_units_high = this_time_units_low = 0; 02002 02003 // Trace delta cycles only when enabled 02004 if (!trace_delta_cycles && this_is_a_delta_cycle) return; 02005 02006 // Check for initialization 02007 if (!initialized) { 02008 initialize(); 02009 initialized = true; 02010 return; 02011 }; 02012 02013 02014 double now_units = sc_time_stamp().to_seconds() / timescale_unit; 02015 unsigned now_units_high, now_units_low; 02016 double_to_special_int64(now_units, &now_units_high, &now_units_low ); 02017 02018 bool now_later_than_previous_time = false; 02019 if( now_units_low > previous_time_units_low 02020 && now_units_high == previous_time_units_high 02021 || now_units_high > previous_time_units_high){ 02022 now_later_than_previous_time = true; 02023 } 02024 02025 bool now_equals_previous_time = false; 02026 if(now_later_than_previous_time){ 02027 this_time_units_high = now_units_high; 02028 this_time_units_low = now_units_low; 02029 } else { 02030 if( now_units_low == previous_time_units_low 02031 && now_units_high == previous_time_units_high){ 02032 now_equals_previous_time = true; 02033 this_time_units_high = now_units_high; 02034 this_time_units_low = now_units_low; 02035 } 02036 } 02037 02038 // Since VCD does not understand 0 time progression, we have to fake 02039 // delta cycles with progressing time by one unit 02040 if(this_is_a_delta_cycle){ 02041 this_time_units_high = previous_time_units_high; 02042 this_time_units_low = previous_time_units_low + 1; 02043 if(this_time_units_low == 1000000000){ 02044 this_time_units_high++; 02045 this_time_units_low=0; 02046 } 02047 static bool warned = false; 02048 if(!warned){ 02049 ::std::cout << "Note: VCD delta cycling with pseudo timesteps (1 unit) " 02050 "is performed.\n" << ::std::endl; 02051 warned = true; 02052 } 02053 } 02054 02055 02056 // Not a delta cycle and time has not progressed 02057 if( ! this_is_a_delta_cycle && now_equals_previous_time && 02058 ( now_units_high != 0 || now_units_low != 0 ) ) { 02059 // Don't print the message at time zero 02060 static bool warned = false; 02061 if( ! warned && ! running_regression ) { 02062 std::sprintf(message, 02063 "Multiple cycles found with same (%u) time units count.\n" 02064 "Waveform viewers will only show the states of the last one.\n" 02065 "Use ((vcd_trace_file*)vcdfile)->sc_set_vcd_time_unit(int exponent10_seconds)\n" 02066 "to increase time resolution.", 02067 now_units_low 02068 ); 02069 put_error_message(message, true); 02070 warned = true; 02071 } 02072 } 02073 02074 // Not a delta cycle and time has gone backward 02075 // This will happen with large number of delta cycles between two real 02076 // advances of time 02077 if(!this_is_a_delta_cycle && !now_equals_previous_time && 02078 !now_later_than_previous_time){ 02079 static bool warned = false; 02080 if(!warned){ 02081 std::sprintf(message, 02082 "Cycle found with falling (%u -> %u) time units count.\n" 02083 "This can occur when delta cycling is activated.\n" 02084 "Cycles with falling time are not shown.\n" 02085 "Use ((vcd_trace_file*)vcdfile)->sc_set_vcd_time_unit(int exponent10_seconds)\n" 02086 "to increase time resolution.", 02087 previous_time_units_low, now_units_low); 02088 put_error_message(message, true); 02089 warned = true; 02090 } 02091 // Note that we don't set this_time_units_high/low to any value only 02092 // in this case because we are not going to do any tracing. In the 02093 // optimized mode, the compiler complains because of this. Therefore, 02094 // we include the lines at the very beginning of this function to make 02095 // the compiler shut up. 02096 return; 02097 } 02098 02099 // Now do the actual printing 02100 bool time_printed = false; 02101 vcd_trace* const* const l_traces = &traces[0]; 02102 for (int i = 0; i < (int)traces.size(); i++) { 02103 vcd_trace* t = l_traces[i]; 02104 if(t->changed()){ 02105 if(time_printed == false){ 02106 char buf[200]; 02107 if(this_time_units_high){ 02108 std::sprintf(buf, "#%u%09u", this_time_units_high, this_time_units_low); 02109 } 02110 else{ 02111 std::sprintf(buf, "#%u", this_time_units_low); 02112 } 02113 std::fputs(buf, fp); 02114 std::fputc('\n', fp); 02115 time_printed = true; 02116 } 02117 02118 // Write the variable 02119 t->write(fp); 02120 std::fputc('\n', fp); 02121 } 02122 } 02123 // Put another newline after all values are printed 02124 if(time_printed) std::fputc('\n', fp); 02125 02126 if(time_printed){ 02127 // We update previous_time_units only when we print time because 02128 // this field stores the previous time that was printed, not the 02129 // previous time this function was called 02130 previous_time_units_high = this_time_units_high; 02131 previous_time_units_low = this_time_units_low; 02132 } 02133 }
void sc_core::vcd_trace_file::initialize | ( | ) | [private] |
sc_vcd_trace.cpp の 1732 行で定義されています。
01733 { 01734 char buf[2000]; 01735 01736 //date: 01737 time_t long_time; 01738 time(&long_time); 01739 struct tm* p_tm; 01740 p_tm = localtime(&long_time); 01741 strftime(buf, 199, "%b %d, %Y %H:%M:%S", p_tm); 01742 std::fprintf(fp, "$date\n %s\n$end\n\n", buf); 01743 01744 //version: 01745 std::fprintf(fp, "$version\n %s\n$end\n\n", sc_version()); 01746 01747 //timescale: 01748 static struct SC_TIMESCALE_TO_TEXT { 01749 double unit; 01750 const char* text; 01751 } timescale_to_text [] = { 01752 { sc_time(1, SC_FS).to_seconds(), "1 fs" }, 01753 { sc_time(10, SC_FS).to_seconds(), "10 fs" }, 01754 { sc_time(100, SC_FS).to_seconds(),"100 fs" }, 01755 { sc_time(1, SC_PS).to_seconds(), "1 ps" }, 01756 { sc_time(10, SC_PS).to_seconds(), "10 ps" }, 01757 { sc_time(100, SC_PS).to_seconds(),"100 ps" }, 01758 { sc_time(1, SC_NS).to_seconds(), "1 ns" }, 01759 { sc_time(10, SC_NS).to_seconds(), "10 ns" }, 01760 { sc_time(100, SC_NS).to_seconds(),"100 ns" }, 01761 { sc_time(1, SC_US).to_seconds(), "1 us" }, 01762 { sc_time(10, SC_US).to_seconds(), "10 us" }, 01763 { sc_time(100, SC_US).to_seconds(),"100 us" }, 01764 { sc_time(1, SC_MS).to_seconds(), "1 ms" }, 01765 { sc_time(10, SC_MS).to_seconds(), "10 ms" }, 01766 { sc_time(100, SC_MS).to_seconds(),"100 ms" }, 01767 { sc_time(1, SC_SEC).to_seconds(), "1 sec" }, 01768 { sc_time(10, SC_SEC).to_seconds(), "10 sec" }, 01769 { sc_time(100, SC_SEC).to_seconds(),"100 sec" } 01770 }; 01771 static int timescale_to_text_n = 01772 sizeof(timescale_to_text)/sizeof(SC_TIMESCALE_TO_TEXT); 01773 01774 for ( int time_i = 0; time_i < timescale_to_text_n; time_i++ ) 01775 { 01776 if (timescale_unit == timescale_to_text[time_i].unit) 01777 { 01778 std::fprintf(fp,"$timescale\n %s\n$end\n\n", 01779 timescale_to_text[time_i].text); 01780 break; 01781 } 01782 } 01783 01784 01785 running_regression = ( getenv( "SYSTEMC_REGRESSION" ) != NULL ); 01786 // Don't print message if running regression 01787 if( ! timescale_set_by_user && ! running_regression ) { 01788 ::std::cout << "WARNING: Default time step is used for VCD tracing." << ::std::endl; 01789 } 01790 01791 // Create a dummy scope 01792 std::fputs("$scope module SystemC $end\n", fp); 01793 01794 //variable definitions: 01795 int i; 01796 for (i = 0; i < (int)traces.size(); i++) { 01797 vcd_trace* t = traces[i]; 01798 t->set_width(); // needed for all vectors 01799 t->print_variable_declaration_line(fp); 01800 } 01801 01802 std::fputs("$upscope $end\n", fp); 01803 01804 std::fputs("$enddefinitions $end\n\n", fp); 01805 01806 // double inittime = sc_simulation_time(); 01807 double inittime = sc_time_stamp().to_seconds(); 01808 01809 std::sprintf(buf, 01810 "All initial values are dumped below at time " 01811 "%g sec = %g timescale units.", 01812 inittime, inittime/timescale_unit 01813 ); 01814 write_comment(buf); 01815 01816 double_to_special_int64(inittime/timescale_unit, 01817 &previous_time_units_high, 01818 &previous_time_units_low ); 01819 01820 01821 std::fputs("$dumpvars\n",fp); 01822 for (i = 0; i < (int)traces.size(); i++) { 01823 vcd_trace* t = traces[i]; 01824 t->write(fp); 01825 std::fputc('\n', fp); 01826 } 01827 std::fputs("$end\n\n", fp); 01828 }
void sc_core::vcd_trace_file::create_vcd_name | ( | std::string * | p_destination | ) | [private] |
sc_vcd_trace.cpp の 2136 行で定義されています。
02137 { 02138 const char first_type_used = 'a'; 02139 const int used_types_count = 'z' - 'a' + 1; 02140 int result; 02141 02142 char char4 = (char)(vcd_name_index % used_types_count); 02143 02144 result = vcd_name_index / used_types_count; 02145 char char3 = (char)(result % used_types_count); 02146 02147 result = result / used_types_count; 02148 char char2 = (char)(result % used_types_count); 02149 02150 char buf[20]; 02151 std::sprintf(buf, "%c%c%c", 02152 char2 + first_type_used, 02153 char3 + first_type_used, 02154 char4 + first_type_used); 02155 *p_destination = buf; 02156 vcd_name_index++; 02157 }
std::string sc_core::vcd_trace_file::obtain_name | ( | ) |
sc_vcd_trace.cpp の 2161 行で定義されています。
02162 { 02163 const char first_type_used = 'a'; 02164 const int used_types_count = 'z' - 'a' + 1; 02165 int result; 02166 02167 char char4 = (char)(vcd_name_index % used_types_count); 02168 02169 result = vcd_name_index / used_types_count; 02170 char char3 = (char)(result % used_types_count); 02171 02172 result = result / used_types_count; 02173 char char2 = (char)(result % used_types_count); 02174 02175 char buf[20]; 02176 std::sprintf(buf, "%c%c%c", 02177 char2 + first_type_used, 02178 char3 + first_type_used, 02179 char4 + first_type_used); 02180 vcd_name_index++; 02181 return std::string(buf); 02182 }
FILE* sc_core::vcd_trace_file::fp [private] |
sc_vcd_trace.h の 210 行で定義されています。
bool sc_core::vcd_trace_file::trace_delta_cycles [private] |
sc_vcd_trace.h の 212 行で定義されています。
unsigned sc_core::vcd_trace_file::vcd_name_index [private] |
sc_vcd_trace.h の 214 行で定義されています。
unsigned sc_core::vcd_trace_file::previous_time_units_low [private] |
sc_vcd_trace.h の 216 行で定義されています。
unsigned sc_core::vcd_trace_file::previous_time_units_high [private] |
sc_vcd_trace.h の 216 行で定義されています。
std::vector<vcd_trace*> sc_core::vcd_trace_file::traces |
sc_vcd_trace.h の 221 行で定義されています。