mirror of https://github.com/YosysHQ/abc.git
Version abc60419
This commit is contained in:
parent
c1710767b2
commit
73b8d1dd79
10
abc.dsp
10
abc.dsp
|
|
@ -502,7 +502,11 @@ SOURCE=.\src\base\io\ioWritePla.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\io\ioWriteVerilog.c
|
||||
SOURCE=.\src\base\io\ioWriteVer.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\io\ioWriteVerAux.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "main"
|
||||
|
|
@ -1302,6 +1306,10 @@ SOURCE=.\src\opt\cut\cutCut.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\cut\cutExpand.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\opt\cut\cutInt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
|
|
@ -743,7 +743,8 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, bool
|
|||
if ( fUpdateLevel )
|
||||
{
|
||||
Abc_AigUpdateLevel_int( pMan );
|
||||
Abc_AigUpdateLevelR_int( pMan );
|
||||
if ( pMan->pNtkAig->vLevelsR )
|
||||
Abc_AigUpdateLevelR_int( pMan );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -819,9 +820,12 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i
|
|||
pFanout->fMarkA = 1;
|
||||
Vec_VecPush( pMan->vLevels, pFanout->Level, pFanout );
|
||||
// schedule the updated fanout for updating reverse level
|
||||
assert( pFanout->fMarkB == 0 );
|
||||
pFanout->fMarkB = 1;
|
||||
Vec_VecPush( pMan->vLevelsR, Abc_NodeReadReverseLevel(pFanout), pFanout );
|
||||
if ( pMan->pNtkAig->vLevelsR )
|
||||
{
|
||||
assert( pFanout->fMarkB == 0 );
|
||||
pFanout->fMarkB = 1;
|
||||
Vec_VecPush( pMan->vLevelsR, Abc_NodeReadReverseLevel(pFanout), pFanout );
|
||||
}
|
||||
}
|
||||
|
||||
// the fanout has changed, update EXOR status of its fanouts
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
|
|||
}
|
||||
else if ( Abc_ObjIsPo(pObj) )
|
||||
{
|
||||
assert( Abc_NtkPoNum(pObj->pNtk) == 1 );
|
||||
assert( Abc_NtkPoNum(pObj->pNtk) > 0 );
|
||||
Vec_PtrRemove( pObj->pNtk->vCos, pObj );
|
||||
pObj->pNtk->nPos--;
|
||||
// add the name to the table
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ static int Abc_CommandRr ( Abc_Frame_t * pAbc, int argc, char ** argv
|
|||
static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandMiter ( 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_CommandFrames ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandSop ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandBdd ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -178,6 +179,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
// Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "miter", Abc_CommandMiter, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "demiter", Abc_CommandDemiter, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "orpos", Abc_CommandOrPos, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "frames", Abc_CommandFrames, 1 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "sop", Abc_CommandSop, 0 );
|
||||
Cmd_CommandAdd( pAbc, "Various", "bdd", Abc_CommandBdd, 0 );
|
||||
|
|
@ -2866,8 +2868,8 @@ int Abc_CommandRr( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
usage:
|
||||
fprintf( pErr, "usage: rr [-W NM] [-fvh]\n" );
|
||||
fprintf( pErr, "\t performs redundancy removal in the current network\n" );
|
||||
fprintf( pErr, "\t-W NM : window size as the number of TFI (N) and TFO (M) logic levels [default = %d%d]\n", nFaninLevels, nFanoutLevels );
|
||||
fprintf( pErr, "\t removes combinational redundancies in the current network\n" );
|
||||
fprintf( pErr, "\t-W NM : window size: TFI (N) and TFO (M) logic levels [default = %d%d]\n", nFaninLevels, nFanoutLevels );
|
||||
fprintf( pErr, "\t-f : toggle RR w.r.t. fanouts [default = %s]\n", fUseFanouts? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
|
|
@ -3027,10 +3029,10 @@ usage:
|
|||
int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
Abc_Ntk_t * pNtk;//, * pNtkRes;
|
||||
int fComb;
|
||||
int c;
|
||||
extern Abc_Ntk_t * Abc_NtkDemiter( Abc_Ntk_t * pNtk );
|
||||
extern int Abc_NtkDemiter( Abc_Ntk_t * pNtk );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
|
|
@ -3062,17 +3064,16 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
if ( !Abc_ObjFanin0(Abc_NtkPo(pNtk,0))->fExor )
|
||||
if ( !Abc_NodeIsExorType(Abc_ObjFanin0(Abc_NtkPo(pNtk,0))) )
|
||||
{
|
||||
fprintf( pErr, "The miter's PO is not an EXOR.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get the new network
|
||||
pNtkRes = Abc_NtkDemiter( pNtk );
|
||||
if ( pNtkRes == NULL )
|
||||
if ( !Abc_NtkDemiter( pNtk ) )
|
||||
{
|
||||
fprintf( pErr, "Miter computation has failed.\n" );
|
||||
fprintf( pErr, "Demitering has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
// replace the current network
|
||||
|
|
@ -3087,6 +3088,79 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandOrPos( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
FILE * pOut, * pErr;
|
||||
Abc_Ntk_t * pNtk;//, * pNtkRes;
|
||||
int fComb;
|
||||
int c;
|
||||
extern int Abc_NtkOrPos( Abc_Ntk_t * pNtk );
|
||||
|
||||
pNtk = Abc_FrameReadNtk(pAbc);
|
||||
pOut = Abc_FrameReadOut(pAbc);
|
||||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'c':
|
||||
fComb ^= 1;
|
||||
break;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "The network is not strashed.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( Abc_NtkPoNum(pNtk) == 1 )
|
||||
{
|
||||
fprintf( pErr, "The network already has one PO.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( Abc_NtkLatchNum(pNtk) )
|
||||
{
|
||||
fprintf( pErr, "The miter has latches. ORing is not performed.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get the new network
|
||||
if ( !Abc_NtkOrPos( pNtk ) )
|
||||
{
|
||||
fprintf( pErr, "ORing the POs has failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
// replace the current network
|
||||
// Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: orpos [-h]\n" );
|
||||
fprintf( pErr, "\t creates single-output miter by ORing the POs of the current network\n" );
|
||||
// fprintf( pErr, "\t-c : computes combinational miter (latches as POs) [default = %s]\n", fComb? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -4540,15 +4614,15 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
// Cut_CellDumpToFile();
|
||||
// else
|
||||
// Cut_CellPrecompute();
|
||||
// Cut_CellLoad();
|
||||
|
||||
Cut_CellLoad();
|
||||
/*
|
||||
{
|
||||
Abc_Ntk_t * pNtkRes;
|
||||
extern Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels );
|
||||
pNtkRes = Abc_NtkTopmost( pNtk, nLevels );
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
}
|
||||
|
||||
*/
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
|
|
|
|||
|
|
@ -704,6 +704,7 @@ Abc_Ntk_t * Abc_NtkFraigRestore()
|
|||
Fraig_Params_t Params;
|
||||
Abc_Ntk_t * pStore, * pFraig;
|
||||
int nWords1, nWords2, nWordsMin;
|
||||
int clk = clock();
|
||||
|
||||
// get the stored network
|
||||
pStore = Abc_FrameReadNtkStore();
|
||||
|
|
@ -740,6 +741,7 @@ Abc_Ntk_t * Abc_NtkFraigRestore()
|
|||
// Fraig_ManReportChoices( p );
|
||||
// transform it into FRAIG
|
||||
pFraig = Abc_NtkFraig( pStore, &Params, 1, 0 );
|
||||
PRT( "Total fraiging time", clock() - clk );
|
||||
if ( pFraig == NULL )
|
||||
return NULL;
|
||||
Abc_NtkDelete( pStore );
|
||||
|
|
|
|||
|
|
@ -957,7 +957,7 @@ void Abc_NtkAddFrame2( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the timeframes of the network.]
|
||||
Synopsis [Splits the miter into two logic cones combined by an EXOR]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -966,7 +966,7 @@ void Abc_NtkAddFrame2( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Abc_NtkDemiter( Abc_Ntk_t * pNtk )
|
||||
int Abc_NtkDemiter( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pNodeC, * pNodeA, * pNodeB, * pNode;
|
||||
Abc_Obj_t * pPoNew;
|
||||
|
|
@ -975,22 +975,33 @@ Abc_Ntk_t * Abc_NtkDemiter( Abc_Ntk_t * pNtk )
|
|||
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
assert( Abc_NtkPoNum(pNtk) == 1 );
|
||||
assert( Abc_ObjFanin0(Abc_NtkPo(pNtk,0))->fExor );
|
||||
if ( !Abc_NodeIsExorType(Abc_ObjFanin0(Abc_NtkPo(pNtk,0))) )
|
||||
{
|
||||
printf( "The root of the miter is not an EXOR gate.\n" );
|
||||
return 0;
|
||||
}
|
||||
pNodeC = Abc_NodeRecognizeMux( Abc_ObjFanin0(Abc_NtkPo(pNtk,0)), &pNodeA, &pNodeB );
|
||||
assert( Abc_ObjRegular(pNodeA) == Abc_ObjRegular(pNodeB) );
|
||||
if ( Abc_ObjFaninC0(Abc_NtkPo(pNtk,0)) )
|
||||
{
|
||||
pNodeA = Abc_ObjNot(pNodeA);
|
||||
pNodeB = Abc_ObjNot(pNodeB);
|
||||
}
|
||||
|
||||
// add the PO corresponding to control input
|
||||
pPoNew = Abc_NtkCreatePo( pNtk );
|
||||
Abc_ObjAddFanin( pPoNew, pNodeC );
|
||||
Abc_NtkLogicStoreName( pPoNew, "addOut1" );
|
||||
|
||||
// add the PO corresponding to other input
|
||||
pPoNew = Abc_NtkCreatePo( pNtk );
|
||||
Abc_ObjAddFanin( pPoNew, Abc_ObjRegular(pNodeA) );
|
||||
Abc_ObjAddFanin( pPoNew, pNodeB );
|
||||
Abc_NtkLogicStoreName( pPoNew, "addOut2" );
|
||||
|
||||
// mark the nodes in the first cone
|
||||
pNodeA = Abc_ObjRegular(pNodeA);
|
||||
pNodeB = Abc_ObjRegular(pNodeB);
|
||||
vNodes1 = Abc_NtkDfsNodes( pNtk, &pNodeC, 1 );
|
||||
vNodes2 = Abc_NtkDfsNodes( pNtk, &pNodeA, 1 );
|
||||
vNodes2 = Abc_NtkDfsNodes( pNtk, &pNodeB, 1 );
|
||||
|
||||
Vec_PtrForEachEntry( vNodes1, pNode, i )
|
||||
pNode->fMarkA = 1;
|
||||
|
|
@ -1003,9 +1014,45 @@ Abc_Ntk_t * Abc_NtkDemiter( Abc_Ntk_t * pNtk )
|
|||
printf( "First cone = %6d. Second cone = %6d. Common = %6d.\n", vNodes1->nSize, vNodes2->nSize, nCommon );
|
||||
Vec_PtrFree( vNodes1 );
|
||||
Vec_PtrFree( vNodes2 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
return pNtk;
|
||||
Synopsis [ORs the outputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkOrPos( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pNode, * pMiter;
|
||||
int i;
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
assert( Abc_NtkLatchNum(pNtk) == 0 );
|
||||
// OR the POs
|
||||
pMiter = Abc_ObjNot( Abc_NtkConst1(pNtk) );
|
||||
Abc_NtkForEachPo( pNtk, pNode, i )
|
||||
pMiter = Abc_AigOr( pNtk->pManFunc, pMiter, Abc_ObjChild0(pNode) );
|
||||
// remove the POs and their names
|
||||
for ( i = Abc_NtkPoNum(pNtk) - 1; i >= 0; i-- )
|
||||
Abc_NtkDeleteObj( Abc_NtkPo(pNtk, i) );
|
||||
assert( Abc_NtkPoNum(pNtk) == 0 );
|
||||
// create the new PO
|
||||
pNode = Abc_NtkCreatePo( pNtk );
|
||||
Abc_ObjAddFanin( pNode, pMiter );
|
||||
Abc_NtkLogicStoreName( pNode, "miter" );
|
||||
// make sure that everything is okay
|
||||
if ( !Abc_NtkCheck( pNtk ) )
|
||||
{
|
||||
printf( "Abc_NtkOrPos: The network check has failed.\n" );
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
|
|||
fprintf( pFile, " (choice = %d)", Num );
|
||||
if ( Num = Abc_NtkGetExorNum(pNtk) )
|
||||
fprintf( pFile, " (exor = %d)", Num );
|
||||
if ( Num2 = Abc_NtkGetMuxNum(pNtk) )
|
||||
fprintf( pFile, " (mux = %d)", Num2-Num );
|
||||
if ( Num2 )
|
||||
fprintf( pFile, " (other = %d)", Abc_NtkNodeNum(pNtk)-3*Num2 );
|
||||
// if ( Num2 = Abc_NtkGetMuxNum(pNtk) )
|
||||
// fprintf( pFile, " (mux = %d)", Num2-Num );
|
||||
// if ( Num2 )
|
||||
// fprintf( pFile, " (other = %d)", Abc_NtkNodeNum(pNtk)-3*Num2 );
|
||||
}
|
||||
else
|
||||
fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) );
|
||||
|
|
@ -109,12 +109,10 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
|
|||
{
|
||||
FILE * pTable;
|
||||
pTable = fopen( "stats.txt", "a+" );
|
||||
fprintf( pTable, "%s ", pNtk->pName );
|
||||
fprintf( pTable, "%4d ", Abc_NtkPiNum(pNtk) );
|
||||
fprintf( pTable, "%4d ", Abc_NtkPoNum(pNtk) );
|
||||
// fprintf( pTable, "%4d ", Abc_NtkLatchNum(pNtk) );
|
||||
fprintf( pTable, "%6d ", Abc_NtkNodeNum(pNtk) );
|
||||
fprintf( pTable, "%6d ", Abc_AigGetLevelNum(pNtk) );
|
||||
fprintf( pTable, "%s ", pNtk->pName );
|
||||
fprintf( pTable, "%d ", Abc_NtkPiNum(pNtk) );
|
||||
fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) );
|
||||
fprintf( pTable, "%d ", Abc_AigGetLevelNum(pNtk) );
|
||||
fprintf( pTable, "\n" );
|
||||
fclose( pTable );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "abc.h"
|
||||
#include "fraig.h"
|
||||
#include "sim.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -47,21 +48,34 @@ struct Abc_RRMan_t_
|
|||
// the miter
|
||||
Abc_Ntk_t * pMiter; // the miter derived from the window
|
||||
Prove_Params_t * pParams; // the miter proving parameters
|
||||
// statistical variables
|
||||
int nNodesOld; // the old number of nodes
|
||||
int nLevelsOld; // the old number of levels
|
||||
int nEdgesTried; // the number of nodes tried
|
||||
int nEdgesRemoved; // the number of nodes proved
|
||||
int timeWindow; // the time to construct the window
|
||||
int timeMiter; // the time to construct the miter
|
||||
int timeProve; // the time to prove the miter
|
||||
int timeUpdate; // the network update time
|
||||
int timeTotal; // the total runtime
|
||||
};
|
||||
|
||||
static Abc_RRMan_t * Abc_RRManStart();
|
||||
static void Abc_RRManStop( Abc_RRMan_t * p );
|
||||
static void Abc_RRManPrintStats( Abc_RRMan_t * p );
|
||||
static void Abc_RRManClean( Abc_RRMan_t * p );
|
||||
static int Abc_NtkRRProve( Abc_RRMan_t * p );
|
||||
static int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Abc_Obj_t * pFanout );
|
||||
static int Abc_NtkRRWindow( Abc_RRMan_t * p );
|
||||
|
||||
static int Abc_NtkRRTfi_int( Vec_Ptr_t * vFaninLeaves, int LevelLimit );
|
||||
static int Abc_NtkRRTfo_int( Vec_Ptr_t * vFanoutRoots, int LevelLimit, Abc_Obj_t * pEdgeFanin, Abc_Obj_t * pEdgeFanout );
|
||||
static int Abc_NtkRRTfi_int( Vec_Ptr_t * vLeaves, int LevelLimit );
|
||||
static int Abc_NtkRRTfo_int( Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, int LevelLimit, Abc_Obj_t * pEdgeFanin, Abc_Obj_t * pEdgeFanout );
|
||||
static int Abc_NtkRRTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vRoots, int LevelLimit );
|
||||
static void Abc_NtkRRTfi_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone );
|
||||
static void Abc_NtkRRTfi_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, int LevelLimit );
|
||||
static Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vRoots );
|
||||
|
||||
static void Abc_NtkRRSimulateStart( Abc_Ntk_t * pNtk );
|
||||
static void Abc_NtkRRSimulateStop( Abc_Ntk_t * pNtk );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -83,14 +97,18 @@ int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFa
|
|||
ProgressBar * pProgress;
|
||||
Abc_RRMan_t * p;
|
||||
Abc_Obj_t * pNode, * pFanin, * pFanout;
|
||||
int i, k, m, nNodes;
|
||||
int i, k, m, nNodes, RetValue, clk, clkTotal = clock();
|
||||
// start the manager
|
||||
p = Abc_RRManStart( nFaninLevels, nFanoutLevels );
|
||||
p->pNtk = pNtk;
|
||||
p->pNtk = pNtk;
|
||||
p->nFaninLevels = nFaninLevels;
|
||||
p->nFanoutLevels = nFanoutLevels;
|
||||
p->nNodesOld = Abc_NtkNodeNum(pNtk);
|
||||
p->nLevelsOld = Abc_AigGetLevelNum(pNtk);
|
||||
// go through the nodes
|
||||
Abc_NtkCleanCopy(pNtk);
|
||||
nNodes = Abc_NtkObjNumMax(pNtk);
|
||||
Abc_NtkRRSimulateStart(pNtk);
|
||||
pProgress = Extra_ProgressBarStart( stdout, nNodes );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
|
|
@ -109,36 +127,87 @@ int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFa
|
|||
{
|
||||
Abc_ObjForEachFanin( pNode, pFanin, k )
|
||||
{
|
||||
// skip the nodes with only one fanout (tree nodes)
|
||||
if ( Abc_ObjFanoutNum(pFanin) == 1 )
|
||||
continue;
|
||||
/*
|
||||
if ( pFanin->Id == 228 && pNode->Id == 2649 )
|
||||
{
|
||||
int k = 0;
|
||||
}
|
||||
*/
|
||||
p->nEdgesTried++;
|
||||
Abc_RRManClean( p );
|
||||
p->pNode = pNode;
|
||||
p->pFanin = pFanin;
|
||||
p->pFanout = NULL;
|
||||
if ( !Abc_NtkRRWindow( p ) )
|
||||
|
||||
clk = clock();
|
||||
RetValue = Abc_NtkRRWindow( p );
|
||||
p->timeWindow += clock() - clk;
|
||||
if ( !RetValue )
|
||||
continue;
|
||||
if ( !Abc_NtkRRProve( p ) )
|
||||
/*
|
||||
if ( pFanin->Id == 228 && pNode->Id == 2649 )
|
||||
{
|
||||
Abc_NtkShowAig( p->pWnd, 0 );
|
||||
}
|
||||
*/
|
||||
clk = clock();
|
||||
RetValue = Abc_NtkRRProve( p );
|
||||
p->timeMiter += clock() - clk;
|
||||
if ( !RetValue )
|
||||
continue;
|
||||
//printf( "%d -> %d (%d)\n", pFanin->Id, pNode->Id, k );
|
||||
|
||||
clk = clock();
|
||||
Abc_NtkRRUpdate( pNtk, p->pNode, p->pFanin, p->pFanout );
|
||||
p->timeUpdate += clock() - clk;
|
||||
|
||||
p->nEdgesRemoved++;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// use the fanouts
|
||||
Abc_ObjForEachFanout( pNode, pFanout, m )
|
||||
Abc_ObjForEachFanin( pNode, pFanin, k )
|
||||
Abc_ObjForEachFanout( pNode, pFanout, m )
|
||||
{
|
||||
// skip the nodes with only one fanout (tree nodes)
|
||||
// if ( Abc_ObjFanoutNum(pFanin) == 1 && Abc_ObjFanoutNum(pNode) == 1 )
|
||||
// continue;
|
||||
|
||||
p->nEdgesTried++;
|
||||
Abc_RRManClean( p );
|
||||
p->pNode = pNode;
|
||||
p->pFanin = pFanin;
|
||||
p->pFanout = pFanout;
|
||||
if ( !Abc_NtkRRWindow( p ) )
|
||||
|
||||
clk = clock();
|
||||
RetValue = Abc_NtkRRWindow( p );
|
||||
p->timeWindow += clock() - clk;
|
||||
if ( !RetValue )
|
||||
continue;
|
||||
if ( !Abc_NtkRRProve( p ) )
|
||||
|
||||
clk = clock();
|
||||
RetValue = Abc_NtkRRProve( p );
|
||||
p->timeMiter += clock() - clk;
|
||||
if ( !RetValue )
|
||||
continue;
|
||||
|
||||
clk = clock();
|
||||
Abc_NtkRRUpdate( pNtk, p->pNode, p->pFanin, p->pFanout );
|
||||
p->timeUpdate += clock() - clk;
|
||||
|
||||
p->nEdgesRemoved++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Abc_NtkRRSimulateStop(pNtk);
|
||||
Extra_ProgressBarStop( pProgress );
|
||||
p->timeTotal = clock() - clkTotal;
|
||||
if ( fVerbose )
|
||||
Abc_RRManPrintStats( p );
|
||||
Abc_RRManStop( p );
|
||||
// put the nodes into the DFS order and reassign their IDs
|
||||
Abc_NtkReassignIds( pNtk );
|
||||
|
|
@ -202,6 +271,33 @@ void Abc_RRManStop( Abc_RRMan_t * p )
|
|||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stop the manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_RRManPrintStats( Abc_RRMan_t * p )
|
||||
{
|
||||
double Ratio = 100.0*(p->nNodesOld - Abc_NtkNodeNum(p->pNtk))/p->nNodesOld;
|
||||
printf( "Redundancy removal statistics:\n" );
|
||||
printf( "Edges tried = %6d.\n", p->nEdgesTried );
|
||||
printf( "Edges removed = %6d. (%5.2f %%)\n", p->nEdgesRemoved, 100.0*p->nEdgesRemoved/p->nEdgesTried );
|
||||
printf( "Node gain = %6d. (%5.2f %%)\n", p->nNodesOld - Abc_NtkNodeNum(p->pNtk), Ratio );
|
||||
printf( "Level gain = %6d.\n", p->nLevelsOld - Abc_AigGetLevelNum(p->pNtk) );
|
||||
PRT( "Windowing ", p->timeWindow );
|
||||
PRT( "Miter ", p->timeMiter );
|
||||
PRT( " Construct ", p->timeMiter - p->timeProve );
|
||||
PRT( " Prove ", p->timeProve );
|
||||
PRT( "Update ", p->timeUpdate );
|
||||
PRT( "TOTAL ", p->timeTotal );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Clean the manager.]
|
||||
|
|
@ -243,11 +339,17 @@ void Abc_RRManClean( Abc_RRMan_t * p )
|
|||
int Abc_NtkRRProve( Abc_RRMan_t * p )
|
||||
{
|
||||
Abc_Ntk_t * pWndCopy;
|
||||
int RetValue;
|
||||
int RetValue, clk;
|
||||
// Abc_NtkShowAig( p->pWnd, 0 );
|
||||
pWndCopy = Abc_NtkDup( p->pWnd );
|
||||
Abc_NtkRRUpdate( pWndCopy, p->pNode->pCopy, p->pFanin->pCopy, p->pFanout? p->pFanout->pCopy : NULL );
|
||||
Abc_NtkRRUpdate( pWndCopy, p->pNode->pCopy->pCopy, p->pFanin->pCopy->pCopy, p->pFanout? p->pFanout->pCopy->pCopy : NULL );
|
||||
if ( !Abc_NtkIsDfsOrdered(pWndCopy) )
|
||||
Abc_NtkReassignIds(pWndCopy);
|
||||
p->pMiter = Abc_NtkMiter( p->pWnd, pWndCopy, 1 );
|
||||
Abc_NtkDelete( pWndCopy );
|
||||
clk = clock();
|
||||
RetValue = Abc_NtkMiterProve( &p->pMiter, p->pParams );
|
||||
p->timeProve += clock() - clk;
|
||||
if ( RetValue == 1 )
|
||||
return 1;
|
||||
return 0;
|
||||
|
|
@ -257,7 +359,9 @@ int Abc_NtkRRProve( Abc_RRMan_t * p )
|
|||
|
||||
Synopsis [Updates the network after redundancy removal.]
|
||||
|
||||
Description []
|
||||
Description [This procedure assumes that non-control value of the fanin
|
||||
was proved redundant. It is okay to concentrate on non-control values
|
||||
because the control values can be seen as redundancy of the fanout edge.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
|
|
@ -280,7 +384,7 @@ int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Ab
|
|||
// replace
|
||||
if ( pFanout == NULL )
|
||||
{
|
||||
Abc_AigReplace( pNtk->pManFunc, pNode, pNodeNew, 0 );
|
||||
Abc_AigReplace( pNtk->pManFunc, pNode, pNodeNew, 1 );
|
||||
return 1;
|
||||
}
|
||||
// find the fanout after redundancy removal
|
||||
|
|
@ -290,7 +394,7 @@ int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Ab
|
|||
pFanoutNew = Abc_AigAnd( pNtk->pManFunc, Abc_ObjNotCond(pNodeNew,Abc_ObjFaninC1(pFanout)), Abc_ObjChild0(pFanout) );
|
||||
else assert( 0 );
|
||||
// replace
|
||||
Abc_AigReplace( pNtk->pManFunc, pFanout, pFanoutNew, 0 );
|
||||
Abc_AigReplace( pNtk->pManFunc, pFanout, pFanoutNew, 1 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -310,59 +414,50 @@ int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Ab
|
|||
***********************************************************************/
|
||||
int Abc_NtkRRWindow( Abc_RRMan_t * p )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pFanout, * pEdgeFanin, * pEdgeFanout;
|
||||
int i, k;
|
||||
Abc_Obj_t * pObj, * pEdgeFanin, * pEdgeFanout;
|
||||
int i, LevelMin, LevelMax, RetValue;
|
||||
|
||||
// get the edge
|
||||
pEdgeFanout = p->pFanout? p->pFanout : p->pNode;
|
||||
pEdgeFanin = p->pFanout? p->pNode : p->pFanin;
|
||||
// get the minimum and maximum levels of the window
|
||||
LevelMin = ABC_MAX( 0, ((int)p->pFanin->Level) - p->nFaninLevels );
|
||||
LevelMax = (int)pEdgeFanout->Level + p->nFanoutLevels;
|
||||
|
||||
// start the TFI leaves with the fanin
|
||||
Abc_NtkIncrementTravId( p->pNtk );
|
||||
Abc_NodeSetTravIdCurrent( p->pFanin );
|
||||
Vec_PtrPush( p->vFaninLeaves, p->pFanin );
|
||||
// mark the TFI cone and collect the leaves down to the given level
|
||||
while ( Abc_NtkRRTfi_int(p->vFaninLeaves, p->pFanin->Level - p->nFaninLevels) );
|
||||
while ( Abc_NtkRRTfi_int(p->vFaninLeaves, LevelMin) );
|
||||
|
||||
// collect the TFO cone of the leaves
|
||||
// mark the leaves with the new TravId
|
||||
Abc_NtkIncrementTravId( p->pNtk );
|
||||
Vec_PtrForEachEntry( p->vFaninLeaves, pObj, i )
|
||||
{
|
||||
Abc_ObjForEachFanout( pObj, pFanout, k )
|
||||
{
|
||||
if ( !Abc_ObjIsNode(pFanout) )
|
||||
continue;
|
||||
if ( pFanout->Level > pEdgeFanout->Level + p->nFanoutLevels )
|
||||
continue;
|
||||
if ( Abc_NodeIsTravIdCurrent(pFanout) )
|
||||
continue;
|
||||
Abc_NodeSetTravIdCurrent( pFanout );
|
||||
Vec_PtrPush( p->vFanoutRoots, pFanout );
|
||||
}
|
||||
}
|
||||
// mark the TFO cone and collect the leaves up to the given level (while skipping the edge)
|
||||
while ( Abc_NtkRRTfo_int(p->vFanoutRoots, pEdgeFanout->Level + p->nFanoutLevels, pEdgeFanin, pEdgeFanout) );
|
||||
// unmark the nodes
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
// traverse the TFO cone of the leaves (while skipping the edge)
|
||||
// (a) mark the nodes in the cone using the current TravId
|
||||
// (b) collect the nodes that have external fanouts into p->vFanoutRoots
|
||||
while ( Abc_NtkRRTfo_int(p->vFaninLeaves, p->vFanoutRoots, LevelMax, pEdgeFanin, pEdgeFanout) );
|
||||
|
||||
// mark the fanout roots
|
||||
Vec_PtrForEachEntry( p->vFanoutRoots, pObj, i )
|
||||
pObj->fMarkA = 1;
|
||||
// collect roots reachable from the fanout (p->vRoots)
|
||||
RetValue = Abc_NtkRRTfo_rec( pEdgeFanout, p->vRoots, LevelMax + 1 );
|
||||
// unmark the fanout roots
|
||||
Vec_PtrForEachEntry( p->vFanoutRoots, pObj, i )
|
||||
pObj->fMarkA = 0;
|
||||
|
||||
// mark the current roots
|
||||
Abc_NtkIncrementTravId( p->pNtk );
|
||||
Vec_PtrForEachEntry( p->vFanoutRoots, pObj, i )
|
||||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
// collect roots reachable from the fanout (p->vRoots)
|
||||
if ( !Abc_NtkRRTfo_rec( pEdgeFanout, p->vRoots, pEdgeFanout->Level + p->nFanoutLevels + 5 ) )
|
||||
// return if the window is infeasible
|
||||
if ( RetValue == 0 )
|
||||
return 0;
|
||||
|
||||
// collect the DFS-ordered new cone (p->vCone) and new leaves (p->vLeaves)
|
||||
// using the previous marks coming from the TFO cone
|
||||
Abc_NtkIncrementTravId( p->pNtk );
|
||||
Vec_PtrForEachEntry( p->vRoots, pObj, i )
|
||||
Abc_NtkRRTfi_rec( pObj, p->vLeaves, p->vCone );
|
||||
// unmark the nodes
|
||||
Vec_PtrForEachEntry( p->vCone, pObj, i )
|
||||
pObj->fMarkA = 0;
|
||||
Vec_PtrForEachEntry( p->vLeaves, pObj, i )
|
||||
pObj->fMarkA = 0;
|
||||
Abc_NtkRRTfi_rec( pObj, p->vLeaves, p->vCone, LevelMin );
|
||||
|
||||
// create a new network
|
||||
p->pWnd = Abc_NtkWindow( p->pNtk, p->vLeaves, p->vCone, p->vRoots );
|
||||
|
|
@ -380,21 +475,22 @@ int Abc_NtkRRWindow( Abc_RRMan_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRRTfi_int( Vec_Ptr_t * vFaninLeaves, int LevelLimit )
|
||||
int Abc_NtkRRTfi_int( Vec_Ptr_t * vLeaves, int LevelLimit )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pNext;
|
||||
int i, k, LevelMax, nSize;
|
||||
assert( LevelLimit >= 0 );
|
||||
// find the maximum level of leaves
|
||||
LevelMax = 0;
|
||||
Vec_PtrForEachEntry( vFaninLeaves, pObj, i )
|
||||
Vec_PtrForEachEntry( vLeaves, pObj, i )
|
||||
if ( LevelMax < (int)pObj->Level )
|
||||
LevelMax = pObj->Level;
|
||||
// if the nodes are all PIs, LevelMax == 0
|
||||
if ( LevelMax == 0 || LevelMax <= LevelLimit )
|
||||
if ( LevelMax <= LevelLimit )
|
||||
return 0;
|
||||
// expand the nodes with the minimum level
|
||||
nSize = Vec_PtrSize(vFaninLeaves);
|
||||
Vec_PtrForEachEntryStop( vFaninLeaves, pObj, i, nSize )
|
||||
nSize = Vec_PtrSize(vLeaves);
|
||||
Vec_PtrForEachEntryStop( vLeaves, pObj, i, nSize )
|
||||
{
|
||||
if ( LevelMax != (int)pObj->Level )
|
||||
continue;
|
||||
|
|
@ -403,18 +499,20 @@ int Abc_NtkRRTfi_int( Vec_Ptr_t * vFaninLeaves, int LevelLimit )
|
|||
if ( Abc_NodeIsTravIdCurrent(pNext) )
|
||||
continue;
|
||||
Abc_NodeSetTravIdCurrent( pNext );
|
||||
Vec_PtrPush( vFaninLeaves, pNext );
|
||||
Vec_PtrPush( vLeaves, pNext );
|
||||
}
|
||||
}
|
||||
// remove old nodes (cannot remove a PI)
|
||||
k = 0;
|
||||
Vec_PtrForEachEntry( vFaninLeaves, pObj, i )
|
||||
Vec_PtrForEachEntry( vLeaves, pObj, i )
|
||||
{
|
||||
if ( LevelMax == (int)pObj->Level )
|
||||
continue;
|
||||
Vec_PtrWriteEntry( vFaninLeaves, k++, pObj );
|
||||
Vec_PtrWriteEntry( vLeaves, k++, pObj );
|
||||
}
|
||||
Vec_PtrShrink( vFaninLeaves, k );
|
||||
Vec_PtrShrink( vLeaves, k );
|
||||
if ( Vec_PtrSize(vLeaves) > 2000 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -429,60 +527,56 @@ int Abc_NtkRRTfi_int( Vec_Ptr_t * vFaninLeaves, int LevelLimit )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkRRTfo_int( Vec_Ptr_t * vFanoutRoots, int LevelLimit, Abc_Obj_t * pEdgeFanin, Abc_Obj_t * pEdgeFanout )
|
||||
int Abc_NtkRRTfo_int( Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, int LevelLimit, Abc_Obj_t * pEdgeFanin, Abc_Obj_t * pEdgeFanout )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pNext;
|
||||
int i, k, LevelMin, nSize;
|
||||
// find the minimum level of roots
|
||||
int i, k, LevelMin, nSize, fObjIsRoot;
|
||||
// find the minimum level of leaves
|
||||
LevelMin = ABC_INFINITY;
|
||||
Vec_PtrForEachEntry( vFanoutRoots, pObj, i )
|
||||
if ( Abc_ObjIsNode(pObj) && !pObj->fMarkA && LevelMin > (int)pObj->Level )
|
||||
Vec_PtrForEachEntry( vLeaves, pObj, i )
|
||||
if ( LevelMin > (int)pObj->Level )
|
||||
LevelMin = pObj->Level;
|
||||
// if the nodes are all POs, LevelMin == ABC_INFINITY
|
||||
if ( LevelMin == ABC_INFINITY || LevelMin > LevelLimit )
|
||||
// if the minimum level exceed the limit, we are done
|
||||
if ( LevelMin > LevelLimit )
|
||||
return 0;
|
||||
// expand the nodes with the minimum level
|
||||
nSize = Vec_PtrSize(vFanoutRoots);
|
||||
Vec_PtrForEachEntryStop( vFanoutRoots, pObj, i, nSize )
|
||||
nSize = Vec_PtrSize(vLeaves);
|
||||
Vec_PtrForEachEntryStop( vLeaves, pObj, i, nSize )
|
||||
{
|
||||
if ( LevelMin != (int)pObj->Level )
|
||||
continue;
|
||||
fObjIsRoot = 0;
|
||||
Abc_ObjForEachFanout( pObj, pNext, k )
|
||||
{
|
||||
if ( !Abc_ObjIsNode(pNext) || pNext->Level > (unsigned)LevelLimit )
|
||||
// check if the fanout is outside of the cone
|
||||
if ( Abc_ObjIsCo(pNext) || pNext->Level > (unsigned)LevelLimit )
|
||||
{
|
||||
pObj->fMarkA = 1;
|
||||
fObjIsRoot = 1;
|
||||
continue;
|
||||
}
|
||||
// skip the edge under check
|
||||
if ( pObj == pEdgeFanin && pNext == pEdgeFanout )
|
||||
continue;
|
||||
// skip the visited fanouts
|
||||
if ( Abc_NodeIsTravIdCurrent(pNext) )
|
||||
continue;
|
||||
Abc_NodeSetTravIdCurrent( pNext );
|
||||
Vec_PtrPush( vFanoutRoots, pNext );
|
||||
Vec_PtrPush( vLeaves, pNext );
|
||||
}
|
||||
if ( fObjIsRoot )
|
||||
Vec_PtrPush( vRoots, pObj );
|
||||
}
|
||||
// remove old nodes
|
||||
k = 0;
|
||||
Vec_PtrForEachEntry( vFanoutRoots, pObj, i )
|
||||
Vec_PtrForEachEntry( vLeaves, pObj, i )
|
||||
{
|
||||
if ( LevelMin == (int)pObj->Level )
|
||||
{
|
||||
// check if the node has external fanouts
|
||||
Abc_ObjForEachFanout( pObj, pNext, k )
|
||||
{
|
||||
if ( pObj == pEdgeFanin && pNext == pEdgeFanout )
|
||||
continue;
|
||||
if ( !Abc_NodeIsTravIdCurrent(pNext) )
|
||||
break;
|
||||
}
|
||||
// if external fanout is found, do not remove the node
|
||||
if ( pNext )
|
||||
continue;
|
||||
}
|
||||
Vec_PtrWriteEntry( vFanoutRoots, k++, pObj );
|
||||
continue;
|
||||
Vec_PtrWriteEntry( vLeaves, k++, pObj );
|
||||
}
|
||||
Vec_PtrShrink( vFanoutRoots, k );
|
||||
Vec_PtrShrink( vLeaves, k );
|
||||
if ( Vec_PtrSize(vLeaves) > 2000 )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -490,7 +584,8 @@ int Abc_NtkRRTfo_int( Vec_Ptr_t * vFanoutRoots, int LevelLimit, Abc_Obj_t * pEdg
|
|||
|
||||
Synopsis [Collects the roots in the TFO of the node.]
|
||||
|
||||
Description []
|
||||
Description [Note that this procedure can be improved by
|
||||
marking and skipping the visited nodes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
|
|
@ -501,14 +596,18 @@ int Abc_NtkRRTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vRoots, int LevelLimit )
|
|||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
int i;
|
||||
// if we encountered a node outside of the TFO cone of the fanins, quit
|
||||
if ( Abc_ObjIsCo(pNode) || pNode->Level > (unsigned)LevelLimit )
|
||||
return 0;
|
||||
if ( Abc_NodeIsTravIdCurrent(pNode) )
|
||||
// if we encountered a node on the boundary, add it to the roots
|
||||
if ( pNode->fMarkA )
|
||||
{
|
||||
Vec_PtrPushUnique( vRoots, pNode );
|
||||
return 1;
|
||||
}
|
||||
// mark the node with the current TravId (needed to have all internal nodes marked)
|
||||
Abc_NodeSetTravIdCurrent( pNode );
|
||||
// traverse the fanouts
|
||||
Abc_ObjForEachFanout( pNode, pFanout, i )
|
||||
if ( !Abc_NtkRRTfo_rec( pFanout, vRoots, LevelLimit ) )
|
||||
return 0;
|
||||
|
|
@ -517,7 +616,7 @@ int Abc_NtkRRTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vRoots, int LevelLimit )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Collects the leaves and cone of the roots.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -526,22 +625,26 @@ int Abc_NtkRRTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vRoots, int LevelLimit )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkRRTfi_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
|
||||
void Abc_NtkRRTfi_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, int LevelLimit )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
// skip visited nodes
|
||||
if ( pNode->fMarkA )
|
||||
if ( Abc_NodeIsTravIdCurrent(pNode) )
|
||||
return;
|
||||
pNode->fMarkA = 1;
|
||||
// add the node if it was not visited in the previus run
|
||||
if ( !Abc_NodeIsTravIdPrevious(pNode) )
|
||||
// add node to leaves if it is not in TFI cone of the leaves (marked before) or below the limit
|
||||
if ( !Abc_NodeIsTravIdPrevious(pNode) || (int)pNode->Level <= LevelLimit )
|
||||
{
|
||||
Abc_NodeSetTravIdCurrent( pNode );
|
||||
Vec_PtrPush( vLeaves, pNode );
|
||||
return;
|
||||
}
|
||||
// mark the node as visited
|
||||
Abc_NodeSetTravIdCurrent( pNode );
|
||||
// call for the node's fanins
|
||||
Abc_ObjForEachFanin( pNode, pFanin, i )
|
||||
Abc_NtkRRTfi_rec( pFanin, vLeaves, vCone );
|
||||
Abc_NtkRRTfi_rec( pFanin, vLeaves, vCone, LevelLimit );
|
||||
// add the node to the cone in topological order
|
||||
Vec_PtrPush( vCone, pNode );
|
||||
}
|
||||
|
||||
|
|
@ -560,6 +663,7 @@ Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vC
|
|||
{
|
||||
Abc_Ntk_t * pNtkNew;
|
||||
Abc_Obj_t * pObj;
|
||||
int fCheck = 1;
|
||||
int i;
|
||||
assert( Abc_NtkIsStrash(pNtk) );
|
||||
// start the network
|
||||
|
|
@ -581,12 +685,15 @@ Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vC
|
|||
Vec_PtrSize(vCone) - Abc_NtkNodeNum(pNtkNew) );
|
||||
// create the POs
|
||||
Vec_PtrForEachEntry( vRoots, pObj, i )
|
||||
{
|
||||
assert( !Abc_ObjIsComplement(pObj->pCopy) );
|
||||
Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pObj->pCopy );
|
||||
}
|
||||
// add the PI/PO names
|
||||
Abc_NtkAddDummyPiNames( pNtkNew );
|
||||
Abc_NtkAddDummyPoNames( pNtkNew );
|
||||
// check
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Abc_NtkWindow: The network check has failed.\n" );
|
||||
return NULL;
|
||||
|
|
@ -594,6 +701,288 @@ Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vC
|
|||
return pNtkNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts simulation to detect non-redundant edges.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkRRSimulateStart( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
unsigned uData, uData0, uData1;
|
||||
int i;
|
||||
Abc_NtkConst1(pNtk)->pData = (void *)~((unsigned)0);
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
pObj->pData = (void *)SIM_RANDOM_UNSIGNED;
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
if ( i == 0 ) continue;
|
||||
uData0 = (unsigned)Abc_ObjFanin0(pObj)->pData;
|
||||
uData1 = (unsigned)Abc_ObjFanin1(pObj)->pData;
|
||||
uData = Abc_ObjFaninC0(pObj)? ~uData0 : uData0;
|
||||
uData &= Abc_ObjFaninC1(pObj)? ~uData1 : uData1;
|
||||
assert( pObj->pData == NULL );
|
||||
pObj->pData = (void *)uData;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops simulation to detect non-redundant edges.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkRRSimulateStop( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
pObj->pData = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void Sim_TraverseNodes_rec( Abc_Obj_t * pRoot, Vec_Str_t * vTargets, Vec_Ptr_t * vNodes );
|
||||
static void Sim_CollectNodes_rec( Abc_Obj_t * pRoot, Vec_Ptr_t * vField );
|
||||
static void Sim_SimulateCollected( Vec_Str_t * vTargets, Vec_Ptr_t * vNodes, Vec_Ptr_t * vField );
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulation to detect non-redundant edges.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Str_t * Abc_NtkRRSimulate( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Vec_Ptr_t * vNodes, * vField;
|
||||
Vec_Str_t * vTargets;
|
||||
Abc_Obj_t * pObj;
|
||||
unsigned uData, uData0, uData1;
|
||||
int PrevCi, Phase, i, k;
|
||||
|
||||
// start the candidates
|
||||
vTargets = Vec_StrStart( Abc_NtkObjNumMax(pNtk) + 1 );
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
Phase = ((Abc_ObjFanoutNum(Abc_ObjFanin1(pObj)) > 1) << 1);
|
||||
Phase |= (Abc_ObjFanoutNum(Abc_ObjFanin0(pObj)) > 1);
|
||||
Vec_StrWriteEntry( vTargets, pObj->Id, (char)Phase );
|
||||
}
|
||||
|
||||
// simulate patters and store them in copy
|
||||
Abc_NtkConst1(pNtk)->pCopy = (Abc_Obj_t *)~((unsigned)0);
|
||||
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||
pObj->pCopy = (Abc_Obj_t *)SIM_RANDOM_UNSIGNED;
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
if ( i == 0 ) continue;
|
||||
uData0 = (unsigned)Abc_ObjFanin0(pObj)->pData;
|
||||
uData1 = (unsigned)Abc_ObjFanin1(pObj)->pData;
|
||||
uData = Abc_ObjFaninC0(pObj)? ~uData0 : uData0;
|
||||
uData &= Abc_ObjFaninC1(pObj)? ~uData1 : uData1;
|
||||
pObj->pCopy = (Abc_Obj_t *)uData;
|
||||
}
|
||||
// store the result in data
|
||||
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||
{
|
||||
uData0 = (unsigned)Abc_ObjFanin0(pObj)->pData;
|
||||
if ( Abc_ObjFaninC0(pObj) )
|
||||
pObj->pData = (void *)~uData0;
|
||||
else
|
||||
pObj->pData = (void *)uData0;
|
||||
}
|
||||
|
||||
// refine the candidates
|
||||
for ( PrevCi = 0; PrevCi < Abc_NtkCiNum(pNtk); PrevCi = i )
|
||||
{
|
||||
vNodes = Vec_PtrAlloc( 10 );
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
for ( i = PrevCi; i < Abc_NtkCiNum(pNtk); i++ )
|
||||
{
|
||||
Sim_TraverseNodes_rec( Abc_NtkCi(pNtk, i), vTargets, vNodes );
|
||||
if ( Vec_PtrSize(vNodes) > 128 )
|
||||
break;
|
||||
}
|
||||
// collect the marked nodes in the topological order
|
||||
vField = Vec_PtrAlloc( 10 );
|
||||
Abc_NtkIncrementTravId( pNtk );
|
||||
Abc_NtkForEachCo( pNtk, pObj, k )
|
||||
Sim_CollectNodes_rec( pObj, vField );
|
||||
|
||||
// simulate these nodes
|
||||
Sim_SimulateCollected( vTargets, vNodes, vField );
|
||||
// prepare for the next loop
|
||||
Vec_PtrFree( vNodes );
|
||||
}
|
||||
|
||||
// clean
|
||||
Abc_NtkForEachObj( pNtk, pObj, i )
|
||||
pObj->pData = NULL;
|
||||
return vTargets;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects nodes starting from the given node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sim_TraverseNodes_rec( Abc_Obj_t * pRoot, Vec_Str_t * vTargets, Vec_Ptr_t * vNodes )
|
||||
{
|
||||
Abc_Obj_t * pFanout;
|
||||
char Entry;
|
||||
int k;
|
||||
if ( Abc_NodeIsTravIdCurrent(pRoot) )
|
||||
return;
|
||||
Abc_NodeSetTravIdCurrent( pRoot );
|
||||
// save the reached targets
|
||||
Entry = Vec_StrEntry(vTargets, pRoot->Id);
|
||||
if ( Entry & 1 )
|
||||
Vec_PtrPush( vNodes, Abc_ObjNot(pRoot) );
|
||||
if ( Entry & 2 )
|
||||
Vec_PtrPush( vNodes, pRoot );
|
||||
// explore the fanouts
|
||||
Abc_ObjForEachFanout( pRoot, pFanout, k )
|
||||
Sim_TraverseNodes_rec( pFanout, vTargets, vNodes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects nodes starting from the given node.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sim_CollectNodes_rec( Abc_Obj_t * pRoot, Vec_Ptr_t * vField )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i;
|
||||
if ( Abc_NodeIsTravIdCurrent(pRoot) )
|
||||
return;
|
||||
if ( !Abc_NodeIsTravIdPrevious(pRoot) )
|
||||
return;
|
||||
Abc_NodeSetTravIdCurrent( pRoot );
|
||||
Abc_ObjForEachFanin( pRoot, pFanin, i )
|
||||
Sim_CollectNodes_rec( pFanin, vField );
|
||||
if ( !Abc_ObjIsCo(pRoot) )
|
||||
pRoot->pData = (void *)Vec_PtrSize(vField);
|
||||
Vec_PtrPush( vField, pRoot );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simulate the given nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sim_SimulateCollected( Vec_Str_t * vTargets, Vec_Ptr_t * vNodes, Vec_Ptr_t * vField )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pFanin0, * pFanin1, * pDisproved;
|
||||
Vec_Ptr_t * vSims;
|
||||
unsigned * pUnsigned, * pUnsignedF;
|
||||
int i, k, Phase, fCompl;
|
||||
// get simulation info
|
||||
vSims = Sim_UtilInfoAlloc( Vec_PtrSize(vField), Vec_PtrSize(vNodes), 0 );
|
||||
// simulate the nodes
|
||||
Vec_PtrForEachEntry( vField, pObj, i )
|
||||
{
|
||||
if ( Abc_ObjIsCi(pObj) )
|
||||
{
|
||||
pUnsigned = Vec_PtrEntry( vSims, i );
|
||||
for ( k = 0; k < Vec_PtrSize(vNodes); k++ )
|
||||
pUnsigned[k] = (unsigned)pObj->pCopy;
|
||||
continue;
|
||||
}
|
||||
if ( Abc_ObjIsCo(pObj) )
|
||||
{
|
||||
pUnsigned = Vec_PtrEntry( vSims, i );
|
||||
pUnsignedF = Vec_PtrEntry( vSims, (int)Abc_ObjFanin0(pObj)->pData );
|
||||
if ( Abc_ObjFaninC0(pObj) )
|
||||
for ( k = 0; k < Vec_PtrSize(vNodes); k++ )
|
||||
pUnsigned[k] = ~pUnsignedF[k];
|
||||
else
|
||||
for ( k = 0; k < Vec_PtrSize(vNodes); k++ )
|
||||
pUnsigned[k] = pUnsignedF[k];
|
||||
// update targets
|
||||
for ( k = 0; k < Vec_PtrSize(vNodes); k++ )
|
||||
{
|
||||
if ( pUnsigned[k] == (unsigned)pObj->pData )
|
||||
continue;
|
||||
pDisproved = Vec_PtrEntry( vNodes, k );
|
||||
fCompl = Abc_ObjIsComplement(pDisproved);
|
||||
pDisproved = Abc_ObjRegular(pDisproved);
|
||||
Phase = Vec_StrEntry( vTargets, pDisproved->Id );
|
||||
if ( fCompl )
|
||||
Phase = (Phase & 2);
|
||||
else
|
||||
Phase = (Phase & 1);
|
||||
Vec_StrWriteEntry( vTargets, pDisproved->Id, (char)Phase );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// simulate the node
|
||||
pFanin0 = Abc_ObjFanin0(pObj);
|
||||
pFanin1 = Abc_ObjFanin1(pObj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
{
|
||||
unsigned uData;
|
||||
if ( pFanin == Abc_ObjFanin0(pNode) )
|
||||
{
|
||||
uData = (unsigned)Abc_ObjFanin1(pNode)->pData;
|
||||
uData = Abc_ObjFaninC1(pNode)? ~uData : uData;
|
||||
}
|
||||
else if ( pFanin == Abc_ObjFanin1(pNode) )
|
||||
{
|
||||
uData = (unsigned)Abc_ObjFanin0(pNode)->pData;
|
||||
uData = Abc_ObjFaninC0(pNode)? ~uData : uData;
|
||||
}
|
||||
uData ^= (unsigned)pNode->pData;
|
||||
// Extra_PrintBinary( stdout, &uData, 32 ); printf( "\n" );
|
||||
if ( Extra_WordCountOnes(uData) > 8 )
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -168,6 +168,14 @@ int CmdCommandTime( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
pAbc->TimeTotal += pAbc->TimeCommand;
|
||||
fprintf( pAbc->Out, "elapse: %3.2f seconds, total: %3.2f seconds\n",
|
||||
(float)pAbc->TimeCommand / CLOCKS_PER_SEC, (float)pAbc->TimeTotal / CLOCKS_PER_SEC );
|
||||
/*
|
||||
{
|
||||
FILE * pTable;
|
||||
pTable = fopen( "runtimes.txt", "a+" );
|
||||
fprintf( pTable, "%4.2f\n", (float)pAbc->TimeCommand / CLOCKS_PER_SEC );
|
||||
fclose( pTable );
|
||||
}
|
||||
*/
|
||||
pAbc->TimeCommand = 0;
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -212,6 +212,12 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
|
|||
// read the model name
|
||||
if ( strcmp( p->vTokens->pArray[0], ".model" ) == 0 )
|
||||
pNtk->pName = Extra_UtilStrsav( p->vTokens->pArray[1] );
|
||||
else if ( strcmp( p->vTokens->pArray[0], ".exdc" ) != 0 )
|
||||
{
|
||||
printf( "%s: File parsing skipped after line %d (\"%s\").\n", p->pFileName,
|
||||
Extra_FileReaderGetLineNumber(p->pReader, 0), p->vTokens->pArray[0] );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// read the inputs/outputs
|
||||
pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,497 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [ioWriteVerilog.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Command processing package.]
|
||||
|
||||
Synopsis [Procedures to output a special subset of Verilog.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: ioWriteVerilog.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "io.h"
|
||||
#include "main.h"
|
||||
#include "mio.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk );
|
||||
static void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
|
||||
static void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
|
||||
static void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
|
||||
static void Io_WriteVerilogRegs( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
|
||||
static void Io_WriteVerilogGates( FILE * pFile, Abc_Ntk_t * pNtk );
|
||||
static void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk );
|
||||
static void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros );
|
||||
static void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk );
|
||||
static int Io_WriteVerilogCheckNtk( Abc_Ntk_t * pNtk );
|
||||
static char * Io_WriteVerilogGetName( Abc_Obj_t * pObj );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Write verilog.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName )
|
||||
{
|
||||
FILE * pFile;
|
||||
|
||||
if ( !(Abc_NtkIsNetlist(pNtk) && (Abc_NtkHasMapping(pNtk) || Io_WriteVerilogCheckNtk(pNtk))) )
|
||||
{
|
||||
printf( "Io_WriteVerilog(): Can produce Verilog for a subset of logic networks.\n" );
|
||||
printf( "The network should be either an AIG or a network after technology mapping.\n" );
|
||||
printf( "The current network is not in the subset; the output files is not written.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// start the output stream
|
||||
pFile = fopen( pFileName, "w" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
fprintf( stdout, "Io_WriteVerilog(): Cannot open the output file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
// write the equations for the network
|
||||
Io_WriteVerilogInt( pFile, pNtk );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes verilog.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
// write inputs and outputs
|
||||
fprintf( pFile, "// Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
|
||||
fprintf( pFile, "module %s ( gclk,\n ", Abc_NtkName(pNtk) );
|
||||
Io_WriteVerilogPis( pFile, pNtk, 3 );
|
||||
fprintf( pFile, ",\n " );
|
||||
Io_WriteVerilogPos( pFile, pNtk, 3 );
|
||||
fprintf( pFile, " );\n" );
|
||||
// write inputs, outputs, registers, and wires
|
||||
fprintf( pFile, " input gclk," );
|
||||
Io_WriteVerilogPis( pFile, pNtk, 10 );
|
||||
fprintf( pFile, ";\n" );
|
||||
fprintf( pFile, " output" );
|
||||
Io_WriteVerilogPos( pFile, pNtk, 5 );
|
||||
fprintf( pFile, ";\n" );
|
||||
if ( Abc_NtkLatchNum(pNtk) > 0 )
|
||||
{
|
||||
fprintf( pFile, " reg" );
|
||||
Io_WriteVerilogRegs( pFile, pNtk, 4 );
|
||||
fprintf( pFile, ";\n" );
|
||||
}
|
||||
fprintf( pFile, " wire" );
|
||||
Io_WriteVerilogWires( pFile, pNtk, 4 );
|
||||
fprintf( pFile, ";\n" );
|
||||
// write registers
|
||||
Io_WriteVerilogLatches( pFile, pNtk );
|
||||
// write the nodes
|
||||
if ( Abc_NtkHasMapping(pNtk) )
|
||||
Io_WriteVerilogGates( pFile, pNtk );
|
||||
else
|
||||
Io_WriteVerilogNodes( pFile, pNtk );
|
||||
// finalize the file
|
||||
fprintf( pFile, "endmodule\n\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the primary inputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
||||
{
|
||||
Abc_Obj_t * pTerm, * pNet;
|
||||
int LineLength;
|
||||
int AddedLength;
|
||||
int NameCounter;
|
||||
int i;
|
||||
|
||||
LineLength = Start;
|
||||
NameCounter = 0;
|
||||
Abc_NtkForEachPi( pNtk, pTerm, i )
|
||||
{
|
||||
pNet = Abc_ObjFanout0(pTerm);
|
||||
// get the line length after this name is written
|
||||
AddedLength = strlen(Abc_ObjName(pNet)) + 2;
|
||||
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
|
||||
{ // write the line extender
|
||||
fprintf( pFile, "\n " );
|
||||
// reset the line length
|
||||
LineLength = 3;
|
||||
NameCounter = 0;
|
||||
}
|
||||
fprintf( pFile, " %s%s", Abc_ObjName(pNet), (i==Abc_NtkPiNum(pNtk)-1)? "" : "," );
|
||||
LineLength += AddedLength;
|
||||
NameCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the primary outputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
||||
{
|
||||
Abc_Obj_t * pTerm, * pNet;
|
||||
int LineLength;
|
||||
int AddedLength;
|
||||
int NameCounter;
|
||||
int i;
|
||||
|
||||
LineLength = Start;
|
||||
NameCounter = 0;
|
||||
Abc_NtkForEachPo( pNtk, pTerm, i )
|
||||
{
|
||||
pNet = Abc_ObjFanin0(pTerm);
|
||||
// get the line length after this name is written
|
||||
AddedLength = strlen(Abc_ObjName(pNet)) + 2;
|
||||
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
|
||||
{ // write the line extender
|
||||
fprintf( pFile, "\n " );
|
||||
// reset the line length
|
||||
LineLength = 3;
|
||||
NameCounter = 0;
|
||||
}
|
||||
fprintf( pFile, " %s%s", Abc_ObjName(pNet), (i==Abc_NtkPoNum(pNtk)-1)? "" : "," );
|
||||
LineLength += AddedLength;
|
||||
NameCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the wires.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
||||
{
|
||||
Abc_Obj_t * pTerm, * pNet;
|
||||
int LineLength;
|
||||
int AddedLength;
|
||||
int NameCounter;
|
||||
int i, Counter, nNodes;
|
||||
|
||||
// count the number of wires
|
||||
nNodes = 0;
|
||||
Abc_NtkForEachNode( pNtk, pTerm, i )
|
||||
{
|
||||
if ( i == 0 )
|
||||
continue;
|
||||
pNet = Abc_ObjFanout0(pTerm);
|
||||
if ( Abc_ObjIsCo(Abc_ObjFanout0(pNet)) )
|
||||
continue;
|
||||
nNodes++;
|
||||
}
|
||||
|
||||
// write the wires
|
||||
Counter = 0;
|
||||
LineLength = Start;
|
||||
NameCounter = 0;
|
||||
Abc_NtkForEachNode( pNtk, pTerm, i )
|
||||
{
|
||||
if ( i == 0 )
|
||||
continue;
|
||||
pNet = Abc_ObjFanout0(pTerm);
|
||||
if ( Abc_ObjIsCo(Abc_ObjFanout0(pNet)) )
|
||||
continue;
|
||||
Counter++;
|
||||
// get the line length after this name is written
|
||||
AddedLength = strlen(Abc_ObjName(pNet)) + 2;
|
||||
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
|
||||
{ // write the line extender
|
||||
fprintf( pFile, "\n " );
|
||||
// reset the line length
|
||||
LineLength = 3;
|
||||
NameCounter = 0;
|
||||
}
|
||||
fprintf( pFile, " %s%s", Io_WriteVerilogGetName(pNet), (Counter==nNodes)? "" : "," );
|
||||
LineLength += AddedLength;
|
||||
NameCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the regs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogRegs( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
||||
{
|
||||
Abc_Obj_t * pLatch, * pNet;
|
||||
int LineLength;
|
||||
int AddedLength;
|
||||
int NameCounter;
|
||||
int i, Counter, nNodes;
|
||||
|
||||
// count the number of latches
|
||||
nNodes = Abc_NtkLatchNum(pNtk);
|
||||
|
||||
// write the wires
|
||||
Counter = 0;
|
||||
LineLength = Start;
|
||||
NameCounter = 0;
|
||||
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
||||
{
|
||||
pNet = Abc_ObjFanout0(pLatch);
|
||||
Counter++;
|
||||
// get the line length after this name is written
|
||||
AddedLength = strlen(Abc_ObjName(pNet)) + 2;
|
||||
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
|
||||
{ // write the line extender
|
||||
fprintf( pFile, "\n " );
|
||||
// reset the line length
|
||||
LineLength = 3;
|
||||
NameCounter = 0;
|
||||
}
|
||||
fprintf( pFile, " %s%s", Io_WriteVerilogGetName(pNet), (Counter==nNodes)? "" : "," );
|
||||
LineLength += AddedLength;
|
||||
NameCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the latches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pLatch;
|
||||
int i;
|
||||
Abc_NtkForEachLatch( pNtk, pLatch, i )
|
||||
{
|
||||
if ( Abc_LatchInit(pLatch) == ABC_INIT_ZERO )
|
||||
fprintf( pFile, " initial begin %s = 1\'b0; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
|
||||
else if ( Abc_LatchInit(pLatch) == ABC_INIT_ONE )
|
||||
fprintf( pFile, " initial begin %s = 1\'b1; end\n", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
|
||||
fprintf( pFile, " always@(posedge gclk) begin %s", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
|
||||
fprintf( pFile, " = %s; end\n", Abc_ObjName(Abc_ObjFanin0(pLatch)) );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the gates.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogGates( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Mio_Gate_t * pGate;
|
||||
Mio_Pin_t * pGatePin;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, k, Counter, nDigits, nFanins;
|
||||
|
||||
Counter = 1;
|
||||
nDigits = Extra_Base10Log( Abc_NtkNodeNum(pNtk) );
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
pGate = pObj->pData;
|
||||
nFanins = Abc_ObjFaninNum(pObj);
|
||||
fprintf( pFile, " %s g%0*d", Mio_GateReadName(pGate), nDigits, Counter++ );
|
||||
fprintf( pFile, "(.%s (%s),", Mio_GateReadOutName(pGate), Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) );
|
||||
for ( pGatePin = Mio_GateReadPins(pGate), k = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), k++ )
|
||||
fprintf( pFile, " .%s (%s)%s", Mio_PinReadName(pGatePin), Io_WriteVerilogGetName(Abc_ObjFanin(pObj,k)), k==nFanins-1? "":"," );
|
||||
fprintf( pFile, ");\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj, * pFanin;
|
||||
int i, k, nFanins;
|
||||
char * pName;
|
||||
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
assert( Abc_SopGetCubeNum(pObj->pData) == 1 );
|
||||
nFanins = Abc_ObjFaninNum(pObj);
|
||||
if ( nFanins == 0 )
|
||||
{
|
||||
fprintf( pFile, " assign %s = 1'b%d;\n", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)), !Abc_SopIsComplement(pObj->pData) );
|
||||
continue;
|
||||
}
|
||||
if ( nFanins == 1 )
|
||||
{
|
||||
pName = Abc_SopIsInv(pObj->pData)? "not" : "and";
|
||||
fprintf( pFile, " %s(%s, ", pName, Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) );
|
||||
fprintf( pFile, "%s);\n", Io_WriteVerilogGetName(Abc_ObjFanin0(pObj)) );
|
||||
continue;
|
||||
}
|
||||
pName = Abc_SopIsComplement(pObj->pData)? "or" : "and";
|
||||
fprintf( pFile, " %s(%s, ", pName, Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||
fprintf( pFile, "%s%s", Io_WriteVerilogGetName(pFanin), (k==nFanins-1? "" : ", ") );
|
||||
fprintf( pFile, ");\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the inputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i, Counter = 2;
|
||||
fprintf( pFile, "(.z (%s)", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
{
|
||||
if ( Counter++ % 4 == 0 )
|
||||
fprintf( pFile, "\n " );
|
||||
fprintf( pFile, " .i%d (%s)", i+1, Io_WriteVerilogGetName(Abc_ObjFanin(pObj,i)) );
|
||||
}
|
||||
for ( ; i < nInMax; i++ )
|
||||
{
|
||||
if ( Counter++ % 4 == 0 )
|
||||
fprintf( pFile, "\n " );
|
||||
fprintf( pFile, " .i%d (%s)", i+1, fPadZeros? "1\'b0" : "1\'b1" );
|
||||
}
|
||||
fprintf( pFile, ");\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Io_WriteVerilogCheckNtk( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i;
|
||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||
{
|
||||
if ( Abc_SopGetCubeNum(pObj->pData) > 1 )
|
||||
{
|
||||
printf( "Node %s contains a cover with more than one cube.\n", Abc_ObjName(pObj) );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prepares the name for writing the Verilog file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Io_WriteVerilogGetName( Abc_Obj_t * pObj )
|
||||
{
|
||||
static char Buffer[20];
|
||||
char * pName;
|
||||
pName = Abc_ObjName(pObj);
|
||||
if ( pName[0] != '[' )
|
||||
return pName;
|
||||
// replace the brackets; as a result, the length of the name does not change
|
||||
strcpy( Buffer, pName );
|
||||
Buffer[0] = 'x';
|
||||
Buffer[strlen(Buffer)-1] = 'x';
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -24,14 +24,14 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk );
|
||||
static void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
|
||||
static void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
|
||||
static void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
|
||||
static void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk );
|
||||
static void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros );
|
||||
static int Io_WriteVerilogCheckNtk( Abc_Ntk_t * pNtk );
|
||||
static char * Io_WriteVerilogGetName( Abc_Obj_t * pObj );
|
||||
static void Io_WriteVerilogAuxInt( FILE * pFile, Abc_Ntk_t * pNtk );
|
||||
static void Io_WriteVerilogAuxPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
|
||||
static void Io_WriteVerilogAuxPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
|
||||
static void Io_WriteVerilogAuxWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
|
||||
static void Io_WriteVerilogAuxNodes( FILE * pFile, Abc_Ntk_t * pNtk );
|
||||
static void Io_WriteVerilogAuxArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros );
|
||||
static int Io_WriteVerilogAuxCheckNtk( Abc_Ntk_t * pNtk );
|
||||
static char * Io_WriteVerilogAuxGetName( Abc_Obj_t * pObj );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -48,30 +48,30 @@ static char * Io_WriteVerilogGetName( Abc_Obj_t * pObj );
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName )
|
||||
void Io_WriteVerilogAux( Abc_Ntk_t * pNtk, char * pFileName )
|
||||
{
|
||||
FILE * pFile;
|
||||
|
||||
if ( !Abc_NtkIsSopNetlist(pNtk) || !Io_WriteVerilogCheckNtk(pNtk) )
|
||||
if ( !Abc_NtkIsSopNetlist(pNtk) || !Io_WriteVerilogAuxCheckNtk(pNtk) )
|
||||
{
|
||||
printf( "Io_WriteVerilog(): Can write Verilog for a very special subset of logic networks.\n" );
|
||||
printf( "Io_WriteVerilogAux(): Can write Verilog for a very special subset of logic networks.\n" );
|
||||
printf( "The current network is not in the subset; writing Verilog is not performed.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( Abc_NtkLatchNum(pNtk) > 0 )
|
||||
printf( "Io_WriteVerilog(): Warning: only combinational portion is being written.\n" );
|
||||
printf( "Io_WriteVerilogAux(): Warning: only combinational portion is being written.\n" );
|
||||
|
||||
// start the output stream
|
||||
pFile = fopen( pFileName, "w" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
fprintf( stdout, "Io_WriteVerilog(): Cannot open the output file \"%s\".\n", pFileName );
|
||||
fprintf( stdout, "Io_WriteVerilogAux(): Cannot open the output file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
// write the equations for the network
|
||||
Io_WriteVerilogInt( pFile, pNtk );
|
||||
Io_WriteVerilogAuxInt( pFile, pNtk );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
|
@ -87,27 +87,27 @@ void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
void Io_WriteVerilogAuxInt( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
// write inputs and outputs
|
||||
fprintf( pFile, "// Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
|
||||
fprintf( pFile, "module %s (\n ", Abc_NtkName(pNtk) );
|
||||
Io_WriteVerilogPis( pFile, pNtk, 3 );
|
||||
Io_WriteVerilogAuxPis( pFile, pNtk, 3 );
|
||||
fprintf( pFile, ",\n " );
|
||||
Io_WriteVerilogPos( pFile, pNtk, 3 );
|
||||
Io_WriteVerilogAuxPos( pFile, pNtk, 3 );
|
||||
fprintf( pFile, " );\n" );
|
||||
// write inputs, outputs and wires
|
||||
fprintf( pFile, " input" );
|
||||
Io_WriteVerilogPis( pFile, pNtk, 5 );
|
||||
Io_WriteVerilogAuxPis( pFile, pNtk, 5 );
|
||||
fprintf( pFile, ";\n" );
|
||||
fprintf( pFile, " output" );
|
||||
Io_WriteVerilogPos( pFile, pNtk, 5 );
|
||||
Io_WriteVerilogAuxPos( pFile, pNtk, 5 );
|
||||
fprintf( pFile, ";\n" );
|
||||
fprintf( pFile, " wire" );
|
||||
Io_WriteVerilogWires( pFile, pNtk, 4 );
|
||||
Io_WriteVerilogAuxWires( pFile, pNtk, 4 );
|
||||
fprintf( pFile, ";\n" );
|
||||
// write the nodes
|
||||
Io_WriteVerilogNodes( pFile, pNtk );
|
||||
Io_WriteVerilogAuxNodes( pFile, pNtk );
|
||||
// finalize the file
|
||||
fprintf( pFile, "endmodule\n\n" );
|
||||
fclose( pFile );
|
||||
|
|
@ -124,7 +124,7 @@ void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
||||
void Io_WriteVerilogAuxPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
||||
{
|
||||
Abc_Obj_t * pTerm, * pNet;
|
||||
int LineLength;
|
||||
|
|
@ -163,7 +163,7 @@ void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
||||
void Io_WriteVerilogAuxPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
||||
{
|
||||
Abc_Obj_t * pTerm, * pNet;
|
||||
int LineLength;
|
||||
|
|
@ -202,7 +202,7 @@ void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
||||
void Io_WriteVerilogAuxWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
||||
{
|
||||
Abc_Obj_t * pTerm, * pNet;
|
||||
int LineLength;
|
||||
|
|
@ -243,7 +243,7 @@ void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
|||
LineLength = 3;
|
||||
NameCounter = 0;
|
||||
}
|
||||
fprintf( pFile, " %s%s", Io_WriteVerilogGetName(pNet), (Counter==nNodes)? "" : "," );
|
||||
fprintf( pFile, " %s%s", Io_WriteVerilogAuxGetName(pNet), (Counter==nNodes)? "" : "," );
|
||||
LineLength += AddedLength;
|
||||
NameCounter++;
|
||||
}
|
||||
|
|
@ -260,7 +260,7 @@ void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
void Io_WriteVerilogAuxNodes( FILE * pFile, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
int i, nCubes, nFanins, Counter, nDigits, fPadZeros;
|
||||
|
|
@ -284,62 +284,62 @@ void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
if ( nCubes == 0 )
|
||||
{
|
||||
fprintf( pFile, " ts_gnd g%0*d ", nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 0, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 0, fPadZeros );
|
||||
}
|
||||
else if ( nCubes == 1 && nFanins == 0 )
|
||||
{
|
||||
fprintf( pFile, " ts_vdd g%0*d ", nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 0, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 0, fPadZeros );
|
||||
}
|
||||
else if ( nFanins == 1 && Abc_SopIsInv(pObj->pData) )
|
||||
{
|
||||
fprintf( pFile, " ts_inv g%0*d ", nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 1, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 1, fPadZeros );
|
||||
}
|
||||
else if ( nFanins == 1 )
|
||||
{
|
||||
fprintf( pFile, " ts_buf g%0*d ", nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 1, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 1, fPadZeros );
|
||||
}
|
||||
else if ( nFanins <= 4 )
|
||||
{
|
||||
fprintf( pFile, " %s%d g%0*d ", pName, 4, nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 4, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 4, fPadZeros );
|
||||
}
|
||||
else if ( nFanins <= 6 )
|
||||
{
|
||||
fprintf( pFile, " %s%d g%0*d ", pName, 6, nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 6, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 6, fPadZeros );
|
||||
}
|
||||
else if ( nFanins == 7 )
|
||||
{
|
||||
fprintf( pFile, " %s%d g%0*d ", pName, 7, nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 7, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 7, fPadZeros );
|
||||
}
|
||||
else if ( nFanins == 8 )
|
||||
{
|
||||
fprintf( pFile, " %s%d g%0*d ", pName, 8, nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 8, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 8, fPadZeros );
|
||||
}
|
||||
else if ( nFanins <= 16 )
|
||||
{
|
||||
fprintf( pFile, " %s%d g%0*d ", pName, 16, nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 16, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 16, fPadZeros );
|
||||
}
|
||||
else if ( nFanins <= 32 )
|
||||
{
|
||||
fprintf( pFile, " %s%d g%0*d ", pName, 32, nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 32, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 32, fPadZeros );
|
||||
}
|
||||
else if ( nFanins <= 64 )
|
||||
{
|
||||
fprintf( pFile, " %s%d g%0*d ", pName, 64, nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 64, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 64, fPadZeros );
|
||||
}
|
||||
else if ( nFanins <= 128 )
|
||||
{
|
||||
fprintf( pFile, " %s%d g%0*d ", pName, 128, nDigits, Counter++ );
|
||||
Io_WriteVerilogArgs( pFile, pObj, 128, fPadZeros );
|
||||
Io_WriteVerilogAuxArgs( pFile, pObj, 128, fPadZeros );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -355,16 +355,16 @@ void Io_WriteVerilogNodes( FILE * pFile, Abc_Ntk_t * pNtk )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros )
|
||||
void Io_WriteVerilogAuxArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZeros )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i, Counter = 2;
|
||||
fprintf( pFile, "(.z (%s)", Io_WriteVerilogGetName(Abc_ObjFanout0(pObj)) );
|
||||
fprintf( pFile, "(.z (%s)", Io_WriteVerilogAuxGetName(Abc_ObjFanout0(pObj)) );
|
||||
Abc_ObjForEachFanin( pObj, pFanin, i )
|
||||
{
|
||||
if ( Counter++ % 4 == 0 )
|
||||
fprintf( pFile, "\n " );
|
||||
fprintf( pFile, " .i%d (%s)", i+1, Io_WriteVerilogGetName(Abc_ObjFanin(pObj,i)) );
|
||||
fprintf( pFile, " .i%d (%s)", i+1, Io_WriteVerilogAuxGetName(Abc_ObjFanin(pObj,i)) );
|
||||
}
|
||||
for ( ; i < nInMax; i++ )
|
||||
{
|
||||
|
|
@ -386,7 +386,7 @@ void Io_WriteVerilogArgs( FILE * pFile, Abc_Obj_t * pObj, int nInMax, int fPadZe
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Io_WriteVerilogCheckNtk( Abc_Ntk_t * pNtk )
|
||||
int Io_WriteVerilogAuxCheckNtk( Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pObj;
|
||||
char * pSop;
|
||||
|
|
@ -423,7 +423,7 @@ int Io_WriteVerilogCheckNtk( Abc_Ntk_t * pNtk )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Io_WriteVerilogGetName( Abc_Obj_t * pObj )
|
||||
char * Io_WriteVerilogAuxGetName( Abc_Obj_t * pObj )
|
||||
{
|
||||
static char Buffer[20];
|
||||
char * pName;
|
||||
|
|
@ -17,4 +17,5 @@ SRC += src/base/io/io.c \
|
|||
src/base/io/ioWriteGml.c \
|
||||
src/base/io/ioWriteList.c \
|
||||
src/base/io/ioWritePla.c \
|
||||
src/base/io/ioWriteVerilog.c
|
||||
src/base/io/ioWriteVer.c \
|
||||
src/base/io/ioWriteVerAux.c
|
||||
|
|
|
|||
|
|
@ -0,0 +1,184 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cutExpand.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [K-feasible cut computation package.]
|
||||
|
||||
Synopsis [Computes the truth table of the cut after expansion.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cutExpand.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cutInt.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define CUT_CELL_MVAR 9
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the stretching phase of the cut w.r.t. the merged cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Cut_TruthPhase( Cut_Cut_t * pCut, Cut_Cut_t * pCut1 )
|
||||
{
|
||||
unsigned uPhase = 0;
|
||||
int i, k;
|
||||
for ( i = k = 0; i < (int)pCut->nLeaves; i++ )
|
||||
{
|
||||
if ( k == (int)pCut1->nLeaves )
|
||||
break;
|
||||
if ( pCut->pLeaves[i] < pCut1->pLeaves[k] )
|
||||
continue;
|
||||
assert( pCut->pLeaves[i] == pCut1->pLeaves[k] );
|
||||
uPhase |= (1 << i);
|
||||
k++;
|
||||
}
|
||||
return uPhase;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes the truth table of the composition of cuts.]
|
||||
|
||||
Description [Inputs are:
|
||||
- a factor cut (truth table is stored inside)
|
||||
- a node in the factor cut
|
||||
- a tree cut to be substituted (truth table is stored inside)
|
||||
- the resulting cut (truth table will be filled in).
|
||||
Note that all cuts, including the resulting one, should be already
|
||||
computed and the nodes should be stored in the ascending order.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cut_TruthCompose( Cut_Cut_t * pCutF, int Node, Cut_Cut_t * pCutT, Cut_Cut_t * pCutRes )
|
||||
{
|
||||
static unsigned uCof0[1<<(CUT_CELL_MVAR-5)];
|
||||
static unsigned uCof1[1<<(CUT_CELL_MVAR-5)];
|
||||
static unsigned uTemp[1<<(CUT_CELL_MVAR-5)];
|
||||
unsigned * pIn, * pOut, * pTemp;
|
||||
unsigned uPhase;
|
||||
int NodeIndex, i, k;
|
||||
|
||||
// sanity checks
|
||||
assert( pCutF->nVarsMax == pCutT->nVarsMax );
|
||||
assert( pCutF->nVarsMax == pCutRes->nVarsMax );
|
||||
assert( pCutF->nVarsMax <= CUT_CELL_MVAR );
|
||||
// the factor cut (pCutF) should have its nodes sorted in the ascending order
|
||||
assert( pCutF->nLeaves <= pCutF->nVarsMax );
|
||||
for ( i = 0; i < (int)pCutF->nLeaves - 1; i++ )
|
||||
assert( pCutF->pLeaves[i] < pCutF->pLeaves[i+1] );
|
||||
// the tree cut (pCutT) should have its nodes sorted in the ascending order
|
||||
assert( pCutT->nLeaves <= pCutT->nVarsMax );
|
||||
for ( i = 0; i < (int)pCutT->nLeaves - 1; i++ )
|
||||
assert( pCutT->pLeaves[i] < pCutT->pLeaves[i+1] );
|
||||
// the resulting cut (pCutRes) should have its nodes sorted in the ascending order
|
||||
assert( pCutRes->nLeaves <= pCutRes->nVarsMax );
|
||||
for ( i = 0; i < (int)pCutRes->nLeaves - 1; i++ )
|
||||
assert( pCutRes->pLeaves[i] < pCutRes->pLeaves[i+1] );
|
||||
// make sure that every node in pCutF (except Node) appears in pCutRes
|
||||
for ( i = 0; i < (int)pCutF->nLeaves; i++ )
|
||||
{
|
||||
if ( pCutF->pLeaves[i] == Node )
|
||||
continue;
|
||||
for ( k = 0; k < (int)pCutRes->nLeaves; k++ )
|
||||
if ( pCutF->pLeaves[i] == pCutRes->pLeaves[k] )
|
||||
break;
|
||||
assert( k < (int)pCutRes->nLeaves ); // node i from pCutF is not found in pCutRes!!!
|
||||
}
|
||||
// make sure that every node in pCutT appears in pCutRes
|
||||
for ( i = 0; i < (int)pCutT->nLeaves; i++ )
|
||||
{
|
||||
for ( k = 0; k < (int)pCutRes->nLeaves; k++ )
|
||||
if ( pCutT->pLeaves[i] == pCutRes->pLeaves[k] )
|
||||
break;
|
||||
assert( k < (int)pCutRes->nLeaves ); // node i from pCutT is not found in pCutRes!!!
|
||||
}
|
||||
|
||||
|
||||
// find the index of the given node in the factor cut
|
||||
NodeIndex = -1;
|
||||
for ( NodeIndex = 0; NodeIndex < (int)pCutF->nLeaves; NodeIndex++ )
|
||||
if ( pCutF->pLeaves[NodeIndex] == Node )
|
||||
break;
|
||||
assert( NodeIndex >= 0 ); // Node should be in pCutF
|
||||
|
||||
// copy the truth table
|
||||
Extra_TruthCopy( uTemp, Cut_CutReadTruth(pCutF), pCutF->nLeaves );
|
||||
|
||||
// bubble-move the NodeIndex variable to be the last one (the most significant one)
|
||||
pIn = uTemp; pOut = uCof0; // uCof0 is used for temporary storage here
|
||||
for ( i = NodeIndex; i < (int)pCutF->nLeaves - 1; i++ )
|
||||
{
|
||||
Extra_TruthSwapAdjacentVars( pOut, pIn, pCutF->nLeaves, i );
|
||||
pTemp = pIn; pIn = pOut; pOut = pTemp;
|
||||
}
|
||||
if ( (pCutF->nLeaves - 1 - NodeIndex) & 1 )
|
||||
Extra_TruthCopy( pOut, pIn, pCutF->nLeaves );
|
||||
// the result of stretching is in uTemp
|
||||
|
||||
// cofactor the factor cut with respect to the node
|
||||
Extra_TruthCopy( uCof0, uTemp, pCutF->nLeaves );
|
||||
Extra_TruthCofactor0( uCof0, pCutF->nLeaves, pCutF->nLeaves-1 );
|
||||
Extra_TruthCopy( uCof1, uTemp, pCutF->nLeaves );
|
||||
Extra_TruthCofactor1( uCof1, pCutF->nLeaves, pCutF->nLeaves-1 );
|
||||
|
||||
// temporarily shrink the factor cut's variables by removing Node
|
||||
for ( i = NodeIndex; i < (int)pCutF->nLeaves - 1; i++ )
|
||||
pCutF->pLeaves[i] = pCutF->pLeaves[i+1];
|
||||
pCutF->nLeaves--;
|
||||
|
||||
// spread out the cofactors' truth tables to the same var order as the resulting cut
|
||||
uPhase = Cut_TruthPhase(pCutRes, pCutF);
|
||||
assert( Extra_WordCountOnes(uPhase) == (int)pCutF->nLeaves );
|
||||
Extra_TruthStretch( uTemp, uCof0, pCutF->nLeaves, pCutF->nVarsMax, uPhase );
|
||||
Extra_TruthCopy( uCof0, uTemp, pCutF->nVarsMax );
|
||||
Extra_TruthStretch( uTemp, uCof1, pCutF->nLeaves, pCutF->nVarsMax, uPhase );
|
||||
Extra_TruthCopy( uCof1, uTemp, pCutF->nVarsMax );
|
||||
|
||||
// spread out the tree cut's truth table to the same var order as the resulting cut
|
||||
uPhase = Cut_TruthPhase(pCutRes, pCutT);
|
||||
assert( Extra_WordCountOnes(uPhase) == (int)pCutT->nLeaves );
|
||||
Extra_TruthStretch( uTemp, Cut_CutReadTruth(pCutT), pCutT->nLeaves, pCutT->nVarsMax, uPhase );
|
||||
|
||||
// create the resulting truth table
|
||||
pTemp = Cut_CutReadTruth(pCutRes);
|
||||
for ( i = Extra_TruthWordNum(pCutRes->nLeaves)-1; i >= 0; i-- )
|
||||
pTemp[i] = (uCof0[i] & ~uTemp[i]) | (uCof1[i] & uTemp[i]);
|
||||
|
||||
// undo the removal of the node from the cut
|
||||
for ( i = (int)pCutF->nLeaves - 1; i >= NodeIndex; --i )
|
||||
pCutF->pLeaves[i+1] = pCutF->pLeaves[i];
|
||||
pCutF->pLeaves[NodeIndex] = Node;
|
||||
pCutF->nLeaves++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -203,6 +203,11 @@ void Cut_CellLoad()
|
|||
*/
|
||||
// add to the table
|
||||
p->nTotal++;
|
||||
|
||||
// Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); printf( "\n" );
|
||||
// if ( p->nTotal == 500 )
|
||||
// break;
|
||||
|
||||
if ( !Cut_CellTableLookup( p, pCell ) ) // new cell
|
||||
p->nGood++;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue