tab2wvs_gram.y 7.5 KB
/* tab2wvs_gram.y - Grammar for tab2wvs  */


%{

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <values.h>

#include "tab2wvs.h"

/*
 * tokenString is global holding last ident, string, literal
 * shorn of quotes
 */

#define TOKENSIZ  	256
#define MAX_NUMBER_LEN  128

typedef union _NameType {
   char name[TOKENSIZ];
   int  ival;
} NameType;

#define YYSTYPE NameType

/* Forward References */

void    install(char *);
void    install_number(char *, int);


/* globals */

extern FILE *Vecfp; /* memory vectors */

SigDef Signal[MAX_SIGNALS];
ClockDef Clock[MAX_CLOCKS];
int nSigs = 0;  /* number of signals */
int nClocks = 0;  /* number of signals */
int nVecs = 0;  /* number of vectors */
int MemWidth = 0;  /* test vector memory width in bits */

static char VecArray[MAX_SIGNALS][MAX_NUMBER_LEN];
static int CurSig    = 0; /* current signal */
static int CurEdge   = 0; /* current edge timing */
static int CurStrobe = 0; /* current strobe timing */
static int ClkSig = 0; /* clock signal flag */
static int ClkPhase = 0; /* clock phases */
static int line_num = 0; 
static int VectorPhase = 0; 

%}

%start Input

/* Reserved Keywords */


/* symbols */

%token tCOLON
%token tEOL
%token tLBRACK
%token tRBRACK
%token tLPAREN
%token tRPAREN
%token tINPUT
%token tOUTPUT
%token tBIDIR
%token tEDGE
%token tSTROBE
%token tCLOCK
%token tVALID

/* patterns */

%token tNUMBER
%token tHEX
%token tIDENT
%token tJUNK

%%

Input		: /* EMPTY */
		| Input Statement
		{
		  line_num++;
		}
;

Statement	: tEOL
		{
		  char c;
		  int i;

		  /* print header */
		  fprintf(Vecfp, "PINORDER ");
		  for(i = 0; i < nSigs; i++)
		  {
		    if(i != nSigs-1)
		      c = ',';
		    else
		      c = ';';
		    if(Signal[i].hex_dig)
		      fprintf(Vecfp,"'h%s%c ",Signal[i].sig_name, c);
		    else
		      fprintf(Vecfp,"%s%c ",Signal[i].sig_name, c);
		  }
		  fprintf(Vecfp,"\n");
		  VectorPhase = 1;
		}
		| Signals tEOL
		{
		  if(!ClkSig)
		    nSigs++;
		  else {
		    ClkSig = 0;
		    nClocks++;
		  }
		  if(nSigs > MAX_SIGNALS)
		  {
		    fprintf(stderr,"Error: exceeded max number of signals %d\n", MAX_SIGNALS);
		    exit(1);
		  }
		  if(nClocks > MAX_CLOCKS)
		  {
		    fprintf(stderr,"Error: exceeded max number of clocks %d\n", MAX_CLOCKS);
		    exit(1);
		  }
		}
		| Vector tEOL
		{
		  int i;

		  nVecs++;
		  CurSig = 0; /* reset */
		  for(i = 0; i < nSigs; i++) {
		    fprintf(Vecfp,"%s ", VecArray[i]);
		  }
		  fprintf(Vecfp, ";\n");
		}
;

		  

Signals         : InputSig
                | OutputSig
                | BiDirectionalSig
                | ValidSig
                | ClockSig
                {
                  ClkSig = 1;
                }
                | error
                {
                  printf("Signal, Unrecognized signal syntax: %s\n", yylval.name);
                }
;


InputSig        : SignalName tINPUT
                {
                  Signal[nSigs].type = WVS_INPUT;
                }
                | InputSig tEDGE tNUMBER
                {
                  Signal[nSigs].edge = $3.ival;
                  CurEdge = $3.ival;
                }
                | InputSig tVALID tIDENT
                {
                  strcpy(Signal[nSigs].val_sig_name, $3.name);
                  Signal[nSigs].valid = 1;
                }
;

