⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc_vcd_trace.cpp

📁 system C源码 一种替代verilog的语言
💻 CPP
📖 第 1 页 / 共 4 页
字号:
{    std::string file_name = name ;    file_name += ".vcd";    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 this the default    initialized = false;    vcd_name_index = 0;    // default time step is the time resolution    timescale_unit = sc_get_time_resolution().to_seconds();    timescale_set_by_user = false;}void vcd_trace_file::initialize(){    char buf[2000];    //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, "$date\n     %s\n$end\n\n", buf);    //version:    std::fprintf(fp, "$version\n %s\n$end\n\n", sc_version());    //timescale:    static struct SC_TIMESCALE_TO_TEXT {        double       unit;        const char*  text;    } timescale_to_text [] = {        { sc_time(1, SC_FS).to_seconds(), "1 fs" },        { sc_time(10, SC_FS).to_seconds(), "10 fs" },        { sc_time(100, SC_FS).to_seconds(),"100 fs" },        { sc_time(1, SC_PS).to_seconds(),  "1 ps" },        { sc_time(10, SC_PS).to_seconds(), "10 ps" },        { sc_time(100, SC_PS).to_seconds(),"100 ps" },        { sc_time(1, SC_NS).to_seconds(),  "1 ns" },        { sc_time(10, SC_NS).to_seconds(), "10 ns" },        { sc_time(100, SC_NS).to_seconds(),"100 ns" },        { sc_time(1, SC_US).to_seconds(),  "1 us" },        { sc_time(10, SC_US).to_seconds(), "10 us" },        { sc_time(100, SC_US).to_seconds(),"100 us" },        { sc_time(1, SC_MS).to_seconds(),  "1 ms" },        { sc_time(10, SC_MS).to_seconds(), "10 ms" },        { sc_time(100, SC_MS).to_seconds(),"100 ms" },        { sc_time(1, SC_SEC).to_seconds(),  "1 sec" },        { sc_time(10, SC_SEC).to_seconds(), "10 sec" },        { sc_time(100, SC_SEC).to_seconds(),"100 sec" }    };    static int timescale_to_text_n =        sizeof(timescale_to_text)/sizeof(SC_TIMESCALE_TO_TEXT);    for ( int time_i = 0; time_i < timescale_to_text_n; time_i++ )    {        if (timescale_unit == timescale_to_text[time_i].unit)        {            std::fprintf(fp,"$timescale\n     %s\n$end\n\n",                timescale_to_text[time_i].text);            break;        }    }    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 VCD tracing." << ::std::endl;    }    // Create a dummy scope    std::fputs("$scope module SystemC $end\n", fp);    //variable definitions:    int i;    for (i = 0; i < (int)traces.size(); i++) {        vcd_trace* t = traces[i];        t->set_width(); // needed for all vectors        t->print_variable_declaration_line(fp);    }    std::fputs("$upscope $end\n", fp);    std::fputs("$enddefinitions  $end\n\n", fp);    // double inittime = sc_simulation_time();    double inittime = sc_time_stamp().to_seconds();        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 );    std::fputs("$dumpvars\n",fp);    for (i = 0; i < (int)traces.size(); i++) {        vcd_trace* t = traces[i];        t->write(fp);        std::fputc('\n', fp);    }    std::fputs("$end\n\n", fp);}// ----------------------------------------------------------------------------#define DEFN_TRACE_METHOD(tp)                                                 \void                                                                          \vcd_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 vcd trace file.", false );           \    }                                                                         \    std::string temp_vcd_name;                                           \    create_vcd_name( &temp_vcd_name );                                        \    traces.push_back( new vcd_ ## tp ## _trace( object_,                      \						name_,                        \						temp_vcd_name ) );            \}DEFN_TRACE_METHOD(bool)DEFN_TRACE_METHOD(float)DEFN_TRACE_METHOD(double)#undef DEFN_TRACE_METHOD#define DEFN_TRACE_METHOD(tp)                                                 \void                                                                          \vcd_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 vcd trace file.", false );           \    }                                                                         \    std::string temp_vcd_name;                                           \    create_vcd_name( &temp_vcd_name );                                        \    traces.push_back( new vcd_ ## tp ## _trace( object_,                      \						name_,                        \						temp_vcd_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                                                                          \vcd_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 vcd trace file.", false );           \    }                                                                         \    std::string temp_vcd_name;                                           \    create_vcd_name( &temp_vcd_name );                                        \    traces.push_back( new vcd_signed_ ## tp ## _trace( object_,               \					               name_,                 \						       temp_vcd_name,         \                                                       width_ ) );            \}#define DEFN_TRACE_METHOD_UNSIGNED(tp)                                        \void                                                                          \vcd_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 vcd trace file.", false );           \    }                                                                         \    std::string temp_vcd_name;                                           \    create_vcd_name( &temp_vcd_name );                                        \    traces.push_back( new vcd_unsigned_ ## tp ## _trace( object_,             \				                         name_,               \						         temp_vcd_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                                                                          \vcd_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 vcd trace file.", false );           \    }                                                                         \    std::string temp_vcd_name;                                           \    create_vcd_name( &temp_vcd_name );                                        \    traces.push_back( new vcd_ ## tp ## _trace( object_,                      \				                         name_,               \						         temp_vcd_name,       \                                                         width_ ) );          \}DEFN_TRACE_METHOD_LONG_LONG(int64)DEFN_TRACE_METHOD_LONG_LONG(uint64)#undef DEFN_TRACE_METHOD_LONG_LONGvoidvcd_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 vcd trace file.", false );    }    std::string temp_vcd_name;    create_vcd_name( &temp_vcd_name );    traces.push_back( new vcd_enum_trace( object_,					  name_,					  temp_vcd_name,					  enum_literals_ ) );}voidvcd_trace_file::write_comment(const std::string& comment){    //no newline in comments allowed, as some viewers may crash    std::fputs("$comment\n", fp);    std::fputs(comment.c_str(), fp);    std::fputs("\n$end\n\n", fp);}voidvcd_trace_file::delta_cycles(bool flag){    trace_delta_cycles = flag;}voidvcd_trace_file::cycle(bool this_is_a_delta_cycle){    char message[4000];    unsigned this_time_units_high, this_time_units_low;        // Just to make g++ shut up in the optimized mode    this_time_units_high = this_time_units_low = 0;    // 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_time_stamp().to_seconds() / timescale_unit;    unsigned now_units_high, now_units_low;    double_to_special_int64(now_units, &now_units_high, &now_units_low );    bool now_later_than_previous_time = false;    if( now_units_low > previous_time_units_low         && now_units_high == previous_time_units_high        || now_units_high > previous_time_units_high){        now_later_than_previous_time = true;    }    bool now_equals_previous_time = false;    if(now_later_than_previous_time){        this_time_units_high = now_units_high;        this_time_units_low = now_units_low;    } else {        if( now_units_low == previous_time_units_low	    && now_units_high == previous_time_units_high){	    now_equals_previous_time = true;            this_time_units_high = now_units_high;            this_time_units_low = now_units_low;	}    }    // Since VCD does not understand 0 time progression, we have to fake    // delta cycles with progressing time by one unit    if(this_is_a_delta_cycle){        this_time_units_high = previous_time_units_high;        this_time_units_low = previous_time_units_low + 1;        if(this_time_units_low == 1000000000){            this_time_units_high++;            this_time_units_low=0;        }        static bool warned = false;        if(!warned){	    ::std::cout << "Note: VCD delta cycling with pseudo timesteps (1 unit) "                    "is performed.\n" << ::std::endl;            warned = true;        }    }    // Not a delta cycle and time has not progressed    if( ! this_is_a_delta_cycle && now_equals_previous_time &&	( now_units_high != 0 || now_units_low != 0 ) ) {	// Don't print the message at time zero        static bool warned = false;        if( ! warned && ! running_regression ) {            std::sprintf(message,                    "Multiple cycles found with same (%u) time units count.\n"                    "Waveform viewers will only show the states of the last one.\n"                    "Use ((vcd_trace_file*)vcdfile)->sc_set_vcd_time_unit(int exponent10_seconds)\n"                    "to increase time resolution.",                    now_units_low                    );            put_error_message(message, true);            warned = true;        }    }    // Not a delta cycle and time has gone backward    // This will happen with large number of delta cycles between two real    // advances of time    if(!this_is_a_delta_cycle && !now_equals_previous_time &&         !now_later_than_previous_time){        static bool warned = false;        if(!warned){            std::sprintf(message,                    "Cycle found with falling (%u -> %u) time units count.\n"                    "This can occur when delta cycling is activated.\n"                    "Cycles with falling time are not shown.\n"                    "Use ((vcd_trace_file*)vcdfile)->sc_set_vcd_time_unit(int exponent10_seconds)\n"                    "to increase time resolution.",                    previous_time_units_low, now_units_low);            put_error_message(message, true);            warned = true;        }	// Note that we don't set this_time_units_high/low to any value only        // in this case because we are not going to do any tracing. In the        // optimized mode, the compiler complains because of this. Therefore,        // we include the lines at the very beginning of this function to make        // the compiler shut up.        return;     }    // Now do the actual printing     bool time_printed = false;    vcd_trace* const* const l_traces = &traces[0];    for (int i = 0; i < (int)traces.size(); i++) {        vcd_trace* t = l_traces[i];        if(t->changed()){            if(time_printed == false){                char buf[200];                if(this_time_units_high){                    std::sprintf(buf, "#%u%09u", this_time_units_high, this_time_units_low);                }                else{                     std::sprintf(buf, "#%u", this_time_units_low);                }                std::fputs(buf, fp);                std::fputc('\n', fp);                time_printed = true;            }	    // Write the variable            t->write(fp);            std::fputc('\n', fp);        }    }    // Put another newline after all values are printed    if(time_printed) std::fputc('\n', fp);    if(time_printed){        // 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 = this_time_units_high;        previous_time_units_low = this_time_units_low;    }}voidvcd_trace_file::create_vcd_name(std::string* p_destination){    const char first_type_used = 'a';    const int used_types_count = 'z' - 'a' + 1;    int result;    char char4 = (char)(vcd_name_index % used_types_count);    result = vcd_name_index / used_types_count;    char char3 = (char)(result % used_types_count);    result = result / used_types_count;    char char2 = (char)(result % used_types_count);    char buf[20];    std::sprintf(buf, "%c%c%c",            char2 + first_type_used,            char3 + first_type_used,            char4 + first_type_used);    *p_destination = buf;    vcd_name_index++;}// same as abovestd::stringvcd_trace_file::obtain_name(){    const char first_type_used = 'a';    const int used_types_count = 'z' - 'a' + 1;    int result;    char char4 = (char)(vcd_name_index % used_types_count);    result = vcd_name_index / used_types_count;    char char3 = (char)(result % used_types_count);    result = result / used_types_count;    char char2 = (char)(result % used_types_count);    char buf[20];    std::sprintf(buf, "%c%c%c",            char2 + first_type_used,            char3 + first_type_used,            char4 + first_type_used);    vcd_name_index++;    return std::string(buf);}vcd_trace_file::~vcd_trace_file(){    int i;    for (i = 0; i < (int)traces.size(); i++) {        vcd_trace* t = traces[i];        delete t;    }    fclose(fp);}// Functions specific to VCD tracingstatic charmap_sc_logic_state_to_vcd_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;}staticvoidremove_vcd_name_problems(std::string& name){    char message[4000];    static bool warned = false;    bool braces_removed = false;    for (unsigned int i = 0; i< name.length(); i++) {      if (name[i] == '[') {	name[i] = '(';	braces_removed = true;      }      else if (name[i] == ']') {	name[i] = ')';	braces_removed = true;      }    }    if(braces_removed && !warned){        std::sprintf(message,                "Traced objects found with name containing [], which may be\n"                "interpreted by the waveform viewer in unexpected ways.\n"                "So the [] is automatically replaced by ().");        put_error_message(message, true);        warned = true;    }}sc_trace_file*sc_create_vcd_trace_file(const char * name){  sc_trace_file *tf;  tf = new vcd_trace_file(name);  sc_get_curr_simcontext()->add_trace_file(tf);  return tf;}voidsc_close_vcd_trace_file( sc_trace_file* tf ){    vcd_trace_file* vcd_tf = (vcd_trace_file*)tf;    delete vcd_tf; }} // namespace sc_core

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -