summaryrefslogtreecommitdiffstats
path: root/src/base
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2005-07-29 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2005-07-29 08:01:00 -0700
commit888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc (patch)
tree11d48c9e9069f54dc300c3571ae63c744c802c50 /src/base
parent7f94414388cce67bd3cc1a6d6269f0ed31ed0d06 (diff)
downloadabc-888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc.tar.gz
abc-888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc.tar.bz2
abc-888e5bed5d7f56a5d86d91a6e8e88f3e5a3454dc.zip
Version abc50729
Diffstat (limited to 'src/base')
-rw-r--r--src/base/abc/abc.c2158
-rw-r--r--src/base/abc/abc.h557
-rw-r--r--src/base/abc/abcAig.c321
-rw-r--r--src/base/abc/abcAttach.c396
-rw-r--r--src/base/abc/abcCheck.c848
-rw-r--r--src/base/abc/abcCollapse.c271
-rw-r--r--src/base/abc/abcCreate.c1121
-rw-r--r--src/base/abc/abcDfs.c446
-rw-r--r--src/base/abc/abcDsd.c48
-rw-r--r--src/base/abc/abcFanio.c196
-rw-r--r--src/base/abc/abcFpga.c247
-rw-r--r--src/base/abc/abcFraig.c585
-rw-r--r--src/base/abc/abcFunc.c419
-rw-r--r--src/base/abc/abcInt.h46
-rw-r--r--src/base/abc/abcLatch.c260
-rw-r--r--src/base/abc/abcMap.c439
-rw-r--r--src/base/abc/abcMinBase.c167
-rw-r--r--src/base/abc/abcMiter.c502
-rw-r--r--src/base/abc/abcNames.c406
-rw-r--r--src/base/abc/abcNetlist.c93
-rw-r--r--src/base/abc/abcPrint.c288
-rw-r--r--src/base/abc/abcRefs.c133
-rw-r--r--src/base/abc/abcRenode.c605
-rw-r--r--src/base/abc/abcSat.c252
-rw-r--r--src/base/abc/abcSop.c461
-rw-r--r--src/base/abc/abcStrash.c541
-rw-r--r--src/base/abc/abcSweep.c434
-rw-r--r--src/base/abc/abcTiming.c631
-rw-r--r--src/base/abc/abcUtil.c780
-rw-r--r--src/base/abc/abcVerify.c310
-rw-r--r--src/base/abc/module.make28
-rw-r--r--src/base/cmd/cmd.c1498
-rw-r--r--src/base/cmd/cmd.h65
-rw-r--r--src/base/cmd/cmdAlias.c120
-rw-r--r--src/base/cmd/cmdApi.c104
-rw-r--r--src/base/cmd/cmdFlag.c112
-rw-r--r--src/base/cmd/cmdHist.c55
-rw-r--r--src/base/cmd/cmdInt.h82
-rw-r--r--src/base/cmd/cmdUtils.c598
-rw-r--r--src/base/cmd/module.make6
-rw-r--r--src/base/io/io.c766
-rw-r--r--src/base/io/io.h74
-rw-r--r--src/base/io/ioInt.h49
-rw-r--r--src/base/io/ioRead.c74
-rw-r--r--src/base/io/ioReadBench.c227
-rw-r--r--src/base/io/ioReadBlif.c642
-rw-r--r--src/base/io/ioReadVerilog.c888
-rw-r--r--src/base/io/ioWriteBench.c224
-rw-r--r--src/base/io/ioWriteBlif.c344
-rw-r--r--src/base/io/ioWriteBlifLogic.c402
-rw-r--r--src/base/io/ioWriteCnf.c76
-rw-r--r--src/base/io/ioWriteGate.c263
-rw-r--r--src/base/io/module.make10
-rw-r--r--src/base/main/main.c267
-rw-r--r--src/base/main/main.h109
-rw-r--r--src/base/main/mainFrame.c417
-rw-r--r--src/base/main/mainInit.c96
-rw-r--r--src/base/main/mainInt.h107
-rw-r--r--src/base/main/mainUtils.c218
-rw-r--r--src/base/main/module.make4
60 files changed, 21886 insertions, 0 deletions
diff --git a/src/base/abc/abc.c b/src/base/abc/abc.c
new file mode 100644
index 00000000..f9bcde33
--- /dev/null
+++ b/src/base/abc/abc.c
@@ -0,0 +1,2158 @@
+/**CFile****************************************************************
+
+ FileName [abc.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Command file.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abc.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "mainInt.h"
+#include "ft.h"
+#include "fraig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Ntk_CommandPrintStats ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandPrintIo ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandPrintFanio ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Ntk_CommandCollapse ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandStrash ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandBalance ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandRenode ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandCleanup ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Ntk_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandFrames ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandSop ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandBdd ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Ntk_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandFraigTrust ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandFraigStore ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandFraigRestore ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandFraigClean ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandFraigSweep ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Ntk_CommandMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandUnmap ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandAttach ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Ntk_CommandFpga ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Ntk_CommandCec ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Ntk_CommandSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_Init( Abc_Frame_t * pAbc )
+{
+ Cmd_CommandAdd( pAbc, "Printing", "print_stats", Ntk_CommandPrintStats, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_io", Ntk_CommandPrintIo, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_fanio", Ntk_CommandPrintFanio, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_factor", Ntk_CommandPrintFactor, 0 );
+
+ Cmd_CommandAdd( pAbc, "Synthesis", "collapse", Ntk_CommandCollapse, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "strash", Ntk_CommandStrash, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "balance", Ntk_CommandBalance, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "renode", Ntk_CommandRenode, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "cleanup", Ntk_CommandCleanup, 1 );
+
+ Cmd_CommandAdd( pAbc, "Various", "logic", Ntk_CommandLogic, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "miter", Ntk_CommandMiter, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "frames", Ntk_CommandFrames, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "sop", Ntk_CommandSop, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "bdd", Ntk_CommandBdd, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "sat", Ntk_CommandSat, 0 );
+
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Ntk_CommandFraig, 1 );
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Ntk_CommandFraigTrust, 1 );
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig_store", Ntk_CommandFraigStore, 0 );
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig_restore", Ntk_CommandFraigRestore, 1 );
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig_clean", Ntk_CommandFraigClean, 0 );
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig_sweep", Ntk_CommandFraigSweep, 1 );
+
+ Cmd_CommandAdd( pAbc, "SC mapping", "map", Ntk_CommandMap, 1 );
+ Cmd_CommandAdd( pAbc, "SC mapping", "unmap", Ntk_CommandUnmap, 1 );
+ Cmd_CommandAdd( pAbc, "SC mapping", "attach", Ntk_CommandAttach, 1 );
+
+ Cmd_CommandAdd( pAbc, "FPGA mapping", "fpga", Ntk_CommandFpga, 1 );
+
+ Cmd_CommandAdd( pAbc, "Verification", "cec", Ntk_CommandCec, 0 );
+ Cmd_CommandAdd( pAbc, "Verification", "sec", Ntk_CommandSec, 0 );
+
+ Ft_FactorStartMan();
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_End()
+{
+ Ft_FactorStopMan();
+ Abc_NtkFraigStoreClean();
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandPrintStats( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ bool fShort;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set the defaults
+ fShort = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "sh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 's':
+ fShort ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( Abc_FrameReadErr(pAbc), "Empty network\n" );
+ return 1;
+ }
+ Abc_NtkPrintStats( pOut, pNtk );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_stats [-h]\n" );
+ fprintf( pErr, "\t prints the network statistics and\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandPrintIo( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pNode;
+ 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;
+ }
+
+ if ( argc > util_optind + 1 )
+ {
+ fprintf( pErr, "Wrong number of auguments.\n" );
+ goto usage;
+ }
+
+ if ( argc == util_optind + 1 )
+ {
+ pNode = Abc_NtkFindNode( pNtk, argv[util_optind] );
+ if ( pNode == NULL )
+ {
+ fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] );
+ return 1;
+ }
+ Abc_NodePrintFanio( pOut, pNode );
+ return 0;
+ }
+ // print the nodes
+ Abc_NtkPrintIo( pOut, pNtk );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_io [-h]\n" );
+ fprintf( pErr, "\t prints the PIs/POs or fanins/fanouts of a node\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandPrintFanio( 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_NtkPrintFanio( pOut, pNtk );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_fanio [-h]\n" );
+ fprintf( pErr, "\t prints the statistics about fanins/fanouts of all nodes\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandPrintFactor( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pNode;
+ 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;
+ }
+
+ if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogicSop(pNtk) )
+ {
+ fprintf( pErr, "Printing factored forms can be done for netlist and SOP networks.\n" );
+ return 1;
+ }
+
+ if ( argc > util_optind + 1 )
+ {
+ fprintf( pErr, "Wrong number of auguments.\n" );
+ goto usage;
+ }
+
+ if ( argc == util_optind + 1 )
+ {
+ pNode = Abc_NtkFindNode( pNtk, argv[util_optind] );
+ if ( pNode == NULL )
+ {
+ fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] );
+ return 1;
+ }
+// Ft_FactorStartMan();
+ Abc_NodePrintFactor( pOut, pNode );
+// Ft_FactorStopMan();
+ return 0;
+ }
+ // print the nodes
+// Ft_FactorStartMan();
+ Abc_NtkPrintFactor( pOut, pNtk );
+// Ft_FactorStopMan();
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_factor [-h] <node>\n" );
+ fprintf( pErr, "\t prints the factored forms of nodes\n" );
+ fprintf( pErr, "\tnode : (optional) one node to consider\n");
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ 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;
+ }
+
+ if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsAig(pNtk) )
+ {
+ fprintf( pErr, "Can only collapse a logic network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( Abc_NtkIsAig(pNtk) )
+ pNtkRes = Abc_NtkCollapse( pNtk, 1 );
+ else
+ {
+ pNtk = Abc_NtkStrash( pNtk );
+ pNtkRes = Abc_NtkCollapse( pNtk, 1 );
+ Abc_NtkDelete( pNtk );
+ }
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Collapsing has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: collapse [-h]\n" );
+ fprintf( pErr, "\t collapses the network by constructing global BDDs\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandStrash( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ 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;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkStrash( pNtk );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Strashing has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: strash [-h]\n" );
+ fprintf( pErr, "\t transforms combinational logic into an AIG\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsAig(pNtk) )
+ {
+ fprintf( pErr, "Cannot balance a network that is not an AIG.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkBalance( pNtk, fDuplicate );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Balancing has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: balance [-dh]\n" );
+ fprintf( pErr, "\t transforms an AIG into a well-balanced AIG\n" );
+ fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int nThresh, nFaninMax, c;
+ int fCnf;
+ int fMulti;
+ int fSimple;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nThresh = 0;
+ nFaninMax = 20;
+ fCnf = 0;
+ fMulti = 0;
+ fSimple = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "tfmcsh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 't':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-t\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nThresh = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nThresh < 0 )
+ goto usage;
+ break;
+ case 'f':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-f\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nFaninMax = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nFaninMax < 0 )
+ goto usage;
+ break;
+ case 'c':
+ fCnf ^= 1;
+ break;
+ case 'm':
+ fMulti ^= 1;
+ break;
+ case 's':
+ fSimple ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsAig(pNtk) )
+ {
+ fprintf( pErr, "Cannot renode a network that is not an AIG.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkRenode( pNtk, nThresh, nFaninMax, fCnf, fMulti, fSimple );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Renoding has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: renode [-t num] [-f num] [-cmsh]\n" );
+ fprintf( pErr, "\t transforms an AIG into a logic network by creating larger nodes\n" );
+ fprintf( pErr, "\t-t num : the threshold for AIG node duplication [default = %d]\n", nThresh );
+ fprintf( pErr, "\t-f num : the maximum fanin size after renoding [default = %d]\n", nFaninMax );
+ fprintf( pErr, "\t-c : performs renoding to derive the CNF [default = %s]\n", fCnf? "yes": "no" );
+ fprintf( pErr, "\t-m : creates multi-input AND graph [default = %s]\n", fMulti? "yes": "no" );
+ fprintf( pErr, "\t-s : creates a simple AIG (no renoding) [default = %s]\n", fSimple? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // modify the current network
+ Abc_NtkCleanup( pNtk, 0 );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: cleanup [-h]\n" );
+ fprintf( pErr, "\t removes dangling nodes\n" );
+// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandLogic( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ 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;
+ }
+
+ if ( !Abc_NtkIsNetlist( pNtk ) )
+ {
+ fprintf( pErr, "This command is only applicable to netlists.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkLogic( pNtk );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Converting to a logic network has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: logic [-h]\n" );
+ fprintf( pErr, "\t transforms a netlist into a logic network\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtk1, * pNtk2, * pNtkRes;
+ int fDelete1, fDelete2;
+ char ** pArgvNew;
+ int nArgcNew;
+ int c;
+ int fCheck;
+ int fComb;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fComb = 1;
+ fCheck = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'c':
+ fComb ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ pArgvNew = argv + util_optind;
+ nArgcNew = argc - util_optind;
+ if ( !Abc_NtkPrepareCommand( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
+ return 1;
+
+ // compute the miter
+ pNtkRes = Abc_NtkMiter( pNtk1, pNtk2, fComb );
+ if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
+ if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
+
+ // get the new network
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Miter computation has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: miter [-ch] <file1> <file2>\n" );
+ fprintf( pErr, "\t computes the miter of the two circuits\n" );
+ fprintf( pErr, "\t-c : computes combinational miter (latches as POs) [default = %s]\n", fComb? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
+ fprintf( pErr, "\tfile2 : (optional) the file with the second network\n");
+ fprintf( pErr, "\t if no files are given, uses the current network and its spec\n");
+ fprintf( pErr, "\t if one file is given, uses the current network and the file\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandFrames( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkTemp, * pNtkRes;
+ int fInitial;
+ int nFrames;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fInitial = 0;
+ nFrames = 5;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "fih" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'f':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-n\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nFrames = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nFrames < 0 )
+ goto usage;
+ break;
+ case 'i':
+ fInitial ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( !Abc_NtkIsAig(pNtk) )
+ {
+ pNtkTemp = Abc_NtkStrash( pNtk );
+ pNtkRes = Abc_NtkFrames( pNtkTemp, nFrames, fInitial );
+ Abc_NtkDelete( pNtkTemp );
+ }
+ else
+ pNtkRes = Abc_NtkFrames( pNtk, nFrames, fInitial );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Unrolling the network has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: frames [-f num] [-ih]\n" );
+ fprintf( pErr, "\t unrolls the network for a number of time frames\n" );
+ fprintf( pErr, "\t-f num : the number of frames to unroll [default = %d]\n", nFrames );
+ fprintf( pErr, "\t-i : toggles initializing the first frame [default = %s]\n", fInitial? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandSop( 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;
+ }
+
+ // get the new network
+ if ( !Abc_NtkIsLogicBdd(pNtk) )
+ {
+ fprintf( pErr, "Converting to SOP is possible when node functions are BDDs.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkBddToSop( pNtk ) )
+ {
+ fprintf( pErr, "Converting to SOP has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: sop [-h]\n" );
+ fprintf( pErr, "\t converts node functions from BDD to SOP\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandBdd( 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;
+ }
+
+ // get the new network
+ if ( !Abc_NtkIsLogicSop(pNtk) )
+ {
+ fprintf( pErr, "Converting to BDD is possible when node functions are SOPs.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkSopToBdd( pNtk ) )
+ {
+ fprintf( pErr, "Converting to BDD has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: bdd [-h]\n" );
+ fprintf( pErr, "\t converts node functions from SOP to BDD\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fVerbose;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( Abc_NtkLatchNum(pNtk) > 0 )
+ {
+ fprintf( stdout, "Currently can only solve the miter for combinational circuits.\n" );
+ return 0;
+ }
+ if ( !(Abc_NtkIsLogicSop(pNtk) || Abc_NtkIsLogicBdd(pNtk)) )
+ {
+ fprintf( stdout, "First convert node representation into BDDs or SOPs.\n" );
+ return 0;
+ }
+ if ( Abc_NtkIsLogicSop(pNtk) )
+ {
+// printf( "Converting node functions from SOP to BDD.\n" );
+ Abc_NtkSopToBdd(pNtk);
+ }
+
+ if ( Abc_NtkMiterSat( pNtk, fVerbose ) )
+ printf( "The miter is satisfiable.\n" );
+ else
+ printf( "The miter is unsatisfiable.\n" );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: sat [-vh]\n" );
+ fprintf( pErr, "\t solves the miter\n" );
+ fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ char Buffer[100];
+ Fraig_Params_t Params;
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ Params.nPatsRand = 2048; // the number of words of random simulation info
+ Params.nPatsDyna = 2048; // the number of words of dynamic simulation info
+ Params.nBTLimit = 99; // the max number of backtracks to perform
+ Params.fFuncRed = 1; // performs only one level hashing
+ Params.fFeedBack = 1; // enables solver feedback
+ Params.fDist1Pats = 1; // enables distance-1 patterns
+ Params.fDoSparse = 0; // performs equiv tests for sparse functions
+ Params.fChoicing = 0; // enables recording structural choices
+ Params.fTryProve = 0; // tries to solve the final miter
+ Params.fVerbose = 0; // the verbosiness flag
+ Params.fVerboseP = 0; // the verbosiness flag
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "RDBrscpvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+
+ case 'R':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-r\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ Params.nPatsRand = atoi(argv[util_optind]);
+ util_optind++;
+ if ( Params.nPatsRand < 0 )
+ goto usage;
+ break;
+ case 'D':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-d\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ Params.nPatsDyna = atoi(argv[util_optind]);
+ util_optind++;
+ if ( Params.nPatsDyna < 0 )
+ goto usage;
+ break;
+ case 'B':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-b\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ Params.nBTLimit = atoi(argv[util_optind]);
+ util_optind++;
+ if ( Params.nBTLimit < 0 )
+ goto usage;
+ break;
+
+ case 'r':
+ Params.fFuncRed ^= 1;
+ break;
+ case 's':
+ Params.fDoSparse ^= 1;
+ break;
+ case 'c':
+ Params.fChoicing ^= 1;
+ break;
+ case 'p':
+ Params.fTryProve ^= 1;
+ break;
+ case 'v':
+ Params.fVerbose ^= 1;
+ break;
+
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsAig(pNtk) )
+ {
+ fprintf( pErr, "Can only fraig a logic network.\n" );
+ return 1;
+ }
+
+ // report the proof
+ Params.fVerboseP = Params.fTryProve;
+
+ // get the new network
+ if ( Abc_NtkIsAig(pNtk) )
+ pNtkRes = Abc_NtkFraig( pNtk, &Params, 0 );
+ else
+ {
+ pNtk = Abc_NtkStrash( pNtk );
+ pNtkRes = Abc_NtkFraig( pNtk, &Params, 0 );
+ Abc_NtkDelete( pNtk );
+ }
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Fraiging has failed.\n" );
+ return 1;
+ }
+
+ if ( Params.fTryProve ) // report the result
+ Abc_NtkMiterReport( pNtkRes );
+
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ sprintf( Buffer, "%d", Params.nBTLimit );
+ fprintf( pErr, "usage: fraig [-R num] [-D num] [-B num] [-rscpvh]\n" );
+ fprintf( pErr, "\t transforms a logic network into a functionally reduced AIG\n" );
+ fprintf( pErr, "\t-R num : number of random patterns (127 < num < 32769) [default = %d]\n", Params.nPatsRand );
+ fprintf( pErr, "\t-D num : number of systematic patterns (127 < num < 32769) [default = %d]\n", Params.nPatsDyna );
+ fprintf( pErr, "\t-B num : number of backtracks for one SAT problem [default = %s]\n", Params.nBTLimit==-1? "infinity" : Buffer );
+ fprintf( pErr, "\t-r : toggle functional reduction [default = %s]\n", Params.fFuncRed? "yes": "no" );
+ fprintf( pErr, "\t-s : toggle considering sparse functions [default = %s]\n", Params.fDoSparse? "yes": "no" );
+ fprintf( pErr, "\t-c : toggle accumulation of choices [default = %s]\n", Params.fChoicing? "yes": "no" );
+ fprintf( pErr, "\t-p : toggle proving the final miter [default = %s]\n", Params.fTryProve? "yes": "no" );
+ fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", Params.fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandFraigTrust( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkFraigTrust( pNtk );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Fraiging in the trust mode has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fraig_trust [-h]\n" );
+ fprintf( pErr, "\t transforms the current network into an AIG assuming it is FRAIG with choices\n" );
+// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandFraigStore( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( !Abc_NtkFraigStore( pNtk ) )
+ {
+ fprintf( pErr, "Fraig storing has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fraig_store [-h]\n" );
+ fprintf( pErr, "\t saves the current network in the AIG database\n" );
+// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandFraigRestore( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkFraigRestore();
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Fraig restoring has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fraig_restore [-h]\n" );
+ fprintf( pErr, "\t makes the current network by fraiging the AIG database\n" );
+// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandFraigClean( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ Abc_NtkFraigStoreClean();
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fraig_clean [-h]\n" );
+ fprintf( pErr, "\t cleans the internal FRAIG storage\n" );
+// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fUseInv;
+ int fVerbose;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fUseInv = 1;
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ivh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'i':
+ fUseInv ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( Abc_NtkIsNetlist(pNtk) )
+ {
+ fprintf( pErr, "Cannot sweep a netlist. Please transform into a logic network.\n" );
+ return 1;
+ }
+ if ( Abc_NtkIsAig(pNtk) )
+ {
+ fprintf( pErr, "Cannot sweep AIGs (use \"fraig\").\n" );
+ return 1;
+ }
+ // modify the current network
+ if ( !Abc_NtkFraigSweep( pNtk, fUseInv, fVerbose ) )
+ {
+ fprintf( pErr, "Sweeping has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fraig_sweep [-vh]\n" );
+ fprintf( pErr, "\t performs technology-dependent sweep\n" );
+// fprintf( pErr, "\t-i : toggle using inverter for complemented nodes [default = %s]\n", fUseInv? "yes": "no" );
+ fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ char Buffer[100];
+ double DelayTarget;
+ int fRecovery;
+ int fVerbose;
+ int fSweep;
+ int c;
+ extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ DelayTarget =-1;
+ fRecovery = 1;
+ fSweep = 1;
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dasvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-d\" should be followed by a floating point number.\n" );
+ goto usage;
+ }
+ DelayTarget = (float)atof(argv[util_optind]);
+ util_optind++;
+ if ( DelayTarget <= 0.0 )
+ goto usage;
+ break;
+ case 'a':
+ fRecovery ^= 1;
+ break;
+ case 's':
+ fSweep ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsAig(pNtk) )
+ {
+ pNtk = Abc_NtkStrash( pNtk );
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Strashing before mapping has failed.\n" );
+ return 1;
+ }
+ pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 );
+ Abc_NtkDelete( pNtkRes );
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Balancing before mapping has failed.\n" );
+ return 1;
+ }
+ fprintf( pOut, "The network was strashed and balanced before mapping.\n" );
+ // get the new network
+ pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ Abc_NtkDelete( pNtk );
+ fprintf( pErr, "Mapping has failed.\n" );
+ return 1;
+ }
+ Abc_NtkDelete( pNtk );
+ }
+ else
+ {
+ // get the new network
+ pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Mapping has failed.\n" );
+ return 1;
+ }
+ }
+
+ if ( fSweep )
+ Abc_NtkFraigSweep( pNtkRes, 0, 0 );
+
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ if ( DelayTarget == -1 )
+ sprintf( Buffer, "not used" );
+ else
+ sprintf( Buffer, "%.3f", DelayTarget );
+ fprintf( pErr, "usage: map [-d num] [-asvh]\n" );
+ fprintf( pErr, "\t performs standard cell mapping of the current network\n" );
+ fprintf( pErr, "\t-d num : sets the global required times [default = %s]\n", Buffer );
+ fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" );
+ fprintf( pErr, "\t-s : toggles sweep after mapping [default = %s]\n", fSweep? "yes": "no" );
+ fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandUnmap( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk );
+
+ 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;
+ }
+ if ( !Abc_NtkIsLogicMap(pNtk) )
+ {
+ fprintf( pErr, "Cannot unmap the network that is not mapped.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( !Abc_NtkUnmap( pNtk ) )
+ {
+ fprintf( pErr, "Unmapping has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: unmap [-h]\n" );
+ fprintf( pErr, "\t replaces the library gates by the logic nodes represented using SOPs\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandAttach( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk );
+
+ 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;
+ }
+
+ if ( !Abc_NtkIsLogicSop(pNtk) )
+ {
+ fprintf( pErr, "Can only attach gates if the nodes have SOP representations.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( !Abc_NtkAttach( pNtk ) )
+ {
+ fprintf( pErr, "Attaching gates has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: attach [-h]\n" );
+ fprintf( pErr, "\t replaces the SOP functions by the gates from the library\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int fRecovery;
+ int fVerbose;
+ extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fRecovery = 1;
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "avh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'a':
+ fRecovery ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsAig(pNtk) )
+ {
+ // strash and balance the network
+ pNtk = Abc_NtkStrash( pNtk );
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Strashing before FPGA mapping has failed.\n" );
+ return 1;
+ }
+ pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 );
+ Abc_NtkDelete( pNtkRes );
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Balancing before FPGA mapping has failed.\n" );
+ return 1;
+ }
+ fprintf( pOut, "The network was strashed and balanced before FPGA mapping.\n" );
+ // get the new network
+ pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ Abc_NtkDelete( pNtk );
+ fprintf( pErr, "FPGA mapping has failed.\n" );
+ return 1;
+ }
+ Abc_NtkDelete( pNtk );
+ }
+ else
+ {
+ // get the new network
+ pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "FPGA mapping has failed.\n" );
+ return 1;
+ }
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fpga [-avh]\n" );
+ fprintf( pErr, "\t performs FPGA mapping of the current network\n" );
+ fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" );
+ fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : prints the command usage\n");
+ return 1;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtk1, * pNtk2;
+ int fDelete1, fDelete2;
+ char ** pArgvNew;
+ int nArgcNew;
+ int c;
+ int fSat;
+
+ extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
+ extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
+
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fSat = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "sh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 's':
+ fSat ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ pArgvNew = argv + util_optind;
+ nArgcNew = argc - util_optind;
+ if ( !Abc_NtkPrepareCommand( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
+ return 1;
+
+ // perform equivalence checking
+ if ( fSat )
+ Abc_NtkCecSat( pNtk1, pNtk2 );
+ else
+ Abc_NtkCecFraig( pNtk1, pNtk2 );
+
+ if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
+ if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: cec [-sh] <file1> <file2>\n" );
+ fprintf( pErr, "\t performs combinational equivalence checking\n" );
+ fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
+ fprintf( pErr, "\tfile2 : (optional) the file with the second network\n");
+ fprintf( pErr, "\t if no files are given, uses the current network and its spec\n");
+ fprintf( pErr, "\t if one file is given, uses the current network and the file\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntk_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtk1, * pNtk2;
+ int fDelete1, fDelete2;
+ char ** pArgvNew;
+ int nArgcNew;
+ int c;
+ int fSat;
+ int nFrames;
+
+ extern void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames );
+ extern void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames );
+
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nFrames = 3;
+ fSat = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "fsh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'f':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-t\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nFrames = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nFrames < 0 )
+ goto usage;
+ break;
+ case 's':
+ fSat ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ pArgvNew = argv + util_optind;
+ nArgcNew = argc - util_optind;
+ if ( !Abc_NtkPrepareCommand( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
+ return 1;
+
+ // perform equivalence checking
+ if ( fSat )
+ Abc_NtkSecSat( pNtk1, pNtk2, nFrames );
+ else
+ Abc_NtkSecFraig( pNtk1, pNtk2, nFrames );
+
+ if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
+ if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: sec [-sh] [-f num] <file1> <file2>\n" );
+ fprintf( pErr, "\t performs bounded sequential equivalence checking\n" );
+ fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\t-f num : the number of time frames to use [default = %d]\n", nFrames );
+ fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
+ fprintf( pErr, "\tfile2 : (optional) the file with the second network\n");
+ fprintf( pErr, "\t if no files are given, uses the current network and its spec\n");
+ fprintf( pErr, "\t if one file is given, uses the current network and the file\n");
+ return 1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
new file mode 100644
index 00000000..d918cbc2
--- /dev/null
+++ b/src/base/abc/abc.h
@@ -0,0 +1,557 @@
+/**CFile****************************************************************
+
+ FileName [abc.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abc.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __ABC_H__
+#define __ABC_H__
+
+/*
+ In the netlist, the PI/PO arrays store PI/PO nets.
+ The names belongs to the nets and are stored in pNet->pData.
+ When a netlist is made combinational:
+ - LO/LI nets are added to PI/PO arrays,
+ - the array of latches is temporarily stored in vLatch2,
+ - the original number of PIs/POs is remembered in nPisOld/nPosOld.
+
+ In a logic network, the PI/PO arrays store PI/PO nodes.
+ The PO nodes have only one fanin edge, which can be complemented.
+ The arrays vNamesPi/vNamesPo/vNamesLatch store PI/PO/latch names.
+ The internal nodes are nameless.
+ When a logic network is made combinational:
+ - laches are added to the PI/PO arrays,
+ - the arrays of names are not changed,
+ - the array of latches is temporarily stored in vLatch2,
+ - the original number of PIs/POs is remembered in nPisOld/nPosOld.
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+
+#include "cuddInt.h"
+#include "extra.h"
+#include "solver.h"
+#include "vec.h"
+#include "stmm.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+// network types
+typedef enum {
+ ABC_NTK_NONE, // unknown
+ ABC_NTK_NETLIST, // net and node list as in the input file
+ 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)
+ ABC_NTK_AIG, // AIG or FRAIG (two input gates with c-attributes on edges)
+ ABC_NTK_SEQ, // sequential AIG (two input gates with c- and latch-attributes on edges)
+ ABC_NTK_OTHER // unused
+} Abc_NtkType_t;
+
+// 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_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 ///
+////////////////////////////////////////////////////////////////////////
+
+//typedef int bool;
+#ifndef bool
+#define bool int
+#endif
+
+typedef struct Abc_Obj_t_ Abc_Obj_t;
+typedef struct Abc_Ntk_t_ Abc_Ntk_t;
+typedef struct Abc_Aig_t_ Abc_Aig_t;
+typedef struct Abc_ManTime_t_ Abc_ManTime_t;
+typedef struct Abc_Time_t_ Abc_Time_t;
+
+struct Abc_Time_t_
+{
+ float Rise;
+ float Fall;
+ float Worst;
+};
+
+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
+ // internal information
+ unsigned fMarkA : 1; // the multipurpose mark
+ unsigned fMarkB : 1; // the multipurpose mark
+ unsigned fMarkC : 1; // the multipurpose mark
+ unsigned fPhase : 1; // the flag to mark the phase of equivalent node
+ unsigned TravId : 12; // the traversal ID
+ unsigned Level : 16; // the level of the node
+ // connectivity
+ Vec_Fan_t vFanins; // the array of fanins
+ Vec_Fan_t vFanouts; // the array of fanouts
+ // miscellaneous
+ Abc_Ntk_t * pNtk; // the host network
+ void * pData; // the network specific data (SOP, BDD, gate, equiv class, etc)
+ Abc_Obj_t * pNext; // the next pointer in the hash table
+ Abc_Obj_t * pCopy; // the copy of this object
+};
+
+struct Abc_Ntk_t_
+{
+ // general information about the network
+ 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
+ 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
+ // 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)
+ // the stats about the number of living objects
+ int nObjs; // the number of living objs
+ int nNets; // the number of living nets
+ int nNodes; // the number of living nodes
+ int nLatches; // the number of latches
+ int nPis; // the number of primary inputs
+ int nPos; // the number of primary outputs
+ // the functionality manager
+ void * pManFunc; // AIG manager, BDD manager, or memory manager for SOPs
+ // the timing manager
+ Abc_ManTime_t * pManTime; // stores arrival/required times for all nodes
+ // 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
+ Vec_Str_t * vStrTemp; // the temporary array
+ // the backup network and the step number
+ Abc_Ntk_t * pNetBackup; // the pointer to the previous backup network
+ int iStep; // the generation number for the given network
+ // memory management
+ Extra_MmFlex_t * pMmNames; // memory manager for net names
+ Extra_MmFixed_t* pMmObj; // memory manager for objects
+ Extra_MmStep_t * pMmStep; // memory manager for arrays
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// 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]; }
+
+// setting data members of the network
+static inline void Abc_NtkSetName ( Abc_Ntk_t * pNtk, char * pName ) { pNtk->pName = pName; }
+static inline void Abc_NtkSetSpec ( Abc_Ntk_t * pNtk, char * pName ) { pNtk->pSpec = 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; }
+
+// 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]; }
+
+// 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; }
+static inline Vec_Fan_t * Abc_ObjFanoutVec( Abc_Obj_t * pObj ) { return &pObj->vFanouts; }
+static inline Abc_Obj_t * Abc_ObjCopy( Abc_Obj_t * pObj ) { return pObj->pCopy; }
+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; }
+
+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 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 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 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; }
+
+// 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)); }
+
+// 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; }
+extern bool Abc_NodeIsConst0( Abc_Obj_t * pNode );
+extern bool Abc_NodeIsConst1( Abc_Obj_t * pNode );
+extern bool Abc_NodeIsBuf( Abc_Obj_t * pNode );
+extern bool Abc_NodeIsInv( Abc_Obj_t * pNode );
+
+// working with the traversal ID
+static inline void Abc_NodeSetTravId( Abc_Obj_t * pNode, int TravId ) { pNode->TravId = TravId; }
+static inline void Abc_NodeSetTravIdCurrent( Abc_Obj_t * pNode ) { pNode->TravId = pNode->pNtk->nTravIds; }
+static inline void Abc_NodeSetTravIdPrevious( Abc_Obj_t * pNode ) { pNode->TravId = pNode->pNtk->nTravIds - 1; }
+static inline bool Abc_NodeIsTravIdCurrent( Abc_Obj_t * pNode ) { return (bool)(pNode->TravId == pNode->pNtk->nTravIds); }
+static inline bool Abc_NodeIsTravIdPrevious( Abc_Obj_t * pNode ) { return (bool)(pNode->TravId == pNode->pNtk->nTravIds - 1); }
+
+// maximum/minimum operators
+#define ABC_MIN(a,b) (((a) < (b))? (a) : (b))
+#define ABC_MAX(a,b) (((a) > (b))? (a) : (b))
+#define ABC_INFINITY (10000000)
+
+// outputs the runtime in seconds
+#define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))
+
+////////////////////////////////////////////////////////////////////////
+/// ITERATORS ///
+////////////////////////////////////////////////////////////////////////
+
+// objects of the network
+#define Abc_NtkForEachObj( pNtk, pObj, i ) \
+ for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \
+ if ( pObj = Abc_NtkObj(pNtk, i) )
+#define Abc_NtkForEachNet( pNtk, pNet, i ) \
+ for ( i = 0; i < Vec_PtrSize(pNtk->vObjs); i++ ) \
+ if ( (pNet = Abc_NtkObj(pNtk, i)) && Abc_ObjIsNet(pNet) )
+#define Abc_NtkForEachNode( pNtk, pNode, i ) \
+ 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++ ) \
+ if ( pObj = Abc_NtkLatch(pNtk, i) )
+// inputs and outputs
+#define Abc_NtkForEachPi( pNtk, pPi, i ) \
+ for ( i = 0; i < Abc_NtkPiNum(pNtk); i++ ) \
+ if ( pPi = Abc_NtkPi(pNtk, i) )
+#define Abc_NtkForEachPo( pNtk, pPo, i ) \
+ for ( i = 0; i < Abc_NtkPoNum(pNtk); i++ ) \
+ 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) )
+#define Abc_NtkForEachCo( pNtk, pPo, i ) \
+ for ( i = 0; i < Abc_NtkCoNum(pNtk); i++ ) \
+ if ( pPo = Abc_NtkPo(pNtk, i) )
+// fanin and fanouts
+#define Abc_ObjForEachFanin( pObj, pFanin, i ) \
+ for ( i = 0; i < Abc_ObjFaninNum(pObj); i++ ) \
+ if ( pFanin = Abc_ObjFanin(pObj, i) )
+#define Abc_ObjForEachFanout( pObj, pFanout, i ) \
+ for ( i = 0; i < Abc_ObjFanoutNum(pObj); i++ ) \
+ if ( pFanout = Abc_ObjFanout(pObj, i) )
+// cubes and literals
+#define Abc_SopForEachCube( pSop, nFanins, pCube ) \
+ for ( pCube = (pSop); *pCube; pCube += (nFanins) + 3 )
+#define Abc_CubeForEachVar( pCube, Value, i ) \
+ for ( i = 0; (pCube[i] != ' ') && (Value = pCube[i]); i++ )
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== abcAig.c ==========================================================*/
+extern Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtk );
+extern void Abc_AigFree( Abc_Aig_t * pMan );
+extern Abc_Obj_t * Abc_AigConst1( Abc_Aig_t * pMan );
+extern Abc_Obj_t * Abc_AigAnd( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
+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 );
+/*=== abcAttach.c ==========================================================*/
+extern int Abc_NtkAttach( Abc_Ntk_t * pNtk );
+/*=== abcCheck.c ==========================================================*/
+extern bool Abc_NtkCheck( Abc_Ntk_t * pNtk );
+extern bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
+/*=== abcCollapse.c ==========================================================*/
+extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fVerbose );
+/*=== abcCreate.c ==========================================================*/
+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 void Abc_NtkFinalizeRegular( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
+extern Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk );
+extern void Abc_NtkDelete( 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_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_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 );
+extern Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
+extern Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin );
+extern Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
+extern Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins );
+extern Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 );
+/*=== abcDfs.c ==========================================================*/
+extern Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk );
+extern Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk );
+extern int Abc_NtkGetLevelNum( Abc_Ntk_t * pNtk );
+extern bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk );
+/*=== abcFanio.c ==========================================================*/
+extern void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin );
+extern void Abc_ObjDeleteFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin );
+extern void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFaninNew );
+extern void Abc_ObjTransferFanout( Abc_Obj_t * pObjOld, Abc_Obj_t * pObjNew );
+extern void Abc_ObjReplace( Abc_Obj_t * pObjOld, Abc_Obj_t * pObjNew );
+/*=== abcFraig.c ==========================================================*/
+extern Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes );
+extern Abc_Ntk_t * Abc_NtkFraigTrust( Abc_Ntk_t * pNtk );
+extern int Abc_NtkFraigStore( Abc_Ntk_t * pNtk );
+extern Abc_Ntk_t * Abc_NtkFraigRestore();
+extern void Abc_NtkFraigStoreClean();
+/*=== abcFunc.c ==========================================================*/
+extern int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk );
+extern char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFunc, int nFanins, Vec_Str_t * vCube, int fMode );
+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 ==========================================================*/
+extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose );
+extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk );
+/*=== abcMiter.c ==========================================================*/
+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 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 );
+extern Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial );
+/*=== 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_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 );
+/*=== abcNetlist.c ==========================================================*/
+extern Abc_Ntk_t * Abc_NtkLogic( 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_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 );
+extern void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode );
+/*=== abcRefs.c ==========================================================*/
+extern int Abc_NodeMffcSize( Abc_Obj_t * pNode );
+extern int Abc_NodeMffcRemove( Abc_Obj_t * pNode );
+/*=== abcRenode.c ==========================================================*/
+extern Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple );
+extern DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld );
+/*=== abcSat.c ==========================================================*/
+extern bool Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int fVerbose );
+extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk );
+/*=== abcSop.c ==========================================================*/
+extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName );
+extern int Abc_SopGetCubeNum( char * pSop );
+extern int Abc_SopGetLitNum( char * pSop );
+extern int Abc_SopGetVarNum( char * pSop );
+extern int Abc_SopGetPhase( char * pSop );
+extern bool Abc_SopIsConst0( char * pSop );
+extern bool Abc_SopIsConst1( char * pSop );
+extern bool Abc_SopIsBuf( char * pSop );
+extern bool Abc_SopIsInv( char * pSop );
+extern bool Abc_SopIsAndType( char * pSop );
+extern bool Abc_SopIsOrType( char * pSop );
+extern int Abc_SopGetIthCareLit( char * pSop, int i );
+extern void Abc_SopComplement( char * pSop );
+extern bool Abc_SopCheck( char * pSop, int nFanins );
+extern void Abc_SopWriteCnf( FILE * pFile, char * pClauses, Vec_Int_t * vVars );
+extern void Abc_SopAddCnfToSolver( solver * pSat, char * pClauses, Vec_Int_t * vVars, Vec_Int_t * vTemp );
+/*=== abcStrash.c ==========================================================*/
+extern Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk );
+extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
+extern Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate );
+/*=== abcSweep.c ==========================================================*/
+extern bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose );
+extern int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose );
+/*=== abcTiming.c ==========================================================*/
+extern Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode );
+extern Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode );
+extern Abc_Time_t * Abc_NtkReadDefaultArrival( Abc_Ntk_t * pNtk );
+extern Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk );
+extern void Abc_NtkTimeSetDefaultArrival( Abc_Ntk_t * pNtk, float Rise, float Fall );
+extern void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall );
+extern void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall );
+extern void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall );
+extern void Abc_NtkTimeFinalize( Abc_Ntk_t * pNtk );
+extern void Abc_ManTimeStop( Abc_ManTime_t * p );
+extern void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew );
+extern void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtk );
+extern float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk );
+extern Abc_Time_t * Abc_NtkGetCiArrivalTimes( Abc_Ntk_t * pNtk );
+extern float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk );
+/*=== abcTravId.c ==========================================================*/
+extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
+extern void Abc_NodeSetTravId( Abc_Obj_t * pObj, int TravId );
+extern void Abc_NodeSetTravIdCurrent( Abc_Obj_t * pObj );
+extern void Abc_NodeSetTravIdPrevious( Abc_Obj_t * pObj );
+extern bool Abc_NodeIsTravIdCurrent( Abc_Obj_t * pObj );
+extern bool Abc_NodeIsTravIdPrevious( Abc_Obj_t * pObj );
+/*=== abcUtil.c ==========================================================*/
+extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
+extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk );
+extern int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk );
+extern int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk );
+extern int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk );
+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 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 );
+extern int Abc_NtkCountChoiceNodes( Abc_Ntk_t * pNtk );
+extern int Abc_NtkPrepareCommand( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc, Abc_Ntk_t ** ppNtk1, Abc_Ntk_t ** ppNtk2, int * pfDelete1, int * pfDelete2 );
+extern void Abc_NodeCollectFanins( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
+extern void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes );
+extern int Abc_NodeCompareLevelsIncrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 );
+extern int Abc_NodeCompareLevelsDecrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 );
+extern Vec_Ptr_t * Abc_AigCollectAll( Abc_Ntk_t * pNtk );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c
new file mode 100644
index 00000000..5ec0d97a
--- /dev/null
+++ b/src/base/abc/abcAig.c
@@ -0,0 +1,321 @@
+/**CFile****************************************************************
+
+ FileName [abcAig.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Simple structural hashing package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcAig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// the simple AIG manager
+struct Abc_Aig_t_
+{
+ Abc_Ntk_t * pAig; // the AIG network
+ Abc_Obj_t * pConst1; // the constant 1 node
+ Abc_Obj_t ** pBins; // the table bins
+ int nBins; // the size of the table
+ int nEntries; // the total number of entries in the table
+ Vec_Ptr_t * vNodes; // the temporary array of nodes
+};
+
+// iterators through the entries in the linked lists of nodes
+#define Abc_AigBinForEachEntry( pBin, pEnt ) \
+ for ( pEnt = pBin; \
+ pEnt; \
+ pEnt = pEnt->pNext )
+#define Abc_AigBinForEachEntrySafe( pBin, pEnt, pEnt2 ) \
+ for ( pEnt = pBin, \
+ pEnt2 = pEnt? pEnt->pNext: NULL; \
+ pEnt; \
+ pEnt = pEnt2, \
+ pEnt2 = pEnt? pEnt->pNext: NULL )
+
+// hash key for the structural hash table
+static inline unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize ) { return ((unsigned)(p0) + (unsigned)(p1) * 12582917) % TableSize; }
+//static inline unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize ) { return ((unsigned)((a)->Id + (b)->Id) * ((a)->Id + (b)->Id + 1) / 2) % TableSize; }
+
+// static hash table procedures
+static void Abc_AigResize( Abc_Aig_t * pMan );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocates the local AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig )
+{
+ Abc_Aig_t * pMan;
+ // start the manager
+ pMan = ALLOC( Abc_Aig_t, 1 );
+ memset( pMan, 0, sizeof(Abc_Aig_t) );
+ // allocate the table
+ pMan->nBins = Cudd_PrimeCopy( 10000 );
+ pMan->pBins = ALLOC( Abc_Obj_t *, pMan->nBins );
+ memset( pMan->pBins, 0, sizeof(Abc_Obj_t *) * pMan->nBins );
+ pMan->vNodes = Vec_PtrAlloc( 100 );
+ // save the current network
+ pMan->pAig = pNtkAig;
+ pMan->pConst1 = Abc_NtkCreateNode( pNtkAig );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deallocates the local AIG manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_AigFree( Abc_Aig_t * pMan )
+{
+ // free the table
+ Vec_PtrFree( pMan->vNodes );
+ free( pMan->pBins );
+ free( pMan );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read the constant 1 node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_AigConst1( Abc_Aig_t * pMan )
+{
+ return pMan->pConst1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs canonicization step.]
+
+ Description [The argument nodes can be complemented.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_AigAnd( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
+{
+ Abc_Obj_t * pAnd;
+ unsigned Key;
+ // check for trivial cases
+ if ( p0 == p1 )
+ return p0;
+ if ( p0 == Abc_ObjNot(p1) )
+ return Abc_ObjNot(pMan->pConst1);
+ if ( Abc_ObjRegular(p0) == pMan->pConst1 )
+ {
+ if ( p0 == pMan->pConst1 )
+ return p1;
+ return Abc_ObjNot(pMan->pConst1);
+ }
+ if ( Abc_ObjRegular(p1) == pMan->pConst1 )
+ {
+ if ( p1 == pMan->pConst1 )
+ return p0;
+ return Abc_ObjNot(pMan->pConst1);
+ }
+ // order the arguments
+ if ( Abc_ObjRegular(p0)->Id > Abc_ObjRegular(p1)->Id )
+ pAnd = p0, p0 = p1, p1 = pAnd;
+ // get the hash key for these two nodes
+ Key = Abc_HashKey2( p0, p1, pMan->nBins );
+ // find the mataching node in the table
+ Abc_AigBinForEachEntry( pMan->pBins[Key], pAnd )
+ if ( Abc_ObjFanin0(pAnd) == Abc_ObjRegular(p0) &&
+ Abc_ObjFanin1(pAnd) == Abc_ObjRegular(p1) &&
+ Abc_ObjFaninC0(pAnd) == Abc_ObjIsComplement(p0) &&
+ Abc_ObjFaninC1(pAnd) == Abc_ObjIsComplement(p1) )
+ return pAnd;
+ // check if it is a good time for table resizing
+ if ( pMan->nEntries > 2 * pMan->nBins )
+ {
+ Abc_AigResize( pMan );
+ Key = Abc_HashKey2( p0, p1, pMan->nBins );
+ }
+ // create the new node
+ pAnd = Abc_NtkCreateNode( pMan->pAig );
+ Abc_ObjAddFanin( pAnd, p0 );
+ Abc_ObjAddFanin( pAnd, p1 );
+ // set the level of the new node
+ pAnd->Level = 1 + ABC_MAX( Abc_ObjRegular(p0)->Level, Abc_ObjRegular(p1)->Level );
+ // add the node to the corresponding linked list in the table
+ pAnd->pNext = pMan->pBins[Key];
+ pMan->pBins[Key] = pAnd;
+ pMan->nEntries++;
+ return pAnd;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements Boolean AND.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_AigOr( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
+{
+ return Abc_ObjNot( Abc_AigAnd( pMan, Abc_ObjNot(p0), Abc_ObjNot(p1) ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements Boolean AND.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_AigXor( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
+{
+ return Abc_AigOr( pMan, Abc_AigAnd(pMan, p0, Abc_ObjNot(p1)),
+ Abc_AigAnd(pMan, p1, Abc_ObjNot(p0)) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs )
+{
+ Abc_Obj_t * pMiter, * pXor;
+ int i;
+ assert( vPairs->nSize % 2 == 0 );
+ // go through the cubes of the node's SOP
+ pMiter = Abc_ObjNot(pMan->pConst1);
+ for ( i = 0; i < vPairs->nSize; i += 2 )
+ {
+ pXor = Abc_AigXor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] );
+ pMiter = Abc_AigOr( pMan, pMiter, pXor );
+ }
+ return pMiter;
+}
+
+/**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.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_AigNodeIsUsedCompl( Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pFanout;
+ int i, iFanin;
+ Abc_ObjForEachFanout( pNode, pFanout, i )
+ {
+ iFanin = Vec_FanFindEntry( &pFanout->vFanins, pNode->Id );
+ assert( iFanin >= 0 );
+ if ( Abc_ObjFaninC( pFanout, iFanin ) )
+ return 1;
+ }
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_AigResize( Abc_Aig_t * pMan )
+{
+ Abc_Obj_t ** pBinsNew;
+ Abc_Obj_t * pEnt, * pEnt2;
+ int nBinsNew, Counter, i, clk;
+ unsigned Key;
+
+clk = clock();
+ // get the new table size
+ nBinsNew = Cudd_PrimeCopy(2 * pMan->nBins);
+ // allocate a new array
+ pBinsNew = ALLOC( Abc_Obj_t *, nBinsNew );
+ memset( pBinsNew, 0, sizeof(Abc_Obj_t *) * nBinsNew );
+ // rehash the entries from the old table
+ Counter = 0;
+ for ( i = 0; i < pMan->nBins; i++ )
+ Abc_AigBinForEachEntrySafe( pMan->pBins[i], pEnt, pEnt2 )
+ {
+ Key = Abc_HashKey2( Abc_ObjFanin(pEnt,0), Abc_ObjFanin(pEnt,1), nBinsNew );
+ pEnt->pNext = pBinsNew[Key];
+ pBinsNew[Key] = pEnt;
+ Counter++;
+ }
+ assert( Counter == pMan->nEntries );
+// printf( "Increasing the structural table size from %6d to %6d. ", pMan->nBins, nBinsNew );
+// PRT( "Time", clock() - clk );
+ // replace the table and the parameters
+ free( pMan->pBins );
+ pMan->pBins = pBinsNew;
+ pMan->nBins = nBinsNew;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcAttach.c b/src/base/abc/abcAttach.c
new file mode 100644
index 00000000..9d9c378f
--- /dev/null
+++ b/src/base/abc/abcAttach.c
@@ -0,0 +1,396 @@
+/**CFile****************************************************************
+
+ FileName [abcAttach.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Attaches the library gates to the current network.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcAttach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "main.h"
+#include "mio.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define ATTACH_FULL (~((unsigned)0))
+#define ATTACH_MASK(n) ((~((unsigned)0)) >> (32-(n)))
+
+static void Abc_AttachSetupTruthTables( unsigned uTruths[][2] );
+static void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthNode );
+static Mio_Gate_t * Abc_AttachFind( Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned * uTruthNode, int * Perm );
+static int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode );
+static int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] );
+static void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm );
+
+static char ** s_pPerms = NULL;
+static int s_nPerms;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Attaches gates from the current library to the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkAttach( Abc_Ntk_t * pNtk )
+{
+ int fCheck = 1;
+ Mio_Library_t * pGenlib;
+ unsigned ** puTruthGates;
+ unsigned uTruths[6][2];
+ Abc_Obj_t * pNode;
+ Mio_Gate_t ** ppGates;
+ int nGates, nFanins, i;
+
+ assert( Abc_NtkIsLogicSop(pNtk) );
+
+ // check that the library is available
+ pGenlib = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame());
+ if ( pGenlib == NULL )
+ {
+ printf( "The current library is not available.\n" );
+ return 0;
+ }
+
+ // start the truth tables
+ Abc_AttachSetupTruthTables( uTruths );
+
+ // collect all the gates
+ ppGates = Mio_CollectRoots( pGenlib, 6, (float)1.0e+20, 1, &nGates );
+
+ // derive the gate truth tables
+ puTruthGates = ALLOC( unsigned *, nGates );
+ puTruthGates[0] = ALLOC( unsigned, 2 * nGates );
+ for ( i = 1; i < nGates; i++ )
+ puTruthGates[i] = puTruthGates[i-1] + 2;
+ for ( i = 0; i < nGates; i++ )
+ Mio_DeriveTruthTable( ppGates[i], uTruths, Mio_GateReadInputs(ppGates[i]), 6, puTruthGates[i] );
+
+ // assign the gates to pNode->pCopy
+ Abc_NtkCleanCopy( pNtk );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ nFanins = Abc_ObjFaninNum(pNode);
+ if ( nFanins == 0 )
+ {
+ if ( Abc_SopIsConst1(pNode->pData) )
+ pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst1(pGenlib);
+ else
+ pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst0(pGenlib);
+ }
+ else if ( nFanins == 1 )
+ {
+ if ( Abc_SopIsBuf(pNode->pData) )
+ pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadBuf(pGenlib);
+ else
+ pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadInv(pGenlib);
+ }
+ else if ( nFanins > 6 )
+ {
+ printf( "Cannot attach gate with more than 6 inputs to node %s.\n", Abc_ObjName(pNode) );
+ free( puTruthGates[0] );
+ free( puTruthGates );
+ free( ppGates );
+ return 0;
+ }
+ else if ( !Abc_NodeAttach( pNode, ppGates, puTruthGates, nGates, uTruths ) )
+ {
+ printf( "Could not attach the library gate to node %s.\n", Abc_ObjName(pNode) );
+ free( puTruthGates[0] );
+ free( puTruthGates );
+ free( ppGates );
+ return 0;
+ }
+ }
+ free( puTruthGates[0] );
+ free( puTruthGates );
+ free( ppGates );
+ FREE( s_pPerms );
+
+ // perform the final transformation
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( pNode->pCopy == NULL )
+ {
+ printf( "Some elementary gates (constant, buffer, or inverter) are missing in the library.\n" );
+ return 0;
+ }
+ }
+
+ // replace SOP representation by the gate representation
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ pNode->pData = pNode->pCopy, pNode->pCopy = NULL;
+ pNtk->Type = ABC_NTK_LOGIC_MAP;
+ Extra_MmFlexStop( pNtk->pManFunc, 0 );
+ pNtk->pManFunc = NULL;
+
+ printf( "Library gates are successfully attached to the nodes.\n" );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkAttach: The network check has failed.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] )
+{
+ int Perm[10];
+ int pTempInts[10];
+ unsigned uTruthNode[2];
+ Abc_Obj_t * pFanin;
+ Mio_Gate_t * pGate;
+ int nFanins, i;
+
+ // compute the node's truth table
+ Abc_AttachComputeTruth( pNode->pData, uTruths, uTruthNode );
+ // find the matching gate and permutation
+ pGate = Abc_AttachFind( ppGates, puTruthGates, nGates, uTruthNode, Perm );
+ if ( pGate == NULL )
+ return 0;
+ // permute the fanins
+ nFanins = Abc_ObjFaninNum(pNode);
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ pTempInts[i] = pFanin->Id;
+ for ( i = 0; i < nFanins; i++ )
+ pNode->vFanins.pArray[Perm[i]].iFan = pTempInts[i];
+ // set the gate
+ pNode->pCopy = (Abc_Obj_t *)pGate;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets up the truth tables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_AttachSetupTruthTables( unsigned uTruths[][2] )
+{
+ int m, v;
+ for ( v = 0; v < 5; v++ )
+ uTruths[v][0] = 0;
+ // set up the truth tables
+ for ( m = 0; m < 32; m++ )
+ for ( v = 0; v < 5; v++ )
+ if ( m & (1 << v) )
+ uTruths[v][0] |= (1 << m);
+ // make adjustments for the case of 6 variables
+ for ( v = 0; v < 5; v++ )
+ uTruths[v][1] = uTruths[v][0];
+ uTruths[5][0] = 0;
+ uTruths[5][1] = ATTACH_FULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute the truth table of the node's cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthRes )
+{
+// Mvc_Cube_t * pCube;
+ unsigned uSignCube[2];
+ int Value;
+// int nInputs = pCover->nBits/2;
+ int nInputs = 6;
+ int nFanins = Abc_SopGetVarNum(pSop);
+ char * pCube;
+ int k;
+
+ // make sure that the number of input truth tables in equal to the number of gate inputs
+ assert( nInputs < 7 );
+
+ // clean the resulting truth table
+ uTruthRes[0] = 0;
+ uTruthRes[1] = 0;
+ if ( nInputs < 6 )
+ {
+ // consider the case when only one unsigned can be used
+// Mvc_CoverForEachCube( pCover, pCube )
+ Abc_SopForEachCube( pSop, nFanins, pCube )
+ {
+ uSignCube[0] = ATTACH_FULL;
+// Mvc_CubeForEachVarValue( pCover, pCube, Var, Value )
+ Abc_CubeForEachVar( pCube, Value, k )
+ {
+ if ( Value == '0' )
+ uSignCube[0] &= ~uTruthsIn[k][0];
+ else if ( Value == '1' )
+ uSignCube[0] &= uTruthsIn[k][0];
+ }
+ uTruthRes[0] |= uSignCube[0];
+ }
+ if ( nInputs < 5 )
+ uTruthRes[0] &= ATTACH_MASK(1<<nInputs);
+ }
+ else
+ {
+ // consider the case when two unsigneds should be used
+// Mvc_CoverForEachCube( pCover, pCube )
+ Abc_SopForEachCube( pSop, nFanins, pCube )
+ {
+ uSignCube[0] = ATTACH_FULL;
+ uSignCube[1] = ATTACH_FULL;
+// Mvc_CubeForEachVarValue( pCover, pCube, Var, Value )
+ Abc_CubeForEachVar( pCube, Value, k )
+ {
+ if ( Value == '0' )
+ {
+ uSignCube[0] &= ~uTruthsIn[k][0];
+ uSignCube[1] &= ~uTruthsIn[k][1];
+ }
+ else if ( Value == '1' )
+ {
+ uSignCube[0] &= uTruthsIn[k][0];
+ uSignCube[1] &= uTruthsIn[k][1];
+ }
+ }
+ uTruthRes[0] |= uSignCube[0];
+ uTruthRes[1] |= uSignCube[1];
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find the gate by truth table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Mio_Gate_t * Abc_AttachFind( Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned * uTruthNode, int * Perm )
+{
+ unsigned uTruthPerm[2];
+ int i, v, iNum;
+
+ // try the gates without permutation
+ if ( (iNum = Abc_AttachCompare( puTruthGates, nGates, uTruthNode )) >= 0 )
+ {
+ for ( v = 0; v < 6; v++ )
+ Perm[v] = v;
+ return ppGates[iNum];
+ }
+ // get permutations
+ if ( s_pPerms == NULL )
+ {
+ s_pPerms = Extra_Permutations( 6 );
+ s_nPerms = Extra_Factorial( 6 );
+ }
+ // try permutations
+ for ( i = 0; i < s_nPerms; i++ )
+ {
+ Abc_TruthPermute( s_pPerms[i], 6, uTruthNode, uTruthPerm );
+ if ( (iNum = Abc_AttachCompare( puTruthGates, nGates, uTruthPerm )) >= 0 )
+ {
+ for ( v = 0; v < 6; v++ )
+ Perm[v] = (int)s_pPerms[i][v];
+ return ppGates[iNum];
+ }
+ }
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find the gate by truth table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode )
+{
+ int i;
+ for ( i = 0; i < nGates; i++ )
+ if ( puTruthGates[i][0] == uTruthNode[0] && puTruthGates[i][1] == uTruthNode[1] )
+ return i;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Permutes the 6-input truth table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm )
+{
+ int nMints, iMintPerm, iMint, v;
+ uTruthPerm[0] = uTruthPerm[1] = 0;
+ nMints = (1 << nVars);
+ for ( iMint = 0; iMint < nMints; iMint++ )
+ {
+ if ( (uTruthNode[iMint/32] & (1 << (iMint%32))) == 0 )
+ continue;
+ iMintPerm = 0;
+ for ( v = 0; v < nVars; v++ )
+ if ( iMint & (1 << v) )
+ iMintPerm |= (1 << pPerm[v]);
+ uTruthPerm[iMintPerm/32] |= (1 << (iMintPerm%32));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c
new file mode 100644
index 00000000..67cfe9df
--- /dev/null
+++ b/src/base/abc/abcCheck.c
@@ -0,0 +1,848 @@
+/**CFile****************************************************************
+
+ FileName [abcCheck.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Consistency checking procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcCheck.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk );
+static bool Abc_NtkCheckPis( Abc_Ntk_t * pNtk );
+static bool Abc_NtkCheckPos( Abc_Ntk_t * pNtk );
+static bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj );
+static bool Abc_NtkCheckNet( Abc_Ntk_t * pNtk, Abc_Obj_t * pNet );
+static bool Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode );
+static bool Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch );
+
+static bool Abc_NtkComparePis( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
+static bool Abc_NtkComparePos( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
+static bool Abc_NtkCompareLatches( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Checks the integrity of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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) )
+ {
+ fprintf( stdout, "NetworkCheck: Unknown network type.\n" );
+ return 0;
+ }
+
+ // check the names
+ if ( !Abc_NtkCheckNames( pNtk ) )
+ return 0;
+
+ // check PIs and POs
+ Abc_NtkCleanCopy( pNtk );
+ if ( !Abc_NtkCheckPis( pNtk ) )
+ return 0;
+ if ( !Abc_NtkCheckPos( pNtk ) )
+ return 0;
+
+ // check the connectivity of objects
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ if ( !Abc_NtkCheckObj( pNtk, pObj ) )
+ return 0;
+
+ // if it is a netlist change nets and latches
+ if ( Abc_NtkIsNetlist(pNtk) )
+ {
+ // check the nets
+ Abc_NtkForEachNet( pNtk, pNet, i )
+ if ( !Abc_NtkCheckNet( pNtk, pNet ) )
+ return 0;
+ }
+
+ // check the nodes
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ if ( !Abc_NtkCheckNode( pNtk, pNode ) )
+ return 0;
+ // check the latches
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ if ( !Abc_NtkCheckLatch( pNtk, pNode ) )
+ return 0;
+
+ // finally, check for combinational loops
+// clk = clock();
+ if ( !Abc_NtkIsAcyclic( pNtk ) )
+ {
+ fprintf( stdout, "NetworkCheck: Network contains a combinational loop.\n" );
+ return 0;
+ }
+// PRT( "Acyclic ", clock() - clk );
+
+ // check the EXDC network if present
+ if ( pNtk->pExdc )
+ {
+ if ( pNtk->Type != pNtk->pExdc->Type )
+ {
+ fprintf( stdout, "NetworkCheck: Network and its EXDC have different types.\n" );
+ return 0;
+ }
+ return Abc_NtkCheck( pNtk->pExdc );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks the names.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkCheckNames( Abc_Ntk_t * pNtk )
+{
+ stmm_generator * gen;
+ Abc_Obj_t * pNet, * pNet2;
+ char * pName;
+ int i;
+
+ if ( Abc_NtkIsNetlist(pNtk) )
+ {
+ // check that the nets in the table are also in the network
+ stmm_foreach_item( pNtk->tName2Net, gen, &pName, (char**)&pNet )
+ {
+ if ( pNet->pData != pName )
+ {
+ fprintf( stdout, "NetworkCheck: Net \"%s\" has different name compared to the one in the name table.\n", pNet->pData );
+ return 0;
+ }
+ }
+ // check that the nets with names are also in the table
+ Abc_NtkForEachNet( pNtk, pNet, i )
+ {
+ if ( pNet->pData && !stmm_lookup( pNtk->tName2Net, pNet->pData, (char**)&pNet2 ) )
+ {
+ fprintf( stdout, "NetworkCheck: Net \"%s\" is in the network but not in the name table.\n", pNet->pData );
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ if ( pNtk->vPis->nSize != pNtk->nPis + pNtk->nLatches )
+ {
+ fprintf( stdout, "NetworkCheck: Incorrect size of the PI array.\n" );
+ return 0;
+ }
+ if ( pNtk->vPos->nSize != pNtk->nPos + pNtk->nLatches )
+ {
+ fprintf( stdout, "NetworkCheck: Incorrect size of the PO array.\n" );
+ return 0;
+ }
+ if ( pNtk->vLatches->nSize != pNtk->nLatches )
+ {
+ fprintf( stdout, "NetworkCheck: Incorrect size of the latch array.\n" );
+ return 0;
+ }
+
+ if ( pNtk->vNamesPi->nSize != pNtk->vPis->nSize )
+ {
+ fprintf( stdout, "NetworkCheck: Incorrect size of the PI names array.\n" );
+ return 0;
+ }
+ if ( pNtk->vNamesPo->nSize != pNtk->vPos->nSize )
+ {
+ fprintf( stdout, "NetworkCheck: Incorrect size of the PO names array.\n" );
+ return 0;
+ }
+ if ( pNtk->vNamesLatch->nSize != pNtk->vLatches->nSize )
+ {
+ fprintf( stdout, "NetworkCheck: Incorrect size of the latch names array.\n" );
+ 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;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Checks the PIs of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkCheckPis( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int i;
+
+ // check that PIs are indeed PIs
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ {
+ if ( Abc_NtkIsNetlist(pNtk) )
+ {
+ if ( !Abc_ObjIsNet(pObj) )
+ {
+ fprintf( stdout, "NetworkCheck: A PI \"%s\" is not a net.\n", Abc_ObjName(pObj) );
+ return 0;
+ }
+ }
+ else
+ {
+ 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;
+ }
+ }
+ if ( !Abc_ObjIsPi(pObj) )
+ {
+ 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;
+ }
+ pObj->pCopy = (Abc_Obj_t *)1;
+ }
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ if ( pObj->pCopy == NULL && Abc_ObjIsPi(pObj) )
+ {
+ fprintf( stdout, "NetworkCheck: Object \"%s\" (id=%d) is a PI but is not in the PI list.\n", Abc_ObjName(pObj), pObj->Id );
+ return 0;
+ }
+ pObj->pCopy = NULL;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks the POs of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkCheckPos( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int i;
+
+ // check that POs are indeed POs
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ if ( Abc_NtkIsNetlist(pNtk) )
+ {
+ if ( !Abc_ObjIsNet(pObj) )
+ {
+ fprintf( stdout, "NetworkCheck: A PO \"%s\" is not a net.\n", Abc_ObjName(pObj) );
+ return 0;
+ }
+ }
+ else
+ {
+ 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;
+ }
+ }
+ if ( !Abc_ObjIsPo(pObj) )
+ {
+ 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;
+ }
+ pObj->pCopy = (Abc_Obj_t *)1;
+ }
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ if ( pObj->pCopy == NULL && Abc_ObjIsPo(pObj) )
+ {
+ fprintf( stdout, "NetworkCheck: Net \"%s\" (id=%d) is in a PO but is not in the PO list.\n", Abc_ObjName(pObj), pObj->Id );
+ return 0;
+ }
+ pObj->pCopy = NULL;
+ }
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Checks the connectivity of the object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanin, * pFanout;
+ int i, Value = 1;
+
+ // check the network
+ if ( pObj->pNtk != pNtk )
+ {
+ 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 )
+ {
+ if ( Vec_FanFindEntry( &pFanin->vFanouts, pObj->Id ) == -1 )
+ {
+ fprintf( stdout, "NodeCheck: Object \"%s\" has fanin ", Abc_ObjName(pObj) );
+ fprintf( stdout, "\"%s\" but the fanin does not have it as a fanout.\n", Abc_ObjName(pFanin) );
+ Value = 0;
+ }
+ }
+ // go through the fanouts of the object and make sure fanouts have this object as a fanin
+ Abc_ObjForEachFanout( pObj, pFanout, i )
+ {
+ if ( Vec_FanFindEntry( &pFanout->vFanins, pObj->Id ) == -1 )
+ {
+ fprintf( stdout, "NodeCheck: Object \"%s\" has fanout ", Abc_ObjName(pObj) );
+ fprintf( stdout, "\"%s\" but the fanout does not have it as a fanin.\n", Abc_ObjName(pFanout) );
+ Value = 0;
+ }
+ }
+ return Value;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks the integrity of a net.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkCheckNet( Abc_Ntk_t * pNtk, Abc_Obj_t * pNet )
+{
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks the integrity of a node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode )
+{
+ // 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_SopCheck( pNode->pData, Abc_ObjFaninNum(pNode) ) )
+ {
+ fprintf( stdout, "NodeCheck: SOP check for node \"%s\" has failed.\n", Abc_ObjName(pNode) );
+ return 0;
+ }
+ }
+ else if ( Abc_NtkIsLogicBdd(pNtk) )
+ {
+ int nSuppSize = Cudd_SupportSize(pNtk->pManFunc, pNode->pData);
+ if ( nSuppSize > Abc_ObjFaninNum(pNode) )
+ {
+ fprintf( stdout, "NodeCheck: BDD of the node \"%s\" has incorrect support size.\n", Abc_ObjName(pNode) );
+ return 0;
+ }
+ }
+ else if ( !Abc_NtkIsAig(pNtk) && !Abc_NtkIsLogicMap(pNtk) )
+ {
+ assert( 0 );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks the integrity of a latch.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch )
+{
+ Abc_Obj_t * pObj;
+ int Value = 1;
+ // check whether the object is a latch
+ if ( !Abc_ObjIsLatch(pLatch) )
+ {
+ fprintf( stdout, "NodeCheck: Latch \"%s\" is in a latch list but has not latch label.\n", Abc_ObjName(pLatch) );
+ Value = 0;
+ }
+ // make sure the latch has a reasonable return value
+ if ( (int)pLatch->pData < 0 || (int)pLatch->pData > 2 )
+ {
+ fprintf( stdout, "NodeCheck: Latch \"%s\" has incorrect reset value (%d).\n",
+ Abc_ObjName(pLatch), (int)pLatch->pData );
+ Value = 0;
+ }
+ // make sure the latch has only one fanin
+ if ( Abc_ObjFaninNum(pLatch) != 1 )
+ {
+ 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;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Compares the PIs of the two networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkComparePis( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
+{
+ Abc_Obj_t * pNode1;
+ 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
+ Abc_NtkForEachPi( pNtk1, pNode1, i )
+ {
+ if ( strcmp( Abc_NtkNamePi(pNtk1,i), Abc_NtkNamePi(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) );
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares the POs of the two networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkComparePos( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
+{
+ Abc_Obj_t * pNode1;
+ int i;
+ if ( Abc_NtkPoNum(pNtk1) != Abc_NtkPoNum(pNtk2) )
+ {
+ printf( "Networks have different number of primary outputs.\n" );
+ return 0;
+ }
+ // for each PI of pNet1 find corresponding PI of pNet2 and reorder them
+ Abc_NtkForEachPo( pNtk1, pNode1, i )
+ {
+ if ( strcmp( Abc_NtkNamePo(pNtk1,i), Abc_NtkNamePo(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) );
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares the latches of the two networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkCompareLatches( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
+{
+ Abc_Obj_t * pNode1;
+ 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 PI of pNet1 find corresponding PI of pNet2 and reorder them
+ Abc_NtkForEachLatch( pNtk1, pNode1, i )
+ {
+ if ( strcmp( Abc_NtkNameLatch(pNtk1,i), Abc_NtkNameLatch(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 );
+ 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;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compares the signals of the networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
+{
+ if ( !Abc_NtkCompareLatches( pNtk1, pNtk2, fComb ) )
+ return 0;
+ if ( !Abc_NtkComparePis( pNtk1, pNtk2, fComb ) )
+ return 0;
+// if ( !Abc_NtkComparePos( pNtk1, pNtk2, fComb ) )
+// return 0;
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcCollapse.c b/src/base/abc/abcCollapse.c
new file mode 100644
index 00000000..372b1553
--- /dev/null
+++ b/src/base/abc/abcCollapse.c
@@ -0,0 +1,271 @@
+/**CFile****************************************************************
+
+ FileName [abcCollapse.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Collapsing the network into two-levels.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcCollapse.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk );
+static DdNode * Abc_NtkGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode );
+static Abc_Ntk_t * Abc_NtkFromGlobalBdds( DdManager * dd, Abc_Ntk_t * pNtk );
+static Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Collapses the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+ DdManager * dd;
+
+ assert( Abc_NtkIsAig(pNtk) );
+
+ // perform FPGA mapping
+ dd = Abc_NtkGlobalBdds( pNtk );
+ if ( dd == NULL )
+ return NULL;
+ if ( fVerbose )
+ printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
+/*
+ {
+ Abc_Obj_t * pNode;
+ int i;
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ {
+ Cudd_RecursiveDeref( dd, (DdNode *)pNode->pNext );
+ pNode->pNext = NULL;
+ }
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ {
+ Cudd_RecursiveDeref( dd, (DdNode *)pNode->pNext );
+ pNode->pNext = NULL;
+ }
+ }
+ Extra_StopManager( dd );
+ return NULL;
+*/
+
+ // transform the result of mapping into a BDD network
+ pNtkNew = Abc_NtkFromGlobalBdds( dd, pNtk );
+ if ( pNtkNew == NULL )
+ {
+ Cudd_Quit( dd );
+ return NULL;
+ }
+ Extra_StopManager( dd );
+
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtkNew );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkCollapse: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives global BDDs for the node function.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Obj_t * pNode;
+ DdNode * bFunc;
+ DdManager * dd;
+ int i;
+
+ // start the manager
+ dd = Cudd_Init( Abc_NtkCiNum(pNtk), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
+ Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
+
+ // set the elementary variables
+ Abc_NtkCleanCopy( pNtk );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ pNode->pCopy = (Abc_Obj_t *)dd->vars[i];
+ // assign the constant node BDD
+ pNode = Abc_AigConst1( pNtk->pManFunc );
+ pNode->pCopy = (Abc_Obj_t *)dd->one; Cudd_Ref( dd->one );
+
+ // construct the BDDs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ bFunc = Abc_NtkGlobalBdds_rec( dd, Abc_ObjFanin0(pNode) );
+ if ( bFunc == NULL )
+ {
+ printf( "Constructing global BDDs timed out.\n" );
+ Extra_ProgressBarStop( pProgress );
+ Cudd_Quit( dd );
+ return NULL;
+ }
+ bFunc = Cudd_NotCond( bFunc, Abc_ObjFaninC0(pNode) );
+ pNode->pNext = (Abc_Obj_t *)bFunc; Cudd_Ref( bFunc );
+ }
+ Extra_ProgressBarStop( pProgress );
+
+ // derefence the intermediate BDDs
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ if ( pNode->pCopy )
+ Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy );
+ Abc_NtkCleanCopy( pNtk );
+ // reorder one more time
+ Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 0 );
+ return dd;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the global BDD of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NtkGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode )
+{
+ DdNode * bFunc, * bFunc0, * bFunc1;
+ assert( !Abc_ObjIsComplement(pNode) );
+ if ( Cudd_ReadKeys(dd) > 500000 )
+ return NULL;
+ // if the result is available return
+ if ( pNode->pCopy )
+ return (DdNode *)pNode->pCopy;
+ // compute the result for both branches
+ bFunc0 = Abc_NtkGlobalBdds_rec( dd, Abc_ObjFanin(pNode,0) );
+ if ( bFunc0 == NULL )
+ return NULL;
+ Cudd_Ref( bFunc0 );
+ bFunc1 = Abc_NtkGlobalBdds_rec( dd, Abc_ObjFanin(pNode,1) );
+ if ( bFunc1 == NULL )
+ return NULL;
+ Cudd_Ref( bFunc1 );
+ bFunc0 = Cudd_NotCond( bFunc0, Abc_ObjFaninC0(pNode) );
+ bFunc1 = Cudd_NotCond( bFunc1, Abc_ObjFaninC1(pNode) );
+ // get the final result
+ bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc );
+ Cudd_RecursiveDeref( dd, bFunc0 );
+ Cudd_RecursiveDeref( dd, bFunc1 );
+ // set the result
+ assert( pNode->pCopy == NULL );
+ pNode->pCopy = (Abc_Obj_t *)bFunc;
+ return bFunc;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the network with the given global BDD.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromGlobalBdds( DdManager * dd, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pNode, * pNodeNew;
+ int i;
+ // start the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC_BDD );
+ // make sure the new manager has the same number of inputs
+ Cudd_bddIthVar( pNtkNew->pManFunc, dd->size-1 );
+ // process the POs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, (DdNode *)pNode->pNext );
+ Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
+ // deref the BDD of the PO
+ Cudd_RecursiveDeref( dd, (DdNode *)pNode->pNext );
+ pNode->pNext = NULL;
+ }
+ Extra_ProgressBarStop( pProgress );
+ // transfer the names
+ Abc_NtkDupNameArrays( pNtk, pNtkNew );
+ Abc_ManTimeDup( pNtk, pNtkNew );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the network with the given global BDD.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc )
+{
+ Abc_Obj_t * pNodeNew, * pTemp;
+ int i;
+ // create a new node
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ // add the fanins in the order, in which they appear in the reordered manager
+ Abc_NtkForEachCi( pNtkNew, pTemp, i )
+ Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtkNew, dd->invperm[i]) );
+ // transfer the function
+ pNodeNew->pData = Extra_TransferLevelByLevel( dd, pNtkNew->pManFunc, bFunc ); Cudd_Ref( pNodeNew->pData );
+ return pNodeNew;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcCreate.c b/src/base/abc/abcCreate.c
new file mode 100644
index 00000000..e4cfb7e3
--- /dev/null
+++ b/src/base/abc/abcCreate.c
@@ -0,0 +1,1121 @@
+/**CFile****************************************************************
+
+ FileName [abcCreate.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Creation/duplication/deletion procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcCreate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "main.h"
+#include "mio.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define ABC_NUM_STEPS 10
+
+static Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type );
+static void Abc_ObjRecycle( Abc_Obj_t * pObj );
+static void Abc_ObjAdd( Abc_Obj_t * pObj );
+
+extern void Extra_StopManager( DdManager * dd );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates a new Ntk.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type )
+{
+ Abc_Ntk_t * pNtk;
+ pNtk = ALLOC( Abc_Ntk_t, 1 );
+ memset( pNtk, 0, sizeof(Abc_Ntk_t) );
+ 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->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);
+ // start the memory managers
+ pNtk->pMmNames = Extra_MmFlexStart();
+ pNtk->pMmObj = Extra_MmFixedStart( sizeof(Abc_Obj_t) );
+ pNtk->pMmStep = Extra_MmStepStart( ABC_NUM_STEPS );
+ // get ready to assign the first Obj ID
+ pNtk->nTravIds = 1;
+ // start the functionality manager
+ if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(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) )
+ assert( 0 );
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts a new network using existing network as a model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj, * pObjNew;
+ 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
+ pNtkNew->pName = util_strsav(pNtk->pName);
+ pNtkNew->pSpec = util_strsav(pNtk->pSpec);
+ // clone the PIs/POs/latches
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_NtkDupObj(pNtkNew, pObj);
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ Abc_NtkDupObj(pNtkNew, pObj);
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ pObjNew = Abc_NtkDupObj(pNtkNew, pObj);
+ Vec_PtrPush( pNtkNew->vPis, pObjNew );
+ Vec_PtrPush( pNtkNew->vPos, pObjNew );
+ }
+ // clean the node copy fields
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ pObj->pCopy = NULL;
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finalizes the network using the existing network as a model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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);
+ 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 [Finalizes the network using the existing network as a model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFinalizeRegular( 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);
+ pDriverNew = pDriver->pCopy;
+ Abc_ObjAddFanin( pObj->pCopy, pDriverNew );
+ }
+ // transfer the names
+ Abc_NtkDupNameArrays( pNtk, pNtkNew );
+ Abc_ManTimeDup( pNtk, pNtkNew );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicate the Ntk.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj, * pFanin;
+ int i, k;
+ if ( pNtk == NULL )
+ return NULL;
+ // 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
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ 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
+ {
+ // 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 );
+ }
+ }
+ // 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 );
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the Ntk.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkDelete( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int TotalMemory, i;
+ int LargePiece = (4 << ABC_NUM_STEPS);
+ if ( pNtk == NULL )
+ return;
+ // make sure all the marks are clean
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ // free large fanout arrays
+ if ( pObj->vFanouts.nCap * 4 > LargePiece )
+ FREE( pObj->vFanouts.pArray );
+ // check that the other things are okay
+ assert( pObj->fMarkA == 0 );
+ assert( pObj->fMarkB == 0 );
+ assert( pObj->fMarkC == 0 );
+ }
+
+ // dereference the BDDs
+ if ( Abc_NtkIsLogicBdd(pNtk) )
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ Cudd_RecursiveDeref( pNtk->pManFunc, pObj->pData );
+
+ FREE( pNtk->pName );
+ FREE( pNtk->pSpec );
+ // copy the EXDC Ntk
+ if ( pNtk->pExdc )
+ 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->vPtrTemp );
+ Vec_IntFree( pNtk->vIntTemp );
+ Vec_StrFree( pNtk->vStrTemp );
+ // free the hash table of Obj name into Obj ID
+ stmm_free_table( pNtk->tName2Net );
+ TotalMemory = 0;
+ TotalMemory += Extra_MmFlexReadMemUsage(pNtk->pMmNames);
+ TotalMemory += Extra_MmFixedReadMemUsage(pNtk->pMmObj);
+ TotalMemory += Extra_MmStepReadMemUsage(pNtk->pMmStep);
+// fprintf( stdout, "The total memory allocated internally by the network = %0.2f Mb.\n", ((double)TotalMemory)/(1<<20) );
+ // free the storage
+ Extra_MmFlexStop ( pNtk->pMmNames, 0 );
+ Extra_MmFixedStop( pNtk->pMmObj, 0 );
+ Extra_MmStepStop ( pNtk->pMmStep, 0 );
+ // free the timing manager
+ if ( pNtk->pManTime )
+ Abc_ManTimeStop( pNtk->pManTime );
+ // start the functionality manager
+ if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(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) )
+ assert( 0 );
+ free( pNtk );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates a new Obj.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
+{
+ Abc_Obj_t * pObj;
+ pObj = (Abc_Obj_t *)Extra_MmFixedEntryFetch( pNtk->pMmObj );
+ memset( pObj, 0, sizeof(Abc_Obj_t) );
+ pObj->Id = -1;
+ pObj->pNtk = pNtk;
+ pObj->Type = Type;
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recycles the Obj.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ObjRecycle( Abc_Obj_t * pObj )
+{
+ Extra_MmFixedEntryRecycle( pObj->pNtk->pMmObj, (char *)pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the node to the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ObjAdd( Abc_Obj_t * pObj )
+{
+ Abc_Ntk_t * pNtk = pObj->pNtk;
+ assert( !Abc_ObjIsComplement(pObj) );
+ // add to the array of objects
+ pObj->Id = pNtk->vObjs->nSize;
+ Vec_PtrPush( pNtk->vObjs, pObj );
+ pNtk->nObjs++;
+ // perform specialized operations depending on the object type
+ if ( Abc_ObjIsNet(pObj) )
+ {
+ // add the name to the table
+ if ( pObj->pData && stmm_insert( pNtk->tName2Net, pObj->pData, (char *)pObj ) )
+ {
+ printf( "Error: The net is already in the table...\n" );
+ assert( 0 );
+ }
+ pNtk->nNets++;
+ }
+ else if ( Abc_ObjIsNode(pObj) )
+ {
+ assert( pObj->Subtype == 0 );
+ pNtk->nNodes++;
+ }
+ else if ( Abc_ObjIsLatch(pObj) )
+ {
+ Vec_PtrPush( pNtk->vLatches, pObj );
+ pNtk->nLatches++;
+ }
+ else if ( Abc_ObjIsTerm(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 );
+ }
+ else
+ {
+ assert( 0 );
+ }
+ assert( pObj->Id >= 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicate the Obj.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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) )
+ 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) )
+ pObjNew->pData = pObj->pData;
+ else if ( !Abc_NtkIsAig(pNtkNew) )
+ assert( 0 );
+ }
+ else if ( Abc_ObjIsNet(pObj) ) // copy the name
+ pObjNew->pData = Abc_NtkRegisterName( pNtkNew, pObj->pData );
+ else if ( Abc_ObjIsLatch(pObj) ) // copy the reset value
+ pObjNew->pData = pObj->pData;
+ pObj->pCopy = pObjNew;
+ // add the object to the network
+ Abc_ObjAdd( pObjNew );
+ return pObjNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deletes the object from the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
+{
+ Vec_Ptr_t * vNodes = pObj->pNtk->vPtrTemp;
+ Abc_Ntk_t * pNtk = pObj->pNtk;
+ int i;
+
+ assert( !Abc_ObjIsComplement(pObj) );
+
+ // delete fanins and fanouts
+ Abc_NodeCollectFanouts( pObj, vNodes );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ Abc_ObjDeleteFanin( vNodes->pArray[i], pObj );
+ Abc_NodeCollectFanins( pObj, vNodes );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ Abc_ObjDeleteFanin( pObj, vNodes->pArray[i] );
+
+ // remove from the list of objects
+ Vec_PtrWriteEntry( pNtk->vObjs, pObj->Id, NULL );
+ pNtk->nObjs--;
+
+ // perform specialized operations depending on the object type
+ if ( Abc_ObjIsNet(pObj) )
+ {
+ // remove the net from the hash table of nets
+ if ( pObj->pData && !stmm_delete( pNtk->tName2Net, (char **)&pObj->pData, (char **)&pObj ) )
+ {
+ printf( "Error: The net is not in the table...\n" );
+ assert( 0 );
+ }
+ pNtk->nNets--;
+ assert( !Abc_ObjIsPi(pObj) && !Abc_ObjIsPo(pObj) );
+ }
+ else if ( Abc_ObjIsNode(pObj) )
+ {
+ pNtk->nNodes--;
+ }
+ else if ( Abc_ObjIsLatch(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
+ assert( 0 );
+ // recycle the net itself
+ Abc_ObjRecycle( 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*************************************************************
+
+ Synopsis [Returns the net with the given name.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName )
+{
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the net with the given name.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName )
+{
+ Abc_Obj_t * pNet;
+ assert( Abc_NtkIsNetlist(pNtk) );
+ if ( stmm_lookup( pNtk->tName2Net, pName, (char**)&pNet ) )
+ return pNet;
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds or creates the net.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName )
+{
+ Abc_Obj_t * pNet;
+ assert( Abc_NtkIsNetlist(pNtk) );
+ if ( pNet = Abc_NtkFindNet( pNtk, pName ) )
+ return pNet;
+ // create a new net
+ pNet = Abc_ObjAlloc( pNtk, ABC_OBJ_TYPE_NET );
+ pNet->pData = Abc_NtkRegisterName( pNtk, pName );
+ Abc_ObjAdd( pNet );
+ return pNet;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_TYPE_NODE );
+ Abc_ObjAdd( pObj );
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCreateTermPi( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_TYPE_TERM );
+ Abc_ObjSetSubtype( pObj, ABC_OBJ_SUBTYPE_PI );
+ Abc_ObjAdd( pObj );
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCreateTermPo( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_TYPE_TERM );
+ Abc_ObjSetSubtype( pObj, ABC_OBJ_SUBTYPE_PO );
+ Abc_ObjAdd( pObj );
+// Abc_NtkAddPo( pObj );
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_TYPE_LATCH );
+ Abc_ObjAdd( pObj );
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates inverter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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) )
+ 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) )
+ pNode->pData = Mio_LibraryReadConst0(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
+ else
+ assert( 0 );
+ return pNode;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates inverter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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) )
+ 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) )
+ pNode->pData = Mio_LibraryReadConst1(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
+ else
+ assert( 0 );
+ return pNode;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates inverter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeCreateInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
+{
+ Abc_Obj_t * pNode;
+ assert( Abc_NtkIsLogic(pNtk) );
+ pNode = Abc_NtkCreateNode( pNtk );
+ Abc_ObjAddFanin( pNode, pFanin );
+ if ( Abc_NtkIsLogicSop(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) )
+ pNode->pData = Mio_LibraryReadInv(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
+ else
+ assert( 0 );
+ return pNode;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates buffer.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeCreateBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
+{
+ Abc_Obj_t * pNode;
+ assert( Abc_NtkIsLogic(pNtk) );
+ pNode = Abc_NtkCreateNode( pNtk );
+ Abc_ObjAddFanin( pNode, pFanin );
+ if ( Abc_NtkIsLogicSop(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) )
+ pNode->pData = Mio_LibraryReadBuf(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
+ else
+ assert( 0 );
+ return pNode;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates inverter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeCreateAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ assert( Abc_NtkIsLogic(pNtk) );
+ pNode = Abc_NtkCreateNode( pNtk );
+ for ( i = 0; i < vFanins->nSize; i++ )
+ Abc_ObjAddFanin( pNode, vFanins->pArray[i] );
+ if ( Abc_NtkIsLogicSop(pNtk) )
+ {
+ char * pSop;
+ pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 );
+ for ( i = 0; i < vFanins->nSize; i++ )
+ pSop[i] = '1';
+ pSop[i++] = ' ';
+ pSop[i++] = '1';
+ pSop[i++] = '\n';
+ pSop[i++] = 0;
+ assert( i == vFanins->nSize + 4 );
+ pNode->pData = pSop;
+ }
+ else if ( Abc_NtkIsLogicBdd(pNtk) )
+ {
+ DdManager * dd = pNtk->pManFunc;
+ DdNode * bFunc, * bTemp;
+ bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc );
+ for ( i = 0; i < vFanins->nSize; i++ )
+ {
+ bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_bddIthVar(pNtk->pManFunc,i) ); Cudd_Ref( bFunc );
+ Cudd_RecursiveDeref( dd, bTemp );
+ }
+ pNode->pData = bFunc;
+ }
+ else
+ assert( 0 );
+ return pNode;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates inverter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeCreateOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ assert( Abc_NtkIsLogic(pNtk) );
+ pNode = Abc_NtkCreateNode( pNtk );
+ for ( i = 0; i < vFanins->nSize; i++ )
+ Abc_ObjAddFanin( pNode, vFanins->pArray[i] );
+ if ( Abc_NtkIsLogicSop(pNtk) )
+ {
+ char * pSop;
+ pSop = Extra_MmFlexEntryFetch( pNtk->pManFunc, vFanins->nSize + 4 );
+ for ( i = 0; i < vFanins->nSize; i++ )
+ pSop[i] = '0';
+ pSop[i++] = ' ';
+ pSop[i++] = '0';
+ pSop[i++] = '\n';
+ pSop[i++] = 0;
+ assert( i == vFanins->nSize + 4 );
+ pNode->pData = pSop;
+ }
+ else if ( Abc_NtkIsLogicBdd(pNtk) )
+ {
+ DdManager * dd = pNtk->pManFunc;
+ DdNode * bFunc, * bTemp;
+ bFunc = Cudd_ReadLogicZero(dd); Cudd_Ref( bFunc );
+ for ( i = 0; i < vFanins->nSize; i++ )
+ {
+ bFunc = Cudd_bddOr( dd, bTemp = bFunc, Cudd_bddIthVar(pNtk->pManFunc,i) ); Cudd_Ref( bFunc );
+ Cudd_RecursiveDeref( dd, bTemp );
+ }
+ pNode->pData = bFunc;
+ }
+ else
+ assert( 0 );
+ return pNode;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates inverter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeCreateMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 )
+{
+ Abc_Obj_t * pNode;
+ assert( Abc_NtkIsLogic(pNtk) );
+ pNode = Abc_NtkCreateNode( pNtk );
+ Abc_ObjAddFanin( pNode, pNodeC );
+ Abc_ObjAddFanin( pNode, pNode1 );
+ Abc_ObjAddFanin( pNode, pNode0 );
+ if ( Abc_NtkIsLogicSop(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 );
+ else
+ assert( 0 );
+ return pNode;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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) )
+ 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) )
+ return pNode->pData == Mio_LibraryReadConst0(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
+ assert( 0 );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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) )
+ 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) )
+ return pNode->pData == Mio_LibraryReadConst1(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
+ assert( 0 );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NodeIsBuf( Abc_Obj_t * pNode )
+{
+ Abc_Ntk_t * pNtk = pNode->pNtk;
+ assert(Abc_ObjIsNode(pNode));
+ if ( Abc_ObjFaninNum(pNode) != 1 )
+ return 0;
+ if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(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) )
+ return pNode->pData == Mio_LibraryReadBuf(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
+ assert( 0 );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NodeIsInv( Abc_Obj_t * pNode )
+{
+ Abc_Ntk_t * pNtk = pNode->pNtk;
+ assert(Abc_ObjIsNode(pNode));
+ if ( Abc_ObjFaninNum(pNode) != 1 )
+ return 0;
+ if ( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(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) )
+ return pNode->pData == Mio_LibraryReadInv(Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()));
+ assert( 0 );
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c
new file mode 100644
index 00000000..7b330b95
--- /dev/null
+++ b/src/base/abc/abcDfs.c
@@ -0,0 +1,446 @@
+/**CFile****************************************************************
+
+ FileName [abcDfs.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures that use depth-first search.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcDfs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// 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 );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Returns the DFS ordered array of logic nodes.]
+
+ Description [Collects only the internal nodes, leaving out PIs, POs and latches.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk )
+{
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNet, * pNode;
+ int i, fMadeComb;
+ // 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_NtkDfs_rec( Abc_ObjFanin0(pNode), vNodes );
+ }
+ return vNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs DFS for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
+{
+ Abc_Obj_t * pFanin;
+ int i;
+ assert( !Abc_ObjIsComplement( pNode ) );
+ // skip the PI
+ if ( Abc_ObjIsPi(pNode) || Abc_ObjIsLatch(pNode) )
+ return;
+ assert( Abc_ObjIsNode( pNode ) );
+
+ // if this node is already visited, skip
+ if ( Abc_NodeIsTravIdCurrent( pNode ) )
+ return;
+ // mark the node as visited
+ Abc_NodeSetTravIdCurrent( 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 );
+ }
+ // add the node after the fanins have been added
+ Vec_PtrPush( vNodes, pNode );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns the DFS ordered array of logic nodes.]
+
+ Description [Collects only the internal nodes, leaving out PIs, POs and latches.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk )
+{
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode;
+ int i;
+ assert( Abc_NtkIsAig(pNtk) );
+ // 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
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Abc_AigDfs_rec( Abc_ObjFanin0(pNode), vNodes );
+ return vNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs DFS for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
+{
+ Abc_Obj_t * pFanin;
+ int i;
+ assert( !Abc_ObjIsComplement( pNode ) );
+ // skip the PI
+ if ( Abc_ObjIsPi(pNode) || Abc_ObjIsLatch(pNode) )
+ return;
+ assert( Abc_ObjIsNode( pNode ) );
+ // if this node is already visited, skip
+ if ( Abc_NodeIsTravIdCurrent( pNode ) )
+ return;
+ // mark the node as visited
+ Abc_NodeSetTravIdCurrent( 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 ) )
+ for ( pFanin = pNode->pData; pFanin; pFanin = pFanin->pData )
+ Abc_AigDfs_rec( pFanin, vNodes );
+ // add the node after the fanins have been added
+ Vec_PtrPush( vNodes, pNode );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes the number of logic levels not counting PIs/POs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkGetLevelNum( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNet, * pNode, * pDriver;
+ unsigned LevelsMax;
+ int i, fMadeComb;
+
+ // set the traversal ID for this traversal
+ Abc_NtkIncrementTravId( pNtk );
+ // perform the traversal
+ LevelsMax = 0;
+ if ( Abc_NtkIsNetlist(pNtk) )
+ {
+ 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 )
+ {
+ pDriver = Abc_ObjFanin0( pNode );
+ Abc_NtkGetLevelNum_rec( pDriver );
+ if ( LevelsMax < pDriver->Level )
+ LevelsMax = pDriver->Level;
+ }
+ }
+ return LevelsMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively counts the number of logic levels of one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkGetLevelNum_rec( Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pFanin;
+ int i;
+ assert( !Abc_ObjIsComplement( pNode ) );
+ // skip the PI
+ if ( Abc_ObjIsPi(pNode) || Abc_ObjIsLatch(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_NtkGetLevelNum_rec( pFanin );
+ if ( pNode->Level < pFanin->Level )
+ pNode->Level = pFanin->Level;
+ }
+ }
+ pNode->Level++;
+ return pNode->Level;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Detects combinational loops.]
+
+ Description [This procedure is based on the idea suggested by Donald Chai.
+ As we traverse the network and visit the nodes, we need to distinquish
+ three types of nodes: (1) those that are visited for the first time,
+ (2) those that have been visited in this traversal but are currently not
+ on the traversal path, (3) those that have been visited and are currently
+ on the travesal path. When the node of type (3) is encountered, it means
+ that there is a combinational loop. To mark the three types of nodes,
+ two new values of the traversal IDs are used.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNet, * pNode;
+ int fAcyclic, fMadeComb, i;
+ // set the traversal ID for this DFS ordering
+ Abc_NtkIncrementTravId( pNtk );
+ Abc_NtkIncrementTravId( pNtk );
+ // pNode->TravId == pNet->nTravIds means "pNode is on the path"
+ // pNode->TravId == pNet->nTravIds - 1 means "pNode is visited but is not on the path"
+ // 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 )
+ {
+ 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;
+ }
+ }
+ }
+ return fAcyclic;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively detects combinational loops.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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 ) );
+ // skip the PI
+ if ( Abc_ObjIsPi(pNode) || Abc_ObjIsLatch(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
+ if ( Abc_NodeIsTravIdCurrent(pNode) )
+ {
+ fprintf( stdout, "Network \"%s\" contains combinational loop!\n", pNtk->pName );
+ fprintf( stdout, "Node \"%s\" is encountered twice on the following path:\n", Abc_ObjName(pNode) );
+ fprintf( stdout, " %s", Abc_ObjName(pNode) );
+ return 0;
+ }
+ // 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 )
+ {
+ // 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;
+ }
+ }
+ }
+ // mark this node as a visited node
+ Abc_NodeSetTravIdPrevious( pNode );
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcDsd.c b/src/base/abc/abcDsd.c
new file mode 100644
index 00000000..47b288d3
--- /dev/null
+++ b/src/base/abc/abcDsd.c
@@ -0,0 +1,48 @@
+/**CFile****************************************************************
+
+ FileName [abcDsd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Decomposes the network using disjoint-support decomposition.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Decomposes the network using disjoint-support decomposition.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcFanio.c b/src/base/abc/abcFanio.c
new file mode 100644
index 00000000..51fc73ce
--- /dev/null
+++ b/src/base/abc/abcFanio.c
@@ -0,0 +1,196 @@
+/**CFile****************************************************************
+
+ FileName [abcFanio.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Various procedures to connect fanins/fanouts.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFanio.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates fanout/fanin relationship between the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
+{
+ Abc_Obj_t * pFaninR = Abc_ObjRegular(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?
+ Vec_FanPush( pObj->pNtk->pMmStep, &pObj->vFanins, Vec_Int2Fan(pFaninR->Id) );
+ Vec_FanPush( pObj->pNtk->pMmStep, &pFaninR->vFanouts, Vec_Int2Fan(pObj->Id) );
+ if ( Abc_ObjIsComplement(pFanin) )
+ Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Destroys fanout/fanin relationship between the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ObjDeleteFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
+{
+ assert( !Abc_ObjIsComplement(pObj) );
+ 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?
+ 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 );
+ return;
+ }
+ if ( !Vec_FanDeleteEntry( &pFanin->vFanouts, pObj->Id ) )
+ {
+ printf( "The obj %d is not found among the fanouts of obj %d ...\n", pObj->Id, pFanin->Id );
+ return;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Replaces a fanin of the node.]
+
+ Description [The node is pObj. An old fanin of this node (pFaninOld) has to be
+ replaced by a new fanin (pFaninNew). Assumes that the node and the old fanin
+ are not complemented. The new fanin can be complemented. In this case, the
+ polarity of the new fanin will change, compared to the polarity of the old fanin.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFaninNew )
+{
+ Abc_Obj_t * pFaninNewR = Abc_ObjRegular(pFaninNew);
+ int iFanin, fCompl;
+ assert( !Abc_ObjIsComplement(pObj) );
+ assert( !Abc_ObjIsComplement(pFaninOld) );
+ assert( pFaninOld != pFaninNewR );
+ assert( pObj->pNtk == pFaninOld->pNtk );
+ assert( pObj->pNtk == pFaninNewR->pNtk );
+ if ( (iFanin = Vec_FanFindEntry( &pObj->vFanins, pFaninOld->Id )) == -1 )
+ {
+ printf( "Fanin node %d is not among the fanins of node %d...\n", pFaninOld->Id, pObj->Id );
+ return;
+ }
+ // remember the polarity of the old fanin
+ fCompl = Abc_ObjFaninC(pObj, iFanin);
+ // replace the old fanin entry by the new fanin entry (removes polarity)
+ Vec_FanWriteEntry( &pObj->vFanins, iFanin, Vec_Int2Fan(pFaninNewR->Id) );
+ // set the polarity of the new fanin
+ if ( fCompl ^ Abc_ObjIsComplement(pFaninNew) )
+ Abc_ObjSetFaninC( pObj, iFanin );
+ // update the fanout of the fanin
+ if ( !Vec_FanDeleteEntry( &pFaninOld->vFanouts, pObj->Id ) )
+ {
+ printf( "The node %d is not among the fanouts of its old fanin %d...\n", pObj->Id, pFaninOld->Id );
+ return;
+ }
+ Vec_FanPush( pObj->pNtk->pMmStep, &pFaninNewR->vFanouts, Vec_Int2Fan(pObj->Id) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfers fanout from the old node to the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * pNodeTo )
+{
+ Vec_Ptr_t * vFanouts = pNodeFrom->pNtk->vPtrTemp;
+ int nFanoutsOld, i;
+ assert( !Abc_ObjIsComplement(pNodeFrom) );
+ assert( !Abc_ObjIsComplement(pNodeTo) );
+ assert( Abc_ObjIsNode(pNodeFrom) );
+ assert( Abc_ObjIsNode(pNodeTo) );
+ assert( pNodeFrom->pNtk == pNodeTo->pNtk );
+ assert( pNodeFrom != pNodeTo );
+ assert( Abc_ObjFanoutNum(pNodeFrom) > 0 );
+ // get the fanouts of the old node
+ nFanoutsOld = Abc_ObjFanoutNum(pNodeTo);
+ Abc_NodeCollectFanouts( pNodeFrom, vFanouts );
+ // patch the fanin of each of them
+ for ( i = 0; i < vFanouts->nSize; i++ )
+ Abc_ObjPatchFanin( vFanouts->pArray[i], pNodeFrom, pNodeTo );
+ assert( Abc_ObjFanoutNum(pNodeFrom) == 0 );
+ assert( Abc_ObjFanoutNum(pNodeTo) == nFanoutsOld + vFanouts->nSize );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Replaces the node by a new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ObjReplace( Abc_Obj_t * pNodeOld, Abc_Obj_t * pNodeNew )
+{
+ assert( !Abc_ObjIsComplement(pNodeOld) );
+ assert( !Abc_ObjIsComplement(pNodeNew) );
+ assert( Abc_ObjIsNode(pNodeOld) );
+ assert( Abc_ObjIsNode(pNodeNew) );
+ assert( pNodeOld->pNtk == pNodeNew->pNtk );
+ assert( pNodeOld != pNodeNew );
+ assert( Abc_ObjFanoutNum(pNodeOld) > 0 );
+ assert( Abc_ObjFanoutNum(pNodeNew) == 0 );
+ // transfer the fanouts to the old node
+ Abc_ObjTransferFanout( pNodeOld, pNodeNew );
+ // remove the old node
+ Abc_NtkDeleteObj( pNodeOld );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcFpga.c b/src/base/abc/abcFpga.c
new file mode 100644
index 00000000..975fbc98
--- /dev/null
+++ b/src/base/abc/abcFpga.c
@@ -0,0 +1,247 @@
+/**CFile****************************************************************
+
+ FileName [abcFpga.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Interface with the FPGA mapping package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFpga.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fpgaInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose );
+static Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk );
+static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Interface with the FPGA mapping package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+ Fpga_Man_t * pMan;
+
+ assert( Abc_NtkIsAig(pNtk) );
+
+ // print a warning about choice nodes
+ if ( Abc_NtkCountChoiceNodes( pNtk ) )
+ printf( "Performing FPGA mapping with choices.\n" );
+
+ // perform FPGA mapping
+ pMan = Abc_NtkToFpga( pNtk, fRecovery, fVerbose );
+ if ( pMan == NULL )
+ return NULL;
+ if ( !Fpga_Mapping( pMan ) )
+ {
+ Fpga_ManFree( pMan );
+ return NULL;
+ }
+
+ // transform the result of mapping into a BDD network
+ pNtkNew = Abc_NtkFromFpga( pMan, pNtk );
+ if ( pNtkNew == NULL )
+ return NULL;
+ Fpga_ManFree( pMan );
+
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtkNew );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkFpga: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Load the network into FPGA manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, int fVerbose )
+{
+ Fpga_Man_t * pMan;
+ ProgressBar * pProgress;
+ Fpga_Node_t * pNodeFpga;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pFanin, * pPrev;
+ int i;
+
+ 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 );
+ if ( pMan == NULL )
+ return NULL;
+ Fpga_ManSetAreaRecovery( pMan, fRecovery );
+ Fpga_ManSetOutputNames( pMan, (char **)pNtk->vNamesPo->pArray );
+ Fpga_ManSetInputArrivals( pMan, Abc_NtkGetCiArrivalFloats(pNtk) );
+
+ // create PIs and remember them in the old nodes
+ Abc_NtkCleanCopy( pNtk );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ pNode->pCopy = (Abc_Obj_t *)Fpga_ManReadInputs(pMan)[i];
+
+ // load the AIG into the mapper
+ vNodes = Abc_AigDfs( pNtk );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // consider the case of a constant
+ pNode = vNodes->pArray[i];
+ if ( Abc_NodeIsConst(pNode) )
+ {
+ Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan);
+ continue;
+ }
+ // add the node to the mapper
+ pNodeFpga = Fpga_NodeAnd( pMan,
+ Fpga_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
+ Fpga_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
+ assert( pNode->pCopy == NULL );
+ // remember the node
+ pNode->pCopy = (Abc_Obj_t *)pNodeFpga;
+ // set up the choice node
+ if ( Abc_NodeIsChoice( 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 );
+ Fpga_NodeSetRepr( (Fpga_Node_t *)pFanin->pCopy, (Fpga_Node_t *)pNode->pCopy );
+ }
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+
+ // set the primary outputs without copying the phase
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Fpga_ManReadOutputs(pMan)[i] = (Fpga_Node_t *)Abc_ObjFanin0(pNode)->pCopy;
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the mapped network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pNode, * pNodeNew;
+ int i, nDupGates;
+ // create the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC_BDD );
+ // make the mapper point to the new network
+ Fpga_CutsCleanSign( pMan );
+ Fpga_ManCleanData0( pMan );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy );
+ // set the constant node
+ if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 )
+ Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NodeCreateConst1(pNtkNew) );
+ // process the nodes in topological order
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNodeNew = Abc_NodeFromFpga_rec( pNtkNew, Fpga_ManReadOutputs(pMan)[i] );
+ assert( !Abc_ObjIsComplement(pNodeNew) );
+ Abc_ObjFanin0(pNode)->pCopy = pNodeNew;
+ }
+ Extra_ProgressBarStop( pProgress );
+ // finalize the new network
+ Abc_NtkFinalize( pNtk, pNtkNew );
+ // decouple the PO driver nodes to reduce the number of levels
+ nDupGates = Abc_NtkLogicMakeSimplePos( pNtkNew );
+ if ( nDupGates && Fpga_ManReadVerbose(pMan) )
+ printf( "Duplicated %d gates to decouple the PO drivers.\n", nDupGates );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive one node after FPGA mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga )
+{
+ Fpga_Cut_t * pCutBest;
+ Fpga_Node_t ** ppLeaves;
+ Abc_Obj_t * pNodeNew;
+ int i, nLeaves;
+ assert( !Fpga_IsComplement(pNodeFpga) );
+ // return if the result if known
+ pNodeNew = (Abc_Obj_t *)Fpga_NodeReadData0( pNodeFpga );
+ if ( pNodeNew )
+ return pNodeNew;
+ assert( Fpga_NodeIsAnd(pNodeFpga) );
+ // get the parameters of the best cut
+ pCutBest = Fpga_NodeReadCutBest( pNodeFpga );
+ ppLeaves = Fpga_CutReadLeaves( pCutBest );
+ nLeaves = Fpga_CutReadLeavesNum( pCutBest );
+ // create a new node
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < nLeaves; i++ )
+ Abc_ObjAddFanin( pNodeNew, Abc_NodeFromFpga_rec(pNtkNew, ppLeaves[i]) );
+ // derive the function of this node
+ pNodeNew->pData = Fpga_TruthsCutBdd( pNtkNew->pManFunc, pCutBest ); Cudd_Ref( pNodeNew->pData );
+ Fpga_NodeSetData0( pNodeFpga, (char *)pNodeNew );
+ return pNodeNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcFraig.c b/src/base/abc/abcFraig.c
new file mode 100644
index 00000000..85dba6f3
--- /dev/null
+++ b/src/base/abc/abcFraig.c
@@ -0,0 +1,585 @@
+/**CFile****************************************************************
+
+ FileName [abcFraig.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures interfacing with the FRAIG package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFraig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fraig.h"
+#include "main.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes );
+static Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
+static Abc_Obj_t * Abc_NodeFromFraig_rec( Abc_Ntk_t * pNtkNew, Fraig_Node_t * pNodeFraig );
+
+static int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk );
+static void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
+static Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+ Fraig_Man_t * pMan;
+ // perform fraiging
+ pMan = Abc_NtkToFraig( pNtk, pParams, fAllNodes );
+ // prove the miter if asked to
+ if ( ((Fraig_Params_t *)pParams)->fTryProve )
+ Fraig_ManProveMiter( pMan );
+ // reconstruct FRAIG in the new network
+ pNtkNew = Abc_NtkFromFraig( pMan, pNtk );
+ Fraig_ManFree( pMan );
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkFraig: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the strashed network into FRAIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes )
+{
+ Fraig_Man_t * pMan;
+ ProgressBar * pProgress;
+ Fraig_Node_t * pNodeFraig;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pConst1;
+ int i;
+
+ assert( Abc_NtkIsAig(pNtk) );
+
+ // create the FRAIG manager
+ pMan = Fraig_ManCreate( pParams );
+
+ // create PIs and remember them in the old nodes
+ Abc_NtkCleanCopy( pNtk );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ pNode->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, i);
+ pConst1 = Abc_AigConst1( pNtk->pManFunc );
+
+ // perform strashing
+ if ( fAllNodes )
+ vNodes = Abc_AigCollectAll( pNtk );
+ else
+ vNodes = Abc_AigDfs( pNtk );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNode = vNodes->pArray[i];
+ if ( pNode == pConst1 )
+ pNodeFraig = Fraig_ManReadConst1(pMan);
+ else
+ pNodeFraig = Fraig_NodeAnd( pMan,
+ Fraig_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
+ Fraig_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
+ assert( pNode->pCopy == NULL );
+ pNode->pCopy = (Abc_Obj_t *)pNodeFraig;
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+
+ // set the primary outputs
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Fraig_ManSetPo( pMan, (Fraig_Node_t *)Abc_ObjFanin0(pNode)->pCopy );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms FRAIG into what looks like a strashed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pNode;//, * pNodeNew;
+ int i;
+ // create the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_AIG );
+ // make the mapper point to the new network
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ Fraig_NodeSetData1( Fraig_ManReadIthVar(pMan, i), (Fraig_Node_t *)pNode->pCopy );
+ // set the constant node
+ Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_AigConst1(pNtkNew->pManFunc) );
+ // process the nodes in topological order
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ Abc_ObjFanin0(pNode)->pCopy = Abc_NodeFromFraig_rec( pNtkNew, Fraig_ManReadOutputs(pMan)[i] );
+ }
+ Extra_ProgressBarStop( pProgress );
+ // finalize the new network
+ Abc_NtkFinalize( pNtk, pNtkNew );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms into AIG one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromFraig_rec( Abc_Ntk_t * pNtkNew, Fraig_Node_t * pNodeFraig )
+{
+ Abc_Obj_t * pRes, * pRes0, * pRes1, * pResMin, * pResCur;
+ Fraig_Node_t * pNodeTemp, * pNodeFraigR = Fraig_Regular(pNodeFraig);
+ void ** ppTail;
+ // check if the node was already considered
+ if ( pRes = (Abc_Obj_t *)Fraig_NodeReadData1(pNodeFraigR) )
+ return Abc_ObjNotCond( pRes, Fraig_IsComplement(pNodeFraig) );
+ // solve the children
+ pRes0 = Abc_NodeFromFraig_rec( pNtkNew, Fraig_NodeReadOne(pNodeFraigR) );
+ pRes1 = Abc_NodeFromFraig_rec( pNtkNew, Fraig_NodeReadTwo(pNodeFraigR) );
+ // derive the new node
+ pRes = Abc_AigAnd( pNtkNew->pManFunc, pRes0, pRes1 );
+ pRes->fPhase = Fraig_NodeReadSimInv( pNodeFraigR );
+ // if the node has an equivalence class, find its representative
+ if ( Fraig_NodeReadRepr(pNodeFraigR) == NULL && Fraig_NodeReadNextE(pNodeFraigR) != NULL )
+ {
+ // go through the FRAIG nodes belonging to this equivalence class
+ // and find the representative node (the node with the smallest level)
+ pResMin = pRes;
+ for ( pNodeTemp = Fraig_NodeReadNextE(pNodeFraigR); pNodeTemp; pNodeTemp = Fraig_NodeReadNextE(pNodeTemp) )
+ {
+ assert( Fraig_NodeReadData1(pNodeTemp) == NULL );
+ pResCur = Abc_NodeFromFraig_rec( pNtkNew, pNodeTemp );
+ if ( pResMin->Level > pResCur->Level )
+ pResMin = pResCur;
+ }
+ // link the nodes in such a way that representative goes first
+ ppTail = &pResMin->pData;
+ if ( pRes != pResMin )
+ {
+ *ppTail = pRes;
+ ppTail = &pRes->pData;
+ }
+ for ( pNodeTemp = Fraig_NodeReadNextE(pNodeFraigR); pNodeTemp; pNodeTemp = Fraig_NodeReadNextE(pNodeTemp) )
+ {
+ pResCur = (Abc_Obj_t *)Fraig_NodeReadData1(pNodeTemp);
+ assert( pResCur );
+ if ( pResMin == pResCur )
+ continue;
+ *ppTail = pResCur;
+ ppTail = &pResCur->pData;
+ }
+ assert( *ppTail == NULL );
+
+ // update the phase of the node
+ pRes = Abc_ObjNotCond( pResMin, (pRes->fPhase ^ pResMin->fPhase) );
+ }
+ Fraig_NodeSetData1( pNodeFraigR, (Fraig_Node_t *)pRes );
+ return Abc_ObjNotCond( pRes, Fraig_IsComplement(pNodeFraig) );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFraigTrust( Abc_Ntk_t * pNtk )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+
+ if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogicSop(pNtk) )
+ {
+ printf( "Abc_NtkFraigTrust: Trust mode works for netlists and logic SOP networks.\n" );
+ return NULL;
+ }
+
+ if ( !Abc_NtkFraigTrustCheck(pNtk) )
+ {
+ printf( "Abc_NtkFraigTrust: The network does not look like an AIG with choice nodes.\n" );
+ return NULL;
+ }
+
+ // perform strashing
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_AIG );
+ Abc_NtkFraigTrustOne( pNtk, pNtkNew );
+ Abc_NtkFinalize( pNtk, pNtkNew );
+
+ // print a warning about choice nodes
+ printf( "Warning: The resulting AIG contains %d choice nodes.\n", Abc_NtkCountChoiceNodes( pNtkNew ) );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkFraigTrust: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks whether the node can be processed in the trust mode.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, nFanins;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ nFanins = Abc_ObjFaninNum(pNode);
+ if ( nFanins < 2 )
+ continue;
+ if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) )
+ continue;
+ if ( !Abc_SopIsOrType(pNode->pData) )
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
+{
+ ProgressBar * pProgress;
+ Abc_Aig_t * pMan = pNtkNew->pManFunc;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pNodeNew, * pObj;
+ int i;
+
+ // perform strashing
+ vNodes = Abc_NtkDfs( pNtk );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // get the node
+ pNode = vNodes->pArray[i];
+ assert( Abc_ObjIsNode(pNode) );
+ // strash the node
+ pNodeNew = Abc_NodeFraigTrust( pMan, pNode );
+ // get the old object
+ if ( Abc_NtkIsNetlist(pNtk) )
+ pObj = Abc_ObjFanout0( pNode ); // the fanout net
+ else
+ pObj = pNode; // the node itself
+ // make sure the node is not yet strashed
+ assert( pObj->pCopy == NULL );
+ // mark the old object with the new AIG node
+ pObj->pCopy = pNodeNew;
+ }
+ Vec_PtrFree( vNodes );
+ Extra_ProgressBarStop( pProgress );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms one node into a FRAIG in the trust mode.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pSum, * pFanin;
+ Abc_Obj_t * pConst1 = Abc_AigConst1(pMan);
+ void ** ppTail;
+ int i, nFanins, fCompl;
+
+ assert( Abc_ObjIsNode(pNode) );
+ // get the number of node's fanins
+ nFanins = Abc_ObjFaninNum( pNode );
+ assert( nFanins == Abc_SopGetVarNum(pNode->pData) );
+ // check if it is a constant
+ if ( nFanins == 0 )
+ return Abc_ObjNotCond( pConst1, Abc_SopIsConst0(pNode->pData) );
+ if ( nFanins == 1 )
+ return Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_SopIsInv(pNode->pData) );
+ if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) )
+ return Abc_AigAnd( pMan,
+ Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,0) ),
+ Abc_ObjNotCond( Abc_ObjFanin1(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,1) ) );
+ assert( Abc_SopIsOrType(pNode->pData) );
+ fCompl = Abc_SopGetIthCareLit(pNode->pData,0);
+ // get the root of the choice node (the first fanin)
+ pSum = Abc_ObjFanin0(pNode)->pCopy;
+ // connect other fanins
+ ppTail = &pSum->pData;
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ if ( i == 0 )
+ continue;
+ *ppTail = pFanin->pCopy;
+ ppTail = &pFanin->pCopy->pData;
+ // set the complemented bit of this cut
+ if ( fCompl ^ Abc_SopGetIthCareLit(pNode->pData, i) )
+ pFanin->pCopy->fPhase = 1;
+ }
+ assert( *ppTail == NULL );
+ return pSum;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkFraigStore( Abc_Ntk_t * pNtk )
+{
+ Abc_Frame_t * p;
+ Abc_Ntk_t * pStore;
+ int nAndsOld;
+
+ if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsAig(pNtk) )
+ {
+ printf( "Convert netlist into a logic network before adding to storage.\n" );
+ return 0;
+ }
+
+ // get the network currently stored
+ p = Abc_FrameGetGlobalFrame();
+ pStore = Abc_FrameReadNtkStore(p);
+ if ( pStore == NULL )
+ {
+ // start the stored network
+ pStore = Abc_NtkStrash( pNtk );
+ if ( pStore == NULL )
+ {
+ printf( "Abc_NtkFraigStore: Initial strashing has failed.\n" );
+ return 0;
+ }
+ // save the parameters
+ Abc_FrameSetNtkStore( p, pStore );
+ Abc_FrameSetNtkStoreSize( p, 1 );
+ nAndsOld = 0;
+ }
+ else
+ {
+ // add the new network to storage
+ nAndsOld = Abc_NtkNodeNum( pStore );
+ if ( !Abc_NtkAppend( pStore, pNtk ) )
+ {
+ printf( "The current network cannot be appended to the stored network.\n" );
+ return 0;
+ }
+ // set the number of networks stored
+ Abc_FrameSetNtkStoreSize( p, Abc_FrameReadNtkStoreSize(p) + 1 );
+ }
+ printf( "The number of AIG nodes added to storage = %5d.\n", Abc_NtkNodeNum(pStore) - nAndsOld );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFraigRestore()
+{
+ Abc_Frame_t * p;
+ Fraig_Params_t Params;
+ Abc_Ntk_t * pStore, * pFraig;
+ int nWords1, nWords2, nWordsMin;
+
+ // get the stored network
+ p = Abc_FrameGetGlobalFrame();
+ pStore = Abc_FrameReadNtkStore(p);
+ Abc_FrameSetNtkStore( p, NULL );
+ if ( pStore == NULL )
+ {
+ printf( "There are no network currently in storage.\n" );
+ return NULL;
+ }
+ printf( "Currently stored %d networks with %d nodes will be fraiged.\n",
+ Abc_FrameReadNtkStoreSize(p), Abc_NtkNodeNum(pStore) );
+
+ // to determine the number of simulation patterns
+ // use the following strategy
+ // at least 64 words (32 words random and 32 words dynamic)
+ // no more than 256M for one circuit (128M + 128M)
+ nWords1 = 32;
+ nWords2 = (1<<27) / (Abc_NtkNodeNum(pStore) + Abc_NtkCiNum(pStore));
+ nWordsMin = ABC_MIN( nWords1, nWords2 );
+
+ // set parameters for fraiging
+ Fraig_ParamsSetDefault( &Params );
+ Params.nPatsRand = nWordsMin * 32; // the number of words of random simulation info
+ Params.nPatsDyna = nWordsMin * 32; // the number of words of dynamic simulation info
+ Params.nBTLimit = 99; // the max number of backtracks to perform
+ Params.fFuncRed = 1; // performs only one level hashing
+ Params.fFeedBack = 1; // enables solver feedback
+ Params.fDist1Pats = 1; // enables distance-1 patterns
+ Params.fDoSparse = 1; // performs equiv tests for sparse functions
+ Params.fChoicing = 1; // enables recording structural choices
+ Params.fTryProve = 0; // tries to solve the final miter
+ Params.fVerbose = 0; // the verbosiness flag
+
+// Fraig_ManReportChoices( p );
+ // transform it into FRAIG
+ pFraig = Abc_NtkFraig( pStore, &Params, 1 );
+ if ( pFraig == NULL )
+ return NULL;
+ Abc_NtkDelete( pStore );
+ return pFraig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigStoreClean()
+{
+ Abc_Frame_t * p;
+ Abc_Ntk_t * pStore;
+ // get the stored network
+ p = Abc_FrameGetGlobalFrame();
+ pStore = Abc_FrameReadNtkStore(p);
+ if ( pStore )
+ Abc_NtkDelete( pStore );
+ Abc_FrameSetNtkStore( p, NULL );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks the correctness of stored networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigStoreCheck( Abc_Ntk_t * pFraig )
+{
+ Abc_Obj_t * pNode0, * pNode1;
+ int nPoOrig, nPoFinal, nStored;
+ int i, k;
+ // check that the PO functions are correct
+ nPoFinal = Abc_NtkPoNum(pFraig);
+ nStored = Abc_FrameReadNtkStoreSize(Abc_FrameGetGlobalFrame());
+ assert( nPoFinal % nStored == 0 );
+ nPoOrig = nPoFinal / nStored;
+ for ( i = 0; i < nPoOrig; i++ )
+ {
+ pNode0 = Abc_ObjFanin0( Abc_NtkPo(pFraig, i) );
+ for ( k = 1; k < nStored; k++ )
+ {
+ pNode1 = Abc_ObjFanin0( Abc_NtkPo(pFraig, k*nPoOrig+i) );
+ if ( pNode0 != pNode1 )
+ printf( "Verification for PO #%d of network #%d has failed. The PO function is not used.\n", i+1, k+1 );
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcFunc.c b/src/base/abc/abcFunc.c
new file mode 100644
index 00000000..59f0dc34
--- /dev/null
+++ b/src/base/abc/abcFunc.c
@@ -0,0 +1,419 @@
+/**CFile****************************************************************
+
+ FileName [abcFunc.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Transformations between different functionality representations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFunc.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, int nFanins );
+static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Converts the network from SOP to BDD representation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ DdManager * dd;
+ int nFaninsMax, i;
+
+ assert( Abc_NtkIsLogicSop(pNtk) );
+
+ // start the functionality manager
+ nFaninsMax = Abc_NtkGetFaninMax( pNtk );
+ if ( nFaninsMax == 0 )
+ printf( "Warning: The network has only constant nodes.\n" );
+
+ dd = Cudd_Init( nFaninsMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
+
+ // convert each node from SOP to BDD
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ assert( pNode->pData );
+ pNode->pData = Abc_ConvertSopToBdd( dd, pNode->pData, Abc_ObjFaninNum(pNode) );
+ if ( pNode->pData == NULL )
+ {
+ printf( "Abc_NtkSopToBdd: Error while converting SOP into BDD.\n" );
+ return 0;
+ }
+ Cudd_Ref( pNode->pData );
+ }
+
+ Extra_MmFlexStop( pNtk->pManFunc, 0 );
+ pNtk->pManFunc = dd;
+
+ // update the network type
+ pNtk->Type = ABC_NTK_LOGIC_BDD;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the node from SOP to BDD representation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, int nFanins )
+{
+ DdNode * bCube, * bTemp, * bVar, * bRes;
+ char * pCube;
+ int i, c;
+
+ bRes = Cudd_Not(dd->one); Cudd_Ref( bRes );
+ for ( c = 0; ; c++ )
+ {
+ // get the cube
+ pCube = pSop + c * (nFanins + 3);
+ if ( *pCube == 0 )
+ break;
+ // construct BDD for the cube
+ bCube = dd->one; Cudd_Ref( bCube );
+ for ( i = 0; i < nFanins; i++ )
+ {
+ if ( pCube[i] == '0' )
+ bVar = Cudd_Not( dd->vars[i] );
+ else if ( pCube[i] == '1' )
+ bVar = dd->vars[i];
+ else
+ continue;
+ bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube );
+ Cudd_RecursiveDeref( dd, bTemp );
+ }
+ bRes = Cudd_bddOr( dd, bTemp = bRes, bCube ); Cudd_Ref( bRes );
+ Cudd_RecursiveDeref( dd, bTemp );
+ Cudd_RecursiveDeref( dd, bCube );
+ }
+ // decide if we need to complement the result
+ pCube = pSop + nFanins + 1;
+ assert( *pCube == '0' || *pCube == '1' );
+ if ( *pCube == '0' )
+ bRes = Cudd_Not(bRes);
+ Cudd_Deref( bRes );
+ return bRes;
+}
+
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Converts the network from BDD to SOP representation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkBddToSop( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ DdManager * dd = pNtk->pManFunc;
+ DdNode * bFunc;
+ int RetValue, i;
+ Vec_Str_t * vCube;
+
+ assert( Abc_NtkIsLogicBdd(pNtk) );
+ Cudd_zddVarsFromBddVars( dd, 2 );
+ // allocate the new manager
+ pNtk->pManFunc = Extra_MmFlexStart();
+ // update the network type
+ pNtk->Type = ABC_NTK_LOGIC_SOP;
+
+ // go through the objects
+ vCube = Vec_StrAlloc( 100 );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ assert( pNode->pData );
+ bFunc = pNode->pData;
+//Extra_bddPrint( dd, bFunc ); printf( "\n" ); printf( "\n" );
+ pNode->pData = Abc_ConvertBddToSop( pNtk->pManFunc, dd, bFunc, Abc_ObjFaninNum(pNode), vCube, -1 );
+ if ( pNode->pData == NULL )
+ return 0;
+ Cudd_RecursiveDeref( dd, bFunc );
+ }
+ Vec_StrFree( vCube );
+
+ // check for remaining references in the package
+ RetValue = Cudd_CheckZeroRef( dd );
+ if ( RetValue > 0 )
+ printf( "\nThe number of referenced nodes = %d\n\n", RetValue );
+// Cudd_PrintInfo( dd, stdout );
+ Cudd_Quit( dd );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the node from BDD to SOP representation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFunc, int nFanins, Vec_Str_t * vCube, int fMode )
+{
+ char * pSop;
+ DdNode * bFuncNew, * bCover, * zCover, * zCover0, * zCover1;
+ int nCubes, nCubes0, nCubes1, fPhase;
+
+ if ( Cudd_IsConstant(bFunc) )
+ {
+ Vec_StrFill( vCube, nFanins, '-' );
+ Vec_StrPush( vCube, '\0' );
+ pSop = Extra_MmFlexEntryFetch( pMan, nFanins + 4 );
+ if ( bFunc == Cudd_ReadLogicZero(dd) )
+ sprintf( pSop, "%s 0\n", vCube->pArray );
+ else
+ sprintf( pSop, "%s 1\n", vCube->pArray );
+ return pSop;
+ }
+
+
+ if ( fMode == -1 )
+ { // try both phases
+
+ // get the ZDD of the negative polarity
+ bCover = Cudd_zddIsop( dd, Cudd_Not(bFunc), Cudd_Not(bFunc), &zCover0 );
+ Cudd_Ref( zCover0 );
+ Cudd_Ref( bCover );
+ Cudd_RecursiveDeref( dd, bCover );
+ nCubes0 = Abc_CountZddCubes( dd, zCover0 );
+
+ // get the ZDD of the positive polarity
+ bCover = Cudd_zddIsop( dd, bFunc, bFunc, &zCover1 );
+ Cudd_Ref( zCover1 );
+ Cudd_Ref( bCover );
+ Cudd_RecursiveDeref( dd, bCover );
+ nCubes1 = Abc_CountZddCubes( dd, zCover1 );
+
+ // compare the number of cubes
+ if ( nCubes1 <= nCubes0 )
+ { // use positive polarity
+ nCubes = nCubes1;
+ zCover = zCover1;
+ Cudd_RecursiveDerefZdd( dd, zCover0 );
+ fPhase = 1;
+ }
+ else
+ { // use negative polarity
+ nCubes = nCubes0;
+ zCover = zCover0;
+ Cudd_RecursiveDerefZdd( dd, zCover1 );
+ fPhase = 0;
+ }
+ }
+ else if ( fMode == 0 )
+ {
+ // get the ZDD of the positive polarity
+ bCover = Cudd_zddIsop( dd, Cudd_Not(bFunc), Cudd_Not(bFunc), &zCover );
+ Cudd_Ref( zCover );
+ Cudd_Ref( bCover );
+ Cudd_RecursiveDeref( dd, bCover );
+ nCubes = Abc_CountZddCubes( dd, zCover );
+ fPhase = 0;
+ }
+ else if ( fMode == 1 )
+ {
+ // get the ZDD of the positive polarity
+ bCover = Cudd_zddIsop( dd, bFunc, bFunc, &zCover );
+ Cudd_Ref( zCover );
+ Cudd_Ref( bCover );
+ Cudd_RecursiveDeref( dd, bCover );
+ nCubes = Abc_CountZddCubes( dd, zCover );
+ fPhase = 1;
+ }
+ else
+ {
+ assert( 0 );
+ }
+
+ // allocate memory for the cover
+ pSop = Extra_MmFlexEntryFetch( pMan, (nFanins + 3) * nCubes + 1 );
+ pSop[(nFanins + 3) * nCubes] = 0;
+ // create the SOP
+ Vec_StrFill( vCube, nFanins, '-' );
+ Vec_StrPush( vCube, '\0' );
+ Abc_ConvertZddToSop( dd, zCover, pSop, nFanins, vCube, fPhase );
+ Cudd_RecursiveDerefZdd( dd, zCover );
+
+ // verify
+ bFuncNew = Abc_ConvertSopToBdd( dd, pSop, nFanins ); Cudd_Ref( bFuncNew );
+//Extra_bddPrint( dd, bFunc );
+//Extra_bddPrint( dd, bFuncNew );
+ if ( bFuncNew != bFunc )
+ printf( "Verification failed.\n" );
+ Cudd_RecursiveDeref( dd, bFuncNew );
+ return pSop;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive the SOP from the ZDD representation of the cubes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ConvertZddToSop_rec( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase, int * pnCubes )
+{
+ DdNode * zC0, * zC1, * zC2;
+ int Index;
+
+ if ( zCover == dd->zero )
+ return;
+ if ( zCover == dd->one )
+ {
+ char * pCube;
+ pCube = pSop + (*pnCubes) * (nFanins + 3);
+ sprintf( pCube, "%s %d\n", vCube->pArray, fPhase );
+ (*pnCubes)++;
+ return;
+ }
+ Index = zCover->index/2;
+ assert( Index < nFanins );
+ extraDecomposeCover( dd, zCover, &zC0, &zC1, &zC2 );
+ vCube->pArray[Index] = '0';
+ Abc_ConvertZddToSop_rec( dd, zC0, pSop, nFanins, vCube, fPhase, pnCubes );
+ vCube->pArray[Index] = '1';
+ Abc_ConvertZddToSop_rec( dd, zC1, pSop, nFanins, vCube, fPhase, pnCubes );
+ vCube->pArray[Index] = '-';
+ Abc_ConvertZddToSop_rec( dd, zC2, pSop, nFanins, vCube, fPhase, pnCubes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive the BDD for the function in the cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase )
+{
+ int nCubes = 0;
+ Abc_ConvertZddToSop_rec( dd, zCover, pSop, nFanins, vCube, fPhase, &nCubes );
+ return nCubes;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes the SOPs of the negative and positive phase of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeBddToCnf( Abc_Obj_t * pNode, Extra_MmFlex_t * pMmMan, Vec_Str_t * vCube, char ** ppSop0, char ** ppSop1 )
+{
+ assert( Abc_NtkIsLogicBdd(pNode->pNtk) );
+ *ppSop0 = Abc_ConvertBddToSop( pMmMan, pNode->pNtk->pManFunc, pNode->pData, Abc_ObjFaninNum(pNode), vCube, 0 );
+ *ppSop1 = Abc_ConvertBddToSop( pMmMan, pNode->pNtk->pManFunc, pNode->pData, Abc_ObjFaninNum(pNode), vCube, 1 );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Count the number of paths in the ZDD.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_CountZddCubes_rec( DdManager * dd, DdNode * zCover, int * pnCubes )
+{
+ DdNode * zC0, * zC1, * zC2;
+ if ( zCover == dd->zero )
+ return;
+ if ( zCover == dd->one )
+ {
+ (*pnCubes)++;
+ return;
+ }
+ extraDecomposeCover( dd, zCover, &zC0, &zC1, &zC2 );
+ Abc_CountZddCubes_rec( dd, zC0, pnCubes );
+ Abc_CountZddCubes_rec( dd, zC1, pnCubes );
+ Abc_CountZddCubes_rec( dd, zC2, pnCubes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Count the number of paths in the ZDD.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CountZddCubes( DdManager * dd, DdNode * zCover )
+{
+ int nCubes = 0;
+ Abc_CountZddCubes_rec( dd, zCover, &nCubes );
+ return nCubes;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcInt.h b/src/base/abc/abcInt.h
new file mode 100644
index 00000000..1a1ab75f
--- /dev/null
+++ b/src/base/abc/abcInt.h
@@ -0,0 +1,46 @@
+/**CFile****************************************************************
+
+ FileName [abcInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Internal declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __ABC_INT_H__
+#define __ABC_INT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
+
diff --git a/src/base/abc/abcLatch.c b/src/base/abc/abcLatch.c
new file mode 100644
index 00000000..a5bb9544
--- /dev/null
+++ b/src/base/abc/abcLatch.c
@@ -0,0 +1,260 @@
+/**CFile****************************************************************
+
+ FileName [abcLatch.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures working with latches.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcLatch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// 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.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkLatchIsSelfFeed_rec( Abc_Obj_t * pLatch, Abc_Obj_t * pLatchRoot )
+{
+ Abc_Obj_t * pFanin;
+ assert( Abc_ObjIsLatch(pLatch) );
+ if ( pLatch == pLatchRoot )
+ return 1;
+ pFanin = Abc_ObjFanin0(pLatch);
+ if ( !Abc_ObjIsLatch(pFanin) )
+ return 0;
+ return Abc_NtkLatchIsSelfFeed_rec( pFanin, pLatch );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if latches form self-loop.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkLatchIsSelfFeed( Abc_Obj_t * pLatch )
+{
+ Abc_Obj_t * pFanin;
+ assert( Abc_ObjIsLatch(pLatch) );
+ pFanin = Abc_ObjFanin0(pLatch);
+ if ( !Abc_ObjIsLatch(pFanin) )
+ return 0;
+ return Abc_NtkLatchIsSelfFeed_rec( pFanin, pLatch );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if latches form self-loop.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkCountSelfFeedLatches( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pLatch;
+ int i, Counter;
+ Counter = 0;
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ Counter += Abc_NtkLatchIsSelfFeed( pLatch );
+ return Counter;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcMap.c b/src/base/abc/abcMap.c
new file mode 100644
index 00000000..ca326ea1
--- /dev/null
+++ b/src/base/abc/abcMap.c
@@ -0,0 +1,439 @@
+/**CFile****************************************************************
+
+ FileName [abcMap.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Interface with the SC mapping package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "main.h"
+#include "mio.h"
+#include "mapper.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose );
+static Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
+static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
+static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
+static Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis );
+static Abc_Obj_t * Abc_NtkFixCiDriver( Abc_Obj_t * pNode );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Interface with the mapping package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+
+ Map_Man_t * pMan;
+
+ assert( Abc_NtkIsAig(pNtk) );
+
+ // check that the library is available
+ if ( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) == NULL )
+ {
+ printf( "The current library is not available.\n" );
+ return 0;
+ }
+
+ // derive the supergate library
+ if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) == NULL && Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) )
+ {
+ printf( "A simple supergate library is derived from gate library \"%s\".\n",
+ Mio_LibraryReadName(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) );
+ Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
+ }
+
+ // print a warning about choice nodes
+ if ( Abc_NtkCountChoiceNodes( pNtk ) )
+ printf( "Performing mapping with choices.\n" );
+
+ // perform the mapping
+ pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, fVerbose );
+ if ( pMan == NULL )
+ return NULL;
+ if ( !Map_Mapping( pMan ) )
+ {
+ Map_ManFree( pMan );
+ return NULL;
+ }
+
+ // reconstruct the network after mapping
+ pNtkNew = Abc_NtkFromMap( pMan, pNtk );
+ if ( pNtkNew == NULL )
+ return NULL;
+ Map_ManFree( pMan );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkMap: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Load the network into manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fVerbose )
+{
+ Map_Man_t * pMan;
+ ProgressBar * pProgress;
+ Map_Node_t * pNodeMap;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pFanin, * pPrev;
+ int i;
+
+ assert( Abc_NtkIsAig(pNtk) );
+
+ // start the mapping manager and set its parameters
+ pMan = Map_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk), Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk), fVerbose );
+ if ( pMan == NULL )
+ return NULL;
+ Map_ManSetAreaRecovery( pMan, fRecovery );
+ Map_ManSetOutputNames( pMan, (char **)pNtk->vNamesPo->pArray );
+ Map_ManSetDelayTarget( pMan, (float)DelayTarget );
+ Map_ManSetInputArrivals( pMan, (Map_Time_t *)Abc_NtkGetCiArrivalTimes(pNtk) );
+
+ // create PIs and remember them in the old nodes
+ Abc_NtkCleanCopy( pNtk );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ pNode->pCopy = (Abc_Obj_t *)Map_ManReadInputs(pMan)[i];
+
+ // load the AIG into the mapper
+ vNodes = Abc_AigDfs( pNtk );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // consider the case of a constant
+ pNode = vNodes->pArray[i];
+ if ( Abc_NodeIsConst(pNode) )
+ {
+ Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan);
+ continue;
+ }
+ // add the node to the mapper
+ pNodeMap = Map_NodeAnd( pMan,
+ Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
+ Map_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
+ assert( pNode->pCopy == NULL );
+ // remember the node
+ pNode->pCopy = (Abc_Obj_t *)pNodeMap;
+ // set up the choice node
+ if ( Abc_NodeIsChoice( 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 );
+ Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy );
+ }
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+
+ // set the primary outputs in the required phase
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Map_ManReadOutputs(pMan)[i] = Map_NotCond( (Map_Node_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the mapped network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew;
+ Map_Node_t * pNodeMap;
+ Abc_Obj_t * pNode, * pNodeNew;
+ int i, nDupGates;
+
+ // create the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC_MAP );
+ // make the mapper point to the new network
+ Map_ManCleanData( pMan );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
+ // set the constant node
+ if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 )
+ Map_NodeSetData( Map_ManReadConst1(pMan), 1, (char *)Abc_NodeCreateConst1(pNtkNew) );
+
+ // assign the mapping of the required phase to the POs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNodeMap = Map_ManReadOutputs(pMan)[i];
+ pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) );
+ assert( !Abc_ObjIsComplement(pNodeNew) );
+ if ( !Abc_ObjIsNode(pNodeNew) )
+ pNodeNew = Abc_NtkFixCiDriver( pNodeNew );
+ 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 );
+ if ( nDupGates && Map_ManReadVerbose(pMan) )
+ printf( "Duplicated %d gates to decouple the PO drivers.\n", nDupGates );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the nodes corrresponding to one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
+{
+ Abc_Obj_t * pNodeNew, * pNodeInv;
+
+ // check if the phase is already implemented
+ pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
+ if ( pNodeNew )
+ return pNodeNew;
+
+ // implement the node if the best cut is assigned
+ if ( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL )
+ return Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, fPhase );
+
+ // if the cut is not assigned, implement the node
+ assert( Map_NodeReadCutBest(pNodeMap, !fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
+ pNodeNew = Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, !fPhase );
+
+ // add the inverter
+ pNodeInv = Abc_NtkCreateNode( pNtkNew );
+ Abc_ObjAddFanin( pNodeInv, pNodeNew );
+ pNodeInv->pData = Mio_LibraryReadInv(Map_ManReadGenLib(Map_NodeReadMan(pNodeMap)));
+
+ // set the inverter
+ Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeInv );
+ return pNodeInv;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the nodes corrresponding to one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
+{
+ Abc_Obj_t * pNodePIs[10];
+ Abc_Obj_t * pNodeNew;
+ Map_Node_t ** ppLeaves;
+ Map_Cut_t * pCutBest;
+ Map_Super_t * pSuperBest;
+ unsigned uPhaseBest;
+ int i, fInvPin, nLeaves;
+
+ // make sure the node can be implemented in this phase
+ assert( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
+ // check if the phase is already implemented
+ pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
+ if ( pNodeNew )
+ return pNodeNew;
+
+ // get the information about the best cut
+ pCutBest = Map_NodeReadCutBest( pNodeMap, fPhase );
+ pSuperBest = Map_CutReadSuperBest( pCutBest, fPhase );
+ uPhaseBest = Map_CutReadPhaseBest( pCutBest, fPhase );
+ nLeaves = Map_CutReadLeavesNum( pCutBest );
+ ppLeaves = Map_CutReadLeaves( pCutBest );
+
+ // collect the PI nodes
+ for ( i = 0; i < nLeaves; i++ )
+ {
+ fInvPin = ((uPhaseBest & (1 << i)) > 0);
+ pNodePIs[i] = Abc_NodeFromMap_rec( pNtkNew, ppLeaves[i], !fInvPin );
+ assert( pNodePIs[i] != NULL );
+ }
+
+ // implement the supergate
+ pNodeNew = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, pSuperBest, pNodePIs, nLeaves );
+ Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeNew );
+ return pNodeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the nodes corrresponding to one supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
+{
+ Mio_Gate_t * pRoot;
+ Map_Super_t ** ppFanins;
+ Abc_Obj_t * pNodeNew, * pNodeFanin;
+ int nFanins, Number, i;
+
+ // get the parameters of the supergate
+ pRoot = Map_SuperReadRoot(pSuper);
+ if ( pRoot == NULL )
+ {
+ Number = Map_SuperReadNum(pSuper);
+ if ( Number < nNodePis )
+ {
+ return pNodePis[Number];
+ }
+ else
+ {
+ assert( 0 );
+ /* It might happen that a super gate with 5 inputs is constructed that
+ * actually depends only on the first four variables; i.e the fifth is a
+ * don't care -- in that case we connect constant node for the fifth
+ * (since the cut only has 4 variables). An interesting question is what
+ * if the first variable (and not the fifth one is the redundant one;
+ * can that happen?) */
+ return Abc_NodeCreateConst0(pNtkNew);
+ }
+ }
+
+ // get information about the fanins of the supergate
+ nFanins = Map_SuperReadFaninNum( pSuper );
+ ppFanins = Map_SuperReadFanins( pSuper );
+ // create a new node with these fanins
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < nFanins; i++ )
+ {
+ pNodeFanin = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, ppFanins[i], pNodePis, nNodePis );
+ Abc_ObjAddFanin( pNodeNew, pNodeFanin );
+ }
+ pNodeNew->pData = pRoot;
+ return pNodeNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Unmaps the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkUnmap( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ char * pSop;
+ int i;
+
+ assert( Abc_NtkIsLogicMap(pNtk) );
+ // update the functionality manager
+ assert( pNtk->pManFunc == NULL );
+ pNtk->pManFunc = Extra_MmFlexStart();
+ pNtk->Type = ABC_NTK_LOGIC_SOP;
+ // update the nodes
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ pSop = Mio_GateReadSop(pNode->pData);
+ assert( Abc_SopGetVarNum(pSop) == Abc_ObjFaninNum(pNode) );
+ pNode->pData = Abc_SopRegister( pNtk->pManFunc, pSop );
+ }
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Add buffer when the CO driver is a CI.]
+
+ Description [Hack: If the PO has the same name as the PI, it will still count
+ as the buffer but this node will not be written into file during writing]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkFixCiDriver( Abc_Obj_t * pNode )
+{
+ Mio_Gate_t * pGateBuffer = Mio_LibraryReadBuf(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
+ Mio_Gate_t * pGateInv = Mio_LibraryReadInv(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
+ // add the buffer
+ if ( pGateBuffer )
+ return Abc_NodeCreateBuf( pNode->pNtk, pNode );
+ // add two inverters
+ if ( pGateInv )
+ return Abc_NodeCreateInv( pNode->pNtk, Abc_NodeCreateInv(pNode->pNtk, pNode) );
+ assert( 0 );
+ return NULL;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c
new file mode 100644
index 00000000..d2d88ebf
--- /dev/null
+++ b/src/base/abc/abcMinBase.c
@@ -0,0 +1,167 @@
+/**CFile****************************************************************
+
+ FileName [abcMinBase.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Makes nodes of the network minimum base.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcMinBase.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Abc_NodeSupport( DdNode * bFunc, Vec_Str_t * vSupport, int nVars );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Makes nodes minimum base.]
+
+ Description [Returns the number of changed nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkMinimumBase( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, Counter;
+ assert( Abc_NtkIsLogicBdd(pNtk) );
+ Counter = 0;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ Counter += Abc_NodeMinimumBase( pNode );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Makes one node minimum base.]
+
+ Description [Returns 1 if the node is changed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeMinimumBase( Abc_Obj_t * pNode )
+{
+ Vec_Str_t * vSupport = pNode->pNtk->vStrTemp;
+ Vec_Ptr_t * vFanins = pNode->pNtk->vPtrTemp;
+ DdNode * bTemp;
+ int i, nVars;
+
+ assert( Abc_NtkIsLogicBdd(pNode->pNtk) );
+ assert( Abc_ObjIsNode(pNode) );
+
+ // compute support
+ nVars = Abc_NodeSupport( Cudd_Regular(pNode->pData), vSupport, Abc_ObjFaninNum(pNode) );
+ if ( nVars == Abc_ObjFaninNum(pNode) )
+ return 0;
+
+ // remove unused fanins
+ Abc_NodeCollectFanins( pNode, vFanins );
+ for ( i = 0; i < vFanins->nSize; i++ )
+ if ( vSupport->pArray[i] == 0 )
+ Abc_ObjDeleteFanin( pNode, vFanins->pArray[i] );
+ assert( nVars == Abc_ObjFaninNum(pNode) );
+
+ // update the function of the node
+ pNode->pData = Extra_bddRemapUp( pNode->pNtk->pManFunc, bTemp = pNode->pData ); Cudd_Ref( pNode->pData );
+ Cudd_RecursiveDeref( pNode->pNtk->pManFunc, bTemp );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes support of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeSupport_rec( DdNode * bFunc, Vec_Str_t * vSupport )
+{
+ if ( cuddIsConstant(bFunc) || Cudd_IsComplement(bFunc->next) )
+ return;
+ vSupport->pArray[ bFunc->index ] = 1;
+ Abc_NodeSupport_rec( cuddT(bFunc), vSupport );
+ Abc_NodeSupport_rec( Cudd_Regular(cuddE(bFunc)), vSupport );
+ bFunc->next = Cudd_Not(bFunc->next);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes support of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeSupportClear_rec( DdNode * bFunc )
+{
+ if ( !Cudd_IsComplement(bFunc->next) )
+ return;
+ bFunc->next = Cudd_Regular(bFunc->next);
+ if ( cuddIsConstant(bFunc) )
+ return;
+ Abc_NodeSupportClear_rec( cuddT(bFunc) );
+ Abc_NodeSupportClear_rec( Cudd_Regular(cuddE(bFunc)) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes support of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeSupport( DdNode * bFunc, Vec_Str_t * vSupport, int nVars )
+{
+ int Counter, i;
+ // compute the support by marking the BDD
+ Vec_StrFill( vSupport, nVars, 0 );
+ Abc_NodeSupport_rec( bFunc, vSupport );
+ // clear the marak
+ Abc_NodeSupportClear_rec( bFunc );
+ // get the number of support variables
+ Counter = 0;
+ for ( i = 0; i < nVars; i++ )
+ Counter += vSupport->pArray[i];
+ return Counter;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcMiter.c b/src/base/abc/abcMiter.c
new file mode 100644
index 00000000..f1037dd2
--- /dev/null
+++ b/src/base/abc/abcMiter.c
@@ -0,0 +1,502 @@
+/**CFile****************************************************************
+
+ FileName [abcMiter.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures to derive the miter of two circuits.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcMiter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+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_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 );
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Derives the miter of two networks.]
+
+ Description [Preprocesses the networks to make sure that they are strashed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
+{
+ Abc_Ntk_t * pTemp = NULL;
+ int fRemove1, fRemove2;
+ // make sure the circuits are strashed
+ fRemove1 = (!Abc_NtkIsAig(pNtk1)) && (pNtk1 = Abc_NtkStrash(pNtk1));
+ fRemove2 = (!Abc_NtkIsAig(pNtk2)) && (pNtk2 = Abc_NtkStrash(pNtk2));
+ if ( pNtk1 && pNtk2 )
+ {
+ // check that the networks have the same PIs/POs/latches
+ // reorder PIs/POs/latches of pNtk2 according to pNtk1
+ // compute the miter of two strashed sequential networks
+ if ( Abc_NtkCompareSignals( pNtk1, pNtk2, fComb ) )
+ pTemp = Abc_NtkMiterInt( pNtk1, pNtk2, fComb );
+ }
+ if ( fRemove1 ) Abc_NtkDelete( pNtk1 );
+ if ( fRemove2 ) Abc_NtkDelete( pNtk2 );
+ return pTemp;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the miter of two sequential networks.]
+
+ Description [Assumes that the networks are strashed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
+{
+ int fCheck = 1;
+ char Buffer[100];
+ Abc_Ntk_t * pNtkMiter;
+
+ assert( Abc_NtkIsAig(pNtk1) );
+ assert( Abc_NtkIsAig(pNtk2) );
+
+ // start the new network
+ pNtkMiter = Abc_NtkAlloc( ABC_NTK_AIG );
+ sprintf( Buffer, "%s_%s_miter", pNtk1->pName, pNtk2->pName );
+ pNtkMiter->pName = util_strsav(Buffer);
+
+ // perform strashing
+ Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, fComb );
+ Abc_NtkMiterAddOne( pNtk1, pNtkMiter );
+ Abc_NtkMiterAddOne( pNtk2, pNtkMiter );
+ Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, fComb );
+
+ // 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 [Prepares the network for mitering.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb )
+{
+ Abc_Obj_t * pObj, * pObjNew;
+ int i;
+ // clean the copy field in all objects
+ Abc_NtkCleanCopy( pNtk1 );
+ Abc_NtkCleanCopy( pNtk2 );
+ if ( fComb )
+ {
+ // create new PIs and remember them in the old PIs
+ Abc_NtkForEachCi( pNtk1, pObj, i )
+ {
+ pObjNew = Abc_NtkCreateTermPi( 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] );
+ }
+ // create the only PO
+ pObjNew = Abc_NtkCreateTermPo( pNtkMiter );
+ // add the PO name
+ Abc_NtkLogicStoreName( pObjNew, "miter" );
+ }
+ else
+ {
+ // create new PIs and remember them in the old PIs
+ Abc_NtkForEachPi( pNtk1, pObj, i )
+ {
+ pObjNew = Abc_NtkCreateTermPi( 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] );
+ }
+ // create the only PO
+ pObjNew = Abc_NtkCreateTermPo( 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 );
+ // add name
+ Abc_NtkLogicStoreNamePlus( pObjNew, pNtk1->vNamesLatch->pArray[i], "_1" );
+ }
+ Abc_NtkForEachLatch( pNtk2, pObj, i )
+ {
+ pObjNew = Abc_NtkDupObj( pNtkMiter, pObj );
+ Vec_PtrPush( pNtkMiter->vPis, pObjNew );
+ Vec_PtrPush( pNtkMiter->vPos, pObjNew );
+ // add name
+ Abc_NtkLogicStoreNamePlus( pObjNew, pNtk2->vNamesLatch->pArray[i], "_2" );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs mitering for one network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter )
+{
+ ProgressBar * pProgress;
+ 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_NtkDfs( pNtk );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ 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 );
+ Extra_ProgressBarStop( pProgress );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Finalizes the miter by adding the output part.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb )
+{
+ Vec_Ptr_t * vPairs;
+ Abc_Obj_t * pDriverNew, * pMiter, * pNode;
+ int i;
+ // collect the PO pairs from both networks
+ vPairs = Vec_PtrAlloc( 100 );
+ if ( fComb )
+ {
+ // collect the CO nodes for the miter
+ Abc_NtkForEachCo( pNtk1, pNode, i )
+ {
+ pDriverNew = Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
+ Vec_PtrPush( vPairs, pDriverNew );
+ pNode = Abc_NtkPo( pNtk2, i );
+ pDriverNew = Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
+ Vec_PtrPush( vPairs, pDriverNew );
+ }
+ }
+ else
+ {
+ // collect the PO nodes for the miter
+ Abc_NtkForEachPo( pNtk1, pNode, i )
+ {
+ pDriverNew = Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
+ Vec_PtrPush( vPairs, pDriverNew );
+ pNode = Abc_NtkPo( pNtk2, i );
+ pDriverNew = Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
+ Vec_PtrPush( vPairs, pDriverNew );
+ }
+ // connect new latches
+ Abc_NtkForEachLatch( pNtk1, pNode, i )
+ {
+ pDriverNew = Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
+ Abc_ObjAddFanin( pNode->pCopy, pDriverNew );
+ }
+ Abc_NtkForEachLatch( pNtk2, pNode, i )
+ {
+ pDriverNew = Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
+ Abc_ObjAddFanin( pNode->pCopy, pDriverNew );
+ }
+ }
+ // add the miter
+ pMiter = Abc_AigMiter( pNtkMiter->pManFunc, vPairs );
+ Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter );
+ Vec_PtrFree( vPairs );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks the status of the miter.]
+
+ Description [Return 1 if the miter is sat for at least one output.
+ Return 0 if the miter is unsat for all its outputs. Returns -1 if the
+ miter is undecided for some outputs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter )
+{
+ Abc_Obj_t * pNodePo, * pChild;
+ int i;
+ assert( Abc_NtkIsAig(pMiter) );
+ Abc_NtkForEachPo( pMiter, pNodePo, i )
+ {
+ pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) );
+ if ( Abc_NodeIsConst(pChild) )
+ {
+ assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter->pManFunc) );
+ if ( !Abc_ObjIsComplement(pChild) )
+ {
+ // if the miter is constant 1, return immediately
+ printf( "MITER IS CONSTANT 1!\n" );
+ return 1;
+ }
+ }
+ // if the miter is undecided (or satisfiable), return immediately
+ else
+ return -1;
+ }
+ // return 0, meaning all outputs are constant zero
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reports the status of the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMiterReport( Abc_Ntk_t * pMiter )
+{
+ Abc_Obj_t * pChild, * pNode;
+ int i;
+ if ( Abc_NtkPoNum(pMiter) == 1 )
+ {
+ pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,0) );
+ if ( Abc_NodeIsConst(Abc_ObjRegular(pChild)) )
+ {
+ if ( Abc_ObjIsComplement(pChild) )
+ printf( "Unsatisfiable.\n" );
+ else
+ printf( "Satisfiable. (Constant 1).\n" );
+ }
+ else
+ printf( "Satisfiable.\n" );
+ }
+ else
+ {
+ Abc_NtkForEachPo( pMiter, pNode, i )
+ {
+ pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) );
+ printf( "Output #%2d : ", i );
+ if ( Abc_NodeIsConst(Abc_ObjRegular(pChild)) )
+ {
+ if ( Abc_ObjIsComplement(pChild) )
+ printf( "Unsatisfiable.\n" );
+ else
+ printf( "Satisfiable. (Constant 1).\n" );
+ }
+ else
+ printf( "Satisfiable.\n" );
+ }
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives the time frames of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial )
+{
+ int fCheck = 1;
+ char Buffer[100];
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkFrames;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pLatch, * pLatchNew;
+ int i;
+ assert( nFrames > 0 );
+ assert( Abc_NtkIsAig(pNtk) );
+ // start the new network
+ pNtkFrames = Abc_NtkAlloc( ABC_NTK_AIG );
+ sprintf( Buffer, "%s_%d_frames", pNtk->pName, nFrames );
+ pNtkFrames->pName = util_strsav(Buffer);
+ // create new latches (or their initial values) and remember them in the new latches
+ if ( !fInitial )
+ {
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ Abc_NtkDupObj( pNtkFrames, pLatch );
+ }
+ else
+ {
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames->pManFunc), ((int)pLatch->pData)!=1 );
+ }
+
+ // create the timeframes
+ vNodes = Abc_NtkDfs( pNtk );
+ pProgress = Extra_ProgressBarStart( stdout, nFrames );
+ for ( i = 0; i < nFrames; i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ Abc_NtkAddFrame( pNtkFrames, pNtk, i, vNodes );
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+
+ // connect the new latches to the outputs of the last frame
+ if ( !fInitial )
+ {
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ {
+ 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] );
+ }
+ 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 ) )
+ {
+ printf( "Abc_NtkFrames: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkFrames );
+ return NULL;
+ }
+ return pNtkFrames;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds one time frame to the new network.]
+
+ Description [Assumes that the latches of the old network point
+ to the outputs of the previous frame of the new network (pLatch->pCopy).
+ In the end, updates the latches of the old network to point to the
+ outputs of the current frame of the new network.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec_Ptr_t * vNodes )
+{
+ char Buffer[10];
+ Abc_Obj_t * pNode, * pNodeNew, * pLatch;
+ Abc_Obj_t * pConst1, * pConst1New;
+ int i;
+ // get the constant nodes
+ pConst1 = Abc_AigConst1( pNtk->pManFunc );
+ pConst1New = Abc_AigConst1( pNtkFrames->pManFunc );
+ // create the prefix to be added to the node names
+ sprintf( Buffer, "_%02d", iFrame );
+ // add the new PI nodes
+ Abc_NtkForEachPi( pNtk, pNode, i )
+ {
+ pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode );
+ Abc_NtkLogicStoreNamePlus( pNodeNew, pNtk->vNamesPi->pArray[i], Buffer );
+ }
+ // add the internal nodes
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ pNode = vNodes->pArray[i];
+ if ( pNode == pConst1 )
+ pNodeNew = pConst1New;
+ else
+ pNodeNew = Abc_AigAnd( pNtkFrames->pManFunc,
+ Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
+ Abc_ObjNotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
+ pNode->pCopy = pNodeNew;
+ }
+ // add the new POs
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ {
+ 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 );
+ }
+ // transfer the implementation of the latch drivers to the latches
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ pLatch->pCopy = Abc_ObjNotCond( Abc_ObjFanin0(pLatch)->pCopy, Abc_ObjFaninC0(pLatch) );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcNames.c b/src/base/abc/abcNames.c
new file mode 100644
index 00000000..da68bf50
--- /dev/null
+++ b/src/base/abc/abcNames.c
@@ -0,0 +1,406 @@
+/**CFile****************************************************************
+
+ FileName [abcNames.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures working with net and node names.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcNames.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Registers the name with the string memory manager.]
+
+ Description [This function should be used to register all names
+ permanentsly stored with the network. The pointer returned by
+ this procedure contains the copy of the name, which should be used
+ in all network manipulation procedures.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_NtkRegisterName( Abc_Ntk_t * pNtk, char * pName )
+{
+ char * pRegName;
+ if ( pName == NULL ) return NULL;
+ pRegName = Extra_MmFlexEntryFetch( pNtk->pMmNames, strlen(pName) + 1 );
+ strcpy( pRegName, pName );
+ return pRegName;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Registers the name with the string memory manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_NtkRegisterNamePlus( Abc_Ntk_t * pNtk, char * pName, char * pSuffix )
+{
+ char * pRegName;
+ assert( pName && pSuffix );
+ pRegName = Extra_MmFlexEntryFetch( pNtk->pMmNames, strlen(pName) + strlen(pSuffix) + 1 );
+ sprintf( pRegName, "%s%s", pName, pSuffix );
+ return pRegName;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the hash table of node names.]
+
+ 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.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+stmm_table * Abc_NtkLogicHashNames( Abc_Ntk_t * pNtk, int Type, int fComb )
+{
+ 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 []
+
+ SeeAlso []
+
+***********************************************************************/
+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 )
+ {
+ 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;
+ }
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ {
+ 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) );
+ }
+}
+
+/**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;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Gets the long name of the node.]
+
+ Description [This name is the output net's name.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_ObjName( Abc_Obj_t * pObj )
+{
+ 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 );
+ }
+ return Buffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds a unique name for the node.]
+
+ Description [If the name exists, tries appending numbers to it until
+ it becomes unique.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_ObjNameUnique( Abc_Ntk_t * pNtk, char * pName )
+{
+ static char Buffer[1000];
+ int Counter;
+ assert( 0 );
+ if ( !stmm_is_member( pNtk->tName2Net, pName ) )
+ return pName;
+ for ( Counter = 1; ; Counter++ )
+ {
+ sprintf( Buffer, "%s_%d", pName, Counter );
+ if ( !stmm_is_member( pNtk->tName2Net, Buffer ) )
+ return Buffer;
+ }
+ return NULL;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds new name to the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_NtkLogicStoreName( Abc_Obj_t * pNodeNew, char * pNameOld )
+{
+ char * pNewName;
+ assert( !Abc_ObjIsComplement(pNodeNew) );
+ // 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) )
+ {
+ Vec_PtrPush( pNodeNew->pNtk->vNamesLatch, pNewName );
+ Vec_PtrPush( pNodeNew->pNtk->vNamesPi, pNewName );
+ Vec_PtrPush( pNodeNew->pNtk->vNamesPo, pNewName );
+ }
+ else
+ assert( 0 );
+ return pNewName;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds new name to the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_NtkLogicStoreNamePlus( Abc_Obj_t * pNodeNew, char * pNameOld, char * pSuffix )
+{
+ char * pNewName;
+ assert( !Abc_ObjIsComplement(pNodeNew) );
+ assert( pSuffix );
+ // 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) )
+ {
+ Vec_PtrPush( pNodeNew->pNtk->vNamesLatch, pNewName );
+ Vec_PtrPush( pNodeNew->pNtk->vNamesPi, pNewName );
+ Vec_PtrPush( pNodeNew->pNtk->vNamesPo, pNewName );
+ }
+ else
+ assert( 0 );
+ return pNewName;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the name arrays from the old network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkCreateNameArrays( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
+{
+ Abc_Obj_t * pNet, * pLatch;
+ 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 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the name arrays.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkDupNameArrays( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
+{
+ Abc_Obj_t * pObj, * pLatch;
+ 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 );
+ // 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] );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c
new file mode 100644
index 00000000..671fa9bc
--- /dev/null
+++ b/src/base/abc/abcNetlist.c
@@ -0,0 +1,93 @@
+/**CFile****************************************************************
+
+ FileName [abcNetlist.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Transforms netlist into a logic network and vice versa.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcNetlist.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Transform the netlist into a logic network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkLogic( Abc_Ntk_t * pNtk )
+{
+ 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
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ Abc_ObjFanout0(pObj)->pCopy = 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, pFanin->pCopy );
+ // create and connect the POs
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ Abc_ObjAddFanin( Abc_NtkCreateTermPo(pNtkNew), Abc_ObjFanin0(pObj)->pCopy );
+ // 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 ( pNtk->pExdc )
+ pNtkNew->pExdc = Abc_NtkLogic( pNtk->pExdc );
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ fprintf( stdout, "Abc_NtkLogic(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcPrint.c b/src/base/abc/abcPrint.c
new file mode 100644
index 00000000..0c3a2b5e
--- /dev/null
+++ b/src/base/abc/abcPrint.c
@@ -0,0 +1,288 @@
+/**CFile****************************************************************
+
+ FileName [abcPrint.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Printing statistics.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcPrint.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "ft.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Print the vital stats of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ fprintf( pFile, "%-15s:", pNtk->pName );
+ fprintf( pFile, " i/o = %3d/%3d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );
+ fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) );
+
+ if ( Abc_NtkIsNetlist(pNtk) )
+ {
+ fprintf( pFile, " net = %5d", Abc_NtkNetNum(pNtk) );
+ fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) );
+ }
+ else if ( Abc_NtkIsAig(pNtk) )
+ fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) );
+ else
+ fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) );
+
+ if ( Abc_NtkIsLogicSop(pNtk) )
+ {
+ fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) );
+// fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) );
+ fprintf( pFile, " lit(fac) = %5d", Abc_NtkGetLitFactNum(pNtk) );
+ }
+ else if ( Abc_NtkIsLogicBdd(pNtk) )
+ fprintf( pFile, " bdd = %5d", Abc_NtkGetBddNodeNum(pNtk) );
+ else if ( Abc_NtkIsLogicMap(pNtk) )
+ {
+ fprintf( pFile, " area = %5.2f", Abc_NtkGetMappedArea(pNtk) );
+ fprintf( pFile, " delay = %5.2f", Abc_NtkDelayTrace(pNtk) );
+ }
+ fprintf( pFile, " lev = %2d", Abc_NtkGetLevelNum(pNtk) );
+ fprintf( pFile, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints PIs/POs and LIs/LOs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNet, * pLatch;
+ int i;
+
+ if ( Abc_NtkIsNetlist(pNtk) )
+ {
+ fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) );
+ Abc_NtkForEachPi( pNtk, pNet, i )
+ fprintf( pFile, " %s", Abc_ObjName(pNet) );
+ fprintf( pFile, "\n" );
+
+ fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) );
+ Abc_NtkForEachPo( pNtk, pNet, i )
+ fprintf( pFile, " %s", Abc_ObjName(pNet) );
+ 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" );
+ }
+ else
+ {
+ fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) );
+ Abc_NtkForEachPi( pNtk, pNet, i )
+ fprintf( pFile, " %s", pNtk->vNamesPi->pArray[i] );
+ fprintf( pFile, "\n" );
+
+ fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) );
+ Abc_NtkForEachPo( pNtk, pNet, 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" );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the distribution of fanins/fanouts in the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintFanio( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, k, nFanins, nFanouts;
+ Vec_Int_t * vFanins, * vFanouts;
+ int nOldSize, nNewSize;
+
+ vFanins = Vec_IntAlloc( 0 );
+ vFanouts = Vec_IntAlloc( 0 );
+ Vec_IntFill( vFanins, 100, 0 );
+ Vec_IntFill( vFanouts, 100, 0 );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ nFanins = Abc_ObjFaninNum(pNode);
+ if ( Abc_NtkIsNetlist(pNtk) )
+ nFanouts = Abc_ObjFanoutNum( Abc_ObjFanout0(pNode) );
+ else
+ nFanouts = Abc_ObjFanoutNum(pNode);
+ if ( nFanins > vFanins->nSize || nFanouts > vFanouts->nSize )
+ {
+ nOldSize = vFanins->nSize;
+ nNewSize = ABC_MAX(nFanins, nFanouts) + 10;
+ Vec_IntGrow( vFanins, nNewSize );
+ Vec_IntGrow( vFanouts, nNewSize );
+ for ( k = nOldSize; k < nNewSize; k++ )
+ {
+ Vec_IntPush( vFanins, 0 );
+ Vec_IntPush( vFanouts, 0 );
+ }
+ }
+ vFanins->pArray[nFanins]++;
+ vFanouts->pArray[nFanouts]++;
+ }
+ fprintf( pFile, "The distribution of fanins and fanouts in the network:\n" );
+ fprintf( pFile, " Number Nodes with fanin Nodes with fanout\n" );
+ for ( k = 0; k < vFanins->nSize; k++ )
+ {
+ if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 )
+ continue;
+ fprintf( pFile, "%5d : ", k );
+ if ( vFanins->pArray[k] == 0 )
+ fprintf( pFile, " " );
+ else
+ fprintf( pFile, "%12d ", vFanins->pArray[k] );
+ fprintf( pFile, " " );
+ if ( vFanouts->pArray[k] == 0 )
+ fprintf( pFile, " " );
+ else
+ fprintf( pFile, "%12d ", vFanouts->pArray[k] );
+ fprintf( pFile, "\n" );
+ }
+ Vec_IntFree( vFanins );
+ Vec_IntFree( vFanouts );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the fanins/fanouts of a node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pNode2;
+ int i;
+ if ( Abc_ObjIsPo(pNode) )
+ pNode = Abc_ObjFanin0(pNode);
+
+ fprintf( pFile, "Fanins (%d): ", Abc_ObjFaninNum(pNode) );
+ Abc_ObjForEachFanin( pNode, pNode2, i )
+ {
+ pNode2->pCopy = NULL;
+ fprintf( pFile, " %s", Abc_ObjName(pNode2) );
+ }
+ fprintf( pFile, "\n" );
+
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "Fanouts (%d): ", Abc_ObjFaninNum(pNode) );
+ Abc_ObjForEachFanout( pNode, pNode2, i )
+ {
+ pNode2->pCopy = NULL;
+ fprintf( pFile, " %s", Abc_ObjName(pNode2) );
+ }
+ fprintf( pFile, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the factored form of one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ Abc_NodePrintFactor( pFile, pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the factored form of one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode )
+{
+ Vec_Int_t * vFactor;
+ if ( Abc_ObjIsPo(pNode) )
+ pNode = Abc_ObjFanin0(pNode);
+ if ( Abc_ObjIsPi(pNode) )
+ {
+ printf( "Skipping the PI node.\n" );
+ return;
+ }
+ if ( Abc_ObjIsLatch(pNode) )
+ {
+ printf( "Skipping the latch.\n" );
+ return;
+ }
+ assert( Abc_ObjIsNode(pNode) );
+ vFactor = Ft_Factor( pNode->pData );
+ pNode->pCopy = NULL;
+ Ft_FactorPrint( stdout, vFactor, NULL, Abc_ObjName(pNode) );
+ Vec_IntFree( vFactor );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcRefs.c b/src/base/abc/abcRefs.c
new file mode 100644
index 00000000..b6a7dce1
--- /dev/null
+++ b/src/base/abc/abcRefs.c
@@ -0,0 +1,133 @@
+/**CFile****************************************************************
+
+ FileName [abcRefs.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Reference counting of the nodes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcRefs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fFanouts, bool fReference );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Procedure returns the size of the MFFC of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeMffcSize( Abc_Obj_t * pNode )
+{
+ int nConeSize1, nConeSize2;
+ assert( !Abc_ObjIsComplement( pNode ) );
+ assert( Abc_ObjIsNode( pNode ) );
+ nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0 ); // dereference
+ nConeSize2 = Abc_NodeRefDeref( pNode, 0, 1 ); // reference
+ assert( nConeSize1 == nConeSize2 );
+ assert( nConeSize1 > 0 );
+ return nConeSize1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Procedure returns the size of the MFFC of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeMffcRemove( Abc_Obj_t * pNode )
+{
+ assert( !Abc_ObjIsComplement( pNode ) );
+ assert( Abc_ObjIsNode( pNode ) );
+ return Abc_NodeRefDeref( pNode, 1, 0 ); // dereference
+}
+
+/**Function*************************************************************
+
+ Synopsis [References/references the node and returns MFFC size.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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) )
+ return 0;
+ pNode0 = Abc_ObjFanin( pNode, 0 );
+ pNode1 = Abc_ObjFanin( pNode, 1 );
+ Counter = 1;
+ if ( fReference )
+ {
+ if ( pNode0->vFanouts.nSize++ == 0 )
+ {
+ Counter += Abc_NodeRefDeref( pNode0, fFanouts, fReference );
+ if ( fFanouts )
+ Abc_ObjAddFanin( pNode, pNode0 );
+ }
+ if ( pNode1->vFanouts.nSize++ == 0 )
+ {
+ Counter += Abc_NodeRefDeref( pNode1, fFanouts, fReference );
+ if ( fFanouts )
+ Abc_ObjAddFanin( pNode, pNode1 );
+ }
+ }
+ else
+ {
+ assert( pNode0->vFanouts.nSize > 0 );
+ assert( pNode1->vFanouts.nSize > 0 );
+ if ( --pNode0->vFanouts.nSize == 0 )
+ {
+ Counter += Abc_NodeRefDeref( pNode0, fFanouts, fReference );
+ if ( fFanouts )
+ Abc_ObjDeleteFanin( pNode, pNode0 );
+ }
+ if ( --pNode1->vFanouts.nSize == 0 )
+ {
+ Counter += Abc_NodeRefDeref( pNode1, fFanouts, fReference );
+ if ( fFanouts )
+ Abc_ObjDeleteFanin( pNode, pNode1 );
+ }
+ }
+ return Counter;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcRenode.c b/src/base/abc/abcRenode.c
new file mode 100644
index 00000000..6a24ab80
--- /dev/null
+++ b/src/base/abc/abcRenode.c
@@ -0,0 +1,605 @@
+/**CFile****************************************************************
+
+ FileName [abcRenode.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures which transform an AIG into the network of nodes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcRenode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
+static Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld );
+
+static DdNode * Abc_NtkRenodeDeriveBdd_rec( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFanins );
+
+static void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax );
+static void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk );
+static void Abc_NtkRenodeSetBoundsMulti( Abc_Ntk_t * pNtk );
+static void Abc_NtkRenodeSetBoundsSimple( Abc_Ntk_t * pNtk );
+static void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the AIG into nodes.]
+
+ Description [Threhold is the max number of nodes duplicated at a node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+
+ assert( Abc_NtkIsAig(pNtk) );
+ assert( nThresh >= 0 );
+ assert( nFaninMax > 1 );
+
+ // print a warning about choice nodes
+ if ( Abc_NtkCountChoiceNodes( pNtk ) )
+ printf( "Warning: The choice nodes in the AIG are removed by renoding.\n" );
+
+ // define the boundary
+ if ( fCnf )
+ Abc_NtkRenodeSetBoundsCnf( pNtk );
+ else if ( fMulti )
+ Abc_NtkRenodeSetBoundsMulti( pNtk );
+ else if ( fSimple )
+ Abc_NtkRenodeSetBoundsSimple( pNtk );
+ else
+ Abc_NtkRenodeSetBounds( pNtk, nThresh, nFaninMax );
+
+ // perform renoding for this boundary
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC_BDD );
+ Abc_NtkRenodeInt( pNtk, pNtkNew );
+ Abc_NtkFinalize( pNtk, pNtkNew );
+
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtkNew );
+
+ // report the number of CNF objects
+ if ( fCnf )
+ {
+// int nClauses = Abc_NtkGetClauseNum(pNtkNew) + 2*Abc_NtkPoNum(pNtkNew) + 2*Abc_NtkLatchNum(pNtkNew);
+// printf( "CNF variables = %d. CNF clauses = %d.\n", Abc_NtkNodeNum(pNtkNew), nClauses );
+ }
+//printf( "Maximum fanin = %d.\n", Abc_NtkGetFaninMax(pNtkNew) );
+
+ // make sure everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkRenode: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the AIG into nodes.]
+
+ Description [Threhold is the max number of nodes duplicated at a node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
+{
+ ProgressBar * pProgress;
+ Abc_Obj_t * pNode, * pConst1, * pNodeNew;
+ int i;
+
+ // set the constant node
+ pConst1 = Abc_AigConst1(pNtk->pManFunc);
+ if ( Abc_ObjFanoutNum(pConst1) > 0 )
+ {
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ pNodeNew->pData = Cudd_ReadOne( pNtkNew->pManFunc ); Cudd_Ref( pNodeNew->pData );
+ pConst1->pCopy = pNodeNew;
+ }
+
+ // perform renoding for POs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ Abc_NtkRenode_rec( pNtkNew, Abc_ObjFanin0(pNode) );
+ }
+ Extra_ProgressBarStop( pProgress );
+
+ // clean the boundaries and data field in the old network
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ {
+ pNode->fMarkA = 0;
+ pNode->pData = NULL;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find the best multi-input node rooted at the given node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld )
+{
+ Vec_Ptr_t * vCone;
+ Abc_Obj_t * pNodeNew;
+ int i;
+
+ assert( !Abc_ObjIsComplement(pNodeOld) );
+ // return if the result if known
+ if ( pNodeOld->pCopy )
+ return pNodeOld->pCopy;
+ assert( Abc_ObjIsNode(pNodeOld) );
+ assert( !Abc_NodeIsConst(pNodeOld) );
+ assert( pNodeOld->fMarkA );
+
+ // collect the renoding cone
+ vCone = Vec_PtrAlloc( 10 );
+ Abc_NtkRenodeCone( pNodeOld, vCone );
+
+ // create a new node
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < vCone->nSize; i++ )
+ Abc_ObjAddFanin( pNodeNew, Abc_NtkRenode_rec(pNtkNew, vCone->pArray[i]) );
+
+ // derive the function of this node
+ pNodeNew->pData = Abc_NtkRenodeDeriveBdd( pNtkNew->pManFunc, pNodeOld, vCone );
+ Cudd_Ref( pNodeNew->pData );
+ Vec_PtrFree( vCone );
+
+ // remember the node
+ pNodeOld->pCopy = pNodeNew;
+ return pNodeOld->pCopy;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives the local BDD of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld )
+{
+ Abc_Obj_t * pFaninOld;
+ DdNode * bFunc;
+ int i;
+ assert( !Abc_NodeIsConst(pNodeOld) );
+ assert( Abc_ObjIsNode(pNodeOld) );
+ // set the elementary BDD variables for the input nodes
+ for ( i = 0; i < vFaninsOld->nSize; i++ )
+ {
+ pFaninOld = vFaninsOld->pArray[i];
+ pFaninOld->pData = Cudd_bddIthVar( dd, i ); Cudd_Ref( pFaninOld->pData );
+ pFaninOld->fMarkC = 1;
+ }
+ // call the recursive BDD computation
+ bFunc = Abc_NtkRenodeDeriveBdd_rec( dd, pNodeOld, vFaninsOld ); Cudd_Ref( bFunc );
+ // dereference the intermediate nodes
+ for ( i = 0; i < vFaninsOld->nSize; i++ )
+ {
+ pFaninOld = vFaninsOld->pArray[i];
+ Cudd_RecursiveDeref( dd, pFaninOld->pData );
+ pFaninOld->fMarkC = 0;
+ }
+ Cudd_Deref( bFunc );
+ return bFunc;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the local BDD of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NtkRenodeDeriveBdd_rec( DdManager * dd, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins )
+{
+ DdNode * bFunc, * bFunc0, * bFunc1;
+ assert( !Abc_ObjIsComplement(pNode) );
+ // if the result is available return
+ if ( pNode->fMarkC )
+ {
+ assert( pNode->pData ); // network has a cycle
+ return pNode->pData;
+ }
+ // mark the node as visited
+ pNode->fMarkC = 1;
+ Vec_PtrPush( vFanins, pNode );
+ // compute the result for both branches
+ bFunc0 = Abc_NtkRenodeDeriveBdd_rec( dd, Abc_ObjFanin(pNode,0), vFanins ); Cudd_Ref( bFunc0 );
+ bFunc1 = Abc_NtkRenodeDeriveBdd_rec( dd, Abc_ObjFanin(pNode,1), vFanins ); Cudd_Ref( bFunc1 );
+ bFunc0 = Cudd_NotCond( bFunc0, Abc_ObjFaninC0(pNode) );
+ bFunc1 = Cudd_NotCond( bFunc1, Abc_ObjFaninC1(pNode) );
+ // get the final result
+ bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc );
+ Cudd_RecursiveDeref( dd, bFunc0 );
+ Cudd_RecursiveDeref( dd, bFunc1 );
+ // set the result
+ pNode->pData = bFunc;
+ assert( pNode->pData );
+ return bFunc;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Limits the cones to be no more than the given size.]
+
+ Description [Returns 1 if the last cone was limited. Returns 0 if no changes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRenodeLimit_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, int nFaninMax, int fCanStop, int fFirst )
+{
+ int nNodes0, nNodes1;
+ assert( !Abc_ObjIsComplement(pNode) );
+ // check if the node should be added to the fanins
+ if ( !fFirst && (pNode->fMarkA || !Abc_ObjIsNode(pNode)) )
+ {
+ Vec_PtrPushUnique( vCone, pNode );
+ return 0;
+ }
+ // if we cannot stop in this branch, collect all nodes
+ if ( !fCanStop )
+ {
+ Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,0), vCone, nFaninMax, 0, 0 );
+ Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 );
+ return 0;
+ }
+ // if we can stop, try the left branch first, and return if we stopped
+ assert( vCone->nSize == 0 );
+ if ( Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,0), vCone, nFaninMax, 1, 0 ) )
+ return 1;
+ // save the number of nodes in the left branch and call for the right branch
+ nNodes0 = vCone->nSize;
+ assert( nNodes0 <= nFaninMax );
+ Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 );
+ // check the number of nodes
+ if ( vCone->nSize <= nFaninMax )
+ return 0;
+ // the number of nodes exceeds the limit
+
+ // get the number of nodes in the right branch
+ vCone->nSize = 0;
+ Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 );
+ // if this number exceeds the limit, solve the problem for this branch
+ if ( vCone->nSize > nFaninMax )
+ {
+ int RetValue;
+ vCone->nSize = 0;
+ RetValue = Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 1, 0 );
+ assert( RetValue == 1 );
+ return 1;
+ }
+
+ nNodes1 = vCone->nSize;
+ assert( nNodes1 <= nFaninMax );
+ if ( nNodes0 >= nNodes1 )
+ { // the left branch is larger - cut it
+ assert( Abc_ObjFanin(pNode,0)->fMarkA == 0 );
+ Abc_ObjFanin(pNode,0)->fMarkA = 1;
+ }
+ else
+ { // the right branch is larger - cut it
+ assert( Abc_ObjFanin(pNode,1)->fMarkA == 0 );
+ Abc_ObjFanin(pNode,1)->fMarkA = 1;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Limits the cones to be no more than the given size.]
+
+ Description [Returns 1 if the last cone was limited. Returns 0 if no changes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRenodeLimit( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, int nFaninMax )
+{
+ vCone->nSize = 0;
+ return Abc_NtkRenodeLimit_rec( pNode, vCone, nFaninMax, 1, 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the expansion boundary for multi-input nodes.]
+
+ Description [The boundary includes the set of PIs and all nodes such that
+ when expanding over the node we duplicate no more than nThresh nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax )
+{
+ Vec_Ptr_t * vCone = pNtk->vPtrTemp;
+ Abc_Obj_t * pNode;
+ int i, nFanouts, nConeSize;
+
+ // make sure the mark is not set
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ assert( pNode->fMarkA == 0 );
+
+ // mark the nodes where expansion stops using pNode->fMarkA
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ // mark the nodes with multiple fanouts
+ nFanouts = Abc_ObjFanoutNum(pNode);
+ nConeSize = Abc_NodeMffcSize(pNode);
+ if ( (nFanouts - 1) * nConeSize > nThresh )
+ pNode->fMarkA = 1;
+ }
+
+ // mark the PO drivers
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+
+ // make sure the fanin limit is met
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ if ( pNode->fMarkA == 0 )
+ continue;
+ // continue cutting branches ntil it meets the fanin limit
+ while ( Abc_NtkRenodeLimit(pNode, vCone, nFaninMax) );
+ assert( vCone->nSize <= nFaninMax );
+ }
+/*
+ // make sure the fanin limit is met
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ if ( pNode->fMarkA == 0 )
+ continue;
+ Abc_NtkRenodeCone( pNode, vCone );
+ assert( vCone->nSize <= nFaninMax );
+ }
+*/
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the expansion boundary for conversion into CNF.]
+
+ Description [The boundary includes the set of PIs, the roots of MUXes,
+ the nodes with multiple fanouts and the nodes with complemented outputs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, nMuxes;
+
+ // make sure the mark is not set
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ assert( pNode->fMarkA == 0 );
+
+ // mark the nodes where expansion stops using pNode->fMarkA
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ // mark the nodes with multiple fanouts
+ if ( Abc_ObjFanoutNum(pNode) > 1 )
+ pNode->fMarkA = 1;
+ // mark the nodes that are roots of MUXes
+ if ( Abc_NodeIsMuxType( pNode ) )
+ {
+ pNode->fMarkA = 1;
+ Abc_ObjFanin0( Abc_ObjFanin0(pNode) )->fMarkA = 1;
+ Abc_ObjFanin0( Abc_ObjFanin1(pNode) )->fMarkA = 1;
+ Abc_ObjFanin1( Abc_ObjFanin0(pNode) )->fMarkA = 1;
+ Abc_ObjFanin1( Abc_ObjFanin1(pNode) )->fMarkA = 1;
+ }
+ else // mark the complemented edges
+ {
+ if ( Abc_ObjFaninC0(pNode) )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+ if ( Abc_ObjFaninC1(pNode) )
+ Abc_ObjFanin1(pNode)->fMarkA = 1;
+ }
+ }
+
+ // mark the PO drivers
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+
+ // count the number of MUXes
+ nMuxes = 0;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ if ( Abc_NodeIsMuxType(pNode) &&
+ Abc_ObjFanin0(pNode)->fMarkA == 0 &&
+ Abc_ObjFanin1(pNode)->fMarkA == 0 )
+ nMuxes++;
+ }
+ printf( "The number of MUXes detected = %d (%5.2f %% of logic).\n", nMuxes, 300.0*nMuxes/Abc_NtkNodeNum(pNtk) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the expansion boundary for conversion into multi-input AND graph.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeSetBoundsMulti( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i;
+
+ // make sure the mark is not set
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ assert( pNode->fMarkA == 0 );
+
+ // mark the nodes where expansion stops using pNode->fMarkA
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ // mark the nodes with multiple fanouts
+ if ( Abc_ObjFanoutNum(pNode) > 1 )
+ pNode->fMarkA = 1;
+ // mark the children if they are pointed by the complemented edges
+ if ( Abc_ObjFaninC0(pNode) )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+ if ( Abc_ObjFaninC1(pNode) )
+ Abc_ObjFanin1(pNode)->fMarkA = 1;
+ }
+
+ // mark the PO drivers
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets a simple boundary.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeSetBoundsSimple( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ // make sure the mark is not set
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ assert( pNode->fMarkA == 0 );
+ // mark the nodes where expansion stops using pNode->fMarkA
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ pNode->fMarkA = 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the fanins of a large node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone )
+{
+ assert( !Abc_ObjIsComplement(pNode) );
+ if ( pNode->fMarkA || !Abc_ObjIsNode(pNode) )
+ {
+ Vec_PtrPushUnique( vCone, pNode );
+ return;
+ }
+ Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,0), vCone );
+ Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,1), vCone );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the fanins of a large node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone )
+{
+ assert( !Abc_ObjIsComplement(pNode) );
+ assert( Abc_ObjIsNode(pNode) );
+ vCone->nSize = 0;
+ Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,0), vCone );
+ Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,1), vCone );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcSat.c b/src/base/abc/abcSat.c
new file mode 100644
index 00000000..fccb7fbc
--- /dev/null
+++ b/src/base/abc/abcSat.c
@@ -0,0 +1,252 @@
+/**CFile****************************************************************
+
+ FileName [abcSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures to solve the miter using the internal SAT solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars );
+static void Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Attempts to solve the miter using an internal SAT solver.]
+
+ Description [Returns 1 if the miter is SAT.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ solver * pSat;
+ lbool status;
+ int clk;
+
+ assert( Abc_NtkIsLogicBdd(pNtk) );
+ assert( Abc_NtkLatchNum(pNtk) == 0 );
+
+ if ( Abc_NtkPoNum(pNtk) > 1 )
+ fprintf( stdout, "Warning: The miter has more than 1 output. SAT will try to prove all of them.\n" );
+
+ // load clauses into the solver
+ clk = clock();
+ pSat = Abc_NtkMiterSatCreate( pNtk );
+// printf( "Created SAT problem with %d variable and %d clauses. ",
+// solver_nvars(pSat), solver_nclauses(pSat) );
+// PRT( "Time", clock() - clk );
+
+ // simplify the problem
+ clk = clock();
+ status = solver_simplify(pSat);
+// printf( "Simplified the problem to %d variables and %d clauses. ",
+// solver_nvars(pSat), solver_nclauses(pSat) );
+// PRT( "Time", clock() - clk );
+ if ( status == l_False )
+ {
+ solver_delete( pSat );
+ printf( "The problem is UNSAT after simplification.\n" );
+ return 0;
+ }
+
+ // solve the miter
+ clk = clock();
+ if ( fVerbose )
+ pSat->verbosity = 1;
+ status = solver_solve( pSat, NULL, NULL );
+// if ( fVerbose )
+// {
+ printf( "The problem is %5s. ", (status == l_True)? "SAT" : "UNSAT" );
+ PRT( "SAT solver time", clock() - clk );
+// }
+ // free the solver
+ solver_delete( pSat );
+ return status == l_True;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets up the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk )
+{
+ solver * pSat;
+ Extra_MmFlex_t * pMmFlex;
+ Abc_Obj_t * pNode;
+ Vec_Str_t * vCube;
+ Vec_Int_t * vVars;
+ char * pSop0, * pSop1;
+ int i;
+
+ assert( Abc_NtkIsLogicBdd(pNtk) );
+
+ // start the data structures
+ pSat = solver_new();
+ pMmFlex = Extra_MmFlexStart();
+ vCube = Vec_StrAlloc( 100 );
+ vVars = Vec_IntAlloc( 100 );
+
+ // add clauses for each internal nodes
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // derive SOPs for both phases of the node
+ Abc_NodeBddToCnf( pNode, pMmFlex, vCube, &pSop0, &pSop1 );
+ // add the clauses to the solver
+ Abc_NodeAddClauses( pSat, pSop0, pSop1, pNode, vVars );
+ }
+ // add clauses for each PO
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ Abc_NodeAddClausesTop( pSat, pNode, vVars );
+
+ // delete
+ Vec_StrFree( vCube );
+ Vec_IntFree( vVars );
+ Extra_MmFlexStop( pMmFlex, 0 );
+ return pSat;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses for the internal node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars )
+{
+ Abc_Obj_t * pFanin;
+ int i, c, nFanins;
+ char * pCube;
+
+ nFanins = Abc_ObjFaninNum( pNode );
+ assert( nFanins == Abc_SopGetVarNum( pSop0 ) );
+
+ // add clauses for the negative phase
+ for ( c = 0; ; c++ )
+ {
+ // get the cube
+ pCube = pSop0 + c * (nFanins + 3);
+ if ( *pCube == 0 )
+ break;
+ // add the clause
+ vVars->nSize = 0;
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ if ( pCube[i] == '0' )
+ Vec_IntPush( vVars, toLit(pFanin->Id) );
+ else if ( pCube[i] == '1' )
+ Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
+ }
+ Vec_IntPush( vVars, neg(toLit(pNode->Id)) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+ }
+
+ // add clauses for the positive phase
+ for ( c = 0; ; c++ )
+ {
+ // get the cube
+ pCube = pSop1 + c * (nFanins + 3);
+ if ( *pCube == 0 )
+ break;
+ // add the clause
+ vVars->nSize = 0;
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ if ( pCube[i] == '0' )
+ Vec_IntPush( vVars, toLit(pFanin->Id) );
+ else if ( pCube[i] == '1' )
+ Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
+ }
+ Vec_IntPush( vVars, toLit(pNode->Id) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses for the PO node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
+{
+ Abc_Obj_t * pFanin;
+
+ pFanin = Abc_ObjFanin0(pNode);
+ if ( Abc_ObjFaninC0(pNode) )
+ {
+ vVars->nSize = 0;
+ Vec_IntPush( vVars, toLit(pFanin->Id) );
+ Vec_IntPush( vVars, toLit(pNode->Id) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+
+ vVars->nSize = 0;
+ Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
+ Vec_IntPush( vVars, neg(toLit(pNode->Id)) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+ }
+ else
+ {
+ vVars->nSize = 0;
+ Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
+ Vec_IntPush( vVars, toLit(pNode->Id) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+
+ vVars->nSize = 0;
+ Vec_IntPush( vVars, toLit(pFanin->Id) );
+ Vec_IntPush( vVars, neg(toLit(pNode->Id)) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+ }
+
+ vVars->nSize = 0;
+ Vec_IntPush( vVars, toLit(pNode->Id) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c
new file mode 100644
index 00000000..9862ea8e
--- /dev/null
+++ b/src/base/abc/abcSop.c
@@ -0,0 +1,461 @@
+/**CFile****************************************************************
+
+ FileName [abcSop.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Implementation of a simple SOP representation of nodes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcSop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+/*
+ The SOPs in this package are represented using char * strings.
+ For example, the SOP of the node:
+
+ .names c d0 d1 MUX
+ 01- 1
+ 1-1 1
+
+ is the string: "01- 1/n1-1 1/n" where '/n' is a single char.
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Registers the cube string with the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName )
+{
+ char * pRegName;
+ if ( pName == NULL ) return NULL;
+ pRegName = Extra_MmFlexEntryFetch( pMan, strlen(pName) + 1 );
+ strcpy( pRegName, pName );
+ return pRegName;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the number of cubes in the cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_SopGetCubeNum( char * pSop )
+{
+ char * pCur;
+ int nCubes = 0;
+ if ( pSop == NULL )
+ return 0;
+ for ( pCur = pSop; *pCur; pCur++ )
+ nCubes += (*pCur == '\n');
+ return nCubes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the number of SOP literals in the cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_SopGetLitNum( char * pSop )
+{
+ char * pCur;
+ int nLits = 0;
+ if ( pSop == NULL )
+ return 0;
+ for ( pCur = pSop; *pCur; pCur++ )
+ {
+ nLits -= (*pCur == '\n');
+ nLits += (*pCur == '0' || *pCur == '1');
+ }
+ return nLits;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the number of variables in the cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_SopGetVarNum( char * pSop )
+{
+ char * pCur;
+ for ( pCur = pSop; *pCur != '\n'; pCur++ );
+ return pCur - pSop - 2;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the phase of the cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_SopGetPhase( char * pSop )
+{
+ int nVars = Abc_SopGetVarNum( pSop );
+ if ( pSop[nVars+1] == '0' )
+ return 0;
+ if ( pSop[nVars+1] == '1' )
+ return 1;
+ assert( 0 );
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the cover is constant 0.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_SopIsConst0( char * pSop )
+{
+ return pSop[0] == ' ' && pSop[1] == '0';
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the cover is constant 1.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_SopIsConst1( char * pSop )
+{
+ return pSop[0] == ' ' && pSop[1] == '1';
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the cover is constant 1.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_SopIsBuf( char * pSop )
+{
+ if ( pSop[4] != 0 )
+ return 0;
+ if ( (pSop[0] == '1' && pSop[2] == '1') || (pSop[0] == '0' && pSop[2] == '0') )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the cover is constant 1.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_SopIsInv( char * pSop )
+{
+ if ( pSop[4] != 0 )
+ return 0;
+ if ( (pSop[0] == '0' && pSop[2] == '1') || (pSop[0] == '1' && pSop[2] == '0') )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the cover is AND with possibly complemented inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_SopIsAndType( char * pSop )
+{
+ char * pCur;
+ if ( Abc_SopGetCubeNum(pSop) != 1 )
+ return 0;
+ for ( pCur = pSop; *pCur != ' '; pCur++ )
+ if ( *pCur == '-' )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the cover is OR with possibly complemented inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_SopIsOrType( char * pSop )
+{
+ char * pCube, * pCur;
+ int nVars, nLits, c;
+ nVars = Abc_SopGetVarNum( pSop );
+ for ( c = 0; ; c++ )
+ {
+ // get the cube
+ pCube = pSop + c * (nVars + 3);
+ if ( *pCube == 0 )
+ break;
+ // count the number of literals in the cube
+ nLits = 0;
+ for ( pCur = pCube; *pCur != ' '; pCur++ )
+ nLits += ( *pCur != '-' );
+ if ( nLits != 1 )
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the i-th literal of the cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_SopGetIthCareLit( char * pSop, int i )
+{
+ char * pCube;
+ int nVars, c;
+ nVars = Abc_SopGetVarNum( pSop );
+ for ( c = 0; ; c++ )
+ {
+ // get the cube
+ pCube = pSop + c * (nVars + 3);
+ if ( *pCube == 0 )
+ break;
+ // get the literal
+ if ( pCube[i] != '-' )
+ return pCube[i] - '0';
+ }
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_SopComplement( char * pSop )
+{
+ char * pCur;
+ for ( pCur = pSop; *pCur; pCur++ )
+ if ( *pCur == '\n' )
+ {
+ if ( *(pCur - 1) == '0' )
+ *(pCur - 1) = '1';
+ else if ( *(pCur - 1) == '1' )
+ *(pCur - 1) = '0';
+ else
+ assert( 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_SopCheck( char * pSop, int nFanins )
+{
+ char * pCubes, * pCubesOld;
+ int fFound0 = 0, fFound1 = 0;
+
+ // check the logic function of the node
+ for ( pCubes = pSop; *pCubes; pCubes++ )
+ {
+ // get the end of the next cube
+ for ( pCubesOld = pCubes; *pCubes != ' '; pCubes++ );
+ // compare the distance
+ if ( pCubes - pCubesOld != nFanins )
+ {
+ fprintf( stdout, "Abc_SopCheck: SOP has a mismatch between its cover and its fanins.\n" );
+ return 0;
+ }
+ // check the output values for this cube
+ pCubes++;
+ if ( *pCubes == '0' )
+ fFound0 = 1;
+ else if ( *pCubes == '1' )
+ fFound1 = 1;
+ else
+ {
+ fprintf( stdout, "Abc_SopCheck: SOP has a strange character in the output part of its cube.\n" );
+ return 0;
+ }
+ // check the last symbol (new line)
+ pCubes++;
+ if ( *pCubes != '\n' )
+ {
+ fprintf( stdout, "Abc_SopCheck: SOP has a cube without new line in the end.\n" );
+ return 0;
+ }
+ }
+ if ( fFound0 && fFound1 )
+ {
+ fprintf( stdout, "Abc_SopCheck: SOP has cubes in both phases.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the CNF of the SOP into file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_SopWriteCnf( FILE * pFile, char * pClauses, Vec_Int_t * vVars )
+{
+ char * pChar;
+ int i;
+ // check the logic function of the node
+ for ( pChar = pClauses; *pChar; pChar++ )
+ {
+ // write the clause
+ for ( i = 0; i < vVars->nSize; i++, pChar++ )
+ if ( *pChar == '0' )
+ fprintf( pFile, "%d ", vVars->pArray[i] );
+ else if ( *pChar == '1' )
+ fprintf( pFile, "%d ", -vVars->pArray[i] );
+ fprintf( pFile, "0\n" );
+ // check that the remainig part is fine
+ assert( *pChar == ' ' );
+ pChar++;
+ assert( *pChar == '1' );
+ pChar++;
+ assert( *pChar == '\n' );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the clauses of for the CNF to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_SopAddCnfToSolver( solver * pSat, char * pClauses, Vec_Int_t * vVars, Vec_Int_t * vTemp )
+{
+ char * pChar;
+ int i, RetValue;
+ // check the logic function of the node
+ for ( pChar = pClauses; *pChar; pChar++ )
+ {
+ // add the clause
+ vTemp->nSize = 0;
+ for ( i = 0; i < vVars->nSize; i++, pChar++ )
+ if ( *pChar == '0' )
+ Vec_IntPush( vTemp, toLit(vVars->pArray[i]) );
+ else if ( *pChar == '1' )
+ Vec_IntPush( vTemp, neg(toLit(vVars->pArray[i])) );
+ // add the clause to the solver
+ RetValue = solver_addclause( pSat, vTemp->pArray, vTemp->pArray + vTemp->nSize );
+ assert( RetValue != 1 );
+ // check that the remainig part is fine
+ assert( *pChar == ' ' );
+ pChar++;
+ assert( *pChar == '1' );
+ pChar++;
+ assert( *pChar == '\n' );
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcStrash.c b/src/base/abc/abcStrash.c
new file mode 100644
index 00000000..eb5b3df7
--- /dev/null
+++ b/src/base/abc/abcStrash.c
@@ -0,0 +1,541 @@
+/**CFile****************************************************************
+
+ FileName [aigStrash.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Strashing of the current network.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: aigStrash.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "extra.h"
+#include "ft.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// static functions
+static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig );
+static Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode );
+static Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop );
+static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop );
+
+static void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate );
+static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, bool fDuplicate );
+static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, int fDuplicate );
+
+extern char * Mio_GateReadSop( void * pGate );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates the strashed AIG network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkAig;
+ assert( !Abc_NtkIsNetlist(pNtk) );
+ if ( Abc_NtkIsLogicBdd(pNtk) )
+ {
+// printf( "Converting node functions from BDD to SOP.\n" );
+ Abc_NtkBddToSop(pNtk);
+ }
+ // print warning about choice nodes
+ if ( Abc_NtkCountChoiceNodes( pNtk ) )
+ printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
+ // perform strashing
+ pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_AIG );
+ Abc_NtkStrashPerform( pNtk, pNtkAig );
+ Abc_NtkFinalize( pNtk, pNtkAig );
+ // print warning about self-feed latches
+ if ( Abc_NtkCountSelfFeedLatches(pNtkAig) )
+ printf( "The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
+ // duplicate EXDC
+ if ( pNtk->pExdc )
+ pNtkAig->pExdc = Abc_NtkStrash( pNtk->pExdc );
+ // make sure everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkAig ) )
+ {
+ printf( "Abc_NtkStrash: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkAig );
+ return NULL;
+ }
+ return pNtkAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the network for strashing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
+{
+ ProgressBar * pProgress;
+ Abc_Aig_t * pMan = pNtkNew->pManFunc;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pNodeNew, * pObj;
+ int i;
+
+ // perform strashing
+ vNodes = Abc_NtkDfs( pNtk );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // get the node
+ pNode = vNodes->pArray[i];
+ assert( Abc_ObjIsNode(pNode) );
+ // strash the node
+ pNodeNew = Abc_NodeStrash( pMan, pNode );
+ // get the old object
+ if ( Abc_NtkIsNetlist(pNtk) )
+ pObj = Abc_ObjFanout0( pNode ); // the fanout net
+ else
+ pObj = vNodes->pArray[i]; // the node itself
+ // make sure the node is not yet strashed
+ assert( pObj->pCopy == NULL );
+ // mark the old object with the new AIG node
+ pObj->pCopy = pNodeNew;
+ }
+ Vec_PtrFree( vNodes );
+ Extra_ProgressBarStop( pProgress );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Strashes one logic node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
+{
+ int fUseFactor = 1;
+ char * pSop;
+
+ assert( Abc_ObjIsNode(pNode) );
+
+ // consider the case when the graph is an AIG
+ if ( Abc_NtkIsAig(pNode->pNtk) )
+ {
+// Abc_Obj_t * pChild0, * pChild1;
+// pChild0 = Abc_ObjFanin0(pNode);
+// pChild1 = Abc_ObjFanin1(pNode);
+ if ( Abc_NodeIsConst(pNode) )
+ return Abc_AigConst1(pMan);
+ return Abc_AigAnd( pMan,
+ Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
+ Abc_ObjNotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
+ }
+
+ // get the SOP of the node
+ if ( Abc_NtkIsLogicMap(pNode->pNtk) )
+ pSop = Mio_GateReadSop(pNode->pData);
+ else
+ pSop = pNode->pData;
+
+ // consider the cconstant node
+ if ( Abc_NodeIsConst(pNode) )
+ {
+ // check if the SOP is constant
+ if ( Abc_SopIsConst1(pSop) )
+ return Abc_AigConst1(pMan);
+ return Abc_ObjNot( Abc_AigConst1(pMan) );
+ }
+
+ // decide when to use factoring
+ if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 )
+ return Abc_NodeStrashFactor( pMan, pNode, pSop );
+ return Abc_NodeStrashSop( pMan, pNode, pSop );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Strashes one logic node using its SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop )
+{
+ Abc_Obj_t * pFanin, * pAnd, * pSum;
+ Abc_Obj_t * pConst1 = Abc_AigConst1(pMan);
+ char * pCube;
+ int i, nFanins;
+
+ // get the number of node's fanins
+ nFanins = Abc_ObjFaninNum( pNode );
+ assert( nFanins == Abc_SopGetVarNum(pSop) );
+ // go through the cubes of the node's SOP
+ pSum = Abc_ObjNot(pConst1);
+ Abc_SopForEachCube( pSop, nFanins, pCube )
+ {
+ // create the AND of literals
+ pAnd = pConst1;
+ Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net
+ {
+ if ( pCube[i] == '1' )
+ pAnd = Abc_AigAnd( pMan, pAnd, pFanin->pCopy );
+ else if ( pCube[i] == '0' )
+ pAnd = Abc_AigAnd( pMan, pAnd, Abc_ObjNot(pFanin->pCopy) );
+ }
+ // add to the sum of cubes
+ pSum = Abc_AigOr( pMan, pSum, pAnd );
+ }
+ // decide whether to complement the result
+ pCube = pSop;
+ if ( pCube[nFanins + 1] == '0' )
+ pSum = Abc_ObjNot(pSum);
+ return pSum;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Strashes one logic node using its SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pSop )
+{
+ Vec_Int_t * vForm;
+ Vec_Ptr_t * vAnds;
+ Abc_Obj_t * pAnd, * pAnd0, * pAnd1, * pFanin;
+ Ft_Node_t * pFtNode;
+ int i, nVars;
+
+ // derive the factored form
+ vForm = Ft_Factor( pSop );
+
+ // sanity checks
+ nVars = Ft_FactorGetNumVars( vForm );
+ assert( nVars >= 0 );
+ assert( vForm->nSize > nVars );
+ assert( nVars == Abc_ObjFaninNum(pRoot) );
+
+ // check for constant Andtion
+ pFtNode = Ft_NodeRead( vForm, 0 );
+ if ( pFtNode->fConst )
+ {
+ Vec_IntFree( vForm );
+ return Abc_ObjNotCond( Abc_AigConst1(pMan), pFtNode->fCompl );
+ }
+
+ // start the array of elementary variables
+ vAnds = Vec_PtrAlloc( 20 );
+ Abc_ObjForEachFanin( pRoot, pFanin, i )
+ Vec_PtrPush( vAnds, pFanin->pCopy );
+
+ // compute the Andtions of other nodes
+ for ( i = nVars; i < vForm->nSize; i++ )
+ {
+ pFtNode = Ft_NodeRead( vForm, i );
+ pAnd0 = Abc_ObjNotCond( vAnds->pArray[pFtNode->iFanin0], pFtNode->fCompl0 );
+ pAnd1 = Abc_ObjNotCond( vAnds->pArray[pFtNode->iFanin1], pFtNode->fCompl1 );
+ pAnd = Abc_AigAnd( pMan, pAnd0, pAnd1 );
+ Vec_PtrPush( vAnds, pAnd );
+ }
+ assert( vForm->nSize = vAnds->nSize );
+ Vec_PtrFree( vAnds );
+
+ // complement the result if necessary
+ pFtNode = Ft_NodeReadLast( vForm );
+ pAnd = Abc_ObjNotCond( pAnd, pFtNode->fCompl );
+ Vec_IntFree( vForm );
+ return pAnd;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Appends the second network to the first.]
+
+ Description [Modifies the first network by adding the logic of the second.
+ Does not add the COs of the second. Does not change the second network.
+ Returns 0 if the appending failed, 1 otherise.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
+{
+ int fCheck = 1;
+ Abc_Obj_t * pObj;
+ int i;
+ // the first network should be an AIG
+ assert( Abc_NtkIsAig(pNtk1) );
+ assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsAig(pNtk2) );
+ if ( Abc_NtkIsLogicBdd(pNtk2) )
+ {
+// printf( "Converting node functions from BDD to SOP.\n" );
+ Abc_NtkBddToSop(pNtk2);
+ }
+ // check that the networks have the same PIs
+ // reorder PIs of pNtk2 according to pNtk1
+ if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1 ) )
+ return 0;
+ // perform strashing
+ Abc_NtkCleanCopy( pNtk2 );
+ Abc_NtkForEachCi( pNtk2, pObj, i )
+ pObj->pCopy = Abc_NtkCi(pNtk1, i);
+ // add pNtk2 to pNtk1 while strashing
+ Abc_NtkStrashPerform( pNtk2, pNtk1 );
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtk1 ) )
+ {
+ printf( "Abc_NtkAppend: The network check has failed.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Balances the AIG network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkAig;
+ assert( Abc_NtkIsAig(pNtk) );
+ // perform balancing
+ pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_AIG );
+ Abc_NtkBalancePerform( pNtk, pNtkAig, fDuplicate );
+ Abc_NtkFinalize( pNtk, pNtkAig );
+ // make sure everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkAig ) )
+ {
+ printf( "Abc_NtkBalance: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkAig );
+ return NULL;
+ }
+ return pNtkAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Balances the AIG network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate )
+{
+ int fCheck = 1;
+ ProgressBar * pProgress;
+ Abc_Obj_t * pNode, * pDriver;
+ int i;
+
+ // copy the constant node
+ Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkAig->pManFunc);
+ // set the level of PIs of AIG according to the arrival times of the old network
+ Abc_NtkSetNodeLevelsArrival( pNtk );
+ // perform balancing of POs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // strash the driver node
+ pDriver = Abc_ObjFanin0(pNode);
+ Abc_NodeBalance_rec( pNtkAig, pDriver, fDuplicate );
+ }
+ Extra_ProgressBarStop( pProgress );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Rebalances the multi-input node rooted at pNodeOld.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, bool fDuplicate )
+{
+ Abc_Aig_t * pMan = pNtkNew->pManFunc;
+ Abc_Obj_t * pNodeNew, * pNode1, * pNode2;
+ Vec_Ptr_t * vSuper;
+ int i;
+ assert( !Abc_ObjIsComplement(pNodeOld) );
+ // return if the result if known
+ if ( pNodeOld->pCopy )
+ return pNodeOld->pCopy;
+ assert( Abc_ObjIsNode(pNodeOld) );
+ // get the implication supergate
+ vSuper = Abc_NodeBalanceCone( pNodeOld, fDuplicate );
+ if ( vSuper->nSize == 0 )
+ { // it means that the supergate contains two nodes in the opposite polarity
+ Vec_PtrFree( vSuper );
+ pNodeOld->pCopy = Abc_ObjNot(Abc_AigConst1(pMan));
+ return pNodeOld->pCopy;
+ }
+ // for each old node, derive the new well-balanced node
+ for ( i = 0; i < vSuper->nSize; i++ )
+ {
+ pNodeNew = Abc_NodeBalance_rec( pNtkNew, Abc_ObjRegular(vSuper->pArray[i]), fDuplicate );
+ vSuper->pArray[i] = Abc_ObjNotCond( pNodeNew, Abc_ObjIsComplement(vSuper->pArray[i]) );
+ }
+ // sort the new nodes by level in the decreasing order
+ Vec_PtrSort( vSuper, Abc_NodeCompareLevelsDecrease );
+ // balance the nodes
+ assert( vSuper->nSize > 1 );
+ while ( vSuper->nSize > 1 )
+ {
+ pNode1 = Vec_PtrPop(vSuper);
+ pNode2 = Vec_PtrPop(vSuper);
+ Abc_VecObjPushUniqueOrderByLevel( vSuper, Abc_AigAnd(pMan, pNode1, pNode2) );
+ }
+ // make sure the balanced node is not assigned
+ assert( pNodeOld->pCopy == NULL );
+ // mark the old node with the new node
+ pNodeOld->pCopy = vSuper->pArray[0];
+ Vec_PtrFree( vSuper );
+ return pNodeOld->pCopy;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collects the nodes in the cone delimited by fMarkA==1.]
+
+ Description [Returns -1 if the AND-cone has the same node in both polarities.
+ Returns 1 if the AND-cone has the same node in the same polarity. Returns 0
+ if the AND-cone has no repeated nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate )
+{
+ Abc_Obj_t * p0, * p1;
+ int RetValue1, RetValue2, i;
+ // check if the node is visited
+ if ( Abc_ObjRegular(pNode)->fMarkB )
+ {
+ // check if the node occurs in the same polarity
+ for ( i = 0; i < vSuper->nSize; i++ )
+ if ( vSuper->pArray[i] == pNode )
+ return 1;
+ // check if the node is present in the opposite polarity
+ for ( i = 0; i < vSuper->nSize; i++ )
+ if ( vSuper->pArray[i] == Abc_ObjNot(pNode) )
+ return -1;
+ assert( 0 );
+ return 0;
+ }
+ // if the new node is complemented or a PI, another gate begins
+ if ( !fFirst && (Abc_ObjIsComplement(pNode) || !Abc_ObjIsNode(pNode) || !fDuplicate && (Abc_ObjFanoutNum(pNode) > 1)) )
+ {
+ Vec_PtrPush( vSuper, pNode );
+ Abc_ObjRegular(pNode)->fMarkB = 1;
+ return 0;
+ }
+ assert( !Abc_ObjIsComplement(pNode) );
+ assert( Abc_ObjIsNode(pNode) );
+ // get the children
+ p0 = Abc_ObjNotCond( Abc_ObjFanin0(pNode), Abc_ObjFaninC0(pNode) );
+ p1 = Abc_ObjNotCond( Abc_ObjFanin1(pNode), Abc_ObjFaninC1(pNode) );
+ // go through the branches
+ RetValue1 = Abc_NodeBalanceCone_rec( p0, vSuper, 0, fDuplicate );
+ RetValue2 = Abc_NodeBalanceCone_rec( p1, vSuper, 0, fDuplicate );
+ if ( RetValue1 == -1 || RetValue2 == -1 )
+ return -1;
+ // return 1 if at least one branch has a duplicate
+ return RetValue1 || RetValue2;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the nodes in the cone delimited by fMarkA==1.]
+
+ Description [Returns -1 if the AND-cone has the same node in both polarities.
+ Returns 1 if the AND-cone has the same node in the same polarity. Returns 0
+ if the AND-cone has no repeated nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, int fDuplicate )
+{
+ Vec_Ptr_t * vNodes;
+ int RetValue, i;
+ assert( !Abc_ObjIsComplement(pNode) );
+ vNodes = Vec_PtrAlloc( 4 );
+ RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, fDuplicate );
+ assert( vNodes->nSize > 0 );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ Abc_ObjRegular((Abc_Obj_t *)vNodes->pArray[i])->fMarkB = 0;
+ if ( RetValue == -1 )
+ vNodes->nSize = 0;
+ return vNodes;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcSweep.c b/src/base/abc/abcSweep.c
new file mode 100644
index 00000000..6890fc57
--- /dev/null
+++ b/src/base/abc/abcSweep.c
@@ -0,0 +1,434 @@
+/**CFile****************************************************************
+
+ FileName [abcDsd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Technology dependent sweep.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fraig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static stmm_table * Abc_NtkFraigEquiv( Fraig_Man_t * p, Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose );
+static void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose );
+static void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fVerbose, int fUseInv );
+static void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fVerbose, int fUseInv );
+static int Abc_NodeDroppingCost( Abc_Obj_t * pNode );
+
+extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Sweping functionally equivalence nodes.]
+
+ Description [Removes gates with equivalent functionality. Works for
+ both technology-independent and mapped networks. If the flag is set,
+ allows adding inverters at the gate outputs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose )
+{
+ int fCheck = 1;
+ Fraig_Params_t Params;
+ Abc_Ntk_t * pNtkAig;
+ Fraig_Man_t * pMan;
+ stmm_table * tEquiv;
+
+ assert( !Abc_NtkIsAig(pNtk) );
+
+ // derive the AIG
+ pNtkAig = Abc_NtkStrash( pNtk );
+ // perform fraiging of the AIG
+ Fraig_ParamsSetDefault( &Params );
+ pMan = Abc_NtkToFraig( pNtkAig, &Params, 0 );
+ // collect the classes of equivalent nets
+ tEquiv = Abc_NtkFraigEquiv( pMan, pNtk, fUseInv, fVerbose );
+
+ // transform the network into the equivalent one
+ Abc_NtkFraigTransform( pNtk, tEquiv, fUseInv, fVerbose );
+ stmm_free_table( tEquiv );
+
+ // free the manager
+ Fraig_ManFree( pMan );
+ Abc_NtkDelete( pNtkAig );
+
+ // cleanup the dangling nodes
+ Abc_NtkCleanup( pNtk, fVerbose );
+ // check
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkFraigSweep: The network check has failed.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects equivalence classses of node in the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+stmm_table * Abc_NtkFraigEquiv( Fraig_Man_t * p, Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose )
+{
+ Abc_Obj_t * pList, * pNode, * pNodeAig;
+ Fraig_Node_t * gNode;
+ Abc_Obj_t ** ppSlot;
+ stmm_table * tStrash2Net;
+ stmm_table * tResult;
+ stmm_generator * gen;
+ int c, Counter;
+
+ // create mapping of strashed nodes into the corresponding network nodes
+ tStrash2Net = stmm_init_table(stmm_ptrcmp,stmm_ptrhash);
+ Abc_NtkForEachNode( pNtk, pNode, c )
+ {
+ // get the strashed node
+ pNodeAig = pNode->pCopy;
+ // skip the dangling nodes
+ if ( pNodeAig == NULL )
+ continue;
+ // skip the constant input nodes
+ if ( Abc_ObjFaninNum(pNode) == 0 )
+ continue;
+ // skip the nodes that fanout into POs
+ if ( Abc_NtkIsLogicMap(pNtk) && Abc_NodeHasUniqueNamedFanout(pNode) )
+ continue;
+ // get the FRAIG node
+ gNode = Fraig_NotCond( Abc_ObjRegular(pNodeAig)->pCopy, Abc_ObjIsComplement(pNodeAig) );
+ if ( !stmm_find_or_add( tStrash2Net, (char *)Fraig_Regular(gNode), (char ***)&ppSlot ) )
+ *ppSlot = NULL;
+ // add the node to the list
+ pNode->pNext = *ppSlot;
+ *ppSlot = pNode;
+ // mark the node if it is complemented
+ pNode->fPhase = Fraig_IsComplement(gNode);
+ }
+
+ // print the classes
+ c = 0;
+ Counter = 0;
+ tResult = stmm_init_table(stmm_ptrcmp,stmm_ptrhash);
+ stmm_foreach_item( tStrash2Net, gen, (char **)&gNode, (char **)&pList )
+ {
+ // skip the trival classes
+ if ( pList == NULL || pList->pNext == NULL )
+ continue;
+ // add the non-trival class
+ stmm_insert( tResult, (char *)pList, NULL );
+ // count nodes in the non-trival classes
+ for ( pNode = pList; pNode; pNode = pNode->pNext )
+ Counter++;
+/*
+ if ( fVerbose )
+ {
+ printf( "Class %2d : {", c );
+ for ( pNode = pList; pNode; pNode = pNode->pNext )
+ {
+ pNode->pCopy = NULL;
+ printf( " %s", Abc_ObjName(pNode) );
+ if ( pNode->fPhase ) printf( "(*)" );
+ }
+ printf( " }\n" );
+ c++;
+ }
+*/
+ }
+ if ( fVerbose )
+ {
+ printf( "Sweeping stats for network \"%s\":\n", pNtk->pName );
+ printf( "Internal nodes = %d. Different functions (up to compl) = %d.\n", Abc_NtkNodeNum(pNtk), stmm_count(tStrash2Net) );
+ printf( "Non-trivial classes = %d. Nodes in non-trivial classes = %d.\n", stmm_count(tResult), Counter );
+ }
+ stmm_free_table( tStrash2Net );
+ return tResult;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the network using the equivalence relation on nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose )
+{
+ stmm_generator * gen;
+ Abc_Obj_t * pList;
+ if ( stmm_count(tEquiv) == 0 )
+ return;
+ // assign levels to the nodes of the network
+ Abc_NtkGetLevelNum( pNtk );
+ // merge nodes in the classes
+ if ( Abc_NtkIsLogicMap( pNtk ) )
+ {
+ Abc_NtkDelayTrace( pNtk );
+ stmm_foreach_item( tEquiv, gen, (char **)&pList, NULL )
+ Abc_NtkFraigMergeClassMapped( pNtk, pList, fUseInv, fVerbose );
+ }
+ else
+ {
+ stmm_foreach_item( tEquiv, gen, (char **)&pList, NULL )
+ Abc_NtkFraigMergeClass( pNtk, pList, fUseInv, fVerbose );
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the list of one-phase equivalent nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose )
+{
+ Abc_Obj_t * pListDir, * pListInv;
+ Abc_Obj_t * pNodeMin, * pNode, * pNext;
+ float Arrival1, Arrival2;
+
+ assert( pChain );
+ assert( pChain->pNext );
+
+ // divide the nodes into two parts:
+ // those that need the invertor and those that don't need
+ pListDir = pListInv = NULL;
+ for ( pNode = pChain, pNext = pChain->pNext;
+ pNode;
+ pNode = pNext, pNext = pNode? pNode->pNext : NULL )
+ {
+ // check to which class the node belongs
+ if ( pNode->fPhase == 1 )
+ {
+ pNode->pNext = pListDir;
+ pListDir = pNode;
+ }
+ else
+ {
+ pNode->pNext = pListInv;
+ pListInv = pNode;
+ }
+ }
+
+ // find the node with the smallest number of logic levels
+ pNodeMin = pListDir;
+ for ( pNode = pListDir; pNode; pNode = pNode->pNext )
+ {
+ Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst;
+ Arrival2 = Abc_NodeReadArrival(pNode )->Worst;
+ assert( Abc_ObjIsPi(pNodeMin) || Arrival1 > 0 );
+ assert( Abc_ObjIsPi(pNode) || Arrival2 > 0 );
+ if ( Arrival1 > Arrival2 ||
+ Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level ||
+ Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level &&
+ Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) )
+ pNodeMin = pNode;
+ }
+
+ // move the fanouts of the direct nodes
+ for ( pNode = pListDir; pNode; pNode = pNode->pNext )
+ if ( pNode != pNodeMin )
+ Abc_ObjTransferFanout( pNode, pNodeMin );
+
+ // find the node with the smallest number of logic levels
+ pNodeMin = pListInv;
+ for ( pNode = pListInv; pNode; pNode = pNode->pNext )
+ {
+ Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst;
+ Arrival2 = Abc_NodeReadArrival(pNode )->Worst;
+ assert( Abc_ObjIsPi(pNodeMin) || Arrival1 > 0 );
+ assert( Abc_ObjIsPi(pNode) || Arrival2 > 0 );
+ if ( Arrival1 > Arrival2 ||
+ Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level ||
+ Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level &&
+ Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) )
+ pNodeMin = pNode;
+ }
+
+ // move the fanouts of the direct nodes
+ for ( pNode = pListInv; pNode; pNode = pNode->pNext )
+ if ( pNode != pNodeMin )
+ Abc_ObjTransferFanout( pNode, pNodeMin );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Process one equivalence class of nodes.]
+
+ Description [This function does not remove the nodes. It only switches
+ around the connections.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose )
+{
+ Abc_Obj_t * pListDir, * pListInv;
+ Abc_Obj_t * pNodeMin, * pNodeMinInv;
+ Abc_Obj_t * pNode, * pNext;
+
+ assert( pChain );
+ assert( pChain->pNext );
+
+ // find the node with the smallest number of logic levels
+ pNodeMin = pChain;
+ for ( pNode = pChain->pNext; pNode; pNode = pNode->pNext )
+ if ( pNodeMin->Level > pNode->Level ||
+ ( pNodeMin->Level == pNode->Level &&
+ Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) ) )
+ pNodeMin = pNode;
+
+ // divide the nodes into two parts:
+ // those that need the invertor and those that don't need
+ pListDir = pListInv = NULL;
+ for ( pNode = pChain, pNext = pChain->pNext;
+ pNode;
+ pNode = pNext, pNext = pNode? pNode->pNext : NULL )
+ {
+ if ( pNode == pNodeMin )
+ continue;
+ // check to which class the node belongs
+ if ( pNodeMin->fPhase == pNode->fPhase )
+ {
+ pNode->pNext = pListDir;
+ pListDir = pNode;
+ }
+ else
+ {
+ pNode->pNext = pListInv;
+ pListInv = pNode;
+ }
+ }
+
+ // move the fanouts of the direct nodes
+ for ( pNode = pListDir; pNode; pNode = pNode->pNext )
+ Abc_ObjTransferFanout( pNode, pNodeMin );
+
+ // skip if there are no inverted nodes
+ if ( pListInv == NULL )
+ return;
+
+ // add the invertor
+ pNodeMinInv = Abc_NodeCreateInv( pNtk, pNodeMin );
+
+ // move the fanouts of the inverted nodes
+ for ( pNode = pListInv; pNode; pNode = pNode->pNext )
+ Abc_ObjTransferFanout( pNode, pNodeMinInv );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of literals saved if this node becomes useless.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeDroppingCost( Abc_Obj_t * pNode )
+{
+ return 1;
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Removes dangling nodes.]
+
+ Description [Returns the number of nodes removed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ int fCheck = 1;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode;
+ int i, Counter;
+ // mark the nodes reachable from the POs
+ vNodes = Abc_NtkDfs( pNtk );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ pNode = vNodes->pArray[i];
+ pNode->fMarkA = 1;
+ }
+ Vec_PtrFree( vNodes );
+ // if it is an AIG, also mark the constant 1 node
+ if ( Abc_NtkIsAig(pNtk) )
+ Abc_AigConst1(pNtk->pManFunc)->fMarkA = 1;
+ // remove the non-marked nodes
+ Counter = 0;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ if ( pNode->fMarkA == 0 )
+ {
+ Abc_NtkDeleteObj( pNode );
+ Counter++;
+ }
+ // unmark the remaining nodes
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ pNode->fMarkA = 0;
+ if ( fVerbose )
+ printf( "Cleanup removed %d dangling nodes.\n", Counter );
+ // check
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkCleanup: The network check has failed.\n" );
+ return -1;
+ }
+ return Counter;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcTiming.c b/src/base/abc/abcTiming.c
new file mode 100644
index 00000000..f017d93c
--- /dev/null
+++ b/src/base/abc/abcTiming.c
@@ -0,0 +1,631 @@
+/**CFile****************************************************************
+
+ FileName [abcTiming.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Computation of timing info for mapped circuits.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcTiming.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "main.h"
+#include "mio.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct Abc_ManTime_t_
+{
+ Abc_Time_t tArrDef;
+ Abc_Time_t tReqDef;
+ Vec_Ptr_t * vArrs;
+ Vec_Ptr_t * vReqs;
+};
+
+// static functions
+static Abc_ManTime_t * Abc_ManTimeStart();
+static void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive );
+static void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk );
+
+static void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode );
+
+// accessing the arrival and required times of a node
+static inline Abc_Time_t * Abc_NodeArrival( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vArrs->pArray[pNode->Id]; }
+static inline Abc_Time_t * Abc_NodeRequired( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vReqs->pArray[pNode->Id]; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode )
+{
+ assert( pNode->pNtk->pManTime );
+ return Abc_NodeArrival(pNode);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode )
+{
+ assert( pNode->pNtk->pManTime );
+ return Abc_NodeRequired(pNode);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NtkReadDefaultArrival( Abc_Ntk_t * pNtk )
+{
+ assert( pNtk->pManTime );
+ return &pNtk->pManTime->tArrDef;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk )
+{
+ assert( pNtk->pManTime );
+ return &pNtk->pManTime->tReqDef;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the default arrival time for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetDefaultArrival( Abc_Ntk_t * pNtk, float Rise, float Fall )
+{
+ if ( Rise == 0.0 && Fall == 0.0 )
+ return;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ pNtk->pManTime->tArrDef.Rise = Rise;
+ pNtk->pManTime->tArrDef.Fall = Fall;
+ pNtk->pManTime->tArrDef.Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the default arrival time for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall )
+{
+ if ( Rise == 0.0 && Fall == 0.0 )
+ return;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ pNtk->pManTime->tReqDef.Rise = Rise;
+ pNtk->pManTime->tReqDef.Rise = Fall;
+ pNtk->pManTime->tReqDef.Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the arrival time for an object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall )
+{
+ Vec_Ptr_t * vTimes;
+ Abc_Time_t * pTime;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ if ( pNtk->pManTime->tArrDef.Rise == Rise && pNtk->pManTime->tArrDef.Fall == Fall )
+ return;
+ Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 );
+ // set the arrival time
+ vTimes = pNtk->pManTime->vArrs;
+ pTime = vTimes->pArray[ObjId];
+ pTime->Rise = Rise;
+ pTime->Fall = Rise;
+ pTime->Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the arrival time for an object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall )
+{
+ Vec_Ptr_t * vTimes;
+ Abc_Time_t * pTime;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ if ( pNtk->pManTime->tReqDef.Rise == Rise && pNtk->pManTime->tReqDef.Fall == Fall )
+ return;
+ Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 );
+ // set the required time
+ vTimes = pNtk->pManTime->vReqs;
+ pTime = vTimes->pArray[ObjId];
+ pTime->Rise = Rise;
+ pTime->Fall = Rise;
+ pTime->Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finalizes the timing manager after setting arr/req times.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeFinalize( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ Abc_Time_t ** ppTimes, * pTime;
+ int i;
+ if ( pNtk->pManTime == NULL )
+ return;
+ Abc_ManTimeExpand( pNtk->pManTime, Abc_NtkObjNum(pNtk), 0 );
+ // set the default timing
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ if ( pTime->Worst != -ABC_INFINITY )
+ continue;
+ *pTime = pNtk->pManTime->tArrDef;
+ }
+ // set the default timing
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vReqs->pArray;
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ if ( pTime->Worst != -ABC_INFINITY )
+ continue;
+ *pTime = pNtk->pManTime->tArrDef;
+ }
+ // set the 0 arrival times for latches and constant nodes
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ pTime->Fall = pTime->Rise = pTime->Worst = 0.0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the timing manager for delay trace.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ Abc_Time_t ** ppTimes, * pTime;
+ int i;
+ // if there is no timing manager, allocate and initialize
+ if ( pNtk->pManTime == NULL )
+ {
+ pNtk->pManTime = Abc_ManTimeStart();
+ Abc_NtkTimeFinalize( pNtk );
+ return;
+ }
+ // if timing manager is given, clean arrivals except for PIs
+ // and required except for POs
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
+ }
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
+ }
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_ManTime_t * Abc_ManTimeStart()
+{
+ Abc_ManTime_t * p;
+ p = ALLOC( Abc_ManTime_t, 1 );
+ memset( p, 0, sizeof(Abc_ManTime_t) );
+ p->vArrs = Vec_PtrAlloc( 0 );
+ p->vReqs = Vec_PtrAlloc( 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManTimeStop( Abc_ManTime_t * p )
+{
+ if ( p->vArrs->nSize > 0 )
+ {
+ free( p->vArrs->pArray[0] );
+ Vec_PtrFree( p->vArrs );
+ }
+ if ( p->vReqs->nSize > 0 )
+ {
+ free( p->vReqs->pArray[0] );
+ Vec_PtrFree( p->vReqs );
+ }
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the timing manager with the PI/PO timing info.]
+
+ Description [The PIs/POs of the new network should be allocated.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew )
+{
+ Abc_Obj_t * pObj;
+ Abc_Time_t ** ppTimesOld, ** ppTimesNew;
+ int i;
+ if ( pNtkOld->pManTime == NULL )
+ return;
+ assert( Abc_NtkPiNum(pNtkOld) == Abc_NtkPiNum(pNtkNew) );
+ assert( Abc_NtkPoNum(pNtkOld) == Abc_NtkPoNum(pNtkNew) );
+ assert( Abc_NtkLatchNum(pNtkOld) == Abc_NtkLatchNum(pNtkNew) );
+ // create the new timing manager
+ pNtkNew->pManTime = Abc_ManTimeStart();
+ Abc_ManTimeExpand( pNtkNew->pManTime, Abc_NtkObjNum(pNtkNew), 0 );
+ // set the default timing
+ pNtkNew->pManTime->tArrDef = pNtkOld->pManTime->tArrDef;
+ pNtkNew->pManTime->tReqDef = pNtkOld->pManTime->tReqDef;
+ // set the PI timing
+ ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vArrs->pArray;
+ ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vArrs->pArray;
+ Abc_NtkForEachPi( pNtkOld, pObj, i )
+ *ppTimesNew[ Abc_NtkPi(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
+ // set the PO timing
+ ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vReqs->pArray;
+ ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vReqs->pArray;
+ Abc_NtkForEachPo( pNtkOld, pObj, i )
+ *ppTimesNew[ Abc_NtkPo(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive )
+{
+ Vec_Ptr_t * vTimes;
+ Abc_Time_t * ppTimes, * ppTimesOld, * pTime;
+ int nSizeOld, nSizeNew, i;
+
+ nSizeOld = p->vArrs->nSize;
+ if ( nSizeOld >= nSize )
+ return;
+ nSizeNew = fProgressive? 2 * nSize : nSize;
+ if ( nSizeNew < 100 )
+ nSizeNew = 100;
+
+ vTimes = p->vArrs;
+ Vec_PtrGrow( vTimes, nSizeNew );
+ vTimes->nSize = nSizeNew;
+ ppTimesOld = ( nSizeOld == 0 )? NULL : vTimes->pArray[0];
+ ppTimes = REALLOC( Abc_Time_t, ppTimesOld, nSizeNew );
+ for ( i = 0; i < nSizeNew; i++ )
+ vTimes->pArray[i] = ppTimes + i;
+ for ( i = nSizeOld; i < nSizeNew; i++ )
+ {
+ pTime = vTimes->pArray[i];
+ pTime->Rise = -ABC_INFINITY;
+ pTime->Fall = -ABC_INFINITY;
+ pTime->Worst = -ABC_INFINITY;
+ }
+
+ vTimes = p->vReqs;
+ Vec_PtrGrow( vTimes, nSizeNew );
+ vTimes->nSize = nSizeNew;
+ ppTimesOld = ( nSizeOld == 0 )? NULL : vTimes->pArray[0];
+ ppTimes = REALLOC( Abc_Time_t, ppTimesOld, nSizeNew );
+ for ( i = 0; i < nSizeNew; i++ )
+ vTimes->pArray[i] = ppTimes + i;
+ for ( i = nSizeOld; i < nSizeNew; i++ )
+ {
+ pTime = vTimes->pArray[i];
+ pTime->Rise = -ABC_INFINITY;
+ pTime->Fall = -ABC_INFINITY;
+ pTime->Worst = -ABC_INFINITY;
+ }
+}
+
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Sets the CI node levels according to the arrival info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtkOld )
+{
+ Abc_Obj_t * pNodeOld, * pNodeNew;
+ float tAndDelay;
+ int i;
+ if ( pNtkOld->pManTime == NULL )
+ return;
+ if ( Mio_LibraryReadNand2(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) == NULL )
+ return;
+ tAndDelay = Mio_LibraryReadDelayNand2Max(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
+ Abc_NtkForEachPi( pNtkOld, pNodeOld, i )
+ {
+ pNodeNew = pNodeOld->pCopy;
+ pNodeNew->Level = (int)(Abc_NodeArrival(pNodeOld)->Worst / tAndDelay);
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the CI node levels according to the arrival info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NtkGetCiArrivalTimes( Abc_Ntk_t * pNtk )
+{
+ Abc_Time_t * p;
+ Abc_Obj_t * pNode;
+ int i;
+ p = ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtk) );
+ memset( p, 0, sizeof(Abc_Time_t) * Abc_NtkCiNum(pNtk) );
+ if ( pNtk->pManTime == NULL )
+ return p;
+ // set the PI arrival times
+ Abc_NtkForEachPi( pNtk, pNode, i )
+ p[i] = *Abc_NodeArrival(pNode);
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Sets the CI node levels according to the arrival info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk )
+{
+ float * p;
+ Abc_Obj_t * pNode;
+ int i;
+ p = ALLOC( float, Abc_NtkCiNum(pNtk) );
+ memset( p, 0, sizeof(float) * Abc_NtkCiNum(pNtk) );
+ if ( pNtk->pManTime == NULL )
+ return p;
+ // set the PI arrival times
+ Abc_NtkForEachPi( pNtk, pNode, i )
+ p[i] = Abc_NodeArrival(pNode)->Worst;
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode, * pDriver;
+ Vec_Ptr_t * vNodes;
+ Abc_Time_t * pTime;
+ float tArrivalMax;
+ int i;
+
+ assert( Abc_NtkIsLogicMap(pNtk) );
+
+ Abc_NtkTimePrepare( pNtk );
+ vNodes = Abc_NtkDfs( pNtk );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ Abc_NodeDelayTraceArrival( vNodes->pArray[i] );
+ Vec_PtrFree( vNodes );
+
+ // get the latest arrival times
+ tArrivalMax = -ABC_INFINITY;
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ pDriver = Abc_ObjFanin0(pNode);
+ pTime = Abc_NodeArrival(pDriver);
+ if ( tArrivalMax < pTime->Worst )
+ tArrivalMax = pTime->Worst;
+ }
+ return tArrivalMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pFanin;
+ Abc_Time_t * pTimeIn, * pTimeOut;
+ float tDelayBlockRise, tDelayBlockFall;
+ Mio_PinPhase_t PinPhase;
+ Mio_Pin_t * pPin;
+ int i;
+
+ // start the arrival time of the node
+ pTimeOut = Abc_NodeArrival(pNode);
+ pTimeOut->Rise = pTimeOut->Fall = 0;
+ // go through the pins of the gate
+ pPin = Mio_GateReadPins(pNode->pData);
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ pTimeIn = Abc_NodeArrival(pFanin);
+ assert( pTimeIn->Worst != -ABC_INFINITY );
+ // get the interesting parameters of this pin
+ PinPhase = Mio_PinReadPhase(pPin);
+ tDelayBlockRise = (float)Mio_PinReadDelayBlockRise( pPin );
+ tDelayBlockFall = (float)Mio_PinReadDelayBlockFall( pPin );
+ // compute the arrival times of the positive phase
+ if ( PinPhase != MIO_PHASE_INV ) // NONINV phase is present
+ {
+ if ( pTimeOut->Rise < pTimeIn->Rise + tDelayBlockRise )
+ pTimeOut->Rise = pTimeIn->Rise + tDelayBlockRise;
+ if ( pTimeOut->Fall < pTimeIn->Fall + tDelayBlockFall )
+ pTimeOut->Fall = pTimeIn->Fall + tDelayBlockFall;
+ }
+ if ( PinPhase != MIO_PHASE_NONINV ) // INV phase is present
+ {
+ if ( pTimeOut->Rise < pTimeIn->Fall + tDelayBlockRise )
+ pTimeOut->Rise = pTimeIn->Fall + tDelayBlockRise;
+ if ( pTimeOut->Fall < pTimeIn->Rise + tDelayBlockFall )
+ pTimeOut->Fall = pTimeIn->Rise + tDelayBlockFall;
+ }
+ pPin = Mio_PinReadNext(pPin);
+ }
+ pTimeOut->Worst = ABC_MAX( pTimeOut->Rise, pTimeOut->Fall );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c
new file mode 100644
index 00000000..1c826f95
--- /dev/null
+++ b/src/base/abc/abcUtil.c
@@ -0,0 +1,780 @@
+/**CFile****************************************************************
+
+ FileName [abcUtils.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Various utilities.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "main.h"
+#include "mio.h"
+#include "ft.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fFanouts, bool fReference );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Increments the current traversal ID of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int i;
+ if ( pNtk->nTravIds == (1<<12)-1 )
+ {
+ pNtk->nTravIds = 0;
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ pObj->TravId = 0;
+ }
+ pNtk->nTravIds++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the number of cubes of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, nCubes = 0;
+ assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ assert( pNode->pData );
+ nCubes += Abc_SopGetCubeNum( pNode->pData );
+ }
+ return nCubes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the number of cubes of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, nLits = 0;
+ assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsLogicSop(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ assert( pNode->pData );
+ nLits += Abc_SopGetLitNum( pNode->pData );
+ }
+ return nLits;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of literals in the factored forms.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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) );
+ nNodes = 0;
+// Ft_FactorStartMan();
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ vFactor = Ft_Factor( pNode->pData );
+ nNodes += Ft_FactorGetNumNodes(vFactor);
+ Vec_IntFree( vFactor );
+ }
+// Ft_FactorStopMan();
+ return nNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the number of BDD nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, nNodes = 0;
+ assert( Abc_NtkIsLogicBdd(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ assert( pNode->pData );
+ nNodes += pNode->pData? Cudd_DagSize( pNode->pData ) : 0;
+ }
+ return nNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the number of BDD nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ DdNode * bCover, * zCover, * bFunc;
+ DdManager * dd = pNtk->pManFunc;
+ int i, nClauses = 0;
+ assert( Abc_NtkIsLogicBdd(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ assert( pNode->pData );
+ bFunc = pNode->pData;
+
+ bCover = Cudd_zddIsop( dd, bFunc, bFunc, &zCover );
+ Cudd_Ref( bCover );
+ Cudd_Ref( zCover );
+ nClauses += Abc_CountZddCubes( dd, zCover );
+ Cudd_RecursiveDeref( dd, bCover );
+ Cudd_RecursiveDerefZdd( dd, zCover );
+
+ bCover = Cudd_zddIsop( dd, Cudd_Not(bFunc), Cudd_Not(bFunc), &zCover );
+ Cudd_Ref( bCover );
+ Cudd_Ref( zCover );
+ nClauses += Abc_CountZddCubes( dd, zCover );
+ Cudd_RecursiveDeref( dd, bCover );
+ Cudd_RecursiveDerefZdd( dd, zCover );
+ }
+ return nClauses;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the area of the mapped circuit.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ double TotalArea;
+ int i;
+ assert( Abc_NtkIsLogicMap(pNtk) );
+ TotalArea = 0.0;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ assert( pNode->pData );
+ TotalArea += Mio_GateReadArea( pNode->pData );
+ }
+ return TotalArea;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the maximum number of fanins.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, nFaninsMax = 0;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( nFaninsMax < Abc_ObjFaninNum(pNode) )
+ nFaninsMax = Abc_ObjFaninNum(pNode);
+ }
+ return nFaninsMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Cleans the copy field of all objects.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int i;
+ i = 0;
+ // set the data filed to NULL
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ pObj->pCopy = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the internal node has a unique CO.]
+
+ Description [Checks if the internal node can borrow a name from a CO
+ fanout. This is possible if there is only one CO with non-complemented
+ fanin edge pointing to this node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeHasUniqueNamedFanout( Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pFanout, * pFanoutNamed;
+ 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) )
+ {
+ assert( Abc_ObjFaninNum(pFanout) == 1 );
+ assert( Abc_ObjFanin0(pFanout) == pNode );
+ pFanoutNamed = pFanout;
+ Counter++;
+ }
+ }
+ if ( Counter == 1 )
+ return pFanoutNamed;
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the PO names can be written directly.]
+
+ 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.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkLogicHasSimplePos( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ assert( !Abc_NtkIsNetlist(pNtk) );
+ // check if there are complemented or idential POs
+ Abc_NtkIncrementTravId( pNtk );
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ {
+ pNode = Abc_ObjChild0(pNode);
+ if ( Abc_ObjIsComplement(pNode) )
+ return 0;
+ if ( Abc_NodeIsTravIdCurrent(pNode) )
+ return 0;
+ Abc_NodeSetTravIdCurrent(pNode);
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the network to have simple POs.]
+
+ 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.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkLogicMakeSimplePos( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode, * pDriver, * pDriverDup, * pFanin;
+ int i, k, nDupGates = 0;
+ assert( Abc_NtkIsLogic(pNtk) );
+ // if a PO driver has more than one fanout, duplicate it
+ 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 );
+ // update the fanin of the PO node
+ Abc_ObjPatchFanin( pNode, pDriver, pDriverDup );
+ assert( Abc_ObjFanoutNum(pDriverDup) == 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) );
+ }
+ return nDupGates;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Inserts a new node in the order by levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_VecObjPushUniqueOrderByLevel( Vec_Ptr_t * p, Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pNode1, * pNode2;
+ int i;
+ if ( Vec_PtrPushUnique(p, pNode) )
+ return;
+ // find the p of the node
+ for ( i = p->nSize-1; i > 0; i-- )
+ {
+ pNode1 = p->pArray[i ];
+ pNode2 = p->pArray[i-1];
+ if ( Abc_ObjRegular(pNode1)->Level <= Abc_ObjRegular(pNode2)->Level )
+ break;
+ p->pArray[i ] = pNode2;
+ p->pArray[i-1] = pNode1;
+ }
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
+
+ Description [The node can be complemented.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NodeIsMuxType( Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pNode0, * pNode1;
+ // check that the node is regular
+ assert( !Abc_ObjIsComplement(pNode) );
+ // if the node is not AND, this is not MUX
+ if ( !Abc_NodeIsAnd(pNode) )
+ return 0;
+ // if the children are not complemented, this is not MUX
+ if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
+ return 0;
+ // get children
+ pNode0 = Abc_ObjFanin0(pNode);
+ pNode1 = Abc_ObjFanin1(pNode);
+ // if the children are not ANDs, this is not MUX
+ if ( Abc_ObjFaninNum(pNode0) != 2 || Abc_ObjFaninNum(pNode1) != 2 )
+ return 0;
+ // otherwise the node is MUX iff it has a pair of equal grandchildren
+ return (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC0(pNode1))) ||
+ (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC1(pNode1))) ||
+ (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC0(pNode1))) ||
+ (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC1(pNode1)));
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recognizes what nodes are control and data inputs of a MUX.]
+
+ Description [If the node is a MUX, returns the control variable C.
+ Assigns nodes T and E to be the then and else variables of the MUX.
+ Node C is never complemented. Nodes T and E can be complemented.
+ This function also recognizes EXOR/NEXOR gates as MUXes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeRecognizeMux( Abc_Obj_t * pNode, Abc_Obj_t ** ppNodeT, Abc_Obj_t ** ppNodeE )
+{
+ Abc_Obj_t * pNode0, * pNode1;
+ assert( !Abc_ObjIsComplement(pNode) );
+ assert( Abc_NodeIsMuxType(pNode) );
+ // get children
+ pNode0 = Abc_ObjFanin0(pNode);
+ pNode1 = Abc_ObjFanin1(pNode);
+ // find the control variable
+// if ( pNode1->p1 == Fraig_Not(pNode2->p1) )
+ if ( Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC0(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p1) )
+ if ( Abc_ObjFaninC0(pNode0) )
+ { // pNode2->p1 is positive phase of C
+ *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
+ *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
+ return Abc_ObjChild0(pNode1);//pNode2->p1;
+ }
+ else
+ { // pNode1->p1 is positive phase of C
+ *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
+ *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
+ return Abc_ObjChild0(pNode0);//pNode1->p1;
+ }
+ }
+// else if ( pNode1->p1 == Fraig_Not(pNode2->p2) )
+ else if ( Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC1(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p1) )
+ if ( Abc_ObjFaninC0(pNode0) )
+ { // pNode2->p2 is positive phase of C
+ *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
+ *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
+ return Abc_ObjChild1(pNode1);//pNode2->p2;
+ }
+ else
+ { // pNode1->p1 is positive phase of C
+ *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
+ *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
+ return Abc_ObjChild0(pNode0);//pNode1->p1;
+ }
+ }
+// else if ( pNode1->p2 == Fraig_Not(pNode2->p1) )
+ else if ( Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC0(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p2) )
+ if ( Abc_ObjFaninC1(pNode0) )
+ { // pNode2->p1 is positive phase of C
+ *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
+ *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
+ return Abc_ObjChild0(pNode1);//pNode2->p1;
+ }
+ else
+ { // pNode1->p2 is positive phase of C
+ *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
+ *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
+ return Abc_ObjChild1(pNode0);//pNode1->p2;
+ }
+ }
+// else if ( pNode1->p2 == Fraig_Not(pNode2->p2) )
+ else if ( Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC1(pNode1)) )
+ {
+// if ( Fraig_IsComplement(pNode1->p2) )
+ if ( Abc_ObjFaninC1(pNode0) )
+ { // pNode2->p2 is positive phase of C
+ *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
+ *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
+ return Abc_ObjChild1(pNode1);//pNode2->p2;
+ }
+ else
+ { // pNode1->p2 is positive phase of C
+ *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
+ *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
+ return Abc_ObjChild1(pNode0);//pNode1->p2;
+ }
+ }
+ assert( 0 ); // this is not MUX
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if it is an AIG with choice nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkCountChoiceNodes( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, Counter;
+ if ( !Abc_NtkIsAig(pNtk) )
+ return 0;
+ Counter = 0;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ Counter += Abc_NodeIsChoice( pNode );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares two network for a two-argument command similar to "verify".]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkPrepareCommand( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc,
+ Abc_Ntk_t ** ppNtk1, Abc_Ntk_t ** ppNtk2, int * pfDelete1, int * pfDelete2 )
+{
+ int fCheck = 1;
+ FILE * pFile;
+ Abc_Ntk_t * pNtk1, * pNtk2;
+ int util_optind = 0;
+
+ *pfDelete1 = 0;
+ *pfDelete2 = 0;
+ if ( argc == util_optind )
+ { // use the spec
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty current network.\n" );
+ return 0;
+ }
+ if ( pNtk->pSpec == NULL )
+ {
+ fprintf( pErr, "The external spec is not given.\n" );
+ return 0;
+ }
+ pFile = fopen( pNtk->pSpec, "r" );
+ if ( pFile == NULL )
+ {
+ fprintf( pErr, "Cannot open the external spec file \"%s\".\n", pNtk->pSpec );
+ return 0;
+ }
+ else
+ fclose( pFile );
+
+ pNtk1 = pNtk;
+ pNtk2 = Io_Read( pNtk->pSpec, fCheck );
+ if ( pNtk2 == NULL )
+ return 0;
+ *pfDelete2 = 1;
+ }
+ else if ( argc == util_optind + 1 )
+ {
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty current network.\n" );
+ return 0;
+ }
+ pNtk1 = pNtk;
+ pNtk2 = Io_Read( argv[util_optind], fCheck );
+ if ( pNtk2 == NULL )
+ return 0;
+ *pfDelete2 = 1;
+ }
+ else if ( argc == util_optind + 2 )
+ {
+ pNtk1 = Io_Read( argv[util_optind], fCheck );
+ if ( pNtk1 == NULL )
+ return 0;
+ pNtk2 = Io_Read( argv[util_optind+1], fCheck );
+ if ( pNtk2 == NULL )
+ {
+ Abc_NtkDelete( pNtk1 );
+ return 0;
+ }
+ *pfDelete1 = 1;
+ *pfDelete2 = 1;
+ }
+ else
+ {
+ fprintf( pErr, "Wrong number of arguments.\n" );
+ return 0;
+ }
+ *ppNtk1 = pNtk1;
+ *ppNtk2 = pNtk2;
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if it is an AIG with choice nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeCollectFanins( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
+{
+ Abc_Obj_t * pFanin;
+ int i;
+ vNodes->nSize = 0;
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ Vec_PtrPush( vNodes, pFanin );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if it is an AIG with choice nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
+{
+ Abc_Obj_t * pFanout;
+ int i;
+ vNodes->nSize = 0;
+ Abc_ObjForEachFanout( pNode, pFanout, i )
+ Vec_PtrPush( vNodes, pFanout );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Procedure used for sorting the nodes in decreasing order of levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeCompareLevelsIncrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
+{
+ int Diff = Abc_ObjRegular(*pp1)->Level - Abc_ObjRegular(*pp2)->Level;
+ if ( Diff < 0 )
+ return -1;
+ if ( Diff > 0 )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Procedure used for sorting the nodes in decreasing order of levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeCompareLevelsDecrease( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
+{
+ int Diff = Abc_ObjRegular(*pp1)->Level - Abc_ObjRegular(*pp2)->Level;
+ if ( Diff > 0 )
+ return -1;
+ if ( Diff < 0 )
+ return 1;
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collect all nodes by level.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_AigCollectAll( Abc_Ntk_t * pNtk )
+{
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode;
+ int i;
+ vNodes = Vec_PtrAlloc( 100 );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ Vec_PtrPush( vNodes, pNode );
+ Vec_PtrSort( vNodes, Abc_NodeCompareLevelsIncrease );
+ return vNodes;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/abcVerify.c b/src/base/abc/abcVerify.c
new file mode 100644
index 00000000..d0b424a9
--- /dev/null
+++ b/src/base/abc/abcVerify.c
@@ -0,0 +1,310 @@
+/**CFile****************************************************************
+
+ FileName [abcVerify.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Combinational and sequential verification for two networks.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcVerify.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fraig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Verifies combinational equivalence by brute-force SAT.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
+{
+ Abc_Ntk_t * pMiter;
+ Abc_Ntk_t * pCnf;
+ int RetValue;
+
+ // get the miter of the two networks
+ pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1 );
+ if ( pMiter == NULL )
+ {
+ printf( "Miter computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pMiter );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are not equivalent.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are equivalent after structural hashing.\n" );
+ return;
+ }
+
+ // convert the miter into a CNF
+ pCnf = Abc_NtkRenode( pMiter, 0, 100, 1, 0, 0 );
+ Abc_NtkDelete( pMiter );
+ if ( pCnf == NULL )
+ {
+ printf( "Renoding for CNF has failed.\n" );
+ return;
+ }
+
+ // solve the CNF using the SAT solver
+ if ( Abc_NtkMiterSat( pCnf, 0 ) )
+ printf( "Networks are not equivalent.\n" );
+ else
+ printf( "Networks are equivalent.\n" );
+ Abc_NtkDelete( pCnf );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Verifies sequential equivalence by fraiging followed by SAT.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
+{
+ Fraig_Params_t Params;
+ Abc_Ntk_t * pMiter;
+ Abc_Ntk_t * pFraig;
+ int RetValue;
+
+ // get the miter of the two networks
+ pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1 );
+ if ( pMiter == NULL )
+ {
+ printf( "Miter computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pMiter );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are not equivalent.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are equivalent after structural hashing.\n" );
+ return;
+ }
+
+ // convert the miter into a FRAIG
+ Fraig_ParamsSetDefault( &Params );
+ pFraig = Abc_NtkFraig( pMiter, &Params, 0 );
+ Abc_NtkDelete( pMiter );
+ if ( pFraig == NULL )
+ {
+ printf( "Fraiging has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pFraig );
+ Abc_NtkDelete( pFraig );
+ if ( RetValue == 0 )
+ {
+ printf( "Networks are equivalent after fraiging.\n" );
+ return;
+ }
+ printf( "Networks are not equivalent.\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verifies sequential equivalence by brute-force SAT.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames )
+{
+ Abc_Ntk_t * pMiter;
+ Abc_Ntk_t * pFrames;
+ Abc_Ntk_t * pCnf;
+ int RetValue;
+
+ // get the miter of the two networks
+ pMiter = Abc_NtkMiter( pNtk1, pNtk2, 0 );
+ if ( pMiter == NULL )
+ {
+ printf( "Miter computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pMiter );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are not equivalent.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are equivalent after structural hashing.\n" );
+ return;
+ }
+
+ // create the timeframes
+ pFrames = Abc_NtkFrames( pMiter, nFrames, 1 );
+ Abc_NtkDelete( pMiter );
+ if ( pFrames == NULL )
+ {
+ printf( "Frames computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pFrames );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pFrames );
+ printf( "Networks are not equivalent.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pFrames );
+ printf( "Networks are equivalent after framing.\n" );
+ return;
+ }
+
+ // convert the miter into a CNF
+ pCnf = Abc_NtkRenode( pFrames, 0, 100, 1, 0, 0 );
+ Abc_NtkDelete( pFrames );
+ if ( pCnf == NULL )
+ {
+ printf( "Renoding for CNF has failed.\n" );
+ return;
+ }
+
+ // solve the CNF using the SAT solver
+ if ( Abc_NtkMiterSat( pCnf, 0 ) )
+ printf( "Networks are not equivalent.\n" );
+ else
+ printf( "Networks are equivalent.\n" );
+ Abc_NtkDelete( pCnf );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verifies combinational equivalence by fraiging followed by SAT]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames )
+{
+ Fraig_Params_t Params;
+ Abc_Ntk_t * pMiter;
+ Abc_Ntk_t * pFraig;
+ Abc_Ntk_t * pFrames;
+ int RetValue;
+
+ // get the miter of the two networks
+ pMiter = Abc_NtkMiter( pNtk1, pNtk2, 0 );
+ if ( pMiter == NULL )
+ {
+ printf( "Miter computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pMiter );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are not equivalent.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are equivalent after structural hashing.\n" );
+ return;
+ }
+
+ // create the timeframes
+ pFrames = Abc_NtkFrames( pMiter, nFrames, 1 );
+ Abc_NtkDelete( pMiter );
+ if ( pFrames == NULL )
+ {
+ printf( "Frames computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pFrames );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pFrames );
+ printf( "Networks are not equivalent.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pFrames );
+ printf( "Networks are equivalent after framing.\n" );
+ return;
+ }
+
+ // convert the miter into a FRAIG
+ Fraig_ParamsSetDefault( &Params );
+ pFraig = Abc_NtkFraig( pMiter, &Params, 0 );
+ Abc_NtkDelete( pFrames );
+ if ( pFraig == NULL )
+ {
+ printf( "Fraiging has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pFraig );
+ Abc_NtkDelete( pFraig );
+ if ( RetValue == 0 )
+ {
+ printf( "Networks are equivalent after fraiging.\n" );
+ return;
+ }
+ printf( "Networks are not equivalent.\n" );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abc/module.make b/src/base/abc/module.make
new file mode 100644
index 00000000..1eb88224
--- /dev/null
+++ b/src/base/abc/module.make
@@ -0,0 +1,28 @@
+SRC += src/base/abc/abc.c \
+ src/base/abc/abcAig.c \
+ src/base/abc/abcAttach.c \
+ src/base/abc/abcCheck.c \
+ src/base/abc/abcCollapse.c \
+ src/base/abc/abcCreate.c \
+ src/base/abc/abcDfs.c \
+ src/base/abc/abcDsd.c \
+ src/base/abc/abcFanio.c \
+ src/base/abc/abcFpga.c \
+ src/base/abc/abcFraig.c \
+ src/base/abc/abcFunc.c \
+ src/base/abc/abcLatch.c \
+ src/base/abc/abcMap.c \
+ src/base/abc/abcMinBase.c \
+ src/base/abc/abcMiter.c \
+ src/base/abc/abcNames.c \
+ src/base/abc/abcNetlist.c \
+ src/base/abc/abcPrint.c \
+ src/base/abc/abcRefs.c \
+ src/base/abc/abcRenode.c \
+ src/base/abc/abcSat.c \
+ src/base/abc/abcSop.c \
+ src/base/abc/abcStrash.c \
+ src/base/abc/abcSweep.c \
+ src/base/abc/abcTiming.c \
+ src/base/abc/abcUtil.c \
+ src/base/abc/abcVerify.c
diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c
new file mode 100644
index 00000000..aa15c0af
--- /dev/null
+++ b/src/base/cmd/cmd.c
@@ -0,0 +1,1498 @@
+/**CFile****************************************************************
+
+ FileName [cmd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Command file.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+#include "cmdInt.h"
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int CmdCommandTime ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandEcho ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandQuit ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandUsage ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandWhich ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandHistory ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandAlias ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandUnalias ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandHelp ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandSource ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandSetVariable ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandUnsetVariable ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandUndo ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandRecall ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandEmpty ( Abc_Frame_t * pAbc, int argc, char ** argv );
+#ifdef WIN32
+static int CmdCommandLs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+#endif
+static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function********************************************************************
+
+ Synopsis [Initializes the command package.]
+
+ SideEffects [Commands are added to the command table.]
+
+ SeeAlso [Cmd_End]
+
+******************************************************************************/
+void Cmd_Init( Abc_Frame_t * pAbc )
+{
+ pAbc->tCommands = st_init_table(strcmp, st_strhash);
+ pAbc->tAliases = st_init_table(strcmp, st_strhash);
+ pAbc->tFlags = st_init_table(strcmp, st_strhash);
+ pAbc->aHistory = Vec_PtrAlloc( 100 );
+
+ Cmd_CommandAdd( pAbc, "Basic", "time", CmdCommandTime, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "echo", CmdCommandEcho, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "quit", CmdCommandQuit, 0);
+// Cmd_CommandAdd( pAbc, "Basic", "usage", CmdCommandUsage, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "history", CmdCommandHistory, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "alias", CmdCommandAlias, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "unalias", CmdCommandUnalias, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "help", CmdCommandHelp, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "source", CmdCommandSource, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "set", CmdCommandSetVariable, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "unset", CmdCommandUnsetVariable, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "undo", CmdCommandUndo, 0);
+// Cmd_CommandAdd( pAbc, "Basic", "recall", CmdCommandRecall, 0);
+ Cmd_CommandAdd( pAbc, "Basic", "empty", CmdCommandEmpty, 0);
+#ifdef WIN32
+ Cmd_CommandAdd( pAbc, "Basic", "ls", CmdCommandLs, 0 );
+#endif
+
+ Cmd_CommandAdd( pAbc, "Various", "sis", CmdCommandSis, 1);
+ Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1);
+}
+
+/**Function********************************************************************
+
+ Synopsis [Ends the command package.]
+
+ Description [Ends the command package. Tables are freed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+void Cmd_End( Abc_Frame_t * pAbc )
+{
+ st_generator * gen;
+ char * pKey, * pValue;
+ int i;
+
+// st_free_table( pAbc->tCommands, (void (*)()) 0, CmdCommandFree );
+// st_free_table( pAbc->tAliases, (void (*)()) 0, CmdCommandAliasFree );
+// st_free_table( pAbc->tFlags, free, free );
+
+ st_foreach_item( pAbc->tCommands, gen, (char **)&pKey, (char **)&pValue )
+ CmdCommandFree( (Abc_Command *)pValue );
+ st_free_table( pAbc->tCommands );
+
+ st_foreach_item( pAbc->tAliases, gen, (char **)&pKey, (char **)&pValue )
+ CmdCommandAliasFree( (Abc_Alias *)pValue );
+ st_free_table( pAbc->tAliases );
+
+ st_foreach_item( pAbc->tFlags, gen, (char **)&pKey, (char **)&pValue )
+ free( pKey ), free( pValue );
+ st_free_table( pAbc->tFlags );
+
+ for ( i = 0; i < pAbc->aHistory->nSize; i++ )
+ free( pAbc->aHistory->pArray[i] );
+ Vec_PtrFree( pAbc->aHistory );
+}
+
+
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandTime( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind )
+ {
+ goto usage;
+ }
+
+ pAbc->TimeTotal += pAbc->TimeCommand;
+ fprintf( pAbc->Out, "elapse: %3.2f seconds, total: %3.2f seconds\n",
+ (float)pAbc->TimeCommand / CLOCKS_PER_SEC, (float)pAbc->TimeTotal / CLOCKS_PER_SEC );
+ pAbc->TimeCommand = 0;
+ return 0;
+
+ usage:
+ fprintf( pAbc->Err, "usage: time [-h]\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandEcho( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int i;
+ int c;
+ int n = 1;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "hn" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'n':
+ n = 0;
+ break;
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ for ( i = util_optind; i < argc; i++ )
+ fprintf( pAbc->Out, "%s ", argv[i] );
+ if ( n )
+ fprintf( pAbc->Out, "\n" );
+ else
+ fflush ( pAbc->Out );
+ return 0;
+
+ usage:
+ fprintf( pAbc->Err, "usage: echo [-h] string \n" );
+ fprintf( pAbc->Err, " -n \t\tsuppress newline at the end\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return ( 1 );
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandQuit( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "hs" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ case 's':
+ return -2;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind )
+ goto usage;
+ return -1;
+
+ usage:
+ fprintf( pAbc->Err, "usage: quit [-h] [-s]\n" );
+ fprintf( pAbc->Err, " -h print the command usage\n" );
+ fprintf( pAbc->Err,
+ " -s frees all the memory before quitting\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandUsage( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind )
+ goto usage;
+ util_print_cpu_stats( pAbc->Out );
+ return 0;
+
+ usage:
+ fprintf( pAbc->Err, "usage: usage [-h]\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandWhich( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ return 0;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandHistory( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int i, num;
+ int size;
+ int c;
+ num = 30;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ }
+ }
+
+ if ( argc > 3 )
+ goto usage;
+
+ size = pAbc->aHistory->nSize;
+ num = ( num < size ) ? num : size;
+ for ( i = size - num; i < size; i++ )
+ fprintf( pAbc->Out, "%s", pAbc->aHistory->pArray[i] );
+ return 0;
+
+ usage:
+ fprintf( pAbc->Err, "usage: history [-h] [num]\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ fprintf( pAbc->Err, " num \t\tprint the last num commands\n" );
+ return ( 1 );
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandAlias( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char *key, *value;
+ st_generator *gen;
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+
+ if ( argc == 1 )
+ {
+ st_foreach_item( pAbc->tAliases, gen, &key, &value )
+ CmdCommandAliasPrint( pAbc, ( Abc_Alias * ) value );
+ return 0;
+
+ }
+ else if ( argc == 2 )
+ {
+ if ( st_lookup( pAbc->tAliases, argv[1], &value ) )
+ CmdCommandAliasPrint( pAbc, ( Abc_Alias * ) value );
+ return 0;
+ }
+
+ // delete any existing alias
+ key = argv[1];
+ if ( st_delete( pAbc->tAliases, &key, &value ) )
+ CmdCommandAliasFree( ( Abc_Alias * ) value );
+ CmdCommandAliasAdd( pAbc, argv[1], argc - 2, argv + 2 );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: alias [-h] [command [string]]\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return ( 1 );
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandUnalias( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int i;
+ char *key, *value;
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc < 2 )
+ {
+ goto usage;
+ }
+
+ for ( i = 1; i < argc; i++ )
+ {
+ key = argv[i];
+ if ( st_delete( pAbc->tAliases, &key, &value ) )
+ {
+ CmdCommandAliasFree( ( Abc_Alias * ) value );
+ }
+ }
+ return 0;
+
+ usage:
+ fprintf( pAbc->Err, "usage: unalias [-h] alias_names\n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandHelp( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ bool fPrintAll;
+ int c;
+
+ fPrintAll = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ah" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'a':
+ case 'v':
+ fPrintAll ^= 1;
+ break;
+ break;
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind )
+ goto usage;
+
+ CmdCommandPrint( pAbc, fPrintAll );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: help [-a] [-h]\n" );
+ fprintf( pAbc->Err, " prints the list of available commands by group\n" );
+ fprintf( pAbc->Err, " -a toggle printing hidden commands [default = %s]\n", fPrintAll? "yes": "no" );
+ fprintf( pAbc->Err, " -h print the command usage\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandSource( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int c, echo, prompt, silent, interactive, quit_count, lp_count;
+ int status = 0; /* initialize so that lint doesn't complain */
+ int lp_file_index, did_subst;
+ char *prompt_string, *real_filename, line[MAX_STR], *command;
+ FILE *fp;
+
+ interactive = silent = prompt = echo = 0;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "hipsx" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ case 'i': /* a hack to distinguish EOF from stdin */
+ interactive = 1;
+ break;
+ case 'p':
+ prompt = 1;
+ break;
+ case 's':
+ silent = 1;
+ break;
+ case 'x':
+ echo ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ /* added to avoid core-dumping when no script file is specified */
+ if ( argc == util_optind )
+ {
+ goto usage;
+ }
+
+ lp_file_index = util_optind;
+ lp_count = 0;
+
+ /*
+ * FIX (Tom, 5/7/95): I'm not sure what the purpose of this outer do loop
+ * is. In particular, lp_file_index is never modified in the loop, so it
+ * looks it would just read the same file over again. Also, SIS had
+ * lp_count initialized to -1, and hence, any file sourced by SIS (if -l or
+ * -t options on "source" were used in SIS) would actually be executed
+ * twice.
+ */
+ do
+ {
+ lp_count++; /* increment the loop counter */
+
+ fp = CmdFileOpen( pAbc, argv[lp_file_index], "r", &real_filename, silent );
+ if ( fp == NULL )
+ {
+ FREE( real_filename );
+ return !silent; /* error return if not silent */
+ }
+
+ quit_count = 0;
+ do
+ {
+ if ( prompt )
+ {
+ prompt_string = Cmd_FlagReadByName( pAbc, "prompt" );
+ if ( prompt_string == NULL )
+ prompt_string = "abc> ";
+
+ }
+ else
+ {
+ prompt_string = NIL( char );
+ }
+
+ /* clear errors -- e.g., EOF reached from stdin */
+ clearerr( fp );
+
+ /* read another command line */
+// if (CmdFgetsFilec(line, MAX_STR, fp, prompt_string) == NULL) {
+// Abc_UtilsPrintPrompt(prompt_string);
+// fflush(stdout);
+ if ( fgets( line, MAX_STR, fp ) == NULL )
+ {
+ if ( interactive )
+ {
+ if ( quit_count++ < 5 )
+ {
+ fprintf( pAbc->Err, "\nUse \"quit\" to leave ABC.\n" );
+ continue;
+ }
+ status = -1; /* fake a 'quit' */
+ }
+ else
+ {
+ status = 0; /* successful end of 'source' ; loop? */
+ }
+ break;
+ }
+ quit_count = 0;
+
+ if ( echo )
+ {
+ fprintf( pAbc->Out, "abc - > %s", line );
+ }
+ command = CmdHistorySubstitution( pAbc, line, &did_subst );
+ if ( command == NIL( char ) )
+ {
+ status = 1;
+ break;
+ }
+ if ( did_subst )
+ {
+ if ( interactive )
+ {
+ fprintf( pAbc->Out, "%s\n", command );
+ }
+ }
+ if ( command != line )
+ {
+ ( void ) strcpy( line, command );
+ }
+ if ( interactive && *line != '\0' )
+ {
+ Cmd_HistoryAddCommand( pAbc, util_strsav(line) );
+ if ( pAbc->Hst != NIL( FILE ) )
+ {
+ fprintf( pAbc->Hst, "%s\n", line );
+ ( void ) fflush( pAbc->Hst );
+ }
+ }
+
+ status = Cmd_CommandExecute( pAbc, line );
+ }
+ while ( status == 0 );
+
+ if ( fp != stdin )
+ {
+ if ( status > 0 )
+ {
+ fprintf( pAbc->Err,
+ "** cmd error: aborting 'source %s'\n",
+ real_filename );
+ }
+ ( void ) fclose( fp );
+ }
+ FREE( real_filename );
+
+ }
+ while ( ( status == 0 ) && ( lp_count <= 0 ) );
+
+ return status;
+
+ usage:
+ fprintf( pAbc->Err, "usage: source [-h] [-p] [-s] [-x] file_name\n" );
+ fprintf( pAbc->Err, "\t-h print the command usage\n" );
+ fprintf( pAbc->Err, "\t-p supply prompt before reading each line\n" );
+ fprintf( pAbc->Err, "\t-s silently ignore nonexistant file\n" );
+ fprintf( pAbc->Err, "\t-x echo each line as it is executed\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandSetVariable( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char *flag_value, *key, *value;
+ st_generator *gen;
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc == 0 || argc > 3 )
+ {
+ goto usage;
+ }
+ else if ( argc == 1 )
+ {
+ st_foreach_item( pAbc->tFlags, gen, &key, &value )
+ {
+ fprintf( pAbc->Out, "%s\t%s\n", key, value );
+ }
+ return 0;
+ }
+ else
+ {
+ key = argv[1];
+ if ( st_delete( pAbc->tFlags, &key, &value ) )
+ {
+ FREE( key );
+ FREE( value );
+ }
+
+ flag_value = argc == 2 ? util_strsav( "" ) : util_strsav( argv[2] );
+
+ ( void ) st_insert( pAbc->tFlags, util_strsav( argv[1] ),
+ flag_value );
+
+ if ( strcmp( argv[1], "abcout" ) == 0 )
+ {
+ if ( pAbc->Out != stdout )
+ {
+ ( void ) fclose( pAbc->Out );
+ }
+ if ( strcmp( flag_value, "" ) == 0 )
+ {
+ flag_value = "-";
+ }
+ pAbc->Out = CmdFileOpen( pAbc, flag_value, "w", NIL( char * ), 0 );
+ if ( pAbc->Out == NULL )
+ {
+ pAbc->Out = stdout;
+ }
+#if HAVE_SETVBUF
+ setvbuf( pAbc->Out, ( char * ) NULL, _IOLBF, 0 );
+#endif
+ }
+ if ( strcmp( argv[1], "abcerr" ) == 0 )
+ {
+ if ( pAbc->Err != stderr )
+ {
+ ( void ) fclose( pAbc->Err );
+ }
+ if ( strcmp( flag_value, "" ) == 0 )
+ {
+ flag_value = "-";
+ }
+ pAbc->Err = CmdFileOpen( pAbc, flag_value, "w", NIL( char * ), 0 );
+ if ( pAbc->Err == NULL )
+ {
+ pAbc->Err = stderr;
+ }
+#if HAVE_SETVBUF
+ setvbuf( pAbc->Err, ( char * ) NULL, _IOLBF, 0 );
+#endif
+ }
+ if ( strcmp( argv[1], "history" ) == 0 )
+ {
+ if ( pAbc->Hst != NIL( FILE ) )
+ {
+ ( void ) fclose( pAbc->Hst );
+ }
+ if ( strcmp( flag_value, "" ) == 0 )
+ {
+ pAbc->Hst = NIL( FILE );
+ }
+ else
+ {
+ pAbc->Hst =
+ CmdFileOpen( pAbc, flag_value, "w", NIL( char * ), 0 );
+ if ( pAbc->Hst == NULL )
+ {
+ pAbc->Hst = NIL( FILE );
+ }
+ }
+ }
+ return 0;
+ }
+
+ usage:
+ fprintf( pAbc->Err, "usage: set [-h] [name] [value]\n" );
+ fprintf( pAbc->Err, "\t sets the value of parameter <name>\n" );
+ fprintf( pAbc->Err, "\t-h : print the command usage\n" );
+ return 1;
+
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandUnsetVariable( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int i;
+ char *key, *value;
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc < 2 )
+ {
+ goto usage;
+ }
+
+ for ( i = 1; i < argc; i++ )
+ {
+ key = argv[i];
+ if ( st_delete( pAbc->tFlags, &key, &value ) )
+ {
+ FREE( key );
+ FREE( value );
+ }
+ }
+ return 0;
+
+
+ usage:
+ fprintf( pAbc->Err, "usage: unset [-h] variables \n" );
+ fprintf( pAbc->Err, " -h \t\tprint the command usage\n" );
+ return 1;
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandUndo( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ if ( pAbc->pNtkCur == NULL )
+ {
+ fprintf( pAbc->Out, "Empty network.\n" );
+ return 0;
+ }
+
+ // if there are no arguments on the command line
+ // set the current network to be the network from the previous step
+ if ( argc == 1 )
+ return CmdCommandRecall( pAbc, argc, argv );
+
+ fprintf( pAbc->Err, "usage: undo\n" );
+ fprintf( pAbc->Err, " sets the current network to be the previously saved network\n" );
+ return 1;
+
+}
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandRecall( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ Abc_Ntk_t * pNtk;
+ int iStep, iStepFound;
+ int nNetsToSave, c;
+ char * pValue;
+ int iStepStart, iStepStop;
+
+ if ( pAbc->pNtkCur == NULL )
+ {
+ fprintf( pAbc->Out, "Empty network.\n" );
+ return 0;
+ }
+
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ // get the number of networks to save
+ pValue = Cmd_FlagReadByName( pAbc, "savesteps" );
+ // if the value of steps to save is not set, assume 1-level undo
+ if ( pValue == NULL )
+ nNetsToSave = 1;
+ else
+ nNetsToSave = atoi(pValue);
+
+ // if there are no arguments on the command line
+ // set the current network to be the network from the previous step
+ if ( argc == 1 )
+ {
+ // get the previously saved network
+ pNtk = Abc_NtkBackup(pAbc->pNtkCur);
+ if ( pNtk == NULL )
+ fprintf( pAbc->Out, "There is no previously saved network.\n" );
+ else // set the current network to be the copy of the previous one
+ Abc_FrameSetCurrentNetwork( pAbc, Abc_NtkDup(pNtk) );
+ return 0;
+ }
+ if ( argc == 2 ) // the second argument is the number of the step to return to
+ {
+ // read the number of the step to return to
+ iStep = atoi(argv[1]);
+ // check whether it is reasonable
+ if ( iStep >= pAbc->nSteps )
+ {
+ iStepStart = pAbc->nSteps - nNetsToSave;
+ if ( iStepStart <= 0 )
+ iStepStart = 1;
+ iStepStop = pAbc->nSteps;
+ if ( iStepStop <= 0 )
+ iStepStop = 1;
+ if ( iStepStart == iStepStop )
+ fprintf( pAbc->Out, "Can only recall step %d.\n", iStepStop );
+ else
+ fprintf( pAbc->Out, "Can only recall steps %d-%d.\n", iStepStart, iStepStop );
+ }
+ else if ( iStep < 0 )
+ fprintf( pAbc->Out, "Cannot recall step %d.\n", iStep );
+ else if ( iStep == 0 )
+ Abc_FrameDeleteAllNetworks( pAbc );
+ else
+ {
+ // scroll backward through the list of networks
+ // to determine if such a network exist
+ iStepFound = 0;
+ for ( pNtk = pAbc->pNtkCur; pNtk; pNtk = Abc_NtkBackup(pNtk) )
+ if ( (iStepFound = Abc_NtkStep(pNtk)) == iStep )
+ break;
+ if ( pNtk == NULL )
+ {
+ iStepStart = iStepFound;
+ if ( iStepStart <= 0 )
+ iStepStart = 1;
+ iStepStop = pAbc->nSteps;
+ if ( iStepStop <= 0 )
+ iStepStop = 1;
+ if ( iStepStart == iStepStop )
+ fprintf( pAbc->Out, "Can only recall step %d.\n", iStepStop );
+ else
+ fprintf( pAbc->Out, "Can only recall steps %d-%d.\n", iStepStart, iStepStop );
+ }
+ else
+ Abc_FrameSetCurrentNetwork( pAbc, Abc_NtkDup(pNtk) );
+ }
+ return 0;
+ }
+
+usage:
+
+ fprintf( pAbc->Err, "usage: recall <num>\n" );
+ fprintf( pAbc->Err, " set the current network to be one of the previous networks\n" );
+ fprintf( pAbc->Err, "<num> : level to return to [default = previous]\n" );
+ return 1;
+}
+
+
+/**Function********************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandEmpty( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ int c;
+
+ if ( pAbc->pNtkCur == NULL )
+ {
+ fprintf( pAbc->Out, "Empty network.\n" );
+ return 0;
+ }
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ Abc_FrameDeleteAllNetworks( pAbc );
+ Abc_FrameRestart( pAbc );
+ return 0;
+usage:
+
+ fprintf( pAbc->Err, "usage: empty [-h]\n" );
+ fprintf( pAbc->Err, " removes all the currently stored networks\n" );
+ fprintf( pAbc->Err, " -h : print the command usage\n");
+ return 1;
+}
+
+
+#if 0
+
+/**Function********************************************************************
+
+ Synopsis [Donald's version.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandUndo( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ Abc_Ntk_t * pNtkTemp;
+ int id, c;
+
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+ if (util_optind <= argc) {
+ pNtkTemp = pAbc->pNtk;
+ pAbc->pNtk = pAbc->pNtkSaved;
+ pAbc->pNtkSaved = pNtkTemp;
+ }
+ id = atoi(argv[util_optind]);
+ pNtkTemp = Cmd_HistoryGetSnapshot(pAbc, id);
+ if (!pNtkTemp)
+ fprintf( pAbc->Err, "Snapshot %d does not exist\n", id);
+ else
+ pAbc->pNtk = Abc_NtkDup(pNtkTemp, Abc_NtkMan(pNtkTemp));
+
+ return 0;
+usage:
+ fprintf( pAbc->Err, "usage: undo\n" );
+ fprintf( pAbc->Err, " swaps the current network and the backup network\n" );
+ return 1;
+}
+
+#endif
+
+
+#ifdef WIN32
+/**Function*************************************************************
+
+ Synopsis [Command to print the contents of the current directory (Windows).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+#include <io.h>
+
+// these structures are defined in <io.h> but are for some reason invisible
+typedef unsigned long _fsize_t; // Could be 64 bits for Win32
+
+struct _finddata_t {
+ unsigned attrib;
+ time_t time_create; // -1 for FAT file systems
+ time_t time_access; // -1 for FAT file systems
+ time_t time_write;
+ _fsize_t size;
+ char name[260];
+};
+
+extern long _findfirst( char *filespec, struct _finddata_t *fileinfo );
+extern int _findnext( long handle, struct _finddata_t *fileinfo );
+extern int _findclose( long handle );
+
+int CmdCommandLs( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ struct _finddata_t c_file;
+ long hFile;
+ int fLong = 0;
+ int fOnlyBLIF = 0;
+ char Buffer[25];
+ int Counter = 0;
+ int fPrintedNewLine;
+ char c;
+
+ util_getopt_reset();
+ while ( (c = util_getopt(argc, argv, "lb") ) != EOF )
+ {
+ switch (c)
+ {
+ case 'l':
+ fLong = 1;
+ break;
+ case 'b':
+ fOnlyBLIF = 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ // find first .mv file in current directory
+ if( (hFile = _findfirst( ((fOnlyBLIF)? "*.mv": "*.*"), &c_file )) == -1L )
+ {
+ if ( fOnlyBLIF )
+ fprintf( pAbc->Out, "No *.mv files in the current directory.\n" );
+ else
+ fprintf( pAbc->Out, "No files in the current directory.\n" );
+ }
+ else
+ {
+ if ( fLong )
+ {
+ fprintf( pAbc->Out, " File Date Size | File Date Size \n" );
+ fprintf( pAbc->Out, " ----------------------------------------------------------------------------- \n" );
+ do
+ {
+ strcpy( Buffer, ctime( &(c_file.time_write) ) );
+ Buffer[16] = 0;
+ fprintf( pAbc->Out, " %-17s %.24s%7ld", c_file.name, Buffer+4, c_file.size );
+ if ( ++Counter % 2 == 0 )
+ {
+ fprintf( pAbc->Out, "\n" );
+ fPrintedNewLine = 1;
+ }
+ else
+ {
+ fprintf( pAbc->Out, " |" );
+ fPrintedNewLine = 0;
+ }
+ }
+ while( _findnext( hFile, &c_file ) == 0 );
+ }
+ else
+ {
+ do
+ {
+ fprintf( pAbc->Out, " %-18s", c_file.name );
+ if ( ++Counter % 4 == 0 )
+ {
+ fprintf( pAbc->Out, "\n" );
+ fPrintedNewLine = 1;
+ }
+ else
+ {
+ fprintf( pAbc->Out, " " );
+ fPrintedNewLine = 0;
+ }
+ }
+ while( _findnext( hFile, &c_file ) == 0 );
+ }
+ if ( !fPrintedNewLine )
+ fprintf( pAbc->Out, "\n" );
+ _findclose( hFile );
+ }
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "Usage: ls [-l] [-b]\n" );
+ fprintf( pAbc->Err, " print the file names in the current directory\n" );
+ fprintf( pAbc->Err, " -l : print in the long format [default = short]\n" );
+ fprintf( pAbc->Err, " -b : print only .mv files [default = all]\n" );
+ return 1;
+}
+#endif
+
+
+
+#ifdef WIN32
+#define unlink _unlink
+#endif
+
+/**Function********************************************************************
+
+ Synopsis [Calls SIS internally.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandSis( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ FILE * pFile;
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkNew;
+ char Command[1000], Buffer[100];
+ char * pSisName;
+ int i;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ goto usage;
+ }
+
+ if ( strcmp( argv[0], "sis" ) != 0 )
+ {
+ fprintf( pErr, "Wrong command: \"%s\".\n", argv[0] );
+ goto usage;
+ }
+
+ if ( argc == 1 )
+ goto usage;
+ if ( strcmp( argv[1], "-h" ) == 0 )
+ goto usage;
+ if ( strcmp( argv[1], "-?" ) == 0 )
+ goto usage;
+
+ // check if SIS is available
+ if ( (pFile = fopen( "sis.exe", "r" )) )
+ pSisName = "sis.exe";
+ else if ( (pFile = fopen( "sis", "r" )) )
+ pSisName = "sis";
+ else if ( pFile == NULL )
+ {
+ fprintf( pErr, "Cannot find \"%s\" or \"%s\" in the current directory.\n", "sis.exe", "sis" );
+ goto usage;
+ }
+ fclose( pFile );
+
+ if ( Abc_NtkIsLogicBdd(pNtk) )
+ Abc_NtkBddToSop(pNtk);
+
+ // write out the current network
+ Io_WriteBlifLogic( pNtk, "_sis_in.blif", 1 );
+
+ // create the file for sis
+ sprintf( Command, "%s -x -c ", pSisName );
+ strcat ( Command, "\"" );
+ strcat ( Command, "read_blif _sis_in.blif" );
+ strcat ( Command, "; " );
+ for ( i = 1; i < argc; i++ )
+ {
+ sprintf( Buffer, " %s", argv[i] );
+ strcat( Command, Buffer );
+ }
+ strcat( Command, "; " );
+ strcat( Command, "write_blif _sis_out.blif" );
+ strcat( Command, "\"" );
+
+ // call SIS
+ if ( system( Command ) )
+ {
+ fprintf( pErr, "The following command has returned non-zero exit status:\n" );
+ fprintf( pErr, "\"%s\"\n", Command );
+ unlink( "_sis_in.blif" );
+ goto usage;
+ }
+
+ // read in the SIS output
+ if ( (pFile = fopen( "_sis_out.blif", "r" )) == NULL )
+ {
+ fprintf( pErr, "Cannot open SIS output file \"%s\".\n", "_sis_out.blif" );
+ unlink( "_sis_in.blif" );
+ goto usage;
+ }
+ fclose( pFile );
+
+ // set the new network
+ pNtkNew = Io_Read( "_sis_out.blif", 1 );
+ // set the original spec of the new network
+ if ( pNtk->pSpec )
+ {
+ FREE( pNtkNew->pSpec );
+ pNtkNew->pSpec = util_strsav( pNtk->pSpec );
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkNew );
+
+ // remove temporary networks
+ unlink( "_sis_in.blif" );
+ unlink( "_sis_out.blif" );
+ return 0;
+
+usage:
+ fprintf( pErr, "\n" );
+ fprintf( pErr, "Usage: sis [-h] <com>\n");
+ fprintf( pErr, " invokes SIS command for the current ABC network\n" );
+ fprintf( pErr, " (the executable of SIS should be in the same directory)\n" );
+ fprintf( pErr, " -h : print the command usage\n" );
+ fprintf( pErr, " <com> : a SIS command (or a semicolon-separated list of commands in quotes)\n" );
+ fprintf( pErr, " Example 1: sis eliminate 0\n" );
+ fprintf( pErr, " Example 2: sis \"ps; rd; fx; ps\"\n" );
+ fprintf( pErr, " Example 3: sis source script.rugged\n" );
+ return 1; // error exit
+}
+
+
+/**Function********************************************************************
+
+ Synopsis [Calls SIS internally.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandMvsis( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ FILE * pFile;
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkNew;
+ char Command[1000], Buffer[100];
+ char * pMvsisName;
+ int i;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ goto usage;
+ }
+
+ if ( strcmp( argv[0], "mvsis" ) != 0 )
+ {
+ fprintf( pErr, "Wrong command: \"%s\".\n", argv[0] );
+ goto usage;
+ }
+
+ if ( argc == 1 )
+ goto usage;
+ if ( strcmp( argv[1], "-h" ) == 0 )
+ goto usage;
+ if ( strcmp( argv[1], "-?" ) == 0 )
+ goto usage;
+
+ // check if MVSIS is available
+ if ( (pFile = fopen( "mvsis.exe", "r" )) )
+ pMvsisName = "mvsis.exe";
+ else if ( (pFile = fopen( "mvsis", "r" )) )
+ pMvsisName = "mvsis";
+ else if ( pFile == NULL )
+ {
+ fprintf( pErr, "Cannot find \"%s\" or \"%s\" in the current directory.\n", "mvsis.exe", "mvsis" );
+ goto usage;
+ }
+ fclose( pFile );
+
+ if ( Abc_NtkIsLogicBdd(pNtk) )
+ Abc_NtkBddToSop(pNtk);
+
+ // write out the current network
+ Io_WriteBlifLogic( pNtk, "_mvsis_in.blif", 1 );
+
+ // create the file for MVSIS
+ sprintf( Command, "%s -x -c ", pMvsisName );
+ strcat ( Command, "\"" );
+ strcat ( Command, "read_blif _mvsis_in.blif" );
+ strcat ( Command, "; " );
+ for ( i = 1; i < argc; i++ )
+ {
+ sprintf( Buffer, " %s", argv[i] );
+ strcat( Command, Buffer );
+ }
+ strcat( Command, "; " );
+ strcat( Command, "write_blif _mvsis_out.blif" );
+ strcat( Command, "\"" );
+
+ // call MVSIS
+ if ( system( Command ) )
+ {
+ fprintf( pErr, "The following command has returned non-zero exit status:\n" );
+ fprintf( pErr, "\"%s\"\n", Command );
+ unlink( "_mvsis_in.blif" );
+ goto usage;
+ }
+
+ // read in the MVSIS output
+ if ( (pFile = fopen( "_mvsis_out.blif", "r" )) == NULL )
+ {
+ fprintf( pErr, "Cannot open MVSIS output file \"%s\".\n", "_mvsis_out.blif" );
+ unlink( "_mvsis_in.blif" );
+ goto usage;
+ }
+ fclose( pFile );
+
+ // set the new network
+ pNtkNew = Io_Read( "_mvsis_out.blif", 1 );
+ // set the original spec of the new network
+ if ( pNtk->pSpec )
+ {
+ FREE( pNtkNew->pSpec );
+ pNtkNew->pSpec = util_strsav( pNtk->pSpec );
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkNew );
+
+ // remove temporary networks
+ unlink( "_mvsis_in.blif" );
+ unlink( "_mvsis_out.blif" );
+ return 0;
+
+usage:
+ fprintf( pErr, "\n" );
+ fprintf( pErr, "Usage: mvsis [-h] <com>\n");
+ fprintf( pErr, " invokes MVSIS command for the current ABC network\n" );
+ fprintf( pErr, " (the executable of MVSIS should be in the same directory)\n" );
+ fprintf( pErr, " -h : print the command usage\n" );
+ fprintf( pErr, " <com> : a MVSIS command (or a semicolon-separated list of commands in quotes)\n" );
+ fprintf( pErr, " Example 1: mvsis fraig_sweep\n" );
+ fprintf( pErr, " Example 2: mvsis \"ps; fxu; ps\"\n" );
+ fprintf( pErr, " Example 3: mvsis source mvsis.rugged\n" );
+ return 1; // error exit
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/cmd/cmd.h b/src/base/cmd/cmd.h
new file mode 100644
index 00000000..6389afae
--- /dev/null
+++ b/src/base/cmd/cmd.h
@@ -0,0 +1,65 @@
+/**CFile****************************************************************
+
+ FileName [cmd.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [External declarations of the command package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmd.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __CMD_H__
+#define __CMD_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct MvCommand Abc_Command; // one command
+typedef struct MvAlias Abc_Alias; // one alias
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== cmd.c ===========================================================*/
+extern void Cmd_Init();
+extern void Cmd_End();
+/*=== cmdApi.c ========================================================*/
+extern void Cmd_CommandAdd( Abc_Frame_t * pAbc, char * sGroup, char * sName, void * pFunc, int fChanges );
+extern int Cmd_CommandExecute( Abc_Frame_t * pAbc, char * sCommand );
+/*=== cmdFlag.c ========================================================*/
+extern char * Cmd_FlagReadByName( Abc_Frame_t * pAbc, char * flag );
+extern void Cmd_FlagDeleteByName( Abc_Frame_t * pAbc, char * key );
+extern void Cmd_FlagUpdateValue( Abc_Frame_t * pAbc, char * key, char * value );
+/*=== cmdHist.c ========================================================*/
+extern void Cmd_HistoryAddCommand( Abc_Frame_t * pAbc, char * command );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/base/cmd/cmdAlias.c b/src/base/cmd/cmdAlias.c
new file mode 100644
index 00000000..37220ef0
--- /dev/null
+++ b/src/base/cmd/cmdAlias.c
@@ -0,0 +1,120 @@
+/**CFile****************************************************************
+
+ FileName [cmdAlias.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures dealing with aliases in the command package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdAlias.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cmdInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CmdCommandAliasAdd( Abc_Frame_t * pAbc, char * sName, int argc, char ** argv )
+{
+ Abc_Alias * pAlias;
+ int fStatus, i;
+
+ pAlias = ALLOC(Abc_Alias, 1);
+ pAlias->sName = util_strsav(sName);
+ pAlias->argc = argc;
+ pAlias->argv = ALLOC(char *, pAlias->argc);
+ for(i = 0; i < argc; i++)
+ pAlias->argv[i] = util_strsav(argv[i]);
+ fStatus = st_insert( pAbc->tAliases, pAlias->sName, (char *) pAlias );
+ assert(!fStatus);
+}
+
+/**Function********************************************************************
+
+ Synopsis [required]
+
+ Description [optional]
+
+ SideEffects [required]
+
+ SeeAlso [optional]
+
+******************************************************************************/
+void CmdCommandAliasPrint( Abc_Frame_t * pAbc, Abc_Alias * pAlias )
+{
+ int i;
+ fprintf(pAbc->Out, "%s\t", pAlias->sName);
+ for(i = 0; i < pAlias->argc; i++)
+ fprintf( pAbc->Out, " %s", pAlias->argv[i] );
+ fprintf( pAbc->Out, "\n" );
+}
+
+/**Function********************************************************************
+
+ Synopsis [required]
+
+ Description [optional]
+
+ SideEffects [required]
+
+ SeeAlso [optional]
+
+******************************************************************************/
+char * CmdCommandAliasLookup( Abc_Frame_t * pAbc, char * sCommand )
+{
+ Abc_Alias * pAlias;
+ char * value;
+ if (!st_lookup( pAbc->tAliases, sCommand, &value))
+ return sCommand;
+ pAlias = (Abc_Alias *) value;
+ return pAlias->argv[0];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CmdCommandAliasFree( Abc_Alias * pAlias )
+{
+ CmdFreeArgv( pAlias->argc, pAlias->argv );
+ FREE(pAlias->sName);
+ FREE(pAlias);
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/cmd/cmdApi.c b/src/base/cmd/cmdApi.c
new file mode 100644
index 00000000..8dd67637
--- /dev/null
+++ b/src/base/cmd/cmdApi.c
@@ -0,0 +1,104 @@
+/**CFile****************************************************************
+
+ FileName [cmdApi.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [External procedures of the command package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdApi.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+#include "cmdInt.h"
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cmd_CommandAdd( Abc_Frame_t * pAbc, char * sGroup, char * sName, void * pFunc, int fChanges )
+{
+ char * key, * value;
+ Abc_Command * pCommand;
+ int fStatus;
+
+ key = sName;
+ if ( st_delete( pAbc->tCommands, &key, &value ) )
+ {
+ // delete existing definition for this command
+ fprintf( pAbc->Err, "Cmd warning: redefining '%s'\n", sName );
+ CmdCommandFree( (Abc_Command *)value );
+ }
+
+ // create the new command
+ pCommand = ALLOC( Abc_Command, 1 );
+ pCommand->sName = util_strsav( sName );
+ pCommand->sGroup = util_strsav( sGroup );
+ pCommand->pFunc = pFunc;
+ pCommand->fChange = fChanges;
+ fStatus = st_insert( pAbc->tCommands, sName, (char *)pCommand );
+ assert( !fStatus ); // the command should not be in the table
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cmd_CommandExecute( Abc_Frame_t * pAbc, char * sCommand )
+{
+ int fStatus = 0, argc, loop;
+ char * sCommandNext, **argv;
+
+ if ( !pAbc->fAutoexac )
+ Cmd_HistoryAddCommand(pAbc, sCommand);
+ sCommandNext = sCommand;
+ do
+ {
+ sCommandNext = CmdSplitLine( pAbc, sCommandNext, &argc, &argv );
+ loop = 0;
+ fStatus = CmdApplyAlias( pAbc, &argc, &argv, &loop );
+ if ( fStatus == 0 )
+ fStatus = CmdCommandDispatch( pAbc, argc, argv );
+ CmdFreeArgv( argc, argv );
+ }
+ while ( fStatus == 0 && *sCommandNext != '\0' );
+ return fStatus;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/cmd/cmdFlag.c b/src/base/cmd/cmdFlag.c
new file mode 100644
index 00000000..96f1f251
--- /dev/null
+++ b/src/base/cmd/cmdFlag.c
@@ -0,0 +1,112 @@
+/**CFile****************************************************************
+
+ FileName [cmdFlag.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures working with flags.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdFlag.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function********************************************************************
+
+ Synopsis [Looks up value of flag in table of named values.]
+
+ Description [The command parser maintains a table of named values. These
+ are manipulated using the 'set' and 'unset' commands. The value of the
+ named flag is returned, or NIL(char) is returned if the flag has not been
+ set.]
+
+ SideEffects []
+
+******************************************************************************/
+char * Cmd_FlagReadByName( Abc_Frame_t * pAbc, char * flag )
+{
+ char *value;
+
+ if (st_lookup(pAbc->tFlags, flag, &value)) {
+ return value;
+ }
+ else {
+ return NIL(char);
+ }
+}
+
+
+/**Function********************************************************************
+
+ Synopsis [Updates a set value by calling instead of set command.]
+
+ Description [Updates a set value by calling instead of set command.]
+
+ SideEffects []
+
+******************************************************************************/
+void Cmd_FlagUpdateValue( Abc_Frame_t * pAbc, char * key, char * value )
+{
+ char *oldValue, *newValue;
+
+ if (!key)
+ return;
+ if (value)
+ newValue = util_strsav(value);
+ else
+ newValue = util_strsav("");
+
+ if (st_delete(pAbc->tFlags, &key, &oldValue))
+ FREE(oldValue);
+
+ st_insert(pAbc->tFlags, key, newValue);
+}
+
+
+/**Function********************************************************************
+
+ Synopsis [Deletes a set value by calling instead of unset command.]
+
+ Description [Deletes a set value by calling instead of unset command.]
+
+ SideEffects []
+
+******************************************************************************/
+void Cmd_FlagDeleteByName( Abc_Frame_t * pAbc, char * key )
+{
+ char *value;
+
+ if (!key)
+ return;
+
+ if (st_delete(pAbc->tFlags, &key, &value)) {
+ FREE(key);
+ FREE(value);
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/cmd/cmdHist.c b/src/base/cmd/cmdHist.c
new file mode 100644
index 00000000..5b46ea00
--- /dev/null
+++ b/src/base/cmd/cmdHist.c
@@ -0,0 +1,55 @@
+/**CFile****************************************************************
+
+ FileName [cmdHist.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures working with history.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdHist.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+#include "cmd.h"
+#include "cmdInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cmd_HistoryAddCommand( Abc_Frame_t * p, char * command )
+{
+ char Buffer[500];
+ strcpy( Buffer, command );
+ if ( command[strlen(command)-1] != '\n' )
+ strcat( Buffer, "\n" );
+ Vec_PtrPush( p->aHistory, util_strsav(Buffer) );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/base/cmd/cmdInt.h b/src/base/cmd/cmdInt.h
new file mode 100644
index 00000000..f0289ad4
--- /dev/null
+++ b/src/base/cmd/cmdInt.h
@@ -0,0 +1,82 @@
+/**CFile****************************************************************
+
+ FileName [cmdInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Internal declarations of the command package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __CMD_INT_H__
+#define __CMD_INT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "mainInt.h"
+#include "cmd.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct MvCommand
+{
+ char * sName; // the command name
+ char * sGroup; // the group name
+ void * pFunc; // the function to execute the command
+ int fChange; // set to 1 to mark that the network is changed
+};
+
+struct MvAlias
+{
+ char * sName; // the alias name
+ int argc; // the number of alias parts
+ char ** argv; // the alias parts
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== cmdAlias.c =============-========================================*/
+extern void CmdCommandAliasAdd( Abc_Frame_t * pAbc, char * sName, int argc, char ** argv );
+extern void CmdCommandAliasPrint( Abc_Frame_t * pAbc, Abc_Alias * pAlias );
+extern char * CmdCommandAliasLookup( Abc_Frame_t * pAbc, char * sCommand );
+extern void CmdCommandAliasFree( Abc_Alias * p );
+/*=== cmdUtils.c =======================================================*/
+extern int CmdCommandDispatch( Abc_Frame_t * pAbc, int argc, char ** argv );
+extern char * CmdSplitLine( Abc_Frame_t * pAbc, char * sCommand, int * argc, char *** argv );
+extern int CmdApplyAlias( Abc_Frame_t * pAbc, int * argc, char *** argv, int * loop );
+extern char * CmdHistorySubstitution( Abc_Frame_t * pAbc, char * line, int * changed );
+extern FILE * CmdFileOpen( Abc_Frame_t * pAbc, char * sFileName, char * sMode, char ** pFileNameReal, int silent );
+extern void CmdFreeArgv( int argc, char ** argv );
+extern void CmdCommandFree( Abc_Command * pCommand );
+extern void CmdCommandPrint( Abc_Frame_t * pAbc, bool fPrintAll );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/base/cmd/cmdUtils.c b/src/base/cmd/cmdUtils.c
new file mode 100644
index 00000000..67a290a2
--- /dev/null
+++ b/src/base/cmd/cmdUtils.c
@@ -0,0 +1,598 @@
+/**CFile****************************************************************
+
+ FileName [cmdUtils.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Various utilities of the command package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cmdUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+#include "abc.h"
+#include "cmdInt.h"
+#include <ctype.h> // proper declaration of isspace
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int CmdCommandPrintCompare( Abc_Command ** ppC1, Abc_Command ** ppC2 );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int cmdCheckShellEscape( Abc_Frame_t * pAbc, int argc, char ** argv)
+{
+ if (argv[0][0] == '!')
+ {
+ const int size = 4096;
+ int i;
+ char buffer[4096];
+ strncpy (buffer, &argv[0][1], size);
+ for (i = 1; i < argc; ++i)
+ {
+ strncat (buffer, " ", size);
+ strncat (buffer, argv[i], size);
+ }
+ if (buffer[0] == 0)
+ strncpy (buffer, "/bin/sh", size);
+ system (buffer);
+
+ // NOTE: Since we reconstruct the cmdline by concatenating
+ // the parts, we lose information. So a command like
+ // `!ls "file name"` will be sent to the system as
+ // `ls file name` which is a BUG
+
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Executes one command.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CmdCommandDispatch( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ Abc_Ntk_t * pNetCopy;
+ int (*pFunc) ( Abc_Frame_t *, int, char ** );
+ Abc_Command * pCommand;
+ char * value;
+ int fError;
+ int clk;
+
+ if ( argc == 0 )
+ return 0;
+
+ if ( cmdCheckShellEscape( pAbc, argc, argv ) == 1 )
+ return 0;
+
+ // get the command
+ if ( !st_lookup( pAbc->tCommands, argv[0], (char **)&pCommand ) )
+ { // the command is not in the table
+ fprintf( pAbc->Err, "** cmd error: unknown command '%s'\n", argv[0] );
+ return 1;
+ }
+
+ // get the backup network if the command is going to change the network
+ if ( pCommand->fChange )
+ {
+ if ( pAbc->pNtkCur )
+ {
+ pNetCopy = Abc_NtkDup( pAbc->pNtkCur );
+ Abc_FrameSetCurrentNetwork( pAbc, pNetCopy );
+ // swap the current network and the backup network
+ // to prevent the effect of resetting the short names
+ Abc_FrameSwapCurrentAndBackup( pAbc );
+ }
+ }
+
+ // execute the command
+ clk = util_cpu_time();
+ pFunc = ( int (*)( Abc_Frame_t *, int, char ** ) ) pCommand->pFunc;
+ fError = (*pFunc)( pAbc, argc, argv );
+ pAbc->TimeCommand += (util_cpu_time() - clk);
+
+// if ( !fError && pCommand->fChange && pAbc->pNtkCur )
+// {
+// Cmd_HistoryAddSnapshot(pAbc, pAbc->pNet);
+// }
+
+ // automatic execution of arbitrary command after each command
+ // usually this is a passive command ...
+ if ( fError == 0 && !pAbc->fAutoexac )
+ {
+ if ( st_lookup( pAbc->tFlags, "autoexec", &value ) )
+ {
+ pAbc->fAutoexac = 1;
+ fError = Cmd_CommandExecute( pAbc, value );
+ pAbc->fAutoexac = 0;
+ }
+ }
+ return fError;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Splits the command line string into individual commands.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * CmdSplitLine( Abc_Frame_t * pAbc, char *sCommand, int *argc, char ***argv )
+{
+ char *p, *start, c;
+ int i, j;
+ char *new_arg;
+ Vec_Ptr_t * vArgs;
+ int single_quote, double_quote;
+
+ vArgs = Vec_PtrAlloc( 10 );
+
+ p = sCommand;
+ for ( ;; )
+ {
+ // skip leading white space
+ while ( isspace( ( int ) *p ) )
+ {
+ p++;
+ }
+
+ // skip until end of this token
+ single_quote = double_quote = 0;
+ for ( start = p; ( c = *p ) != '\0'; p++ )
+ {
+ if ( c == ';' || c == '#' || isspace( ( int ) c ) )
+ {
+ if ( !single_quote && !double_quote )
+ {
+ break;
+ }
+ }
+ if ( c == '\'' )
+ {
+ single_quote = !single_quote;
+ }
+ if ( c == '"' )
+ {
+ double_quote = !double_quote;
+ }
+ }
+ if ( single_quote || double_quote )
+ {
+ ( void ) fprintf( pAbc->Err, "** cmd warning: ignoring unbalanced quote ...\n" );
+ }
+ if ( start == p )
+ break;
+
+ new_arg = ALLOC( char, p - start + 1 );
+ j = 0;
+ for ( i = 0; i < p - start; i++ )
+ {
+ c = start[i];
+ if ( ( c != '\'' ) && ( c != '\"' ) )
+ {
+ new_arg[j++] = isspace( ( int ) c ) ? ' ' : start[i];
+ }
+ }
+ new_arg[j] = '\0';
+ Vec_PtrPush( vArgs, new_arg );
+ }
+
+ *argc = vArgs->nSize;
+ *argv = (char **)Vec_PtrReleaseArray( vArgs );
+ Vec_PtrFree( vArgs );
+ if ( *p == ';' )
+ {
+ p++;
+ }
+ else if ( *p == '#' )
+ {
+ for ( ; *p != 0; p++ ); // skip to end of line
+ }
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Replaces parts of the command line string by aliases if given.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CmdApplyAlias( Abc_Frame_t * pAbc, int *argcp, char ***argvp, int *loop )
+{
+ int i, argc, stopit, added, offset, did_subst, subst, fError, newc, j;
+ char *arg, **argv, **newv;
+ Abc_Alias *alias;
+
+ argc = *argcp;
+ argv = *argvp;
+ stopit = 0;
+ for ( ; *loop < 20; ( *loop )++ )
+ {
+ if ( argc == 0 )
+ return 0;
+ if ( stopit != 0 || st_lookup( pAbc->tAliases, argv[0], (char **) &alias ) == 0 )
+ {
+ return 0;
+ }
+ if ( strcmp( argv[0], alias->argv[0] ) == 0 )
+ {
+ stopit = 1;
+ }
+ FREE( argv[0] );
+ added = alias->argc - 1;
+
+ /* shift all the arguments to the right */
+ if ( added != 0 )
+ {
+ argv = REALLOC( char *, argv, argc + added );
+ for ( i = argc - 1; i >= 1; i-- )
+ {
+ argv[i + added] = argv[i];
+ }
+ for ( i = 1; i <= added; i++ )
+ {
+ argv[i] = NIL( char );
+ }
+ argc += added;
+ }
+ subst = 0;
+ for ( i = 0, offset = 0; i < alias->argc; i++, offset++ )
+ {
+ arg = CmdHistorySubstitution( pAbc, alias->argv[i], &did_subst );
+ if ( arg == NIL( char ) )
+ {
+ *argcp = argc;
+ *argvp = argv;
+ return ( 1 );
+ }
+ if ( did_subst != 0 )
+ {
+ subst = 1;
+ }
+ fError = 0;
+ do
+ {
+ arg = CmdSplitLine( pAbc, arg, &newc, &newv );
+ /*
+ * If there's a complete `;' terminated command in `arg',
+ * when split_line() returns arg[0] != '\0'.
+ */
+ if ( arg[0] == '\0' )
+ { /* just a bunch of words */
+ break;
+ }
+ fError = CmdApplyAlias( pAbc, &newc, &newv, loop );
+ if ( fError == 0 )
+ {
+ fError = CmdCommandDispatch( pAbc, newc, newv );
+ }
+ CmdFreeArgv( newc, newv );
+ }
+ while ( fError == 0 );
+ if ( fError != 0 )
+ {
+ *argcp = argc;
+ *argvp = argv;
+ return ( 1 );
+ }
+ added = newc - 1;
+ if ( added != 0 )
+ {
+ argv = REALLOC( char *, argv, argc + added );
+ for ( j = argc - 1; j > offset; j-- )
+ {
+ argv[j + added] = argv[j];
+ }
+ argc += added;
+ }
+ for ( j = 0; j <= added; j++ )
+ {
+ argv[j + offset] = newv[j];
+ }
+ FREE( newv );
+ offset += added;
+ }
+ if ( subst == 1 )
+ {
+ for ( i = offset; i < argc; i++ )
+ {
+ FREE( argv[i] );
+ }
+ argc = offset;
+ }
+ *argcp = argc;
+ *argvp = argv;
+ }
+
+ fprintf( pAbc->Err, "** cmd warning: alias loop\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs history substitution (now, disabled).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * CmdHistorySubstitution( Abc_Frame_t * pAbc, char *line, int *changed )
+{
+ // as of today, no history substitution
+ *changed = 0;
+ return line;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Opens the file with path (now, disabled).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+FILE * CmdFileOpen( Abc_Frame_t * pAbc, char *sFileName, char *sMode, char **pFileNameReal, int silent )
+{
+ char * sRealName, * sPathUsr, * sPathLib, * sPathAll;
+ FILE * pFile;
+
+ if (strcmp(sFileName, "-") == 0) {
+ if (strcmp(sMode, "w") == 0) {
+ sRealName = util_strsav( "stdout" );
+ pFile = stdout;
+ }
+ else {
+ sRealName = util_strsav( "stdin" );
+ pFile = stdin;
+ }
+ }
+ else {
+ sRealName = NULL;
+ if (strcmp(sMode, "r") == 0) {
+
+ /* combine both pathes if exist */
+ sPathUsr = Cmd_FlagReadByName(pAbc,"open_path");
+ sPathLib = Cmd_FlagReadByName(pAbc,"lib_path");
+
+ if ( sPathUsr == NULL && sPathLib == NULL ) {
+ sPathAll = NULL;
+ }
+ else if ( sPathUsr == NULL ) {
+ sPathAll = util_strsav( sPathLib );
+ }
+ else if ( sPathLib == NULL ) {
+ sPathAll = util_strsav( sPathUsr );
+ }
+ else {
+ sPathAll = ALLOC( char, strlen(sPathLib)+strlen(sPathUsr)+5 );
+ sprintf( sPathAll, "%s:%s",sPathUsr, sPathLib );
+ }
+ if ( sPathAll != NIL(char) ) {
+ sRealName = util_file_search(sFileName, sPathAll, "r");
+ FREE( sPathAll );
+ }
+ }
+ if (sRealName == NIL(char)) {
+ sRealName = util_tilde_expand(sFileName);
+ }
+ if ((pFile = fopen(sRealName, sMode)) == NIL(FILE)) {
+ if (! silent) {
+ perror(sRealName);
+ }
+ }
+ }
+ if ( pFileNameReal )
+ *pFileNameReal = sRealName;
+ else
+ FREE(sRealName);
+
+ return pFile;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the previously allocated argv array.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CmdFreeArgv( int argc, char **argv )
+{
+ int i;
+ for ( i = 0; i < argc; i++ )
+ FREE( argv[i] );
+ FREE( argv );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the previously allocated command.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CmdCommandFree( Abc_Command * pCommand )
+{
+ free( pCommand->sGroup );
+ free( pCommand->sName );
+ free( pCommand );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints commands alphabetically by group.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void CmdCommandPrint( Abc_Frame_t * pAbc, bool fPrintAll )
+{
+ char *key, *value;
+ st_generator * gen;
+ Abc_Command ** ppCommands;
+ Abc_Command * pCommands;
+ int nCommands, i;
+ char * sGroupCur;
+ int LenghtMax, nColumns, iCom = 0;
+
+ // put all commands into one array
+ nCommands = st_count( pAbc->tCommands );
+ ppCommands = ALLOC( Abc_Command *, nCommands );
+ i = 0;
+ st_foreach_item( pAbc->tCommands, gen, &key, &value )
+ {
+ pCommands = (Abc_Command *)value;
+ if ( fPrintAll || pCommands->sName[0] != '_' )
+ ppCommands[i++] = pCommands;
+ }
+ nCommands = i;
+
+ // sort command by group and then by name, alphabetically
+ qsort( (void *)ppCommands, nCommands, sizeof(Abc_Command *),
+ (int (*)(const void *, const void *)) CmdCommandPrintCompare );
+ assert( CmdCommandPrintCompare( ppCommands, ppCommands + nCommands - 1 ) <= 0 );
+
+ // get the longest command name
+ LenghtMax = 0;
+ for ( i = 0; i < nCommands; i++ )
+ if ( LenghtMax < (int)strlen(ppCommands[i]->sName) )
+ LenghtMax = (int)strlen(ppCommands[i]->sName);
+ // get the number of columns
+ nColumns = 79 / (LenghtMax + 2);
+
+ // print the starting message
+ fprintf( pAbc->Out, " Welcome to ABC!" );
+
+ // print the command by group
+ sGroupCur = NULL;
+ for ( i = 0; i < nCommands; i++ )
+ if ( sGroupCur && strcmp( sGroupCur, ppCommands[i]->sGroup ) == 0 )
+ { // this command belongs to the same group as the previous one
+ if ( iCom++ % nColumns == 0 )
+ fprintf( pAbc->Out, "\n" );
+ // print this command
+ fprintf( pAbc->Out, " %-*s", LenghtMax, ppCommands[i]->sName );
+ }
+ else
+ { // this command starts the new group of commands
+ // start the new group
+ fprintf( pAbc->Out, "\n" );
+ fprintf( pAbc->Out, "\n" );
+ fprintf( pAbc->Out, "%s commands:\n", ppCommands[i]->sGroup );
+ // print this command
+ fprintf( pAbc->Out, " %-*s", LenghtMax, ppCommands[i]->sName );
+ // remember current command group
+ sGroupCur = ppCommands[i]->sGroup;
+ // reset the command counter
+ iCom = 1;
+ }
+ fprintf( pAbc->Out, "\n" );
+ FREE( ppCommands );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Comparision function used for sorting commands.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int CmdCommandPrintCompare( Abc_Command ** ppC1, Abc_Command ** ppC2 )
+{
+ Abc_Command * pC1 = *ppC1;
+ Abc_Command * pC2 = *ppC2;
+ int RetValue;
+
+ RetValue = strcmp( pC1->sGroup, pC2->sGroup );
+ if ( RetValue < 0 )
+ return -1;
+ if ( RetValue > 0 )
+ return 1;
+ // the command belong to the same group
+
+ // put commands with "_" at the end of the list
+ if ( pC1->sName[0] != '_' && pC2->sName[0] == '_' )
+ return -1;
+ if ( pC1->sName[0] == '_' && pC2->sName[0] != '_' )
+ return 1;
+
+ RetValue = strcmp( pC1->sName, pC2->sName );
+ if ( RetValue < 0 )
+ return -1;
+ if ( RetValue > 0 )
+ return 1;
+ // should not be two indentical commands
+ assert( 0 );
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/base/cmd/module.make b/src/base/cmd/module.make
new file mode 100644
index 00000000..1eca3f65
--- /dev/null
+++ b/src/base/cmd/module.make
@@ -0,0 +1,6 @@
+SRC += src/base/cmd/cmd.c \
+ src/base/cmd/cmdAlias.c \
+ src/base/cmd/cmdApi.c \
+ src/base/cmd/cmdFlag.c \
+ src/base/cmd/cmdHist.c \
+ src/base/cmd/cmdUtils.c
diff --git a/src/base/io/io.c b/src/base/io/io.c
new file mode 100644
index 00000000..4698de91
--- /dev/null
+++ b/src/base/io/io.c
@@ -0,0 +1,766 @@
+/**CFile****************************************************************
+
+ FileName [io.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Command file.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: io.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+#include "mainInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int IoCommandRead ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadBlif ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadBench ( Abc_Frame_t * pAbc, int argc, char **argv );
+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 );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_Init( Abc_Frame_t * pAbc )
+{
+ Cmd_CommandAdd( pAbc, "I/O", "read", IoCommandRead, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_blif", IoCommandReadBlif, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_bench", IoCommandReadBench, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_verilog", IoCommandReadVerilog, 1 );
+ 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 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_End()
+{
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandRead( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ char * FileName;
+ FILE * pFile;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind + 1 )
+ {
+ goto usage;
+ }
+
+ // get the input file name
+ FileName = argv[util_optind];
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
+ if ( FileName = Extra_FileGetSimilarName( FileName, ".mv", ".blif", ".pla", ".mvpla", NULL ) )
+ fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
+ fprintf( pAbc->Err, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+
+ // set the new network
+ pNtk = Io_Read( FileName, fCheck );
+ if ( pNtk == NULL )
+ {
+ fprintf( pAbc->Err, "Reading network from file has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: read [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network from file in Verilog/BLIF/BENCH format\n" );
+ fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" );
+ fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
+ fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandReadBlif( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk, * pTemp;
+ char * FileName;
+ FILE * pFile;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind + 1 )
+ {
+ goto usage;
+ }
+
+ // get the input file name
+ FileName = argv[util_optind];
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
+ if ( FileName = Extra_FileGetSimilarName( FileName, ".mv", ".blif", ".pla", ".mvpla", NULL ) )
+ fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
+ fprintf( pAbc->Err, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+
+ // set the new network
+ pNtk = Io_ReadBlif( FileName, fCheck );
+ if ( pNtk == NULL )
+ {
+ fprintf( pAbc->Err, "Reading network from BLIF file has failed.\n" );
+ return 1;
+ }
+
+ pNtk = Abc_NtkLogic( pTemp = pNtk );
+ Abc_NtkDelete( pTemp );
+ if ( pNtk == NULL )
+ {
+ fprintf( pAbc->Err, "Converting to logic network after reading has failed.\n" );
+ return 1;
+ }
+
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: read_blif [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in binary BLIF format\n" );
+ fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" );
+ fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
+ fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
+ return 1;
+}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandReadBench( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk, * pTemp;
+ char * FileName;
+ FILE * pFile;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind + 1 )
+ {
+ goto usage;
+ }
+
+ // get the input file name
+ FileName = argv[util_optind];
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
+ if ( FileName = Extra_FileGetSimilarName( FileName, ".mv", ".blif", ".pla", ".mvpla", NULL ) )
+ fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
+ fprintf( pAbc->Err, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+
+ // set the new network
+ pNtk = Io_ReadBench( FileName, fCheck );
+ if ( pNtk == NULL )
+ {
+ fprintf( pAbc->Err, "Reading network from BENCH file has failed.\n" );
+ return 1;
+ }
+
+ pNtk = Abc_NtkLogic( pTemp = pNtk );
+ Abc_NtkDelete( pTemp );
+ if ( pNtk == NULL )
+ {
+ fprintf( pAbc->Err, "Converting to logic network after reading has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: read_bench [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in BENCH format\n" );
+ fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" );
+ fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
+ fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandReadVerilog( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk, * pTemp;
+ char * FileName;
+ FILE * pFile;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind + 1 )
+ {
+ goto usage;
+ }
+
+ // get the input file name
+ FileName = argv[util_optind];
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
+ if ( FileName = Extra_FileGetSimilarName( FileName, ".mv", ".blif", ".pla", ".mvpla", NULL ) )
+ fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
+ fprintf( pAbc->Err, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+
+ // set the new network
+ pNtk = Io_ReadVerilog( FileName, fCheck );
+ if ( pNtk == NULL )
+ {
+ fprintf( pAbc->Err, "Reading network from Verilog file has failed.\n" );
+ return 1;
+ }
+
+ pNtk = Abc_NtkLogic( pTemp = pNtk );
+ Abc_NtkDelete( pTemp );
+ if ( pNtk == NULL )
+ {
+ fprintf( pAbc->Err, "Converting to logic network after reading has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: read_verilog [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in Verilog (IWLS 2005 subset)\n" );
+ fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" );
+ fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
+ fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandReadPla( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk, * pTemp;
+ char * FileName;
+ FILE * pFile;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != util_optind + 1 )
+ {
+ goto usage;
+ }
+
+ // get the input file name
+ FileName = argv[util_optind];
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
+ if ( FileName = Extra_FileGetSimilarName( FileName, ".mv", ".blif", ".pla", ".mvpla", NULL ) )
+ fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
+ fprintf( pAbc->Err, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+
+ // set the new network
+// pNtk = Io_ReadPla( FileName, fCheck );
+ fprintf( pAbc->Err, "This command is currently not implemented.\n" );
+ pNtk = NULL;
+ if ( pNtk == NULL )
+ {
+ fprintf( pAbc->Err, "Reading network from PLA file has failed.\n" );
+ return 1;
+ }
+
+ pNtk = Abc_NtkLogic( pTemp = pNtk );
+ Abc_NtkDelete( pTemp );
+ if ( pNtk == NULL )
+ {
+ fprintf( pAbc->Err, "Converting to logic network after reading has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: read_pla [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in PLA\n" );
+ fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" );
+ fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
+ fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * FileName;
+ int fMadeComb;
+ int fWriteLatches;
+ int c;
+
+ 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 ( pAbc->pNtkCur == NULL )
+ {
+ fprintf( pAbc->Out, "Empty network.\n" );
+ return 0;
+ }
+
+ if ( argc != util_optind + 1 )
+ {
+ 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
+ {
+ assert( 0 );
+ }
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_blif [-lh] <file>\n" );
+ fprintf( pAbc->Err, "\t write the network into a BLIF file\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 IoCommandWriteGate( 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_NtkIsLogicMap(pNtk) )
+ {
+ fprintf( pAbc->Out, "The network is not mapped.\n" );
+ return 0;
+ }
+/*
+ if ( Abc_NtkLatchNum(pNtk) > 0 )
+ {
+ fprintf( pAbc->Out, "The network has latches.\n" );
+ return 0;
+ }
+*/
+ if ( argc != util_optind + 1 )
+ {
+ goto usage;
+ }
+
+ // get the input file name
+ FileName = argv[util_optind];
+ // write the file
+ Io_WriteGate( pNtk, FileName );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_gate [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the network into a mapped BLIF file (.gate ...)\n" );
+// fprintf( pAbc->Err, "\t-l : toggle writing latches [default = %s]\n", fWriteLatches? "yes":"no" );
+ fprintf( pAbc->Err, "\t-h : print the help massage\n" );
+ fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteBench( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ Abc_Ntk_t * pNtk;
+ char * FileName;
+ int fWriteLatches;
+ int c;
+
+ pNtk = pAbc->pNtkCur;
+ fWriteLatches = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "lh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'l':
+ fWriteLatches ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pAbc->Out, "Empty network.\n" );
+ return 0;
+ }
+
+ if ( !Abc_NtkIsAig(pNtk) )
+ {
+ fprintf( pAbc->Out, "The network should be an AIG.\n" );
+ return 0;
+ }
+
+ if ( argc != util_optind + 1 )
+ {
+ goto usage;
+ }
+
+ // get the input file name
+ FileName = argv[util_optind];
+ // write the file
+ Io_WriteBench( pNtk, FileName );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_bench [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the network in BENCH format\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 IoCommandWriteCnf( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * FileName;
+ int c;
+
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pAbc->pNtkCur == NULL )
+ {
+ fprintf( pAbc->Out, "Empty network.\n" );
+ return 0;
+ }
+
+ if ( argc != util_optind + 1 )
+ {
+ goto usage;
+ }
+
+ // get the input file name
+ FileName = argv[util_optind];
+ // write the file
+ if ( !Io_WriteCnf( pAbc->pNtkCur, FileName ) )
+ {
+ printf( "Writing CNF has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_cnf [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the miter cone into a CNF file\n" );
+ fprintf( pAbc->Err, "\t-h : print the help massage\n" );
+ fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/io.h b/src/base/io/io.h
new file mode 100644
index 00000000..ba61faac
--- /dev/null
+++ b/src/base/io/io.h
@@ -0,0 +1,74 @@
+/**CFile****************************************************************
+
+ FileName [io.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: io.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __IO_H__
+#define __IO_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define IO_WRITE_LINE_LENGTH 78 // the output line length
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== abcRead.c ==========================================================*/
+extern Abc_Ntk_t * Io_Read( char * pFileName, int fCheck );
+/*=== abcReadBlif.c ==========================================================*/
+extern Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck );
+/*=== abcReadBench.c ==========================================================*/
+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 );
+/*=== 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_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
+/*=== 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 );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/base/io/ioInt.h b/src/base/io/ioInt.h
new file mode 100644
index 00000000..69d125fc
--- /dev/null
+++ b/src/base/io/ioInt.h
@@ -0,0 +1,49 @@
+/**CFile****************************************************************
+
+ FileName [ioInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __IO_INT_H__
+#define __IO_INT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/src/base/io/ioRead.c b/src/base/io/ioRead.c
new file mode 100644
index 00000000..18e4b153
--- /dev/null
+++ b/src/base/io/ioRead.c
@@ -0,0 +1,74 @@
+/**CFile****************************************************************
+
+ FileName [ioRead.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedure to read network from file.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioRead.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Read the network from a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_Read( char * pFileName, int fCheck )
+{
+ Abc_Ntk_t * pNtk, * pTemp;
+ // set the new network
+ if ( Extra_FileNameCheckExtension( pFileName, "blif" ) )
+ pNtk = Io_ReadBlif( pFileName, fCheck );
+ else if ( Extra_FileNameCheckExtension( pFileName, "v" ) )
+ pNtk = Io_ReadVerilog( pFileName, fCheck );
+ else if ( Extra_FileNameCheckExtension( pFileName, "bench" ) )
+ pNtk = Io_ReadBench( pFileName, fCheck );
+ else
+ {
+ fprintf( stderr, "Unknown file format\n" );
+ return NULL;
+ }
+ if ( pNtk == NULL )
+ return NULL;
+ pNtk = Abc_NtkLogic( pTemp = pNtk );
+ Abc_NtkDelete( pTemp );
+ if ( pNtk == NULL )
+ {
+ fprintf( stdout, "Converting to logic network after reading has failed.\n" );
+ return NULL;
+ }
+ return pNtk;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+
diff --git a/src/base/io/ioReadBench.c b/src/base/io/ioReadBench.c
new file mode 100644
index 00000000..0660adc7
--- /dev/null
+++ b/src/base/io/ioReadBench.c
@@ -0,0 +1,227 @@
+/**CFile****************************************************************
+
+ FileName [ioReadBench.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to read BENCH files.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioReadBench.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Read the network from BENCH file.]
+
+ Description [Currently works only for the miter cone.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadBench( char * pFileName, int fCheck )
+{
+ Extra_FileReader_t * p;
+ Abc_Ntk_t * pNtk;
+
+ // start the file
+ p = Extra_FileReaderAlloc( pFileName, "#", "\n", " \t\r,()=" );
+ if ( p == NULL )
+ return NULL;
+
+ // read the network
+ pNtk = Io_ReadBenchNetwork( p );
+ Extra_FileReaderFree( p );
+ if ( pNtk == NULL )
+ return NULL;
+
+ // make sure that everything is okay with the network structure
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Io_ReadBench: The network check has failed.\n" );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ return pNtk;
+}
+/**Function*************************************************************
+
+ Synopsis [Read the network from BENCH file.]
+
+ Description [Currently works only for the miter cone.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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;
+ Vec_Str_t * vString;
+ char * pType;
+ int SymbolIn, SymbolOut, i, iLine;
+
+ // 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) );
+
+ // go through the lines of the file
+ vString = Vec_StrAlloc( 100 );
+ pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p) );
+ for ( iLine = 0; vTokens = Extra_FileReaderGetTokens(p); iLine++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p), NULL );
+
+ if ( vTokens->nSize == 1 )
+ {
+ printf( "%s: Wrong input file format.\n", Extra_FileReaderGetFileName(p) );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+
+ // 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 );
+ }
+ 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 );
+ }
+ 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 );
+ }
+ 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
+ {
+ 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 );
+ // 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") );
+ }
+ 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_ReadSetNonDrivenNets( pNtk );
+ Vec_StrFree( vString );
+ return pNtk;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+
diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c
new file mode 100644
index 00000000..6d9c2347
--- /dev/null
+++ b/src/base/io/ioReadBlif.c
@@ -0,0 +1,642 @@
+/**CFile****************************************************************
+
+ FileName [ioReadBlif.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to read BLIF files.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioReadBlif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+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
+ // 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
+ // temporary storage for 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
+};
+
+static Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName );
+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 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_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
+static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Read the network from BLIF file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
+{
+ Io_ReadBlif_t * p;
+ Abc_Ntk_t * pNtk, * pNtkExdc;
+
+ // start the file
+ p = Io_ReadBlifFile( pFileName );
+ if ( p == NULL )
+ return NULL;
+
+ // read the network
+ pNtk = Io_ReadBlifNetwork( p );
+ if ( pNtk == NULL )
+ {
+ Io_ReadBlifFree( p );
+ return NULL;
+ }
+ Abc_NtkTimeFinalize( pNtk );
+
+ // read the EXDC network
+ if ( p->fParsingExdc )
+ {
+ pNtkExdc = Io_ReadBlifNetwork( p );
+ if ( pNtkExdc == NULL )
+ {
+ Abc_NtkDelete( pNtk );
+ Io_ReadBlifFree( p );
+ return NULL;
+ }
+ pNtk->pExdc = pNtkExdc;
+ }
+ Io_ReadBlifFree( p );
+
+ // make sure that everything is okay with the network structure
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Io_ReadBlif: The network check has failed.\n" );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts the reading data structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName )
+{
+ Extra_FileReader_t * pReader;
+ Io_ReadBlif_t * p;
+
+ // start the reader
+ pReader = Extra_FileReaderAlloc( pFileName, "#", "\n", " \t\r" );
+ if ( pReader == NULL )
+ return NULL;
+
+ // start the reading data structure
+ p = ALLOC( Io_ReadBlif_t, 1 );
+ memset( p, 0, sizeof(Io_ReadBlif_t) );
+ p->pFileName = pFileName;
+ p->pReader = pReader;
+ p->Output = stdout;
+ p->vNewTokens = Vec_PtrAlloc( 100 );
+ p->vCubes = Vec_StrAlloc( 100 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the data structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadBlifFree( Io_ReadBlif_t * p )
+{
+ Extra_FileReaderFree( p->pReader );
+ Vec_PtrFree( p->vNewTokens );
+ Vec_StrFree( p->vCubes );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the error message including the file name and line number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p )
+{
+ if ( p->LineCur == 0 ) // the line number is not given
+ fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError );
+ else // print the error message with the line number
+ fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Gets the tokens taking into account the line breaks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p )
+{
+ Vec_Ptr_t * vTokens;
+ char * pLastToken;
+ int i;
+
+ // get rid of the old tokens
+ if ( p->vNewTokens->nSize > 0 )
+ {
+ for ( i = 0; i < p->vNewTokens->nSize; i++ )
+ free( p->vNewTokens->pArray[i] );
+ p->vNewTokens->nSize = 0;
+ }
+
+ // get the new tokens
+ vTokens = Extra_FileReaderGetTokens(p->pReader);
+ if ( vTokens == NULL )
+ return vTokens;
+
+ // check if there is a transfer to another line
+ pLastToken = vTokens->pArray[vTokens->nSize - 1];
+ if ( pLastToken[ strlen(pLastToken)-1 ] != '\\' )
+ return vTokens;
+
+ // remove the slash
+ pLastToken[ strlen(pLastToken)-1 ] = 0;
+ if ( pLastToken[0] == 0 )
+ vTokens->nSize--;
+ // load them into the new array
+ for ( i = 0; i < vTokens->nSize; i++ )
+ Vec_PtrPush( p->vNewTokens, util_strsav(vTokens->pArray[i]) );
+
+ // load as long as there is the line break
+ while ( 1 )
+ {
+ // get the new tokens
+ vTokens = Extra_FileReaderGetTokens(p->pReader);
+ if ( vTokens->nSize == 0 )
+ return p->vNewTokens;
+ // check if there is a transfer to another line
+ pLastToken = vTokens->pArray[vTokens->nSize - 1];
+ if ( pLastToken[ strlen(pLastToken)-1 ] == '\\' )
+ {
+ // remove the slash
+ pLastToken[ strlen(pLastToken)-1 ] = 0;
+ if ( pLastToken[0] == 0 )
+ vTokens->nSize--;
+ // load them into the new array
+ for ( i = 0; i < vTokens->nSize; i++ )
+ Vec_PtrPush( p->vNewTokens, util_strsav(vTokens->pArray[i]) );
+ continue;
+ }
+ // otherwise, load them and break
+ for ( i = 0; i < vTokens->nSize; i++ )
+ Vec_PtrPush( p->vNewTokens, util_strsav(vTokens->pArray[i]) );
+ break;
+ }
+ return p->vNewTokens;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Reads the BLIF file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
+{
+ ProgressBar * pProgress;
+ Vec_Ptr_t * vTokens;
+ char * pModelName;
+ int iLine, fTokensReady, fStatus;
+
+ // read the model name
+ if ( !p->fParsingExdc )
+ {
+ // read the model name
+ vTokens = Io_ReadBlifGetTokens(p);
+ if ( vTokens == NULL || strcmp( vTokens->pArray[0], ".model" ) )
+ {
+ p->LineCur = 0;
+ sprintf( p->sError, "Wrong input file format." );
+ Io_ReadBlifPrintErrorMessage( p );
+ return NULL;
+ }
+ pModelName = vTokens->pArray[1];
+ // allocate the empty network
+ p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST );
+ p->pNtk->pName = util_strsav( pModelName );
+ p->pNtk->pSpec = util_strsav( p->pFileName );
+ }
+ else
+ p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST );
+
+ // read the inputs/outputs
+ pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
+ fTokensReady = fStatus = 0;
+ for ( iLine = 0; fTokensReady || (vTokens = Io_ReadBlifGetTokens(p)); iLine++ )
+ {
+ if ( iLine % 1000 == 0 )
+ Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL );
+
+ // consider different line types
+ fTokensReady = 0;
+ if ( !strcmp( vTokens->pArray[0], ".names" ) )
+ { fStatus = Io_ReadBlifNetworkNames( p, &vTokens ); fTokensReady = 1; }
+ else if ( !strcmp( vTokens->pArray[0], ".latch" ) )
+ fStatus = Io_ReadBlifNetworkLatch( p, vTokens );
+ else if ( !strcmp( vTokens->pArray[0], ".inputs" ) )
+ fStatus = Io_ReadBlifNetworkInputs( p, vTokens );
+ else if ( !strcmp( vTokens->pArray[0], ".outputs" ) )
+ fStatus = Io_ReadBlifNetworkOutputs( p, vTokens );
+ else if ( !strcmp( vTokens->pArray[0], ".input_arrival" ) )
+ fStatus = Io_ReadBlifNetworkInputArrival( p, vTokens );
+ else if ( !strcmp( vTokens->pArray[0], ".default_input_arrival" ) )
+ fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, vTokens );
+ else if ( !strcmp( vTokens->pArray[0], ".exdc" ) )
+ { p->fParsingExdc = 1; break; }
+ else if ( !strcmp( vTokens->pArray[0], ".end" ) )
+ break;
+ else
+ printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName,
+ Extra_FileReaderGetLineNumber(p->pReader, 0), vTokens->pArray[0] );
+ 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 );
+ return p->pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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 );
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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 );
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
+{
+ Abc_Ntk_t * pNtk = p->pNtk;
+ Abc_Obj_t * pNet, * pLatch;
+ int ResetValue;
+
+ if ( vTokens->nSize < 3 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "The .latch line does not have enough tokens." );
+ 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 );
+ // get the latch reset value
+ if ( vTokens->nSize == 3 )
+ ResetValue = 2;
+ else
+ {
+ ResetValue = atoi(vTokens->pArray[3]);
+ if ( ResetValue != 0 && ResetValue != 1 && ResetValue != 2 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "The .latch line has an unknown reset value (%s).", vTokens->pArray[3] );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ }
+ Abc_ObjSetData( pLatch, (void *)ResetValue );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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;
+
+ // 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);
+ sprintf( p->sError, "The .names line has less than two tokens." );
+ 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 );
+
+ // 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];
+ if ( pToken[0] == '.' )
+ break;
+ // read the cube
+ if ( vTokens->nSize != 1 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "The number of tokens in the constant cube is wrong." );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // create the cube
+ Char = ((char *)vTokens->pArray[0])[0];
+ Vec_StrPush( p->vCubes, ' ' );
+ Vec_StrPush( p->vCubes, Char );
+ Vec_StrPush( p->vCubes, '\n' );
+ }
+ else
+ while ( vTokens = Io_ReadBlifGetTokens(p) )
+ {
+ pToken = vTokens->pArray[0];
+ if ( pToken[0] == '.' )
+ break;
+ // read the cube
+ if ( vTokens->nSize != 2 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "The number of tokens in the cube is wrong." );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // create the cube
+ for ( i = 0; i < nFanins; i++ )
+ Vec_StrPush( p->vCubes, ((char *)vTokens->pArray[0])[i] );
+ // check the char
+ Char = ((char *)vTokens->pArray[1])[0];
+ if ( Char != '0' && Char != '1' )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "The output character in the constant cube is wrong." );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ Vec_StrPush( p->vCubes, ' ' );
+ Vec_StrPush( p->vCubes, Char );
+ Vec_StrPush( p->vCubes, '\n' );
+ }
+ // if there is nothing there
+ if ( p->vCubes->nSize == 0 )
+ {
+ // create an empty cube
+ Vec_StrPush( p->vCubes, ' ' );
+ Vec_StrPush( p->vCubes, '0' );
+ 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_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
+{
+ Abc_Obj_t * pNet;
+ char * pFoo1, * pFoo2;
+ double TimeRise, TimeFall;
+
+ // make sure this is indeed the .inputs line
+ assert( strncmp( vTokens->pArray[0], ".input_arrival", 14 ) == 0 );
+ if ( vTokens->nSize != 4 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "Wrong number of arguments on .input_arrival line." );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pNet = Abc_NtkFindNet( p->pNtk, vTokens->pArray[1] );
+ if ( pNet == NULL )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "Cannot find object corresponding to %s on .input_arrival line.", vTokens->pArray[1] );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ TimeRise = strtod( vTokens->pArray[2], &pFoo1 );
+ TimeFall = strtod( vTokens->pArray[3], &pFoo2 );
+ if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .input_arrival line.", vTokens->pArray[2], vTokens->pArray[3] );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // set the arrival time
+ Abc_NtkTimeSetArrival( p->pNtk, pNet->Id, (float)TimeRise, (float)TimeFall );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
+{
+ char * pFoo1, * pFoo2;
+ double TimeRise, TimeFall;
+
+ // make sure this is indeed the .inputs line
+ assert( strncmp( vTokens->pArray[0], ".default_input_arrival", 23 ) == 0 );
+ if ( vTokens->nSize != 3 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "Wrong number of arguments on .default_input_arrival line." );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ TimeRise = strtod( vTokens->pArray[1], &pFoo1 );
+ TimeFall = strtod( vTokens->pArray[2], &pFoo2 );
+ if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_input_arrival line.", vTokens->pArray[1], vTokens->pArray[2] );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // set the arrival time
+ Abc_NtkTimeSetDefaultArrival( p->pNtk, (float)TimeRise, (float)TimeFall );
+ return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioReadVerilog.c b/src/base/io/ioReadVerilog.c
new file mode 100644
index 00000000..a3b5a0bf
--- /dev/null
+++ b/src/base/io/ioReadVerilog.c
@@ -0,0 +1,888 @@
+/**CFile****************************************************************
+
+ FileName [ioReadVerilog.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to read a subset of structural Verilog from IWLS 2005 benchmark.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioReadVerilog.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Io_ReadVer_t_ Io_ReadVer_t; // all reading info
+struct Io_ReadVer_t_
+{
+ // general info about file
+ char * pFileName; // the name of the file
+ Extra_FileReader_t* pReader; // the input file reader
+ // current processing info
+ st_table * tKeywords; // mapping of keywords into codes
+ Abc_Ntk_t * pNtk; // the primary network
+ // the error message
+ FILE * Output; // the output stream
+ char sError[1000]; // the error string generated during parsing
+ int LineCur; // the line currently being parsed
+ Vec_Ptr_t * vSkipped; // temporary storage for skipped objects
+};
+
+// verilog keyword types
+typedef enum {
+ VER_NONE = 0,
+ VER_MODULE = -1,
+ VER_ENDMODULE = -2,
+ VER_INPUT = -3,
+ VER_OUTPUT = -4,
+ VER_INOUT = -5,
+ VER_WIRE = -6,
+ VER_ASSIGN = -7
+} Ver_KeywordType_t;
+
+// the list of verilog keywords
+static char * s_Keywords[10] =
+{
+ NULL, // unused
+ "module", // -1
+ "endmodule", // -2
+ "input", // -3
+ "output", // -4
+ "inout", // -5
+ "wire", // -6
+ "assign" // -7
+};
+
+// the list of gates in the Cadence library
+static char * s_CadenceGates[40][5] =
+{
+ { "INVX1", "1", "1", "0 1\n", NULL }, // 0
+ { "INVX2", "1", "1", "0 1\n", NULL }, // 1
+ { "INVX4", "1", "1", "0 1\n", NULL }, // 2
+ { "INVX8", "1", "1", "0 1\n", NULL }, // 3
+ { "BUFX1", "1", "1", "1 1\n", NULL }, // 4
+ { "BUFX3", "1", "1", "1 1\n", NULL }, // 5
+ { "NOR2X1", "2", "1", "00 1\n", NULL }, // 6
+ { "NOR3X1", "3", "1", "000 1\n", NULL }, // 7
+ { "NOR4X1", "4", "1", "0000 1\n", NULL }, // 8
+ { "NAND2X1", "2", "1", "11 0\n", NULL }, // 9
+ { "NAND2X2", "2", "1", "11 0\n", NULL }, // 10
+ { "NAND3X1", "3", "1", "111 0\n", NULL }, // 11
+ { "NAND4X1", "4", "1", "1111 0\n", NULL }, // 12
+ { "OR2X1", "2", "1", "00 0\n", NULL }, // 13
+ { "OR4X1", "4", "1", "0000 0\n", NULL }, // 14
+ { "AND2X1", "2", "1", "11 1\n", NULL }, // 15
+ { "XOR2X1", "2", "1", "01 1\n10 1\n", NULL }, // 16
+ { "MX2X1", "3", "1", "01- 1\n1-1 1\n", NULL }, // 17
+ { "OAI21X1", "3", "1", "00- 1\n--0 1\n", NULL }, // 18
+ { "OAI22X1", "4", "1", "00-- 1\n--00 1\n", NULL }, // 19
+ { "OAI33X1", "6", "1", "000--- 1\n---000 1\n", NULL }, // 20
+ { "AOI21X1", "3", "1", "11- 0\n--1 0\n", NULL }, // 21
+ { "AOI22X1", "4", "1", "11-- 0\n--11 0\n", NULL }, // 22
+ { "CLKBUFX1", "1", "1", "1 1\n", NULL }, // 23
+ { "CLKBUFX2", "1", "1", "1 1\n", NULL }, // 24
+ { "CLKBUFX3", "1", "1", "1 1\n", NULL }, // 25
+ { "ADDHX1", "2", "2", "11 1\n", "01 1\n10 1\n" }, // 26
+ { "ADDFX1", "3", "2", "11- 1\n-11 1\n1-1 1\n", "001 1\n010 1\n100 1\n111 1\n" }, // 27
+ { "DFFSRX1", "1", "1", NULL, NULL }, // 28
+ { "DFFX1", "1", "1", NULL, NULL }, // 29
+ { "SDFFSRX1", "1", "1", NULL, NULL }, // 30
+ { "TLATSRX1", "1", "1", NULL, NULL }, // 31
+ { "TLATX1", "1", "1", NULL, NULL }, // 32
+ { "TBUFX1", "1", "1", NULL, NULL }, // 33
+ { "TBUFX2", "1", "1", NULL, NULL }, // 34
+ { "TBUFX4", "1", "1", NULL, NULL }, // 35
+ { "TBUFX8", "1", "1", NULL, NULL }, // 36
+ { "TINVX1", "1", "1", NULL, NULL } // 37
+};
+
+static Io_ReadVer_t * Io_ReadVerFile( char * pFileName );
+static Abc_Ntk_t * Io_ReadVerNetwork( Io_ReadVer_t * p );
+static bool Io_ReadVerNetworkAssign( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens );
+static bool Io_ReadVerNetworkSignal( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType );
+static bool Io_ReadVerNetworkGateSimple( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType );
+static bool Io_ReadVerNetworkGateComplex( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType );
+static bool Io_ReadVerNetworkLatch( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens );
+static void Io_ReadVerPrintErrorMessage( Io_ReadVer_t * p );
+static void Io_ReadVerFree( Io_ReadVer_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Read the network from BENCH file.]
+
+ Description [Currently works only for the miter cone.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck )
+{
+ Io_ReadVer_t * p;
+ Abc_Ntk_t * pNtk;
+
+ // start the file
+ p = Io_ReadVerFile( pFileName );
+ if ( p == NULL )
+ return NULL;
+
+ // read the network
+ pNtk = Io_ReadVerNetwork( p );
+ Io_ReadVerFree( p );
+ if ( pNtk == NULL )
+ return NULL;
+
+ // make sure that everything is okay with the network structure
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Io_ReadVerilog: The network check has failed.\n" );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts the reading data structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Io_ReadVer_t * Io_ReadVerFile( char * pFileName )
+{
+ Extra_FileReader_t * pReader;
+ Io_ReadVer_t * p;
+ int i;
+
+ // start the reader
+ pReader = Extra_FileReaderAlloc( pFileName, "/", ";", " \t\r\n,()" );
+ if ( pReader == NULL )
+ return NULL;
+
+ // start the reading data structure
+ p = ALLOC( Io_ReadVer_t, 1 );
+ memset( p, 0, sizeof(Io_ReadVer_t) );
+ p->pFileName = pFileName;
+ p->pReader = pReader;
+ p->Output = stdout;
+ p->vSkipped = Vec_PtrAlloc( 100 );
+
+ // insert the keywords and gate names into the hash table
+ p->tKeywords = st_init_table(strcmp, st_strhash);
+ for ( i = 0; i < 10; i++ )
+ if ( s_Keywords[i] )
+ st_insert( p->tKeywords, (char *)s_Keywords[i], (char *)-i );
+ for ( i = 0; i < 40; i++ )
+ if ( s_CadenceGates[i][0] )
+ st_insert( p->tKeywords, (char *)s_CadenceGates[i][0], (char *)i );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the data structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadVerFree( Io_ReadVer_t * p )
+{
+ Extra_FileReaderFree( p->pReader );
+ Vec_PtrFree( p->vSkipped );
+ st_free_table( p->tKeywords );
+ FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the error message including the file name and line number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadVerPrintErrorMessage( Io_ReadVer_t * p )
+{
+ if ( p->LineCur == 0 ) // the line number is not given
+ fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError );
+ else // print the error message with the line number
+ fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the verilog file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadVerNetwork( Io_ReadVer_t * p )
+{
+ char Buffer[1000];
+ ProgressBar * pProgress;
+ Ver_KeywordType_t LineType;
+ Vec_Ptr_t * vTokens;
+ Abc_Ntk_t * pNtk;
+ char * pModelName;
+ int i;
+
+ // read the model name
+ vTokens = Extra_FileReaderGetTokens( p->pReader );
+ if ( vTokens == NULL || strcmp( vTokens->pArray[0], "module" ) )
+ {
+ p->LineCur = 0;
+ sprintf( p->sError, "Wrong input file format." );
+ Io_ReadVerPrintErrorMessage( p );
+ return NULL;
+ }
+ pModelName = vTokens->pArray[1];
+
+ // allocate the empty network
+ pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST );
+ pNtk->pName = util_strsav( pModelName );
+ pNtk->pSpec = util_strsav( p->pFileName );
+
+ // read the inputs/outputs
+ pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
+ for ( i = 0; vTokens = Extra_FileReaderGetTokens(p->pReader); i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL );
+
+ // get the line type
+ if ( !st_lookup( p->tKeywords, vTokens->pArray[0], (char **)&LineType ) )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "The first token \"%s\" cannot be recognized.", vTokens->pArray[0] );
+ Io_ReadVerPrintErrorMessage( p );
+ return NULL;
+ }
+ // consider Verilog directives
+ if ( LineType < 0 )
+ {
+ if ( LineType == VER_ENDMODULE )
+ break;
+ if ( LineType == VER_ASSIGN )
+ {
+ if ( !Io_ReadVerNetworkAssign( p, pNtk, vTokens ) )
+ return NULL;
+ continue;
+ }
+ if ( !Io_ReadVerNetworkSignal( p, pNtk, vTokens, LineType ) )
+ return NULL;
+ continue;
+ }
+ // proces single output gates
+ if ( LineType < 26 )
+ {
+ if ( !Io_ReadVerNetworkGateSimple( p, pNtk, vTokens, LineType ) )
+ return NULL;
+ continue;
+ }
+ // process complex gates
+ if ( LineType < 28 )
+ {
+ if ( !Io_ReadVerNetworkGateComplex( p, pNtk, vTokens, LineType ) )
+ return NULL;
+ continue;
+
+ }
+ // process the latches
+ if ( LineType < 33 )
+ {
+ if ( !Io_ReadVerNetworkLatch( p, pNtk, vTokens ) )
+ return NULL;
+ continue;
+ }
+ // add the tri-state element to the skipped ones
+ sprintf( Buffer, "%s %s", vTokens->pArray[0], vTokens->pArray[1] );
+ Vec_PtrPush( p->vSkipped, util_strsav(Buffer) );
+ }
+ Extra_ProgressBarStop( pProgress );
+
+ if ( p->vSkipped->nSize > 0 )
+ {
+ printf( "IoReadVerilog() skipped %d tri-state elements:\n", p->vSkipped->nSize );
+ for ( i = 0; i < p->vSkipped->nSize; i++ )
+ {
+ if ( i < 2 )
+ printf( "%s,\n", p->vSkipped->pArray[i] );
+ else
+ {
+ printf( "%s, etc.\n", p->vSkipped->pArray[i] );
+ break;
+ }
+ }
+ for ( i = 0; i < p->vSkipped->nSize; i++ )
+ free( p->vSkipped->pArray[i] );
+ }
+ Io_ReadSetNonDrivenNets( pNtk );
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads one assign directive in the verilog file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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 )
+ {
+ // 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." );
+ 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 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 1 );
+ sprintf( p->sError, "Cannot find net \"%s\".", vTokens->pArray[1] );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ Abc_ObjAddFanin( pNet, pNode );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads one signal the verilog file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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 * pToken;
+ int nSignals, k, Start, s;
+
+ nSignals = 0;
+ pToken = vTokens->pArray[1];
+ if ( pToken[0] == '[' )
+ {
+ nSignals = atoi(pToken + 1) + 1;
+ if ( nSignals < 1 || nSignals > 1024 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "Incorrect number of signals in the expression \"%s\".", pToken );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ if ( nSignals == 1 )
+ nSignals = 0;
+ Start = 2;
+ }
+ else
+ Start = 1;
+ for ( k = Start; k < vTokens->nSize; k++ )
+ {
+ pToken = vTokens->pArray[k];
+ // print the signal name
+ if ( nSignals )
+ {
+ 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 );
+ if ( LineType == VER_OUTPUT || LineType == VER_INOUT )
+ Abc_NtkMarkNetPo( pNet );
+ }
+ }
+ else
+ {
+ pNet = Abc_NtkFindOrCreateNet( pNtk, pToken );
+ if ( LineType == VER_INPUT || LineType == VER_INOUT )
+ Abc_NtkMarkNetPi( pNet );
+ if ( LineType == VER_OUTPUT || LineType == VER_INOUT )
+ Abc_NtkMarkNetPo( pNet );
+ }
+ }
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Reads a simple gate from the verilog file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Io_ReadVerNetworkGateSimple( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType )
+{
+ Abc_Obj_t * pNode, * pNet, * pNodeConst, * pNetConst;
+ 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';
+ for ( k = 2; k < vTokens->nSize - 1; k++ )
+ {
+ pToken = vTokens->pArray[k];
+ if ( pToken[0] == '.' )
+ continue;
+ pNet = Abc_NtkFindNet( pNtk, pToken );
+ if ( pNet )
+ {
+ 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 );
+ return 0;
+ }
+ if ( Abc_ObjFaninNum(pNode) != nFanins )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "Gate \"%s\" has a wrong number of inputs.", vTokens->pArray[1] );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+
+ // add the fanout net
+ pToken = vTokens->pArray[vTokens->nSize - 1];
+ if ( pToken[0] == '.' )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "Gate \"%s\" does not have a fanout.", vTokens->pArray[1] );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ pNet = Abc_NtkFindNet( pNtk, pToken );
+ if ( pNet == NULL )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "Cannot find net \"%s\".", pToken );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ Abc_ObjAddFanin( pNet, pNode );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads a complex gate from the verilog file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Io_ReadVerNetworkGateComplex( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType )
+{
+ Abc_Obj_t * pNode1, * pNode2, * pNet;
+ char * pToken, * pToken1, * pToken2;
+ int nFanins, k;
+
+ // 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';
+ for ( k = 2; k < vTokens->nSize; k++ )
+ {
+ pToken = vTokens->pArray[k];
+ if ( pToken[0] == '.' )
+ continue;
+ pNet = Abc_NtkFindNet( pNtk, pToken );
+ if ( pNet == NULL )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "Cannot find net \"%s\".", pToken );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ Abc_ObjAddFanin( pNode1, pNet );
+ Abc_ObjAddFanin( pNode2, pNet );
+ if ( Abc_ObjFaninNum(pNode1) == nFanins )
+ {
+ k++;
+ break;
+ }
+ }
+ // find the tokens corresponding to the output
+ pToken1 = pToken2 = NULL;
+ for ( ; k < vTokens->nSize; k++ )
+ {
+ pToken = vTokens->pArray[k];
+ if ( pToken[0] == '.' )
+ continue;
+ if ( pToken1 == NULL )
+ pToken1 = pToken;
+ else
+ pToken2 = pToken;
+ }
+ // quit if one of the tokens is not given
+ if ( pToken1 == NULL || pToken2 == NULL )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "An output of a two-output gate \"%s\" is not specified.", vTokens->pArray[1] );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+
+ // add the fanout net
+ pNet = Abc_NtkFindNet( pNtk, pToken1 );
+ if ( pNet == NULL )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "Cannot find net \"%s\".", pToken1 );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ Abc_ObjAddFanin( pNet, pNode1 );
+
+ // add the fanout net
+ pNet = Abc_NtkFindNet( pNtk, pToken2 );
+ if ( pNet == NULL )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "Cannot find net \"%s\".", pToken2 );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ Abc_ObjAddFanin( pNet, pNode2 );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads a latch from the verilog file.]
+
+ Description [This procedure treats T-latch as if it were D-latch.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Io_ReadVerNetworkLatch( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens )
+{
+ Abc_Obj_t * pLatch, * pNet, * pNode;
+ char * pToken, * pToken2, * pTokenRN, * pTokenSN, * pTokenSI, * pTokenSE, * pTokenD, * pTokenQ, * pTokenQN;
+ int k, fRN1, fSN1;
+
+ // collect the FF signals
+ pTokenRN = pTokenSN = pTokenSI = pTokenSE = pTokenD = pTokenQ = pTokenQN = NULL;
+ for ( k = 2; k < vTokens->nSize-1; k++ )
+ {
+ pToken = vTokens->pArray[k];
+ pToken2 = vTokens->pArray[k+1];
+ if ( pToken[1] == 'R' && pToken[2] == 'N' && pToken[3] == 0 )
+ pTokenRN = (pToken2[0] == '.')? NULL : pToken2;
+ else if ( pToken[1] == 'S' && pToken[2] == 'N' && pToken[3] == 0 )
+ pTokenSN = (pToken2[0] == '.')? NULL : pToken2;
+ else if ( pToken[1] == 'S' && pToken[2] == 'I' && pToken[3] == 0 )
+ pTokenSI = (pToken2[0] == '.')? NULL : pToken2;
+ else if ( pToken[1] == 'S' && pToken[2] == 'E' && pToken[3] == 0 )
+ pTokenSE = (pToken2[0] == '.')? NULL : pToken2;
+ else if ( pToken[1] == 'D' && pToken[2] == 0 )
+ pTokenD = (pToken2[0] == '.')? NULL : pToken2;
+ else if ( pToken[1] == 'Q' && pToken[2] == 0 )
+ pTokenQ = (pToken2[0] == '.')? NULL : pToken2;
+ else if ( pToken[1] == 'Q' && pToken[2] == 'N' && pToken[3] == 0 )
+ pTokenQN = (pToken2[0] == '.')? NULL : pToken2;
+ else if ( pToken[1] == 'C' && pToken[2] == 'K' && pToken[3] == 0 ) {}
+ else
+ assert( 0 );
+ if ( pToken2[0] != '.' )
+ k++;
+ }
+
+ if ( pTokenD == NULL )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 1 );
+ sprintf( p->sError, "Cannot read pin D of the latch \"%s\".", vTokens->pArray[1] );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ if ( pTokenQ == NULL && pTokenQN == NULL )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 1 );
+ sprintf( p->sError, "Cannot read pins Q/QN of the latch \"%s\".", vTokens->pArray[1] );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ if ( (pTokenRN == NULL) ^ (pTokenSN == NULL) )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 1 );
+ sprintf( p->sError, "Cannot read pins RN/SN of the latch \"%s\".", vTokens->pArray[1] );
+ 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 )
+ {
+ // 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 );
+ }
+ }
+ Abc_ObjAddFanin( pLatch, pNet );
+ Abc_ObjSetSubtype( pNet, ABC_OBJ_SUBTYPE_LI );
+
+ // 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 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "Cannot find latch output net \"%s\".", pTokenQ );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ Abc_ObjAddFanin( pNet, pNode );
+ }
+ 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 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "Cannot find latch output net \"%s\".", pTokenQN );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ Abc_ObjAddFanin( pNet, pNode );
+ }
+
+ // set the initial value
+ if ( pTokenRN == NULL && pTokenSN == NULL )
+ Abc_ObjSetData( pLatch, (char *)2 );
+ else
+ {
+ fRN1 = (strcmp( pTokenRN, "1'b1" ) == 0);
+ fSN1 = (strcmp( pTokenSN, "1'b1" ) == 0);
+ if ( fRN1 && fSN1 )
+ Abc_ObjSetData( pLatch, (char *)2 );
+ else if ( fRN1 )
+ Abc_ObjSetData( pLatch, (char *)1 );
+ else if ( fSN1 )
+ Abc_ObjSetData( pLatch, (char *)0 );
+ else
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
+ sprintf( p->sError, "Cannot read the initial value of latch \"%s\".", vTokens->pArray[1] );
+ Io_ReadVerPrintErrorMessage( p );
+ return 0;
+ }
+ }
+ 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/ioWriteBench.c b/src/base/io/ioWriteBench.c
new file mode 100644
index 00000000..954c2238
--- /dev/null
+++ b/src/base/io/ioWriteBench.c
@@ -0,0 +1,224 @@
+/**CFile****************************************************************
+
+ FileName [ioWriteBench.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: ioWriteBench.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+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 ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Writes the network in BENCH format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_WriteBench( Abc_Ntk_t * pNtk, char * pFileName )
+{
+ Abc_Ntk_t * pExdc;
+ FILE * pFile;
+ assert( Abc_NtkIsAig(pNtk) );
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Io_WriteBench(): Cannot open the output file.\n" );
+ return 0;
+ }
+ fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pSpec, Extra_TimeStamp() );
+ // write the network
+ Io_WriteBenchOne( pFile, pNtk );
+ // 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;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the network in BENCH format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_WriteBenchOne( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ 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) );
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ fprintf( pFile, "OUTPUT(%s)\n", Abc_NtkNamePo(pNtk,i) );
+ 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) );
+ }
+
+ // 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;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the network in BENCH format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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 []
+
+ 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(pObj) );
+ if ( Abc_NodeIsConst(pObj) ) // constant node
+ {
+ if ( fPhase )
+ sprintf( Buffer, "%s", "vdd" );
+ else
+ sprintf( Buffer, "%s", "gnd" );
+ return Buffer;
+ }
+ // 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;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c
new file mode 100644
index 00000000..d9c69273
--- /dev/null
+++ b/src/base/io/ioWriteBlif.c
@@ -0,0 +1,344 @@
+/**CFile****************************************************************
+
+ FileName [ioWriteBlif.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to write BLIF files.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioWriteBlif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.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_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 );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**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 )
+{
+ Abc_Ntk_t * pExdc;
+ FILE * pFile;
+ assert( Abc_NtkIsNetlist(pNtk) );
+ pFile = fopen( FileName, "w" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Io_WriteBlif(): Cannot open the output file.\n" );
+ return;
+ }
+ // write the model name
+ fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
+ // write the network
+ Io_NtkWriteOne( pFile, pNtk );
+ // write EXDC network if it exists
+ pExdc = Abc_NtkExdc( pNtk );
+ if ( pExdc )
+ {
+ fprintf( pFile, "\n" );
+ fprintf( pFile, ".exdc\n" );
+ Io_NtkWriteOne( pFile, pExdc );
+ }
+ // 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_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Obj_t * pNode, * pLatch;
+ int i;
+
+ // write the PIs
+ fprintf( pFile, ".inputs" );
+ Io_NtkWritePis( pFile, pNtk );
+ fprintf( pFile, "\n" );
+
+ // write the POs
+ fprintf( pFile, ".outputs" );
+ Io_NtkWritePos( pFile, pNtk );
+ fprintf( pFile, "\n" );
+
+ // write the timing info
+ Io_WriteTimingInfo( pFile, pNtk );
+
+ // write the latches
+ if ( !Abc_NtkIsComb(pNtk) )
+ {
+ fprintf( pFile, "\n" );
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ Io_NtkWriteLatch( pFile, pLatch );
+ fprintf( pFile, "\n" );
+ }
+
+ // write each internal node
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ Io_NtkWriteNode( pFile, pNode );
+ }
+ Extra_ProgressBarStop( pProgress );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the primary input list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i;
+
+ LineLength = 7;
+ NameCounter = 0;
+ Abc_NtkForEachPi( pNtk, pNet, i )
+ {
+ // 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++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the primary input list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i;
+
+ LineLength = 8;
+ NameCounter = 0;
+ Abc_NtkForEachPo( pNtk, pNet, i )
+ {
+ // 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++;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Write the latch into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch )
+{
+ Abc_Obj_t * pNetLi, * pNetLo;
+ int Reset;
+ pNetLi = Abc_ObjFanin0( pLatch );
+ pNetLo = Abc_ObjFanout0( 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, " %d\n", Reset );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Write the node into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+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) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the primary input list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ char * pName;
+ int i;
+
+ LineLength = 6;
+ NameCounter = 0;
+ Abc_ObjForEachFanin( pNode, pNet, i )
+ {
+ // get the fanin name
+ pName = Abc_ObjName(pNet);
+ // 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(Abc_ObjFanout0(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", pName );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the timing info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ Abc_Time_t * pTime, * pTimeDef;
+ int i;
+
+ if ( pNtk->pManTime == NULL )
+ return;
+
+ pTimeDef = Abc_NtkReadDefaultArrival( pNtk );
+ fprintf( pFile, ".default_input_arrival %g %g\n", pTimeDef->Rise, pTimeDef->Fall );
+ Abc_NtkForEachPi( pNtk, pNode, i )
+ {
+ 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 );
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioWriteBlifLogic.c b/src/base/io/ioWriteBlifLogic.c
new file mode 100644
index 00000000..aa1d65b9
--- /dev/null
+++ b/src/base/io/ioWriteBlifLogic.c
@@ -0,0 +1,402 @@
+/**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/ioWriteCnf.c b/src/base/io/ioWriteCnf.c
new file mode 100644
index 00000000..144ff167
--- /dev/null
+++ b/src/base/io/ioWriteCnf.c
@@ -0,0 +1,76 @@
+/**CFile****************************************************************
+
+ FileName [ioWriteCnf.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to CNF of the miter cone.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioWriteCnf.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Io_WriteCnfInt( FILE * pFile, Abc_Ntk_t * pNtk );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Write the miter cone into a CNF file for the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_WriteCnf( Abc_Ntk_t * pNtk, char * pFileName )
+{
+ solver * pSat;
+ if ( !Abc_NtkIsLogicBdd(pNtk) )
+ {
+ fprintf( stdout, "Io_WriteCnf(): Currently can process logic networks with BDDs.\n" );
+ return 0;
+ }
+ if ( Abc_NtkPoNum(pNtk) != 1 )
+ {
+ fprintf( stdout, "Io_WriteCnf(): Currently can only solve the miter (the network with one PO).\n" );
+ return 0;
+ }
+ if ( Abc_NtkLatchNum(pNtk) != 0 )
+ {
+ fprintf( stdout, "Io_WriteCnf(): Currently can only solve the miter for combinational circuits.\n" );
+ return 0;
+ }
+ // create solver with clauses
+ pSat = Abc_NtkMiterSatCreate( pNtk );
+ // write the clauses
+ Asat_SolverWriteDimacs( pSat, pFileName );
+ // free the solver
+ solver_delete( pSat );
+ return 1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioWriteGate.c b/src/base/io/ioWriteGate.c
new file mode 100644
index 00000000..3a3c45eb
--- /dev/null
+++ b/src/base/io/ioWriteGate.c
@@ -0,0 +1,263 @@
+/**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/module.make b/src/base/io/module.make
new file mode 100644
index 00000000..d9f46c2c
--- /dev/null
+++ b/src/base/io/module.make
@@ -0,0 +1,10 @@
+SRC += src/base/io/io.c \
+ src/base/io/ioRead.c \
+ src/base/io/ioReadBench.c \
+ src/base/io/ioReadBlif.c \
+ src/base/io/ioReadVerilog.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
diff --git a/src/base/main/main.c b/src/base/main/main.c
new file mode 100644
index 00000000..ed1e929d
--- /dev/null
+++ b/src/base/main/main.c
@@ -0,0 +1,267 @@
+/**CFile****************************************************************
+
+ FileName [main.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [The main package.]
+
+ Synopsis [Here everything starts.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: main.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int TypeCheck( Abc_Frame_t * pAbc, char * s);
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [The main() procedure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int main( int argc, char * argv[] )
+{
+ Abc_Frame_t * pAbc;
+ char sCommandUsr[500], sCommandTmp[100], sReadCmd[20], sWriteCmd[20], c;
+ char * sCommand, * sOutFile, * sInFile;
+ int fStatus = 0;
+ bool fBatch, fInitSource, fInitRead, fFinalWrite;
+
+ // added to detect memory leaks:
+#ifdef _DEBUG
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+#endif
+
+ // get global frame (singleton pattern)
+ // will be initialized on first call
+ pAbc = Abc_FrameGetGlobalFrame();
+
+ // default options
+ fBatch = 0;
+ fInitSource = 1;
+ fInitRead = 0;
+ fFinalWrite = 0;
+ sInFile = sOutFile = NULL;
+ sprintf( sReadCmd, "read_blif_mv" );
+ sprintf( sWriteCmd, "write_blif_mv" );
+
+ util_getopt_reset();
+ while ((c = util_getopt(argc, argv, "c:hf:F:o:st:T:x")) != EOF) {
+ switch(c) {
+ case 'c':
+ strcpy( sCommandUsr, util_optarg );
+ fBatch = 1;
+ break;
+
+ case 'f':
+ sprintf(sCommandUsr, "source %s", util_optarg);
+ fBatch = 1;
+ break;
+
+ case 'F':
+ sprintf(sCommandUsr, "source -x %s", util_optarg);
+ fBatch = 1;
+ break;
+
+ case 'h':
+ goto usage;
+ break;
+
+ case 'o':
+ sOutFile = util_optarg;
+ fFinalWrite = 1;
+ break;
+
+ case 's':
+ fInitSource = 0;
+ break;
+
+ case 't':
+ if ( TypeCheck( pAbc, util_optarg ) )
+ {
+ if ( !strcmp(util_optarg, "none") == 0 )
+ {
+ fInitRead = 1;
+ sprintf( sReadCmd, "read_%s", util_optarg );
+ }
+ }
+ else {
+ goto usage;
+ }
+ fBatch = 1;
+ break;
+
+ case 'T':
+ if ( TypeCheck( pAbc, util_optarg ) )
+ {
+ if (!strcmp(util_optarg, "none") == 0)
+ {
+ fFinalWrite = 1;
+ sprintf( sWriteCmd, "write_%s", util_optarg);
+ }
+ }
+ else {
+ goto usage;
+ }
+ fBatch = 1;
+ break;
+
+ case 'x':
+ fFinalWrite = 0;
+ fInitRead = 0;
+ fBatch = 1;
+ break;
+
+ default:
+ goto usage;
+ }
+ }
+
+ if ( fBatch )
+ {
+ pAbc->fBatchMode = 1;
+
+ if (argc - util_optind == 0)
+ {
+ sInFile = NULL;
+ }
+ else if (argc - util_optind == 1)
+ {
+ fInitRead = 1;
+ sInFile = argv[util_optind];
+ }
+ else
+ {
+ Abc_UtilsPrintUsage( pAbc, argv[0] );
+ }
+
+ // source the resource file
+ if ( fInitSource )
+ {
+ Abc_UtilsSource( pAbc );
+ }
+
+ fStatus = 0;
+ if ( fInitRead && sInFile )
+ {
+ sprintf( sCommandTmp, "%s %s", sReadCmd, sInFile );
+ fStatus = Cmd_CommandExecute( pAbc, sCommandTmp );
+ }
+
+ if ( fStatus == 0 )
+ {
+ /* cmd line contains `source <file>' */
+ fStatus = Cmd_CommandExecute( pAbc, sCommandUsr );
+ if ( (fStatus == 0 || fStatus == -1) && fFinalWrite && sOutFile )
+ {
+ sprintf( sCommandTmp, "%s %s", sWriteCmd, sOutFile );
+ fStatus = Cmd_CommandExecute( pAbc, sCommandTmp );
+ }
+ }
+
+ }
+ else
+ {
+ // start interactive mode
+ // print the hello line
+ Abc_UtilsPrintHello( pAbc );
+
+ // source the resource file
+ if ( fInitSource )
+ {
+ Abc_UtilsSource( pAbc );
+ }
+
+ // execute commands given by the user
+ while ( !feof(stdin) )
+ {
+ // print command line prompt and
+ // get the command from the user
+ sCommand = Abc_UtilsGetUsersInput( pAbc );
+
+ // execute the user's command
+ fStatus = Cmd_CommandExecute( pAbc, sCommand );
+
+ // stop if the user quitted or an error occurred
+ if ( fStatus == -1 || fStatus == -2 )
+ break;
+ }
+ }
+
+ // if the memory should be freed, quit packages
+ if ( fStatus == -2 )
+ {
+ // perform uninitializations
+ Abc_FrameEnd( pAbc );
+ // stop the framework
+ Abc_FrameDeallocate( pAbc );
+ }
+ return 0;
+
+usage:
+ Abc_UtilsPrintHello( pAbc );
+ Abc_UtilsPrintUsage( pAbc, argv[0] );
+ return 1;
+}
+
+
+/**Function********************************************************************
+
+ Synopsis [Returns 1 if s is a file type recognized, else returns 0.]
+
+ Description [Returns 1 if s is a file type recognized by VIS, else returns
+ 0. Recognized types are "blif", "blif_mv", "blif_mvs", and "none".]
+
+ SideEffects []
+
+******************************************************************************/
+static int
+TypeCheck(
+ Abc_Frame_t * pAbc,
+ char * s)
+{
+ if (strcmp(s, "blif") == 0) {
+ return 1;
+ }
+ else if (strcmp(s, "blif_mv") == 0) {
+ return 1;
+ }
+ else if (strcmp(s, "blif_mvs") == 0) {
+ return 1;
+ }
+ else if (strcmp(s, "none") == 0) {
+ return 1;
+ }
+ else {
+ fprintf( pAbc->Err, "unknown type %s\n", s );
+ return 0;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/main/main.h b/src/base/main/main.h
new file mode 100644
index 00000000..c5d6a0c8
--- /dev/null
+++ b/src/base/main/main.h
@@ -0,0 +1,109 @@
+/**CFile****************************************************************
+
+ FileName [main.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [The main package.]
+
+ Synopsis [External declarations of the main package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: main.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __MAIN_H__
+#define __MAIN_H__
+
+////////////////////////////////////////////////////////////////////////
+/// TYPEDEFS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// the framework containing all data
+typedef struct Abc_Frame_t_ Abc_Frame_t;
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+// this include should be the first one in the list
+// it is used to catch memory leaks on Windows
+#include "leaks.h"
+
+// standard includes
+#include <stdio.h>
+#include <string.h>
+
+// includes from GLU
+#include "util.h"
+#include "st.h"
+
+// data structure packages
+#include "extra.h"
+#include "vec.h"
+
+// core packages
+#include "abc.h"
+#include "cmd.h"
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// GLOBAL VARIABLES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== mvFrame.c ===========================================================*/
+extern Abc_Ntk_t * Abc_FrameReadNet( Abc_Frame_t * p );
+extern FILE * Abc_FrameReadOut( Abc_Frame_t * p );
+extern FILE * Abc_FrameReadErr( Abc_Frame_t * p );
+extern bool Abc_FrameReadMode( Abc_Frame_t * p );
+extern bool Abc_FrameSetMode( Abc_Frame_t * p, bool fNameMode );
+extern void Abc_FrameRestart( Abc_Frame_t * p );
+
+extern void Abc_FrameSetCurrentNetwork( Abc_Frame_t * p, Abc_Ntk_t * pNet );
+extern void Abc_FrameSwapCurrentAndBackup( Abc_Frame_t * p );
+extern void Abc_FrameReplaceCurrentNetwork( Abc_Frame_t * p, Abc_Ntk_t * pNet );
+extern void Abc_FrameDeleteAllNetworks( Abc_Frame_t * p );
+
+extern void Abc_FrameSetGlobalFrame( Abc_Frame_t * p );
+extern Abc_Frame_t * Abc_FrameGetGlobalFrame();
+
+extern Abc_Ntk_t * Abc_FrameReadNtkStore ( Abc_Frame_t * pFrame );
+extern int Abc_FrameReadNtkStoreSize ( Abc_Frame_t * pFrame );
+extern void Abc_FrameSetNtkStore ( Abc_Frame_t * pFrame, Abc_Ntk_t * pNtk );
+extern void Abc_FrameSetNtkStoreSize ( Abc_Frame_t * pFrame, int nStored );
+
+extern void * Abc_FrameReadLibLut ( Abc_Frame_t * pFrame );
+extern void * Abc_FrameReadLibGen ( Abc_Frame_t * pFrame );
+extern void * Abc_FrameReadLibSuper ( Abc_Frame_t * pFrame );
+extern void Abc_FrameSetLibLut ( Abc_Frame_t * pFrame, void * pLib );
+extern void Abc_FrameSetLibGen ( Abc_Frame_t * pFrame, void * pLib );
+extern void Abc_FrameSetLibSuper ( Abc_Frame_t * pFrame, void * pLib );
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c
new file mode 100644
index 00000000..0b0cbbbd
--- /dev/null
+++ b/src/base/main/mainFrame.c
@@ -0,0 +1,417 @@
+/**CFile****************************************************************
+
+ FileName [mainFrame.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [The main package.]
+
+ Synopsis [The global framework resides in this file.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: mainFrame.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Abc_Frame_t * Abc_FrameGlobalFrame = 0;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Frame_t * Abc_FrameAllocate()
+{
+ Abc_Frame_t * p;
+
+ // allocate and clean
+ p = ALLOC( Abc_Frame_t, 1 );
+ memset( p, 0, sizeof(Abc_Frame_t) );
+ // get version
+ p->sVersion = Abc_UtilsGetVersion( p );
+ // set streams
+ p->Err = stderr;
+ p->Out = stdout;
+ p->Hst = NULL;
+ // set the starting step
+ p->nSteps = 1;
+ p->fBatchMode = 0;
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_FrameDeallocate( Abc_Frame_t * p )
+{
+ Abc_FrameDeleteAllNetworks( p );
+ free( p );
+ p = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_FrameRestart( Abc_Frame_t * p )
+{
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_FrameReadNet( Abc_Frame_t * p )
+{
+ return p->pNtkCur;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+FILE * Abc_FrameReadOut( Abc_Frame_t * p )
+{
+ return p->Out;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+FILE * Abc_FrameReadErr( Abc_Frame_t * p )
+{
+ return p->Err;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_FrameReadMode( Abc_Frame_t * p )
+{
+ int fShortNames;
+ char * pValue;
+ pValue = Cmd_FlagReadByName( p, "namemode" );
+ if ( pValue == NULL )
+ fShortNames = 0;
+ else
+ fShortNames = atoi(pValue);
+ return fShortNames;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_FrameSetMode( Abc_Frame_t * p, bool fNameMode )
+{
+ char Buffer[2];
+ bool fNameModeOld;
+ fNameModeOld = Abc_FrameReadMode( p );
+ Buffer[0] = '0' + fNameMode;
+ Buffer[1] = 0;
+ Cmd_FlagUpdateValue( p, "namemode", (char *)Buffer );
+ return fNameModeOld;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Sets the given network to be the current one.]
+
+ Description [Takes the network and makes it the current network.
+ The previous current network is attached to the given network as
+ a backup copy. In the stack of backup networks contains too many
+ networks (defined by the paramater "savesteps"), the bottom
+ most network is deleted.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_FrameSetCurrentNetwork( Abc_Frame_t * p, Abc_Ntk_t * pNetNew )
+{
+ Abc_Ntk_t * pNet, * pNet2, * pNet3;
+ int nNetsPresent;
+ int nNetsToSave;
+ char * pValue;
+
+ // link it to the previous network
+ Abc_NtkSetBackup( pNetNew, p->pNtkCur );
+ // set the step of this network
+ Abc_NtkSetStep( pNetNew, ++p->nSteps );
+ // set this network to be the current network
+ p->pNtkCur = pNetNew;
+
+ // remove any extra network that may happen to be in the stack
+ pValue = Cmd_FlagReadByName( p, "savesteps" );
+ // if the value of steps to save is not set, assume 1-level undo
+ if ( pValue == NULL )
+ nNetsToSave = 1;
+ else
+ nNetsToSave = atoi(pValue);
+
+ // count the network, remember the last one, and the one before the last one
+ nNetsPresent = 0;
+ pNet2 = pNet3 = NULL;
+ for ( pNet = p->pNtkCur; pNet; pNet = Abc_NtkBackup(pNet2) )
+ {
+ nNetsPresent++;
+ pNet3 = pNet2;
+ pNet2 = pNet;
+ }
+
+ // remove the earliest backup network if it is more steps away than we store
+ if ( nNetsPresent - 1 > nNetsToSave )
+ { // delete the last network
+ Abc_NtkDelete( pNet2 );
+ // clean the pointer of the network before the last one
+ Abc_NtkSetBackup( pNet3, NULL );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [This procedure swaps the current and the backup network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_FrameSwapCurrentAndBackup( Abc_Frame_t * p )
+{
+ Abc_Ntk_t * pNtkCur, * pNetBack, * pNetBack2;
+ int iStepCur, iStepBack;
+
+ pNtkCur = p->pNtkCur;
+ pNetBack = Abc_NtkBackup( pNtkCur );
+ iStepCur = Abc_NtkStep ( pNtkCur );
+
+ // if there is no backup nothing to reset
+ if ( pNetBack == NULL )
+ return;
+
+ // remember the backup of the backup
+ pNetBack2 = Abc_NtkBackup( pNetBack );
+ iStepBack = Abc_NtkStep ( pNetBack );
+
+ // set pNtkCur to be the next after the backup's backup
+ Abc_NtkSetBackup( pNtkCur, pNetBack2 );
+ Abc_NtkSetStep ( pNtkCur, iStepBack );
+
+ // set pNtkCur to be the next after the backup
+ Abc_NtkSetBackup( pNetBack, pNtkCur );
+ Abc_NtkSetStep ( pNetBack, iStepCur );
+
+ // set the current network
+ p->pNtkCur = pNetBack;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Replaces the current network by the given one.]
+
+ Description [This procedure does not modify the stack of saved
+ networks.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_FrameReplaceCurrentNetwork( Abc_Frame_t * p, Abc_Ntk_t * pNet )
+{
+ if ( pNet == NULL )
+ return;
+
+ // transfer the parameters to the new network
+ if ( p->pNtkCur )
+ {
+ Abc_NtkSetBackup( pNet, Abc_NtkBackup(p->pNtkCur) );
+ Abc_NtkSetStep( pNet, Abc_NtkStep(p->pNtkCur) );
+ // delete the current network
+ Abc_NtkDelete( p->pNtkCur );
+ }
+ else
+ {
+ Abc_NtkSetBackup( pNet, NULL );
+ Abc_NtkSetStep( pNet, ++p->nSteps );
+ }
+ // set the new current network
+ p->pNtkCur = pNet;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_FrameDeleteAllNetworks( Abc_Frame_t * p )
+{
+ Abc_Ntk_t * pNet, * pNet2;
+ // delete all the currently saved networks
+ for ( pNet = p->pNtkCur,
+ pNet2 = pNet? Abc_NtkBackup(pNet): NULL;
+ pNet;
+ pNet = pNet2,
+ pNet2 = pNet? Abc_NtkBackup(pNet): NULL )
+ Abc_NtkDelete( pNet );
+ // set the current network empty
+ p->pNtkCur = NULL;
+ fprintf( p->Out, "All networks have been deleted.\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_FrameSetGlobalFrame( Abc_Frame_t * p )
+{
+ Abc_FrameGlobalFrame = p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Frame_t * Abc_FrameGetGlobalFrame()
+{
+ if ( Abc_FrameGlobalFrame == 0 )
+ {
+ // start the framework
+ Abc_FrameGlobalFrame = Abc_FrameAllocate();
+ // perform initializations
+ Abc_FrameInit( Abc_FrameGlobalFrame );
+ }
+ return Abc_FrameGlobalFrame;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_FrameReadNtkStore ( Abc_Frame_t * pFrame ) { return pFrame->pStored; }
+int Abc_FrameReadNtkStoreSize ( Abc_Frame_t * pFrame ) { return pFrame->nStored; }
+void Abc_FrameSetNtkStore ( Abc_Frame_t * pFrame, Abc_Ntk_t * pNtk ) { pFrame->pStored = pNtk; }
+void Abc_FrameSetNtkStoreSize ( Abc_Frame_t * pFrame, int nStored ) { pFrame->nStored = nStored; }
+
+void * Abc_FrameReadLibLut ( Abc_Frame_t * pFrame ) { return pFrame->pLibLut; }
+void * Abc_FrameReadLibGen ( Abc_Frame_t * pFrame ) { return pFrame->pLibGen; }
+void * Abc_FrameReadLibSuper ( Abc_Frame_t * pFrame ) { return pFrame->pLibSuper; }
+void Abc_FrameSetLibLut ( Abc_Frame_t * pFrame, void * pLib ) { pFrame->pLibLut = pLib; }
+void Abc_FrameSetLibGen ( Abc_Frame_t * pFrame, void * pLib ) { pFrame->pLibGen = pLib; }
+void Abc_FrameSetLibSuper ( Abc_Frame_t * pFrame, void * pLib ) { pFrame->pLibSuper = pLib; }
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/main/mainInit.c b/src/base/main/mainInit.c
new file mode 100644
index 00000000..13710dcb
--- /dev/null
+++ b/src/base/main/mainInit.c
@@ -0,0 +1,96 @@
+/**CFile****************************************************************
+
+ FileName [mainInit.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [The main package.]
+
+ Synopsis [Initialization procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: mainInit.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern void Abc_Init( Abc_Frame_t * pAbc );
+extern void Abc_End ( Abc_Frame_t * pAbc );
+extern void Io_Init( Abc_Frame_t * pAbc );
+extern void Io_End ( Abc_Frame_t * pAbc );
+extern void Cmd_Init( Abc_Frame_t * pAbc );
+extern void Cmd_End ( Abc_Frame_t * pAbc );
+extern void Fpga_Init( Abc_Frame_t * pAbc );
+extern void Fpga_End ( Abc_Frame_t * pAbc );
+extern void Map_Init( Abc_Frame_t * pAbc );
+extern void Map_End ( Abc_Frame_t * pAbc );
+extern void Mio_Init( Abc_Frame_t * pAbc );
+extern void Mio_End ( Abc_Frame_t * pAbc );
+extern void Super_Init( Abc_Frame_t * pAbc );
+extern void Super_End ( Abc_Frame_t * pAbc );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Starts all the packages.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_FrameInit( Abc_Frame_t * pAbc )
+{
+ Cmd_Init( pAbc );
+ Io_Init( pAbc );
+ Abc_Init( pAbc );
+ Fpga_Init( pAbc );
+ Map_Init( pAbc );
+ Mio_Init( pAbc );
+ Super_Init( pAbc );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Stops all the packages.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_FrameEnd( Abc_Frame_t * pAbc )
+{
+ Abc_End( pAbc );
+ Io_End( pAbc );
+ Cmd_End( pAbc );
+ Fpga_End( pAbc );
+ Map_End( pAbc );
+ Mio_End( pAbc );
+ Super_End( pAbc );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h
new file mode 100644
index 00000000..557c4e2f
--- /dev/null
+++ b/src/base/main/mainInt.h
@@ -0,0 +1,107 @@
+/**CFile****************************************************************
+
+ FileName [mainInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [The main package.]
+
+ Synopsis [Internal declarations of the main package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: mainInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __Abc_INT_H__
+#define __Abc_INT_H__
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "main.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+// the current version
+#define ABC_VERSION "UC Berkeley, ABC 1.0"
+
+// the maximum length of an input line
+#define MAX_STR 32768
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct Abc_Frame_t_
+{
+ // general info
+ char * sVersion; // the name of the current version
+ // commands, aliases, etc
+ st_table * tCommands; // the command table
+ st_table * tAliases; // the alias table
+ st_table * tFlags; // the flag table
+ Vec_Ptr_t * aHistory; // the command history
+ // the functionality
+ Abc_Ntk_t * pNtkCur; // the current network
+ int nSteps; // the counter of different network processed
+ // when this flag is 1, the current command is executed in autoexec mode
+ int fAutoexac;
+ // output streams
+ FILE * Out;
+ FILE * Err;
+ FILE * Hst;
+ // used for runtime measurement
+ int TimeCommand; // the runtime of the last command
+ int TimeTotal; // the total runtime of all commands
+ int fBatchMode; // are we invoked in batch mode?
+ // temporary storage for structural choices
+ Abc_Ntk_t * pStored; // the stored networks
+ int nStored; // the number of stored networks
+
+ void * pLibLut; // the current LUT library
+ void * pLibGen; // the current genlib
+ void * pLibSuper; // the current supergate library
+};
+
+////////////////////////////////////////////////////////////////////////
+/// GLOBAL VARIABLES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== mvMain.c ===========================================================*/
+extern int main( int argc, char * argv[] );
+/*=== mvInit.c ===================================================*/
+extern void Abc_FrameInit( Abc_Frame_t * pAbc );
+extern void Abc_FrameEnd( Abc_Frame_t * pAbc );
+/*=== mvFrame.c =====================================================*/
+extern Abc_Frame_t * Abc_FrameAllocate();
+extern void Abc_FrameDeallocate( Abc_Frame_t * p );
+/*=== mvUtils.c =====================================================*/
+extern char * Abc_UtilsGetVersion( Abc_Frame_t * pAbc );
+extern char * Abc_UtilsGetUsersInput( Abc_Frame_t * pAbc );
+extern void Abc_UtilsPrintHello( Abc_Frame_t * pAbc );
+extern void Abc_UtilsPrintUsage( Abc_Frame_t * pAbc, char * ProgName );
+extern void Abc_UtilsSource( Abc_Frame_t * pAbc );
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/src/base/main/mainUtils.c b/src/base/main/mainUtils.c
new file mode 100644
index 00000000..35d3c364
--- /dev/null
+++ b/src/base/main/mainUtils.c
@@ -0,0 +1,218 @@
+/**CFile****************************************************************
+
+ FileName [mainUtils.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [The main package.]
+
+ Synopsis [Miscellaneous utilities.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: mainUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "mainInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+static char * DateReadFromDateString(char * datestr);
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_UtilsGetVersion( Abc_Frame_t * pAbc )
+{
+ static char Version[1000];
+ sprintf(Version, "%s (compiled %s %s)", ABC_VERSION, __DATE__, __TIME__);
+ return Version;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_UtilsGetUsersInput( Abc_Frame_t * pAbc )
+{
+ static char Buffer[1000], Prompt[1000];
+ sprintf( Prompt, "abc %02d> ", pAbc->nSteps );
+ fprintf( pAbc->Out, "%s", Prompt );
+ fgets( Buffer, 999, stdin );
+ return Buffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_UtilsPrintHello( Abc_Frame_t * pAbc )
+{
+ fprintf( pAbc->Out, "%s\n", pAbc->sVersion );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_UtilsPrintUsage( Abc_Frame_t * pAbc, char * ProgName )
+{
+ fprintf( pAbc->Err, "\n" );
+ fprintf( pAbc->Err,
+ "usage: %s [-c cmd] [-f script] [-h] [-o file] [-s] [-t type] [-T type] [-x] [file]\n",
+ ProgName);
+ fprintf( pAbc->Err, " -c cmd\texecute commands `cmd'\n");
+ fprintf( pAbc->Err, " -F script\texecute commands from a script file and echo commands\n");
+ fprintf( pAbc->Err, " -f script\texecute commands from a script file\n");
+ fprintf( pAbc->Err, " -h\t\tprint the command usage\n");
+ fprintf( pAbc->Err, " -o file\tspecify output filename to store the result\n");
+ fprintf( pAbc->Err, " -s\t\tdo not read any initialization file\n");
+ fprintf( pAbc->Err, " -t type\tspecify input type (blif_mv (default), blif_mvs, blif, or none)\n");
+ fprintf( pAbc->Err, " -T type\tspecify output type (blif_mv (default), blif_mvs, blif, or none)\n");
+ fprintf( pAbc->Err, " -x\t\tequivalent to '-t none -T none'\n");
+ fprintf( pAbc->Err, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_UtilsSource( Abc_Frame_t * pAbc )
+{
+#ifdef WIN32
+ if ( Cmd_CommandExecute(pAbc, "source abc.rc") )
+ {
+ if ( Cmd_CommandExecute(pAbc, "source ..\\abc.rc") == 0 )
+ printf( "Loaded \"abc.rc\" from the parent directory.\n" );
+ else if ( Cmd_CommandExecute(pAbc, "source ..\\..\\abc.rc") == 0 )
+ printf( "Loaded \"abc.rc\" from the grandparent directory.\n" );
+ }
+#else
+ {
+ char * sPath1, * sPath2;
+
+ // If .rc is present in both the home and current directories, then read
+ // it from the home directory. Otherwise, read it from wherever it's located.
+ sPath1 = util_file_search(".rc", "~/", "r");
+ sPath2 = util_file_search(".rc", ".", "r");
+
+ if ( sPath1 && sPath2 ) {
+ /* ~/.rc == .rc : Source the file only once */
+ (void) Cmd_CommandExecute(pAbc, "source -s ~/.rc");
+ }
+ else {
+ if (sPath1) {
+ (void) Cmd_CommandExecute(pAbc, "source -s ~/.rc");
+ }
+ if (sPath2) {
+ (void) Cmd_CommandExecute(pAbc, "source -s .rc");
+ }
+ }
+ if ( sPath1 ) FREE(sPath1);
+ if ( sPath2 ) FREE(sPath2);
+
+ /* execute the abc script which can be open with the "open_path" */
+ Cmd_CommandExecute( pAbc, "source -s abc.rc" );
+ }
+#endif //WIN32
+
+ return;
+}
+
+/**Function********************************************************************
+
+ Synopsis [Returns the date in a brief format assuming its coming from
+ the program `date'.]
+
+ Description [optional]
+
+ SideEffects []
+
+******************************************************************************/
+char *
+DateReadFromDateString(
+ char * datestr)
+{
+ static char result[25];
+ char day[10];
+ char month[10];
+ char zone[10];
+ char *at;
+ int date;
+ int hour;
+ int minute;
+ int second;
+ int year;
+
+ if (sscanf(datestr, "%s %s %2d %2d:%2d:%2d %s %4d",
+ day, month, &date, &hour, &minute, &second, zone, &year) == 8) {
+ if (hour >= 12) {
+ if (hour >= 13) hour -= 12;
+ at = "PM";
+ }
+ else {
+ if (hour == 0) hour = 12;
+ at = "AM";
+ }
+ (void) sprintf(result, "%d-%3s-%02d at %d:%02d %s",
+ date, month, year % 100, hour, minute, at);
+ return result;
+ }
+ else {
+ return datestr;
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/main/module.make b/src/base/main/module.make
new file mode 100644
index 00000000..59e1315e
--- /dev/null
+++ b/src/base/main/module.make
@@ -0,0 +1,4 @@
+SRC += src/base/main/main.c \
+ src/base/main/mainFrame.c \
+ src/base/main/mainInit.c \
+ src/base/main/mainUtils.c