summaryrefslogtreecommitdiffstats
path: root/src/base
diff options
context:
space:
mode:
Diffstat (limited to 'src/base')
-rw-r--r--src/base/abc/abc.h5
-rw-r--r--src/base/abc/abcFanio.c24
-rw-r--r--src/base/abc/abcShow.c77
-rw-r--r--src/base/abci/abc.c561
-rw-r--r--src/base/abci/abcAuto.c2
-rw-r--r--src/base/abci/abcCas.c2
-rw-r--r--src/base/abci/abcCascade.c2
-rw-r--r--src/base/abci/abcCollapse.c18
-rw-r--r--src/base/abci/abcDsd.c2
-rw-r--r--src/base/abci/abcExact.c4
-rw-r--r--src/base/abci/abcGen.c49
-rw-r--r--src/base/abci/abcIvy.c2
-rw-r--r--src/base/abci/abcLutmin.c2
-rw-r--r--src/base/abci/abcNpn.c6
-rw-r--r--src/base/abci/abcNtbdd.c5
-rw-r--r--src/base/abci/abcProve.c2
-rw-r--r--src/base/abci/abcReach.c2
-rw-r--r--src/base/abci/abcSymm.c2
-rw-r--r--src/base/abci/abcUnate.c2
-rw-r--r--src/base/abci/abcUnreach.c2
-rw-r--r--src/base/acb/acbFunc.c2
-rw-r--r--src/base/cmd/cmdStarter.c3
-rw-r--r--src/base/io/io.c39
-rw-r--r--src/base/io/ioWritePla.c133
-rw-r--r--src/base/main/abcapis.h3
-rw-r--r--src/base/wlc/wlc.h9
-rw-r--r--src/base/wlc/wlcBlast.c617
-rw-r--r--src/base/wlc/wlcCom.c151
-rw-r--r--src/base/wlc/wlcMem.c129
-rw-r--r--src/base/wlc/wlcNdr.c8
-rw-r--r--src/base/wlc/wlcNtk.c35
-rw-r--r--src/base/wlc/wlcReadVer.c22
-rw-r--r--src/base/wlc/wlcWriteVer.c73
-rw-r--r--src/base/wln/module.make6
-rw-r--r--src/base/wln/wln.c51
-rw-r--r--src/base/wln/wln.h259
-rw-r--r--src/base/wln/wlnNdr.c332
-rw-r--r--src/base/wln/wlnNtk.c321
-rw-r--r--src/base/wln/wlnObj.c151
-rw-r--r--src/base/wln/wlnRetime.c487
-rw-r--r--src/base/wln/wlnWriteVer.c494
41 files changed, 3956 insertions, 140 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index 8ac5040d..dd189c6d 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -600,7 +600,7 @@ extern ABC_DLL int Abc_NtkCheckUniqueCiNames( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkCheckUniqueCoNames( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkCheckUniqueCioNames( Abc_Ntk_t * pNtk );
/*=== abcCollapse.c ==========================================================*/
-extern ABC_DLL Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose );
+extern ABC_DLL Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fVerbose );
extern ABC_DLL Abc_Ntk_t * Abc_NtkCollapseSat( Abc_Ntk_t * pNtk, int nCubeLim, int nBTLimit, int nCostMax, int fCanon, int fReverse, int fCnfShared, int fVerbose );
extern ABC_DLL Gia_Man_t * Abc_NtkClpGia( Abc_Ntk_t * pNtk );
/*=== abcCut.c ==========================================================*/
@@ -657,6 +657,7 @@ extern ABC_DLL void Abc_ObjPatchFanoutFanin( Abc_Obj_t * pObj, int
extern ABC_DLL Abc_Obj_t * Abc_ObjInsertBetween( Abc_Obj_t * pNodeIn, Abc_Obj_t * pNodeOut, Abc_ObjType_t Type );
extern ABC_DLL void Abc_ObjTransferFanout( Abc_Obj_t * pObjOld, Abc_Obj_t * pObjNew );
extern ABC_DLL void Abc_ObjReplace( Abc_Obj_t * pObjOld, Abc_Obj_t * pObjNew );
+extern ABC_DLL void Abc_ObjReplaceByConstant( Abc_Obj_t * pNode, int fConst1 );
extern ABC_DLL int Abc_ObjFanoutFaninNum( Abc_Obj_t * pFanout, Abc_Obj_t * pFanin );
/*=== abcFanOrder.c ==========================================================*/
extern ABC_DLL int Abc_NtkMakeLegit( Abc_Ntk_t * pNtk );
@@ -761,7 +762,7 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkToNetlistBench( Abc_Ntk_t * pNtk );
/*=== abcNtbdd.c ==========================================================*/
extern ABC_DLL Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd, void * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi );
extern ABC_DLL Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk );
-extern ABC_DLL void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fVerbose );
+extern ABC_DLL void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose );
extern ABC_DLL void * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan );
extern ABC_DLL int Abc_NtkSizeOfGlobalBdds( Abc_Ntk_t * pNtk );
/*=== abcNtk.c ==========================================================*/
diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c
index caa57a4e..519debb1 100644
--- a/src/base/abc/abcFanio.c
+++ b/src/base/abc/abcFanio.c
@@ -337,6 +337,30 @@ void Abc_ObjReplace( Abc_Obj_t * pNodeOld, Abc_Obj_t * pNodeNew )
/**Function*************************************************************
+ Synopsis [Replaces a node by a constant.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ObjReplaceByConstant( Abc_Obj_t * pNode, int fConst1 )
+{
+ Abc_Obj_t * pNodeNew;
+ assert( Abc_NtkIsLogic(pNode->pNtk) );
+ assert( !Abc_ObjIsCo(pNode) );
+ pNodeNew = fConst1 ? Abc_NtkCreateNodeConst1(pNode->pNtk) : Abc_NtkCreateNodeConst0(pNode->pNtk);
+ // transfer the fanouts to the old node
+ Abc_ObjTransferFanout( pNode, pNodeNew );
+ // remove the old node
+ if ( Abc_ObjIsNode(pNode) )
+ Abc_NtkDeleteObj_rec( pNode, 1 );
+}
+
+/**Function*************************************************************
+
Synopsis [Returns the index of the fanin in the fanin list of the fanout.]
Description []
diff --git a/src/base/abc/abcShow.c b/src/base/abc/abcShow.c
index 13dd9346..f91397df 100644
--- a/src/base/abc/abcShow.c
+++ b/src/base/abc/abcShow.c
@@ -85,12 +85,13 @@ void Abc_NodeShowBddOne( DdManager * dd, DdNode * bFunc )
SeeAlso []
***********************************************************************/
-void Abc_NodeShowBdd( Abc_Obj_t * pNode )
+void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl )
{
FILE * pFile;
Vec_Ptr_t * vNamesIn;
char FileNameDot[200];
char * pNameOut;
+ DdManager * dd = (DdManager *)pNode->pNtk->pManFunc;
assert( Abc_NtkIsBddLogic(pNode->pNtk) );
// create the file name
@@ -105,7 +106,14 @@ void Abc_NodeShowBdd( Abc_Obj_t * pNode )
// set the node names
vNamesIn = Abc_NodeGetFaninNames( pNode );
pNameOut = Abc_ObjName(pNode);
- Cudd_DumpDot( (DdManager *)pNode->pNtk->pManFunc, 1, (DdNode **)&pNode->pData, (char **)vNamesIn->pArray, &pNameOut, pFile );
+ if ( fCompl )
+ Cudd_DumpDot( dd, 1, (DdNode **)&pNode->pData, (char **)vNamesIn->pArray, &pNameOut, pFile );
+ else
+ {
+ DdNode * bAdd = Cudd_BddToAdd( dd, (DdNode *)pNode->pData ); Cudd_Ref( bAdd );
+ Cudd_DumpDot( dd, 1, (DdNode **)&bAdd, (char **)vNamesIn->pArray, &pNameOut, pFile );
+ Cudd_RecursiveDeref( dd, bAdd );
+ }
Abc_NodeFreeNames( vNamesIn );
Abc_NtkCleanCopy( pNode->pNtk );
fclose( pFile );
@@ -113,9 +121,72 @@ void Abc_NodeShowBdd( Abc_Obj_t * pNode )
// visualize the file
Abc_ShowFile( FileNameDot );
}
+void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl )
+{
+ char FileNameDot[200];
+ char ** ppNamesIn, ** ppNamesOut;
+ DdManager * dd; DdNode * bFunc;
+ Vec_Ptr_t * vFuncsGlob;
+ Abc_Obj_t * pObj; int i;
+ FILE * pFile;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, 0 );
+ if ( dd == NULL )
+ {
+ printf( "Construction of global BDDs has failed.\n" );
+ return;
+ }
+ //printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
+
+ // complement the global functions
+ vFuncsGlob = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Vec_PtrPush( vFuncsGlob, Abc_ObjGlobalBdd(pObj) );
+
+ // create the file name
+ Abc_ShowGetFileName( pNtk->pName, FileNameDot );
+ // check that the file can be opened
+ if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", FileNameDot );
+ return;
+ }
+
+ // set the node names
+ ppNamesIn = Abc_NtkCollectCioNames( pNtk, 0 );
+ ppNamesOut = Abc_NtkCollectCioNames( pNtk, 1 );
+ if ( fCompl )
+ Cudd_DumpDot( dd, Abc_NtkCoNum(pNtk), (DdNode **)Vec_PtrArray(vFuncsGlob), ppNamesIn, ppNamesOut, pFile );
+ else
+ {
+ DdNode ** pbAdds = ABC_ALLOC( DdNode *, Vec_PtrSize(vFuncsGlob) );
+ Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i )
+ { pbAdds[i] = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( pbAdds[i] ); }
+ Cudd_DumpDot( dd, Abc_NtkCoNum(pNtk), pbAdds, ppNamesIn, ppNamesOut, pFile );
+ Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i )
+ Cudd_RecursiveDeref( dd, pbAdds[i] );
+ ABC_FREE( pbAdds );
+ }
+ ABC_FREE( ppNamesIn );
+ ABC_FREE( ppNamesOut );
+ fclose( pFile );
+
+ // cleanup
+ Abc_NtkFreeGlobalBdds( pNtk, 0 );
+ Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i )
+ Cudd_RecursiveDeref( dd, bFunc );
+ Vec_PtrFree( vFuncsGlob );
+ Extra_StopManager( dd );
+ Abc_NtkCleanCopy( pNtk );
+
+ // visualize the file
+ Abc_ShowFile( FileNameDot );
+}
#else
-void Abc_NodeShowBdd( Abc_Obj_t * pNode ) {}
+void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl ) {}
+void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl ) {}
#endif
/**Function*************************************************************
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 0e527058..181ca54a 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -86,6 +86,7 @@ static int Abc_CommandPrintMffc ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintLevel ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintSupport ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrintMint ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintSymms ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintUnate ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintAuto ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -154,6 +155,7 @@ static int Abc_CommandTwoExact ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandLutExact ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAllExact ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTestExact ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandMajGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandComb ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -184,6 +186,7 @@ static int Abc_CommandExtSeqDcs ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandReach ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandNode ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandCof ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTopmost ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTopAnd ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTrim ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -314,6 +317,8 @@ static int Abc_CommandInsWin ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandPermute ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandUnpermute ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCubeEnum ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPathEnum ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandFunEnum ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandDCec ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -775,6 +780,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Printing", "print_factor", Abc_CommandPrintFactor, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_level", Abc_CommandPrintLevel, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_supp", Abc_CommandPrintSupport, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_mint", Abc_CommandPrintMint, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_symm", Abc_CommandPrintSymms, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_unate", Abc_CommandPrintUnate, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_auto", Abc_CommandPrintAuto, 0 );
@@ -844,6 +850,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Exact synthesis", "lutexact", Abc_CommandLutExact, 0 );
Cmd_CommandAdd( pAbc, "Exact synthesis", "allexact", Abc_CommandAllExact, 0 );
Cmd_CommandAdd( pAbc, "Exact synthesis", "testexact", Abc_CommandTestExact, 0 );
+ Cmd_CommandAdd( pAbc, "Exact synthesis", "majgen", Abc_CommandMajGen, 0 );
Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 );
Cmd_CommandAdd( pAbc, "Various", "comb", Abc_CommandComb, 1 );
@@ -874,8 +881,9 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "reach", Abc_CommandReach, 0 );
Cmd_CommandAdd( pAbc, "Various", "cone", Abc_CommandCone, 1 );
Cmd_CommandAdd( pAbc, "Various", "node", Abc_CommandNode, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "cof", Abc_CommandCof, 1 );
Cmd_CommandAdd( pAbc, "Various", "topmost", Abc_CommandTopmost, 1 );
- Cmd_CommandAdd( pAbc, "Various", "topand", Abc_CommandTopAnd, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "topand", Abc_CommandTopAnd, 1 );
Cmd_CommandAdd( pAbc, "Various", "trim", Abc_CommandTrim, 1 );
Cmd_CommandAdd( pAbc, "Various", "short_names", Abc_CommandShortNames, 0 );
Cmd_CommandAdd( pAbc, "Various", "move_names", Abc_CommandMoveNames, 0 );
@@ -999,6 +1007,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Sequential", "permute", Abc_CommandPermute, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "unpermute", Abc_CommandUnpermute, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "cubeenum", Abc_CommandCubeEnum, 0 );
+ Cmd_CommandAdd( pAbc, "Sequential", "pathenum", Abc_CommandPathEnum, 0 );
+ Cmd_CommandAdd( pAbc, "Sequential", "funenum", Abc_CommandFunEnum, 0 );
Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 );
Cmd_CommandAdd( pAbc, "Verification", "dcec", Abc_CommandDCec, 0 );
@@ -2013,6 +2023,68 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandPrintMint( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
+ Abc_Obj_t * pObj;
+ int c;
+ int fVerbose;
+
+ // set defaults
+ fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "svwh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( -1, "Empty network.\n" );
+ return 1;
+ }
+ if ( Abc_NtkIsStrash(pNtk) )
+ {
+ Abc_Print( -1, "This command works only for logic networks (run \"clp\").\n" );
+ return 1;
+ }
+ if ( !Abc_NtkHasBdd(pNtk) )
+ {
+ Abc_Print( -1, "This command works only for logic networks with local functions represented by BDDs.\n" );
+ return 1;
+ }
+ Abc_NtkForEachNode( pNtk, pObj, c )
+ printf( "ObjId %3d : SuppSize = %5d MintCount = %32.0f\n", c, Abc_ObjFaninNum(pObj),
+ Cudd_CountMinterm((DdManager *)pNtk->pManFunc, (DdNode *)pObj->pData, Abc_ObjFaninNum(pObj)) );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: print_mint [-svwh]\n" );
+ Abc_Print( -2, "\t prints the number of on-set minterms in the PO functions\n" );
+ Abc_Print( -2, "\t-v : enable verbose output [default = %s].\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
@@ -2991,15 +3063,22 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
Abc_Obj_t * pNode;
- int c;
- extern void Abc_NodeShowBdd( Abc_Obj_t * pNode );
+ int c, fCompl = 0, fGlobal = 0;
+ extern void Abc_NodeShowBdd( Abc_Obj_t * pNode, int fCompl );
+ extern void Abc_NtkShowBdd( Abc_Ntk_t * pNtk, int fCompl );
// set defaults
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "cgh" ) ) != EOF )
{
switch ( c )
{
+ case 'c':
+ fCompl ^= 1;
+ break;
+ case 'g':
+ fGlobal ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -3013,12 +3092,20 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
+ if ( fGlobal )
+ {
+ Abc_Ntk_t * pTemp = Abc_NtkIsStrash(pNtk) ? pNtk : Abc_NtkStrash(pNtk, 0, 0, 0);
+ Abc_NtkShowBdd( pTemp, fCompl );
+ if ( pTemp != pNtk )
+ Abc_NtkDelete( pTemp );
+ return 0;
+ }
+
if ( !Abc_NtkIsBddLogic(pNtk) )
{
Abc_Print( -1, "Visualizing BDDs can only be done for logic BDD networks (run \"bdd\").\n" );
return 1;
}
-
if ( argc > globalUtilOptind + 1 )
{
Abc_Print( -1, "Wrong number of auguments.\n" );
@@ -3042,17 +3129,20 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
}
- Abc_NodeShowBdd( pNode );
+ Abc_NodeShowBdd( pNode, fCompl );
return 0;
usage:
- Abc_Print( -2, "usage: show_bdd [-h] <node>\n" );
- Abc_Print( -2, " visualizes the BDD of a node using DOT and GSVIEW\n" );
+ Abc_Print( -2, "usage: show_bdd [-cgh] <node>\n" );
+ Abc_Print( -2, " uses DOT and GSVIEW to visualize the global BDDs of primary outputs\n" );
+ Abc_Print( -2, " in terms of primary inputs or the local BDD of a node in terms of its fanins\n" );
#ifdef WIN32
Abc_Print( -2, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" );
Abc_Print( -2, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" );
#endif
- Abc_Print( -2, "\t<node>: the node to consider [default = the driver of the first PO]\n");
+ Abc_Print( -2, "\t<node>: (optional) the node to consider [default = the driver of the first PO]\n");
+ Abc_Print( -2, "\t-c : toggle visualizing BDD with complemented edges [default = %s].\n", fCompl? "yes": "no" );
+ Abc_Print( -2, "\t-g : toggle visualizing the global BDDs of primary outputs [default = %s].\n", fGlobal? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
@@ -3173,16 +3263,18 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
int fBddSizeMax;
int fDualRail;
int fReorder;
+ int fReverse;
int c;
pNtk = Abc_FrameReadNtk(pAbc);
// set defaults
fVerbose = 0;
fReorder = 1;
+ fReverse = 0;
fDualRail = 0;
fBddSizeMax = ABC_INFINITY;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Brdvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Brodvh" ) ) != EOF )
{
switch ( c )
{
@@ -3197,15 +3289,18 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( fBddSizeMax < 0 )
goto usage;
break;
+ case 'r':
+ fReorder ^= 1;
+ break;
+ case 'o':
+ fReverse ^= 1;
+ break;
case 'd':
fDualRail ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
- case 'r':
- fReorder ^= 1;
- break;
case 'h':
goto usage;
default:
@@ -3227,11 +3322,11 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
// get the new network
if ( Abc_NtkIsStrash(pNtk) )
- pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fVerbose );
+ pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fReverse, fVerbose );
else
{
pNtk = Abc_NtkStrash( pNtk, 0, 0, 0 );
- pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fVerbose );
+ pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, fReverse, fVerbose );
Abc_NtkDelete( pNtk );
}
if ( pNtkRes == NULL )
@@ -3244,10 +3339,11 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: collapse [-B <num>] [-rdvh]\n" );
+ Abc_Print( -2, "usage: collapse [-B <num>] [-rodvh]\n" );
Abc_Print( -2, "\t collapses the network by constructing global BDDs\n" );
Abc_Print( -2, "\t-B <num>: limit on live BDD nodes during collapsing [default = %d]\n", fBddSizeMax );
Abc_Print( -2, "\t-r : toggles dynamic variable reordering [default = %s]\n", fReorder? "yes": "no" );
+ Abc_Print( -2, "\t-o : toggles reverse variable ordering [default = %s]\n", fReverse? "yes": "no" );
Abc_Print( -2, "\t-d : toggles dual-rail collapsing mode [default = %s]\n", fDualRail? "yes": "no" );
Abc_Print( -2, "\t-v : print verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
@@ -8217,7 +8313,7 @@ int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv )
Bmc_EsPar_t Pars, * pPars = &Pars;
Bmc_EsParSetDefault( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "INaogvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "INTaogvh" ) ) != EOF )
{
switch ( c )
{
@@ -8243,6 +8339,17 @@ int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nNodes < 0 )
goto usage;
break;
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->RuntimeLim = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->RuntimeLim < 0 )
+ goto usage;
+ break;
case 'a':
pPars->fOnlyAnd ^= 1;
break;
@@ -8290,10 +8397,11 @@ int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: twoexact [-IN <num>] [-aogvh] <hex>\n" );
+ Abc_Print( -2, "usage: twoexact [-INT <num>] [-aogvh] <hex>\n" );
Abc_Print( -2, "\t exact synthesis of multi-input function using two-input gates\n" );
Abc_Print( -2, "\t-I <num> : the number of input variables [default = %d]\n", pPars->nVars );
- Abc_Print( -2, "\t-N <num> : the number of MAJ3 nodes [default = %d]\n", pPars->nNodes );
+ Abc_Print( -2, "\t-N <num> : the number of two-input nodes [default = %d]\n", pPars->nNodes );
+ Abc_Print( -2, "\t-T <num> : the runtime limit in seconds [default = %d]\n", pPars->RuntimeLim );
Abc_Print( -2, "\t-a : toggle using only AND-gates (without XOR-gates) [default = %s]\n", pPars->fOnlyAnd ? "yes" : "no" );
Abc_Print( -2, "\t-o : toggle using additional optimizations [default = %s]\n", pPars->fFewerVars ? "yes" : "no" );
Abc_Print( -2, "\t-g : toggle using Glucose 3.0 by Gilles Audemard and Laurent Simon [default = %s]\n", pPars->fGlucose ? "yes" : "no" );
@@ -8329,7 +8437,7 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv )
Bmc_EsPar_t Pars, * pPars = &Pars;
Bmc_EsParSetDefault( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "INKiaogvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "INKTiaogvh" ) ) != EOF )
{
switch ( c )
{
@@ -8366,6 +8474,17 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nLutSize < 0 )
goto usage;
break;
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->RuntimeLim = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->RuntimeLim < 0 )
+ goto usage;
+ break;
case 'i':
pPars->fUseIncr ^= 1;
break;
@@ -8421,11 +8540,12 @@ int Abc_CommandLutExact( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: lutexact [-INK <num>] [-iaogvh] <hex>\n" );
+ Abc_Print( -2, "usage: lutexact [-INKT <num>] [-iaogvh] <hex>\n" );
Abc_Print( -2, "\t exact synthesis of I-input function using N K-input gates\n" );
Abc_Print( -2, "\t-I <num> : the number of input variables [default = %d]\n", pPars->nVars );
Abc_Print( -2, "\t-N <num> : the number of K-input nodes [default = %d]\n", pPars->nNodes );
Abc_Print( -2, "\t-K <num> : the number of node fanins [default = %d]\n", pPars->nLutSize );
+ Abc_Print( -2, "\t-T <num> : the runtime limit in seconds [default = %d]\n", pPars->RuntimeLim );
Abc_Print( -2, "\t-i : toggle using incremental solving [default = %s]\n", pPars->fUseIncr ? "yes" : "no" );
Abc_Print( -2, "\t-a : toggle using only AND-gates when K = 2 [default = %s]\n", pPars->fOnlyAnd ? "yes" : "no" );
Abc_Print( -2, "\t-o : toggle using additional optimizations [default = %s]\n", pPars->fFewerVars ? "yes" : "no" );
@@ -8681,6 +8801,62 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandMajGen( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern int Gem_Enumerate( int nVars, int fDump, int fVerbose );
+ int c, nVars = 8, fDump = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Ndvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nVars = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nVars < 0 )
+ goto usage;
+ break;
+ case 'd':
+ fDump ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ Gem_Enumerate( nVars, fDump, fVerbose );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: majgen [-N <num>] [-dvh]>\n" );
+ Abc_Print( -2, "\t generates networks for majority gates\n" );
+ Abc_Print( -2, "\t-N <num> : the maximum number of variables [default = %d]\n", nVars );
+ Abc_Print( -2, "\t-d : toggle dumping functions into a file [default = %s]\n", fVerbose ? "yes" : "no" );
+ Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose ? "yes" : "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandLogic( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk, * pNtkRes;
@@ -11067,6 +11243,81 @@ usage:
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandCof( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pNode;
+ int c, Const;
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ // set defaults
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ Abc_Print( -1, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsLogic(pNtk) )
+ {
+ Abc_Print( -1, "Currently can only be applied to a logic network.\n" );
+ return 1;
+ }
+
+ if ( argc != globalUtilOptind + 2 )
+ {
+ Abc_Print( -1, "Wrong number of auguments.\n" );
+ goto usage;
+ }
+ pNode = Abc_NtkFindCi( pNtk, argv[globalUtilOptind] );
+ if ( pNode == NULL )
+ pNode = Abc_NtkFindNode( pNtk, argv[globalUtilOptind] );
+ if ( pNode == NULL )
+ {
+ Abc_Print( -1, "Cannot find node \"%s\".\n", argv[globalUtilOptind] );
+ return 1;
+ }
+ Const = atoi( argv[globalUtilOptind+1] );
+ if ( Const != 0 && Const != 1 )
+ {
+ Abc_Print( -1, "Constant should be 0 or 1.\n", argv[globalUtilOptind+1] );
+ return 1;
+ }
+ Abc_ObjReplaceByConstant( pNode, Const );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: cof [-h] <node> <const>\n" );
+ Abc_Print( -2, "\t replaces one node in a logic network by constant 0 or 1\n" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t<node> : the node to replace\n");
+ Abc_Print( -2, "\t<const> : the constant to replace the node with\n");
+ Abc_Print( -2, "\tname : the node name\n");
+ return 1;
+}
+
/**Function*************************************************************
@@ -12057,9 +12308,11 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
// Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
int c;
int nVars; // the number of variables
+ int nArgs; // the number of arguments
int nLutSize = -1; // the size of LUTs
int nLuts = -1; // the number of LUTs
int fAdder;
+ int fAdderTree;
int fSorter;
int fMesh;
int fMulti;
@@ -12076,10 +12329,13 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
extern void Abc_GenFpga( char * pFileName, int nLutSize, int nLuts, int nVars );
extern void Abc_GenOneHot( char * pFileName, int nVars );
extern void Abc_GenRandom( char * pFileName, int nPis );
+ extern void Abc_GenAdderTree( char * pFileName, int nArgs, int nBits );
// set defaults
nVars = 8;
+ nArgs = 8;
fAdder = 0;
+ fAdderTree = 0;
fSorter = 0;
fMesh = 0;
fMulti = 0;
@@ -12088,7 +12344,7 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
fRandom = 0;
fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "NKLasemftrvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "NAKLabsemftrvh" ) ) != EOF )
{
switch ( c )
{
@@ -12103,6 +12359,17 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nVars < 0 )
goto usage;
break;
+ case 'A':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-A\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nArgs = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nArgs < 0 )
+ goto usage;
+ break;
case 'K':
if ( globalUtilOptind >= argc )
{
@@ -12128,6 +12395,9 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'a':
fAdder ^= 1;
break;
+ case 'b':
+ fAdderTree ^= 1;
+ break;
case 's':
fSorter ^= 1;
break;
@@ -12183,6 +12453,14 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_GenOneHot( FileName, nVars );
else if ( fRandom )
Abc_GenRandom( FileName, nVars );
+ else if ( fAdderTree )
+ {
+ printf( "Generating adder tree with %d arguments and %d bits.\n", nArgs, nVars );
+ Abc_GenAdderTree( FileName, nArgs, nVars );
+ sprintf( Command, "%%read %s; %%blast; &put", FileName );
+ Cmd_CommandExecute( pAbc, Command );
+ return 0;
+ }
else
{
Abc_Print( -1, "Type of circuit is not specified.\n" );
@@ -12194,12 +12472,14 @@ int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: gen [-NKL num] [-asemftrvh] <file>\n" );
+ Abc_Print( -2, "usage: gen [-NAKL num] [-asemftrvh] <file>\n" );
Abc_Print( -2, "\t generates simple circuits\n" );
Abc_Print( -2, "\t-N num : the number of variables [default = %d]\n", nVars );
+ Abc_Print( -2, "\t-A num : the number of agruments (for adder tree) [default = %d]\n", nArgs );
Abc_Print( -2, "\t-K num : the LUT size (to be used with switch -f) [default = %d]\n", nLutSize );
Abc_Print( -2, "\t-L num : the LUT count (to be used with switch -f) [default = %d]\n", nLuts );
Abc_Print( -2, "\t-a : generate ripple-carry adder [default = %s]\n", fAdder? "yes": "no" );
+ Abc_Print( -2, "\t-b : generate an adder tree [default = %s]\n", fAdderTree? "yes": "no" );
Abc_Print( -2, "\t-s : generate a sorter [default = %s]\n", fSorter? "yes": "no" );
Abc_Print( -2, "\t-e : generate a mesh [default = %s]\n", fMesh? "yes": "no" );
Abc_Print( -2, "\t-m : generate a multiplier [default = %s]\n", fMulti? "yes": "no" );
@@ -12871,11 +13151,12 @@ int Abc_CommandTestColor( Abc_Frame_t * pAbc, int argc, char ** argv )
***********************************************************************/
int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
{
+ extern void Dau_NetworkEnumTest();
//Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
int nCutMax = 1;
int nLeafMax = 4;
int nDivMax = 2;
- int nDecMax = 70;
+ int nDecMax = 3;
int nNumOnes = 4;
int fNewAlgo = 0;
int fNewOrder = 0;
@@ -13029,7 +13310,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
*/
{
// extern void Abc_EnumerateFuncs( int nDecMax, int nDivMax, int fVerbose );
-// Abc_EnumerateFuncs( nDecMax, nDivMax, fVerbose );
+// Abc_EnumerateFuncs( 4, 7, 0 );
}
/*
if ( fNewAlgo )
@@ -13080,7 +13361,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
// Cba_PrsReadBlifTest();
}
// Abc_NtkComputePaths( Abc_FrameReadNtk(pAbc) );
-// Psl_FileTest();
+ //Dau_NetworkEnumTest();
+ //Ext_TruthDiagnoseTest();
return 0;
usage:
Abc_Print( -2, "usage: test [-CKDNM] [-aovwh] <file_name>\n" );
@@ -22756,6 +23038,183 @@ usage:
return 1;
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandPathEnum( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Abc_EnumerateFrontierTest( int nSize );
+ int c, nSize = 4, fZddAlgo = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Nzvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nSize = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nSize < 0 )
+ goto usage;
+ break;
+ case 'z':
+ fZddAlgo ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ Abc_Print( -2, "Unknown switch.\n");
+ goto usage;
+ }
+ }
+ Abc_EnumerateFrontierTest( nSize );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: pathenum [-N num] [-vh]\n" );
+ Abc_Print( -2, "\t enumerates self-avoiding paths on the NxN grid\n" );
+ Abc_Print( -2, "\t-N num : the size of the grid to consider [default = %d]\n", nSize );
+// Abc_Print( -2, "\t-z : toggle using ZDD-based algorithm [default = %s]\n", fZddAlgo? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandFunEnum( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Dtt_EnumerateLf( int nVars, int nNodeMax, int fDelay, int fMulti, int fVerbose );
+ extern void Dau_FunctionEnum( int nInputs, int nVars, int nNodeMax, int fUseTwo, int fReduce, int fVerbose );
+ int c, nInputs = 4, nVars = 4, nNodeMax = 32, fUseTwo = 0, fReduce = 0, fSimple = 0, fDelay = 0, fMulti = 0, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "SIMtrldmvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'S':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nInputs = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nInputs < 0 )
+ goto usage;
+ break;
+ case 'I':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nVars = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nVars < 0 )
+ goto usage;
+ break;
+ case 'M':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nNodeMax = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nNodeMax < 0 )
+ goto usage;
+ break;
+ case 't':
+ fUseTwo ^= 1;
+ break;
+ case 'r':
+ fReduce ^= 1;
+ break;
+ case 'l':
+ fSimple ^= 1;
+ break;
+ case 'd':
+ fDelay ^= 1;
+ break;
+ case 'm':
+ fMulti ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ Abc_Print( -2, "Unknown switch.\n");
+ goto usage;
+ }
+ }
+ if ( fSimple || fDelay )
+ {
+ if ( nVars < 3 || nVars > 5 )
+ {
+ Abc_Print( -1, "The number of inputs should be 3 <= I <= 5.\n" );
+ goto usage;
+ }
+ Dtt_EnumerateLf( nVars, nNodeMax, fDelay, fMulti, fVerbose );
+ }
+ else
+ {
+ if ( nVars < 2 || nVars > 6 )
+ {
+ Abc_Print( -1, "The number of inputs should be 2 <= I <= 6.\n" );
+ goto usage;
+ }
+ if ( nInputs < nVars || nInputs > 6 )
+ {
+ Abc_Print( -1, "The intermediate support size should be I <= S <= 6.\n" );
+ goto usage;
+ }
+ Dau_FunctionEnum( nInputs, nVars, nNodeMax, fUseTwo, fReduce, fVerbose );
+ }
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: funenum [-SIM num] [-trldmvh]\n" );
+ Abc_Print( -2, "\t enumerates minimum 2-input-gate implementations\n" );
+ Abc_Print( -2, "\t-S num : the maximum intermediate support size [default = %d]\n", nInputs );
+ Abc_Print( -2, "\t-I num : the number of inputs of Boolean functions [default = %d]\n", nVars );
+ Abc_Print( -2, "\t-M num : the maximum number of 2-input gates [default = %d]\n", nNodeMax );
+ Abc_Print( -2, "\t-t : toggle adding combination of two gates [default = %s]\n", fUseTwo? "yes": "no" );
+ Abc_Print( -2, "\t-r : toggle reducing the last level [default = %s]\n", fReduce? "yes": "no" );
+ Abc_Print( -2, "\t-l : toggle generating L(f) rather than C(f) [default = %s]\n", fSimple? "yes": "no" );
+ Abc_Print( -2, "\t-d : toggle generating D(f) rather than C(f) [default = %s]\n", fDelay? "yes": "no" );
+ Abc_Print( -2, "\t-m : toggle generating multiplicity statistics [default = %s]\n", fMulti? "yes": "no" );
+ Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
/**Function*************************************************************
@@ -42647,11 +43106,11 @@ usage:
***********************************************************************/
int Abc_CommandAbc9Polyn( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern void Gia_PolynBuild2Test( Gia_Man_t * pGia, int nExtra, int fSigned, int fVerbose, int fVeryVerbose );
- Vec_Int_t * vOrder = NULL;
- int c, nExtra = -1, fOld = 0, fSimple = 1, fSigned = 0, fVerbose = 0, fVeryVerbose = 0;
+ extern void Gia_PolynBuild2Test( Gia_Man_t * pGia, char * pSign, int nExtra, int fSigned, int fVerbose, int fVeryVerbose );
+ Vec_Int_t * vOrder = NULL; char * pSign = NULL;
+ int c, nExtra = 0, fOld = 0, fSimple = 1, fSigned = 0, fVerbose = 0, fVeryVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "Noasvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "NSoasvwh" ) ) != EOF )
{
switch ( c )
{
@@ -42666,6 +43125,15 @@ int Abc_CommandAbc9Polyn( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nExtra < 0 )
goto usage;
break;
+ case 'S':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-S\" should be followed by a char string without spaces.\n" );
+ goto usage;
+ }
+ pSign = argv[globalUtilOptind];
+ globalUtilOptind++;
+ break;
case 'o':
fOld ^= 1;
break;
@@ -42692,6 +43160,11 @@ int Abc_CommandAbc9Polyn( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9Esop(): There is no AIG.\n" );
return 0;
}
+ if ( argc >= globalUtilOptind + 1 )
+ {
+ printf( "Trailing symbols on the command line (\"%s\").\n", argv[globalUtilOptind] );
+ return 0;
+ }
if ( fOld )
{
vOrder = fSimple ? NULL : Gia_PolynReorder( pAbc->pGia, fVerbose, fVeryVerbose );
@@ -42699,11 +43172,11 @@ int Abc_CommandAbc9Polyn( Abc_Frame_t * pAbc, int argc, char ** argv )
Vec_IntFreeP( &vOrder );
}
else
- Gia_PolynBuild2Test( pAbc->pGia, nExtra, fSigned, fVerbose, fVeryVerbose );
+ Gia_PolynBuild2Test( pAbc->pGia, pSign, nExtra, fSigned, fVerbose, fVeryVerbose );
return 0;
usage:
- Abc_Print( -2, "usage: &polyn [-N num] [-oasvwh]\n" );
+ Abc_Print( -2, "usage: &polyn [-N num] [-oasvwh] [-S str]\n" );
Abc_Print( -2, "\t derives algebraic polynomial from AIG\n" );
Abc_Print( -2, "\t-N num : the number of additional primary outputs (-1 = unused) [default = %d]\n", nExtra );
Abc_Print( -2, "\t-o : toggles old computation [default = %s]\n", fOld? "yes": "no" );
@@ -42712,6 +43185,18 @@ usage:
Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggles printing very verbose information [default = %s]\n", fVeryVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
+ Abc_Print( -2, "\t\n");
+ Abc_Print( -2, "\t-S str : (optional) the output signature as a character string\n" );
+ Abc_Print( -2, "\t The format used to represent the output signature is very restrictive.\n" );
+ Abc_Print( -2, "\t It should be a string without spaces containing monomials in terms of\n" );
+ Abc_Print( -2, "\t inputs (i<num>) and outputs (o<num>) where <num> is 0-based. Coefficients\n" );
+ Abc_Print( -2, "\t are degrees of two, represented by log2 of their value: for example, \n" );
+ Abc_Print( -2, "\t \"2\" is 2^2 = 4, \"-4\" is -2^4=-16, \"-0\" is -2^0=-1, etc\n" );
+ Abc_Print( -2, "\t Two types of signature are accepted:\n" );
+ Abc_Print( -2, "\t (1) a sequence of monomials without parentheses (for example, \"-2*o0+1*o1+0*o2\")\n" );
+ Abc_Print( -2, "\t (2) a product of two sequences followed by a sum with a sequence\n" );
+ Abc_Print( -2, "\t (for example, \"(4*o0+2*o1+1*o2)*(4*i3+2*i4+1*i5)+(4*o3+2*o4+1*o5)\")\n" );
+ Abc_Print( -2, "\t Here is the signature of a signed 2-bit multiplier: \"(0*o0+1*o1+2*o2-3*o3)\"\n" );
return 1;
}
@@ -43362,6 +43847,16 @@ int Abc_CommandAbc9Mfs( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current AIG has no mapping.\n" );
return 0;
}
+ if ( Gia_ManLutSizeMax(pAbc->pGia) > 6 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current mapping has nodes with more than 6 inputs. Cannot use \"mfs\".\n" );
+ return 0;
+ }
+ if ( pAbc->pGia->pAigExtra && Gia_ManPiNum(pAbc->pGia->pAigExtra) > 6 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Mfs(): The current white-boxes have more than 6 inputs. Cannot use \"mfs\".\n" );
+ return 0;
+ }
pTemp = Gia_ManPerformMfs( pAbc->pGia, pPars );
Abc_FrameUpdateGia( pAbc, pTemp );
return 0;
@@ -43379,7 +43874,7 @@ usage:
Abc_Print( -2, "\t-d : toggle performing redundancy removal [default = %s]\n", pPars->fRrOnly? "yes": "no" );
Abc_Print( -2, "\t-a : toggle minimizing area or area+edges [default = %s]\n", pPars->fArea? "area": "area+edges" );
Abc_Print( -2, "\t-e : toggle high-effort resubstitution [default = %s]\n", pPars->fMoreEffort? "yes": "no" );
- Abc_Print( -2, "\t-b : toggle preserving all while boxes [default = %s]\n", pPars->fAllBoxes? "yes": "no" );
+ Abc_Print( -2, "\t-b : toggle preserving all white boxes [default = %s]\n", pPars->fAllBoxes? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-w : toggle printing detailed stats for each node [default = %s]\n", pPars->fVeryVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
diff --git a/src/base/abci/abcAuto.c b/src/base/abci/abcAuto.c
index 18c92657..8f7eead0 100644
--- a/src/base/abci/abcAuto.c
+++ b/src/base/abci/abcAuto.c
@@ -62,7 +62,7 @@ void Abc_NtkAutoPrint( Abc_Ntk_t * pNtk, int Output, int fNaive, int fVerbose )
Abc_Obj_t * pObj;
// compute the global BDDs
- if ( Abc_NtkBuildGlobalBdds(pNtk, 10000000, 1, 1, fVerbose) == NULL )
+ if ( Abc_NtkBuildGlobalBdds(pNtk, 10000000, 1, 1, 0, fVerbose) == NULL )
return;
// get information about the network
diff --git a/src/base/abci/abcCas.c b/src/base/abci/abcCas.c
index 9abdd792..6615bff0 100644
--- a/src/base/abci/abcCas.c
+++ b/src/base/abci/abcCas.c
@@ -70,7 +70,7 @@ Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVer
assert( Abc_NtkIsStrash(pNtk) );
// compute the global BDDs
- if ( Abc_NtkBuildGlobalBdds(pNtk, fBddSizeMax, 1, fReorder, fVerbose) == NULL )
+ if ( Abc_NtkBuildGlobalBdds(pNtk, fBddSizeMax, 1, fReorder, 0, fVerbose) == NULL )
return NULL;
if ( fVerbose )
diff --git a/src/base/abci/abcCascade.c b/src/base/abci/abcCascade.c
index 70f2e891..50e66675 100644
--- a/src/base/abci/abcCascade.c
+++ b/src/base/abci/abcCascade.c
@@ -1010,7 +1010,7 @@ Abc_Ntk_t * Abc_NtkBddDec( Abc_Ntk_t * pNtk, int fVerbose )
int i;
assert( Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkCoNum(pNtk) <= BDD_FUNC_MAX );
- dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddSizeMax, fDropInternal, fReorder, fVerbose );
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddSizeMax, fDropInternal, fReorder, 0, fVerbose );
if ( dd == NULL )
{
Abc_Print( -1, "Construction of global BDDs has failed.\n" );
diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c
index 1542c25a..caeea3a1 100644
--- a/src/base/abci/abcCollapse.c
+++ b/src/base/abci/abcCollapse.c
@@ -118,7 +118,7 @@ int Abc_NtkMinimumBase2( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc )
+Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc, int fReverse )
{
Abc_Obj_t * pNodeNew, * pTemp;
int i;
@@ -126,12 +126,12 @@ Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode
pNodeNew = Abc_NtkCreateNode( pNtkNew );
// add the fanins in the order, in which they appear in the reordered manager
Abc_NtkForEachCi( pNtkNew, pTemp, i )
- Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtkNew, dd->invperm[i]) );
+ Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtkNew, fReverse ? Abc_NtkCiNum(pNtkNew)-1-dd->invperm[i] : dd->invperm[i]) );
// transfer the function
pNodeNew->pData = Extra_TransferLevelByLevel( dd, (DdManager *)pNtkNew->pManFunc, bFunc ); Cudd_Ref( (DdNode *)pNodeNew->pData );
return pNodeNew;
}
-Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk )
+Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk, int fReverse )
{
ProgressBar * pProgress;
Abc_Ntk_t * pNtkNew;
@@ -147,7 +147,7 @@ Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsStrash(pNtk->pExdc) );
assert( Abc_NtkCoNum(pNtk->pExdc) == 1 );
// compute the global BDDs
- if ( Abc_NtkBuildGlobalBdds(pNtk->pExdc, 10000000, 1, 1, 0) == NULL )
+ if ( Abc_NtkBuildGlobalBdds(pNtk->pExdc, 10000000, 1, 1, 0, 0) == NULL )
return NULL;
// transfer tot the same manager
ddExdc = (DdManager *)Abc_NtkGlobalBddMan( pNtk->pExdc );
@@ -188,21 +188,21 @@ Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk )
Abc_ObjAddFanin( pNode->pCopy, pDriver->pCopy );
continue;
}
- pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, (DdNode *)Abc_ObjGlobalBdd(pNode) );
+ pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, (DdNode *)Abc_ObjGlobalBdd(pNode), fReverse );
Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
}
Extra_ProgressBarStop( pProgress );
return pNtkNew;
}
-Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose )
+Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fVerbose )
{
Abc_Ntk_t * pNtkNew;
abctime clk = Abc_Clock();
assert( Abc_NtkIsStrash(pNtk) );
// compute the global BDDs
- if ( Abc_NtkBuildGlobalBdds(pNtk, fBddSizeMax, 1, fReorder, fVerbose) == NULL )
+ if ( Abc_NtkBuildGlobalBdds(pNtk, fBddSizeMax, 1, fReorder, fReverse, fVerbose) == NULL )
return NULL;
if ( fVerbose )
{
@@ -212,7 +212,7 @@ Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, i
}
// create the new network
- pNtkNew = Abc_NtkFromGlobalBdds( pNtk );
+ pNtkNew = Abc_NtkFromGlobalBdds( pNtk, fReverse );
Abc_NtkFreeGlobalBdds( pNtk, 1 );
if ( pNtkNew == NULL )
return NULL;
@@ -236,7 +236,7 @@ Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, i
#else
-Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose )
+Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fVerbose )
{
return NULL;
}
diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c
index 4d8f5217..5121a4fc 100644
--- a/src/base/abci/abcDsd.c
+++ b/src/base/abci/abcDsd.c
@@ -67,7 +67,7 @@ Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, int fVerbose, int fPrint, int fS
DdManager * dd;
Abc_Ntk_t * pNtkNew;
assert( Abc_NtkIsStrash(pNtk) );
- dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose );
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, fVerbose );
if ( dd == NULL )
return NULL;
if ( fVerbose )
diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c
index 2fbf63dd..b717f5b4 100644
--- a/src/base/abci/abcExact.c
+++ b/src/base/abci/abcExact.c
@@ -2983,8 +2983,8 @@ void Abc_ExactStoreTest( int fVerbose )
Abc_Ntk_t * pNtk;
Abc_Obj_t * pFanins[4];
Vec_Ptr_t * vNames;
- char pPerm[4];
- int Cost;
+ char pPerm[4] = {0};
+ int Cost = 0;
pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
pNtk->pName = Extra_UtilStrsav( "exact" );
diff --git a/src/base/abci/abcGen.c b/src/base/abci/abcGen.c
index 26ee3f86..e90040ab 100644
--- a/src/base/abci/abcGen.c
+++ b/src/base/abci/abcGen.c
@@ -821,6 +821,55 @@ void Abc_GenFsm( char * pFileName, int nPis, int nPos, int nStates, int nLines,
Vec_StrFree( vCond );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_AdderTree( FILE * pFile, int nArgs, int nBits )
+{
+ int i, k, nDigits = Abc_Base10Log( nBits ), Log2 = Abc_Base2Log( nArgs );
+ assert( nArgs > 1 && nBits > 1 );
+ fprintf( pFile, "module adder_tree_%d_%d (\n ", nArgs, nBits );
+ for ( i = 0; i < nBits; i++, fprintf(pFile, "\n ") )
+ for ( k = 0; k < nArgs; k++ )
+ fprintf( pFile, " i%0*d_%0*d,", nDigits, k, nDigits, nBits-1-i );
+ fprintf( pFile, " z\n" );
+ fprintf( pFile, " );\n" );
+ for ( i = 0; i < nBits; i++ )
+ {
+ fprintf( pFile, " input" );
+ for ( k = 0; k < nArgs; k++ )
+ fprintf( pFile, " i%0*d_%0*d%s", nDigits, k, nDigits, nBits-1-i, k==nArgs-1 ? "":"," );
+ fprintf( pFile, ";\n" );
+ }
+ fprintf( pFile, " output [%d:0] z;\n", nBits+Log2-1 );
+ for ( i = 0; i < nArgs; i++ )
+ {
+ fprintf( pFile, " wire [%d:0] t%d = {", nBits-1, i );
+ for ( k = 0; k < nBits; k++ )
+ fprintf( pFile, " i%0*d_%0*d%s", nDigits, i, nDigits, nBits-1-k, k==nBits-1 ? "":"," );
+ fprintf( pFile, " };\n" );
+ }
+ for ( i = 0; i < nArgs-1; i++ )
+ fprintf( pFile, " wire [%d:0] s%d = t%d + %s%d;\n", nBits+Log2-1, i+1, i+1, i ? "s":"t", i );
+ fprintf( pFile, " assign z = s%d;\n", nArgs-1 );
+ fprintf( pFile, "endmodule\n\n" );
+}
+void Abc_GenAdderTree( char * pFileName, int nArgs, int nBits )
+{
+ FILE * pFile = fopen( pFileName, "w" );
+ fprintf( pFile, "// %d-argument %d-bit adder-tree generated by ABC on %s\n", nArgs, nBits, Extra_TimeStamp() );
+ Abc_AdderTree( pFile, nArgs, nBits );
+ fclose( pFile );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c
index 59481d3e..e4a5d3b4 100644
--- a/src/base/abci/abcIvy.c
+++ b/src/base/abci/abcIvy.c
@@ -600,7 +600,7 @@ int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars )
printf( "Attempting BDDs with node limit %d ...\n", pParams->nBddSizeLimit );
fflush( stdout );
}
- pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0 );
+ pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0, 0 );
if ( pNtk )
{
Abc_NtkDelete( pNtkTemp );
diff --git a/src/base/abci/abcLutmin.c b/src/base/abci/abcLutmin.c
index ad686299..2ac44060 100644
--- a/src/base/abci/abcLutmin.c
+++ b/src/base/abci/abcLutmin.c
@@ -739,7 +739,7 @@ Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose )
else
pNtkNew = Abc_NtkStrash( pNtkInit, 0, 1, 0 );
// collapse the network
- pNtkNew = Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, 1, 0 );
+ pNtkNew = Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, 1, 0, 0 );
Abc_NtkDelete( pTemp );
if ( pNtkNew == NULL )
return NULL;
diff --git a/src/base/abci/abcNpn.c b/src/base/abci/abcNpn.c
index d2d06924..744b6443 100644
--- a/src/base/abci/abcNpn.c
+++ b/src/base/abci/abcNpn.c
@@ -295,10 +295,6 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
}
else if ( NpnType == 7 )
{
- extern unsigned Abc_TtCanonicizeHie(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int fExact );
- extern Abc_TtHieMan_t * Abc_TtHieManStart( int nVars, int nLevels );
- extern void Abc_TtHieManStop(Abc_TtHieMan_t * p );
-
int fExact = 0;
Abc_TtHieMan_t * pMan = Abc_TtHieManStart( p->nVars, 5 );
for ( i = 0; i < p->nFuncs; i++ )
@@ -318,8 +314,6 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
typedef unsigned(*TtCanonicizeFunc)(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres);
- Abc_TtHieMan_t * Abc_TtHieManStart(int nVars, int nLevels);
- void Abc_TtHieManStop(Abc_TtHieMan_t * p);
int fHigh = 1, iEnumThres = 25;
Abc_TtHieMan_t * pMan = Abc_TtHieManStart(p->nVars, 5);
diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c
index 0225d800..a55ea227 100644
--- a/src/base/abci/abcNtbdd.c
+++ b/src/base/abci/abcNtbdd.c
@@ -254,7 +254,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t *
SeeAlso []
***********************************************************************/
-void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDropInternal, int fReorder, int fVerbose )
+void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose )
{
ProgressBar * pProgress;
Abc_Obj_t * pObj, * pFanin;
@@ -287,8 +287,7 @@ void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDropInter
Abc_NtkForEachCi( pNtk, pObj, i )
if ( Abc_ObjFanoutNum(pObj) > 0 )
{
- bFunc = dd->vars[i];
-// bFunc = dd->vars[Abc_NtkCiNum(pNtk) - 1 - i];
+ bFunc = fReverse ? dd->vars[Abc_NtkCiNum(pNtk) - 1 - i] : dd->vars[i];
Abc_ObjSetGlobalBdd( pObj, bFunc ); Cudd_Ref( bFunc );
}
diff --git a/src/base/abci/abcProve.c b/src/base/abci/abcProve.c
index c31e9d94..03722926 100644
--- a/src/base/abci/abcProve.c
+++ b/src/base/abci/abcProve.c
@@ -201,7 +201,7 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
fflush( stdout );
}
clk = Abc_Clock();
- pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0 );
+ pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0, 0 );
if ( pNtk )
{
Abc_NtkDelete( pNtkTemp );
diff --git a/src/base/abci/abcReach.c b/src/base/abci/abcReach.c
index 908b16be..bf705dc9 100644
--- a/src/base/abci/abcReach.c
+++ b/src/base/abci/abcReach.c
@@ -271,7 +271,7 @@ void Abc_NtkVerifyUsingBdds( Abc_Ntk_t * pNtk, int nBddMax, int nIterMax, int fP
assert( Abc_ObjFanoutNum(Abc_NtkPo(pNtk,0)) == 0 ); // PO should go first
// compute the global BDDs of the latches
- dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddMax, 1, fReorder, fVerbose );
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddMax, 1, fReorder, 0, fVerbose );
if ( dd == NULL )
{
printf( "The number of intermediate BDD nodes exceeded the limit (%d).\n", nBddMax );
diff --git a/src/base/abci/abcSymm.c b/src/base/abci/abcSymm.c
index 096c3ae4..36a5ee3e 100644
--- a/src/base/abci/abcSymm.c
+++ b/src/base/abci/abcSymm.c
@@ -99,7 +99,7 @@ void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fReorder, int
// compute the global functions
clk = Abc_Clock();
- dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, fReorder, fVerbose );
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, fReorder, 0, fVerbose );
printf( "Shared BDD size = %d nodes.\n", Abc_NtkSizeOfGlobalBdds(pNtk) );
Cudd_AutodynDisable( dd );
if ( !fGarbCollect )
diff --git a/src/base/abci/abcUnate.c b/src/base/abci/abcUnate.c
index 63003237..211f1ca3 100644
--- a/src/base/abci/abcUnate.c
+++ b/src/base/abci/abcUnate.c
@@ -82,7 +82,7 @@ void Abc_NtkPrintUnateBdd( Abc_Ntk_t * pNtk, int fUseNaive, int fVerbose )
abctime clkBdd, clkUnate;
// compute the global BDDs
- dd = (DdManager *)Abc_NtkBuildGlobalBdds(pNtk, 10000000, 1, 1, fVerbose);
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds(pNtk, 10000000, 1, 1, 0, fVerbose);
if ( dd == NULL )
return;
clkBdd = Abc_Clock() - clk;
diff --git a/src/base/abci/abcUnreach.c b/src/base/abci/abcUnreach.c
index 679d9eed..ae4bc84b 100644
--- a/src/base/abci/abcUnreach.c
+++ b/src/base/abci/abcUnreach.c
@@ -67,7 +67,7 @@ int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, int fVerbose )
}
// compute the global BDDs of the latches
- dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose );
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, fVerbose );
if ( dd == NULL )
return 0;
if ( fVerbose )
diff --git a/src/base/acb/acbFunc.c b/src/base/acb/acbFunc.c
index d73d1d59..1efb5807 100644
--- a/src/base/acb/acbFunc.c
+++ b/src/base/acb/acbFunc.c
@@ -198,7 +198,7 @@ int Acb_WireIsTarget( int Token, Abc_Nam_t * pNames )
}
void * Acb_VerilogSimpleParse( Vec_Int_t * vBuffer, Abc_Nam_t * pNames )
{
- void * pDesign = NULL;
+ Ndr_Data_t * pDesign = NULL;
Vec_Int_t * vInputs = Vec_IntAlloc(100);
Vec_Int_t * vOutputs = Vec_IntAlloc(100);
Vec_Int_t * vWires = Vec_IntAlloc(100);
diff --git a/src/base/cmd/cmdStarter.c b/src/base/cmd/cmdStarter.c
index 47cdd9ed..ffb2b752 100644
--- a/src/base/cmd/cmdStarter.c
+++ b/src/base/cmd/cmdStarter.c
@@ -176,7 +176,8 @@ void Cmd_RunStarter( char * pFileName, char * pBinary, char * pCommand, int nCor
ABC_FREE( Buffer );
fclose( pFile );
return;
- }
+ }
+ fclose( pFileTemp );
}
}
diff --git a/src/base/io/io.c b/src/base/io/io.c
index 5133ef0d..f155c7b6 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -2678,14 +2678,24 @@ usage:
***********************************************************************/
int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv )
{
+ extern int Io_WriteMoPlaM( Abc_Ntk_t * pNtk, char * pFileName, int nMints );
char * pFileName;
- int c, fUseMoPla = 0;
+ int c, fUseMoPla = 0, nMints = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "mh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Mmh" ) ) != EOF )
{
switch ( c )
{
+ case 'M':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nMints = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ break;
case 'm':
fUseMoPla ^= 1;
break;
@@ -2705,15 +2715,28 @@ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv )
// get the output file name
pFileName = argv[globalUtilOptind];
// call the corresponding file writer
- Io_Write( pAbc->pNtkCur, pFileName, fUseMoPla ? IO_FILE_MOPLA : IO_FILE_PLA );
+ if ( nMints )
+ {
+ if ( Abc_NtkIsBddLogic(pAbc->pNtkCur) )
+ Io_WriteMoPlaM( pAbc->pNtkCur, pFileName, nMints );
+ else
+ {
+ Abc_Ntk_t * pStrash = Abc_NtkStrash( pAbc->pNtkCur, 0, 0, 0 );
+ Io_WriteMoPlaM( pStrash, pFileName, nMints );
+ Abc_NtkDelete( pStrash );
+ }
+ }
+ else
+ Io_Write( pAbc->pNtkCur, pFileName, fUseMoPla ? IO_FILE_MOPLA : IO_FILE_PLA );
return 0;
usage:
- fprintf( pAbc->Err, "usage: write_pla [-mh] <file>\n" );
- fprintf( pAbc->Err, "\t writes the collapsed network into a PLA file\n" );
- fprintf( pAbc->Err, "\t-m : toggle writing multi-output PLA [default = %s]\n", fUseMoPla? "yes":"no" );
- fprintf( pAbc->Err, "\t-h : print the help massage\n" );
- fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
+ fprintf( pAbc->Err, "usage: write_pla [-M <num>] [-mh] <file>\n" );
+ fprintf( pAbc->Err, "\t writes the collapsed network into a PLA file\n" );
+ fprintf( pAbc->Err, "\t-M <num> : the number of on-set minterms to write [default = %d]\n", nMints );
+ fprintf( pAbc->Err, "\t-m : toggle writing multi-output PLA [default = %s]\n", fUseMoPla? "yes":"no" );
+ fprintf( pAbc->Err, "\t-h : print the help massage\n" );
+ fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
return 1;
}
diff --git a/src/base/io/ioWritePla.c b/src/base/io/ioWritePla.c
index 676617a1..8aa9ee19 100644
--- a/src/base/io/ioWritePla.c
+++ b/src/base/io/ioWritePla.c
@@ -383,14 +383,14 @@ int Io_WriteMoPlaOneIntMinterms( FILE * pFile, Abc_Ntk_t * pNtk, DdManager * dd,
***********************************************************************/
int Io_WriteMoPlaOne( FILE * pFile, Abc_Ntk_t * pNtk )
{
- int fVerbose = 1;
+ int fVerbose = 0;
DdManager * dd;
DdNode * bFunc;
Vec_Ptr_t * vFuncsGlob;
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkIsStrash(pNtk) );
- dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose );
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, fVerbose );
if ( dd == NULL )
return 0;
if ( fVerbose )
@@ -445,9 +445,136 @@ int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * pFileName )
return 1;
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the network in PLA format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_WriteMoPlaOneIntMintermsM( FILE * pFile, Abc_Ntk_t * pNtk, DdManager * dd, DdNode * bFunc, int nMints )
+{
+ Abc_Obj_t * pNode;
+ int * pArray = ABC_CALLOC( int, dd->size );
+ DdNode ** pbMints = Cudd_bddPickArbitraryMinterms( dd, bFunc, dd->vars, dd->size, nMints );
+ int i, k, nInputs = Abc_NtkCiNum(pNtk);
+ assert( dd->size == Abc_NtkCiNum(pNtk) );
+
+ // write the header
+ fprintf( pFile, ".i %d\n", nInputs );
+ fprintf( pFile, ".o %d\n", 1 );
+ fprintf( pFile, ".ilb" );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ fprintf( pFile, " %s", Abc_ObjName(pNode) );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, ".ob" );
+ fprintf( pFile, " %s", Abc_ObjName(Abc_NtkCo(pNtk, 0)) );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, ".p %d\n", nMints );
+
+ // iterate through minterms
+ for ( k = 0; k < nMints; k++ )
+ {
+ Cudd_BddToCubeArray( dd, pbMints[k], pArray );
+ for ( i = 0; i < Abc_NtkCiNum(pNtk); i++ )
+ if ( pArray[i] == 0 )
+ fprintf( pFile, "%c", '0' );
+ else if ( pArray[i] == 1 )
+ fprintf( pFile, "%c", '1' );
+ else if ( pArray[i] == 2 )
+ fprintf( pFile, "%c", '-' );
+ fprintf( pFile, " " );
+ fprintf( pFile, "%c", '1' );
+ fprintf( pFile, "\n" );
+ }
+ fprintf( pFile, ".e\n" );
+
+ //for ( k = 0; k < nMints; k++ )
+ // Cudd_RecursiveDeref( dd, pbMints[k] );
+ ABC_FREE( pbMints );
+ ABC_FREE( pArray );
+ return 1;
+}
+int Io_WriteMoPlaOneM( FILE * pFile, Abc_Ntk_t * pNtk, int nMints )
+{
+ int fVerbose = 0;
+ DdManager * dd;
+ DdNode * bFunc;
+ Vec_Ptr_t * vFuncsGlob;
+ Abc_Obj_t * pObj;
+ int i;
+ if ( Abc_NtkIsStrash(pNtk) )
+ {
+ assert( Abc_NtkIsStrash(pNtk) );
+ dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, fVerbose );
+ if ( dd == NULL )
+ return 0;
+ if ( fVerbose )
+ printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
+
+ // complement the global functions
+ vFuncsGlob = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Vec_PtrPush( vFuncsGlob, Abc_ObjGlobalBdd(pObj) );
+
+ // get the output function
+ bFunc = (DdNode *)Vec_PtrEntry(vFuncsGlob, 0);
+ if ( bFunc == Cudd_ReadOne(dd) )
+ printf( "First primary output has constant 1 function.\n" );
+ else if ( Cudd_Not(bFunc) == Cudd_ReadOne(dd) )
+ printf( "First primary output has constant 0 function.\n" );
+ else
+ Io_WriteMoPlaOneIntMintermsM( pFile, pNtk, dd, bFunc, nMints );
+ Abc_NtkFreeGlobalBdds( pNtk, 0 );
+
+ // cleanup
+ Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i )
+ Cudd_RecursiveDeref( dd, bFunc );
+ Vec_PtrFree( vFuncsGlob );
+ //Extra_StopManager( dd );
+ Cudd_Quit( dd );
+ }
+ else if ( Abc_NtkIsBddLogic(pNtk) )
+ {
+ DdNode * bFunc = (DdNode *)Abc_ObjFanin0(Abc_NtkCo(pNtk, 0))->pData;
+ dd = (DdManager *)pNtk->pManFunc;
+ if ( dd->size == Abc_NtkCiNum(pNtk) )
+ Io_WriteMoPlaOneIntMintermsM( pFile, pNtk, dd, bFunc, nMints );
+ else
+ {
+ printf( "Cannot write minterms because the size of the manager for local BDDs is not equal to\n" );
+ printf( "the number of primary inputs. (It is likely that the current network is not collapsed.)\n" );
+ }
+ }
+ return 1;
+}
+int Io_WriteMoPlaM( Abc_Ntk_t * pNtk, char * pFileName, int nMints )
+{
+ FILE * pFile;
+ assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsBddLogic(pNtk) );
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Io_WriteMoPlaM(): Cannot open the output file.\n" );
+ return 0;
+ }
+ fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
+ Io_WriteMoPlaOneM( pFile, pNtk, nMints );
+ fclose( pFile );
+ return 1;
+}
+
+
#else
-int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * pFileName ) { return 1; }
+int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * pFileName ) { return 1; }
+int Io_WriteMoPlaM( Abc_Ntk_t * pNtk, char * pFileName, int nMints ) { return 1; }
#endif
diff --git a/src/base/main/abcapis.h b/src/base/main/abcapis.h
index af7888e1..9ac2036a 100644
--- a/src/base/main/abcapis.h
+++ b/src/base/main/abcapis.h
@@ -98,6 +98,9 @@ extern ABC_DLL int * Abc_FrameReadBoxes( Abc_Frame_t * pAbc );
extern ABC_DLL int Abc_FrameReadProbStatus( Abc_Frame_t * pAbc );
extern ABC_DLL void * Abc_FrameReadCex( Abc_Frame_t * pAbc );
+// procedure to return sequential equivalences
+extern ABC_DLL int * Abc_FrameReadMiniAigEquivClasses( Abc_Frame_t * pAbc );
+
ABC_NAMESPACE_HEADER_END
#endif
diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h
index 02921722..3a84031e 100644
--- a/src/base/wlc/wlc.h
+++ b/src/base/wlc/wlc.h
@@ -100,7 +100,8 @@ typedef enum {
WLC_OBJ_WRITE, // 55: write port
WLC_OBJ_ARI_ADDSUB, // 56: adder-subtractor
WLC_OBJ_SEL, // 57: positionally encoded selector
- WLC_OBJ_NUMBER // 57: unused
+ WLC_OBJ_DEC, // 58: decoder
+ WLC_OBJ_NUMBER // 59: unused
} Wlc_ObjType_t;
// when adding new types, remember to update table Wlc_Names in "wlcNtk.c"
@@ -139,6 +140,7 @@ struct Wlc_Ntk_t_
Vec_Int_t vCis; // combinational inputs
Vec_Int_t vCos; // combinational outputs
Vec_Int_t vFfs; // flops
+ Vec_Int_t vFfs2; // flops
Vec_Int_t * vInits; // initial values
char * pInits; // initial values
int nObjs[WLC_OBJ_NUMBER]; // counter of objects of each type
@@ -208,6 +210,7 @@ struct Wlc_BstPar_t_
int fAddOutputs;
int fMulti;
int fBooth;
+ int fCla;
int fNoCleanup;
int fCreateMiter;
int fDecMuxes;
@@ -226,6 +229,7 @@ static inline void Wlc_BstParDefault( Wlc_BstPar_t * pPar )
pPar->fAddOutputs = 0;
pPar->fMulti = 0;
pPar->fBooth = 0;
+ pPar->fCla = 0;
pPar->fCreateMiter = 0;
pPar->fDecMuxes = 0;
pPar->fVerbose = 0;
@@ -272,6 +276,7 @@ static inline Wlc_Obj_t * Wlc_NtkPo( Wlc_Ntk_t * p, int i )
static inline Wlc_Obj_t * Wlc_NtkCi( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vCis, i) ); }
static inline Wlc_Obj_t * Wlc_NtkCo( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vCos, i) ); }
static inline Wlc_Obj_t * Wlc_NtkFf( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vFfs, i) ); }
+static inline Wlc_Obj_t * Wlc_NtkFf2( Wlc_Ntk_t * p, int i ) { return Wlc_NtkObj( p, Vec_IntEntry(&p->vFfs2, i) ); }
static inline int Wlc_ObjIsPi( Wlc_Obj_t * p ) { return p->Type == WLC_OBJ_PI; }
static inline int Wlc_ObjIsPo( Wlc_Obj_t * p ) { return p->fIsPo; }
@@ -347,6 +352,8 @@ static inline Wlc_Obj_t * Wlc_ObjCo2PoFo( Wlc_Ntk_t * p, int iCoId )
for ( i = 0; (i < Wlc_NtkCoNum(p)) && (((pCo) = Wlc_NtkCo(p, i)), 1); i++ )
#define Wlc_NtkForEachFf( p, pFf, i ) \
for ( i = 0; (i < Vec_IntSize(&p->vFfs)) && (((pFf) = Wlc_NtkFf(p, i)), 1); i++ )
+#define Wlc_NtkForEachFf2( p, pFf, i ) \
+ for ( i = 0; (i < Vec_IntSize(&p->vFfs2)) && (((pFf) = Wlc_NtkFf2(p, i)), 1); i++ )
#define Wlc_ObjForEachFanin( pObj, iFanin, i ) \
for ( i = 0; (i < Wlc_ObjFaninNum(pObj)) && (((iFanin) = Wlc_ObjFaninId(pObj, i)), 1); i++ )
diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c
index b97dfdad..e4088f9c 100644
--- a/src/base/wlc/wlcBlast.c
+++ b/src/base/wlc/wlcBlast.c
@@ -131,6 +131,12 @@ int Wlc_NtkMuxTree2( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData
Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vData, m)) ) );
return Abc_LitNot( Gia_ManHashAndMulti(pNew, vTemp) );
}
+void Wlc_NtkPrintNameArray( Vec_Ptr_t * vNames )
+{
+ int i; char * pTemp;
+ Vec_PtrForEachEntry( char *, vNames, pTemp, i )
+ printf( "%2d : %s\n", i, pTemp );
+}
/**Function*************************************************************
@@ -345,9 +351,9 @@ void Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int
for ( b = 0; b < nBits; b++ )
Wlc_BlastFullAdder( pNew, pAdd0[b], pAdd1[b], Carry, &Carry, &pAdd0[b] );
}
-void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) // result is in pAdd0
+void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0
{
- int b, Carry = 1;
+ int b;
for ( b = 0; b < nBits; b++ )
Wlc_BlastFullAdder( pNew, pAdd0[b], Abc_LitNot(pAdd1[b]), Carry, &Carry, &pAdd0[b] );
}
@@ -375,7 +381,7 @@ void Wlc_BlastAdderCLA_rec( Gia_Man_t * pNew, int * pGen, int * pPro, int * pCar
Wlc_BlastAdderCLA_one( pNew, pGen2, pPro2, pCar, pGen1, pPro1, pCar+nBits/2 ); // returns *pGen1, *pPro1, pCar[nBits/2]
}
}
-void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits ) // result is in pAdd0
+void Wlc_BlastAdderCLA_int( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int CarryIn ) // result is in pAdd0
{
int * pGen = ABC_CALLOC( int, nBits );
int * pPro = ABC_CALLOC( int, nBits );
@@ -383,12 +389,12 @@ void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits )
int b, Gen, Pro;
if ( nBits == 1 )
{
- int Carry = 0;
+ int Carry = CarryIn;
Wlc_BlastFullAdder( pNew, pAdd0[0], pAdd1[0], Carry, &Carry, &pAdd0[0] );
return;
}
assert( nBits >= 2 );
- pCar[0] = 0;
+ pCar[0] = CarryIn;
for ( b = 0; b < nBits; b++ )
{
pGen[b] = Gia_ManHashAnd(pNew, pAdd0[b], pAdd1[b]);
@@ -401,6 +407,117 @@ void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits )
ABC_FREE(pPro);
ABC_FREE(pCar);
}
+void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int fSign, int CarryIn ) // result is in pAdd0
+{
+ int i, Log2 = Abc_Base2Log(nBits);
+ int * pAdd0n = ABC_CALLOC( int, 1<<Log2 );
+ int * pAdd1n = ABC_CALLOC( int, 1<<Log2 );
+ for ( i = 0; i < nBits; i++ )
+ {
+ pAdd0n[i] = pAdd0[i];
+ pAdd1n[i] = pAdd1[i];
+ }
+ for ( ; i < (1<<Log2); i++ )
+ {
+ pAdd0n[i] = fSign ? pAdd0[nBits-1] : 0;
+ pAdd1n[i] = fSign ? pAdd1[nBits-1] : 0;
+ }
+ Wlc_BlastAdderCLA_int( pNew, pAdd0n, pAdd1n, 1<<Log2, CarryIn );
+ for ( i = 0; i < nBits; i++ )
+ pAdd0[i] = pAdd0n[i];
+ ABC_FREE(pAdd0n);
+ ABC_FREE(pAdd1n);
+}
+
+void Wlc_BlastAdderFast_int( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int Log2, int CarryIn ) // result is in pAdd0
+{
+ int i, b, Gen, Pro, nBits = 1 << Log2;
+ int * pGen = ABC_CALLOC( int, nBits+1 );
+ int * pPro = ABC_CALLOC( int, nBits+1 );
+ int * pPro2= ABC_CALLOC( int, nBits+1 );
+ if ( nBits == 1 )
+ {
+ int Carry = CarryIn;
+ Wlc_BlastFullAdder( pNew, pAdd0[0], pAdd1[0], Carry, &Carry, &pAdd0[0] );
+ ABC_FREE(pGen);
+ ABC_FREE(pPro);
+ ABC_FREE(pPro2);
+ return;
+ }
+ assert( nBits >= 2 );
+ pGen[0] = CarryIn;
+ pPro[0] = 0;
+ pPro2[0]= 0;
+ for ( b = 1; b <= nBits; b++ )
+ {
+ pGen[b] = Gia_ManHashAnd(pNew, pAdd0[b-1], pAdd1[b-1]);
+ pPro[b] = Gia_ManHashXor(pNew, pAdd0[b-1], pAdd1[b-1]);
+ pPro2[b]= pPro[b];
+ }
+
+ // Han-Carlson adder from http://www.aoki.ecei.tohoku.ac.jp/arith/mg/algorithm.html
+ for ( b = 1; b <= nBits; b += 2 )
+ {
+ Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-1]) );
+ Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-1]);
+ pPro[b] = Pro;
+ pGen[b] = Gen;
+ }
+ for ( i = 1; i < Log2-1; i++ )
+ {
+ for ( b = 1 + 2*i; b <= nBits; b += 2 )
+ {
+ Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-i*2]) );
+ Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-i*2]);
+ pPro[b] = Pro;
+ pGen[b] = Gen;
+ }
+ }
+ for ( b = nBits/2 + 1; b <= nBits; b += 2 )
+ {
+ Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-nBits/2]) );
+ Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-nBits/2]);
+ pPro[b] = Pro;
+ pGen[b] = Gen;
+ }
+ for ( b = 2; b <= nBits; b += 2 )
+ {
+ Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-1]) );
+ Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-1]);
+ pPro[b] = Pro;
+ pGen[b] = Gen;
+ }
+
+ for ( b = 0; b < nBits; b++ )
+ pAdd0[b] = Gia_ManHashXor(pNew, pPro2[b+1], pGen[b]);
+ pAdd0[nBits] = pGen[nBits];
+
+ ABC_FREE(pGen);
+ ABC_FREE(pPro);
+ ABC_FREE(pPro2);
+}
+void Wlc_BlastAdderFast( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int fSign, int CarryIn ) // result is in pAdd0
+{
+ int i, Log2 = Abc_Base2Log(nBits);
+ int * pAdd0n = ABC_CALLOC( int, (1<<Log2)+1 );
+ int * pAdd1n = ABC_CALLOC( int, (1<<Log2)+1 );
+ for ( i = 0; i < nBits; i++ )
+ {
+ pAdd0n[i] = pAdd0[i];
+ pAdd1n[i] = pAdd1[i];
+ }
+ for ( ; i < (1<<Log2); i++ )
+ {
+ pAdd0n[i] = fSign ? pAdd0[nBits-1] : 0;
+ pAdd1n[i] = fSign ? pAdd1[nBits-1] : 0;
+ }
+ Wlc_BlastAdderFast_int( pNew, pAdd0n, pAdd1n, Log2, CarryIn );
+ for ( i = 0; i <= nBits; i++ )
+ pAdd0[i] = pAdd0n[i];
+ ABC_FREE(pAdd0n);
+ ABC_FREE(pAdd1n);
+}
+
void Wlc_BlastMinus( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vRes )
{
int * pRes = Wlc_VecCopy( vRes, pNum, nNum );
@@ -700,7 +817,7 @@ void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds )
Vec_IntFree( vSupp );
Vec_WrdFree( vTemp );
}
-void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes )
+void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes, int fSigned, int fCla )
{
Vec_Int_t * vLevel, * vProd;
int i, NodeS, NodeC, LevelS, LevelC, Node1, Node2, Node3, Level1, Level2, Level3;
@@ -758,9 +875,112 @@ void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vL
}
Vec_IntPush( vRes, 0 );
Vec_IntPush( vLevel, 0 );
- Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), 0 );
+
+ if ( fCla )
+ Wlc_BlastAdderCLA( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), fSigned, 0 );
+ else
+ Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), 0 );
+}
+
+int Wlc_BlastAddLevel( Gia_Man_t * pNew, int Start )
+{
+ int i;
+ if ( Start == 0 )
+ Gia_ManCleanLevels( pNew, 5 * Gia_ManObjNum(pNew) );
+ for ( i = Start; i < Gia_ManObjNum(pNew); i++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( pNew, i );
+ if ( Gia_ObjIsAnd(pObj) )
+ Gia_ObjSetAndLevel( pNew, pObj );
+ }
+ return Gia_ManObjNum(pNew);
+}
+void Wlc_IntInsert2( Gia_Man_t * pNew, Vec_Int_t * vProd, int iLit )
+{
+ int i, Entry, Level = Gia_ObjLevelId(pNew, Abc_Lit2Var(iLit));
+ Vec_IntForEachEntryReverse( vProd, Entry, i )
+ if ( Gia_ObjLevelId(pNew, Abc_Lit2Var(Entry)) >= Level )
+ break;
+ Vec_IntInsert( vProd, i + 1, iLit );
+// Vec_IntForEachEntry( vProd, Entry, i )
+// printf( "Obj=%d(%d) ", Abc_Lit2Var(Entry), Gia_ObjLevelId(pNew, Abc_Lit2Var(Entry)) );
+// printf( "\n" );
+}
+void Wlc_IntSortCostReverse( Gia_Man_t * pNew, int * pArray, int nSize )
+{
+ int i, j, best_i;
+ for ( i = 0; i < nSize-1; i++ )
+ {
+ best_i = i;
+ for ( j = i+1; j < nSize; j++ )
+ if ( Gia_ObjLevelId(pNew, Abc_Lit2Var(pArray[j])) > Gia_ObjLevelId(pNew, Abc_Lit2Var(pArray[best_i])) )
+ best_i = j;
+ ABC_SWAP( int, pArray[i], pArray[best_i] );
+ }
+}
+void Wlc_BlastReduceMatrix2( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Int_t * vRes, int fSigned, int fCla )
+{
+ Vec_Int_t * vProd, * vTemp;
+ int i, NodeS, NodeC, Node1, Node2, Node3;
+ int Start = Wlc_BlastAddLevel( pNew, 0 );
+ int nSize = Vec_WecSize(vProds);
+ Vec_WecForEachLevel( vProds, vProd, i )
+ Wlc_IntSortCostReverse( pNew, Vec_IntArray(vProd), Vec_IntSize(vProd) );
+ for ( i = 0; i < nSize; i++ )
+ {
+ while ( 1 )
+ {
+ vProd = Vec_WecEntry( vProds, i );
+ if ( Vec_IntSize(vProd) < 3 )
+ break;
+
+ Node1 = Vec_IntPop( vProd );
+ Node2 = Vec_IntPop( vProd );
+ Node3 = Vec_IntPop( vProd );
+
+ assert( Gia_ObjLevelId(pNew, Abc_Lit2Var(Node3)) >= Gia_ObjLevelId(pNew, Abc_Lit2Var(Node2)) );
+ assert( Gia_ObjLevelId(pNew, Abc_Lit2Var(Node2)) >= Gia_ObjLevelId(pNew, Abc_Lit2Var(Node1)) );
+
+ Wlc_BlastFullAdder( pNew, Node1, Node2, Node3, &NodeC, &NodeS );
+ Start = Wlc_BlastAddLevel( pNew, Start );
+
+ Wlc_IntInsert2( pNew, vProd, NodeS );
+
+ vProd = Vec_WecEntry( vProds, i+1 );
+ Wlc_IntInsert2( pNew, vProd, NodeC );
+ }
+ }
+
+ // make all ranks have two products
+ for ( i = 0; i < nSize; i++ )
+ {
+ vProd = Vec_WecEntry( vProds, i );
+ while ( Vec_IntSize(vProd) < 2 )
+ Vec_IntPush( vProd, 0 );
+ assert( Vec_IntSize(vProd) == 2 );
+ }
+// Vec_WecPrint( vProds, 0 );
+
+ Vec_IntClear( vRes );
+ vTemp = Vec_IntAlloc( 100 );
+ for ( i = 0; i < nSize; i++ )
+ {
+ vProd = Vec_WecEntry( vProds, i );
+ Vec_IntPush( vRes, Vec_IntEntry(vProd, 0) );
+ Vec_IntPush( vTemp, Vec_IntEntry(vProd, 1) );
+ }
+ Vec_IntPush( vRes, 0 );
+ Vec_IntPush( vTemp, 0 );
+
+ if ( fCla )
+ Wlc_BlastAdderCLA( pNew, Vec_IntArray(vRes), Vec_IntArray(vTemp), Vec_IntSize(vRes), fSigned, 0 );
+ else
+ Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vTemp), Vec_IntSize(vRes), 0 );
+ Vec_IntFree( vTemp );
}
-void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes )
+
+
+void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla )
{
Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB );
Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB );
@@ -768,11 +988,21 @@ void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA
for ( i = 0; i < nArgA; i++ )
for ( k = 0; k < nArgB; k++ )
{
- Vec_WecPush( vProds, i+k, Gia_ManHashAnd(pNew, pArgA[i], pArgB[k]) );
+ int fCompl = fSigned && ((i == nArgA-1) ^ (k == nArgB-1));
+ Vec_WecPush( vProds, i+k, Abc_LitNotCond(Gia_ManHashAnd(pNew, pArgA[i], pArgB[k]), fCompl) );
Vec_WecPush( vLevels, i+k, 0 );
}
+ if ( fSigned )
+ {
+ Vec_WecPush( vProds, nArgA, 1 );
+ Vec_WecPush( vLevels, nArgA, 0 );
+
+ Vec_WecPush( vProds, nArgA+nArgB-1, 1 );
+ Vec_WecPush( vLevels, nArgA+nArgB-1, 0 );
+ }
- Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes );
+ Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla );
+// Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla );
Vec_WecFree( vProds );
Vec_WecFree( vLevels );
@@ -797,12 +1027,24 @@ void Wlc_BlastSquare( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp,
}
}
- Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes );
+ Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, 0, 0 );
Vec_WecFree( vProds );
Vec_WecFree( vLevels );
}
-void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned )
+void Wlc_BlastDecoder( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_Int_t * vRes )
+{
+ int i, k, nMints = 1 << nNum;
+ Vec_IntClear( vRes );
+ for ( i = 0; i < nMints; i++ )
+ {
+ int iMint = 1;
+ for ( k = 0; k < nNum; k++ )
+ iMint = Gia_ManHashAnd( pNew, iMint, Abc_LitNotCond(pNum[k], !((i >> k) & 1)) );
+ Vec_IntPush( vRes, iMint );
+ }
+}
+void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla )
{
Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB + 3 );
Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB + 3 );
@@ -871,7 +1113,8 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int
//Vec_WecPrint( vProds, 0 );
//Wlc_BlastPrintMatrix( pNew, vProds );
//printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) );
- Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes );
+ Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla );
+// Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla );
Vec_WecFree( vProds );
Vec_WecFree( vLevels );
@@ -897,13 +1140,15 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
Tim_Man_t * pManTime = NULL;
If_LibBox_t * pBoxLib = NULL;
Vec_Ptr_t * vTables = NULL;
+ Vec_Int_t * vFf2Ci = Vec_IntAlloc( 100 );
+ Vec_Int_t * vRegClasses = NULL;
Gia_Man_t * pTemp, * pNew, * pExtra = NULL;
Wlc_Obj_t * pObj, * pObj2;
Vec_Int_t * vBits = &p->vBits, * vTemp0, * vTemp1, * vTemp2, * vRes, * vAddOutputs = NULL, * vAddObjs = NULL;
int nBits = Wlc_NtkPrepareBits( p );
- int nRange, nRange0, nRange1, nRange2;
- int i, k, b, iFanin, iLit, nAndPrev, * pFans0, * pFans1, * pFans2;
- int nFFins = 0, nFFouts = 0, curPi = 0, curPo = 0;
+ int nRange, nRange0, nRange1, nRange2, nRange3;
+ int i, k, b, iFanin, iLit, nAndPrev, * pFans0, * pFans1, * pFans2, * pFans3;
+ int nFFins = 0, nFFouts = 0, curPi = 0, curPo = 0, nFf2Regs = 0;
int nBitCis = 0, nBitCos = 0, fAdded = 0;
Wlc_BstPar_t Par, * pPar = &Par;
Wlc_BstParDefault( pPar );
@@ -930,6 +1175,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
if ( pPar->vBoxIds )
{
int nNewCis = 0, nNewCos = 0;
+ assert( Vec_IntSize(&p->vFfs2) == 0 );
Wlc_NtkForEachObj( p, pObj, i )
pObj->Mark = 0;
// count bit-width of regular CIs/COs
@@ -961,6 +1207,61 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
// create box library
pBoxLib = If_LibBoxStart();
}
+ if ( Vec_IntSize(&p->vFfs2) > 0 )
+ {
+ Vec_Int_t * vSignature;
+ int nNewCis = 0, nNewCos = 0;
+ assert( pPar->vBoxIds == 0 );
+ // count bit-width of regular CIs/COs
+ Wlc_NtkForEachCi( p, pObj, i )
+ nBitCis += Wlc_ObjRange( pObj );
+ Wlc_NtkForEachCo( p, pObj, i )
+ nBitCos += Wlc_ObjRange( pObj );
+ // count bit-width of additional CIs/COs due to selected multipliers
+ Wlc_NtkForEachFf2( p, pObj, i )
+ {
+ // currently works only for multipliers
+ assert( pObj->Type == WLC_OBJ_FF );
+ assert( Wlc_ObjRange(pObj) == Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
+ nNewCis += Wlc_ObjRange(pObj);
+ nNewCos += 2*Wlc_ObjRange(pObj) + 3;
+ nFf2Regs+= Wlc_ObjRange(pObj);
+ }
+ // create hierarchy manager
+ pManTime = Tim_ManStart( nBitCis + nNewCis + nFf2Regs, nBitCos + nNewCos + nFf2Regs );
+ curPi = nBitCis + nFf2Regs;
+ curPo = 0;
+ // create AIG manager for logic of the boxes
+ pExtra = Gia_ManStart( Wlc_NtkObjNum(p) );
+ Gia_ManHashAlloc( pExtra );
+ assert( !pPar->fGiaSimple );
+ // create register classes
+ vRegClasses = Vec_IntAlloc(0);
+ vSignature = Vec_IntAlloc( 100 );
+ Vec_IntPushTwo( vSignature, -1, -1 );
+ Wlc_NtkForEachFf2( p, pObj, i )
+ {
+ int iClk0, iClk = Wlc_ObjFaninId( pObj, 1 );
+ int iAsyn0, iAsyn = Wlc_ObjFaninId( pObj, 5 );
+ nRange = Wlc_ObjRange(pObj);
+ Vec_IntForEachEntryDouble( vSignature, iClk0, iAsyn0, k )
+ if ( iClk == iClk0 && iAsyn == iAsyn0 )
+ {
+ for ( b = 0; b < nRange; b++ )
+ Vec_IntPush( vRegClasses, k/2 );
+ break;
+ }
+ if ( k < Vec_IntSize(vSignature) )
+ continue;
+ for ( b = 0; b < nRange; b++ )
+ Vec_IntPush( vRegClasses, k/2 );
+ Vec_IntPushTwo( vSignature, iClk, iAsyn );
+ }
+ assert( Vec_IntSize(vRegClasses) == nFf2Regs );
+ Vec_IntFree( vSignature );
+ // create box library
+ pBoxLib = If_LibBoxStart();
+ }
// blast in the topological order
Wlc_NtkForEachObj( p, pObj, i )
{
@@ -972,9 +1273,11 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
nRange0 = Wlc_ObjFaninNum(pObj) > 0 ? Wlc_ObjRange( Wlc_ObjFanin0(p, pObj) ) : -1;
nRange1 = Wlc_ObjFaninNum(pObj) > 1 ? Wlc_ObjRange( Wlc_ObjFanin1(p, pObj) ) : -1;
nRange2 = Wlc_ObjFaninNum(pObj) > 2 ? Wlc_ObjRange( Wlc_ObjFanin2(p, pObj) ) : -1;
- pFans0 = Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL;
- pFans1 = Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL;
- pFans2 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL;
+ nRange3 = Wlc_ObjFaninNum(pObj) > 3 ? Wlc_ObjRange( Wlc_ObjFanin(p, pObj, 3) ) : -1;
+ pFans0 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL;
+ pFans1 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL;
+ pFans2 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL;
+ pFans3 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL;
Vec_IntClear( vRes );
assert( nRange > 0 );
if ( pPar->vBoxIds && pObj->Mark )
@@ -1043,7 +1346,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
if ( pObj->Type == WLC_OBJ_ARI_ADD )
Wlc_BlastAdder( pExtra, pArg0, pArg1, nRange, CarryIn ); // result is in pFan0 (vRes)
else
- Wlc_BlastSubtract( pExtra, pArg0, pArg1, nRange ); // result is in pFan0 (vRes)
+ Wlc_BlastSubtract( pExtra, pArg0, pArg1, nRange, 1 ); // result is in pFan0 (vRes)
Vec_IntShrink( vRes, nRange );
}
else if ( fUseOldMultiplierBlasting )
@@ -1078,13 +1381,15 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
// add box to the library
sprintf( Buffer, "%s%03d", pObj->Type == WLC_OBJ_ARI_ADD ? "add":"mul", 1+If_LibBoxNum(pBoxLib) );
- pBox = If_BoxStart( Abc_UtilStrsav(Buffer), 1+If_LibBoxNum(pBoxLib), nRange, nRange0 + nRange1 + nRange2, 0, 0, 0 );
+ pBox = If_BoxStart( Abc_UtilStrsav(Buffer), 1+If_LibBoxNum(pBoxLib), nRange0 + nRange1 + nRange2, nRange, 0, 0, 0 );
If_LibBoxAdd( pBoxLib, pBox );
for ( k = 0; k < pBox->nPis * pBox->nPos; k++ )
pBox->pDelays[k] = 1;
}
- else if ( Wlc_ObjIsCi(pObj) )
+ else if ( Wlc_ObjIsCi(pObj) || pObj->Type == WLC_OBJ_FF ) // assuming that FFs are ordered immediately after PIs
{
+ if ( pObj->Type == WLC_OBJ_FF )
+ Vec_IntPush( vFf2Ci, Gia_ManCiNum(pNew) );
if ( Wlc_ObjRangeIsReversed(pObj) )
{
for ( k = 0; k < nRange; k++ )
@@ -1099,6 +1404,10 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
}
if ( pObj->Type == WLC_OBJ_FO )
nFFouts += Vec_IntSize(vRes);
+ if ( pObj->Type == WLC_OBJ_FF )
+ {
+ // complement flop output whose init state is 1
+ }
}
else if ( pObj->Type == WLC_OBJ_BUF )
{
@@ -1391,12 +1700,31 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
int CarryIn = Wlc_ObjFaninNum(pObj) == 3 ? pFans2[0] : 0;
if ( pObj->Type == WLC_OBJ_ARI_ADD )
- Wlc_BlastAdder( pNew, pArg0, pArg1, nRange, CarryIn ); // result is in pFan0 (vRes)
-// Wlc_BlastAdderCLA( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes)
+ {
+ if ( pPar->fCla )
+ Wlc_BlastAdderCLA( pNew, pArg0, pArg1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj), CarryIn ); // result is in pFan0 (vRes)
+ //Wlc_BlastAdderFast( pNew, pArg0, pArg1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj), CarryIn ); // result is in pFan0 (vRes)
+ else
+ Wlc_BlastAdder( pNew, pArg0, pArg1, nRangeMax, CarryIn ); // result is in pFan0 (vRes)
+ }
else
- Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange ); // result is in pFan0 (vRes)
+ Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange, 1 ); // result is in pFan0 (vRes)
Vec_IntShrink( vRes, nRange );
}
+ else if ( pObj->Type == WLC_OBJ_ARI_ADDSUB )
+ {
+ int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange2, nRange3) );
+ int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans2, nRange2, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
+ int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans2, nRange2, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
+ int * pArg2 = Wlc_VecLoadFanins( vTemp2, pFans3, nRange3, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
+ int ModeIn = pFans0[0];
+ int CarryIn = pFans1[0]; int j;
+ Wlc_BlastAdder ( pNew, pArg0, pArg2, nRangeMax, CarryIn ); // result is in pArg0 (vTemp0)
+ Wlc_BlastSubtract( pNew, pArg1, pArg2, nRangeMax, Abc_LitNot(CarryIn) ); // result is in pArg1 (vTemp1)
+ Vec_IntClear( vRes );
+ for ( j = 0; j < nRange; j++ )
+ Vec_IntPush( vRes, Gia_ManHashMux(pNew, ModeIn, pArg0[j], pArg1[j]) );
+ }
else if ( pObj->Type == WLC_OBJ_ARI_MULTI )
{
if ( fUseOldMultiplierBlasting )
@@ -1416,10 +1744,11 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
if ( Wlc_NtkCountConstBits(pArg0, nRangeMax) < Wlc_NtkCountConstBits(pArg1, nRangeMax) )
ABC_SWAP( int *, pArg0, pArg1 );
if ( pPar->fBooth )
- Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned );
+ Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned, pPar->fCla );
+ else if ( pPar->fCla )
+ Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla );
else
Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned );
- //Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes );
if ( nRange > Vec_IntSize(vRes) )
Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 );
else
@@ -1475,6 +1804,15 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
else
Vec_IntShrink( vRes, nRange );
}
+ else if ( pObj->Type == WLC_OBJ_DEC )
+ {
+ int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange0, 0 );
+ Wlc_BlastDecoder( pNew, pArg0, nRange0, vTemp2, vRes );
+ if ( nRange > Vec_IntSize(vRes) )
+ Vec_IntFillExtra( vRes, nRange, 0 );
+ else
+ Vec_IntShrink( vRes, nRange );
+ }
else if ( pObj->Type == WLC_OBJ_TABLE )
Wlc_BlastTable( pNew, Wlc_ObjTable(p, pObj), pFans0, nRange0, nRange, vRes );
else assert( 0 );
@@ -1499,6 +1837,102 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
Vec_IntFree( vTemp1 );
Vec_IntFree( vTemp2 );
Vec_IntFree( vRes );
+ // create flop boxes
+ Wlc_NtkForEachFf2( p, pObj, i )
+ {
+ If_Box_t * pBox;
+ char Buffer[100];
+ float * pTable;
+ Vec_Int_t * vTemp0 = Vec_IntAlloc( 100 );
+ Vec_Int_t * vTemp1 = Vec_IntAlloc( 100 );
+ int iLit, nRange = Wlc_ObjRange(pObj);
+ int * pFans0, * pFans1, * pFans2, * pFans3;
+ int iReset, iSet, iEnable;
+ int nRangeIn = 2*nRange + 3; // D, reset, set, enable, Q
+ int iSre = Wlc_ObjFaninId(pObj, 6);
+
+ assert( pObj->Type == WLC_OBJ_FF );
+
+ // create new box
+ if ( vTables == NULL )
+ Tim_ManSetDelayTables( pManTime, (vTables = Vec_PtrAlloc(100)) );
+ Tim_ManCreateBox( pManTime, curPo, nRangeIn, curPi, nRange, Vec_PtrSize(vTables), 0 );
+ curPi += nRange;
+ curPo += nRangeIn;
+
+ // create delay table
+ pTable = ABC_ALLOC( float, 3 + nRange * nRangeIn );
+ pTable[0] = Vec_PtrSize(vTables);
+ pTable[1] = nRangeIn;
+ pTable[2] = nRange;
+ for ( k = 0; k < nRange * nRangeIn; k++ )
+ pTable[3 + k] = 1.0;
+ Vec_PtrPush( vTables, pTable );
+
+ // create combinational outputs in the normal manager
+ pFans0 = Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL;
+ pFans1 = Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL;
+ pFans2 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL;
+ pFans3 = Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL;
+ for ( k = 0; k < nRange; k++ )
+ Gia_ManAppendCo( pNew, pFans0[k] );
+ Gia_ManAppendCo( pNew, pFans1[0] );
+ Gia_ManAppendCo( pNew, pFans2[0] );
+ Gia_ManAppendCo( pNew, pFans3[0] );
+ for ( k = 0; k < nRange; k++ )
+ Gia_ManAppendCo( pNew, Gia_Obj2Lit(pNew, Gia_ManCi(pNew, Vec_IntEntry(vFf2Ci, i)+k)) );
+
+ // make sure there is enough primary inputs in the manager
+ for ( k = Gia_ManPiNum(pExtra); k < nRangeIn; k++ )
+ Gia_ManAppendCi( pExtra );
+ // create combinational inputs
+ for ( k = 0; k < nRange; k++ )
+ Vec_IntPush( vTemp0, Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, k)) );
+ iReset = Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange+0));
+ iSet = Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange+1));
+ iEnable = Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange+2));
+ for ( k = 0; k < nRange; k++ )
+ Vec_IntPush( vTemp1, Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRangeIn-nRange+k)) );
+
+ // bit-blast in the external manager
+ for ( k = 0; k < nRange; k++ )
+ {
+ // enable
+ //iLitFlop = Gia_LitNotCond( Gia_ObjCopy(pObj), Gia_FlopIsOne(pObj) );
+ //iLit = Gia_ManHashMux( Gia_ObjGia(pObj), Gia_FlopEnableCopy(pObj), iLit, iLitFlop );
+ iLit = Gia_ManHashMux( pExtra, iEnable, Vec_IntEntry(vTemp0, k), Vec_IntEntry(vTemp1, k) );
+ if ( iSre )
+ {
+ // reset
+ //iLit = Gia_ManHashAnd( Gia_ObjGia(pObj), iLit, Gia_LitNot(Gia_FlopResetCopy(pObj)) );
+ iLit = Gia_ManHashAnd( pExtra, iLit, Abc_LitNot(iReset) );
+ // set
+ //iLit = Gia_ManHashOr( Gia_ObjGia(pObj), iLit, Gia_FlopSetCopy(pObj) );
+ iLit = Gia_ManHashOr( pExtra, iLit, iSet );
+ }
+ else
+ {
+ // set
+ //iLit = Gia_ManHashOr( Gia_ObjGia(pObj), iLit, Gia_FlopSetCopy(pObj) );
+ iLit = Gia_ManHashOr( pExtra, iLit, iSet );
+ // reset
+ //iLit = Gia_ManHashAnd( Gia_ObjGia(pObj), iLit, Gia_LitNot(Gia_FlopResetCopy(pObj)) );
+ iLit = Gia_ManHashAnd( pExtra, iLit, Abc_LitNot(iReset) );
+ }
+ // create outputs in the external manager
+ Gia_ManAppendCo( pExtra, iLit );
+ }
+
+ // add box to the library
+ sprintf( Buffer, "%s%03d", "ff_comb", 1+If_LibBoxNum(pBoxLib) );
+ pBox = If_BoxStart( Abc_UtilStrsav(Buffer), 1+If_LibBoxNum(pBoxLib), nRangeIn, nRange, 0, 0, 0 );
+ If_LibBoxAdd( pBoxLib, pBox );
+ for ( k = 0; k < pBox->nPis * pBox->nPos; k++ )
+ pBox->pDelays[k] = 1;
+ Vec_IntFree( vTemp0 );
+ Vec_IntFree( vTemp1 );
+ }
+ Vec_IntFree( vFf2Ci );
// create COs
if ( pPar->fCreateMiter )
{
@@ -1588,8 +2022,19 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
//Vec_IntErase( vBits );
//Vec_IntErase( &p->vCopies );
// set the number of registers
- assert( nFFins == nFFouts );
- Gia_ManSetRegNum( pNew, nFFins );
+ if ( Vec_IntSize(&p->vFfs2) > 0 )
+ {
+ assert( nFFins == 0 && nFFouts == 0 );
+ // complement flop inputs whose init state is 1
+ for ( i = 0; i < nFf2Regs; i++ )
+ Gia_ManAppendCo( pNew, Gia_ManAppendCi(pNew) );
+ //Gia_ManSetRegNum( pNew, nFf2Regs );
+ }
+ else
+ {
+ assert( nFFins == nFFouts );
+ Gia_ManSetRegNum( pNew, nFFins );
+ }
// finalize AIG
if ( !pPar->fGiaSimple && !pPar->fNoCleanup )
{
@@ -1614,6 +2059,24 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
}
}
// finalize AIG with boxes
+ if ( Vec_IntSize(&p->vFfs2) > 0 )
+ {
+ curPo += nBitCos + nFf2Regs;
+ assert( curPi == Tim_ManCiNum(pManTime) );
+ assert( curPo == Tim_ManCoNum(pManTime) );
+ // finalize the extra AIG
+ pExtra = Gia_ManCleanup( pTemp = pExtra );
+ Gia_ManStop( pTemp );
+ assert( Gia_ManPoNum(pExtra) == Gia_ManCiNum(pNew) - nBitCis - nFf2Regs );
+ // attach
+ pNew->pAigExtra = pExtra;
+ pNew->pManTime = pManTime;
+ // normalize AIG
+ pNew = Gia_ManDupNormalize( pTemp = pNew, 0 );
+ Gia_ManTransferTiming( pNew, pTemp );
+ Gia_ManStop( pTemp );
+ //Tim_ManPrint( pManTime );
+ }
if ( pPar->vBoxIds )
{
curPo += nBitCos;
@@ -1622,7 +2085,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
// finalize the extra AIG
pExtra = Gia_ManCleanup( pTemp = pExtra );
Gia_ManStop( pTemp );
- assert( Gia_ManPoNum(pExtra) == Gia_ManCiNum(pNew) - nBitCis );
+ assert( Gia_ManPoNum(pExtra) == Gia_ManCiNum(pNew) - nBitCis - nFf2Regs );
// attach
pNew->pAigExtra = pExtra;
pNew->pManTime = pManTime;
@@ -1676,6 +2139,38 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
}
}
+ Wlc_NtkForEachFf2( p, pObj, i )
+ {
+ char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
+ nRange = Wlc_ObjRange( pObj );
+ if ( fSkipBitRange && nRange == 1 )
+ {
+ char Buffer[1000];
+ sprintf( Buffer, "%s_fo", pName );
+ Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
+ }
+ else
+ for ( k = 0; k < nRange; k++ )
+ {
+ char Buffer[1000];
+ sprintf( Buffer, "%s_fo[%d]", pName, k );
+ Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
+ }
+ }
+ Wlc_NtkForEachFf2( p, pObj, i )
+ {
+ char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
+ nRange = Wlc_ObjRange( pObj );
+ if ( fSkipBitRange && nRange == 1 )
+ Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
+ else
+ for ( k = 0; k < nRange; k++ )
+ {
+ char Buffer[1000];
+ sprintf( Buffer, "%s[%d]", pName, k );
+ Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
+ }
+ }
if ( p->pInits && fAdded )
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav("abc_reset_flop") );
if ( pPar->vBoxIds )
@@ -1696,6 +2191,43 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
assert( Vec_PtrSize(pNew->vNamesIn) == Gia_ManCiNum(pNew) );
// create output names
pNew->vNamesOut = Vec_PtrAlloc( Gia_ManCoNum(pNew) );
+ Wlc_NtkForEachFf2( p, pObj, i )
+ {
+ int iFanin;
+ Wlc_ObjForEachFanin( pObj, iFanin, b )
+ {
+ char * pName = Wlc_ObjName(p, iFanin);
+ nRange = Wlc_ObjRange( Wlc_NtkObj(p, iFanin) );
+ if ( fSkipBitRange && nRange == 1 )
+ Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
+ else
+ for ( k = 0; k < nRange; k++ )
+ {
+ char Buffer[1000];
+ sprintf( Buffer, "%s[%d]", pName, k );
+ Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
+ }
+ if ( b == 3 )
+ break;
+ }
+ {
+ char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
+ nRange = Wlc_ObjRange( pObj );
+ if ( fSkipBitRange && nRange == 1 )
+ {
+ char Buffer[1000];
+ sprintf( Buffer, "%s_in", pName );
+ Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
+ }
+ else
+ for ( k = 0; k < nRange; k++ )
+ {
+ char Buffer[1000];
+ sprintf( Buffer, "%s_in[%d]", pName, k );
+ Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
+ }
+ }
+ }
if ( pPar->vBoxIds )
{
Wlc_NtkForEachObjVec( pPar->vBoxIds, p, pObj, i )
@@ -1786,6 +2318,24 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
}
}
+ Wlc_NtkForEachFf2( p, pObj, i )
+ {
+ char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
+ nRange = Wlc_ObjRange( pObj );
+ if ( fSkipBitRange && nRange == 1 )
+ {
+ char Buffer[1000];
+ sprintf( Buffer, "%s_fi", pName );
+ Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
+ }
+ else
+ for ( k = 0; k < nRange; k++ )
+ {
+ char Buffer[1000];
+ sprintf( Buffer, "%s_fi[%d]", pName, k );
+ Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
+ }
+ }
assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) );
// replace the current library
@@ -1815,11 +2365,14 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn )
ABC_FREE( pNameGeneric );
printf( "Dumped two parts of the miter into files \"%s\" and \"%s\".\n", pFileName0, pFileName1 );
}
+ //Wlc_NtkPrintNameArray( pNew->vNamesIn );
+ //Wlc_NtkPrintNameArray( pNew->vNamesOut );
if ( pPar->vBoxIds )
{
- Vec_PtrFreeP( &pNew->vNamesIn );
- Vec_PtrFreeP( &pNew->vNamesOut );
+ Vec_PtrFreeFree( pNew->vNamesIn ); pNew->vNamesIn = NULL;
+ Vec_PtrFreeFree( pNew->vNamesOut ); pNew->vNamesOut = NULL;
}
+ pNew->vRegClasses = vRegClasses;
return pNew;
}
diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c
index 711763c7..5b99cb00 100644
--- a/src/base/wlc/wlcCom.c
+++ b/src/base/wlc/wlcCom.c
@@ -38,7 +38,9 @@ static int Abc_CommandPdrAbs ( Abc_Frame_t * pAbc, int argc, char ** argv )
static int Abc_CommandAbs2 ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMemAbs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandBlast ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandBlastMem ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandGraft ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRetime ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandProfile ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandShow ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -82,7 +84,9 @@ void Wlc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Word level", "%abs2", Abc_CommandAbs2, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%memabs", Abc_CommandMemAbs, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%blastmem", Abc_CommandBlastMem, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 );
+ Cmd_CommandAdd( pAbc, "Word level", "%retime", Abc_CommandRetime, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 );
Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 );
@@ -967,12 +971,12 @@ usage:
int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
- Gia_Man_t * pNew = NULL; int c;
+ Gia_Man_t * pNew = NULL; int c, fMiter = 0, fDumpNames = 0;
Wlc_BstPar_t Par, * pPar = &Par;
Wlc_BstParDefault( pPar );
pPar->nOutputRange = 2;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombdsvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombadstnvh" ) ) != EOF )
{
switch ( c )
{
@@ -1032,12 +1036,22 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'b':
pPar->fBooth ^= 1;
break;
+ case 'a':
+ pPar->fCla ^= 1;
+ break;
case 'd':
pPar->fCreateMiter ^= 1;
break;
case 's':
pPar->fDecMuxes ^= 1;
break;
+ case 't':
+ pPar->fCreateMiter ^= 1;
+ fMiter ^= 1;
+ break;
+ case 'n':
+ fDumpNames ^= 1;
+ break;
case 'v':
pPar->fVerbose ^= 1;
break;
@@ -1080,10 +1094,31 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( 1, "Abc_CommandBlast(): Bit-blasting has failed.\n" );
return 0;
}
+ // generate miter
+ if ( fMiter )
+ {
+ Gia_Man_t * pTemp = pNew;
+ pNew = Gia_ManTransformMiter( pNew );
+ Gia_ManStop( pTemp );
+ Abc_Print( 1, "Bit-blasting created a traditional multi-output miter by XORing POs pair-wise.\n" );
+ if ( fDumpNames )
+ {
+ int i; char * pName;
+ FILE * pFile = fopen( "pio_name_map.txt", "wb" );
+ if ( pNew->vNamesIn )
+ Vec_PtrForEachEntry( char *, pNew->vNamesIn, pName, i )
+ fprintf( pFile, "i%d %s\n", i, pName );
+ if ( pNew->vNamesOut )
+ Vec_PtrForEachEntry( char *, pNew->vNamesOut, pName, i )
+ fprintf( pFile, "o%d %s\n", i, pName );
+ fclose( pFile );
+ Abc_Print( 1, "Finished dumping file \"pio_name_map.txt\" containing PI/PO name mapping.\n" );
+ }
+ }
Abc_FrameUpdateGia( pAbc, pNew );
return 0;
usage:
- Abc_Print( -2, "usage: %%blast [-ORAM num] [-combdsvh]\n" );
+ Abc_Print( -2, "usage: %%blast [-ORAM num] [-combadstnvh]\n" );
Abc_Print( -2, "\t performs bit-blasting of the word-level design\n" );
Abc_Print( -2, "\t-O num : zero-based index of the first word-level PO to bit-blast [default = %d]\n", pPar->iOutput );
Abc_Print( -2, "\t-R num : the total number of word-level POs to bit-blast [default = %d]\n", pPar->nOutputRange );
@@ -1093,8 +1128,11 @@ usage:
Abc_Print( -2, "\t-o : toggle using additional POs on the word-level boundaries [default = %s]\n", pPar->fAddOutputs? "yes": "no" );
Abc_Print( -2, "\t-m : toggle creating boxes for all multipliers in the design [default = %s]\n", pPar->fMulti? "yes": "no" );
Abc_Print( -2, "\t-b : toggle generating radix-4 Booth multipliers [default = %s]\n", pPar->fBooth? "yes": "no" );
- Abc_Print( -2, "\t-d : toggle creating dual-output miter [default = %s]\n", pPar->fCreateMiter? "yes": "no" );
+ Abc_Print( -2, "\t-a : toggle generating carry-look-ahead adder [default = %s]\n", pPar->fCla? "yes": "no" );
+ Abc_Print( -2, "\t-d : toggle creating dual-output multi-output miter [default = %s]\n", pPar->fCreateMiter? "yes": "no" );
Abc_Print( -2, "\t-s : toggle creating decoded MUXes [default = %s]\n", pPar->fDecMuxes? "yes": "no" );
+ Abc_Print( -2, "\t-t : toggle creating regular multi-output miter [default = %s]\n", fMiter? "yes": "no" );
+ Abc_Print( -2, "\t-n : toggle dumping signal names into a text file [default = %s]\n", fDumpNames? "yes": "no" );
Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPar->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -1111,6 +1149,52 @@ usage:
SeeAlso []
******************************************************************************/
+int Abc_CommandBlastMem( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern Wlc_Ntk_t * Wlc_NtkMemBlast( Wlc_Ntk_t * p );
+ Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ Abc_Print( 1, "Abc_CommandBlastMem(): There is no current design.\n" );
+ return 0;
+ }
+ pNtk = Wlc_NtkMemBlast( pNtk );
+ Wlc_AbcUpdateNtk( pAbc, pNtk );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%blastmem [-vh]\n" );
+ Abc_Print( -2, "\t performs blasting of memory read/write ports\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
int Abc_CommandGraft( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern Wlc_Ntk_t * Wlc_NtkGraftMulti( Wlc_Ntk_t * p, int fVerbose );
@@ -1157,6 +1241,63 @@ usage:
SeeAlso []
******************************************************************************/
+int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Wln_NtkRetimeTest( char * pFileName );
+ FILE * pFile;
+ char * pFileName = NULL;
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
+ {
+ printf( "Abc_CommandRetime(): Input file name should be given on the command line.\n" );
+ return 0;
+ }
+ // get the file name
+ pFileName = argv[globalUtilOptind];
+ if ( (pFile = fopen( pFileName, "r" )) == NULL )
+ {
+ Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName );
+ if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".ndr", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", pFileName );
+ Abc_Print( 1, "\n" );
+ return 0;
+ }
+ fclose( pFile );
+ Wln_NtkRetimeTest( pFileName );
+ return 0;
+usage:
+ Abc_Print( -2, "usage: %%retime [-vh]\n" );
+ Abc_Print( -2, "\t performs retiming for the NDR design\n" );
+ Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
int Abc_CommandProfile( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc);
@@ -1672,7 +1813,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
//Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc );
//pNtk = Wlc_NtkDupSingleNodes( pNtk );
//Wlc_AbcUpdateNtk( pAbc, pNtk );
- Ndr_ModuleTestSelSel();
+ //Wln_ReadNdrTest();
//pNtk = Wlc_NtkMemAbstractTest( pNtk );
//Wlc_AbcUpdateNtk( pAbc, pNtk );
return 0;
diff --git a/src/base/wlc/wlcMem.c b/src/base/wlc/wlcMem.c
index b310afb6..ccc319e5 100644
--- a/src/base/wlc/wlcMem.c
+++ b/src/base/wlc/wlcMem.c
@@ -35,6 +35,133 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
+ Synopsis [Memory blasting.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wlc_NtkMemBlast_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins )
+{
+ Wlc_Obj_t * pObj;
+ int i, iFanin;
+ if ( Wlc_ObjCopy(p, iObj) )
+ return;
+ pObj = Wlc_NtkObj( p, iObj );
+ Wlc_ObjForEachFanin( pObj, iFanin, i )
+ Wlc_NtkMemBlast_rec( pNew, p, iFanin, vFanins );
+ if ( pObj->Type == WLC_OBJ_WRITE )
+ {
+ Vec_Int_t * vTemp = Vec_IntAlloc( 1 );
+ Vec_Int_t * vBits = Vec_IntAlloc( 100 );
+ Wlc_Obj_t * pMem = Wlc_ObjFanin0(p, pObj);
+ Wlc_Obj_t * pAddr = Wlc_ObjFanin1(p, pObj);
+ Wlc_Obj_t * pData = Wlc_ObjFanin2(p, pObj);
+ int DataW = Wlc_ObjRange(pData);
+ int AddrW = Wlc_ObjRange(pAddr);
+ int nRegs = 1 << AddrW, iObjNew, iObjDec;
+ assert( nRegs * DataW == Wlc_ObjRange(pMem) );
+ assert( Wlc_ObjRange(pObj) == Wlc_ObjRange(pMem) );
+ // create decoder
+ iObjDec = Wlc_ObjAlloc( pNew, WLC_OBJ_DEC, 0, nRegs-1, 0 );
+ Vec_IntFill( vTemp, 1, Wlc_ObjCopy(p, Wlc_ObjId(p, pAddr)) );
+ Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObjDec), vTemp );
+ // create decoder bits
+ for ( i = 0; i < nRegs; i++ )
+ {
+ int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_SELECT, 0, i, i );
+ Vec_IntFill( vTemp, 1, iObjDec );
+ Vec_IntPushTwo( vTemp, i, i );
+ Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp );
+ Vec_IntPush( vBits, iObj2 );
+ }
+ // create data words
+ Vec_IntClear( vFanins );
+ for ( i = 0; i < nRegs; i++ )
+ {
+ int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_SELECT, 0, i*DataW+DataW-1, i*DataW );
+ Vec_IntFill( vTemp, 1, Wlc_ObjCopy(p, Wlc_ObjId(p, pMem)) );
+ Vec_IntPushTwo( vTemp, i*DataW+DataW-1, i*DataW );
+ Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp );
+ Vec_IntPush( vFanins, iObj2 );
+ }
+ // create MUXes of data words controlled by decoder bits
+ for ( i = 0; i < nRegs; i++ )
+ {
+ int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_MUX, 0, DataW-1, 0 );
+ Vec_IntFill( vTemp, 1, Vec_IntEntry(vBits, i) );
+ Vec_IntPushTwo( vTemp, Wlc_ObjCopy(p, Wlc_ObjId(p, pData)), Vec_IntEntry(vFanins, i) );
+ Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp );
+ Vec_IntWriteEntry( vFanins, i, iObj2 );
+ }
+ // concatenate the results
+ iObjNew = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_CONCAT, 0, nRegs*DataW-1, 0 );
+ Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObjNew), vFanins );
+ Wlc_ObjSetCopy( p, iObj, iObjNew );
+ Vec_IntFree( vTemp );
+ Vec_IntFree( vBits );
+ }
+ else if ( pObj->Type == WLC_OBJ_READ )
+ {
+ Vec_Int_t * vTemp = Vec_IntAlloc( 1 );
+ Wlc_Obj_t * pMem = Wlc_ObjFanin0(p, pObj);
+ Wlc_Obj_t * pAddr = Wlc_ObjFanin1(p, pObj);
+ int DataW = Wlc_ObjRange(pObj);
+ int AddrW = Wlc_ObjRange(pAddr);
+ int nRegs = 1 << AddrW, iObjNew;
+ assert( nRegs * DataW == Wlc_ObjRange(pMem) );
+ Vec_IntClear( vFanins );
+ Vec_IntPush( vFanins, Wlc_ObjCopy(p, Wlc_ObjId(p, pAddr)) );
+ for ( i = 0; i < nRegs; i++ )
+ {
+ int iObj2 = Wlc_ObjAlloc( pNew, WLC_OBJ_BIT_SELECT, 0, i*DataW+DataW-1, i*DataW );
+ Vec_IntFill( vTemp, 1, Wlc_ObjCopy(p, Wlc_ObjId(p, pMem)) );
+ Vec_IntPushTwo( vTemp, i*DataW+DataW-1, i*DataW );
+ Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObj2), vTemp );
+ Vec_IntPush( vFanins, iObj2 );
+ }
+ iObjNew = Wlc_ObjAlloc( pNew, WLC_OBJ_MUX, 0, DataW-1, 0 );
+ Wlc_ObjAddFanins( pNew, Wlc_NtkObj(pNew, iObjNew), vFanins );
+ Wlc_ObjSetCopy( p, iObj, iObjNew );
+ Vec_IntFree( vTemp );
+ }
+ else
+ Wlc_ObjDup( pNew, p, iObj, vFanins );
+}
+Wlc_Ntk_t * Wlc_NtkMemBlast( Wlc_Ntk_t * p )
+{
+ Wlc_Ntk_t * pNew;
+ Wlc_Obj_t * pObj;
+ Vec_Int_t * vFanins;
+ int i;
+ Wlc_NtkCleanCopy( p );
+ vFanins = Vec_IntAlloc( 100 );
+ pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
+ pNew->fSmtLib = p->fSmtLib;
+ pNew->fMemPorts = p->fMemPorts;
+ pNew->fEasyFfs = p->fEasyFfs;
+ Wlc_NtkForEachCi( p, pObj, i )
+ Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ Wlc_NtkForEachCo( p, pObj, i )
+ Wlc_NtkMemBlast_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
+ Wlc_NtkForEachCo( p, pObj, i )
+ Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), pObj->fIsFi );
+ if ( p->vInits )
+ pNew->vInits = Vec_IntDup( p->vInits );
+ if ( p->pInits )
+ pNew->pInits = Abc_UtilStrsav( p->pInits );
+ Vec_IntFree( vFanins );
+ if ( p->pSpec )
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
Synopsis [Collect memory nodes.]
Description []
@@ -827,7 +954,7 @@ int Wlc_NtkMemAbstract( Wlc_Ntk_t * p, int nIterMax, int fDumpAbs, int fPdrVerbo
Vec_Wec_t * vRefines = Vec_WecAlloc( 100 );
Vec_Int_t * vNodeFrames = Vec_IntAlloc( 100 );
Vec_Int_t * vMemObjs, * vMemFanins, * vFirstTotal, * vRefine;
- int RetValue, iFirstMemPi, iFirstCi, iFirstMemCi, nDcBits, nIters;
+ int RetValue = -1, iFirstMemPi, iFirstCi, iFirstMemCi, nDcBits, nIters;
vMemObjs = Wlc_NtkCollectMemory( p );
vMemFanins = Wlc_NtkCollectMemFanins( p, vMemObjs );
diff --git a/src/base/wlc/wlcNdr.c b/src/base/wlc/wlcNdr.c
index 3e6600c3..16c7d778 100644
--- a/src/base/wlc/wlcNdr.c
+++ b/src/base/wlc/wlcNdr.c
@@ -71,6 +71,7 @@ int Ndr_TypeNdr2Wlc( int Type )
if ( Type == ABC_OPER_LOGIC_XOR ) return WLC_OBJ_LOGIC_XOR; // 30: logic XOR
if ( Type == ABC_OPER_SEL_NMUX ) return WLC_OBJ_MUX; // 08: multiplexer
if ( Type == ABC_OPER_SEL_SEL ) return WLC_OBJ_SEL; // 57: selector
+ if ( Type == ABC_OPER_SEL_DEC ) return WLC_OBJ_DEC; // 58: decoder
if ( Type == ABC_OPER_COMP_EQU ) return WLC_OBJ_COMP_EQU; // 31: compare equal
if ( Type == ABC_OPER_COMP_NOTEQU ) return WLC_OBJ_COMP_NOTEQU; // 32: compare not equal
if ( Type == ABC_OPER_COMP_LESS ) return WLC_OBJ_COMP_LESS; // 33: compare less
@@ -129,6 +130,7 @@ int Ndr_TypeWlc2Ndr( int Type )
if ( Type == WLC_OBJ_LOGIC_OR ) return ABC_OPER_LOGIC_OR; // 29: logic OR
if ( Type == WLC_OBJ_LOGIC_XOR ) return ABC_OPER_LOGIC_XOR; // 30: logic XOR
if ( Type == WLC_OBJ_SEL ) return ABC_OPER_SEL_SEL; // 57: selector
+ if ( Type == WLC_OBJ_DEC ) return ABC_OPER_SEL_DEC; // 58: decoder
if ( Type == WLC_OBJ_COMP_EQU ) return ABC_OPER_COMP_EQU; // 31: compare equal
if ( Type == WLC_OBJ_COMP_NOTEQU ) return ABC_OPER_COMP_NOTEQU; // 32: compare not equal
if ( Type == WLC_OBJ_COMP_LESS ) return ABC_OPER_COMP_LESS; // 33: compare less
@@ -342,9 +344,10 @@ void Wlc_NtkCheckIntegrity( void * pData )
}
Ndr_ModForEachObj( p, Mod, Obj )
{
+ int Type = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE );
int i, * pArray, nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
for ( i = 0; i < nArray; i++ )
- if ( Vec_IntGetEntry(vMap, pArray[i]) == 0 )
+ if ( Vec_IntGetEntry(vMap, pArray[i]) == 0 && !(Type == ABC_OPER_DFFRSE && (i >= 5 || i <= 7)) )
printf( "Input name %d appearing as fanin %d of obj %d is not used as output name in any object.\n", pArray[i], i, Obj );
}
Vec_IntFree( vMap );
@@ -396,6 +399,8 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
Vec_IntPush( &pNtk->vFfs, Vec_IntEntry(vFanins, 0) );
continue;
}
+ if ( Type == ABC_OPER_DFFRSE )
+ Vec_IntPush( &pNtk->vFfs2, iObj );
if ( Type == ABC_OPER_SLICE )
Vec_IntPushTwo( vFanins, End, Beg );
else if ( Type == ABC_OPER_CONST )
@@ -467,6 +472,7 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData )
assert( !fFound && i == NameId );
}
//Ndr_NtkPrintNodes( pNtk );
+ //Wlc_WriteVer( pNtk, "temp_ndr.v", 0, 0 );
// derive topological order
pNtk = Wlc_NtkDupDfs( pTemp = pNtk, 0, 1 );
Wlc_NtkFree( pTemp );
diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c
index b8a4b9b1..4ac0c66c 100644
--- a/src/base/wlc/wlcNtk.c
+++ b/src/base/wlc/wlcNtk.c
@@ -87,7 +87,10 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = {
"table", // 53: bit table
"READ", // 54: mem read port
"WRITE", // 55: mem write port
- NULL // 56: unused
+ "addsub", // 56: adder/subtractor
+ "sel", // 57: selector
+ "dec", // 58: decoder
+ NULL // 58: unused
};
char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; }
@@ -261,6 +264,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p )
ABC_FREE( p->vCis.pArray );
ABC_FREE( p->vCos.pArray );
ABC_FREE( p->vFfs.pArray );
+ ABC_FREE( p->vFfs2.pArray );
Vec_IntFreeP( &p->vInits );
ABC_FREE( p->vTravIds.pArray );
ABC_FREE( p->vNameIds.pArray );
@@ -283,6 +287,7 @@ int Wlc_NtkMemUsage( Wlc_Ntk_t * p )
Mem += 4 * p->vCis.nCap;
Mem += 4 * p->vCos.nCap;
Mem += 4 * p->vFfs.nCap;
+ Mem += 4 * p->vFfs2.nCap;
Mem += sizeof(Wlc_Obj_t) * p->nObjsAlloc;
Mem += Abc_NamMemUsed(p->pManName);
Mem += Mem_FlexReadMemUsage(p->pMemFanin);
@@ -637,6 +642,11 @@ void Wlc_NtkPrintNode( Wlc_Ntk_t * p, Wlc_Obj_t * pObj )
printf( "FO\n" );
return;
}
+ if ( pObj->Type != WLC_OBJ_CONST && Wlc_ObjFaninNum(pObj) == 0 )
+ {
+ printf( "Unknown object without fanins\n" );
+ return;
+ }
if ( pObj->Type != WLC_OBJ_CONST )
{
printf( "%6d%s %5s ", Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)), Wlc_ObjIsSigned(Wlc_ObjFanin0(p, pObj)) ? "s" : " ", Wlc_Names[(int)pObj->Type] );
@@ -858,10 +868,13 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v
{
Wlc_Obj_t * pObj;
int i, iFanin;
+ if ( iObj == 0 )
+ return;
if ( Wlc_ObjCopy(p, iObj) )
return;
//printf( "Visiting node %d\n", iObj );
pObj = Wlc_NtkObj( p, iObj );
+ assert( pObj->Type != WLC_OBJ_FF );
Wlc_ObjForEachFanin( pObj, iFanin, i )
Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins );
Wlc_ObjDup( pNew, p, iObj, vFanins );
@@ -898,9 +911,9 @@ Wlc_Ntk_t * Wlc_NtkDupDfsSimple( Wlc_Ntk_t * p )
Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq )
{
Wlc_Ntk_t * pNew;
- Wlc_Obj_t * pObj;
+ Wlc_Obj_t * pObj, * pObjNew;
Vec_Int_t * vFanins;
- int i;
+ int i, k, iObj, iFanin;
vFanins = Vec_IntAlloc( 100 );
Wlc_NtkCleanCopy( p );
pNew = Wlc_NtkAlloc( p->pName, p->nObjsAlloc );
@@ -915,12 +928,28 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p, int fMarked, int fSeq )
Wlc_ObjDup( pNew, p, Wlc_ObjId(p, pObj), vFanins );
pObj->Type = Type;
}
+ Wlc_NtkForEachFf2( p, pObj, i )
+ {
+ int iObjNew = Wlc_ObjAlloc( pNew, pObj->Type, Wlc_ObjIsSigned(pObj), pObj->End, pObj->Beg );
+ Wlc_ObjSetCopy( p, Wlc_ObjId(p, pObj), iObjNew );
+ Vec_IntPush( &pNew->vFfs2, iObjNew );
+ }
Wlc_NtkForEachCo( p, pObj, i )
if ( !fMarked || pObj->Mark )
Wlc_NtkDupDfs_rec( pNew, p, Wlc_ObjId(p, pObj), vFanins );
Wlc_NtkForEachCo( p, pObj, i )
if ( !fMarked || pObj->Mark )
Wlc_ObjSetCo( pNew, Wlc_ObjCopyObj(pNew, p, pObj), fSeq ? pObj->fIsFi : 0 );
+ Wlc_NtkForEachFf2( p, pObj, i )
+ {
+ iObj = Wlc_ObjId(p, pObj);
+ Wlc_ObjForEachFanin( pObj, iFanin, k )
+ Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins );
+ Wlc_ObjCollectCopyFanins( p, iObj, vFanins );
+ pObjNew = Wlc_NtkObj( pNew, Wlc_ObjCopy(p, iObj) );
+ Wlc_ObjAddFanins( pNew, pObjNew, vFanins );
+ pObjNew->fXConst = pObj->fXConst;
+ }
Vec_IntFree( vFanins );
if ( fSeq )
{
diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c
index 9974dd44..34966777 100644
--- a/src/base/wlc/wlcReadVer.c
+++ b/src/base/wlc/wlcReadVer.c
@@ -1277,7 +1277,7 @@ startword:
}
else if ( Wlc_PrsStrCmp( pStart, "ABC_DFFRSE" ) )
{
- int NameId[8], fFound, nBits = 1, fFlopIn, fFlopOut, fFlopClk, fFlopRst, fFlopSet, fFlopEna, fFlopAsync, fFlopInit;
+ int NameId[10] = {0}, fFound, fFlopIn, fFlopClk, fFlopRst, fFlopSet, fFlopEna, fFlopAsync, fFlopSre, fFlopInit, fFlopOut;
pStart += strlen("ABC_DFF");
while ( 1 )
{
@@ -1286,13 +1286,14 @@ startword:
break;
pStart = Wlc_PrsSkipSpaces( pStart+1 );
fFlopIn = (pStart[0] == 'd');
- fFlopOut = (pStart[0] == 'q');
fFlopClk = (pStart[0] == 'c');
fFlopRst = (pStart[0] == 'r');
- fFlopSet = (pStart[0] == 's');
+ fFlopSet = (pStart[0] == 's' && pStart[1] == 'e');
fFlopEna = (pStart[0] == 'e');
fFlopAsync = (pStart[0] == 'a');
+ fFlopSre = (pStart[0] == 's' && pStart[1] == 'r');
fFlopInit = (pStart[0] == 'i');
+ fFlopOut = (pStart[0] == 'q');
pStart = Wlc_PrsFindSymbol( pStart, '(' );
if ( pStart == NULL )
return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." );
@@ -1301,8 +1302,6 @@ startword:
return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." );
if ( fFlopIn )
NameId[0] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
- else if ( fFlopOut )
- NameId[7] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
else if ( fFlopClk )
NameId[1] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
else if ( fFlopRst )
@@ -1313,8 +1312,12 @@ startword:
NameId[4] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
else if ( fFlopAsync )
NameId[5] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
- else if ( fFlopInit )
+ else if ( fFlopSre )
NameId[6] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
+ else if ( fFlopInit )
+ NameId[7] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
+ else if ( fFlopOut )
+ NameId[8] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
else
assert( 0 );
if ( !fFound )
@@ -1323,7 +1326,7 @@ startword:
if ( NameId[0] == -1 || NameId[7] == -1 )
return Wlc_PrsWriteErrorMessage( p, pStart, "Name of flop input or flop output is missing." );
// create output
- pObj = Wlc_NtkObj( p->pNtk, NameId[7] );
+ pObj = Wlc_NtkObj( p->pNtk, NameId[8] );
Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_FF );
Vec_IntClear( p->vFanins );
Vec_IntPush( p->vFanins, NameId[0] );
@@ -1333,6 +1336,7 @@ startword:
Vec_IntPush( p->vFanins, NameId[4] );
Vec_IntPush( p->vFanins, NameId[5] );
Vec_IntPush( p->vFanins, NameId[6] );
+ Vec_IntPush( p->vFanins, NameId[7] );
Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
}
else if ( Wlc_PrsStrCmp( pStart, "ABC_DFF" ) )
@@ -1571,6 +1575,10 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr )
// derive topological order
if ( p->pNtk )
{
+ Wlc_Obj_t * pObj; int i;
+ Wlc_NtkForEachObj( p->pNtk, pObj, i )
+ if ( pObj->Type == WLC_OBJ_FF )
+ Vec_IntPush( &p->pNtk->vFfs2, Wlc_ObjId(p->pNtk, pObj) );
pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 );
pNtk->pSpec = Abc_UtilStrsav( pFileName );
}
diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c
index dbf24e68..30f10e14 100644
--- a/src/base/wlc/wlcWriteVer.c
+++ b/src/base/wlc/wlcWriteVer.c
@@ -192,7 +192,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
continue;
fprintf( pFile, " assign " );
}
- else if ( (pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3) || pObj->Type == WLC_OBJ_FF )
+ else if ( (pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3) || pObj->Type == WLC_OBJ_SEL )
fprintf( pFile, "reg %s ", Range );
else
fprintf( pFile, "wire %s ", Range );
@@ -275,12 +275,62 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
fprintf( pFile, " : %s = ", Wlc_ObjName(p, i) );
fprintf( pFile, "%s ;\n", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, k)) );
}
+ fprintf( pFile, " " );
+ fprintf( pFile, "default" );
+ fprintf( pFile, " : %s = ", Wlc_ObjName(p, i) );
+ fprintf( pFile, "%d\'b", Wlc_ObjRange(pObj) );
+ for ( j = Wlc_ObjRange(pObj)-1; j >= 0; j-- )
+ fprintf( pFile, "%d", 0 );
+ fprintf( pFile, " ;\n" );
fprintf( pFile, " " );
fprintf( pFile, "endcase\n" );
fprintf( pFile, " " );
fprintf( pFile, "end\n" );
continue;
}
+ else if ( pObj->Type == WLC_OBJ_DEC )
+ {
+ int nRange = Wlc_ObjRange(Wlc_ObjFanin0(p, pObj));
+ assert( (1 << nRange) == Wlc_ObjRange(pObj) );
+ fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) );
+ for ( k = 0; k < Wlc_ObjRange(pObj); k++ )
+ {
+ fprintf( pFile, " " );
+ fprintf( pFile, "wire " );
+ fprintf( pFile, "%s_", Wlc_ObjName(p, i) );
+ for ( j = 0; j < nRange; j++ )
+ fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 );
+ fprintf( pFile, " = " );
+ for ( j = 0; j < nRange; j++ )
+ fprintf( pFile, "%s%s%s[%d]",
+ j ? " & ":"", ((k >> (nRange-1-j)) & 1) ? " ":"~",
+ Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 0)), nRange-1-j );
+ fprintf( pFile, " ;\n" );
+ }
+ fprintf( pFile, " " );
+ fprintf( pFile, "assign %s = { ", Wlc_ObjName(p, i) );
+ for ( k = Wlc_ObjRange(pObj)-1; k >= 0; k-- )
+ {
+ fprintf( pFile, "%s%s_", k < Wlc_ObjRange(pObj)-1 ? ", ":"", Wlc_ObjName(p, i) );
+ for ( j = 0; j < nRange; j++ )
+ fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 );
+ }
+ fprintf( pFile, " } ;\n" );
+ continue;
+ }
+ else if ( pObj->Type == WLC_OBJ_ARI_ADDSUB )
+ {
+ // out = mode ? a+b+cin : a-b-cin
+ fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) );
+ fprintf( pFile, " " );
+ fprintf( pFile, "assign " );
+ fprintf( pFile, "%s = %s ? %s + %s + %s : %s - %s - %s ;\n",
+ Wlc_ObjName(p, i), Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)),
+ Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)), Wlc_ObjName(p, Wlc_ObjFaninId(pObj,3)), Wlc_ObjName(p, Wlc_ObjFaninId1(pObj)),
+ Wlc_ObjName(p, Wlc_ObjFaninId2(pObj)), Wlc_ObjName(p, Wlc_ObjFaninId(pObj,3)), Wlc_ObjName(p, Wlc_ObjFaninId1(pObj))
+ );
+ continue;
+ }
else if ( pObj->Type == WLC_OBJ_READ || pObj->Type == WLC_OBJ_WRITE )
{
if ( p->fMemPorts )
@@ -311,13 +361,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
}
else if ( pObj->Type == WLC_OBJ_FF )
{
- char * pInNames[8] = {"d", "clk", "reset", "set", "enable", "async", "sre", "init"};
fprintf( pFile, "%s ;\n", Wlc_ObjName(p, i) );
- fprintf( pFile, " " );
- fprintf( pFile, "%s (", "ABC_DFFRSE" );
- Wlc_ObjForEachFanin( pObj, iFanin, k )
- fprintf( pFile, " .%s(%s),", pInNames[k], Wlc_ObjName(p, iFanin) );
- fprintf( pFile, " .%s(%s) ) ;\n", "q", Wlc_ObjName(p, i) );
continue;
}
else
@@ -425,7 +469,8 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
fprintf( pFile, "#" );
else
{
- assert( 0 );
+ //assert( 0 );
+ printf( "Failed to write node \"%s\" with unknown operator type (%d).\n", Wlc_ObjName(p, i), pObj->Type );
fprintf( pFile, "???\n" );
continue;
}
@@ -510,6 +555,18 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p, int fNoFlops )
}
assert( !p->vInits || iFanin == (int)strlen(p->pInits) );
}
+ // write DFFs in the end
+ fprintf( pFile, "\n" );
+ Wlc_NtkForEachFf2( p, pObj, i )
+ {
+ char * pInNames[8] = {"d", "clk", "reset", "set", "enable", "async", "sre", "init"};
+ fprintf( pFile, " " );
+ fprintf( pFile, "%s (", "ABC_DFFRSE" );
+ Wlc_ObjForEachFanin( pObj, iFanin, k )
+ if ( iFanin ) fprintf( pFile, " .%s(%s),", pInNames[k], Wlc_ObjName(p, iFanin) );
+ fprintf( pFile, " .%s(%s) ) ;\n", "q", Wlc_ObjName(p, Wlc_ObjId(p, pObj)) );
+ }
+ fprintf( pFile, "\n" );
fprintf( pFile, "endmodule\n\n" );
}
void Wlc_WriteVer( Wlc_Ntk_t * p, char * pFileName, int fAddCos, int fNoFlops )
diff --git a/src/base/wln/module.make b/src/base/wln/module.make
new file mode 100644
index 00000000..6689baf0
--- /dev/null
+++ b/src/base/wln/module.make
@@ -0,0 +1,6 @@
+SRC += src/base/wln/wln.c \
+ src/base/wln/wlnNdr.c \
+ src/base/wln/wlnNtk.c \
+ src/base/wln/wlnObj.c \
+ src/base/wln/wlnRetime.c \
+ src/base/wln/wlnWriteVer.c
diff --git a/src/base/wln/wln.c b/src/base/wln/wln.c
new file mode 100644
index 00000000..2fbe26e0
--- /dev/null
+++ b/src/base/wln/wln.c
@@ -0,0 +1,51 @@
+/**CFile****************************************************************
+
+ FileName [wln.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wln.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wln.h b/src/base/wln/wln.h
new file mode 100644
index 00000000..c862b262
--- /dev/null
+++ b/src/base/wln/wln.h
@@ -0,0 +1,259 @@
+/**CFile****************************************************************
+
+ FileName [wlc.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Verilog parser.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - August 22, 2014.]
+
+ Revision [$Id: wlc.h,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__base__wln__wln_h
+#define ABC__base__wln__wln_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "aig/gia/gia.h"
+#include "misc/vec/vecHash.h"
+#include "misc/extra/extra.h"
+#include "misc/util/utilNam.h"
+#include "misc/util/utilTruth.h"
+#include "aig/miniaig/abcOper.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Wln_Vec_t_ Wln_Vec_t;
+struct Wln_Vec_t_
+{
+ int nCap;
+ int nSize;
+ union { int Array[2];
+ int * pArray[1]; };
+};
+
+typedef struct Wln_Ntk_t_ Wln_Ntk_t;
+struct Wln_Ntk_t_
+{
+ char * pName; // model name
+ char * pSpec; // input file name
+ int fSmtLib; // derived from SMT-LIB
+ Vec_Int_t vCis; // combinational inputs
+ Vec_Int_t vCos; // combinational outputs
+ Vec_Int_t vFfs; // flops
+ Vec_Int_t vTypes; // object types
+ Wln_Vec_t * vFanins; // object fanins (exceptions: const, select)
+ Vec_Int_t vRanges; // object ranges
+ Hash_IntMan_t * pRanges; // object ranges
+ Vec_Int_t vNameIds; // object name IDs
+ Vec_Int_t vInstIds; // object name IDs
+ Abc_Nam_t * pManName; // object names
+ Vec_Str_t vSigns; // object signedness
+ int nTravIds; // counter of traversal IDs
+ Vec_Int_t vTravIds; // trav IDs of the objects
+ Vec_Int_t vCopies; // object first bits
+ Vec_Int_t vBits; // object mapping into AIG nodes
+ Vec_Int_t vLevels; // object levels
+ Vec_Int_t vRefs; // object reference counters
+ Vec_Int_t vFanout; // static fanout
+ Vec_Int_t vFaninAttrs; // static fanin attributes
+ Vec_Int_t vFaninLists; // static fanin attributes
+ Vec_Ptr_t * vTables; // tables
+ int nObjs[ABC_OPER_LAST]; // counter of objects of each type
+ int nAnds[ABC_OPER_LAST]; // counter of AND gates after blasting
+};
+
+static inline int Wln_NtkObjNum( Wln_Ntk_t * p ) { return Vec_IntSize(&p->vTypes); }
+static inline int Wln_NtkCiNum( Wln_Ntk_t * p ) { return Vec_IntSize(&p->vCis); }
+static inline int Wln_NtkCoNum( Wln_Ntk_t * p ) { return Vec_IntSize(&p->vCos); }
+static inline int Wln_NtkFfNum( Wln_Ntk_t * p ) { return Vec_IntSize(&p->vFfs); }
+static inline int Wln_NtkPiNum( Wln_Ntk_t * p ) { return Wln_NtkCiNum(p) - Wln_NtkFfNum(p); }
+static inline int Wln_NtkPoNum( Wln_Ntk_t * p ) { return Wln_NtkCoNum(p) - Wln_NtkFfNum(p); }
+
+static inline int Wln_NtkCi( Wln_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vCis, i); }
+static inline int Wln_NtkCo( Wln_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vCos, i); }
+static inline int Wln_NtkFf( Wln_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vFfs, i); }
+
+static inline int Wln_ObjType( Wln_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vTypes, i); }
+static inline int Wln_ObjIsNone( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_NONE; }
+static inline int Wln_ObjIsCi( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_CI; }
+static inline int Wln_ObjIsCo( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_CO; }
+static inline int Wln_ObjIsCio( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_CI || Wln_ObjType(p, i)==ABC_OPER_CO; }
+static inline int Wln_ObjIsFon( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_FON; }
+static inline int Wln_ObjIsFf( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_DFFRSE; }
+static inline int Wln_ObjIsConst( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_CONST; }
+static inline int Wln_ObjIsSlice( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_SLICE; }
+static inline int Wln_ObjIsRotate( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_SHIFT_ROTL || Wln_ObjType(p, i) == ABC_OPER_SHIFT_ROTR; }
+static inline int Wln_ObjIsTable( Wln_Ntk_t * p, int i ) { return Wln_ObjType(p, i) == ABC_OPER_TABLE; }
+
+static inline int Wln_ObjFaninNum( Wln_Ntk_t * p, int i ) { return p->vFanins[i].nSize; }
+static inline int * Wln_ObjFanins( Wln_Ntk_t * p, int i ) { return Wln_ObjFaninNum(p, i) > 2 ? p->vFanins[i].pArray[0] : p->vFanins[i].Array; }
+static inline int Wln_ObjFanin( Wln_Ntk_t * p, int i, int f ) { return Wln_ObjFaninNum(p, i) > 2 ? p->vFanins[i].pArray[0][f] : p->vFanins[i].Array[f]; }
+static inline void Wln_ObjSetFanin( Wln_Ntk_t * p, int i, int f, int v ) { Wln_ObjFanins( p, i )[f] = v; }
+static inline int Wln_ObjFanin0( Wln_Ntk_t * p, int i ) { return Wln_ObjFanin( p, i, 0 ); }
+static inline int Wln_ObjFanin1( Wln_Ntk_t * p, int i ) { return Wln_ObjFanin( p, i, 1 ); }
+static inline int Wln_ObjFanin2( Wln_Ntk_t * p, int i ) { return Wln_ObjFanin( p, i, 2 ); }
+
+static inline int Wln_ObjRangeId( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vRanges, i ); }
+static inline int Wln_ObjRangeEnd( Wln_Ntk_t * p, int i ) { return Hash_IntObjData0( p->pRanges, Wln_ObjRangeId(p, i) ); }
+static inline int Wln_ObjRangeBeg( Wln_Ntk_t * p, int i ) { return Hash_IntObjData1( p->pRanges, Wln_ObjRangeId(p, i) ); }
+static inline int Wln_ObjRangeIsReversed( Wln_Ntk_t * p, int i ) { return Wln_ObjRangeEnd(p, i) < Wln_ObjRangeBeg(p, i); }
+static inline int Wln_ObjRange( Wln_Ntk_t * p, int i ) { return 1 + Abc_AbsInt(Wln_ObjRangeEnd(p, i)-Wln_ObjRangeBeg(p, i)); }
+
+static inline int Wln_ObjIsSigned( Wln_Ntk_t * p, int i ) { return (int)Vec_StrEntry(&p->vSigns, i); }
+static inline void Wln_ObjSetSigned( Wln_Ntk_t * p, int i ) { Vec_StrSetEntry(&p->vSigns, i, (char)1); }
+static inline int Wln_ObjIsSignedFanin0( Wln_Ntk_t * p, int i ) { return Wln_ObjIsSigned( p, p->fSmtLib ? i : Wln_ObjFanin0(p, i) ); }
+static inline int Wln_ObjIsSignedFanin1( Wln_Ntk_t * p, int i ) { return Wln_ObjIsSigned( p, p->fSmtLib ? i : Wln_ObjFanin1(p, i) ); }
+static inline int Wln_ObjIsSignedFanin01( Wln_Ntk_t * p, int i ) { return Wln_ObjIsSignedFanin0( p, i ) && Wln_ObjIsSignedFanin1( p, i ); }
+static inline int Wln_ObjSign( Wln_Ntk_t * p, int i ) { return Abc_Var2Lit( Wln_ObjRange(p, i), Wln_ObjIsSigned(p, i) ); }
+
+static inline void Wln_NtkCleanCopy( Wln_Ntk_t * p ) { Vec_IntFill( &p->vCopies, Vec_IntCap(&p->vTypes), 0 ); }
+static inline int Wln_NtkHasCopy( Wln_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 0; }
+static inline void Wln_ObjSetCopy( Wln_Ntk_t * p, int i, int c ) { Vec_IntWriteEntry( &p->vCopies, i, c ); }
+static inline int Wln_ObjCopy( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vCopies, i ); }
+
+static inline void Wln_NtkCleanLevel( Wln_Ntk_t * p ) { Vec_IntFill( &p->vLevels, Vec_IntCap(&p->vTypes), 0 ); }
+static inline int Wln_NtkHasLevel( Wln_Ntk_t * p ) { return Vec_IntSize( &p->vLevels ) > 0; }
+static inline void Wln_ObjSetLevel( Wln_Ntk_t * p, int i, int l ) { Vec_IntWriteEntry( &p->vLevels, i, l ); }
+static inline int Wln_ObjLevel( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vLevels, i ); }
+
+static inline void Wln_NtkCleanNameId( Wln_Ntk_t * p ) { Vec_IntFill( &p->vNameIds, Vec_IntCap(&p->vTypes), 0 ); }
+static inline int Wln_NtkHasNameId( Wln_Ntk_t * p ) { return Vec_IntSize( &p->vNameIds ) > 0; }
+static inline void Wln_ObjSetNameId( Wln_Ntk_t * p, int i, int n ) { Vec_IntWriteEntry( &p->vNameIds, i, n ); }
+static inline int Wln_ObjNameId( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vNameIds, i ); }
+
+static inline void Wln_NtkCleanInstId( Wln_Ntk_t * p ) { Vec_IntFill( &p->vInstIds, Vec_IntCap(&p->vTypes), 0 ); }
+static inline int Wln_NtkHasInstId( Wln_Ntk_t * p ) { return Vec_IntSize( &p->vInstIds ) > 0; }
+static inline void Wln_ObjSetInstId( Wln_Ntk_t * p, int i, int n ) { Vec_IntWriteEntry( &p->vInstIds, i, n ); }
+static inline int Wln_ObjInstId( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vInstIds, i ); }
+
+static inline void Wln_NtkCleanRefs( Wln_Ntk_t * p ) { Vec_IntFill( &p->vRefs, Vec_IntCap(&p->vTypes), 0 ); }
+static inline int Wln_NtkHasRefs( Wln_Ntk_t * p ) { return Vec_IntSize( &p->vRefs ) > 0; }
+static inline void Wln_ObjSetRefs( Wln_Ntk_t * p, int i, int n ) { Vec_IntWriteEntry( &p->vRefs, i, n ); }
+static inline int Wln_ObjRefs( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vRefs, i ); }
+static inline int Wln_ObjRefsInc( Wln_Ntk_t * p, int i ) { return (*Vec_IntEntryP( &p->vRefs, i ))++; }
+static inline int Wln_ObjRefsDec( Wln_Ntk_t * p, int i ) { return --(*Vec_IntEntryP( &p->vRefs, i )); }
+static inline void Wln_ObjRefsFaninInc( Wln_Ntk_t * p, int i, int k ) { Wln_ObjRefsInc( p, Wln_ObjFanin(p, i, k) ); }
+static inline void Wln_ObjRefsFaninDec( Wln_Ntk_t * p, int i, int k ) { Wln_ObjRefsDec( p, Wln_ObjFanin(p, i, k) ); }
+
+static inline int Wln_ObjFanoutNum( Wln_Ntk_t * p, int i ) { return Vec_IntEntry( &p->vRefs, i ); }
+static inline int * Wln_ObjFanouts( Wln_Ntk_t * p, int i ) { return Vec_IntEntryP( &p->vFanout, Vec_IntEntry(&p->vFanout, i) ); }
+static inline int Wln_ObjFanout( Wln_Ntk_t * p, int i, int f ) { return Wln_ObjFanouts( p, i )[f]; }
+static inline void Wln_ObjSetFanout( Wln_Ntk_t * p, int i, int f, int v ){ Wln_ObjFanouts( p, i )[f] = v; }
+
+static inline void Wln_NtkIncrementTravId( Wln_Ntk_t * p ) { if (!p->nTravIds++) Vec_IntFill(&p->vTravIds, Vec_IntCap(&p->vTypes), 0); }
+static inline void Wln_ObjSetTravIdCurrent( Wln_Ntk_t * p, int i ) { Vec_IntWriteEntry( &p->vTravIds, i, p->nTravIds ); }
+static inline int Wln_ObjIsTravIdCurrent( Wln_Ntk_t * p, int i ) { return (Vec_IntEntry(&p->vTravIds, i) == p->nTravIds); }
+static inline int Wln_ObjIsTravIdPrevious( Wln_Ntk_t * p, int i ) { return (Vec_IntEntry(&p->vTravIds, i) == p->nTravIds-1); }
+static inline int Wln_ObjCheckTravId( Wln_Ntk_t * p, int i ) { if ( Wln_ObjIsTravIdCurrent(p, i) ) return 1; Wln_ObjSetTravIdCurrent(p, i); return 0; }
+
+static inline int Wln_ObjCioId( Wln_Ntk_t * p, int i ) { assert( Wln_ObjIsCio(p, i) ); return Wln_ObjFanin1(p, i); }
+static inline int Wln_ObjIsPi( Wln_Ntk_t * p, int i ) { return Wln_ObjIsCi(p, i) && Wln_ObjCioId(p, i) < Wln_NtkPiNum(p); }
+static inline int Wln_ObjIsPo( Wln_Ntk_t * p, int i ) { return Wln_ObjIsCo(p, i) && Wln_ObjCioId(p, i) < Wln_NtkPoNum(p); }
+static inline int Wln_ObjIsRo( Wln_Ntk_t * p, int i ) { return Wln_ObjIsCi(p, i) && Wln_ObjCioId(p, i) >= Wln_NtkPiNum(p); }
+static inline int Wln_ObjIsRi( Wln_Ntk_t * p, int i ) { return Wln_ObjIsCo(p, i) && Wln_ObjCioId(p, i) >= Wln_NtkPoNum(p); }
+static inline int Wln_ObjRoToRi( Wln_Ntk_t * p, int i ) { assert( Wln_ObjIsRo(p, i) ); return Wln_NtkCo(p, Wln_NtkCoNum(p) - Wln_NtkCiNum(p) + Wln_ObjCioId(p, i)); }
+static inline int Wln_ObjRiToRo( Wln_Ntk_t * p, int i ) { assert( Wln_ObjIsRi(p, i) ); return Wln_NtkCi(p, Wln_NtkCiNum(p) - Wln_NtkCoNum(p) + Wln_ObjCioId(p, i)); }
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// ITERATORS ///
+////////////////////////////////////////////////////////////////////////
+
+#define Wln_NtkForEachObj( p, i ) \
+ for ( i = 1; i < Wln_NtkObjNum(p); i++ )
+#define Wln_NtkForEachObjReverse( p, i ) \
+ for ( i = Wln_NtkObjNum(p) - 1; i > 0; i-- )
+#define Wln_NtkForEachObjInternal( p, i ) \
+ for ( i = 1; i < Wln_NtkObjNum(p); i++ ) if ( Wln_ObjIsCio(p, i) ) {} else
+
+#define Wln_NtkForEachPi( p, iPi, i ) \
+ for ( i = 0; (i < Wln_NtkPiNum(p)) && (((iPi) = Wln_NtkCi(p, i)), 1); i++ )
+#define Wln_NtkForEachPo( p, iPo, i ) \
+ for ( i = 0; (i < Wln_NtkPoNum(p)) && (((iPo) = Wln_NtkCo(p, i)), 1); i++ )
+#define Wln_NtkForEachCi( p, iCi, i ) \
+ for ( i = 0; (i < Wln_NtkCiNum(p)) && (((iCi) = Wln_NtkCi(p, i)), 1); i++ )
+#define Wln_NtkForEachCo( p, iCo, i ) \
+ for ( i = 0; (i < Wln_NtkCoNum(p)) && (((iCo) = Wln_NtkCo(p, i)), 1); i++ )
+#define Wln_NtkForEachFf( p, iFf, i ) \
+ for ( i = 0; (i < Wln_NtkFfNum(p)) && (((iFf) = Wln_NtkFf(p, i)), 1); i++ )
+
+#define Wln_ObjForEachFanin( p, iObj, iFanin, i ) \
+ for ( i = 0; (i < Wln_ObjFaninNum(p, iObj)) && (((iFanin) = Wln_ObjFanin(p, iObj, i)), 1); i++ ) if ( !iFanin ) {} else
+#define Wln_ObjForEachFaninReverse( pObj, iFanin, i ) \
+ for ( i = Wln_ObjFaninNum(p, iObj) - 1; (i >= 0) && (((iFanin) = Wln_ObjFanin(p, iObj, i)), 1); i-- ) if ( !iFanin ) {} else
+
+#define Wln_ObjForEachFanoutStatic( p, iObj, iFanout, i ) \
+ for ( i = 0; (i < Wln_ObjRefs(p, iObj)) && (((iFanout) = Wln_ObjFanout(p, iObj, i)), 1); i++ )
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== wlcNdr.c ========================================================*/
+extern Wln_Ntk_t * Wln_ReadNdr( char * pFileName );
+extern void Wln_WriteNdr( Wln_Ntk_t * pNtk, char * pFileName );
+extern Wln_Ntk_t * Wln_NtkFromNdr( void * pData );
+extern void * Wln_NtkToNdr( Wln_Ntk_t * pNtk );
+/*=== wlcNtk.c ========================================================*/
+extern Wln_Ntk_t * Wln_NtkAlloc( char * pName, int nObjsMax );
+extern void Wln_NtkFree( Wln_Ntk_t * p );
+extern int Wln_NtkMemUsage( Wln_Ntk_t * p );
+extern void Wln_NtkPrint( Wln_Ntk_t * p );
+extern Wln_Ntk_t * Wln_NtkDupDfs( Wln_Ntk_t * p );
+extern void Wln_NtkCreateRefs( Wln_Ntk_t * p );
+extern void Wln_NtkStartFaninMap( Wln_Ntk_t * p, Vec_Int_t * vFaninMap, int nMulti );
+extern void Wln_NtkStartFanoutMap( Wln_Ntk_t * p, Vec_Int_t * vFanoutMap, Vec_Int_t * vFanoutNums, int nMulti );
+extern void Wln_NtkStaticFanoutStart( Wln_Ntk_t * p );
+extern void Wln_NtkStaticFanoutStop( Wln_Ntk_t * p );
+extern void Wln_NtkStaticFanoutTest( Wln_Ntk_t * p );
+/*=== wlcObj.c ========================================================*/
+extern char * Wln_ObjName( Wln_Ntk_t * p, int iObj );
+extern char * Wln_ObjConstString( Wln_Ntk_t * p, int iObj );
+extern void Wln_ObjUpdateType( Wln_Ntk_t * p, int iObj, int Type );
+extern void Wln_ObjSetConst( Wln_Ntk_t * p, int iObj, int NameId );
+extern void Wln_ObjSetSlice( Wln_Ntk_t * p, int iObj, int SliceId );
+extern void Wln_ObjAddFanin( Wln_Ntk_t * p, int iObj, int i );
+extern int Wln_ObjAddFanins( Wln_Ntk_t * p, int iObj, Vec_Int_t * vFanins );
+extern int Wln_ObjAlloc( Wln_Ntk_t * p, int Type, int Signed, int End, int Beg );
+extern int Wln_ObjClone( Wln_Ntk_t * pNew, Wln_Ntk_t * p, int iObj );
+extern int Wln_ObjCreateCo( Wln_Ntk_t * p, int iFanin );
+extern void Wln_ObjPrint( Wln_Ntk_t * p, int iObj );
+/*=== wlcRetime.c ========================================================*/
+extern Vec_Int_t * Wln_NtkRetime( Wln_Ntk_t * p );
+/*=== wlcWriteVer.c ========================================================*/
+extern void Wln_WriteVer( Wln_Ntk_t * p, char * pFileName );
+
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/base/wln/wlnNdr.c b/src/base/wln/wlnNdr.c
new file mode 100644
index 00000000..c87100a2
--- /dev/null
+++ b/src/base/wln/wlnNdr.c
@@ -0,0 +1,332 @@
+/**CFile****************************************************************
+
+ FileName [wlnNdr.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis [Constructing WLN network from NDR data structure.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnNdr.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+#include "aig/miniaig/ndr.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Wln_NtkToNdr( Wln_Ntk_t * p )
+{
+ Vec_Int_t * vFanins;
+ int i, k, iObj, iFanin;
+ // create a new module
+ void * pDesign = Ndr_Create( 1 );
+ int ModId = Ndr_AddModule( pDesign, 1 );
+ // add primary inputs
+ Wln_NtkForEachPi( p, iObj, i )
+ {
+ Ndr_AddObject( pDesign, ModId, ABC_OPER_CI, 0,
+ Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj), Wln_ObjIsSigned(p, iObj),
+ 0, NULL, 1, &iObj, NULL ); // no fanins
+ }
+ // add internal nodes
+ vFanins = Vec_IntAlloc( 10 );
+ Wln_NtkForEachObjInternal( p, iObj )
+ {
+ Vec_IntClear( vFanins );
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ Vec_IntPush( vFanins, iFanin );
+ Ndr_AddObject( pDesign, ModId, Wln_ObjType(p, iObj), 0,
+ Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj), Wln_ObjIsSigned(p, iObj),
+ Vec_IntSize(vFanins), Vec_IntArray(vFanins), 1, &iObj,
+ Wln_ObjIsConst(p, iObj) ? Wln_ObjConstString(p, iObj) : NULL );
+ }
+ Vec_IntFree( vFanins );
+ // add primary outputs
+ Wln_NtkForEachPo( p, iObj, i )
+ {
+ Ndr_AddObject( pDesign, ModId, ABC_OPER_CO, 0,
+ Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj), Wln_ObjIsSigned(p, iObj),
+ 1, &iObj, 0, NULL, NULL );
+ }
+ return pDesign;
+}
+void Wln_WriteNdr( Wln_Ntk_t * p, char * pFileName )
+{
+ void * pDesign = Wln_NtkToNdr( p );
+ Ndr_Write( pFileName, pDesign );
+ Ndr_Delete( pDesign );
+ printf( "Dumped the current design into file \"%s\".\n", pFileName );
+}
+void Wln_NtkToNdrTest( Wln_Ntk_t * p )
+{
+ // transform
+ void * pDesign = Wln_NtkToNdr( p );
+
+ // collect names
+ char ** ppNames = ABC_ALLOC( char *, Wln_NtkObjNum(p) + 1 ); int i;
+ Wln_NtkForEachObj( p, i )
+ ppNames[i] = Abc_UtilStrsav(Wln_ObjName(p, i));
+
+ // verify by writing Verilog
+ Ndr_WriteVerilog( NULL, pDesign, ppNames );
+ Ndr_Write( "test.ndr", pDesign );
+
+ // cleanup
+ Ndr_Delete( pDesign );
+ Wln_NtkForEachObj( p, i )
+ ABC_FREE( ppNames[i] );
+ ABC_FREE( ppNames );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ndr_ObjGetRange( Ndr_Data_t * p, int Obj, int * End, int * Beg )
+{
+ int * pArray, nArray = Ndr_ObjReadArray( p, Obj, NDR_RANGE, &pArray );
+ int Signed = 0; *End = *Beg = 0;
+ if ( nArray == 0 )
+ return 0;
+ if ( nArray == 3 )
+ Signed = 1;
+ if ( nArray == 1 )
+ *End = *Beg = pArray[0];
+ else
+ *End = pArray[0], *Beg = pArray[1];
+ return Signed;
+}
+void Ndr_NtkPrintObjects( Wln_Ntk_t * pNtk )
+{
+ int k, iObj, iFanin;
+ printf( "Node IDs and their fanins:\n" );
+ Wln_NtkForEachObj( pNtk, iObj )
+ {
+ printf( "%5d = ", iObj );
+ Wln_ObjForEachFanin( pNtk, iObj, iFanin, k )
+ printf( "%5d ", iFanin );
+ for ( ; k < 4; k++ )
+ printf( " " );
+ printf( " Name Id %d ", Wln_ObjNameId(pNtk, iObj) );
+ if ( Wln_ObjIsPi(pNtk, iObj) )
+ printf( " pi " );
+ if ( Wln_ObjIsPo(pNtk, iObj) )
+ printf( " po " );
+ printf( "\n" );
+ }
+}
+void Wln_NtkCheckIntegrity( void * pData )
+{
+ Ndr_Data_t * p = (Ndr_Data_t *)pData;
+ Vec_Int_t * vMap = Vec_IntAlloc( 100 );
+ int Mod = 2, Obj;
+ Ndr_ModForEachObj( p, Mod, Obj )
+ {
+ int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT );
+ if ( NameId == -1 )
+ {
+ int Type = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE );
+ if ( Type != ABC_OPER_CO )
+ printf( "Internal object %d of type %s has no output name.\n", Obj, Abc_OperName(Type) );
+ continue;
+ }
+ if ( Vec_IntGetEntry(vMap, NameId) > 0 )
+ printf( "Output name %d is used more than once (obj %d and obj %d).\n", NameId, Vec_IntGetEntry(vMap, NameId), Obj );
+ Vec_IntSetEntry( vMap, NameId, Obj );
+ }
+ Ndr_ModForEachObj( p, Mod, Obj )
+ {
+ int Type = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE );
+ int i, * pArray, nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
+ for ( i = 0; i < nArray; i++ )
+ if ( Vec_IntGetEntry(vMap, pArray[i]) == 0 && !(Type == ABC_OPER_DFFRSE && (i >= 5 || i <= 7)) )
+ printf( "Input name %d appearing as fanin %d of obj %d is not used as output name in any object.\n", pArray[i], i, Obj );
+ }
+ Vec_IntFree( vMap );
+}
+Wln_Ntk_t * Wln_NtkFromNdr( void * pData )
+{
+ Ndr_Data_t * p = (Ndr_Data_t *)pData;
+ Vec_Int_t * vName2Obj, * vFanins = Vec_IntAlloc( 100 );
+ Vec_Ptr_t * vConstStrings = Vec_PtrAlloc( 100 );
+ int Mod = 2, i, k, iFanin, iObj, Obj, * pArray, nDigits, fFound, NameId, NameIdMax;
+ Wln_Ntk_t * pTemp, * pNtk = Wln_NtkAlloc( "top", Ndr_DataObjNum(p, Mod) );
+ Wln_NtkCheckIntegrity( pData );
+ //pNtk->pSpec = Abc_UtilStrsav( pFileName );
+ // construct network and save name IDs
+ Wln_NtkCleanNameId( pNtk );
+ Wln_NtkCleanInstId( pNtk );
+ Ndr_ModForEachPi( p, Mod, Obj )
+ {
+ int End, Beg, Signed = Ndr_ObjGetRange(p, Obj, &End, &Beg);
+ int iObj = Wln_ObjAlloc( pNtk, ABC_OPER_CI, Signed, End, Beg );
+ int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT );
+ int InstId = Ndr_ObjReadBody( p, Obj, NDR_NAME );
+ Wln_ObjSetNameId( pNtk, iObj, NameId );
+ if ( InstId > 0 ) Wln_ObjSetInstId( pNtk, iObj, InstId );
+ }
+ Ndr_ModForEachNode( p, Mod, Obj )
+ {
+ int End, Beg, Signed = Ndr_ObjGetRange(p, Obj, &End, &Beg);
+ int Type = Ndr_ObjReadBody( p, Obj, NDR_OPERTYPE );
+ int nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
+ Vec_Int_t F = {nArray, nArray, pArray}, * vTemp = &F;
+ int iObj = Wln_ObjAlloc( pNtk, Type, Signed, End, Beg );
+ int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT );
+ int InstId = Ndr_ObjReadBody( p, Obj, NDR_NAME );
+ Vec_IntClear( vFanins );
+ Vec_IntAppend( vFanins, vTemp );
+ assert( Type != ABC_OPER_DFF );
+ if ( Wln_ObjIsSlice(pNtk, iObj) )
+ Wln_ObjSetSlice( pNtk, iObj, Hash_Int2ManInsert(pNtk->pRanges, End, Beg, 0) );
+ else if ( Wln_ObjIsConst(pNtk, iObj) )
+ Vec_PtrPush( vConstStrings, (char *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION) );
+// else if ( Type == ABC_OPER_BIT_MUX && Vec_IntSize(vFanins) == 3 )
+// ABC_SWAP( int, Wln_ObjFanins(pNtk, iObj)[1], Wln_ObjFanins(pNtk, iObj)[2] );
+ Wln_ObjAddFanins( pNtk, iObj, vFanins );
+ Wln_ObjSetNameId( pNtk, iObj, NameId );
+ if ( InstId > 0 ) Wln_ObjSetInstId( pNtk, iObj, InstId );
+ if ( Type == ABC_OPER_ARI_SMUL )
+ {
+ assert( Wln_ObjFaninNum(pNtk, iObj) == 2 );
+ Wln_ObjSetSigned( pNtk, Wln_ObjFanin0(pNtk, iObj) );
+ Wln_ObjSetSigned( pNtk, Wln_ObjFanin1(pNtk, iObj) );
+ }
+ }
+ // mark primary outputs
+ Ndr_ModForEachPo( p, Mod, Obj )
+ {
+ int End, Beg, Signed = Ndr_ObjGetRange(p, Obj, &End, &Beg);
+ int nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray );
+ int iObj = Wln_ObjAlloc( pNtk, ABC_OPER_CO, Signed, End, Beg );
+ int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT );
+ int InstId = Ndr_ObjReadBody( p, Obj, NDR_NAME );
+ assert( nArray == 1 && NameId == -1 && InstId == -1 );
+ Wln_ObjAddFanin( pNtk, iObj, pArray[0] );
+ }
+ Vec_IntFree( vFanins );
+ // remove instance names if they are not given
+ //Vec_IntPrint( &pNtk->vInstIds );
+ if ( Vec_IntCountPositive(&pNtk->vInstIds) == 0 )
+ Vec_IntErase( &pNtk->vInstIds );
+ // map name IDs into object IDs
+ vName2Obj = Vec_IntInvert( &pNtk->vNameIds, 0 );
+ Wln_NtkForEachObj( pNtk, i )
+ Wln_ObjForEachFanin( pNtk, i, iFanin, k )
+ Wln_ObjSetFanin( pNtk, i, k, Vec_IntEntry(vName2Obj, iFanin) );
+ Vec_IntFree(vName2Obj);
+ // create fake object names
+ NameIdMax = Vec_IntFindMax(&pNtk->vNameIds);
+ nDigits = Abc_Base10Log( NameIdMax+1 );
+ pNtk->pManName = Abc_NamStart( NameIdMax+1, 10 );
+ for ( i = 1; i <= NameIdMax; i++ )
+ {
+ char pName[20]; sprintf( pName, "s%0*d", nDigits, i );
+ NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound );
+ assert( !fFound && i == NameId );
+ }
+ // add const strings
+ i = 0;
+ Wln_NtkForEachObj( pNtk, iObj )
+ if ( Wln_ObjIsConst(pNtk, iObj) )
+ Wln_ObjSetConst( pNtk, iObj, Abc_NamStrFindOrAdd(pNtk->pManName, (char *)Vec_PtrEntry(vConstStrings, i++), NULL) );
+ assert( i == Vec_PtrSize(vConstStrings) );
+ Vec_PtrFree( vConstStrings );
+ //Ndr_NtkPrintObjects( pNtk );
+ //Wln_WriteVer( pNtk, "temp_ndr.v", 0, 0 );
+ // derive topological order
+ pNtk = Wln_NtkDupDfs( pTemp = pNtk );
+ Wln_NtkFree( pTemp );
+ //Ndr_NtkPrintObjects( pNtk );
+ //pNtk->fMemPorts = 1; // the network contains memory ports
+ //pNtk->fEasyFfs = 1; // the network contains simple flops
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Wln_Ntk_t * Wln_ReadNdr( char * pFileName )
+{
+ void * pData = Ndr_Read( pFileName );
+ Wln_Ntk_t * pNtk = Wln_NtkFromNdr( pData );
+ //char * ppNames[10] = { NULL, "a", "b", "c", "d", "e", "f", "g", "h", "i" };
+ //Ndr_WriteVerilog( NULL, pData, ppNames );
+ Ndr_Delete( pData );
+ return pNtk;
+}
+void Wln_ReadNdrTest()
+{
+ Wln_Ntk_t * pNtk = Wln_ReadNdr( "D:\\temp\\brijesh\\for_alan_dff_warning\\work_fir_filter_fir_filter_proc_out.ndr" );
+ //Wln_Ntk_t * pNtk = Wln_ReadNdr( "flop.ndr" );
+ Wln_WriteVer( pNtk, "test__test.v" );
+ Wln_NtkPrint( pNtk );
+ Wln_NtkStaticFanoutTest( pNtk );
+ Wln_NtkFree( pNtk );
+}
+void Wln_NtkRetimeTest( char * pFileName )
+{
+ void * pData = Ndr_Read( pFileName );
+ Wln_Ntk_t * pNtk = Wln_NtkFromNdr( pData );
+ Ndr_Delete( pData );
+ if ( !Wln_NtkHasInstId(pNtk) )
+ printf( "The design has no delay information.\n" );
+ else
+ {
+ Vec_Int_t * vMoves = Wln_NtkRetime( pNtk );
+ Vec_IntPrint( vMoves );
+ Vec_IntFree( vMoves );
+ }
+ Wln_NtkFree( pNtk );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnNtk.c b/src/base/wln/wlnNtk.c
new file mode 100644
index 00000000..39c03964
--- /dev/null
+++ b/src/base/wln/wlnNtk.c
@@ -0,0 +1,321 @@
+/**CFile****************************************************************
+
+ FileName [wlnNtk.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis [Network construction procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnNtk.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creating networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Wln_Ntk_t * Wln_NtkAlloc( char * pName, int nObjsMax )
+{
+ Wln_Ntk_t * p; int i;
+ p = ABC_CALLOC( Wln_Ntk_t, 1 );
+ p->pName = pName ? Extra_FileNameGeneric( pName ) : NULL;
+ Vec_IntGrow( &p->vCis, 111 );
+ Vec_IntGrow( &p->vCos, 111 );
+ Vec_IntGrow( &p->vFfs, 111 );
+ Vec_IntGrow( &p->vTypes, nObjsMax+1 );
+ Vec_StrGrow( &p->vSigns, nObjsMax+1 );
+ Vec_IntGrow( &p->vRanges, nObjsMax+1 );
+ Vec_IntPush( &p->vTypes, -1 );
+ Vec_StrPush( &p->vSigns, -1 );
+ Vec_IntPush( &p->vRanges, -1 );
+ p->vFanins = ABC_CALLOC( Wln_Vec_t, nObjsMax+1 );
+ p->pRanges = Hash_IntManStart( 1000 );
+ for ( i = 0; i < 65; i++ )
+ Hash_Int2ManInsert( p->pRanges, i, i, 0 );
+ for ( i = 1; i < 64; i++ )
+ Hash_Int2ManInsert( p->pRanges, i, 0, 0 );
+ assert( Hash_IntManEntryNum(p->pRanges) == 128 );
+ return p;
+}
+void Wln_NtkFree( Wln_Ntk_t * p )
+{
+ int i;
+ for ( i = 0; i < Wln_NtkObjNum(p); i++ )
+ if ( Wln_ObjFaninNum(p, i) > 2 )
+ ABC_FREE( p->vFanins[i].pArray[0] );
+ ABC_FREE( p->vFanins );
+
+ if ( p->pRanges ) Hash_IntManStop( p->pRanges );
+ if ( p->pManName ) Abc_NamStop( p->pManName );
+
+ ABC_FREE( p->vCis.pArray );
+ ABC_FREE( p->vCos.pArray );
+ ABC_FREE( p->vFfs.pArray );
+
+ ABC_FREE( p->vTypes.pArray );
+ ABC_FREE( p->vSigns.pArray );
+ ABC_FREE( p->vRanges.pArray );
+ ABC_FREE( p->vNameIds.pArray );
+ ABC_FREE( p->vInstIds.pArray );
+ ABC_FREE( p->vTravIds.pArray );
+ ABC_FREE( p->vCopies.pArray );
+ ABC_FREE( p->vBits.pArray );
+ ABC_FREE( p->vLevels.pArray );
+ ABC_FREE( p->vRefs.pArray );
+ ABC_FREE( p->vFanout.pArray );
+ ABC_FREE( p->vFaninAttrs.pArray );
+ ABC_FREE( p->vFaninLists.pArray );
+
+ ABC_FREE( p->pName );
+ ABC_FREE( p->pSpec );
+ ABC_FREE( p );
+}
+int Wln_NtkMemUsage( Wln_Ntk_t * p )
+{
+ int Mem = sizeof(Wln_Ntk_t);
+ Mem += 4 * p->vCis.nCap;
+ Mem += 4 * p->vCos.nCap;
+ Mem += 4 * p->vFfs.nCap;
+ Mem += 1 * p->vTypes.nCap;
+ Mem += 4 * p->vRanges.nCap;
+ Mem += 4 * p->vNameIds.nCap;
+ Mem += 4 * p->vInstIds.nCap;
+ Mem += 4 * p->vTravIds.nCap;
+ Mem += 4 * p->vCopies.nCap;
+ Mem += 4 * p->vBits.nCap;
+ Mem += 4 * p->vLevels.nCap;
+ Mem += 4 * p->vRefs.nCap;
+ Mem += 4 * p->vFanout.nCap;
+ Mem += 4 * p->vFaninAttrs.nCap;
+ Mem += 4 * p->vFaninLists.nCap;
+ Mem += 20 * Hash_IntManEntryNum(p->pRanges);
+ Mem += Abc_NamMemUsed(p->pManName);
+ return Mem;
+}
+void Wln_NtkPrint( Wln_Ntk_t * p )
+{
+ int iObj;
+ printf( "Printing %d objects of network \"%s\":\n", Wln_NtkObjNum(p), p->pName );
+ Wln_NtkForEachObj( p, iObj )
+ Wln_ObjPrint( p, iObj );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicating network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_NtkTransferNames( Wln_Ntk_t * pNew, Wln_Ntk_t * p )
+{
+ assert( pNew->pManName == NULL && p->pManName != NULL );
+ pNew->pManName = p->pManName;
+ p->pManName = NULL;
+ assert( !Wln_NtkHasCopy(pNew) && Wln_NtkHasCopy(p) );
+ if ( Wln_NtkHasNameId(p) )
+ {
+ int i;
+ assert( !Wln_NtkHasNameId(pNew) && Wln_NtkHasNameId(p) );
+ Wln_NtkCleanNameId( pNew );
+ Wln_NtkForEachObj( p, i )
+ if ( Wln_ObjCopy(p, i) && i < Vec_IntSize(&p->vNameIds) && Wln_ObjNameId(p, i) )
+ Wln_ObjSetNameId( pNew, Wln_ObjCopy(p, i), Wln_ObjNameId(p, i) );
+ Vec_IntErase( &p->vNameIds );
+ }
+ if ( Wln_NtkHasInstId(p) )
+ {
+ int i;
+ assert( !Wln_NtkHasInstId(pNew) && Wln_NtkHasInstId(p) );
+ Wln_NtkCleanInstId( pNew );
+ Wln_NtkForEachObj( p, i )
+ if ( Wln_ObjCopy(p, i) && i < Vec_IntSize(&p->vInstIds) && Wln_ObjInstId(p, i) )
+ Wln_ObjSetInstId( pNew, Wln_ObjCopy(p, i), Wln_ObjInstId(p, i) );
+ Vec_IntErase( &p->vInstIds );
+ }
+}
+int Wln_ObjDup( Wln_Ntk_t * pNew, Wln_Ntk_t * p, int iObj )
+{
+ int i, iFanin, iObjNew = Wln_ObjClone( pNew, p, iObj );
+ Wln_ObjForEachFanin( p, iObj, iFanin, i )
+ Wln_ObjAddFanin( pNew, iObjNew, Wln_ObjCopy(p, iFanin) );
+ if ( Wln_ObjIsConst(p, iObj) )
+ Wln_ObjSetConst( pNew, iObjNew, Wln_ObjFanin0(p, iObj) );
+ else if ( Wln_ObjIsSlice(p, iObj) || Wln_ObjIsRotate(p, iObj) || Wln_ObjIsTable(p, iObj) )
+ Wln_ObjSetFanin( p, iObjNew, 1, Wln_ObjFanin1(p, iObj) );
+ Wln_ObjSetCopy( p, iObj, iObjNew );
+ return iObjNew;
+}
+int Wln_NtkDupDfs_rec( Wln_Ntk_t * pNew, Wln_Ntk_t * p, int iObj )
+{
+ int i, iFanin;
+ if ( iObj == 0 )
+ return 0;
+ if ( Wln_ObjCopy(p, iObj) )
+ return Wln_ObjCopy(p, iObj);
+ //printf( "Visiting node %d\n", iObj );
+ assert( !Wln_ObjIsFf(p, iObj) );
+ Wln_ObjForEachFanin( p, iObj, iFanin, i )
+ Wln_NtkDupDfs_rec( pNew, p, iFanin );
+ return Wln_ObjDup( pNew, p, iObj );
+}
+Wln_Ntk_t * Wln_NtkDupDfs( Wln_Ntk_t * p )
+{
+ int i, k, iObj, iFanin;
+ Wln_Ntk_t * pNew = Wln_NtkAlloc( p->pName, Wln_NtkObjNum(p) );
+ pNew->fSmtLib = p->fSmtLib;
+ if ( p->pSpec ) pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Wln_NtkCleanCopy( p );
+ Wln_NtkForEachCi( p, iObj, i )
+ Wln_ObjDup( pNew, p, iObj );
+ Wln_NtkForEachFf( p, iObj, i )
+ Wln_ObjSetCopy( p, iObj, Wln_ObjClone(pNew, p, iObj) );
+ Wln_NtkForEachCo( p, iObj, i )
+ Wln_NtkDupDfs_rec( pNew, p, iObj );
+ Wln_NtkForEachFf( p, iObj, i )
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ Wln_ObjAddFanin( pNew, Wln_ObjCopy(p, iObj), Wln_NtkDupDfs_rec(pNew, p, iFanin) );
+ if ( Wln_NtkHasNameId(p) )
+ Wln_NtkTransferNames( pNew, p );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create fanin/fanout map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_NtkCreateRefs( Wln_Ntk_t * p )
+{
+ int k, iObj, iFanin;
+ Wln_NtkCleanRefs( p );
+ Wln_NtkForEachObj( p, iObj )
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ Wln_ObjRefsInc( p, iFanin );
+}
+int Wln_NtkFaninNum( Wln_Ntk_t * p )
+{
+ int iObj, nEdges = 0;
+ Wln_NtkForEachObj( p, iObj )
+ nEdges += Wln_ObjFaninNum(p, iObj);
+ return nEdges;
+}
+void Wln_NtkStartFaninMap( Wln_Ntk_t * p, Vec_Int_t * vFaninMap, int nMulti )
+{
+ int iObj, iOffset = Wln_NtkObjNum(p);
+ Vec_IntFill( vFaninMap, iOffset + nMulti * Wln_NtkFaninNum(p), 0 );
+ Wln_NtkForEachObj( p, iObj )
+ {
+ Vec_IntWriteEntry( vFaninMap, iObj, iOffset );
+ iOffset += nMulti * Wln_ObjFaninNum(p, iObj);
+ }
+ assert( iOffset == Vec_IntSize(vFaninMap) );
+}
+void Wln_NtkStartFanoutMap( Wln_Ntk_t * p, Vec_Int_t * vFanoutMap, Vec_Int_t * vFanoutNums, int nMulti )
+{
+ int iObj, iOffset = Wln_NtkObjNum(p);
+ Vec_IntFill( vFanoutMap, iOffset + nMulti * Vec_IntSum(vFanoutNums), 0 );
+ Wln_NtkForEachObj( p, iObj )
+ {
+ Vec_IntWriteEntry( vFanoutMap, iObj, iOffset );
+ iOffset += nMulti * Wln_ObjRefs(p, iObj);
+ }
+ assert( iOffset == Vec_IntSize(vFanoutMap) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Static fanout.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_NtkStaticFanoutStart( Wln_Ntk_t * p )
+{
+ int k, iObj, iFanin;
+ Vec_Int_t * vRefsCopy = Vec_IntAlloc(0);
+ Wln_NtkCreateRefs( p );
+ Wln_NtkStartFanoutMap( p, &p->vFanout, &p->vRefs, 1 );
+ ABC_SWAP( Vec_Int_t, *vRefsCopy, p->vRefs );
+ // add fanouts
+ Wln_NtkCleanRefs( p );
+ Wln_NtkForEachObj( p, iObj )
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ Wln_ObjSetFanout( p, iFanin, Wln_ObjRefsInc(p, iFanin), iObj );
+ // double-check the current number of fanouts added
+ Wln_NtkForEachObj( p, iObj )
+ assert( Wln_ObjRefs(p, iObj) == Vec_IntEntry(vRefsCopy, iObj) );
+ Vec_IntFree( vRefsCopy );
+}
+void Wln_NtkStaticFanoutStop( Wln_Ntk_t * p )
+{
+ Vec_IntErase( &p->vRefs );
+ Vec_IntErase( &p->vFanout );
+}
+void Wln_NtkStaticFanoutTest( Wln_Ntk_t * p )
+{
+ int k, iObj, iFanout;
+ printf( "Printing fanouts of %d objects of network \"%s\":\n", Wln_NtkObjNum(p), p->pName );
+ Wln_NtkStaticFanoutStart( p );
+ Wln_NtkForEachObj( p, iObj )
+ {
+ Wln_ObjPrint( p, iObj );
+ printf( " Fanouts : " );
+ Wln_ObjForEachFanoutStatic( p, iObj, iFanout, k )
+ printf( "%5d ", iFanout );
+ printf( "\n" );
+ }
+ Wln_NtkStaticFanoutStop( p );
+ printf( "\n" );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnObj.c b/src/base/wln/wlnObj.c
new file mode 100644
index 00000000..ec373304
--- /dev/null
+++ b/src/base/wln/wlnObj.c
@@ -0,0 +1,151 @@
+/**CFile****************************************************************
+
+ FileName [wlnObj.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis [Object construction procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnObj.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creating objects.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Wln_ObjName( Wln_Ntk_t * p, int iObj )
+{
+ static char Buffer[100];
+ if ( Wln_NtkHasNameId(p) && Wln_ObjNameId(p, iObj) )
+ return Abc_NamStr( p->pManName, Wln_ObjNameId(p, iObj) );
+ sprintf( Buffer, "n%d", iObj );
+ return Buffer;
+}
+char * Wln_ObjConstString( Wln_Ntk_t * p, int iObj )
+{
+ assert( Wln_ObjIsConst(p, iObj) );
+ return Abc_NamStr( p->pManName, Wln_ObjFanin0(p, iObj) );
+}
+void Wln_ObjUpdateType( Wln_Ntk_t * p, int iObj, int Type )
+{
+ assert( Wln_ObjIsNone(p, iObj) );
+ p->nObjs[Wln_ObjType(p, iObj)]--;
+ Vec_IntWriteEntry( &p->vTypes, iObj, Type );
+ p->nObjs[Wln_ObjType(p, iObj)]++;
+}
+void Wln_ObjSetConst( Wln_Ntk_t * p, int iObj, int NameId )
+{
+ assert( Wln_ObjIsConst(p, iObj) );
+ Wln_ObjSetFanin( p, iObj, 0, NameId );
+}
+void Wln_ObjSetSlice( Wln_Ntk_t * p, int iObj, int SliceId )
+{
+ assert( Wln_ObjIsSlice(p, iObj) );
+ Wln_ObjSetFanin( p, iObj, 1, SliceId );
+}
+void Wln_ObjAddFanin( Wln_Ntk_t * p, int iObj, int i )
+{
+ Wln_Vec_t * pVec = p->vFanins + iObj;
+ if ( Wln_ObjFaninNum(p, iObj) < 2 )
+ pVec->Array[pVec->nSize++] = i;
+ else if ( Wln_ObjFaninNum(p, iObj) == 2 )
+ {
+ int * pArray = ABC_ALLOC( int, 4 );
+ pArray[0] = pVec->Array[0];
+ pArray[1] = pVec->Array[1];
+ pArray[2] = i;
+ pVec->pArray[0] = pArray;
+ pVec->nSize = 3;
+ pVec->nCap = 4;
+ }
+ else
+ {
+ if ( pVec->nSize == pVec->nCap )
+ pVec->pArray[0] = ABC_REALLOC( int, pVec->pArray[0], (pVec->nCap = 2*pVec->nSize) );
+ assert( pVec->nSize < pVec->nCap );
+ pVec->pArray[0][pVec->nSize++] = i;
+ }
+}
+int Wln_ObjAddFanins( Wln_Ntk_t * p, int iObj, Vec_Int_t * vFanins )
+{
+ int i, iFanin;
+ Vec_IntForEachEntry( vFanins, iFanin, i )
+ Wln_ObjAddFanin( p, iObj, iFanin );
+ return iObj;
+}
+int Wln_ObjAlloc( Wln_Ntk_t * p, int Type, int Signed, int End, int Beg )
+{
+ int iObj = Vec_IntSize(&p->vTypes);
+ if ( iObj == Vec_IntCap(&p->vTypes) )
+ {
+ p->vFanins = ABC_REALLOC( Wln_Vec_t, p->vFanins, 2 * iObj );
+ memset( p->vFanins + iObj, 0, sizeof(Wln_Vec_t) * iObj );
+ Vec_IntGrow( &p->vTypes, 2 * iObj );
+ }
+ assert( iObj == Vec_StrSize(&p->vSigns) );
+ assert( iObj == Vec_IntSize(&p->vRanges) );
+ Vec_IntPush( &p->vTypes, Type );
+ Vec_StrPush( &p->vSigns, (char)Signed );
+ Vec_IntPush( &p->vRanges, Hash_Int2ManInsert(p->pRanges, End, Beg, 0) );
+ if ( Wln_ObjIsCi(p, iObj) ) Wln_ObjSetFanin( p, iObj, 1, Vec_IntSize(&p->vCis) ), Vec_IntPush( &p->vCis, iObj );
+ if ( Wln_ObjIsCo(p, iObj) ) Wln_ObjSetFanin( p, iObj, 1, Vec_IntSize(&p->vCos) ), Vec_IntPush( &p->vCos, iObj );
+ if ( Wln_ObjIsFf(p, iObj) ) Vec_IntPush( &p->vFfs, iObj );
+ p->nObjs[Type]++;
+ return iObj;
+}
+int Wln_ObjClone( Wln_Ntk_t * pNew, Wln_Ntk_t * p, int iObj )
+{
+ return Wln_ObjAlloc( pNew, Wln_ObjType(p, iObj), Wln_ObjIsSigned(p, iObj), Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj) );
+}
+int Wln_ObjCreateCo( Wln_Ntk_t * p, int iFanin )
+{
+ int iCo = Wln_ObjClone( p, p, iFanin );
+ Wln_ObjUpdateType( p, iCo, ABC_OPER_CO );
+ Wln_ObjAddFanin( p, iCo, iFanin );
+ return iCo;
+}
+void Wln_ObjPrint( Wln_Ntk_t * p, int iObj )
+{
+ int k, iFanin, Type = Wln_ObjType(p, iObj);
+ printf( "Obj %6d : Type = %6s Fanins = %d : ", iObj, Abc_OperName(Type), Wln_ObjFaninNum(p, iObj) );
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ printf( "%5d ", iFanin );
+ printf( "\n" );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnRetime.c b/src/base/wln/wlnRetime.c
new file mode 100644
index 00000000..459af2d9
--- /dev/null
+++ b/src/base/wln/wlnRetime.c
@@ -0,0 +1,487 @@
+/**CFile****************************************************************
+
+ FileName [wlnRetime.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis [Retiming.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnRetime.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+#include "misc/vec/vecHsh.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Wln_Ret_t_ Wln_Ret_t;
+struct Wln_Ret_t_
+{
+ Wln_Ntk_t * pNtk; // static netlist
+ Vec_Int_t vFanins; // fanins and edge places
+ Vec_Int_t vFanouts; // fanouts and edge places
+ Vec_Int_t vEdgeLinks; // edge links
+ Vec_Int_t vFfClasses; // flop classes
+ Vec_Int_t vNodeDelays; // object delays
+ Vec_Int_t vPathDelays; // delays from sources to sinks
+ Vec_Int_t vSources; // critical sources
+ Vec_Int_t vSinks; // critical sinks
+ Vec_Int_t vFront; // retiming frontier
+ Vec_Int_t vMoves; // retiming moves (paired with delay)
+ int nClasses; // the number of flop classes
+ int DelayMax; // critical delay at any time
+};
+
+static inline int * Wln_RetFanins( Wln_Ret_t * p, int i ) { return Vec_IntEntryP( &p->vFanins, Vec_IntEntry(&p->vFanins, i) ); }
+static inline int * Wln_RetFanouts( Wln_Ret_t * p, int i ) { return Vec_IntEntryP( &p->vFanouts, Vec_IntEntry(&p->vFanouts, i) ); }
+
+#define Wln_RetForEachFanin( p, iObj, iFanin, pLink, i ) \
+ for ( i = 0; (i < Wln_ObjFaninNum(p->pNtk, iObj)) && \
+ (((iFanin) = Wln_RetFanins(p, iObj)[2*i]), 1) && \
+ ((pLink) = (Wln_RetFanins(p, iObj)+2*i+1)); i++ ) if ( !iFanin ) {} else
+
+#define Wln_RetForEachFanout( p, iObj, iFanout, pLink, i ) \
+ for ( i = 0; (i < Wln_ObjRefs(p->pNtk, iObj)) && \
+ (((iFanout) = Wln_RetFanouts(p, iObj)[2*i]), 1) && \
+ ((pLink) = Vec_IntEntryP(&p->vFanins, Wln_RetFanouts(p, iObj)[2*i+1])); i++ ) if ( !iFanout ) {} else
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Retiming manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wln_RetComputeFfClasses( Wln_Ntk_t * pNtk, Vec_Int_t * vClasses )
+{
+ int i, k, iObj, nClasses;
+ Hsh_VecMan_t * p = Hsh_VecManStart( 10 );
+ Vec_Int_t * vFlop = Vec_IntAlloc( 6 );
+ Vec_IntFill( vClasses, Wln_NtkObjNum(pNtk), -1 );
+ Wln_NtkForEachFf( pNtk, iObj, i )
+ {
+ Vec_IntClear( vFlop );
+ for ( k = 1; k <= 6; k++ )
+ Vec_IntPush( vFlop, Wln_ObjFanin(pNtk, iObj, k) );
+ Vec_IntWriteEntry( vClasses, iObj, Hsh_VecManAdd(p, vFlop) );
+ }
+ nClasses = Hsh_VecSize( p );
+ Hsh_VecManStop( p );
+ Vec_IntFree( vFlop );
+ printf( "Detected %d flop classes.\n", nClasses );
+ return nClasses;
+}
+Wln_Ret_t * Wln_RetAlloc( Wln_Ntk_t * pNtk )
+{
+ Wln_Ret_t * p; int k, iObj, iFanin;
+ Vec_Int_t * vRefsCopy = Vec_IntAlloc(0);
+ p = ABC_CALLOC( Wln_Ret_t, 1 );
+ p->pNtk = pNtk;
+ Wln_NtkCreateRefs( pNtk );
+ Wln_NtkStartFaninMap( pNtk, &p->vFanins, 2 );
+ Wln_NtkStartFanoutMap( pNtk, &p->vFanouts, &pNtk->vRefs, 2 );
+ ABC_SWAP( Vec_Int_t, *vRefsCopy, pNtk->vRefs );
+ Wln_NtkCleanRefs( pNtk );
+ Vec_IntGrow( &p->vEdgeLinks, 10*Wln_NtkFfNum(pNtk) );
+ Vec_IntPushTwo( &p->vEdgeLinks, -1, -1 );
+ Wln_NtkForEachObj( pNtk, iObj )
+ Wln_ObjForEachFanin( pNtk, iObj, iFanin, k )
+ {
+ int * pFanins = Wln_RetFanins( p, iObj );
+ int * pFanouts = Wln_RetFanouts( p, iFanin );
+ int Index = Wln_ObjRefsInc( pNtk, iFanin );
+ pFanins[2*k+0] = iFanin;
+ pFanins[2*k+1] = Wln_ObjIsFf(pNtk, iFanin) ? Vec_IntSize(&p->vEdgeLinks) : 0;
+ pFanouts[2*Index+0] = iObj;
+ pFanouts[2*Index+1] = Vec_IntEntry(&p->vFanins, iObj) + 2*k + 1;
+ if ( Wln_ObjIsFf(pNtk, iFanin) )
+ Vec_IntPushTwo( &p->vEdgeLinks, 0, iFanin );
+ }
+ // double-check the current number of fanouts added
+ Wln_NtkForEachObj( pNtk, iObj )
+ assert( Wln_ObjRefs(pNtk, iObj) == Vec_IntEntry(vRefsCopy, iObj) );
+ Vec_IntFree( vRefsCopy );
+ // other data
+ p->nClasses = Wln_RetComputeFfClasses( pNtk, &p->vFfClasses );
+ ABC_SWAP( Vec_Int_t, p->vNodeDelays, pNtk->vInstIds );
+ Vec_IntGrow( &p->vSources, 1000 );
+ Vec_IntGrow( &p->vSinks, 1000 );
+ Vec_IntGrow( &p->vFront, 1000 );
+ Vec_IntGrow( &p->vMoves, 1000 );
+ return p;
+}
+void Wln_RetFree( Wln_Ret_t * p )
+{
+ ABC_FREE( p->vFanins.pArray );
+ ABC_FREE( p->vFanouts.pArray );
+ ABC_FREE( p->vEdgeLinks.pArray );
+ ABC_FREE( p->vFfClasses.pArray );
+ ABC_FREE( p->vNodeDelays.pArray );
+ ABC_FREE( p->vPathDelays.pArray );
+ ABC_FREE( p->vSources.pArray );
+ ABC_FREE( p->vSinks.pArray );
+ ABC_FREE( p->vFront.pArray );
+ ABC_FREE( p->vMoves.pArray );
+ ABC_FREE( p );
+}
+int Wln_RetMemUsage( Wln_Ret_t * p )
+{
+ int Mem = sizeof(Wln_Ret_t);
+ Mem += 4 * p->vFanins.nCap;
+ Mem += 4 * p->vFanouts.nCap;
+ Mem += 4 * p->vEdgeLinks.nCap;
+ Mem += 4 * p->vFfClasses.nCap;
+ Mem += 4 * p->vNodeDelays.nCap;
+ Mem += 4 * p->vPathDelays.nCap;
+ Mem += 4 * p->vSources.nCap;
+ Mem += 4 * p->vSinks.nCap;
+ Mem += 4 * p->vFront.nCap;
+ Mem += 4 * p->vMoves.nCap;
+ return Mem;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Delay propagation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_RetMarkChanges_rec( Wln_Ret_t * p, int iObj )
+{
+ int k, iFanout, * pLink, * pDelay = Vec_IntEntryP( &p->vPathDelays, iObj );
+ if ( *pDelay < 0 )
+ return;
+ *pDelay = -1;
+ Wln_RetForEachFanout( p, iObj, iFanout, pLink, k )
+ if ( !pLink[0] )
+ Wln_RetMarkChanges_rec( p, iFanout );
+}
+int Wln_RetPropDelay_rec( Wln_Ret_t * p, int iObj )
+{
+ int k, iFanin, * pLink, * pDelay = Vec_IntEntryP( &p->vPathDelays, iObj );
+ if ( *pDelay >= 0 )
+ return *pDelay;
+ Wln_RetForEachFanin( p, iObj, iFanin, pLink, k )
+ if ( pLink[0] )
+ *pDelay = Abc_MaxInt(*pDelay, 0);
+ else
+ *pDelay = Abc_MaxInt(*pDelay, Wln_RetPropDelay_rec(p, iFanin));
+ *pDelay += Vec_IntEntry( &p->vNodeDelays, iObj );
+ return *pDelay;
+}
+int Wln_RetPropDelay( Wln_Ret_t * p, Vec_Int_t * vFront )
+{
+ int i, iObj, DelayMax = 0;
+ if ( vFront )
+ {
+ Vec_IntForEachEntry( vFront, iObj, i )
+ Wln_RetMarkChanges_rec( p, iObj );
+ }
+ else
+ {
+ Vec_IntFill( &p->vPathDelays, Wln_NtkObjNum(p->pNtk), -1 );
+ Wln_NtkForEachCi( p->pNtk, iObj, i )
+ Vec_IntWriteEntry( &p->vPathDelays, iObj, 0 );
+ }
+ Vec_IntClear( &p->vSinks );
+ Wln_NtkForEachObj( p->pNtk, iObj )
+ if ( !Wln_ObjIsCo(p->pNtk, iObj) )
+ {
+ int Delay = Wln_RetPropDelay_rec(p, iObj);
+ if ( DelayMax == Delay )
+ Vec_IntPush( &p->vSinks, iObj );
+ else if ( DelayMax < Delay )
+ {
+ DelayMax = Delay;
+ Vec_IntFill( &p->vSinks, 1, iObj );
+ }
+ }
+ return DelayMax;
+}
+
+void Wln_RetFindSources_rec( Wln_Ret_t * p, int iObj )
+{
+ int k, iFanin, * pLink, FaninDelay, fTerm = 1;
+ if ( Wln_ObjIsCi(p->pNtk, iObj) || Wln_ObjCheckTravId(p->pNtk, iObj) )
+ return;
+ FaninDelay = Vec_IntEntry( &p->vPathDelays, iObj ) - Vec_IntEntry( &p->vNodeDelays, iObj );
+ Wln_RetForEachFanin( p, iObj, iFanin, pLink, k )
+ {
+ if ( !pLink[0] )
+ continue;
+ fTerm = 0;
+ if ( Vec_IntEntry(&p->vPathDelays, iFanin) == FaninDelay )
+ Wln_RetFindSources_rec( p, iFanin );
+ }
+ if ( fTerm )
+ Vec_IntPush( &p->vSources, iObj );
+}
+void Wln_RetFindSources( Wln_Ret_t * p )
+{
+ int i, iObj;
+ Vec_IntClear( &p->vSources );
+ Wln_NtkIncrementTravId( p->pNtk );
+ Vec_IntForEachEntry( &p->vSinks, iObj, i )
+ Wln_RetFindSources_rec( p, iObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Retimability check.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Wln_RetHeadToTail( Wln_Ret_t * p, int * pHead )
+{
+ int * pLink;
+ assert( pHead[0] );
+ pLink = Vec_IntEntryP( &p->vEdgeLinks, pHead[0] );
+ if ( pLink[0] == 0 )
+ return pHead;
+ return Wln_RetHeadToTail( p, pLink );
+}
+
+static inline int Wln_RetCheckForwardOne( Wln_Ret_t * p, int iObj )
+{
+ int k, iFanin, * pLink, iFlop, Class = -1;
+ Wln_RetForEachFanin( p, iObj, iFanin, pLink, k )
+ {
+ if ( !pLink[0] )
+ return 0;
+ iFlop = Vec_IntEntry( &p->vEdgeLinks, pLink[0] + 1 );
+ assert( Wln_ObjIsFf( p->pNtk, iFlop ) );
+ if ( Class == -1 )
+ Class = Vec_IntEntry( &p->vFfClasses, iFlop );
+ else if ( Class != Vec_IntEntry( &p->vFfClasses, iFlop ) )
+ return 0;
+ }
+ return 1;
+}
+int Wln_RetCheckForward( Wln_Ret_t * p, Vec_Int_t * vSet )
+{
+ int i, iObj;
+ Vec_IntForEachEntry( vSet, iObj, i )
+ if ( !Wln_RetCheckForwardOne( p, iObj ) )
+ return 0;
+ return 1;
+}
+
+static inline int Wln_RetCheckBackwardOne( Wln_Ret_t * p, int iObj )
+{
+ int k, iFanin, * pLink, iFlop, Class = -1;
+ Wln_RetForEachFanout( p, iObj, iFanin, pLink, k )
+ {
+ if ( !pLink[0] )
+ return 0;
+ pLink = Wln_RetHeadToTail( p, pLink );
+ iFlop = Vec_IntEntry( &p->vEdgeLinks, pLink[0] + 1 );
+ assert( Wln_ObjIsFf( p->pNtk, iFlop ) );
+ if ( Class == -1 )
+ Class = Vec_IntEntry( &p->vFfClasses, iFlop );
+ else if ( Class != Vec_IntEntry( &p->vFfClasses, iFlop ) )
+ return 0;
+ }
+ return 1;
+}
+int Wln_RetCheckBackward( Wln_Ret_t * p, Vec_Int_t * vSet )
+{
+ int i, iObj;
+ Vec_IntForEachEntry( vSet, iObj, i )
+ if ( !Wln_RetCheckBackwardOne( p, iObj ) )
+ return 0;
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Moving flops.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wln_RetRemoveOneFanin( Wln_Ret_t * p, int iObj )
+{
+ int k, iFanin, * pLink, iFlop, iFlop1 = -1;
+ int * pFanins = Wln_RetFanins( p, iObj );
+ Wln_RetForEachFanin( p, iObj, iFanin, pLink, k )
+ {
+ assert( pLink[0] );
+ pFanins[2*k+1] = Vec_IntEntry( &p->vEdgeLinks, pLink[0] );
+ iFlop = Vec_IntEntry( &p->vEdgeLinks, pLink[0] + 1 );
+ assert( Wln_ObjIsFf( p->pNtk, iFlop ) );
+ if ( iFlop1 == -1 )
+ iFlop1 = iFlop;
+ }
+ return iFlop1;
+}
+int Wln_RetRemoveOneFanout( Wln_Ret_t * p, int iObj )
+{
+ int k, iFanin, * pLink, iFlop, iFlop1 = -1;
+ //int * pFanins = Wln_RetFanins( p, iObj );
+ Wln_RetForEachFanout( p, iObj, iFanin, pLink, k )
+ {
+ assert( pLink[0] );
+ pLink = Wln_RetHeadToTail( p, pLink );
+ iFlop = Vec_IntEntry( &p->vEdgeLinks, pLink[0] + 1 );
+ pLink[0] = 0;
+ assert( Wln_ObjIsFf( p->pNtk, iFlop ) );
+ if ( iFlop1 == -1 )
+ iFlop1 = iFlop;
+ }
+ return iFlop1;
+}
+void Wln_RetInsertOneFanin( Wln_Ret_t * p, int iObj, int iFlop )
+{
+ int k, iFanin, * pLink;
+ int * pFanins = Wln_RetFanins( p, iObj );
+ assert( Wln_ObjIsFf( p->pNtk, iFlop ) );
+ Wln_RetForEachFanin( p, iObj, iFanin, pLink, k )
+ {
+ int iHead = pFanins[2*k+1];
+ pFanins[2*k+1] = Vec_IntSize(&p->vEdgeLinks);
+ Vec_IntPushTwo( &p->vEdgeLinks, iHead, iFlop );
+ }
+}
+void Wln_RetInsertOneFanout( Wln_Ret_t * p, int iObj, int iFlop )
+{
+ int k, iFanin, * pLink;
+ assert( Wln_ObjIsFf( p->pNtk, iFlop ) );
+ Wln_RetForEachFanout( p, iObj, iFanin, pLink, k )
+ {
+ if ( pLink[0] )
+ pLink = Wln_RetHeadToTail( p, pLink );
+ pLink = Vec_IntEntryP( &p->vEdgeLinks, pLink[0] );
+ assert( pLink[0] == 0 );
+ pLink[0] = Vec_IntSize(&p->vEdgeLinks);
+ Vec_IntPushTwo( &p->vEdgeLinks, 0, iFlop );
+ }
+}
+void Wln_RetRetimeForward( Wln_Ret_t * p, Vec_Int_t * vSet )
+{
+ int i, iObj, iFlop;
+ Vec_IntForEachEntry( vSet, iObj, i )
+ {
+ iFlop = Wln_RetRemoveOneFanin( p, iObj );
+ Wln_RetInsertOneFanout( p, iObj, iFlop );
+ }
+}
+void Wln_RetRetimeBackward( Wln_Ret_t * p, Vec_Int_t * vSet )
+{
+ int i, iObj, iFlop;
+ Vec_IntForEachEntry( vSet, iObj, i )
+ {
+ iFlop = Wln_RetRemoveOneFanout( p, iObj );
+ Wln_RetInsertOneFanin( p, iObj, iFlop );
+ }
+}
+void Wln_RetAddToMoves( Wln_Ret_t * p, Vec_Int_t * vSet, int Delay, int fForward )
+{
+ int i, iObj;
+ if ( vSet == NULL )
+ {
+ Vec_IntPushTwo( &p->vMoves, 0, Delay );
+ return;
+ }
+ Vec_IntForEachEntry( vSet, iObj, i )
+ {
+ int NameId = Vec_IntEntry( &p->pNtk->vNameIds, iObj );
+ Vec_IntPushTwo( &p->vMoves, fForward ? NameId : -NameId, Delay );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Retiming computation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Wln_NtkRetime( Wln_Ntk_t * pNtk )
+{
+ Wln_Ret_t * p = Wln_RetAlloc( pNtk );
+ Vec_Int_t * vSources = &p->vSources;
+ Vec_Int_t * vSinks = &p->vSinks;
+ Vec_Int_t * vFront = &p->vFront;
+ Vec_Int_t * vMoves = Vec_IntAlloc(0);
+ p->DelayMax = Wln_RetPropDelay( p, NULL );
+ Wln_RetFindSources( p );
+ Wln_RetAddToMoves( p, NULL, p->DelayMax, 0 );
+ while ( Vec_IntSize(vSources) || Vec_IntSize(vSinks) )
+ {
+ int fForward = Vec_IntSize(vSources) && Wln_RetCheckForward( p, vSources );
+ int fBackward = Vec_IntSize(vSinks) && Wln_RetCheckBackward( p, vSinks );
+ if ( !fForward && !fBackward )
+ {
+ printf( "Cannot retime forward and backward.\n" );
+ break;
+ }
+ Vec_IntSort( vSources, 0 );
+ Vec_IntSort( vSinks, 0 );
+ if ( Vec_IntTwoCountCommon(vSources, vSinks) )
+ {
+ printf( "Cannot reduce delay by retiming.\n" );
+ break;
+ }
+ Vec_IntClear( vFront );
+ if ( (fForward && !fBackward) || (fForward && fBackward && Vec_IntSize(vSources) < Vec_IntSize(vSinks)) )
+ Wln_RetRetimeForward( p, vSources ), Vec_IntAppend( vFront, vSources ), fForward = 1, fBackward = 0;
+ else
+ Wln_RetRetimeBackward( p, vSinks ), Vec_IntAppend( vFront, vSources ), fForward = 0, fBackward = 1;
+ p->DelayMax = Wln_RetPropDelay( p, vFront );
+ Wln_RetAddToMoves( p, vFront, p->DelayMax, fForward );
+ Wln_RetFindSources( p );
+ if ( 2*Vec_IntSize(&p->vEdgeLinks) > Vec_IntCap(&p->vEdgeLinks) )
+ Vec_IntGrow( &p->vEdgeLinks, 4*Vec_IntSize(&p->vEdgeLinks) );
+ }
+ ABC_SWAP( Vec_Int_t, *vMoves, p->vMoves );
+ Wln_RetFree( p );
+ return vMoves;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/base/wln/wlnWriteVer.c b/src/base/wln/wlnWriteVer.c
new file mode 100644
index 00000000..1c37e311
--- /dev/null
+++ b/src/base/wln/wlnWriteVer.c
@@ -0,0 +1,494 @@
+/**CFile****************************************************************
+
+ FileName [wlnWriteVer.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Word-level network.]
+
+ Synopsis [Writing Verilog.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 23, 2018.]
+
+ Revision [$Id: wlnWriteVer.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wln.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_WriteTableOne( FILE * pFile, int nFans, int nOuts, word * pTable, int Id )
+{
+ int m, nMints = (1<<nFans);
+// Abc_TtPrintHexArrayRev( stdout, pTable, nMints ); printf( "\n" );
+ assert( nOuts > 0 && nOuts <= 64 && (64 % nOuts) == 0 );
+ fprintf( pFile, "module table%d(ind, val);\n", Id );
+ fprintf( pFile, " input [%d:0] ind;\n", nFans-1 );
+ fprintf( pFile, " output [%d:0] val;\n", nOuts-1 );
+ fprintf( pFile, " reg [%d:0] val;\n", nOuts-1 );
+ fprintf( pFile, " always @(ind)\n" );
+ fprintf( pFile, " begin\n" );
+ fprintf( pFile, " case (ind)\n" );
+ for ( m = 0; m < nMints; m++ )
+ fprintf( pFile, " %d\'h%x: val = %d\'h%x;\n", nFans, m, nOuts, (unsigned)((pTable[(nOuts * m) >> 6] >> ((nOuts * m) & 63)) & Abc_Tt6Mask(nOuts)) );
+ fprintf( pFile, " endcase\n" );
+ fprintf( pFile, " end\n" );
+ fprintf( pFile, "endmodule\n" );
+ fprintf( pFile, "\n" );
+}
+void Wln_WriteTables( FILE * pFile, Wln_Ntk_t * p )
+{
+ Vec_Int_t * vNodes;
+ word * pTable;
+ int i, iObj;
+ if ( p->vTables == NULL || Vec_PtrSize(p->vTables) == 0 )
+ return;
+ // map tables into their nodes
+ vNodes = Vec_IntStart( Vec_PtrSize(p->vTables) );
+ Wln_NtkForEachObj( p, iObj )
+ if ( Wln_ObjType(p, iObj) == ABC_OPER_TABLE )
+ Vec_IntWriteEntry( vNodes, Wln_ObjFanin1(p, iObj), iObj );
+ // write tables
+ Vec_PtrForEachEntry( word *, p->vTables, pTable, i )
+ {
+ int iNode = Vec_IntEntry( vNodes, i );
+ int iFanin = Wln_ObjFanin0( p, iNode );
+ Wln_WriteTableOne( pFile, Wln_ObjRange(p, iFanin), Wln_ObjRange(p, iNode), pTable, i );
+ }
+ Vec_IntFree( vNodes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [This was used to add POs to each node except PIs and MUXes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_WriteAddPos( Wln_Ntk_t * p )
+{
+ int iObj;
+ Wln_NtkForEachObj( p, iObj )
+ if ( !Wln_ObjIsCio(p, iObj) )
+ Wln_ObjCreateCo( p, iObj );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Wln_WriteVerIntVec( FILE * pFile, Wln_Ntk_t * p, Vec_Int_t * vVec, int Start )
+{
+ char * pName;
+ int LineLength = Start;
+ int NameCounter = 0;
+ int AddedLength, i, iObj;
+ Vec_IntForEachEntry( vVec, iObj, i )
+ {
+ pName = Wln_ObjName( p, iObj );
+ // get the line length after this name is written
+ AddedLength = strlen(pName) + 2;
+ if ( NameCounter && LineLength + AddedLength + 3 > 70 )
+ { // write the line extender
+ fprintf( pFile, "\n " );
+ // reset the line length
+ LineLength = Start;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s%s", pName, (i==Vec_IntSize(vVec)-1)? "" : "," );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+}
+void Wln_WriteVerInt( FILE * pFile, Wln_Ntk_t * p )
+{
+ int k, j, iObj, iFanin;
+ char Range[100];
+ fprintf( pFile, "module %s ( ", p->pName );
+ fprintf( pFile, "\n " );
+ if ( Wln_NtkCiNum(p) > 0 )
+ {
+ Wln_WriteVerIntVec( pFile, p, &p->vCis, 3 );
+ fprintf( pFile, ",\n " );
+ }
+ if ( Wln_NtkCoNum(p) > 0 )
+ Wln_WriteVerIntVec( pFile, p, &p->vCos, 3 );
+ fprintf( pFile, " );\n" );
+ Wln_NtkForEachObj( p, iObj )
+ {
+ int End = Wln_ObjRangeEnd(p, iObj);
+ int Beg = Wln_ObjRangeBeg(p, iObj);
+ int nDigits = Abc_Base10Log(Abc_AbsInt(End)+1) + Abc_Base10Log(Abc_AbsInt(Beg)+1) + (int)(End < 0) + (int)(Beg < 0);
+ sprintf( Range, "%s[%d:%d]%*s", (!p->fSmtLib && Wln_ObjIsSigned(p, iObj)) ? "signed ":" ", End, Beg, 8-nDigits, "" );
+ fprintf( pFile, " " );
+ if ( Wln_ObjIsCi(p, iObj) )
+ fprintf( pFile, "input " );
+ else if ( Wln_ObjIsCo(p, iObj) )
+ fprintf( pFile, "output " );
+ else
+ fprintf( pFile, " " );
+ if ( Wln_ObjIsCio(p, iObj) )
+ {
+ fprintf( pFile, "wire %s %s ;\n", Range, Wln_ObjName(p, iObj) );
+ if ( Wln_ObjIsCi(p, iObj) )
+ continue;
+ fprintf( pFile, " assign " );
+ fprintf( pFile, "%-16s = %s ;\n", Wln_ObjName(p, iObj), Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ continue;
+ }
+ if ( Wln_ObjType(p, iObj) == ABC_OPER_SEL_NMUX || Wln_ObjType(p, iObj) == ABC_OPER_SEL_SEL )
+ fprintf( pFile, "reg %s ", Range );
+ else
+ fprintf( pFile, "wire %s ", Range );
+ if ( Wln_ObjType(p, iObj) == ABC_OPER_TABLE )
+ {
+ // wire [3:0] s4972; table0 s4972_Index(s4971, s4972);
+ fprintf( pFile, "%s ; table%d", Wln_ObjName(p, iObj), Wln_ObjFanin1(p, iObj) );
+ fprintf( pFile, " s%d_Index(%s, ", iObj, Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ fprintf( pFile, "%s)", Wln_ObjName(p, iObj) );
+ }
+ else if ( Wln_ObjIsConst(p, iObj) )
+ fprintf( pFile, "%-16s = %s", Wln_ObjName(p, iObj), Wln_ObjConstString(p, iObj) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_ROTR || Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_ROTL )
+ {
+ // wire [27:0] s4960 = (s57 >> 17) | (s57 << 11);
+ int Num0 = Wln_ObjFanin1(p, iObj);
+ int Num1 = Wln_ObjRange(p, iObj) - Num0;
+ assert( Num0 > 0 && Num0 < Wln_ObjRange(p, iObj) );
+ fprintf( pFile, "%-16s = ", Wln_ObjName(p, iObj) );
+ if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_ROTR )
+ fprintf( pFile, "(%s >> %d) | (%s << %d)", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Num0, Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Num1 );
+ else
+ fprintf( pFile, "(%s << %d) | (%s >> %d)", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Num0, Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Num1 );
+ }
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_SEL_NMUX )
+ {
+ fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) );
+ fprintf( pFile, " " );
+ fprintf( pFile, "always @( " );
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ fprintf( pFile, "%s%s", k ? " or ":"", Wln_ObjName(p, Wln_ObjFanin(p, iObj, k)) );
+ fprintf( pFile, " )\n" );
+ fprintf( pFile, " " );
+ fprintf( pFile, "begin\n" );
+ fprintf( pFile, " " );
+ fprintf( pFile, "case ( %s )\n", Wln_ObjName(p, Wln_ObjFanin(p, iObj, 0)) );
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ {
+ if ( !k ) continue;
+ fprintf( pFile, " " );
+ fprintf( pFile, "%d : %s = ", k-1, Wln_ObjName(p, iObj) );
+ fprintf( pFile, "%s ;\n", Wln_ObjName(p, Wln_ObjFanin(p, iObj, k)) );
+ }
+ fprintf( pFile, " " );
+ fprintf( pFile, "endcase\n" );
+ fprintf( pFile, " " );
+ fprintf( pFile, "end\n" );
+ continue;
+ }
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_SEL_SEL )
+ {
+ fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) );
+ fprintf( pFile, " " );
+ fprintf( pFile, "always @( " );
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ fprintf( pFile, "%s%s", k ? " or ":"", Wln_ObjName(p, Wln_ObjFanin(p, iObj, k)) );
+ fprintf( pFile, " )\n" );
+ fprintf( pFile, " " );
+ fprintf( pFile, "begin\n" );
+ fprintf( pFile, " " );
+ fprintf( pFile, "case ( %s )\n", Wln_ObjName(p, Wln_ObjFanin(p, iObj, 0)) );
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ {
+ if ( !k ) continue;
+ fprintf( pFile, " " );
+ fprintf( pFile, "%d\'b", Wln_ObjFaninNum(p, iObj)-1 );
+ for ( j = Wln_ObjFaninNum(p, iObj)-1; j > 0; j-- )
+ fprintf( pFile, "%d", (int)(j==k) );
+ fprintf( pFile, " : %s = ", Wln_ObjName(p, iObj) );
+ fprintf( pFile, "%s ;\n", Wln_ObjName(p, Wln_ObjFanin(p, iObj, k)) );
+ }
+ fprintf( pFile, " " );
+ fprintf( pFile, "default" );
+ fprintf( pFile, " : %s = ", Wln_ObjName(p, iObj) );
+ fprintf( pFile, "%d\'b", Wln_ObjRange(p, iObj) );
+ for ( j = Wln_ObjRange(p, iObj)-1; j >= 0; j-- )
+ fprintf( pFile, "%d", 0 );
+ fprintf( pFile, " ;\n" );
+ fprintf( pFile, " " );
+ fprintf( pFile, "endcase\n" );
+ fprintf( pFile, " " );
+ fprintf( pFile, "end\n" );
+ continue;
+ }
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_SEL_DEC )
+ {
+ int nRange = Wln_ObjRange(p, Wln_ObjFanin0(p, iObj));
+ assert( (1 << nRange) == Wln_ObjRange(p, iObj) );
+ fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) );
+ for ( k = 0; k < Wln_ObjRange(p, iObj); k++ )
+ {
+ fprintf( pFile, " " );
+ fprintf( pFile, "wire " );
+ fprintf( pFile, "%s_", Wln_ObjName(p, iObj) );
+ for ( j = 0; j < nRange; j++ )
+ fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 );
+ fprintf( pFile, " = " );
+ for ( j = 0; j < nRange; j++ )
+ fprintf( pFile, "%s%s%s[%d]",
+ j ? " & ":"", ((k >> (nRange-1-j)) & 1) ? " ":"~",
+ Wln_ObjName(p, Wln_ObjFanin(p, iObj, 0)), nRange-1-j );
+ fprintf( pFile, " ;\n" );
+ }
+ fprintf( pFile, " " );
+ fprintf( pFile, "assign %s = { ", Wln_ObjName(p, iObj) );
+ for ( k = Wln_ObjRange(p, iObj)-1; k >= 0; k-- )
+ {
+ fprintf( pFile, "%s%s_", k < Wln_ObjRange(p, iObj)-1 ? ", ":"", Wln_ObjName(p, iObj) );
+ for ( j = 0; j < nRange; j++ )
+ fprintf( pFile, "%d", (k >> (nRange-1-j)) & 1 );
+ }
+ fprintf( pFile, " } ;\n" );
+ continue;
+ }
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_ADDSUB )
+ {
+ // out = mode ? a+b+cin : a-b-cin
+ fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) );
+ fprintf( pFile, " " );
+ fprintf( pFile, "assign " );
+ fprintf( pFile, "%s = %s ? %s + %s + %s : %s - %s - %s ;\n",
+ Wln_ObjName(p, iObj), Wln_ObjName(p, Wln_ObjFanin0(p, iObj)),
+ Wln_ObjName(p, Wln_ObjFanin2(p, iObj)), Wln_ObjName(p, Wln_ObjFanin(p, iObj,3)), Wln_ObjName(p, Wln_ObjFanin1(p, iObj)),
+ Wln_ObjName(p, Wln_ObjFanin2(p, iObj)), Wln_ObjName(p, Wln_ObjFanin(p, iObj,3)), Wln_ObjName(p, Wln_ObjFanin1(p, iObj))
+ );
+ continue;
+ }
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_RAMR || Wln_ObjType(p, iObj) == ABC_OPER_RAMW )
+ {
+ if ( 1 )
+ {
+ fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) );
+ fprintf( pFile, " " );
+ fprintf( pFile, "%s (", Wln_ObjType(p, iObj) == ABC_OPER_RAMR ? "ABC_READ" : "ABC_WRITE" );
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ fprintf( pFile, " .%s(%s),", k==0 ? "mem_in" : (k==1 ? "addr": "data"), Wln_ObjName(p, iFanin) );
+ fprintf( pFile, " .%s(%s) ) ;\n", Wln_ObjType(p, iObj) == ABC_OPER_RAMR ? "data" : "mem_out", Wln_ObjName(p, iObj) );
+ continue;
+ }
+ else
+ {
+ int nBitsMem = Wln_ObjRange(p, Wln_ObjFanin(p, iObj, 0) );
+ //int nBitsAddr = Wln_ObjRange(p, Wln_ObjFanin(p, iObj, 1) );
+ int nBitsDat = Wln_ObjType(p, iObj) == ABC_OPER_RAMR ? Wln_ObjRange(p, iObj) : Wln_ObjRange(p, Wln_ObjFanin(p, iObj, 2));
+ int Depth = nBitsMem / nBitsDat;
+ assert( nBitsMem % nBitsDat == 0 );
+ fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) );
+ fprintf( pFile, " " );
+ fprintf( pFile, "%s_%d (", Wln_ObjType(p, iObj) == ABC_OPER_RAMR ? "CPL_MEM_READ" : "CPL_MEM_WRITE", Depth );
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ fprintf( pFile, " .%s(%s),", k==0 ? "mem_data_in" : (k==1 ? "addr_in": "data_in"), Wln_ObjName(p, iFanin) );
+ fprintf( pFile, " .%s(%s) ) ;\n", "data_out", Wln_ObjName(p, iObj) );
+ continue;
+ }
+ }
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_DFFRSE )
+ {
+ fprintf( pFile, "%s ;\n", Wln_ObjName(p, iObj) );
+ continue;
+ }
+ else
+ {
+ fprintf( pFile, "%-16s = ", Wln_ObjName(p, iObj) );
+ if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_BUF )
+ fprintf( pFile, "%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_MUX )
+ {
+ fprintf( pFile, "%s ? ", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ fprintf( pFile, "%s : ", Wln_ObjName(p, Wln_ObjFanin1(p, iObj)) );
+ fprintf( pFile, "%s", Wln_ObjName(p, Wln_ObjFanin2(p, iObj)) );
+ }
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_MIN )
+ fprintf( pFile, "-%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_INV )
+ fprintf( pFile, "~%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_LOGIC_NOT )
+ fprintf( pFile, "!%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_AND )
+ fprintf( pFile, "&%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_OR )
+ fprintf( pFile, "|%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_XOR )
+ fprintf( pFile, "^%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_NAND )
+ fprintf( pFile, "~&%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_NOR )
+ fprintf( pFile, "~|%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_RED_NXOR )
+ fprintf( pFile, "~^%s", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_SLICE )
+ fprintf( pFile, "%s [%d:%d]", Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Wln_ObjRangeEnd(p, iObj), Wln_ObjRangeBeg(p, iObj) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_SIGNEXT )
+ fprintf( pFile, "{ {%d{%s[%d]}}, %s }", Wln_ObjRange(p, iObj) - Wln_ObjRange(p, Wln_ObjFanin0(p, iObj)), Wln_ObjName(p, Wln_ObjFanin0(p, iObj)), Wln_ObjRange(p, Wln_ObjFanin0(p, iObj)) - 1, Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ZEROPAD )
+ fprintf( pFile, "{ {%d{1\'b0}}, %s }", Wln_ObjRange(p, iObj) - Wln_ObjRange(p, Wln_ObjFanin0(p, iObj)), Wln_ObjName(p, Wln_ObjFanin0(p, iObj)) );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_CONCAT )
+ {
+ fprintf( pFile, "{" );
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ fprintf( pFile, " %s%s", Wln_ObjName(p, Wln_ObjFanin(p, iObj, k)), k == Wln_ObjFaninNum(p, iObj)-1 ? "":"," );
+ fprintf( pFile, " }" );
+ }
+ else
+ {
+ fprintf( pFile, "%s ", Wln_ObjName(p, Wln_ObjFanin(p, iObj, 0)) );
+ if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_R )
+ fprintf( pFile, ">>" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_RA )
+ fprintf( pFile, ">>>" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_L )
+ fprintf( pFile, "<<" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_SHIFT_LA )
+ fprintf( pFile, "<<<" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_AND )
+ fprintf( pFile, "&" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_OR )
+ fprintf( pFile, "|" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_XOR )
+ fprintf( pFile, "^" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_NAND )
+ fprintf( pFile, "~&" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_NOR )
+ fprintf( pFile, "~|" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_BIT_NXOR )
+ fprintf( pFile, "~^" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_LOGIC_IMPL )
+ fprintf( pFile, "=>" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_LOGIC_AND )
+ fprintf( pFile, "&&" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_LOGIC_OR )
+ fprintf( pFile, "||" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_LOGIC_XOR )
+ fprintf( pFile, "^^" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_EQU )
+ fprintf( pFile, "==" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_NOTEQU )
+ fprintf( pFile, "!=" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_LESS )
+ fprintf( pFile, "<" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_MORE )
+ fprintf( pFile, ">" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_LESSEQU )
+ fprintf( pFile, "<=" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_COMP_MOREEQU )
+ fprintf( pFile, ">=" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_ADD )
+ fprintf( pFile, "+" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_SUB )
+ fprintf( pFile, "-" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_MUL )
+ fprintf( pFile, "*" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_DIV )
+ fprintf( pFile, "/" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_REM )
+ fprintf( pFile, "%%" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_MOD )
+ fprintf( pFile, "%%" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_POW )
+ fprintf( pFile, "**" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_SQRT )
+ fprintf( pFile, "@" );
+ else if ( Wln_ObjType(p, iObj) == ABC_OPER_ARI_SQUARE )
+ fprintf( pFile, "#" );
+ else
+ {
+ //assert( 0 );
+ printf( "Failed to write node \"%s\" with unknown operator type (%d).\n", Wln_ObjName(p, iObj), Wln_ObjType(p, iObj) );
+ fprintf( pFile, "???\n" );
+ continue;
+ }
+ fprintf( pFile, " %s", Wln_ObjName(p, Wln_ObjFanin(p, iObj, 1)) );
+ if ( Wln_ObjFaninNum(p, iObj) == 3 && Wln_ObjType(p, iObj) == ABC_OPER_ARI_ADD )
+ fprintf( pFile, " + %s", Wln_ObjName(p, Wln_ObjFanin(p, iObj, 2)) );
+ }
+ }
+ fprintf( pFile, " ;%s\n", (p->fSmtLib && Wln_ObjIsSigned(p, iObj)) ? " // signed SMT-LIB operator" : "" );
+ }
+ iFanin = 0;
+ // write DFFs in the end
+ fprintf( pFile, "\n" );
+ Wln_NtkForEachFf( p, iObj, j )
+ {
+ char * pInNames[8] = {"d", "clk", "reset", "set", "enable", "async", "sre", "init"};
+ fprintf( pFile, " " );
+ fprintf( pFile, "%s (", "ABC_DFFRSE" );
+ Wln_ObjForEachFanin( p, iObj, iFanin, k )
+ if ( iFanin ) fprintf( pFile, " .%s(%s),", pInNames[k], Wln_ObjName(p, iFanin) );
+ fprintf( pFile, " .%s(%s) ) ;\n", "q", Wln_ObjName(p, iObj) );
+ }
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "endmodule\n\n" );
+}
+void Wln_WriteVer( Wln_Ntk_t * p, char * pFileName )
+{
+ FILE * pFile;
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Wln_WriteVer(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+ fprintf( pFile, "// Benchmark \"%s\" written by ABC on %s\n", p->pName, Extra_TimeStamp() );
+ fprintf( pFile, "\n" );
+ Wln_WriteTables( pFile, p );
+// if ( fAddCos )
+// Wln_WriteAddPos( p );
+ Wln_WriteVerInt( pFile, p );
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+