/**CFile**************************************************************** FileName [ioWriteBook.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Command processing package.] Synopsis [Procedures to write Bookshelf files.] Author [Myungchul Kim] Affiliation [U of Michigan] Date [Ver. 1.0. Started - October 25, 2008.] Revision [$Id: ioWriteBook.c,v 1.00 2005/11/10 00:00:00 mckima Exp $] ***********************************************************************/ #include "ioAbc.h" #include "main.h" #include "mio.h" ABC_NAMESPACE_IMPL_START #define NODES 0 #define PL 1 #define coreHeight 1 #define termWidth 1 #define termHeight 1 //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// static unsigned Io_NtkWriteNodes( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWritePiPoNodes( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteLatchNode( FILE * pFile, Abc_Obj_t * pLatch, int NodesOrPl ); static unsigned Io_NtkWriteIntNode( FILE * pFile, Abc_Obj_t * pNode, int NodesOrPl ); static unsigned Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode ); static void Io_NtkWriteNets( FILE * pFile, Abc_Ntk_t * pNtk ); static void Io_NtkWriteIntNet( FILE * pFile, Abc_Obj_t * pNode ); static void Io_NtkBuildLayout( FILE * pFile1, FILE *pFile2, Abc_Ntk_t * pNtk, double aspectRatio, double whiteSpace, unsigned coreCellArea ); static void Io_NtkWriteScl( FILE * pFile, unsigned numCoreRows, double layoutWidth ); static void Io_NtkWritePl( FILE * pFile, Abc_Ntk_t * pNtk, unsigned numTerms, double layoutHeight, double layoutWidth ); static Vec_Ptr_t * Io_NtkOrderingPads( Abc_Ntk_t * pNtk, Vec_Ptr_t * vTerms ); static Abc_Obj_t * Io_NtkBfsPads( Abc_Ntk_t * pNtk, Abc_Obj_t * pCurrEntry, unsigned numTerms, int * pOrdered ); static int Abc_NodeIsNand2( Abc_Obj_t * pNode ); static int Abc_NodeIsNor2( Abc_Obj_t * pNode ); static int Abc_NodeIsAnd2( Abc_Obj_t * pNode ); static int Abc_NodeIsOr2( Abc_Obj_t * pNode ); static int Abc_NodeIsXor2( Abc_Obj_t * pNode ); static int Abc_NodeIsXnor2( Abc_Obj_t * pNode ); static inline double Abc_Rint( double x ) { return (double)(int)x; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Write the network into a Bookshelf file with the given name.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_WriteBookLogic( Abc_Ntk_t * pNtk, char * FileName ) { Abc_Ntk_t * pNtkTemp; // derive the netlist pNtkTemp = Abc_NtkToNetlist(pNtk); if ( pNtkTemp == NULL ) { fprintf( stdout, "Writing BOOK has failed.\n" ); return; } Io_WriteBook( pNtkTemp, FileName ); Abc_NtkDelete( pNtkTemp ); } /**Function************************************************************* Synopsis [Write the network into a BOOK file with the given name.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_WriteBook( Abc_Ntk_t * pNtk, char * FileName ) { FILE * pFileNodes, * pFileNets, * pFileAux; FILE * pFileScl, * pFilePl, * pFileWts; char * FileExt = ABC_CALLOC( char, strlen(FileName)+7 ); unsigned coreCellArea=0; Abc_Ntk_t * pExdc, * pNtkTemp; int i; assert( Abc_NtkIsNetlist(pNtk) ); // start writing the files strcpy(FileExt, FileName); pFileNodes = fopen( strcat(FileExt,".nodes"), "w" ); strcpy(FileExt, FileName); pFileNets = fopen( strcat(FileExt,".nets"), "w" ); strcpy(FileExt, FileName); pFileAux = fopen( strcat(FileExt,".aux"), "w" ); // write the aux file if ( (pFileNodes == NULL) || (pFileNets == NULL) || (pFileAux == NULL) ) { fclose( pFileAux ); fprintf( stdout, "Io_WriteBook(): Cannot open the output files.\n" ); return; } fprintf( pFileAux, "RowBasedPlacement : %s.nodes %s.nets %s.scl %s.pl %s.wts", FileName, FileName, FileName, FileName, FileName ); fclose( pFileAux ); // write the master network coreCellArea+=Io_NtkWriteNodes( pFileNodes, pNtk ); Io_NtkWriteNets( pFileNets, pNtk ); // write EXDC network if it exists pExdc = Abc_NtkExdc( pNtk ); if ( pExdc ) { coreCellArea+=Io_NtkWriteNodes( pFileNodes, pNtk ); Io_NtkWriteNets( pFileNets, pNtk ); } // make sure there is no logic hierarchy assert( Abc_NtkWhiteboxNum(pNtk) == 0 ); // write the hierarchy if present if ( Abc_NtkBlackboxNum(pNtk) > 0 ) { Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pNtkTemp, i ) { if ( pNtkTemp == pNtk ) continue; coreCellArea+=Io_NtkWriteNodes( pFileNodes, pNtkTemp ); Io_NtkWriteNets( pFileNets, pNtkTemp ); } } fclose( pFileNodes ); fclose( pFileNets ); strcpy(FileExt, FileName); pFileScl = fopen( strcat(FileExt,".scl"), "w" ); strcpy(FileExt, FileName); pFilePl = fopen( strcat(FileExt,".pl"), "w" ); strcpy(FileExt, FileName); pFileWts = fopen( strcat(FileExt,".wts"), "w" ); ABC_FREE(FileExt); Io_NtkBuildLayout( pFileScl, pFilePl, pNtk, 1.0, 10, coreCellArea ); fclose( pFileScl ); fclose( pFilePl ); fclose( pFileWts ); } /**Function************************************************************* Synopsis [Write the network into a BOOK file with the given name.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned Io_NtkWriteNodes( FILE * pFile, Abc_Ntk_t * pNtk ) { ProgressBar * pProgress; Abc_Obj_t * pLatch, * pNode; unsigned numTerms, numNodes, coreCellArea=0; int i; assert( Abc_NtkIsNetlist(pNtk) ); // write the forehead numTerms=Abc_NtkPiNum(pNtk)+Abc_NtkPoNum(pNtk); numNodes=numTerms+Abc_NtkNodeNum(pNtk)+Abc_NtkLatchNum(pNtk); printf("NumNodes : %d\t", numNodes ); printf("NumTerminals : %d\n", numTerms ); fprintf( pFile, "UCLA nodes 1.0\n"); fprintf( pFile, "NumNodes : %d\n", numNodes ); fprintf( pFile, "NumTerminals : %d\n", numTerms ); // write the PI/POs Io_NtkWritePiPoNodes( pFile, pNtk ); // write the latches if ( !Abc_NtkIsComb(pNtk) ) Abc_NtkForEachLatch( pNtk, pLatch, i ) { Io_NtkWriteLatchNode( pFile, pLatch, NODES ); coreCellArea+=6*coreHeight; } // write each internal node pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) ); Abc_NtkForEachNode( pNtk, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); coreCellArea+=Io_NtkWriteIntNode( pFile, pNode, NODES ); } Extra_ProgressBarStop( pProgress ); return coreCellArea; } /**Function************************************************************* Synopsis [Writes the primary input nodes into a file] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWritePiPoNodes( FILE * pFile, Abc_Ntk_t * pNtk ) { Abc_Obj_t * pTerm, * pNet; int i; Abc_NtkForEachPi( pNtk, pTerm, i ) { pNet = Abc_ObjFanout0(pTerm); fprintf( pFile, "i%s_input\t", Abc_ObjName(pNet) ); fprintf( pFile, "terminal "); fprintf( pFile, " %d %d\n", termWidth, termHeight ); } Abc_NtkForEachPo( pNtk, pTerm, i ) { pNet = Abc_ObjFanin0(pTerm); fprintf( pFile, "o%s_output\t", Abc_ObjName(pNet) ); fprintf( pFile, "terminal "); fprintf( pFile, " %d %d\n", termWidth, termHeight ); } } /**Function************************************************************* Synopsis [Write the latch nodes into a file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteLatchNode( FILE * pFile, Abc_Obj_t * pLatch, int NodesOrPl ) { Abc_Obj_t * pNetLi, * pNetLo; pNetLi = Abc_ObjFanin0( Abc_ObjFanin0(pLatch) ); pNetLo = Abc_ObjFanout0( Abc_ObjFanout0(pLatch) ); /// write the latch line fprintf( pFile, "%s_%s_latch\t", Abc_ObjName(pNetLi), Abc_ObjName(pNetLo) ); if (NodesOrPl == NODES) fprintf( pFile, " %d %d\n", 6, 1 ); } /**Function************************************************************* Synopsis [Write the internal node into a file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned Io_NtkWriteIntNode( FILE * pFile, Abc_Obj_t * pNode, int NodesOrPl ) { unsigned sizex=0, sizey=coreHeight, isize=0; //double nx, ny, xstep, ystep; Abc_Obj_t * pNeti, *pNeto; int i; // write the network after mapping if ( Abc_NtkHasMapping(pNode->pNtk) ) sizex=Io_NtkWriteNodeGate( pFile, pNode ); else { Abc_ObjForEachFanin( pNode, pNeti, i ) fprintf( pFile, "%s_", Abc_ObjName(pNeti) ); Abc_ObjForEachFanout( pNode, pNeto, i ) fprintf( pFile, "%s_", Abc_ObjName(pNeto) ); fprintf( pFile, "name\t" ); if(NodesOrPl == NODES) { isize=Abc_ObjFaninNum(pNode); if ( Abc_NodeIsConst0(pNode) || Abc_NodeIsConst1(pNode) ) sizex=0; else if ( Abc_NodeIsInv(pNode) ) sizex=1; else if ( Abc_NodeIsBuf(pNode) ) sizex=2; else { assert( Abc_NtkHasSop(pNode->pNtk) ); if ( Abc_NodeIsNand2(pNode) || Abc_NodeIsNor2(pNode) ) sizex=2; else if ( Abc_NodeIsAnd2(pNode) || Abc_NodeIsOr2(pNode) ) sizex=3; else if ( Abc_NodeIsXor2(pNode) || Abc_NodeIsXnor2(pNode) ) sizex=5; else { assert( isize > 2 ); sizex=isize+Abc_SopGetCubeNum((char *)pNode->pData); } } } } if(NodesOrPl == NODES) { fprintf( pFile, " %d %d\n", sizex, sizey ); // Equally place pins. Size pins needs / isize+#output+1 isize= isize + Abc_ObjFanoutNum(pNode) + 1; } return sizex*sizey; /* xstep = sizex / isize; ystep = sizey / isize; nx= -0.5 * sizex; ny= -0.5 * sizey; Abc_ObjForEachFanin( pNode, pFanin, i ) { nx+= xstep; ny+= ystep; if (fabs(nx) < 0.001) nx= 0; if (fabs(ny) < 0.001) ny= 0; } Abc_ObjForEachFanout( pNode, pFanout, i ) { nx+= xstep; ny+= ystep; if (fabs(nx) < 0.001) nx= 0; if (fabs(ny) < 0.001) ny= 0; } */ } /**Function************************************************************* Synopsis [Writes the internal node after tech mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode ) { Mio_Gate_t * pGate = (Mio_Gate_t *)pNode->pData; Mio_Pin_t * pGatePin; int i; // write the node gate for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ ) fprintf( pFile, "%s_", Abc_ObjName( Abc_ObjFanin(pNode,i) ) ); assert ( i == Abc_ObjFaninNum(pNode) ); fprintf( pFile, "%s_%s\t", Abc_ObjName( Abc_ObjFanout0(pNode) ), Mio_GateReadName(pGate) ); return Mio_GateReadArea(pGate); } /**Function************************************************************* Synopsis [Write the nets into a file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteNets( FILE * pFile, Abc_Ntk_t * pNtk ) { ProgressBar * pProgress; Abc_Obj_t * pNet; unsigned numPin=0; int i; assert( Abc_NtkIsNetlist(pNtk) ); // write the head Abc_NtkForEachNet( pNtk, pNet, i ) numPin+=Abc_ObjFaninNum(pNet)+Abc_ObjFanoutNum(pNet); printf( "NumNets : %d\t", Abc_NtkNetNum(pNtk) ); printf( "NumPins : %d\n\n", numPin ); fprintf( pFile, "UCLA nets 1.0\n"); fprintf( pFile, "NumNets : %d\n", Abc_NtkNetNum(pNtk) ); fprintf( pFile, "NumPins : %d\n", numPin ); // write nets pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNetNum(pNtk) ); Abc_NtkForEachNet( pNtk, pNet, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); Io_NtkWriteIntNet( pFile, pNet ); } Extra_ProgressBarStop( pProgress ); } /**Function************************************************************* Synopsis [Write the nets into a file.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteIntNet( FILE * pFile, Abc_Obj_t * pNet ) { Abc_Obj_t * pFanin, * pFanout; Abc_Obj_t * pNeti, * pNeto; Abc_Obj_t * pNetLi, * pNetLo, * pLatch; int i, j; int NetDegree=Abc_ObjFaninNum(pNet)+Abc_ObjFanoutNum(pNet); fprintf( pFile, "NetDegree\t:\t\t%d\t\t%s\n", NetDegree, Abc_ObjName(Abc_ObjFanin0(pNet)) ); pFanin=Abc_ObjFanin0(pNet); if ( Abc_ObjIsPi(pFanin) ) fprintf( pFile, "i%s_input I\n", Abc_ObjName(pNet) ); else { if(!Abc_NtkIsComb(pNet->pNtk) && Abc_ObjFaninNum(pFanin) && Abc_ObjIsLatch(Abc_ObjFanin0(pFanin)) ) { pLatch=Abc_ObjFanin0(pFanin); pNetLi=Abc_ObjFanin0(Abc_ObjFanin0(pLatch)); pNetLo=Abc_ObjFanout0(Abc_ObjFanout0(pLatch)); fprintf( pFile, "%s_%s_latch I : ", Abc_ObjName(pNetLi), Abc_ObjName(pNetLo) ); } else { Abc_ObjForEachFanin( pFanin, pNeti, j ) fprintf( pFile, "%s_", Abc_ObjName(pNeti) ); Abc_ObjForEachFanout( pFanin, pNeto, j ) fprintf( pFile, "%s_", Abc_ObjName(pNeto) ); if ( Abc_NtkHasMapping(pNet->pNtk) ) fprintf( pFile, "%s : ", Mio_GateReadName((Mio_Gate_t *)pFanin->pData) ); else fprintf( pFile, "name I : " ); } // offsets are simlply 0.00 0.00 at the moment fprintf( pFile, "%.2f %.2f\n", .0, .0 ); } Abc_ObjForEachFanout( pNet, pFanout, i ) { if ( Abc_ObjIsPo(pFanout) ) fprintf( pFile, "o%s_output O\n", Abc_ObjName(pNet) ); else { if(!Abc_NtkIsComb(pNet->pNtk) && Abc_ObjFanoutNum(pFanout) && Abc_ObjIsLatch( Abc_ObjFanout0(pFanout) ) ) { pLatch=Abc_ObjFanout0(pFanout); pNetLi=Abc_ObjFanin0(Abc_ObjFanin0(pLatch)); pNetLo=Abc_ObjFanout0(Abc_ObjFanout0(pLatch)); fprintf( pFile, "%s_%s_latch O : ", Abc_ObjName(pNetLi), Abc_ObjName(pNetLo) ); } else { Abc_ObjForEachFanin( pFanout, pNeti, j ) fprintf( pFile, "%s_", Abc_ObjName(pNeti) ); Abc_ObjForEachFanout( pFanout, pNeto, j ) fprintf( pFile, "%s_", Abc_ObjName(pNeto) ); if ( Abc_NtkHasMapping(pNet->pNtk) ) fprintf( pFile, "%s : ", Mio_GateReadName((Mio_Gate_t *)pFanout->pData) ); else fprintf( pFile, "name O : " ); } // offsets are simlply 0.00 0.00 at the moment fprintf( pFile, "%.2f %.2f\n", .0, .0 ); } } } /**Function************************************************************* Synopsis [Write the network into a BOOK file with the given name.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkBuildLayout( FILE * pFileScl, FILE * pFilePl, Abc_Ntk_t * pNtk, double aspectRatio, double whiteSpace, unsigned coreCellArea ) { unsigned numCoreCells=Abc_NtkNodeNum(pNtk)+Abc_NtkLatchNum(pNtk); double targetLayoutArea = coreCellArea/(1.0-(whiteSpace/100.0)); unsigned numCoreRows=(aspectRatio>0.0) ? (Abc_Rint(sqrt(targetLayoutArea/aspectRatio)/coreHeight)) : 0; unsigned numTerms=Abc_NtkPiNum(pNtk)+Abc_NtkPoNum(pNtk); unsigned totalWidth=coreCellArea/coreHeight; double layoutHeight = numCoreRows * coreHeight; double layoutWidth = Abc_Rint(targetLayoutArea/layoutHeight); double actualLayoutArea = layoutWidth * layoutHeight; printf( "Core cell height(==site height) is %d\n", coreHeight ); printf( "Total core cell width is %d giving an ave width of %f\n", totalWidth, (double)(totalWidth/numCoreCells)); printf( "Target Dimensions:\n" ); printf( " Area : %f\n", targetLayoutArea ); printf( " WS%% : %f\n", whiteSpace ); printf( " AR : %f\n", aspectRatio ); printf( "Actual Dimensions:\n" ); printf( " Width : %f\n", layoutWidth ); printf( " Height: %f (%d rows)\n", layoutHeight, numCoreRows); printf( " Area : %f\n", actualLayoutArea ); printf( " WS%% : %f\n", 100*(actualLayoutArea-coreCellArea)/actualLayoutArea ); printf( " AR : %f\n\n", layoutWidth/layoutHeight ); Io_NtkWriteScl( pFileScl, numCoreRows, layoutWidth ); Io_NtkWritePl( pFilePl, pNtk, numTerms, layoutHeight, layoutWidth ); } /**Function************************************************************* Synopsis [Write the network into a BOOK file with the given name.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWriteScl( FILE * pFile, unsigned numCoreRows, double layoutWidth ) { int origin_y=0; char * rowOrients[2] = {"N", "FS"}; char symmetry='Y'; double sitewidth=1.0; double spacing=1.0; unsigned rowId; // write the forehead fprintf( pFile, "UCLA scl 1.0\n\n" ); fprintf( pFile, "Numrows : %d\n\n", numCoreRows ); for( rowId=0 ; rowId<numCoreRows ; rowId++, origin_y += coreHeight ) { fprintf( pFile, "CoreRow Horizontal\n" ); fprintf( pFile, " Coordinate : \t%d\n", origin_y); fprintf( pFile, " Height : \t%d\n", coreHeight); fprintf( pFile, " Sitewidth : \t%d\n", (unsigned)sitewidth ); fprintf( pFile, " Sitespacing : \t%d\n", (unsigned)spacing ); fprintf( pFile, " Siteorient : \t%s\n", rowOrients[rowId%2] ); //if( coreRow[i].site.symmetry.rot90 || coreRow[i].site.symmetry.y || coreRow[i].site.symmetry.x ) fprintf( pFile, " Sitesymmetry : \t%c\n", symmetry ); //else fprintf( pFile, "Sitesymmetry : \t\t\t1\n" ); fprintf( pFile, " SubrowOrigin : \t%d Numsites : \t%d\n", 0, (unsigned)layoutWidth ); fprintf( pFile, "End\n" ); } } /**Function************************************************************* Synopsis [Write the network into a BOOK file with the given name.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_NtkWritePl( FILE * pFile, Abc_Ntk_t * pNtk, unsigned numTerms, double layoutWidth, double layoutHeight ) { Abc_Obj_t * pTerm, * pLatch, * pNode; Vec_Ptr_t * vTerms = Vec_PtrAlloc ( numTerms ); Vec_Ptr_t * vOrderedTerms = Vec_PtrAlloc ( numTerms ); double layoutPerim = 2*layoutWidth + 2*layoutHeight; double nextLoc_x, nextLoc_y; double delta; unsigned termsOnTop, termsOnBottom, termsOnLeft, termsOnRight; unsigned t; int i; termsOnTop = termsOnBottom = (unsigned)(Abc_Rint(numTerms*(layoutWidth/layoutPerim))); termsOnLeft = numTerms - (termsOnTop+termsOnBottom); termsOnRight = (unsigned)(ceil(termsOnLeft/2.0)); termsOnLeft -= termsOnRight; Abc_NtkForEachPi( pNtk, pTerm, i ) Vec_PtrPush( vTerms, pTerm ); Abc_NtkForEachPo( pNtk, pTerm, i ) Vec_PtrPush( vTerms, pTerm ); // Ordering Pads vOrderedTerms=Io_NtkOrderingPads( pNtk, vTerms ); assert( termsOnTop+termsOnBottom+termsOnLeft+termsOnRight == (unsigned)Vec_PtrSize(vOrderedTerms) ); printf( "Done constructing layout region\n" ); printf( "Terminals: %d\n", numTerms ); printf( " Top: %d\n", termsOnTop ); printf( " Bottom: %d\n", termsOnBottom ); printf( " Left: %d\n", termsOnLeft ); printf( " Right: %d\n", termsOnRight ); fprintf( pFile, "UCLA pl 1.0\n\n" ); nextLoc_x = floor(.0); nextLoc_y = ceil(layoutHeight + 2*coreHeight); delta = layoutWidth / termsOnTop; for(t = 0; t < termsOnTop; t++) { pTerm = (Abc_Obj_t *)Vec_PtrEntry( vOrderedTerms, t ); if( Abc_ObjIsPi(pTerm) ) fprintf( pFile, "i%s_input\t\t", Abc_ObjName(Abc_ObjFanout0(pTerm)) ); else fprintf( pFile, "o%s_output\t\t", Abc_ObjName(Abc_ObjFanin0(pTerm)) ); if( t && Abc_Rint(nextLoc_x) < Abc_Rint(nextLoc_x-delta)+termWidth ) nextLoc_x++; fprintf( pFile, "%d\t\t%d\t: %s /FIXED\n", (int)Abc_Rint(nextLoc_x), (int)Abc_Rint(nextLoc_y), "FS" ); nextLoc_x += delta; } nextLoc_x = floor(.0); nextLoc_y = floor(.0 - 2*coreHeight - termHeight); delta = layoutWidth / termsOnBottom; for(;t < termsOnTop+termsOnBottom; t++) { pTerm = (Abc_Obj_t *)Vec_PtrEntry( vOrderedTerms, t ); if( Abc_ObjIsPi(pTerm) ) fprintf( pFile, "i%s_input\t\t", Abc_ObjName(Abc_ObjFanout0(pTerm)) ); else fprintf( pFile, "o%s_output\t\t", Abc_ObjName(Abc_ObjFanin0(pTerm)) ); if( t!=termsOnTop && Abc_Rint(nextLoc_x) < Abc_Rint(nextLoc_x-delta)+termWidth ) nextLoc_x++; fprintf( pFile, "%d\t\t%d\t: %s /FIXED\n", (int)Abc_Rint(nextLoc_x), (int)Abc_Rint(nextLoc_y), "N" ); nextLoc_x += delta; } nextLoc_x = floor(.0-2*coreHeight-termWidth); nextLoc_y = floor(.0); delta = layoutHeight / termsOnLeft; for(;t < termsOnTop+termsOnBottom+termsOnLeft; t++) { pTerm = (Abc_Obj_t *)Vec_PtrEntry( vOrderedTerms, t ); if( Abc_ObjIsPi(pTerm) ) fprintf( pFile, "i%s_input\t\t", Abc_ObjName(Abc_ObjFanout0(pTerm)) ); else fprintf( pFile, "o%s_output\t\t", Abc_ObjName(Abc_ObjFanin0(pTerm)) ); if( Abc_Rint(nextLoc_y) < Abc_Rint(nextLoc_y-delta)+termHeight ) nextLoc_y++; fprintf( pFile, "%d\t\t%d\t: %s /FIXED\n", (int)Abc_Rint(nextLoc_x), (int)Abc_Rint(nextLoc_y), "E" ); nextLoc_y += delta; } nextLoc_x = ceil(layoutWidth+2*coreHeight); nextLoc_y = floor(.0); delta = layoutHeight / termsOnRight; for(;t < termsOnTop+termsOnBottom+termsOnLeft+termsOnRight; t++) { pTerm = (Abc_Obj_t *)Vec_PtrEntry( vOrderedTerms, t ); if( Abc_ObjIsPi(pTerm) ) fprintf( pFile, "i%s_input\t\t", Abc_ObjName(Abc_ObjFanout0(pTerm)) ); else fprintf( pFile, "o%s_output\t\t", Abc_ObjName(Abc_ObjFanin0(pTerm)) ); if( Abc_Rint(nextLoc_y) < Abc_Rint(nextLoc_y-delta)+termHeight ) nextLoc_y++; fprintf( pFile, "%d\t\t%d\t: %s /FIXED\n", (int)Abc_Rint(nextLoc_x), (int)Abc_Rint(nextLoc_y), "FW" ); nextLoc_y += delta; } if( !Abc_NtkIsComb(pNtk) ) Abc_NtkForEachLatch( pNtk, pLatch, i ) { Io_NtkWriteLatchNode( pFile, pLatch, PL ); fprintf( pFile, "\t%d\t\t%d\t: %s\n", 0, 0, "N" ); } Abc_NtkForEachNode( pNtk, pNode, i ) { Io_NtkWriteIntNode( pFile, pNode, PL ); fprintf( pFile, "\t%d\t\t%d\t: %s\n", 0, 0, "N" ); } } /**Function************************************************************* Synopsis [Returns the closest I/O to a given I/O.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Ptr_t * Io_NtkOrderingPads( Abc_Ntk_t * pNtk, Vec_Ptr_t * vTerms ) { ProgressBar * pProgress; unsigned numTerms=Vec_PtrSize(vTerms); unsigned termIdx=0, termCount=0; int * pOrdered = ABC_ALLOC(int, numTerms); int newNeighbor=1; Vec_Ptr_t * vOrderedTerms = Vec_PtrAlloc ( numTerms ); Abc_Obj_t * pNeighbor, * pNextTerm; unsigned i; for( i=0 ; i<numTerms ; i++ ) pOrdered[i]=0; pNextTerm = (Abc_Obj_t *)Vec_PtrEntry(vTerms, termIdx++); pProgress = Extra_ProgressBarStart( stdout, numTerms ); while( termCount < numTerms && termIdx < numTerms ) { if( pOrdered[Abc_ObjId(pNextTerm)] && !newNeighbor ) { pNextTerm = (Abc_Obj_t *)Vec_PtrEntry( vTerms, termIdx++ ); continue; } if(!Vec_PtrPushUnique( vOrderedTerms, pNextTerm )) { pOrdered[Abc_ObjId(pNextTerm)]=1; termCount++; } pNeighbor=Io_NtkBfsPads( pNtk, pNextTerm, numTerms, pOrdered ); if( (newNeighbor=!Vec_PtrPushUnique( vOrderedTerms, pNeighbor )) ) { pOrdered[Abc_ObjId(pNeighbor)]=1; termCount++; pNextTerm=pNeighbor; } else if(termIdx < numTerms) pNextTerm = (Abc_Obj_t *)Vec_PtrEntry( vTerms, termIdx++ ); Extra_ProgressBarUpdate( pProgress, termCount, NULL ); } Extra_ProgressBarStop( pProgress ); assert(termCount==numTerms); return vOrderedTerms; } /**Function************************************************************* Synopsis [Returns the closest I/O to a given I/O.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Obj_t * Io_NtkBfsPads( Abc_Ntk_t * pNtk, Abc_Obj_t * pTerm, unsigned numTerms, int * pOrdered ) { Vec_Ptr_t * vNeighbors = Vec_PtrAlloc ( numTerms ); Abc_Obj_t * pNet, * pNode, * pNeighbor; int foundNeighbor=0; int i; assert(Abc_ObjIsPi(pTerm) || Abc_ObjIsPo(pTerm) ); Abc_NtkIncrementTravId ( pNtk ); Abc_NodeSetTravIdCurrent( pTerm ); if(Abc_ObjIsPi(pTerm)) { pNet = Abc_ObjFanout0(pTerm); Abc_ObjForEachFanout( pNet, pNode, i ) Vec_PtrPush( vNeighbors, pNode ); } else { pNet = Abc_ObjFanin0(pTerm); Abc_ObjForEachFanin( pNet, pNode, i ) Vec_PtrPush( vNeighbors, pNode ); } while ( Vec_PtrSize(vNeighbors) >0 ) { pNeighbor = (Abc_Obj_t *)Vec_PtrEntry( vNeighbors, 0 ); assert( Abc_ObjIsNode(pNeighbor) || Abc_ObjIsTerm(pNeighbor) ); Vec_PtrRemove( vNeighbors, pNeighbor ); if( Abc_NodeIsTravIdCurrent( pNeighbor ) ) continue; Abc_NodeSetTravIdCurrent( pNeighbor ); if( ((Abc_ObjIsPi(pNeighbor) || Abc_ObjIsPo(pNeighbor))) && !pOrdered[Abc_ObjId(pNeighbor)] ) { foundNeighbor=1; break; } if( Abc_ObjFanoutNum( pNeighbor ) ) { pNet=Abc_ObjFanout0( pNeighbor ); if( !Abc_NtkIsComb(pNtk) && Abc_ObjIsLatch(pNet) ) pNet=Abc_ObjFanout0( Abc_ObjFanout0(pNet) ); Abc_ObjForEachFanout( pNet, pNode, i ) if( !Abc_NodeIsTravIdCurrent(pNode) ) Vec_PtrPush( vNeighbors, pNode ); } if( Abc_ObjFaninNum( pNeighbor ) ) { if( !Abc_NtkIsComb(pNtk) && Abc_ObjIsLatch(Abc_ObjFanin0(pNeighbor)) ) pNeighbor=Abc_ObjFanin0( Abc_ObjFanin0(pNeighbor) ); Abc_ObjForEachFanin( pNeighbor, pNet, i ) if( !Abc_NodeIsTravIdCurrent(pNode=Abc_ObjFanin0(pNet)) ) Vec_PtrPush( vNeighbors, pNode ); } } return ( foundNeighbor ) ? pNeighbor : pTerm; } /**Function************************************************************* Synopsis [Test is the node is nand2.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NodeIsNand2( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; assert( Abc_NtkIsNetlist(pNtk) ); assert( Abc_ObjIsNode(pNode) ); if ( Abc_ObjFaninNum(pNode) != 2 ) return 0; if ( Abc_NtkHasSop(pNtk) ) return ( !strcmp(((char *)pNode->pData), "-0 1\n0- 1\n") || !strcmp(((char *)pNode->pData), "0- 1\n-0 1\n") || !strcmp(((char *)pNode->pData), "11 0\n") ); if ( Abc_NtkHasMapping(pNtk) ) return pNode->pData == (void *)Mio_LibraryReadNand2((Mio_Library_t *)Abc_FrameReadLibGen()); assert( 0 ); return 0; } /**Function************************************************************* Synopsis [Test is the node is nand2.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NodeIsNor2( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; assert( Abc_NtkIsNetlist(pNtk) ); assert( Abc_ObjIsNode(pNode) ); if ( Abc_ObjFaninNum(pNode) != 2 ) return 0; if ( Abc_NtkHasSop(pNtk) ) return ( !strcmp(((char *)pNode->pData), "00 1\n") ); assert( 0 ); return 0; } /**Function************************************************************* Synopsis [Test is the node is and2.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NodeIsAnd2( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; assert( Abc_NtkIsNetlist(pNtk) ); assert( Abc_ObjIsNode(pNode) ); if ( Abc_ObjFaninNum(pNode) != 2 ) return 0; if ( Abc_NtkHasSop(pNtk) ) return Abc_SopIsAndType(((char *)pNode->pData)); if ( Abc_NtkHasMapping(pNtk) ) return pNode->pData == (void *)Mio_LibraryReadAnd2((Mio_Library_t *)Abc_FrameReadLibGen()); assert( 0 ); return 0; } /**Function************************************************************* Synopsis [Test is the node is or2.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NodeIsOr2( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; assert( Abc_NtkIsNetlist(pNtk) ); assert( Abc_ObjIsNode(pNode) ); if ( Abc_ObjFaninNum(pNode) != 2 ) return 0; if ( Abc_NtkHasSop(pNtk) ) return ( Abc_SopIsOrType(((char *)pNode->pData)) || !strcmp(((char *)pNode->pData), "01 0\n") || !strcmp(((char *)pNode->pData), "10 0\n") || !strcmp(((char *)pNode->pData), "00 0\n") ); //off-sets, too assert( 0 ); return 0; } /**Function************************************************************* Synopsis [Test is the node is xor2.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NodeIsXor2( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; assert( Abc_NtkIsNetlist(pNtk) ); assert( Abc_ObjIsNode(pNode) ); if ( Abc_ObjFaninNum(pNode) != 2 ) return 0; if ( Abc_NtkHasSop(pNtk) ) return ( !strcmp(((char *)pNode->pData), "01 1\n10 1\n") || !strcmp(((char *)pNode->pData), "10 1\n01 1\n") ); assert( 0 ); return 0; } /**Function************************************************************* Synopsis [Test is the node is xnor2.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NodeIsXnor2( Abc_Obj_t * pNode ) { Abc_Ntk_t * pNtk = pNode->pNtk; assert( Abc_NtkIsNetlist(pNtk) ); assert( Abc_ObjIsNode(pNode) ); if ( Abc_ObjFaninNum(pNode) != 2 ) return 0; if ( Abc_NtkHasSop(pNtk) ) return ( !strcmp(((char *)pNode->pData), "11 1\n00 1\n") || !strcmp(((char *)pNode->pData), "00 1\n11 1\n") ); assert( 0 ); return 0; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END