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

📄 sc_vcd_trace.cpp

📁 system C源码 一种替代verilog的语言
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*****************************************************************************  The following code is derived, directly or indirectly, from the SystemC  source code Copyright (c) 1996-2006 by all Contributors.  All Rights reserved.  The contents of this file are subject to the restrictions and limitations  set forth in the SystemC Open Source License Version 2.4 (the "License");  You may not use this file except in compliance with such restrictions and  limitations. You may obtain instructions on how to receive a copy of the  License at http://www.systemc.org/. Software distributed by Contributors  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF  ANY KIND, either express or implied. See the License for the specific  language governing rights and limitations under the License. *****************************************************************************//*****************************************************************************  sc_vcd_trace.cpp - Implementation of VCD tracing.  Original Author - Abhijit Ghosh, Synopsys, Inc. *****************************************************************************//*****************************************************************************  MODIFICATION LOG - modifiers, enter your name, affiliation, date and  changes you are making here.      Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.  Description of Modification: - Replaced 'width' of sc_(u)int with their                                 'bitwidth()'.          Name, Affiliation, Date:  Description of Modification: *****************************************************************************//*****************************************************************************   Acknowledgement: The tracing mechanism is based on the tracing   mechanism developed at Infineon (formerly Siemens HL). Though this   code is somewhat different, and significantly enhanced, the basics   are identical to what was originally contributed by Infineon.  The   contribution of Infineon in the development of this tracing   technology is hereby acknowledged. *****************************************************************************/#include <assert.h>#include <time.h>#include <cstdlib>#include "sysc/kernel/sc_simcontext.h"#include "sysc/kernel/sc_ver.h"#include "sysc/datatypes/bit/sc_bit.h"#include "sysc/datatypes/bit/sc_logic.h"#include "sysc/datatypes/bit/sc_lv_base.h"#include "sysc/datatypes/int/sc_signed.h"#include "sysc/datatypes/int/sc_unsigned.h"#include "sysc/datatypes/int/sc_int_base.h"#include "sysc/datatypes/int/sc_uint_base.h"#include "sysc/datatypes/fx/fx.h"#include "sysc/tracing/sc_vcd_trace.h"namespace sc_core {static bool running_regression = false;// Forward declarations for functions that come later in the file// Map sc_dt::sc_logic to printable VCDstatic char map_sc_logic_state_to_vcd_state(char in_char);// Remove name problems associated with [] in vcd namesstatic void remove_vcd_name_problems(std::string& name);const char* vcd_types[vcd_trace_file::VCD_LAST]={"wire","real"};// ----------------------------------------------------------------------------//  CLASS : vcd_trace////  Base class for VCD traces.// ----------------------------------------------------------------------------class vcd_trace{public:    vcd_trace(const std::string& name_, const std::string& vcd_name_);    // Needs to be pure virtual as has to be defined by the particular    // type being traced    virtual void write(FILE* f) = 0;        virtual void set_width();    static const char* strip_leading_bits(const char* originalbuf);    // Comparison function needs to be pure virtual too    virtual bool changed() = 0;    // Make this virtual as some derived classes may overwrite    virtual void print_variable_declaration_line(FILE* f);    void compose_data_line(char* rawdata, char* compdata);    std::string compose_line(const std::string data);    virtual ~vcd_trace();    const std::string name;    const std::string vcd_name;    const char* vcd_var_typ_name;    int bit_width; };vcd_trace::vcd_trace(const std::string& name_,		     const std::string& vcd_name_): name(name_),  vcd_name(vcd_name_),  bit_width(0){    /* Intentionally blank */}        voidvcd_trace::compose_data_line(char* rawdata, char* compdata){    assert(rawdata != compdata);    if(bit_width == 0)    {        compdata[0] = '\0';    }    else    {        if(bit_width == 1)        {            compdata[0] = rawdata[0];            strcpy(&(compdata[1]), vcd_name.c_str());        }        else        {            const char* effective_begin = strip_leading_bits(rawdata);            std::sprintf(compdata, "b%s %s", effective_begin, vcd_name.c_str());        }    }}// same as above but not that uglystd::stringvcd_trace::compose_line(const std::string data){  if(bit_width == 0)    return "";  if(bit_width == 1)    return data + vcd_name;  return std::string("b")+strip_leading_bits(data.c_str())+" "+vcd_name;}voidvcd_trace::print_variable_declaration_line(FILE* f){    char buf[2000];    if ( bit_width <= 0 )    {        std::sprintf(buf, "Traced object \"%s\" has 0 Bits, cannot be traced.",	    name.c_str());        put_error_message(buf, false);    }    else    {	std::string namecopy = name; 	remove_vcd_name_problems(namecopy);	if ( bit_width == 1 )	{	    std::sprintf(buf, "$var %s  % 3d  %s  %s       $end\n",		vcd_var_typ_name,		bit_width,		vcd_name.c_str(),		namecopy.c_str());	}	else	{	    std::sprintf(buf, "$var %s  % 3d  %s  %s [%d:0]  $end\n",                vcd_var_typ_name,		bit_width,		vcd_name.c_str(),		namecopy.c_str(),		bit_width-1);	}        std::fputs(buf, f);    }}voidvcd_trace::set_width(){  /* Intentionally Blank, should be defined for each type separately */}const char*vcd_trace::strip_leading_bits(const char* originalbuf){    //*********************************************************************    // - Remove multiple leading 0,z,x, and replace by only one    // - For example,    //    b000z100    -> b0z100    //    b00000xxx   -> b0xxx    //    b000        -> b0    //    bzzzzz1     -> bz1    //    bxxxz10     -> xz10    // - For leading 0's followed by 1, remove all leading 0's    //    b0000010101 -> b10101      const char* position = originalbuf;    if( strlen(originalbuf) < 2 ||	(originalbuf[0] != 'z' && originalbuf[0] != 'x' &&	 originalbuf[0] != '0' ))      return originalbuf;    char first_char = *position;    while(*position == first_char)    {        position++;    }    if(first_char == '0' && *position == '1')        return position;    // else    return position-1;}vcd_trace::~vcd_trace(){  /* Intentionally Blank */}template <class T>class vcd_T_trace : public vcd_trace{  public:    vcd_T_trace( const T& object_,		 const std::string& name_,		 const std::string& vcd_name_,		 vcd_trace_file::vcd_enum type_ )    : vcd_trace( name_, vcd_name_ ),      object( object_ ),      old_value( object_ )    {        vcd_var_typ_name = vcd_types[type_];    }    void write( FILE* f )    {        std::fprintf( f, "%s", compose_line( 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 vcd_T_trace<sc_dt::sc_bv_base> vcd_sc_bv_trace;typedef vcd_T_trace<sc_dt::sc_lv_base> vcd_sc_lv_trace;// Trace sc_dt::sc_bv_base (sc_dt::sc_bv)voidvcd_trace_file::trace(    const sc_dt::sc_bv_base& object, const std::string& name){   traceT(object,name);}   // Trace sc_dt::sc_lv_base (sc_dt::sc_lv)voidvcd_trace_file::trace(    const sc_dt::sc_lv_base& object, const std::string& name){   traceT(object,name);}/*****************************************************************************/class vcd_bool_trace : public vcd_trace {public:    vcd_bool_trace(const bool& object_,		   const std::string& name_,		   const std::string& vcd_name_);    void write(FILE* f);    bool changed();protected:    const bool& object;    bool old_value;};vcd_bool_trace::vcd_bool_trace(const bool& object_,			       const std::string& name_,			       const std::string& vcd_name_): vcd_trace(name_, vcd_name_), object(object_){    vcd_var_typ_name = "wire";    bit_width = 1;    old_value = object;}boolvcd_bool_trace::changed(){    return object != old_value;}voidvcd_bool_trace::write(FILE* f){    if (object == true) std::fputc('1', f);    else std::fputc('0', f);    std::fprintf(f,"%s", vcd_name.c_str());    old_value = object;}//*****************************************************************************class vcd_sc_bit_trace : public vcd_trace {public:    vcd_sc_bit_trace(const sc_dt::sc_bit& , const std::string& ,     	const std::string& );    void write(FILE* f);    bool changed();protected:    const sc_dt::sc_bit& object;    sc_dt::sc_bit old_value;};vcd_sc_bit_trace::vcd_sc_bit_trace( const sc_dt::sc_bit& object_,				    const std::string& name,				    const std::string& vcd_name): vcd_trace(name, vcd_name), object( object_ ){    vcd_var_typ_name = "wire";    bit_width = 1;    old_value = object;}boolvcd_sc_bit_trace::changed(){    return object != old_value;}voidvcd_sc_bit_trace::write(FILE* f){    if (object == true) std::fputc('1', f);    else std::fputc('0', f);    std::fprintf(f,"%s", vcd_name.c_str());    old_value = object;}/*****************************************************************************/class vcd_sc_logic_trace : public vcd_trace {public:    vcd_sc_logic_trace(const sc_dt::sc_logic& object_,		       const std::string& name_,		       const std::string& vcd_name_);    void write(FILE* f);    bool changed();protected:        const sc_dt::sc_logic& object;    sc_dt::sc_logic old_value;};vcd_sc_logic_trace::vcd_sc_logic_trace(const sc_dt::sc_logic& object_,				       const std::string& name_,				       const std::string& vcd_name_) : vcd_trace(name_, vcd_name_), object(object_){    vcd_var_typ_name = "wire";    bit_width = 1;    old_value = object;}boolvcd_sc_logic_trace::changed(){    return object != old_value;}voidvcd_sc_logic_trace::write(FILE* f){    char out_char;    out_char = map_sc_logic_state_to_vcd_state(object.to_char());    std::fputc(out_char, f);     std::fprintf(f,"%s", vcd_name.c_str());    old_value = object;}/*****************************************************************************/class vcd_sc_unsigned_trace : public vcd_trace {public:    vcd_sc_unsigned_trace(const sc_dt::sc_unsigned& object,			  const std::string& name_,			  const std::string& vcd_name_);    void write(FILE* f);    bool changed();    void set_width();protected:        const sc_dt::sc_unsigned& object;    sc_dt::sc_unsigned old_value;};vcd_sc_unsigned_trace::vcd_sc_unsigned_trace(const sc_dt::sc_unsigned& object_,					     const std::string& name_,					     const std::string& vcd_name_) : vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length())// The last may look strange, but is correct{    vcd_var_typ_name = "wire";    old_value = object;}boolvcd_sc_unsigned_trace::changed(){    return object != old_value;}voidvcd_sc_unsigned_trace::write(FILE* f){    char rawdata[1000], *rawdata_ptr = rawdata;    char compdata[1000];    int bitindex;    for (bitindex = object.length() - 1; bitindex >= 0; --bitindex) {        *rawdata_ptr++ = "01"[(object)[bitindex]];    }    *rawdata_ptr = '\0';    compose_data_line(rawdata, compdata);    std::fputs(compdata, f);    old_value = object;}voidvcd_sc_unsigned_trace::set_width(){    bit_width = object.length();}/*****************************************************************************/class vcd_sc_signed_trace : public vcd_trace {public:    vcd_sc_signed_trace(const sc_dt::sc_signed& object,			const std::string& name_,			const std::string& vcd_name_);    void write(FILE* f);    bool changed();    void set_width();protected:        const sc_dt::sc_signed& object;    sc_dt::sc_signed old_value;};vcd_sc_signed_trace::vcd_sc_signed_trace(const sc_dt::sc_signed& object_,					 const std::string& name_,					 const std::string& vcd_name_) : vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length()){    vcd_var_typ_name = "wire";    old_value = object;}boolvcd_sc_signed_trace::changed(){    return object != old_value;}voidvcd_sc_signed_trace::write(FILE* f){    char rawdata[1000], *rawdata_ptr = rawdata;    char compdata[1000];    int bitindex;    for (bitindex = object.length() - 1; bitindex >= 0; --bitindex) {        *rawdata_ptr++ = "01"[(object)[bitindex]];    }    *rawdata_ptr = '\0';    compose_data_line(rawdata, compdata);    std::fputs(compdata, f);    old_value = object;}voidvcd_sc_signed_trace::set_width(){    bit_width = object.length();}/*****************************************************************************/class vcd_sc_uint_base_trace : public vcd_trace {public:    vcd_sc_uint_base_trace(const sc_dt::sc_uint_base& object,			   const std::string& name_,			   const std::string& vcd_name_);    void write(FILE* f);    bool changed();    void set_width();protected:        const sc_dt::sc_uint_base& object;    sc_dt::sc_uint_base old_value;};vcd_sc_uint_base_trace::vcd_sc_uint_base_trace(                                          const sc_dt::sc_uint_base& object_,					  const std::string& name_,					  const std::string& vcd_name_): vcd_trace(name_, vcd_name_), object(object_), old_value(object_.length())// The last may look strange, but is correct{    vcd_var_typ_name = "wire";    old_value = object;}boolvcd_sc_uint_base_trace::changed(){

⌨️ 快捷键说明

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