You are on page 1of 9

C:\Users\saurav\Desktop\EE658\HW3\readckt.

Wednesday, October 02, 2013 11:44 AM

/*=======================================================================
A simple parser for "self" format
The circuit format (called "self" format) is based on outputs of
a ISCAS 85 format translator written by Dr. Sandeep Gupta.
The format uses only integers to represent circuit information.
The format is as follows:
1
-----0 GATE

2
------outline

3
4
5
6 ...
------- ----------------------0 IPT
#_of_fout
#_of_fin
inlines
1 BRCH
2 XOR(currently not implemented)
3 OR
4 NOR
5 NOT
6 NAND
7 AND

1 PI
2 FB
3 PO

outline
outline
outline

0
1 BRCH
2 - 7

#_of_fout
inline
0

0
#_of_fin

inlines

Author: Chihang Chen


Date: 9/16/94
=======================================================================*/
/*=======================================================================
- Write your program as a subroutine under main().
The following is an example to add another command 'lev' under main()
enum e_com {READ, PC, HELP, QUIT, LEV};
#define NUMFUNCS 5
int cread(), pc(), quit(), lev();
struct cmdstruc command[NUMFUNCS] = {
{"READ", cread, EXEC},
{"PC", pc, CKTLD},
{"HELP", help, EXEC},
{"QUIT", quit, EXEC},
{"LEV", lev, CKTLD},
};
lev()
{
...
}
=======================================================================*/
#include <stdio.h>
#include <ctype.h>
-1-

C:\Users\saurav\Desktop\EE658\HW3\readckt.c

Wednesday, October 02, 2013 11:44 AM

#include <stdlib.h>
#define MAXLINE 81
#define MAXNAME 31

/* Input buffer size */


/* File name size */

#define Upcase(x) ((isalpha(x) && islower(x))? toupper(x) : (x))


#define Lowcase(x) ((isalpha(x) && isupper(x))? tolower(x) : (x))
enum
enum
enum
enum

e_com
e_state
e_ntype
e_gtype

{READ, PC, HELP, QUIT, LEVEL};


{EXEC, CKTLD};
/* Gstate values */
{GATE, PI, FB, PO};
/* column 1 of circuit format */
{IPT, BRCH, XOR, OR, NOR, NOT, NAND, AND}; /* gate types */

struct cmdstruc {
char name[MAXNAME];
int (*fptr)();
enum e_state state;
};

/* command syntax */
/* function pointer of the commands */
/* execution state sequence */

typedef struct n_struc {


unsigned indx;
unsigned num;
enum e_gtype type;
unsigned fin;
unsigned fout;
struct n_struc **unodes;
struct n_struc **dnodes;
int level;
} NSTRUC;

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

