
/* ###--------------------------------------------------------------### */
/*									*/
/* file		: vh_lspec.c						*/
/* date		: Oct 26 1993						*/
/* version	: v1.92							*/
/* author	: Pirouz BAZARGAN SABET					*/
/* contents	: This file contains the set of functions used by the	*/
/*		  linker to build data structures, and to check the	*/
/*		  consistency of the description :			*/
/*									*/
/*		  vhl_addlkdfig, vhl_addlkdins, vhl_addsimsig,		*/
/*		  vhl_addbussig, vhl_addwrbsig, vhl_addwrireg,		*/
/*		  vhl_addwriaux, vhl_addwribux, vhl_addprjbvl,		*/
/*		  vhl_addprjrvl, vhl_addredlst, vhl_makgst   ,		*/
/*		  vhl_linker   , vhl_restor   , vhl_resord		*/
/*									*/
/* ###--------------------------------------------------------------### */

#include <stdio.h>
#include MUT_H
#include MLO_H
#include BEH_H
#include PAT_H
#include "vh_ltype.h"
#include "vh_lspec.h"

/* ###--------------------------------------------------------------### */
/* function	: vhl_addlkdfig						*/
/* description	: prepare an empty LKDFIG structure			*/
/* called funct	: mbkalloc						*/
/* ###--------------------------------------------------------------### */

struct lkdfig *vhl_addlkdfig (ptlofig)

struct lofig *ptlofig;

  {
  struct lkdfig *ptlkdfig;

  ptlkdfig         = (struct lkdfig *) mbkalloc (sizeof(struct lkdfig));
  ptlkdfig->NEXT   = VHL_HEDLKF;
  ptlkdfig->NAME   = ptlofig->NAME;
  ptlkdfig->LKDINS = NULL;
  ptlkdfig->SIMSIG = NULL;
  ptlkdfig->BUSSIG = NULL;
  ptlkdfig->VALSIZ = 0;

  VHL_HEDLKF = ptlkdfig;

  return (ptlkdfig);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addlkdins						*/
/* description	: prepare an empty LKDINS structure and then fill its	*/
/*		  fields.						*/
/* called funct	: vhl_addwrbsig, vhl_addwrireg, vhl_addredlst,		*/
/*		  vhl_addwriaux, vhl_addwribux, vhu_toolbug  ,		*/
/*		  vhu_chktab   , vhu_addtab   , reverse      ,		*/
/*		  concatname   , mbkalloc     , addchain		*/
/* ###--------------------------------------------------------------### */

struct lkdins *vhl_addlkdins (dict, ptlkdfig, ptloins, aux_flg, ptvalsiz)

struct dct_entry **dict;
struct lkdfig     *ptlkdfig;
struct loins      *ptloins;
char               aux_flg;
unsigned int      *ptvalsiz;

  {
  int            count;
  struct locon  *ptlocon;
  struct losig  *ptlosig;
  struct befig  *ptbefig;
  struct berin  *ptberin;
  struct bepor  *ptbepor;
  struct beout  *ptbeout;
  struct bebus  *ptbebus;
  struct bebux  *ptbebux;
  struct bereg  *ptbereg;
  struct beaux  *ptbeaux;
  struct lkdins *ptlkdins;
  struct redlst *ptredlst;
  struct simsig *ptsimsig;
  struct bussig *ptbussig;
  struct wrbsig *ptwrbsig;
  struct prjbvl *ptprjbvl;
  struct wrssig *ptwrssig;
  char          *reg_name;
  char          *aux_name;
  char          *bux_name;

  ptlkdins          = (struct lkdins *) mbkalloc (sizeof(struct lkdins));
  ptlkdins->INSNAME = ptloins->INSNAME;
  ptlkdins->EVAL    = 1;

	/* ###------------------------------------------------------### */
	/*    Extract from the dictionnary the  pointer of the BEFIG	*/
	/* related to the instance					*/
	/* ###------------------------------------------------------### */

  ptbefig = (struct befig *)
            vhu_chktab (dict,ptloins->FIGNAME,NULL,VHL_PNTDFN);

  if (ptbefig == NULL)
    vhu_toolbug (13,"vhl_addlkdins",ptloins->INSNAME,0);

	/* ###------------------------------------------------------### */
	/*    Link with the instance's model				*/
	/* ###------------------------------------------------------### */

  ptlkdins->BEFIG   = ptbefig;
  ptlkdins->WRSSIG  = NULL;
  ptlkdins->WRBSIG  = NULL;
  ptlkdins->WRIAUX  = NULL;
  ptlkdins->WRIBUX  = NULL;
  ptlkdins->WRIREG  = NULL;
  ptlkdins->REDLST  = NULL;
  ptlkdins->CIRCUI  = ptbefig->CIRCUI;

  ptlkdins->NEXT   = ptlkdfig->LKDINS;
  ptlkdfig->LKDINS = ptlkdins;

	/* ###------------------------------------------------------### */
	/*    For each BERIN create an empty REDLST (due to evaluation	*/
	/* constraints redlst is organised as a table - see vhx_evalue)	*/
	/* ###------------------------------------------------------### */

  count   = 0;
  ptberin = ptbefig->BERIN;
  while (ptberin != NULL)
    {
    count++;
    ptberin = ptberin->NEXT;
    }

  if (count == 0)
    ptlkdins->REDLST = NULL;
  else
    ptlkdins->REDLST = vhl_addredlst (count);

	/* ###------------------------------------------------------### */
	/*    For each BEOUT create an empty WRSSIG			*/
	/* ###------------------------------------------------------### */

  ptbeout = ptbefig->BEOUT;
  while (ptbeout != NULL)
    {
    ptlkdins->WRSSIG = vhl_addwrssig (ptlkdins, ptbeout, ptvalsiz);
    ptbeout          = ptbeout->NEXT;
    }
  ptlkdins->WRSSIG = (struct wrssig *)
                     reverse ((struct chain *)ptlkdins->WRSSIG);

	/* ###------------------------------------------------------### */
	/*    For each BEBUS create an WRBSIG. The WRBSIG list must be	*/
	/* reversed to obtain the same order of ports as in BEBUS list.	*/
	/* ###------------------------------------------------------### */

  ptbebus = ptbefig->BEBUS;
  while (ptbebus != NULL)
    {
    ptlkdins->WRBSIG = vhl_addwrbsig (ptlkdins, ptbebus, ptvalsiz);
    ptbebus          = ptbebus->NEXT;
    }
  ptlkdins->WRBSIG = (struct wrbsig *)
                     reverse ((struct chain *)ptlkdins->WRBSIG);


	/* ###------------------------------------------------------### */
	/*    For each BEBUX create an WRIBUX. The WRIBUX list must be	*/
	/* reversed to obtain the same order of ports as in BEBUX list.	*/
	/*    Scan the BERIN list (and REDLST) to find the primary input*/
	/* that has the same name and make a link			*/
	/* ###------------------------------------------------------### */

  ptbebux = ptbefig->BEBUX;
  while (ptbebux != NULL)
    {
    ptlkdins->WRIBUX = vhl_addwribux (ptlkdins, ptbebux, ptvalsiz);
    bux_name         = concatname    (ptlkdins->INSNAME,ptbebux->NAME);

    vhu_addtab (dict,bux_name,NULL,VHL_PNTDFN,ptlkdins->WRIBUX);
    vhu_addtab (dict,bux_name,NULL,VHL_SIGDFN,'U');

    ptberin  = ptbefig->BERIN;
    ptredlst = ptlkdins->REDLST;
    while ((char *)ptberin->NAME != ptbebux->NAME)
      {
      ptberin = ptberin->NEXT;
      ptredlst++;
      }
    ptredlst->VALU   = ptlkdins->WRIBUX->CURVAL;
    ptbebux          = ptbebux->NEXT;
    }
  ptlkdins->WRIBUX = (struct wribux *)
                     reverse ((struct chain *)ptlkdins->WRIBUX);

	/* ###------------------------------------------------------### */
	/*    For each BEREG create an WRIREG. The WRIREG list must be	*/
	/* reversed to obtain the same order of ports as in BEREG list.	*/
	/*    Scan the BERIN list (and REDLST) to find the primary input*/
	/* that has the same name and make a link			*/
	/* ###------------------------------------------------------### */

  ptbereg = ptbefig->BEREG;

  while (ptbereg != NULL)
    {
    ptlkdins->WRIREG = vhl_addwrireg (ptlkdins, ptbereg, ptvalsiz);
    reg_name = concatname (ptlkdins->INSNAME,ptbereg->NAME);

    vhu_addtab (dict,reg_name,NULL,VHL_PNTDFN,ptlkdins->WRIREG);
    vhu_addtab (dict,reg_name,NULL,VHL_SIGDFN,'R');

    ptberin  = ptbefig->BERIN;
    ptredlst = ptlkdins->REDLST;
    while ((char *)ptberin->NAME != ptbereg->NAME)
      {
      ptberin = ptberin->NEXT;
      ptredlst++;
      }
    ptredlst->VALU   = ptlkdins->WRIREG->CURVAL;
    ptbereg          = ptbereg->NEXT;
    }
  ptlkdins->WRIREG = (struct wrireg *)
                     reverse ((struct chain *)ptlkdins->WRIREG);

	/* ###------------------------------------------------------### */
	/*    For each BEDLY create an WRIAUX.				*/
	/* ###------------------------------------------------------### */

  ptbeaux = ptbefig->BEDLY;
  while (ptbeaux != NULL)
    {
    ptlkdins->WRIAUX = vhl_addwriaux (ptlkdins, ptbeaux, ptvalsiz);

    ptberin  = ptbefig->BERIN;
    ptredlst = ptlkdins->REDLST;
    while (ptberin->NAME != ptbeaux->NAME)
      {
      ptberin = ptberin->NEXT;
      ptredlst++;
      }
    ptredlst->VALU   = ptlkdins->WRIAUX->CURVAL;
    ptbeaux          = ptbeaux->NEXT;
    }

	/* ###------------------------------------------------------### */
	/*    For each BEAUX create an WRIAUX.				*/
	/* ###------------------------------------------------------### */

  if (aux_flg == 1)
    {
    ptbeaux = ptbefig->BEAUX;
    while (ptbeaux != NULL)
      {
      ptlkdins->WRIAUX = vhl_addwriaux (ptlkdins, ptbeaux, ptvalsiz);
      aux_name         = concatname    (ptlkdins->INSNAME,ptbeaux->NAME);

      vhu_addtab (dict,aux_name,NULL,VHL_PNTDFN,ptlkdins->WRIAUX);
      vhu_addtab (dict,aux_name,NULL,VHL_SIGDFN,'X');

      ptberin  = ptbefig->BERIN;
      ptredlst = ptlkdins->REDLST;
      while (ptberin->NAME != ptbeaux->NAME)
        {
        ptberin = ptberin->NEXT;
        ptredlst++;
        }
      ptredlst->VALU   = ptlkdins->WRIAUX->CURVAL;
      ptbeaux          = ptbeaux->NEXT;
      }
    }

	/* ###------------------------------------------------------### */
	/*    The WRIAUX list must be reversed to obtain the same order	*/
	/* of as in BEAUX (top) and BEDLY (bottom) list.		*/
	/* ###------------------------------------------------------### */

  ptlkdins->WRIAUX = (struct wriaux *)
                     reverse ((struct chain *)ptlkdins->WRIAUX);

	/* ###------------------------------------------------------### */
	/*    For each formal port of the instance find the actual	*/
	/* signal connected to the port and make the link depending on	*/
	/* the type of the port.					*/
	/* ###------------------------------------------------------### */

  ptlocon = ptloins->LOCON;
  while (ptlocon != NULL)
    {
    switch (ptlocon->DIRECTION)
      {

	/* ###------------------------------------------------------### */
	/* For a simple IN port :					*/
	/*   Find the correct REDLST and link it to the BUSSIG or SIMSIG*/
	/*    Add the current LKDINS to the REDINS of the signal.	*/
	/* ###------------------------------------------------------### */

      case ('I') :
        ptberin  = ptbefig->BERIN;
        ptredlst = ptlkdins->REDLST;
        while ((char *)ptberin->NAME != ptlocon->NAME)
          {
          ptberin  = ptberin->NEXT;
          ptredlst++;
          }
        ptlosig = ptlocon->SIG;

        if (vhu_chktab (dict,ptlosig,NULL,VHL_SIGDFN) == VHL_BUSDFN)
          {
          ptbussig = (struct bussig *)
                     vhu_chktab (dict,ptlosig,NULL,VHL_PNTDFN);
          ptbussig->REDINS = addchain (ptbussig->REDINS, ptlkdins);
          ptredlst->VALU   = ptbussig->CURVAL;
          }
        else
          {
          ptsimsig = (struct simsig *)
                     vhu_chktab (dict,ptlosig,NULL,VHL_PNTDFN);
          ptsimsig->REDINS = addchain (ptsimsig->REDINS, ptlkdins);
          ptredlst->VALU   = ptsimsig->CURVAL;
          }
        break;

	/* ###------------------------------------------------------### */
	/* For a simple OUT port :					*/
	/*    Find the correct WRSSIG and link it to the SIMSIG		*/
	/* ###------------------------------------------------------### */

      case ('O') :
        ptbeout  = ptbefig->BEOUT;
        ptwrssig = ptlkdins->WRSSIG;
        while (ptbeout->NAME != ptlocon->NAME)
          {
          ptbeout  = ptbeout->NEXT;
          ptwrssig = ptwrssig->NEXT;
          }
        ptlosig          = ptlocon->SIG;
        ptwrssig->SIMSIG = (struct simsig *)
                           vhu_chktab (dict,ptlosig,NULL,VHL_PNTDFN);
        break;

	/* ###------------------------------------------------------### */
	/* For a bused OUT port :					*/
	/*    Find the correct WRBSIG and link it to the BUSSIG.	*/
	/*    Update the list of projected values of the BUSSIG.	*/
	/* ###------------------------------------------------------### */

      case ('Z') :
        ptbebus  = ptbefig->BEBUS;
        ptwrbsig = ptlkdins->WRBSIG;
        while (ptbebus->NAME != ptlocon->NAME)
          {
          ptbebus  = ptbebus->NEXT;
          ptwrbsig = ptwrbsig->NEXT;
          }
        ptlosig  = ptlocon->SIG;
        ptbussig = (struct bussig *)vhu_chktab (dict,ptlosig,NULL,VHL_PNTDFN);

        ptwrbsig->BUSSIG = ptbussig;
        ptprjbvl         = ptbussig->PRJBVL;

        while (ptprjbvl->GLNEXT != NULL)
          ptprjbvl = ptprjbvl->GLNEXT;
        ptprjbvl->GLNEXT = ptwrbsig->PRJBVL;
        break;

	/* ###------------------------------------------------------### */
	/* For a simple INOUT port :					*/
	/*    Find the correct REDLST and link it to the SIMSIG.	*/
	/*    Add the current LKDINS to the REDINS of the signal.	*/
	/*    Find the correct WRSSIG an link it to the SIMSIG		*/
	/* ###------------------------------------------------------### */

      case ('B') :
        ptberin  = ptbefig->BERIN;
        ptredlst = ptlkdins->REDLST;
        while ((char *)ptberin->NAME != ptlocon->NAME)
          {
          ptberin  = ptberin->NEXT;
          ptredlst++;
          }
        ptlosig  = ptlocon->SIG;
        ptsimsig = (struct simsig *)vhu_chktab (dict,ptlosig,NULL,VHL_PNTDFN);

        ptsimsig->REDINS = addchain (ptsimsig->REDINS, ptlkdins);
        ptredlst->VALU   = ptsimsig->CURVAL;

        ptbeout  = ptbefig->BEOUT;
        ptwrssig = ptlkdins->WRSSIG;
        while (ptbeout->NAME != ptlocon->NAME)
          {
          ptbeout  = ptbeout->NEXT;
          ptwrssig = ptwrssig->NEXT;
          }
        ptwrssig->SIMSIG = ptsimsig;
        break;

	/* ###------------------------------------------------------### */
	/* For a bused INOUT port :					*/
	/*    Find the correct REDLST and link it to the BUSSIG.	*/
	/*    Add the current LKDINS to the REDINS of the signal.	*/
	/*    Find the correct WRBSIG an link it to the BUSSIG.		*/
	/*    Update the list of projected values of the BUSSIG.	*/
	/* ###------------------------------------------------------### */

      case ('T') :
        ptberin  = ptbefig->BERIN;
        ptredlst = ptlkdins->REDLST;
        while (ptberin->NAME != ptlocon->NAME)
          {
          ptberin  = ptberin->NEXT;
          ptredlst++;
          }
        ptlosig  = ptlocon->SIG;
        ptbussig = (struct bussig *)vhu_chktab (dict,ptlosig,NULL,VHL_PNTDFN);

        ptbussig->REDINS = addchain (ptbussig->REDINS, ptlkdins);
        ptredlst->VALU   = ptbussig->CURVAL;

        ptbebus  = ptbefig->BEBUS;
        ptwrbsig = ptlkdins->WRBSIG;
        while (ptbebus->NAME != ptlocon->NAME)
          {
          ptbebus  = ptbebus->NEXT;
          ptwrbsig = ptwrbsig->NEXT;
          }
        ptwrbsig->BUSSIG = ptbussig;
        ptprjbvl         = ptbussig->PRJBVL;
        while (ptprjbvl->GLNEXT != NULL)
          ptprjbvl = ptprjbvl->GLNEXT;
        ptprjbvl->GLNEXT = ptwrbsig->PRJBVL;

        break;

      default :
        vhu_toolbug (18,"vhl_addlkdins",ptloins->INSNAME,ptlocon->DIRECTION);
      }

    ptlocon = ptlocon->NEXT;
    }

  return (ptlkdins);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addsimsig						*/
/* description	: Used to add an structure simsig to an lkdfig		*/
/* called funct	: mbkalloc						*/
/* ###--------------------------------------------------------------### */

struct simsig *vhl_addsimsig (lastsimsig, ptlosig, ptvalsiz)

struct simsig *lastsimsig;
struct losig  *ptlosig;
unsigned int  *ptvalsiz;

  {
  struct simsig *ptsimsig;

  ptsimsig            = (struct simsig *)mbkalloc (sizeof(struct simsig));

  ptsimsig->NAMECHAIN = ptlosig->NAMECHAIN;
  ptsimsig->REDINS    = NULL;
  ptsimsig->CURVAL    = (char *) mbkalloc (sizeof(char));
  ptsimsig->PRJVAL    = '0';
  *(ptsimsig->CURVAL) = '0';

  ptsimsig->NEXT      = lastsimsig;

  *ptvalsiz += 2;

  return (ptsimsig);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addbussig						*/
/* description	: Used to add an structure bussig to an lkdfig		*/
/* called funct	: mbkalloc						*/
/* ###--------------------------------------------------------------### */

struct bussig *vhl_addbussig (lastbussig, ptlosig, ptvalsiz)

struct bussig *lastbussig;
struct losig  *ptlosig;
unsigned int  *ptvalsiz;

  {
  struct bussig *ptbussig;

  ptbussig                 = (struct bussig *)mbkalloc (sizeof(struct bussig));

  ptbussig->NAMECHAIN      = ptlosig->NAMECHAIN;
  ptbussig->REDINS         = NULL;
  ptbussig->CURVAL         = (char *)         mbkalloc (sizeof(char));
  ptbussig->PRJBVL         = (struct prjbvl *)mbkalloc (sizeof(struct prjbvl));
  ptbussig->PRJBVL->GLNEXT = NULL;
  ptbussig->PRJBVL->CNDVAL = '0';
  ptbussig->PRJBVL->DRVVAL = '0';
  ptbussig->PRJBVL->NEXT   = NULL;
  ptbussig->TYPE           = ptlosig->USER->TYPE;

  ptbussig->NEXT           = lastbussig;

  *(ptbussig->CURVAL)      = '0';

  *ptvalsiz += 3;

  return (ptbussig);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addwrbsig						*/
/* description	: Used to add an structure wrbsig to an lkdfig		*/
/* called funct	: mbkalloc, vhl_addprjbvl				*/
/* ###--------------------------------------------------------------### */

struct wrbsig *vhl_addwrbsig (ptlkdins, ptbebus, ptvalsiz)

struct lkdins *ptlkdins;
struct bebus  *ptbebus;
unsigned int *ptvalsiz;

  {
  struct wrbsig *ptwrbsig;
  struct binode *ptbinode;

  ptwrbsig = (struct wrbsig *)mbkalloc (sizeof(struct wrbsig));

  ptwrbsig->PRJBVL = NULL;
  ptwrbsig->BUSSIG = NULL;
  ptwrbsig->BEBUS  = ptbebus;

  ptbinode = ptbebus->BINODE;
  while (ptbinode != NULL)
    {
    ptwrbsig->PRJBVL = vhl_addprjbvl (ptwrbsig->PRJBVL, ptvalsiz);
    ptbinode         = ptbinode->NEXT;
    }

  ptwrbsig->NEXT   = ptlkdins->WRBSIG;
  ptlkdins->WRBSIG = ptwrbsig;

  return (ptwrbsig);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addwrireg						*/
/* description	: Used to add an structure wrireg to an lkdfig		*/
/* called funct	: mbkalloc, vhl_addprjrvl				*/
/* ###--------------------------------------------------------------### */

struct wrireg *vhl_addwrireg (ptlkdins, ptbereg, ptvalsiz)

struct lkdins *ptlkdins;
struct bereg  *ptbereg;
unsigned int  *ptvalsiz;

  {
  struct wrireg *ptwrireg;
  struct binode *ptbinode;

  ptwrireg = (struct wrireg *)mbkalloc (sizeof(struct wrireg));

  ptwrireg->LKDINS    = ptlkdins;
  ptwrireg->BEREG     = ptbereg;

  ptwrireg->PRJRVL    = NULL;
  ptwrireg->CURVAL    = (char *)mbkalloc(sizeof(char));
  *(ptwrireg->CURVAL) = '0';

  ptbinode = ptbereg->BINODE;
  while (ptbinode != NULL)
    {
    ptwrireg->PRJRVL = vhl_addprjrvl (ptwrireg->PRJRVL, ptvalsiz);
    ptbinode         = ptbinode->NEXT;
    }

  ptwrireg->NEXT   = ptlkdins->WRIREG;
  ptlkdins->WRIREG = ptwrireg;

  (*ptvalsiz)++;

  return (ptwrireg);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addwribux						*/
/* description	: Used to add an structure wribux to an lkdfig		*/
/* called funct	: mbkalloc, vhl_addprjbvl				*/
/* ###--------------------------------------------------------------### */

struct wribux *vhl_addwribux (ptlkdins, ptbebux, ptvalsiz)

struct lkdins *ptlkdins;
struct bebux  *ptbebux;
unsigned int  *ptvalsiz;

  {
  struct wribux *ptwribux;
  struct binode *ptbinode;

  ptwribux = (struct wribux *)mbkalloc (sizeof(struct wribux));

  ptwribux->LKDINS    = ptlkdins;
  ptwribux->BEBUX     = ptbebux;

  ptwribux->PRJBVL    = NULL;
  ptwribux->CURVAL    = (char *)mbkalloc(sizeof(char));
  *(ptwribux->CURVAL) = '0';

  ptbinode = ptbebux->BINODE;
  while (ptbinode != NULL)
    {
    ptwribux->PRJBVL = vhl_addprjbvl (ptwribux->PRJBVL, ptvalsiz);
    ptbinode         = ptbinode->NEXT;
    }

  ptwribux->NEXT   = ptlkdins->WRIBUX;
  ptlkdins->WRIBUX = ptwribux;

  (*ptvalsiz)++;

  return (ptwribux);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addwriaux						*/
/* description	: Used to add an structure wriaux to an lkdfig		*/
/* called funct	: mbkalloc						*/
/* ###--------------------------------------------------------------### */

struct wriaux *vhl_addwriaux (ptlkdins, ptbeaux, ptvalsiz)

struct lkdins *ptlkdins;
struct beaux  *ptbeaux;
unsigned int  *ptvalsiz;

  {
  struct wriaux *ptwriaux;

  ptwriaux = (struct wriaux *)mbkalloc (sizeof(struct wriaux));

  ptwriaux->LKDINS    = ptlkdins;
  ptwriaux->PRJVAL    = '0';
  ptwriaux->BEAUX     = ptbeaux;

  ptwriaux->CURVAL    = (char *)mbkalloc(sizeof(char));
  *(ptwriaux->CURVAL) = '0';

  ptwriaux->NEXT   = ptlkdins->WRIAUX;
  ptlkdins->WRIAUX = ptwriaux;

  *ptvalsiz += 2;

  return (ptwriaux);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addwrssig						*/
/* description	: Used to add an structure wrssig to an lkdfig		*/
/* called funct	: mbkalloc						*/
/* ###--------------------------------------------------------------### */

struct wrssig *vhl_addwrssig (ptlkdins, ptbeout, ptvalsiz)

struct lkdins *ptlkdins;
struct beout  *ptbeout;
unsigned int  *ptvalsiz;

  {
  struct wrssig *ptwrssig;

  ptwrssig = (struct wrssig *) mbkalloc (sizeof(struct wrssig));

  ptwrssig->SIMSIG = NULL;
  ptwrssig->BEOUT  = ptbeout;

  ptwrssig->NEXT   = ptlkdins->WRSSIG;
  ptlkdins->WRSSIG = ptwrssig;

  return (ptwrssig);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addprjbvl						*/
/* description	: Used to add an projected bi-value to an wrbsig	*/
/* called funct	: mbkalloc						*/
/* ###--------------------------------------------------------------### */

struct prjbvl *vhl_addprjbvl (lastprjbvl, ptvalsiz)

struct prjbvl *lastprjbvl;
unsigned int  *ptvalsiz;

  {
  struct prjbvl *ptprjbvl;

  ptprjbvl = (struct prjbvl *)mbkalloc (sizeof(struct prjbvl));

  ptprjbvl->CNDVAL = '0';
  ptprjbvl->DRVVAL = '0';

  ptprjbvl->NEXT   = lastprjbvl;
  ptprjbvl->GLNEXT = lastprjbvl;

  *ptvalsiz += 2;

  return (ptprjbvl);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addprjrvl						*/
/* description	: Used to add an projected bi-value to an wrireg	*/
/* called funct	: mbkalloc						*/
/* ###--------------------------------------------------------------### */

struct prjrvl *vhl_addprjrvl (lastprjrvl, ptvalsiz)

struct prjrvl *lastprjrvl;
unsigned int  *ptvalsiz;

  {
  struct prjrvl *ptprjrvl;

  ptprjrvl = (struct prjrvl *)mbkalloc (sizeof(struct prjrvl));

  ptprjrvl->CNDVAL = '0';
  ptprjrvl->DRVVAL = '0';

  ptprjrvl->NEXT   = lastprjrvl;

  *ptvalsiz += 2;

  return (ptprjrvl);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_addredlst						*/
/* description	: Used to add an redlst to an lkdins			*/
/* called funct	: mbkalloc						*/
/* ###--------------------------------------------------------------### */

struct redlst *vhl_addredlst (count)

int count;

  {
  struct redlst *ptredlst;
  struct redlst *pnt;
  int            i;

  ptredlst = (struct redlst *)mbkalloc (count * sizeof(struct redlst));

  pnt = ptredlst;
  for (i=1 ; i<count ; i++)
    {
    pnt->VALU = NULL;
    pnt->NEXT = pnt + 1;
    pnt++;
    }
  pnt->VALU = NULL;
  pnt->NEXT = NULL;

  return (ptredlst);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_makgst						*/
/* description	: This function creates a ghost structure level to	*/
/*		  handle fully behavioural descriptions			*/
/* called funct	: addlofig, addlosig, addchain, mbkalloc		*/
/* ###--------------------------------------------------------------### */

struct lofig *vhl_makgst (ptbefig)

struct befig *ptbefig;

  {
  struct chain *namelst;
  struct locon *ptlocon;
  struct bepor *ptbepor;
  struct lofig *ptlofig;
  struct loins *ptloins;
  struct losig *ptlosig;
  int           index=0;
  char          lofigname[80];

  sprintf (lofigname,"root_of_%s",ptbefig->NAME);
  ptlofig = addlofig (lofigname);

  ptloins = (struct loins *) mbkalloc (sizeof(struct loins));
  ptloins->INSNAME = ptbefig->NAME;
  ptloins->FIGNAME = ptbefig->NAME;
  ptloins->LOCON   = NULL;
  ptloins->USER    = NULL;
  ptloins->NEXT    = NULL;

  ptlofig->LOINS = ptloins;

  ptbepor = ptbefig->BEPOR;
  while (ptbepor != NULL)
    {
    namelst      = addchain (NULL   ,ptbepor->NAME);
    ptlosig      = addlosig (ptlofig,index,namelst,'E',(float) 0);

    if (ptbepor->TYPE != 'B')
      ptlosig->USER = addptype(ptlosig->USER,ptbepor->TYPE,NULL);

    ptlocon      = (struct locon *) mbkalloc (2 * sizeof(struct locon));

    ptlocon->NAME      = ptbepor->NAME;
    ptlocon->SIG       = ptlosig;
    ptlocon->ROOT      = (void *)ptlofig;
    ptlocon->DIRECTION = ptbepor->DIRECTION;
    ptlocon->TYPE      = 'E';
    ptlocon->USER      = NULL;
    ptlocon->NEXT      = ptlofig->LOCON;
    ptlofig->LOCON     = ptlocon++;

    ptlocon->NAME      = ptbepor->NAME;
    ptlocon->SIG       = ptlosig;
    ptlocon->ROOT      = (void *)ptloins;
    ptlocon->DIRECTION = ptbepor->DIRECTION;
    ptlocon->TYPE      = 'I';
    ptlocon->USER      = NULL;
    ptlocon->NEXT      = ptloins->LOCON;
    ptloins->LOCON     = ptlocon;

    ptbepor = ptbepor->NEXT;
    index++;
    }
  ptlofig->LOCON = (struct locon *) reverse (ptlofig->LOCON);
  ptloins->LOCON = (struct locon *) reverse (ptloins->LOCON);

  return (ptlofig);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_linker						*/
/* description	: This function generates the structure used by the	*/
/*		  simulator						*/
/* called funct	: mbkalloc						*/
/* ###--------------------------------------------------------------### */

int vhl_linker (dict, ptpaseq, aux_flg)

struct dct_entry **dict;
struct paseq      *ptpaseq;
char               aux_flg;

  {
  struct lofig  *ptlofig;
  struct losig  *ptlosig;
  struct loins  *ptloins;
  struct locon  *ptlocon;
  struct lkdfig *ptlkdfig;
  struct lkdins *ptlkdins;
  struct bussig *ptbussig;
  struct simsig *ptsimsig;
  int            sig_type;
  int            sig_mode;
  int            max_iol;
  int            i;
  struct paiol  *ptpaiol;
  unsigned int   valsiz = 0;
  int            errflg = 0;

	/* ###------------------------------------------------------### */
	/*    Find the root model of the description by scanning the	*/
	/* list of LOFIGs til the end. (The last LOFIG must be the root)*/
	/* ###------------------------------------------------------### */

  if ((ptlofig = HEAD_LOFIG) == NULL)
    vhu_toolbug (13, "vhl_linker", NULL, 0);

  while (ptlofig->NEXT != NULL)
    ptlofig = ptlofig->NEXT;

  ptlkdfig = vhl_addlkdfig (ptlofig);

	/* ###------------------------------------------------------### */
	/*   For each LOCON of root save its direction in the		*/
	/* dictionnary							*/
	/* ###------------------------------------------------------### */

  ptlocon = ptlofig->LOCON;
  while (ptlocon != NULL)
    {
    vhu_addtab (dict,ptlocon->NAME,NULL,VHL_MODDFN,ptlocon->DIRECTION);
    ptlocon = ptlocon->NEXT;
    }

	/* ###------------------------------------------------------### */
	/*   Create a BUSSIG or a SIMSIG for each LOSIG of root		*/
	/* ###------------------------------------------------------### */

  ptlocon = ptlofig->LOCON;
  while (ptlocon != NULL)
    {
    ptlosig = ptlocon->SIG;
    if (ptlosig->USER == NULL)
      {
      ptlkdfig->SIMSIG = vhl_addsimsig (ptlkdfig->SIMSIG, ptlosig, &valsiz);
      ptsimsig         = ptlkdfig->SIMSIG;
      vhu_addtab (dict,ptlosig,NULL,VHL_PNTDFN,(int)ptsimsig);
      vhu_addtab (dict,ptlosig,NULL,VHL_SIGDFN,VHL_NORDFN);
      vhu_addtab (dict,ptlocon->NAME,NULL,VHL_PNTDFN,ptsimsig);
      vhu_addtab (dict,ptlocon->NAME,NULL,VHL_SIGDFN,'S');
      }
    else
      {
      ptlkdfig->BUSSIG = vhl_addbussig (ptlkdfig->BUSSIG, ptlosig, &valsiz);
      ptbussig         = ptlkdfig->BUSSIG;
      vhu_addtab (dict,ptlosig,NULL,VHL_PNTDFN,ptbussig);
      vhu_addtab (dict,ptlosig,NULL,VHL_SIGDFN,VHL_BUSDFN);
      vhu_addtab (dict,ptlocon->NAME,NULL,VHL_PNTDFN,ptbussig);
      vhu_addtab (dict,ptlocon->NAME,NULL,VHL_SIGDFN,'B');
      }

    ptlocon = ptlocon->NEXT;
    }

  ptlosig = ptlofig->LOSIG;
  while (ptlosig != NULL)
    {
    if (ptlosig->TYPE == 'I')
      {
      if (ptlosig->USER == NULL)
        {
        ptlkdfig->SIMSIG = vhl_addsimsig (ptlkdfig->SIMSIG, ptlosig, &valsiz);
        ptsimsig         = ptlkdfig->SIMSIG;
        vhu_addtab (dict,ptlosig,NULL,VHL_PNTDFN,(int)ptsimsig);
        vhu_addtab (dict,ptlosig,NULL,VHL_SIGDFN,VHL_NORDFN);
        vhu_addtab (dict,getsigname (ptlosig) ,NULL,VHL_PNTDFN,ptsimsig);
        vhu_addtab (dict,getsigname (ptlosig) ,NULL,VHL_SIGDFN,'S');
        }
      else
        {
        ptlkdfig->BUSSIG = vhl_addbussig (ptlkdfig->BUSSIG, ptlosig, &valsiz);
        ptbussig         = ptlkdfig->BUSSIG;
        vhu_addtab (dict,ptlosig,NULL,VHL_PNTDFN,ptbussig);
        vhu_addtab (dict,ptlosig,NULL,VHL_SIGDFN,VHL_BUSDFN);
        vhu_addtab (dict,getsigname (ptlosig),NULL,VHL_PNTDFN,ptbussig);
        vhu_addtab (dict,getsigname (ptlosig),NULL,VHL_SIGDFN,'B');
        }
      }

    ptlosig = ptlosig->NEXT;
    }

	/* ###------------------------------------------------------### */
	/*   Create a LKDINS for each LOINS of root			*/
	/* ###------------------------------------------------------### */

  ptloins = ptlofig->LOINS;
  while (ptloins != NULL)
    {
    ptlkdins  = vhl_addlkdins (dict, ptlkdfig, ptloins, aux_flg, &valsiz);
    VHX_EVENT = addchain (VHX_EVENT,ptlkdins);
    ptloins   = ptloins->NEXT;
    }

	/* ###------------------------------------------------------### */
	/*   Link structures generated by the pattern compiler with the	*/
	/* description (through the PAIOL structures)			*/
	/* ###------------------------------------------------------### */

  max_iol = ptpaseq->IOLNBR;
  ptpaiol = ptpaseq->PAIOL;
  for (i=0 ; i<max_iol ; i++)
    {
    sig_type = vhu_chktab (dict,ptpaiol->NAME,NULL,VHL_SIGDFN);
    sig_mode = vhu_chktab (dict,ptpaiol->NAME,NULL,VHL_MODDFN);
    if (sig_type != 0)
      {
      switch (ptpaiol->MODE)
        {
        case ('I'):
          if (sig_mode != 'I')
            errflg = vhu_error (103,ptpaiol->NAME);
          break;
        case ('T'):
          if (sig_mode != 'T')
            errflg = vhu_error (103,ptpaiol->NAME);
          break;
        case ('O'):
          if ((sig_mode != 'O') && (sig_mode != 'B') && (sig_mode != 'Z'))
            errflg = vhu_error (103,ptpaiol->NAME);
          else
            ptpaiol->MODE = sig_mode;
          break;
        case ('S'):
          if (sig_mode != 0)
            errflg = vhu_error (103,ptpaiol->NAME);
          else
            {
            switch (sig_type)
              {
              case 'B':
                ptpaiol->MODE = 'X'; break;
              case 'X':
                ptpaiol->MODE = 'S'; break;
              case 'S':
                ptpaiol->MODE = 'W'; break;
              case 'U':
                ptpaiol->MODE = 'U'; break;
              case 'R':
                errflg = vhu_error (103,ptpaiol->NAME); break;
              }
            }
          break;
        case ('R'):
          if (sig_type != 'R')
            errflg = vhu_error (103,ptpaiol->NAME);
          break;
        default :
           fprintf(stderr,"Linker Error : Mode is unknown.\n");
        }
      }
    else
      errflg = vhu_error (104,ptpaiol->NAME);

    ptpaiol->SIG  = (void *) vhu_chktab (dict,ptpaiol->NAME,NULL,VHL_PNTDFN);
    ptpaiol++;
    }

  ptlkdfig->VALSIZ = valsiz;

  return (errflg);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_restor						*/
/* description	: restore the mode of external ports of the description	*/
/*		  when the declared mode is LINKAGE.			*/
/*									*/
/*		  First, it restores (if necessary) the informations on	*/
/*		  internal ports checking the consistency between the	*/
/*		  model and the instance. Then, it propagates restored	*/
/*		  informations through the signals til the external	*/
/*		  ports. In the final step it checks the consistency of	*/
/*		  connexions on the restored external ports.		*/ 
/* called funct	: vhu_initab , vhu_chktab, vhu_addtab, vhu_fretab,	*/
/*		  vhu_toolbug, vhu_error , mbkalloc  , addptype		*/
/* ###--------------------------------------------------------------### */

int vhl_restor (dict, ptlofig, head_befig)

struct dct_entry **dict;
struct lofig      *ptlofig;
struct befig      *head_befig;

  {
  struct loins      *ptloins;
  struct locon      *ptlocon;
  struct losig      *ptlosig;
  struct befig      *ptbefig;
  struct bepor      *ptbepor;
  int                update_flg;
  int                mode;
  int                new_mode;
  int                receiv_nbr;
  int                emettr_nbr;
  int                connec_nbr;
  int                errflg = 0;
  struct dct_entry **lcl_dic;

  if (ptlofig != NULL)
    {
    lcl_dic = vhu_initab ();

	/* ###------------------------------------------------------### */
	/*    Find the root model of the description by scanning the	*/
	/* list of LOFIGs til the end. (The last LOFIG must be the root)*/
	/* ###------------------------------------------------------### */

  while (ptlofig->NEXT != NULL)
    ptlofig = ptlofig->NEXT;

	/* ###------------------------------------------------------### */
	/*    Fill the dictionnary with external LOCONs of mode linkage	*/
	/* ###------------------------------------------------------### */

    ptlocon = ptlofig->LOCON;
    while (ptlocon != NULL)
      {
      /*if (ptlocon->DIRECTION == 'X') 
          {*/
      vhu_addtab (lcl_dic,ptlocon->SIG,NULL,VHL_SIGDFN,VHL_UKNDFN);
         /* } */
      ptlocon = ptlocon->NEXT;
      }

	/* ###------------------------------------------------------### */
	/*    Fill the dictionnary with internal signals		*/
	/* ###------------------------------------------------------### */

    ptlosig = ptlofig->LOSIG;
    while (ptlosig != NULL)
      {
      if (ptlosig->TYPE == 'I')
        vhu_addtab (lcl_dic,ptlosig,NULL,VHL_SIGDFN,VHL_UKNDFN);
      ptlosig = ptlosig->NEXT;
      }

	/* ###------------------------------------------------------### */
	/*    For each LOINS ... :					*/
	/* ###------------------------------------------------------### */

    ptloins = ptlofig->LOINS;
    while (ptloins != NULL)
      {
	/* ###------------------------------------------------------### */
	/*    Scan the list of BEFIGs to find the model of the instance	*/
	/* ###------------------------------------------------------### */

      if ((ptbefig=(struct befig *)vhu_chktab(dict,ptloins->FIGNAME,
                                              NULL,VHL_PNTDFN)) == NULL)
        {
        ptbefig = head_befig;
        while ((ptbefig != NULL) && (ptbefig->NAME != ptloins->FIGNAME))
          ptbefig = ptbefig->NEXT;

        if (ptbefig == NULL)
          vhu_toolbug (13,"vhl_restor",ptloins->INSNAME,0);
        else
          vhu_addtab(dict,ptloins->FIGNAME,NULL,VHL_PNTDFN,ptbefig);
        }

	/* ###------------------------------------------------------### */
	/*    Check consistency of the instance and its model :		*/
	/* for each port names must be the same				*/
	/* ###------------------------------------------------------### */

      ptbepor = ptbefig->BEPOR;
      ptlocon = ptloins->LOCON;
      while ((ptbepor != NULL) && (ptlocon != NULL))
        {
        update_flg = 0;
        if (ptbepor->NAME != ptlocon->NAME)
          errflg = vhu_error (102,ptbefig->NAME);
        else
          {

          if (ptlocon->DIRECTION != 'X')
            {

	/* ###------------------------------------------------------### */
	/*    if the LOCON's mode is not 'linkage', modes must be the	*/
	/* same. In such a case if the LOSIG has to be restored, read	*/
	/* the old RDW flags of the signal then update these flags.	*/
	/* ###------------------------------------------------------### */

            if (ptbepor->DIRECTION != ptlocon->DIRECTION)
              errflg = vhu_error (102,ptbefig->NAME);
            else
              {
              if ((mode=vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_SIGDFN)) != 0)
                {
                update_flg = 1;
                receiv_nbr = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_RNBDFN);
                emettr_nbr = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_WNBDFN);
                connec_nbr = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_CNBDFN);
                }
              }
            }
          else
            {

	/* ###------------------------------------------------------### */
	/*    if the LOCON's mode is 'linkage', restore the mode, read	*/
	/* the old RDW flags of the LOSIG then update these flags.	*/
	/* ###------------------------------------------------------### */

            ptlocon->DIRECTION = ptbepor->DIRECTION;
            update_flg = 1;
            mode       = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_SIGDFN);
            receiv_nbr = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_RNBDFN);
            emettr_nbr = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_WNBDFN);
            connec_nbr = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_CNBDFN);
            }

	/* ###------------------------------------------------------### */
	/*    Update RDW flags						*/
	/* ###------------------------------------------------------### */

          if (update_flg == 1)
            {
            connec_nbr++;
            switch (ptbepor->DIRECTION)
              {
              case 'I' :
                new_mode = mode | VHL_REDDFN;
                receiv_nbr++;
                break;
              case 'O' :
                new_mode = mode | VHL_WRTDFN;
                emettr_nbr++;
                break;
              case 'Z' :
                new_mode = mode | VHL_DECDFN;
                if (ptlocon->SIG->USER == NULL)
                  ptlocon->SIG->USER = addptype (NULL,ptbepor->TYPE,NULL);
                else
                  {
                  if (ptlocon->SIG->USER->TYPE !=  ptbepor->TYPE)
                    errflg = vhu_error (111,getsigname (ptlocon->SIG));
                  }
                emettr_nbr++;
                break;
              case 'B' :
                new_mode = mode | VHL_WRTDFN | VHL_REDDFN;
                receiv_nbr++;
                emettr_nbr++;
                break;
              case 'T' :
                new_mode = mode | VHL_DECDFN | VHL_REDDFN;
                if (ptlocon->SIG->USER == NULL)
                  ptlocon->SIG->USER = addptype (NULL,ptbepor->TYPE,NULL);
                else
                  {
                  if (ptlocon->SIG->USER->TYPE !=  ptbepor->TYPE)
                    errflg = vhu_error (111, getsigname (ptlocon->SIG));
                  }
                receiv_nbr++;
                emettr_nbr++;
                break;
              }
            vhu_addtab (lcl_dic,ptlocon->SIG,NULL,VHL_SIGDFN,new_mode);
            vhu_addtab (lcl_dic,ptlocon->SIG,NULL,VHL_RNBDFN,receiv_nbr);
            vhu_addtab (lcl_dic,ptlocon->SIG,NULL,VHL_WNBDFN,emettr_nbr);
            vhu_addtab (lcl_dic,ptlocon->SIG,NULL,VHL_CNBDFN,connec_nbr);
            }
          }

        ptbepor = ptbepor->NEXT;
        ptlocon = ptlocon->NEXT;
        }

	/* ###------------------------------------------------------### */
	/*    It is an error if there is not the same number of BEPOR	*/
	/* and LOCON							*/
	/* ###------------------------------------------------------### */

      if ((ptbepor != NULL) || (ptlocon != NULL))
        errflg = vhu_error (102,ptbefig->NAME);

      ptloins = ptloins->NEXT;
      }

	/* ###------------------------------------------------------### */
	/*    Scan the list of external LOCONs looking for linkage. If	*/
	/* found restore its mode					*/
	/* ###------------------------------------------------------### */

    ptlocon = ptlofig->LOCON;
    while (ptlocon != NULL)
      {
      mode = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_SIGDFN);
      if (mode != 0)
        {
        connec_nbr = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_CNBDFN) + 1;
        receiv_nbr = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_RNBDFN);
        emettr_nbr = vhu_chktab (lcl_dic,ptlocon->SIG,NULL,VHL_WNBDFN);
        mode      &= VHL_REDDFN | VHL_WRTDFN | VHL_DECDFN;

        switch (mode)
          {
          case (VHL_REDDFN):
            if ((ptlocon->DIRECTION != 'X') && (ptlocon->DIRECTION != 'I'))
              errflg = vhu_error (111,ptlocon->NAME);
            ptlocon->DIRECTION = 'I';
            emettr_nbr++;
            break;
          case (VHL_WRTDFN):
            if ((ptlocon->DIRECTION != 'X') && (ptlocon->DIRECTION != 'O'))
              errflg = vhu_error (111,ptlocon->NAME);
            ptlocon->DIRECTION = 'O';
            receiv_nbr++;
            break;
          case (VHL_DECDFN):
            if ((ptlocon->DIRECTION != 'X') && (ptlocon->DIRECTION != 'Z'))
              errflg = vhu_error (111,ptlocon->NAME);
            ptlocon->DIRECTION = 'Z';
            emettr_nbr++;
            receiv_nbr++;
            break;
          case (VHL_REDDFN | VHL_WRTDFN):
            if ((ptlocon->DIRECTION != 'X') && (ptlocon->DIRECTION != 'B'))
              errflg = vhu_error (111,ptlocon->NAME);
            ptlocon->DIRECTION = 'B';
            receiv_nbr++;
            break;
          case (VHL_REDDFN | VHL_DECDFN):
            if ((ptlocon->DIRECTION != 'X') && (ptlocon->DIRECTION != 'T'))
              errflg = vhu_error (111,ptlocon->NAME);
            ptlocon->DIRECTION = 'T';
            emettr_nbr++;
            receiv_nbr++;
            break;
          }
        vhu_addtab (lcl_dic,ptlocon->SIG,NULL,VHL_RNBDFN,receiv_nbr);
        vhu_addtab (lcl_dic,ptlocon->SIG,NULL,VHL_WNBDFN,emettr_nbr);
        vhu_addtab (lcl_dic,ptlocon->SIG,NULL,VHL_CNBDFN,connec_nbr);
        }
      ptlocon = ptlocon->NEXT;
      }

	/* ###------------------------------------------------------### */
	/*    For each LOSIG added into the dictionnary check the	*/
	/* coherence of connections					*/
	/* ###------------------------------------------------------### */

    ptlosig = ptlofig->LOSIG;
    while (ptlosig != NULL)
      {
      if ((mode=vhu_chktab(lcl_dic,ptlosig,NULL,VHL_SIGDFN)) != 0)
        {
        receiv_nbr = vhu_chktab (lcl_dic,ptlosig,NULL,VHL_RNBDFN);
        emettr_nbr = vhu_chktab (lcl_dic,ptlosig,NULL,VHL_WNBDFN);
        connec_nbr = vhu_chktab (lcl_dic,ptlosig,NULL,VHL_CNBDFN);

        if (receiv_nbr == 0)
          vhu_warning (3, getsigname (ptlosig));

        if (emettr_nbr == 0)
          errflg = vhu_error (109, getsigname (ptlosig));
        if ((emettr_nbr > 1) && ((mode & VHL_WRTDFN) == VHL_WRTDFN))
          errflg = vhu_error (114, getsigname (ptlosig));
        if (connec_nbr == 0)
          errflg = vhu_error (110, getsigname (ptlosig));

        if (((mode & VHL_WRTDFN) == VHL_WRTDFN) &&
            ((mode & VHL_DECDFN) == VHL_DECDFN))
          errflg = vhu_error (111, getsigname (ptlosig));
        }
      ptlosig = ptlosig->NEXT;
      }

    vhu_fretab (lcl_dic);
    }

  return (errflg);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhl_resord						*/
/* description	: put the LOCONs of each instance  in the same order as	*/
/*		  the BEPOR.						*/
/*		  WARNING : This function is used to repare a bug in	*/
/*		  ap2alx tools. So it is to be removed when a correct	*/
/*		  version of ap2alx is installed			*/
/* ###--------------------------------------------------------------### */

void vhl_resord (dict, ptlofig, head_befig)

struct dct_entry **dict;
struct lofig      *ptlofig;
struct befig      *head_befig;

  {
  struct loins      *ptloins;
  struct locon      *ptlocon;
  struct befig      *ptbefig;
  struct bepor      *ptbepor;
  struct dct_entry **lcl_dic;

  if (ptlofig != NULL)
    {
    lcl_dic = vhu_initab ();

	/* ###------------------------------------------------------### */
	/*    Find the root model of the description by scanning the	*/
	/* list of LOFIGs til the end. (The last LOFIG must be the root)*/
	/* ###------------------------------------------------------### */

  while (ptlofig->NEXT != NULL)
    ptlofig = ptlofig->NEXT;

	/* ###------------------------------------------------------### */
	/*    For each LOINS ... :					*/
	/* ###------------------------------------------------------### */

    ptloins = ptlofig->LOINS;
    while (ptloins != NULL)
      {

	/* ###------------------------------------------------------### */
	/*    Fill the local dictionnary with the internal LOCONs' SIG	*/
	/* and DIRECTION fields. Then, delete the LOCON's list		*/
	/* ###------------------------------------------------------### */

      ptlocon = ptloins->LOCON;
      while (ptlocon != NULL)
        {
        vhu_addtab (lcl_dic,ptlocon->NAME,ptloins->FIGNAME,VHL_SIGDFN,
                    ptlocon->DIRECTION);
        vhu_addtab (lcl_dic,ptlocon->NAME,ptloins->FIGNAME,VHL_PNTDFN,
                    ptlocon->SIG);
        ptlocon = ptlocon->NEXT;
        }
      ptloins->LOCON = NULL;

	/* ###------------------------------------------------------### */
	/*    Scan the list of BEFIGs to find the model of the instance	*/
	/* ###------------------------------------------------------### */

      if ((ptbefig=(struct befig *)vhu_chktab(dict,ptloins->FIGNAME,
                                              NULL,VHL_PNTDFN)) == NULL)
        {
        ptbefig = head_befig;
        while ((ptbefig != NULL) && (ptbefig->NAME != ptloins->FIGNAME))
          ptbefig = ptbefig->NEXT;

        if (ptbefig == NULL)
          vhu_toolbug (13,"vhl_restor",ptloins->INSNAME,0);
        else
          vhu_addtab(dict,ptloins->FIGNAME,NULL,VHL_PNTDFN,ptbefig);
        }

	/* ###------------------------------------------------------### */
	/*    Make a copy of list of BEPORs (create a list of LOCONs)	*/
	/* ###------------------------------------------------------### */

      ptbepor = ptbefig->BEPOR;
      while (ptbepor != NULL)
        {
        ptlocon = (struct locon *) mbkalloc (sizeof(struct locon));

        ptlocon->NAME      = ptbepor->NAME;
        ptlocon->ROOT      = ptloins;
        ptlocon->TYPE      = 'I';
        ptlocon->USER      = NULL;
        ptlocon->NEXT      = ptloins->LOCON;
        ptlocon->DIRECTION = vhu_chktab (lcl_dic,ptlocon->NAME,ptloins->FIGNAME,
                                         VHL_SIGDFN);
        ptlocon->SIG       = (struct losig *)
                             vhu_chktab (lcl_dic,ptlocon->NAME,ptloins->FIGNAME,
                                         VHL_PNTDFN);

        ptloins->LOCON = ptlocon;
        ptbepor = ptbepor->NEXT;
        }
      ptloins->LOCON = (struct locon *)
                       reverse ((struct chain *) ptloins->LOCON);

      ptloins = ptloins->NEXT;
      }

    vhu_fretab (lcl_dic);
    }
  }
