Commit 80983617 by Alan Mishchenko

Version abc50812

parent 273ba030
......@@ -301,15 +301,15 @@ SOURCE=.\src\base\io\ioReadVerilog.c
# End Source File
# Begin Source File
SOURCE=.\src\base\io\ioWriteBench.c
SOURCE=.\src\base\io\ioUtil.c
# End Source File
# Begin Source File
SOURCE=.\src\base\io\ioWriteBlif.c
SOURCE=.\src\base\io\ioWriteBench.c
# End Source File
# Begin Source File
SOURCE=.\src\base\io\ioWriteBlifLogic.c
SOURCE=.\src\base\io\ioWriteBlif.c
# End Source File
# Begin Source File
......@@ -317,10 +317,6 @@ SOURCE=.\src\base\io\ioWriteCnf.c
# End Source File
# Begin Source File
SOURCE=.\src\base\io\ioWriteGate.c
# End Source File
# Begin Source File
SOURCE=.\src\base\io\ioWritePla.c
# End Source File
# End Group
......
No preview for this file type
......@@ -6,13 +6,13 @@
--------------------Configuration: abc - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPD94.tmp" with contents
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP4DC.tmp" with contents
[
/nologo /MLd /W3 /Gm /GX /ZI /Od /I "src\base\abc" /I "src\base\cmd" /I "src\base\io" /I "src\base\main" /I "src\bdd\cudd" /I "src\bdd\epd" /I "src\bdd\mtr" /I "src\bdd\parse" /I "src\bdd\dsd" /I "src\bdd\reo" /I "src\sop\mvc" /I "src\sop\ft" /I "src\sat\asat" /I "src\sat\msat" /I "src\sat\fraig" /I "src\opt\fxa" /I "src\opt\fxu" /I "src\map\fpga" /I "src\map\mapper" /I "src\map\mio" /I "src\map\super" /I "src\misc\extra" /I "src\misc\st" /I "src\misc\util" /I "src\misc\vec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D "HAVE_ASSERT_H" /FR"Debug/" /Fp"Debug/abc.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"C:\_projects\abc\src\sat\sim\simSupp.c"
"C:\_projects\abc\src\base\abc\abcMap.c"
]
Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPD94.tmp"
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPD95.tmp" with contents
Creating command line "cl.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP4DC.tmp"
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP4DD.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/abc.pdb" /debug /machine:I386 /out:"_TEST/abc.exe" /pdbtype:sept
.\Debug\abc.obj
......@@ -59,11 +59,8 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
.\Debug\ioReadBlif.obj
.\Debug\ioReadPla.obj
.\Debug\ioReadVerilog.obj
.\Debug\ioWriteBench.obj
.\Debug\ioWriteBlif.obj
.\Debug\ioWriteBlifLogic.obj
.\Debug\ioWriteCnf.obj
.\Debug\ioWriteGate.obj
.\Debug\ioWritePla.obj
.\Debug\main.obj
.\Debug\mainFrame.obj
......@@ -194,6 +191,12 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
.\Debug\fraigTable.obj
.\Debug\fraigUtil.obj
.\Debug\fraigVec.obj
.\Debug\simMan.obj
.\Debug\simSat.obj
.\Debug\simSupp.obj
.\Debug\simSym.obj
.\Debug\simUnate.obj
.\Debug\simUtils.obj
.\Debug\fxu.obj
.\Debug\fxuCreate.obj
.\Debug\fxuHeapD.obj
......@@ -245,6 +248,7 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
.\Debug\superGate.obj
.\Debug\superWrite.obj
.\Debug\extraUtilBdd.obj
.\Debug\extraUtilBitMatrix.obj
.\Debug\extraUtilFile.obj
.\Debug\extraUtilMemory.obj
.\Debug\extraUtilMisc.obj
......@@ -260,20 +264,15 @@ kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32
.\Debug\safe_mem.obj
.\Debug\strsav.obj
.\Debug\texpand.obj
.\Debug\simUtils.obj
.\Debug\simSat.obj
.\Debug\simSupp.obj
.\Debug\simSym.obj
.\Debug\simUnate.obj
.\Debug\simMan.obj
.\Debug\extraUtilBitMatrix.obj
.\Debug\ioUtil.obj
.\Debug\ioWriteBench.obj
]
Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPD95.tmp"
Creating command line "link.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP4DD.tmp"
<h3>Output Window</h3>
Compiling...
simSupp.c
abcMap.c
Linking...
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPD96.tmp" with contents
Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP4DE.tmp" with contents
[
/nologo /o"Debug/abc.bsc"
.\Debug\abc.sbr
......@@ -320,11 +319,8 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPD96.tmp" with conte
.\Debug\ioReadBlif.sbr
.\Debug\ioReadPla.sbr
.\Debug\ioReadVerilog.sbr
.\Debug\ioWriteBench.sbr
.\Debug\ioWriteBlif.sbr
.\Debug\ioWriteBlifLogic.sbr
.\Debug\ioWriteCnf.sbr
.\Debug\ioWriteGate.sbr
.\Debug\ioWritePla.sbr
.\Debug\main.sbr
.\Debug\mainFrame.sbr
......@@ -455,6 +451,12 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPD96.tmp" with conte
.\Debug\fraigTable.sbr
.\Debug\fraigUtil.sbr
.\Debug\fraigVec.sbr
.\Debug\simMan.sbr
.\Debug\simSat.sbr
.\Debug\simSupp.sbr
.\Debug\simSym.sbr
.\Debug\simUnate.sbr
.\Debug\simUtils.sbr
.\Debug\fxu.sbr
.\Debug\fxuCreate.sbr
.\Debug\fxuHeapD.sbr
......@@ -506,6 +508,7 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPD96.tmp" with conte
.\Debug\superGate.sbr
.\Debug\superWrite.sbr
.\Debug\extraUtilBdd.sbr
.\Debug\extraUtilBitMatrix.sbr
.\Debug\extraUtilFile.sbr
.\Debug\extraUtilMemory.sbr
.\Debug\extraUtilMisc.sbr
......@@ -521,14 +524,9 @@ Creating temporary file "C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPD96.tmp" with conte
.\Debug\safe_mem.sbr
.\Debug\strsav.sbr
.\Debug\texpand.sbr
.\Debug\simUtils.sbr
.\Debug\simSat.sbr
.\Debug\simSupp.sbr
.\Debug\simSym.sbr
.\Debug\simUnate.sbr
.\Debug\simMan.sbr
.\Debug\extraUtilBitMatrix.sbr]
Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSPD96.tmp"
.\Debug\ioUtil.sbr
.\Debug\ioWriteBench.sbr]
Creating command line "bscmake.exe @C:\DOCUME~1\alanmi\LOCALS~1\Temp\RSP4DE.tmp"
Creating browse info file...
<h3>Output Window</h3>
......
......@@ -30,6 +30,7 @@
static int Abc_CommandPrintStats ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintIo ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintLatch ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintFanio ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandPrintSupport ( Abc_Frame_t * pAbc, int argc, char ** argv );
......@@ -90,6 +91,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
{
Cmd_CommandAdd( pAbc, "Printing", "print_stats", Abc_CommandPrintStats, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_io", Abc_CommandPrintIo, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_latch", Abc_CommandPrintLatch, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_fanio", Abc_CommandPrintFanio, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_factor", Abc_CommandPrintFactor, 0 );
Cmd_CommandAdd( pAbc, "Printing", "print_supp", Abc_CommandPrintSupport, 0 );
......@@ -285,6 +287,56 @@ usage:
SeeAlso []
***********************************************************************/
int Abc_CommandPrintLatch( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
pNtk = Abc_FrameReadNet(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
// print the nodes
Abc_NtkPrintLatch( pOut, pNtk );
return 0;
usage:
fprintf( pErr, "usage: print_latch [-h]\n" );
fprintf( pErr, "\t prints information about latches\n" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandPrintFanio( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
......@@ -366,9 +418,9 @@ int Abc_CommandPrintFactor( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogicSop(pNtk) )
if ( !Abc_NtkIsLogicSop(pNtk) )
{
fprintf( pErr, "Printing factored forms can be done for netlist and SOP networks.\n" );
fprintf( pErr, "Printing factored forms can be done for SOP networks.\n" );
return 1;
}
......@@ -1296,7 +1348,7 @@ int Abc_CommandLogic( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// get the new network
pNtkRes = Abc_NtkLogic( pNtk );
pNtkRes = Abc_NtkNetlistToLogic( pNtk );
if ( pNtkRes == NULL )
{
fprintf( pErr, "Converting to a logic network has failed.\n" );
......@@ -2297,14 +2349,14 @@ int Abc_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( Abc_NtkIsNetlist(pNtk) )
if ( Abc_NtkIsAig(pNtk) )
{
fprintf( pErr, "Cannot sweep a netlist. Please transform into a logic network.\n" );
fprintf( pErr, "Cannot sweep AIGs (use \"fraig\").\n" );
return 1;
}
if ( Abc_NtkIsAig(pNtk) )
if ( !Abc_NtkIsLogic(pNtk) )
{
fprintf( pErr, "Cannot sweep AIGs (use \"fraig\").\n" );
fprintf( pErr, "Transform the current network into a logic network.\n" );
return 1;
}
// modify the current network
......
......@@ -44,7 +44,8 @@
// network types
typedef enum {
ABC_NTK_NONE, // unknown
ABC_NTK_NETLIST, // net and node list as in the input file
ABC_NTK_NETLIST_SOP, // netlist with nodes represented using SOPs
ABC_NTK_NETLIST_MAP, // netlist with nodes represented using gates from the library
ABC_NTK_LOGIC_SOP, // only SOP logic nodes (similar to SIS network)
ABC_NTK_LOGIC_BDD, // only BDD logic nodes (similar to BDS network)
ABC_NTK_LOGIC_MAP, // only mapped logic nodes (similar to mapped SIS network)
......@@ -55,22 +56,15 @@ typedef enum {
// object types
typedef enum {
ABC_OBJ_TYPE_NONE, // unknown
ABC_OBJ_TYPE_NET, // net
ABC_OBJ_TYPE_NODE, // node
ABC_OBJ_TYPE_LATCH, // latch
ABC_OBJ_TYPE_TERM, // terminal
ABC_OBJ_TYPE_OTHER // unused
ABC_OBJ_NONE, // unknown
ABC_OBJ_NET, // net
ABC_OBJ_NODE, // node
ABC_OBJ_LATCH, // latch
ABC_OBJ_PI, // terminal
ABC_OBJ_PO, // terminal
ABC_OBJ_OTHER // unused
} Abc_ObjType_t;
// object subtypes
typedef enum {
ABC_OBJ_SUBTYPE_PI = 0x01, // primary input
ABC_OBJ_SUBTYPE_PO = 0x02, // primary output
ABC_OBJ_SUBTYPE_LI = 0x04, // primary latch input
ABC_OBJ_SUBTYPE_LO = 0x08 // primary latch output
} Abc_ObjSubtype_t;
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
......@@ -98,8 +92,8 @@ struct Abc_Obj_t_ // 12 words
{
// high-level information
unsigned Type : 4; // the object type
unsigned Subtype : 4; // the object subtype
unsigned Id : 24; // the ID of the object
unsigned Unused : 2; // currently unused
unsigned Id : 26; // the ID of the object
// internal information
unsigned fMarkA : 1; // the multipurpose mark
unsigned fMarkB : 1; // the multipurpose mark
......@@ -119,21 +113,18 @@ struct Abc_Obj_t_ // 12 words
struct Abc_Ntk_t_
{
// general information about the network
// general information
Abc_NtkType_t Type; // type of the network
char * pName; // the network name
char * pSpec; // the name of the spec file if present
// name representation in the netlist
// name representation
stmm_table * tName2Net; // the table hashing net names into net pointer
// name representation in the logic network
Vec_Ptr_t * vNamesPi; // the array of PI node names
Vec_Ptr_t * vNamesLatch; // the array of latch names names
Vec_Ptr_t * vNamesPo; // the array of PO node names
stmm_table * tObj2Name; // the table hashing PI/PO/latch pointers into names
// components of the network
Vec_Ptr_t * vObjs; // the array of all objects (net, nodes, latches)
Vec_Ptr_t * vPis; // the array of PIs
Vec_Ptr_t * vPos; // the array of POs
Vec_Ptr_t * vLatches; // the array of latches (or the cutset in the sequential network)
Vec_Ptr_t * vCis; // the array of combinational inputs (PIs followed by latches)
Vec_Ptr_t * vCos; // the array of combinational outputs (POs followed by latches)
Vec_Ptr_t * vLats; // the array of latches (or the cutset in the sequential network)
// the stats about the number of living objects
int nObjs; // the number of living objs
int nNets; // the number of living nets
......@@ -148,9 +139,6 @@ struct Abc_Ntk_t_
// the external don't-care if given
Abc_Ntk_t * pExdc; // the EXDC network
// miscellaneous data members
Vec_Ptr_t * vLatches2; // the temporary array of latches
int nPisOld; // the number of old PIs
int nPosOld; // the number of old PIs
unsigned nTravIds; // the unique traversal IDs of nodes
Vec_Ptr_t * vPtrTemp; // the temporary array
Vec_Int_t * vIntTemp; // the temporary array
......@@ -193,24 +181,12 @@ struct Abc_ManRes_t_
////////////////////////////////////////////////////////////////////////
// reading data members of the network
static inline char * Abc_NtkName( Abc_Ntk_t * pNtk ) { return pNtk->pName; }
static inline char * Abc_NtkSpec( Abc_Ntk_t * pNtk ) { return pNtk->pSpec; }
static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pNtk->nTravIds; }
static inline Abc_Ntk_t * Abc_NtkExdc( Abc_Ntk_t * pNtk ) { return pNtk->pExdc; }
static inline Abc_Ntk_t * Abc_NtkBackup( Abc_Ntk_t * pNtk ) { return pNtk->pNetBackup; }
static inline int Abc_NtkStep ( Abc_Ntk_t * pNtk ) { return pNtk->iStep; }
static inline Vec_Ptr_t * Abc_NtkObjVec( Abc_Ntk_t * pNtk ) { return pNtk->vObjs; }
static inline Vec_Ptr_t * Abc_NtkLatchVec( Abc_Ntk_t * pNtk ) { return pNtk->vLatches; }
static inline Vec_Ptr_t * Abc_NtkPiVec( Abc_Ntk_t * pNtk ) { return pNtk->vPis; }
static inline Vec_Ptr_t * Abc_NtkPoVec( Abc_Ntk_t * pNtk ) { return pNtk->vPos; }
static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { return pNtk->vObjs->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkLatch( Abc_Ntk_t * pNtk, int i ) { return pNtk->vLatches->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { return pNtk->vPis->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { return pNtk->vPos->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { return pNtk->vPis->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { return pNtk->vPos->pArray[i]; }
static inline char * Abc_NtkName( Abc_Ntk_t * pNtk ) { return pNtk->pName; }
static inline char * Abc_NtkSpec( Abc_Ntk_t * pNtk ) { return pNtk->pSpec; }
static inline int Abc_NtkTravId( Abc_Ntk_t * pNtk ) { return pNtk->nTravIds; }
static inline Abc_Ntk_t * Abc_NtkExdc( Abc_Ntk_t * pNtk ) { return pNtk->pExdc; }
static inline Abc_Ntk_t * Abc_NtkBackup( Abc_Ntk_t * pNtk ) { return pNtk->pNetBackup; }
static inline int Abc_NtkStep ( Abc_Ntk_t * pNtk ) { return pNtk->iStep; }
// setting data members of the network
static inline void Abc_NtkSetName ( Abc_Ntk_t * pNtk, char * pName ) { pNtk->pName = pName; }
......@@ -218,41 +194,41 @@ static inline void Abc_NtkSetSpec ( Abc_Ntk_t * pNtk, char * pName )
static inline void Abc_NtkSetBackup( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNetBackup ) { pNtk->pNetBackup = pNetBackup; }
static inline void Abc_NtkSetStep ( Abc_Ntk_t * pNtk, int iStep ) { pNtk->iStep = iStep; }
// getting the number of objects
static inline int Abc_NtkObjNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjs; }
static inline int Abc_NtkNetNum( Abc_Ntk_t * pNtk ) { return pNtk->nNets; }
static inline int Abc_NtkNodeNum( Abc_Ntk_t * pNtk ) { return pNtk->nNodes; }
static inline int Abc_NtkLatchNum( Abc_Ntk_t * pNtk ) { return pNtk->nLatches; }
static inline int Abc_NtkPiNum( Abc_Ntk_t * pNtk ) { return pNtk->nPis; }
static inline int Abc_NtkPoNum( Abc_Ntk_t * pNtk ) { return pNtk->nPos; }
static inline int Abc_NtkCiNum( Abc_Ntk_t * pNtk ) { return pNtk->vCis->nSize; }
static inline int Abc_NtkCoNum( Abc_Ntk_t * pNtk ) { return pNtk->vCos->nSize; }
// reading objects
static inline Abc_Obj_t * Abc_NtkObj( Abc_Ntk_t * pNtk, int i ) { assert( i < Vec_PtrSize(pNtk->vObjs) ); return pNtk->vObjs->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkLatch( Abc_Ntk_t * pNtk, int i ) { assert( i < Vec_PtrSize(pNtk->vLats) ); return pNtk->vLats->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkPi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPiNum(pNtk) ); return pNtk->vCis->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkPo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkPoNum(pNtk) ); return pNtk->vCos->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkCi( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkCiNum(pNtk) ); return pNtk->vCis->pArray[i]; }
static inline Abc_Obj_t * Abc_NtkCo( Abc_Ntk_t * pNtk, int i ) { assert( i < Abc_NtkCoNum(pNtk) ); return pNtk->vCos->pArray[i]; }
// checking the network type
static inline bool Abc_NtkIsNetlist( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_NETLIST; }
static inline bool Abc_NtkIsLogicSop( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_LOGIC_SOP; }
static inline bool Abc_NtkIsLogicBdd( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_LOGIC_BDD; }
static inline bool Abc_NtkIsLogicMap( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_LOGIC_MAP; }
static inline bool Abc_NtkIsLogic( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_LOGIC_SOP || pNtk->Type == ABC_NTK_LOGIC_BDD || pNtk->Type == ABC_NTK_LOGIC_MAP; }
static inline bool Abc_NtkIsAig( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_AIG; }
static inline bool Abc_NtkIsSeq( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_SEQ; }
// getting the number of different objects in the network
static inline int Abc_NtkObjNum( Abc_Ntk_t * pNtk ) { return pNtk->nObjs; }
static inline int Abc_NtkNetNum( Abc_Ntk_t * pNtk ) { return pNtk->nNets; }
static inline int Abc_NtkNodeNum( Abc_Ntk_t * pNtk ) { return pNtk->nNodes; }
static inline int Abc_NtkLatchNum( Abc_Ntk_t * pNtk ) { return pNtk->nLatches; }
static inline int Abc_NtkPiNum( Abc_Ntk_t * pNtk ) { return pNtk->nPis; }
static inline int Abc_NtkPoNum( Abc_Ntk_t * pNtk ) { return pNtk->nPos; }
static inline int Abc_NtkCiNum( Abc_Ntk_t * pNtk ) { return pNtk->vPis->nSize; }
static inline int Abc_NtkCoNum( Abc_Ntk_t * pNtk ) { return pNtk->vPos->nSize; }
// getting hold of the names of the PIs/POs/latches
static inline char * Abc_NtkNameLatch(Abc_Ntk_t * pNtk, int i){ return pNtk->vNamesLatch->pArray[i]; }
static inline char * Abc_NtkNamePi( Abc_Ntk_t * pNtk, int i ) { return pNtk->vNamesPi->pArray[i]; }
static inline char * Abc_NtkNamePo( Abc_Ntk_t * pNtk, int i ) { return pNtk->vNamesPo->pArray[i]; }
static inline char * Abc_NtkNameCi( Abc_Ntk_t * pNtk, int i ) { return pNtk->vNamesPi->pArray[i]; }
static inline char * Abc_NtkNameCo( Abc_Ntk_t * pNtk, int i ) { return pNtk->vNamesPo->pArray[i]; }
static inline bool Abc_NtkIsNetlist( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_NETLIST_SOP || pNtk->Type == ABC_NTK_NETLIST_MAP; }
static inline bool Abc_NtkIsNetlistSop( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_NETLIST_SOP; }
static inline bool Abc_NtkIsNetlistMap( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_NETLIST_MAP; }
static inline bool Abc_NtkIsLogic( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_LOGIC_SOP || pNtk->Type == ABC_NTK_LOGIC_BDD || pNtk->Type == ABC_NTK_LOGIC_MAP; }
static inline bool Abc_NtkIsLogicSop( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_LOGIC_SOP; }
static inline bool Abc_NtkIsLogicBdd( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_LOGIC_BDD; }
static inline bool Abc_NtkIsLogicMap( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_LOGIC_MAP; }
static inline bool Abc_NtkIsAig( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_AIG; }
static inline bool Abc_NtkIsSeq( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_SEQ; }
static inline bool Abc_NtkIsMapped( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_NETLIST_MAP || pNtk->Type == ABC_NTK_LOGIC_MAP; }
static inline bool Abc_NtkIsSop( Abc_Ntk_t * pNtk ) { return pNtk->Type == ABC_NTK_NETLIST_SOP || pNtk->Type == ABC_NTK_LOGIC_SOP; }
static inline bool Abc_NtkIsComb( Abc_Ntk_t * pNtk ) { return Abc_NtkLatchNum(pNtk) == 0; }
// working with complemented attributes of objects
static inline bool Abc_ObjIsComplement( Abc_Obj_t * p ) { return (bool)(((unsigned)p) & 01); }
static inline Abc_Obj_t * Abc_ObjRegular( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned)(p) & ~01); }
static inline Abc_Obj_t * Abc_ObjNot( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned)(p) ^ 01); }
static inline Abc_Obj_t * Abc_ObjNotCond( Abc_Obj_t * p, int c ) { return (Abc_Obj_t *)((unsigned)(p) ^ (c)); }
// reading data members of the object
static inline unsigned Abc_ObjType( Abc_Obj_t * pObj ) { return pObj->Type; }
static inline unsigned Abc_ObjSubtype( Abc_Obj_t * pObj ) { return pObj->Subtype; }
static inline unsigned Abc_ObjId( Abc_Obj_t * pObj ) { return pObj->Id; }
static inline int Abc_ObjTravId( Abc_Obj_t * pObj ) { return pObj->TravId; }
static inline Vec_Fan_t * Abc_ObjFaninVec( Abc_Obj_t * pObj ) { return &pObj->vFanins; }
......@@ -261,47 +237,56 @@ static inline Abc_Obj_t * Abc_ObjCopy( Abc_Obj_t * pObj ) { return pObj-
static inline Abc_Ntk_t * Abc_ObjNtk( Abc_Obj_t * pObj ) { return pObj->pNtk; }
static inline void * Abc_ObjData( Abc_Obj_t * pObj ) { return pObj->pData; }
// setting data members of the network
static inline void Abc_ObjSetCopy( Abc_Obj_t * pObj, Abc_Obj_t * pCopy ) { pObj->pCopy = pCopy; }
static inline void Abc_ObjSetData( Abc_Obj_t * pObj, void * pData ) { pObj->pData = pData; }
// working with complemented attributes of objects
static inline bool Abc_ObjIsComplement( Abc_Obj_t * p ) { return (bool)(((unsigned)p) & 01); }
static inline Abc_Obj_t * Abc_ObjRegular( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned)(p) & ~01); }
static inline Abc_Obj_t * Abc_ObjNot( Abc_Obj_t * p ) { return (Abc_Obj_t *)((unsigned)(p) ^ 01); }
static inline Abc_Obj_t * Abc_ObjNotCond( Abc_Obj_t * p, int c ) { return (Abc_Obj_t *)((unsigned)(p) ^ (c)); }
// working with fanin/fanout edges
static inline int Abc_ObjFaninNum( Abc_Obj_t * pObj ) { return pObj->vFanins.nSize; }
static inline int Abc_ObjFanoutNum( Abc_Obj_t * pObj ) { return pObj->vFanouts.nSize; }
static inline int Abc_ObjFaninId( Abc_Obj_t * pObj, int i){ return pObj->vFanins.pArray[i].iFan; }
static inline int Abc_ObjFaninId0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].iFan; }
static inline int Abc_ObjFaninId1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].iFan; }
static inline Abc_Obj_t * Abc_ObjFanout( Abc_Obj_t * pObj, int i ){ return pObj->pNtk->vObjs->pArray[ pObj->vFanouts.pArray[i].iFan ]; }
static inline Abc_Obj_t * Abc_ObjFanout0( Abc_Obj_t * pObj ) { return pObj->pNtk->vObjs->pArray[ pObj->vFanouts.pArray[0].iFan ]; }
static inline Abc_Obj_t * Abc_ObjFanin( Abc_Obj_t * pObj, int i ) { return pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[i].iFan ]; }
static inline Abc_Obj_t * Abc_ObjFanin0( Abc_Obj_t * pObj ) { return pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[0].iFan ]; }
static inline Abc_Obj_t * Abc_ObjFanin1( Abc_Obj_t * pObj ) { return pObj->pNtk->vObjs->pArray[ pObj->vFanins.pArray[1].iFan ]; }
static inline int Abc_ObjFaninId( Abc_Obj_t * pObj, int i){ return pObj->vFanins.pArray[i].iFan; }
static inline int Abc_ObjFaninId0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].iFan; }
static inline int Abc_ObjFaninId1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].iFan; }
static inline Abc_Obj_t * Abc_ObjFanin0Ntk( Abc_Obj_t * pObj ) { return Abc_NtkIsNetlist(pObj->pNtk)? Abc_ObjFanin0(pObj) : pObj; }
static inline bool Abc_ObjFaninC( Abc_Obj_t * pObj, int i ){ return pObj->vFanins.pArray[i].fCompl; }
static inline bool Abc_ObjFaninC0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].fCompl; }
static inline bool Abc_ObjFaninC1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].fCompl; }
static inline int Abc_ObjFaninL( Abc_Obj_t * pObj, int i ){ return pObj->vFanins.pArray[i].nLats; }
static inline int Abc_ObjFaninL0( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[0].nLats; }
static inline int Abc_ObjFaninL1( Abc_Obj_t * pObj ) { return pObj->vFanins.pArray[1].nLats; }
static inline Abc_Obj_t * Abc_ObjChild0( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin0(pObj), Abc_ObjFaninC0(pObj) );}
static inline Abc_Obj_t * Abc_ObjChild1( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( Abc_ObjFanin1(pObj), Abc_ObjFaninC1(pObj) );}
static inline void Abc_ObjSetFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl = 1; }
static inline void Abc_ObjXorFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl ^= 1; }
// setting data members of the network
static inline void Abc_ObjSetCopy( Abc_Obj_t * pObj, Abc_Obj_t * pCopy ) { pObj->pCopy = pCopy; }
static inline void Abc_ObjSetData( Abc_Obj_t * pObj, void * pData ) { pObj->pData = pData; }
static inline void Abc_ObjSetSubtype( Abc_Obj_t * pObj, Abc_ObjSubtype_t Subtype ) { pObj->Subtype |= Subtype; }
static inline void Abc_ObjUnsetSubtype( Abc_Obj_t * pObj, Abc_ObjSubtype_t Subtype ) { pObj->Subtype &= ~Subtype; }
static inline void Abc_ObjXorFaninC( Abc_Obj_t * pObj, int i ){ pObj->vFanins.pArray[i].fCompl ^= 1; }
static inline void Abc_ObjSetFaninL( Abc_Obj_t * pObj, int i, int nLats ) { pObj->vFanins.pArray[i].nLats = nLats; }
static inline void Abc_ObjAddFaninL( Abc_Obj_t * pObj, int i, int nLats ) { pObj->vFanins.pArray[i].nLats += nLats; }
// checking the object type
static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_TYPE_NODE; }
static inline bool Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_TYPE_NET; }
static inline bool Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_TYPE_LATCH; }
static inline bool Abc_ObjIsTerm( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_TYPE_TERM; }
static inline bool Abc_ObjIsPi( Abc_Obj_t * pObj ) { return ((pObj->Subtype & ABC_OBJ_SUBTYPE_PI) > 0); }
static inline bool Abc_ObjIsPo( Abc_Obj_t * pObj ) { return ((pObj->Subtype & ABC_OBJ_SUBTYPE_PO) > 0); }
static inline bool Abc_ObjIsLi( Abc_Obj_t * pObj ) { return ((pObj->Subtype & ABC_OBJ_SUBTYPE_LI) > 0); }
static inline bool Abc_ObjIsLo( Abc_Obj_t * pObj ) { return ((pObj->Subtype & ABC_OBJ_SUBTYPE_LO) > 0); }
static inline bool Abc_ObjIsCi( Abc_Obj_t * pObj ) { if ( Abc_NtkIsNetlist(pObj->pNtk) ) return ((pObj->Subtype & (ABC_OBJ_SUBTYPE_PI | ABC_OBJ_SUBTYPE_LO)) > 0); else return (Abc_ObjIsPi(pObj) || Abc_ObjIsLatch(pObj)); }
static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { if ( Abc_NtkIsNetlist(pObj->pNtk) ) return ((pObj->Subtype & (ABC_OBJ_SUBTYPE_PO | ABC_OBJ_SUBTYPE_LI)) > 0); else return (Abc_ObjIsPo(pObj) || Abc_ObjIsLatch(pObj)); }
static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; }
static inline bool Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NET; }
static inline bool Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH; }
static inline bool Abc_ObjIsPi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI; }
static inline bool Abc_ObjIsPo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO; }
static inline bool Abc_ObjIsPio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_PO; }
static inline bool Abc_ObjIsCi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_LATCH; }
static inline bool Abc_ObjIsCo( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH; }
static inline bool Abc_ObjIsCio( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI || pObj->Type == ABC_OBJ_PO || pObj->Type == ABC_OBJ_LATCH; }
// checking the node type
static inline bool Abc_NodeIsAnd( Abc_Obj_t * pNode ) { assert(Abc_ObjIsNode(Abc_ObjRegular(pNode))); assert(Abc_NtkIsAig(Abc_ObjRegular(pNode)->pNtk)); return Abc_ObjFaninNum(Abc_ObjRegular(pNode)) == 2; }
static inline bool Abc_NodeIsChoice( Abc_Obj_t * pNode ) { assert(Abc_ObjIsNode(Abc_ObjRegular(pNode))); assert(Abc_NtkIsAig(Abc_ObjRegular(pNode)->pNtk)); return Abc_ObjRegular(pNode)->pData != NULL && Abc_ObjFanoutNum(Abc_ObjRegular(pNode)) > 0; }
static inline bool Abc_NodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_ObjIsNode(Abc_ObjRegular(pNode))); return Abc_ObjFaninNum(Abc_ObjRegular(pNode)) == 0; }
static inline bool Abc_NodeIsAigAnd( Abc_Obj_t * pNode ) { assert(Abc_NtkIsAig(pNode->pNtk)); return Abc_ObjFaninNum(pNode) == 2; }
static inline bool Abc_NodeIsAigChoice( Abc_Obj_t * pNode ){ assert(Abc_NtkIsAig(pNode->pNtk)); return pNode->pData != NULL && Abc_ObjFanoutNum(pNode) > 0; }
static inline bool Abc_NodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_ObjIsNode(Abc_ObjRegular(pNode))); return Abc_ObjFaninNum(Abc_ObjRegular(pNode)) == 0; }
extern bool Abc_NodeIsConst0( Abc_Obj_t * pNode );
extern bool Abc_NodeIsConst1( Abc_Obj_t * pNode );
extern bool Abc_NodeIsBuf( Abc_Obj_t * pNode );
......@@ -337,7 +322,7 @@ static inline bool Abc_NodeIsTravIdPrevious( Abc_Obj_t * pNode ) { r
for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \
if ( (pNode = Abc_NtkObj(pNtk, i)) && Abc_ObjIsNode(pNode) )
#define Abc_NtkForEachLatch( pNtk, pObj, i ) \
for ( i = 0; i < Vec_PtrSize(pNtk->vLatches); i++ ) \
for ( i = 0; i < Vec_PtrSize(pNtk->vLats); i++ ) \
if ( pObj = Abc_NtkLatch(pNtk, i) )
// inputs and outputs
#define Abc_NtkForEachPi( pNtk, pPi, i ) \
......@@ -348,10 +333,10 @@ static inline bool Abc_NodeIsTravIdPrevious( Abc_Obj_t * pNode ) { r
if ( pPo = Abc_NtkPo(pNtk, i) )
#define Abc_NtkForEachCi( pNtk, pPi, i ) \
for ( i = 0; i < Abc_NtkCiNum(pNtk); i++ ) \
if ( pPi = Abc_NtkPi(pNtk, i) )
if ( pPi = Abc_NtkCi(pNtk, i) )
#define Abc_NtkForEachCo( pNtk, pPo, i ) \
for ( i = 0; i < Abc_NtkCoNum(pNtk); i++ ) \
if ( pPo = Abc_NtkPo(pNtk, i) )
if ( pPo = Abc_NtkCo(pNtk, i) )
// fanin and fanouts
#define Abc_ObjForEachFanin( pObj, pFanin, i ) \
for ( i = 0; i < Abc_ObjFaninNum(pObj); i++ ) \
......@@ -378,7 +363,8 @@ extern Abc_Obj_t * Abc_AigAnd( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_
extern Abc_Obj_t * Abc_AigOr( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
extern Abc_Obj_t * Abc_AigXor( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
extern Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs );
extern bool Abc_AigNodeIsUsedCompl( Abc_Obj_t * pNode );
extern bool Abc_AigNodeHasComplFanoutEdge( Abc_Obj_t * pNode );
extern bool Abc_AigNodeHasComplFanoutEdgeTrav( Abc_Obj_t * pNode );
/*=== abcAttach.c ==========================================================*/
extern int Abc_NtkAttach( Abc_Ntk_t * pNtk );
/*=== abcCheck.c ==========================================================*/
......@@ -392,22 +378,21 @@ extern void Abc_NtkFreeGlobalBdds( DdManager * dd, Abc_Ntk_t * pNt
extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type );
extern Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type );
extern void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
extern Abc_Ntk_t * Abc_NtkStartRead( char * pName );
extern void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAllCis );
extern void Abc_NtkDelete( Abc_Ntk_t * pNtk );
extern void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj );
extern void Abc_NtkDeleteObj( Abc_Obj_t * pObj );
extern void Abc_NtkMarkNetPi( Abc_Obj_t * pObj );
extern void Abc_NtkMarkNetPo( Abc_Obj_t * pObj );
extern Abc_Obj_t * Abc_NtkAddPoNode( Abc_Obj_t * pObj );
extern void Abc_NtkRemovePoNode( Abc_Obj_t * pNode );
extern Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreateTermPi( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreateTermPo( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk );
......@@ -444,9 +429,6 @@ extern int Abc_NtkBddToSop( Abc_Ntk_t * pNtk );
extern void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Extra_MmFlex_t * pMmMan, Vec_Str_t * vCube, char ** ppSop0, char ** ppSop1 );
extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover );
/*=== abcLatch.c ==========================================================*/
extern bool Abc_NtkIsComb( Abc_Ntk_t * pNtk );
extern bool Abc_NtkMakeComb( Abc_Ntk_t * pNtk );
extern bool Abc_NtkMakeSeq( Abc_Ntk_t * pNtk );
extern bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch );
extern int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk );
/*=== abcMap.c ==========================================================*/
......@@ -457,6 +439,7 @@ extern int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk );
extern int Abc_NodeMinimumBase( Abc_Obj_t * pNode );
/*=== abcMiter.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
extern Abc_Ntk_t * Abc_NtkMiterOne( Abc_Ntk_t * pNtk, int Out, int In1, int In2 );
extern int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter );
extern void Abc_NtkMiterReport( Abc_Ntk_t * pMiter );
extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
......@@ -464,20 +447,24 @@ extern Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fIni
/*=== abcNames.c ====================================================*/
extern char * Abc_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName );
extern char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix );
extern stmm_table * Abc_NtkLogicHashNames( Abc_Ntk_t * pNtk, int Type, int fComb );
extern void Abc_NtkLogicTransferNames( Abc_Ntk_t * pNtk );
extern char * Abc_NtkNameLatchInput( Abc_Ntk_t * pNtk, int i );
extern char * Abc_ObjName( Abc_Obj_t * pNode );
extern char * Abc_ObjNameSuffix( Abc_Obj_t * pObj, char * pSuffix );
extern char * Abc_ObjNameUnique( Abc_Ntk_t * pNtk, char * pName );
extern char * Abc_NtkLogicStoreName( Abc_Obj_t * pNodeNew, char * pNameOld );
extern char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pNodeNew, char * pNameOld, char * pSuffix );
extern void Abc_NtkDupNameArrays( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
extern void Abc_NtkCreateNameArrays( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
extern void Abc_NtkCreateCioNamesTable( Abc_Ntk_t * pNtk );
extern void Abc_NtkDupCioNamesTable( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
/*=== abcNetlist.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkLogic( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkNetlistToLogic( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkLogicToNetlistBench( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk );
/*=== abcPrint.c ==========================================================*/
extern void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk );
extern void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk );
extern void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk );
extern void Abc_NtkPrintFanio( FILE * pFile, Abc_Ntk_t * pNtk );
extern void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode );
extern void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk );
......@@ -497,6 +484,15 @@ extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk );
/*=== abcSop.c ==========================================================*/
extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName );
extern char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars );
extern char * Abc_SopCreateAnd2( Extra_MmFlex_t * pMan, int fCompl0, int fCompl1 );
extern char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateNand( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateOr( Extra_MmFlex_t * pMan, int nVars, int * pfCompl );
extern char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateInv( Extra_MmFlex_t * pMan );
extern char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan );
extern int Abc_SopGetCubeNum( char * pSop );
extern int Abc_SopGetLitNum( char * pSop );
extern int Abc_SopGetVarNum( char * pSop );
......@@ -552,9 +548,9 @@ extern int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk );
extern double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk );
extern void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeHasUniqueNamedFanout( Abc_Obj_t * pNode );
extern bool Abc_NtkLogicHasSimplePos( Abc_Ntk_t * pNtk );
extern int Abc_NtkLogicMakeSimplePos( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode );
extern bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk );
extern int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate );
extern void Abc_VecObjPushUniqueOrderByLevel( Vec_Ptr_t * p, Abc_Obj_t * pNode );
extern bool Abc_NodeIsMuxType( Abc_Obj_t * pNode );
extern Abc_Obj_t * Abc_NodeRecognizeMux( Abc_Obj_t * pNode, Abc_Obj_t ** ppNodeT, Abc_Obj_t ** ppNodeE );
......@@ -567,7 +563,7 @@ extern int Abc_NodeCompareLevelsDecrease( Abc_Obj_t ** pp1, Abc_O
extern Vec_Ptr_t * Abc_AigCollectAll( Abc_Ntk_t * pNtk );
extern Vec_Ptr_t * Abc_NodeGetFaninNames( Abc_Obj_t * pNode );
extern void Abc_NodeFreeFaninNames( Vec_Ptr_t * vNames );
extern char ** Abc_NtkCollectCioNames( Abc_Ntk_t * pNtk, int fCollectCos );
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
......@@ -255,7 +255,7 @@ Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs )
SeeAlso []
***********************************************************************/
bool Abc_AigNodeIsUsedCompl( Abc_Obj_t * pNode )
bool Abc_AigNodeHasComplFanoutEdge( Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanout;
int i, iFanin;
......@@ -269,6 +269,35 @@ bool Abc_AigNodeIsUsedCompl( Abc_Obj_t * pNode )
return 0;
}
/**Function*************************************************************
Synopsis [Returns 1 if the node has at least one complemented fanout.]
Description [A fanout is complemented if the fanout's fanin edge pointing
to the given node is complemented. Only the fanouts with current TravId
are counted.]
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_AigNodeHasComplFanoutEdgeTrav( Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanout;
int i, iFanin;
Abc_ObjForEachFanout( pNode, pFanout, i )
{
if ( !Abc_NodeIsTravIdCurrent(pFanout) )
continue;
iFanin = Vec_FanFindEntry( &pFanout->vFanins, pNode->Id );
assert( iFanin >= 0 );
if ( Abc_ObjFaninC( pFanout, iFanin ) )
return 1;
}
return 0;
}
/**Function*************************************************************
......
......@@ -19,6 +19,7 @@
***********************************************************************/
#include "abc.h"
#include "main.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -56,11 +57,19 @@ bool Abc_NtkCheck( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj, * pNet, * pNode;
int i;
if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsAig(pNtk) && !Abc_NtkIsLogic(pNtk) )
if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsAig(pNtk) )
{
fprintf( stdout, "NetworkCheck: Unknown network type.\n" );
return 0;
}
if ( Abc_NtkIsMapped(pNtk) )
{
if ( pNtk->pManFunc != Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) )
{
fprintf( stdout, "NetworkCheck: The library of the mapped network is not the global library.\n" );
return 0;
}
}
// check the names
if ( !Abc_NtkCheckNames( pNtk ) )
......@@ -81,11 +90,24 @@ bool Abc_NtkCheck( Abc_Ntk_t * pNtk )
// if it is a netlist change nets and latches
if ( Abc_NtkIsNetlist(pNtk) )
{
if ( Abc_NtkNetNum(pNtk) == 0 )
{
fprintf( stdout, "NetworkCheck: Netlist has no nets.\n" );
return 0;
}
// check the nets
Abc_NtkForEachNet( pNtk, pNet, i )
if ( !Abc_NtkCheckNet( pNtk, pNet ) )
return 0;
}
else
{
if ( Abc_NtkNetNum(pNtk) != 0 )
{
fprintf( stdout, "NetworkCheck: A network that is not a netlist has nets.\n" );
return 0;
}
}
// check the nodes
Abc_NtkForEachNode( pNtk, pNode, i )
......@@ -132,7 +154,7 @@ bool Abc_NtkCheck( Abc_Ntk_t * pNtk )
bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk )
{
stmm_generator * gen;
Abc_Obj_t * pNet, * pNet2;
Abc_Obj_t * pNet, * pNet2, * pObj;
char * pName;
int i;
......@@ -157,82 +179,46 @@ bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk )
}
}
}
else
// check PI/PO/latch names
Abc_NtkForEachPi( pNtk, pObj, i )
{
if ( pNtk->vPis->nSize != pNtk->nPis + pNtk->nLatches )
if ( !stmm_lookup( pNtk->tObj2Name, (char *)pObj, &pName ) )
{
fprintf( stdout, "NetworkCheck: Incorrect size of the PI array.\n" );
fprintf( stdout, "NetworkCheck: PI \"%s\" is in the network but not in the name table.\n", Abc_ObjName(pObj) );
return 0;
}
if ( pNtk->vPos->nSize != pNtk->nPos + pNtk->nLatches )
if ( Abc_NtkIsNetlist(pNtk) && strcmp( Abc_ObjName(Abc_ObjFanout0(pObj)), pName ) )
{
fprintf( stdout, "NetworkCheck: Incorrect size of the PO array.\n" );
fprintf( stdout, "NetworkCheck: PI \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) );
return 0;
}
if ( pNtk->vLatches->nSize != pNtk->nLatches )
}
Abc_NtkForEachPo( pNtk, pObj, i )
{
if ( !stmm_lookup( pNtk->tObj2Name, (char *)pObj, &pName ) )
{
fprintf( stdout, "NetworkCheck: Incorrect size of the latch array.\n" );
fprintf( stdout, "NetworkCheck: PO \"%s\" is in the network but not in the name table.\n", Abc_ObjName(pObj) );
return 0;
}
if ( pNtk->vNamesPi->nSize != pNtk->vPis->nSize )
if ( Abc_NtkIsNetlist(pNtk) && strcmp( Abc_ObjName(Abc_ObjFanin0(pObj)), pName ) )
{
fprintf( stdout, "NetworkCheck: Incorrect size of the PI names array.\n" );
fprintf( stdout, "NetworkCheck: PO \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) );
return 0;
}
if ( pNtk->vNamesPo->nSize != pNtk->vPos->nSize )
}
Abc_NtkForEachLatch( pNtk, pObj, i )
{
if ( !stmm_lookup( pNtk->tObj2Name, (char *)pObj, &pName ) )
{
fprintf( stdout, "NetworkCheck: Incorrect size of the PO names array.\n" );
fprintf( stdout, "NetworkCheck: Latch \"%s\" is in the network but not in the name table.\n", Abc_ObjName(pObj) );
return 0;
}
if ( pNtk->vNamesLatch->nSize != pNtk->vLatches->nSize )
if ( Abc_NtkIsNetlist(pNtk) && strcmp( Abc_ObjName(Abc_ObjFanout0(pObj)), pName ) )
{
fprintf( stdout, "NetworkCheck: Incorrect size of the latch names array.\n" );
fprintf( stdout, "NetworkCheck: Latch \"%s\" has a different name compared to its net.\n", Abc_ObjName(pObj) );
return 0;
}
/*
Abc_Obj_t * pNode, * pNode2;
Abc_NtkForEachPi( pNtk, pNode, i )
{
if ( !stmm_lookup( pNtk->tName2Net, Abc_NtkNamePi(pNtk,i), (char**)&pNode2 ) )
{
fprintf( stdout, "NetworkCheck: PI \"%s\" is in the network but not in the name table.\n", Abc_NtkNamePi(pNtk,i) );
return 0;
}
if ( pNode != pNode2 )
{
fprintf( stdout, "NetworkCheck: PI \"%s\" has a different pointer in the name table.\n", Abc_NtkNamePi(pNtk,i) );
return 0;
}
}
Abc_NtkForEachPo( pNtk, pNode, i )
{
if ( !stmm_lookup( pNtk->tName2Net, Abc_NtkNamePo(pNtk,i), (char**)&pNode2 ) )
{
fprintf( stdout, "NetworkCheck: PO \"%s\" is in the network but not in the name table.\n", Abc_NtkNamePo(pNtk,i) );
return 0;
}
if ( pNode != pNode2 )
{
fprintf( stdout, "NetworkCheck: PO \"%s\" has a different pointer in the name table.\n", Abc_NtkNamePo(pNtk,i) );
return 0;
}
}
Abc_NtkForEachLatch( pNtk, pNode, i )
{
if ( !stmm_lookup( pNtk->tName2Net, Abc_NtkNameLatch(pNtk,i), (char**)&pNode2 ) )
{
fprintf( stdout, "NetworkCheck: Latch \"%s\" is in the network but not in the name table.\n", Abc_NtkNameLatch(pNtk,i) );
return 0;
}
if ( pNode != pNode2 )
{
fprintf( stdout, "NetworkCheck: Latch \"%s\" has a different pointer in the name table.\n", Abc_NtkNameLatch(pNtk,i) );
return 0;
}
}
*/
}
return 1;
}
......@@ -254,33 +240,28 @@ bool Abc_NtkCheckPis( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj;
int i;
if ( Abc_NtkCiNum(pNtk) != Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) )
{
fprintf( stdout, "NetworkCheck: Incorrect size of the PI array.\n" );
return 0;
}
// check that PIs are indeed PIs
Abc_NtkForEachPi( pNtk, pObj, i )
{
if ( Abc_NtkIsNetlist(pNtk) )
if ( !Abc_ObjIsPi(pObj) )
{
if ( !Abc_ObjIsNet(pObj) )
{
fprintf( stdout, "NetworkCheck: A PI \"%s\" is not a net.\n", Abc_ObjName(pObj) );
return 0;
}
fprintf( stdout, "NetworkCheck: Object \"%s\" (id=%d) is in the PI list but is not a PI.\n", Abc_ObjName(pObj), pObj->Id );
return 0;
}
else
if ( pObj->pData )
{
if ( !Abc_ObjIsTerm(pObj) )
{
fprintf( stdout, "NetworkCheck: A PI \"%s\" is not a terminal node.\n", Abc_ObjName(pObj) );
return 0;
}
if ( pObj->pData )
{
fprintf( stdout, "NetworkCheck: A PI \"%s\" has a logic function.\n", Abc_ObjName(pObj) );
return 0;
}
fprintf( stdout, "NetworkCheck: A PI \"%s\" has a logic function.\n", Abc_ObjName(pObj) );
return 0;
}
if ( !Abc_ObjIsPi(pObj) )
if ( Abc_ObjFaninNum(pObj) > 0 )
{
fprintf( stdout, "NetworkCheck: Object \"%s\" (id=%d) is in the PI list but is not a PI.\n", Abc_ObjName(pObj), pObj->Id );
fprintf( stdout, "NetworkCheck: A PI \"%s\" has fanins.\n", Abc_ObjName(pObj) );
return 0;
}
pObj->pCopy = (Abc_Obj_t *)1;
......@@ -313,33 +294,33 @@ bool Abc_NtkCheckPos( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj;
int i;
if ( Abc_NtkCoNum(pNtk) != Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) )
{
fprintf( stdout, "NetworkCheck: Incorrect size of the PO array.\n" );
return 0;
}
// check that POs are indeed POs
Abc_NtkForEachPo( pNtk, pObj, i )
{
if ( Abc_NtkIsNetlist(pNtk) )
if ( !Abc_ObjIsPo(pObj) )
{
if ( !Abc_ObjIsNet(pObj) )
{
fprintf( stdout, "NetworkCheck: A PO \"%s\" is not a net.\n", Abc_ObjName(pObj) );
return 0;
}
fprintf( stdout, "NetworkCheck: Net \"%s\" (id=%d) is in the PO list but is not a PO.\n", Abc_ObjName(pObj), pObj->Id );
return 0;
}
else
if ( pObj->pData )
{
if ( !Abc_ObjIsTerm(pObj) )
{
fprintf( stdout, "NetworkCheck: A PO \"%s\" is not a terminal node.\n", Abc_ObjName(pObj) );
return 0;
}
if ( pObj->pData )
{
fprintf( stdout, "NetworkCheck: A PO \"%s\" has a logic function.\n", Abc_ObjName(pObj) );
return 0;
}
fprintf( stdout, "NetworkCheck: A PO \"%s\" has a logic function.\n", Abc_ObjName(pObj) );
return 0;
}
if ( !Abc_ObjIsPo(pObj) )
if ( Abc_ObjFaninNum(pObj) != 1 )
{
fprintf( stdout, "NetworkCheck: Net \"%s\" (id=%d) is in the PO list but is not a PO.\n", Abc_ObjName(pObj), pObj->Id );
fprintf( stdout, "NetworkCheck: A PO \"%s\" does not have one fanin.\n", Abc_ObjName(pObj) );
return 0;
}
if ( Abc_ObjFanoutNum(pObj) > 0 )
{
fprintf( stdout, "NetworkCheck: A PO \"%s\" has fanouts.\n", Abc_ObjName(pObj) );
return 0;
}
pObj->pCopy = (Abc_Obj_t *)1;
......@@ -379,30 +360,12 @@ bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
fprintf( stdout, "NetworkCheck: Object \"%s\" does not belong to the network.\n", Abc_ObjName(pObj) );
return 0;
}
// the object cannot be a net if it is not a netlist
if ( Abc_ObjIsNet(pObj) && !Abc_NtkIsNetlist(pNtk) )
{
fprintf( stdout, "NetworkCheck: Object \"%s\" is a net but the network is not a netlist.\n", Abc_ObjName(pObj) );
return 0;
}
// check the object ID
if ( pObj->Id < 0 || (int)pObj->Id > pNtk->vObjs->nSize )
{
fprintf( stdout, "NetworkCheck: Object \"%s\" has incorrect ID.\n", Abc_ObjName(pObj) );
return 0;
}
// a PI has no fanins
if ( Abc_ObjIsPi(pObj) && Abc_ObjFaninNum(pObj) > 0 )
{
fprintf( stdout, "PI \"%s\" has fanins.\n", Abc_ObjName(pObj) );
return 0;
}
// detect internal nets that are not driven
if ( !Abc_ObjIsPi(pObj) && Abc_ObjFaninNum(pObj) == 0 && Abc_ObjIsNet(pObj) )
{
fprintf( stdout, "Net \"%s\" is not driven.\n", Abc_ObjName(pObj) );
return 0;
}
// go through the fanins of the object and make sure fanins have this object as a fanout
Abc_ObjForEachFanin( pObj, pFanin, i )
{
......@@ -439,6 +402,16 @@ bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
***********************************************************************/
bool Abc_NtkCheckNet( Abc_Ntk_t * pNtk, Abc_Obj_t * pNet )
{
if ( Abc_ObjFaninNum(pNet) == 0 )
{
fprintf( stdout, "NetworkCheck: Net \"%s\" is not driven.\n", Abc_ObjName(pNet) );
return 0;
}
if ( Abc_ObjFaninNum(pNet) > 1 )
{
fprintf( stdout, "NetworkCheck: Net \"%s\" has more than one driver.\n", Abc_ObjName(pNet) );
return 0;
}
return 1;
}
......@@ -455,15 +428,20 @@ bool Abc_NtkCheckNet( Abc_Ntk_t * pNtk, Abc_Obj_t * pNet )
***********************************************************************/
bool Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode )
{
// detect internal nodes that do not have nets
if ( Abc_NtkIsNetlist(pNtk) && Abc_ObjFanoutNum(pNode) == 0 )
{
fprintf( stdout, "Node (id = %d) has no net to drive.\n", pNode->Id );
return 0;
}
// the node should have a function assigned unless it is an AIG
if ( pNode->pData == NULL && !Abc_NtkIsAig(pNtk) )
{
fprintf( stdout, "NodeCheck: An internal node \"%s\" has no logic function.\n", Abc_ObjName(pNode) );
return 0;
}
// the netlist and SOP logic network should have SOPs
if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsNetlistSop(pNtk) || Abc_NtkIsLogicSop(pNtk) )
{
if ( !Abc_SopCheck( pNode->pData, Abc_ObjFaninNum(pNode) ) )
{
......@@ -480,7 +458,7 @@ bool Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode )
return 0;
}
}
else if ( !Abc_NtkIsAig(pNtk) && !Abc_NtkIsLogicMap(pNtk) )
else if ( !Abc_NtkIsAig(pNtk) && !Abc_NtkIsLogicMap(pNtk) && !Abc_NtkIsNetlistMap(pNtk) )
{
assert( 0 );
}
......@@ -500,8 +478,12 @@ bool Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode )
***********************************************************************/
bool Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch )
{
Abc_Obj_t * pObj;
int Value = 1;
if ( pNtk->vLats->nSize != Abc_NtkLatchNum(pNtk) )
{
fprintf( stdout, "NetworkCheck: Incorrect size of the latch array.\n" );
return 0;
}
// check whether the object is a latch
if ( !Abc_ObjIsLatch(pLatch) )
{
......@@ -521,22 +503,6 @@ bool Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch )
fprintf( stdout, "NodeCheck: Latch \"%s\" has wrong number (%d) of fanins.\n", Abc_ObjName(pLatch), Abc_ObjFaninNum(pLatch) );
Value = 0;
}
// make sure the latch has fanins and fanouts that are labeled accordingly
if ( Abc_NtkIsNetlist(pNtk) )
{
pObj = Abc_ObjFanin0( pLatch );
if ( !Abc_ObjIsLi(pObj) )
{
fprintf( stdout, "NodeCheck: Latch \"%s\" has a fanin that is not labeled as LI.\n", Abc_ObjName(pLatch) );
Value = 0;
}
pObj = Abc_ObjFanout0( pLatch );
if ( !Abc_ObjIsLo(pObj) )
{
fprintf( stdout, "NodeCheck: Latch \"%s\" has a fanout that is not labeled as LO.\n", Abc_ObjName(pLatch) );
Value = 0;
}
}
return Value;
}
......@@ -556,7 +522,7 @@ bool Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch )
***********************************************************************/
bool Abc_NtkComparePis( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
{
Abc_Obj_t * pNode1;
Abc_Obj_t * pObj1;
int i;
if ( Abc_NtkPiNum(pNtk1) != Abc_NtkPiNum(pNtk2) )
{
......@@ -564,12 +530,12 @@ bool Abc_NtkComparePis( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
return 0;
}
// for each PI of pNet1 find corresponding PI of pNet2 and reorder them
Abc_NtkForEachPi( pNtk1, pNode1, i )
Abc_NtkForEachPi( pNtk1, pObj1, i )
{
if ( strcmp( Abc_NtkNamePi(pNtk1,i), Abc_NtkNamePi(pNtk2,i) ) != 0 )
if ( strcmp( Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkPi(pNtk2,i)) ) != 0 )
{
printf( "Primary input #%d is different in network 1 ( \"%s\") and in network 2 (\"%s\").\n",
i, Abc_NtkNamePi(pNtk1,i), Abc_NtkNamePi(pNtk2,i) );
i, Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkPi(pNtk2,i)) );
return 0;
}
}
......@@ -589,7 +555,7 @@ bool Abc_NtkComparePis( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
***********************************************************************/
bool Abc_NtkComparePos( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
{
Abc_Obj_t * pNode1;
Abc_Obj_t * pObj1;
int i;
if ( Abc_NtkPoNum(pNtk1) != Abc_NtkPoNum(pNtk2) )
{
......@@ -597,12 +563,12 @@ bool Abc_NtkComparePos( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
return 0;
}
// for each PI of pNet1 find corresponding PI of pNet2 and reorder them
Abc_NtkForEachPo( pNtk1, pNode1, i )
Abc_NtkForEachPo( pNtk1, pObj1, i )
{
if ( strcmp( Abc_NtkNamePo(pNtk1,i), Abc_NtkNamePo(pNtk2,i) ) != 0 )
if ( strcmp( Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkPo(pNtk2,i)) ) != 0 )
{
printf( "Primary output #%d is different in network 1 ( \"%s\") and in network 2 (\"%s\").\n",
i, Abc_NtkNamePo(pNtk1,i), Abc_NtkNamePo(pNtk2,i) );
i, Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkPo(pNtk2,i)) );
return 0;
}
}
......@@ -622,7 +588,7 @@ bool Abc_NtkComparePos( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
***********************************************************************/
bool Abc_NtkCompareLatches( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
{
Abc_Obj_t * pNode1;
Abc_Obj_t * pObj1;
int i;
if ( !fComb )
return 1;
......@@ -632,190 +598,15 @@ bool Abc_NtkCompareLatches( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
return 0;
}
// for each PI of pNet1 find corresponding PI of pNet2 and reorder them
Abc_NtkForEachLatch( pNtk1, pNode1, i )
Abc_NtkForEachLatch( pNtk1, pObj1, i )
{
if ( strcmp( Abc_NtkNameLatch(pNtk1,i), Abc_NtkNameLatch(pNtk2,i) ) != 0 )
if ( strcmp( Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkLatch(pNtk2,i)) ) != 0 )
{
printf( "Latch #%d is different in network 1 ( \"%s\") and in network 2 (\"%s\").\n",
i, Abc_NtkNameLatch(pNtk1,i), Abc_NtkNameLatch(pNtk2,i) );
return 0;
}
}
return 1;
}
/**Function*************************************************************
Synopsis [Compares the PIs of the two networks.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_NtkComparePis2( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
{
Abc_Obj_t * pNode1, * pNode2;
Vec_Ptr_t * vNodesNew, * vNamesNew;
stmm_table * tNames;
int i;
if ( Abc_NtkPiNum(pNtk1) != Abc_NtkPiNum(pNtk2) )
{
printf( "Networks have different number of primary inputs.\n" );
return 0;
}
// for each PI of pNet1 find corresponding PI of pNet2 and reorder them
vNodesNew = Vec_PtrAlloc( 100 );
vNamesNew = Vec_PtrAlloc( 100 );
tNames = Abc_NtkLogicHashNames( pNtk2, 0, fComb );
Abc_NtkForEachCi( pNtk1, pNode1, i )
{
if ( stmm_lookup( tNames, Abc_NtkNamePi(pNtk1,i), (char **)&pNode2 ) )
{
Vec_PtrPush( vNodesNew, pNode2 );
Vec_PtrPush( vNamesNew, pNode2->pCopy );
}
else
{
printf( "Primary input \"%s\" of network 1 is not in network 2.\n", pNtk1->vNamesPi->pArray[i] );
Vec_PtrFree( vNodesNew );
Vec_PtrFree( vNamesNew );
return 0;
}
if ( !fComb && i == Abc_NtkPiNum(pNtk2)-1 )
break;
}
stmm_free_table( tNames );
// add latches to the PI/PO lists to work as CIs/COs
if ( !fComb )
{
Abc_NtkForEachLatch( pNtk2, pNode2, i )
{
Vec_PtrPush( vNodesNew, pNode2 );
Vec_PtrPush( vNamesNew, Abc_NtkNameLatch(pNtk2,i) );
}
}
Vec_PtrFree( pNtk2->vPis ); pNtk2->vPis = vNodesNew; vNodesNew = NULL;
Vec_PtrFree( pNtk2->vNamesPi ); pNtk2->vNamesPi = vNamesNew; vNamesNew = NULL;
return 1;
}
/**Function*************************************************************
Synopsis [Compares the POs of the two networks.]
Description [If the flag is 1, compares the first n POs of pNet1, where
n is the number of POs in pNet2.]
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_NtkComparePos2( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
{
Abc_Obj_t * pNode1, * pNode2;
Vec_Ptr_t * vNodesNew, * vNamesNew;
stmm_table * tNames;
int i;
if ( Abc_NtkPoNum(pNtk1) != Abc_NtkPoNum(pNtk2) )
{
printf( "Networks have different number of primary outputs.\n" );
return 0;
}
// for each PO of pNet1 find corresponding PO of pNet2 and reorder them
vNodesNew = Vec_PtrAlloc( 100 );
vNamesNew = Vec_PtrAlloc( 100 );
tNames = Abc_NtkLogicHashNames( pNtk2, 1, fComb );
Abc_NtkForEachCo( pNtk1, pNode1, i )
{
if ( stmm_lookup( tNames, Abc_NtkNamePo(pNtk1,i), (char **)&pNode2 ) )
{
Vec_PtrPush( vNodesNew, pNode2 );
Vec_PtrPush( vNamesNew, pNode2->pCopy );
}
else
{
printf( "Primary output \"%s\" of network 1 is not in network 2.\n", pNtk1->vNamesPo->pArray[i] );
Vec_PtrFree( vNodesNew );
Vec_PtrFree( vNamesNew );
return 0;
}
if ( !fComb && i == Abc_NtkPoNum(pNtk2)-1 )
break;
}
stmm_free_table( tNames );
// add latches to the PI/PO lists to work as CIs/COs
if ( !fComb )
{
Abc_NtkForEachLatch( pNtk2, pNode2, i )
{
Vec_PtrPush( vNodesNew, pNode2 );
Vec_PtrPush( vNamesNew, Abc_NtkNameLatch(pNtk2,i) );
}
}
Vec_PtrFree( pNtk2->vPos ); pNtk2->vPos = vNodesNew; vNodesNew = NULL;
Vec_PtrFree( pNtk2->vNamesPo ); pNtk2->vNamesPo = vNamesNew; vNamesNew = NULL;
return 1;
}
/**Function*************************************************************
Synopsis [Compares the latches of the two networks.]
Description [This comparison procedure should be always called before
the other two.]
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_NtkCompareLatches2( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
{
Abc_Obj_t * pNode1, * pNode2;
Vec_Ptr_t * vNodesNew, * vNamesNew;
stmm_table * tNames;
int i;
if ( !fComb )
return 1;
if ( Abc_NtkLatchNum(pNtk1) != Abc_NtkLatchNum(pNtk2) )
{
printf( "Networks have different number of latches.\n" );
return 0;
}
// for each latch of pNet1 find corresponding latch of pNet2 and reorder them
vNodesNew = Vec_PtrAlloc( 100 );
vNamesNew = Vec_PtrAlloc( 100 );
tNames = Abc_NtkLogicHashNames( pNtk2, 2, fComb );
Abc_NtkForEachLatch( pNtk1, pNode1, i )
{
if ( stmm_lookup( tNames, Abc_NtkNameLatch(pNtk1,i), (char **)&pNode2 ) )
{
Vec_PtrPush( vNodesNew, pNode2 );
Vec_PtrPush( vNamesNew, pNode2->pCopy );
}
else
{
printf( "Latch \"%s\" of network 1 is not in network 2.\n", pNtk1->vNamesLatch->pArray[i] );
Vec_PtrFree( vNodesNew );
Vec_PtrFree( vNamesNew );
i, Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkLatch(pNtk2,i)) );
return 0;
}
}
stmm_free_table( tNames );
Vec_PtrFree( pNtk2->vLatches ); pNtk2->vLatches = vNodesNew; vNodesNew = NULL;
Vec_PtrFree( pNtk2->vNamesLatch ); pNtk2->vNamesLatch = vNamesNew; vNamesNew = NULL;
return 1;
}
......
......@@ -242,9 +242,6 @@ Abc_Ntk_t * Abc_NtkFromGlobalBdds( DdManager * dd, Abc_Ntk_t * pNtk )
Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
}
Extra_ProgressBarStop( pProgress );
// transfer the names
Abc_NtkDupNameArrays( pNtk, pNtkNew );
Abc_ManTimeDup( pNtk, pNtkNew );
return pNtkNew;
}
......
......@@ -57,17 +57,15 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type )
pNtk->Type = Type;
// start the object storage
pNtk->vObjs = Vec_PtrAlloc( 100 );
pNtk->vLatches = Vec_PtrAlloc( 100 );
pNtk->vPis = Vec_PtrAlloc( 100 );
pNtk->vPos = Vec_PtrAlloc( 100 );
pNtk->vNamesPi = Vec_PtrAlloc( 100 );
pNtk->vNamesPo = Vec_PtrAlloc( 100 );
pNtk->vNamesLatch = Vec_PtrAlloc( 100 );
pNtk->vLats = Vec_PtrAlloc( 100 );
pNtk->vCis = Vec_PtrAlloc( 100 );
pNtk->vCos = Vec_PtrAlloc( 100 );
pNtk->vPtrTemp = Vec_PtrAlloc( 100 );
pNtk->vIntTemp = Vec_IntAlloc( 100 );
pNtk->vStrTemp = Vec_StrAlloc( 100 );
// start the hash table
pNtk->tName2Net = stmm_init_table(strcmp, stmm_strhash);
pNtk->tObj2Name = stmm_init_table(stmm_ptrcmp, stmm_ptrhash);
// start the memory managers
pNtk->pMmNames = Extra_MmFlexStart();
pNtk->pMmObj = Extra_MmFixedStart( sizeof(Abc_Obj_t) );
......@@ -75,13 +73,15 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type )
// get ready to assign the first Obj ID
pNtk->nTravIds = 1;
// start the functionality manager
if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
pNtk->pManFunc = Extra_MmFlexStart();
else if ( Abc_NtkIsLogicBdd(pNtk) )
pNtk->pManFunc = Cudd_Init( 20, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
else if ( Abc_NtkIsAig(pNtk) )
pNtk->pManFunc = Abc_AigAlloc( pNtk );
else if ( !Abc_NtkIsLogicMap(pNtk) )
else if ( Abc_NtkIsMapped(pNtk) )
pNtk->pManFunc = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame());
else
assert( 0 );
return pNtk;
}
......@@ -104,7 +104,6 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type )
int i;
if ( pNtk == NULL )
return NULL;
assert( Type != ABC_NTK_NETLIST );
// start the network
pNtkNew = Abc_NtkAlloc( Type );
// duplicate the name and the spec
......@@ -118,12 +117,15 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type )
Abc_NtkForEachLatch( pNtk, pObj, i )
{
pObjNew = Abc_NtkDupObj(pNtkNew, pObj);
Vec_PtrPush( pNtkNew->vPis, pObjNew );
Vec_PtrPush( pNtkNew->vPos, pObjNew );
Vec_PtrPush( pNtkNew->vCis, pObjNew );
Vec_PtrPush( pNtkNew->vCos, pObjNew );
}
// clean the node copy fields
Abc_NtkForEachNode( pNtk, pObj, i )
pObj->pCopy = NULL;
// transfer the names
Abc_NtkDupCioNamesTable( pNtk, pNtkNew );
Abc_ManTimeDup( pNtk, pNtkNew );
return pNtkNew;
}
......@@ -142,22 +144,68 @@ void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
Abc_Obj_t * pObj, * pDriver, * pDriverNew;
int i;
assert( !Abc_NtkIsNetlist(pNtk) );
// set the COs of the strashed network
Abc_NtkForEachCo( pNtk, pObj, i )
{
pDriver = Abc_ObjFanin0(pObj);
pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) );
pDriverNew = Abc_ObjNotCond(pDriver->pCopy, Abc_ObjFaninC0(pObj));
Abc_ObjAddFanin( pObj->pCopy, pDriverNew );
}
// transfer the names
Abc_NtkDupNameArrays( pNtk, pNtkNew );
Abc_ManTimeDup( pNtk, pNtkNew );
}
/**Function*************************************************************
Synopsis [Duplicate the Ntk.]
Synopsis [Starts a new network using existing network as a model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkStartRead( char * pName )
{
Abc_Ntk_t * pNtkNew;
// allocate the empty network
pNtkNew = Abc_NtkAlloc( ABC_NTK_NETLIST_SOP );
// set the specs
pNtkNew->pName = util_strsav( pName );
pNtkNew->pSpec = util_strsav( pName );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Finalizes the network using the existing network as a model.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pLatch;
int i;
assert( Abc_NtkIsNetlist(pNtk) );
// fix the net drivers
Abc_NtkFixNonDrivenNets( pNtk );
// create the names table
Abc_NtkCreateCioNamesTable( pNtk );
// add latches to the CI/CO arrays
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
Vec_PtrPush( pNtk->vCis, pLatch );
Vec_PtrPush( pNtk->vCos, pLatch );
}
}
/**Function*************************************************************
Synopsis [Duplicate the network.]
Description []
......@@ -173,46 +221,28 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
int i, k;
if ( pNtk == NULL )
return NULL;
assert( !Abc_NtkIsSeq(pNtk) );
// start the network
pNtkNew = Abc_NtkAlloc( pNtk->Type );
// duplicate the name and the spec
pNtkNew->pName = util_strsav(pNtk->pName);
pNtkNew->pSpec = util_strsav(pNtk->pSpec);
// duplicate the objects
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->Type );
// duplicate the nets and nodes
Abc_NtkForEachObj( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
if ( pObj->pCopy == NULL )
Abc_NtkDupObj(pNtkNew, pObj);
// connect the objects
Abc_NtkForEachObj( pNtk, pObj, i )
Abc_ObjForEachFanin( pObj, pFanin, k )
{
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
if ( Abc_ObjFaninC( pObj, k ) )
Abc_ObjSetFaninC( pObj->pCopy, k );
// latch numbers on edges are not copied
}
// postprocess
if ( Abc_NtkIsNetlist(pNtk) )
{
// mark the PI/PO nets of the new network
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkMarkNetPi( pObj->pCopy );
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NtkMarkNetPo( pObj->pCopy );
}
else
// for AIGs copy the complemented attributes
if ( Abc_NtkIsAig(pNtk) )
{
// add latches to the PI/PO lists to work as CIs/COs
Abc_NtkForEachLatch( pNtk, pObj, i )
{
Vec_PtrPush( pNtkNew->vPis, pObj->pCopy );
Vec_PtrPush( pNtkNew->vPos, pObj->pCopy );
}
// set the data pointers and complemented attributes
Abc_NtkForEachObj( pNtk, pObj, i )
Abc_ObjForEachFanin( pObj, pFanin, k )
if ( Abc_ObjFaninC( pObj, k ) )
Abc_ObjSetFaninC( pObj->pCopy, k );
// add the nodes to the structural hashing table
// TODO ???
}
// copy the CI/CO names if saved
if ( !Abc_NtkIsNetlist(pNtk) )
Abc_NtkDupNameArrays( pNtk, pNtkNew );
// copy the timing info
Abc_ManTimeDup( pNtk, pNtkNew );
// duplicate the EXDC Ntk
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
......@@ -238,24 +268,15 @@ Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAll
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin;
char Buffer[1000];
int i, k, Output;
int i, k;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsAig(pNtk) );
assert( Abc_ObjIsTerm(pNode) || Abc_ObjIsLatch(pNode) );
// get the number of this output
Output = -1;
Abc_NtkForEachCo( pNtk, pObj, i )
if ( pObj == pNode )
{
Output = i;
break;
}
assert( Output >= 0 );
assert( Abc_ObjIsCo(pNode) );
// start the network
pNtkNew = Abc_NtkAlloc( pNtk->Type );
// duplicate the name and the spec
sprintf( Buffer, "%s_%s", pNtk->pName, Abc_NtkNameCo(pNtk,Output) );
// set the name
sprintf( Buffer, "%s_%s", pNtk->pName, Abc_ObjName(pNode) );
pNtkNew->pName = util_strsav(Buffer);
// collect the nodes in the TFI of the output
......@@ -265,8 +286,8 @@ Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAll
{
if ( fUseAllCis || Abc_NodeIsTravIdCurrent(pObj) ) // TravId is set by DFS
{
pObj->pCopy = Abc_NtkCreateTermPi(pNtkNew);
Abc_NtkLogicStoreName( pObj->pCopy, Abc_NtkNameCi(pNtk, i) );
pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
}
}
// establish connection between the constant nodes
......@@ -291,10 +312,11 @@ Abc_Ntk_t * Abc_NtkSplitOutput( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int fUseAll
}
}
Vec_PtrFree( vNodes );
// add the PO corresponding to this output
pNode->pCopy = Abc_NtkCreateTermPo( pNtkNew );
pNode->pCopy = Abc_NtkCreatePo( pNtkNew );
Abc_ObjAddFanin( pNode->pCopy, Abc_ObjFanin0(pNode)->pCopy );
Abc_NtkLogicStoreName( pNode->pCopy, Abc_NtkNameCo(pNtk, Output) );
Abc_NtkLogicStoreName( pNode->pCopy, Abc_ObjName(pNode) );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
......@@ -343,17 +365,15 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
Abc_NtkDelete( pNtk->pExdc );
// free the arrays
Vec_PtrFree( pNtk->vObjs );
Vec_PtrFree( pNtk->vLatches );
Vec_PtrFree( pNtk->vPis );
Vec_PtrFree( pNtk->vPos );
Vec_PtrFree( pNtk->vNamesPi );
Vec_PtrFree( pNtk->vNamesPo );
Vec_PtrFree( pNtk->vNamesLatch );
Vec_PtrFree( pNtk->vLats );
Vec_PtrFree( pNtk->vCis );
Vec_PtrFree( pNtk->vCos );
Vec_PtrFree( pNtk->vPtrTemp );
Vec_IntFree( pNtk->vIntTemp );
Vec_StrFree( pNtk->vStrTemp );
// free the hash table of Obj name into Obj ID
stmm_free_table( pNtk->tName2Net );
stmm_free_table( pNtk->tObj2Name );
TotalMemory = 0;
TotalMemory += Extra_MmFlexReadMemUsage(pNtk->pMmNames);
TotalMemory += Extra_MmFixedReadMemUsage(pNtk->pMmObj);
......@@ -367,17 +387,71 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
if ( pNtk->pManTime )
Abc_ManTimeStop( pNtk->pManTime );
// start the functionality manager
if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
Extra_MmFlexStop( pNtk->pManFunc, 0 );
else if ( Abc_NtkIsLogicBdd(pNtk) )
Extra_StopManager( pNtk->pManFunc );
else if ( Abc_NtkIsAig(pNtk) )
Abc_AigFree( pNtk->pManFunc );
else if ( !Abc_NtkIsLogicMap(pNtk) )
else if ( !Abc_NtkIsMapped(pNtk) )
assert( 0 );
free( pNtk );
}
/**Function*************************************************************
Synopsis [Reads the verilog file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNets;
Abc_Obj_t * pNet, * pNode;
int i;
// check for non-driven nets
vNets = Vec_PtrAlloc( 100 );
Abc_NtkForEachNet( pNtk, pNet, i )
{
if ( Abc_ObjFaninNum(pNet) > 0 )
continue;
// add the constant 0 driver
pNode = Abc_NtkCreateNode( pNtk );
// set the constant function
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") );
// add the fanout net
Abc_ObjAddFanin( pNet, pNode );
// add the net to those for which the warning will be printed
Vec_PtrPush( vNets, pNet->pData );
}
// print the warning
if ( vNets->nSize > 0 )
{
printf( "Constant-zero drivers were added to %d non-driven nets:\n", vNets->nSize );
for ( i = 0; i < vNets->nSize; i++ )
{
if ( i == 0 )
printf( "%s", vNets->pArray[i] );
else if ( i == 1 )
printf( ", %s", vNets->pArray[i] );
else if ( i == 2 )
{
printf( ", %s, etc.", vNets->pArray[i] );
break;
}
}
printf( "\n" );
}
Vec_PtrFree( vNets );
}
......@@ -451,24 +525,22 @@ void Abc_ObjAdd( Abc_Obj_t * pObj )
}
else if ( Abc_ObjIsNode(pObj) )
{
assert( pObj->Subtype == 0 );
pNtk->nNodes++;
}
else if ( Abc_ObjIsLatch(pObj) )
{
Vec_PtrPush( pNtk->vLatches, pObj );
Vec_PtrPush( pNtk->vLats, pObj );
pNtk->nLatches++;
}
else if ( Abc_ObjIsTerm(pObj) )
else if ( Abc_ObjIsPi(pObj) )
{
// if it is PIs/POs, add it
assert( !(Abc_ObjIsPi(pObj) && Abc_ObjIsPo(pObj)) );
if ( Abc_ObjIsPi(pObj) )
Vec_PtrPush( pNtk->vPis, pObj ), pNtk->nPis++;
else if ( Abc_ObjIsPo(pObj) )
Vec_PtrPush( pNtk->vPos, pObj ), pNtk->nPos++;
else
assert( 0 );
Vec_PtrPush( pNtk->vCis, pObj );
pNtk->nPis++;
}
else if ( Abc_ObjIsPo(pObj) )
{
Vec_PtrPush( pNtk->vCos, pObj );
pNtk->nPos++;
}
else
{
......@@ -492,14 +564,13 @@ Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj )
{
Abc_Obj_t * pObjNew;
pObjNew = Abc_ObjAlloc( pNtkNew, pObj->Type );
pObjNew->Subtype = pObj->Subtype;
if ( Abc_ObjIsNode(pObj) ) // copy the function
{
if ( Abc_NtkIsNetlist(pNtkNew) || Abc_NtkIsLogicSop(pNtkNew) )
if ( Abc_NtkIsSop(pNtkNew) )
pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pObj->pData );
else if ( Abc_NtkIsLogicBdd(pNtkNew) )
pObjNew->pData = Cudd_bddTransfer(pObj->pNtk->pManFunc, pNtkNew->pManFunc, pObj->pData), Cudd_Ref(pObjNew->pData);
else if ( Abc_NtkIsLogicMap(pNtkNew) )
else if ( Abc_NtkIsMapped(pNtkNew) )
pObjNew->pData = pObj->pData;
else if ( !Abc_NtkIsAig(pNtkNew) )
assert( 0 );
......@@ -566,11 +637,7 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
pNtk->nLatches--;
assert( 0 ); // currently do not allow removing latches
}
else if ( Abc_ObjIsTerm(pObj) )
{
assert( 0 ); // currently do not allow removing latches
}
else
else
assert( 0 );
// recycle the net itself
Abc_ObjRecycle( pObj );
......@@ -579,100 +646,6 @@ void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
/**Function*************************************************************
Synopsis [Adds a new PI net to the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkMarkNetPi( Abc_Obj_t * pObj )
{
assert( Abc_NtkIsNetlist(pObj->pNtk) );
assert( Abc_ObjIsNet(pObj) );
assert( pObj->Id >= 0 );
Abc_ObjSetSubtype( pObj, ABC_OBJ_SUBTYPE_PI );
Vec_PtrPush( pObj->pNtk->vPis, pObj );
pObj->pNtk->nPis++;
}
/**Function*************************************************************
Synopsis [Adds a new PO Obj to the Objwork.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkMarkNetPo( Abc_Obj_t * pObj )
{
assert( Abc_NtkIsNetlist(pObj->pNtk) );
assert( Abc_ObjIsNet(pObj) );
assert( pObj->Id >= 0 );
Abc_ObjSetSubtype( pObj, ABC_OBJ_SUBTYPE_PO );
Vec_PtrPush( pObj->pNtk->vPos, pObj );
pObj->pNtk->nPos++;
}
/**Function*************************************************************
Synopsis [Adds a new PO node to the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NtkAddPoNode( Abc_Obj_t * pDriver )
{
Abc_Obj_t * pNodePo, * pDriverR = Abc_ObjRegular(pDriver);
Abc_Ntk_t * pNtk = pDriverR->pNtk;
// this function only works for logic networks
assert( !Abc_NtkIsNetlist(pNtk) );
assert( pDriverR->Id >= 0 );
// the cannot be a PO node
assert( !Abc_ObjIsPo(pDriverR) );
// create a new PO node
pNodePo = Abc_NtkCreateTermPo( pNtk );
// create the fanin (possibly complemented)
Abc_ObjAddFanin( pNodePo, pDriver );
return pNodePo;
}
/**Function*************************************************************
Synopsis [Removes a node from the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkRemovePoNode( Abc_Obj_t * pNode )
{
assert( Abc_ObjFanoutNum(pNode) == 0 );
assert( Abc_ObjIsPo(pNode) );
Abc_ObjDeleteFanin( pNode, Abc_ObjFanin0(pNode) );
pNode->pNtk->vObjs->pArray[ pNode->Id ] = NULL;
pNode->pNtk->nNodes--;
pNode->pNtk->nPos--;
Abc_ObjRecycle( pNode );
}
/**Function*************************************************************
......@@ -687,12 +660,12 @@ void Abc_NtkRemovePoNode( Abc_Obj_t * pNode )
***********************************************************************/
Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName )
{
Abc_Obj_t * pNode, * pDriver;
Abc_Obj_t * pObj, * pDriver;
int i, Num;
// check if the node is among CIs
Abc_NtkForEachCi( pNtk, pNode, i )
Abc_NtkForEachCi( pNtk, pObj, i )
{
if ( strcmp( Abc_NtkNameCi(pNtk,i), pName ) == 0 )
if ( strcmp( Abc_ObjName(pObj), pName ) == 0 )
{
if ( i < Abc_NtkPiNum(pNtk) )
printf( "Node \"%s\" is a primary input.\n", pName );
......@@ -702,11 +675,11 @@ Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName )
}
}
// search the node among COs
Abc_NtkForEachCo( pNtk, pNode, i )
Abc_NtkForEachCo( pNtk, pObj, i )
{
if ( strcmp( Abc_NtkNameCo(pNtk,i), pName ) == 0 )
if ( strcmp( Abc_ObjName(pObj), pName ) == 0 )
{
pDriver = Abc_ObjFanin0(pNode);
pDriver = Abc_ObjFanin0(pObj);
if ( !Abc_ObjIsNode(pDriver) )
{
printf( "Node \"%s\" does not have logic associated with it.\n", pName );
......@@ -727,18 +700,18 @@ Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName )
printf( "The node \"%s\" with ID %d is not in the current network.\n", pName, Num );
return NULL;
}
pNode = Abc_NtkObj( pNtk, Num );
if ( pNode == NULL )
pObj = Abc_NtkObj( pNtk, Num );
if ( pObj == NULL )
{
printf( "The node \"%s\" with ID %d has been removed from the current network.\n", pName, Num );
return NULL;
}
if ( !Abc_ObjIsNode(pNode) )
if ( !Abc_ObjIsNode(pObj) )
{
printf( "Object with ID %d is not a node.\n", Num );
return NULL;
}
return pNode;
return pObj;
}
/**Function*************************************************************
......@@ -759,7 +732,7 @@ Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName )
// search the node among COs
Abc_NtkForEachCo( pNtk, pNode, i )
{
if ( strcmp( Abc_NtkNameCo(pNtk,i), pName ) == 0 )
if ( strcmp( Abc_ObjName(pNode), pName ) == 0 )
return pNode;
}
return NULL;
......@@ -803,7 +776,7 @@ Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName )
if ( pNet = Abc_NtkFindNet( pNtk, pName ) )
return pNet;
// create a new net
pNet = Abc_ObjAlloc( pNtk, ABC_OBJ_TYPE_NET );
pNet = Abc_ObjAlloc( pNtk, ABC_OBJ_NET );
pNet->pData = Abc_NtkRegisterName( pNtk, pName );
Abc_ObjAdd( pNet );
return pNet;
......@@ -823,7 +796,7 @@ Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName )
Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_TYPE_NODE );
pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_NODE );
Abc_ObjAdd( pObj );
return pObj;
}
......@@ -839,11 +812,10 @@ Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NtkCreateTermPi( Abc_Ntk_t * pNtk )
Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_TYPE_TERM );
Abc_ObjSetSubtype( pObj, ABC_OBJ_SUBTYPE_PI );
pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_PI );
Abc_ObjAdd( pObj );
return pObj;
}
......@@ -859,13 +831,11 @@ Abc_Obj_t * Abc_NtkCreateTermPi( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NtkCreateTermPo( Abc_Ntk_t * pNtk )
Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_TYPE_TERM );
Abc_ObjSetSubtype( pObj, ABC_OBJ_SUBTYPE_PO );
pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_PO );
Abc_ObjAdd( pObj );
// Abc_NtkAddPo( pObj );
return pObj;
}
......@@ -883,7 +853,7 @@ Abc_Obj_t * Abc_NtkCreateTermPo( Abc_Ntk_t * pNtk )
Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_TYPE_LATCH );
pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_LATCH );
Abc_ObjAdd( pObj );
return pObj;
}
......@@ -902,13 +872,12 @@ Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk )
Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
if ( Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 0\n" );
else if ( Abc_NtkIsLogicBdd(pNtk) )
pNode->pData = Cudd_ReadLogicZero(pNtk->pManFunc), Cudd_Ref( pNode->pData );
else if ( Abc_NtkIsLogicMap(pNtk) )
else if ( Abc_NtkIsMapped(pNtk) )
pNode->pData = Mio_LibraryReadConst0(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
else
assert( 0 );
......@@ -929,13 +898,12 @@ Abc_Obj_t * Abc_NodeCreateConst0( Abc_Ntk_t * pNtk )
Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
if ( Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 1\n" );
else if ( Abc_NtkIsLogicBdd(pNtk) )
pNode->pData = Cudd_ReadOne(pNtk->pManFunc), Cudd_Ref( pNode->pData );
else if ( Abc_NtkIsLogicMap(pNtk) )
else if ( Abc_NtkIsMapped(pNtk) )
pNode->pData = Mio_LibraryReadConst1(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
else
assert( 0 );
......@@ -956,14 +924,14 @@ Abc_Obj_t * Abc_NodeCreateConst1( Abc_Ntk_t * pNtk )
Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
{
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) );
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
Abc_ObjAddFanin( pNode, pFanin );
if ( Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, "0 1\n" );
else if ( Abc_NtkIsLogicBdd(pNtk) )
pNode->pData = Cudd_Not(Cudd_bddIthVar(pNtk->pManFunc,0)), Cudd_Ref( pNode->pData );
else if ( Abc_NtkIsLogicMap(pNtk) )
else if ( Abc_NtkIsMapped(pNtk) )
pNode->pData = Mio_LibraryReadInv(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
else
assert( 0 );
......@@ -984,14 +952,14 @@ Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
{
Abc_Obj_t * pNode;
assert( Abc_NtkIsLogic(pNtk) );
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
pNode = Abc_NtkCreateNode( pNtk );
Abc_ObjAddFanin( pNode, pFanin );
if ( Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, "1 1\n" );
else if ( Abc_NtkIsLogicBdd(pNtk) )
pNode->pData = Cudd_bddIthVar(pNtk->pManFunc,0), Cudd_Ref( pNode->pData );
else if ( Abc_NtkIsLogicMap(pNtk) )
else if ( Abc_NtkIsMapped(pNtk) )
pNode->pData = Mio_LibraryReadBuf(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
else
assert( 0 );
......@@ -1017,7 +985,7 @@ Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
pNode = Abc_NtkCreateNode( pNtk );
for ( i = 0; i < vFanins->nSize; i++ )
Abc_ObjAddFanin( pNode, vFanins->pArray[i] );
if ( Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
{
char * pSop;
pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 );
......@@ -1066,7 +1034,7 @@ Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
pNode = Abc_NtkCreateNode( pNtk );
for ( i = 0; i < vFanins->nSize; i++ )
Abc_ObjAddFanin( pNode, vFanins->pArray[i] );
if ( Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
{
char * pSop;
pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 );
......@@ -1115,7 +1083,7 @@ Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t *
Abc_ObjAddFanin( pNode, pNodeC );
Abc_ObjAddFanin( pNode, pNode1 );
Abc_ObjAddFanin( pNode, pNode0 );
if ( Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
pNode->pData = Abc_SopRegister( pNtk->pManFunc, "11- 1\n0-1 1\n" );
else if ( Abc_NtkIsLogicBdd(pNtk) )
pNode->pData = Cudd_bddIte(pNtk->pManFunc,Cudd_bddIthVar(pNtk->pManFunc,0),Cudd_bddIthVar(pNtk->pManFunc,1),Cudd_bddIthVar(pNtk->pManFunc,2)), Cudd_Ref( pNode->pData );
......@@ -1164,13 +1132,13 @@ bool Abc_NodeIsConst0( Abc_Obj_t * pNode )
Abc_Ntk_t * pNtk = pNode->pNtk;
assert(Abc_ObjIsNode(pNode));
assert(Abc_NodeIsConst(pNode));
if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
return Abc_SopIsConst0(pNode->pData);
if ( Abc_NtkIsLogicBdd(pNtk) )
return Cudd_IsComplement(pNode->pData);
if ( Abc_NtkIsAig(pNtk) )
return Abc_ObjNot(pNode) == Abc_AigConst1(pNode->pNtk->pManFunc);
if ( Abc_NtkIsLogicMap(pNtk) )
if ( Abc_NtkIsMapped(pNtk) )
return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
assert( 0 );
return 0;
......@@ -1192,13 +1160,13 @@ bool Abc_NodeIsConst1( Abc_Obj_t * pNode )
Abc_Ntk_t * pNtk = pNode->pNtk;
assert(Abc_ObjIsNode(pNode));
assert(Abc_NodeIsConst(pNode));
if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
return Abc_SopIsConst1(pNode->pData);
if ( Abc_NtkIsLogicBdd(pNtk) )
return !Cudd_IsComplement(pNode->pData);
if ( Abc_NtkIsAig(pNtk) )
return pNode == Abc_AigConst1(pNode->pNtk->pManFunc);
if ( Abc_NtkIsLogicMap(pNtk) )
if ( Abc_NtkIsMapped(pNtk) )
return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
assert( 0 );
return 0;
......@@ -1221,13 +1189,13 @@ bool Abc_NodeIsBuf( Abc_Obj_t * pNode )
assert(Abc_ObjIsNode(pNode));
if ( Abc_ObjFaninNum(pNode) != 1 )
return 0;
if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
return Abc_SopIsBuf(pNode->pData);
if ( Abc_NtkIsLogicBdd(pNtk) )
return !Cudd_IsComplement(pNode->pData);
if ( Abc_NtkIsAig(pNtk) )
return 0;
if ( Abc_NtkIsLogicMap(pNtk) )
if ( Abc_NtkIsMapped(pNtk) )
return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
assert( 0 );
return 0;
......@@ -1250,13 +1218,13 @@ bool Abc_NodeIsInv( Abc_Obj_t * pNode )
assert(Abc_ObjIsNode(pNode));
if ( Abc_ObjFaninNum(pNode) != 1 )
return 0;
if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) )
if ( Abc_NtkIsSop(pNtk) )
return Abc_SopIsInv(pNode->pData);
if ( Abc_NtkIsLogicBdd(pNtk) )
return Cudd_IsComplement(pNode->pData);
if ( Abc_NtkIsAig(pNtk) )
return 0;
if ( Abc_NtkIsLogicMap(pNtk) )
if ( Abc_NtkIsMapped(pNtk) )
return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
assert( 0 );
return 0;
......
......@@ -24,10 +24,11 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
static void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
static int Abc_NtkGetLevelNum_rec( Abc_Obj_t * pNode );
static bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode );
static void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
static void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
static void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLevels );
static int Abc_NtkGetLevelNum_rec( Abc_Obj_t * pNode );
static bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......@@ -37,7 +38,8 @@ static bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode );
Synopsis [Returns the DFS ordered array of logic nodes.]
Description [Collects only the internal nodes, leaving out PIs, POs and latches.]
Description [Collects only the internal nodes, leaving CIs and CO.
However it marks with the current TravId both CIs and COs.]
SideEffects []
......@@ -47,28 +49,16 @@ static bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode );
Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNet, * pNode;
int i, fMadeComb;
Abc_Obj_t * pNode;
int i;
// set the traversal ID
Abc_NtkIncrementTravId( pNtk );
// start the array of nodes
vNodes = Vec_PtrAlloc( 100 );
// go through the PO nodes and call for each of them
if ( Abc_NtkIsNetlist(pNtk) )
{
fMadeComb = Abc_NtkMakeComb( pNtk );
Abc_NtkForEachPo( pNtk, pNet, i )
{
if ( Abc_ObjIsCi(pNet) )
continue;
Abc_NtkDfs_rec( Abc_ObjFanin0(pNet), vNodes );
}
if ( fMadeComb ) Abc_NtkMakeSeq( pNtk );
}
else
Abc_NtkForEachCo( pNtk, pNode, i )
{
Abc_NtkForEachCo( pNtk, pNode, i )
Abc_NtkDfs_rec( Abc_ObjFanin0(pNode), vNodes );
Abc_NodeSetTravIdCurrent( pNode );
Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(Abc_ObjFanin0(pNode)), vNodes );
}
return vNodes;
}
......@@ -87,27 +77,21 @@ Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk )
Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes )
{
Vec_Ptr_t * vNodes;
int i, fMadeComb;
int i;
// set the traversal ID
Abc_NtkIncrementTravId( pNtk );
// start the array of nodes
vNodes = Vec_PtrAlloc( 100 );
// go through the PO nodes and call for each of them
if ( Abc_NtkIsNetlist(pNtk) )
for ( i = 0; i < nNodes; i++ )
{
fMadeComb = Abc_NtkMakeComb( pNtk );
for ( i = 0; i < nNodes; i++ )
if ( Abc_ObjIsCo(ppNodes[i]) )
{
Abc_NodeSetTravIdCurrent(ppNodes[i]);
Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(Abc_ObjFanin0(ppNodes[i])), vNodes );
}
else if ( Abc_ObjIsNode(ppNodes[i]) )
Abc_NtkDfs_rec( ppNodes[i], vNodes );
if ( fMadeComb )
Abc_NtkMakeSeq( pNtk );
}
else
{
for ( i = 0; i < nNodes; i++ )
if ( Abc_ObjIsCo(ppNodes[i]) )
Abc_NtkDfs_rec( Abc_ObjFanin0(ppNodes[i]), vNodes );
else if ( Abc_ObjIsNode(ppNodes[i]) )
Abc_NtkDfs_rec( ppNodes[i], vNodes );
}
return vNodes;
}
......@@ -127,35 +111,19 @@ void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
Abc_Obj_t * pFanin;
int i;
assert( !Abc_ObjIsComplement( pNode ) );
assert( !Abc_ObjIsNet(pNode) );
// if this node is already visited, skip
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return;
// mark the node as visited
Abc_NodeSetTravIdCurrent( pNode );
// skip the PI
if ( Abc_ObjIsPi(pNode) || Abc_ObjIsLatch(pNode) )
// skip the CI
if ( Abc_ObjIsCi(pNode) )
return;
assert( Abc_ObjIsNode( pNode ) );
// visit the transitive fanin of the node
if ( Abc_NtkIsNetlist(pNode->pNtk) )
{
Abc_ObjForEachFanin( pNode, pFanin, i )
{
if ( Abc_ObjIsCi(pFanin) )
continue;
pFanin = Abc_ObjFanin0(pFanin);
Abc_NtkDfs_rec( pFanin, vNodes );
}
}
else
{
Abc_ObjForEachFanin( pNode, pFanin, i )
Abc_NtkDfs_rec( pFanin, vNodes );
}
Abc_ObjForEachFanin( pNode, pFanin, i )
Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(pFanin), vNodes );
// add the node after the fanins have been added
Vec_PtrPush( vNodes, pNode );
}
......@@ -165,7 +133,8 @@ void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
Synopsis [Returns the DFS ordered array of logic nodes.]
Description [Collects only the internal nodes, leaving out PIs, POs and latches.]
Description [Collects only the internal nodes, leaving CIs and CO.
However it marks with the current TravId both CIs and COs.]
SideEffects []
......@@ -184,7 +153,10 @@ Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk )
vNodes = Vec_PtrAlloc( 100 );
// go through the PO nodes and call for each of them
Abc_NtkForEachCo( pNtk, pNode, i )
{
Abc_NodeSetTravIdCurrent( pNode );
Abc_AigDfs_rec( Abc_ObjFanin0(pNode), vNodes );
}
return vNodes;
}
......@@ -203,21 +175,20 @@ void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
Abc_Obj_t * pFanin;
int i;
assert( !Abc_ObjIsComplement( pNode ) );
// if this node is already visited, skip
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return;
// mark the node as visited
Abc_NodeSetTravIdCurrent( pNode );
// skip the PI
if ( Abc_ObjIsPi(pNode) || Abc_ObjIsLatch(pNode) )
if ( Abc_ObjIsCi(pNode) )
return;
assert( Abc_ObjIsNode( pNode ) );
// visit the transitive fanin of the node
Abc_ObjForEachFanin( pNode, pFanin, i )
Abc_AigDfs_rec( pFanin, vNodes );
// visit the equivalent nodes
if ( Abc_NodeIsChoice( pNode ) )
if ( Abc_NodeIsAigChoice( pNode ) )
for ( pFanin = pNode->pData; pFanin; pFanin = pFanin->pData )
Abc_AigDfs_rec( pFanin, vNodes );
// add the node after the fanins have been added
......@@ -235,22 +206,51 @@ void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
SeeAlso []
***********************************************************************/
void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLevels )
Vec_Ptr_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi )
{
Vec_Ptr_t * vLevels;
Abc_Obj_t * pFanout;
int i;
assert( fTfi == 0 );
assert( !Abc_NtkIsNetlist(pNode->pNtk) );
// set the traversal ID
Abc_NtkIncrementTravId( pNode->pNtk );
vLevels = Vec_PtrAlloc( 100 );
if ( Abc_ObjIsNode(pNode) )
Abc_DfsLevelizedTfo_rec( pNode, vLevels );
else
{
Abc_NodeSetTravIdCurrent( pNode );
Abc_ObjForEachFanout( pNode, pFanout, i )
Abc_DfsLevelizedTfo_rec( pFanout, vLevels );
}
return vLevels;
}
/**Function*************************************************************
Synopsis [Collects nodes in the DFS manner by level.]
Description [The number of levels should be set!!!]
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLevels )
{
Abc_Obj_t * pFanout;
int i;
// if this node is already visited, skip
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return;
// mark the node as visited
Abc_NodeSetTravIdCurrent( pNode );
// skip the terminals
if ( Abc_ObjIsTerm(pNode) || Abc_ObjIsLatch(pNode) )
if ( Abc_ObjIsCo(pNode) )
return;
assert( Abc_ObjIsNode(pNode) );
// add the node to the structure
if ( vLevels->nSize <= (int)pNode->Level )
{
......@@ -260,40 +260,11 @@ void Abc_DfsLevelizedTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLevels )
vLevels->nSize = pNode->Level + 1;
}
Vec_PtrPush( vLevels->pArray[pNode->Level], pNode );
// visit the TFO
Abc_ObjForEachFanout( pNode, pFanout, i )
Abc_DfsLevelizedTfo_rec( pFanout, vLevels );
}
/**Function*************************************************************
Synopsis [Collects nodes in the DFS manner by level.]
Description [The number of levels should be set!!!]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi )
{
Vec_Ptr_t * vLevels;
Abc_Obj_t * pFanout;
int i;
assert( fTfi == 0 );
// set the traversal ID
Abc_NtkIncrementTravId( pNode->pNtk );
vLevels = Vec_PtrAlloc( 100 );
if ( Abc_ObjIsNode(pNode) )
Abc_DfsLevelizedTfo_rec( pNode, vLevels );
else
Abc_ObjForEachFanout( pNode, pFanout, i )
Abc_DfsLevelizedTfo_rec( pFanout, vLevels );
return vLevels;
}
/**Function*************************************************************
......@@ -308,40 +279,17 @@ Vec_Ptr_t * Abc_DfsLevelized( Abc_Obj_t * pNode, bool fTfi )
***********************************************************************/
int Abc_NtkGetLevelNum( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNet, * pNode, * pDriver;
unsigned LevelsMax;
int i, fMadeComb;
Abc_Obj_t * pNode;
int i, LevelsMax;
// set the traversal ID for this traversal
Abc_NtkIncrementTravId( pNtk );
// perform the traversal
LevelsMax = 0;
if ( Abc_NtkIsNetlist(pNtk) )
Abc_NtkForEachNode( pNtk, pNode, i )
{
fMadeComb = Abc_NtkMakeComb( pNtk );
Abc_NtkForEachPo( pNtk, pNet, i )
{
if ( Abc_ObjIsCi(pNet) )
continue;
pDriver = Abc_ObjFanin0( pNet );
Abc_NtkGetLevelNum_rec( pDriver );
if ( LevelsMax < pDriver->Level )
LevelsMax = pDriver->Level;
}
if ( fMadeComb ) Abc_NtkMakeSeq( pNtk );
}
else
{
// Abc_NtkForEachCo( pNtk, pNode, i )
Abc_NtkForEachNode( pNtk, pNode, i )
{
// pDriver = Abc_ObjFanin0( pNode );
pDriver = pNode;
Abc_NtkGetLevelNum_rec( pDriver );
if ( LevelsMax < pDriver->Level )
LevelsMax = pDriver->Level;
}
Abc_NtkGetLevelNum_rec( pNode );
if ( LevelsMax < (int)pNode->Level )
LevelsMax = (int)pNode->Level;
}
return LevelsMax;
}
......@@ -361,40 +309,23 @@ int Abc_NtkGetLevelNum_rec( Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanin;
int i;
assert( !Abc_ObjIsComplement( pNode ) );
assert( !Abc_ObjIsNet(pNode) );
// skip the PI
if ( Abc_ObjIsPi(pNode) || Abc_ObjIsLatch(pNode) )
if ( Abc_ObjIsCi(pNode) )
return 0;
assert( Abc_ObjIsNode( pNode ) );
// if this node is already visited, return
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return pNode->Level;
// mark the node as visited
Abc_NodeSetTravIdCurrent( pNode );
// visit the transitive fanin
pNode->Level = 0;
if ( Abc_NtkIsNetlist(pNode->pNtk) )
{
Abc_ObjForEachFanin( pNode, pFanin, i )
{
if ( Abc_ObjIsCi(pFanin) )
continue;
pFanin = Abc_ObjFanin0(pFanin);
Abc_NtkGetLevelNum_rec( pFanin );
if ( pNode->Level < pFanin->Level )
pNode->Level = pFanin->Level;
}
}
else
Abc_ObjForEachFanin( pNode, pFanin, i )
{
Abc_ObjForEachFanin( pNode, pFanin, i )
{
Abc_NtkGetLevelNum_rec( pFanin );
if ( pNode->Level < pFanin->Level )
pNode->Level = pFanin->Level;
}
Abc_NtkGetLevelNum_rec( Abc_ObjFanin0Ntk(pFanin) );
if ( pNode->Level < pFanin->Level )
pNode->Level = pFanin->Level;
}
pNode->Level++;
return pNode->Level;
......@@ -421,8 +352,8 @@ int Abc_NtkGetLevelNum_rec( Abc_Obj_t * pNode )
***********************************************************************/
bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNet, * pNode;
int fAcyclic, fMadeComb, i;
Abc_Obj_t * pNode;
int fAcyclic, i;
// set the traversal ID for this DFS ordering
Abc_NtkIncrementTravId( pNtk );
Abc_NtkIncrementTravId( pNtk );
......@@ -431,38 +362,16 @@ bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk )
// pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited"
// traverse the network to detect cycles
fAcyclic = 1;
if ( Abc_NtkIsNetlist(pNtk) )
{
fMadeComb = Abc_NtkMakeComb( pNtk );
Abc_NtkForEachPo( pNtk, pNet, i )
{
if ( Abc_ObjIsCi(pNet) )
continue;
pNode = Abc_ObjFanin0( pNet );
if ( Abc_NodeIsTravIdPrevious(pNode) )
continue;
// traverse the output logic cone to detect the combinational loops
if ( (fAcyclic = Abc_NtkIsAcyclic_rec( pNode )) == 0 )
{ // stop as soon as the first loop is detected
fprintf( stdout, " (the output node)\n" );
break;
}
}
if ( fMadeComb ) Abc_NtkMakeSeq( pNtk );
}
else
Abc_NtkForEachCo( pNtk, pNode, i )
{
Abc_NtkForEachCo( pNtk, pNode, i )
{
pNode = Abc_ObjFanin0( pNode );
if ( Abc_NodeIsTravIdPrevious(pNode) )
continue;
// traverse the output logic cone to detect the combinational loops
if ( (fAcyclic = Abc_NtkIsAcyclic_rec( pNode )) == 0 )
{ // stop as soon as the first loop is detected
fprintf( stdout, " (the output node)\n" );
break;
}
pNode = Abc_ObjFanin0Ntk(Abc_ObjFanin0(pNode));
if ( Abc_NodeIsTravIdPrevious(pNode) )
continue;
// traverse the output logic cone to detect the combinational loops
if ( ( fAcyclic = Abc_NtkIsAcyclic_rec(pNode) ) == 0 )
{ // stop as soon as the first loop is detected
fprintf( stdout, " (the output node)\n" );
break;
}
}
return fAcyclic;
......@@ -484,13 +393,11 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
Abc_Ntk_t * pNtk = pNode->pNtk;
Abc_Obj_t * pFanin;
int fAcyclic, i;
assert( !Abc_ObjIsComplement( pNode ) );
assert( !Abc_ObjIsNet(pNode) );
// skip the PI
if ( Abc_ObjIsPi(pNode) || Abc_ObjIsLatch(pNode) )
if ( Abc_ObjIsCi(pNode) )
return 1;
assert( Abc_ObjIsNode( pNode ) );
// make sure the node is not visited
assert( !Abc_NodeIsTravIdPrevious(pNode) );
// check if the node is part of the combinational loop
......@@ -503,47 +410,22 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
}
// mark this node as a node on the current path
Abc_NodeSetTravIdCurrent( pNode );
// visit the transitive fanin
if ( Abc_NtkIsNetlist(pNode->pNtk) )
{
Abc_ObjForEachFanin( pNode, pFanin, i )
{
if ( Abc_ObjIsCi(pFanin) )
continue;
pFanin = Abc_ObjFanin0(pFanin);
// make sure there is no mixing of networks
assert( pFanin->pNtk == pNode->pNtk );
// check if the fanin is visited
if ( Abc_NodeIsTravIdPrevious(pFanin) )
continue;
// traverse searching for the loop
fAcyclic = Abc_NtkIsAcyclic_rec( pFanin );
// return as soon as the loop is detected
if ( fAcyclic == 0 )
{
fprintf( stdout, " <-- %s", Abc_ObjName(pNode) );
return 0;
}
}
}
else
Abc_ObjForEachFanin( pNode, pFanin, i )
{
Abc_ObjForEachFanin( pNode, pFanin, i )
pFanin = Abc_ObjFanin0Ntk(pFanin);
// make sure there is no mixing of networks
assert( pFanin->pNtk == pNode->pNtk );
// check if the fanin is visited
if ( Abc_NodeIsTravIdPrevious(pFanin) )
continue;
// traverse searching for the loop
fAcyclic = Abc_NtkIsAcyclic_rec( pFanin );
// return as soon as the loop is detected
if ( fAcyclic == 0 )
{
// make sure there is no mixing of networks
assert( pFanin->pNtk == pNode->pNtk );
// check if the fanin is visited
if ( Abc_NodeIsTravIdPrevious(pFanin) )
continue;
// traverse searching for the loop
fAcyclic = Abc_NtkIsAcyclic_rec( pFanin );
// return as soon as the loop is detected
if ( fAcyclic == 0 )
{
fprintf( stdout, " <-- %s", Abc_ObjName(pNode) );
return 0;
}
fprintf( stdout, " <-- %s", Abc_ObjName(pNode) );
return 0;
}
}
// mark this node as a visited node
......
......@@ -103,6 +103,7 @@ Abc_Ntk_t * Abc_NtkDsdInternal( DdManager * dd, Abc_Ntk_t * pNtk, bool fVerbose,
{
Dsd_Manager_t * pManDsd;
Abc_Ntk_t * pNtkNew;
char ** ppNamesCi, ** ppNamesCo;
// perform the decomposition
pManDsd = Abc_NtkDsdPerform( dd, pNtk, fVerbose );
......@@ -120,7 +121,13 @@ Abc_Ntk_t * Abc_NtkDsdInternal( DdManager * dd, Abc_Ntk_t * pNtk, bool fVerbose,
Abc_NtkFinalize( pNtk, pNtkNew );
if ( fPrint )
Dsd_TreePrint( stdout, pManDsd, (char **)pNtk->vNamesPi->pArray, (char **)pNtk->vNamesPo->pArray, fShort, -1 );
{
ppNamesCi = Abc_NtkCollectCioNames( pNtk, 0 );
ppNamesCo = Abc_NtkCollectCioNames( pNtk, 1 );
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, fShort, -1 );
free( ppNamesCi );
free( ppNamesCo );
}
// stop the DSD manager
Dsd_ManagerStop( pManDsd );
......
......@@ -45,10 +45,10 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
assert( !Abc_ObjIsComplement(pObj) );
assert( pObj->pNtk == pFaninR->pNtk );
assert( pObj->Id >= 0 && pFaninR->Id >= 0 );
assert( pObj->Id < (1<<21)-1 ); // created but forgot to add it to the network?
assert( pFaninR->Id < (1<<21)-1 ); // created but forgot to add it to the network?
assert( pObj->Id < (1<<26)-1 ); // created but forgot to add it to the network?
assert( pFaninR->Id < (1<<26)-1 ); // created but forgot to add it to the network?
Vec_FanPush( pObj->pNtk->pMmStep, &pObj->vFanins, Vec_Int2Fan(pFaninR->Id) );
Vec_FanPush( pObj->pNtk->pMmStep, &pFaninR->vFanouts, Vec_Int2Fan(pObj->Id) );
Vec_FanPush( pObj->pNtk->pMmStep, &pFaninR->vFanouts, Vec_Int2Fan(pObj->Id) );
if ( Abc_ObjIsComplement(pFanin) )
Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 );
}
......@@ -71,8 +71,8 @@ void Abc_ObjDeleteFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
assert( !Abc_ObjIsComplement(pFanin) );
assert( pObj->pNtk == pFanin->pNtk );
assert( pObj->Id >= 0 && pFanin->Id >= 0 );
assert( pObj->Id < (1<<21)-1 ); // created but forgot to add it to the network?
assert( pFanin->Id < (1<<21)-1 ); // created but forgot to add it to the network?
assert( pObj->Id < (1<<26)-1 ); // created but forgot to add it to the network?
assert( pFanin->Id < (1<<26)-1 ); // created but forgot to add it to the network?
if ( !Vec_FanDeleteEntry( &pObj->vFanins, pFanin->Id ) )
{
printf( "The obj %d is not found among the fanins of obj %d ...\n", pFanin->Id, pObj->Id );
......
......@@ -108,11 +108,11 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
assert( Abc_NtkIsAig(pNtk) );
// start the mapping manager and set its parameters
pMan = Fpga_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk), Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk), fVerbose );
pMan = Fpga_ManCreate( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), fVerbose );
if ( pMan == NULL )
return NULL;
Fpga_ManSetAreaRecovery( pMan, fRecovery );
Fpga_ManSetOutputNames( pMan, (char **)pNtk->vNamesPo->pArray );
Fpga_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
Fpga_ManSetInputArrivals( pMan, Abc_NtkGetCiArrivalFloats(pNtk) );
// create PIs and remember them in the old nodes
......@@ -141,7 +141,7 @@ Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
// remember the node
pNode->pCopy = (Abc_Obj_t *)pNodeFpga;
// set up the choice node
if ( Abc_NodeIsChoice( pNode ) )
if ( Abc_NodeIsAigChoice( pNode ) )
for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
{
Fpga_NodeSetNextE( (Fpga_Node_t *)pPrev->pCopy, (Fpga_Node_t *)pFanin->pCopy );
......@@ -197,7 +197,7 @@ Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk )
// finalize the new network
Abc_NtkFinalize( pNtk, pNtkNew );
// decouple the PO driver nodes to reduce the number of levels
nDupGates = Abc_NtkLogicMakeSimplePos( pNtkNew );
nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
if ( nDupGates && Fpga_ManReadVerbose(pMan) )
printf( "Duplicated %d gates to decouple the PO drivers.\n", nDupGates );
return pNtkNew;
......
......@@ -250,7 +250,7 @@ Abc_Ntk_t * Abc_NtkFraigTrust( Abc_Ntk_t * pNtk )
int fCheck = 1;
Abc_Ntk_t * pNtkNew;
if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogicSop(pNtk) )
if ( !Abc_NtkIsLogicSop(pNtk) )
{
printf( "Abc_NtkFraigTrust: Trust mode works for netlists and logic SOP networks.\n" );
return NULL;
......
......@@ -30,164 +30,6 @@
/**Function*************************************************************
Synopsis [Checks whether the network is combinational.]
Description [The network is combinational if it has no latches.]
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_NtkIsComb( Abc_Ntk_t * pNtk )
{
return pNtk->vLatches->nSize == 0;
}
/**Function*************************************************************
Synopsis [Makes the network combinational.]
Description [If the network is sequential, the latches are disconnected,
while the latch inputs and outputs are added to the PIs and POs.]
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_NtkMakeComb( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pLatch, * pNet;
int i;
if ( !Abc_NtkIsNetlist(pNtk) )
return 0;
// skip if the network is already combinational
if ( Abc_NtkIsComb( pNtk ) )
return 0;
// save the number of PIs/POs
assert( pNtk->nPisOld == 0 );
assert( pNtk->nPosOld == 0 );
pNtk->nPisOld = pNtk->vPis->nSize;
pNtk->nPosOld = pNtk->vPos->nSize;
if ( Abc_NtkIsNetlist(pNtk) )
{
// go through the latches
// - disconnect LO/LI nets from latches
// - add them to the PI/PO lists
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
// process the input of the latch
pNet = Abc_ObjFanin0( pLatch );
assert( Abc_ObjIsLi( pNet ) );
if ( !Vec_FanDeleteEntry( &pNet->vFanouts, pLatch->Id ) )
{
printf( "Abc_NtkMakeComb: The latch is not found among the fanouts of the fanin net...\n" );
return 0;
}
if ( !Abc_ObjIsPo( pNet ) )
Abc_NtkMarkNetPo( pNet );
// process the output of the latch
pNet = Abc_ObjFanout0( pLatch );
assert( Abc_ObjIsLo( pNet ) );
if ( !Vec_FanDeleteEntry( &pNet->vFanins, pLatch->Id ) )
{
printf( "Abc_NtkMakeComb: The latch is not found among the fanins of the fanout net...\n" );
return 0;
}
assert( !Abc_ObjIsPi( pNet ) );
Abc_NtkMarkNetPi( pNet );
}
}
else
{
assert( 0 );
/*
// go through the latches and add them to PIs and POs
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
// pLatch->Type = ABC_OBJ_TYPE_NODE;
Vec_PtrPush( pNtk->vPis, pLatch );
Vec_PtrPush( pNtk->vPos, pLatch );
// add the names of the latches to the names of the PIs
Vec_PtrPush( pNtk->vNamesPi, pNtk->vNamesLatch->pArray[i] );
}
*/
}
// save the latches in the backup place
pNtk->vLatches2 = pNtk->vLatches;
pNtk->vLatches = Vec_PtrAlloc( 0 );
return 1;
}
/**Function*************************************************************
Synopsis [Makes the network sequential again.]
Description [If the network was made combinational by disconnecting
latches, this procedure makes it sequential again.]
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_NtkMakeSeq( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pLatch, * pNet;
int i;
if ( !Abc_NtkIsNetlist(pNtk) )
return 0;
// skip if the network has no latches
if ( pNtk->vLatches2 == NULL || pNtk->vLatches2->nSize == 0 )
return 0;
// move the latches from the backup place
Vec_PtrFree( pNtk->vLatches );
pNtk->vLatches = pNtk->vLatches2;
pNtk->vLatches2 = NULL;
if ( Abc_NtkIsNetlist(pNtk) )
{
// go through the latches and connect the LI/LO nets back to the latches
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
// process the input of the latch
pNet = Abc_ObjFanin0( pLatch );
assert( Abc_ObjIsLi( pNet ) );
Vec_FanPush( pNtk->pMmStep, &pNet->vFanouts, Vec_Int2Fan(pLatch->Id) );
// process the output of the latch
pNet = Abc_ObjFanout0( pLatch );
assert( Abc_ObjIsLo( pNet ) );
Vec_FanPush( pNtk->pMmStep, &pNet->vFanins, Vec_Int2Fan(pLatch->Id) );
}
// clean the PI/PO attributes of the former latch variables
for ( i = pNtk->nPisOld; i < pNtk->vPis->nSize; i++ )
Abc_ObjUnsetSubtype( Abc_NtkPi(pNtk, i), ABC_OBJ_SUBTYPE_PI );
for ( i = pNtk->nPosOld; i < pNtk->vPos->nSize; i++ )
Abc_ObjUnsetSubtype( Abc_NtkPo(pNtk, i), ABC_OBJ_SUBTYPE_PO );
}
else
{
assert( 0 );
// Vec_PtrShrink( pNtk->vNamesPi, pNtk->nPisOld );
}
// remove the nodes from the PI/PO lists
Vec_PtrShrink( pNtk->vPis, pNtk->nPisOld );
Vec_PtrShrink( pNtk->vPos, pNtk->nPosOld );
pNtk->nPis = pNtk->vPis->nSize;
pNtk->nPos = pNtk->vPos->nSize;
pNtk->nPisOld = 0;
pNtk->nPosOld = 0;
return 1;
}
/**Function*************************************************************
Synopsis [Checks if latches form self-loop.]
Description []
......
......@@ -138,7 +138,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, i
if ( pMan == NULL )
return NULL;
Map_ManSetAreaRecovery( pMan, fRecovery );
Map_ManSetOutputNames( pMan, (char **)pNtk->vNamesPo->pArray );
Map_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
Map_ManSetDelayTarget( pMan, (float)DelayTarget );
Map_ManSetInputArrivals( pMan, (Map_Time_t *)Abc_NtkGetCiArrivalTimes(pNtk) );
......@@ -168,7 +168,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, i
// remember the node
pNode->pCopy = (Abc_Obj_t *)pNodeMap;
// set up the choice node
if ( Abc_NodeIsChoice( pNode ) )
if ( Abc_NodeIsAigChoice( pNode ) )
for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
{
Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy );
......@@ -203,7 +203,7 @@ Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
Abc_Obj_t * pNode, * pNodeNew;
int i, nDupGates;
// create the new network
// create the new network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC_MAP );
// make the mapper point to the new network
Map_ManCleanData( pMan );
......@@ -226,12 +226,8 @@ Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
}
Extra_ProgressBarStop( pProgress );
// transfer the names
Abc_NtkDupNameArrays( pNtk, pNtkNew );
Abc_ManTimeDup( pNtk, pNtkNew );
// decouple the PO driver nodes to reduce the number of levels
nDupGates = Abc_NtkLogicMakeSimplePos( pNtkNew );
nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
if ( nDupGates && Map_ManReadVerbose(pMan) )
printf( "Duplicated %d gates to decouple the PO drivers.\n", nDupGates );
return pNtkNew;
......@@ -398,7 +394,7 @@ int Abc_NtkUnmap( Abc_Ntk_t * pNtk )
assert( Abc_NtkIsLogicMap(pNtk) );
// update the functionality manager
assert( pNtk->pManFunc == NULL );
assert( pNtk->pManFunc == Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
pNtk->pManFunc = Extra_MmFlexStart();
pNtk->Type = ABC_NTK_LOGIC_SOP;
// update the nodes
......
......@@ -27,6 +27,7 @@
static Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
static void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb );
static void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter );
static void Abc_NtkMiterAddOneNode( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pNode );
static void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb );
static void Abc_NtkAddFrame( Abc_Ntk_t * pNetNew, Abc_Ntk_t * pNet, int iFrame, Vec_Ptr_t * vNodes );
......@@ -130,16 +131,16 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk
// create new PIs and remember them in the old PIs
Abc_NtkForEachCi( pNtk1, pObj, i )
{
pObjNew = Abc_NtkCreateTermPi( pNtkMiter );
pObjNew = Abc_NtkCreatePi( pNtkMiter );
// remember this PI in the old PIs
pObj->pCopy = pObjNew;
pObj = Abc_NtkCi(pNtk2, i);
pObj->pCopy = pObjNew;
// add name
Abc_NtkLogicStoreName( pObjNew, pNtk1->vNamesPi->pArray[i] );
Abc_NtkLogicStoreName( pObjNew, Abc_ObjName(pObj) );
}
// create the only PO
pObjNew = Abc_NtkCreateTermPo( pNtkMiter );
pObjNew = Abc_NtkCreatePo( pNtkMiter );
// add the PO name
Abc_NtkLogicStoreName( pObjNew, "miter" );
}
......@@ -148,34 +149,34 @@ void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtk
// create new PIs and remember them in the old PIs
Abc_NtkForEachPi( pNtk1, pObj, i )
{
pObjNew = Abc_NtkCreateTermPi( pNtkMiter );
pObjNew = Abc_NtkCreatePi( pNtkMiter );
// remember this PI in the old PIs
pObj->pCopy = pObjNew;
pObj = Abc_NtkPi(pNtk2, i);
pObj->pCopy = pObjNew;
// add name
Abc_NtkLogicStoreName( pObjNew, pNtk1->vNamesPi->pArray[i] );
Abc_NtkLogicStoreName( pObjNew, Abc_ObjName(pObj) );
}
// create the only PO
pObjNew = Abc_NtkCreateTermPo( pNtkMiter );
pObjNew = Abc_NtkCreatePo( pNtkMiter );
// add the PO name
Abc_NtkLogicStoreName( pObjNew, "miter" );
// create the latches
Abc_NtkForEachLatch( pNtk1, pObj, i )
{
pObjNew = Abc_NtkDupObj( pNtkMiter, pObj );
Vec_PtrPush( pNtkMiter->vPis, pObjNew );
Vec_PtrPush( pNtkMiter->vPos, pObjNew );
Vec_PtrPush( pNtkMiter->vCis, pObjNew );
Vec_PtrPush( pNtkMiter->vCos, pObjNew );
// add name
Abc_NtkLogicStoreNamePlus( pObjNew, pNtk1->vNamesLatch->pArray[i], "_1" );
Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_1" );
}
Abc_NtkForEachLatch( pNtk2, pObj, i )
{
pObjNew = Abc_NtkDupObj( pNtkMiter, pObj );
Vec_PtrPush( pNtkMiter->vPis, pObjNew );
Vec_PtrPush( pNtkMiter->vPos, pObjNew );
Vec_PtrPush( pNtkMiter->vCis, pObjNew );
Vec_PtrPush( pNtkMiter->vCos, pObjNew );
// add name
Abc_NtkLogicStoreNamePlus( pObjNew, pNtk2->vNamesLatch->pArray[i], "_2" );
Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_2" );
}
}
}
......@@ -219,6 +220,41 @@ void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter )
Extra_ProgressBarStop( pProgress );
}
/**Function*************************************************************
Synopsis [Performs mitering for one network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkMiterAddOneNode( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pRoot )
{
Vec_Ptr_t * vNodes;
Abc_Obj_t * pNode, * pNodeNew, * pConst1, * pConst1New;
int i;
// get the constant nodes
pConst1 = Abc_AigConst1( pNtk->pManFunc );
pConst1New = Abc_AigConst1( pNtkMiter->pManFunc );
// perform strashing
vNodes = Abc_NtkDfsNodes( pNtk, &pRoot, 1 );
for ( i = 0; i < vNodes->nSize; i++ )
{
pNode = vNodes->pArray[i];
if ( pNode == pConst1 )
pNodeNew = pConst1New;
else
pNodeNew = Abc_AigAnd( pNtkMiter->pManFunc,
Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
Abc_ObjNotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
pNode->pCopy = pNodeNew;
}
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
......@@ -245,7 +281,7 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt
{
pDriverNew = Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
Vec_PtrPush( vPairs, pDriverNew );
pNode = Abc_NtkPo( pNtk2, i );
pNode = Abc_NtkCo( pNtk2, i );
pDriverNew = Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
Vec_PtrPush( vPairs, pDriverNew );
}
......@@ -279,6 +315,80 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt
Vec_PtrFree( vPairs );
}
/**Function*************************************************************
Synopsis [Derives the miter of two cofactors of one output.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkMiterOne( Abc_Ntk_t * pNtk, int Out, int In1, int In2 )
{
int fCheck = 1;
char Buffer[100];
Abc_Ntk_t * pNtkMiter;
Abc_Obj_t * pRoot, * pOutput1, * pOutput2, * pMiter;
assert( Abc_NtkIsAig(pNtk) );
assert( Out < Abc_NtkCoNum(pNtk) );
assert( In1 < Abc_NtkCiNum(pNtk) );
assert( In2 < Abc_NtkCiNum(pNtk) );
// start the new network
pNtkMiter = Abc_NtkAlloc( ABC_NTK_AIG );
sprintf( Buffer, "%s_%s_miter", pNtk->pName, Abc_ObjName(Abc_NtkCo(pNtk, Out)) );
pNtkMiter->pName = util_strsav(Buffer);
// get the root output
pRoot = Abc_NtkCo(pNtk,Out);
// perform strashing
Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 );
// set the first cofactor
Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) );
if ( In2 >= 0 )
Abc_NtkCi(pNtk, In2)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc );
// add the first cofactor
Abc_NtkMiterAddOneNode( pNtk, pNtkMiter, pRoot );
// save the output
pOutput1 = Abc_ObjFanin0(pRoot)->pCopy;
// set the second cofactor
Abc_NtkCi(pNtk, In1)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc );
if ( In2 >= 0 )
Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) );
// add the second cofactor
Abc_NtkMiterAddOneNode( pNtk, pNtkMiter, pRoot );
// save the output
pOutput2 = Abc_ObjFanin0(pRoot)->pCopy;
// create the miter of the two outputs
pMiter = Abc_AigXor( pNtkMiter->pManFunc, pOutput1, pOutput2 );
Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter );
// make sure that everything is okay
if ( fCheck && !Abc_NtkCheck( pNtkMiter ) )
{
printf( "Abc_NtkMiter: The network check has failed.\n" );
Abc_NtkDelete( pNtkMiter );
return NULL;
}
return pNtkMiter;
}
/**Function*************************************************************
Synopsis [Checks the status of the miter.]
......@@ -422,12 +532,10 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial )
{
pLatchNew = Abc_NtkLatch(pNtkFrames, i);
Abc_ObjAddFanin( pLatchNew, Abc_ObjFanin0(pLatch)->pCopy );
Vec_PtrPush( pNtkFrames->vPis, pLatchNew );
Vec_PtrPush( pNtkFrames->vPos, pLatchNew );
Abc_NtkLogicStoreName( pLatchNew, pNtk->vNamesLatch->pArray[i] );
Vec_PtrPush( pNtkFrames->vCis, pLatchNew );
Vec_PtrPush( pNtkFrames->vCos, pLatchNew );
Abc_NtkLogicStoreName( pLatchNew, Abc_ObjName(pLatch) );
}
assert( pNtkFrames->vPis->nSize == pNtkFrames->vNamesPi->nSize );
assert( pNtkFrames->vPos->nSize == pNtkFrames->vNamesPo->nSize );
}
// make sure that everything is okay
if ( fCheck && !Abc_NtkCheck( pNtkFrames ) )
......@@ -468,7 +576,7 @@ void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec_
Abc_NtkForEachPi( pNtk, pNode, i )
{
pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode );
Abc_NtkLogicStoreNamePlus( pNodeNew, pNtk->vNamesPi->pArray[i], Buffer );
Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer );
}
// add the internal nodes
for ( i = 0; i < vNodes->nSize; i++ )
......@@ -487,7 +595,7 @@ void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec_
{
pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode );
Abc_ObjAddFanin( pNodeNew, Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ) );
Abc_NtkLogicStoreNamePlus( pNodeNew, pNtk->vNamesPo->pArray[i], Buffer );
Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer );
}
// transfer the implementation of the latch drivers to the latches
Abc_NtkForEachLatch( pNtk, pLatch, i )
......
......@@ -73,135 +73,44 @@ char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix )
/**Function*************************************************************
Synopsis [Returns the hash table of node names.]
Synopsis [Gets the long name of the node.]
Description [Creates the hash table of names into nodes for the given
type of nodes. Additionally, sets the node copy pointers to the names.
Returns NULL if name duplication is detected.]
Description [This name is the output net's name.]
SideEffects []
SeeAlso []
***********************************************************************/
stmm_table * Abc_NtkLogicHashNames( Abc_Ntk_t * pNtk, int Type, int fComb )
char * Abc_ObjName( Abc_Obj_t * pObj )
{
stmm_table * tNames;
int i, Limit;
tNames = stmm_init_table( strcmp, stmm_strhash );
if ( Type == 0 ) // PI
{
Limit = fComb? Abc_NtkCiNum(pNtk) : Abc_NtkPiNum(pNtk);
for ( i = 0; i < Limit; i++ )
{
if ( stmm_insert( tNames, Abc_NtkNameCi(pNtk,i), (char *)Abc_NtkCi(pNtk,i) ) )
{
printf( "Error: The name is already in the table...\n" );
return NULL;
}
Abc_NtkCi(pNtk,i)->pCopy = (Abc_Obj_t *)Abc_NtkNameCi(pNtk,i);
}
}
else if ( Type == 1 ) // PO
{
Limit = fComb? Abc_NtkCoNum(pNtk) : Abc_NtkPoNum(pNtk);
for ( i = 0; i < Limit; i++ )
{
if ( stmm_insert( tNames, Abc_NtkNameCo(pNtk,i), (char *)Abc_NtkCo(pNtk,i) ) )
{
printf( "Error: The name is already in the table...\n" );
return NULL;
}
Abc_NtkCo(pNtk,i)->pCopy = (Abc_Obj_t *)Abc_NtkNameCo(pNtk,i);
}
}
else if ( Type == 2 ) // latch
{
for ( i = 0; i < Abc_NtkLatchNum(pNtk); i++ )
{
if ( stmm_insert( tNames, Abc_NtkNameLatch(pNtk,i), (char *)Abc_NtkLatch(pNtk,i) ) )
{
printf( "Error: The name is already in the table...\n" );
return NULL;
}
Abc_NtkLatch(pNtk,i)->pCopy = (Abc_Obj_t *)Abc_NtkNameLatch(pNtk,i);
}
}
return tNames;
}
/**Function*************************************************************
Synopsis [Transfers the names to the node copy pointers.]
Description [This procedure is used for writing networks into a file.
Assumes that the latch input names are created from latch names using
suffix "_in".]
SideEffects []
static char Buffer[500];
char * pName;
SeeAlso []
// check if the object is in the lookup table
if ( stmm_lookup( pObj->pNtk->tObj2Name, (char *)pObj, &pName ) )
return pName;
***********************************************************************/
void Abc_NtkLogicTransferNames( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode, * pDriver, * pFanoutNamed;
int i;
// transfer the PI/PO/latch names
Abc_NtkForEachPi( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Abc_NtkNamePi(pNtk,i);
Abc_NtkForEachPo( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Abc_NtkNamePo(pNtk,i);
Abc_NtkForEachLatch( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Abc_NtkNameLatch(pNtk,i);
Abc_NtkForEachNode( pNtk, pNode, i )
pNode->pCopy = NULL;
// additionally, transfer the names to the CO drivers if they have unique COs
Abc_NtkForEachPo( pNtk, pNode, i )
// consider network types
if ( Abc_NtkIsNetlist(pObj->pNtk) )
{
pDriver = Abc_ObjFanin0(pNode);
// skip the drivers already having names
if ( pDriver->pCopy )
continue;
// get the named fanout
pFanoutNamed = Abc_NodeHasUniqueNamedFanout( pDriver );
if ( pFanoutNamed == NULL || pFanoutNamed != pNode )
continue;
// assign the name;
assert( pNode == pFanoutNamed );
pDriver->pCopy = pFanoutNamed->pCopy;
// in a netlist, nets have names, nodes have no names
if ( Abc_ObjIsNode(pObj) )
pObj = Abc_ObjFanout0(pObj);
assert( Abc_ObjIsNet(pObj) );
// if the name is not given, invent it
if ( pObj->pData )
sprintf( Buffer, "%s", pObj->pData );
else
sprintf( Buffer, "[%d]", pObj->Id ); // make sure this name is unique!!!
}
Abc_NtkForEachLatch( pNtk, pNode, i )
else
{
pDriver = Abc_ObjFanin0(pNode);
// skip the drivers already having names
if ( pDriver->pCopy )
continue;
// get the named fanout
pFanoutNamed = Abc_NodeHasUniqueNamedFanout( pDriver );
if ( pFanoutNamed == NULL || pFanoutNamed != pNode )
continue;
// assign the name;
assert( pNode == Abc_NtkLatch(pNtk,i) );
pDriver->pCopy = (Abc_Obj_t *)Abc_NtkRegisterName( pNtk, Abc_NtkNameLatchInput(pNtk,i) );
// in a logic network, PI/PO/latch names are stored in the hash table
// internal nodes have made up names
assert( Abc_ObjIsNode(pObj) );
sprintf( Buffer, "[%d]", pObj->Id );
}
}
/**Function*************************************************************
Synopsis [Gets the long name of the node.]
Description [This name is the output net's name.]
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_NtkNameLatchInput( Abc_Ntk_t * pNtk, int i )
{
static char Buffer[500];
sprintf( Buffer, "%s_in", Abc_NtkNameLatch(pNtk, i) );
return Buffer;
}
......@@ -216,31 +125,10 @@ char * Abc_NtkNameLatchInput( Abc_Ntk_t * pNtk, int i )
SeeAlso []
***********************************************************************/
char * Abc_ObjName( Abc_Obj_t * pObj )
char * Abc_ObjNameSuffix( Abc_Obj_t * pObj, char * pSuffix )
{
static char Buffer[500];
assert( !Abc_NtkIsSeq(pObj->pNtk) );
// consider network types
if ( Abc_NtkIsNetlist(pObj->pNtk) )
{
// in a netlist, nets have names, nodes have no names
assert( Abc_ObjIsNet(pObj) );
// if the name is not given, invent it
if ( pObj->pData )
sprintf( Buffer, "%s", pObj->pData );
else
sprintf( Buffer, "[%d]", pObj->Id ); // make sure this name is unique!!!
}
else
{
// in a logic network, PIs/POs/latches have names, internal nodes have no names
// (exception: an internal node borrows name from its unique non-complemented CO fanout)
assert( !Abc_ObjIsNet(pObj) );
if ( pObj->pCopy )
sprintf( Buffer, "%s", (char *)pObj->pCopy );
else
sprintf( Buffer, "[%d]", pObj->Id );
}
sprintf( Buffer, "%s%s", Abc_ObjName(pObj), pSuffix );
return Buffer;
}
......@@ -277,32 +165,25 @@ char * Abc_ObjNameUnique( Abc_Ntk_t * pNtk, char * pName )
Synopsis [Adds new name to the network.]
Description []
Description [The new object (pObjNew) is a PI, PO or latch. The name
is registered and added to the hash table.]
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_NtkLogicStoreName( Abc_Obj_t * pNodeNew, char * pNameOld )
char * Abc_NtkLogicStoreName( Abc_Obj_t * pObjNew, char * pNameOld )
{
char * pNewName;
assert( !Abc_ObjIsComplement(pNodeNew) );
assert( Abc_ObjIsCio(pObjNew) );
// get the new name
pNewName = Abc_NtkRegisterName( pNodeNew->pNtk, pNameOld );
// add the name
if ( Abc_ObjIsPi(pNodeNew) )
Vec_PtrPush( pNodeNew->pNtk->vNamesPi, pNewName );
else if ( Abc_ObjIsPo(pNodeNew) )
Vec_PtrPush( pNodeNew->pNtk->vNamesPo, pNewName );
else if ( Abc_ObjIsLatch(pNodeNew) )
pNewName = Abc_NtkRegisterName( pObjNew->pNtk, pNameOld );
// add the name to the table
if ( stmm_insert( pObjNew->pNtk->tObj2Name, (char *)pObjNew, pNewName ) )
{
Vec_PtrPush( pNodeNew->pNtk->vNamesLatch, pNewName );
Vec_PtrPush( pNodeNew->pNtk->vNamesPi, pNewName );
Vec_PtrPush( pNodeNew->pNtk->vNamesPo, pNewName );
assert( 0 ); // the object is added for the second time
}
else
assert( 0 );
return pNewName;
}
......@@ -317,26 +198,18 @@ char * Abc_NtkLogicStoreName( Abc_Obj_t * pNodeNew, char * pNameOld )
SeeAlso []
***********************************************************************/
char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pNodeNew, char * pNameOld, char * pSuffix )
char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pObjNew, char * pNameOld, char * pSuffix )
{
char * pNewName;
assert( !Abc_ObjIsComplement(pNodeNew) );
assert( pSuffix );
assert( Abc_ObjIsCio(pObjNew) );
// get the new name
pNewName = Abc_NtkRegisterNamePlus( pNodeNew->pNtk, pNameOld, pSuffix );
// add the name
if ( Abc_ObjIsPi(pNodeNew) )
Vec_PtrPush( pNodeNew->pNtk->vNamesPi, pNewName );
else if ( Abc_ObjIsPo(pNodeNew) )
Vec_PtrPush( pNodeNew->pNtk->vNamesPo, pNewName );
else if ( Abc_ObjIsLatch(pNodeNew) )
pNewName = Abc_NtkRegisterNamePlus( pObjNew->pNtk, pNameOld, pSuffix );
// add the name to the table
if ( stmm_insert( pObjNew->pNtk->tObj2Name, (char *)pObjNew, pNewName ) )
{
Vec_PtrPush( pNodeNew->pNtk->vNamesLatch, pNewName );
Vec_PtrPush( pNodeNew->pNtk->vNamesPi, pNewName );
Vec_PtrPush( pNodeNew->pNtk->vNamesPo, pNewName );
assert( 0 ); // the object is added for the second time
}
else
assert( 0 );
return pNewName;
}
......@@ -351,22 +224,18 @@ char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pNodeNew, char * pNameOld, char *
SeeAlso []
***********************************************************************/
void Abc_NtkCreateNameArrays( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
void Abc_NtkCreateCioNamesTable( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNet, * pLatch;
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsNetlist(pNtkNew) );
assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) );
assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) );
assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) );
assert( st_count(pNtkNew->tName2Net) == 0 );
Abc_NtkForEachPi( pNtk, pNet, i )
Abc_NtkLogicStoreName( pNtkNew->vPis->pArray[i], pNet->pData );
Abc_NtkForEachPo( pNtk, pNet, i )
Abc_NtkLogicStoreName( pNtkNew->vPos->pArray[i], pNet->pData );
Abc_NtkForEachLatch( pNtk, pLatch, i )
Abc_NtkLogicStoreName( pNtkNew->vLatches->pArray[i], Abc_ObjFanout0(pLatch)->pData );
assert( st_count(pNtk->tObj2Name) == 0 );
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkLogicStoreName( pObj, Abc_ObjFanout0(pObj)->pData );
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NtkLogicStoreName( pObj, Abc_ObjFanin0(pObj)->pData );
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_NtkLogicStoreName( pObj, Abc_ObjFanout0(pObj)->pData );
}
/**Function*************************************************************
......@@ -380,23 +249,22 @@ void Abc_NtkCreateNameArrays( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
SeeAlso []
***********************************************************************/
void Abc_NtkDupNameArrays( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
void Abc_NtkDupCioNamesTable( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
Abc_Obj_t * pObj, * pLatch;
Abc_Obj_t * pObj;
int i;
assert( !Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsNetlist(pNtkNew) );
assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) );
assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) );
assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) );
assert( st_count(pNtkNew->tName2Net) == 0 );
assert( st_count(pNtk->tObj2Name) > 0 );
assert( st_count(pNtkNew->tObj2Name) == 0 );
// copy the CI/CO names if given
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_NtkLogicStoreName( pNtkNew->vPis->pArray[i], pNtk->vNamesPi->pArray[i] );
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NtkLogicStoreName( pNtkNew->vPos->pArray[i], pNtk->vNamesPo->pArray[i] );
Abc_NtkForEachLatch( pNtk, pLatch, i )
Abc_NtkLogicStoreName( pNtkNew->vLatches->pArray[i], pNtk->vNamesLatch->pArray[i] );
Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pObj) );
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(pObj) );
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(pObj) );
}
////////////////////////////////////////////////////////////////////////
......
......@@ -39,55 +39,299 @@
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkLogic( Abc_Ntk_t * pNtk )
Abc_Ntk_t * Abc_NtkNetlistToLogic( Abc_Ntk_t * pNtk )
{
int fCheck = 1;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin;
int i, k;
assert( Abc_NtkIsNetlist(pNtk) );
// start the network
pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC_SOP );
// duplicate the name and the spec
pNtkNew->pName = util_strsav(pNtk->pName);
pNtkNew->pSpec = util_strsav(pNtk->pSpec);
// clean the copy field
Abc_NtkCleanCopy( pNtk );
// create the PIs and point to them from the nets
Abc_NtkForEachPi( pNtk, pObj, i )
pObj->pCopy = Abc_NtkCreateTermPi( pNtkNew );
// create the latches and point to them from the latch fanout nets
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_ObjFanout0(pObj)->pCopy = Abc_NtkDupObj(pNtkNew, pObj);
// duplicate the nodes and point to them from the fanout nets
if ( Abc_NtkIsNetlistSop(pNtk) )
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC_SOP );
else
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC_MAP );
// duplicate the nodes
Abc_NtkForEachNode( pNtk, pObj, i )
Abc_ObjFanout0(pObj)->pCopy = Abc_NtkDupObj(pNtkNew, pObj);
Abc_NtkDupObj(pNtkNew, pObj);
// reconnect the internal nodes in the new network
Abc_NtkForEachNode( pNtk, pObj, i )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pFanin)->pCopy );
// collect the CO nodes
Abc_NtkFinalize( pNtk, pNtkNew );
// fix the problem with CO pointing directing to CIs
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
// duplicate EXDC
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkNetlistToLogic( pNtk->pExdc );
if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkNetlistToLogic(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Transform the logic network into a netlist.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew, * pNtkTemp;
assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsAig(pNtk) );
if ( Abc_NtkIsLogicBdd(pNtk) )
{
Abc_NtkBddToSop(pNtk);
pNtkNew = Abc_NtkLogicSopToNetlist( pNtk );
Abc_NtkSopToBdd(pNtk);
}
else if ( Abc_NtkIsAig(pNtk) )
{
pNtkTemp = Abc_NtkAigToLogicSop(pNtk);
pNtkNew = Abc_NtkLogicSopToNetlist( pNtkTemp );
Abc_NtkDelete( pNtkTemp );
}
else
pNtkNew = Abc_NtkLogicSopToNetlist( pNtk );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Converts the AIG into the netlist.]
Description [This procedure does not copy the choices.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkLogicToNetlistBench( Abc_Ntk_t * pNtk )
{
Abc_Ntk_t * pNtkNew, * pNtkTemp;
assert( Abc_NtkIsAig(pNtk) );
pNtkTemp = Abc_NtkAigToLogicSopBench( pNtk );
pNtkNew = Abc_NtkLogicSopToNetlist( pNtkTemp );
Abc_NtkDelete( pNtkTemp );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Transform the logic network into a netlist.]
Description [The logic network given to this procedure should
have exactly the same structure as the resulting netlist. The COs
can only point to CIs if they have identical names. Otherwise,
they should have a node between them, even if this node is
inverter or buffer.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
{
int fCheck = 1;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pNet, * pDriver, * pFanin;
char * pNameCo;
int i, k;
assert( Abc_NtkIsLogicSop(pNtk) || Abc_NtkIsLogicMap(pNtk) );
assert( Abc_NtkLogicHasSimpleCos(pNtk) );
// start the netlist by creating PI/PO/Latch objects
if ( Abc_NtkIsLogicSop(pNtk) )
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST_SOP );
else
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST_MAP );
// create the CI nets and remember them in the new CI nodes
Abc_NtkForEachCi( pNtk, pObj, i )
{
pNet = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pObj) );
Abc_ObjAddFanin( pNet, pObj->pCopy );
pObj->pCopy->pCopy = pNet;
}
// duplicate all nodes
Abc_NtkForEachNode( pNtk, pObj, i )
Abc_NtkDupObj(pNtkNew, pObj);
// first add the nets to the CO drivers
Abc_NtkForEachCo( pNtk, pObj, i )
{
pDriver = Abc_ObjFanin0(pObj);
if ( Abc_ObjIsCi(pDriver) )
{
assert( !strcmp( Abc_ObjName(pDriver), Abc_ObjName(pObj) ) );
Abc_ObjAddFanin( pObj->pCopy, pDriver->pCopy->pCopy );
continue;
}
assert( Abc_ObjIsNode(pDriver) );
// the driver is a node
// get the CO name
pNameCo = Abc_ObjIsPo(pObj)? Abc_ObjName(pObj) : Abc_ObjNameSuffix( pObj, "_in" );
// make sure CO has a unique name
assert( Abc_NtkFindNet( pNtkNew, pNameCo ) == NULL );
// create the CO net and connect it to CO
pNet = Abc_NtkFindOrCreateNet( pNtkNew, pNameCo );
Abc_ObjAddFanin( pObj->pCopy, pNet );
// connect the CO net to the new driver and remember it in the new driver
Abc_ObjAddFanin( pNet, pDriver->pCopy );
pDriver->pCopy->pCopy = pNet;
}
// create the missing nets
Abc_NtkForEachNode( pNtk, pObj, i )
{
if ( pObj->pCopy->pCopy ) // the net of the new object is already created
continue;
// create the new net
pNet = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pObj) );
Abc_ObjAddFanin( pNet, pObj->pCopy );
pObj->pCopy->pCopy = pNet;
}
// connect nodes to the fanins nets
Abc_NtkForEachNode( pNtk, pObj, i )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy->pCopy );
// duplicate EXDC
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkLogicToNetlist( pNtk->pExdc );
if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkLogicSopToNetlist(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Converts the AIG into the logic network with SOPs.]
Description [Correctly handles the case of choice nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk )
{
int fCheck = 1;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin, * pNodeNew;
int i, k;
assert( Abc_NtkIsAig(pNtk) );
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC_SOP );
// duplicate the nodes and create node functions
Abc_NtkForEachNode( pNtk, pObj, i )
{
Abc_NtkDupObj(pNtkNew, pObj);
pObj->pCopy->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
}
// create the choice nodes
Abc_NtkForEachNode( pNtk, pObj, i )
{
if ( !Abc_NodeIsAigChoice(pObj) )
continue;
// create an OR gate
pNodeNew = Abc_NtkCreateNode(pNtk);
// add fanins
Vec_IntClear( pNtk->vIntTemp );
for ( k = 0, pFanin = pObj; pFanin; pFanin = pFanin->pData, k++ )
{
Vec_IntPush( pNtk->vIntTemp, (int)(pObj->fPhase != pFanin->fPhase) );
Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
}
// create the logic function
pNodeNew->pData = Abc_SopCreateOr( pNtk->pManFunc, pNtk->vIntTemp->nSize, pNtk->vIntTemp->pArray );
// set the new node
pObj->pCopy = pNodeNew;
}
// connect the objects
Abc_NtkForEachObj( pNtk, pObj, i )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
// create and connect the POs
Abc_NtkForEachPo( pNtk, pObj, i )
// connect the COs
Abc_NtkFinalize( pNtk, pNtkNew );
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
// duplicate the EXDC Ntk
if ( pNtk->pExdc )
{
if ( Abc_ObjFaninNum(pObj) == 0 )
Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), pObj->pCopy );
if ( Abc_NtkIsAig(pNtk->pExdc) )
pNtkNew->pExdc = Abc_NtkAigToLogicSop( pNtk->pExdc );
else
Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), Abc_ObjFanin0(pObj)->pCopy );
pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
}
// connect the latches
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy );
// add the latches to the PI/PO arrays to make them look at CIs/COs
Abc_NtkForEachLatch( pNtk, pObj, i )
Vec_PtrPush( pNtkNew->vPis, pObj->pCopy );
Abc_NtkForEachLatch( pNtk, pObj, i )
Vec_PtrPush( pNtkNew->vPos, pObj->pCopy );
// transfer the names
Abc_NtkCreateNameArrays( pNtk, pNtkNew );
// duplicate EXDC
if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkAigToLogicSop(): Network check has failed.\n" );
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Converts the AIG into the logic network with SOPs for bench writing.]
Description [This procedure does not copy the choices.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk )
{
int fCheck = 1;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin;
Vec_Ptr_t * vNodes;
int i, k;
assert( Abc_NtkIsAig(pNtk) );
if ( Abc_NtkCountChoiceNodes(pNtk) )
printf( "Warning: Choice nodes are skipped.\n" );
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC_SOP );
// collect the nodes to be used (marks all nodes with current TravId)
vNodes = Abc_NtkDfs( pNtk );
// create inverters for the CI and remember them
Abc_NtkForEachCi( pNtk, pObj, i )
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
// duplicate the nodes, create node functions, and inverters
Vec_PtrForEachEntry( vNodes, pObj, i )
{
Abc_NtkDupObj( pNtkNew, pObj );
pObj->pCopy->pData = Abc_SopCreateAnd( pNtkNew->pManFunc, 2 );
if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
pObj->pCopy->pCopy = Abc_NodeCreateInv( pNtkNew, pObj->pCopy );
}
// connect the objects
Vec_PtrForEachEntry( vNodes, pObj, i )
Abc_ObjForEachFanin( pObj, pFanin, k )
{
if ( Abc_ObjFaninC( pObj, k ) )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy->pCopy );
else
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
}
Vec_PtrFree( vNodes );
// connect the COs
Abc_NtkFinalize( pNtk, pNtkNew );
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
// duplicate the EXDC Ntk
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkLogic( pNtk->pExdc );
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkLogic(): Network check has failed.\n" );
printf( "Warning: The EXDc network is skipped.\n" );
if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkAigToLogicSopBench(): Network check has failed.\n" );
return pNtkNew;
}
......
......@@ -72,6 +72,10 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk )
fprintf( pFile, " area = %5.2f", Abc_NtkGetMappedArea(pNtk) );
fprintf( pFile, " delay = %5.2f", Abc_NtkDelayTrace(pNtk) );
}
else if ( !Abc_NtkIsAig(pNtk) )
{
assert( 0 );
}
fprintf( pFile, " lev = %2d", Abc_NtkGetLevelNum(pNtk) );
fprintf( pFile, "\n" );
}
......@@ -89,43 +93,87 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk )
***********************************************************************/
void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj, * pLatch;
Abc_Obj_t * pObj;
int i;
if ( Abc_NtkIsNetlist(pNtk) )
fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) );
Abc_NtkForEachPi( pNtk, pObj, i )
fprintf( pFile, " %s", Abc_ObjName(pObj) );
fprintf( pFile, "\n" );
fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) );
Abc_NtkForEachPo( pNtk, pObj, i )
fprintf( pFile, " %s", Abc_ObjName(pObj) );
fprintf( pFile, "\n" );
fprintf( pFile, "Latches (%d): ", Abc_NtkLatchNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pObj, i )
fprintf( pFile, " %s", Abc_ObjName(pObj) );
fprintf( pFile, "\n" );
}
/**Function*************************************************************
Synopsis [Prints statistics about latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pLatch;
int i, Counter0, Counter1, Counter2;
int Init0, Init1, Init2;
if ( Abc_NtkLatchNum(pNtk) == 0 )
{
fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) );
Abc_NtkForEachPi( pNtk, pObj, i )
fprintf( pFile, " %s", Abc_ObjName(pObj) );
fprintf( pFile, "\n" );
fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) );
Abc_NtkForEachPo( pNtk, pObj, i )
fprintf( pFile, " %s", Abc_ObjName(pObj) );
fprintf( pFile, "\n" );
fprintf( pFile, "Latches (%d): ", Abc_NtkLatchNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pLatch, i )
fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanout0(pLatch)) );
fprintf( pFile, "\n" );
fprintf( pFile, "The network is combinational.\n" );
return;
}
else
assert( !Abc_NtkIsNetlist(pNtk) );
Init0 = Init1 = Init2 = 0;
Counter0 = Counter1 = Counter2 = 0;
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) );
Abc_NtkForEachPi( pNtk, pObj, i )
fprintf( pFile, " %s", pNtk->vNamesPi->pArray[i] );
fprintf( pFile, "\n" );
fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) );
Abc_NtkForEachPo( pNtk, pObj, i )
fprintf( pFile, " %s", pNtk->vNamesPo->pArray[i] );
fprintf( pFile, "\n" );
fprintf( pFile, "Latches (%d): ", Abc_NtkLatchNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pLatch, i )
fprintf( pFile, " %s", pNtk->vNamesLatch->pArray[i] );
fprintf( pFile, "\n" );
if ( pLatch->pData == (void *)0 )
Init0++;
else if ( pLatch->pData == (void *)1 )
Init1++;
else if ( pLatch->pData == (void *)2 )
Init2++;
else
assert( 0 );
if ( Abc_ObjFaninNum( Abc_ObjFanin0(pLatch) ) == 0 )
{
Counter0++;
if ( pLatch->pData == (void *)2 )
Counter1++;
else
{
if ( Abc_NtkIsAig(pNtk) )
{
if ( (pLatch->pData == (void *)1) ^ Abc_ObjFaninC0(pLatch) )
Counter2++;
}
else
{
if ( (pLatch->pData == (void *)1) ^ Abc_NodeIsConst0(pLatch) )
Counter2++;
}
}
}
}
fprintf( pFile, "Latches = %5d: Init 0 = %5d. Init 1 = %5d. Init any = %5d.\n", Abc_NtkLatchNum(pNtk), Init0, Init1, Init2 );
fprintf( pFile, "Constant driver = %4d. Init any = %4d. Init match = %4d.\n", Counter0, Counter1, Counter2 );
fprintf( pFile, "The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtk) );
}
/**Function*************************************************************
......@@ -245,7 +293,7 @@ void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i;
assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) );
assert( Abc_NtkIsLogicSop(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
Abc_NodePrintFactor( pFile, pNode );
}
......@@ -264,7 +312,7 @@ void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk )
void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode )
{
Vec_Int_t * vFactor;
if ( Abc_ObjIsPo(pNode) )
if ( Abc_ObjIsCo(pNode) )
pNode = Abc_ObjFanin0(pNode);
if ( Abc_ObjIsPi(pNode) )
{
......
......@@ -86,7 +86,7 @@ int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fFanouts, bool fReference )
{
Abc_Obj_t * pNode0, * pNode1;
int Counter;
if ( Abc_ObjIsPi(pNode) || Abc_ObjIsLatch(pNode) )
if ( Abc_ObjIsCi(pNode) )
return 0;
pNode0 = Abc_ObjFanin( pNode, 0 );
pNode1 = Abc_ObjFanin( pNode, 1 );
......
......@@ -81,6 +81,9 @@ Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCn
// make the network minimum base
Abc_NtkMinimumBase( pNtkNew );
// fix the problem with complemented and duplicated CO edges
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
// report the number of CNF objects
if ( fCnf )
{
......@@ -130,7 +133,7 @@ void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
Abc_NtkForEachCo( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
if ( Abc_ObjIsTerm(Abc_ObjFanin0(pNode)) )
if ( Abc_ObjIsCi(Abc_ObjFanin0(pNode)) )
continue;
Abc_NtkRenode_rec( pNtkNew, Abc_ObjFanin0(pNode) );
}
......
......@@ -91,7 +91,6 @@ void Abc_NodePrintBdd( Abc_Obj_t * pNode )
return;
}
// set the node names
Abc_NtkLogicTransferNames( pNode->pNtk );
vNamesIn = Abc_NodeGetFaninNames( pNode );
pNameOut = Abc_ObjName(pNode);
Cudd_DumpDot( pNode->pNtk->pManFunc, 1, (DdNode **)&pNode->pData, (char **)vNamesIn->pArray, &pNameOut, pFile );
......
......@@ -72,23 +72,199 @@ char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName )
***********************************************************************/
char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars )
{
char * pSopCover;
char * pCube;
int i, v;
pSopCover = Extra_MmFlexEntryFetch( pMan, nCubes * (nVars + 3) + 1 );
char * pSopCover, * pCube;
int i, Length;
Length = nCubes * (nVars + 3);
pSopCover = Extra_MmFlexEntryFetch( pMan, Length + 1 );
memset( pSopCover, '-', Length );
pSopCover[Length] = 0;
for ( i = 0; i < nCubes; i++ )
{
pCube = pSopCover + i * (nVars + 3);
for ( v = 0; v < nVars; v++ )
pCube[v] = '-';
pCube[nVars + 0] = ' ';
pCube[nVars + 1] = '1';
pCube[nVars + 2] = '\n';
}
pSopCover[nCubes * (nVars + 3)] = 0;
return pSopCover;
}
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateAnd2( Extra_MmFlex_t * pMan, int fCompl0, int fCompl1 )
{
char Buffer[6];
Buffer[0] = '1' - fCompl0;
Buffer[1] = '1' - fCompl1;
Buffer[2] = ' ';
Buffer[3] = '1';
Buffer[4] = '\n';
Buffer[5] = 0;
return Abc_SopRegister( pMan, Buffer );
}
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars )
{
char * pSop;
int i;
pSop = Abc_SopStart( pMan, 1, nVars );
for ( i = 0; i < nVars; i++ )
pSop[i] = '1';
return pSop;
}
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateNand( Extra_MmFlex_t * pMan, int nVars )
{
char * pSop;
int i;
pSop = Abc_SopStart( pMan, 1, nVars );
for ( i = 0; i < nVars; i++ )
pSop[i] = '1';
pSop[nVars + 1] = '0';
return pSop;
}
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateOr( Extra_MmFlex_t * pMan, int nVars, int * pfCompl )
{
char * pSop;
int i;
pSop = Abc_SopStart( pMan, 1, nVars );
for ( i = 0; i < nVars; i++ )
pSop[i] = '0' + (pfCompl? pfCompl[i] : 0);
pSop[nVars + 1] = '0';
return pSop;
}
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars )
{
char * pSop;
int i;
pSop = Abc_SopStart( pMan, 1, nVars );
for ( i = 0; i < nVars; i++ )
pSop[i] = '0';
return pSop;
}
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars )
{
assert( nVars == 2 );
return Abc_SopRegister(pMan, "01 1\n10 1\n");
}
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars )
{
assert( nVars == 2 );
return Abc_SopRegister(pMan, "11 1\n11 1\n");
}
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateInv( Extra_MmFlex_t * pMan )
{
return Abc_SopRegister(pMan, "0 1\n");
}
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan )
{
return Abc_SopRegister(pMan, "1 1\n");
}
/**Function*************************************************************
......
......@@ -121,7 +121,7 @@ stmm_table * Abc_NtkFraigEquiv( Fraig_Man_t * p, Abc_Ntk_t * pNtk, int fUseInv,
if ( Abc_ObjFaninNum(pNode) == 0 )
continue;
// skip the nodes that fanout into POs
if ( Abc_NtkIsLogicMap(pNtk) && Abc_NodeHasUniqueNamedFanout(pNode) )
if ( Abc_NodeHasUniqueCoFanout(pNode) )
continue;
// get the FRAIG node
gNode = Fraig_NotCond( Abc_ObjRegular(pNodeAig)->pCopy, Abc_ObjIsComplement(pNodeAig) );
......@@ -254,8 +254,8 @@ void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUs
{
Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst;
Arrival2 = Abc_NodeReadArrival(pNode )->Worst;
assert( Abc_ObjIsPi(pNodeMin) || Arrival1 > 0 );
assert( Abc_ObjIsPi(pNode) || Arrival2 > 0 );
assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 );
assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 );
if ( Arrival1 > Arrival2 ||
Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level ||
Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level &&
......@@ -274,8 +274,8 @@ void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUs
{
Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst;
Arrival2 = Abc_NodeReadArrival(pNode )->Worst;
assert( Abc_ObjIsPi(pNodeMin) || Arrival1 > 0 );
assert( Abc_ObjIsPi(pNode) || Arrival2 > 0 );
assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 );
assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 );
if ( Arrival1 > Arrival2 ||
Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level ||
Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level &&
......
......@@ -285,7 +285,7 @@ Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUn
pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC_BDD );
// create PIs corresponding to LOs
Abc_NtkForEachLatch( pNtk, pNode, i )
pNode->pCopy = Abc_NtkCreateTermPi(pNtkNew);
pNode->pCopy = Abc_NtkCreatePi(pNtkNew);
// create a new node
pNodeNew = Abc_NtkCreateNode(pNtkNew);
......@@ -306,15 +306,15 @@ Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUn
// make the new node drive all the COs
Abc_NtkForEachCo( pNtk, pNode, i )
Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), pNodeNew );
Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew );
// copy the CI/CO names
Abc_NtkForEachLatch( pNtk, pNode, i )
Abc_NtkLogicStoreName( pNtkNew->vPis->pArray[i], Abc_NtkNameLatch(pNtk, i) );
Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pNode) );
Abc_NtkForEachPo( pNtk, pNode, i )
Abc_NtkLogicStoreName( pNtkNew->vPos->pArray[i], Abc_NtkNamePo(pNtk, i) );
Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(pNode) );
Abc_NtkForEachLatch( pNtk, pNode, i )
Abc_NtkLogicStoreName( pNtkNew->vPos->pArray[Abc_NtkPoNum(pNtk) + i], Abc_NtkNameLatchInput(pNtk, i) );
Abc_NtkLogicStoreName( Abc_NtkCo(pNtkNew,Abc_NtkPoNum(pNtk) + i), Abc_ObjName(pNode) );
// transform the network to the SOP representation
Abc_NtkBddToSop( pNtkNew );
......
......@@ -72,7 +72,7 @@ int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i, nCubes = 0;
assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) );
assert( Abc_NtkIsSop(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
{
assert( pNode->pData );
......@@ -96,7 +96,7 @@ int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i, nLits = 0;
assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) );
assert( Abc_NtkIsSop(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
{
assert( pNode->pData );
......@@ -121,7 +121,7 @@ int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk )
Vec_Int_t * vFactor;
Abc_Obj_t * pNode;
int nNodes, i;
assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) );
assert( Abc_NtkIsSop(pNtk) );
nNodes = 0;
// Ft_FactorStartMan();
Abc_NtkForEachNode( pNtk, pNode, i )
......@@ -281,121 +281,139 @@ void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
Abc_Obj_t * Abc_NodeHasUniqueNamedFanout( Abc_Obj_t * pNode )
Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode )
{
Abc_Obj_t * pFanout, * pFanoutNamed;
Abc_Obj_t * pFanout, * pFanoutCo;
int i, Counter;
if ( !Abc_ObjIsNode(pNode) )
return NULL;
Counter = 0;
Abc_ObjForEachFanout( pNode, pFanout, i )
{
if ( (Abc_ObjIsPo(pFanout) || Abc_ObjIsLatch(pFanout)) && !Abc_ObjFaninC0(pFanout) )
if ( Abc_ObjIsCo(pFanout) && !Abc_ObjFaninC0(pFanout) )
{
assert( Abc_ObjFaninNum(pFanout) == 1 );
assert( Abc_ObjFanin0(pFanout) == pNode );
pFanoutNamed = pFanout;
pFanoutCo = pFanout;
Counter++;
}
}
if ( Counter == 1 )
return pFanoutNamed;
return pFanoutCo;
return NULL;
}
/**Function*************************************************************
Synopsis [Returns 1 if the PO names can be written directly.]
Synopsis [Returns 1 if COs of a logic network are simple.]
Description [This is true if the POs of the logic network are
not complemented and not duplicated. This condition has to be
specifically enforced after mapping, to make sure additional
INVs/BUFs are not written into the file.]
Description [The COs of a logic network are simple under three conditions:
(1) The edge from CO to its driver is not complemented.
(2) No two COs share the same driver.
(3) The driver is not a CI unless the CI and the CO have the same name
(and so the inv/buf should not be written into a file).]
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_NtkLogicHasSimplePos( Abc_Ntk_t * pNtk )
bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
Abc_Obj_t * pNode, * pDriver;
int i;
assert( !Abc_NtkIsNetlist(pNtk) );
// check if there are complemented or idential POs
Abc_NtkIncrementTravId( pNtk );
Abc_NtkForEachPo( pNtk, pNode, i )
Abc_NtkForEachCo( pNtk, pNode, i )
{
pNode = Abc_ObjChild0(pNode);
if ( Abc_ObjIsComplement(pNode) )
pDriver = Abc_ObjFanin0(pNode);
if ( Abc_ObjFaninC0(pNode) )
return 0;
if ( Abc_NodeIsTravIdCurrent(pNode) )
if ( Abc_NodeIsTravIdCurrent(pDriver) )
return 0;
Abc_NodeSetTravIdCurrent(pNode);
if ( Abc_ObjIsCi(pDriver) && strcmp( Abc_ObjName(pDriver), Abc_ObjName(pNode) ) != 0 )
return 0;
Abc_NodeSetTravIdCurrent(pDriver);
}
return 1;
}
/**Function*************************************************************
Synopsis [Transforms the network to have simple POs.]
Synopsis [Transforms the network to have simple COs.]
Description [The POs are simple if the POs of the logic network are
not complemented and not duplicated. This condition has to be
specifically enforced after FPGA mapping, to make sure additional
INVs/BUFs are not written into the file.]
Description [The COs of a logic network are simple under three conditions:
(1) The edge from the CO to its driver is not complemented.
(2) No two COs share the same driver.
(3) The driver is not a CI unless the CI and the CO have the same name
(and so the inv/buf should not be written into a file).
In some cases, such as FPGA mapping, we prevent the increase in delay
by duplicating the driver nodes, rather than adding invs/bufs.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkLogicMakeSimplePos( Abc_Ntk_t * pNtk )
int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate )
{
Abc_Obj_t * pNode, * pDriver, * pDriverDup, * pFanin;
Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin;
int i, k, nDupGates = 0;
assert( Abc_NtkIsLogic(pNtk) );
// if a PO driver has more than one fanout, duplicate it
// process the COs by adding inverters and buffers when necessary
Abc_NtkForEachCo( pNtk, pNode, i )
{
pDriver = Abc_ObjFanin0(pNode);
if ( Abc_ObjFanoutNum(pDriver) == 1 )
continue;
// do not modify CI
if ( !Abc_ObjIsNode(pDriver) )
continue;
pDriverDup = Abc_NtkDupObj( pNtk, pDriver );
Abc_ObjForEachFanin( pDriver, pFanin, k )
Abc_ObjAddFanin( pDriverDup, pFanin );
if ( Abc_ObjIsCi(pDriver) )
{
// skip the case when the CI deriver has the same name as CO
if ( strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) == 0 )
continue;
}
else
{
// skip the case when the driver's unique CO fanout is this CO
if ( Abc_NodeHasUniqueCoFanout(pDriver) == pNode )
continue;
}
if ( fDuplicate && !Abc_ObjIsCi(pDriver) )
{
pDriverNew = Abc_NtkDupObj( pNtk, pDriver );
Abc_ObjForEachFanin( pDriver, pFanin, k )
Abc_ObjAddFanin( pDriverNew, pFanin );
if ( Abc_ObjFaninC0(pNode) )
{
// change polarity of the duplicated driver
if ( Abc_NtkIsLogicSop(pNtk) )
Abc_SopComplement( pDriverNew->pData );
else if ( Abc_NtkIsLogicBdd(pNtk) )
pDriverNew->pData = Cudd_Not( pDriverNew->pData );
else
assert( 0 );
Abc_ObjXorFaninC(pNode, 0);
}
}
else
{
// add inverters and buffers when necessary
if ( Abc_ObjFaninC0(pNode) )
{
pDriverNew = Abc_NodeCreateInv( pNtk, pDriver );
Abc_ObjXorFaninC( pNode, 0 );
}
else
pDriverNew = Abc_NodeCreateBuf( pNtk, pDriver );
}
// update the fanin of the PO node
Abc_ObjPatchFanin( pNode, pDriver, pDriverDup );
assert( Abc_ObjFanoutNum(pDriverDup) == 1 );
Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
assert( Abc_ObjFanoutNum(pDriverNew) == 1 );
nDupGates++;
}
// if a PO comes complemented change the drivers function
Abc_NtkForEachCo( pNtk, pNode, i )
{
pDriver = Abc_ObjFanin0(pNode);
if ( !Abc_ObjFaninC0(pNode) )
continue;
// do not modify PIs and LOs
if ( !Abc_ObjIsNode(pDriver) )
continue;
// the driver is complemented - change polarity
if ( Abc_NtkIsLogicSop(pNtk) )
Abc_SopComplement( pDriver->pData );
else if ( Abc_NtkIsLogicBdd(pNtk) )
pDriver->pData = Cudd_Not( pDriver->pData );
else
assert( 0 );
// update the complemented edge of the fanin
Abc_ObjXorFaninC(pNode, 0);
assert( !Abc_ObjFaninC0(pNode) );
}
assert( Abc_NtkLogicHasSimpleCos(pNtk) );
return nDupGates;
}
/**Function*************************************************************
Synopsis [Inserts a new node in the order by levels.]
......@@ -444,7 +462,7 @@ bool Abc_NodeIsMuxType( Abc_Obj_t * pNode )
// check that the node is regular
assert( !Abc_ObjIsComplement(pNode) );
// if the node is not AND, this is not MUX
if ( !Abc_NodeIsAnd(pNode) )
if ( !Abc_NodeIsAigAnd(pNode) )
return 0;
// if the children are not complemented, this is not MUX
if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
......@@ -576,7 +594,7 @@ int Abc_NtkCountChoiceNodes( Abc_Ntk_t * pNtk )
return 0;
Counter = 0;
Abc_NtkForEachNode( pNtk, pNode, i )
Counter += Abc_NodeIsChoice( pNode );
Counter += Abc_NodeIsAigChoice( pNode );
return Counter;
}
......@@ -818,6 +836,37 @@ void Abc_NodeFreeFaninNames( Vec_Ptr_t * vNames )
Vec_PtrFree( vNames );
}
/**Function*************************************************************
Synopsis [Collects the CI or CO names.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char ** Abc_NtkCollectCioNames( Abc_Ntk_t * pNtk, int fCollectCos )
{
Abc_Obj_t * pObj;
char ** ppNames;
int i;
if ( fCollectCos )
{
ppNames = ALLOC( char *, Abc_NtkCoNum(pNtk) );
Abc_NtkForEachCo( pNtk, pObj, i )
ppNames[i] = Abc_ObjName(pObj);
}
else
{
ppNames = ALLOC( char *, Abc_NtkCiNum(pNtk) );
Abc_NtkForEachCi( pNtk, pObj, i )
ppNames[i] = Abc_ObjName(pObj);
}
return ppNames;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
......@@ -32,7 +32,6 @@ static int IoCommandReadVerilog ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadPla ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBlif ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteGate ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBench ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteCnf ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWritePla ( Abc_Frame_t * pAbc, int argc, char **argv );
......@@ -61,7 +60,6 @@ void Io_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "I/O", "read_pla", IoCommandReadPla, 1 );
Cmd_CommandAdd( pAbc, "I/O", "write_blif", IoCommandWriteBlif, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_gate", IoCommandWriteGate, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_bench", IoCommandWriteBench, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_cnf", IoCommandWriteCnf, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_pla", IoCommandWritePla, 0 );
......@@ -214,7 +212,7 @@ int IoCommandReadBlif( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
pNtk = Abc_NtkLogic( pTemp = pNtk );
pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
Abc_NtkDelete( pTemp );
if ( pNtk == NULL )
{
......@@ -294,7 +292,7 @@ int IoCommandReadBench( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
pNtk = Abc_NtkLogic( pTemp = pNtk );
pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
Abc_NtkDelete( pTemp );
if ( pNtk == NULL )
{
......@@ -374,7 +372,7 @@ int IoCommandReadVerilog( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
pNtk = Abc_NtkLogic( pTemp = pNtk );
pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
Abc_NtkDelete( pTemp );
if ( pNtk == NULL )
{
......@@ -454,7 +452,7 @@ int IoCommandReadPla( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
pNtk = Abc_NtkLogic( pTemp = pNtk );
pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
Abc_NtkDelete( pTemp );
if ( pNtk == NULL )
{
......@@ -488,8 +486,8 @@ usage:
***********************************************************************/
int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
{
Abc_Ntk_t * pNtk;
char * FileName;
int fMadeComb;
int fWriteLatches;
int c;
......@@ -509,7 +507,8 @@ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
}
}
if ( pAbc->pNtkCur == NULL )
pNtk = pAbc->pNtkCur;
if ( pNtk == NULL )
{
fprintf( pAbc->Out, "Empty network.\n" );
return 0;
......@@ -519,38 +518,15 @@ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
{
goto usage;
}
if ( Abc_NtkIsLogicMap(pAbc->pNtkCur) )
{
fprintf( pAbc->Out, "Use \"write_gate\" or unmap the network (\"unmap\").\n" );
return 1;
}
// get the input file name
FileName = argv[util_optind];
// write the file
if ( Abc_NtkIsNetlist(pAbc->pNtkCur) )
{
if ( !fWriteLatches )
fMadeComb = Abc_NtkMakeComb( pAbc->pNtkCur );
Io_WriteBlif( pAbc->pNtkCur, FileName );
if ( !fWriteLatches && fMadeComb )
Abc_NtkMakeSeq( pAbc->pNtkCur );
}
else if ( Abc_NtkIsLogicSop(pAbc->pNtkCur) || Abc_NtkIsAig(pAbc->pNtkCur) )
{
Io_WriteBlifLogic( pAbc->pNtkCur, FileName, fWriteLatches );
}
else if ( Abc_NtkIsLogicBdd(pAbc->pNtkCur) )
{
// printf( "Converting node functions from BDD to SOP.\n" );
Abc_NtkBddToSop(pAbc->pNtkCur);
Io_WriteBlifLogic( pAbc->pNtkCur, FileName, fWriteLatches );
}
else
// check the network type
if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsAig(pNtk) )
{
assert( 0 );
fprintf( pAbc->Out, "Currently can only write logic networks and AIGs.\n" );
return 0;
}
Io_WriteBlifLogic( pNtk, FileName, fWriteLatches );
return 0;
usage:
......@@ -573,14 +549,13 @@ usage:
SeeAlso []
***********************************************************************/
int IoCommandWriteGate( Abc_Frame_t * pAbc, int argc, char **argv )
int IoCommandWriteBench( Abc_Frame_t * pAbc, int argc, char **argv )
{
Abc_Ntk_t * pNtk;
Abc_Ntk_t * pNtk, * pNtkTemp;
char * FileName;
int fWriteLatches;
int c;
pNtk = pAbc->pNtkCur;
fWriteLatches = 1;
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "lh" ) ) != EOF )
......@@ -597,84 +572,19 @@ int IoCommandWriteGate( Abc_Frame_t * pAbc, int argc, char **argv )
}
}
pNtk = pAbc->pNtkCur;
if ( pNtk == NULL )
{
fprintf( pAbc->Out, "Empty network.\n" );
return 0;
}
if ( !Abc_NtkIsLogicMap(pNtk) )
{
fprintf( pAbc->Out, "The network is not mapped.\n" );
return 0;
}
/*
if ( Abc_NtkLatchNum(pNtk) > 0 )
{
fprintf( pAbc->Out, "The network has latches.\n" );
return 0;
}
*/
if ( argc != util_optind + 1 )
{
goto usage;
}
// get the input file name
FileName = argv[util_optind];
// write the file
Io_WriteGate( pNtk, FileName );
return 0;
usage:
fprintf( pAbc->Err, "usage: write_gate [-h] <file>\n" );
fprintf( pAbc->Err, "\t write the network into a mapped BLIF file (.gate ...)\n" );
// fprintf( pAbc->Err, "\t-l : toggle writing latches [default = %s]\n", fWriteLatches? "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;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int IoCommandWriteBench( Abc_Frame_t * pAbc, int argc, char **argv )
{
Abc_Ntk_t * pNtk;
char * FileName;
int fWriteLatches;
int c;
pNtk = pAbc->pNtkCur;
fWriteLatches = 1;
util_getopt_reset();
while ( ( c = util_getopt( argc, argv, "lh" ) ) != EOF )
{
switch ( c )
{
case 'l':
fWriteLatches ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pAbc->Out, "Empty network.\n" );
return 0;
}
if ( !Abc_NtkIsAig(pNtk) )
{
......@@ -682,15 +592,15 @@ int IoCommandWriteBench( Abc_Frame_t * pAbc, int argc, char **argv )
return 0;
}
if ( argc != util_optind + 1 )
// derive the netlist
pNtkTemp = Abc_NtkLogicToNetlistBench(pNtk);
if ( pNtkTemp == NULL )
{
goto usage;
fprintf( pAbc->Out, "Writing BENCH has failed.\n" );
return 0;
}
// get the input file name
FileName = argv[util_optind];
// write the file
Io_WriteBench( pNtk, FileName );
Io_WriteBench( pNtkTemp, FileName );
Abc_NtkDelete( pNtkTemp );
return 0;
usage:
......@@ -772,6 +682,7 @@ usage:
***********************************************************************/
int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv )
{
Abc_Ntk_t * pNtk, * pNtkTemp;
char * FileName;
int c;
......@@ -787,31 +698,41 @@ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv )
}
}
if ( pAbc->pNtkCur == NULL )
pNtk = pAbc->pNtkCur;
if ( pNtk == NULL )
{
fprintf( pAbc->Out, "Empty network.\n" );
return 0;
}
if ( Abc_NtkGetLevelNum(pAbc->pNtkCur) > 1 )
if ( Abc_NtkGetLevelNum(pNtk) > 1 )
{
fprintf( pAbc->Out, "PLA writing is available for collapsed networks.\n" );
return 0;
}
if ( Abc_NtkLatchNum(pNtk) > 0 )
{
fprintf( pAbc->Out, "Latches are writed at PI/PO pairs in the PLA file.\n" );
return 0;
}
if ( argc != util_optind + 1 )
{
goto usage;
}
// get the input file name
FileName = argv[util_optind];
// write the file
if ( !Io_WritePla( pAbc->pNtkCur, FileName ) )
// derive the netlist
pNtkTemp = Abc_NtkLogicToNetlist(pNtk);
if ( pNtkTemp == NULL )
{
printf( "Writing PLA has failed.\n" );
return 1;
fprintf( pAbc->Out, "Writing PLA has failed.\n" );
return 0;
}
Io_WritePla( pNtkTemp, FileName );
Abc_NtkDelete( pNtkTemp );
return 0;
usage:
......
......@@ -53,18 +53,22 @@ extern Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck );
extern Abc_Ntk_t * Io_ReadBench( char * pFileName, int fCheck );
/*=== abcReadVerilog.c ==========================================================*/
extern Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck );
extern void Io_ReadSetNonDrivenNets( Abc_Ntk_t * pNet );
/*=== abcReadPla.c ==========================================================*/
extern Abc_Ntk_t * Io_ReadPla( char * pFileName, int fCheck );
/*=== abcUtil.c ==========================================================*/
extern Abc_Obj_t * Io_ReadCreatePi( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Io_ReadCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO );
extern Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, char * pNamesIn[], int nInputs );
extern Abc_Obj_t * Io_ReadCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 );
extern Abc_Obj_t * Io_ReadCreateInv( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut );
extern Abc_Obj_t * Io_ReadCreateBuf( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut );
/*=== abcWriteBlif.c ==========================================================*/
extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName );
extern void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk );
/*=== abcWriteBlifLogic.c ==========================================================*/
extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk );
/*=== abcWriteBench.c ==========================================================*/
extern int Io_WriteBench( Abc_Ntk_t * pNtk, char * FileName );
/*=== abcWriteGate.c ==========================================================*/
extern int Io_WriteGate( Abc_Ntk_t * pNtk, char * FileName );
/*=== abcWriteCnf.c ==========================================================*/
extern int Io_WriteCnf( Abc_Ntk_t * pNtk, char * FileName );
/*=== abcWritePla.c ==========================================================*/
......
......@@ -58,7 +58,7 @@ Abc_Ntk_t * Io_Read( char * pFileName, int fCheck )
}
if ( pNtk == NULL )
return NULL;
pNtk = Abc_NtkLogic( pTemp = pNtk );
pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
Abc_NtkDelete( pTemp );
if ( pNtk == NULL )
{
......
......@@ -82,17 +82,13 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
ProgressBar * pProgress;
Vec_Ptr_t * vTokens;
Abc_Ntk_t * pNtk;
Abc_Obj_t * pNet, * pLatch, * pNode;
Abc_Obj_t * pNet, * pNode;
Vec_Str_t * vString;
char * pType;
int SymbolIn, SymbolOut, i, iLine;
char * pType, ** ppNames;
int iLine, nNames;
// allocate the empty network
pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST );
// set the specs
pNtk->pName = util_strsav( Extra_FileReaderGetFileName(p) );
pNtk->pSpec = util_strsav( Extra_FileReaderGetFileName(p) );
pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) );
// go through the lines of the file
vString = Vec_StrAlloc( 100 );
......@@ -110,115 +106,61 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
// get the type of the line
if ( strncmp( vTokens->pArray[0], "INPUT", 5 ) == 0 )
{
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[1] );
if ( Abc_ObjIsPi(pNet) )
printf( "Warning: PI net \"%s\" appears twice in the list.\n", vTokens->pArray[1] );
else
Abc_NtkMarkNetPi( pNet );
}
Io_ReadCreatePi( pNtk, vTokens->pArray[1] );
else if ( strncmp( vTokens->pArray[0], "OUTPUT", 5 ) == 0 )
{
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[1] );
if ( Abc_ObjIsPo(pNet) )
printf( "Warning: PO net \"%s\" appears twice in the list.\n", vTokens->pArray[1] );
else
Abc_NtkMarkNetPo( pNet );
}
Io_ReadCreatePo( pNtk, vTokens->pArray[1] );
else
{
// get the node name and the node type
pType = vTokens->pArray[1];
if ( strcmp(pType, "DFF") == 0 )
{
// create a new node and add it to the network
pLatch = Abc_NtkCreateLatch( pNtk );
// create the LO (PI)
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[0] );
Abc_ObjAddFanin( pNet, pLatch );
Abc_ObjSetSubtype( pNet, ABC_OBJ_SUBTYPE_LO );
// save the LI (PO)
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[2] );
Abc_ObjAddFanin( pLatch, pNet );
Abc_ObjSetSubtype( pNet, ABC_OBJ_SUBTYPE_LI );
}
Io_ReadCreateLatch( pNtk, vTokens->pArray[2], vTokens->pArray[0] );
else
{
// create a new node and add it to the network
pNode = Abc_NtkCreateNode( pNtk );
// get the input symbol to be inserted
if ( !strncmp(pType, "BUF", 3) || !strcmp(pType, "AND") || !strcmp(pType, "NAND") )
SymbolIn = '1';
else if ( !strncmp(pType, "NOT", 3) || !strcmp(pType, "OR") || !strcmp(pType, "NOR") )
SymbolIn = '0';
else if ( !strcmp(pType, "XOR") || !strcmp(pType, "NXOR") )
SymbolIn = '*';
else
ppNames = (char **)vTokens->pArray + 2;
nNames = vTokens->nSize - 2;
pNode = Io_ReadCreateNode( pNtk, vTokens->pArray[0], ppNames, nNames );
// assign the cover
if ( strcmp(pType, "AND") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateAnd(pNtk->pManFunc, nNames) );
else if ( strcmp(pType, "OR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateOr(pNtk->pManFunc, nNames, NULL) );
else if ( strcmp(pType, "NAND") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateNand(pNtk->pManFunc, nNames) );
else if ( strcmp(pType, "NOR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateNor(pNtk->pManFunc, nNames) );
else if ( strcmp(pType, "XOR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateXor(pNtk->pManFunc, nNames) );
else if ( strcmp(pType, "NXOR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateNxor(pNtk->pManFunc, nNames) );
else if ( strncmp(pType, "BUF", 3) == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateBuf(pNtk->pManFunc) );
else if ( strcmp(pType, "NOT") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateInv(pNtk->pManFunc) );
else
{
printf( "Cannot determine gate type \"%s\" in line %d.\n", pType, Extra_FileReaderGetLineNumber(p, 0) );
Abc_NtkDelete( pNtk );
return NULL;
}
// get the output symbol
if ( !strcmp(pType, "NAND") || !strcmp(pType, "OR") || !strcmp(pType, "NXOR") )
SymbolOut = '0';
else
SymbolOut = '1';
// add the fanout net
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[0] );
Abc_ObjAddFanin( pNet, pNode );
// add the fanin nets
for ( i = 2; i < vTokens->nSize; i++ )
{
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[i] );
Abc_ObjAddFanin( pNode, pNet );
}
if ( SymbolIn != '*' )
{
// fill in the function
Vec_StrFill( vString, vTokens->nSize - 2, (char)SymbolIn );
Vec_StrPush( vString, ' ' );
Vec_StrPush( vString, (char)SymbolOut );
Vec_StrPush( vString, '\n' );
Vec_StrPush( vString, '\0' );
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, vString->pArray) );
}
else
{ // write XOR/NXOR gates
assert( i == 4 );
if ( SymbolOut == '1' )
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "01 1\n10 1\n") );
else
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "00 1\n11 1\n") );
}
}
}
}
Extra_ProgressBarStop( pProgress );
Vec_StrFree( vString );
// check if constant have been added
if ( pNet = Abc_NtkFindNet( pNtk, "vdd" ) )
{
// create the constant 1 node
pNode = Abc_NtkCreateNode( pNtk );
Abc_ObjAddFanin( pNet, pNode );
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 1\n") );
}
Io_ReadCreateConst( pNtk, "vdd", 1 );
if ( pNet = Abc_NtkFindNet( pNtk, "gnd" ) )
{
// create the constant 1 node
pNode = Abc_NtkCreateNode( pNtk );
Abc_ObjAddFanin( pNet, pNode );
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") );
}
Io_ReadCreateConst( pNtk, "gnd", 0 );
Io_ReadSetNonDrivenNets( pNtk );
Vec_StrFree( vString );
Abc_NtkFinalizeRead( pNtk );
return pNtk;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -19,6 +19,8 @@
***********************************************************************/
#include "io.h"
#include "main.h"
#include "mio.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -28,19 +30,19 @@ typedef struct Io_ReadBlif_t_ Io_ReadBlif_t; // all reading info
struct Io_ReadBlif_t_
{
// general info about file
char * pFileName; // the name of the file
Extra_FileReader_t* pReader; // the input file reader
char * pFileName; // the name of the file
Extra_FileReader_t * pReader; // the input file reader
// current processing info
Abc_Ntk_t * pNtk; // the primary network
Abc_Ntk_t * pNtkExdc; // the exdc network
int fParsingExdc; // this flag is on, when we are parsing EXDC network
int LineCur; // the line currently parsed
Abc_Ntk_t * pNtk; // the primary network
Abc_Ntk_t * pNtkExdc; // the exdc network
int fParsingExdc; // this flag is on, when we are parsing EXDC network
int LineCur; // the line currently parsed
// temporary storage for tokens
Vec_Ptr_t * vNewTokens; // the temporary storage for the tokens
Vec_Str_t * vCubes; // the temporary storage for the tokens
Vec_Ptr_t * vNewTokens; // the temporary storage for the tokens
Vec_Str_t * vCubes; // the temporary storage for the tokens
// the error message
FILE * Output; // the output stream
char sError[1000]; // the error string generated during parsing
FILE * Output; // the output stream
char sError[1000]; // the error string generated during parsing
};
static Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName );
......@@ -48,11 +50,13 @@ static void Io_ReadBlifFree( Io_ReadBlif_t * p );
static void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p );
static Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p );
static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p );
static char * Io_ReadBlifCleanName( char * pName );
static int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens );
static int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
......@@ -271,7 +275,7 @@ Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
{
ProgressBar * pProgress;
Vec_Ptr_t * vTokens;
char * pModelName;
char * pModelName, * pDirective;
int iLine, fTokensReady, fStatus;
// read the model name
......@@ -288,12 +292,12 @@ Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
}
pModelName = vTokens->pArray[1];
// allocate the empty network
p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST );
p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST_SOP );
p->pNtk->pName = util_strsav( pModelName );
p->pNtk->pSpec = util_strsav( p->pFileName );
}
else
p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST );
p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST_SOP );
// read the inputs/outputs
pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
......@@ -305,32 +309,35 @@ Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
// consider different line types
fTokensReady = 0;
if ( !strcmp( vTokens->pArray[0], ".names" ) )
pDirective = vTokens->pArray[0];
if ( !strcmp( pDirective, ".names" ) )
{ fStatus = Io_ReadBlifNetworkNames( p, &vTokens ); fTokensReady = 1; }
else if ( !strcmp( vTokens->pArray[0], ".latch" ) )
else if ( !strcmp( pDirective, ".gate" ) )
fStatus = Io_ReadBlifNetworkGate( p, vTokens );
else if ( !strcmp( pDirective, ".latch" ) )
fStatus = Io_ReadBlifNetworkLatch( p, vTokens );
else if ( !strcmp( vTokens->pArray[0], ".inputs" ) )
else if ( !strcmp( pDirective, ".inputs" ) )
fStatus = Io_ReadBlifNetworkInputs( p, vTokens );
else if ( !strcmp( vTokens->pArray[0], ".outputs" ) )
else if ( !strcmp( pDirective, ".outputs" ) )
fStatus = Io_ReadBlifNetworkOutputs( p, vTokens );
else if ( !strcmp( vTokens->pArray[0], ".input_arrival" ) )
else if ( !strcmp( pDirective, ".input_arrival" ) )
fStatus = Io_ReadBlifNetworkInputArrival( p, vTokens );
else if ( !strcmp( vTokens->pArray[0], ".default_input_arrival" ) )
else if ( !strcmp( pDirective, ".default_input_arrival" ) )
fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, vTokens );
else if ( !strcmp( vTokens->pArray[0], ".exdc" ) )
else if ( !strcmp( pDirective, ".exdc" ) )
{ p->fParsingExdc = 1; break; }
else if ( !strcmp( vTokens->pArray[0], ".end" ) )
else if ( !strcmp( pDirective, ".end" ) )
break;
else
printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName,
Extra_FileReaderGetLineNumber(p->pReader, 0), vTokens->pArray[0] );
Extra_FileReaderGetLineNumber(p->pReader, 0), pDirective );
if ( vTokens == NULL ) // some files do not have ".end" in the end
break;
if ( fStatus == 1 )
return NULL;
}
Extra_ProgressBarStop( pProgress );
Io_ReadSetNonDrivenNets( p->pNtk );
Abc_NtkFinalizeRead( p->pNtk );
return p->pNtk;
}
......@@ -347,17 +354,9 @@ Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
***********************************************************************/
int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
Abc_Ntk_t * pNtk = p->pNtk;
Abc_Obj_t * pNet;
int i;
for ( i = 1; i < vTokens->nSize; i++ )
{
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[i] );
if ( Abc_ObjIsPi(pNet) )
printf( "Warning: PI net \"%s\" appears twice in the list.\n", vTokens->pArray[i] );
else
Abc_NtkMarkNetPi( pNet );
}
Io_ReadCreatePi( p->pNtk, vTokens->pArray[i] );
return 0;
}
......@@ -374,17 +373,9 @@ int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
***********************************************************************/
int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
Abc_Ntk_t * pNtk = p->pNtk;
Abc_Obj_t * pNet;
int i;
for ( i = 1; i < vTokens->nSize; i++ )
{
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[i] );
if ( Abc_ObjIsPo(pNet) )
printf( "Warning: PO net \"%s\" appears twice in the list.\n", vTokens->pArray[i] );
else
Abc_NtkMarkNetPo( pNet );
}
Io_ReadCreatePo( p->pNtk, vTokens->pArray[i] );
return 0;
}
......@@ -402,7 +393,7 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
Abc_Ntk_t * pNtk = p->pNtk;
Abc_Obj_t * pNet, * pLatch;
Abc_Obj_t * pLatch;
int ResetValue;
if ( vTokens->nSize < 3 )
......@@ -412,16 +403,8 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
// create a new node and add it to the network
pLatch = Abc_NtkCreateLatch( pNtk );
// create the LO (PI)
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[2] );
Abc_ObjAddFanin( pNet, pLatch );
Abc_ObjSetSubtype( pNet, ABC_OBJ_SUBTYPE_LO );
// save the LI (PO)
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[1] );
Abc_ObjAddFanin( pLatch, pNet );
Abc_ObjSetSubtype( pNet, ABC_OBJ_SUBTYPE_LI );
// create the latch
pLatch = Io_ReadCreateLatch( pNtk, vTokens->pArray[1], vTokens->pArray[2] );
// get the latch reset value
if ( vTokens->nSize == 3 )
ResetValue = 2;
......@@ -455,12 +438,11 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
{
Vec_Ptr_t * vTokens = *pvTokens;
Abc_Ntk_t * pNtk = p->pNtk;
Abc_Obj_t * pNet, * pNode;
char * pToken, Char;
int i, nFanins;
Abc_Obj_t * pNode;
char * pToken, Char, ** ppNames;
int nFanins, nNames;
// create a new node and add it to the network
pNode = Abc_NtkCreateNode( pNtk );
if ( vTokens->nSize < 2 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
......@@ -468,19 +450,17 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
// go through the nets
for ( i = 1; i < vTokens->nSize - 1; i++ )
{
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[i] );
Abc_ObjAddFanin( pNode, pNet );
}
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[vTokens->nSize - 1] );
Abc_ObjAddFanin( pNet, pNode );
// create the node
ppNames = (char **)vTokens->pArray + 1;
nNames = vTokens->nSize - 2;
pNode = Io_ReadCreateNode( pNtk, ppNames[nNames], ppNames, nNames );
// derive the functionality of the node
p->vCubes->nSize = 0;
nFanins = vTokens->nSize - 2;
if ( nFanins == 0 )
{
while ( vTokens = Io_ReadBlifGetTokens(p) )
{
pToken = vTokens->pArray[0];
......@@ -500,7 +480,9 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
Vec_StrPush( p->vCubes, Char );
Vec_StrPush( p->vCubes, '\n' );
}
}
else
{
while ( vTokens = Io_ReadBlifGetTokens(p) )
{
pToken = vTokens->pArray[0];
......@@ -515,8 +497,7 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
return 1;
}
// create the cube
for ( i = 0; i < nFanins; i++ )
Vec_StrPush( p->vCubes, ((char *)vTokens->pArray[0])[i] );
Vec_StrAppend( p->vCubes, vTokens->pArray[0] );
// check the char
Char = ((char *)vTokens->pArray[1])[0];
if ( Char != '0' && Char != '1' )
......@@ -530,6 +511,7 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
Vec_StrPush( p->vCubes, Char );
Vec_StrPush( p->vCubes, '\n' );
}
}
// if there is nothing there
if ( p->vCubes->nSize == 0 )
{
......@@ -539,13 +521,116 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
Vec_StrPush( p->vCubes, '\n' );
}
Vec_StrPush( p->vCubes, 0 );
// set the pointer to the functionality of the node
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, p->vCubes->pArray) );
// return the last array of tokens
*pvTokens = vTokens;
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
Mio_Library_t * pGenlib;
Mio_Gate_t * pGate;
Abc_Obj_t * pNode;
char ** ppNames;
int i, nNames;
// check that the library is available
pGenlib = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame());
if ( pGenlib == NULL )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "The current library is not available." );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
// create a new node and add it to the network
if ( vTokens->nSize < 2 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "The .gate line has less than two tokens." );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
// get the gate
pGate = Mio_LibraryReadGateByName( pGenlib, vTokens->pArray[1] );
if ( pGate == NULL )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Cannot find gate \"%s\" in the library.", vTokens->pArray[1] );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
// if this is the first line with gate, update the network type
if ( Abc_NtkNodeNum(p->pNtk) == 0 )
{
assert( p->pNtk->Type = ABC_NTK_NETLIST_SOP );
p->pNtk->Type = ABC_NTK_NETLIST_MAP;
Extra_MmFlexStop( p->pNtk->pManFunc, 0 );
p->pNtk->pManFunc = pGenlib;
}
// remove the formal parameter names
for ( i = 2; i < vTokens->nSize; i++ )
{
vTokens->pArray[i] = Io_ReadBlifCleanName( vTokens->pArray[i] );
if ( vTokens->pArray[i] == NULL )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "Invalid gate input assignment." );
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
}
// create the node
ppNames = (char **)vTokens->pArray + 2;
nNames = vTokens->nSize - 3;
pNode = Io_ReadCreateNode( p->pNtk, ppNames[nNames], ppNames, nNames );
// set the pointer to the functionality of the node
Abc_ObjSetData( pNode, pGate );
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Io_ReadBlifCleanName( char * pName )
{
int i, Length;
Length = strlen(pName);
for ( i = 0; i < Length; i++ )
if ( pName[i] == '=' )
return pName + i + 1;
return NULL;
}
/**Function*************************************************************
......
......@@ -82,7 +82,7 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
ProgressBar * pProgress;
Vec_Ptr_t * vTokens;
Abc_Ntk_t * pNtk;
Abc_Obj_t * pNet, * pNode;
Abc_Obj_t * pTerm, * pNode;
Vec_Str_t ** ppSops;
char Buffer[100];
int nInputs = -1, nOutputs = -1, nProducts = -1;
......@@ -90,11 +90,7 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
int i, k, iLine, nDigits, nCubes;
// allocate the empty network
pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST );
// set the specs
pNtk->pName = util_strsav( Extra_FileReaderGetFileName(p) );
pNtk->pSpec = util_strsav( Extra_FileReaderGetFileName(p) );
pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) );
// go through the lines of the file
nCubes = 0;
......@@ -126,26 +122,14 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
if ( vTokens->nSize - 1 != nInputs )
printf( "Warning: Mismatch between the number of PIs on the .i line (%d) and the number of PIs on the .ilb line (%d).\n", nInputs, vTokens->nSize - 1 );
for ( i = 1; i < vTokens->nSize; i++ )
{
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[i] );
if ( Abc_ObjIsPi(pNet) )
printf( "Warning: PI net \"%s\" appears twice in the list.\n", vTokens->pArray[1] );
else
Abc_NtkMarkNetPi( pNet );
}
Io_ReadCreatePi( pNtk, vTokens->pArray[i] );
}
else if ( strcmp( vTokens->pArray[0], ".ob" ) == 0 )
{
if ( vTokens->nSize - 1 != nOutputs )
printf( "Warning: Mismatch between the number of POs on the .o line (%d) and the number of POs on the .ob line (%d).\n", nOutputs, vTokens->nSize - 1 );
for ( i = 1; i < vTokens->nSize; i++ )
{
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[i] );
if ( Abc_ObjIsPo(pNet) )
printf( "Warning: PO net \"%s\" appears twice in the list.\n", vTokens->pArray[1] );
else
Abc_NtkMarkNetPo( pNet );
}
Io_ReadCreatePo( pNtk, vTokens->pArray[i] );
}
else
{
......@@ -162,8 +146,7 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
for ( i = 0; i < nInputs; i++ )
{
sprintf( Buffer, "x%0*d", nDigits, i );
pNet = Abc_NtkFindOrCreateNet( pNtk, Buffer );
Abc_NtkMarkNetPi( pNet );
Io_ReadCreatePi( pNtk, Buffer );
}
}
if ( Abc_NtkPoNum(pNtk) == 0 )
......@@ -178,8 +161,7 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
for ( i = 0; i < nOutputs; i++ )
{
sprintf( Buffer, "z%0*d", nDigits, i );
pNet = Abc_NtkFindOrCreateNet( pNtk, Buffer );
Abc_NtkMarkNetPo( pNet );
Io_ReadCreatePo( pNtk, Buffer );
}
}
if ( Abc_NtkNodeNum(pNtk) == 0 )
......@@ -187,13 +169,13 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
// create the PO drivers and add them
// start the SOP covers
ppSops = ALLOC( Vec_Str_t *, nOutputs );
Abc_NtkForEachPo( pNtk, pNet, i )
Abc_NtkForEachPo( pNtk, pTerm, i )
{
ppSops[i] = Vec_StrAlloc( 100 );
pNode = Abc_NtkCreateNode(pNtk);
for ( k = 0; k < nInputs; k++ )
Abc_ObjAddFanin( pNode, Abc_NtkPi(pNtk,k) );
Abc_ObjAddFanin( pNet, pNode );
Abc_ObjAddFanin( Abc_ObjFanout0(pTerm), pNode );
}
}
// read the cubes
......@@ -237,9 +219,9 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
nCubes, nProducts );
// add the SOP covers
Abc_NtkForEachPo( pNtk, pNet, i )
Abc_NtkForEachPo( pNtk, pTerm, i )
{
pNode = Abc_ObjFanin0(pNet);
pNode = Abc_ObjFanin0Ntk(pTerm);
if ( ppSops[i]->nSize == 0 )
{
Abc_ObjRemoveFanins(pNode);
......@@ -251,6 +233,7 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
Vec_StrFree( ppSops[i] );
}
free( ppSops );
Abc_NtkFinalizeRead( pNtk );
return pNtk;
}
......
......@@ -271,10 +271,16 @@ Abc_Ntk_t * Io_ReadVerNetwork( Io_ReadVer_t * p )
pModelName = vTokens->pArray[1];
// allocate the empty network
pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST );
pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST_SOP );
pNtk->pName = util_strsav( pModelName );
pNtk->pSpec = util_strsav( p->pFileName );
// create constant nodes and nets
Abc_NtkFindOrCreateNet( pNtk, "1'b0" );
Abc_NtkFindOrCreateNet( pNtk, "1'b1" );
Io_ReadCreateConst( pNtk, "1'b0", 0 );
Io_ReadCreateConst( pNtk, "1'b1", 1 );
// read the inputs/outputs
pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
for ( i = 0; vTokens = Extra_FileReaderGetTokens(p->pReader); i++ )
......@@ -348,7 +354,7 @@ Abc_Ntk_t * Io_ReadVerNetwork( Io_ReadVer_t * p )
for ( i = 0; i < p->vSkipped->nSize; i++ )
free( p->vSkipped->pArray[i] );
}
Io_ReadSetNonDrivenNets( pNtk );
Abc_NtkFinalizeRead( pNtk );
return pNtk;
}
......@@ -365,48 +371,25 @@ Abc_Ntk_t * Io_ReadVerNetwork( Io_ReadVer_t * p )
***********************************************************************/
bool Io_ReadVerNetworkAssign( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens )
{
Abc_Obj_t * pNet, * pNode;
assert( strcmp( vTokens->pArray[0], "assign" ) == 0 );
if ( strcmp( vTokens->pArray[3], "1'b0" ) != 0 && strcmp( vTokens->pArray[3], "1'b1" ) != 0 )
// make sure the driving variable exists
if ( !Abc_NtkFindNet( pNtk, vTokens->pArray[3] ) )
{
// handle assignment to a variable
if ( vTokens->nSize == 4 && (pNet = Abc_NtkFindNet(pNtk, vTokens->pArray[3])) )
{
// allocate the buffer node
pNode = Abc_NtkCreateNode( pNtk );
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "1 1\n") );
// add the fanin net
Abc_ObjAddFanin( pNode, pNet );
// add the fanout net
pNet = Abc_NtkFindNet(pNtk, vTokens->pArray[1]);
Abc_ObjAddFanin( pNet, pNode );
return 1;
}
// produce error in case of more complex assignment
p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
sprintf( p->sError, "The assign operator is handled only for assignment to a variable and a constant." );
sprintf( p->sError, "Cannot find net \"%s\". The assign operator is handled only for assignment to a variable and a constant.", vTokens->pArray[3] );
Io_ReadVerPrintErrorMessage( p );
return 0;
}
// allocate constant node
pNode = Abc_NtkCreateNode( pNtk );
// set the constant function
if ( ((char *)vTokens->pArray[3])[3] == '0' )
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") );
else
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 1\n") );
// set the fanout net
pNet = Abc_NtkFindNet( pNtk, vTokens->pArray[1] );
if ( pNet == NULL )
// make sure the driven variable exists
if ( !Abc_NtkFindNet( pNtk, vTokens->pArray[1] ) )
{
p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 1 );
p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
sprintf( p->sError, "Cannot find net \"%s\".", vTokens->pArray[1] );
Io_ReadVerPrintErrorMessage( p );
return 0;
}
Abc_ObjAddFanin( pNet, pNode );
// create a buffer
Io_ReadCreateBuf( pNtk, vTokens->pArray[3], vTokens->pArray[1] );
return 1;
}
......@@ -423,8 +406,8 @@ bool Io_ReadVerNetworkAssign( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vT
***********************************************************************/
bool Io_ReadVerNetworkSignal( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType )
{
char Buffer[1000];
Abc_Obj_t * pNet;
char Buffer[1000];
char * pToken;
int nSignals, k, Start, s;
......@@ -455,26 +438,27 @@ bool Io_ReadVerNetworkSignal( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vT
for ( s = 0; s < nSignals; s++ )
{
sprintf( Buffer, "%s[%d]", pToken, s );
pNet = Abc_NtkFindOrCreateNet( pNtk, Buffer );
if ( LineType == VER_INPUT || LineType == VER_INOUT )
Abc_NtkMarkNetPi( pNet );
Io_ReadCreatePi( pNtk, Buffer );
if ( LineType == VER_OUTPUT || LineType == VER_INOUT )
Abc_NtkMarkNetPo( pNet );
Io_ReadCreatePo( pNtk, Buffer );
if ( LineType != VER_INPUT && LineType != VER_OUTPUT && LineType != VER_INOUT )
pNet = Abc_NtkFindOrCreateNet( pNtk, Buffer );
}
}
else
{
pNet = Abc_NtkFindOrCreateNet( pNtk, pToken );
if ( LineType == VER_INPUT || LineType == VER_INOUT )
Abc_NtkMarkNetPi( pNet );
Io_ReadCreatePi( pNtk, pToken );
if ( LineType == VER_OUTPUT || LineType == VER_INOUT )
Abc_NtkMarkNetPo( pNet );
Io_ReadCreatePo( pNtk, pToken );
if ( LineType != VER_INPUT && LineType != VER_OUTPUT && LineType != VER_INOUT )
pNet = Abc_NtkFindOrCreateNet( pNtk, pToken );
}
}
return 1;
}
/**Function*************************************************************
Synopsis [Reads a simple gate from the verilog file.]
......@@ -488,17 +472,15 @@ bool Io_ReadVerNetworkSignal( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vT
***********************************************************************/
bool Io_ReadVerNetworkGateSimple( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType )
{
Abc_Obj_t * pNode, * pNet, * pNodeConst, * pNetConst;
Abc_Obj_t * pNet, * pNode;
char * pToken;
int nFanins, k;
// create the node
pNode = Abc_NtkCreateNode( pNtk );
// set the function
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][3]) );
// skip the gate type and gate name
// add the fanin nets
nFanins = s_CadenceGates[LineType][1][0] - '0';
// skip the gate type and gate name
for ( k = 2; k < vTokens->nSize - 1; k++ )
{
pToken = vTokens->pArray[k];
......@@ -510,23 +492,6 @@ bool Io_ReadVerNetworkGateSimple( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t
Abc_ObjAddFanin( pNode, pNet );
continue;
}
// handle the case of a constant
if ( strcmp( pToken, "1'b0" ) == 0 || strcmp( pToken, "1'b1" ) == 0 )
{
// create the net and link it to the node
pNetConst = Abc_NtkFindOrCreateNet( pNtk, pToken );
Abc_ObjAddFanin( pNode, pNetConst );
// allocate constant node
pNodeConst = Abc_NtkCreateNode( pNtk );
// set the constant function
if ( pToken[3] == '0' )
Abc_ObjSetData( pNodeConst, Abc_SopRegister(pNtk->pManFunc, " 0\n") );
else
Abc_ObjSetData( pNodeConst, Abc_SopRegister(pNtk->pManFunc, " 1\n") );
// add this node as the fanin of the constant net
Abc_ObjAddFanin( pNetConst, pNodeConst );
continue;
}
p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
sprintf( p->sError, "Cannot find net \"%s\".", pToken );
Io_ReadVerPrintErrorMessage( p );
......@@ -558,6 +523,8 @@ bool Io_ReadVerNetworkGateSimple( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t
return 0;
}
Abc_ObjAddFanin( pNet, pNode );
// set the function
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][3]) );
return 1;
}
......@@ -580,9 +547,7 @@ bool Io_ReadVerNetworkGateComplex( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t
// create the nodes
pNode1 = Abc_NtkCreateNode( pNtk );
Abc_ObjSetData( pNode1, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][3]) );
pNode2 = Abc_NtkCreateNode( pNtk );
Abc_ObjSetData( pNode2, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][4]) );
// skip the gate type and gate name
// add the fanin nets
nFanins = s_CadenceGates[LineType][1][0] - '0';
......@@ -649,6 +614,8 @@ bool Io_ReadVerNetworkGateComplex( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t
return 0;
}
Abc_ObjAddFanin( pNet, pNode2 );
Abc_ObjSetData( pNode1, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][3]) );
Abc_ObjSetData( pNode2, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][4]) );
return 1;
}
......@@ -665,7 +632,7 @@ bool Io_ReadVerNetworkGateComplex( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t
***********************************************************************/
bool Io_ReadVerNetworkLatch( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens )
{
Abc_Obj_t * pLatch, * pNet, * pNode;
Abc_Obj_t * pLatch, * pNet;
char * pToken, * pToken2, * pTokenRN, * pTokenSN, * pTokenSI, * pTokenSE, * pTokenD, * pTokenQ, * pTokenQN;
int k, fRN1, fSN1;
......@@ -717,59 +684,20 @@ bool Io_ReadVerNetworkLatch( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTo
Io_ReadVerPrintErrorMessage( p );
return 0;
}
// create the latch
pLatch = Abc_NtkCreateLatch( pNtk );
// create the LO (PI)
pNet = Abc_NtkFindOrCreateNet( pNtk, vTokens->pArray[1] );
Abc_ObjAddFanin( pNet, pLatch );
Abc_ObjSetSubtype( pNet, ABC_OBJ_SUBTYPE_LO );
// save the LI (PO)
pNet = Abc_NtkFindNet( pNtk, pTokenD );
if ( pNet == NULL )
if ( Abc_NtkFindNet( pNtk, pTokenD ) == NULL )
{
// check the case if it is not a constant input
if ( strcmp( pTokenD, "1'b0" ) && strcmp( pTokenD, "1'b1" ) )
{
p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
sprintf( p->sError, "Cannot find latch input net \"%s\".", pTokenD );
Io_ReadVerPrintErrorMessage( p );
return 0;
}
// create the constant net
if ( strcmp( pTokenD, "1'b0" ) == 0 )
pNet = Abc_NtkFindOrCreateNet( pNtk, "Constant0" );
else
pNet = Abc_NtkFindOrCreateNet( pNtk, "Constant1" );
// drive it with the constant node
if ( Abc_ObjFaninNum( pNet ) == 0 )
{
// allocate constant node
pNode = Abc_NtkCreateNode( pNtk );
// set the constant function
if ( strcmp( pTokenD, "1'b0" ) == 0 )
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") );
else
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 1\n") );
// add the fanout net
Abc_ObjAddFanin( pNet, pNode );
}
p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
sprintf( p->sError, "Cannot find latch input net \"%s\".", pTokenD );
Io_ReadVerPrintErrorMessage( p );
return 0;
}
Abc_ObjAddFanin( pLatch, pNet );
Abc_ObjSetSubtype( pNet, ABC_OBJ_SUBTYPE_LI );
// create the latch
pLatch = Io_ReadCreateLatch( pNtk, pTokenD, vTokens->pArray[1] );
// create the buffer if Q signal is available
if ( pTokenQ )
{
// create the node
pNode = Abc_NtkCreateNode( pNtk);
// set the function
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "1 1\n") );
// create fanin and fanout nets
pNet = Abc_NtkFindNet( pNtk, vTokens->pArray[1] );
Abc_ObjAddFanin( pNode, pNet );
pNet = Abc_NtkFindNet( pNtk, pTokenQ );
if ( pNet == NULL )
{
......@@ -778,17 +706,10 @@ bool Io_ReadVerNetworkLatch( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTo
Io_ReadVerPrintErrorMessage( p );
return 0;
}
Abc_ObjAddFanin( pNet, pNode );
Io_ReadCreateBuf( pNtk, vTokens->pArray[1], pTokenQ );
}
if ( pTokenQN )
{
// create the node
pNode = Abc_NtkCreateNode( pNtk );
// set the function
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "0 1\n") );
// create fanin and fanout nets
pNet = Abc_NtkFindNet( pNtk, vTokens->pArray[1] );
Abc_ObjAddFanin( pNode, pNet );
pNet = Abc_NtkFindNet( pNtk, pTokenQN );
if ( pNet == NULL )
{
......@@ -797,7 +718,7 @@ bool Io_ReadVerNetworkLatch( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTo
Io_ReadVerPrintErrorMessage( p );
return 0;
}
Abc_ObjAddFanin( pNet, pNode );
Io_ReadCreateInv( pNtk, vTokens->pArray[1], pTokenQN );
}
// set the initial value
......@@ -824,62 +745,6 @@ bool Io_ReadVerNetworkLatch( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTo
return 1;
}
/**Function*************************************************************
Synopsis [Reads the verilog file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_ReadSetNonDrivenNets( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNets;
Abc_Obj_t * pNet, * pNode;
int i;
// check for non-driven nets
vNets = Vec_PtrAlloc( 100 );
Abc_NtkForEachNet( pNtk, pNet, i )
{
if ( !Abc_ObjIsPi(pNet) && Abc_ObjFaninNum(pNet) == 0 )
{
// add the constant 0 driver
pNode = Abc_NtkCreateNode( pNtk );
// set the constant function
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, " 0\n") );
// add the fanout net
Abc_ObjAddFanin( pNet, pNode );
// add the net to those for which the warning will be printed
Vec_PtrPush( vNets, pNet->pData );
}
}
// print the warning
if ( vNets->nSize > 0 )
{
printf( "The reader added constant-zero driver to %d non-driven nets:\n", vNets->nSize );
for ( i = 0; i < vNets->nSize; i++ )
{
if ( i == 0 )
printf( "%s", vNets->pArray[i] );
else if ( i == 1 )
printf( ", %s", vNets->pArray[i] );
else if ( i == 2 )
{
printf( ", %s, etc.", vNets->pArray[i] );
break;
}
}
printf( "\n" );
}
Vec_PtrFree( vNets );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
/**CFile****************************************************************
FileName [ioUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Command processing package.]
Synopsis [Procedures to write the network in BENCH format.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ioUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "io.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates PI terminal and net.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Io_ReadCreatePi( Abc_Ntk_t * pNtk, char * pName )
{
Abc_Obj_t * pNet, * pTerm;
// get the PI net
pNet = Abc_NtkFindNet( pNtk, pName );
if ( pNet )
printf( "Warning: PI \"%s\" appears twice in the list.\n", pName );
pNet = Abc_NtkFindOrCreateNet( pNtk, pName );
// add the PI node
pTerm = Abc_NtkCreatePi( pNtk );
Abc_ObjAddFanin( pNet, pTerm );
return pTerm;
}
/**Function*************************************************************
Synopsis [Creates PO terminal and net.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName )
{
Abc_Obj_t * pNet, * pTerm;
// get the PO net
pNet = Abc_NtkFindNet( pNtk, pName );
if ( pNet && Abc_ObjFaninNum(pNet) == 0 )
printf( "Warning: PO \"%s\" appears twice in the list.\n", pName );
pNet = Abc_NtkFindOrCreateNet( pNtk, pName );
// add the PO node
pTerm = Abc_NtkCreatePo( pNtk );
Abc_ObjAddFanin( pTerm, pNet );
return pTerm;
}
/**Function*************************************************************
Synopsis [Create a latch with the given input/output.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Io_ReadCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO )
{
Abc_Obj_t * pLatch, * pNet;
// create a new latch and add it to the network
pLatch = Abc_NtkCreateLatch( pNtk );
// get the LI net
pNet = Abc_NtkFindOrCreateNet( pNtk, pNetLI );
Abc_ObjAddFanin( pLatch, pNet );
// get the LO net
pNet = Abc_NtkFindOrCreateNet( pNtk, pNetLO );
Abc_ObjAddFanin( pNet, pLatch );
return pLatch;
}
/**Function*************************************************************
Synopsis [Create node and the net driven by it.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, char * pNamesIn[], int nInputs )
{
Abc_Obj_t * pNet, * pNode;
int i;
// create a new node
pNode = Abc_NtkCreateNode( pNtk );
// add the fanin nets
for ( i = 0; i < nInputs; i++ )
{
pNet = Abc_NtkFindOrCreateNet( pNtk, pNamesIn[i] );
Abc_ObjAddFanin( pNode, pNet );
}
// add the fanout net
pNet = Abc_NtkFindOrCreateNet( pNtk, pNameOut );
Abc_ObjAddFanin( pNet, pNode );
return pNode;
}
/**Function*************************************************************
Synopsis [Create a constant 0 node driving the net with this name.]
Description [Assumes that the net already exists.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Io_ReadCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 )
{
Abc_Obj_t * pNet, * pTerm;
pTerm = fConst1? Abc_NodeCreateConst1(pNtk) : Abc_NodeCreateConst0(pNtk);
pNet = Abc_NtkFindNet(pNtk, pName); assert( pNet );
Abc_ObjAddFanin( pNet, pTerm );
return pTerm;
}
/**Function*************************************************************
Synopsis [Create an inverter or buffer for the given net.]
Description [Assumes that the nets already exist.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Io_ReadCreateInv( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut )
{
Abc_Obj_t * pNet, * pNode;
pNet = Abc_NtkFindNet(pNtk, pNameIn); assert( pNet );
pNode = Abc_NodeCreateInv(pNtk, pNet);
pNet = Abc_NtkFindNet(pNtk, pNameOut); assert( pNet );
Abc_ObjAddFanin( pNet, pNode );
return pNode;
}
/**Function*************************************************************
Synopsis [Create an inverter or buffer for the given net.]
Description [Assumes that the nets already exist.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Io_ReadCreateBuf( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut )
{
Abc_Obj_t * pNet, * pNode;
pNet = Abc_NtkFindNet(pNtk, pNameIn); assert( pNet );
pNode = Abc_NodeCreateBuf(pNtk, pNet);
pNet = Abc_NtkFindNet(pNtk, pNameOut); assert( pNet );
Abc_ObjAddFanin( pNet, pNode );
return pNet;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -26,8 +26,6 @@
static int Io_WriteBenchOne( FILE * pFile, Abc_Ntk_t * pNtk );
static int Io_WriteBenchOneNode( FILE * pFile, Abc_Obj_t * pNode );
static char * Io_BenchNodeName( Abc_Obj_t * pObj, int fPhase );
static char * Io_BenchNodeNameInv( Abc_Obj_t * pObj );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
......@@ -48,7 +46,7 @@ int Io_WriteBench( Abc_Ntk_t * pNtk, char * pFileName )
{
Abc_Ntk_t * pExdc;
FILE * pFile;
assert( Abc_NtkIsAig(pNtk) );
assert( Abc_NtkIsNetlistSop(pNtk) );
pFile = fopen( pFileName, "w" );
if ( pFile == NULL )
{
......@@ -61,12 +59,7 @@ int Io_WriteBench( Abc_Ntk_t * pNtk, char * pFileName )
// write EXDC network if it exists
pExdc = Abc_NtkExdc( pNtk );
if ( pExdc )
{
printf( "Io_WriteBench: EXDC is not written (warning).\n" );
// fprintf( pFile, "\n" );
// fprintf( pFile, ".exdc\n" );
// Io_LogicWriteOne( pFile, pExdc );
}
// finalize the file
fclose( pFile );
return 1;
......@@ -89,51 +82,23 @@ int Io_WriteBenchOne( FILE * pFile, Abc_Ntk_t * pNtk )
Abc_Obj_t * pNode;
int i;
assert( Abc_NtkIsLogicSop(pNtk) || Abc_NtkIsAig(pNtk) );
// write the PIs/POs/latches
Abc_NtkForEachPi( pNtk, pNode, i )
fprintf( pFile, "INPUT(%s)\n", Abc_NtkNamePi(pNtk,i) );
fprintf( pFile, "INPUT(%s)\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
Abc_NtkForEachPo( pNtk, pNode, i )
fprintf( pFile, "OUTPUT(%s)\n", Abc_NtkNamePo(pNtk,i) );
fprintf( pFile, "OUTPUT(%s)\n", Abc_ObjName(Abc_ObjFanin0(pNode)) );
Abc_NtkForEachLatch( pNtk, pNode, i )
fprintf( pFile, "%-11s = DFF(%s)\n",
Abc_NtkNameLatch(pNtk,i), Abc_NtkNameLatchInput(pNtk,i) );
// set the node names
Abc_NtkCleanCopy( pNtk );
Abc_NtkForEachCi( pNtk, pNode, i )
pNode->pCopy = (Abc_Obj_t *)Abc_NtkNameCi(pNtk,i);
// write intervers for COs appearing in negative polarity
Abc_NtkForEachCi( pNtk, pNode, i )
{
if ( Abc_AigNodeIsUsedCompl(pNode) )
fprintf( pFile, "%-11s = NOT(%s)\n",
Io_BenchNodeNameInv(pNode),
Abc_NtkNameCi(pNtk,i) );
}
Abc_ObjName(pNode), Abc_ObjName(Abc_ObjFanin0(pNode)) );
// write internal nodes
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
if ( Abc_NodeIsConst(pNode) )
continue;
Io_WriteBenchOneNode( pFile, pNode );
}
Extra_ProgressBarStop( pProgress );
// write buffers for CO
Abc_NtkForEachCo( pNtk, pNode, i )
{
fprintf( pFile, "%-11s = BUFF(%s)\n",
(i < Abc_NtkPoNum(pNtk))? Abc_NtkNamePo(pNtk,i) :
Abc_NtkNameLatchInput( pNtk, i-Abc_NtkPoNum(pNtk) ),
Io_BenchNodeName( Abc_ObjFanin0(pNode), !Abc_ObjFaninC0(pNode) ) );
}
Abc_NtkCleanCopy( pNtk );
return 1;
}
......@@ -151,70 +116,36 @@ int Io_WriteBenchOne( FILE * pFile, Abc_Ntk_t * pNtk )
***********************************************************************/
int Io_WriteBenchOneNode( FILE * pFile, Abc_Obj_t * pNode )
{
assert( Abc_ObjIsNode(pNode) );
// write the AND gate
fprintf( pFile, "%-11s", Io_BenchNodeName( pNode, 1 ) );
fprintf( pFile, " = AND(%s, ", Io_BenchNodeName( Abc_ObjFanin0(pNode), !Abc_ObjFaninC0(pNode) ) );
fprintf( pFile, "%s)\n", Io_BenchNodeName( Abc_ObjFanin1(pNode), !Abc_ObjFaninC1(pNode) ) );
// write the inverter if necessary
if ( Abc_AigNodeIsUsedCompl(pNode) )
{
fprintf( pFile, "%-11s = NOT(", Io_BenchNodeName( pNode, 0 ) );
fprintf( pFile, "%s)\n", Io_BenchNodeName( pNode, 1 ) );
}
return 1;
}
/**Function*************************************************************
Synopsis [Returns the name of an internal AIG node.]
Description []
SideEffects []
int nFanins;
SeeAlso []
***********************************************************************/
char * Io_BenchNodeName( Abc_Obj_t * pObj, int fPhase )
{
static char Buffer[500];
if ( pObj->pCopy ) // PIs and latches
{
sprintf( Buffer, "%s%s", (char *)pObj->pCopy, (fPhase? "":"_c") );
return Buffer;
assert( Abc_ObjIsNode(pNode) );
nFanins = Abc_ObjFaninNum(pNode);
if ( nFanins == 0 )
{ // write the constant 1 node
assert( Abc_NodeIsConst1(pNode) );
fprintf( pFile, "%-11s", Abc_ObjName(Abc_ObjFanout0(pNode)) );
fprintf( pFile, " = vdd\n" );
}
assert( Abc_ObjIsNode(pObj) );
if ( Abc_NodeIsConst(pObj) ) // constant node
{
if ( fPhase )
sprintf( Buffer, "%s", "vdd" );
else if ( nFanins == 1 )
{ // write the interver/buffer
if ( Abc_NodeIsBuf(pNode) )
{
fprintf( pFile, "%-11s = BUFF(", Abc_ObjName(Abc_ObjFanout0(pNode)) );
fprintf( pFile, "%s)\n", Abc_ObjName(Abc_ObjFanin0(pNode)) );
}
else
sprintf( Buffer, "%s", "gnd" );
return Buffer;
{
fprintf( pFile, "%-11s = NOT(", Abc_ObjName(Abc_ObjFanout0(pNode)) );
fprintf( pFile, "%s)\n", Abc_ObjName(Abc_ObjFanin0(pNode)) );
}
}
// internal nodes
sprintf( Buffer, "%s%s", Abc_ObjName(pObj), (fPhase? "":"_c") );
return Buffer;
}
/**Function*************************************************************
Synopsis [Returns the name of an internal AIG node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Io_BenchNodeNameInv( Abc_Obj_t * pObj )
{
static char Buffer[500];
sprintf( Buffer, "%s%s", Abc_ObjName(pObj), "_c" );
return Buffer;
else
{ // write the AND gate
fprintf( pFile, "%-11s", Abc_ObjName(Abc_ObjFanout0(pNode)) );
fprintf( pFile, " = AND(%s, ", Abc_ObjName(Abc_ObjFanin0(pNode)) );
fprintf( pFile, "%s)\n", Abc_ObjName(Abc_ObjFanin1(pNode)) );
}
return 1;
}
////////////////////////////////////////////////////////////////////////
......
......@@ -19,14 +19,17 @@
***********************************************************************/
#include "io.h"
#include "main.h"
#include "mio.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode );
static void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode );
static void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode );
static void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch );
......@@ -46,7 +49,32 @@ static void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch );
SeeAlso []
***********************************************************************/
void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName )
void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
{
Abc_Ntk_t * pNtkTemp;
// derive the netlist
pNtkTemp = Abc_NtkLogicToNetlist(pNtk);
if ( pNtkTemp == NULL )
{
fprintf( stdout, "Writing BLIF has failed.\n" );
return;
}
Io_WriteBlif( pNtkTemp, FileName, fWriteLatches );
Abc_NtkDelete( pNtkTemp );
}
/**Function*************************************************************
Synopsis [Write the network into a BLIF file with the given name.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
{
Abc_Ntk_t * pExdc;
FILE * pFile;
......@@ -60,14 +88,14 @@ void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName )
// write the model name
fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
// write the network
Io_NtkWriteOne( pFile, pNtk );
Io_NtkWriteOne( pFile, pNtk, fWriteLatches );
// write EXDC network if it exists
pExdc = Abc_NtkExdc( pNtk );
if ( pExdc )
{
fprintf( pFile, "\n" );
fprintf( pFile, ".exdc\n" );
Io_NtkWriteOne( pFile, pExdc );
Io_NtkWriteOne( pFile, pExdc, fWriteLatches );
}
// finalize the file
fprintf( pFile, ".end\n" );
......@@ -88,7 +116,7 @@ void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName )
SeeAlso []
***********************************************************************/
void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk )
void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
{
ProgressBar * pProgress;
Abc_Obj_t * pNode, * pLatch;
......@@ -96,19 +124,19 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk )
// write the PIs
fprintf( pFile, ".inputs" );
Io_NtkWritePis( pFile, pNtk );
Io_NtkWritePis( pFile, pNtk, fWriteLatches );
fprintf( pFile, "\n" );
// write the POs
fprintf( pFile, ".outputs" );
Io_NtkWritePos( pFile, pNtk );
Io_NtkWritePos( pFile, pNtk, fWriteLatches );
fprintf( pFile, "\n" );
// write the timing info
Io_WriteTimingInfo( pFile, pNtk );
// write the latches
if ( !Abc_NtkIsComb(pNtk) )
if ( fWriteLatches && !Abc_NtkIsComb(pNtk) )
{
fprintf( pFile, "\n" );
Abc_NtkForEachLatch( pNtk, pLatch, i )
......@@ -138,9 +166,9 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk )
void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
{
Abc_Obj_t * pNet;
Abc_Obj_t * pTerm, * pNet;
int LineLength;
int AddedLength;
int NameCounter;
......@@ -148,20 +176,44 @@ void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk )
LineLength = 7;
NameCounter = 0;
Abc_NtkForEachPi( pNtk, pNet, i )
if ( fWriteLatches )
{
// get the line length after this name is written
AddedLength = strlen(Abc_ObjName(pNet)) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
Abc_NtkForEachPi( pNtk, pTerm, i )
{
pNet = Abc_ObjFanout0(pTerm);
// get the line length after this name is written
AddedLength = strlen(Abc_ObjName(pNet)) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", Abc_ObjName(pNet) );
LineLength += AddedLength;
NameCounter++;
}
}
else
{
Abc_NtkForEachCi( pNtk, pTerm, i )
{
pNet = Abc_ObjFanout0(pTerm);
// get the line length after this name is written
AddedLength = strlen(Abc_ObjName(pNet)) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", Abc_ObjName(pNet) );
LineLength += AddedLength;
NameCounter++;
}
fprintf( pFile, " %s", Abc_ObjName(pNet) );
LineLength += AddedLength;
NameCounter++;
}
}
......@@ -176,9 +228,9 @@ void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk )
void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
{
Abc_Obj_t * pNet;
Abc_Obj_t * pTerm, * pNet;
int LineLength;
int AddedLength;
int NameCounter;
......@@ -186,20 +238,44 @@ void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk )
LineLength = 8;
NameCounter = 0;
Abc_NtkForEachPo( pNtk, pNet, i )
if ( fWriteLatches )
{
// get the line length after this name is written
AddedLength = strlen(Abc_ObjName(pNet)) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
Abc_NtkForEachPo( pNtk, pTerm, i )
{
pNet = Abc_ObjFanin0(pTerm);
// get the line length after this name is written
AddedLength = strlen(Abc_ObjName(pNet)) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", Abc_ObjName(pNet) );
LineLength += AddedLength;
NameCounter++;
}
}
else
{
Abc_NtkForEachCo( pNtk, pTerm, i )
{
pNet = Abc_ObjFanin0(pTerm);
// get the line length after this name is written
AddedLength = strlen(Abc_ObjName(pNet)) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", Abc_ObjName(pNet) );
LineLength += AddedLength;
NameCounter++;
}
fprintf( pFile, " %s", Abc_ObjName(pNet) );
LineLength += AddedLength;
NameCounter++;
}
}
......@@ -224,8 +300,8 @@ void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch )
Reset = (int)Abc_ObjData( pLatch );
// write the latch line
fprintf( pFile, ".latch" );
fprintf( pFile, " %10s", Abc_ObjName(pNetLi) );
fprintf( pFile, " %10s", Abc_ObjName(pNetLo) );
fprintf( pFile, " %10s", Abc_ObjName(pNetLi) );
fprintf( pFile, " %10s", Abc_ObjName(pNetLo) );
fprintf( pFile, " %d\n", Reset );
}
......@@ -243,12 +319,46 @@ void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch )
***********************************************************************/
void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode )
{
// write the .names line
fprintf( pFile, ".names" );
Io_NtkWriteNodeFanins( pFile, pNode );
fprintf( pFile, "\n" );
// write the cubes
fprintf( pFile, "%s", Abc_ObjData(pNode) );
if ( Abc_NtkIsNetlistMap(pNode->pNtk) )
{
// write the .gate line
fprintf( pFile, ".gate" );
Io_NtkWriteNodeGate( pFile, pNode );
fprintf( pFile, "\n" );
}
else
{
// write the .names line
fprintf( pFile, ".names" );
Io_NtkWriteNodeFanins( pFile, pNode );
fprintf( pFile, "\n" );
// write the cubes
fprintf( pFile, "%s", Abc_ObjData(pNode) );
}
}
/**Function*************************************************************
Synopsis [Writes the primary input list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode )
{
Mio_Gate_t * pGate = pNode->pData;
Mio_Pin_t * pGatePin;
int i;
// write the node
fprintf( pFile, " %s ", Mio_GateReadName(pGate) );
for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
fprintf( pFile, "%s=%s ", Mio_PinReadName(pGatePin), Abc_ObjName( Abc_ObjFanin(pNode,i) ) );
assert ( i == Abc_ObjFaninNum(pNode) );
fprintf( pFile, "%s=%s", Mio_GateReadOutName(pGate), Abc_ObjName(pNode) );
}
/**Function*************************************************************
......@@ -332,7 +442,7 @@ void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk )
pTime = Abc_NodeReadArrival(pNode);
if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall )
continue;
fprintf( pFile, ".input_arrival %s %g %g\n", Abc_NtkNamePi(pNtk,i), pTime->Rise, pTime->Fall );
fprintf( pFile, ".input_arrival %s %g %g\n", Abc_ObjName(pNode), pTime->Rise, pTime->Fall );
}
}
......
/**CFile****************************************************************
FileName [ioWriteBlifLogic.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Command processing package.]
Synopsis [Procedures to write BLIF files for a logic network.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ioWriteBlifLogic.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "io.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Io_LogicWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_LogicWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_LogicWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_LogicWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode, int fMark );
static void Io_LogicWriteNode( FILE * pFile, Abc_Obj_t * pNode );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Write the network into a BLIF file with the given name.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
{
Abc_Ntk_t * pExdc;
FILE * pFile;
assert( !Abc_NtkIsNetlist(pNtk) );
pFile = fopen( FileName, "w" );
if ( pFile == NULL )
{
fprintf( stdout, "Io_WriteBlifLogic(): Cannot open the output file.\n" );
return;
}
// write the model name
fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
// write the network
Io_LogicWriteOne( pFile, pNtk, fWriteLatches );
// write EXDC network if it exists
pExdc = Abc_NtkExdc( pNtk );
if ( pExdc )
{
fprintf( pFile, "\n" );
fprintf( pFile, ".exdc\n" );
Io_LogicWriteOne( pFile, pExdc, 0 );
}
// finalize the file
fprintf( pFile, ".end\n" );
fclose( pFile );
}
/**Function*************************************************************
Synopsis [Write one network.]
Description [Writes a network composed of PIs, POs, internal nodes,
and latches. The following rules are used to print the names of
internal nodes: ]
SideEffects []
SeeAlso []
***********************************************************************/
void Io_LogicWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
{
ProgressBar * pProgress;
Abc_Obj_t * pNode, * pLatch, * pDriver;
Vec_Ptr_t * vNodes;
int i;
assert( Abc_NtkIsLogicSop(pNtk) || Abc_NtkIsAig(pNtk) );
// print a warning about choice nodes
if ( i = Abc_NtkCountChoiceNodes( pNtk ) )
printf( "Warning: The AIG is written into the file, including %d choice nodes.\n", i );
// write the PIs
fprintf( pFile, ".inputs" );
Io_LogicWritePis( pFile, pNtk, fWriteLatches );
fprintf( pFile, "\n" );
// write the POs
fprintf( pFile, ".outputs" );
Io_LogicWritePos( pFile, pNtk, fWriteLatches );
fprintf( pFile, "\n" );
if ( fWriteLatches )
{
// write the timing info
Io_WriteTimingInfo( pFile, pNtk );
// write the latches
if ( Abc_NtkLatchNum(pNtk) )
{
fprintf( pFile, "\n" );
Abc_NtkForEachLatch( pNtk, pLatch, i )
fprintf( pFile, ".latch %10s %10s %d\n",
Abc_NtkNameLatchInput(pNtk,i), Abc_NtkNameLatch(pNtk,i), (int)pLatch->pData );
fprintf( pFile, "\n" );
}
}
// set the node names
Abc_NtkLogicTransferNames( pNtk );
// collect internal nodes
if ( Abc_NtkIsAig(pNtk) )
vNodes = Abc_AigDfs( pNtk );
else
vNodes = Abc_NtkDfs( pNtk );
// write internal nodes
pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
for ( i = 0; i < vNodes->nSize; i++ )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
Io_LogicWriteNode( pFile, Vec_PtrEntry(vNodes, i) );
}
Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vNodes );
// write inverters/buffers for each CO
Abc_NtkForEachLatch( pNtk, pLatch, i )
{
pDriver = Abc_ObjFanin0(pLatch);
// consider the case when the latch is driving itself
if ( pDriver == pLatch )
{
fprintf( pFile, ".names %s %s\n%d 1\n",
Abc_NtkNameLatch(pNtk,i), Abc_NtkNameLatchInput(pNtk,i), !Abc_ObjFaninC0(pLatch) );
continue;
}
// skip if they have the same name
if ( pDriver->pCopy && strcmp( (char *)pDriver->pCopy, Abc_NtkNameLatchInput(pNtk,i) ) == 0 )
{
/*
Abc_Obj_t * pFanout;
int k;
printf( "latch name = %s.\n", (char *)pLatch->pCopy );
printf( "driver name = %s.\n", (char *)pDriver->pCopy );
Abc_ObjForEachFanout( pDriver, pFanout, k )
printf( "driver's fanout name = %s. Fanins = %d. Compl0 = %d. \n",
Abc_ObjName(pFanout), Abc_ObjFaninNum(pFanout), Abc_ObjFaninC0(pFanout) );
*/
assert( !Abc_ObjFaninC0(pLatch) );
continue;
}
// write inverter/buffer depending on whether the edge is complemented
fprintf( pFile, ".names %s %s\n%d 1\n",
Abc_ObjName(pDriver), Abc_NtkNameLatchInput(pNtk,i), !Abc_ObjFaninC0(pLatch) );
}
Abc_NtkForEachPo( pNtk, pNode, i )
{
pDriver = Abc_ObjFanin0(pNode);
// skip if they have the same name
if ( pDriver->pCopy && strcmp( (char *)pDriver->pCopy, Abc_NtkNamePo(pNtk,i) ) == 0 )
{
assert( !Abc_ObjFaninC0(pNode) );
continue;
}
// write inverter/buffer depending on whether the PO is complemented
fprintf( pFile, ".names %s %s\n%d 1\n",
Abc_ObjName(pDriver), Abc_NtkNamePo(pNtk,i), !Abc_ObjFaninC0(pNode) );
}
Abc_NtkCleanCopy( pNtk );
}
/**Function*************************************************************
Synopsis [Writes the primary input list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_LogicWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
{
char * pName;
int LineLength;
int AddedLength;
int NameCounter;
int nLimit;
int i;
LineLength = 7;
NameCounter = 0;
nLimit = fWriteLatches? Abc_NtkPiNum(pNtk) : Abc_NtkCiNum(pNtk);
for ( i = 0; i < nLimit; i++ )
{
pName = pNtk->vNamesPi->pArray[i];
// get the line length after this name is written
AddedLength = strlen(pName) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", pName );
LineLength += AddedLength;
NameCounter++;
}
}
/**Function*************************************************************
Synopsis [Writes the primary input list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_LogicWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
{
char * pName;
int LineLength;
int AddedLength;
int NameCounter;
int nLimit;
int i;
LineLength = 8;
NameCounter = 0;
nLimit = fWriteLatches? Abc_NtkPoNum(pNtk) : Abc_NtkCoNum(pNtk);
for ( i = 0; i < nLimit; i++ )
{
pName = pNtk->vNamesPo->pArray[i];
// get the line length after this name is written
AddedLength = strlen(pName) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", pName );
LineLength += AddedLength;
NameCounter++;
}
}
/**Function*************************************************************
Synopsis [Write the node into a file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_LogicWriteNode( FILE * pFile, Abc_Obj_t * pNode )
{
Abc_Obj_t * pTemp;
int i, k, nFanins, fMark;
assert( !Abc_ObjIsComplement( pNode ) );
assert( Abc_ObjIsNode(pNode) );
// set the mark that is true if the node is a choice node
fMark = Abc_NtkIsAig(pNode->pNtk) && Abc_NodeIsChoice(pNode);
// write the .names line
fprintf( pFile, ".names" );
Io_LogicWriteNodeFanins( pFile, pNode, fMark );
fprintf( pFile, "\n" );
// write the cubes
if ( Abc_NtkIsLogicSop(pNode->pNtk) )
fprintf( pFile, "%s", Abc_ObjData(pNode) );
else if ( Abc_NtkIsAig(pNode->pNtk) )
{
if ( pNode == Abc_AigConst1(pNode->pNtk->pManFunc) )
{
fprintf( pFile, " 1\n" );
return;
}
assert( Abc_ObjFaninNum(pNode) == 2 );
// write the AND gate
for ( i = 0; i < 2; i++ )
fprintf( pFile, "%d", !Abc_ObjFaninC(pNode,i) );
fprintf( pFile, " 1\n" );
// write the choice node if present
if ( fMark )
{
// count the number of fanins of the choice node and write the names line
nFanins = 1;
fprintf( pFile, ".names %sc", Abc_ObjName(pNode) );
for ( pTemp = pNode->pData; pTemp; pTemp = pTemp->pData, nFanins++ )
fprintf( pFile, " %s", Abc_ObjName(pTemp) );
fprintf( pFile, " %s\n", Abc_ObjName(pNode) );
// write the cubes for each of the fanins
for ( i = 0, pTemp = pNode; pTemp; pTemp = pTemp->pData, i++ )
{
for ( k = 0; k < nFanins; k++ )
if ( k == i )
fprintf( pFile, "%d", (int)(pNode->fPhase == pTemp->fPhase) );
else
fprintf( pFile, "-" );
fprintf( pFile, " 1\n" );
}
}
}
else
{
assert( 0 );
}
}
/**Function*************************************************************
Synopsis [Writes the primary input list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_LogicWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode, int fMark )
{
Abc_Obj_t * pFanin;
int LineLength;
int AddedLength;
int NameCounter;
char * pName;
int i;
LineLength = 6;
NameCounter = 0;
Abc_ObjForEachFanin( pNode, pFanin, i )
{
// get the fanin name
pName = Abc_ObjName(pFanin);
// get the line length after the fanin name is written
AddedLength = strlen(pName) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", pName );
LineLength += AddedLength;
NameCounter++;
}
// get the output name
pName = Abc_ObjName(pNode);
// get the line length after the output name is written
AddedLength = strlen(pName) + 1;
if ( NameCounter && LineLength + AddedLength > 75 )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s%s", pName, fMark? "c" : "" );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ioWriteGate.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Command processing package.]
Synopsis [Procedures to write the mapped network.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ioWriteGate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "io.h"
#include "main.h"
#include "mio.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Io_WriteGateOne( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_WriteGatePis( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_WriteGatePos( FILE * pFile, Abc_Ntk_t * pNtk );
static void Io_WriteGateNode( FILE * pFile, Abc_Obj_t * pNode, Mio_Gate_t * pGate );
static char * Io_ReadNodeName( Abc_Obj_t * pNode );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Writes mapped network into a BLIF file compatible with SIS.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Io_WriteGate( Abc_Ntk_t * pNtk, char * pFileName )
{
Abc_Ntk_t * pExdc;
FILE * pFile;
assert( Abc_NtkIsLogicMap(pNtk) );
pFile = fopen( pFileName, "w" );
if ( pFile == NULL )
{
fprintf( stdout, "Io_WriteGate(): Cannot open the output file.\n" );
return 0;
}
// write the model name
fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
// write the network
Io_WriteGateOne( pFile, pNtk );
// write EXDC network if it exists
pExdc = Abc_NtkExdc( pNtk );
if ( pExdc )
printf( "Io_WriteGate: EXDC is not written (warning).\n" );
// finalize the file
fprintf( pFile, ".end\n" );
fclose( pFile );
return 1;
}
/**Function*************************************************************
Synopsis [Write one network.]
Description [Writes a network composed of PIs, POs, internal nodes,
and latches. The following rules are used to print the names of
internal nodes: ]
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteGateOne( FILE * pFile, Abc_Ntk_t * pNtk )
{
ProgressBar * pProgress;
Abc_Obj_t * pNode, * pLatch;
int i;
assert( Abc_NtkIsLogicMap(pNtk) );
assert( Abc_NtkLogicHasSimplePos(pNtk) );
// write the PIs
fprintf( pFile, ".inputs" );
Io_WriteGatePis( pFile, pNtk );
fprintf( pFile, "\n" );
// write the POs
fprintf( pFile, ".outputs" );
Io_WriteGatePos( pFile, pNtk );
fprintf( pFile, "\n" );
// write the timing info
Io_WriteTimingInfo( pFile, pNtk );
// write the latches
if ( Abc_NtkLatchNum(pNtk) )
{
fprintf( pFile, "\n" );
Abc_NtkForEachLatch( pNtk, pLatch, i )
fprintf( pFile, ".latch %s %s %d\n",
Abc_NtkNameLatchInput(pNtk,i), Abc_NtkNameLatch(pNtk,i), (int)pLatch->pData );
fprintf( pFile, "\n" );
}
// set the node names
Abc_NtkLogicTransferNames( pNtk );
// write internal nodes
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
Io_WriteGateNode( pFile, pNode, pNode->pData );
}
Extra_ProgressBarStop( pProgress );
Abc_NtkCleanCopy( pNtk );
}
/**Function*************************************************************
Synopsis [Writes the primary input list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteGatePis( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
char * pName;
int LineLength;
int AddedLength;
int NameCounter;
int i;
LineLength = 7;
NameCounter = 0;
Abc_NtkForEachPi( pNtk, pNode, i )
{
pName = pNtk->vNamesPi->pArray[i];
// get the line length after this name is written
AddedLength = strlen(pName) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", pName );
LineLength += AddedLength;
NameCounter++;
}
}
/**Function*************************************************************
Synopsis [Writes the primary input list.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteGatePos( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int LineLength;
int AddedLength;
int NameCounter;
char * pName;
int i;
LineLength = 8;
NameCounter = 0;
Abc_NtkForEachPo( pNtk, pNode, i )
{
pName = pNtk->vNamesPo->pArray[i];
// get the line length after this name is written
AddedLength = strlen(pName) + 1;
if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
{ // write the line extender
fprintf( pFile, " \\\n" );
// reset the line length
LineLength = 0;
NameCounter = 0;
}
fprintf( pFile, " %s", pName );
LineLength += AddedLength;
NameCounter++;
}
}
/**Function*************************************************************
Synopsis [Write the node into a file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteGateNode( FILE * pFile, Abc_Obj_t * pNode, Mio_Gate_t * pGate )
{
Mio_Pin_t * pGatePin;
int i;
// do not write the buffer whose input and output have the same name
if ( Abc_ObjFaninNum(pNode) == 1 && Abc_ObjFanin0(pNode)->pCopy && pNode->pCopy )
if ( strcmp( (char*)Abc_ObjFanin0(pNode)->pCopy, (char*)pNode->pCopy ) == 0 )
return;
// write the node
fprintf( pFile, ".gate %s ", Mio_GateReadName(pGate) );
for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
fprintf( pFile, "%s=%s ", Mio_PinReadName(pGatePin), Io_ReadNodeName( Abc_ObjFanin(pNode,i) ) );
assert ( i == Abc_ObjFaninNum(pNode) );
fprintf( pFile, "%s=%s\n", Mio_GateReadOutName(pGate), Io_ReadNodeName(pNode) );
}
/**Function*************************************************************
Synopsis [Returns the name of the node to write.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Io_ReadNodeName( Abc_Obj_t * pNode )
{
if ( pNode->pCopy )
return (char *)pNode->pCopy;
return Abc_ObjName(pNode);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -46,7 +46,7 @@ int Io_WritePla( Abc_Ntk_t * pNtk, char * pFileName )
Abc_Ntk_t * pExdc;
FILE * pFile;
assert( Abc_NtkIsLogicSop(pNtk) );
assert( Abc_NtkIsNetlistSop(pNtk) );
assert( Abc_NtkGetLevelNum(pNtk) == 1 );
pFile = fopen( pFileName, "w" );
......@@ -61,12 +61,7 @@ int Io_WritePla( Abc_Ntk_t * pNtk, char * pFileName )
// write EXDC network if it exists
pExdc = Abc_NtkExdc( pNtk );
if ( pExdc )
{
printf( "Io_WritePla: EXDC is not written (warning).\n" );
// fprintf( pFile, "\n" );
// fprintf( pFile, ".exdc\n" );
// Io_LogicWriteOne( pFile, pExdc );
}
// finalize the file
fclose( pFile );
return 1;
......@@ -91,9 +86,9 @@ int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk )
int i, k, nProducts, nInputs, nOutputs, nFanins;
nProducts = 0;
Abc_NtkForEachPo( pNtk, pNode, i )
Abc_NtkForEachCo( pNtk, pNode, i )
{
pDriver = Abc_ObjFanin0(pNode);
pDriver = Abc_ObjFanin0Ntk(pNode);
if ( !Abc_ObjIsNode(pDriver) )
{
nProducts++;
......@@ -121,11 +116,11 @@ int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk )
fprintf( pFile, ".o %d\n", nOutputs );
fprintf( pFile, ".ilb" );
Abc_NtkForEachCi( pNtk, pNode, i )
fprintf( pFile, " %s", Abc_NtkNameCi(pNtk, i) );
fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanout0(pNode)) );
fprintf( pFile, "\n" );
fprintf( pFile, ".ob" );
Abc_NtkForEachCo( pNtk, pNode, i )
fprintf( pFile, " %s", Abc_NtkNameCo(pNtk, i) );
fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin0(pNode)) );
fprintf( pFile, "\n" );
fprintf( pFile, ".p %d\n", nProducts );
......@@ -143,7 +138,7 @@ int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk )
pCubeOut[i] = '1';
// consider special cases of nodes
pDriver = Abc_ObjFanin0(pNode);
pDriver = Abc_ObjFanin0Ntk(pNode);
if ( !Abc_ObjIsNode(pDriver) )
{
pCubeIn[(int)pDriver->pCopy] = '1' - Abc_ObjFaninC0(pNode);
......
......@@ -4,9 +4,8 @@ SRC += src/base/io/io.c \
src/base/io/ioReadBlif.c \
src/base/io/ioReadPla.c \
src/base/io/ioReadVerilog.c \
src/base/io/ioUtil.c \
src/base/io/ioWriteBench.c \
src/base/io/ioWriteBlif.c \
src/base/io/ioWriteBlifLogic.c \
src/base/io/ioWriteCnf.c \
src/base/io/ioWriteGate.c \
src/base/io/ioWritePla.c
//These are the APIs, enums and data structures that we use
//and expect from our use of CSAT.
enum GateType
{
// GateType defines the gate type that can be added to circuit by
// CSAT_AddGate();
enum GateType
{
CSAT_CONST = 0, // constant gate
CSAT_BPI, // boolean PI
CSAT_BPPI, // bit level PSEUDO PRIMARY INPUT
CSAT_BAND, // bit level AND
CSAT_BNAND, // bit level NAND
CSAT_BOR, // bit level OR
CSAT_BNOR, // bit level NOR
CSAT_BXOR, // bit level XOR
CSAT_BXNOR, // bit level XNOR
CSAT_BINV, // bit level INVERTER
CSAT_BBUF, // bit level BUFFER
CSAT_BPPO, // bit level PSEUDO PRIMARY OUTPUT
CSAT_BPO, // boolean PO
};
#endif
//CSAT_StatusT defines the return value by CSAT_Solve();
#ifndef _CSAT_STATUS_
#define _CSAT_STATUS_
enum CSAT_StatusT
{
UNDETERMINED = 0,
UNSATISFIABLE,
SATISFIABLE,
TIME_OUT,
FRAME_OUT,
NO_TARGET,
ABORTED,
SEQ_SATISFIABLE
};
#endif
// CSAT_OptionT defines the solver option about learning
// which is used by CSAT_SetSolveOption();
#ifndef _CSAT_OPTION_
#define _CSAT_OPTION_
enum CSAT_OptionT
{
BASE_LINE = 0,
IMPLICT_LEARNING, //default
EXPLICT_LEARNING
};
#endif
#ifndef _CSAT_Target_Result
#define _CSAT_Target_Result
typedef struct _CSAT_Target_ResultT CSAT_Target_ResultT;
/*
struct _CSAT_Target_ResultT
{
enum CSAT_StatusT status; //solve status of the target
int num_dec; //num of decisions to solve the target
int num_imp; //num of implications to solve the target
int num_cftg; //num of conflict gates learned
int num_cfts; //num of conflict signals in conflict gates
double time; //time(in second) used to solver the target
int no_sig; // if "status" is SATISFIABLE, "no_sig" is the number of
// primary inputs, if the "status" is TIME_OUT, "no_sig" is the
// number of constant signals found.
char** names; // if the "status" is SATISFIABLE, "names" is the name array of
// primary inputs, "values" is the value array of primary
// inputs that satisfy the target.
// if the "status" is TIME_OUT, "names" is the name array of
// constant signals found (signals at the root of decision
// tree),"values" is the value array of constant signals found.
int* values;
};
*/
// create a new manager
CSAT_Manager CSAT_InitManager(void);
// set solver options for learning
void CSAT_SetSolveOption(CSAT_Manager mng,enum CSAT_OptionT option);
// add a gate to the circuit
// the meaning of the parameters are:
// type: the type of the gate to be added
// name: the name of the gate to be added, name should be unique in a circuit.
// nofi: number of fanins of the gate to be added;
// fanins: the name array of fanins of the gate to be added
int CSAT_AddGate(CSAT_Manager mng,
enum GateType type,
char* name,
int nofi,
char** fanins,
int dc_attr=0);
// check if there are gates that are not used by any primary ouput.
// if no such gates exist, return 1 else return 0;
int CSAT_Check_Integrity(CSAT_Manager mng);
// set time limit for solving a target.
// runtime: time limit (in second).
void CSAT_SetTimeLimit(CSAT_Manager mng ,int runtime);
void CSAT_SetLearnLimit (CSAT_Manager mng ,int num);
void CSAT_SetSolveBacktrackLimit (CSAT_Manager mng ,int num);
void CSAT_SetLearnBacktrackLimit (CSAT_Manager mng ,int num);
void CSAT_EnableDump(CSAT_Manager mng ,char* dump_file);
// the meaning of the parameters are:
// nog: number of gates that are in the targets
// names: name array of gates
// values: value array of the corresponding gates given in "names" to be
// solved. the relation of them is AND.
int CSAT_AddTarget(CSAT_Manager mng, int nog, char**names, int* values);
// initialize the solver internal data structure.
void CSAT_SolveInit(CSAT_Manager mng);
void CSAT_AnalyzeTargets(CSAT_Manager mng);
// solve the targets added by CSAT_AddTarget()
enum CSAT_StatusT CSAT_Solve(CSAT_Manager mng);
// get the solve status of a target
// TargetID: the target id returned by CSAT_AddTarget().
CSAT_Target_ResultT*
CSAT_Get_Target_Result(CSAT_Manager mng, int TargetID);
void CSAT_Dump_Bench_File(CSAT_Manager mng);
......@@ -231,7 +231,7 @@ void Fpga_ManFree( Fpga_Man_t * p )
FREE( p->pInputs );
FREE( p->pOutputs );
FREE( p->pBins );
// FREE( p->ppOutputNames );
FREE( p->ppOutputNames );
if ( p->pSimInfo )
{
FREE( p->pSimInfo[0] );
......
......@@ -265,7 +265,7 @@ void Map_ManFree( Map_Man_t * p )
FREE( p->pInputs );
FREE( p->pOutputs );
FREE( p->pBins );
// FREE( p->ppOutputNames );
FREE( p->ppOutputNames );
if ( p->pSimInfo ) FREE( p->pSimInfo[0] );
FREE( p->pSimInfo );
FREE( p );
......
......@@ -39,9 +39,8 @@
typedef struct Abc_Fan_t_ Abc_Fan_t;
struct Abc_Fan_t_ // 1 word
{
unsigned iFan : 21; // the ID of the object
unsigned nLats : 3; // the number of latches (up to 7)
unsigned Inits : 7; // the initial values of the latches
unsigned iFan : 26; // the ID of the object
unsigned nLats : 5; // the number of latches (up to 31)
unsigned fCompl : 1; // the complemented attribute
};
......
......@@ -183,7 +183,7 @@ int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets )
// detect the differences in the simulation info
Sim_UtilInfoDetectDiffs( p->vSim0->pArray[pNode->Id], p->vSim1->pArray[pNode->Id], p->nSimWords, p->vDiffs );
// create patterns
// create new patterns
Vec_IntForEachEntry( p->vDiffs, LuckyPat, k )
{
// set the new pattern
......@@ -194,6 +194,7 @@ int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets )
if ( Sim_SimInfoHasVar( p, pNodeCi, LuckyPat ) )
Sim_SetBit( pPat->pData, v );
Vec_PtrPush( p->vFifo, pPat );
break;
}
}
}
......@@ -256,6 +257,13 @@ void Sim_ComputeSuppSetTargets( Sim_Man_t * p )
***********************************************************************/
void Sim_UtilAssignFromFifo( Sim_Man_t * p )
{
Sim_Pat_t * pPat;
int i;
for ( i = 0; i < p->nSimBits; i++ )
{
pPat = Vec_PtrPop( p->vFifo );
}
}
////////////////////////////////////////////////////////////////////////
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment