Пример #1
0
/*
 * count and list all acc world (prim terminal) drivers
 */
void mei_count_drivers(handle inst, handle net)
{
 int count = 0;
 handle term;
 char s1[1024], s2[1024];
 
 io_printf(" ... processing drivers for %s:\n", acc_fetch_fullname(net));
 for (term = acc_next_driver(net, NULL); term != NULL;
  term = acc_next_driver(net, term))
  {
   if (mei_isinside(inst, term) == 1) { strcpy(s1, "inside"); count++; }
   else strcpy(s1, "outside");

   if (acc_fetch_type(term) == accTerminal)
    {
     sprintf(s2, "prim %s port %d", acc_fetch_fullname(acc_handle_parent(term)),
      acc_fetch_index(term));
    }
   else strcpy(s2, acc_fetch_fullname(term));

   io_printf(" +++ %s is %s driver of %s in %s.\n", s2,
    s1, acc_fetch_fullname(net), acc_fetch_fullname(inst));
  }
 io_printf("net %s has %d inside drivers.\n", acc_fetch_name(net), count);
}
Пример #2
0
/*
 * variable value change call back routine
 */
int var_prt_vclchg(p_vc_record vcp)
{
 /* unsigned long long now, chgtim; */
 int otyp, ltime, htime;
 handle net;
 char s1[1024], s2[1024], s3[1024];

 /* current time */
 ltime = tf_getlongsimtime(&htime);
 /* -- 
 now = ((unsigned long long) ((unsigned long) htime)) << 32
  | ((unsigned long long) ((unsigned long) ltime));

 -* vc record time *- 
 chgtim = ((unsigned long long) ((unsigned long) vcp->vc_hightime)) << 32
  | ((unsigned long long) ((unsigned long) vcp->vc_lowtime));
 -- */

 /* net handle assigned to user data field */
 net = (handle) vcp->user_data; 
 otyp = acc_fetch_type(net);

 if (vcp->vc_reason != event_value_change)
  {
   /* these do not have value, i.e. get va8ue return NULL with error */
   if (otyp == accPort || otyp == accPortBit || otyp == accTerminal)
    {
     sprintf(s1, "obj=%s", acc_fetch_type_str(otyp));
    }
   else strcpy(s1, acc_fetch_value(net, "%b", NULL));
  }

 switch (vcp->vc_reason) {
  case logic_value_change:
   sprintf(s2, "scalar=%u(%s)", (unsigned) vcp->out_value.logic_value, s1); 
   break;
  case sregister_value_change:
   sprintf(s2, "sr-scalar=%u(%s)", (unsigned) vcp->out_value.logic_value, s1); 
   break;
  case real_value_change: case realtime_value_change:
   sprintf(s2, "**error**");
   break;
  case event_value_change:
   strcpy(s2, "**event**");
   break;
  default:
   sprintf(s2, "vector=%s", s1);
 }  

 /* --
 io_printf("--> now %uL (chg time %uL): %s=%s\n", now, chgtim,
 -- */

 if (otyp != accTerminal) strcpy(s3, acc_fetch_fullname(net));
 else strcpy(s3, "**terminal**");

 io_printf("--> now %d (chg time %d): %s=%s\n", ltime, vcp->vc_lowtime, s3,
  s2); 
 return(0);
}
Пример #3
0
/*
 * wire strength change value change call back routine
 */
int wire_prt_vclchg(p_vc_record vcp)
{
 /* unsigned long long now, chgtim; */
 int typ, ltime, htime;
 handle net;
 char s1[1024], s2[1024], s3[1024];

 /* current time */
 ltime = tf_getlongsimtime(&htime);
 /* ---
 now = ((unsigned long long) ((unsigned long) htime)) << 32
  | ((unsigned long long) ((unsigned long) ltime));

 -* vc record time *- 
 chgtim = ((unsigned long long) ((unsigned long) vcp->vc_hightime)) << 32
  | ((unsigned long long) ((unsigned long) vcp->vc_lowtime));
 --- */

 /* net handle assigned to user data field */
 net = (handle) vcp->user_data; 

 /* build strength value string */
 sprintf(s1, "<%d, %d>=%d", (int) vcp->out_value.strengths_s.strength1, 
  (int) vcp->out_value.strengths_s.strength2,   
  (int) vcp->out_value.strengths_s.logic_value);
 
 /* also get value as internal strength %v string */
 strcpy(s2, acc_fetch_value(net, "%v", NULL));

 if (vcp->vc_reason != strength_value_change)
  {
   io_printf("*** ERROR: wire change reason %d - strength change expected\n",
    vcp->vc_reason);
  }
 /* ---
 io_printf("--> now %uL (chg time %uL): %s=%s(%s)\n", now, chgtim,
 -- */

 /* terminals do not have names */
 typ = acc_fetch_type(net);
 if (typ != accTerminal) strcpy(s3, acc_fetch_fullname(net));
 else strcpy(s3, "**terminal**");

 io_printf("--> now %d (chg time %d): %s=%s(%s)\n", ltime, vcp->vc_lowtime,
  s3, s2, s1); 
 return(0);
}
Пример #4
0
/**
 * @name    Find the root handle
 * @brief   Find the root handle using an optional name
 *
 * Get a handle to the root simulator object.  This is usually the toplevel.
 *
 * If no name is provided, we return the first root instance.
 *
 * If name is provided, we check the name against the available objects until
 * we find a match.  If no match is found we return NULL
 */
GpiObjHdl *FliImpl::get_root_handle(const char *name)
{
    mtiRegionIdT root;
    char *rgn_name;
    char *rgn_fullname;
    std::string root_name;
    std::string root_fullname;
    PLI_INT32 accType;
    PLI_INT32 accFullType;

    for (root = mti_GetTopRegion(); root != NULL; root = mti_NextRegion(root)) {
        LOG_DEBUG("Iterating over: %s", mti_GetRegionName(root));
        if (name == NULL || !strcmp(name, mti_GetRegionName(root)))
            break;
    }

    if (!root) {
        goto error;
    }

    rgn_name     = mti_GetRegionName(root);
    rgn_fullname = mti_GetRegionFullName(root);

    root_name     = rgn_name;
    root_fullname = rgn_fullname;
    mti_VsimFree(rgn_fullname);

    LOG_DEBUG("Found toplevel: %s, creating handle....", root_name.c_str());

    accType     = acc_fetch_type(root);
    accFullType = acc_fetch_fulltype(root);

    return create_gpi_obj_from_handle(root, root_name, root_fullname, accType, accFullType);

error:

    LOG_ERROR("FLI: Couldn't find root handle %s", name);

    for (root = mti_GetTopRegion(); root != NULL; root = mti_NextRegion(root)) {
        if (name == NULL)
            break;

        LOG_ERROR("FLI: Toplevel instances: %s != %s...", name, mti_GetRegionName(root));
    }
    return NULL;
}
Пример #5
0
GpiObjHdl* FliImpl::native_check_create(void *raw_hdl, GpiObjHdl *parent)
{
    LOG_DEBUG("Trying to convert a raw handle to an FLI Handle.");

    const char * c_name     = acc_fetch_name(raw_hdl);
    const char * c_fullname = acc_fetch_fullname(raw_hdl);

    if (!c_name) {
        LOG_DEBUG("Unable to query the name of the raw handle.");
        return NULL;
    }

    std::string name    = c_name;
    std::string fq_name = c_fullname;

    PLI_INT32 accType     = acc_fetch_type(raw_hdl);
    PLI_INT32 accFullType = acc_fetch_fulltype(raw_hdl);

    return create_gpi_obj_from_handle(raw_hdl, name, fq_name, accType, accFullType);
}
Пример #6
0
/*
 * routine to add vcl to one net/reg/var/event
 */
static void add_vcl(handle net)
{
 int typ, fulltyp;
 char s1[1024];

 /* DBG remove -- */
 typ = acc_fetch_type(net);
 fulltyp = acc_fetch_fulltype(net);
 if (typ != accTerminal) strcpy(s1, acc_fetch_fullname(net));
 else strcpy(s1, "**terminal**");
 io_printf("Adding vcl for %s type %s (fulltype %s)\n", s1,
  acc_fetch_type_str(typ), acc_fetch_type_str(fulltyp));
 /* --- */

 if (typ == accNet)
  {
   acc_vcl_add(net, wire_prt_vclchg, (void *) net, vcl_verilog_strength);  
  }
 else acc_vcl_add(net, var_prt_vclchg, (void *) net, vcl_verilog_logic);  
}
Пример #7
0
GpiIterator::Status FliIterator::next_handle(std::string &name, GpiObjHdl **hdl, void **raw_hdl)
{
    HANDLE obj;
    GpiObjHdl *new_obj;

    if (!selected)
        return GpiIterator::END;

    gpi_objtype_t obj_type  = m_parent->get_type();
    std::string parent_name = m_parent->get_name();

    /* We want the next object in the current mapping.
     * If the end of mapping is reached then we want to
     * try next one until a new object is found
     */
    do {
        obj = NULL;

        if (m_iterator != m_currentHandles->end()) {
            obj = *m_iterator++;

            /* For GPI_GENARRAY, only allow the generate statements through that match the name
             * of the generate block.
             */
            if (obj_type == GPI_GENARRAY) {
                if (acc_fetch_fulltype(obj) == accForGenerate) {
                    std::string rgn_name = mti_GetRegionName(static_cast<mtiRegionIdT>(obj));
                    if (rgn_name.compare(0,parent_name.length(),parent_name) != 0) {
                        obj = NULL;
                        continue;
                    }
                } else {
                    obj = NULL;
                    continue;
                }
            }

            break;
        } else {
            LOG_DEBUG("No more valid handles in the current OneToMany=%d iterator", *one2many);
        }

        if (++one2many >= selected->end()) {
            obj = NULL;
            break;
        }

        /* GPI_GENARRAY are pseudo-regions and all that should be searched for are the sub-regions */
        if (obj_type == GPI_GENARRAY && *one2many != FliIterator::OTM_REGIONS) {
            LOG_DEBUG("fli_iterator OneToMany=%d skipped for GPI_GENARRAY type", *one2many);
            continue;
        }

        populate_handle_list(*one2many);

        switch (*one2many) {
            case FliIterator::OTM_CONSTANTS:
            case FliIterator::OTM_VARIABLE_SUB_ELEMENTS:
                m_currentHandles = &m_vars;
                m_iterator = m_vars.begin();
                break;
            case FliIterator::OTM_SIGNALS:
            case FliIterator::OTM_SIGNAL_SUB_ELEMENTS:
                m_currentHandles = &m_sigs;
                m_iterator = m_sigs.begin();
                break;
            case FliIterator::OTM_REGIONS:
                m_currentHandles = &m_regs;
                m_iterator = m_regs.begin();
                break;
            default:
                LOG_WARN("Unhandled OneToMany Type (%d)", *one2many);
        }
    } while (!obj);

    if (NULL == obj) {
        LOG_DEBUG("No more children, all relationships tested");
        return GpiIterator::END;
    }

    char *c_name;
    PLI_INT32 accType = 0;
    PLI_INT32 accFullType = 0;
    switch (*one2many) {
        case FliIterator::OTM_CONSTANTS:
        case FliIterator::OTM_VARIABLE_SUB_ELEMENTS:
            c_name = mti_GetVarName(static_cast<mtiVariableIdT>(obj));
            accFullType = accType = mti_GetVarKind(static_cast<mtiVariableIdT>(obj));
            break;
        case FliIterator::OTM_SIGNALS:
            c_name = mti_GetSignalName(static_cast<mtiSignalIdT>(obj));
            accType     = acc_fetch_type(obj);
            accFullType = acc_fetch_fulltype(obj);
            break;
        case FliIterator::OTM_SIGNAL_SUB_ELEMENTS:
            c_name = mti_GetSignalNameIndirect(static_cast<mtiSignalIdT>(obj), NULL, 0);
            accType     = acc_fetch_type(obj);
            accFullType = acc_fetch_fulltype(obj);
            break;
        case FliIterator::OTM_REGIONS:
            c_name = mti_GetRegionName(static_cast<mtiRegionIdT>(obj));
            accType     = acc_fetch_type(obj);
            accFullType = acc_fetch_fulltype(obj);
            break;
        default:
            LOG_WARN("Unhandled OneToMany Type (%d)", *one2many);
    }

    if (!c_name) {
        if (!VS_TYPE_IS_VHDL(accFullType)) {
            *raw_hdl = (void *)obj;
            return GpiIterator::NOT_NATIVE_NO_NAME;
        }

        return GpiIterator::NATIVE_NO_NAME;
    }

    /*
     * If the parent is not a generate loop, then watch for generate handles and create
     * the pseudo-region.
     *
     * NOTE: Taking advantage of the "caching" to only create one pseudo-region object.
     *       Otherwise a list would be required and checked while iterating
     */
    if (*one2many == FliIterator::OTM_REGIONS && obj_type != GPI_GENARRAY && accFullType == accForGenerate) {
        std::string idx_str = c_name;
        std::size_t found = idx_str.find_last_of("(");

        if (found != std::string::npos && found != 0) {
            FliObj *fli_obj = dynamic_cast<FliObj *>(m_parent);

            name        = idx_str.substr(0,found);
            obj         = m_parent->get_handle<HANDLE>();
            accType     = fli_obj->get_acc_type();
            accFullType = fli_obj->get_acc_full_type();
        } else {
            LOG_WARN("Unhandled Generate Loop Format - %s", name.c_str());
            name = c_name;
        }
    } else {
        name = c_name;
    }

    if (*one2many == FliIterator::OTM_SIGNAL_SUB_ELEMENTS) {
        mti_VsimFree(c_name);
    }

    std::string fq_name = m_parent->get_fullname();
    if (fq_name == "/") {
        fq_name += name;
    } else if (*one2many == FliIterator::OTM_SIGNAL_SUB_ELEMENTS ||
               *one2many == FliIterator::OTM_VARIABLE_SUB_ELEMENTS ||
                obj_type == GPI_GENARRAY) {
        std::size_t found;

        if (obj_type == GPI_STRUCTURE) {
            found = name.find_last_of(".");
        } else {
            found = name.find_last_of("(");
        }

        if (found != std::string::npos) {
            fq_name += name.substr(found);
            if (obj_type != GPI_GENARRAY) {
                name = name.substr(found+1);
            }
        } else {
            LOG_WARN("Unhandled Sub-Element Format - %s", name.c_str());
            fq_name += "/" + name;
        }
    } else {
        fq_name += "/" + name;
    }

    FliImpl *fli_impl = reinterpret_cast<FliImpl *>(m_impl);
    new_obj = fli_impl->create_gpi_obj_from_handle(obj, name, fq_name, accType, accFullType);
    if (new_obj) {
        *hdl = new_obj;
        return GpiIterator::NATIVE;
    } else {
        return GpiIterator::NOT_NATIVE;
    }
}
Пример #8
0
/**
 * @name    Native Check Create
 * @brief   Determine whether a simulation object is native to FLI and create
 *          a handle if it is
 */
