/**Function************************************************************* Synopsis [Starts the record for the given network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkRecStart( Abc_Ntk_t * pNtk, int nVars, int nCuts ) { Abc_ManRec_t * p; Abc_Obj_t * pObj, ** ppSpot; char Buffer[10]; unsigned * pTruth; int i, RetValue; int clkTotal = clock(), clk; assert( s_pMan == NULL ); if ( pNtk == NULL ) { assert( nVars > 2 && nVars <= 16 ); pNtk = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); pNtk->pName = Extra_UtilStrsav( "record" ); } else { if ( Abc_NtkGetChoiceNum(pNtk) > 0 ) { printf( "The starting record should be a network without choice nodes.\n" ); return; } if ( Abc_NtkPiNum(pNtk) > 16 ) { printf( "The starting record should be a network with no more than %d primary inputs.\n", 16 ); return; } if ( Abc_NtkPiNum(pNtk) > nVars ) printf( "The starting record has %d inputs (warning only).\n", Abc_NtkPiNum(pNtk) ); pNtk = Abc_NtkDup( pNtk ); } // create the primary inputs for ( i = Abc_NtkPiNum(pNtk); i < nVars; i++ ) { pObj = Abc_NtkCreatePi( pNtk ); Buffer[0] = 'a' + i; Buffer[1] = 0; Abc_ObjAssignName( pObj, Buffer, NULL ); } Abc_NtkCleanCopy( pNtk ); Abc_NtkCleanEquiv( pNtk ); // start the manager p = ABC_ALLOC( Abc_ManRec_t, 1 ); memset( p, 0, sizeof(Abc_ManRec_t) ); p->pNtk = pNtk; p->nVars = Abc_NtkPiNum(pNtk); p->nWords = Kit_TruthWordNum( p->nVars ); p->nCuts = nCuts; p->nVarsInit = nVars; // create elementary truth tables p->vTtElems = Vec_PtrAlloc( 0 ); assert( p->vTtElems->pArray == NULL ); p->vTtElems->nSize = p->nVars; p->vTtElems->nCap = p->nVars; p->vTtElems->pArray = (void *)Extra_TruthElementary( p->nVars ); // allocate room for node truth tables if ( Abc_NtkObjNum(pNtk) > (1<<14) ) p->vTtNodes = Vec_PtrAllocSimInfo( 2 * Abc_NtkObjNum(pNtk), p->nWords ); else p->vTtNodes = Vec_PtrAllocSimInfo( 1<<14, p->nWords ); // create hash table p->nBins = 50011; p->pBins = ABC_ALLOC( Abc_Obj_t *, p->nBins ); memset( p->pBins, 0, sizeof(Abc_Obj_t *) * p->nBins ); // set elementary tables Kit_TruthFill( Vec_PtrEntry(p->vTtNodes, 0), p->nVars ); Abc_NtkForEachPi( pNtk, pObj, i ) Kit_TruthCopy( Vec_PtrEntry(p->vTtNodes, pObj->Id), Vec_PtrEntry(p->vTtElems, i), p->nVars ); // compute the tables clk = clock(); Abc_AigForEachAnd( pNtk, pObj, i ) { RetValue = Abc_NtkRecComputeTruth( pObj, p->vTtNodes, p->nVars ); assert( RetValue ); }
/**Function************************************************************* Synopsis [Writes the graph structure of network for DOT.] Description [Useful for graph visualization using tools such as GraphViz: http://www.graphviz.org/] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse ) { FILE * pFile; Abc_Obj_t * pNode, * pFanin; char * pSopString; int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl; int Limit = 300; assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) ); if ( vNodes->nSize < 1 ) { printf( "The set has no nodes. DOT file is not written.\n" ); return; } if ( vNodes->nSize > Limit ) { printf( "The set has more than %d nodes. DOT file is not written.\n", Limit ); return; } // start the stream if ( (pFile = fopen( pFileName, "w" )) == NULL ) { fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); return; } // transform logic functions from BDD to SOP if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) ) { if ( !Abc_NtkBddToSop(pNtk, 0) ) { printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" ); return; } } // mark the nodes from the set Vec_PtrForEachEntry( vNodes, pNode, i ) pNode->fMarkC = 1; if ( vNodesShow ) Vec_PtrForEachEntry( vNodesShow, pNode, i ) pNode->fMarkB = 1; // get the levels of nodes LevelMax = Abc_NtkLevel( pNtk ); if ( fUseReverse ) { LevelMin = Abc_NtkLevelReverse( pNtk ); assert( LevelMax == LevelMin ); Vec_PtrForEachEntry( vNodes, pNode, i ) if ( Abc_ObjIsNode(pNode) ) pNode->Level = LevelMax - pNode->Level + 1; } // find the largest and the smallest levels LevelMin = 10000; LevelMax = -1; fHasCos = 0; Vec_PtrForEachEntry( vNodes, pNode, i ) { if ( Abc_ObjIsCo(pNode) ) { fHasCos = 1; continue; } if ( LevelMin > (int)pNode->Level ) LevelMin = pNode->Level; if ( LevelMax < (int)pNode->Level ) LevelMax = pNode->Level; } // set the level of the CO nodes if ( fHasCos ) { LevelMax++; Vec_PtrForEachEntry( vNodes, pNode, i ) { if ( Abc_ObjIsCo(pNode) ) pNode->Level = LevelMax; } } // write the DOT header fprintf( pFile, "# %s\n", "Network structure generated by ABC" ); fprintf( pFile, "\n" ); fprintf( pFile, "digraph network {\n" ); fprintf( pFile, "size = \"7.5,10\";\n" ); // fprintf( pFile, "size = \"10,8.5\";\n" ); // fprintf( pFile, "size = \"14,11\";\n" ); // fprintf( pFile, "page = \"8,11\";\n" ); // fprintf( pFile, "ranksep = 0.5;\n" ); // fprintf( pFile, "nodesep = 0.5;\n" ); fprintf( pFile, "center = true;\n" ); // fprintf( pFile, "orientation = landscape;\n" ); // fprintf( pFile, "edge [fontsize = 10];\n" ); // fprintf( pFile, "edge [dir = none];\n" ); fprintf( pFile, "edge [dir = back];\n" ); fprintf( pFile, "\n" ); // labels on the left of the picture fprintf( pFile, "{\n" ); fprintf( pFile, " node [shape = plaintext];\n" ); fprintf( pFile, " edge [style = invis];\n" ); fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); // generate node names with labels for ( Level = LevelMax; Level >= LevelMin; Level-- ) { // the visible node name fprintf( pFile, " Level%d", Level ); fprintf( pFile, " [label = " ); // label name fprintf( pFile, "\"" ); fprintf( pFile, "\"" ); fprintf( pFile, "];\n" ); } // genetate the sequence of visible/invisible nodes to mark levels fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); for ( Level = LevelMax; Level >= LevelMin; Level-- ) { // the visible node name fprintf( pFile, " Level%d", Level ); // the connector if ( Level != LevelMin ) fprintf( pFile, " ->" ); else fprintf( pFile, ";" ); } fprintf( pFile, "\n" ); fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); // generate title box on top fprintf( pFile, "{\n" ); fprintf( pFile, " rank = same;\n" ); fprintf( pFile, " LevelTitle1;\n" ); fprintf( pFile, " title1 [shape=plaintext,\n" ); fprintf( pFile, " fontsize=20,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); fprintf( pFile, "%s", "Network structure visualized by ABC" ); fprintf( pFile, "\\n" ); fprintf( pFile, "Benchmark \\\"%s\\\". ", pNtk->pName ); fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); // generate statistics box fprintf( pFile, "{\n" ); fprintf( pFile, " rank = same;\n" ); fprintf( pFile, " LevelTitle2;\n" ); fprintf( pFile, " title2 [shape=plaintext,\n" ); fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); if ( Abc_NtkObjNum(pNtk) == Vec_PtrSize(vNodes) ) fprintf( pFile, "The network contains %d logic nodes and %d latches.", Abc_NtkNodeNum(pNtk), Abc_NtkLatchNum(pNtk) ); else fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Abc_NtkCountLogicNodes(vNodes), LevelMax - LevelMin + 1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); // generate the POs if ( fHasCos ) { fprintf( pFile, "{\n" ); fprintf( pFile, " rank = same;\n" ); // the labeling node of this level fprintf( pFile, " Level%d;\n", LevelMax ); // generate the PO nodes Vec_PtrForEachEntry( vNodes, pNode, i ) { if ( !Abc_ObjIsCo(pNode) ) continue; fprintf( pFile, " Node%d [label = \"%s%s\"", pNode->Id, (Abc_ObjIsBi(pNode)? Abc_ObjName(Abc_ObjFanout0(pNode)):Abc_ObjName(pNode)), (Abc_ObjIsBi(pNode)? "_in":"") ); fprintf( pFile, ", shape = %s", (Abc_ObjIsBi(pNode)? "box":"invtriangle") ); if ( pNode->fMarkB ) fprintf( pFile, ", style = filled" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); } // generate nodes of each rank for ( Level = LevelMax - fHasCos; Level >= LevelMin && Level > 0; Level-- ) { fprintf( pFile, "{\n" ); fprintf( pFile, " rank = same;\n" ); // the labeling node of this level fprintf( pFile, " Level%d;\n", Level ); Vec_PtrForEachEntry( vNodes, pNode, i ) { if ( (int)pNode->Level != Level ) continue; if ( Abc_ObjFaninNum(pNode) == 0 ) continue; // fprintf( pFile, " Node%d [label = \"%d\"", pNode->Id, pNode->Id ); if ( Abc_NtkIsStrash(pNtk) ) pSopString = ""; else if ( Abc_NtkHasMapping(pNtk) && fGateNames ) pSopString = Mio_GateReadName(pNode->pData); else if ( Abc_NtkHasMapping(pNtk) ) pSopString = Abc_NtkPrintSop(Mio_GateReadSop(pNode->pData)); else pSopString = Abc_NtkPrintSop(pNode->pData); fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id, pSopString ); fprintf( pFile, ", shape = ellipse" ); if ( pNode->fMarkB ) fprintf( pFile, ", style = filled" ); fprintf( pFile, "];\n" ); } fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); } // generate the PI nodes if any if ( LevelMin == 0 ) { fprintf( pFile, "{\n" ); fprintf( pFile, " rank = same;\n" ); // the labeling node of this level fprintf( pFile, " Level%d;\n", LevelMin ); // generate the PO nodes Vec_PtrForEachEntry( vNodes, pNode, i ) { if ( !Abc_ObjIsCi(pNode) ) { // check if the costant node is present if ( Abc_ObjFaninNum(pNode) == 0 && Abc_ObjFanoutNum(pNode) > 0 ) { fprintf( pFile, " Node%d [label = \"Const%d\"", pNode->Id, Abc_NtkIsStrash(pNode->pNtk) || Abc_NodeIsConst1(pNode) ); fprintf( pFile, ", shape = ellipse" ); if ( pNode->fMarkB ) fprintf( pFile, ", style = filled" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } continue; } fprintf( pFile, " Node%d [label = \"%s\"", pNode->Id, (Abc_ObjIsBo(pNode)? Abc_ObjName(Abc_ObjFanin0(pNode)):Abc_ObjName(pNode)) ); fprintf( pFile, ", shape = %s", (Abc_ObjIsBo(pNode)? "box":"triangle") ); if ( pNode->fMarkB ) fprintf( pFile, ", style = filled" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); }