From 78fbd336aa584c4d285123ad18617aa9277016b4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 1 Oct 2005 08:01:00 -0700 Subject: Version abc51001 --- src/base/abc/abc.h | 3 +- src/base/abc/abcAig.c | 1 - src/base/abc/abcShow.c | 64 ++++++++++++++++- src/base/abci/abc.c | 58 +++++++++++----- src/base/abci/abcBalance.c | 161 +++++++++++++++++++++++++++++++++++++++++++ src/base/abci/abcCut.c | 164 ++++++++++++++++++++++++++++++++++++++++++-- src/base/abci/abcRewrite.c | 2 +- src/base/abcs/abcRetCore.c | 18 ++--- src/base/abcs/abcRetDelay.c | 50 ++++++++------ src/base/abcs/abcRetImpl.c | 14 ++-- src/base/abcs/abcRetUtil.c | 8 +++ src/base/abcs/abcs.h | 16 +++-- src/base/io/io.c | 2 +- src/base/io/io.h | 2 +- src/base/io/ioWriteDot.c | 29 +++++++- src/base/main/main.c | 5 +- 16 files changed, 520 insertions(+), 77 deletions(-) (limited to 'src/base') diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index 50787d9b..64df9fc5 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -439,7 +439,8 @@ extern bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fVerbose ); /*=== abcCut.c ==========================================================*/ extern void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj ); -extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj ); +extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fMulti ); +extern void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fFirst ); extern void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj ); extern void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj ); /*=== abcDfs.c ==========================================================*/ diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c index 639f4926..3f7f8d7c 100644 --- a/src/base/abc/abcAig.c +++ b/src/base/abc/abcAig.c @@ -1231,7 +1231,6 @@ void Abc_AigCheckFaninOrder( Abc_Aig_t * pMan ) { int i0 = Abc_ObjRegular(Abc_ObjChild0(pEnt))->Id; int i1 = Abc_ObjRegular(Abc_ObjChild1(pEnt))->Id; - int x = 0; printf( "Node %d has incorrect ordering of fanins.\n", pEnt->Id ); } } diff --git a/src/base/abc/abcShow.c b/src/base/abc/abcShow.c index e36f5219..cc8b90f6 100644 --- a/src/base/abc/abcShow.c +++ b/src/base/abc/abcShow.c @@ -111,13 +111,73 @@ void Abc_NtkShowAig( Abc_Ntk_t * pNtk ) Abc_NtkForEachObj( pNtk, pNode, i ) Vec_PtrPush( vNodes, pNode ); // write the DOT file - Io_WriteDot( pNtk, vNodes, NULL, FileNameDot ); + Io_WriteDot( pNtk, vNodes, NULL, FileNameDot, 0 ); Vec_PtrFree( vNodes ); // visualize the file Abc_ShowFile( FileNameDot ); } +/**Function************************************************************* + + Synopsis [Visualizes AIG with choices.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkShowMulti( Abc_Ntk_t * pNtk ) +{ + FILE * pFile; + Abc_Obj_t * pNode; + Vec_Ptr_t * vNodes; + char FileNameDot[200]; + int i; + extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk ); + extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk ); + extern void Abc_NtkBalanceLevel( Abc_Ntk_t * pNtk ); + + assert( Abc_NtkIsStrash(pNtk) ); + // create the file name + Abc_ShowGetFileName( pNtk->pName, FileNameDot ); + // check that the file can be opened + if ( (pFile = fopen( FileNameDot, "w" )) == NULL ) + { + fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot ); + return; + } + + // get the implication supergates + Abc_NtkBalanceAttach( pNtk ); + // set the levels based on the implication supergates + Abc_NtkBalanceLevel( pNtk ); + + // collect all nodes that are roots + vNodes = Vec_PtrAlloc( 100 ); + Abc_NtkForEachCi( pNtk, pNode, i ) + Vec_PtrPush( vNodes, pNode ); + Abc_NtkForEachNode( pNtk, pNode, i ) + if ( pNode->pCopy || Abc_ObjFaninNum(pNode) == 0 ) + Vec_PtrPush( vNodes, pNode ); + Abc_NtkForEachPo( pNtk, pNode, i ) + Vec_PtrPush( vNodes, pNode ); + + // write the DOT file + Io_WriteDot( pNtk, vNodes, NULL, FileNameDot, 1 ); + Vec_PtrFree( vNodes ); + + // undo the supergates + Abc_NtkBalanceDetach( pNtk ); + // set the normal levels + Abc_NtkGetLevelNum( pNtk ); + + // visualize the file + Abc_ShowFile( FileNameDot ); +} + /**Function************************************************************* Synopsis [Visualizes a reconvergence driven cut at the node.] @@ -170,7 +230,7 @@ void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax ) // add the root node to the cone (for visualization) Vec_PtrPush( vCutSmall, pNode ); // write the DOT file - Io_WriteDot( pNode->pNtk, vInside, vCutSmall, FileNameDot ); + Io_WriteDot( pNode->pNtk, vInside, vCutSmall, FileNameDot, 0 ); // stop the cut computation manager Abc_NtkManCutStop( p ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 38472a0c..4e2e14a2 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -932,20 +932,24 @@ int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv ) FILE * pOut, * pErr; Abc_Ntk_t * pNtk; int c; + int fMulti; extern void Abc_NtkShowAig( Abc_Ntk_t * pNtk ); + extern void Abc_NtkShowMulti( Abc_Ntk_t * pNtk ); pNtk = Abc_FrameReadNet(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); // set defaults + fMulti = 0; util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF ) + while ( ( c = util_getopt( argc, argv, "mh" ) ) != EOF ) { switch ( c ) { - case 'h': - goto usage; + case 'm': + fMulti ^= 1; + break; default: goto usage; } @@ -962,7 +966,16 @@ int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Visualizing AIG can only be done for AIGs (run \"strash\" or \"seq\").\n" ); return 1; } - Abc_NtkShowAig( pNtk ); + if ( fMulti && !Abc_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "Visualizing multi-input ANDs cannot be done for sequential network (run \"unseq\").\n" ); + return 1; + } + + if ( !fMulti ) + Abc_NtkShowAig( pNtk ); + else + Abc_NtkShowMulti( pNtk ); return 0; usage: @@ -972,6 +985,7 @@ usage: fprintf( pErr, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" ); fprintf( pErr, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" ); #endif + fprintf( pErr, "\t-m : toggles visualization of multi-input ANDs [default = %s].\n", fMulti? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; } @@ -1300,8 +1314,8 @@ usage: fprintf( pErr, "\t-F num : the maximum fanin size after renoding [default = %d]\n", nFaninMax ); fprintf( pErr, "\t-T num : the threshold for AIG node duplication [default = %d]\n", nThresh ); fprintf( pErr, "\t (an AIG node is the root of a new node after renoding\n" ); - fprintf( pErr, "\t if doing so prevents duplication of more than %d AIG nodes,\n", nThresh ); - fprintf( pErr, "\t that is, if [(numFanouts(Node)-1) * size(MFFC(Node))] > %d)\n", nThresh ); + fprintf( pErr, "\t if this leads to duplication of no more than %d AIG nodes,\n", nThresh ); + fprintf( pErr, "\t that is, if [(numFanouts(Node)-1) * size(MFFC(Node))] <= %d)\n", nThresh ); fprintf( pErr, "\t-m : creates multi-input AND graph [default = %s]\n", fMulti? "yes": "no" ); fprintf( pErr, "\t-s : creates a simple AIG (no renoding) [default = %s]\n", fSimple? "yes": "no" ); fprintf( pErr, "\t-c : performs renoding to derive the CNF [default = %s]\n", fCnf? "yes": "no" ); @@ -2733,13 +2747,14 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) // set defaults memset( pParams, 0, sizeof(Cut_Params_t) ); pParams->nVarsMax = 5; // the max cut size ("k" of the k-feasible cuts) - pParams->nKeepMax = 250; // the max number of cuts kept at a node + pParams->nKeepMax = 1000; // the max number of cuts kept at a node pParams->fTruth = 0; // compute truth tables pParams->fFilter = 1; // filter dominated cuts pParams->fDrop = 0; // drop cuts on the fly + pParams->fMulti = 0; // use multi-input AND-gates pParams->fVerbose = 0; // the verbosiness flag util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "KMtfdvh" ) ) != EOF ) + while ( ( c = util_getopt( argc, argv, "KMtfdmvh" ) ) != EOF ) { switch ( c ) { @@ -2774,6 +2789,9 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'd': pParams->fDrop ^= 1; break; + case 'm': + pParams->fMulti ^= 1; + break; case 'v': pParams->fVerbose ^= 1; break; @@ -2800,13 +2818,14 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdvh]\n" ); + fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdmvh]\n" ); fprintf( pErr, "\t computes k-feasible cuts for the AIG\n" ); fprintf( pErr, "\t-K num : max number of leaves (4 <= num <= 6) [default = %d]\n", pParams->nVarsMax ); fprintf( pErr, "\t-M num : max number of cuts stored at a node [default = %d]\n", pParams->nKeepMax ); fprintf( pErr, "\t-t : toggle truth table computation [default = %s]\n", pParams->fTruth? "yes": "no" ); fprintf( pErr, "\t-f : toggle filtering of duplicated/dominated [default = %s]\n", pParams->fFilter? "yes": "no" ); fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "yes": "no" ); + fprintf( pErr, "\t-m : toggle using multi-input AND-gates [default = %s]\n", pParams->fMulti? "yes": "no" ); fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; @@ -2839,9 +2858,9 @@ int Abc_CommandScut( Abc_Frame_t * pAbc, int argc, char ** argv ) // set defaults memset( pParams, 0, sizeof(Cut_Params_t) ); pParams->nVarsMax = 5; // the max cut size ("k" of the k-feasible cuts) - pParams->nKeepMax = 250; // the max number of cuts kept at a node + pParams->nKeepMax = 1000; // the max number of cuts kept at a node pParams->fTruth = 0; // compute truth tables - pParams->fFilter = 0; // filter dominated cuts + pParams->fFilter = 1; // filter dominated cuts pParams->fSeq = 1; // compute sequential cuts pParams->fVerbose = 0; // the verbosiness flag util_getopt_reset(); @@ -4347,8 +4366,7 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) int fForward; int fBackward; int fInitial; - - extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk ); + int fVerbose; pNtk = Abc_FrameReadNet(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -4358,8 +4376,9 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) fForward = 0; fBackward = 0; fInitial = 0; + fVerbose = 0; util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "fbih" ) ) != EOF ) + while ( ( c = util_getopt( argc, argv, "fbivh" ) ) != EOF ) { switch ( c ) { @@ -4372,6 +4391,9 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'i': fInitial ^= 1; break; + case 'v': + fVerbose ^= 1; + break; case 'h': goto usage; default: @@ -4393,13 +4415,13 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) // get the new network if ( fForward ) - Abc_NtkSeqRetimeForward( pNtk ); + Abc_NtkSeqRetimeForward( pNtk, fVerbose ); else if ( fBackward ) - Abc_NtkSeqRetimeBackward( pNtk ); + Abc_NtkSeqRetimeBackward( pNtk, fVerbose ); else if ( fInitial ) - Abc_NtkSeqRetimeInitial( pNtk ); + Abc_NtkSeqRetimeInitial( pNtk, fVerbose ); else - Abc_NtkSeqRetimeDelay( pNtk ); + Abc_NtkSeqRetimeDelay( pNtk, fVerbose ); return 0; usage: diff --git a/src/base/abci/abcBalance.c b/src/base/abci/abcBalance.c index 035a2d1a..c612a1ce 100644 --- a/src/base/abci/abcBalance.c +++ b/src/base/abci/abcBalance.c @@ -242,6 +242,167 @@ int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, } + + +/**Function************************************************************* + + Synopsis [Collects the nodes in the implication supergate.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NodeFindCone_rec( Abc_Obj_t * pNode ) +{ + Vec_Ptr_t * vNodes; + Abc_Obj_t * pNodeC, * pNodeT, * pNodeE; + int RetValue, i; + assert( !Abc_ObjIsComplement(pNode) ); + if ( Abc_ObjIsCi(pNode) ) + return NULL; + // start the new array + vNodes = Vec_PtrAlloc( 4 ); + // if the node is the MUX collect its fanins + if ( Abc_NodeIsMuxType(pNode) ) + { + pNodeC = Abc_NodeRecognizeMux( pNode, &pNodeT, &pNodeE ); + Vec_PtrPush( vNodes, Abc_ObjRegular(pNodeC) ); + Vec_PtrPushUnique( vNodes, Abc_ObjRegular(pNodeT) ); + Vec_PtrPushUnique( vNodes, Abc_ObjRegular(pNodeE) ); + } + else + { + // collect the nodes in the implication supergate + RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, 1 ); + assert( vNodes->nSize > 1 ); + // unmark the visited nodes + Vec_PtrForEachEntry( vNodes, pNode, i ) + Abc_ObjRegular(pNode)->fMarkB = 0; + // if we found the node and its complement in the same implication supergate, + // return empty set of nodes (meaning that we should use constant-0 node) + if ( RetValue == -1 ) + vNodes->nSize = 0; + } + // call for the fanin + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + pNode = Abc_ObjRegular(pNode); + if ( pNode->pCopy ) + continue; + pNode->pCopy = (Abc_Obj_t *)Abc_NodeFindCone_rec( pNode ); + } + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Attaches the implication supergates to internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + int i; + Abc_NtkCleanCopy( pNtk ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + pNode = Abc_ObjFanin0(pNode); + if ( pNode->pCopy ) + continue; + pNode->pCopy = (Abc_Obj_t *)Abc_NodeFindCone_rec( pNode ); + } +} + +/**Function************************************************************* + + Synopsis [Attaches the implication supergates to internal nodes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + int i; + Abc_NtkForEachNode( pNtk, pNode, i ) + if ( pNode->pCopy ) + { + Vec_PtrFree( (Vec_Ptr_t *)pNode->pCopy ); + pNode->pCopy = NULL; + } +} + +/**Function************************************************************* + + Synopsis [Compute levels of implication supergates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkBalanceLevel_rec( Abc_Obj_t * pNode ) +{ + Vec_Ptr_t * vSuper; + Abc_Obj_t * pFanin; + int i, LevelMax; + assert( !Abc_ObjIsComplement(pNode) ); + if ( pNode->Level > 0 ) + return pNode->Level; + if ( Abc_ObjIsCi(pNode) ) + return 0; + vSuper = (Vec_Ptr_t *)pNode->pCopy; + assert( vSuper != NULL ); + LevelMax = 0; + Vec_PtrForEachEntry( vSuper, pFanin, i ) + { + pFanin = Abc_ObjRegular(pFanin); + Abc_NtkBalanceLevel_rec(pFanin); + if ( LevelMax < (int)pFanin->Level ) + LevelMax = pFanin->Level; + } + pNode->Level = LevelMax + 1; + return pNode->Level; +} + + +/**Function************************************************************* + + Synopsis [Compute levels of implication supergates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkBalanceLevel( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + int i; + Abc_NtkForEachObj( pNtk, pNode, i ) + pNode->Level = 0; + Abc_NtkForEachCo( pNtk, pNode, i ) + Abc_NtkBalanceLevel_rec( Abc_ObjFanin0(pNode) ); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abcCut.c b/src/base/abci/abcCut.c index 64dec4a4..7cc3d65b 100644 --- a/src/base/abci/abcCut.c +++ b/src/base/abci/abcCut.c @@ -25,6 +25,9 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +static void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq ); +static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// @@ -49,7 +52,12 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) int i; int clk = clock(); + extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk ); + extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk ); + assert( Abc_NtkIsStrash(pNtk) ); + if ( pParams->fMulti ) + Abc_NtkBalanceAttach(pNtk); // start the manager pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); @@ -76,7 +84,13 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) if ( Abc_NodeIsConst(pObj) ) continue; // compute the cuts to the internal node - Abc_NodeGetCuts( p, pObj ); + Abc_NodeGetCuts( p, pObj, pParams->fMulti ); + // consider dropping the fanins cuts + if ( pParams->fDrop ) + { + Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); + Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) ); + } // add cuts due to choices if ( Abc_NodeIsAigChoice(pObj) ) { @@ -88,7 +102,11 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) } Vec_PtrFree( vNodes ); Vec_IntFree( vChoices ); + if ( pParams->fMulti ) + Abc_NtkBalanceDetach(pNtk); PRT( "Total", clock() - clk ); +Abc_NtkPrintCuts_( p, pNtk, 0 ); +// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk ); return p; } @@ -105,7 +123,68 @@ PRT( "Total", clock() - clk ); ***********************************************************************/ Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) { - return NULL; + Cut_Man_t * p; + Abc_Obj_t * pObj; + int i, nIters, fStatus; + int clk = clock(); + + assert( Abc_NtkIsSeq(pNtk) ); + assert( pParams->fSeq ); + + // start the manager + pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); + pParams->nCutSet = pNtk->vLats->nSize; + p = Cut_ManStart( pParams ); + + // set cuts for PIs + Abc_NtkForEachPi( pNtk, pObj, i ) + Cut_NodeSetTriv( p, pObj->Id ); + // label the cutset nodes and set their number in the array + // assign the elementary cuts to the cutset nodes + Abc_SeqForEachCutsetNode( pNtk, pObj, i ) + { + assert( pObj->fMarkC == 0 ); + pObj->fMarkC = 1; + pObj->pCopy = (Abc_Obj_t *)i; + Cut_NodeSetTriv( p, pObj->Id ); + } + + // process the nodes + for ( nIters = 0; nIters < 10; nIters++ ) + { +//printf( "ITERATION %d:\n", nIters ); + // compute the cuts for the internal nodes + Abc_AigForEachAnd( pNtk, pObj, i ) + Abc_NodeGetCutsSeq( p, pObj, nIters==0 ); +Abc_NtkPrintCuts( p, pNtk, 1 ); + // merge the new cuts with the old cuts + Abc_NtkForEachPi( pNtk, pObj, i ) + Cut_NodeNewMergeWithOld( p, pObj->Id ); + Abc_AigForEachAnd( pNtk, pObj, i ) + Cut_NodeNewMergeWithOld( p, pObj->Id ); + // for the cutset, merge temp with new + fStatus = 0; + Abc_SeqForEachCutsetNode( pNtk, pObj, i ) + fStatus |= Cut_NodeTempTransferToNew( p, pObj->Id, i ); + if ( fStatus == 0 ) + break; + } + + // if the status is not finished, transfer new to old for the cutset + Abc_SeqForEachCutsetNode( pNtk, pObj, i ) + Cut_NodeNewMergeWithOld( p, pObj->Id ); + + // transfer the old cuts to the new positions + Abc_NtkForEachObj( pNtk, pObj, i ) + Cut_NodeOldTransferToNew( p, pObj->Id ); + + // unlabel the cutset nodes + Abc_SeqForEachCutsetNode( pNtk, pObj, i ) + pObj->fMarkC = 0; +PRT( "Total", clock() - clk ); +printf( "Converged after %d iterations.\n", nIters ); +Abc_NtkPrintCuts( p, pNtk, 1 ); + return p; } /**Function************************************************************* @@ -126,7 +205,7 @@ void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj ) return pList; Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj) ); Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj) ); - return Abc_NodeGetCuts( p, pObj ); + return Abc_NodeGetCuts( p, pObj, 0 ); } /**Function************************************************************* @@ -140,10 +219,35 @@ void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj ) SeeAlso [] ***********************************************************************/ -void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj ) +void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fMulti ) { + int fTriv = (!fMulti) || (pObj->pCopy != NULL); + assert( Abc_NtkIsStrash(pObj->pNtk) ); + assert( Abc_ObjFaninNum(pObj) == 2 ); return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), - Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); + Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), 1, 1, fTriv ); +} + +/**Function************************************************************* + + Synopsis [Computes the cuts for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv ) +{ + int CutSetNum; + assert( Abc_NtkIsSeq(pObj->pNtk) ); + assert( Abc_ObjFaninNum(pObj) == 2 ); +// fTriv = pObj->fMarkC ? 0 : fTriv; + CutSetNum = pObj->fMarkC ? (int)pObj->pCopy : -1; + Cut_NodeComputeCutsSeq( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), + Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), Abc_ObjFaninL0(pObj), Abc_ObjFaninL1(pObj), fTriv, CutSetNum ); } /**Function************************************************************* @@ -159,7 +263,7 @@ void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj ) ***********************************************************************/ void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj ) { - return Cut_NodeReadCuts( p, pObj->Id ); + return Cut_NodeReadCutsNew( p, pObj->Id ); } /**Function************************************************************* @@ -178,6 +282,54 @@ void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj ) Cut_NodeFreeCuts( p, pObj->Id ); } +/**Function************************************************************* + + Synopsis [Computes the cuts for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq ) +{ + Cut_Man_t * pMan = p; + Cut_Cut_t * pList; + Abc_Obj_t * pObj; + int i; + printf( "Cuts of the network:\n" ); + Abc_NtkForEachObj( pNtk, pObj, i ) + { + pList = Abc_NodeReadCuts( p, pObj ); + printf( "Node %s:\n", Abc_ObjName(pObj) ); + Cut_CutPrintList( pList, fSeq ); + } +} + +/**Function************************************************************* + + Synopsis [Computes the cuts for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq ) +{ + Cut_Man_t * pMan = p; + Cut_Cut_t * pList; + Abc_Obj_t * pObj; + pObj = Abc_NtkObj( pNtk, 2 * Abc_NtkObjNum(pNtk) / 3 ); + pList = Abc_NodeReadCuts( p, pObj ); + printf( "Node %s:\n", Abc_ObjName(pObj) ); + Cut_CutPrintList( pList, fSeq ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c index b70d30e6..a14718c4 100644 --- a/src/base/abci/abcRewrite.c +++ b/src/base/abci/abcRewrite.c @@ -192,7 +192,7 @@ void Abc_NodePrintCuts( Abc_Obj_t * pNode ) { Extra_PrintBinary( stdout, (unsigned *)&pCut->uSign, 16 ); printf( " " ); - Cut_CutPrint( pCut ); + Cut_CutPrint( pCut, 0 ); printf( "\n" ); } } diff --git a/src/base/abcs/abcRetCore.c b/src/base/abcs/abcRetCore.c index f6ba0c59..22735597 100644 --- a/src/base/abcs/abcRetCore.c +++ b/src/base/abcs/abcRetCore.c @@ -46,7 +46,7 @@ SeeAlso [] ***********************************************************************/ -void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk ) +void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fVerbose ) { Vec_Ptr_t * vMoves; Abc_Obj_t * pNode; @@ -72,7 +72,7 @@ void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk ) +void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose ) { Vec_Ptr_t * vMoves; Abc_Obj_t * pNode; @@ -83,7 +83,7 @@ void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk ) Vec_PtrForEachEntryReverse( vMoves, pNode, i ) Abc_ObjRetimeForwardTry( pNode, 1 ); // implement this backward retiming - RetValue = Abc_NtkImplementRetimingBackward( pNtk, vMoves ); + RetValue = Abc_NtkImplementRetimingBackward( pNtk, vMoves, fVerbose ); Vec_PtrFree( vMoves ); if ( RetValue == 0 ) printf( "Retiming completed but initial state computation has failed.\n" ); @@ -100,14 +100,14 @@ void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk ) +void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fVerbose ) { Vec_Str_t * vLags; int RetValue; // get the retiming vector - vLags = Abc_NtkSeqRetimeDelayLags( pNtk ); + vLags = Abc_NtkSeqRetimeDelayLags( pNtk, fVerbose ); // implement this retiming - RetValue = Abc_NtkImplementRetiming( pNtk, vLags ); + RetValue = Abc_NtkImplementRetiming( pNtk, vLags, fVerbose ); Vec_StrFree( vLags ); if ( RetValue == 0 ) printf( "Retiming completed but initial state computation has failed.\n" ); @@ -124,14 +124,14 @@ void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -void Abc_NtkSeqRetimeInitial( Abc_Ntk_t * pNtk ) +void Abc_NtkSeqRetimeInitial( Abc_Ntk_t * pNtk, int fVerbose ) { Vec_Str_t * vLags; int RetValue; // get the retiming vector - vLags = Abc_NtkSeqRetimeDelayLags( pNtk ); + vLags = Abc_NtkSeqRetimeDelayLags( pNtk, fVerbose ); // implement this retiming - RetValue = Abc_NtkImplementRetiming( pNtk, vLags ); + RetValue = Abc_NtkImplementRetiming( pNtk, vLags, fVerbose ); Vec_StrFree( vLags ); if ( RetValue == 0 ) printf( "Retiming completed but initial state computation has failed.\n" ); diff --git a/src/base/abcs/abcRetDelay.c b/src/base/abcs/abcRetDelay.c index 277e7750..0697c699 100644 --- a/src/base/abcs/abcRetDelay.c +++ b/src/base/abcs/abcRetDelay.c @@ -31,8 +31,8 @@ static inline void Abc_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { Vec_IntW static inline int Abc_NodeGetLag( int LValue, int Fi ) { return (LValue + 256*Fi)/Fi - 256 - (int)(LValue % Fi == 0); } // the internal procedures -static int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax ); -static int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi ); +static int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose ); +static int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose ); static int Abc_NodeUpdateLValue( Abc_Obj_t * pObj, int Fi ); // node status after updating its arrival time @@ -55,15 +55,15 @@ static void Abc_RetimingExperiment( Abc_Ntk_t * pNtk, Vec_Str_t * vLags ); SeeAlso [] ***********************************************************************/ -Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk ) +Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose ) { Vec_Str_t * vLags; Abc_Obj_t * pNode; - int i, FiMax, FiBest; + int i, FiMax, FiBest, RetValue; assert( Abc_NtkIsSeq( pNtk ) ); // start storage for sequential arrival times -// assert( pNtk->pData == NULL ); + assert( pNtk->pData == NULL ); pNtk->pData = Vec_IntAlloc( 0 ); // get the upper bound on the clock period @@ -75,11 +75,17 @@ Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk ) FiMax += 2; // make sure this clock period is feasible - assert( Abc_NtkRetimeForPeriod( pNtk, FiMax ) ); + assert( Abc_NtkRetimeForPeriod( pNtk, FiMax, fVerbose ) ); // search for the optimal clock period between 0 and nLevelMax - FiBest = Abc_NtkRetimeSearch_rec( pNtk, 0, FiMax ); + FiBest = Abc_NtkRetimeSearch_rec( pNtk, 0, FiMax, fVerbose ); + + // recompute the best LValues + RetValue = Abc_NtkRetimeForPeriod( pNtk, FiBest, fVerbose ); + assert( RetValue ); + // print the result + if ( fVerbose ) printf( "The best clock period is %3d.\n", FiBest ); // convert to lags @@ -91,9 +97,6 @@ Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk ) Abc_AigForEachAnd( pNtk, pNode, i ) printf( "%d=%d ", i, Abc_NodeReadLValue(pNode) ); printf( "\n" ); -*/ - -/* printf( "Lags : " ); Abc_AigForEachAnd( pNtk, pNode, i ) if ( Vec_StrEntry(vLags,i) != 0 ) @@ -101,8 +104,6 @@ Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk ) printf( "\n" ); */ -// Abc_RetimingExperiment( pNtk, vLags ); - // free storage Vec_IntFree( pNtk->pData ); pNtk->pData = NULL; @@ -120,17 +121,17 @@ Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk ) SeeAlso [] ***********************************************************************/ -int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax ) +int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, int FiMin, int FiMax, int fVerbose ) { int Median; assert( FiMin < FiMax ); if ( FiMin + 1 == FiMax ) return FiMax; Median = FiMin + (FiMax - FiMin)/2; - if ( Abc_NtkRetimeForPeriod( pNtk, Median ) ) - return Abc_NtkRetimeSearch_rec( pNtk, FiMin, Median ); // Median is feasible + if ( Abc_NtkRetimeForPeriod( pNtk, Median, fVerbose ) ) + return Abc_NtkRetimeSearch_rec( pNtk, FiMin, Median, fVerbose ); // Median is feasible else - return Abc_NtkRetimeSearch_rec( pNtk, Median, FiMax ); // Median is infeasible + return Abc_NtkRetimeSearch_rec( pNtk, Median, FiMax, fVerbose ); // Median is infeasible } /**Function************************************************************* @@ -213,7 +214,7 @@ int Abc_NtkRetimeForPeriod2( Abc_Ntk_t * pNtk, int Fi ) printf( "Period = %3d. Updated nodes = %6d. Infeasible %s\n", Fi, vFrontier->nSize, pReason ); else printf( "Period = %3d. Updated nodes = %6d. Feasible\n", Fi, vFrontier->nSize ); -// Vec_PtrFree( vFrontier ); + Vec_PtrFree( vFrontier ); return RetValue != ABC_UPDATE_FAIL; } @@ -228,7 +229,7 @@ int Abc_NtkRetimeForPeriod2( Abc_Ntk_t * pNtk, int Fi ) SeeAlso [] ***********************************************************************/ -int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi ) +int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi, int fVerbose ) { Abc_Obj_t * pObj; int i, c, RetValue, fChange, Counter; @@ -237,11 +238,13 @@ int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi ) // set l-values of all nodes to be minus infinity Vec_IntFill( pNtk->pData, Abc_NtkObjNumMax(pNtk), -ABC_INFINITY ); + // set l-values for the constant and PIs pObj = Abc_NtkObj( pNtk, 0 ); Abc_NodeSetLValue( pObj, 0 ); Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NodeSetLValue( pObj, 0 ); + // update all values iteratively Counter = 0; for ( c = 0; c < 20; c++ ) { @@ -272,10 +275,13 @@ int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, int Fi ) } // report the results - if ( RetValue == ABC_UPDATE_FAIL ) - printf( "Period = %3d. Iterations = %3d. Updates = %6d. Infeasible %s\n", Fi, c, Counter, pReason ); - else - printf( "Period = %3d. Iterations = %3d. Updates = %6d. Feasible\n", Fi, c, Counter ); + if ( fVerbose ) + { + if ( RetValue == ABC_UPDATE_FAIL ) + printf( "Period = %3d. Iterations = %3d. Updates = %6d. Infeasible %s\n", Fi, c, Counter, pReason ); + else + printf( "Period = %3d. Iterations = %3d. Updates = %6d. Feasible\n", Fi, c, Counter ); + } return RetValue != ABC_UPDATE_FAIL; } diff --git a/src/base/abcs/abcRetImpl.c b/src/base/abcs/abcRetImpl.c index 0082ff22..93d5566d 100644 --- a/src/base/abcs/abcRetImpl.c +++ b/src/base/abcs/abcRetImpl.c @@ -44,7 +44,7 @@ static void Abc_NtkRetimeSetInitialValues( Abc_Ntk_t * pNtk, stmm_table * tTable SeeAlso [] ***********************************************************************/ -int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags ) +int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose ) { Vec_Int_t * vSteps; Vec_Ptr_t * vMoves; @@ -53,8 +53,10 @@ int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags ) // forward retiming vSteps = Abc_NtkUtilRetimingSplit( vLags, 1 ); // translate each set of steps into moves + if ( fVerbose ) printf( "The number of forward steps = %6d.\n", Vec_IntSize(vSteps) ); vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 1 ); + if ( fVerbose ) printf( "The number of forward moves = %6d.\n", Vec_PtrSize(vMoves) ); // implement this retiming Abc_NtkImplementRetimingForward( pNtk, vMoves ); @@ -64,11 +66,13 @@ int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags ) // backward retiming vSteps = Abc_NtkUtilRetimingSplit( vLags, 0 ); // translate each set of steps into moves + if ( fVerbose ) printf( "The number of backward steps = %6d.\n", Vec_IntSize(vSteps) ); vMoves = Abc_NtkUtilRetimingGetMoves( pNtk, vSteps, 0 ); + if ( fVerbose ) printf( "The number of backward moves = %6d.\n", Vec_PtrSize(vMoves) ); // implement this retiming - RetValue = Abc_NtkImplementRetimingBackward( pNtk, vMoves ); + RetValue = Abc_NtkImplementRetimingBackward( pNtk, vMoves, fVerbose ); Vec_IntFree( vSteps ); Vec_PtrFree( vMoves ); return RetValue; @@ -156,7 +160,7 @@ void Abc_ObjRetimeForward( Abc_Obj_t * pObj ) SeeAlso [] ***********************************************************************/ -int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves ) +int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int fVerbose ) { Abc_RetEdge_t RetEdge; stmm_table * tTable; @@ -216,6 +220,7 @@ int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves ) Abc_NtkDelete( pNtkProb ); Vec_IntFree( vValues ); + if ( fVerbose ) printf( "The number of ANDs in the AIG = %5d.\n", Abc_NtkNodeNum(pNtkMiter) ); // transform the miter into a logic network for efficient CNF construction @@ -225,6 +230,7 @@ int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves ) // solve the miter clk = clock(); RetValue = Abc_NtkMiterSat( pNtkCnf, 30, 0 ); +if ( fVerbose ) if ( clock() - clk > 500 ) { PRT( "SAT solving time", clock() - clk ); @@ -289,7 +295,7 @@ int Abc_ObjRetimeBackward( Abc_Obj_t * pObj, Abc_Ntk_t * pNtkNew, stmm_table * t // consider the case when all fanout latchs have don't-care values // the new values on the fanin edges will be don't-cares if ( !fMet0 && !fMet1 && !fMetN ) - { + { // update the fanout edges Abc_ObjForEachFanout( pObj, pFanout, i ) Abc_ObjFaninLDeleteLast( pFanout, Abc_ObjEdgeNum(pObj, pFanout) ); diff --git a/src/base/abcs/abcRetUtil.c b/src/base/abcs/abcRetUtil.c index b8f2cf25..94825c25 100644 --- a/src/base/abcs/abcRetUtil.c +++ b/src/base/abcs/abcRetUtil.c @@ -175,6 +175,14 @@ Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vSteps, b if ( !fChange ) { printf( "Warning: %d strange steps.\n", Vec_IntSize(vSteps) ); + /* + Vec_IntForEachEntry( vSteps, Number, i ) + { + RetStep = Abc_Int2RetStep( Number ); + printf( "%d(%d) ", RetStep.iNode, RetStep.nLatches ); + } + printf( "\n" ); + */ break; } } diff --git a/src/base/abcs/abcs.h b/src/base/abcs/abcs.h index 9e0669d4..fb45efba 100644 --- a/src/base/abcs/abcs.h +++ b/src/base/abcs/abcs.h @@ -214,6 +214,8 @@ static inline void Abc_ObjFaninLInsertLast( Abc_Obj_t * pObj, int Edge, Abc_Init unsigned EntryNew = EntryCur | (Init << (2 * Abc_ObjFaninL(pObj, Edge))); assert( Init >= 0 && Init < 4 ); assert( Abc_ObjFaninL(pObj, Edge) < ABC_MAX_EDGE_LATCH ); + if ( Abc_ObjFaninL(pObj, Edge) >= ABC_MAX_EDGE_LATCH ) + printf( "The limit on latched on the edge (%d) is exceeded.\n", ABC_MAX_EDGE_LATCH ); Abc_ObjFaninLSetInit( pObj, Edge, EntryNew ); Abc_ObjAddFaninL( pObj, Edge, 1 ); } @@ -293,16 +295,16 @@ static inline void Abc_ObjRetimeBackwardTry( Abc_Obj_t * pObj, int nLatches ) //////////////////////////////////////////////////////////////////////// /*=== abcRetCore.c ===========================================================*/ -extern void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk ); -extern void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk ); -extern void Abc_NtkSeqRetimeInitial( Abc_Ntk_t * pNtk ); -extern void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk ); +extern void Abc_NtkSeqRetimeForward( Abc_Ntk_t * pNtk, int fVerbose ); +extern void Abc_NtkSeqRetimeBackward( Abc_Ntk_t * pNtk, int fVerbose ); +extern void Abc_NtkSeqRetimeInitial( Abc_Ntk_t * pNtk, int fVerbose ); +extern void Abc_NtkSeqRetimeDelay( Abc_Ntk_t * pNtk, int fVerbose ); /*=== abcRetDelay.c ==========================================================*/ -extern Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk ); +extern Vec_Str_t * Abc_NtkSeqRetimeDelayLags( Abc_Ntk_t * pNtk, int fVerbose ); /*=== abcRetImpl.c ===========================================================*/ -extern int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags ); +extern int Abc_NtkImplementRetiming( Abc_Ntk_t * pNtk, Vec_Str_t * vLags, int fVerbose ); extern void Abc_NtkImplementRetimingForward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves ); -extern int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves ); +extern int Abc_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int fVerbose ); /*=== abcRetUtil.c ===========================================================*/ extern Vec_Ptr_t * Abc_NtkUtilRetimingTry( Abc_Ntk_t * pNtk, bool fForward ); extern Vec_Ptr_t * Abc_NtkUtilRetimingGetMoves( Abc_Ntk_t * pNtk, Vec_Int_t * vNodes, bool fForward ); diff --git a/src/base/io/io.c b/src/base/io/io.c index 7a6ca49f..2f7bd229 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -891,7 +891,7 @@ int IoCommandWriteDot( Abc_Frame_t * pAbc, int argc, char **argv ) FileName = argv[util_optind]; // write the file vNodes = Abc_NtkCollectObjects( pAbc->pNtkCur ); - Io_WriteDot( pAbc->pNtkCur, vNodes, NULL, FileName ); + Io_WriteDot( pAbc->pNtkCur, vNodes, NULL, FileName, 0 ); Vec_PtrFree( vNodes ); return 0; diff --git a/src/base/io/io.h b/src/base/io/io.h index 6bf3a85c..a5aae529 100644 --- a/src/base/io/io.h +++ b/src/base/io/io.h @@ -76,7 +76,7 @@ extern int Io_WriteBench( Abc_Ntk_t * pNtk, char * FileName ); /*=== abcWriteCnf.c ==========================================================*/ extern int Io_WriteCnf( Abc_Ntk_t * pNtk, char * FileName ); /*=== abcWriteDot.c ==========================================================*/ -extern void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName ); +extern void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fMulti ); /*=== abcWriteEqn.c ==========================================================*/ extern void Io_WriteEqn( Abc_Ntk_t * pNtk, char * pFileName ); /*=== abcWriteGml.c ==========================================================*/ diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c index cd297db7..cf4e3d15 100644 --- a/src/base/io/ioWriteDot.c +++ b/src/base/io/ioWriteDot.c @@ -31,7 +31,7 @@ /**Function************************************************************* - Synopsis [Writes the graph structure of AIG in DOT.] + Synopsis [Writes the graph structure of AIG for DOT.] Description [Useful for graph visualization using tools such as GraphViz: http://www.graphviz.org/] @@ -41,7 +41,7 @@ SeeAlso [] ***********************************************************************/ -void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName ) +void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fMulti ) { FILE * pFile; Abc_Obj_t * pNode, * pTemp, * pPrev; @@ -177,7 +177,7 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); - fprintf( pFile, "The set contains %d nodes and spans %d levels.", vNodes->nSize, LevelMax - LevelMin ); + fprintf( pFile, "The set contains %d nodes and spans %d levels.", vNodes->nSize, LevelMax - LevelMin + 1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); @@ -284,6 +284,29 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, { if ( Abc_ObjFaninNum(pNode) == 0 ) continue; + if ( fMulti && Abc_ObjIsNode(pNode) ) + { + Vec_Ptr_t * vSuper; + Abc_Obj_t * pFanin; + int k, fCompl; + vSuper = (Vec_Ptr_t *)pNode->pCopy; + assert( vSuper != NULL ); + Vec_PtrForEachEntry( vSuper, pFanin, k ) + { + fCompl = Abc_ObjIsComplement(pFanin); + pFanin = Abc_ObjRegular(pFanin); + if ( !pFanin->fMarkC ) + continue; + fprintf( pFile, "Node%d", pNode->Id ); + fprintf( pFile, " -> " ); + fprintf( pFile, "Node%d%s", pFanin->Id, (Abc_ObjIsLatch(pFanin)? "_out":"") ); + fprintf( pFile, " [" ); + fprintf( pFile, "style = %s", fCompl? "dotted" : "bold" ); + fprintf( pFile, "]" ); + fprintf( pFile, ";\n" ); + } + continue; + } // generate the edge from this node to the next if ( Abc_ObjFanin0(pNode)->fMarkC ) { diff --git a/src/base/main/main.c b/src/base/main/main.c index 6668d088..9311e9ea 100644 --- a/src/base/main/main.c +++ b/src/base/main/main.c @@ -53,11 +53,14 @@ int main( int argc, char * argv[] ) char * sCommand, * sOutFile, * sInFile; int fStatus = 0; bool fBatch, fInitSource, fInitRead, fFinalWrite; - + // added to detect memory leaks: #ifdef _DEBUG _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif + +// Npn_Experiment(); +// Npn_Generate(); // get global frame (singleton pattern) // will be initialized on first call -- cgit v1.2.3