GpiObjHdl*  FliImpl::native_check_create(int32_t index, GpiObjHdl *parent)
{
    gpi_objtype_t obj_type = parent->get_type();

    HANDLE hdl;
    PLI_INT32 accType;
    PLI_INT32 accFullType;
    char buff[14];

    if (obj_type == GPI_GENARRAY) {
        LOG_DEBUG("Looking for index %d from %s", index, parent->get_name_str());

        snprintf(buff, 14, "(%d)", index);

        std::string idx = buff;
        std::string name = parent->get_name() + idx;
        std::string fq_name = parent->get_fullname() + idx;

        std::vector<char> writable(fq_name.begin(), fq_name.end());
        writable.push_back('\0');

        if ((hdl = mti_FindRegion(&writable[0])) != NULL) {
            accType     = acc_fetch_type(hdl);
            accFullType = acc_fetch_fulltype(hdl);
            LOG_DEBUG("Found region %s -> %p", fq_name.c_str(), hdl);
            LOG_DEBUG("        Type: %d", accType);
            LOG_DEBUG("   Full Type: %d", accFullType);
        } else {
            LOG_DEBUG("Didn't find anything named %s", &writable[0]);
            return NULL;
        }

        return create_gpi_obj_from_handle(hdl, name, fq_name, accType, accFullType);
    } else if (obj_type == GPI_REGISTER || obj_type == GPI_ARRAY || obj_type == GPI_STRING) {
        FliValueObjHdl *fli_obj = reinterpret_cast<FliValueObjHdl *>(parent);

        LOG_DEBUG("Looking for index %u from %s", index, parent->get_name_str());

        if ((hdl = fli_obj->get_sub_hdl(index)) == NULL) {
            LOG_DEBUG("Didn't find the index %d", index);
            return NULL;
        }

        snprintf(buff, 14, "(%d)", index);

        std::string idx = buff;
        std::string name = parent->get_name() + idx;
        std::string fq_name = parent->get_fullname() + idx;

        if (!(fli_obj->is_var())) {
            accType     = acc_fetch_type(hdl);
            accFullType = acc_fetch_fulltype(hdl);
            LOG_DEBUG("Found a signal %s -> %p", fq_name.c_str(), hdl);
            LOG_DEBUG("        Type: %d", accType);
            LOG_DEBUG("   Full Type: %d", accFullType);
        } else {
            accFullType = accType = mti_GetVarKind(static_cast<mtiVariableIdT>(hdl));
            LOG_DEBUG("Found a variable %s -> %p", fq_name.c_str(), hdl);
            LOG_DEBUG("        Type: %d", accType);
            LOG_DEBUG("   Full Type: %d", accFullType);
        }
        return create_gpi_obj_from_handle(hdl, name, fq_name, accType, accFullType);
    } else {
        LOG_ERROR("FLI: Parent of type %d must be of type GPI_GENARRAY, GPI_REGISTER, GPI_ARRAY, or GPI_STRING to have an index.", obj_type);
        return NULL;
    }
}
Пример #9
0
/**
 * @name    Native Check Create
 * @brief   Determine whether a simulation object is native to FLI and create
 *          a handle if it is
 */
