Subversion Repositories Vertical

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/*
2
 * hdl.y parser for verilog net lists 
3
 *  by  Frank Bennett 
4
 *
5
 * i.e. hdl s.g 
6
 * products two files: s.nam, s.seq - 1 net per line
7
 *   s.seq is sorted by reference designator
8
 *   s.nam is sorted by netname
9
 *
10
 * - primarily handles "flat" verilog HDL netlists.
11
 * - parses hierarchical netlist but currently doesn't flatten them.
12
 * - concatenated signal names need to be expanded. currently the whole
13
 *   netname bundle is given the name : "concatenation"
14
 * - not included :
15
 * 	Behavioral Statements
16
 *	Specify blocks
17
 *
18
 *  PD yacc :
19
 * byacc, Bob Corbett. Berkely yacc adapted for MINIX by Peter Housel
20
 * COLOGNE:commands/lex-yacc/byacc.tar.Z
21
 *
22
 * DOS extender - 386 to avoid malloc problems
23
 * djgpp.zip 
24
 * wuarchive.wustl.edu   (128.252.135.4): /mirrors3/garbo.uwasa.fi/programming
25
 */
26
%{
27
#define YYDEBUG 1
28
#include <string.h>
29
#include <ctype.h>
30
#include <errno.h>
31
#include <stdio.h>
32
#include <fcntl.h>
33
 
34
#define out(c) putc(c,yyout)
35
#define NCOM 300
36
 
37
int	bug=0, ind ;
38
FILE 	*fopen(), *freopen(), *fi, *ft, *fo, *fr ;
39
static 	int i, comment=0;
40
char  	*cp, *st, refd[20], part[20] ;
41
char	ln[80] ;
42
 
43
extern char 	*strsave(), *malloc();
44
extern int	yyleng, lexval ;
45
extern char	yytext[];
46
extern char	yysbuf[];
47
 
48
typedef struct YYS_TYPE { /* use instead of %union below */
49
    int i;
50
    char s[50];
51
    } yys_type ;
52
#define YYSTYPE     yys_type
53
 
54
 
55
# define YYLMAX 132
56
 
57
int	yylineno =0;
58
int	yyleng ;
59
char	yytext[YYLMAX];
60
char	yysbuf[YYLMAX];
61
char 	modnam[YYLMAX];
62
int 	yysptr = -1, yylast, toklast;
63
FILE	*yyout;
64
#define YYNL 10
65
 
66
 
67
%}
68
 
69
/* HP-UX yacc seems to be fussy about :
70
%union {
71
    int i;
72
    char s[50];
73
    }
74
 */
75
 
76
%token NL NAME NUMBER MODULE ENDMODULE WIRE INPUT OUTPUT INOUT
77
%token NETTYPE ASSIGN STRENGTH0 STRENGTH1 GATETYPE INITIAL
78
%token PARAMETER REG TIME INTEGER REAL EVENT DEFPARAM
79
%token BIN_OP UNARY_OP PRIMITIVE ENDPRIM TABLE ENDTABLE
80
%token OUT_SYM LEV_SYM EDGE_SYM
81
 
82
%left BIN_OP
83
 
84
%start modules
85
 
86
%%
87
modules 	: modules mod_prim
88
		| modules         error
89
		|      	  mod_prim
90
		;
91
 
92
mod_prim	: module
93
		| primitive
94
		;
95
 
96
primitive	: PRIMITIVE NAME '(' list_of_vars ')' ';' prim_body ENDPRIM
97
		;
98
 
99
list_of_vars	: list_of_vars ',' NAME
100
		| NAME
101
		;
102
 
103
prim_body	: UDP_decl UDP_init table_def
104
		| UDP_decl          table_def
105
		;
106
 
107
UDP_decl	: output_decl
108
		| input_decl
109
		| reg_decl
110
		;
111
 
112
UDP_init	: INITIAL NAME '=' init_val
113
		;
114
 
115
init_val	: '1' '\'' 'b' '0'
116
		| '1' '\'' 'b' '1'
117
		| '1' '\'' 'b' 'x'
118
		| '1'
119
		| '0'
120
		;
121
 
122
table_def	: TABLE table_entries ENDTABLE
123
		;
124
 
125
table_entries	: table_entries combin_entry
126
		|               combin_entry
127
		| table_entries seq_entry
128
		|               seq_entry
129
		;
130
 
131
combin_entry	: level_in_list ':' OUT_SYM ';'
132
		;
133
 
134
seq_entry	: level_in_list ':' state ':' next_state ';'
135
		|  edge_in_list ':' state ':' next_state ';'
136
		;
137
 
138
level_in_list 	: LEV_SYM
139
		;
140
 
141
edge_in_list	: LEV_SYM edge LEV_SYM
142
		|         edge
143
		;
144
 
145
edge		: '(' LEV_SYM LEV_SYM ')'
146
		| EDGE_SYM
147
		;
148
 
149
state		: LEV_SYM
150
		;
151
next_state	: OUT_SYM
152
		;
153
 
154
module		: MODULE NAME ';' mod_body ENDMODULE 
155
      	 	| MODULE NAME '('list_of_ports')' ';' mod_body ENDMODULE 
156
		;
157
 
158
list_of_ports	: list_of_ports ',' port
159
		| port
160
		;
161
 
162
port		: NAME
163
		| NAME '[' const_exp ']'
164
		| NAME '[' const_exp ':' const_exp ']'
165
		;
166
 
167
mod_body	: mod_body module_item 
168
		|          module_item 
169
		;
170
 
171
module_item	: param_decl
172
		| input_decl
173
		| output_decl
174
		| inout_decl
175
		| net_decl
176
		| reg_decl
177
		| time_decl
178
		| integer_decl
179
		| real_decl
180
		| event_decl
181
		| gate_decl
182
		| module_instant
183
		| defparm_decl
184
		| cont_assign
185
		;
186
 
187
param_decl	: PARAMETER
188
		;
189
reg_decl	: REG
190
		;
191
time_decl	: TIME
192
		;
193
integer_decl	: INTEGER
194
		;
195
real_decl	: REAL
196
		;
197
event_decl	: EVENT
198
		;
199
defparm_decl	: DEFPARAM
200
		;
201
gate_decl	: GATETYPE                   gate_instant
202
		| GATETYPE dr_strength       gate_instant
203
		| GATETYPE             delay gate_instant
204
		| GATETYPE dr_strength delay gate_instant
205
		;
206
 
207
gate_instant	: NAME '(' exp ')'
208
		;
209
 
210
input_decl	: INPUT       list_vars ';'
211
		| INPUT range list_vars ';'
212
		;
213
 
214
output_decl	: OUTPUT       list_vars ';'
215
		| OUTPUT range list_vars ';'
216
		;
217
 
218
inout_decl	: INOUT       list_vars ';'
219
		| INOUT range list_vars ';'
220
		;
221
 
222
net_decl	: NETTYPE             list_vars ';'
223
		| NETTYPE range       list_vars ';'
224
		| NETTYPE       delay list_vars ';'
225
		| NETTYPE range delay list_vars ';'
226
		;
227
 
228
range		: '[' const_exp ':' const_exp ']' 
229
		;
230
 
231
delay		: '#' number
232
		| '#' NAME
233
		;
234
 
235
dr_strength	: '(' STRENGTH0 ',' STRENGTH1 ')'
236
		| '(' STRENGTH1 ',' STRENGTH0 ')'
237
		;
238
 
239
list_vars	: list_vars ',' NAME
240
		|               NAME
241
		;
242
 
243
module_instant	: name_mod         mod_inst_list ';' 
244
              	| name_mod par_val mod_inst_list ';' 
245
		;
246
 
247
name_mod	: NAME
248
		{ strcpy( part, yytext); }
249
		;
250
 
251
mod_inst_list	: mod_inst_list ',' mod_inst
252
		|                   mod_inst
253
		;
254
 
255
mod_inst	: reference '(' list_mod_conn ')'
256
        	| reference '(' list_nam_conn ')'
257
		;
258
 
259
reference	: NAME
260
		{ strcpy( refd, yytext); }
261
		;
262
 
263
list_mod_conn	: list_mod_conn ',' exp
264
		|                   exp
265
		;
266
 
267
list_nam_conn	: list_nam_conn ',' nam_conn
268
		|                   nam_conn
269
		;
270
 
271
nam_conn	: '.' NAME '(' sig_nam ')'
272
		{
273
		    fprintf(fo,"%-18s %-22s %-10s %10s %s\n",
274
			 $4.s, refd, $2.s, part, modnam);
275
		}
276
		;
277
 
278
sig_nam		: NAME
279
		| NAME '[' exp ']'
280
		{ strcpy($$.s, $1.s);
281
		  strcat($$.s, "[");
282
		  strcat($$.s, $3.s);
283
		  strcat($$.s, "]");
284
		}
285
		| NAME '[' exp ':' exp ']'
286
		{ strcpy($$.s, $1.s);
287
		  strcat($$.s, "[");
288
		  strcat($$.s, $3.s);
289
		  strcat($$.s, ":");
290
		  strcat($$.s, $5.s);
291
		  strcat($$.s, "]");
292
		}
293
		| concatenation
294
		{ strcpy($$.s, "concatenation");}
295
		;
296
 
297
par_val		: '#' '(' exp ')' 
298
		;
299
 
300
cont_assign	: ASSIGN                   list_assigns ';'
301
		| ASSIGN dr_strength       list_assigns ';'
302
		| ASSIGN             delay list_assigns ';'
303
		| ASSIGN dr_strength delay list_assigns ';'
304
		;
305
 
306
list_assigns	: list_assigns ',' assignment
307
		|                  assignment
308
		;
309
 
310
assignment	: lvalue '='     exp
311
		| lvalue '=' '(' exp ')'
312
		;
313
 
314
lvalue		: NAME
315
		| NAME '[' exp ']'
316
		| concatenation
317
		;
318
 
319
const_exp	: exp
320
		;
321
 
322
concatenation	: '{' exp_list '}'
323
		;
324
 
325
exp_list	: exp_list ',' exp
326
		|              exp
327
		;
328
 
329
exp		: primary
330
		| UNARY_OP primary
331
		| UNARY_OP '(' exp ')'
332
		| exp BIN_OP exp
333
		;
334
 
335
primary		: number
336
		| NAME '[' exp ']'
337
		| NAME
338
		| concatenation
339
		;
340
 
341
number		: NUMBER
342
		| NUMBER '\'' 'b' NUMBER
343
		| NUMBER '\'' 'd' NUMBER
344
		| NUMBER '\'' 'o' NUMBER
345
		;
346
 
347
%%	/* start of main */
348
 
349
main(argc,argv)
350
int	argc;
351
char	*argv[];
352
{
353
    int	i,p;
354
    char frnam[60], fsnam[60];
355
    yyout =stderr;
356
 
357
 
358
    if(argc == 1) {
359
	fprintf(stderr,"use:hdl [-ds] file\n"); exit(1);
360
    }
361
    for(i=1; i<argc; i++)
362
    	if(argv[i][0] == '-'){
363
		bug     = ((argv[i][1] == 'd') || (argv[i][2] == 'd'));
364
	}
365
	else break;
366
 
367
 
368
    if(freopen( argv[i],"r",stdin) == NULL){
369
	fprintf(stderr,"can't open %s\n", argv[i]);exit(1);
370
    }	else {
371
	/* open output */
372
	for( cp=argv[i], st=fsnam ; *cp && *cp != '.' ; )*st++ = *cp++;
373
	*st = 0;
374
	strcpy( frnam, fsnam );	
375
	strcat( frnam, ".nam");	strcat( fsnam, ".seq");
376
 
377
	if((fo = fopen(fsnam, "w")) == NULL) err("can't open %s",fsnam);
378
 
379
	fprintf(stderr,"reading nets from %s\n", argv[i]);
380
    }
381
 
382
    yyparse() ;
383
 
384
    fclose(fo);
385
 
386
    fprintf(stderr,"sorting...\n");
387
    sprintf(ln, "sort <%s >%s", fsnam, frnam);	system(ln);
388
}
389
 
390
 