OutputSig       : SignalName tOUTPUT
                {
                  Signal[nSigs].type = WVS_OUTPUT;
                }
                | OutputSig tSTROBE tNUMBER
                {
                  Signal[nSigs].strobe = $3.ival;
                  CurStrobe = $3.ival;
                }
                | OutputSig tVALID tIDENT
                {
                  strcpy(Signal[nSigs].val_sig_name, $3.name);
                  Signal[nSigs].valid = 1;
                }
;

BiDirectionalSig: SignalName tBIDIR tIDENT tNUMBER
                {
                  strcpy(Signal[nSigs].en_sig_name, $3.name);
                  Signal[nSigs].type = WVS_BIDIR;
                  Signal[nSigs].polarity = $4.ival;
                }
                | BiDirectionalSig tEDGE tNUMBER
                {
                  Signal[nSigs].edge = $3.ival;
                  CurEdge = $3.ival;
                }
                | BiDirectionalSig tSTROBE tNUMBER
                {
                  Signal[nSigs].strobe = $3.ival;
                  CurStrobe = $3.ival;
                }
                | BiDirectionalSig tVALID tIDENT
                {
                  strcpy(Signal[nSigs].val_sig_name, $3.name);
                  Signal[nSigs].valid = 1;
                }
                | error
;

ValidSig        : SignalName tVALID
                {
                  Signal[nSigs].type = WVS_VALID;
                  CurEdge = 0;
                }
;

ClockSig        : SignalName tCLOCK tNUMBER tLPAREN tNUMBER tRPAREN
                {
                  /* copy signal name, don't increment signals */
                  strcpy(Clock[nClocks].sig_name, Signal[nSigs].sig_name);
                  ClkPhase = 0;
                  Clock[nClocks].val[ClkPhase] = $3.ival;
                  Clock[nClocks].time[ClkPhase] = $5.ival;
                  ClkPhase++;
                  Clock[nClocks].phases = ClkPhase;
                }
                | ClockSig tNUMBER tLPAREN tNUMBER tRPAREN
                {
                  /* copy signal name, don't increment signals */
                  if(ClkPhase > MAX_CLK_PHASES) {
                    fprintf(stderr,"Error, exceeded max number of clk phases %d\n",
                        ClkPhase);
                    exit(1);
                  }
                  Clock[nClocks].val[ClkPhase] = $3.ival;
                  Clock[nClocks].time[ClkPhase] = $5.ival;
                  ClkPhase++;
                  Clock[nClocks].phases = ClkPhase;
                }
;


SignalName      : Bus
                {
                  Signal[nSigs].type    = WVS_INPUT; /* default */
                  Signal[nSigs].edge    = CurEdge; /* default */
                  Signal[nSigs].strobe  = CurStrobe; /* default */
                  Signal[nSigs].valid = 0;
                  MemWidth += Signal[nSigs].hex_dig * 4;
                }
                | tIDENT
                {
                  strcpy(Signal[nSigs].sig_name, $1.name);
                  Signal[nSigs].size    = 1;
                  Signal[nSigs].msb     = 0;
                  Signal[nSigs].lsb     = 0;
                  Signal[nSigs].hex_dig = 0;
                  Signal[nSigs].type    = WVS_INPUT; /* default */
                  Signal[nSigs].edge    = CurEdge; /* default */
                  Signal[nSigs].strobe  = CurStrobe; /* default */
                  Signal[nSigs].valid = 0;
                  MemWidth += 4;
                }
;


Bus             : tIDENT tLBRACK tNUMBER tCOLON tNUMBER tRBRACK
                {
                  sprintf(Signal[nSigs].sig_name, "%s[%d:%d]\0",$1.name,$3.ival,$5.ival);
                  Signal[nSigs].msb     = $3.ival;
                  Signal[nSigs].lsb     = $5.ival;
                  Signal[nSigs].size    = $3.ival - $5.ival + 1;
                  Signal[nSigs].hex_dig = (Signal[nSigs].size + 3) / 4;
                }
;

Vector          : VecNumber
                | Vector VecNumber
                | error
                {
                  printf("Unrecognized signal syntax: %s\n", yylval.name);
                }
;

VecNumber       : tNUMBER
                {
                  strcpy(VecArray[CurSig++],$1.name);
                }
                | tHEX
                {
                  strcpy(VecArray[CurSig++],&($1.name[2]));
                }
;


%%

#include "tab2wvs_scan.c"