GpiObjHdl*  FliImpl::native_check_create(std::string &name, GpiObjHdl *parent)
{
    bool search_rgn       = false;
    bool search_sig       = false;
    bool search_var       = false;

    std::string   fq_name  = parent->get_fullname();
    gpi_objtype_t obj_type = parent->get_type();

    if (fq_name == "/") {
        fq_name += name;
        search_rgn = true;
        search_sig = true;
        search_var = true;
    } else if (obj_type == GPI_MODULE) {
        fq_name += "/" + name;
        search_rgn = true;
        search_sig = true;
        search_var = true;
    } else if (obj_type == GPI_STRUCTURE) {
        FliValueObjHdl *fli_obj = reinterpret_cast<FliValueObjHdl *>(parent);

        fq_name += "." + name;
        search_rgn = false;
        search_var = fli_obj->is_var();
        search_sig = !search_var;
    } else {
        LOG_ERROR("FLI: Parent of type %d must be of type GPI_MODULE or GPI_STRUCTURE to have a child.", obj_type);
        return NULL;
    }

    LOG_DEBUG("Looking for child %s from %s", name.c_str(), parent->get_name_str());

    std::vector<char> writable(fq_name.begin(), fq_name.end());
    writable.push_back('\0');

    HANDLE hdl = NULL;
    PLI_INT32 accType;
    PLI_INT32 accFullType;

    if (search_rgn && (hdl = mti_FindRegion(&writable[0])) != NULL) {
        accType     = acc_fetch_type(hdl);
        accFullType = acc_fetch_fulltype(hdl);
        LOG_DEBUG("Found region %s -> %p", fq_name.c_str(), hdl);
        LOG_DEBUG("        Type: %d", accType);
        LOG_DEBUG("   Full Type: %d", accFullType);
    } else if (search_sig && (hdl = mti_FindSignal(&writable[0])) != NULL) {
        accType     = acc_fetch_type(hdl);
        accFullType = acc_fetch_fulltype(hdl);
        LOG_DEBUG("Found a signal %s -> %p", fq_name.c_str(), hdl);
        LOG_DEBUG("        Type: %d", accType);
        LOG_DEBUG("   Full Type: %d", accFullType);
    } else if (search_var && (hdl = mti_FindVar(&writable[0])) != NULL) {
        accFullType = accType = mti_GetVarKind(static_cast<mtiVariableIdT>(hdl));
        LOG_DEBUG("Found a variable %s -> %p", fq_name.c_str(), hdl);
        LOG_DEBUG("        Type: %d", accType);
        LOG_DEBUG("   Full Type: %d", accFullType);
    } else if (search_rgn){
        mtiRegionIdT rgn;

        /* If not found, check to see if the name of a generate loop and create a pseudo-region */
        for (rgn = mti_FirstLowerRegion(parent->get_handle<mtiRegionIdT>()); rgn != NULL; rgn = mti_NextRegion(rgn)) {
            if (acc_fetch_fulltype(rgn) == accForGenerate) {
                std::string rgn_name = mti_GetRegionName(static_cast<mtiRegionIdT>(rgn));
                if (rgn_name.compare(0,name.length(),name) == 0) {
                    FliObj *fli_obj = dynamic_cast<FliObj *>(parent);
                    return create_gpi_obj_from_handle(parent->get_handle<HANDLE>(), name, fq_name, fli_obj->get_acc_type(), fli_obj->get_acc_full_type());
                }
            }
        }
    }

    if (NULL == hdl) {
        LOG_DEBUG("Didn't find anything named %s", &writable[0]);
        return NULL;
    }

    /* Generate Loops have inconsistent behavior across fli.  A "name"
     * without an index, i.e. dut.loop vs dut.loop(0), will attempt to map
     * to index 0, if index 0 exists.  If it doesn't then it won't find anything.
     *
     * If this unique case is hit, we need to create the Pseudo-region, with the handle
     * being equivalent to the parent handle.
     */
    if (accFullType == accForGenerate) {
        FliObj *fli_obj = dynamic_cast<FliObj *>(parent);
        return create_gpi_obj_from_handle(parent->get_handle<HANDLE>(), name, fq_name, fli_obj->get_acc_type(), fli_obj->get_acc_full_type());
    }

    return create_gpi_obj_from_handle(hdl, name, fq_name, accType, accFullType);
}
Пример #10
0
/*************************************************
  lxt2_add
    - add object to file
 ************************************************/