391
int 
392
yylex() /* Gets the next token from the input stream */
393
{
394
	int  c, i, j ;
395
	static int eline ; 
396
	extern int bug;
397
 
398
start:
399
	if(yysptr == -1){
400
		i = 0;	eline =1; yylineno++;
401
		/* get line to yysbuf */
402
		while( ((c=getchar()) != EOF) && (c != YYNL)){
403
			if(c == '\t'){ c=' ';do yysbuf[i++] = c; while(i & 7);}
404
			else	{
405
				if (c != ' ')eline =0;	
406
				yysbuf[i++] = c;
407
			}
408
		}
409
		yysptr = 0;
410
		yysbuf[i] = '\0';
411
		yylast = toklast = 0;
412
	}
413
	if(c == EOF) 
414
	    return(EOF);
415
 
416
	while( (c = yysbuf[yysptr]) == ' ') yysptr++;
417
 
418
	if(bug){
419
		fprintf(yyout,"%03d:%s\n",yylineno,yysbuf);
420
		for( i=yysptr ; i>0 ; i-- )out(' ');
421
	}
422
 
423
	 if ( c == YYNL || c== 0 ){ 
424
		yysptr= -1;
425
		if(bug)fprintf(yyout,"\n");
426
		goto start;
427
	 } 
428
 
429
	 if( comment ){
430
		while( (c = yysbuf[yysptr++]) != '*' && c != '/'&& c );
431
		if( c == '*' && yysbuf[yysptr]=='/' )
432
		    comment-- ;
433
	        if( c == '/' && yysbuf[yysptr]=='*' )
434
		    comment++ ;
435
		if( c ==  0  )
436
		    yysptr = -1;
437
		if( comment )
438
		    goto start;
439
		yysptr++;
440
		    goto start;
441
	 }
442
 
443
	 if( c == '/' ) { /* comment // ? */
444
	     if( yysbuf[yysptr+1] == '/') {
445
	     	yysptr= -1;
446
	     	goto start;
447
	     }
448
	     if( yysbuf[yysptr+1] == '*') {
449
		comment++; yysptr +=2;
450
		goto start;
451
	     }
452
	 }
453
	 if( c == '\\'){ /* escaped name */
454
 		yyleng=0;
455
	        while( (c=yysbuf[++yysptr]) != ' ' ) 
456
	                yytext[yyleng++] = c;
457
		yytext[yyleng] = '\0'; 
458
	        if(bug)fprintf(yyout,"    ^tok:NAME\n");
459
		if( toklast==MODULE ){
460
		    toklast = 0;
461
		    strcpy(modnam, yytext);
462
		    fprintf(stderr,"module %s\n", modnam);
463
		}
464
		if( toklast==PRIMITIVE ){
465
		    toklast = 0;
466
		    strcpy(modnam, yytext);
467
		    fprintf(stderr,"primitive %s\n", modnam);
468
		}
469
		strcpy(yylval.s, yytext);
470
		return(NAME);
471
	 }
472
	 if( isalpha(c) ) {
473
		if( yylast == '\'' ){ /* number base - 1'b0 */
474
		    yysptr++;
475
	 	    if(bug)
476
         	       if(c < ' ')   fprintf(yyout,"    ^CHAR:%d\n",c);
477
			      else   fprintf(yyout,"    ^CHAR:%c\n",c);
478
	            yylast = c;
479
	            return(c);
480
		}
481
		if( (j=chktok()) != 0){
482
		    toklast = j; 
483
		    return(j);
484
		}
485
        name:
486
 		yyleng=0;
487
	        while( isalpha(c) || isdigit(c) || c=='_' ) {
488
	                yytext[yyleng++] = c; c = yysbuf[++yysptr];
489
       		}
490
		yytext[yyleng] = '\0'; 
491
	        if(bug)fprintf(yyout,"    ^tok:NAME\n");
492
		if( toklast==MODULE ){
493
		    toklast = 0;
494
		    strcpy(modnam, yytext);
495
		    fprintf(stderr,"module %s\n", modnam);
496
		}
497
		if( toklast==PRIMITIVE ){
498
		    toklast = 0;
499
		    strcpy(modnam, yytext);
500
		    fprintf(stderr,"primitive %s\n", modnam);
501
		}
502
		strcpy(yylval.s, yytext);
503
		return(NAME);
504
	 } 
505
	 if( isdigit(c) ) {
506
 		yyleng=0;
507
	        while( isdigit(c) ) {
508
	                yytext[yyleng++] = c; c = yysbuf[++yysptr];
509
       		}
510
		yytext[yyleng] = '\0'; 
511
	        if(bug)fprintf(yyout,"    ^tok:NUMBER\n");
512
		strcpy(yylval.s, yytext);
513
		return(NUMBER);
514
	 }
515
	 yysptr++; yylast = c;
516
	 if( c=='+' || c=='-' || c=='&' || c=='|' || c=='^' ){
517
	     if(bug) fprintf(yyout,"    ^BIN_OP:%c\n",c);
518
	     return(BIN_OP);
519
	 }
520
	 if( c=='!' || c=='~' ){
521
	     if(bug) fprintf(yyout,"    ^UNARY_OP:%c\n",c);
522
	     return(UNARY_OP);
523
	 }
524
	 if(bug)
525
	     if(c < ' ')
526
		fprintf(yyout,"    ^CHAR:%d\n",c);
527
	     else
528
		fprintf(yyout,"    ^CHAR:%c\n",c);
529
	 return(c);
530
} /* nexttoken */
531
 
