Commit f866920e by Alan Mishchenko

Added a new demitering feature for dual-output miters.

parent 6c2ac766
......@@ -557,6 +557,7 @@ extern void Aig_ObjConnect( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_
extern void Aig_ObjDisconnect( Aig_Man_t * p, Aig_Obj_t * pObj );
extern void Aig_ObjDelete( Aig_Man_t * p, Aig_Obj_t * pObj );
extern void Aig_ObjDelete_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int fFreeTop );
extern void Aig_ObjDeletePo( Aig_Man_t * p, Aig_Obj_t * pObj );
extern void Aig_ObjPrint( Aig_Man_t * p, Aig_Obj_t * pObj );
extern void Aig_ObjPatchFanin0( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFaninNew );
extern void Aig_ObjReplace( Aig_Man_t * p, Aig_Obj_t * pObjOld, Aig_Obj_t * pObjNew, int fUpdateLevel );
......
......@@ -268,6 +268,27 @@ void Aig_ObjDelete_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int fFreeTop )
/**Function*************************************************************
Synopsis [Deletes the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ObjDeletePo( Aig_Man_t * p, Aig_Obj_t * pObj )
{
assert( Aig_ObjIsPo(pObj) );
Aig_ObjDeref(Aig_ObjFanin0(pObj));
pObj->pFanin0 = NULL;
p->nObjs[pObj->Type]--;
Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
Aig_ManRecycleMemory( p, pObj );
}
/**Function*************************************************************
Synopsis [Replaces the first fanin of the node by the new fanin.]
Description []
......
......@@ -168,6 +168,7 @@ extern Aig_Man_t * Saig_ManDualRail( Aig_Man_t * p, int fMiter );
extern Aig_Man_t * Saig_ManCreateMiterTwo( Aig_Man_t * pOld, Aig_Man_t * pNew, int nFrames );
extern int Saig_ManDemiterSimple( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 );
extern int Saig_ManDemiterSimpleDiff( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 );
extern int Saig_ManDemiterDual( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 );
extern int Ssw_SecSpecialMiter( Aig_Man_t * p0, Aig_Man_t * p1, int nFrames, int fVerbose );
/*=== saigOutdec.c ==========================================================*/
extern Aig_Man_t * Saig_ManDecPropertyOutput( Aig_Man_t * pAig, int nLits, int fVerbose );
......
......@@ -696,6 +696,63 @@ int Saig_ManDemiterSimpleDiff( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t **
/**Function*************************************************************
Synopsis [Returns 1 if AIG can be demitered.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Saig_ManDemiterDual( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 )
{
Aig_Man_t * pTemp;
Aig_Obj_t * pObj;
int i, k;
if ( p->pFanData )
Aig_ManFanoutStop( p );
k = 0;
pTemp = Aig_ManDupSimple( p );
Saig_ManForEachPo( pTemp, pObj, i )
{
if ( i & 1 )
Aig_ObjDeletePo( pTemp, pObj );
else
Vec_PtrWriteEntry( pTemp->vPos, k++, pObj );
}
Saig_ManForEachLi( pTemp, pObj, i )
Vec_PtrWriteEntry( pTemp->vPos, k++, pObj );
Vec_PtrShrink( pTemp->vPos, k );
pTemp->nTruePos = k - Saig_ManRegNum(pTemp);
Aig_ManSeqCleanup( pTemp );
*ppAig0 = Aig_ManDupSimple( pTemp );
Aig_ManStop( pTemp );
k = 0;
pTemp = Aig_ManDupSimple( p );
Saig_ManForEachPo( pTemp, pObj, i )
{
if ( i & 1 )
Vec_PtrWriteEntry( pTemp->vPos, k++, pObj );
else
Aig_ObjDeletePo( pTemp, pObj );
}
Saig_ManForEachLi( pTemp, pObj, i )
Vec_PtrWriteEntry( pTemp->vPos, k++, pObj );
Vec_PtrShrink( pTemp->vPos, k );
pTemp->nTruePos = k - Saig_ManRegNum(pTemp);
Aig_ManSeqCleanup( pTemp );
*ppAig1 = Aig_ManDupSimple( pTemp );
Aig_ManStop( pTemp );
return 1;
}
/**Function*************************************************************
Synopsis [Duplicates the AIG to have constant-0 initial state.]
Description []
......
......@@ -5513,21 +5513,30 @@ usage:
int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);//, * pNtkRes;
int fSeq;
int fDual, fSeq, fVerbose;
int c;
extern int Abc_NtkDemiter( Abc_Ntk_t * pNtk );
extern int Abc_NtkDarDemiter( Abc_Ntk_t * pNtk );
extern int Abc_NtkDarDemiterDual( Abc_Ntk_t * pNtk, int fVerbose );
// set defaults
fDual = 0;
fSeq = 1;
fVerbose = 1;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "sh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "dsvh" ) ) != EOF )
{
switch ( c )
{
case 'd':
fDual ^= 1;
break;
case 's':
fSeq ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
default:
goto usage;
}
......@@ -5545,6 +5554,22 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( (Abc_NtkPoNum(pNtk) & 1) )
{
Abc_Print( -1, "The number of POs should be even.\n" );
return 0;
}
if ( fDual )
{
if ( !Abc_NtkDarDemiterDual( pNtk, fVerbose ) )
{
Abc_Print( -1, "Demitering has failed.\n" );
return 1;
}
return 0;
}
// get the new network
if ( fSeq )
{
......@@ -5577,9 +5602,11 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
Abc_Print( -2, "usage: demiter [-sh]\n" );
Abc_Print( -2, "\t removes topmost EXOR from the miter to create two POs\n" );
Abc_Print( -2, "\t-s : applied multi-output algorithm [default = %s]\n", fSeq? "yes": "no" );
Abc_Print( -2, "usage: demiter [-dsvh]\n" );
Abc_Print( -2, "\t removes topmost XOR from the miter to create two POs\n" );
Abc_Print( -2, "\t-d : demiters a dual-output miter (without XORs) [default = %s]\n", fSeq? "yes": "no" );
Abc_Print( -2, "\t-s : applies a multi-output algorithm [default = %s]\n", fSeq? "yes": "no" );
Abc_Print( -2, "\t-v : toggles outputting verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
......
......@@ -2051,6 +2051,74 @@ int Abc_NtkDarDemiter( Abc_Ntk_t * pNtk )
Aig_ManStop( pMan );
return 1;
}
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkDarDemiterDual( Abc_Ntk_t * pNtk, int fVerbose )
{
char * pFileNameGeneric, pFileName0[1000], pFileName1[1000];
Aig_Man_t * pMan, * pPart0, * pPart1;//, * pMiter;
if ( (Abc_NtkPoNum(pNtk) & 1) )
{
printf( "The number of POs should be even.\n" );
return 0;
}
// derive the AIG manager
pMan = Abc_NtkToDar( pNtk, 0, 1 );
if ( pMan == NULL )
{
printf( "Converting network into AIG has failed.\n" );
return 0;
}
// if ( !Saig_ManDemiterSimple( pMan, &pPart0, &pPart1 ) )
if ( !Saig_ManDemiterDual( pMan, &pPart0, &pPart1 ) )
{
printf( "Demitering has failed.\n" );
return 0;
}
// create new AIG
ABC_FREE( pPart0->pName );
pPart0->pName = Aig_UtilStrsav( "part0" );
// create new AIGs
ABC_FREE( pPart1->pName );
pPart1->pName = Aig_UtilStrsav( "part1" );
// create file names
pFileNameGeneric = Extra_FileNameGeneric( pNtk->pSpec );
sprintf( pFileName0, "%s%s", pFileNameGeneric, "_part0.aig" );
sprintf( pFileName1, "%s%s", pFileNameGeneric, "_part1.aig" );
ABC_FREE( pFileNameGeneric );
Ioa_WriteAiger( pPart0, pFileName0, 0, 0 );
Ioa_WriteAiger( pPart1, pFileName1, 0, 0 );
printf( "Demitering produced two files \"%s\" and \"%s\".\n", pFileName0, pFileName1 );
// dump files
if ( fVerbose )
{
// printf( "Init: " );
Aig_ManPrintStats( pMan );
// printf( "Part1: " );
Aig_ManPrintStats( pPart0 );
// printf( "Part2: " );
Aig_ManPrintStats( pPart1 );
}
// create two-level miter
// pMiter = Saig_ManCreateMiterTwo( pPart0, pPart1, 2 );
// Aig_ManDumpBlif( pMiter, "miter01.blif", NULL, NULL );
// Aig_ManStop( pMiter );
// printf( "The new miter is written into file \"%s\".\n", "miter01.blif" );
Aig_ManStop( pPart0 );
Aig_ManStop( pPart1 );
Aig_ManStop( pMan );
return 1;
}
/**Function*************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment