1 /****************************************************************************
2 Copyright (C) 1987-2015 by Jeffery P. Hansen
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 ****************************************************************************/
18 #include "thyme.h"
19
20 /*****************************************************************************
21 *
22 * Create a new declaration scope object
23 *
24 * Parameter:
25 * s Scope object to be initialized
26 * parent Parent scope
27 *
28 *****************************************************************************/
ScopeDecl_init(ScopeDecl * s,ScopeDecl * parent)29 void ScopeDecl_init(ScopeDecl *s,ScopeDecl *parent)
30 {
31 s->sd_parent = parent;
32 SHash_init(&s->sd_nets);
33 }
34
35 /*****************************************************************************
36 *
37 * Uninitialize a declaration scope object
38 *
39 * Parameter:
40 * s Scope object to be uninitialized
41 *
42 *****************************************************************************/
ScopeDecl_uninit(ScopeDecl * s)43 void ScopeDecl_uninit(ScopeDecl *s)
44 {
45 SHash_uninit(&s->sd_nets);
46 }
47
48
new_Scope(const char * path,Scope * parent,ModuleInst * mi)49 Scope *new_Scope(const char *path,Scope *parent,ModuleInst *mi)
50 {
51 Scope *s = (Scope*) malloc(sizeof(Scope));
52
53 Scope_init(s,path,parent,mi);
54
55 return s;
56 }
57
delete_Scope(Scope * s)58 void delete_Scope(Scope *s)
59 {
60 Scope_uninit(s);
61 free(s);
62 }
63
Scope_init(Scope * s,const char * path,Scope * parent,ModuleInst * mi)64 void Scope_init(Scope *s,const char *path,Scope *parent,ModuleInst *mi)
65 {
66 s->s_path = path ? strdup(path) : 0;
67 s->s_parent = parent;
68 s->s_instance = mi;
69 s->s_peer = 0;
70 SHash_init(&s->s_nets);
71 SHash_init(&s->s_tasks);
72 }
73
Scope_uninit(Scope * s)74 void Scope_uninit(Scope *s)
75 {
76 if (s->s_path) free(s->s_path);
77 SHash_uninit(&s->s_nets);
78 SHash_uninit(&s->s_tasks);
79 }
80
Scope_setPeer(Scope * s,Scope * peer)81 void Scope_setPeer(Scope *s,Scope *peer)
82 {
83 s->s_peer = peer;
84 }
85
Scope_findNet(Scope * s,const char * name,unsigned flags)86 Net *Scope_findNet(Scope *s,const char *name,unsigned flags)
87 {
88 Circuit *c = &vgsim.vg_circuit; /* Top-level circuit */
89 Net *n = 0;
90
91 /*
92 * If scope is null, look only for fully qualified names.
93 */
94 if (!s)
95 return Circuit_findNet(c,name);
96
97 /*
98 * Look for 'name' in local name table.
99 */
100 n = (Net*) SHash_find(&s->s_nets,name);
101 if (n) return n;
102
103 /*
104 * Look for 'name' in parent scope
105 */
106 if (s->s_parent && !(flags & SDF_LOCAL_ONLY))
107 n = Scope_findNet(s->s_parent,name,flags);
108 if (n) return n;
109
110 /*
111 * Look for 'name' in peer module.
112 */
113 if (s->s_peer)
114 return Scope_findNet(s->s_peer,name,flags);
115
116 /*
117 * Look for 'name' as a fully qualified net name.
118 */
119 n = Circuit_findNet(c,name);
120 if (n) return n;
121
122 if (strchr(name,'.')) {
123 char *tempName = (char*)malloc(strlen(s->s_path)+strlen(name)+2);
124 sprintf(tempName,"%s.%s",s->s_path,name);
125 n = Circuit_findNet(c,tempName);
126 free(tempName);
127 }
128
129 return n;
130 }
131
Scope_defNet(Scope * s,const char * name,Net * n)132 void Scope_defNet(Scope *s,const char *name,Net *n)
133 {
134 Circuit *c = &vgsim.vg_circuit; /* Top-level circuit */
135
136 SHash_insert(&s->s_nets,name,n);
137 SHash_insert(&c->c_nets,n->n_name,n);
138 }
139
Scope_replaceLocalNet(Scope * s,const char * name,Net * n)140 void Scope_replaceLocalNet(Scope *s,const char *name,Net *n)
141 {
142 SHash_replace(&s->s_nets,name,n);
143 }
144
145
Scope_findTask(Scope * s,const char * name)146 UserTask *Scope_findTask(Scope *s,const char *name)
147 {
148 return (UserTask*)SHash_find(&s->s_tasks,name);
149 }
150
Scope_defineTask(Scope * s,const char * name,UserTask * ut)151 int Scope_defineTask(Scope *s,const char *name,UserTask *ut)
152 {
153 if (Scope_findTask(s,name)) return -1;
154
155 SHash_insert(&s->s_tasks,name,ut);
156
157 return 0;
158 }
159
Scope_findParm(Scope * scope,const char * name)160 Value *Scope_findParm(Scope *scope,const char *name)
161 {
162 Net *n = (Net*) Scope_findNet(scope,name,SDF_LOCAL_ONLY);
163 if (!n) return 0;
164 if (!(Net_getType(n) & NT_P_PARAMETER)) return 0;
165
166 return Net_getValue(n);
167 }
168
169 /*****************************************************************************
170 *
171 * Find a net in a declaration scope object
172 *
173 * Parameter:
174 * s Scope object to be uninitialized
175 * name Name of net to look for
176 * flags Flags modifying net lookup
177 *
178 *****************************************************************************/
ScopeDecl_findNet(ScopeDecl * s,const char * name,unsigned flags)179 NetDecl *ScopeDecl_findNet(ScopeDecl *s,const char *name,unsigned flags)
180 {
181 NetDecl *n;
182
183 n = (NetDecl*) SHash_find(&s->sd_nets,name);
184 if (!n && s->sd_parent && !(flags & SDF_LOCAL_ONLY))
185 n = ScopeDecl_findNet(s->sd_parent,name,flags);
186
187 return n;
188 }
189
190 /*****************************************************************************
191 *
192 * Define a new net in a declaration scope
193 *
194 * Parameter:
195 * s Scope object to be uninitialized
196 * n Net declaration object to add
197 *
198 *****************************************************************************/
ScopeDecl_defNet(ScopeDecl * s,NetDecl * n)199 void ScopeDecl_defNet(ScopeDecl *s,NetDecl*n)
200 {
201 SHash_insert(&s->sd_nets,n->n_name,n);
202 }
203
204 /*****************************************************************************
205 *
206 * Create a new module declaration object
207 *
208 * Parameter:
209 * name Name of the module
210 *
211 * Returns: Newly create module object.
212 *
213 *****************************************************************************/
new_ModuleDecl(const char * name)214 ModuleDecl *new_ModuleDecl(const char *name)
215 {
216 ModuleDecl *m = (ModuleDecl*) malloc(sizeof(ModuleDecl));
217
218 m->m_name = name ? strdup(name) : 0;
219 m->m_errorsDone = 0;
220 m->m_specify = 0;
221 List_init(&m->m_ports);
222 List_init(&m->m_parmPorts);
223 List_init(&m->m_items);
224 ScopeDecl_init(&m->m_scope,0);
225 SHash_init(&m->m_tasks);
226 m->m_faninnodes = 0;
227
228 m->m_timescale = currentTimescale;
229
230 return m;
231 }
232
233 /*****************************************************************************
234 *
235 * Delete a module declaration object and reclaim all memory.
236 *
237 * Parameter:
238 * m Module declaration to be destroyed.
239 *
240 *****************************************************************************/
delete_ModuleDecl(ModuleDecl * m)241 void delete_ModuleDecl(ModuleDecl *m)
242 {
243 free(m->m_name);
244 List_uninit(&m->m_ports);
245 List_uninit(&m->m_parmPorts);
246 ScopeDecl_uninit(&m->m_scope);
247 SHash_uninit(&m->m_tasks);
248 if (m->m_specify) delete_Specify(m->m_specify);
249 free(m);
250 }
251
252 /*****************************************************************************
253 *
254 * Add a port to a module declaration
255 *
256 * Parameter:
257 * m Module declaration to which to add port
258 * name Name of port to add
259 *
260 *****************************************************************************/
ModuleDecl_addPort(ModuleDecl * m,const char * name)261 void ModuleDecl_addPort(ModuleDecl *m,const char *name)
262 {
263 List_addToTail(&m->m_ports,strdup(name));
264 }
265
266 /*****************************************************************************
267 *
268 * Define a 'parameter' in a module
269 *
270 * Parameter:
271 * m Module in which to define parameter
272 * name Name of the parameter
273 * e Expression for the parameter
274 * isPort Non-zero if this is a parameter port.
275 *
276 *****************************************************************************/
ModuleDecl_defineParm(ModuleDecl * m,const char * name,Expr * e,int isPort)277 void ModuleDecl_defineParm(ModuleDecl *m,const char *name,Expr *e, int isPort)
278 {
279 MIParameter *mip = new_MIParameter(name,e);
280
281 List_addToTail(&m->m_items, mip);
282
283 if (isPort) {
284 mip->mip_ppPos = List_numElems(&m->m_parmPorts);
285 List_addToTail(&m->m_parmPorts,strdup(name));
286 }
287 }
288
ModuleDecl_isParm(ModuleDecl * m,const char * name)289 int ModuleDecl_isParm(ModuleDecl *m,const char *name)
290 {
291 ListElem *le;
292
293 for (le = List_first(&m->m_parmPorts);le;le = List_next(&m->m_parmPorts,le)) {
294 const char *portName = (const char*)ListElem_obj(le);
295 if (strcmp(name,portName) == 0) return 1;
296 }
297 return 0;
298 }
299
300 /*****************************************************************************
301 *
302 * Print basic information about a module definition.
303 *
304 * Parameters:
305 * m Module to display.
306 *
307 *****************************************************************************/
ModuleDecl_printData(ModuleDecl * m)308 void ModuleDecl_printData(ModuleDecl *m)
309 {
310 ListElem *le;
311
312 printf("module %s\n",ModuleDecl_getName(m));
313 printf(" line %d\n",m->m_place.p_lineNo);
314
315 for (le = List_first(&m->m_items);le;le = List_next(&m->m_items,le)) {
316 ModuleItem *mi = (ModuleItem*) ListElem_obj(le);
317
318 switch (mi->mi_type) {
319 case IC_PARAMETER :
320 {
321 MIParameter *mip = (MIParameter*) mi;
322 ListElem *le2;
323 for (le2 = List_first(&m->m_parmPorts);le2;le2 = List_next(&m->m_parmPorts,le2)) {
324 char *parmPort = (char*) ListElem_obj(le2);
325 if (strcmp(parmPort,mip->mip_name) == 0) break;
326 }
327 /* If parameter is parmport ... */
328 if (le2) {
329 Value *v = Expr_parmEval(mip->mip_expr,0,PEF_NONE);
330 if (v) {
331 char buf[STRMAX];
332 Value_getstr(v,buf);
333 printf(" parmport %s %s\n",mip->mip_name,buf);
334 } else
335 printf(" parmport %s 0\n",mip->mip_name);
336 }
337
338
339 }
340 break;
341 case IC_NETDECL :
342 {
343 NetDecl *nd = mi->mi_netdec.mid_decl;
344 int rangeok = 1;
345 char typeName[STRMAX],rangeExpr[STRMAX];
346 VRange *range;
347
348 if ((NetDecl_getType(nd) & NT_P_IO_MASK)) {
349 NT_getStr((NetDecl_getType(nd) & NT_P_IO_MASK)|NT_P_WIRE, typeName);
350 } else if ((NetDecl_getType(nd) & NT_P_WIRE)) {
351 strcpy(typeName,"wire");
352 } else if ((NetDecl_getType(nd) & NT_P_REG)) {
353 strcpy(typeName,"reg");
354 } else
355 break; /* ignore this type */
356
357 range = NetDecl_getRange(nd);
358 if (VRange_getDirect(range,rangeExpr) < 0)
359 rangeok = 0;
360
361 printf(" %s %s %s\n",typeName, NetDecl_getName(nd),rangeExpr);
362 if (!rangeok) {
363 errorFile(ModuleItem_getPlace(mi),ERR_BADPRTRANGE,NetDecl_getName(nd));
364 }
365 }
366 break;
367 case IC_INSTANCE :
368 printf(" instance %s %s\n",mi->mi_inst.mii_name, mi->mi_inst.mii_instName);
369 break;
370 default :
371 break;
372 }
373 }
374
375 printf("endmodule %s\n",ModuleDecl_getName(m));
376 }
377
378 /*****************************************************************************
379 *
380 * Print a module declaration (for debugging purposes)
381 *
382 * Parameters:
383 * m Module declaration to print
384 * f File in which to print declaration
385 *
386 *****************************************************************************/
ModuleDecl_print(ModuleDecl * m,FILE * f)387 void ModuleDecl_print(ModuleDecl *m,FILE *f)
388 {
389 fprintf(f,"module %s",m->m_name);
390
391 /*
392 * Display the parameter ports
393 */
394 if (List_numElems(&m->m_parmPorts) > 0) {
395 ListElem *E;
396 int notFirst = 0;
397
398 fprintf(f," #(");
399 for (E = List_first(&m->m_parmPorts);E;E = List_next(&m->m_parmPorts,E)) {
400 const char *name = (const char*) ListElem_obj(E);
401 if (notFirst) fprintf(f,", ");
402 notFirst = 1;
403 fprintf(f,"%s",name);
404 }
405 fprintf(f,")");
406 }
407
408 /*
409 * Display the ports
410 */
411 if (List_numElems(&m->m_ports) > 0) {
412 ListElem *E;
413 int notFirst = 0;
414
415 fprintf(f," (");
416 for (E = List_first(&m->m_ports);E;E = List_next(&m->m_ports,E)) {
417 const char *name = (const char*) ListElem_obj(E);
418 if (notFirst) fprintf(f,", ");
419 notFirst = 1;
420 fprintf(f,"%s",name);
421 }
422 fprintf(f,")");
423 }
424 fprintf(f,";\n");
425
426
427 /*
428 * Display the items.
429 */
430 if (List_numElems(&m->m_items) > 0) {
431 ListElem *E;
432
433 for (E = List_first(&m->m_items);E;E = List_next(&m->m_items,E)) {
434 ModuleItem *mi = (ModuleItem*) ListElem_obj(E);
435
436 if (mi->mi_type != IC_NETDECL && mi->mi_type != IC_PARAMETER)
437 fprintf(f,"\n");
438
439 ModuleItem_print(mi,f);
440 }
441 }
442
443 fprintf(f,"\n");
444 fprintf(f,"endmodule\n");
445 }
446
ModuleDecl_findNet(ModuleDecl * m,const char * name)447 NetDecl *ModuleDecl_findNet(ModuleDecl *m,const char *name)
448 {
449 return ScopeDecl_findNet(&m->m_scope,name,0);
450 }
451
452 /*****************************************************************************
453 *
454 * Add a net declaration to a module.
455 *
456 * Parameters:
457 * m Module declaration object
458 * n Net declaration object
459 *
460 *****************************************************************************/
ModuleDecl_defNet(ModuleDecl * m,NetDecl * n)461 void ModuleDecl_defNet(ModuleDecl *m,NetDecl*n)
462 {
463 ScopeDecl_defNet(&m->m_scope,n);
464 List_addToTail(&m->m_items, new_MINetDecl(n));
465 }
466
467 /*****************************************************************************
468 *
469 * Create the specify data object for a module if not already created.
470 *
471 * Parameters:
472 * m Module declaration object
473 *
474 *****************************************************************************/
ModuleDecl_makeSpecify(ModuleDecl * m)475 void ModuleDecl_makeSpecify(ModuleDecl *m)
476 {
477 if (!m->m_specify)
478 m->m_specify = new_Specify(m);
479 }
480
ModuleDecl_numPorts(ModuleDecl * m,nettype_t ptype)481 int ModuleDecl_numPorts(ModuleDecl *m,nettype_t ptype)
482 {
483 ListElem *le;
484 int n = 0;
485
486 ptype &= NT_P_IO_MASK;
487
488 for (le = List_first(&m->m_ports);le;le = List_next(&m->m_ports,le)) {
489 char *name = (char*)ListElem_obj(le);
490 NetDecl *nd = (NetDecl*)ModuleDecl_findNet(m,name);
491 if (nd && ((NetDecl_getType(nd) & NT_P_IO_MASK) == ptype))
492 n++;
493 }
494
495 return n;
496 }
497
ModuleDecl_findTask(ModuleDecl * m,const char * name)498 UserTaskDecl *ModuleDecl_findTask(ModuleDecl *m,const char *name)
499 {
500 return (UserTaskDecl*)SHash_find(&m->m_tasks,name);
501 }
502
ModuleDecl_defineTask(ModuleDecl * m,const char * name,UserTaskDecl * utd)503 int ModuleDecl_defineTask(ModuleDecl *m,const char *name,UserTaskDecl *utd)
504 {
505 if (ModuleDecl_findTask(m,name)) return -1;
506
507 SHash_insert(&m->m_tasks,name,utd);
508
509 return 0;
510 }
511
512 /*****************************************************************************
513 *
514 * Make an array of strings from the keys of the elements in a hash tabe
515 *
516 *****************************************************************************/
getHashKeys(SHash * H)517 static char **getHashKeys(SHash *H)
518 {
519 char **keys = (char **) malloc(sizeof(char*)*(Hash_numElems(H)+1));
520 HashElem *he;
521 int i = 0;
522
523 for (he = Hash_first(H);he;he = Hash_next(H,he)) {
524 const char *name = SHashElem_key(he);
525 keys[i++] = strdup(name);
526 }
527 keys[i] = 0;
528
529 return keys;
530 }
531
532 #if 0
533 static void printHList(SHash *H)
534 {
535 HashElem *he;
536 int is_first = 1;
537
538 for (he = Hash_first(H);he;he = Hash_next(H,he)) {
539 const char *name = SHashElem_key(he);
540 if (!is_first) printf(", ");
541 printf("%s",name);
542 is_first = 0;
543 }
544 }
545 #endif
546
547 /*****************************************************************************
548 *
549 * Sort the itemlist in a module to be in topological order (used for path-delay modules)
550 *
551 * Parameters:
552 * m Module to be sorted
553 *
554 *****************************************************************************/
ModuleDecl_makeFaninTree(ModuleDecl * m)555 int ModuleDecl_makeFaninTree(ModuleDecl *m)
556 {
557 ListElem *le;
558 int i;
559
560 #if 0
561 printf("ModuleDecl_makeFaninTree(%s)\n",m->m_name);
562 #endif
563 m->m_faninnodes = new_SHash();
564
565
566 for (le = List_first(&m->m_items);le; le = List_next(&m->m_items,le)) {
567 ModuleItem *item = (ModuleItem*) ListElem_obj(le);
568
569 switch (item->mi_type) {
570 default :
571 #if 0
572 printf(" mitem\n");
573 #endif
574 break;
575 case IC_ASSIGN :
576 {
577 MIAssign *a = (MIAssign*) item;
578 FaninNode *fn = new_FaninNode(item);
579 SHash outH,inH;
580
581 SHash_init(&outH);
582 SHash_init(&inH);
583
584 Expr_getStaticReaders(a->mia_lhs, &outH);
585 Expr_getStaticReaders(a->mia_rhs, &inH);
586
587 fn->fn_out = getHashKeys(&outH);
588 fn->fn_in = getHashKeys(&inH);
589
590 for (i = 0;fn->fn_out[i];i++) {
591 if (!SHash_find(m->m_faninnodes,fn->fn_out[i]))
592 SHash_insert(m->m_faninnodes,fn->fn_out[i],fn);
593 else
594 errorModule(m, ModuleItem_getPlace(fn->fn_item),ERR_PATHDREASSGN,fn->fn_out[i]);
595 }
596
597 #if 0
598 printf(" assign ");
599 printHList(&outH);
600 printf(" = ");
601 printHList(&inH);
602 printf("\n");
603 #endif
604
605
606 SHash_uninit(&inH);
607 SHash_uninit(&outH);
608 }
609 break;
610 case IC_GATE :
611 {
612 MIGate *g = (MIGate*) item;
613 FaninNode *fn = new_FaninNode(item);
614 SHash outH,inH;
615 ListElem *le;
616 int i;
617 int N = List_numElems(g->mig_ports);
618
619 SHash_init(&outH);
620 SHash_init(&inH);
621
622 for (i = 1, le = List_first(g->mig_ports);le;i++, le = List_next(g->mig_ports,le)) {
623 Expr *port = (Expr*)ListElem_obj(le);
624
625 if ((i == 1) || (g->mig_desc->gd_gac == GAC_MULTOUT && i != N))
626 Expr_getStaticReaders(port, &outH);
627 else
628 Expr_getStaticReaders(port, &inH);
629 }
630
631 fn->fn_out = getHashKeys(&outH);
632 fn->fn_in = getHashKeys(&inH);
633
634 for (i = 0;fn->fn_out[i];i++) {
635 if (!SHash_find(m->m_faninnodes,fn->fn_out[i]))
636 SHash_insert(m->m_faninnodes,fn->fn_out[i],fn);
637 else
638 errorModule(m, ModuleItem_getPlace(fn->fn_item),ERR_PATHDREASSGN,fn->fn_out[i]);
639 }
640
641 #if 0
642 printf(" gate ");
643 printHList(&outH);
644 printf(" = ");
645 printHList(&inH);
646 printf("\n");
647 #endif
648 SHash_uninit(&inH);
649 SHash_uninit(&outH);
650 }
651 break;
652 }
653 }
654
655 return 0;
656 }
657
ModuleDecl_clearFaninFlags(ModuleDecl * m)658 void ModuleDecl_clearFaninFlags(ModuleDecl *m)
659 {
660 HashElem *he;
661 int i;
662
663 for (he = Hash_first(m->m_faninnodes);he;he = Hash_next(m->m_faninnodes,he)) {
664 FaninNode *fn = (FaninNode *)HashElem_obj(he);
665 fn->fn_flag = 0;
666 if (fn->fn_outNets) {
667 for (i = 0;fn->fn_out[i];i++)
668 fn->fn_outNets[i] = 0;
669 }
670 if (fn->fn_inNets) {
671 for (i = 0;fn->fn_in[i];i++)
672 fn->fn_inNets[i] = 0;
673 }
674 }
675 }
676
ModuleInst_findTask(ModuleInst * mi,const char * name)677 UserTask *ModuleInst_findTask(ModuleInst *mi,const char *name)
678 {
679 return Scope_findTask(ModuleInst_getScope(mi),name);
680 }
681
ModuleInst_defineTask(ModuleInst * mi,const char * name,UserTask * ut)682 int ModuleInst_defineTask(ModuleInst *mi,const char *name,UserTask *ut)
683 {
684 return Scope_defineTask(ModuleInst_getScope(mi),name,ut);
685 }
686
687
688 /*****************************************************************************
689 *
690 * Create a new net declaration object
691 *
692 * Parameters:
693 * name Name of the net
694 * wtype Type of the net WIRE, REG, etc.
695 * range Bit-range of the net (uninstantiated)
696 * addrRange Address range if this is a memory (or null otherwise)
697 * place Place where net is declared
698 *
699 *****************************************************************************/
new_NetDecl(const char * name,int wtype,VRange * range,VRange * addrRange,Place * place)700 NetDecl *new_NetDecl(const char *name,int wtype,VRange *range,VRange *addrRange,Place *place)
701 {
702 NetDecl *n = (NetDecl *) malloc(sizeof(NetDecl));
703
704 n->n_name = strdup(name);
705 n->n_type = wtype;
706 n->n_range = range;
707 n->n_addrRange = addrRange;
708 if (place)
709 Place_copy(&n->n_place, place);
710 else
711 Place_init(&n->n_place, "");
712
713 return n;
714 }
715
new_ModuleInst(ModuleDecl * md,Circuit * c,ModuleInst * parent,const char * path)716 ModuleInst *new_ModuleInst(ModuleDecl *md,Circuit *c,ModuleInst *parent,const char *path)
717 {
718 ModuleInst *mc = (ModuleInst*) malloc(sizeof(ModuleInst));
719
720 ModuleInst_init(mc,md,c,parent,path);
721
722 return mc;
723 }
724
delete_ModuleInst(ModuleInst * mc)725 void delete_ModuleInst(ModuleInst *mc)
726 {
727 ModuleInst_uninit(mc);
728 free(mc);
729 }
730
ModuleInst_init(ModuleInst * mi,ModuleDecl * md,Circuit * c,ModuleInst * parent,const char * path)731 void ModuleInst_init(ModuleInst *mi,ModuleDecl *md,Circuit *c,ModuleInst *parent,const char *path)
732 {
733 mi->mc_path = strdup(path);
734 mi->mc_peer = 0;
735 mi->mc_mod = md;
736 mi->mc_circuit = c;
737 mi->mc_parent = parent;
738 List_init(&mi->mc_threads);
739 Scope_init(&mi->mc_scope,path,0,mi);
740 }
741
ModuleInst_uninit(ModuleInst * mc)742 void ModuleInst_uninit(ModuleInst *mc)
743 {
744 free(mc->mc_path);
745 Scope_uninit(&mc->mc_scope);
746 }
747
ModuleInst_findParm(ModuleInst * mc,const char * name)748 Value *ModuleInst_findParm(ModuleInst *mc,const char *name)
749 {
750 return Scope_findParm(&mc->mc_scope,name);
751 }
752
753
ModuleInst_defParm(ModuleInst * mc,const char * name,Value * value)754 void ModuleInst_defParm(ModuleInst *mc,const char *name,Value *value)
755 {
756 char fullName[2*STRMAX];
757 Net *n;
758
759 sprintf(fullName,"%s.%s",mc->mc_path,name);
760 n = new_Net(fullName,NT_PARAMETER,Value_nbits(value)-1,0);
761 Value_copy(Net_getValue(n),value);
762
763 Scope_defNet(ModuleInst_getScope(mc),name,n);
764 }
765
766
767 /*****************************************************************************
768 *
769 * Find a named net in the context of a module instance
770 *
771 * Parameters:
772 * mc Current module context
773 * name Name of net
774 *
775 * The following rules are used to lookup the net name:
776 *
777 * 1) Look for 'name' in the local net table.
778 * 2) If the module has a peer, look in the peer module. For modules with
779 * peers, this is the final search step.
780 * 3) Look for 'name' in the circuit net table for fully qualified names
781 * such as 'top.foo.n'.
782 * 4) Treat 'name' as a relative name such as 'foo.n'. This is done by
783 * prepending the path for the current module and searching again as
784 * a fully qualified path.
785 *
786 *****************************************************************************/
ModuleInst_findNet(ModuleInst * mc,const char * name)787 Net *ModuleInst_findNet(ModuleInst *mc,const char *name)
788 {
789 return Scope_findNet(ModuleInst_getScope(mc), name, 0);
790 }
791
792 /*****************************************************************************
793 *
794 * Define a net
795 *
796 * Parameters:
797 * mc Current module context
798 * name Local name of net
799 * n Net object with full path name
800 *
801 *****************************************************************************/
ModuleInst_defNet(ModuleInst * mc,const char * name,Net * n)802 void ModuleInst_defNet(ModuleInst *mc,const char *name,Net *n)
803 {
804 Scope_defNet(ModuleInst_getScope(mc), name, n);
805 }
806
807 /*****************************************************************************
808 *
809 * Lookup the local name of a net
810 *
811 * Parameters:
812 * mi Current module context
813 * n Net object
814 *
815 *****************************************************************************/
ModuleInst_findLocalNetName(ModuleInst * mi,Net * n)816 const char *ModuleInst_findLocalNetName(ModuleInst *mi,Net *n)
817 {
818 HashElem *he;
819 SHash *nets = &mi->mc_scope.s_nets;
820
821 for (he = Hash_first(nets);he;he = Hash_next(nets,he)) {
822 Net *mi_n = (Net *) HashElem_obj(he);
823 if (mi_n == n)
824 return SHashElem_key(he);
825 }
826 return 0;
827 }
828
new_FaninNode(ModuleItem * item)829 FaninNode *new_FaninNode(ModuleItem *item)
830 {
831 FaninNode *fn = (FaninNode*) malloc(sizeof(FaninNode));
832
833 fn->fn_item = item;
834 fn->fn_out = 0;
835 fn->fn_outNets = 0;
836 fn->fn_in = 0;
837 fn->fn_inNets = 0;
838 fn->fn_flag = 0;
839
840 return fn;
841 }
842
843