532
int chktok()
533
{
534
    static struct { char *keyword; int val, tok; } key [] = {
535
	"module " ,   0, MODULE,
536
	"endmodule" , 0, ENDMODULE, 
537
	"primitive ", 0, PRIMITIVE,
538
	"endprimitive",0,ENDPRIM,
539
	"input "    , 0, INPUT,
540
	"output "   , 0, OUTPUT,
541
	"inout "    , 0, INOUT,
542
	"assign "   , 0, ASSIGN,
543
	"wire "     , 0, NETTYPE,
544
	"triand "   , 1, NETTYPE,
545
	"trior "    , 2, NETTYPE,
546
	"tri1 "     , 3, NETTYPE,
547
	"tri "      , 4, NETTYPE,
548
	"supply0 "  , 5, NETTYPE,
549
	"supply1 "  , 6, NETTYPE,
550
	"wor "      , 7, NETTYPE,
551
	"trireg "   , 8, NETTYPE,
552
	"supply0 "  , 0, STRENGTH0,
553
	"strong0 "  , 1, STRENGTH0,
554
	"pull0 "    , 2, STRENGTH0,
555
	"weak0 "    , 3, STRENGTH0,
556
	"highz0 "   , 4, STRENGTH0,
557
	"supply1 "  , 0, STRENGTH1,
558
	"strong1 "  , 1, STRENGTH1,
559
	"pull1 "    , 2, STRENGTH1,
560
	"weak1 "    , 3, STRENGTH1,
561
	"highz1 "   , 4, STRENGTH1,
562
	"parameter ", 0, PARAMETER,
563
	"reg "	    , 0, REG,
564
	"time "	    , 0, TIME,
565
	"integer "  , 0, INTEGER,
566
	"real "     , 0, REAL,
567
	"event "    , 0, EVENT,
568
	"defparam " , 0, DEFPARAM,
569
	"and "	    , 0, GATETYPE,
570
	"nand "     , 1, GATETYPE,
571
	"or " 	    , 2, GATETYPE,
572
	"nor "      , 3, GATETYPE,
573
	"xor "	    , 4, GATETYPE,
574
	"xnor "     , 5, GATETYPE,
575
	"buf "	    , 6, GATETYPE,
576
	"tran "     , 7, GATETYPE,
577
	"table "    , 0, TABLE,
578
	"endtable"  , 0, ENDTABLE,
579
	"initial "  , 0, INITIAL,
580
	NULL, 0, 0
581
	};
582
    int	save, i, j ;
583
    char	*s; 
584
 
585
    for( j=0 ; (s=key[j].keyword) != NULL ; j++) {
586
	save = yysptr; yyleng = 0;
587
	while( *s == yysbuf[yysptr++] && *s )
588
	    yytext[yyleng++] = *s++;
589
	if(*s == '\0'){
590
	    yytext[yyleng] = '\0';
591
	    yysptr--;
592
	    if(bug){
593
		for( i=yysptr-1 ; i>0 ; i-- )out(' ');
594
		fprintf(yyout,"    ^tok:%s\n",yytext);
595
	    }
596
	    yylval.i = key[j].val;
597
	    return(key[j].tok);
598
        }
599
        yysptr = save;
600
    }
601
    return(0);
602
}
603
 
604
yyerror(s)
605
char	*s;
606
{
607
    int  i;
608
 
609
    fprintf(stderr,"%s error on line %d\n",s,yylineno);
610
    fprintf(stderr,"%s\n", yysbuf);
611
    for( i=yysptr ; i>0 ; i-- )out(' ');
612
    fprintf(stderr,"^\n");
613
}
614
 
615
char *strsave(s)
616
char *s;
617
{
618
    char *p, *malloc();
619
 
620
    if((p = malloc(strlen(s)+1)) != NULL) strcpy(p,s);
621
    if( p==NULL)err("out of malloc space");
622
    return(p);
623
}
624
 
625
err(s,t)
626
char *s,*t;
627
{
628
    fprintf(stderr,s,t); fprintf(stderr,"\n");
629
    exit(1);
630
}