diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2012-03-27 20:15:02 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2012-03-27 20:15:02 -0700 |
commit | a21f2986aa907e5cf484cd7cd467290d192bf816 (patch) | |
tree | 8ae3fc7d1cb6316865bb4c8abc46aead9c91ba16 /src/base | |
parent | 08253a50eba6c2b7f0346763c923a5abff20708e (diff) | |
download | abc-a21f2986aa907e5cf484cd7cd467290d192bf816.tar.gz abc-a21f2986aa907e5cf484cd7cd467290d192bf816.tar.bz2 abc-a21f2986aa907e5cf484cd7cd467290d192bf816.zip |
Enabling mapping into multi-input AND/OR gates.
Diffstat (limited to 'src/base')
-rw-r--r-- | src/base/abc/abcUtil.c | 82 | ||||
-rw-r--r-- | src/base/abci/abc.c | 96 | ||||
-rw-r--r-- | src/base/abci/abcIf.c | 7 |
3 files changed, 176 insertions, 9 deletions
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 4bf881bc..eec7c50d 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -2060,6 +2060,88 @@ Abc_Ntk_t * Abc_NtkAddBuffs( Abc_Ntk_t * pNtkInit, int fVerbose ) return pNtk; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NodeSopToCubes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew ) +{ + Abc_Obj_t * pNodeOr, * pNodeNew, * pFanin; + char * pCube, * pSop = (char *)pNodeOld->pData; + int v, Value, nVars = Abc_ObjFaninNum(pNodeOld), nFanins; + // create the root node + if ( Abc_SopGetCubeNum(pSop) < 2 ) + { + pNodeNew = Abc_NtkDupObj( pNtkNew, pNodeOld, 0 ); + Abc_ObjForEachFanin( pNodeOld, pFanin, v ) + Abc_ObjAddFanin( pNodeNew, pFanin->pCopy ); + assert( pNodeOld->pCopy == pNodeNew ); + return; + } + // add the OR gate + pNodeOr = Abc_NtkCreateNode( pNtkNew ); + pNodeOr->pData = Abc_SopCreateOr( (Mem_Flex_t *)pNtkNew->pManFunc, Abc_SopGetCubeNum(pSop), NULL ); + // check the logic function of the node + Abc_SopForEachCube( pSop, nVars, pCube ) + { + nFanins = 0; + Abc_CubeForEachVar( pCube, Value, v ) + if ( Value == '0' || Value == '1' ) + nFanins++; + assert( nFanins > 0 ); + // create node + pNodeNew = Abc_NtkCreateNode( pNtkNew ); + pNodeNew->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, nFanins, NULL ); + nFanins = 0; + Abc_CubeForEachVar( pCube, Value, v ) + { + if ( Value != '0' && Value != '1' ) + continue; + Abc_ObjAddFanin( pNodeNew, Abc_ObjFanin(pNodeOld, v)->pCopy ); + if ( Value == '0' ) + Abc_SopComplementVar( (char *)pNodeNew->pData, nFanins ); + nFanins++; + } + Abc_ObjAddFanin( pNodeOr, pNodeNew ); + } + // check the complement + if ( Abc_SopIsComplement(pSop) ) + Abc_SopComplement( (char *)pNodeOr->pData ); + // mark the old node with the new one + assert( pNodeOld->pCopy == NULL ); + pNodeOld->pCopy = pNodeOr; +} +Abc_Ntk_t * Abc_NtkSopToCubes( Abc_Ntk_t * pNtk ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pNode; + Vec_Ptr_t * vNodes; + int i; + assert( Abc_NtkIsSopLogic(pNtk) ); + Abc_NtkCleanCopy( pNtk ); + pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); + // perform conversion in the topological order + vNodes = Abc_NtkDfs( pNtk, 0 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i ) + Abc_NodeSopToCubes( pNode, pNtkNew ); + Vec_PtrFree( vNodes ); + // make sure everything is okay + Abc_NtkFinalize( pNtk, pNtkNew ); + if ( !Abc_NtkCheck( pNtkNew ) ) + { + printf( "Abc_NtkSopToCubes: The network check has failed.\n" ); + Abc_NtkDelete( pNtkNew ); + return NULL; + } + return pNtkNew; +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 1bfbd4f3..31256e87 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -137,6 +137,7 @@ static int Abc_CommandReorder ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandBidec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandOrder ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMuxes ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCubes ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandExtSeqDcs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandReach ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -583,6 +584,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Various", "bidec", Abc_CommandBidec, 1 ); Cmd_CommandAdd( pAbc, "Various", "order", Abc_CommandOrder, 0 ); Cmd_CommandAdd( pAbc, "Various", "muxes", Abc_CommandMuxes, 1 ); + Cmd_CommandAdd( pAbc, "Various", "cubes", Abc_CommandCubes, 1 ); Cmd_CommandAdd( pAbc, "Various", "ext_seq_dcs", Abc_CommandExtSeqDcs, 0 ); Cmd_CommandAdd( pAbc, "Various", "reach", Abc_CommandReach, 0 ); Cmd_CommandAdd( pAbc, "Various", "cone", Abc_CommandCone, 1 ); @@ -7000,6 +7002,68 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandCubes( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Abc_Ntk_t * Abc_NtkSopToCubes( Abc_Ntk_t * pNtk ); + Abc_Ntk_t * pNtk, * pNtkRes; + int c; + + pNtk = Abc_FrameReadNtk(pAbc); + // set defaults + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( pNtk == NULL ) + { + Abc_Print( -1, "Empty network.\n" ); + return 1; + } + + if ( !Abc_NtkIsSopLogic(pNtk) ) + { + Abc_Print( -1, "Only a SOP logic network can be transformed into cubes.\n" ); + return 1; + } + + // get the new network + pNtkRes = Abc_NtkSopToCubes( pNtk ); + if ( pNtkRes == NULL ) + { + Abc_Print( -1, "Converting to cubes has failed.\n" ); + return 1; + } + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + Abc_Print( -2, "usage: cubes [-h]\n" ); + Abc_Print( -2, "\t converts the current network into a network derived by creating\n" ); + Abc_Print( -2, "\t a separate node for each product and sum in the local SOPs\n" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* @@ -13388,7 +13452,7 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) fLutMux = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCFADEWSqaflepmrsdbugyojikcvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGDEWSqaflepmrsdbugyojikcvh" ) ) != EOF ) { switch ( c ) { @@ -13438,6 +13502,17 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nAreaIters < 0 ) goto usage; break; + case 'G': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-G\" should be followed by a positive integer no less than 3.\n" ); + goto usage; + } + pPars->nGateSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nGateSize < 2 ) + goto usage; + break; case 'D': if ( globalUtilOptind >= argc ) { @@ -13674,7 +13749,15 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->fTruth = 1; pPars->fExpRed = 0; } - + // modify the subgraph recording + if ( pPars->fUserRecLib ) + { + pPars->fTruth = 1; + pPars->fCutMin = 1; + pPars->fExpRed = 0; + pPars->fUsePerm = 1; + pPars->pLutLib = NULL; + } // modify for global delay optimization if ( pPars->fDelayOpt ) { @@ -13684,15 +13767,15 @@ int Abc_CommandIf( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->fUsePerm = 1; pPars->pLutLib = NULL; } - // modify the subgraph recording - if ( pPars->fUserRecLib ) + // modify for global delay optimization + if ( pPars->nGateSize > 0 ) { pPars->fTruth = 1; pPars->fCutMin = 1; pPars->fExpRed = 0; pPars->fUsePerm = 1; pPars->pLutLib = NULL; - pPars->fCutMin = 1; + pPars->nLutSize = pPars->nGateSize; } /* @@ -13772,12 +13855,13 @@ usage: sprintf( LutSize, "library" ); else sprintf( LutSize, "%d", pPars->nLutSize ); - Abc_Print( -2, "usage: if [-KCFA num] [-DEW float] [-S str] [-qarlepmsdbugyojikcvh]\n" ); + Abc_Print( -2, "usage: if [-KCFAG num] [-DEW float] [-S str] [-qarlepmsdbugyojikcvh]\n" ); Abc_Print( -2, "\t performs FPGA technology mapping of the network\n" ); Abc_Print( -2, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, LutSize ); Abc_Print( -2, "\t-C num : the max number of priority cuts (0 < num < 2^12) [default = %d]\n", pPars->nCutsMax ); Abc_Print( -2, "\t-F num : the number of area flow recovery iterations (num >= 0) [default = %d]\n", pPars->nFlowIters ); Abc_Print( -2, "\t-A num : the number of exact area recovery iterations (num >= 0) [default = %d]\n", pPars->nAreaIters ); + Abc_Print( -2, "\t-G num : the max AND/OR gate size for mapping (0 = unused) [default = %d]\n", pPars->nGateSize ); Abc_Print( -2, "\t-D float : sets the delay constraint for the mapping [default = %s]\n", Buffer ); Abc_Print( -2, "\t-E float : sets epsilon used for tie-breaking [default = %f]\n", pPars->Epsilon ); Abc_Print( -2, "\t-W float : sets wire delay between adjects LUTs [default = %f]\n", pPars->WireDelay ); diff --git a/src/base/abci/abcIf.c b/src/base/abci/abcIf.c index f2b101b9..cf32d8ec 100644 --- a/src/base/abci/abcIf.c +++ b/src/base/abci/abcIf.c @@ -197,6 +197,7 @@ If_Man_t * Abc_NtkToIf( Abc_Ntk_t * pNtk, If_Par_t * pPars ) // start the mapping manager and set its parameters pIfMan = If_ManStart( pPars ); + pIfMan->pName = Abc_UtilStrsav( Abc_NtkName(pNtk) ); // print warning about excessive memory usage if ( 1.0 * Abc_NtkObjNum(pNtk) * pIfMan->nObjBytes / (1<<30) > 1.0 ) @@ -294,7 +295,7 @@ Abc_Ntk_t * Abc_NtkFromIf( If_Man_t * pIfMan, Abc_Ntk_t * pNtk ) // create the new network if ( pIfMan->pPars->fUseBdds || pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv ) pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD ); - else if ( pIfMan->pPars->fUseSops ) + else if ( pIfMan->pPars->fUseSops || pIfMan->pPars->nGateSize > 0 ) pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); else pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_AIG ); @@ -437,7 +438,7 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t pCutBest = If_ObjCutBest( pIfObj ); // printf( "%d 0x%02X %d\n", pCutBest->nLeaves, 0xff & *If_CutTruth(pCutBest), pIfMan->pPars->pFuncCost(pCutBest) ); // if ( pIfMan->pPars->pLutLib && pIfMan->pPars->pLutLib->fVarPinDelays ) - if ( !pIfMan->pPars->fDelayOpt && !pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserRecLib ) + if ( !pIfMan->pPars->fDelayOpt && !pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserRecLib && !pIfMan->pPars->nGateSize ) If_CutRotatePins( pIfMan, pCutBest ); if ( pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv ) { @@ -464,7 +465,7 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t // transform truth table into the BDD pNodeNew->pData = Kit_TruthToBdd( (DdManager *)pNtkNew->pManFunc, If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), 1 ); Cudd_Ref((DdNode *)pNodeNew->pData); } - else if ( pIfMan->pPars->fUseSops ) + else if ( pIfMan->pPars->fUseSops || pIfMan->pPars->nGateSize > 0 ) { // transform truth table into the SOP int RetValue = Kit_TruthIsop( If_CutTruth(pCutBest), If_CutLeaveNum(pCutBest), vCover, 1 ); |