
/***********************************************************************


	Copyright (C) 1991,
	Virginia Polytechnic Institute & State University


	This program was originally written by Mr. Hyung K. Lee
	under the supervision of Dr. Dong S. Ha, in the Bradley
	Department of Electrical Engineering, VPI&SU, in 1991.

	This program is released for research use only. This program,
	or any derivative thereof, may not be reproduced nor used 
	for any commercial product without the written permission 
	of the authors.

	For detailed information, please contact to

	Dr. Dong S. Ha
	Bradley Department of Electrical Engineering
	Virginia Polytechnic Institute & State University
	Blacksburg, VA 24061

        Ph.: (540) 231-4942
        Fax: (540) 231-3362
        E-Mail: ha@vt.edu
        Web: http://www.ee.vt.edu/ha

***********************************************************************/

/**************************** HISTORY **********************************

	atalanta & fsim: version 1.0

	Original: H. K. Lee, 8/15/1990
	Updated: H. K. Lee, 8/15/1991

	atalanta & fsim: version 1.1

	Changed Parser and added on-line manual: H. K. Lee, 10/5/1992

	Now, atalanta accepts the circuit written in the netlist format
	of ISCAS89 benchmark circuits as well as the netlist format of
	ISCAS85 benchmark circuits.

***********************************************************************/

/*------------------------------------------------------------------
	filename:  pio.c
	This file contains all subroutines needed for input/output
	of atalanta and fsim results.
--------------------------------------------------------------------*/
#include <stdio.h>
#include "atpg.h"

extern char cctmode;

#define chars_per_line 60
#define chars_per_column 50
#define number_of_spaces 5

/* macros for the bit operation of a computer word */
#define setbit(word,n) word&=bitmask[n]
#define resetbit(word,n) word|=(~bitmask[n])
#define checkbit(word,n) ((word&bitmask[n])!=ALL0)
#define putbit(fp,word,n) if(checkbit(word,n)) putc('1',fp); else putc('0',fp)

/*	printinputs
	print nth bit test pattern of the circuit input
*/
void printinputs(fp,npi,nth_bit)
FILE *fp;
int npi,nth_bit;
{
    register int j;
    for(j=0;j<npi;j++)
       putbit(fp,net[j]->output1,nth_bit);
}

/*	printoutputs
	print nth bit output response of the circuit
*/
void printoutputs(fp,npo,nth_bit)
FILE *fp;
int npo,nth_bit;
{
    register int j;
    for(j=0;j<npo;j++)
       putbit(fp,net[primaryout[j]]->output1,nth_bit);
}

#define TEST_PER_LINE 13

boolean print_test_topic(fp,npi,npo,name)
FILE *fp;
int npi,npo;
char name[];
{
   register int i;

   fprintf(fp,"* Name of circuit:  %s\n",name);
   fprintf(fp,"* Primary inputs :\n  ");
   for(i=0;i<npi;i++) {
      if(cctmode==ISCAS89) fprintf(fp,"%s ",net[i]->symbol->symbol);
      else fprintf(fp,"%5d ",net[i]->index);
      if(((i+1) mod TEST_PER_LINE == 0) || (i==npi-1))
	 fprintf(fp,"\n  ");
   }
   fprintf(fp,"\n");
   fprintf(fp,"* Primary outputs:\n  ");
   for(i=0;i<npo;i++) {
      if(cctmode==ISCAS89)
	 fprintf(fp,"%s ",net[primaryout[i]]->symbol->symbol);
      else fprintf(fp,"%5d ",net[primaryout[i]]->index);
      if(((i+1) mod TEST_PER_LINE == 0) || (i==npi-1))
	 fprintf(fp,"\n  ");
   }
   fprintf(fp,"\n\n* Test patterns and fault free responses:\n\n");
}

/*	printio
	prints nth bit test patterns and outputs of the circuit
*/
int printio(fp,npi,npo,nth_bit,start)
FILE *fp;
int npi,npo,nth_bit,start;
{
   fprintf(fp,"%4d: ",start);
   printinputs(fp,npi,nth_bit);
   fprintf(fp," ");
   printoutputs(fp,npo,nth_bit);
   fprintf(fp,"\n");
}

void print_log_topic(fp,name)
FILE *fp;
char name[];
{
   fprintf(fp,"* Log file for the circuit %s.\n",name);
   fprintf(fp,"* Number of faults detected by each test pattern:\n\n");
}

/*	pget_test
	Reads test input files and stores in parallel.
	Returns number of test patterns read.
	Returns 0 if EOF is encountered.
*/
int pget_test(fp,input,npi,nbit)
FILE *fp;
level input[];
int npi,nbit;
{
   register int i;
   register int c;
   int ntest;
   unsigned mask1=~(ALL1<<1);
   boolean valid=FALSE;

   i=0;
   for(ntest=0;ntest<nbit;ntest++) {
      while((c=getc(fp))!=EOF) {
         switch(c) {
	 case '*': while((c=getc(fp))!='\n') if(c == EOF) break; break;
	 case ':': valid=TRUE; break;
	 case '0': if(valid) input[i++]<<=1; break;
         case '1': if(valid) {input[i]<<=1; input[i++]|=mask1;} break;
	 }
         if(i==npi) {i=0; valid=FALSE; break;}
      }
      if(c==EOF) break;
   }
   if(i>0 && i<npi) return(0);
   return(ntest);
}

/*	printfault: prints a fault 	*/
char *fault2str[4]={"/0","/1","/0","/1"};
void printfault(fp,f,mode)
FILE *fp;
FAULTPTR f;
boolean mode;
{
   GATEPTR gut;

   if(cctmode==ISCAS89) {
      if(f->faulty_line >= 0) {
	 gut = f->faulty_gate->inlis[f->faulty_line];
	 fprintf(fp, "%s", gut->symbol->symbol);
         fprintf(fp, "->");
      }
      fprintf(fp,"%s %s",f->faulty_gate->symbol->symbol,fault2str[f->fault]);
   } else {
      switch(f->fault) {
         case INsa0:  fprintf(fp,"Input line %d s-a-0 ",f->faulty_line+1); break;
         case INsa1:  fprintf(fp,"Input line %d s-a-1 ",f->faulty_line+1); break;
         case OUTsa0: fprintf(fp,"Output line s-a-0 "); break;
         case OUTsa1: fprintf(fp,"Output line s-a-1 "); break;
      }
      fprintf(fp,"of gate %d ",f->faulty_gate->index);
   }
   if(mode) switch(f->covered) {
      case DETECTED: fprintf(fp,"detected"); break;
      case UNDETECTED: fprintf(fp,"undetected"); break;
      case PROCESSED: fprintf(fp,"aborted"); break;
      case REDUNDANT: fprintf(fp,"redundant");
   }
   fprintf(fp,"\n");
}


/* The following subroutines are necessary for debugging or
   exteraction of net lists --- not used in normal mode */

#define logic_type(gut) \
switch(gut->fn) { \
case AND: if(gut->ninput==1)printf("buff");else printf("and "); break; \
case NAND: if(gut->ninput==1)printf("not ");else printf("nand"); break; \
case OR: if(gut->ninput==1)printf("buff");else printf("or  "); break; \
case NOR: if(gut->ninput==1)printf("not ");else printf("nor "); break; \
case XOR: if(gut->ninput==1)printf("buff");else printf("xor "); break; \
case PI: printf("input");}

void print_gate(gut)
register GATEPTR gut;
{
   register int i;

/*
   printf("%s: ",gut->symbol->symbol);
*/
   if(gut->fn==PI) 
      printf("input(%d)",gut->gid);
   else {
      printf("%d = ",gut->gid);
      logic_type(gut); 
      printf("(");
      for(i=0;i<gut->ninput;i++) 
         if(i==0) printf("%d",gut->inlis[i]->gid);
         else printf(",%d",gut->inlis[i]->gid);
      printf(")");
   }
   printf("\n");
}

void sprint_gate(gut)
register GATEPTR gut;
{
   register int i;

/*
   printf("%s: ",gut->symbol->symbol);
*/
   if(gut->fn==PI) 
      printf("input(%s)",gut->symbol->symbol);
   else {
      printf("%s = ",gut->symbol->symbol);
      logic_type(gut); 
      printf("(");
      for(i=0;i<gut->ninput;i++) 
         if(i==0) printf("%s",gut->inlis[i]->symbol->symbol);
         else printf(",%s",gut->inlis[i]->symbol->symbol);
      printf(")");
   }
   printf("\n");
}

/*
void print_output_cone(gut,maxdpi,mode)
register GATEPTR gut; int maxdpi;
char mode;
{
   register int i,j;

   push(event_lis[gut->dpi],gut);
   set(gut->ichange);
   for(i=gut->dpi;i<maxdpi;i++)
      while(!is_empty(event_lis[i])) {
	 gut=pop(event_lis[i]);
	 reset(gut->ichange);
	 if(mode=='s') sprint_gate(gut);
	 else print_gate(gut);
	 for(j=0;j<gut->noutput;j++) {
	    if(!gut->outlis[j]->ichange) {
	       push(event_lis[gut->outlis[j]->dpi],gut->outlis[j]);
	       set(gut->outlis[j]->ichange);
	    }
	 }
      }
}

void print_input_cone(gut,mode)
register GATEPTR gut;
char mode;
{
   register int i,j;

   push(event_lis[gut->dpi],gut);
   set(gut->ichange);
   for(i=gut->dpi;i>=0;i--)
      while(!is_empty(event_lis[i])) {
	 gut=pop(event_lis[i]);
	 reset(gut->ichange);
	 if(mode=='s') sprint_gate(gut);
	 else print_gate(gut);
	 for(j=0;j<gut->ninput;j++) {
	    if(!gut->inlis[j]->ichange) {
	       push(event_lis[gut->inlis[j]->dpi],gut->inlis[j]);
	       set(gut->inlis[j]->ichange);
	    }
	 }
      }
}
*/
