
/* ###--------------------------------------------------------------### */
/*									*/
/* file		: vh_xspec.c						*/
/* date		: Sep  3 1993						*/
/* version	: v1.92							*/
/* author	: VUONG H.N.						*/
/* description	: This file contains functions relative to the execution*/
/*		  of a circuit :					*/
/*		  vhx_redpat , vhx_inireg, vhx_wrtpat, vhx_muxbit,	*/
/*		  vhx_worbit , vhx_regbit, vhx_evalue, vhx_savall,	*/
/*		  vhx_execute, vhx_chkerr, vhx_update, vhx_initfig	*/
/*		  vhx_core   ,						*/
/*									*/
/* ###--------------------------------------------------------------### */

#include <stdio.h>
#include <time.h>
#include MUT_H
#include BEH_H
#include LOG_H
#include PAT_H
#include "vh_ltype.h"
#include "vh_utype.h"
#include "vh_xspec.h"

/* ###--------------------------------------------------------------### */
/* function	: vhx_muxbit						*/
/* description	: resolution function for MUX_BIT typed signals		*/
/* called func.	: none							*/
/* ###--------------------------------------------------------------### */

char vhx_muxbit (ptr_bvl , curval)

  struct prjbvl *ptr_bvl;
  char           curval;

  {
  char resval      = '1';
  int  active_driv = 0;

  while (ptr_bvl != NULL)
    {
    if (ptr_bvl->CNDVAL == '1')
      {
      resval = ptr_bvl->DRVVAL;
      active_driv++;
      }
    ptr_bvl = ptr_bvl->GLNEXT;
    }

  if (active_driv > 1)
    resval = 'E';

  return (resval);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_worbit						*/
/* description	: resolution function for WOR_BIT typed signals		*/
/* called func.	: none							*/
/* ###--------------------------------------------------------------### */

char vhx_worbit (ptr_bvl , curval)

  struct prjbvl *ptr_bvl;
  char           curval;

  {
  char resval      = '1';
  int  active_one  = 0;
  int  active_zero = 0;

  while (ptr_bvl != NULL)
    {
    if (ptr_bvl->CNDVAL == '1')
      {
      if ((resval = ptr_bvl->DRVVAL) == '1')
        active_one  = 1;
      else
        active_zero = 1;
      }
    ptr_bvl = ptr_bvl->GLNEXT;
    }

  if ((active_one + active_zero) > 1)
    resval = 'E';

  return (resval);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_regbit						*/
/* description	: resolution function for REG_BIT typed signals		*/
/* called func.	: none							*/
/* ###--------------------------------------------------------------### */

char vhx_regbit (ptr_rvl , curval)

  struct prjrvl *ptr_rvl;
  char           curval;

  {
  char resval      = curval;
  int  active_driv = 0;

  while (ptr_rvl != NULL)
    {
    if (ptr_rvl->CNDVAL == '1')
      {
      resval = ptr_rvl->DRVVAL;
      active_driv++;
      }
    ptr_rvl = ptr_rvl->NEXT;
    }

  if (active_driv > 1)
    resval = 'E';

  return (resval);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_evalue						*/
/* description	: computes a BDD's value depending on its node's value	*/
/* called func.	: vhu_toolbug						*/
/* ###--------------------------------------------------------------### */

char vhx_evalue (ptr_lkdins , ptr_bdd)

struct lkdins *ptr_lkdins;
pNode ptr_bdd;
  {
  int indexbdd;
  char value;

  while ((ptr_bdd != zero) && (ptr_bdd != one))
    {
    indexbdd = ptr_bdd->index ;
    value    = *((ptr_lkdins->REDLST + indexbdd - 2)->VALU) ;
    if (value == '0')
      ptr_bdd = ptr_bdd->low ;
    else
      {
      if (value == '1')
        ptr_bdd = ptr_bdd->high ;
      else
        vhu_toolbug (8,"vhx_evalue","",value);
      }
    }

  if (ptr_bdd == zero)
    return ('0');
  else
    return ('1');
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_savall						*/
/* description	: saves the whole state of the circuit			*/
/* called func.	: none							*/
/* ###--------------------------------------------------------------### */

void vhx_savall (fp, ptlkdfig)

FILE          *fp;
struct lkdfig *ptlkdfig;

  {

  struct simsig *ptsimsig = ptlkdfig->SIMSIG;
  struct bussig *ptbussig = ptlkdfig->BUSSIG;
  struct lkdins *ptlkdins = ptlkdfig->LKDINS;
  struct wrireg *ptwrireg;
  struct wriaux *ptwriaux;
  struct wribux *ptwribux;
  struct prjbvl *ptprjbvl;
  struct prjrvl *ptprjrvl;

  fwrite (&(ptlkdfig->VALSIZ), sizeof (unsigned int), 1 ,fp);
  while (ptsimsig != NULL)
    {
    fputc (  ptsimsig->PRJVAL , fp);
    fputc (*(ptsimsig->CURVAL), fp);
    ptsimsig = ptsimsig->NEXT;
    }

  while (ptbussig != NULL)
    {
    ptprjbvl = ptbussig->PRJBVL;
    while (ptprjbvl != NULL)
      {
      fputc (ptprjbvl->DRVVAL, fp);
      fputc (ptprjbvl->CNDVAL, fp);
      ptprjbvl = ptprjbvl->GLNEXT;
      }
    fputc (*(ptbussig->CURVAL), fp);
    ptbussig = ptbussig->NEXT;
    }

  while (ptlkdins != NULL)
    {
    ptwrireg = ptlkdins->WRIREG;
    ptwriaux = ptlkdins->WRIAUX;
    ptwribux = ptlkdins->WRIBUX;

    while (ptwrireg != NULL)
      {
      ptprjrvl = ptwrireg->PRJRVL;
      while (ptprjrvl != NULL)
        {
        fputc (ptprjrvl->DRVVAL, fp);
        fputc (ptprjrvl->CNDVAL, fp);
        ptprjrvl = ptprjrvl->NEXT;
        }
      fputc (*(ptwrireg->CURVAL), fp);
      ptwrireg = ptwrireg->NEXT;
      }

    while (ptwribux != NULL)
      {
      ptprjbvl = ptwribux->PRJBVL;
      while (ptprjbvl != NULL)
        {
        fputc (ptprjbvl->DRVVAL, fp);
        fputc (ptprjbvl->CNDVAL, fp);
        ptprjbvl = ptprjbvl->NEXT;
        }
      fputc (*(ptwribux->CURVAL), fp);
      ptwribux = ptwribux->NEXT;
      }

    while (ptwriaux != NULL)
      {
      fputc (  ptwriaux->PRJVAL , fp);
      fputc (*(ptwriaux->CURVAL), fp);
      ptwriaux = ptwriaux->NEXT;
      }
    ptlkdins = ptlkdins->NEXT;
    }
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_inireg						*/
/* description	: forces new values into registers			*/
/* called func.	: vhu_chktab, vhu_warning, addchain			*/
/* ###--------------------------------------------------------------### */

void vhx_inireg (dict, pt_paini)

struct dct_entry **dict;
struct paini      *pt_paini;

  {
  struct wrireg *pt_wrireg;

	/* ###------------------------------------------------------### */
	/*    For each paini structure, first find the pointer of the	*/
	/* register then, force its value				*/
	/* ###------------------------------------------------------### */

  while (pt_paini != NULL)
    {
    pt_wrireg = (struct wrireg *)
                vhu_chktab (dict, pt_paini->NAME, NULL, VHL_PNTDFN);
    if (pt_wrireg == NULL)
      vhu_warning (1, pt_paini->NAME);
    else
      {
      *(pt_wrireg->CURVAL) = pt_paini->VALUE;

      if (pt_wrireg->LKDINS->EVAL == 0)
        {
        VHX_EVENT = addchain (VHX_EVENT, pt_wrireg->LKDINS);
        pt_wrireg->LKDINS->EVAL = 1;
        }
      }
    pt_paini = pt_paini->NEXT;
    }
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_redpat						*/
/* description	: reads a simulation pattern from the pattern		*/
/*		  description structure and initialises values in the	*/
/*		  circuit						*/
/* called func.	: addchain						*/
/* ###--------------------------------------------------------------### */

void vhx_redpat (pt_paseq, pt_papat)

struct paseq      *pt_paseq;
struct papat      *pt_papat;

  {
  struct paiol  *pt_paiol;
  struct bussig *pt_bussig;
  struct simsig *pt_simsig;
  struct paevt  *pt_paevt;

	/* ###------------------------------------------------------### */
	/*    Set the projected value of inputs (ports of mode I or T)	*/
	/* ###------------------------------------------------------### */

  pt_paevt = pt_papat->PAEVT;
  while (pt_paevt != NULL)
    {
    pt_paiol = pt_paseq->PAIOL + pt_paevt->INDEX;
    if (pt_paiol->MODE == 'I')
      {
      VHX_SIGUPD = addchain (VHX_SIGUPD, pt_paiol->SIG);
      ((struct simsig *)pt_paiol->SIG)->PRJVAL = pt_paevt->USRVAL;
      }
    else
      {
      if (pt_paiol->MODE == 'T')
        {
        VHX_BUSUPD = addchain (VHX_BUSUPD,pt_paiol->SIG);
        if ((pt_paevt->USRVAL == '1') || (pt_paevt->USRVAL == '0'))
          {
          ((struct bussig *)pt_paiol->SIG)->PRJBVL->DRVVAL = pt_paevt->USRVAL;
          ((struct bussig *)pt_paiol->SIG)->PRJBVL->CNDVAL = '1';
          }
        else
          ((struct bussig *)pt_paiol->SIG)->PRJBVL->CNDVAL = '0';
        }
      }
    pt_paevt = pt_paevt->NEXT;
    }
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_wrtpat						*/
/* description	: saves in the pattern description structure the result	*/
/*		  of the simulation cycle				*/
/* called func.	: vhu_toolbug, vhu_error, pat_addpaevt			*/
/* ###--------------------------------------------------------------### */

int vhx_wrtpat (pt_paseq, pt_papat)

struct paseq *pt_paseq;
struct papat *pt_papat;

  {
  char           value;
  int            i;
  int            err_flg = 0;
  int            max_iol;
  int            max_err = 0;
  struct paiol  *pt_paiol;
  struct bussig *pt_bussig;
  struct simsig *pt_simsig;
  struct wrireg *pt_wrireg;
  struct paevt  *pt_paevt;

  max_iol  = pt_paseq->IOLNBR;
  pt_paiol = pt_paseq->PAIOL;
  for (i=0 ; i<max_iol ; i++)
    {
	/* ###------------------------------------------------------### */
	/*    For each input-output ...					*/
	/* ###------------------------------------------------------### */

    if (pt_paiol->MODE != 'I')
      {
	/* ###------------------------------------------------------### */
	/*    Read the input-output's value from the description -	*/
	/* skip simple inputs						*/
	/* ###------------------------------------------------------### */

      switch (pt_paiol->MODE)
        {
        case 'X' :
        case 'T' :
        case 'Z' :
          pt_bussig =  (struct bussig *)pt_paiol->SIG;
          value     = *(pt_bussig->CURVAL);
          break;

        case 'B' :
        case 'O' :
        case 'W' :
          pt_simsig =  (struct simsig *)pt_paiol->SIG;
          value     = *(pt_simsig->CURVAL);
          break;

        case 'S' :
          value     = *( ((struct wriaux *)pt_paiol->SIG)->CURVAL);
          break;

        case 'U' :
          value     = *( ((struct wribux *)pt_paiol->SIG)->CURVAL);
          break;

        case 'R' :
          pt_wrireg =  (struct wrireg *)pt_paiol->SIG;
          value     = *(pt_wrireg->CURVAL);
          break;

        default :
          vhu_toolbug (7,"vhx_wrtpat",pt_paiol->NAME,pt_paiol->MODE);
          break;
        }

	/* ###------------------------------------------------------### */
	/*    Scan user predicted event for the current input-output	*/
	/* ###------------------------------------------------------### */

      pt_paevt = pt_papat->PAEVT;
      while (pt_paevt != NULL)
        {
        if (pt_paevt->INDEX == i)
          break;
        pt_paevt = pt_paevt->NEXT;
        }

	/* ###------------------------------------------------------### */
	/*    If no user predicted event has been found and an event has*/
	/* been occured, add a new paevt structure to the pattern. Use	*/
	/* a wrong value (the not of the simulated value) as user	*/
	/* defined value						*/
	/* ###------------------------------------------------------### */

      if ((pt_paevt == NULL) && (pt_paiol->VALUE != value))
        {
        pt_paevt        = pat_addpaevt (pt_papat->PAEVT, i, '-');
        pt_papat->PAEVT = pt_paevt;
        if (value == '0')
          {
          pt_paevt->USRVAL = '+';
          pt_paevt->SIMVAL = '+';
          }
        }

	/* ###------------------------------------------------------### */
	/*    If there is an event related to the input-output, and if	*/
	/* the value predicted by the user and the simulated value do	*/
	/* not match print out an error message. In such a case add an	*/
	/* event on the same input-ouput with a wrong predicted value	*/
	/* to the next pattern (if it exists)				*/
	/* ###------------------------------------------------------### */

      if (pt_paevt != NULL)
        {
        switch (pt_paevt->USRVAL)
          {
          case '-':
          case '0':
            if (value == '1')
              {
              vhu_error (113,pt_paiol->NAME);
              max_err++;
              err_flg = 1;
              pt_paevt->SIMVAL = '+';
              }
            break;
          case '*':
            if (value == '1')
              pt_paevt->SIMVAL = '+';
            else
              pt_paevt->SIMVAL = '-';
            break;
          case '+':
          case '1':
            if (value == '0')
              {
              vhu_error (113,pt_paiol->NAME);
              max_err++;
              err_flg = 1;
              pt_paevt->SIMVAL = '-';
              }
            break;
          }

        if ((err_flg == 1) && (pt_papat->NEXT != NULL))
          {
          pt_paevt = pt_papat->NEXT->PAEVT;
          while (pt_paevt != NULL)
            {
            if (pt_paevt->INDEX == i)
              break;
            pt_paevt = pt_paevt->NEXT;
            }

          if (pt_paevt == NULL)
            {
            pt_paevt              = pat_addpaevt (pt_papat->NEXT->PAEVT,i,'-');
            pt_papat->NEXT->PAEVT = pt_paevt;
            if (value == '0')
              {
              pt_paevt->USRVAL = '+';
              pt_paevt->SIMVAL = '+';
              }
            }
          }
        }
      }
	/* ###------------------------------------------------------### */
	/*    Save the value in the paiol structure to make event	*/
	/* detections possible for the next pattern			*/
	/* ###------------------------------------------------------### */

    err_flg = 0;
    pt_paiol->VALUE = value;
    pt_paiol++;
    }

	/* ###------------------------------------------------------### */
	/*    Set the simulation flag of the pattern			*/
	/* ###------------------------------------------------------### */

    pt_papat->SIMFLAG = 'S';
    return (max_err);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_update						*/
/* description	: updates the current value of signals computed in the	*/
/*		  last evaluation cycle					*/
/* called func.	: vhx_muxbit, vhx_worbit, vhx_regbit, addchain,		*/
/*		  freechain						*/
/* ###--------------------------------------------------------------### */

void vhx_update ()

  {
  struct chain  *cur_chain;
  struct chain  *ptr_lkdins;
  struct chain  *pt_errbus;
  struct chain  *pt_errreg;
  struct wrireg *ptr_wrireg;
  struct wriaux *ptr_wriaux;
  struct wribux *ptr_wribux;
  struct bussig *ptr_bussig;
  struct simsig *ptr_simsig;
  char           resval;
  char           already_rcd = 0;

	/* ###------------------------------------------------------### */
	/*    Update simple signals' value				*/
	/* ###------------------------------------------------------### */

  cur_chain = VHX_SIGUPD;
  while (cur_chain != NULL)
    {
    ptr_simsig = (struct simsig *)cur_chain->DATA;
    if (ptr_simsig->PRJVAL != *(ptr_simsig->CURVAL))
      {
      *(ptr_simsig->CURVAL) = ptr_simsig->PRJVAL;
      ptr_lkdins = ptr_simsig->REDINS;
      while (ptr_lkdins != NULL)
        {
        if (((struct lkdins *)ptr_lkdins->DATA)->EVAL == 0)
          {
          VHX_EVENT = addchain(VHX_EVENT,ptr_lkdins->DATA);
          ((struct lkdins *)ptr_lkdins->DATA)->EVAL = 1;
          }
        ptr_lkdins = ptr_lkdins->NEXT;
        }
      }
    cur_chain = cur_chain->NEXT;
    }
  freechain (VHX_SIGUPD);
  VHX_SIGUPD = NULL;

	/* ###------------------------------------------------------### */
	/*    Update bused signals's value (also handles errors occured	*/
	/* when resolution functions are called)			*/
	/* ###------------------------------------------------------### */

  cur_chain = VHX_BUSUPD;
  while (cur_chain != NULL)
    {
    ptr_bussig = (struct bussig *)cur_chain->DATA;
    switch (ptr_bussig->TYPE)
      {
      case 'W' :
        resval = vhx_worbit (ptr_bussig->PRJBVL,*(ptr_bussig->CURVAL));
        break;
      case 'M' :
        resval = vhx_muxbit (ptr_bussig->PRJBVL,*(ptr_bussig->CURVAL));
        break;
      default :
        vhu_toolbug (22,"vhx_update",ptr_bussig->NAMECHAIN->DATA,
                        ptr_bussig->TYPE);
        break;
      }

    if (resval == 'E')
      {
      pt_errbus   = VHX_BUSERR;
      already_rcd = 0;
      while (pt_errbus != NULL)
        {
        if (((struct bussig *)pt_errbus->DATA) ==  ptr_bussig)
 /* There was an error already recorded in the error's list */
          {
          already_rcd = 1;
          break;
          }
        else
          pt_errbus = pt_errbus->NEXT;
        }
      if (already_rcd == 0)
        VHX_BUSERR = addchain(VHX_BUSERR, ptr_bussig);
      }
    else
      {
      pt_errbus = VHX_BUSERR;
      while (pt_errbus != NULL)
        {
        if (((struct bussig *)pt_errbus->DATA) ==  ptr_bussig)
 /* There was an error recorded in the error's list */
          {
          VHX_BUSERR = delchain(VHX_BUSERR, pt_errbus);
          break;
          }
        else
          pt_errbus = pt_errbus->NEXT;
        }
      if ( *(ptr_bussig->CURVAL) != resval )
        {
        *(ptr_bussig->CURVAL) = resval;
        ptr_lkdins = ptr_bussig->REDINS;
        while (ptr_lkdins != NULL)
          {
          if (((struct lkdins *)ptr_lkdins->DATA)->EVAL == 0)
            {
            VHX_EVENT = addchain(VHX_EVENT,ptr_lkdins->DATA);
            ((struct lkdins *)ptr_lkdins->DATA)->EVAL = 1;
            }
          ptr_lkdins = ptr_lkdins->NEXT;
          }
        }
      }

    cur_chain = cur_chain->NEXT;
    }
  freechain (VHX_BUSUPD);
  VHX_BUSUPD = NULL;


	/* ###------------------------------------------------------### */
	/*    Update internal bused signals's value (also handles	*/
	/* errors occured when resolution functions are called)		*/
	/* ###------------------------------------------------------### */

  cur_chain = VHX_BUXUPD;
  while (cur_chain != NULL)
    {
    ptr_wribux = (struct wribux *)cur_chain->DATA;
    switch (ptr_wribux->BEBUX->TYPE)
      {
      case 'W' :
        resval = vhx_worbit (ptr_wribux->PRJBVL,*(ptr_wribux->CURVAL));
        break;
      case 'M' :
        resval = vhx_muxbit (ptr_wribux->PRJBVL,*(ptr_wribux->CURVAL));
        break;
      default :
        vhu_toolbug (22,"vhx_update",ptr_wribux->BEBUX->NAME,
                        ptr_wribux->BEBUX->TYPE);
        break;
      }

    if (resval == 'E')
      {
      pt_errbus   = VHX_BUXERR;
      already_rcd = 0;
      while (pt_errbus != NULL)
        {
        if (((struct wribux *)pt_errbus->DATA) ==  ptr_wribux)
 /* There was an error already recorded in the error's list */
          {
          already_rcd = 1;
          break;
          }
        else
          pt_errbus = pt_errbus->NEXT;
        }
      if (already_rcd == 0)
        VHX_BUXERR = addchain (VHX_BUXERR, ptr_wribux);
      }
    else
      {
      pt_errbus = VHX_BUXERR;
      while (pt_errbus != NULL)
        {
        if (((struct wribux *)pt_errbus->DATA) ==  ptr_wribux)
 /* There was an error recorded in the error's list */
          {
          VHX_BUXERR = delchain(VHX_BUXERR, pt_errbus);
          break;
          }
        else
          pt_errbus = pt_errbus->NEXT;
        }
      if ( *(ptr_wribux->CURVAL) != resval )
        {
        *(ptr_wribux->CURVAL) = resval;
        VHX_EVENT = addchain (VHX_EVENT,ptr_wribux->LKDINS);
        ptr_wribux->LKDINS->EVAL = 1;
        }
      }

    cur_chain = cur_chain->NEXT;
    }
  freechain (VHX_BUXUPD);
  VHX_BUXUPD = NULL;

	/* ###------------------------------------------------------### */
	/*    Updating registers (also handles errors occured when	*/
	/* resolution functions are called)				*/
	/* ###------------------------------------------------------### */

  cur_chain = VHX_REGUPD;
  while (cur_chain != NULL)
    {
    ptr_wrireg = (struct wrireg *)cur_chain->DATA;
    resval = vhx_regbit(ptr_wrireg->PRJRVL,*(ptr_wrireg->CURVAL));

/* Error of the resolving function */

    if (resval == 'E')
      {
      pt_errreg = VHX_REGERR;
      already_rcd = 0;
      while (pt_errreg != NULL)
        {
        if (((struct wrireg *)pt_errreg->DATA) ==  ptr_wrireg)
 /* There was an error already recorded in the error's list */
          {
          already_rcd = 1;
          break;
          }
        else
          pt_errreg = pt_errreg->NEXT;
        }
      if (already_rcd == 0)
        VHX_REGERR = addchain(VHX_REGERR, ptr_wrireg);
      }
    else
      {
      pt_errreg = VHX_REGERR;
      while (pt_errreg != NULL)
        {
        if (((struct wrireg *)pt_errreg->DATA) ==  ptr_wrireg)
 /* There was an error recorded in the error's list */
          {
          VHX_REGERR = delchain(VHX_REGERR, pt_errreg);
          break;
          }
        else
          pt_errreg = pt_errreg->NEXT;
        }

      if ( *(ptr_wrireg->CURVAL) != resval )
        {
        *(ptr_wrireg->CURVAL) = resval;
        if (ptr_wrireg->LKDINS->EVAL == 0)
          {
          VHX_EVENT = addchain(VHX_EVENT,ptr_wrireg->LKDINS);
          ptr_wrireg->LKDINS->EVAL = 1;
          }
        }
      }
    cur_chain = cur_chain->NEXT;
    }
  freechain(VHX_REGUPD);
  VHX_REGUPD = NULL;


	/* ###------------------------------------------------------### */
	/*    Updating simple internal signals				*/
	/* ###------------------------------------------------------### */

  cur_chain = VHX_AUXUPD;
  while (cur_chain != NULL)
    {
    ptr_wriaux = (struct wriaux *)cur_chain->DATA;
    if (ptr_wriaux->PRJVAL != *(ptr_wriaux->CURVAL))
      {
      *(ptr_wriaux->CURVAL) = ptr_wriaux->PRJVAL;
      if (ptr_wriaux->LKDINS->EVAL == 0)
        {
        VHX_EVENT = addchain(VHX_EVENT,ptr_wriaux->LKDINS);
        ptr_wriaux->LKDINS->EVAL = 1;
        }
      }

    cur_chain = cur_chain->NEXT;
    }
  freechain (VHX_AUXUPD);
  VHX_AUXUPD = NULL;

  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_execute						*/
/* description	: executes all instances of the circuit (execution of a	*/
/*		  delta cycle)						*/
/* called func.	: vhx_evalue, addchain, delchain, freechain		*/
/* ###--------------------------------------------------------------### */

void vhx_execute ()

  {

  struct chain  *cur_chain;
  struct lkdins *ptr_lkdins;
  struct beout  *ptr_beout;
  struct bebus  *ptr_bebus;
  struct bebux  *ptr_bebux;
  struct beaux  *ptr_beaux;
  struct bereg  *ptr_bereg;
  struct bemsg  *ptr_bemsg;
  struct wrssig *ptr_wrssig;
  struct wrbsig *ptr_wrbsig;
  struct wrireg *ptr_wrireg;
  struct wriaux *ptr_wriaux;
  struct wribux *ptr_wribux;
  struct binode *ptr_binode;
  struct prjbvl *ptr_prjbvl;
  struct prjrvl *ptr_prjrvl;
  char           resval;
  short          already_rcd = 1;
  struct chain  *pt_errmsg;

  cur_chain = VHX_EVENT;
  while (cur_chain != NULL)
    {
	/* ###------------------------------------------------------### */
	/*    for each lkdins that is to be executed ...		*/
	/* ###------------------------------------------------------### */

    ptr_lkdins = (struct lkdins *)cur_chain->DATA;

	/* ###------------------------------------------------------### */
	/*    Computes projected value of WRSSIGs			*/
	/* ###------------------------------------------------------### */

    ptr_wrssig = ptr_lkdins->WRSSIG;
    while (ptr_wrssig != NULL)
      {
      ptr_beout  = ptr_wrssig->BEOUT;
      resval     = vhx_evalue (ptr_lkdins, ptr_beout->NODE);
      ptr_wrssig->SIMSIG->PRJVAL = resval;
      VHX_SIGUPD = addchain (VHX_SIGUPD, ptr_wrssig->SIMSIG);
      ptr_wrssig = ptr_wrssig->NEXT;
      }

	/* ###------------------------------------------------------### */
	/*    Computes projected value of WRIAUXs			*/
	/* ###------------------------------------------------------### */

    ptr_wriaux = ptr_lkdins->WRIAUX;
    while (ptr_wriaux != NULL)
      {
      ptr_beaux  = ptr_wriaux->BEAUX;
      resval     = vhx_evalue (ptr_lkdins, ptr_beaux->NODE);
      ptr_wriaux->PRJVAL = resval;
      VHX_AUXUPD = addchain (VHX_AUXUPD, ptr_wriaux);
      ptr_wriaux = ptr_wriaux->NEXT;
      }

	/* ###------------------------------------------------------### */
	/*    Computes projected value of WRBSIGs			*/
	/* ###------------------------------------------------------### */

    ptr_wrbsig = ptr_lkdins->WRBSIG;
    while (ptr_wrbsig != NULL)
      {
      ptr_bebus  = ptr_wrbsig->BEBUS;
      ptr_prjbvl = ptr_wrbsig->PRJBVL;
      ptr_binode = ptr_bebus->BINODE;
      while (ptr_binode != NULL)
        {
        ptr_prjbvl->CNDVAL = vhx_evalue (ptr_lkdins, ptr_binode->CNDNODE);
        ptr_prjbvl->DRVVAL = vhx_evalue (ptr_lkdins, ptr_binode->VALNODE);
        ptr_prjbvl         = ptr_prjbvl->NEXT;
        ptr_binode         = ptr_binode->NEXT;
        }
      VHX_BUSUPD = addchain (VHX_BUSUPD, ptr_wrbsig->BUSSIG);
      ptr_wrbsig = ptr_wrbsig->NEXT;
      }

	/* ###------------------------------------------------------### */
	/*    Computes projected value of WRIREGs			*/
	/* ###------------------------------------------------------### */

    ptr_wrireg = ptr_lkdins->WRIREG;
    while (ptr_wrireg != NULL)
      {
      ptr_bereg  = ptr_wrireg->BEREG;
      ptr_prjrvl = ptr_wrireg->PRJRVL;
      ptr_binode = ptr_bereg->BINODE;
      while (ptr_binode != NULL)
        {
        ptr_prjrvl->CNDVAL = vhx_evalue (ptr_lkdins, ptr_binode->CNDNODE);
        ptr_prjrvl->DRVVAL = vhx_evalue (ptr_lkdins, ptr_binode->VALNODE);
        ptr_prjrvl         = ptr_prjrvl->NEXT;
        ptr_binode         = ptr_binode->NEXT;
        }
      VHX_REGUPD = addchain (VHX_REGUPD, ptr_wrireg);
      ptr_wrireg = ptr_wrireg->NEXT;
      }

	/* ###------------------------------------------------------### */
	/*    Compute projected value of WRIBUXs			*/
	/* ###------------------------------------------------------### */

    ptr_wribux = ptr_lkdins->WRIBUX;
    while (ptr_wribux != NULL)
      {
      ptr_bebux  = ptr_wribux->BEBUX;
      ptr_prjbvl = ptr_wribux->PRJBVL;
      ptr_binode = ptr_bebux->BINODE;
      while (ptr_binode != NULL)
        {
        ptr_prjbvl->CNDVAL = vhx_evalue (ptr_lkdins, ptr_binode->CNDNODE);
        ptr_prjbvl->DRVVAL = vhx_evalue (ptr_lkdins, ptr_binode->VALNODE);
        ptr_prjbvl         = ptr_prjbvl->NEXT;
        ptr_binode         = ptr_binode->NEXT;
        }
      VHX_BUXUPD = addchain (VHX_BUXUPD, ptr_wribux);
      ptr_wribux = ptr_wribux->NEXT;
      }

	/* ###------------------------------------------------------### */
	/*    Compute BEMSG's condition					*/
	/* ###------------------------------------------------------### */

    ptr_bemsg = ptr_lkdins->BEFIG->BEMSG;
    while (ptr_bemsg != NULL)
      {
      resval = vhx_evalue (ptr_lkdins, ptr_bemsg->NODE);
      if (resval != '1')
        {
        pt_errmsg   = VHX_MSGERR;
        already_rcd = 0;
        while (pt_errmsg != NULL)
          {
          if (((struct bemsg *)pt_errmsg->DATA) ==  ptr_bemsg)
            {
            already_rcd = 1;
            break;
            }
          else
            pt_errmsg = pt_errmsg->NEXT;
          }
        if (already_rcd == 0)
          VHX_MSGERR = addchain (VHX_MSGERR, ptr_bemsg);
        }
      else
        {
        pt_errmsg = VHX_MSGERR;
        while (pt_errmsg != NULL)
          {
          if (((struct bemsg *)pt_errmsg->DATA) ==  ptr_bemsg)
            {
            VHX_MSGERR = delchain (VHX_MSGERR, pt_errmsg);
            break;
            }
          else
            pt_errmsg = pt_errmsg->NEXT;
          }
        }

      ptr_bemsg = ptr_bemsg->NEXT;
      }

    ptr_lkdins->EVAL = 0;
    cur_chain        = cur_chain->NEXT;
    }

  freechain (VHX_EVENT);
  VHX_EVENT = NULL;

  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_chkerr						*/
/* description	: verifies that no errors remains at the end of the last*/
/*		  delta cycle						*/
/* called func.	: vhu_error						*/
/* ###--------------------------------------------------------------### */

int vhx_chkerr ()

  {
  short          errflg = 0;
  struct wrireg *pt_wrireg;
  struct bemsg  *pt_bemsg;
  struct bereg  *pt_bereg;
  char          *level;
  char          *label;
  char           name[256];
  struct lkdins *pt_lkdins;
  struct bemsg  *pt_bemsg_tmp;
  char           SORTIE = 0;

  while (VHX_MSGERR != NULL)
    {
    pt_bemsg = ((struct bemsg *)VHX_MSGERR->DATA);
    if (pt_bemsg->LEVEL == 'W')
      level = "WARNING";
    else
      {
      level = "ERROR";
      errflg = 1;
      }
    if(pt_bemsg->LABEL)
      label = pt_bemsg->LABEL;
    else
      label = "";

    pt_lkdins = VHL_HEDLKF->LKDINS;
    while((pt_lkdins != NULL) && (SORTIE != 1))
      {
      pt_bemsg_tmp = pt_lkdins->BEFIG->BEMSG;
      while((pt_bemsg_tmp != NULL) && (pt_bemsg_tmp != pt_bemsg))
        pt_bemsg_tmp = pt_bemsg_tmp->NEXT;
      if (pt_bemsg_tmp == pt_bemsg)
        SORTIE = 1;
      else
        pt_lkdins = pt_lkdins->NEXT;
      }
    SORTIE = 0;

    (void)fprintf (stderr,"%s : `%s` assert violation on cell %s : %s\n",level,label,pt_lkdins->INSNAME,pt_bemsg->MESSAGE);
    VHX_MSGERR = VHX_MSGERR->NEXT;
    }

  while (VHX_BUSERR != NULL)
    {
    vhu_error (112,((struct bussig *)VHX_BUSERR->DATA)->NAMECHAIN->DATA);
    errflg = 1;
    VHX_BUSERR = VHX_BUSERR->NEXT;
    }

  while (VHX_REGERR != NULL)
    {
    sprintf (name,"%s.%s",((struct wrireg *)VHX_REGERR->DATA)->LKDINS->INSNAME,
                          ((struct wrireg *)VHX_REGERR->DATA)->BEREG->NAME);
    vhu_error (112,name);
    errflg = 1;
    VHX_REGERR = VHX_REGERR->NEXT;
    }

  return (errflg);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_initfig						*/
/* description	: initialize a description (reading values from a save	*/
/*		  file)							*/
/* called func.	: none							*/
/* ###--------------------------------------------------------------### */

char vhx_initfig (ptlkdfig, fp)

struct lkdfig *ptlkdfig;
FILE          *fp;

  {
  struct simsig *ptsimsig = ptlkdfig->SIMSIG;
  struct bussig *ptbussig = ptlkdfig->BUSSIG;
  struct lkdins *ptlkdins = ptlkdfig->LKDINS;
  struct wrireg *ptwrireg;
  struct wriaux *ptwriaux;
  struct wribux *ptwribux;
  struct prjbvl *ptprjbvl;
  struct prjrvl *ptprjrvl;
  unsigned int   valsiz;
  char           errflg = 0;

  fread (&valsiz, sizeof(unsigned int), 1, fp);
  if (valsiz != ptlkdfig->VALSIZ)
    {
    vhu_error (115,NULL);
    errflg = 1;
    }
  else
    {
    while (ptsimsig != NULL)
      {
      ptsimsig->PRJVAL    = fgetc (fp);
      *(ptsimsig->CURVAL) = fgetc (fp);
      ptsimsig            = ptsimsig->NEXT;
      }

    while (ptbussig != NULL)
      {
      ptprjbvl = ptbussig->PRJBVL;
      while (ptprjbvl != NULL)
        {
        ptprjbvl->DRVVAL = fgetc (fp);
        ptprjbvl->CNDVAL = fgetc (fp);
        ptprjbvl = ptprjbvl->GLNEXT;
        }
      *(ptbussig->CURVAL) = fgetc (fp);
      ptbussig = ptbussig->NEXT;
      }

    while (ptlkdins != NULL)
      {
      ptwrireg = ptlkdins->WRIREG;
      ptwriaux = ptlkdins->WRIAUX;
      ptwribux = ptlkdins->WRIBUX;

      while (ptwrireg != NULL)
        {
        ptprjrvl = ptwrireg->PRJRVL;
        while (ptprjrvl != NULL)
          {
          ptprjrvl->DRVVAL = fgetc (fp);
          ptprjrvl->CNDVAL = fgetc (fp);
          ptprjrvl = ptprjrvl->NEXT;
          }
        *(ptwrireg->CURVAL) = fgetc (fp);
        ptwrireg = ptwrireg->NEXT;
        }

      while (ptwribux != NULL)
        {
        ptprjbvl = ptwribux->PRJBVL;
        while (ptprjbvl != NULL)
          {
          ptprjbvl->DRVVAL = fgetc (fp);
          ptprjbvl->CNDVAL = fgetc (fp);
          ptprjbvl = ptprjbvl->NEXT;
          }
        *(ptwribux->CURVAL) = fgetc (fp);
        ptwribux = ptwribux->NEXT;
        }

      while (ptwriaux != NULL)
        {
        ptwriaux->PRJVAL    = fgetc (fp);
        *(ptwriaux->CURVAL) = fgetc (fp);
        ptwriaux = ptwriaux->NEXT;
        }
      ptlkdins = ptlkdins->NEXT;
      }
    }
  return (errflg);
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_initval						*/
/* description	: initialize a description (all values set to 1)	*/
/* called func.	: none							*/
/* ###--------------------------------------------------------------### */

void vhx_initval (ptlkdfig, value)

struct lkdfig *ptlkdfig;
unsigned int   value;

  {
  struct simsig *ptsimsig = ptlkdfig->SIMSIG;
  struct bussig *ptbussig = ptlkdfig->BUSSIG;
  struct lkdins *ptlkdins = ptlkdfig->LKDINS;
  struct wrireg *ptwrireg;
  struct wriaux *ptwriaux;
  struct wribux *ptwribux;

  if (value == 1)
    {
    while (ptsimsig != NULL)
      {
      *(ptsimsig->CURVAL) = '1';
      ptsimsig = ptsimsig->NEXT;
      }

    while (ptbussig != NULL)
      {
      *(ptbussig->CURVAL) = '1';
      ptbussig = ptbussig->NEXT;
      }

    while (ptlkdins != NULL)
      {
      ptwrireg = ptlkdins->WRIREG;
      ptwriaux = ptlkdins->WRIAUX;
      ptwribux = ptlkdins->WRIBUX;

      while (ptwrireg != NULL)
        {
        *(ptwrireg->CURVAL) = '1';
        ptwrireg = ptwrireg->NEXT;
        }

      while (ptwribux != NULL)
        {
        *(ptwribux->CURVAL) = '1';
        ptwribux = ptwribux->NEXT;
        }

      while (ptwriaux != NULL)
        {
        *(ptwriaux->CURVAL) = '1';
        ptwriaux = ptwriaux->NEXT;
        }
      ptlkdins = ptlkdins->NEXT;
      }
    }
  }

/* ###--------------------------------------------------------------### */
/* function	: vhx_core						*/
/* description	: create a core file of the lkdfig			*/
/* called func.	: none							*/
/* ###--------------------------------------------------------------### */

void vhx_core (fp, pt_hedlkdfig)

FILE          *fp          ;
struct lkdfig *pt_hedlkdfig;

  {
  struct lkdfig *pt_lkdfig;
  time_t         clock;
  struct lkdins *pt_lkdins;
  struct simsig *pt_simsig;
  struct bussig *pt_bussig;
  struct wrireg *pt_wrireg;
  struct wriaux *pt_wriaux;
  struct wribux *pt_wribux;

  time (&clock);

  (void)fprintf (fp,"Core file generated from %s\n", pt_hedlkdfig->NAME);
  (void)fprintf (fp,"\t\tdate : %s \n \n", ctime(&clock));

  pt_lkdfig = pt_hedlkdfig;
  while (pt_lkdfig != NULL)
    {
    (void)fprintf(fp,"======== Figure : %s ==========\n",pt_lkdfig->NAME);

    (void)fprintf(fp,"\t------- simple signals --------\n");
    pt_simsig = pt_lkdfig->SIMSIG;
    while (pt_simsig != NULL)
      {
      if (pt_simsig->NAMECHAIN != NULL)
        {
        (void)fprintf(fp,"%s = %c\n", (char *)(pt_simsig->NAMECHAIN->DATA),
                                             *(pt_simsig->CURVAL));
        }
      pt_simsig = pt_simsig->NEXT;
      }

    (void)fprintf(fp,"\t------- buses --------\n");
    pt_bussig = pt_lkdfig->BUSSIG;
    while (pt_bussig != NULL)
      {
      if (pt_bussig->NAMECHAIN != NULL)
        {
        (void)fprintf(fp,"%s = %c\n", (char *)(pt_bussig->NAMECHAIN->DATA),
                                             *(pt_bussig->CURVAL));
        }
      pt_bussig = pt_bussig->NEXT;
      }

    (void)fprintf(fp,"\t------- internal registers --------\n");
    pt_lkdins = pt_lkdfig->LKDINS;
    pt_wrireg = pt_lkdins->WRIREG;
    while (pt_wrireg != NULL)
      {
      (void)fprintf(fp,"%s.%s = %c\n",  pt_wrireg->LKDINS->INSNAME,
                                        pt_wrireg->BEREG->NAME,
                                      *(pt_wrireg->CURVAL));
      pt_wrireg = pt_wrireg->NEXT;
      }

    (void)fprintf(fp,"\t------- internal simple signals -------\n");
    pt_wriaux = pt_lkdins->WRIAUX;
    while (pt_wriaux != NULL)
      {
      (void)fprintf(fp,"%s.%s = %c\n",  pt_wriaux->LKDINS->INSNAME,
                                        pt_wriaux->BEAUX->NAME,
                                      *(pt_wriaux->CURVAL));
      pt_wriaux = pt_wriaux->NEXT;
      }

    (void)fprintf(fp,"\t------- internal bus --------\n");
    pt_wribux = pt_lkdins->WRIBUX;
    while (pt_wribux != NULL)
      {
      (void)fprintf(fp,"%s.%s = %c\n",  pt_wribux->LKDINS->INSNAME,
                                        pt_wribux->BEBUX->NAME,
                                      *(pt_wribux->CURVAL));
      pt_wribux = pt_wribux->NEXT;
      }
    pt_lkdfig = pt_lkdfig->NEXT;
    }

  }
