From 80983617b3f2843a176c8de1fee84de17a507fe9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 12 Aug 2005 08:01:00 -0700 Subject: Version abc50812 --- abc.dsp | 10 +- abc.opt | Bin 52736 -> 52736 bytes abc.plg | 54 +++-- src/base/abc/abc.c | 66 ++++++- src/base/abc/abc.h | 244 ++++++++++++----------- src/base/abc/abcAig.c | 31 ++- src/base/abc/abcCheck.c | 435 +++++++++++------------------------------ src/base/abc/abcCollapse.c | 3 - src/base/abc/abcCreate.c | 430 +++++++++++++++++++--------------------- src/base/abc/abcDfs.c | 324 ++++++++++-------------------- src/base/abc/abcDsd.c | 9 +- src/base/abc/abcFanio.c | 10 +- src/base/abc/abcFpga.c | 8 +- src/base/abc/abcFraig.c | 2 +- src/base/abc/abcLatch.c | 158 --------------- src/base/abc/abcMap.c | 14 +- src/base/abc/abcMiter.c | 148 ++++++++++++-- src/base/abc/abcNames.c | 248 ++++++----------------- src/base/abc/abcNetlist.c | 312 +++++++++++++++++++++++++---- src/base/abc/abcPrint.c | 114 +++++++---- src/base/abc/abcRefs.c | 2 +- src/base/abc/abcRenode.c | 5 +- src/base/abc/abcShow.c | 1 - src/base/abc/abcSop.c | 190 +++++++++++++++++- src/base/abc/abcSweep.c | 10 +- src/base/abc/abcUnreach.c | 10 +- src/base/abc/abcUtil.c | 171 ++++++++++------ src/base/io/io.c | 161 ++++----------- src/base/io/io.h | 16 +- src/base/io/ioRead.c | 2 +- src/base/io/ioReadBench.c | 124 ++++-------- src/base/io/ioReadBlif.c | 217 +++++++++++++------- src/base/io/ioReadPla.c | 39 ++-- src/base/io/ioReadVerilog.c | 219 ++++----------------- src/base/io/ioUtil.c | 201 +++++++++++++++++++ src/base/io/ioWriteBench.c | 129 +++--------- src/base/io/ioWriteBlif.c | 204 ++++++++++++++----- src/base/io/ioWriteBlifLogic.c | 402 ------------------------------------- src/base/io/ioWriteGate.c | 263 ------------------------- src/base/io/ioWritePla.c | 17 +- src/base/io/module.make | 3 +- src/csat_apis.h | 125 ++++++++++++ src/map/fpga/fpgaCreate.c | 2 +- src/map/mapper/mapperCreate.c | 2 +- src/misc/vec/vecFan.h | 5 +- src/sat/sim/simSupp.c | 10 +- 46 files changed, 2351 insertions(+), 2799 deletions(-) create mode 100644 src/base/io/ioUtil.c delete mode 100644 src/base/io/ioWriteBlifLogic.c delete mode 100644 src/base/io/ioWriteGate.c create mode 100644 src/csat_apis.h diff --git a/abc.dsp b/abc.dsp index e68fe877..2a5f0988 100644 --- a/abc.dsp +++ b/abc.dsp @@ -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 diff --git a/abc.opt b/abc.opt index 70b6511f..c6e3269a 100644 Binary files a/abc.opt and b/abc.opt differ diff --git a/abc.plg b/abc.plg index 32aa5a29..502d4e16 100644 --- a/abc.plg +++ b/abc.plg @@ -6,13 +6,13 @@ --------------------Configuration: abc - Win32 Debug--------------------

Command Lines

-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"

Output Window

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...

Output Window

diff --git a/src/base/abc/abc.c b/src/base/abc/abc.c index f64cc008..a02764b1 100644 --- a/src/base/abc/abc.c +++ b/src/base/abc/abc.c @@ -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 ); @@ -274,6 +276,56 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + 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 [] @@ -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 diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index ad226c86..99af9ac6 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -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 /// diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c index 5ec0d97a..590bc4d2 100644 --- a/src/base/abc/abcAig.c +++ b/src/base/abc/abcAig.c @@ -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************************************************************* diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c index 6a733185..5686baaf 100644 --- a/src/base/abc/abcCheck.c +++ b/src/base/abc/abcCheck.c @@ -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; } diff --git a/src/base/abc/abcCollapse.c b/src/base/abc/abcCollapse.c index 3ee086c0..2b2da719 100644 --- a/src/base/abc/abcCollapse.c +++ b/src/base/abc/abcCollapse.c @@ -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; } diff --git a/src/base/abc/abcCreate.c b/src/base/abc/abcCreate.c index 83654635..c530f3f6 100644 --- a/src/base/abc/abcCreate.c +++ b/src/base/abc/abcCreate.c @@ -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; diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c index b1153d40..a02c3602 100644 --- a/src/base/abc/abcDfs.c +++ b/src/base/abc/abcDfs.c @@ -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 diff --git a/src/base/abc/abcDsd.c b/src/base/abc/abcDsd.c index c9adab38..e92907e3 100644 --- a/src/base/abc/abcDsd.c +++ b/src/base/abc/abcDsd.c @@ -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 ); diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c index 866c6e5d..2e242d9c 100644 --- a/src/base/abc/abcFanio.c +++ b/src/base/abc/abcFanio.c @@ -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 ); diff --git a/src/base/abc/abcFpga.c b/src/base/abc/abcFpga.c index 975fbc98..336a382c 100644 --- a/src/base/abc/abcFpga.c +++ b/src/base/abc/abcFpga.c @@ -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; diff --git a/src/base/abc/abcFraig.c b/src/base/abc/abcFraig.c index 75c5c290..2b6f0af2 100644 --- a/src/base/abc/abcFraig.c +++ b/src/base/abc/abcFraig.c @@ -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; diff --git a/src/base/abc/abcLatch.c b/src/base/abc/abcLatch.c index a5bb9544..d804601e 100644 --- a/src/base/abc/abcLatch.c +++ b/src/base/abc/abcLatch.c @@ -28,164 +28,6 @@ /// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// -/**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.] diff --git a/src/base/abc/abcMap.c b/src/base/abc/abcMap.c index e5f4e104..4c53ba8e 100644 --- a/src/base/abc/abcMap.c +++ b/src/base/abc/abcMap.c @@ -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 diff --git a/src/base/abc/abcMiter.c b/src/base/abc/abcMiter.c index f72fab0f..52141ebb 100644 --- a/src/base/abc/abcMiter.c +++ b/src/base/abc/abcMiter.c @@ -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 ) diff --git a/src/base/abc/abcNames.c b/src/base/abc/abcNames.c index da68bf50..82040404 100644 --- a/src/base/abc/abcNames.c +++ b/src/base/abc/abcNames.c @@ -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) ); } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c index 0b7b44a0..5a4b7447 100644 --- a/src/base/abc/abcNetlist.c +++ b/src/base/abc/abcNetlist.c @@ -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; } diff --git a/src/base/abc/abcPrint.c b/src/base/abc/abcPrint.c index c3e3107c..1eac5333 100644 --- a/src/base/abc/abcPrint.c +++ b/src/base/abc/abcPrint.c @@ -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) ) { diff --git a/src/base/abc/abcRefs.c b/src/base/abc/abcRefs.c index b6a7dce1..eee0530a 100644 --- a/src/base/abc/abcRefs.c +++ b/src/base/abc/abcRefs.c @@ -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 ); diff --git a/src/base/abc/abcRenode.c b/src/base/abc/abcRenode.c index ab1a09c3..12bf0912 100644 --- a/src/base/abc/abcRenode.c +++ b/src/base/abc/abcRenode.c @@ -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) ); } diff --git a/src/base/abc/abcShow.c b/src/base/abc/abcShow.c index 2ddd2a79..5a6e1828 100644 --- a/src/base/abc/abcShow.c +++ b/src/base/abc/abcShow.c @@ -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 ); diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c index aabc2660..b72b48ee 100644 --- a/src/base/abc/abcSop.c +++ b/src/base/abc/abcSop.c @@ -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************************************************************* diff --git a/src/base/abc/abcSweep.c b/src/base/abc/abcSweep.c index 495bf1eb..17f2f0c6 100644 --- a/src/base/abc/abcSweep.c +++ b/src/base/abc/abcSweep.c @@ -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 && diff --git a/src/base/abc/abcUnreach.c b/src/base/abc/abcUnreach.c index 5d5a759b..21196f97 100644 --- a/src/base/abc/abcUnreach.c +++ b/src/base/abc/abcUnreach.c @@ -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 ); diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 001a7231..f144bbdc 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -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 /// diff --git a/src/base/io/io.c b/src/base/io/io.c index 5e72d307..b1f44abd 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -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] \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: diff --git a/src/base/io/io.h b/src/base/io/io.h index d4cea912..2465fa9f 100644 --- a/src/base/io/io.h +++ b/src/base/io/io.h @@ -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 ==========================================================*/ diff --git a/src/base/io/ioRead.c b/src/base/io/ioRead.c index aef5d57a..8a0c11a5 100644 --- a/src/base/io/ioRead.c +++ b/src/base/io/ioRead.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 ) { diff --git a/src/base/io/ioReadBench.c b/src/base/io/ioReadBench.c index 0660adc7..9667fcc7 100644 --- a/src/base/io/ioReadBench.c +++ b/src/base/io/ioReadBench.c @@ -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 /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c index 10346729..693f1104 100644 --- a/src/base/io/ioReadBlif.c +++ b/src/base/io/ioReadBlif.c @@ -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************************************************************* diff --git a/src/base/io/ioReadPla.c b/src/base/io/ioReadPla.c index 16b87fc9..951fb229 100644 --- a/src/base/io/ioReadPla.c +++ b/src/base/io/ioReadPla.c @@ -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; } diff --git a/src/base/io/ioReadVerilog.c b/src/base/io/ioReadVerilog.c index a3b5a0bf..755fb1db 100644 --- a/src/base/io/ioReadVerilog.c +++ b/src/base/io/ioReadVerilog.c @@ -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 /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c new file mode 100644 index 00000000..132684cc --- /dev/null +++ b/src/base/io/ioUtil.c @@ -0,0 +1,201 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/io/ioWriteBench.c b/src/base/io/ioWriteBench.c index 0b7591c0..980015b2 100644 --- a/src/base/io/ioWriteBench.c +++ b/src/base/io/ioWriteBench.c @@ -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; } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c index d9c69273..79de62b8 100644 --- a/src/base/io/ioWriteBlif.c +++ b/src/base/io/ioWriteBlif.c @@ -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 ); } } diff --git a/src/base/io/ioWriteBlifLogic.c b/src/base/io/ioWriteBlifLogic.c deleted file mode 100644 index aa1d65b9..00000000 --- a/src/base/io/ioWriteBlifLogic.c +++ /dev/null @@ -1,402 +0,0 @@ -/**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 /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/io/ioWriteGate.c b/src/base/io/ioWriteGate.c deleted file mode 100644 index 3a3c45eb..00000000 --- a/src/base/io/ioWriteGate.c +++ /dev/null @@ -1,263 +0,0 @@ -/**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 /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/base/io/ioWritePla.c b/src/base/io/ioWritePla.c index 01d2f59b..48e358e3 100644 --- a/src/base/io/ioWritePla.c +++ b/src/base/io/ioWritePla.c @@ -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); diff --git a/src/base/io/module.make b/src/base/io/module.make index 3e5be57a..899f8166 100644 --- a/src/base/io/module.make +++ b/src/base/io/module.make @@ -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 diff --git a/src/csat_apis.h b/src/csat_apis.h new file mode 100644 index 00000000..0b009167 --- /dev/null +++ b/src/csat_apis.h @@ -0,0 +1,125 @@ +//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); diff --git a/src/map/fpga/fpgaCreate.c b/src/map/fpga/fpgaCreate.c index aae49f4c..1e654ded 100644 --- a/src/map/fpga/fpgaCreate.c +++ b/src/map/fpga/fpgaCreate.c @@ -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] ); diff --git a/src/map/mapper/mapperCreate.c b/src/map/mapper/mapperCreate.c index 826d6287..eb938847 100644 --- a/src/map/mapper/mapperCreate.c +++ b/src/map/mapper/mapperCreate.c @@ -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 ); diff --git a/src/misc/vec/vecFan.h b/src/misc/vec/vecFan.h index 451724d6..01335da0 100644 --- a/src/misc/vec/vecFan.h +++ b/src/misc/vec/vecFan.h @@ -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 }; diff --git a/src/sat/sim/simSupp.c b/src/sat/sim/simSupp.c index 9f747e0f..3ae1d3ab 100644 --- a/src/sat/sim/simSupp.c +++ b/src/sat/sim/simSupp.c @@ -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 ); + + } } //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3