📄 create_supp.c
字号:
/* calcolo il numero di PI, PO e FF */ n_pi = n_po = 0; clock_descr = find_clock_descr(); reset_descr = find_reset_descr(); preset_descr = find_preset_descr(); if( VERBOSE ) { if( reset_descr != -1 ) if(!create_silent) printf( "(create_netlist) Circuit with RESET: %s\n", descr[reset_descr].name ); if( preset_descr != -1 ) if(!create_silent) printf( "(create_netlist) Circuit with PRESET: %s\n" , descr[preset_descr].name); } if( clock_descr == -1 ) if(!create_silent) printf( "(create_netlist) Clock not found: combinatorial network\n" ); /* controlla il fanin dei FF */ check_ff_fanin(); for( i = 0; i < n_descr; i++ ) { switch( descr[i].attr ) { case PI: n_pi++; break; case PO: n_po++; break; case INTERNAL: descr[i].ff_type = FFD; if( descr[i].type == FF ) { n_ff++; /* controlla che il fanin dei FF sia 2, 3, 4 */ if( descr[i].fanin < 2 || descr[i].fanin > 4 ) { printf( "(create_netlist) ERROR 1: %d, %s fanin FF lower than 2 or bigger than 4\n", i, descr[i].name ); exit( 1 ); } /* Mette a posto l'ordine di clk, dato: from[0] = dato from[1] = clock from[2] = reset o preset (se esiste) from[3] = preset (se esiste) p1 = descrittore clock p2 = descrittore reset p3 = descrittore preset p4 = descrittore dato */ p1 = p2 = p3 = p4 = -1; for( j = 0; j < descr[i].fanin; j++ ) { if( descr[i].from[j] == clock_descr ) p1 = clock_descr; else if( descr[i].from[j] == reset_descr ) p2 = reset_descr; else if( descr[i].from[j] == preset_descr ) p3 = preset_descr; else p4 = descr[i].from[j]; }/* printf( "FF %s, descr = %d, fanin = %d, p1 = %d, p2 = %d, p3 = %d, p4 = %d\n", descr[i].name, i, descr[i].fanin, p1, p2, p3, p4 );*/ /* fisso il campo from */ descr[i].from[0] = p4; /* printf( "(create_netlist) FF %s, clock = %s\n", descr[i].name, descr[clock_descr].name ); */ /* printf( "*****************\n" ); printf( "clock_descr = %d\n", clock_descr ); */ descr[i].from[1] = clock_descr; /* se il fanin e` 3, registra il reset o il preset */ if( descr[i].fanin == 3 ) { if( p2 == -1 && p3 == -1 ) { printf( "(create_netlist) ERROR: %d, %s, fanin = 3, but RESET nor PRESET are present\n", i, descr[i].name ); dump_descr(); exit( 1 ); } descr[i].from[2] = (p2 == -1 ? p3 : p2); } /* se il fanin e` 4, no problem */ if( descr[i].fanin == 4 ) { descr[i].from[2] = p2; descr[i].from[4] = p3; } /* FF con reset */ if( (p2 != -1) && (p3 == -1) ) descr[i].ff_type = FFDR; /* FF con preset */ if( (p2 == -1) && (p3 != -1) ) descr[i].ff_type = FFDP; /* FF con reset e preset */ if( (p2 != -1) && (p3 != -1) ) descr[i].ff_type = FFDRP; } break; } } if( n_ff != 0 && clock_descr == -1 ) { printf( "(create_netlist) Clock not found\n" ); dump_descr(); exit( 1 ); } /*-------------------------------*/ /* controlla che il CK sia un PI */ for( i = 0; i < n_descr; i++ ) if( descr[i].type == FF ) if( (descr[descr[i].from[1]].attr != PI) || (descr[i].from[1] != clock_descr) ) { printf( "(create_netlist) ERROR 2: gated clock .\n" ); exit( 1 ); } /*--------------------------------------------------------*/ /* controlla che i segnali di reset e preset siano dei PI */ for( i = 0; i < n_descr; i++ ) if( descr[i].type == FF ) if( descr[i].fanin > 2 ) { if( descr[descr[i].from[2]].attr != PI ) { printf( "(create_netlist) ERROR 3: descr[%d].from[2] isn't a PI\n", i ); exit( 1 ); } if( descr[i].fanin > 3 ) if( descr[descr[i].from[3]].attr != PI ) { printf( "(create_netlist) ERROR 4: descr[%d].from[3] isn't a PI\n", i ); exit( 1 ); } } /*---------------------------------------------------------------*/ /* controlla che il segnale di reset e preset siano RESET/PRESET */ for( i = 0; i < n_descr; i++ ) if( descr[i].type == FF ) if( descr[i].fanin > 2 ) { if( (descr[i].from[2] != reset_descr) && (descr[i].from[2] != preset_descr) ) { printf( "(create_netlist) ERROR 5: reset/preset descriptor not correct\n" ); exit( 1 ); } if( descr[i].fanin > 3 ) if( (descr[i].from[3] != reset_descr) && (descr[i].from[3] != preset_descr) ) { printf( "(create_netlist) ERROR 6: reset/preset descriptor not correct\n" ); exit( 1 ); } } /*----------------------------------------------------------- ATTENZIONE: a questo punto descr contiene anche il segnale di reset e/o preset, la chiamata a questa procedura elima il segale di reset */ destroy_reset( reset_descr, preset_descr ); if( VERBOSE ) { if(!create_silent) printf( "(create_netlist) Create found:\n" ); if(!create_silent) printf( "%d PI\n%d PO\n%d FF\n", n_pi, n_po, n_ff ); } /* alloca la memoria per i vettori contenenti PI, PO e FF */ if( reset_descr != -1 ) { if( VERBOSE ) if(!create_silent) printf( "(create_netlist) Lowering n_pi, there is a reset to skip over\n" ); n_pi--; } if( preset_descr != -1 ) { if( VERBOSE ) if(!create_silent) printf( "(create_netlist) Lowering n_pi, there is a preset to skip over\n" ); n_pi--; } pi_array = (int *)malloc( sizeof( int )*n_pi ); if( pi_array == NULL ) { printf( "(create_netlist) Memory error, quitting...\n" ); exit( 1 ); } ppi_array = (int *)malloc( sizeof( int )*n_ff ); if( ppi_array == NULL ) { printf( "(create_netlist) Memory error, quitting...\n" ); exit( 1 ); } /* scrive la lista dei descrittori dei PI */ j = 0; k = 0; for( i = 0; i < n_descr; i++ ) switch( descr[i].attr ) { case PI: pi_array[j++] = i; break; case INTERNAL: if( descr[i].type == FF ) ppi_array[k++] = i; break; } max_len = 0; n_elem = 0; for( i = 0; i < MAXASSOC; i++ ) if( list_of_assoc[i].name != 0 ) { if( list_of_assoc[i].n_el > max_len ) max_len = list_of_assoc[i].n_el; n_elem += list_of_assoc[i].n_el; } /* collego descr alla libreria */ for( i = 0; i < n_descr; i++ ) switch( descr[i].type ) { case LOGIC0: descr[i].gate_id = LOGIC_0; descr[i].level = 0; break; case LOGIC1: descr[i].gate_id = LOGIC_1; descr[i].level = 0; break; case NAND: if( descr[i].fanin == 2 ) descr[i].gate_id = NAND2; if( descr[i].fanin == 3 ) descr[i].gate_id = NAND3; if( descr[i].fanin == 4 ) descr[i].gate_id = NAND4; if( descr[i].fanin == 5 ) descr[i].gate_id = NAND5; break; case AND: if( descr[i].fanin == 2 ) descr[i].gate_id = AND2; if( descr[i].fanin == 3 ) descr[i].gate_id = AND3; if( descr[i].fanin == 4 ) descr[i].gate_id = AND4; if( descr[i].fanin == 5 ) descr[i].gate_id = AND5; break; case OR: if( descr[i].fanin == 2 ) descr[i].gate_id = OR2; if( descr[i].fanin == 3 ) descr[i].gate_id = OR3; if( descr[i].fanin == 4 ) descr[i].gate_id = OR4; if( descr[i].fanin == 5 ) descr[i].gate_id = OR5; break; case NOR: if( descr[i].fanin == 2 ) descr[i].gate_id = NOR2; if( descr[i].fanin == 3 ) descr[i].gate_id = NOR3; if( descr[i].fanin == 4 ) descr[i].gate_id = NOR4; if( descr[i].fanin == 5 ) descr[i].gate_id = NOR5; break; case EXOR: if( descr[i].fanin == 2 ) descr[i].gate_id = XOR2; if( descr[i].fanin == 3 ) descr[i].gate_id = XOR3; if( descr[i].fanin == 4 ) descr[i].gate_id = XOR4; if( descr[i].fanin == 5 ) descr[i].gate_id = XOR5; break; case EXNOR: if( descr[i].fanin == 2 ) descr[i].gate_id = XNOR2; if( descr[i].fanin == 3 ) descr[i].gate_id = XNOR3; if( descr[i].fanin == 4 ) descr[i].gate_id = XNOR4; if( descr[i].fanin == 5 ) descr[i].gate_id = XNOR5; break; case NOT: descr[i].gate_id = INV; break; case BUF: descr[i].gate_id = BUFF; break; case FF: if( descr[i].ff_type == FFD ) descr[i].gate_id = FFDG; if( descr[i].ff_type == FFDR ) descr[i].gate_id = FFDRG; if( descr[i].ff_type == FFDP ) descr[i].gate_id = FFDPG; if( descr[i].ff_type == FFDRP ) descr[i].gate_id = FFDRPG; /******/ if( descr[i].gate_id == 0 ) { printf( "(create_netlist) Fatal error in library binding, exit.\n" ); exit( 1 ); } break; default: printf( "(create_netlist) Unknown descriptor: %s, %d\n", descr[i].name, descr[i].type ); exit( 1 ); } if( !mode ) { if(!create_silent) printf( "HASH chain max size = %d\n", max_len ); if( max_len != 0.0 ) if(!create_silent) printf( "HASH average size =%f\n", n_elem/max_len ); else if(!create_silent) printf( "HASH average size = 0\n" ); /* calcola il livello */ if(!create_silent) printf( "Start computing level, " ); } if(!create_silent) printf( "\n%d descriptor found\n", n_descr ); #if STRONG_DEBUG check_netlist(); #endif compute_level( n_pi, n_ff, pi_array, ppi_array ); /* controllo che il livello sia corretto */ #if STRONG_DEBUG check_level(); #endif if( !mode ) if(!create_silent) printf( "end computing level.\n" ); /* determina il descrittore del clock, questa deve essere l'ultima operazione fatta perche` nei passi precedenti posso aver modificato il descrittore cancellando i segnali di reset/preset */ find_clock_tree(); /*if( VERBOSE )*/ /*dump_descr();*/}/* struttura locale, la uso per il calcolo del livello */struct fifo{ int desc; struct fifo *link;};struct fifo *mytail, myhead; /* NB: myhead e` un nodo dummy */int *visited; /** ** routines per gestione coda FIFO **/int insert (int desc);int extract (int * pdesc); int insert(int desc){ struct fifo *p1; #if TRACE == 1 printf( "[insert]\n" ); #endif if (NULL == (p1 = (struct fifo *) malloc(sizeof(struct fifo)))) return 1; p1->desc = desc; p1->link = NULL; mytail = (mytail->link = p1); return 0;} /* end of insert() */ int extract(int *pdesc){ struct fifo *p1; #if TRACE == 1 printf( "[extract]\n" ); #endif p1 = myhead.link; if (!p1) return 1; *pdesc = p1->desc; myhead.link = p1->link; if(mytail == p1) mytail = &myhead ; free(p1); return 0;}/* calcola il livello di ogni descrittore a partire da PI e FF */int compute_level(int n_pi,int n_ff,int *pi_array,int *ppi_array){ /* Uso una lista FIFO di #descr */ int this_desc, next_level, next_desc; int i; DESCRIPTOR *p, *p1; #if TRACE == 1 printf( "[compute_level]\n" ); #endif /* inizializza la lista */ myhead.link = NULL; mytail = &myhead; visited = (int*) malloc(n_descr*sizeof(int)); if(!visited) return(1); /* inizializzo tutti i descrittori a livello nullo, che poi incrementero` */ for (i = 0, p = descr; i < n_descr; i++, p++) { p->level = 0L; visited[i]= 0 ; } max_level = 0; /* PI & FF & LOGIC_1 & LOGIC_0: gia` giustamente a livello 0 */ for( i = 0; i < n_descr; i++ ) if( descr[i].attr == INTERNAL && (descr[i].type == LOGIC0 || descr[i].type == LOGIC1) ) insert( i ); for (i = 0; i < n_pi; ++i) { /*printf("PI-%d\n",pi_array[i]);*/ if (insert(pi_array[i])) return 1; } for (i = 0; i < n_ff; ++i) { /*printf("FF-%d\n",ppi_array[i]);*/ if (insert(ppi_array[i])) return 1; } /* vai a esplorare il grafo calcolando il MAX livello, escludendo i FF */ while (!extract(&this_desc)) { /*printf("EXT-%d\n",this_desc);*/ p = &descr[this_desc]; next_level = p->level + 1; /* scandisci i gate a livello successivo */ for (i = 0; i < p->fanout; i++) { next_desc = p->to[i]; p1 = &descr[next_desc]; visited[next_desc]++; if ((p1->level < next_level) && (p1->type != FF)) { if(visited[next_desc] < p1->fanin) { /*printf("Delaying %s\n", p1->name);*/ /*printf("DEL-%d\n",next_desc) ;*/ } else if (visited[next_desc] == p1->fanin) { /*printf("Setting %s to %d\n", p1->name, next_level);*/ /*printf("INS-%d\n",next_desc);*/ p1->level = next_level; if (next_level > max_level) max_level = next_level; if (insert(next_desc)) return 1; } else { printf("ERROR: Asynchronous loop detected\n"); printf("\t(net %s from gate %s to gate %s is a feedback net)\n", p->to_name, p->name, p1->name); #if VERBOSE dump_descr(); #endif exit(1); } } } } free(visited); visited=NULL; return 0;} /* end of compute_level() */ int Hfun( char *s, int tablen ){ char *p; unsigned int h = 0, g; int i; #if TRACE == 1 printf( "[Hfun]\n" ); #endif for (p = s, i = strlen( s ); i; p++, i--) { h <<= 4; h += *p; if( (g = (h & 0xF0000000L)) ) h ^= g ^ (g >> 24); } return h % tablen;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -