sc_wif_trace.cpp
来自「基于4个mips核的noc设计」· C++ 代码 · 共 1,863 行 · 第 1/4 页
CPP
1,863 行
{ 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_bv_base> wif_sc_bv_trace;typedef wif_T_trace<sc_lv_base> wif_sc_lv_trace;//***********************************************************************// wif_trace_file functions//***********************************************************************wif_trace_file::wif_trace_file(const char * name){ sc_string file_name = name ; file_name += ".awif"; fp = fopen((const char *) file_name, "w"); if (!fp) { sc_string msg = sc_string("Cannot write trace file '") + file_name + "'"; 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 fprintf(fp, "init ;\n\n"); //timescale: if (timescale_unit == 1e-15) sprintf(buf,"0"); else if(timescale_unit == 1e-14) sprintf(buf,"1"); else if(timescale_unit == 1e-13) sprintf(buf,"2"); else if(timescale_unit == 1e-12) sprintf(buf,"3"); else if(timescale_unit == 1e-11) sprintf(buf,"4"); else if(timescale_unit == 1e-10) sprintf(buf,"5"); else if(timescale_unit == 1e-9) sprintf(buf,"6"); else if(timescale_unit == 1e-8) sprintf(buf,"7"); else if(timescale_unit == 1e-7) sprintf(buf,"8"); else if(timescale_unit == 1e-6) sprintf(buf,"9"); else if(timescale_unit == 1e-5) sprintf(buf,"10"); else if(timescale_unit == 1e-4) sprintf(buf,"11"); else if(timescale_unit == 1e-3) sprintf(buf,"12"); else if(timescale_unit == 1e-2) sprintf(buf,"13"); else if(timescale_unit == 1e-1) sprintf(buf,"14"); else if(timescale_unit == 1e0) sprintf(buf,"15"); else if(timescale_unit == 1e1) sprintf(buf,"16"); else if(timescale_unit == 1e2) sprintf(buf,"17"); 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); fprintf(fp, "comment \"ASCII WIF file produced on date: %s\" ;\n", buf); //version: fprintf(fp, "comment \"Created by %s\" ;\n", sc_version()); //conversion info 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 ) { cout << "WARNING: Default time step is used for WIF tracing." << endl; } // Define the two types we need to represent bool and sc_logic fprintf(fp, "type scalar \"BIT\" enum '0', '1' ;\n"); fprintf(fp, "type scalar \"MVL\" enum '0', '1', 'X', 'Z', '?' ;\n"); fprintf(fp, "\n"); //variable definitions: int i; for (i = 0; i < 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 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 < traces.size(); i++) { wif_trace* t = traces[i]; t->write(fp); }}void wif_trace_file::sc_set_wif_time_unit(int exponent10_seconds){ if(initialized){ wif_put_error_message("WIF trace timescale unit cannot be changed once tracing has begun.\n" "To change the scale, create a new trace file.", false); return; } if(exponent10_seconds < -15 || exponent10_seconds > 2){ wif_put_error_message( "set_wif_time_unit() has valid exponent range -15...+2.", false); return; } if (exponent10_seconds == -15) timescale_unit = 1e-15; else if(exponent10_seconds == -14) timescale_unit = 1e-14; else if(exponent10_seconds == -13) timescale_unit = 1e-13; else if(exponent10_seconds == -12) timescale_unit = 1e-12; else if(exponent10_seconds == -11) timescale_unit = 1e-11; else if(exponent10_seconds == -10) timescale_unit = 1e-10; else if(exponent10_seconds == -9) timescale_unit = 1e-9; else if(exponent10_seconds == -8) timescale_unit = 1e-8; else if(exponent10_seconds == -7) timescale_unit = 1e-7; else if(exponent10_seconds == -6) timescale_unit = 1e-6; else if(exponent10_seconds == -5) timescale_unit = 1e-5; else if(exponent10_seconds == -4) timescale_unit = 1e-4; else if(exponent10_seconds == -3) timescale_unit = 1e-3; else if(exponent10_seconds == -2) timescale_unit = 1e-2; else if(exponent10_seconds == -1) timescale_unit = 1e-1; else if(exponent10_seconds == 0) timescale_unit = 1e0; else if(exponent10_seconds == 1) timescale_unit = 1e1; else if(exponent10_seconds == 2) timescale_unit = 1e2; char buf[200]; sprintf(buf, "Note: WIF trace timescale unit is set by user to 1e%d sec.\n", exponent10_seconds); cout << buf << flush; timescale_set_by_user = true;}// ----------------------------------------------------------------------------#define DEFN_TRACE_METHOD(tp) \void \wif_trace_file::trace( const tp& object_, const sc_string& name_ ) \{ \ if( initialized ) { \ wif_put_error_message( \ "No traces can be added once simulation has started.\n" \ "To add traces, create a new wif trace file.", false ); \ } \ sc_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(sc_bit)DEFN_TRACE_METHOD(sc_logic)DEFN_TRACE_METHOD(float)DEFN_TRACE_METHOD(double)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 sc_string& name_, \ int width_ ) \{ \ if( initialized ) { \ wif_put_error_message( \ "No traces can be added once simulation has started.\n" \ "To add traces, create a new wif trace file.", false ); \ } \ sc_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 sc_string& name_, \ int width_ ) \{ \ if( initialized ) { \ wif_put_error_message( \ "No traces can be added once simulation has started.\n" \ "To add traces, create a new wif trace file.", false ); \ } \ sc_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_UNSIGNEDvoidwif_trace_file::trace( const unsigned& object_, const sc_string& name_, const char** enum_literals_ ){ if( initialized ) { wif_put_error_message( "No traces can be added once simulation has started.\n" "To add traces, create a new wif trace file.", false ); } sc_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_bv_base& object_, const sc_string& name_ ){ traceT( object_, name_, WIF_BIT );}voidwif_trace_file::trace( const sc_lv_base& object_, const sc_string& name_ ){ traceT( object_, name_, WIF_MVL );}voidwif_trace_file::write_comment(const sc_string& comment){ //no newline in comments allowed fprintf(fp, "comment \"%s\" ;\n", (const char *) comment);}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.raw_data(); for (int i = 0; i < traces.size(); i++) { wif_trace* t = l_traces[i]; if(t->changed()){ if(time_printed == false){ if(delta_units_high){ fprintf(fp, "delta_time %u%09u ;\n", delta_units_high, delta_units_low); } else{ fprintf(fp, "delta_time %u ;\n", delta_units_low); } time_printed = true; } // Write the variable t->write(fp); } } if(time_printed) { 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(sc_string* ptr_to_str){ char buf[50]; sprintf(buf,"O%d", wif_name_index); *ptr_to_str = buf; wif_name_index++;}sc_stringwif_trace_file::obtain_new_index(){ char buf[32]; sprintf( buf, "O%d", wif_name_index ++ ); return sc_string( buf );}// Cleanup and close trace filewif_trace_file::~wif_trace_file(){ int i; for (i = 0; i < 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;}// no output should be done directly to cout, cerr, etc.voidwif_put_error_message(const char* msg, bool just_warning){ if(just_warning){ cout << "WIF Trace Warning:\n" << msg << "\n" << endl; } else{ cout << "WIF Trace ERROR:\n" << msg << "\n" << endl; }}// 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;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?