static void lxt2_add( handle object, int depth )
{
    int	   real  = 0;
    int	   event = 0;
    int	   flags;
    int    msb;
    int	   lsb;
    info_p info;
    handle block;
    handle term;
    static int filter[] = {
	accIntegerVar,
	accNamedEvent,
	accNet,
	accRealVar,
	accRegister,
	accTimeVar,
	0
    };

    switch( acc_fetch_type(object) ) {
    case accNamedEvent:
	flags = LXT2_WR_SYM_F_BITS;
	event = 1;
	break;
    case accRealVar:
	flags = LXT2_WR_SYM_F_DOUBLE;
        real = 1;
	break;
    case accIntegerVar:
    case accNet:
    case accPort:
    case accReg:
    case accTimeVar:
    case accParameter:
	flags = LXT2_WR_SYM_F_BITS;
	break;
    case accStatement:
    case accTask:
    case accModule:
	term = null;
	while(1) {
	    term = acc_next( filter, object, term );
	    if( term == null ) {
		break;
	    }
	    lxt2_add( term, depth );
	} 
	if( depth == 1 ) {
	    return;
	}
	block = null;
	while(1) {
	    block = acc_next_child( object, block );
	    if( block == null ) {
		break;
	    }
	    lxt2_add( block, (depth==0) ? 0 : depth-1 );
	} 
	return;
    default:
	return;
    }	
    info = (info_p)malloc( sizeof(info_t) );
    if( !info ) {
	tf_error( "cannot allocate memory" );
        tf_dofinish();
	return;
    }
    info->object     = object;
    info->name       = strdup( acc_fetch_fullname(object) );
    info->next       = lxt.objectList;
    lxt.objectList   = info;
    info->sequence   = lxt.sequence;
    info->event      = event;
    info->real	     = real;
    info->updateNext = 0;

    if( real ) {
    	info->symbol = lxt2_wr_symbol_add( lxt.t, info->name, 0, 0, 0, flags );
    } else if( event ) {
    	info->symbol = lxt2_wr_symbol_add( lxt.t, info->name, 0, 0, 0, flags );
    } else {
    	acc_fetch_range( object, &msb, &lsb );
#if DEBUG
	io_printf( "lxt2_add: %s [ %d : %d ]\n", 
		info->name, msb, lsb );
#endif
    	info->symbol = lxt2_wr_symbol_add( lxt.t, info->name, 0, msb, lsb, flags );
    }
    acc_vcl_add( object, lxt2_changed, (char*)info, vcl_verilog_logic );
#if DEBUG
    io_printf( "lxt2_recordvars: adding %p %s\n", info->symbol, info->name );
#endif
}