diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2020-01-19 02:18:32 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2020-01-19 02:18:32 -0800 |
commit | f1a3cffe594ece1e2febbaa836cf71be3608f9c2 (patch) | |
tree | 7f8a426b71615eed6a6c06910653a416e09c85df /src | |
parent | 19b8d9bf7ca6c9d51ea829b40c46a801a1ac0e11 (diff) | |
download | abc-f1a3cffe594ece1e2febbaa836cf71be3608f9c2.tar.gz abc-f1a3cffe594ece1e2febbaa836cf71be3608f9c2.tar.bz2 abc-f1a3cffe594ece1e2febbaa836cf71be3608f9c2.zip |
Adding new command to generate specialized miter.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/abci/abc.c | 72 | ||||
-rw-r--r-- | src/base/abci/abcMiter.c | 156 |
2 files changed, 228 insertions, 0 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index da784655..51b84ad9 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -163,6 +163,7 @@ static int Abc_CommandMajGen ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandComb ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandMiter2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDemiter ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandOrPos ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAndPos ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -872,6 +873,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 ); Cmd_CommandAdd( pAbc, "Various", "comb", Abc_CommandComb, 1 ); Cmd_CommandAdd( pAbc, "Various", "miter", Abc_CommandMiter, 1 ); + Cmd_CommandAdd( pAbc, "Various", "miter2", Abc_CommandMiter2, 1 ); Cmd_CommandAdd( pAbc, "Various", "demiter", Abc_CommandDemiter, 1 ); Cmd_CommandAdd( pAbc, "Various", "orpos", Abc_CommandOrPos, 1 ); Cmd_CommandAdd( pAbc, "Various", "andpos", Abc_CommandAndPos, 1 ); @@ -9441,6 +9443,76 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandMiter2( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Ptr_t * Abc_NtkReadNodeNames( Abc_Ntk_t * pNtk, char * pFileName ); + extern Abc_Ntk_t * Abc_NtkSpecialMiter( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes ); + + Abc_Ntk_t * pNtk, * pNtkRes; + Vec_Ptr_t * vNodes; + char * pFileName; + int c, fVerbose = 0; + pNtk = Abc_FrameReadNtk(pAbc); + + // set defaults + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + // get the second network + if ( argc != globalUtilOptind + 1 ) + { + Abc_Print( -1, "The file with node names is not given.\n" ); + return 1; + } + if ( !Abc_NtkIsLogic(pNtk) ) + { + Abc_Print( -1, "The base network should be logic network from BLIF file.\n" ); + return 1; + } + // read the second network + pFileName = argv[globalUtilOptind]; + if ( (vNodes = Abc_NtkReadNodeNames(pNtk, pFileName)) == NULL ) + { + Abc_Print( -1, "Cannot read node names from file \"%s\".\n", pFileName ); + return 1; + } + pNtkRes = Abc_NtkSpecialMiter( pNtk, vNodes ); + Vec_PtrFree( vNodes ); + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); + return 0; + +usage: + Abc_Print( -2, "usage: miter2 [-h] <file>\n" ); + Abc_Print( -2, "\t derives specialized miter\n" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t<file> : file name with node names\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c index 46f533c1..81b032d4 100644 --- a/src/base/abci/abcMiter.c +++ b/src/base/abci/abcMiter.c @@ -1246,6 +1246,162 @@ Vec_Ptr_t * Abc_NtkTryNewMiter( char * pFileName0, char * pFileName1 ) return vCexes; } +/**Function************************************************************* + + Synopsis [Read node names.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Ptr_t * Abc_NtkReadNodeNames( Abc_Ntk_t * pNtk, char * pFileName ) +{ + char Buffer[1000]; + Vec_Ptr_t * vNodes = NULL; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open node list \"%s\".\n", pFileName ); + return NULL; + } + vNodes = Vec_PtrAlloc( 100 ); + while ( fgets(Buffer, 1000, pFile) != NULL ) + { + char * pToken = strtok( Buffer, " \n\r\t" ); + while ( pToken ) + { + Abc_Obj_t * pObj = Abc_NtkFindNode( pNtk, pToken ); + if ( pObj == NULL ) + { + printf( "Cannot find node \"%s\".\n", pToken ); + Vec_PtrFree( vNodes ); + fclose( pFile ); + return NULL; + } + Vec_PtrPush( vNodes, pObj ); + pToken = strtok( NULL, " \n\r\t" ); + } + } + fclose( pFile ); + return vNodes; +} + +/**Function************************************************************* + + Synopsis [Deriving specialized miter.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Obj_t * Abc_NtkSpecialMuxTree_rec( Abc_Ntk_t * pNew, Abc_Obj_t ** pCtrl, int nCtrl, Abc_Obj_t ** pData, int Shift ) +{ + Abc_Obj_t * pLit0, * pLit1; + if ( nCtrl == 0 ) + return pData[Shift]; + pLit0 = Abc_NtkSpecialMuxTree_rec( pNew, pCtrl, nCtrl-1, pData, Shift ); + pLit1 = Abc_NtkSpecialMuxTree_rec( pNew, pCtrl, nCtrl-1, pData, Shift + (1<<(nCtrl-1)) ); + return Abc_NtkCreateNodeMux( pNew, pCtrl[nCtrl-1], pLit1, pLit0 ); +} +Abc_Ntk_t * Abc_NtkSpecialMiter( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pObj, * pFanin, * pObjNew, * pPoNew; char * pName; + Vec_Int_t * vFirsts = Vec_IntAlloc( Vec_PtrSize(vNodes) ); + Vec_Ptr_t * vNames = Vec_PtrAlloc( 100 ); + Vec_Ptr_t * vFanins = Vec_PtrAlloc( 100 ); + Vec_Ptr_t * vDatas = Vec_PtrAlloc( 100 ); + Vec_Ptr_t * vDfs = Abc_NtkDfs( pNtk, 1 ); + Vec_Ptr_t * vCopies = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) ); + int i, k, Index, First, nNewPis = 0; + // count the number of additional inputs + Abc_NtkCleanCopy( pNtk ); + Abc_NtkCleanMarkA( pNtk ); + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + { + char Buffer[1000]; + assert( Abc_ObjIsNode(pObj) ); + pObj->fMarkA = 1; + Vec_IntPush( vFirsts, nNewPis ); + nNewPis += 1 << Abc_ObjFaninNum(pObj); + for ( k = 0; k < (1 << Abc_ObjFaninNum(pObj)); k++ ) + { + sprintf( Buffer, "pi_%s_%d", Abc_ObjName(pObj), k ); + Vec_PtrPush( vNames, Abc_UtilStrsav(Buffer) ); + } + } + // create new network with the additional PIs + pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); + pNtkNew->pName = Extra_UtilStrsav( "miter" ); + Vec_PtrForEachEntry( char *, vNames, pName, i ) + Abc_ObjAssignName( Abc_NtkCreatePi(pNtkNew), pName, NULL ); + // duplicate PIs + Abc_NtkForEachCi( pNtk, pObj, i ) + pObj->pCopy = Abc_NtkDupObj( pNtkNew, pObj, 1 ); + // copy nodes + Vec_PtrForEachEntry( Abc_Obj_t *, vDfs, pObj, i ) + { + if ( !pObj->fMarkA ) + { + Abc_NtkDupObj( pNtkNew, pObj, 1 ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); + Vec_PtrWriteEntry( vCopies, pObj->Id, pObj->pCopy ); + continue; + } + Vec_PtrClear( vFanins ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + Vec_PtrPush( vFanins, pFanin->pCopy ); + Index = Vec_PtrFind( vNodes, pObj ); + assert( Index >= 0 ); + First = Vec_IntEntry( vFirsts, Index ); + Vec_PtrClear( vDatas ); + for ( k = 0; k < (1 << Abc_ObjFaninNum(pObj)); k++ ) + Vec_PtrPush( vDatas, Abc_NtkCi(pNtkNew, First + k) ); + pObj->pCopy = Abc_NtkSpecialMuxTree_rec( pNtkNew, + (Abc_Obj_t **)Vec_PtrArray(vFanins), Vec_PtrSize(vFanins), + (Abc_Obj_t **)Vec_PtrArray(vDatas), 0 ); + Vec_PtrWriteEntry( vCopies, pObj->Id, pObj->pCopy ); + } + Vec_PtrForEachEntry( Abc_Obj_t *, vDfs, pObj, i ) + { + pObj->fMarkA = 0; + Abc_NtkDupObj( pNtkNew, pObj, 0 ); + Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), "_copy" ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); + } + // create miter + Vec_PtrClear( vDatas ); + Abc_NtkForEachCo( pNtk, pObj, i ) + { + Vec_PtrClear( vFanins ); + Vec_PtrPush( vFanins, Abc_ObjFanin0(pObj)->pCopy ); + Vec_PtrPush( vFanins, (Abc_Obj_t *)Vec_PtrEntry(vCopies, Abc_ObjId(Abc_ObjFanin0(pObj))) ); + Vec_PtrPush( vDatas, Abc_NtkCreateNodeExor(pNtkNew, vFanins) ); + } + if ( Vec_PtrSize(vDatas) > 1 ) + pObjNew = Abc_NtkCreateNodeOr( pNtkNew, vDatas ); + else + pObjNew = (Abc_Obj_t *)Vec_PtrEntry(vDatas, 0); + Abc_ObjAddFanin( (pPoNew = Abc_NtkCreatePo(pNtkNew)), pObjNew ); + Abc_ObjAssignName( pPoNew, "miter_output", NULL ); + // cleanup + Vec_IntFree( vFirsts ); + Vec_PtrFreeFree( vNames ); + Vec_PtrFree( vFanins ); + Vec_PtrFree( vDatas ); + Vec_PtrFree( vDfs ); + Vec_PtrFree( vCopies ); + return pNtkNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// |