node index(from 0 to NumOfLine - 1 */


line number(May be different from indx */
gate type */
number of fanins */
number of fanouts */
pointer to array of up nodes */
pointer to array of down nodes */
level of the gate output */

/*----------------- Command definitions ----------------------------------*/


#define NUMFUNCS 5
int cread(), pc(), help(), quit(), level();
struct cmdstruc command[NUMFUNCS] = {
{"READ", cread, EXEC},
{"PC", pc, CKTLD},
{"HELP", help, EXEC},
{"QUIT", quit, EXEC},
{"LEVEL", level, CKTLD},
};
/*------------------------------------------------------------------------*/
enum e_state Gstate = EXEC;
/* global exectution sequence */
NSTRUC *Node;
/* dynamic array of nodes */
NSTRUC **Pinput;
/* pointer to array of primary inputs */
NSTRUC **Poutput;
/* pointer to array of primary outputs */
int Nnodes;
/* number of nodes */
int Npi;
/* number of primary inputs */
int Npo;
/* number of primary outputs */
int Done = 0;
/* status bit to terminate program */
/*------------------------------------------------------------------------*/
/*----------------------------------------------------------------------input: nothing
-2-

C:\Users\saurav\Desktop\EE658\HW3\readckt.c

Wednesday, October 02, 2013 11:44 AM

output: nothing
called by: shell
description:
This is the main program of the simulator. It displays the prompt, reads
and parses the user command, and calls the corresponding routines.
Commands not reconized by the parser are passed along to the shell.
The command is executed according to some pre-determined sequence.
For example, we have to read in the circuit description file before any
action commands. The code uses "Gstate" to check the execution
sequence.
Pointers to functions are used to make function calls which makes the
code short and clean.
-----------------------------------------------------------------------*/
main()
{
enum e_com com;
char cline[MAXLINE], wstr[MAXLINE], *cp;
while(!Done) {
printf("\nCommand>");
fgets(cline, MAXLINE, stdin);
if(sscanf(cline, "%s", wstr) != 1) continue;
cp = wstr;
while(*cp){
*cp= Upcase(*cp);
cp++;
}
cp = cline + strlen(wstr);
com = READ;
while(com < NUMFUNCS && strcmp(wstr, command[com].name)) com++;
if(com < NUMFUNCS) {
if(command[com].state <= Gstate) (*command[com].fptr)(cp);
else printf("Execution out of sequence!\n");
}
else system(cline);
}
}
/*----------------------------------------------------------------------input: circuit description file name
output: nothing
called by: main
description:
This routine reads in the circuit description file and set up all the
required data structure. It first checks if the file exists, then it
sets up a mapping table, determines the number of nodes, PI's and PO's,
allocates dynamic data arrays, and fills in the structural information
of the circuit. In the ISCAS circuit description format, only upstream
nodes are specified. Downstream nodes are implied. However, to facilitate
forward implication, they are also built up in the data structure.
To have the maximal flexibility, three passes through the circuit file
are required: the first pass to determine the size of the mapping table
, the second to fill in the mapping table, and the third to actually
set up the circuit information. These procedures may be simplified in
-3-

C:\Users\saurav\Desktop\EE658\HW3\readckt.c

Wednesday, October 02, 2013 11:44 AM

the future.
-----------------------------------------------------------------------*/
cread(cp)
char *cp;
{
char buf[MAXLINE];
int ntbl, *tbl, i, j, k, nd, tp, fo, fi, ni = 0, no = 0;
FILE *fd;
NSTRUC *np;
sscanf(cp, "%s", buf);
if((fd = fopen(buf,"r")) == NULL) {
printf("File %s does not exist!\n", buf);
return;
}
if(Gstate >= CKTLD) clear();
Nnodes = Npi = Npo = ntbl = 0;
while(fgets(buf, MAXLINE, fd) != NULL) {
if(sscanf(buf,"%d %d", &tp, &nd) == 2) {
if(ntbl < nd) ntbl = nd;
Nnodes ++;
if(tp == PI) Npi++;
else if(tp == PO) Npo++;
}
}
tbl = (int *) malloc(++ntbl * sizeof(int));
fseek(fd, 0L, 0);
i = 0;
while(fgets(buf, MAXLINE, fd) != NULL) {
if(sscanf(buf,"%d %d", &tp, &nd) == 2) tbl[nd] = i++;
}
allocate();
fseek(fd, 0L, 0);
while(fscanf(fd, "%d %d", &tp, &nd) != EOF) {
np = &Node[tbl[nd]];
np->num = nd;
if(tp == PI) Pinput[ni++] = np;
else if(tp == PO) Poutput[no++] = np;
switch(tp) {
case PI:
case PO:
case GATE:
fscanf(fd, "%d %d %d", &np->type, &np->fout, &np->fin);
break;
case FB:
np->fout = np->fin = 1;
fscanf(fd, "%d", &np->type);
break;
default:
printf("Unknown node type!\n");
-4-

C:\Users\saurav\Desktop\EE658\HW3\readckt.c

Wednesday, October 02, 2013 11:44 AM

exit(-1);
}
np->unodes = (NSTRUC **) malloc(np->fin * sizeof(NSTRUC *));
np->dnodes = (NSTRUC **) malloc(np->fout * sizeof(NSTRUC *));
for(i = 0; i < np->fin; i++) {
fscanf(fd, "%d", &nd);
np->unodes[i] = &Node[tbl[nd]];
}
for(i = 0; i < np->fout; np->dnodes[i++] = NULL);
}
for(i = 0; i < Nnodes; i++) {
for(j = 0; j < Node[i].fin; j++) {
np = Node[i].unodes[j];
k = 0;
while(np->dnodes[k] != NULL) k++;
np->dnodes[k] = &Node[i];
}
}
fclose(fd);
Gstate = CKTLD;
printf("==> OK\n");
}

/*-----------------------input: level
output: nothing
called by: main
prints levels of all the nodes of the ckt
------------------------------*/
level(cp)
char *cp;
{
char buf[MAXLINE];
int i = 0,j, tp, max;
FILE *fd;
NSTRUC *np;

sscanf(cp, "%s", buf);


// printf("%s",buf);
if((fd = fopen(buf,"r")) == NULL) {
printf("File %s does not exist!\n", buf);
return;
}

while(fgets(buf, MAXLINE, fd) != NULL) {


np = &Node[i];
if(sscanf(buf,"%d", &tp) == 1) {
if(tp == PI) np->level = 0;
else
if ((tp == GATE) || (tp == PO))
-5-

C:\Users\saurav\Desktop\EE658\HW3\readckt.c

Wednesday, October 02, 2013 11:44 AM

{
for (j = 0; j<np->fin; j++)
{
if(j == 0){
max = np->unodes[j]->level; }
else if((np->unodes[j]->level) > max)
{
max = np->unodes[j]->level;
}
}
np->level = max+1;
}
else if(tp == FB)
{
np->level = np->unodes[0]->level + 1;
}
i++;
}
}
}

/*----------------------------------------------------------------------input: nothing
output: nothing
called by: main
description:
The routine prints out the circuit description from previous READ command.
-----------------------------------------------------------------------*/
pc(cp)
char *cp;
{
int i, j;
NSTRUC *np;
char *gname();
printf(" Node
Type \tIn
\t\t\tOut
\t\t\tLevel\n");
printf("------ ------\t-------\t\t\t-------\t\t\t------\n");
for(i = 0; i<Nnodes; i++) {
np = &Node[i];
// printf(\"%d",np->level);
printf("\t\t\t\t\t");
// printf("%d",np->level);
-6-

C:\Users\saurav\Desktop\EE658\HW3\readckt.c

Wednesday, October 02, 2013 11:44 AM

for(j = 0; j<np->fout; j++) printf("%d ",np->dnodes[j]->num);


printf("\t\t\t");
printf("%d",np->level);
printf("\r%5d %s\t", np->num, gname(np->type));
// printf("%d",np->level);
for(j = 0; j<np->fin; j++) printf("%d ",np->unodes[j]->num);
printf("\n");
//printf("\n");
}
printf("Primary inputs: ");
for(i = 0; i<Npi; i++) printf("%d ",Pinput[i]->num);
printf("\n");
printf("Primary outputs: ");
for(i = 0; i<Npo; i++) printf("%d ",Poutput[i]->num);
printf("\n\n");
printf("Number of nodes = %d\n", Nnodes);
printf("Number of primary inputs = %d\n", Npi);
printf("Number of primary outputs = %d\n", Npo);
}
/*----------------------------------------------------------------------input: nothing
output: nothing
called by: main
description:
The routine prints out help information for each command.
-----------------------------------------------------------------------*/
help()
{
printf("READ filename - ");
printf("read in circuit file and creat all data structures\n");
printf("PC - ");
printf("print circuit information\n");
printf("HELP - ");
printf("print this help information\n");
printf("QUIT - ");
printf("stop and exit\n");
}
/*----------------------------------------------------------------------input: nothing
output: nothing
called by: main
description:
Set Done to 1 which will terminates the program.
-----------------------------------------------------------------------*/
quit()
{
Done = 1;
}

-7-

C:\Users\saurav\Desktop\EE658\HW3\readckt.c

Wednesday, October 02, 2013 11:44 AM

/*======================================================================*/
/*----------------------------------------------------------------------input: nothing
output: nothing
called by: cread
description:
This routine clears the memory space occupied by the previous circuit
before reading in new one. It frees up the dynamic arrays Node.unodes,
Node.dnodes, Node.flist, Node, Pinput, Poutput, and Tap.
-----------------------------------------------------------------------*/
clear()
{
int i;
for(i = 0; i<Nnodes; i++) {
free(Node[i].unodes);
free(Node[i].dnodes);
}
free(Node);
free(Pinput);
free(Poutput);
Gstate = EXEC;
}
/*----------------------------------------------------------------------input: nothing
output: nothing
called by: cread
description:
This routine allocatess the memory space required by the circuit
description data structure. It allocates the dynamic arrays Node,
Node.flist, Node, Pinput, Poutput, and Tap. It also set the default
tap selection and the fanin and fanout to 0.
-----------------------------------------------------------------------*/
allocate()
{
int i;
Node = (NSTRUC *) malloc(Nnodes * sizeof(NSTRUC));
Pinput = (NSTRUC **) malloc(Npi * sizeof(NSTRUC *));
Poutput = (NSTRUC **) malloc(Npo * sizeof(NSTRUC *));
for(i = 0; i<Nnodes; i++) {
Node[i].indx = i;
Node[i].fin = Node[i].fout = 0;
}
}
/*----------------------------------------------------------------------input: gate type
output: string of the gate type
called by: pc
description:
The routine receive an integer gate type and return the gate type in
-8-

C:\Users\saurav\Desktop\EE658\HW3\readckt.c

Wednesday, October 02, 2013 11:44 AM

character string.
-----------------------------------------------------------------------*/
char *gname(tp)
int tp;
{
switch(tp) {
case 0: return("PI");
case 1: return("BRANCH");
case 2: return("XOR");
case 3: return("OR");
case 4: return("NOR");
case 5: return("NOT");
case 6: return("NAND");
case 7: return("AND");
}
}
/*========================= End of program ============================*/

-9-

You might also like