📄 sc_wif_trace.cpp
字号:
std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), "SC_WIF_UNDEF"); } else std::fprintf(f, "assign %s \"%s\" ;\n", wif_name.c_str(), literals[object]); old_value = object;}wif_enum_trace::~wif_enum_trace(){ /* Intentionally blank */}template <class T>class wif_T_trace: public wif_trace{public: wif_T_trace( const T& object_, const std::string& name_, const std::string& wif_name_, wif_trace_file::wif_enum type_ ) : wif_trace( name_, wif_name_), object( object_ ), old_value( object_ ) { wif_type = wif_names[type_]; } void write( FILE* f ) { std::fprintf( f, "assign %s \"%s\" ;\n", wif_name.c_str(), object.to_string().c_str() ); old_value = object; } bool changed() { return !(object == old_value); } void set_width() { bit_width = object.length(); }protected: const T& object; T old_value;};typedef wif_T_trace<sc_dt::sc_bv_base> wif_sc_bv_trace;typedef wif_T_trace<sc_dt::sc_lv_base> wif_sc_lv_trace;//***********************************************************************// wif_trace_file functions//***********************************************************************wif_trace_file::wif_trace_file(const char * name){ std::string file_name = name ; file_name += ".awif"; fp = fopen(file_name.c_str(), "w"); if (!fp) { std::string msg = std::string("Cannot write trace file '") + file_name + "'"; ::std::cerr << "FATAL: " << msg << "\n"; exit(1); } trace_delta_cycles = false; // make it the default initialized = false; wif_name_index = 0; // default time step is the time resolution timescale_unit = sc_get_time_resolution().to_seconds(); timescale_set_by_user = false;}void wif_trace_file::initialize(){ char buf[2000]; // init std::fprintf(fp, "init ;\n\n"); //timescale: if (timescale_unit == 1e-15) std::sprintf(buf,"0"); else if(timescale_unit == 1e-14) std::sprintf(buf,"1"); else if(timescale_unit == 1e-13) std::sprintf(buf,"2"); else if(timescale_unit == 1e-12) std::sprintf(buf,"3"); else if(timescale_unit == 1e-11) std::sprintf(buf,"4"); else if(timescale_unit == 1e-10) std::sprintf(buf,"5"); else if(timescale_unit == 1e-9) std::sprintf(buf,"6"); else if(timescale_unit == 1e-8) std::sprintf(buf,"7"); else if(timescale_unit == 1e-7) std::sprintf(buf,"8"); else if(timescale_unit == 1e-6) std::sprintf(buf,"9"); else if(timescale_unit == 1e-5) std::sprintf(buf,"10"); else if(timescale_unit == 1e-4) std::sprintf(buf,"11"); else if(timescale_unit == 1e-3) std::sprintf(buf,"12"); else if(timescale_unit == 1e-2) std::sprintf(buf,"13"); else if(timescale_unit == 1e-1) std::sprintf(buf,"14"); else if(timescale_unit == 1e0) std::sprintf(buf,"15"); else if(timescale_unit == 1e1) std::sprintf(buf,"16"); else if(timescale_unit == 1e2) std::sprintf(buf,"17"); std::fprintf(fp,"header %s \"%s\" ;\n\n", buf, sc_version()); //date: time_t long_time; time(&long_time); struct tm* p_tm; p_tm = localtime(&long_time); strftime(buf, 199, "%b %d, %Y %H:%M:%S", p_tm); std::fprintf(fp, "comment \"ASCII WIF file produced on date: %s\" ;\n", buf); //version: std::fprintf(fp, "comment \"Created by %s\" ;\n", sc_version()); //conversion info std::fprintf(fp, "comment \"Convert this file to binary WIF format using a2wif\" ;\n\n"); running_regression = ( getenv( "SYSTEMC_REGRESSION" ) != NULL ); // Don't print message if running regression if( ! timescale_set_by_user && ! running_regression ) { ::std::cout << "WARNING: Default time step is used for WIF tracing." << ::std::endl; } // Define the two types we need to represent bool and sc_logic std::fprintf(fp, "type scalar \"BIT\" enum '0', '1' ;\n"); std::fprintf(fp, "type scalar \"MVL\" enum '0', '1', 'X', 'Z', '?' ;\n"); std::fprintf(fp, "\n"); //variable definitions: int i; for (i = 0; i < (int)traces.size(); i++) { wif_trace* t = traces[i]; t->set_width(); //needed for all vectors t->print_variable_declaration_line(fp); } double inittime = sc_time_stamp().to_seconds(); previous_time = inittime/timescale_unit; // Dump all values at initial time std::sprintf(buf, "All initial values are dumped below at time " "%g sec = %g timescale units.", inittime, inittime/timescale_unit ); write_comment(buf); double_to_special_int64(inittime/timescale_unit, &previous_time_units_high, &previous_time_units_low ); for (i = 0; i < (int)traces.size(); i++) { wif_trace* t = traces[i]; t->write(fp); }}// ----------------------------------------------------------------------------#define DEFN_TRACE_METHOD(tp) \void \wif_trace_file::trace( const tp& object_, const std::string& name_ ) \{ \ if( initialized ) { \ put_error_message( \ "No traces can be added once simulation has started.\n" \ "To add traces, create a new wif trace file.", false ); \ } \ std::string temp_wif_name; \ create_wif_name( &temp_wif_name ); \ traces.push_back( new wif_ ## tp ## _trace( object_, \ name_, \ temp_wif_name ) ); \}DEFN_TRACE_METHOD(bool)DEFN_TRACE_METHOD(float)DEFN_TRACE_METHOD(double)#undef DEFN_TRACE_METHOD#define DEFN_TRACE_METHOD(tp) \void \wif_trace_file::trace(const sc_dt::tp& object_, const std::string& name_)\{ \ if( initialized ) { \ put_error_message( \ "No traces can be added once simulation has started.\n" \ "To add traces, create a new wif trace file.", false ); \ } \ std::string temp_wif_name; \ create_wif_name( &temp_wif_name ); \ traces.push_back( new wif_ ## tp ## _trace( object_, \ name_, \ temp_wif_name ) ); \}DEFN_TRACE_METHOD(sc_bit)DEFN_TRACE_METHOD(sc_logic)DEFN_TRACE_METHOD(sc_signed)DEFN_TRACE_METHOD(sc_unsigned)DEFN_TRACE_METHOD(sc_int_base)DEFN_TRACE_METHOD(sc_uint_base)DEFN_TRACE_METHOD(sc_fxval)DEFN_TRACE_METHOD(sc_fxval_fast)DEFN_TRACE_METHOD(sc_fxnum)DEFN_TRACE_METHOD(sc_fxnum_fast)#undef DEFN_TRACE_METHOD#define DEFN_TRACE_METHOD_SIGNED(tp) \void \wif_trace_file::trace( const tp& object_, \ const std::string& name_, \ int width_ ) \{ \ if( initialized ) { \ put_error_message( \ "No traces can be added once simulation has started.\n" \ "To add traces, create a new wif trace file.", false ); \ } \ std::string temp_wif_name; \ create_wif_name( &temp_wif_name ); \ traces.push_back( new wif_signed_ ## tp ## _trace( object_, \ name_, \ temp_wif_name, \ width_ ) ); \}#define DEFN_TRACE_METHOD_UNSIGNED(tp) \void \wif_trace_file::trace( const unsigned tp& object_, \ const std::string& name_, \ int width_ ) \{ \ if( initialized ) { \ put_error_message( \ "No traces can be added once simulation has started.\n" \ "To add traces, create a new wif trace file.", false ); \ } \ std::string temp_wif_name; \ create_wif_name( &temp_wif_name ); \ traces.push_back( new wif_unsigned_ ## tp ## _trace( object_, \ name_, \ temp_wif_name, \ width_ ) ); \}DEFN_TRACE_METHOD_SIGNED(char)DEFN_TRACE_METHOD_SIGNED(short)DEFN_TRACE_METHOD_SIGNED(int)DEFN_TRACE_METHOD_SIGNED(long)DEFN_TRACE_METHOD_UNSIGNED(char)DEFN_TRACE_METHOD_UNSIGNED(short)DEFN_TRACE_METHOD_UNSIGNED(int)DEFN_TRACE_METHOD_UNSIGNED(long)#undef DEFN_TRACE_METHOD_SIGNED#undef DEFN_TRACE_METHOD_UNSIGNED#define DEFN_TRACE_METHOD_LONG_LONG(tp) \void \wif_trace_file::trace( const sc_dt::tp& object_, \ const std::string& name_, \ int width_ ) \{ \ if( initialized ) { \ put_error_message( \ "No traces can be added once simulation has started.\n" \ "To add traces, create a new wif trace file.", false ); \ } \ std::string temp_wif_name; \ create_wif_name( &temp_wif_name ); \ traces.push_back( new wif_ ## tp ## _trace( object_, \ name_, \ temp_wif_name, \ width_ ) ); \}DEFN_TRACE_METHOD_LONG_LONG(int64)DEFN_TRACE_METHOD_LONG_LONG(uint64)#undef DEFN_TRACE_METHOD_LONG_LONGvoidwif_trace_file::trace( const unsigned& object_, const std::string& name_, const char** enum_literals_ ){ if( initialized ) { put_error_message( "No traces can be added once simulation has started.\n" "To add traces, create a new wif trace file.", false ); } std::string temp_wif_name; create_wif_name( &temp_wif_name ); traces.push_back( new wif_enum_trace( object_, name_, temp_wif_name, enum_literals_ ) );}voidwif_trace_file::trace( const sc_dt::sc_bv_base& object_, const std::string& name_ ){ traceT( object_, name_, WIF_BIT );}voidwif_trace_file::trace( const sc_dt::sc_lv_base& object_, const std::string& name_ ){ traceT( object_, name_, WIF_MVL );}voidwif_trace_file::write_comment(const std::string& comment){ //no newline in comments allowed std::fprintf(fp, "comment \"%s\" ;\n", comment.c_str());}voidwif_trace_file::delta_cycles(bool flag){ trace_delta_cycles = flag;}voidwif_trace_file::cycle(bool this_is_a_delta_cycle){ unsigned now_units_high, now_units_low; // Trace delta cycles only when enabled if (!trace_delta_cycles && this_is_a_delta_cycle) return; // Check for initialization if (!initialized) { initialize(); initialized = true; return; }; // double now_units = sc_simulation_time() / timescale_unit; double now_units = sc_time_stamp().to_seconds() / timescale_unit; double_to_special_int64(now_units, &now_units_high, &now_units_low ); // Now do the real stuff unsigned delta_units_high, delta_units_low; double diff_time; diff_time = now_units - previous_time; double_to_special_int64(diff_time, &delta_units_high, &delta_units_low); if (this_is_a_delta_cycle && (diff_time == 0.0)) delta_units_low++; // Increment time for delta cycle simulation // Note that in the last statement above, we are assuming no more // than 2^32 delta cycles - seems realistic bool time_printed = false; wif_trace* const* const l_traces = &traces[0]; for (int i = 0; i < (int)traces.size(); i++) { wif_trace* t = l_traces[i]; if(t->changed()){ if(time_printed == false){ if(delta_units_high){ std::fprintf(fp, "delta_time %u%09u ;\n", delta_units_high, delta_units_low); } else{ std::fprintf(fp, "delta_time %u ;\n", delta_units_low); } time_printed = true; } // Write the variable t->write(fp); } } if(time_printed) { std::fprintf(fp, "\n"); // Put another newline // We update previous_time_units only when we print time because // this field stores the previous time that was printed, not the // previous time this function was called previous_time_units_high = now_units_high; previous_time_units_low = now_units_low; previous_time = now_units; }}// Create a WIF name for a variablevoidwif_trace_file::create_wif_name(std::string* ptr_to_str){ char buf[50]; std::sprintf(buf,"O%d", wif_name_index); *ptr_to_str = buf; wif_name_index++;}std::stringwif_trace_file::obtain_new_index(){ char buf[32]; std::sprintf( buf, "O%d", wif_name_index ++ ); return std::string( buf );}// Cleanup and close trace filewif_trace_file::~wif_trace_file(){ int i; for (i = 0; i < (int)traces.size(); i++) { wif_trace* t = traces[i]; delete t; } fclose(fp);}// Map sc_logic values to values understandable by WIFstatic charmap_sc_logic_state_to_wif_state(char in_char){ char out_char; switch(in_char){ case 'U': case 'X': case 'W': case 'D': out_char = 'X'; break; case '0': case 'L': out_char = '0'; break; case '1': case 'H': out_char = '1'; break; case 'Z': out_char = 'Z'; break; default: out_char = '?'; } return out_char;}#if 0// no output should be done directly to ::std::cout, cerr, etc.voidput_error_message(const char* msg, bool just_warning){ if(just_warning){ ::std::cout << "WIF Trace Warning:\n" << msg << "\n" << ::std::endl; } else{ ::std::cout << "WIF Trace ERROR:\n" << msg << "\n" << ::std::endl; }}#endif // 0// Create the trace filesc_trace_file*sc_create_wif_trace_file(const char * name){ sc_trace_file *tf; tf = new wif_trace_file(name); sc_get_curr_simcontext()->add_trace_file(tf); return tf;}voidsc_close_wif_trace_file( sc_trace_file* tf ){ wif_trace_file* wif_tf = (wif_trace_file*)tf; delete wif_tf;}} // namespace sc_core
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -