/* program to convert .vec test vector format into ES2 .tlf test stream
   format.

   Note, This program is unsupported by ES2/US2, does not conform to ES2
   coding standards and has not been released as a quality assured
   product.
*/
#include <ctype.h>
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define maxsigs 300
#define out_delay 200.0
#define cnt_delay 100.0 /* must be less than out_delay */

#define SG sigs[i]
#define foris for(i=0;i<sindex;i++)


/* set up parser vars */
char cmt_start_ch      = '{',
     cmt_end_ch        = '}',
     line_cmt_ch       = '#',
     x_id_start_chs[]  = {'$','_','\0'},
     x_id_chs[]        = {'[',']','$','_','\0'},
     x_space_chs[]     = {';',':','@','-','=','\0'},
     op_chs[]          = {'+','*','/','\0'};
char *keys[] = { "END", "INPUT", "OUTPUT", "PIN", "BIDIR", "DEFPINS" };
#include "procs6.c"

float time = 0.0;
int  sindex = 0;
struct sig { char v,ov,dir,odir, vt, name[N_L]; } sigs[maxsigs];


FILE *fo,*fs;

main(argc,argv)
int argc; char *argv[];
{int i,l,j,c;
 char dirval,tc;
 if (argc<2) error("USAGE: vectlf <designname> [-s[tdout]] [-id*ent]\n");
 if(arg_num(argc,argv,"-i*dent")) {printf("Version APR/11/88\n"); exit(0);}
 fin= efopen(cf(argv[1],".vec"),"r");
 init();
 if(arg_num(argc,argv,"-s*tdout")) fo=stdout;
   else fo= efopen(cf(argv[1],".tlf"),"w");
 fs = efopen(cf(argv[1],".sig"),"w");

/*------------------------------------------------------------------*/


expect_sym("DEFPINS");
while (strneq(s,"END"))
{
 g_s();
 if (strneq(s,"PIN") && strneq(s,"END"))
   error("expected PIN or END");
  else
  {
   if (strcmp(s,"PIN") ==0)
   {get_int();
    g_s();
    if (strequ(s,"VSS") || strequ(s,"VDD")) /* do nothing */ ;
    else
    {
     if (t!=ident) error("Signal name expected");
     strcpy(sigs[sindex].name,s);
     g_s();
     if (s[0] != 'I' && s[0] != 'O' && s[0] != 'B')
      error("INPUT, OUTPUT, or BIDIR expected");
     sigs[sindex].vt = s[0];
     sindex++;                 }}
                                 }
                                   } /* while */

/*------- Now write the tlf header ----------------------------------*/
/*------- note: the sig number is the array index +1 ----------------*/


/* dummy control sigs are i+1001 */
foris
 { fpf(fo,"%s%d %s\n","S ",i+1,SG.name);
   if (SG.vt == 'B')
     fpf(fo,"%s%d %s%s\n","S ",i+1001,SG.name,"cnt");
 }

/*------- tlf header complete ---------------------------------------*/

writesig(); /* write the .sig file */

/* init values */
foris { SG.v = '-'; SG.dir = '-'; }

/*
 foris fpf(fo,"%s %c %c\n",SG.name,SG.vt,SG.v);
*/

/* write the initial values of outputs and IOs */
foris
{ if (SG.vt == 'I') printval('I',0.0,i,'0');
  if (SG.vt != 'I') printval('O',0.0,i,'X');
  if (SG.vt == 'B'||SG.vt=='T') printval('O',0.0,i+1000,'0');
}

/*-------- Read and deal with vectors ------------------------------*/


while (!feof(fin))  /* deal with vector */
{

 foris { SG.ov = SG.v; SG.odir = SG.dir; } /* copy old values */
 get_vline();
 if(!feof(fin)) {

 /* insert Z to turn off tester drive for bidirs and tristates */
 foris
   if(SG.odir == 'I'   &&
      SG.dir  == 'O'        ) printval('Z',time,i,'X');

 /* change the inputs and bidir inputs */
 foris
  if ((SG.vt == 'I' || (SG.dir=='I' && SG.odir == 'I')) &&
       SG.v != SG.ov)
        printval('I',time,i,SG.v);

 /* change bidirs cnt signals */
 foris
  if (   (SG.vt == 'B'||SG.vt=='T')
     &&  SG.dir != SG.odir)
     { if(SG.dir == 'I') dirval='1'; else dirval='0';
       printval('O',time+cnt_delay,i+1000,dirval); }

 /* change outputs and bidir outputs */
 foris
  {
   if ((SG.vt == 'O' && SG.v != SG.ov) ||
       (SG.dir == 'O' &&
        (SG.dir != SG.odir || SG.v != SG.ov)))
              printval('O',time+out_delay,i,SG.v);
  }

 foris
  {
   if (SG.dir == 'I' && SG.odir == 'O')
              printval('Z',time+out_delay,i,'X');
  }

 insert_dir_vector();


/*
 foris fpf(fo,"%s %c %c\n",SG.name,SG.vt,SG.v);
*/

 time += 1000.0;
 } /* if !eof */
} /* END of vector while */

fpf(fo,"\nE\n");
fpf(stdout,"-I-  %5.0f vectors generated\n",time/1000);

} /* main */

/*------------------------------------------------------------------*/

insert_dir_vector()

{int flag = FALSE, i; /* fpf(fo,"entering insert_dir_vector "); */
 foris
  if ((SG.odir == 'O' || SG.odir == '-')   &&
      SG.dir == 'I'        ) flag = TRUE;
 if (flag)
  { time += 1000.0;
    foris
     if ((SG.odir == 'O' || SG.odir == '-') && SG.dir == 'I')
            printval('I',time,i,SG.v);
  }

}

/*------------------------------------------------------------------*/

cv(c)
char c;
{ switch (c) {
  case 'L': return('0');
  case 'H': return('1');
  default : return(c);
 }
}


vt(c)
char c;
{ if (c == 'L' || c == 'H') return('I'); else
   {if (c == '0' || c == '1' || c == 'X') return('O');
    else return('U'); }}


/*------------------------------------------------------------------*/

get_value()
{ /* fpf(fo,"gv\n"); */
 do {
     xgetch();
     if (ch=='#') { while (ch != '\n') xgetch(); }
     if (ch=='{') { while (ch != '}')  xgetch(); }
     ch= uc(ch);
               } while (cinstring(ch,"HL10X") == FALSE && ch != EOF);
 return(ch);
}

/*------------------------------------------------------------------*/

get_vline()
{ int i; char c;
  foris
  { c = get_value();
    if (SG.vt == 'O' && (c == 'H' || c == 'L'))
                            error("Expected output value");
    if (SG.vt == 'I' && (c == '0' || c == '1' || c == 'X'))
                            error("Expected input value");
    if (SG.vt == 'B' && c == 'X') SG.dir = 'O';
          else SG.dir = vt(c);
    SG.v = cv(c);
  } /* for */
}

/*------------------------------------------------------------------*/

printval(io,t,node,val)
char io,val;
float t;
int node;
{ static float print_time = 0.0;
  static int   printed_so_far=0;
  static char  print_io='-';
  static int   first=TRUE;

/* printf("%c %f %c\n",io,t,val); */
  if (t == print_time && io == print_io)
  { if (printed_so_far >7) {printed_so_far=0; fpf(fo," -\n            ");}
    fpf(fo," %d:%c",node+1,val);
    printed_so_far++;
  }
  else
  { print_io = io; print_time = t;
    if (!first) fpf(fo,"\n");
    fpf(fo,"%c %7.1f %d:%c",io,t,node+1,val);
    printed_so_far = 0; first=FALSE;
  }
}

/*--------------------------------------------------------------------*/

char *dumsig()
{ static char st[20];
  static int sn=0;
  sprintf(st,"dum%d",sn++);
  return(st);
}

writesig()
{int i;
 /* write inputs */
 foris
 {if (SG.vt == 'I')
    {  fpf(fs,"$ \"IPS8B\", \"%sins\"\n[\n\"bond\", \"%s\", %d\n",
               SG.name,SG.name,i+1);
       fpf(fs,"\"y\", \"%s\", %d\n]\n\n",dumsig(),i+500);
    }
 }

 /* write outputs */
 foris
 {if (SG.vt == 'O')
    {  fpf(fs,"$ \"OPS1U\", \"%sins\"\n[\n\"bond\", \"%s\", %d\n",
               SG.name,SG.name,i+1);
       fpf(fs,"\"a\", \"%s\", %d\n]\n\n",dumsig(),i+300);
    }
 }

 /* write bidirs */
 foris
 {if (SG.vt == 'B' || SG.vt == 'T')
    {  fpf(fs,"$ \"IOS1P\", \"%sins\"\n[\n\"bond\", \"%s\", %d\n",
               SG.name,SG.name,i+1);
       fpf(fs,"\"y\", \"%s\", %d\n",dumsig(),i+300);
       fpf(fs,"\"a\", \"%s\", %d\n",dumsig(),i+700);
       fpf(fs,"\"en\", \"%scnt\", %d\n]\n\n",SG.name,i+1001);
    }
 }


}

/*--------------------------------------------------------------------*/