summaryrefslogtreecommitdiffstats
path: root/src/base/io
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2008-01-30 20:01:00 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2008-01-30 20:01:00 -0800
commit0c6505a26a537dc911b6566f82d759521e527c08 (patch)
treef2687995efd4943fe3b1307fce7ef5942d0a57b3 /src/base/io
parent4d30a1e4f1edecff86d5066ce4653a370e59e5e1 (diff)
downloadabc-0c6505a26a537dc911b6566f82d759521e527c08.tar.gz
abc-0c6505a26a537dc911b6566f82d759521e527c08.tar.bz2
abc-0c6505a26a537dc911b6566f82d759521e527c08.zip
Version abc80130_2
Diffstat (limited to 'src/base/io')
-rw-r--r--src/base/io/io.c1599
-rw-r--r--src/base/io/io.h110
-rw-r--r--src/base/io/ioInt.h6
-rw-r--r--src/base/io/ioRead.c81
-rw-r--r--src/base/io/ioReadAiger.c366
-rw-r--r--src/base/io/ioReadBaf.c171
-rw-r--r--src/base/io/ioReadBench.c223
-rw-r--r--src/base/io/ioReadBlif.c772
-rw-r--r--src/base/io/ioReadBlifAig.c1013
-rw-r--r--src/base/io/ioReadBlifMv.c1702
-rw-r--r--src/base/io/ioReadDsd.c308
-rw-r--r--src/base/io/ioReadEdif.c17
-rw-r--r--src/base/io/ioReadEqn.c73
-rw-r--r--src/base/io/ioReadPla.c7
-rw-r--r--src/base/io/ioReadVerilog.c727
-rw-r--r--src/base/io/ioUtil.c571
-rw-r--r--src/base/io/ioWriteAiger.c375
-rw-r--r--src/base/io/ioWriteBaf.c168
-rw-r--r--src/base/io/ioWriteBench.c188
-rw-r--r--src/base/io/ioWriteBlif.c173
-rw-r--r--src/base/io/ioWriteBlifMv.c519
-rw-r--r--src/base/io/ioWriteCnf.c65
-rw-r--r--src/base/io/ioWriteDot.c572
-rw-r--r--src/base/io/ioWriteEqn.c117
-rw-r--r--src/base/io/ioWriteGml.c2
-rw-r--r--src/base/io/ioWriteList.c288
-rw-r--r--src/base/io/ioWritePla.c23
-rw-r--r--src/base/io/ioWriteVerilog.c639
-rw-r--r--src/base/io/io_.c48
-rw-r--r--src/base/io/module.make13
30 files changed, 9346 insertions, 1590 deletions
diff --git a/src/base/io/io.c b/src/base/io/io.c
index 89703214..fe88a285 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -26,23 +26,43 @@
////////////////////////////////////////////////////////////////////////
static int IoCommandRead ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadAiger ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadBaf ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadBlif ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadBlifMv ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadBench ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadDsd ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadEdif ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadEqn ( Abc_Frame_t * pAbc, int argc, char **argv );
-static int IoCommandReadVerilog ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadInit ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandReadPla ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadTruth ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadVerilog ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadVer ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandReadVerLib ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWrite ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteHie ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteAiger ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteBaf ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBlif ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteBlifMv ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteBench ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteCellNet( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteCnf ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteCounter( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteDot ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteEqn ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWriteGml ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteList ( Abc_Frame_t * pAbc, int argc, char **argv );
static int IoCommandWritePla ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv );
+static int IoCommandWriteVerLib ( Abc_Frame_t * pAbc, int argc, char **argv );
+
+extern int glo_fMapped;
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
@@ -59,20 +79,38 @@ static int IoCommandWritePla ( Abc_Frame_t * pAbc, int argc, char **argv );
void Io_Init( Abc_Frame_t * pAbc )
{
Cmd_CommandAdd( pAbc, "I/O", "read", IoCommandRead, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_aiger", IoCommandReadAiger, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_baf", IoCommandReadBaf, 1 );
Cmd_CommandAdd( pAbc, "I/O", "read_blif", IoCommandReadBlif, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_blif_mv", IoCommandReadBlifMv, 1 );
Cmd_CommandAdd( pAbc, "I/O", "read_bench", IoCommandReadBench, 1 );
- Cmd_CommandAdd( pAbc, "I/O", "read_edif", IoCommandReadEdif, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_dsd", IoCommandReadDsd, 1 );
+// Cmd_CommandAdd( pAbc, "I/O", "read_edif", IoCommandReadEdif, 1 );
Cmd_CommandAdd( pAbc, "I/O", "read_eqn", IoCommandReadEqn, 1 );
- Cmd_CommandAdd( pAbc, "I/O", "read_verilog", IoCommandReadVerilog, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_init", IoCommandReadInit, 1 );
Cmd_CommandAdd( pAbc, "I/O", "read_pla", IoCommandReadPla, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_truth", IoCommandReadTruth, 1 );
+ Cmd_CommandAdd( pAbc, "I/O", "read_verilog", IoCommandReadVerilog, 1 );
+// Cmd_CommandAdd( pAbc, "I/O", "read_ver", IoCommandReadVer, 1 );
+// Cmd_CommandAdd( pAbc, "I/O", "read_verlib", IoCommandReadVerLib, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "write", IoCommandWrite, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "write_hie", IoCommandWriteHie, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "write_aiger", IoCommandWriteAiger, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "write_baf", IoCommandWriteBaf, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_blif", IoCommandWriteBlif, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "write_blif_mv", IoCommandWriteBlifMv, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_bench", IoCommandWriteBench, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "write_cellnet", IoCommandWriteCellNet, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "write_counter", IoCommandWriteCounter, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_cnf", IoCommandWriteCnf, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_dot", IoCommandWriteDot, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_eqn", IoCommandWriteEqn, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_gml", IoCommandWriteGml, 0 );
+// Cmd_CommandAdd( pAbc, "I/O", "write_list", IoCommandWriteList, 0 );
Cmd_CommandAdd( pAbc, "I/O", "write_pla", IoCommandWritePla, 0 );
+ Cmd_CommandAdd( pAbc, "I/O", "write_verilog", IoCommandWriteVerilog, 0 );
+// Cmd_CommandAdd( pAbc, "I/O", "write_verlib", IoCommandWriteVerLib, 0 );
}
/**Function*************************************************************
@@ -104,17 +142,20 @@ void Io_End()
int IoCommandRead( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk;
- char * FileName;
- FILE * pFile;
+ char * pFileName;
int fCheck;
int c;
fCheck = 1;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ glo_fMapped = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "mch" ) ) != EOF )
{
switch ( c )
{
+ case 'm':
+ glo_fMapped ^= 1;
+ break;
case 'c':
fCheck ^= 1;
break;
@@ -124,38 +165,132 @@ int IoCommandRead( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the input file name
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_Read( pFileName, Io_ReadFileType(pFileName), fCheck );
+ if ( pNtk == NULL )
+ return 1;
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
- if ( argc != util_optind + 1 )
+usage:
+ fprintf( pAbc->Err, "usage: read [-mch] <file>\n" );
+ fprintf( pAbc->Err, "\t replaces the current network by the network read from <file>\n" );
+ fprintf( pAbc->Err, "\t by calling the parser that matches the extension of <file>\n" );
+ fprintf( pAbc->Err, "\t (to read a hierarchical design, use \"read_hie\")\n" );
+ fprintf( pAbc->Err, "\t-m : toggle reading mapped Verilog [default = %s]\n", glo_fMapped? "yes":"no" );
+ 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 IoCommandReadAiger( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
{
- goto usage;
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
-
+ if ( argc != globalUtilOptind + 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", ".eqn", ".bench" ) )
- fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
- fprintf( pAbc->Err, "\n" );
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_Read( pFileName, IO_FILE_AIGER, fCheck );
+ if ( pNtk == NULL )
return 1;
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: read_aiger [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in the AIGER format (http://fmv.jku.at/aiger)\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 IoCommandReadBaf( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
- fclose( pFile );
-
- // set the new network
- pNtk = Io_Read( FileName, fCheck );
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the input file name
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_Read( pFileName, IO_FILE_BAF, 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, "usage: read_baf [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in Binary Aig Format (BAF)\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" );
@@ -175,18 +310,23 @@ usage:
***********************************************************************/
int IoCommandReadBlif( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk, * pTemp;
- char * FileName;
- FILE * pFile;
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
+ int fReadAsAig;
int fCheck;
int c;
+ extern Abc_Ntk_t * Io_ReadBlifAsAig( char * pFileName, int fCheck );
fCheck = 1;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ fReadAsAig = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ach" ) ) != EOF )
{
switch ( c )
{
+ case 'a':
+ fReadAsAig ^= 1;
+ break;
case 'c':
fCheck ^= 1;
break;
@@ -196,47 +336,34 @@ int IoCommandReadBlif( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
-
- if ( argc != util_optind + 1 )
- {
+ if ( argc != globalUtilOptind + 1 )
goto usage;
- }
-
// get the input file name
- FileName = argv[util_optind];
- if ( (pFile = fopen( FileName, "r" )) == NULL )
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ if ( fReadAsAig )
+ pNtk = Io_ReadBlifAsAig( pFileName, fCheck );
+ else
+// pNtk = Io_Read( pFileName, IO_FILE_BLIF, fCheck );
{
- fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
- if ( FileName = Extra_FileGetSimilarName( FileName, ".mv", ".blif", ".pla", ".eqn", ".bench" ) )
- 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;
+ Abc_Ntk_t * pTemp;
+ pNtk = Io_ReadBlif( pFileName, fCheck );
+ if ( pNtk == NULL )
+ return 1;
+ pNtk = Abc_NtkToLogic( pTemp = pNtk );
+ Abc_NtkDelete( pTemp );
}
- pNtk = Abc_NtkNetlistToLogic( 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, "usage: read_blif [-ach] <file>\n" );
fprintf( pAbc->Err, "\t read the network in binary BLIF format\n" );
+ fprintf( pAbc->Err, "\t-a : toggle creating AIG while reading the file [default = %s]\n", fReadAsAig? "yes":"no" );
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" );
@@ -254,17 +381,16 @@ usage:
SeeAlso []
***********************************************************************/
-int IoCommandReadBench( Abc_Frame_t * pAbc, int argc, char ** argv )
+int IoCommandReadBlifMv( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk, * pTemp;
- char * FileName;
- FILE * pFile;
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
int fCheck;
int c;
fCheck = 1;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
{
switch ( c )
{
@@ -277,39 +403,68 @@ int IoCommandReadBench( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
-
- if ( argc != util_optind + 1 )
- {
+ if ( argc != globalUtilOptind + 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", ".eqn", ".bench" ) )
- fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
- fprintf( pAbc->Err, "\n" );
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_Read( pFileName, IO_FILE_BLIFMV, fCheck );
+ if ( pNtk == NULL )
return 1;
- }
- fclose( pFile );
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
- // set the new network
- pNtk = Io_ReadBench( FileName, fCheck );
- if ( pNtk == NULL )
+usage:
+ fprintf( pAbc->Err, "usage: read_blif_mv [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in BLIF-MV 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;
+ char * pFileName;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
{
- fprintf( pAbc->Err, "Reading network from BENCH file has failed.\n" );
- return 1;
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
-
- pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
- Abc_NtkDelete( pTemp );
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the input file name
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_Read( pFileName, IO_FILE_BENCH, fCheck );
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;
@@ -334,17 +489,17 @@ usage:
SeeAlso []
***********************************************************************/
-int IoCommandReadEdif( Abc_Frame_t * pAbc, int argc, char ** argv )
+int IoCommandReadDsd( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk, * pTemp;
- char * FileName;
- FILE * pFile;
+ Abc_Ntk_t * pNtk;
+ char * pString;
int fCheck;
int c;
+ extern Abc_Ntk_t * Io_ReadDsd( char * pFormula );
fCheck = 1;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
{
switch ( c )
{
@@ -357,47 +512,195 @@ int IoCommandReadEdif( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the input file name
+ pString = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_ReadDsd( pString );
+ if ( pNtk == NULL )
+ return 1;
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
- if ( argc != util_optind + 1 )
+usage:
+ fprintf( pAbc->Err, "usage: read_dsd [-h] <formula>\n" );
+ fprintf( pAbc->Err, "\t parses a formula representing DSD of a function\n" );
+ fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
+ fprintf( pAbc->Err, "\tformula : the formula representing disjoint-support decomposition (DSD)\n" );
+ fprintf( pAbc->Err, "\t Example of a formula: !(a*(b+CA(!d,e*f,c))*79B3(g,h,i,k))\n" );
+ fprintf( pAbc->Err, "\t where \'!\' is an INV, \'*\' is an AND, \'+\' is an XOR, \n" );
+ fprintf( pAbc->Err, "\t CA and 79B3 are hexadecimal representations of truth tables\n" );
+ fprintf( pAbc->Err, "\t (in this case CA=11001010 is truth table of MUX(Data0,Data1,Ctrl))\n" );
+ fprintf( pAbc->Err, "\t The lower chars (a,b,c,etc) are reserved for elementary variables.\n" );
+ fprintf( pAbc->Err, "\t The upper chars (A,B,C,etc) are reserved for hexadecimal digits.\n" );
+ fprintf( pAbc->Err, "\t No spaces are allowed in formulas. In parantheses, LSB goes first.\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandReadEdif( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
{
- goto usage;
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
-
+ if ( argc != globalUtilOptind + 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", ".eqn", ".bench" ) )
- fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
- fprintf( pAbc->Err, "\n" );
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_Read( pFileName, IO_FILE_EDIF, fCheck );
+ if ( pNtk == NULL )
return 1;
- }
- fclose( pFile );
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
- // set the new network
- pNtk = Io_ReadEdif( FileName, fCheck );
- if ( pNtk == NULL )
+usage:
+ fprintf( pAbc->Err, "usage: read_edif [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in EDIF (works only for ISCAS benchmarks)\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 IoCommandReadEqn( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
{
- fprintf( pAbc->Err, "Reading network from EDIF file has failed.\n" );
+ switch ( c )
+ {
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the input file name
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_Read( pFileName, IO_FILE_EQN, fCheck );
+ if ( pNtk == NULL )
return 1;
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: read_eqn [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in equation 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 IoCommandReadInit( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
+ int c;
+ extern void Io_ReadBenchInit( Abc_Ntk_t * pNtk, char * pFileName );
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
- pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
- Abc_NtkDelete( pTemp );
if ( pNtk == NULL )
{
- fprintf( pAbc->Err, "Converting to logic network after reading has failed.\n" );
+ fprintf( pErr, "Empty network.\n" );
return 1;
}
+ // get the input file name
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Abc_NtkDup( pNtk );
+ Io_ReadBenchInit( pNtk, pFileName );
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
return 0;
usage:
- fprintf( pAbc->Err, "usage: read_edif [-ch] <file>\n" );
- fprintf( pAbc->Err, "\t read the network in EDIF (works only for ISCAS benchmarks)\n" );
- fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" );
+ fprintf( pAbc->Err, "usage: read_init [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t reads initial state of the network in BENCH format\n" );
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
return 1;
@@ -414,17 +717,16 @@ usage:
SeeAlso []
***********************************************************************/
-int IoCommandReadEqn( Abc_Frame_t * pAbc, int argc, char ** argv )
+int IoCommandReadPla( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk, * pTemp;
- char * FileName;
- FILE * pFile;
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
int fCheck;
int c;
fCheck = 1;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
{
switch ( c )
{
@@ -437,46 +739,150 @@ int IoCommandReadEqn( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the input file name
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_Read( pFileName, IO_FILE_PLA, fCheck );
+ if ( pNtk == NULL )
+ return 1;
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
- if ( argc != util_optind + 1 )
+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 IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ char * pSopCover;
+ int fHex;
+ int c;
+
+ fHex = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "xh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'x':
+ fHex ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( argc != globalUtilOptind + 1 )
{
goto usage;
}
- // get the input file name
- FileName = argv[util_optind];
- if ( (pFile = fopen( FileName, "r" )) == NULL )
+ // convert truth table to SOP
+ if ( fHex )
+ pSopCover = Abc_SopFromTruthHex(argv[globalUtilOptind]);
+ else
+ pSopCover = Abc_SopFromTruthBin(argv[globalUtilOptind]);
+ if ( pSopCover == NULL )
{
- fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
- if ( FileName = Extra_FileGetSimilarName( FileName, ".mv", ".blif", ".pla", ".eqn", ".bench" ) )
- fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
- fprintf( pAbc->Err, "\n" );
+ fprintf( pAbc->Err, "Reading truth table has failed.\n" );
return 1;
}
- fclose( pFile );
- // set the new network
- pNtk = Io_ReadEqn( FileName, fCheck );
+ pNtk = Abc_NtkCreateWithNode( pSopCover );
+ free( pSopCover );
if ( pNtk == NULL )
{
- fprintf( pAbc->Err, "Reading network from the equation file has failed.\n" );
+ fprintf( pAbc->Err, "Deriving the network has failed.\n" );
return 1;
}
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ return 0;
- pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
- Abc_NtkDelete( pTemp );
- if ( pNtk == NULL )
+usage:
+ fprintf( pAbc->Err, "usage: read_truth [-xh] <truth>\n" );
+ fprintf( pAbc->Err, "\t creates network with node having given truth table\n" );
+ fprintf( pAbc->Err, "\t-x : toggles between bin and hex representation [default = %s]\n", fHex? "hex":"bin" );
+ fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
+ fprintf( pAbc->Err, "\ttruth : truth table with most signficant bit first (e.g. 1000 for AND(a,b))\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandReadVerilog( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
+ int fCheck;
+ int c;
+
+ fCheck = 1;
+ glo_fMapped = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "mch" ) ) != EOF )
{
- fprintf( pAbc->Err, "Converting to logic network after reading has failed.\n" );
- return 1;
+ switch ( c )
+ {
+ case 'm':
+ glo_fMapped ^= 1;
+ break;
+ case 'c':
+ fCheck ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the input file name
+ pFileName = argv[globalUtilOptind];
+ // read the file using the corresponding file reader
+ pNtk = Io_Read( pFileName, IO_FILE_VERILOG, fCheck );
+ if ( pNtk == NULL )
+ return 1;
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
return 0;
usage:
- fprintf( pAbc->Err, "usage: read_eqn [-ch] <file>\n" );
- fprintf( pAbc->Err, "\t read the network in equation format\n" );
+ fprintf( pAbc->Err, "usage: read_verilog [-mch] <file>\n" );
+ fprintf( pAbc->Err, "\t read the network in Verilog (IWLS 2002/2005 subset)\n" );
+ fprintf( pAbc->Err, "\t-m : toggle reading mapped Verilog [default = %s]\n", glo_fMapped? "yes":"no" );
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" );
@@ -494,17 +900,23 @@ usage:
SeeAlso []
***********************************************************************/
-int IoCommandReadVerilog( Abc_Frame_t * pAbc, int argc, char ** argv )
+int IoCommandReadVer( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk, * pTemp;
- char * FileName;
+ Abc_Ntk_t * pNtk, * pNtkNew;
+ Abc_Lib_t * pDesign;
+ char * pFileName;
FILE * pFile;
int fCheck;
int c;
+ extern Abc_Ntk_t * Abc_LibDeriveAig( Abc_Ntk_t * pNtk, Abc_Lib_t * pLib );
+ extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck, int fUseMemMan );
+
+ printf( "Stand-alone structural Verilog reader is available as command \"read_verilog\".\n" );
+ return 0;
fCheck = 1;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
{
switch ( c )
{
@@ -518,45 +930,55 @@ int IoCommandReadVerilog( Abc_Frame_t * pAbc, int argc, char ** argv )
}
}
- if ( argc != util_optind + 1 )
+ if ( argc != globalUtilOptind + 1 )
{
goto usage;
}
// get the input file name
- FileName = argv[util_optind];
- if ( (pFile = fopen( FileName, "r" )) == NULL )
+ pFileName = argv[globalUtilOptind];
+ if ( (pFile = fopen( pFileName, "r" )) == NULL )
{
- fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
- if ( FileName = Extra_FileGetSimilarName( FileName, ".mv", ".blif", ".pla", ".eqn", ".bench" ) )
- fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
+ fprintf( pAbc->Err, "Cannot open input file \"%s\". ", pFileName );
+ if ( pFileName = Extra_FileGetSimilarName( pFileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) )
+ fprintf( pAbc->Err, "Did you mean \"%s\"?", pFileName );
fprintf( pAbc->Err, "\n" );
return 1;
}
fclose( pFile );
// set the new network
- pNtk = Io_ReadVerilog( FileName, fCheck );
- if ( pNtk == NULL )
+ pDesign = Ver_ParseFile( pFileName, Abc_FrameReadLibVer(), fCheck, 1 );
+ if ( pDesign == NULL )
{
fprintf( pAbc->Err, "Reading network from the verilog file has failed.\n" );
return 1;
}
- pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk );
- Abc_NtkDelete( pTemp );
+ // derive root design
+ pNtk = Abc_LibDeriveRoot( pDesign );
+ Abc_LibFree( pDesign, NULL );
if ( pNtk == NULL )
{
- fprintf( pAbc->Err, "Converting to logic network after reading has failed.\n" );
+ fprintf( pAbc->Err, "Deriving root module has failed.\n" );
+ return 1;
+ }
+
+ // derive the AIG network from this design
+ pNtkNew = Abc_LibDeriveAig( pNtk, Abc_FrameReadLibVer() );
+ Abc_NtkDelete( pNtk );
+ if ( pNtkNew == NULL )
+ {
+ fprintf( pAbc->Err, "Converting root module to AIG has failed.\n" );
return 1;
}
// replace the current network
- Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkNew );
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, "usage: read_ver [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read a network in structural verilog (using current library)\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" );
@@ -574,17 +996,18 @@ usage:
SeeAlso []
***********************************************************************/
-int IoCommandReadPla( Abc_Frame_t * pAbc, int argc, char ** argv )
+int IoCommandReadVerLib( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- Abc_Ntk_t * pNtk, * pTemp;
- char * FileName;
+ Abc_Lib_t * pLibrary;
+ char * pFileName;
FILE * pFile;
int fCheck;
int c;
+ extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck, int fUseMemMan );
fCheck = 1;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
{
switch ( c )
{
@@ -598,45 +1021,41 @@ int IoCommandReadPla( Abc_Frame_t * pAbc, int argc, char ** argv )
}
}
- if ( argc != util_optind + 1 )
+ if ( argc != globalUtilOptind + 1 )
{
goto usage;
}
// get the input file name
- FileName = argv[util_optind];
- if ( (pFile = fopen( FileName, "r" )) == NULL )
+ pFileName = argv[globalUtilOptind];
+ if ( (pFile = fopen( pFileName, "r" )) == NULL )
{
- fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName );
- if ( FileName = Extra_FileGetSimilarName( FileName, ".mv", ".blif", ".pla", ".eqn", ".bench" ) )
- fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName );
+ fprintf( pAbc->Err, "Cannot open input file \"%s\". ", pFileName );
+ if ( pFileName = Extra_FileGetSimilarName( pFileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) )
+ fprintf( pAbc->Err, "Did you mean \"%s\"?", pFileName );
fprintf( pAbc->Err, "\n" );
return 1;
}
fclose( pFile );
// set the new network
- pNtk = Io_ReadPla( FileName, fCheck );
- if ( pNtk == NULL )
+ pLibrary = Ver_ParseFile( pFileName, NULL, fCheck, 0 );
+ if ( pLibrary == NULL )
{
- fprintf( pAbc->Err, "Reading network from PLA file has failed.\n" );
+ fprintf( pAbc->Err, "Reading library from the verilog file has failed.\n" );
return 1;
}
-
- pNtk = Abc_NtkNetlistToLogic( 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 );
+ printf( "The library contains %d gates.\n", st_count(pLibrary->tModules) );
+ // free old library
+ if ( Abc_FrameReadLibVer() )
+ Abc_LibFree( Abc_FrameReadLibVer(), NULL );
+ // read new library
+ Abc_FrameSetLibVer( pLibrary );
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, "usage: read_verlib [-ch] <file>\n" );
+ fprintf( pAbc->Err, "\t read a gate library in structural verilog\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" );
@@ -655,57 +1074,87 @@ usage:
SeeAlso []
***********************************************************************/
-int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
+int IoCommandWrite( Abc_Frame_t * pAbc, int argc, char **argv )
{
- Abc_Ntk_t * pNtk;
- char * FileName;
- int fWriteLatches;
+ char * pFileName;
int c;
- fWriteLatches = 1;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "lh" ) ) != EOF )
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
- case 'l':
- fWriteLatches ^= 1;
- break;
case 'h':
goto usage;
default:
goto usage;
}
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ Io_Write( pAbc->pNtkCur, pFileName, Io_ReadFileType(pFileName) );
+ return 0;
- pNtk = pAbc->pNtkCur;
- if ( pNtk == NULL )
- {
- fprintf( pAbc->Out, "Empty network.\n" );
- return 0;
- }
+usage:
+ fprintf( pAbc->Err, "usage: write [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t writes the current network into <file> by calling\n" );
+ fprintf( pAbc->Err, "\t the writer that matches the extension of <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;
+}
- if ( argc != util_optind + 1 )
- {
- goto usage;
- }
- FileName = argv[util_optind];
+/**Function*************************************************************
- // check the network type
- if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsSeq(pNtk) )
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteHie( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * pBaseName, * pFileName;
+ int c;
+
+ glo_fMapped = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "mh" ) ) != EOF )
{
- fprintf( pAbc->Out, "Currently can only write logic networks, AIGs, and seq AIGs.\n" );
- return 0;
+ switch ( c )
+ {
+ case 'm':
+ glo_fMapped ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
- Io_WriteBlifLogic( pNtk, FileName, fWriteLatches );
-// Io_WriteBlif( pNtk, FileName, fWriteLatches );
+ if ( argc != globalUtilOptind + 2 )
+ goto usage;
+ // get the output file name
+ pBaseName = argv[globalUtilOptind];
+ pFileName = argv[globalUtilOptind+1];
+ // call the corresponding file writer
+// Io_Write( pAbc->pNtkCur, pFileName, Io_ReadFileType(pFileName) );
+ Io_WriteHie( pAbc->pNtkCur, pBaseName, pFileName );
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, "usage: write_hie [-h] <orig> <file>\n" );
+ fprintf( pAbc->Err, "\t writes the current network into <file> by calling\n" );
+ fprintf( pAbc->Err, "\t the hierarchical writer that matches the extension of <file>\n" );
+ fprintf( pAbc->Err, "\t-m : toggle reading mapped Verilog for <orig> [default = %s]\n", glo_fMapped? "yes":"no" );
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
+ fprintf( pAbc->Err, "\torig : the name of the original file with the hierarchical design\n" );
fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
return 1;
}
@@ -721,21 +1170,25 @@ usage:
SeeAlso []
***********************************************************************/
-int IoCommandWriteBench( Abc_Frame_t * pAbc, int argc, char **argv )
+int IoCommandWriteAiger( Abc_Frame_t * pAbc, int argc, char **argv )
{
- Abc_Ntk_t * pNtk, * pNtkTemp;
- char * FileName;
- int fWriteLatches;
+ char * pFileName;
+ int fWriteSymbols;
+ int fCompact;
int c;
- fWriteLatches = 1;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "lh" ) ) != EOF )
+ fCompact = 1;
+ fWriteSymbols = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "sch" ) ) != EOF )
{
switch ( c )
{
- case 'l':
- fWriteLatches ^= 1;
+ case 's':
+ fWriteSymbols ^= 1;
+ break;
+ case 'c':
+ fCompact ^= 1;
break;
case 'h':
goto usage;
@@ -743,44 +1196,213 @@ int IoCommandWriteBench( Abc_Frame_t * pAbc, int argc, char **argv )
goto usage;
}
}
-
- pNtk = pAbc->pNtkCur;
- if ( pNtk == NULL )
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ if ( !Abc_NtkIsStrash(pAbc->pNtkCur) )
{
- fprintf( pAbc->Out, "Empty network.\n" );
- return 0;
+ fprintf( stdout, "Writing this format is only possible for structurally hashed AIGs.\n" );
+ return 1;
}
+ Io_WriteAiger( pAbc->pNtkCur, pFileName, fWriteSymbols, fCompact );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_aiger [-sch] <file>\n" );
+ fprintf( pAbc->Err, "\t write the network in the AIGER format (http://fmv.jku.at/aiger)\n" );
+ fprintf( pAbc->Err, "\t-s : toggle saving I/O names [default = %s]\n", fWriteSymbols? "yes" : "no" );
+ fprintf( pAbc->Err, "\t-c : toggle writing more compactly [default = %s]\n", fCompact? "yes" : "no" );
+ fprintf( pAbc->Err, "\t-h : print the help massage\n" );
+ fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .aig)\n" );
+ return 1;
+}
- if ( argc != util_optind + 1 )
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteBaf( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * pFileName;
+ int c;
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_BAF );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_baf [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the network into a BLIF file\n" );
+ fprintf( pAbc->Err, "\t-h : print the help massage\n" );
+ fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .baf)\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * pFileName;
+ int c;
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
- // get the input file name
- FileName = argv[util_optind];
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_BLIF );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_blif [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the network into a BLIF file\n" );
+ fprintf( pAbc->Err, "\t-h : print the help massage\n" );
+ fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .blif)\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
- if ( !Abc_NtkIsStrash(pNtk) )
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteBlifMv( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * pFileName;
+ int c;
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
- fprintf( pAbc->Out, "The network should be an AIG.\n" );
- return 0;
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_BLIFMV );
+ return 0;
- // derive the netlist
- pNtkTemp = Abc_NtkLogicToNetlistBench(pNtk);
- if ( pNtkTemp == NULL )
+usage:
+ fprintf( pAbc->Err, "usage: write_blif_mv [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the network into a BLIF-MV file\n" );
+ fprintf( pAbc->Err, "\t-h : print the help massage\n" );
+ fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .mv)\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteBench( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * pFileName;
+ int fUseLuts;
+ int c;
+
+ fUseLuts = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "lh" ) ) != EOF )
{
- fprintf( pAbc->Out, "Writing BENCH has failed.\n" );
- return 0;
+ switch ( c )
+ {
+ case 'l':
+ fUseLuts ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ if ( !fUseLuts )
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_BENCH );
+ else
+ {
+ Abc_Ntk_t * pNtkTemp;
+ pNtkTemp = Abc_NtkToNetlist( pAbc->pNtkCur );
+ Abc_NtkToAig( pNtkTemp );
+ Io_WriteBenchLut( pNtkTemp, pFileName );
+ Abc_NtkDelete( pNtkTemp );
}
- Io_WriteBench( pNtkTemp, FileName );
- Abc_NtkDelete( pNtkTemp );
return 0;
usage:
- fprintf( pAbc->Err, "usage: write_bench [-h] <file>\n" );
+ fprintf( pAbc->Err, "usage: write_bench [-lh] <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-l : toggle using LUTs in the output [default = %s]\n", fUseLuts? "yes" : "no" );
fprintf( pAbc->Err, "\t-h : print the help massage\n" );
- fprintf( pAbc->Err, "\tfile : the name of the file to write\n" );
+ fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .bench)\n" );
return 1;
}
@@ -795,13 +1417,15 @@ usage:
SeeAlso []
***********************************************************************/
-int IoCommandWriteCnf( Abc_Frame_t * pAbc, int argc, char **argv )
+int IoCommandWriteCellNet( Abc_Frame_t * pAbc, int argc, char **argv )
{
- char * FileName;
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
int c;
+ extern void Io_WriteCellNet( Abc_Ntk_t * pNtk, char * pFileName );
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
@@ -811,31 +1435,95 @@ int IoCommandWriteCnf( Abc_Frame_t * pAbc, int argc, char **argv )
goto usage;
}
}
-
- if ( pAbc->pNtkCur == NULL )
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ pNtk = pAbc->pNtkCur;
+ if ( pNtk == NULL )
{
fprintf( pAbc->Out, "Empty network.\n" );
return 0;
}
-
- if ( argc != util_optind + 1 )
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ if ( !Abc_NtkIsLogic(pNtk) )
{
- goto usage;
+ fprintf( pAbc->Out, "The network should be a logic network (if it an AIG, use command \"logic\")\n" );
+ return 0;
}
+ Io_WriteCellNet( pNtk, pFileName );
+ return 0;
- // get the input file name
- FileName = argv[util_optind];
- // write the file
- if ( !Io_WriteCnf( pAbc->pNtkCur, FileName ) )
+usage:
+ fprintf( pAbc->Err, "usage: write_cellnet [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the network is the cellnet format\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;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteCnf( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * pFileName;
+ int c;
+ int fAllPrimes;
+ int fNewAlgo;
+ extern Abc_Ntk_t * Abc_NtkDarToCnf( Abc_Ntk_t * pNtk, char * pFileName );
+
+ fNewAlgo = 1;
+ fAllPrimes = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "nph" ) ) != EOF )
{
- printf( "Writing CNF has failed.\n" );
- return 1;
+ switch ( c )
+ {
+ case 'n':
+ fNewAlgo ^= 1;
+ break;
+ case 'p':
+ fAllPrimes ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // check if the feature will be used
+ if ( Abc_NtkIsStrash(pAbc->pNtkCur) && fAllPrimes )
+ {
+ fAllPrimes = 0;
+ printf( "Warning: Selected option to write all primes has no effect when deriving CNF from AIG.\n" );
+ }
+ // call the corresponding file writer
+ if ( fNewAlgo )
+ Abc_NtkDarToCnf( pAbc->pNtkCur, pFileName );
+ else if ( fAllPrimes )
+ Io_WriteCnf( pAbc->pNtkCur, pFileName, 1 );
+ else
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_CNF );
return 0;
usage:
- fprintf( pAbc->Err, "usage: write_cnf [-h] <file>\n" );
+ fprintf( pAbc->Err, "usage: write_cnf [-nph] <file>\n" );
fprintf( pAbc->Err, "\t write the miter cone into a CNF file\n" );
+ fprintf( pAbc->Err, "\t-n : toggle using new algorithm [default = %s]\n", fNewAlgo? "yes" : "no" );
+ fprintf( pAbc->Err, "\t-p : toggle using all primes to enhance implicativity [default = %s]\n", fAllPrimes? "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;
@@ -854,12 +1542,11 @@ usage:
***********************************************************************/
int IoCommandWriteDot( Abc_Frame_t * pAbc, int argc, char **argv )
{
- char * FileName;
- Vec_Ptr_t * vNodes;
+ char * pFileName;
int c;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
@@ -869,40 +1556,24 @@ int IoCommandWriteDot( Abc_Frame_t * pAbc, int argc, char **argv )
goto usage;
}
}
-
- if ( pAbc->pNtkCur == NULL )
- {
- fprintf( pAbc->Out, "Empty network.\n" );
- return 0;
- }
-
- if ( !Abc_NtkIsStrash(pAbc->pNtkCur) )
- {
- fprintf( stdout, "IoCommandWriteDot(): Currently can only process logic networks with BDDs.\n" );
- return 0;
- }
-
- if ( argc != util_optind + 1 )
- {
+ if ( argc != globalUtilOptind + 1 )
goto usage;
- }
-
- // get the input file name
- FileName = argv[util_optind];
- // write the file
- vNodes = Abc_NtkCollectObjects( pAbc->pNtkCur );
- Io_WriteDot( pAbc->pNtkCur, vNodes, NULL, FileName );
- Vec_PtrFree( vNodes );
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_DOT );
return 0;
usage:
fprintf( pAbc->Err, "usage: write_dot [-h] <file>\n" );
- fprintf( pAbc->Err, "\t write the AIG into a DOT file\n" );
+ fprintf( pAbc->Err, "\t write the current network into a DOT 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;
}
+#include "fra.h"
+
/**Function*************************************************************
Synopsis []
@@ -914,17 +1585,22 @@ usage:
SeeAlso []
***********************************************************************/
-int IoCommandWriteEqn( Abc_Frame_t * pAbc, int argc, char **argv )
+int IoCommandWriteCounter( Abc_Frame_t * pAbc, int argc, char **argv )
{
- Abc_Ntk_t * pNtk, * pNtkTemp;
- char * FileName;
+ Abc_Ntk_t * pNtk;
+ char * pFileName;
int c;
+ int fNames;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ fNames = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "nh" ) ) != EOF )
{
switch ( c )
{
+ case 'n':
+ fNames ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -939,32 +1615,128 @@ int IoCommandWriteEqn( Abc_Frame_t * pAbc, int argc, char **argv )
return 0;
}
- if ( argc != util_optind + 1 )
+ if ( argc != globalUtilOptind + 1 )
{
goto usage;
}
+ // get the input file name
+ pFileName = argv[globalUtilOptind];
- if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) )
+ if ( pNtk->pModel == NULL && pNtk->pSeqModel == NULL )
{
- fprintf( stdout, "IoCommandWriteGml(): Currently can only process logic networks with BDDs.\n" );
+ fprintf( pAbc->Out, "Counter-example is not available.\n" );
return 0;
}
- // get the input file name
- FileName = argv[util_optind];
- // write the file
- // get rid of complemented covers if present
- if ( Abc_NtkIsSopLogic(pNtk) )
- Abc_NtkLogicMakeDirectSops(pNtk);
- // derive the netlist
- pNtkTemp = Abc_NtkLogicToNetlist(pNtk);
- if ( pNtkTemp == NULL )
+ // write the counter-example into the file
+ if ( pNtk->pModel )
{
- fprintf( pAbc->Out, "Writing BENCH has failed.\n" );
- return 0;
+ Abc_Obj_t * pObj;
+ FILE * pFile = fopen( pFileName, "w" );
+ int i;
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "IoCommandWriteCounter(): Cannot open the output file \"%s\".\n", pFileName );
+ return 1;
+ }
+ if ( fNames )
+ {
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ fprintf( pFile, "%s=%c ", Abc_ObjName(pObj), '0'+(pNtk->pModel[i]==1) );
+ }
+ else
+ {
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ fprintf( pFile, "%c", '0'+(pNtk->pModel[i]==1) );
+ }
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+ }
+ else
+ {
+ Fra_Cex_t * pCex = pNtk->pSeqModel;
+ Abc_Obj_t * pObj;
+ FILE * pFile;
+ int i, f;
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ if ( !Abc_LatchIsInit0(pObj) )
+ {
+ fprintf( stdout, "IoCommandWriteCounter(): The init-state should be all-0 for counter-example to work.\n" );
+ fprintf( stdout, "Run commands \"undc\" and \"zero\" and then rerun the equivalence check.\n" );
+ return 1;
+ }
+
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "IoCommandWriteCounter(): Cannot open the output file \"%s\".\n", pFileName );
+ return 1;
+ }
+ if ( fNames )
+ {
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ fprintf( pFile, "%s@0=%c ", Abc_ObjName(Abc_ObjFanout0(pObj)), '0'+!Abc_LatchIsInit0(pObj) );
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ fprintf( pFile, "%s@%d=%c ", Abc_ObjName(pObj), f, '0'+Abc_InfoHasBit(pCex->pData, pCex->nRegs+pCex->nPis*f + i) );
+ }
+ else
+ {
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ fprintf( pFile, "%c", '0'+!Abc_LatchIsInit0(pObj) );
+ for ( i = pCex->nRegs; i < pCex->nBits; i++ )
+ fprintf( pFile, "%c", '0'+Abc_InfoHasBit(pCex->pData, i) );
+ }
+ fprintf( pFile, "\n" );
+ fclose( pFile );
}
- Io_WriteEqn( pNtkTemp, FileName );
- Abc_NtkDelete( pNtkTemp );
+
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_counter [-nh] <file>\n" );
+ fprintf( pAbc->Err, "\t saves counter-example derived by \"sat\", \"iprove\", or \"dprove\"\n" );
+ fprintf( pAbc->Err, "\t the file contains values for each PI in the natural order\n" );
+ fprintf( pAbc->Err, "\t-n : write input names into the file [default = %s]\n", fNames? "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 IoCommandWriteEqn( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * pFileName;
+ int c;
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_EQN );
return 0;
usage:
@@ -988,11 +1760,11 @@ usage:
***********************************************************************/
int IoCommandWriteGml( Abc_Frame_t * pAbc, int argc, char **argv )
{
- char * FileName;
+ char * pFileName;
int c;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
@@ -1002,33 +1774,81 @@ int IoCommandWriteGml( Abc_Frame_t * pAbc, int argc, char **argv )
goto usage;
}
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_GML );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_gml [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write network using graph representation formal GML\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;
+}
+
+/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteList( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * pFileName;
+ int fUseHost;
+ int c;
+
+ printf( "This command currently does not work.\n" );
+ return 0;
+
+ fUseHost = 1;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "nh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'n':
+ fUseHost ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
if ( pAbc->pNtkCur == NULL )
{
fprintf( pAbc->Out, "Empty network.\n" );
return 0;
}
-
- if ( !Abc_NtkIsLogic(pAbc->pNtkCur) && !Abc_NtkIsStrash(pAbc->pNtkCur) )
+/*
+ if ( !Abc_NtkIsSeq(pAbc->pNtkCur) )
{
- fprintf( stdout, "IoCommandWriteGml(): Currently can only process logic networks with BDDs.\n" );
+ fprintf( stdout, "IoCommandWriteList(): Can write adjacency list for sequential AIGs only.\n" );
return 0;
}
-
- if ( argc != util_optind + 1 )
- {
- goto usage;
- }
-
+*/
// get the input file name
- FileName = argv[util_optind];
+ pFileName = argv[globalUtilOptind];
// write the file
- Io_WriteGml( pAbc->pNtkCur, FileName );
+ Io_WriteList( pAbc->pNtkCur, pFileName, fUseHost );
return 0;
usage:
- fprintf( pAbc->Err, "usage: write_gml [-h] <file>\n" );
+ fprintf( pAbc->Err, "usage: write_list [-nh] <file>\n" );
fprintf( pAbc->Err, "\t write network using graph representation formal GML\n" );
+ fprintf( pAbc->Err, "\t-n : toggle writing host node [default = %s]\n", fUseHost? "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;
@@ -1047,12 +1867,11 @@ usage:
***********************************************************************/
int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv )
{
- Abc_Ntk_t * pNtk, * pNtkTemp;
- char * FileName;
+ char * pFileName;
int c;
- util_getopt_reset();
- while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
@@ -1062,47 +1881,111 @@ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv )
goto usage;
}
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_PLA );
+ return 0;
- pNtk = pAbc->pNtkCur;
- if ( pNtk == NULL )
- {
- fprintf( pAbc->Out, "Empty network.\n" );
- return 0;
- }
+usage:
+ fprintf( pAbc->Err, "usage: write_pla [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the collapsed network into a PLA 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;
+}
- if ( Abc_NtkGetLevelNum(pNtk) > 1 )
- {
- fprintf( pAbc->Out, "PLA writing is available for collapsed networks.\n" );
- return 0;
- }
+/**Function*************************************************************
+
+ Synopsis []
- if ( Abc_NtkLatchNum(pNtk) > 0 )
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ char * pFileName;
+ int c;
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
- fprintf( pAbc->Out, "Latches are writed at PI/PO pairs in the PLA file.\n" );
- return 0;
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
+ // get the output file name
+ pFileName = argv[globalUtilOptind];
+ // call the corresponding file writer
+ Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_VERILOG );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: write_verilog [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the current network in Verilog format\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;
+}
- if ( argc != util_optind + 1 )
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IoCommandWriteVerLib( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ Abc_Lib_t * pLibrary;
+ char * pFileName;
+ int c;
+ extern void Io_WriteVerilogLibrary( Abc_Lib_t * pLibrary, char * pFileName );
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
- goto usage;
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
}
+ if ( argc != globalUtilOptind + 1 )
+ goto usage;
// get the input file name
- FileName = argv[util_optind];
-
+ pFileName = argv[globalUtilOptind];
// derive the netlist
- pNtkTemp = Abc_NtkLogicToNetlist(pNtk);
- if ( pNtkTemp == NULL )
+ pLibrary = Abc_FrameReadLibVer();
+ if ( pLibrary == NULL )
{
- fprintf( pAbc->Out, "Writing PLA has failed.\n" );
+ fprintf( pAbc->Out, "Verilog library is not specified.\n" );
return 0;
}
- Io_WritePla( pNtkTemp, FileName );
- Abc_NtkDelete( pNtkTemp );
+// Io_WriteVerilogLibrary( pLibrary, pFileName );
return 0;
usage:
- fprintf( pAbc->Err, "usage: write_pla [-h] <file>\n" );
- fprintf( pAbc->Err, "\t write the collapsed network into a PLA file\n" );
+ fprintf( pAbc->Err, "usage: write_verlib [-h] <file>\n" );
+ fprintf( pAbc->Err, "\t write the current verilog library\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;
diff --git a/src/base/io/io.h b/src/base/io/io.h
index 6bf3a85c..126de332 100644
--- a/src/base/io/io.h
+++ b/src/base/io/io.h
@@ -21,6 +21,10 @@
#ifndef __IO_H__
#define __IO_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
@@ -35,8 +39,27 @@
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
+// network functionality
+typedef enum {
+ IO_FILE_NONE = 0,
+ IO_FILE_AIGER,
+ IO_FILE_BAF,
+ IO_FILE_BLIF,
+ IO_FILE_BLIFMV,
+ IO_FILE_BENCH,
+ IO_FILE_CNF,
+ IO_FILE_DOT,
+ IO_FILE_EDIF,
+ IO_FILE_EQN,
+ IO_FILE_GML,
+ IO_FILE_LIST,
+ IO_FILE_PLA,
+ IO_FILE_VERILOG,
+ IO_FILE_UNKNOWN
+} Io_FileType_t;
+
////////////////////////////////////////////////////////////////////////
-/// MACRO DEFITIONS ///
+/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#define IO_WRITE_LINE_LENGTH 78 // the output line length
@@ -45,48 +68,79 @@
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-/*=== abcRead.c ==========================================================*/
-extern Abc_Ntk_t * Io_Read( char * pFileName, int fCheck );
-/*=== abcReadBlif.c ==========================================================*/
+/*=== abcReadAiger.c ==========================================================*/
+extern Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck );
+/*=== abcReadBaf.c ============================================================*/
+extern Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck );
+/*=== abcReadBlif.c ===========================================================*/
extern Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck );
+/*=== abcReadBlifMv.c =========================================================*/
+extern Abc_Ntk_t * Io_ReadBlifMv( char * pFileName, int fBlifMv, int fCheck );
/*=== abcReadBench.c ==========================================================*/
extern Abc_Ntk_t * Io_ReadBench( char * pFileName, int fCheck );
-/*=== abcReadEdif.c ==========================================================*/
+/*=== abcReadEdif.c ===========================================================*/
extern Abc_Ntk_t * Io_ReadEdif( char * pFileName, int fCheck );
-/*=== abcReadEqn.c ==========================================================*/
+/*=== abcReadEqn.c ============================================================*/
extern Abc_Ntk_t * Io_ReadEqn( char * pFileName, int fCheck );
-/*=== abcReadVerilog.c ==========================================================*/
-extern Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck );
-/*=== abcReadPla.c ==========================================================*/
+/*=== abcReadPla.c ============================================================*/
extern Abc_Ntk_t * Io_ReadPla( char * pFileName, int fCheck );
-/*=== abcUtil.c ==========================================================*/
-extern Abc_Obj_t * Io_ReadCreatePi( Abc_Ntk_t * pNtk, char * pName );
-extern Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName );
-extern Abc_Obj_t * Io_ReadCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO );
-extern Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, char * pNamesIn[], int nInputs );
-extern Abc_Obj_t * Io_ReadCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 );
-extern Abc_Obj_t * Io_ReadCreateInv( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut );
-extern Abc_Obj_t * Io_ReadCreateBuf( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut );
+/*=== abcReadVerilog.c ========================================================*/
+extern Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck );
+/*=== abcWriteAiger.c =========================================================*/
+extern void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName, int fWriteSymbols, int fCompact );
+/*=== abcWriteBaf.c ===========================================================*/
+extern void Io_WriteBaf( Abc_Ntk_t * pNtk, char * pFileName );
/*=== abcWriteBlif.c ==========================================================*/
-extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
+extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk );
-/*=== abcWriteBench.c ==========================================================*/
+/*=== abcWriteBlifMv.c ==========================================================*/
+extern void Io_WriteBlifMv( Abc_Ntk_t * pNtk, char * FileName );
+/*=== abcWriteBench.c =========================================================*/
extern int Io_WriteBench( Abc_Ntk_t * pNtk, char * FileName );
-/*=== abcWriteCnf.c ==========================================================*/
-extern int Io_WriteCnf( Abc_Ntk_t * pNtk, char * FileName );
-/*=== abcWriteDot.c ==========================================================*/
-extern void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName );
-/*=== abcWriteEqn.c ==========================================================*/
+extern int Io_WriteBenchLut( Abc_Ntk_t * pNtk, char * FileName );
+/*=== abcWriteCnf.c ===========================================================*/
+extern int Io_WriteCnf( Abc_Ntk_t * pNtk, char * FileName, int fAllPrimes );
+/*=== abcWriteDot.c ===========================================================*/
+extern void Io_WriteDot( Abc_Ntk_t * pNtk, char * FileName );
+extern void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse );
+extern void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse );
+/*=== abcWriteEqn.c ===========================================================*/
extern void Io_WriteEqn( Abc_Ntk_t * pNtk, char * pFileName );
-/*=== abcWriteGml.c ==========================================================*/
+/*=== abcWriteGml.c ===========================================================*/
extern void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName );
-/*=== abcWritePla.c ==========================================================*/
+/*=== abcWriteList.c ==========================================================*/
+extern void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost );
+/*=== abcWritePla.c ===========================================================*/
extern int Io_WritePla( Abc_Ntk_t * pNtk, char * FileName );
+/*=== abcWriteVerilog.c =======================================================*/
+extern void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * FileName );
+/*=== abcUtil.c ===============================================================*/
+extern Io_FileType_t Io_ReadFileType( char * pFileName );
+extern Abc_Ntk_t * Io_ReadNetlist( char * pFileName, Io_FileType_t FileType, int fCheck );
+extern Abc_Ntk_t * Io_Read( char * pFileName, Io_FileType_t FileType, int fCheck );
+extern void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType );
+extern void Io_WriteHie( Abc_Ntk_t * pNtk, char * pBaseName, char * pFileName );
+extern Abc_Obj_t * Io_ReadCreatePi( Abc_Ntk_t * pNtk, char * pName );
+extern Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName );
+extern Abc_Obj_t * Io_ReadCreateAssert( Abc_Ntk_t * pNtk, char * pName );
+extern Abc_Obj_t * Io_ReadCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO );
+extern Abc_Obj_t * Io_ReadCreateResetLatch( Abc_Ntk_t * pNtk, int fBlifMv );
+extern Abc_Obj_t * Io_ReadCreateResetMux( Abc_Ntk_t * pNtk, char * pResetLO, char * pDataLI, int fBlifMv );
+extern Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, char * pNamesIn[], int nInputs );
+extern Abc_Obj_t * Io_ReadCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 );
+extern Abc_Obj_t * Io_ReadCreateInv( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut );
+extern Abc_Obj_t * Io_ReadCreateBuf( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut );
+extern FILE * Io_FileOpen( const char * FileName, const char * PathVar, const char * Mode, int fVerbose );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
-#endif
-
diff --git a/src/base/io/ioInt.h b/src/base/io/ioInt.h
index 736884c4..3daf3c75 100644
--- a/src/base/io/ioInt.h
+++ b/src/base/io/ioInt.h
@@ -34,16 +34,16 @@
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
-/// MACRO DEFITIONS ///
+/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+#endif
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
-#endif
-
diff --git a/src/base/io/ioRead.c b/src/base/io/ioRead.c
deleted file mode 100644
index acf4deda..00000000
--- a/src/base/io/ioRead.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/**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 if ( Extra_FileNameCheckExtension( pFileName, "edf" ) )
- pNtk = Io_ReadEdif( pFileName, fCheck );
- else if ( Extra_FileNameCheckExtension( pFileName, "pla" ) )
- pNtk = Io_ReadPla( pFileName, fCheck );
- else if ( Extra_FileNameCheckExtension( pFileName, "eqn" ) )
- pNtk = Io_ReadEqn( pFileName, fCheck );
- else
- {
- fprintf( stderr, "Unknown file format\n" );
- return NULL;
- }
- if ( pNtk == NULL )
- return NULL;
-
- pNtk = Abc_NtkNetlistToLogic( 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/ioReadAiger.c b/src/base/io/ioReadAiger.c
new file mode 100644
index 00000000..4820bced
--- /dev/null
+++ b/src/base/io/ioReadAiger.c
@@ -0,0 +1,366 @@
+/**CFile****************************************************************
+
+ FileName [ioReadAiger.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to read binary AIGER format developed by
+ Armin Biere, Johannes Kepler University (http://fmv.jku.at/)]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - December 16, 2006.]
+
+ Revision [$Id: ioReadAiger.c,v 1.00 2006/12/16 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Extracts one unsigned AIG edge from the input buffer.]
+
+ Description [This procedure is a slightly modified version of Armin Biere's
+ procedure "unsigned decode (FILE * file)". ]
+
+ SideEffects [Updates the current reading position.]
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Io_ReadAigerDecode( char ** ppPos )
+{
+ unsigned x = 0, i = 0;
+ unsigned char ch;
+
+// while ((ch = getnoneofch (file)) & 0x80)
+ while ((ch = *(*ppPos)++) & 0x80)
+ x |= (ch & 0x7f) << (7 * i++);
+
+ return x | (ch << (7 * i));
+}
+
+/**Function*************************************************************
+
+ Synopsis [Decodes the encoded array of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Io_WriteDecodeLiterals( char ** ppPos, int nEntries )
+{
+ Vec_Int_t * vLits;
+ int Lit, LitPrev, Diff, i;
+ vLits = Vec_IntAlloc( nEntries );
+ LitPrev = Io_ReadAigerDecode( ppPos );
+ Vec_IntPush( vLits, LitPrev );
+ for ( i = 1; i < nEntries; i++ )
+ {
+// Diff = Lit - LitPrev;
+// Diff = (Lit < LitPrev)? -Diff : Diff;
+// Diff = ((2 * Diff) << 1) | (int)(Lit < LitPrev);
+ Diff = Io_ReadAigerDecode( ppPos );
+ Diff = (Diff & 1)? -(Diff >> 1) : Diff >> 1;
+ Lit = Diff + LitPrev;
+ Vec_IntPush( vLits, Lit );
+ LitPrev = Lit;
+ }
+ return vLits;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the AIG in the binary AIGER format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck )
+{
+ ProgressBar * pProgress;
+ FILE * pFile;
+ Vec_Ptr_t * vNodes, * vTerms;
+ Vec_Int_t * vLits = NULL;
+ Abc_Obj_t * pObj, * pNode0, * pNode1;
+ Abc_Ntk_t * pNtkNew;
+ int nTotal, nInputs, nOutputs, nLatches, nAnds, nFileSize, iTerm, nDigits, i;
+ char * pContents, * pDrivers, * pSymbols, * pCur, * pName, * pType;
+ unsigned uLit0, uLit1, uLit;
+
+ // read the file into the buffer
+ nFileSize = Extra_FileSize( pFileName );
+ pFile = fopen( pFileName, "rb" );
+ pContents = ALLOC( char, nFileSize );
+ fread( pContents, nFileSize, 1, pFile );
+ fclose( pFile );
+
+ // check if the input file format is correct
+ if ( strncmp(pContents, "aig", 3) != 0 || (pContents[3] != ' ' && pContents[3] != '2') )
+ {
+ fprintf( stdout, "Wrong input file format.\n" );
+ return NULL;
+ }
+
+ // allocate the empty AIG
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
+ pName = Extra_FileNameGeneric( pFileName );
+ pNtkNew->pName = Extra_UtilStrsav( pName );
+ pNtkNew->pSpec = Extra_UtilStrsav( pFileName );
+ free( pName );
+
+
+ // read the file type
+ pCur = pContents; while ( *pCur++ != ' ' );
+ // read the number of objects
+ nTotal = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of inputs
+ nInputs = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of latches
+ nLatches = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of outputs
+ nOutputs = atoi( pCur ); while ( *pCur++ != ' ' );
+ // read the number of nodes
+ nAnds = atoi( pCur ); while ( *pCur++ != '\n' );
+ // check the parameters
+ if ( nTotal != nInputs + nLatches + nAnds )
+ {
+ fprintf( stdout, "The paramters are wrong.\n" );
+ return NULL;
+ }
+
+ // prepare the array of nodes
+ vNodes = Vec_PtrAlloc( 1 + nInputs + nLatches + nAnds );
+ Vec_PtrPush( vNodes, Abc_ObjNot( Abc_AigConst1(pNtkNew) ) );
+
+ // create the PIs
+ for ( i = 0; i < nInputs; i++ )
+ {
+ pObj = Abc_NtkCreatePi(pNtkNew);
+ Vec_PtrPush( vNodes, pObj );
+ }
+ // create the POs
+ for ( i = 0; i < nOutputs; i++ )
+ {
+ pObj = Abc_NtkCreatePo(pNtkNew);
+ }
+ // create the latches
+ nDigits = Extra_Base10Log( nLatches );
+ for ( i = 0; i < nLatches; i++ )
+ {
+ pObj = Abc_NtkCreateLatch(pNtkNew);
+ Abc_LatchSetInit0( pObj );
+ pNode0 = Abc_NtkCreateBi(pNtkNew);
+ pNode1 = Abc_NtkCreateBo(pNtkNew);
+ Abc_ObjAddFanin( pObj, pNode0 );
+ Abc_ObjAddFanin( pNode1, pObj );
+ Vec_PtrPush( vNodes, pNode1 );
+ // assign names to latch and its input
+// Abc_ObjAssignName( pObj, Abc_ObjNameDummy("_L", i, nDigits), NULL );
+// printf( "Creating latch %s with input %d and output %d.\n", Abc_ObjName(pObj), pNode0->Id, pNode1->Id );
+ }
+
+
+ if ( pContents[3] == ' ' ) // standard AIGER
+ {
+ // remember the beginning of latch/PO literals
+ pDrivers = pCur;
+ // scroll to the beginning of the binary data
+ for ( i = 0; i < nLatches + nOutputs; )
+ if ( *pCur++ == '\n' )
+ i++;
+ }
+ else // modified AIGER
+ {
+ vLits = Io_WriteDecodeLiterals( &pCur, nLatches + nOutputs );
+ }
+
+ // create the AND gates
+ pProgress = Extra_ProgressBarStart( stdout, nAnds );
+ for ( i = 0; i < nAnds; i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ uLit = ((i + 1 + nInputs + nLatches) << 1);
+ uLit1 = uLit - Io_ReadAigerDecode( &pCur );
+ uLit0 = uLit1 - Io_ReadAigerDecode( &pCur );
+// assert( uLit1 > uLit0 );
+ pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), uLit0 & 1 );
+ pNode1 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit1 >> 1), uLit1 & 1 );
+ assert( Vec_PtrSize(vNodes) == i + 1 + nInputs + nLatches );
+ Vec_PtrPush( vNodes, Abc_AigAnd(pNtkNew->pManFunc, pNode0, pNode1) );
+ }
+ Extra_ProgressBarStop( pProgress );
+
+ // remember the place where symbols begin
+ pSymbols = pCur;
+
+ // read the latch driver literals
+ pCur = pDrivers;
+ if ( pContents[3] == ' ' ) // standard AIGER
+ {
+ Abc_NtkForEachLatchInput( pNtkNew, pObj, i )
+ {
+ uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
+ pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) );
+ Abc_ObjAddFanin( pObj, pNode0 );
+ }
+ // read the PO driver literals
+ Abc_NtkForEachPo( pNtkNew, pObj, i )
+ {
+ uLit0 = atoi( pCur ); while ( *pCur++ != '\n' );
+ pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );//^ (uLit0 < 2) );
+ Abc_ObjAddFanin( pObj, pNode0 );
+ }
+ }
+ else
+ {
+ // read the latch driver literals
+ Abc_NtkForEachLatchInput( pNtkNew, pObj, i )
+ {
+ uLit0 = Vec_IntEntry( vLits, i );
+ pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
+ Abc_ObjAddFanin( pObj, pNode0 );
+ }
+ // read the PO driver literals
+ Abc_NtkForEachPo( pNtkNew, pObj, i )
+ {
+ uLit0 = Vec_IntEntry( vLits, i+Abc_NtkLatchNum(pNtkNew) );
+ pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, uLit0 >> 1), (uLit0 & 1) );
+ Abc_ObjAddFanin( pObj, pNode0 );
+ }
+ Vec_IntFree( vLits );
+ }
+
+ // read the names if present
+ pCur = pSymbols;
+ if ( *pCur != 'c' )
+ {
+ int Counter = 0;
+ while ( pCur < pContents + nFileSize && *pCur != 'c' )
+ {
+ // get the terminal type
+ pType = pCur;
+ if ( *pCur == 'i' )
+ vTerms = pNtkNew->vPis;
+ else if ( *pCur == 'l' )
+ vTerms = pNtkNew->vBoxes;
+ else if ( *pCur == 'o' )
+ vTerms = pNtkNew->vPos;
+ else
+ {
+ fprintf( stdout, "Wrong terminal type.\n" );
+ return NULL;
+ }
+ // get the terminal number
+ iTerm = atoi( ++pCur ); while ( *pCur++ != ' ' );
+ // get the node
+ if ( iTerm >= Vec_PtrSize(vTerms) )
+ {
+ fprintf( stdout, "The number of terminal is out of bound.\n" );
+ return NULL;
+ }
+ pObj = Vec_PtrEntry( vTerms, iTerm );
+ if ( *pType == 'l' )
+ pObj = Abc_ObjFanout0(pObj);
+ // assign the name
+ pName = pCur; while ( *pCur++ != '\n' );
+ // assign this name
+ *(pCur-1) = 0;
+ Abc_ObjAssignName( pObj, pName, NULL );
+ if ( *pType == 'l' )
+ {
+ Abc_ObjAssignName( Abc_ObjFanin0(pObj), Abc_ObjName(pObj), "L" );
+ Abc_ObjAssignName( Abc_ObjFanin0(Abc_ObjFanin0(pObj)), Abc_ObjName(pObj), "_in" );
+ }
+ // mark the node as named
+ pObj->pCopy = (Abc_Obj_t *)Abc_ObjName(pObj);
+ }
+
+ // assign the remaining names
+ Abc_NtkForEachPi( pNtkNew, pObj, i )
+ {
+ if ( pObj->pCopy ) continue;
+ Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
+ Counter++;
+ }
+ Abc_NtkForEachLatchOutput( pNtkNew, pObj, i )
+ {
+ if ( pObj->pCopy ) continue;
+ Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
+ Abc_ObjAssignName( Abc_ObjFanin0(pObj), Abc_ObjName(pObj), "L" );
+ Abc_ObjAssignName( Abc_ObjFanin0(Abc_ObjFanin0(pObj)), Abc_ObjName(pObj), "_in" );
+ Counter++;
+ }
+ Abc_NtkForEachPo( pNtkNew, pObj, i )
+ {
+ if ( pObj->pCopy ) continue;
+ Abc_ObjAssignName( pObj, Abc_ObjName(pObj), NULL );
+ Counter++;
+ }
+// if ( Counter )
+// printf( "Io_ReadAiger(): Added %d default names for nameless I/O/register objects.\n", Counter );
+ }
+ else
+ {
+// printf( "Io_ReadAiger(): I/O/register names are not given. Generating short names.\n" );
+ Abc_NtkShortNames( pNtkNew );
+ }
+
+ // read the name of the model if given
+ if ( *pCur == 'c' )
+ {
+ if ( !strncmp( pCur + 2, ".model", 6 ) )
+ {
+ char * pTemp;
+ for ( pTemp = pCur + 9; *pTemp && *pTemp != '\n'; pTemp++ );
+ *pTemp = 0;
+ free( pNtkNew->pName );
+ pNtkNew->pName = Extra_UtilStrsav( pCur + 9 );
+ }
+ }
+
+
+ // skipping the comments
+ free( pContents );
+ Vec_PtrFree( vNodes );
+
+ // remove the extra nodes
+ Abc_AigCleanup( pNtkNew->pManFunc );
+
+ // check the result
+ if ( fCheck && !Abc_NtkCheckRead( pNtkNew ) )
+ {
+ printf( "Io_ReadAiger: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioReadBaf.c b/src/base/io/ioReadBaf.c
new file mode 100644
index 00000000..8dce54af
--- /dev/null
+++ b/src/base/io/ioReadBaf.c
@@ -0,0 +1,171 @@
+/**CFile****************************************************************
+
+ FileName [ioReadBaf.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to read AIG in the binary format.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioReadBaf.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Reads the AIG in the binary format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck )
+{
+ ProgressBar * pProgress;
+ FILE * pFile;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pObj, * pNode0, * pNode1;
+ Abc_Ntk_t * pNtkNew;
+ int nInputs, nOutputs, nLatches, nAnds, nFileSize, Num, i;
+ char * pContents, * pName, * pCur;
+ unsigned * pBufferNode;
+
+ // read the file into the buffer
+ nFileSize = Extra_FileSize( pFileName );
+ pFile = fopen( pFileName, "rb" );
+ pContents = ALLOC( char, nFileSize );
+ fread( pContents, nFileSize, 1, pFile );
+ fclose( pFile );
+
+ // skip the comments (comment lines begin with '#' and end with '\n')
+ for ( pCur = pContents; *pCur == '#'; )
+ while ( *pCur++ != '\n' );
+
+ // read the name
+ pName = pCur; while ( *pCur++ );
+ // read the number of inputs
+ nInputs = atoi( pCur ); while ( *pCur++ );
+ // read the number of outputs
+ nOutputs = atoi( pCur ); while ( *pCur++ );
+ // read the number of latches
+ nLatches = atoi( pCur ); while ( *pCur++ );
+ // read the number of nodes
+ nAnds = atoi( pCur ); while ( *pCur++ );
+
+ // allocate the empty AIG
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
+ pNtkNew->pName = Extra_UtilStrsav( pName );
+ pNtkNew->pSpec = Extra_UtilStrsav( pFileName );
+
+ // prepare the array of nodes
+ vNodes = Vec_PtrAlloc( 1 + nInputs + nLatches + nAnds );
+ Vec_PtrPush( vNodes, Abc_AigConst1(pNtkNew) );
+
+ // create the PIs
+ for ( i = 0; i < nInputs; i++ )
+ {
+ pObj = Abc_NtkCreatePi(pNtkNew);
+ Abc_ObjAssignName( pObj, pCur, NULL ); while ( *pCur++ );
+ Vec_PtrPush( vNodes, pObj );
+ }
+ // create the POs
+ for ( i = 0; i < nOutputs; i++ )
+ {
+ pObj = Abc_NtkCreatePo(pNtkNew);
+ Abc_ObjAssignName( pObj, pCur, NULL ); while ( *pCur++ );
+ }
+ // create the latches
+ for ( i = 0; i < nLatches; i++ )
+ {
+ pObj = Abc_NtkCreateLatch(pNtkNew);
+ Abc_ObjAssignName( pObj, pCur, NULL ); while ( *pCur++ );
+
+ pNode0 = Abc_NtkCreateBi(pNtkNew);
+ Abc_ObjAssignName( pNode0, pCur, NULL ); while ( *pCur++ );
+
+ pNode1 = Abc_NtkCreateBo(pNtkNew);
+ Abc_ObjAssignName( pNode1, pCur, NULL ); while ( *pCur++ );
+ Vec_PtrPush( vNodes, pNode1 );
+
+ Abc_ObjAddFanin( pObj, pNode0 );
+ Abc_ObjAddFanin( pNode1, pObj );
+ }
+
+ // get the pointer to the beginning of the node array
+ pBufferNode = (int *)(pContents + (nFileSize - (2 * nAnds + nOutputs + nLatches) * sizeof(int)) );
+ // make sure we are at the place where the nodes begin
+ if ( pBufferNode != (int *)pCur )
+ {
+ free( pContents );
+ Vec_PtrFree( vNodes );
+ Abc_NtkDelete( pNtkNew );
+ printf( "Warning: Internal reader error.\n" );
+ return NULL;
+ }
+
+ // create the AND gates
+ pProgress = Extra_ProgressBarStart( stdout, nAnds );
+ for ( i = 0; i < nAnds; i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, pBufferNode[2*i+0] >> 1), pBufferNode[2*i+0] & 1 );
+ pNode1 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, pBufferNode[2*i+1] >> 1), pBufferNode[2*i+1] & 1 );
+ Vec_PtrPush( vNodes, Abc_AigAnd(pNtkNew->pManFunc, pNode0, pNode1) );
+ }
+ Extra_ProgressBarStop( pProgress );
+
+ // read the POs
+ Abc_NtkForEachCo( pNtkNew, pObj, i )
+ {
+ Num = pBufferNode[2*nAnds+i];
+ if ( Abc_ObjFanoutNum(pObj) > 0 && Abc_ObjIsLatch(Abc_ObjFanout0(pObj)) )
+ {
+ Abc_ObjSetData( Abc_ObjFanout0(pObj), (void *)(Num & 3) );
+ Num >>= 2;
+ }
+ pNode0 = Abc_ObjNotCond( Vec_PtrEntry(vNodes, Num >> 1), Num & 1 );
+ Abc_ObjAddFanin( pObj, pNode0 );
+ }
+ free( pContents );
+ Vec_PtrFree( vNodes );
+
+ // remove the extra nodes
+// Abc_AigCleanup( pNtkNew->pManFunc );
+
+ // check the result
+ if ( fCheck && !Abc_NtkCheckRead( pNtkNew ) )
+ {
+ printf( "Io_ReadBaf: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioReadBench.c b/src/base/io/ioReadBench.c
index 393b2216..007147bc 100644
--- a/src/base/io/ioReadBench.c
+++ b/src/base/io/ioReadBench.c
@@ -27,7 +27,7 @@
static Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p );
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
@@ -47,7 +47,7 @@ Abc_Ntk_t * Io_ReadBench( char * pFileName, int fCheck )
Abc_Ntk_t * pNtk;
// start the file
- p = Extra_FileReaderAlloc( pFileName, "#", "\n", " \t\r,()=" );
+ p = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t,()=" );
if ( p == NULL )
return NULL;
@@ -66,6 +66,7 @@ Abc_Ntk_t * Io_ReadBench( char * pFileName, int fCheck )
}
return pNtk;
}
+
/**Function*************************************************************
Synopsis []
@@ -82,10 +83,11 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
ProgressBar * pProgress;
Vec_Ptr_t * vTokens;
Abc_Ntk_t * pNtk;
- Abc_Obj_t * pNet, * pNode;
+ Abc_Obj_t * pNode, * pNet;
Vec_Str_t * vString;
- char * pType, ** ppNames;
- int iLine, nNames;
+ unsigned uTruth[8];
+ char * pType, ** ppNames, * pString;
+ int iLine, nNames, nDigits, fLutsPresent = 0;
// allocate the empty network
pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) );
@@ -100,6 +102,7 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
if ( vTokens->nSize == 1 )
{
printf( "%s: Wrong input file format.\n", Extra_FileReaderGetFileName(p) );
+ Vec_StrFree( vString );
Abc_NtkDelete( pNtk );
return NULL;
}
@@ -113,8 +116,90 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
{
// get the node name and the node type
pType = vTokens->pArray[1];
- if ( strcmp(pType, "DFF") == 0 )
- Io_ReadCreateLatch( pNtk, vTokens->pArray[2], vTokens->pArray[0] );
+ if ( strncmp(pType, "DFF", 3) == 0 ) // works for both DFF and DFFRSE
+ {
+ pNode = Io_ReadCreateLatch( pNtk, vTokens->pArray[2], vTokens->pArray[0] );
+// Abc_LatchSetInit0( pNode );
+ if ( pType[3] == '0' )
+ Abc_LatchSetInit0( pNode );
+ else if ( pType[3] == '1' )
+ Abc_LatchSetInit1( pNode );
+ else
+ Abc_LatchSetInitDc( pNode );
+ }
+ else if ( strcmp(pType, "LUT") == 0 )
+ {
+ fLutsPresent = 1;
+ ppNames = (char **)vTokens->pArray + 3;
+ nNames = vTokens->nSize - 3;
+ // check the number of inputs
+ if ( nNames > 8 )
+ {
+ printf( "%s: Currently cannot read truth tables with more than 8 inputs (%d).\n", Extra_FileReaderGetFileName(p), nNames );
+ Vec_StrFree( vString );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ // get the hex string
+ pString = vTokens->pArray[2];
+ if ( strncmp( pString, "0x", 2 ) )
+ {
+ printf( "%s: The LUT signature (%s) does not look like a hexadecimal beginning with \"0x\".\n", Extra_FileReaderGetFileName(p), pString );
+ Vec_StrFree( vString );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ pString += 2;
+ // pad the string with zero's if needed
+ nDigits = (1 << nNames) / 4;
+ if ( nDigits == 0 )
+ nDigits = 1;
+ if ( strlen(pString) < (unsigned)nDigits )
+ {
+ Vec_StrFill( vString, nDigits - strlen(pString), '0' );
+ Vec_StrPrintStr( vString, pString );
+ Vec_StrPush( vString, 0 );
+ pString = Vec_StrArray( vString );
+ }
+ // read the hex number from the string
+ if ( !Extra_ReadHexadecimal( uTruth, pString, nNames ) )
+ {
+ printf( "%s: Reading hexadecimal number (%s) has failed.\n", Extra_FileReaderGetFileName(p), pString );
+ Vec_StrFree( vString );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ // check if the node is a constant node
+ if ( Extra_TruthIsConst0(uTruth, nNames) )
+ {
+ pNode = Io_ReadCreateNode( pNtk, vTokens->pArray[0], ppNames, 0 );
+ Abc_ObjSetData( pNode, Abc_SopRegister( pNtk->pManFunc, " 0\n" ) );
+ }
+ else if ( Extra_TruthIsConst1(uTruth, nNames) )
+ {
+ pNode = Io_ReadCreateNode( pNtk, vTokens->pArray[0], ppNames, 0 );
+ Abc_ObjSetData( pNode, Abc_SopRegister( pNtk->pManFunc, " 1\n" ) );
+ }
+ else
+ {
+ // create the node
+ pNode = Io_ReadCreateNode( pNtk, vTokens->pArray[0], ppNames, nNames );
+ assert( nNames > 0 );
+ if ( nNames > 1 )
+ Abc_ObjSetData( pNode, Abc_SopCreateFromTruth(pNtk->pManFunc, nNames, uTruth) );
+ else if ( pString[0] == '2' )
+ Abc_ObjSetData( pNode, Abc_SopCreateBuf(pNtk->pManFunc) );
+ else if ( pString[0] == '1' )
+ Abc_ObjSetData( pNode, Abc_SopCreateInv(pNtk->pManFunc) );
+ else
+ {
+ printf( "%s: Reading truth table (%s) of single-input node has failed.\n", Extra_FileReaderGetFileName(p), pString );
+ Vec_StrFree( vString );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ }
+ }
else
{
// create a new node and add it to the network
@@ -123,7 +208,7 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
pNode = Io_ReadCreateNode( pNtk, vTokens->pArray[0], ppNames, nNames );
// assign the cover
if ( strcmp(pType, "AND") == 0 )
- Abc_ObjSetData( pNode, Abc_SopCreateAnd(pNtk->pManFunc, nNames) );
+ Abc_ObjSetData( pNode, Abc_SopCreateAnd(pNtk->pManFunc, nNames, NULL) );
else if ( strcmp(pType, "OR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateOr(pNtk->pManFunc, nNames, NULL) );
else if ( strcmp(pType, "NAND") == 0 )
@@ -132,15 +217,22 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
Abc_ObjSetData( pNode, Abc_SopCreateNor(pNtk->pManFunc, nNames) );
else if ( strcmp(pType, "XOR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateXor(pNtk->pManFunc, nNames) );
- else if ( strcmp(pType, "NXOR") == 0 )
+ else if ( strcmp(pType, "NXOR") == 0 || strcmp(pType, "XNOR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateNxor(pNtk->pManFunc, nNames) );
else if ( strncmp(pType, "BUF", 3) == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateBuf(pNtk->pManFunc) );
else if ( strcmp(pType, "NOT") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateInv(pNtk->pManFunc) );
- else
+ else if ( strncmp(pType, "MUX", 3) == 0 )
+ Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "1-0 1\n-11 1\n") );
+ else if ( strncmp(pType, "gnd", 3) == 0 )
+ Abc_ObjSetData( pNode, Abc_SopRegister( pNtk->pManFunc, " 0\n" ) );
+ else if ( strncmp(pType, "vdd", 3) == 0 )
+ Abc_ObjSetData( pNode, Abc_SopRegister( pNtk->pManFunc, " 1\n" ) );
+ else
{
- printf( "Cannot determine gate type \"%s\" in line %d.\n", pType, Extra_FileReaderGetLineNumber(p, 0) );
+ printf( "Io_ReadBenchNetwork(): Cannot determine gate type \"%s\" in line %d.\n", pType, Extra_FileReaderGetLineNumber(p, 0) );
+ Vec_StrFree( vString );
Abc_NtkDelete( pNtk );
return NULL;
}
@@ -150,17 +242,116 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
Extra_ProgressBarStop( pProgress );
Vec_StrFree( vString );
- // check if constant have been added
- if ( pNet = Abc_NtkFindNet( pNtk, "vdd" ) )
- Io_ReadCreateConst( pNtk, "vdd", 1 );
- if ( pNet = Abc_NtkFindNet( pNtk, "gnd" ) )
- Io_ReadCreateConst( pNtk, "gnd", 0 );
+ // check if constant 0 is present
+ if ( (pNet = Abc_NtkFindNet( pNtk, "gnd" )) )
+ {
+ if ( Abc_ObjFaninNum(pNet) == 0 )
+ Io_ReadCreateConst( pNtk, "gnd", 0 );
+ }
+ if ( (pNet = Abc_NtkFindNet( pNtk, "1" )) )
+ {
+ if ( Abc_ObjFaninNum(pNet) == 0 )
+ {
+ printf( "Io_ReadBenchNetwork(): Adding constant 0 fanin to non-driven net \"1\".\n" );
+ Io_ReadCreateConst( pNtk, "1", 0 );
+ }
+ }
+ // check if constant 1 is present
+ if ( (pNet = Abc_NtkFindNet( pNtk, "vdd" )) )
+ {
+ if ( Abc_ObjFaninNum(pNet) == 0 )
+ Io_ReadCreateConst( pNtk, "vdd", 1 );
+ }
+ if ( (pNet = Abc_NtkFindNet( pNtk, "2" )) )
+ {
+ if ( Abc_ObjFaninNum(pNet) == 0 )
+ {
+ printf( "Io_ReadBenchNetwork(): Adding constant 1 fanin to non-driven net \"2\".\n" );
+ Io_ReadCreateConst( pNtk, "2", 1 );
+ }
+ }
Abc_NtkFinalizeRead( pNtk );
+
+ // if LUTs are present, collapse the truth tables into cubes
+ if ( fLutsPresent )
+ {
+ if ( !Abc_NtkToBdd(pNtk) )
+ {
+ printf( "Io_ReadBenchNetwork(): Converting to BDD has failed.\n" );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ if ( !Abc_NtkToSop(pNtk, 0) )
+ {
+ printf( "Io_ReadBenchNetwork(): Converting to SOP has failed.\n" );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ }
return pNtk;
}
+/**Function*************************************************************
+
+ Synopsis [Reads initial state in BENCH format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadBenchInit( Abc_Ntk_t * pNtk, char * pFileName )
+{
+ char pBuffer[1000];
+ FILE * pFile;
+ char * pToken;
+ Abc_Obj_t * pObj;
+ int Num;
+ pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ printf( "Io_ReadBenchInit(): Failed to open file \"%s\".\n", pFileName );
+ return;
+ }
+ while ( fgets( pBuffer, 999, pFile ) )
+ {
+ pToken = strtok( pBuffer, " \n\t\r" );
+ // find the latch output
+ Num = Nm_ManFindIdByName( pNtk->pManName, pToken, ABC_OBJ_BO );
+ if ( Num < 0 )
+ {
+ printf( "Io_ReadBenchInit(): Cannot find register with output %s.\n", pToken );
+ continue;
+ }
+ pObj = Abc_ObjFanin0( Abc_NtkObj( pNtk, Num ) );
+ if ( !Abc_ObjIsLatch(pObj) )
+ {
+ printf( "Io_ReadBenchInit(): The signal is not a register output %s.\n", pToken );
+ continue;
+ }
+ // assign the new init state
+ pToken = strtok( NULL, " \n\t\r" );
+ if ( pToken[0] == '0' )
+ Abc_LatchSetInit0( pObj );
+ else if ( pToken[0] == '1' )
+ Abc_LatchSetInit1( pObj );
+ else if ( pToken[0] == '2' )
+ Abc_LatchSetInitDc( pObj );
+ else
+ {
+ printf( "Io_ReadBenchInit(): The signal %s has unknown initial value (%s).\n",
+ Abc_ObjName(Abc_ObjFanout0(pObj)), pToken );
+ continue;
+ }
+ }
+ fclose( pFile );
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c
index 946de42b..d0750178 100644
--- a/src/base/io/ioReadBlif.c
+++ b/src/base/io/ioReadBlif.c
@@ -33,42 +33,47 @@ struct Io_ReadBlif_t_
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
+ Abc_Ntk_t * pNtkMaster; // the primary network
+ Abc_Ntk_t * pNtkCur; // the primary network
int LineCur; // the line currently parsed
// temporary storage for tokens
+ Vec_Ptr_t * vTokens; // the current 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
+ int fError; // set to 1 when error occurs
};
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 char * Io_ReadBlifCleanName( char * pName );
+static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p );
+static Abc_Ntk_t * Io_ReadBlifNetworkOne( 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_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens );
static int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
+static int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
+static int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster );
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
- Synopsis [Reads the network from a BLIF file.]
+ Synopsis [Reads the (hierarchical) network from the BLIF file.]
- Description [Works only for flat (non-hierarchical) BLIF.]
+ Description []
SideEffects []
@@ -78,34 +83,22 @@ static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t *
Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
{
Io_ReadBlif_t * p;
- Abc_Ntk_t * pNtk, * pNtkExdc;
+ Abc_Ntk_t * pNtk;
// start the file
p = Io_ReadBlifFile( pFileName );
if ( p == NULL )
return NULL;
- // read the network
+ // read the hierarchical network
pNtk = Io_ReadBlifNetwork( p );
if ( pNtk == NULL )
{
Io_ReadBlifFree( p );
return NULL;
}
+ pNtk->pSpec = Extra_UtilStrsav( pFileName );
Abc_NtkTimeInitialize( 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
@@ -120,7 +113,7 @@ Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
/**Function*************************************************************
- Synopsis [Starts the reading data structure.]
+ Synopsis [Iteratively reads several networks in the hierarchical design.]
Description []
@@ -129,140 +122,80 @@ Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
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 )
+Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
{
- Vec_Ptr_t * vTokens;
- char * pLastToken;
- int i;
+ Abc_Ntk_t * pNtk, * pNtkMaster;
- // get rid of the old tokens
- if ( p->vNewTokens->nSize > 0 )
+ // read the name of the master network
+ p->vTokens = Io_ReadBlifGetTokens(p);
+ if ( p->vTokens == NULL || strcmp( p->vTokens->pArray[0], ".model" ) )
{
- for ( i = 0; i < p->vNewTokens->nSize; i++ )
- free( p->vNewTokens->pArray[i] );
- p->vNewTokens->nSize = 0;
+ p->LineCur = 0;
+ sprintf( p->sError, "Wrong input file format." );
+ Io_ReadBlifPrintErrorMessage( p );
+ return NULL;
}
- // 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 )
+ // read networks (with EXDC)
+ pNtkMaster = NULL;
+ while ( p->vTokens )
{
- // 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 ] == '\\' )
+ // read the network and its EXDC if present
+ pNtk = Io_ReadBlifNetworkOne( p );
+ if ( pNtk == NULL )
+ break;
+ if ( p->vTokens && strcmp(p->vTokens->pArray[0], ".exdc") == 0 )
{
- // 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]) );
+ pNtk->pExdc = Io_ReadBlifNetworkOne( p );
+ Abc_NtkFinalizeRead( pNtk->pExdc );
+ if ( pNtk->pExdc == NULL )
+ break;
+ }
+ // add this network as part of the hierarchy
+ if ( pNtkMaster == NULL ) // no master network so far
+ {
+ p->pNtkMaster = pNtkMaster = pNtk;
continue;
}
- // otherwise, load them and break
- for ( i = 0; i < vTokens->nSize; i++ )
- Vec_PtrPush( p->vNewTokens, util_strsav(vTokens->pArray[i]) );
- break;
+/*
+ // make sure hierarchy does not have the network with this name
+ if ( pNtkMaster->tName2Model && stmm_is_member( pNtkMaster->tName2Model, pNtk->pName ) )
+ {
+ p->LineCur = 0;
+ sprintf( p->sError, "Model %s is multiply defined in the file.", pNtk->pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ Abc_NtkDelete( pNtk );
+ Abc_NtkDelete( pNtkMaster );
+ pNtkMaster = NULL;
+ return NULL;
+ }
+ // add the network to the hierarchy
+ if ( pNtkMaster->tName2Model == NULL )
+ pNtkMaster->tName2Model = stmm_init_table(strcmp, stmm_strhash);
+ stmm_insert( pNtkMaster->tName2Model, pNtk->pName, (char *)pNtk );
+*/
}
- return p->vNewTokens;
+/*
+ // if there is a hierarchy, connect the boxes
+ if ( pNtkMaster && pNtkMaster->tName2Model )
+ {
+ if ( Io_ReadBlifNetworkConnectBoxes( p, pNtkMaster ) )
+ {
+ Abc_NtkDelete( pNtkMaster );
+ return NULL;
+ }
+ }
+ else
+*/
+ if ( !p->fError )
+ Abc_NtkFinalizeRead( pNtkMaster );
+ // return the master network
+ return pNtkMaster;
}
-
/**Function*************************************************************
- Synopsis [Reads the BLIF file.]
+ Synopsis [Reads one (main or exdc) network from the BLIF file.]
Description []
@@ -271,74 +204,89 @@ Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p )
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
+Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
{
ProgressBar * pProgress;
- Vec_Ptr_t * vTokens;
- char * pModelName, * pDirective;
+ Abc_Ntk_t * pNtk;
+ char * pDirective;
int iLine, fTokensReady, fStatus;
+ // make sure the tokens are present
+ assert( p->vTokens != NULL );
+
+ // create the new network
+ p->pNtkCur = pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 );
// read the model name
- if ( !p->fParsingExdc )
+ if ( strcmp( p->vTokens->pArray[0], ".model" ) == 0 )
+ pNtk->pName = Extra_UtilStrsav( p->vTokens->pArray[1] );
+ else if ( strcmp( p->vTokens->pArray[0], ".exdc" ) != 0 )
{
- // 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_TYPE_NETLIST, ABC_FUNC_SOP );
- p->pNtk->pName = util_strsav( pModelName );
- p->pNtk->pSpec = util_strsav( p->pFileName );
+ printf( "%s: File parsing skipped after line %d (\"%s\").\n", p->pFileName,
+ Extra_FileReaderGetLineNumber(p->pReader, 0), p->vTokens->pArray[0] );
+ Abc_NtkDelete(pNtk);
+ p->pNtkCur = NULL;
+ return NULL;
}
- else
- p->pNtk = Abc_NtkAlloc( ABC_TYPE_NETLIST, ABC_FUNC_SOP );
// read the inputs/outputs
+ if ( p->pNtkMaster == NULL )
pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
fTokensReady = fStatus = 0;
- for ( iLine = 0; fTokensReady || (vTokens = Io_ReadBlifGetTokens(p)); iLine++ )
+ for ( iLine = 0; fTokensReady || (p->vTokens = Io_ReadBlifGetTokens(p)); iLine++ )
{
- if ( iLine % 1000 == 0 )
+ if ( p->pNtkMaster == NULL && iLine % 1000 == 0 )
Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL );
// consider different line types
fTokensReady = 0;
- pDirective = vTokens->pArray[0];
+ pDirective = p->vTokens->pArray[0];
if ( !strcmp( pDirective, ".names" ) )
- { fStatus = Io_ReadBlifNetworkNames( p, &vTokens ); fTokensReady = 1; }
+ { fStatus = Io_ReadBlifNetworkNames( p, &p->vTokens ); fTokensReady = 1; }
else if ( !strcmp( pDirective, ".gate" ) )
- fStatus = Io_ReadBlifNetworkGate( p, vTokens );
+ fStatus = Io_ReadBlifNetworkGate( p, p->vTokens );
else if ( !strcmp( pDirective, ".latch" ) )
- fStatus = Io_ReadBlifNetworkLatch( p, vTokens );
+ fStatus = Io_ReadBlifNetworkLatch( p, p->vTokens );
else if ( !strcmp( pDirective, ".inputs" ) )
- fStatus = Io_ReadBlifNetworkInputs( p, vTokens );
+ fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens );
else if ( !strcmp( pDirective, ".outputs" ) )
- fStatus = Io_ReadBlifNetworkOutputs( p, vTokens );
+ fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens );
+ else if ( !strcmp( pDirective, ".asserts" ) )
+ fStatus = Io_ReadBlifNetworkAsserts( p, p->vTokens );
else if ( !strcmp( pDirective, ".input_arrival" ) )
- fStatus = Io_ReadBlifNetworkInputArrival( p, vTokens );
+ fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens );
else if ( !strcmp( pDirective, ".default_input_arrival" ) )
- fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, vTokens );
+ fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens );
+// else if ( !strcmp( pDirective, ".subckt" ) )
+// fStatus = Io_ReadBlifNetworkSubcircuit( p, p->vTokens );
else if ( !strcmp( pDirective, ".exdc" ) )
- { p->fParsingExdc = 1; break; }
+ break;
else if ( !strcmp( pDirective, ".end" ) )
+ {
+ p->vTokens = Io_ReadBlifGetTokens(p);
break;
+ }
+ else if ( !strcmp( pDirective, ".blackbox" ) )
+ {
+ pNtk->ntkType = ABC_NTK_NETLIST;
+ pNtk->ntkFunc = ABC_FUNC_BLACKBOX;
+ Extra_MmFlexStop( pNtk->pManFunc );
+ pNtk->pManFunc = NULL;
+ }
else
printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName,
Extra_FileReaderGetLineNumber(p->pReader, 0), pDirective );
- if ( vTokens == NULL ) // some files do not have ".end" in the end
+ if ( p->vTokens == NULL ) // some files do not have ".end" in the end
break;
if ( fStatus == 1 )
+ {
+ Extra_ProgressBarStop( pProgress );
+ Abc_NtkDelete( pNtk );
return NULL;
+ }
}
+ if ( p->pNtkMaster == NULL )
Extra_ProgressBarStop( pProgress );
- Abc_NtkFinalizeRead( p->pNtk );
- return p->pNtk;
+ return pNtk;
}
/**Function*************************************************************
@@ -356,7 +304,7 @@ int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
int i;
for ( i = 1; i < vTokens->nSize; i++ )
- Io_ReadCreatePi( p->pNtk, vTokens->pArray[i] );
+ Io_ReadCreatePi( p->pNtkCur, vTokens->pArray[i] );
return 0;
}
@@ -375,7 +323,7 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
int i;
for ( i = 1; i < vTokens->nSize; i++ )
- Io_ReadCreatePo( p->pNtk, vTokens->pArray[i] );
+ Io_ReadCreatePo( p->pNtkCur, vTokens->pArray[i] );
return 0;
}
@@ -390,12 +338,30 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
SeeAlso []
***********************************************************************/
-int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
+int Io_ReadBlifNetworkAsserts( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
- Abc_Ntk_t * pNtk = p->pNtk;
+ int i;
+ for ( i = 1; i < vTokens->nSize; i++ )
+ Io_ReadCreateAssert( p->pNtkCur, vTokens->pArray[i] );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
+{
+ Abc_Ntk_t * pNtk = p->pNtkCur;
Abc_Obj_t * pLatch;
int ResetValue;
-
if ( vTokens->nSize < 3 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
@@ -407,10 +373,10 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
pLatch = Io_ReadCreateLatch( pNtk, vTokens->pArray[1], vTokens->pArray[2] );
// get the latch reset value
if ( vTokens->nSize == 3 )
- ResetValue = 2;
+ Abc_LatchSetInitDc( pLatch );
else
{
- ResetValue = atoi(vTokens->pArray[3]);
+ ResetValue = atoi(vTokens->pArray[vTokens->nSize-1]);
if ( ResetValue != 0 && ResetValue != 1 && ResetValue != 2 )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
@@ -418,8 +384,13 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
+ if ( ResetValue == 0 )
+ Abc_LatchSetInit0( pLatch );
+ else if ( ResetValue == 1 )
+ Abc_LatchSetInit1( pLatch );
+ else if ( ResetValue == 2 )
+ Abc_LatchSetInitDc( pLatch );
}
- Abc_ObjSetData( pLatch, (void *)ResetValue );
return 0;
}
@@ -437,7 +408,7 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
{
Vec_Ptr_t * vTokens = *pvTokens;
- Abc_Ntk_t * pNtk = p->pNtk;
+ Abc_Ntk_t * pNtk = p->pNtkCur;
Abc_Obj_t * pNode;
char * pToken, Char, ** ppNames;
int nFanins, nNames;
@@ -500,7 +471,7 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
Vec_StrAppend( p->vCubes, vTokens->pArray[0] );
// check the char
Char = ((char *)vTokens->pArray[1])[0];
- if ( Char != '0' && Char != '1' )
+ if ( Char != '0' && Char != '1' && Char != 'x' && Char != 'n' )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
sprintf( p->sError, "The output character in the constant cube is wrong." );
@@ -525,6 +496,16 @@ int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
// set the pointer to the functionality of the node
Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, p->vCubes->pArray) );
+ // check the size
+ if ( Abc_ObjFaninNum(pNode) != Abc_SopGetVarNum(Abc_ObjData(pNode)) )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "The number of fanins (%d) of node %s is different from SOP size (%d).",
+ Abc_ObjFaninNum(pNode), Abc_ObjName(Abc_ObjFanout(pNode,0)), Abc_SopGetVarNum(Abc_ObjData(pNode)) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+
// return the last array of tokens
*pvTokens = vTokens;
return 0;
@@ -550,7 +531,7 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
int i, nNames;
// check that the library is available
- pGenlib = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame());
+ pGenlib = Abc_FrameReadLibGen();
if ( pGenlib == NULL )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
@@ -579,12 +560,12 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
}
// if this is the first line with gate, update the network type
- if ( Abc_NtkNodeNum(p->pNtk) == 0 )
+ if ( Abc_NtkNodeNum(p->pNtkCur) == 0 )
{
- assert( p->pNtk->ntkFunc == ABC_FUNC_SOP );
- p->pNtk->ntkFunc = ABC_FUNC_MAP;
- Extra_MmFlexStop( p->pNtk->pManFunc, 0 );
- p->pNtk->pManFunc = pGenlib;
+ assert( p->pNtkCur->ntkFunc == ABC_FUNC_SOP );
+ p->pNtkCur->ntkFunc = ABC_FUNC_MAP;
+ Extra_MmFlexStop( p->pNtkCur->pManFunc );
+ p->pNtkCur->pManFunc = pGenlib;
}
// remove the formal parameter names
@@ -603,13 +584,54 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
// create the node
ppNames = (char **)vTokens->pArray + 2;
nNames = vTokens->nSize - 3;
- pNode = Io_ReadCreateNode( p->pNtk, ppNames[nNames], ppNames, nNames );
+ pNode = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames], ppNames, nNames );
// set the pointer to the functionality of the node
Abc_ObjSetData( pNode, pGate );
return 0;
}
+/**Function*************************************************************
+
+ Synopsis [Creates a multi-input multi-output box in the hierarchical design.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
+{
+ Abc_Obj_t * pBox;
+ Vec_Ptr_t * vNames;
+ char * pName;
+ int i;
+
+ // create a new node and add it to the network
+ if ( vTokens->nSize < 3 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "The .subcircuit line has less than three tokens." );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+
+ // store the names of formal/actual inputs/outputs of the box
+ vNames = Vec_PtrAlloc( 10 );
+ Vec_PtrForEachEntryStart( vTokens, pName, i, 1 )
+// Vec_PtrPush( vNames, Abc_NtkRegisterName(p->pNtkCur, pName) );
+ Vec_PtrPush( vNames, Extra_UtilStrsav(pName) ); // memory leak!!!
+
+ // create a new box and add it to the network
+ pBox = Abc_NtkCreateBlackbox( p->pNtkCur );
+ // set the pointer to the node names
+ Abc_ObjSetData( pBox, vNames );
+ // remember the line of the file
+ pBox->pCopy = (void *)Extra_FileReaderGetLineNumber(p->pReader, 0);
+ return 0;
+}
/**Function*************************************************************
@@ -658,7 +680,7 @@ int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
- pNet = Abc_NtkFindNet( p->pNtk, vTokens->pArray[1] );
+ pNet = Abc_NtkFindNet( p->pNtkCur, vTokens->pArray[1] );
if ( pNet == NULL )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
@@ -676,7 +698,7 @@ int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
return 1;
}
// set the arrival time
- Abc_NtkTimeSetArrival( p->pNtk, pNet->Id, (float)TimeRise, (float)TimeFall );
+ Abc_NtkTimeSetArrival( p->pNtkCur, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall );
return 0;
}
@@ -715,10 +737,366 @@ int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vToken
return 1;
}
// set the arrival time
- Abc_NtkTimeSetDefaultArrival( p->pNtk, (float)TimeRise, (float)TimeFall );
+ Abc_NtkTimeSetDefaultArrival( p->pNtkCur, (float)TimeRise, (float)TimeFall );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the error message including the file name and line number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p )
+{
+ p->fError = 1;
+ 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, Extra_UtilStrsav(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, Extra_UtilStrsav(vTokens->pArray[i]) );
+ continue;
+ }
+ // otherwise, load them and break
+ for ( i = 0; i < vTokens->nSize; i++ )
+ Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
+ break;
+ }
+ return p->vNewTokens;
+}
+
+/**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\r", " \t" );
+
+ 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 [Connect one box.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, stmm_table * tName2Model )
+{
+ Vec_Ptr_t * pNames;
+ Abc_Ntk_t * pNtkModel;
+ Abc_Obj_t * pObj, * pNet;
+ char * pName, * pActual;
+ int i, Length, Start;
+
+ // get the model for this box
+ pNames = pBox->pData;
+ if ( !stmm_lookup( tName2Model, Vec_PtrEntry(pNames, 0), (char **)&pNtkModel ) )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot find the model for subcircuit %s.", Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+
+ // create the fanins of the box
+ Abc_NtkForEachPi( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+ if ( Abc_NtkPiNum(pNtkModel) == 0 )
+ Start = 1;
+ else
+ {
+ Vec_PtrForEachEntryStart( pNames, pName, i, 1 )
+ {
+ pActual = Io_ReadBlifCleanName(pName);
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ Length = pActual - pName - 1;
+ pName[Length] = 0;
+ // find the PI net with this name
+ pObj = Abc_NtkFindNet( pNtkModel, pName );
+ if ( pObj == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // get the PI
+ pObj = Abc_ObjFanin0(pObj);
+ // quit if this is not a PI net
+ if ( !Abc_ObjIsPi(pObj) )
+ {
+ pName[Length] = '=';
+ Start = i;
+ break;
+ }
+ // remember the actual name in the net
+ if ( pObj->pCopy != NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pObj->pCopy = (void *)pActual;
+ // quit if we processed all PIs
+ if ( i == Abc_NtkPiNum(pNtkModel) )
+ {
+ Start = i+1;
+ break;
+ }
+ }
+ }
+ // create the fanins of the box
+ Abc_NtkForEachPi( pNtkModel, pObj, i )
+ {
+ pActual = (void *)pObj->pCopy;
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal input \"%s\" of model %s is not driven.", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual );
+ Abc_ObjAddFanin( pBox, pNet );
+ }
+ Abc_NtkForEachPi( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+
+ // create the fanouts of the box
+ Abc_NtkForEachPo( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+ Vec_PtrForEachEntryStart( pNames, pName, i, Start )
+ {
+ pActual = Io_ReadBlifCleanName(pName);
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ Length = pActual - pName - 1;
+ pName[Length] = 0;
+ // find the PO net with this name
+ pObj = Abc_NtkFindNet( pNtkModel, pName );
+ if ( pObj == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot find formal output \"%s\" as an PO of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // get the PO
+ pObj = Abc_ObjFanout0(pObj);
+ if ( pObj->pCopy != NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal output \"%s\" is used more than once.", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pObj->pCopy = (void *)pActual;
+ }
+ // create the fanouts of the box
+ Abc_NtkForEachPo( pNtkModel, pObj, i )
+ {
+ pActual = (void *)pObj->pCopy;
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal output \"%s\" of model %s is not driven.", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual );
+ Abc_ObjAddFanin( pNet, pBox );
+ }
+ Abc_NtkForEachPo( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+
+ // remove the array of names, assign the pointer to the model
+ Vec_PtrForEachEntry( pBox->pData, pName, i )
+ free( pName );
+ Vec_PtrFree( pBox->pData );
+ pBox->pData = pNtkModel;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Connect the boxes in the hierarchy of networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkConnectBoxesOne( Io_ReadBlif_t * p, Abc_Ntk_t * pNtk, stmm_table * tName2Model )
+{
+ Abc_Obj_t * pBox;
+ int i;
+ // go through the boxes
+ Abc_NtkForEachBlackbox( pNtk, pBox, i )
+ if ( Io_ReadBlifNetworkConnectBoxesOneBox( p, pBox, tName2Model ) )
+ return 1;
+ Abc_NtkFinalizeRead( pNtk );
+ return 0;
+}
+
+#if 0
+
+/**Function*************************************************************
+
+ Synopsis [Connect the boxes in the hierarchy of networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster )
+{
+ stmm_generator * gen;
+ Abc_Ntk_t * pNtk;
+ char * pName;
+ // connect the master network
+ if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtkMaster, pNtkMaster->tName2Model ) )
+ return 1;
+ // connect other networks
+ stmm_foreach_item( pNtkMaster->tName2Model, gen, &pName, (char **)&pNtk )
+ if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtk, pNtkMaster->tName2Model ) )
+ return 1;
return 0;
}
+#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/base/io/ioReadBlifAig.c b/src/base/io/ioReadBlifAig.c
new file mode 100644
index 00000000..c448bab6
--- /dev/null
+++ b/src/base/io/ioReadBlifAig.c
@@ -0,0 +1,1013 @@
+/**CFile****************************************************************
+
+ FileName [ioReadBlifAig.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to read BLIF file into AIG.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - December 23, 2006.]
+
+ Revision [$Id: ioReadBlifAig.c,v 1.00 2006/12/23 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "extra.h"
+#include "vecPtr.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// latch initial values
+typedef enum {
+ IO_BLIF_INIT_NONE = 0, // 0: unknown
+ IO_BLIF_INIT_ZERO, // 1: zero
+ IO_BLIF_INIT_ONE, // 2: one
+ IO_BLIF_INIT_DC // 3: don't-care
+} Io_BlifInit_t;
+
+typedef struct Io_BlifObj_t_ Io_BlifObj_t; // parsing object
+struct Io_BlifObj_t_
+{
+ unsigned fPi : 1; // the object is a primary input
+ unsigned fPo : 1; // the object is a primary output
+ unsigned fLi : 1; // the object is a latch input
+ unsigned fLo : 1; // the object is a latch output
+ unsigned fDef : 1; // the object is defined as a table (node, PO, LI)
+ unsigned fLoop : 1; // flag for loop detection
+ unsigned Init : 2; // the latch initial state
+ unsigned Offset : 24; // temporary number
+ char * pName; // the name of this object
+ void * pEquiv; // the AIG node representing this line
+ Io_BlifObj_t * pNext; // the next obj in the hash table
+};
+
+typedef struct Io_BlifMan_t_ Io_BlifMan_t; // parsing manager
+struct Io_BlifMan_t_
+{
+ // general info about file
+ char * pFileName; // the name of the file
+ char * pBuffer; // the begining of the file buffer
+ Vec_Ptr_t * vLines; // the line beginnings
+ // temporary objects
+ Io_BlifObj_t * pObjects; // the storage for objects
+ int nObjects; // the number of objects allocated
+ int iObjNext; // the next free object
+ // file lines
+ char * pModel; // .model line
+ Vec_Ptr_t * vInputs; // .inputs lines
+ Vec_Ptr_t * vOutputs; // .outputs lines
+ Vec_Ptr_t * vLatches; // .latches lines
+ Vec_Ptr_t * vNames; // .names lines
+ // network objects
+ Vec_Ptr_t * vPis; // the PI structures
+ Vec_Ptr_t * vPos; // the PO structures
+ Vec_Ptr_t * vLis; // the LI structures
+ Vec_Ptr_t * vLos; // the LO structures
+ // mapping of names into objects
+ Io_BlifObj_t ** pTable; // the hash table
+ int nTableSize; // the hash table size
+ // current processing info
+ Abc_Ntk_t * pAig; // the network under construction
+ Vec_Ptr_t * vTokens; // the current tokens
+ char sError[512]; // the error string generated during parsing
+ // statistics
+ int nTablesRead; // the number of processed tables
+ int nTablesLeft; // the number of dangling tables
+};
+
+// static functions
+static Io_BlifMan_t * Io_BlifAlloc();
+static void Io_BlifFree( Io_BlifMan_t * p );
+static char * Io_BlifLoadFile( char * pFileName );
+static void Io_BlifReadPreparse( Io_BlifMan_t * p );
+static Abc_Ntk_t * Io_BlifParse( Io_BlifMan_t * p );
+static int Io_BlifParseModel( Io_BlifMan_t * p, char * pLine );
+static int Io_BlifParseInputs( Io_BlifMan_t * p, char * pLine );
+static int Io_BlifParseOutputs( Io_BlifMan_t * p, char * pLine );
+static int Io_BlifParseLatch( Io_BlifMan_t * p, char * pLine );
+static int Io_BlifParseNames( Io_BlifMan_t * p, char * pLine );
+static int Io_BlifParseConstruct( Io_BlifMan_t * p );
+static int Io_BlifCharIsSpace( char s ) { return s == ' ' || s == '\t' || s == '\r' || s == '\n'; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Reads the network from the BLIF file as an AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadBlifAsAig( char * pFileName, int fCheck )
+{
+ FILE * pFile;
+ Io_BlifMan_t * p;
+ Abc_Ntk_t * pAig;
+
+ // check that the file is available
+ pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Io_Blif(): The file is unavailable (absent or open).\n" );
+ return 0;
+ }
+ fclose( pFile );
+
+ // start the file reader
+ p = Io_BlifAlloc();
+ p->pFileName = pFileName;
+ p->pBuffer = Io_BlifLoadFile( pFileName );
+ if ( p->pBuffer == NULL )
+ {
+ Io_BlifFree( p );
+ return NULL;
+ }
+ // prepare the file for parsing
+ Io_BlifReadPreparse( p );
+ // construct the network
+ pAig = Io_BlifParse( p );
+ if ( p->sError[0] )
+ fprintf( stdout, "%s\n", p->sError );
+ if ( pAig == NULL )
+ return NULL;
+ Io_BlifFree( p );
+
+ // make sure that everything is okay with the network structure
+ if ( fCheck && !Abc_NtkCheckRead( pAig ) )
+ {
+ printf( "Io_Blif: The network check has failed.\n" );
+ Abc_NtkDelete( pAig );
+ return NULL;
+ }
+ return pAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates the BLIF parsing structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Io_BlifMan_t * Io_BlifAlloc()
+{
+ Io_BlifMan_t * p;
+ p = ALLOC( Io_BlifMan_t, 1 );
+ memset( p, 0, sizeof(Io_BlifMan_t) );
+ p->vLines = Vec_PtrAlloc( 512 );
+ p->vInputs = Vec_PtrAlloc( 512 );
+ p->vOutputs = Vec_PtrAlloc( 512 );
+ p->vLatches = Vec_PtrAlloc( 512 );
+ p->vNames = Vec_PtrAlloc( 512 );
+ p->vTokens = Vec_PtrAlloc( 512 );
+ p->vPis = Vec_PtrAlloc( 512 );
+ p->vPos = Vec_PtrAlloc( 512 );
+ p->vLis = Vec_PtrAlloc( 512 );
+ p->vLos = Vec_PtrAlloc( 512 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the BLIF parsing structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_BlifFree( Io_BlifMan_t * p )
+{
+ if ( p->pAig )
+ Abc_NtkDelete( p->pAig );
+ if ( p->pBuffer ) free( p->pBuffer );
+ if ( p->pObjects ) free( p->pObjects );
+ if ( p->pTable ) free( p->pTable );
+ Vec_PtrFree( p->vLines );
+ Vec_PtrFree( p->vInputs );
+ Vec_PtrFree( p->vOutputs );
+ Vec_PtrFree( p->vLatches );
+ Vec_PtrFree( p->vNames );
+ Vec_PtrFree( p->vTokens );
+ Vec_PtrFree( p->vPis );
+ Vec_PtrFree( p->vPos );
+ Vec_PtrFree( p->vLis );
+ Vec_PtrFree( p->vLos );
+ free( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Hashing for character strings.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static unsigned Io_BlifHashString( char * pName, int TableSize )
+{
+ static int s_Primes[10] = {
+ 1291, 1699, 2357, 4177, 5147,
+ 5647, 6343, 7103, 7873, 8147
+ };
+ unsigned i, Key = 0;
+ for ( i = 0; pName[i] != '\0'; i++ )
+ Key ^= s_Primes[i%10]*pName[i]*pName[i];
+ return Key % TableSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks if the given name exists in the table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Io_BlifObj_t ** Io_BlifHashLookup( Io_BlifMan_t * p, char * pName )
+{
+ Io_BlifObj_t ** ppEntry;
+ for ( ppEntry = p->pTable + Io_BlifHashString(pName, p->nTableSize); *ppEntry; ppEntry = &(*ppEntry)->pNext )
+ if ( !strcmp((*ppEntry)->pName, pName) )
+ return ppEntry;
+ return ppEntry;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds or add the given name to the table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Io_BlifObj_t * Io_BlifHashFindOrAdd( Io_BlifMan_t * p, char * pName )
+{
+ Io_BlifObj_t ** ppEntry;
+ ppEntry = Io_BlifHashLookup( p, pName );
+ if ( *ppEntry == NULL )
+ {
+ assert( p->iObjNext < p->nObjects );
+ *ppEntry = p->pObjects + p->iObjNext++;
+ (*ppEntry)->pName = pName;
+ }
+ return *ppEntry;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collects the already split tokens.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_BlifCollectTokens( Vec_Ptr_t * vTokens, char * pInput, char * pOutput )
+{
+ char * pCur;
+ Vec_PtrClear( vTokens );
+ for ( pCur = pInput; pCur < pOutput; pCur++ )
+ {
+ if ( *pCur == 0 )
+ continue;
+ Vec_PtrPush( vTokens, pCur );
+ while ( *++pCur );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Splits the line into tokens.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_BlifSplitIntoTokens( Vec_Ptr_t * vTokens, char * pLine, char Stop )
+{
+ char * pCur;
+ // clear spaces
+ for ( pCur = pLine; *pCur != Stop; pCur++ )
+ if ( Io_BlifCharIsSpace(*pCur) )
+ *pCur = 0;
+ // collect tokens
+ Io_BlifCollectTokens( vTokens, pLine, pCur );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the 1-based number of the line in which the token occurs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_BlifGetLine( Io_BlifMan_t * p, char * pToken )
+{
+ char * pLine;
+ int i;
+ Vec_PtrForEachEntry( p->vLines, pLine, i )
+ if ( pToken < pLine )
+ return i;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Conservatively estimates the number of primary inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_BlifEstimatePiNum( Io_BlifMan_t * p )
+{
+ char * pCur;
+ int i, fSpaces;
+ int Counter = 0;
+ Vec_PtrForEachEntry( p->vInputs, pCur, i )
+ for ( fSpaces = 0; *pCur; pCur++ )
+ {
+ if ( Io_BlifCharIsSpace(*pCur) )
+ {
+ if ( !fSpaces )
+ Counter++;
+ fSpaces = 1;
+ }
+ else
+ fSpaces = 0;
+ }
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Conservatively estimates the number of AIG nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_BlifEstimateAndNum( Io_BlifMan_t * p )
+{
+ Io_BlifObj_t * pObj;
+ char * pCur;
+ int i, CounterOne, Counter = 0;
+ for ( i = 0; i < p->iObjNext; i++ )
+ {
+ pObj = p->pObjects + i;
+ if ( !pObj->fDef )
+ continue;
+ CounterOne = 0;
+ for ( pCur = pObj->pName + strlen(pObj->pName); *pCur != '.'; pCur++ )
+ if ( *pCur == '0' || *pCur == '1' )
+ CounterOne++;
+ if ( CounterOne )
+ Counter += CounterOne - 1;
+ }
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the file into a character buffer.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static char * Io_BlifLoadFile( char * pFileName )
+{
+ FILE * pFile;
+ int nFileSize;
+ char * pContents;
+ pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Io_BlifLoadFile(): The file is unavailable (absent or open).\n" );
+ return NULL;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nFileSize = ftell( pFile );
+ if ( nFileSize == 0 )
+ {
+ printf( "Io_BlifLoadFile(): The file is empty.\n" );
+ return NULL;
+ }
+ pContents = ALLOC( char, nFileSize + 10 );
+ rewind( pFile );
+ fread( pContents, nFileSize, 1, pFile );
+ fclose( pFile );
+ // finish off the file with the spare .end line
+ // some benchmarks suddenly break off without this line
+ strcpy( pContents + nFileSize, "\n.end\n" );
+ return pContents;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the parsing.]
+
+ Description [Performs several preliminary operations:
+ - Cuts the file buffer into separate lines.
+ - Removes comments and line extenders.
+ - Sorts lines by directives.
+ - Estimates the number of objects.
+ - Allocates room for the objects.
+ - Allocates room for the hash table.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_BlifReadPreparse( Io_BlifMan_t * p )
+{
+ char * pCur, * pPrev;
+ int i, fComment = 0;
+ // parse the buffer into lines and remove comments
+ Vec_PtrPush( p->vLines, p->pBuffer );
+ for ( pCur = p->pBuffer; *pCur; pCur++ )
+ {
+ if ( *pCur == '\n' )
+ {
+ *pCur = 0;
+ fComment = 0;
+ Vec_PtrPush( p->vLines, pCur + 1 );
+ }
+ else if ( *pCur == '#' )
+ fComment = 1;
+ // remove comments
+ if ( fComment )
+ *pCur = 0;
+ }
+
+ // unfold the line extensions and sort lines by directive
+ Vec_PtrForEachEntry( p->vLines, pCur, i )
+ {
+ if ( *pCur == 0 )
+ continue;
+ // find previous non-space character
+ for ( pPrev = pCur - 2; pPrev >= p->pBuffer; pPrev-- )
+ if ( !Io_BlifCharIsSpace(*pPrev) )
+ break;
+ // if it is the line extender, overwrite it with spaces
+ if ( *pPrev == '\\' )
+ {
+ for ( ; *pPrev; pPrev++ )
+ *pPrev = ' ';
+ *pPrev = ' ';
+ continue;
+ }
+ // skip spaces at the beginning of the line
+ while ( Io_BlifCharIsSpace(*pCur++) );
+ // parse directives
+ if ( *(pCur-1) != '.' )
+ continue;
+ if ( !strncmp(pCur, "names", 5) )
+ Vec_PtrPush( p->vNames, pCur );
+ else if ( !strncmp(pCur, "latch", 5) )
+ Vec_PtrPush( p->vLatches, pCur );
+ else if ( !strncmp(pCur, "inputs", 6) )
+ Vec_PtrPush( p->vInputs, pCur );
+ else if ( !strncmp(pCur, "outputs", 7) )
+ Vec_PtrPush( p->vOutputs, pCur );
+ else if ( !strncmp(pCur, "model", 5) )
+ p->pModel = pCur;
+ else if ( !strncmp(pCur, "end", 3) || !strncmp(pCur, "exdc", 4) )
+ break;
+ else
+ {
+ pCur--;
+ if ( pCur[strlen(pCur)-1] == '\r' )
+ pCur[strlen(pCur)-1] = 0;
+ fprintf( stdout, "Line %d: Skipping line \"%s\".\n", Io_BlifGetLine(p, pCur), pCur );
+ }
+ }
+
+ // count the number of objects
+ p->nObjects = Io_BlifEstimatePiNum(p) + Vec_PtrSize(p->vLatches) + Vec_PtrSize(p->vNames) + 512;
+
+ // allocate memory for objects
+ p->pObjects = ALLOC( Io_BlifObj_t, p->nObjects );
+ memset( p->pObjects, 0, p->nObjects * sizeof(Io_BlifObj_t) );
+
+ // allocate memory for the hash table
+ p->nTableSize = p->nObjects/2 + 1;
+ p->pTable = ALLOC( Io_BlifObj_t *, p->nTableSize );
+ memset( p->pTable, 0, p->nTableSize * sizeof(Io_BlifObj_t *) );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Reads the AIG in the binary AIGER format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Abc_Ntk_t * Io_BlifParse( Io_BlifMan_t * p )
+{
+ Abc_Ntk_t * pAig;
+ char * pLine;
+ int i;
+ // parse the model
+ if ( !Io_BlifParseModel( p, p->pModel ) )
+ return NULL;
+ // parse the inputs
+ Vec_PtrForEachEntry( p->vInputs, pLine, i )
+ if ( !Io_BlifParseInputs( p, pLine ) )
+ return NULL;
+ // parse the outputs
+ Vec_PtrForEachEntry( p->vOutputs, pLine, i )
+ if ( !Io_BlifParseOutputs( p, pLine ) )
+ return NULL;
+ // parse the latches
+ Vec_PtrForEachEntry( p->vLatches, pLine, i )
+ if ( !Io_BlifParseLatch( p, pLine ) )
+ return NULL;
+ // parse the nodes
+ Vec_PtrForEachEntry( p->vNames, pLine, i )
+ if ( !Io_BlifParseNames( p, pLine ) )
+ return NULL;
+ // reconstruct the network from the parsed data
+ if ( !Io_BlifParseConstruct( p ) )
+ return NULL;
+ // return the network
+ pAig = p->pAig;
+ p->pAig = NULL;
+ return pAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the model line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_BlifParseModel( Io_BlifMan_t * p, char * pLine )
+{
+ char * pToken;
+ Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
+ pToken = Vec_PtrEntry( p->vTokens, 0 );
+ assert( !strcmp(pToken, "model") );
+ if ( Vec_PtrSize(p->vTokens) != 2 )
+ {
+ sprintf( p->sError, "Line %d: Model line has %d entries while it should have 2.", Io_BlifGetLine(p, pToken), Vec_PtrSize(p->vTokens) );
+ return 0;
+ }
+ p->pModel = Vec_PtrEntry( p->vTokens, 1 );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the inputs line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_BlifParseInputs( Io_BlifMan_t * p, char * pLine )
+{
+ Io_BlifObj_t * pObj;
+ char * pToken;
+ int i;
+ Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
+ pToken = Vec_PtrEntry(p->vTokens, 0);
+ assert( !strcmp(pToken, "inputs") );
+ Vec_PtrForEachEntryStart( p->vTokens, pToken, i, 1 )
+ {
+ pObj = Io_BlifHashFindOrAdd( p, pToken );
+ if ( pObj->fPi )
+ {
+ sprintf( p->sError, "Line %d: Primary input (%s) is defined more than once.", Io_BlifGetLine(p, pToken), pToken );
+ return 0;
+ }
+ pObj->fPi = 1;
+ Vec_PtrPush( p->vPis, pObj );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the outputs line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_BlifParseOutputs( Io_BlifMan_t * p, char * pLine )
+{
+ Io_BlifObj_t * pObj;
+ char * pToken;
+ int i;
+ Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
+ pToken = Vec_PtrEntry(p->vTokens, 0);
+ assert( !strcmp(pToken, "outputs") );
+ Vec_PtrForEachEntryStart( p->vTokens, pToken, i, 1 )
+ {
+ pObj = Io_BlifHashFindOrAdd( p, pToken );
+ if ( pObj->fPo )
+ fprintf( stdout, "Line %d: Primary output (%s) is defined more than once (warning only).\n", Io_BlifGetLine(p, pToken), pToken );
+ pObj->fPo = 1;
+ Vec_PtrPush( p->vPos, pObj );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the latches line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_BlifParseLatch( Io_BlifMan_t * p, char * pLine )
+{
+ Io_BlifObj_t * pObj;
+ char * pToken;
+ int Init;
+ Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
+ pToken = Vec_PtrEntry(p->vTokens,0);
+ assert( !strcmp(pToken, "latch") );
+ if ( Vec_PtrSize(p->vTokens) < 3 )
+ {
+ sprintf( p->sError, "Line %d: Latch does not have input name and output name.", Io_BlifGetLine(p, pToken) );
+ return 0;
+ }
+ // get initial value
+ if ( Vec_PtrSize(p->vTokens) > 3 )
+ Init = atoi( Vec_PtrEntry(p->vTokens,3) );
+ else
+ Init = 2;
+ if ( Init < 0 || Init > 2 )
+ {
+ sprintf( p->sError, "Line %d: Initial state of the latch is incorrect (%s).", Io_BlifGetLine(p, pToken), Vec_PtrEntry(p->vTokens,3) );
+ return 0;
+ }
+ if ( Init == 0 )
+ Init = IO_BLIF_INIT_ZERO;
+ else if ( Init == 1 )
+ Init = IO_BLIF_INIT_ONE;
+ else // if ( Init == 2 )
+ Init = IO_BLIF_INIT_DC;
+ // get latch input
+ pObj = Io_BlifHashFindOrAdd( p, Vec_PtrEntry(p->vTokens,1) );
+ pObj->fLi = 1;
+ Vec_PtrPush( p->vLis, pObj );
+ pObj->Init = Init;
+ // get latch output
+ pObj = Io_BlifHashFindOrAdd( p, Vec_PtrEntry(p->vTokens,2) );
+ if ( pObj->fPi )
+ {
+ sprintf( p->sError, "Line %d: Primary input (%s) is also defined latch output.", Io_BlifGetLine(p, pToken), Vec_PtrEntry(p->vTokens,2) );
+ return 0;
+ }
+ if ( pObj->fLo )
+ {
+ sprintf( p->sError, "Line %d: Latch output (%s) is defined as the output of another latch.", Io_BlifGetLine(p, pToken), Vec_PtrEntry(p->vTokens,2) );
+ return 0;
+ }
+ pObj->fLo = 1;
+ Vec_PtrPush( p->vLos, pObj );
+ pObj->Init = Init;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the nodes line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_BlifParseNames( Io_BlifMan_t * p, char * pLine )
+{
+ Io_BlifObj_t * pObj;
+ char * pName;
+ Io_BlifSplitIntoTokens( p->vTokens, pLine, '\0' );
+ assert( !strcmp(Vec_PtrEntry(p->vTokens,0), "names") );
+ pName = Vec_PtrEntryLast( p->vTokens );
+ pObj = Io_BlifHashFindOrAdd( p, pName );
+ if ( pObj->fPi )
+ {
+ sprintf( p->sError, "Line %d: Primary input (%s) has a table.", Io_BlifGetLine(p, pName), pName );
+ return 0;
+ }
+ if ( pObj->fLo )
+ {
+ sprintf( p->sError, "Line %d: Latch output (%s) has a table.", Io_BlifGetLine(p, pName), pName );
+ return 0;
+ }
+ if ( pObj->fDef )
+ {
+ sprintf( p->sError, "Line %d: Signal (%s) is defined more than once.", Io_BlifGetLine(p, pName), pName );
+ return 0;
+ }
+ pObj->fDef = 1;
+ // remember offset to the first fanin name
+ pObj->pName = pName;
+ pObj->Offset = pObj->pName - (char *)Vec_PtrEntry(p->vTokens,1);
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the AIG from the file parsing info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Abc_Obj_t * Io_BlifParseTable( Io_BlifMan_t * p, char * pTable, Vec_Ptr_t * vFanins )
+{
+ char * pProduct, * pOutput;
+ Abc_Obj_t * pRes, * pCube;
+ int i, k, Polarity = -1;
+
+ p->nTablesRead++;
+ // get the tokens
+ Io_BlifSplitIntoTokens( p->vTokens, pTable, '.' );
+ if ( Vec_PtrSize(p->vTokens) == 0 )
+ return Abc_ObjNot( Abc_AigConst1(p->pAig) );
+ if ( Vec_PtrSize(p->vTokens) == 1 )
+ {
+ pOutput = Vec_PtrEntry( p->vTokens, 0 );
+ if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] )
+ {
+ sprintf( p->sError, "Line %d: Constant table has wrong output value (%s).", Io_BlifGetLine(p, pOutput), pOutput );
+ return NULL;
+ }
+ return Abc_ObjNotCond( Abc_AigConst1(p->pAig), pOutput[0] == '0' );
+ }
+ pProduct = Vec_PtrEntry( p->vTokens, 0 );
+ if ( Vec_PtrSize(p->vTokens) % 2 == 1 )
+ {
+ sprintf( p->sError, "Line %d: Table has odd number of tokens (%d).", Io_BlifGetLine(p, pProduct), Vec_PtrSize(p->vTokens) );
+ return NULL;
+ }
+ // parse the table
+ pRes = Abc_ObjNot( Abc_AigConst1(p->pAig) );
+ for ( i = 0; i < Vec_PtrSize(p->vTokens)/2; i++ )
+ {
+ pProduct = Vec_PtrEntry( p->vTokens, 2*i + 0 );
+ pOutput = Vec_PtrEntry( p->vTokens, 2*i + 1 );
+ if ( strlen(pProduct) != (unsigned)Vec_PtrSize(vFanins) )
+ {
+ sprintf( p->sError, "Line %d: Cube (%s) has size different from the fanin count (%d).", Io_BlifGetLine(p, pProduct), pProduct, Vec_PtrSize(vFanins) );
+ return NULL;
+ }
+ if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] )
+ {
+ sprintf( p->sError, "Line %d: Output value (%s) is incorrect.", Io_BlifGetLine(p, pProduct), pOutput );
+ return NULL;
+ }
+ if ( Polarity == -1 )
+ Polarity = pOutput[0] - '0';
+ else if ( Polarity != pOutput[0] - '0' )
+ {
+ sprintf( p->sError, "Line %d: Output value (%s) differs from the value in the first line of the table (%d).", Io_BlifGetLine(p, pProduct), pOutput, Polarity );
+ return NULL;
+ }
+ // parse one product product
+ pCube = Abc_AigConst1(p->pAig);
+ for ( k = 0; pProduct[k]; k++ )
+ {
+ if ( pProduct[k] == '0' )
+ pCube = Abc_AigAnd( p->pAig->pManFunc, pCube, Abc_ObjNot(Vec_PtrEntry(vFanins,k)) );
+ else if ( pProduct[k] == '1' )
+ pCube = Abc_AigAnd( p->pAig->pManFunc, pCube, Vec_PtrEntry(vFanins,k) );
+ else if ( pProduct[k] != '-' )
+ {
+ sprintf( p->sError, "Line %d: Product term (%s) contains character (%c).", Io_BlifGetLine(p, pProduct), pProduct, pProduct[k] );
+ return NULL;
+ }
+ }
+ pRes = Abc_AigOr( p->pAig->pManFunc, pRes, pCube );
+ }
+ pRes = Abc_ObjNotCond( pRes, Polarity == 0 );
+ return pRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the AIG from the file parsing info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Abc_Obj_t * Io_BlifParseConstruct_rec( Io_BlifMan_t * p, char * pName )
+{
+ Vec_Ptr_t * vFanins;
+ Abc_Obj_t * pFaninAbc;
+ Io_BlifObj_t * pObjIo;
+ char * pNameFanin;
+ int i;
+ // get the IO object with this name
+ pObjIo = *Io_BlifHashLookup( p, pName );
+ if ( pObjIo == NULL )
+ {
+ sprintf( p->sError, "Line %d: Signal (%s) is not defined as a table.", Io_BlifGetLine(p, pName), pName );
+ return NULL;
+ }
+ // loop detection
+ if ( pObjIo->fLoop )
+ {
+ sprintf( p->sError, "Line %d: Signal (%s) appears twice on a combinational path.", Io_BlifGetLine(p, pName), pName );
+ return NULL;
+ }
+ // check if the AIG is already constructed
+ if ( pObjIo->pEquiv )
+ return pObjIo->pEquiv;
+ // mark this node on the path
+ pObjIo->fLoop = 1;
+ // construct the AIGs for the fanins
+ vFanins = Vec_PtrAlloc( 8 );
+ Io_BlifCollectTokens( vFanins, pObjIo->pName - pObjIo->Offset, pObjIo->pName );
+ Vec_PtrForEachEntry( vFanins, pNameFanin, i )
+ {
+ pFaninAbc = Io_BlifParseConstruct_rec( p, pNameFanin );
+ if ( pFaninAbc == NULL )
+ {
+ Vec_PtrFree( vFanins );
+ return NULL;
+ }
+ Vec_PtrWriteEntry( vFanins, i, pFaninAbc );
+ }
+ // construct the node
+ pObjIo->pEquiv = Io_BlifParseTable( p, pObjIo->pName + strlen(pObjIo->pName), vFanins );
+ Vec_PtrFree( vFanins );
+ // unmark this node on the path
+ pObjIo->fLoop = 0;
+ // remember the new node
+ return pObjIo->pEquiv;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the AIG from the file parsing info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_BlifParseConstruct( Io_BlifMan_t * p )
+{
+ Abc_Ntk_t * pAig;
+ Io_BlifObj_t * pObjIo, * pObjIoInput;
+ Abc_Obj_t * pObj, * pLatch;
+ int i;
+ // allocate the empty AIG
+ pAig = p->pAig = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
+ pAig->pName = Extra_UtilStrsav( p->pModel );
+ pAig->pSpec = Extra_UtilStrsav( p->pFileName );
+ // create PIs
+ Vec_PtrForEachEntry( p->vPis, pObjIo, i )
+ {
+ pObj = Abc_NtkCreatePi( pAig );
+ Abc_ObjAssignName( pObj, pObjIo->pName, NULL );
+ pObjIo->pEquiv = pObj;
+ }
+ // create POs
+ Vec_PtrForEachEntry( p->vPos, pObjIo, i )
+ {
+ pObj = Abc_NtkCreatePo( pAig );
+ Abc_ObjAssignName( pObj, pObjIo->pName, NULL );
+ }
+ // create latches
+ Vec_PtrForEachEntry( p->vLos, pObjIo, i )
+ {
+ // add the latch input terminal
+ pObj = Abc_NtkCreateBi( pAig );
+ pObjIoInput = Vec_PtrEntry( p->vLis, i );
+ Abc_ObjAssignName( pObj, pObjIoInput->pName, NULL );
+
+ // add the latch box
+ pLatch = Abc_NtkCreateLatch( pAig );
+ pLatch->pData = (void *)pObjIo->Init;
+ Abc_ObjAssignName( pLatch, pObjIo->pName, "L" );
+ Abc_ObjAddFanin( pLatch, pObj );
+
+ // add the latch output terminal
+ pObj = Abc_NtkCreateBo( pAig );
+ Abc_ObjAssignName( pObj, pObjIo->pName, NULL );
+ Abc_ObjAddFanin( pObj, pLatch );
+ // set the value of the latch output
+// pObjIo->pEquiv = Abc_ObjNotCond( pObj, pObjIo->Init );
+ pObjIo->pEquiv = pObj;
+ }
+ // traverse the nodes from the POs
+ Vec_PtrForEachEntry( p->vPos, pObjIo, i )
+ {
+ pObj = Io_BlifParseConstruct_rec( p, pObjIo->pName );
+ if ( pObj == NULL )
+ return 0;
+ Abc_ObjAddFanin( Abc_NtkPo(p->pAig, i), pObj );
+ }
+ // traverse the nodes from the latch inputs
+ Vec_PtrForEachEntry( p->vLis, pObjIo, i )
+ {
+ pObj = Io_BlifParseConstruct_rec( p, pObjIo->pName );
+ if ( pObj == NULL )
+ return 0;
+// pObj = Abc_ObjNotCond( pObj, pObjIo->Init );
+ Abc_ObjAddFanin( Abc_ObjFanin0(Abc_NtkBox(p->pAig, i)), pObj );
+ }
+ p->nTablesLeft = Vec_PtrSize(p->vNames) - p->nTablesRead;
+ if ( p->nTablesLeft )
+ printf( "The number of dangling tables = %d.\n", p->nTablesLeft );
+ printf( "AND nodes = %6d. Estimate = %6d.\n", Abc_NtkNodeNum(p->pAig), Io_BlifEstimateAndNum(p) );
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioReadBlifMv.c b/src/base/io/ioReadBlifMv.c
new file mode 100644
index 00000000..97f2fbf3
--- /dev/null
+++ b/src/base/io/ioReadBlifMv.c
@@ -0,0 +1,1702 @@
+/**CFile****************************************************************
+
+ FileName [ioReadBlifMv.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to read BLIF-MV file.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - January 8, 2007.]
+
+ Revision [$Id: ioReadBlifMv.c,v 1.00 2007/01/08 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "extra.h"
+#include "vecPtr.h"
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define IO_BLIFMV_MAXVALUES 256
+
+typedef struct Io_MvVar_t_ Io_MvVar_t; // parsing var
+typedef struct Io_MvMod_t_ Io_MvMod_t; // parsing model
+typedef struct Io_MvMan_t_ Io_MvMan_t; // parsing manager
+
+struct Io_MvVar_t_
+{
+ int nValues; // the number of values
+ char ** pNames; // the value names
+};
+
+struct Io_MvMod_t_
+{
+ // file lines
+ char * pName; // .model line
+ Vec_Ptr_t * vInputs; // .inputs lines
+ Vec_Ptr_t * vOutputs; // .outputs lines
+ Vec_Ptr_t * vLatches; // .latch lines
+ Vec_Ptr_t * vResets; // .reset lines
+ Vec_Ptr_t * vNames; // .names lines
+ Vec_Ptr_t * vSubckts; // .subckt lines
+ Vec_Ptr_t * vMvs; // .mv lines
+ int fBlackBox; // indicates blackbox model
+ // the resulting network
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pResetLatch;
+ // the parent manager
+ Io_MvMan_t * pMan;
+};
+
+struct Io_MvMan_t_
+{
+ // general info about file
+ int fBlifMv; // the file is BLIF-MV
+ int fUseReset; // the reset circuitry is added
+ char * pFileName; // the name of the file
+ char * pBuffer; // the contents of the file
+ Vec_Ptr_t * vLines; // the line beginnings
+ // the results of reading
+ Abc_Lib_t * pDesign; // the design under construction
+ int nNDnodes; // the counter of ND nodes
+ // intermediate storage for models
+ Vec_Ptr_t * vModels; // vector of models
+ Io_MvMod_t * pLatest; // the current model
+ // current processing info
+ Vec_Ptr_t * vTokens; // the current tokens
+ Vec_Ptr_t * vTokens2; // the current tokens
+ Vec_Str_t * vFunc; // the local function
+ // error reporting
+ char sError[512]; // the error string generated during parsing
+ // statistics
+ int nTablesRead; // the number of processed tables
+ int nTablesLeft; // the number of dangling tables
+};
+
+// static functions
+static Io_MvMan_t * Io_MvAlloc();
+static void Io_MvFree( Io_MvMan_t * p );
+static Io_MvMod_t * Io_MvModAlloc();
+static void Io_MvModFree( Io_MvMod_t * p );
+static char * Io_MvLoadFile( char * pFileName );
+static void Io_MvReadPreparse( Io_MvMan_t * p );
+static void Io_MvReadInterfaces( Io_MvMan_t * p );
+static Abc_Lib_t * Io_MvParse( Io_MvMan_t * p );
+static int Io_MvParseLineModel( Io_MvMod_t * p, char * pLine );
+static int Io_MvParseLineInputs( Io_MvMod_t * p, char * pLine );
+static int Io_MvParseLineOutputs( Io_MvMod_t * p, char * pLine );
+static int Io_MvParseLineLatch( Io_MvMod_t * p, char * pLine );
+static int Io_MvParseLineSubckt( Io_MvMod_t * p, char * pLine );
+static int Io_MvParseLineMv( Io_MvMod_t * p, char * pLine );
+static int Io_MvParseLineNamesMv( Io_MvMod_t * p, char * pLine, int fReset );
+static int Io_MvParseLineNamesBlif( Io_MvMod_t * p, char * pLine );
+static int Io_MvParseLineGateBlif( Io_MvMod_t * p, Vec_Ptr_t * vTokens );
+static Io_MvVar_t * Abc_NtkMvVarDup( Abc_Ntk_t * pNtk, Io_MvVar_t * pVar );
+
+static int Io_MvCharIsSpace( char s ) { return s == ' ' || s == '\t' || s == '\r' || s == '\n'; }
+static int Io_MvCharIsMvSymb( char s ) { return s == '(' || s == ')' || s == '{' || s == '}' || s == '-' || s == ',' || s == '!'; }
+
+extern void Abc_NtkStartMvVars( Abc_Ntk_t * pNtk );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Reads the network from the BLIF or BLIF-MV file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadBlifMv( char * pFileName, int fBlifMv, int fCheck )
+{
+ FILE * pFile;
+ Io_MvMan_t * p;
+ Abc_Ntk_t * pNtk;
+ Abc_Lib_t * pDesign;
+ char * pDesignName;
+ int RetValue, i;
+
+ // check that the file is available
+ pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Io_ReadBlifMv(): The file is unavailable (absent or open).\n" );
+ return 0;
+ }
+ fclose( pFile );
+
+ // start the file reader
+ p = Io_MvAlloc();
+ p->fBlifMv = fBlifMv;
+ p->fUseReset = 0;
+ p->pFileName = pFileName;
+ p->pBuffer = Io_MvLoadFile( pFileName );
+ if ( p->pBuffer == NULL )
+ {
+ Io_MvFree( p );
+ return NULL;
+ }
+ // set the design name
+ pDesignName = Extra_FileNameGeneric( pFileName );
+ p->pDesign = Abc_LibCreate( pDesignName );
+ free( pDesignName );
+ // free the HOP manager
+ Hop_ManStop( p->pDesign->pManFunc );
+ p->pDesign->pManFunc = NULL;
+ // prepare the file for parsing
+ Io_MvReadPreparse( p );
+ // parse interfaces of each network
+ Io_MvReadInterfaces( p );
+ // construct the network
+ pDesign = Io_MvParse( p );
+ if ( p->sError[0] )
+ fprintf( stdout, "%s\n", p->sError );
+ Io_MvFree( p );
+ if ( pDesign == NULL )
+ return NULL;
+// pDesign should be linked to all models of the design
+
+ // make sure that everything is okay with the network structure
+ if ( fCheck )
+ {
+ Vec_PtrForEachEntry( pDesign->vModules, pNtk, i )
+ {
+ if ( !Abc_NtkCheckRead( pNtk ) )
+ {
+ printf( "Io_ReadBlifMv: The network check has failed for network %s.\n", pNtk->pName );
+ Abc_LibFree( pDesign, NULL );
+ return NULL;
+ }
+ }
+ }
+
+//Abc_LibPrint( pDesign );
+
+ // detect top-level model
+ RetValue = Abc_LibFindTopLevelModels( pDesign );
+ pNtk = Vec_PtrEntry( pDesign->vTops, 0 );
+ if ( RetValue > 1 )
+ printf( "Warning: The design has %d root-level modules. The first one (%s) will be used.\n",
+ Vec_PtrSize(pDesign->vTops), pNtk->pName );
+
+ // extract the master network
+ pNtk->pDesign = pDesign;
+ pDesign->pManFunc = NULL;
+
+ // verify the design for cyclic dependence
+ assert( Vec_PtrSize(pDesign->vModules) > 0 );
+ if ( Vec_PtrSize(pDesign->vModules) == 1 )
+ {
+// printf( "Warning: The design is not hierarchical.\n" );
+ Abc_LibFree( pDesign, pNtk );
+ pNtk->pDesign = NULL;
+ pNtk->pSpec = Extra_UtilStrsav( pFileName );
+ }
+ else
+ Abc_NtkIsAcyclicHierarchy( pNtk );
+
+//Io_WriteBlifMv( pNtk, "_temp_.mv" );
+ if ( pNtk->pSpec == NULL )
+ pNtk->pSpec = Extra_UtilStrsav( pFileName );
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates the BLIF parsing structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Io_MvMan_t * Io_MvAlloc()
+{
+ Io_MvMan_t * p;
+ p = ALLOC( Io_MvMan_t, 1 );
+ memset( p, 0, sizeof(Io_MvMan_t) );
+ p->vLines = Vec_PtrAlloc( 512 );
+ p->vModels = Vec_PtrAlloc( 512 );
+ p->vTokens = Vec_PtrAlloc( 512 );
+ p->vTokens2 = Vec_PtrAlloc( 512 );
+ p->vFunc = Vec_StrAlloc( 512 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the BLIF parsing structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_MvFree( Io_MvMan_t * p )
+{
+ Io_MvMod_t * pMod;
+ int i;
+ if ( p->pDesign )
+ Abc_LibFree( p->pDesign, NULL );
+ if ( p->pBuffer )
+ free( p->pBuffer );
+ if ( p->vLines )
+ Vec_PtrFree( p->vLines );
+ if ( p->vModels )
+ {
+ Vec_PtrForEachEntry( p->vModels, pMod, i )
+ Io_MvModFree( pMod );
+ Vec_PtrFree( p->vModels );
+ }
+ Vec_PtrFree( p->vTokens );
+ Vec_PtrFree( p->vTokens2 );
+ Vec_StrFree( p->vFunc );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates the BLIF parsing structure for one model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Io_MvMod_t * Io_MvModAlloc()
+{
+ Io_MvMod_t * p;
+ p = ALLOC( Io_MvMod_t, 1 );
+ memset( p, 0, sizeof(Io_MvMod_t) );
+ p->vInputs = Vec_PtrAlloc( 512 );
+ p->vOutputs = Vec_PtrAlloc( 512 );
+ p->vLatches = Vec_PtrAlloc( 512 );
+ p->vResets = Vec_PtrAlloc( 512 );
+ p->vNames = Vec_PtrAlloc( 512 );
+ p->vSubckts = Vec_PtrAlloc( 512 );
+ p->vMvs = Vec_PtrAlloc( 512 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates the BLIF parsing structure for one model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_MvModFree( Io_MvMod_t * p )
+{
+// if ( p->pNtk )
+// Abc_NtkDelete( p->pNtk );
+ Vec_PtrFree( p->vInputs );
+ Vec_PtrFree( p->vOutputs );
+ Vec_PtrFree( p->vLatches );
+ Vec_PtrFree( p->vResets );
+ Vec_PtrFree( p->vNames );
+ Vec_PtrFree( p->vSubckts );
+ Vec_PtrFree( p->vMvs );
+ free( p );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of given chars.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvCountChars( char * pLine, char Char )
+{
+ char * pCur;
+ int Counter = 0;
+ for ( pCur = pLine; *pCur; pCur++ )
+ if ( *pCur == Char )
+ Counter++;
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the place where the arrow is hiding.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static char * Io_MvFindArrow( char * pLine )
+{
+ char * pCur;
+ for ( pCur = pLine; *(pCur+1); pCur++ )
+ if ( *pCur == '-' && *(pCur+1) == '>' )
+ {
+ *pCur = ' ';
+ *(pCur+1) = ' ';
+ return pCur;
+ }
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the already split tokens.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_MvCollectTokens( Vec_Ptr_t * vTokens, char * pInput, char * pOutput )
+{
+ char * pCur;
+ Vec_PtrClear( vTokens );
+ for ( pCur = pInput; pCur < pOutput; pCur++ )
+ {
+ if ( *pCur == 0 )
+ continue;
+ Vec_PtrPush( vTokens, pCur );
+ while ( *++pCur );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Splits the line into tokens.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_MvSplitIntoTokens( Vec_Ptr_t * vTokens, char * pLine, char Stop )
+{
+ char * pCur;
+ // clear spaces
+ for ( pCur = pLine; *pCur != Stop; pCur++ )
+ if ( Io_MvCharIsSpace(*pCur) )
+ *pCur = 0;
+ // collect tokens
+ Io_MvCollectTokens( vTokens, pLine, pCur );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Splits the line into tokens when .default may be present.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_MvSplitIntoTokensMv( Vec_Ptr_t * vTokens, char * pLine )
+{
+ char * pCur;
+ // clear spaces
+ for ( pCur = pLine; *pCur != '.' || *(pCur+1) == 'd'; pCur++ )
+ if ( Io_MvCharIsSpace(*pCur) )
+ *pCur = 0;
+ // collect tokens
+ Io_MvCollectTokens( vTokens, pLine, pCur );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Splits the line into tokens.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_MvSplitIntoTokensAndClear( Vec_Ptr_t * vTokens, char * pLine, char Stop, char Char )
+{
+ char * pCur;
+ // clear spaces
+ for ( pCur = pLine; *pCur != Stop; pCur++ )
+ if ( Io_MvCharIsSpace(*pCur) || *pCur == Char )
+ *pCur = 0;
+ // collect tokens
+ Io_MvCollectTokens( vTokens, pLine, pCur );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the 1-based number of the line in which the token occurs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvGetLine( Io_MvMan_t * p, char * pToken )
+{
+ char * pLine;
+ int i;
+ Vec_PtrForEachEntry( p->vLines, pLine, i )
+ if ( pToken < pLine )
+ return i;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the file into a character buffer.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static char * Io_MvLoadFile( char * pFileName )
+{
+ FILE * pFile;
+ int nFileSize;
+ char * pContents;
+ pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Io_MvLoadFile(): The file is unavailable (absent or open).\n" );
+ return NULL;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nFileSize = ftell( pFile );
+ if ( nFileSize == 0 )
+ {
+ printf( "Io_MvLoadFile(): The file is empty.\n" );
+ return NULL;
+ }
+ pContents = ALLOC( char, nFileSize + 10 );
+ rewind( pFile );
+ fread( pContents, nFileSize, 1, pFile );
+ fclose( pFile );
+ // finish off the file with the spare .end line
+ // some benchmarks suddenly break off without this line
+ strcpy( pContents + nFileSize, "\n.end\n" );
+ return pContents;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the parsing.]
+
+ Description [Performs several preliminary operations:
+ - Cuts the file buffer into separate lines.
+ - Removes comments and line extenders.
+ - Sorts lines by directives.
+ - Estimates the number of objects.
+ - Allocates room for the objects.
+ - Allocates room for the hash table.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_MvReadPreparse( Io_MvMan_t * p )
+{
+ char * pCur, * pPrev;
+ int i, fComment = 0;
+ // parse the buffer into lines and remove comments
+ Vec_PtrPush( p->vLines, p->pBuffer );
+ for ( pCur = p->pBuffer; *pCur; pCur++ )
+ {
+ if ( *pCur == '\n' )
+ {
+ *pCur = 0;
+// if ( *(pCur-1) == '\r' )
+// *(pCur-1) = 0;
+ fComment = 0;
+ Vec_PtrPush( p->vLines, pCur + 1 );
+ }
+ else if ( *pCur == '#' )
+ fComment = 1;
+ // remove comments
+ if ( fComment )
+ *pCur = 0;
+ }
+
+ // unfold the line extensions and sort lines by directive
+ Vec_PtrForEachEntry( p->vLines, pCur, i )
+ {
+ if ( *pCur == 0 )
+ continue;
+ // find previous non-space character
+ for ( pPrev = pCur - 2; pPrev >= p->pBuffer; pPrev-- )
+ if ( !Io_MvCharIsSpace(*pPrev) )
+ break;
+ // if it is the line extender, overwrite it with spaces
+ if ( *pPrev == '\\' )
+ {
+ for ( ; *pPrev; pPrev++ )
+ *pPrev = ' ';
+ *pPrev = ' ';
+ continue;
+ }
+ // skip spaces at the beginning of the line
+ while ( Io_MvCharIsSpace(*pCur++) );
+ // parse directives
+ if ( *(pCur-1) != '.' )
+ continue;
+ if ( !strncmp(pCur, "names", 5) || !strncmp(pCur, "table", 5) || !strncmp(pCur, "gate", 4) )
+ Vec_PtrPush( p->pLatest->vNames, pCur );
+ else if ( p->fBlifMv && (!strncmp(pCur, "def ", 4) || !strncmp(pCur, "default ", 8)) )
+ continue;
+ else if ( !strncmp(pCur, "latch", 5) )
+ Vec_PtrPush( p->pLatest->vLatches, pCur );
+ else if ( !strncmp(pCur, "r ", 2) || !strncmp(pCur, "reset ", 6) )
+ Vec_PtrPush( p->pLatest->vResets, pCur );
+ else if ( !strncmp(pCur, "inputs", 6) )
+ Vec_PtrPush( p->pLatest->vInputs, pCur );
+ else if ( !strncmp(pCur, "outputs", 7) )
+ Vec_PtrPush( p->pLatest->vOutputs, pCur );
+ else if ( !strncmp(pCur, "subckt", 6) )
+ Vec_PtrPush( p->pLatest->vSubckts, pCur );
+ else if ( p->fBlifMv && !strncmp(pCur, "mv", 2) )
+ Vec_PtrPush( p->pLatest->vMvs, pCur );
+ else if ( !strncmp(pCur, "blackbox", 8) )
+ p->pLatest->fBlackBox = 1;
+ else if ( !strncmp(pCur, "model", 5) )
+ {
+ p->pLatest = Io_MvModAlloc();
+ p->pLatest->pName = pCur;
+ p->pLatest->pMan = p;
+ }
+ else if ( !strncmp(pCur, "end", 3) )
+ {
+ if ( p->pLatest )
+ Vec_PtrPush( p->vModels, p->pLatest );
+ p->pLatest = NULL;
+ }
+ else if ( !strncmp(pCur, "exdc", 4) )
+ {
+ fprintf( stdout, "Line %d: Skipping EXDC network.\n", Io_MvGetLine(p, pCur) );
+ break;
+ }
+ else if ( !strncmp(pCur, "delay", 5) )
+ {}
+ else if ( !strncmp(pCur, "input_arrival", 13) )
+ {}
+ else if ( !strncmp(pCur, "output_required", 15) )
+ {}
+ else
+ {
+ pCur--;
+ if ( pCur[strlen(pCur)-1] == '\r' )
+ pCur[strlen(pCur)-1] = 0;
+ fprintf( stdout, "Line %d: Skipping line \"%s\".\n", Io_MvGetLine(p, pCur), pCur );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses interfaces of the models.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void Io_MvReadInterfaces( Io_MvMan_t * p )
+{
+ Io_MvMod_t * pMod;
+ char * pLine;
+ int i, k;
+ // iterate through the models
+ Vec_PtrForEachEntry( p->vModels, pMod, i )
+ {
+ // parse the model
+ if ( !Io_MvParseLineModel( pMod, pMod->pName ) )
+ return;
+ // add model to the design
+ if ( !Abc_LibAddModel( p->pDesign, pMod->pNtk ) )
+ {
+ sprintf( p->sError, "Line %d: Model %s is defined twice.", Io_MvGetLine(p, pMod->pName), pMod->pName );
+ return;
+ }
+ // parse the inputs
+ Vec_PtrForEachEntry( pMod->vInputs, pLine, k )
+ if ( !Io_MvParseLineInputs( pMod, pLine ) )
+ return;
+ // parse the outputs
+ Vec_PtrForEachEntry( pMod->vOutputs, pLine, k )
+ if ( !Io_MvParseLineOutputs( pMod, pLine ) )
+ return;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Abc_Lib_t * Io_MvParse( Io_MvMan_t * p )
+{
+ Abc_Lib_t * pDesign;
+ Io_MvMod_t * pMod;
+ char * pLine;
+ int i, k;
+ // iterate through the models
+ Vec_PtrForEachEntry( p->vModels, pMod, i )
+ {
+ // check if there any MV lines
+ if ( Vec_PtrSize(pMod->vMvs) > 0 )
+ Abc_NtkStartMvVars( pMod->pNtk );
+ // parse the mv lines
+ Vec_PtrForEachEntry( pMod->vMvs, pLine, k )
+ if ( !Io_MvParseLineMv( pMod, pLine ) )
+ return NULL;
+ // if reset lines are used there should be the same number of them as latches
+ if ( Vec_PtrSize(pMod->vResets) > 0 )
+ {
+ if ( Vec_PtrSize(pMod->vLatches) != Vec_PtrSize(pMod->vResets) )
+ {
+ sprintf( p->sError, "Line %d: Model %s has different number of latches (%d) and reset nodes (%d).",
+ Io_MvGetLine(p, pMod->pName), Abc_NtkName(pMod->pNtk), Vec_PtrSize(pMod->vLatches), Vec_PtrSize(pMod->vResets) );
+ return NULL;
+ }
+ // create binary latch with 1-data and 0-init
+ if ( p->fUseReset )
+ pMod->pResetLatch = Io_ReadCreateResetLatch( pMod->pNtk, p->fBlifMv );
+ }
+ // parse the latches
+ Vec_PtrForEachEntry( pMod->vLatches, pLine, k )
+ if ( !Io_MvParseLineLatch( pMod, pLine ) )
+ return NULL;
+ // parse the reset lines
+ if ( p->fUseReset )
+ Vec_PtrForEachEntry( pMod->vResets, pLine, k )
+ if ( !Io_MvParseLineNamesMv( pMod, pLine, 1 ) )
+ return NULL;
+ // parse the nodes
+ if ( p->fBlifMv )
+ {
+ Vec_PtrForEachEntry( pMod->vNames, pLine, k )
+ if ( !Io_MvParseLineNamesMv( pMod, pLine, 0 ) )
+ return NULL;
+ }
+ else
+ {
+ Vec_PtrForEachEntry( pMod->vNames, pLine, k )
+ if ( !Io_MvParseLineNamesBlif( pMod, pLine ) )
+ return NULL;
+ }
+ // parse the subcircuits
+ Vec_PtrForEachEntry( pMod->vSubckts, pLine, k )
+ if ( !Io_MvParseLineSubckt( pMod, pLine ) )
+ return NULL;
+ // finalize the network
+ Abc_NtkFinalizeRead( pMod->pNtk );
+ }
+ if ( p->nNDnodes )
+// printf( "Warning: The parser added %d PIs to replace non-deterministic nodes.\n", p->nNDnodes );
+ printf( "Warning: The parser added %d constant 0 nodes to replace non-deterministic nodes.\n", p->nNDnodes );
+ // return the network
+ pDesign = p->pDesign;
+ p->pDesign = NULL;
+ return pDesign;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the model line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLineModel( Io_MvMod_t * p, char * pLine )
+{
+ Vec_Ptr_t * vTokens = p->pMan->vTokens;
+ char * pToken;
+ Io_MvSplitIntoTokens( vTokens, pLine, '\0' );
+ pToken = Vec_PtrEntry( vTokens, 0 );
+ assert( !strcmp(pToken, "model") );
+ if ( Vec_PtrSize(vTokens) != 2 )
+ {
+ sprintf( p->pMan->sError, "Line %d: Model line has %d entries while it should have 2.", Io_MvGetLine(p->pMan, pToken), Vec_PtrSize(vTokens) );
+ return 0;
+ }
+ if ( p->fBlackBox )
+ p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_BLACKBOX, 1 );
+ else if ( p->pMan->fBlifMv )
+ p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_BLIFMV, 1 );
+ else
+ p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 );
+ p->pNtk->pName = Extra_UtilStrsav( Vec_PtrEntry(vTokens, 1) );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the inputs line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLineInputs( Io_MvMod_t * p, char * pLine )
+{
+ Vec_Ptr_t * vTokens = p->pMan->vTokens;
+ char * pToken;
+ int i;
+ Io_MvSplitIntoTokens( vTokens, pLine, '\0' );
+ pToken = Vec_PtrEntry(vTokens, 0);
+ assert( !strcmp(pToken, "inputs") );
+ Vec_PtrForEachEntryStart( vTokens, pToken, i, 1 )
+ Io_ReadCreatePi( p->pNtk, pToken );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the outputs line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLineOutputs( Io_MvMod_t * p, char * pLine )
+{
+ Vec_Ptr_t * vTokens = p->pMan->vTokens;
+ char * pToken;
+ int i;
+ Io_MvSplitIntoTokens( vTokens, pLine, '\0' );
+ pToken = Vec_PtrEntry(vTokens, 0);
+ assert( !strcmp(pToken, "outputs") );
+ Vec_PtrForEachEntryStart( vTokens, pToken, i, 1 )
+ Io_ReadCreatePo( p->pNtk, pToken );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the latches line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLineLatch( Io_MvMod_t * p, char * pLine )
+{
+ Vec_Ptr_t * vTokens = p->pMan->vTokens;
+ Abc_Obj_t * pObj, * pNet;
+ char * pToken;
+ int Init;
+ Io_MvSplitIntoTokens( vTokens, pLine, '\0' );
+ pToken = Vec_PtrEntry(vTokens,0);
+ assert( !strcmp(pToken, "latch") );
+ if ( Vec_PtrSize(vTokens) < 3 )
+ {
+ sprintf( p->pMan->sError, "Line %d: Latch does not have input name and output name.", Io_MvGetLine(p->pMan, pToken) );
+ return 0;
+ }
+ // create latch
+ if ( p->pResetLatch == NULL )
+ {
+ pObj = Io_ReadCreateLatch( p->pNtk, Vec_PtrEntry(vTokens,1), Vec_PtrEntry(vTokens,2) );
+ // get initial value
+ if ( p->pMan->fBlifMv )
+ Abc_LatchSetInit0( pObj );
+ else
+ {
+ if ( Vec_PtrSize(vTokens) > 3 )
+ Init = atoi( Vec_PtrEntryLast(vTokens) );
+ else
+ Init = 2;
+ if ( Init < 0 || Init > 2 )
+ {
+ sprintf( p->pMan->sError, "Line %d: Initial state of the latch is incorrect \"%s\".", Io_MvGetLine(p->pMan, pToken), Vec_PtrEntry(vTokens,3) );
+ return 0;
+ }
+ if ( Init == 0 )
+ Abc_LatchSetInit0( pObj );
+ else if ( Init == 1 )
+ Abc_LatchSetInit1( pObj );
+ else // if ( Init == 2 )
+ Abc_LatchSetInitDc( pObj );
+ }
+ }
+ else
+ {
+ // get the net corresponding to the output of the latch
+ pNet = Abc_NtkFindOrCreateNet( p->pNtk, Vec_PtrEntry(vTokens,2) );
+ // get the net corresponding to the latch output (feeding into reset MUX)
+ pNet = Abc_NtkFindOrCreateNet( p->pNtk, Abc_ObjNameSuffix(pNet, "_out") );
+ // create latch
+ pObj = Io_ReadCreateLatch( p->pNtk, Vec_PtrEntry(vTokens,1), Abc_ObjName(pNet) );
+ Abc_LatchSetInit0( pObj );
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the subckt line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLineSubckt( Io_MvMod_t * p, char * pLine )
+{
+ Vec_Ptr_t * vTokens = p->pMan->vTokens;
+ Abc_Ntk_t * pModel;
+ Abc_Obj_t * pBox, * pNet, * pTerm;
+ char * pToken, * pName, ** ppNames;
+ int nEquals, i, k;
+
+ // split the line into tokens
+ nEquals = Io_MvCountChars( pLine, '=' );
+ Io_MvSplitIntoTokensAndClear( vTokens, pLine, '\0', '=' );
+ pToken = Vec_PtrEntry(vTokens,0);
+ assert( !strcmp(pToken, "subckt") );
+
+ // get the model for this box
+ pName = Vec_PtrEntry(vTokens,1);
+ pModel = Abc_LibFindModelByName( p->pMan->pDesign, pName );
+ if ( pModel == NULL )
+ {
+ sprintf( p->pMan->sError, "Line %d: Cannot find the model for subcircuit %s.", Io_MvGetLine(p->pMan, pToken), pName );
+ return 0;
+ }
+
+ // check if the number of tokens is correct
+ if ( nEquals != Abc_NtkPiNum(pModel) + Abc_NtkPoNum(pModel) )
+ {
+ sprintf( p->pMan->sError, "Line %d: The number of ports (%d) in .subckt differs from the sum of PIs and POs of the model (%d).",
+ Io_MvGetLine(p->pMan, pToken), nEquals, Abc_NtkPiNum(pModel) + Abc_NtkPoNum(pModel) );
+ return 0;
+ }
+
+ // get the names
+ ppNames = (char **)Vec_PtrArray(vTokens) + 2 + p->pMan->fBlifMv;
+
+ // create the box with these terminals
+ if ( Abc_NtkHasBlackbox(pModel) )
+ pBox = Abc_NtkCreateBlackbox( p->pNtk );
+ else
+ pBox = Abc_NtkCreateWhitebox( p->pNtk );
+ pBox->pData = pModel;
+ if ( p->pMan->fBlifMv )
+ Abc_ObjAssignName( pBox, Vec_PtrEntry(vTokens,2), NULL );
+ Abc_NtkForEachPi( pModel, pTerm, i )
+ {
+ // find this terminal among the formal inputs of the subcircuit
+ pName = Abc_ObjName(Abc_ObjFanout0(pTerm));
+ for ( k = 0; k < nEquals; k++ )
+ if ( !strcmp( ppNames[2*k], pName ) )
+ break;
+ if ( k == nEquals )
+ {
+ sprintf( p->pMan->sError, "Line %d: Cannot find PI \"%s\" of the model \"%s\" as a formal input of the subcircuit.",
+ Io_MvGetLine(p->pMan, pToken), pName, Abc_NtkName(pModel) );
+ return 0;
+ }
+ // create the BI with the actual name
+ pNet = Abc_NtkFindOrCreateNet( p->pNtk, ppNames[2*k+1] );
+ pTerm = Abc_NtkCreateBi( p->pNtk );
+ Abc_ObjAddFanin( pBox, pTerm );
+ Abc_ObjAddFanin( pTerm, pNet );
+ }
+ Abc_NtkForEachPo( pModel, pTerm, i )
+ {
+ // find this terminal among the formal outputs of the subcircuit
+ pName = Abc_ObjName(Abc_ObjFanin0(pTerm));
+ for ( k = 0; k < nEquals; k++ )
+ if ( !strcmp( ppNames[2*k], pName ) )
+ break;
+ if ( k == nEquals )
+ {
+ sprintf( p->pMan->sError, "Line %d: Cannot find PO \"%s\" of the modell \"%s\" as a formal output of the subcircuit.",
+ Io_MvGetLine(p->pMan, pToken), pName, Abc_NtkName(pModel) );
+ return 0;
+ }
+ // create the BI with the actual name
+ pNet = Abc_NtkFindOrCreateNet( p->pNtk, ppNames[2*k+1] );
+ pTerm = Abc_NtkCreateBo( p->pNtk );
+ Abc_ObjAddFanin( pNet, pTerm );
+ Abc_ObjAddFanin( pTerm, pBox );
+ }
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Parses the mv line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLineMv( Io_MvMod_t * p, char * pLine )
+{
+ Vec_Ptr_t * vTokens = p->pMan->vTokens;
+ Abc_Obj_t * pObj;
+ Io_MvVar_t * pVar;
+ Extra_MmFlex_t * pFlex;
+ char * pName;
+ int nCommas, nValues, i, k;
+ // count commas and get the tokens
+ nCommas = Io_MvCountChars( pLine, ',' );
+ Io_MvSplitIntoTokensAndClear( vTokens, pLine, '\0', ',' );
+ pName = Vec_PtrEntry(vTokens,0);
+ assert( !strcmp(pName, "mv") );
+ // get the number of values
+ if ( Vec_PtrSize(vTokens) <= nCommas + 2 )
+ {
+ sprintf( p->pMan->sError, "Line %d: The number of values in not specified in .mv line.", Io_MvGetLine(p->pMan, pName), pName );
+ return 0;
+ }
+ nValues = atoi( Vec_PtrEntry(vTokens,nCommas+2) );
+ if ( nValues < 2 || nValues > IO_BLIFMV_MAXVALUES )
+ {
+ sprintf( p->pMan->sError, "Line %d: The number of values (%d) is incorrect (should be >= 2 and <= %d).",
+ Io_MvGetLine(p->pMan, pName), nValues, IO_BLIFMV_MAXVALUES );
+ return 0;
+ }
+ // if there is no symbolic values, quit
+ if ( nValues == 2 && Vec_PtrSize(vTokens) == nCommas + 3 )
+ return 1;
+ if ( Vec_PtrSize(vTokens) > nCommas + 3 && Vec_PtrSize(vTokens) - (nCommas + 3) != nValues )
+ {
+ sprintf( p->pMan->sError, "Line %d: Wrong number (%d) of symbolic value names (should be %d).",
+ Io_MvGetLine(p->pMan, pName), Vec_PtrSize(vTokens) - (nCommas + 3), nValues );
+ return 0;
+ }
+ // go through variables
+ pFlex = Abc_NtkMvVarMan( p->pNtk );
+ for ( i = 0; i <= nCommas; i++ )
+ {
+ pName = Vec_PtrEntry( vTokens, i+1 );
+ pObj = Abc_NtkFindOrCreateNet( p->pNtk, pName );
+ // allocate variable
+ pVar = (Io_MvVar_t *)Extra_MmFlexEntryFetch( pFlex, sizeof(Io_MvVar_t) );
+ pVar->nValues = nValues;
+ pVar->pNames = NULL;
+ // create names
+ if ( Vec_PtrSize(vTokens) > nCommas + 3 )
+ {
+ pVar->pNames = (char **)Extra_MmFlexEntryFetch( pFlex, sizeof(char *) * nValues );
+ Vec_PtrForEachEntryStart( vTokens, pName, k, nCommas + 3 )
+ {
+ pVar->pNames[k-(nCommas + 3)] = (char *)Extra_MmFlexEntryFetch( pFlex, strlen(pName) + 1 );
+ strcpy( pVar->pNames[k-(nCommas + 3)], pName );
+ }
+ }
+ // save the variable
+ Abc_ObjSetMvVar( pObj, pVar );
+ }
+ // make sure the names are unique
+ if ( pVar->pNames )
+ {
+ for ( i = 0; i < nValues; i++ )
+ for ( k = i+1; k < nValues; k++ )
+ if ( !strcmp(pVar->pNames[i], pVar->pNames[k]) )
+ {
+ pName = Vec_PtrEntry(vTokens,0);
+ sprintf( p->pMan->sError, "Line %d: Symbolic value name \"%s\" is repeated in .mv line.",
+ Io_MvGetLine(p->pMan, pName), pVar->pNames[i] );
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the values into the BLIF-MV representation for the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvWriteValues( Abc_Obj_t * pNode, Vec_Str_t * vFunc )
+{
+ char Buffer[10];
+ Abc_Obj_t * pFanin;
+ int i;
+ // add the fanin number of values
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ sprintf( Buffer, "%d", Abc_ObjMvVarNum(pFanin) );
+ Vec_StrAppend( vFunc, Buffer );
+ Vec_StrPush( vFunc, ' ' );
+ }
+ // add the node number of values
+ sprintf( Buffer, "%d", Abc_ObjMvVarNum(Abc_ObjFanout0(pNode)) );
+ Vec_StrAppend( vFunc, Buffer );
+ Vec_StrPush( vFunc, '\n' );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Translated one literal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLiteralMv( Io_MvMod_t * p, Abc_Obj_t * pNode, char * pToken, Vec_Str_t * vFunc, int iLit )
+{
+ char Buffer[10];
+ Io_MvVar_t * pVar;
+ Abc_Obj_t * pFanin, * pNet;
+ char * pCur, * pNext;
+ int i;
+ // consider the equality literal
+ if ( pToken[0] == '=' )
+ {
+ // find the fanins
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ if ( !strcmp( Abc_ObjName(pFanin), pToken + 1 ) )
+ break;
+ if ( i == Abc_ObjFaninNum(pNode) )
+ {
+ sprintf( p->pMan->sError, "Line %d: Node name in the table \"%s\" cannot be found on .names line.",
+ Io_MvGetLine(p->pMan, pToken), pToken + 1 );
+ return 0;
+ }
+ Vec_StrPush( vFunc, '=' );
+ sprintf( Buffer, "%d", i );
+ Vec_StrAppend( vFunc, Buffer );
+ Vec_StrPush( vFunc, (char)((iLit == -1)? '\n' : ' ') );
+ return 1;
+ }
+ // consider regular literal
+ assert( iLit < Abc_ObjFaninNum(pNode) );
+ pNet = iLit >= 0 ? Abc_ObjFanin(pNode, iLit) : Abc_ObjFanout0(pNode);
+ pVar = Abc_ObjMvVar( pNet );
+ // if the var is absent or has no symbolic values quit
+ if ( pVar == NULL || pVar->pNames == NULL )
+ {
+ Vec_StrAppend( vFunc, pToken );
+ Vec_StrPush( vFunc, (char)((iLit == -1)? '\n' : ' ') );
+ return 1;
+ }
+ // parse the literal using symbolic values
+ for ( pCur = pToken; *pCur; pCur++ )
+ {
+ if ( Io_MvCharIsMvSymb(*pCur) )
+ {
+ Vec_StrPush( vFunc, *pCur );
+ continue;
+ }
+ // find the next MvSymb char
+ for ( pNext = pCur+1; *pNext; pNext++ )
+ if ( Io_MvCharIsMvSymb(*pNext) )
+ break;
+ // look for the value name
+ for ( i = 0; i < pVar->nValues; i++ )
+ if ( !strncmp( pVar->pNames[i], pCur, pNext-pCur ) )
+ break;
+ if ( i == pVar->nValues )
+ {
+ *pNext = 0;
+ sprintf( p->pMan->sError, "Line %d: Cannot find value name \"%s\" among the value names of variable \"%s\".",
+ Io_MvGetLine(p->pMan, pToken), pCur, Abc_ObjName(pNet) );
+ return 0;
+ }
+ // value name is found
+ sprintf( Buffer, "%d", i );
+ Vec_StrAppend( vFunc, Buffer );
+ // update the pointer
+ pCur = pNext - 1;
+ }
+ Vec_StrPush( vFunc, (char)((iLit == -1)? '\n' : ' ') );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the MV-SOP cover from the file parsing info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static char * Io_MvParseTableMv( Io_MvMod_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vTokens2, int nInputs, int nOutputs, int iOut )
+{
+ Vec_Str_t * vFunc = p->pMan->vFunc;
+ char * pFirst, * pToken;
+ int iStart, i;
+ // prepare the place for the cover
+ Vec_StrClear( vFunc );
+ // write the number of values
+// Io_MvWriteValues( pNode, vFunc );
+ // get the first token
+ pFirst = Vec_PtrEntry( vTokens2, 0 );
+ if ( pFirst[0] == '.' )
+ {
+ // write the default literal
+ Vec_StrPush( vFunc, 'd' );
+ pToken = Vec_PtrEntry(vTokens2, 1 + iOut);
+ if ( !Io_MvParseLiteralMv( p, pNode, pToken, vFunc, -1 ) )
+ return NULL;
+ iStart = 1 + nOutputs;
+ }
+ else
+ iStart = 0;
+ // write the remaining literals
+ while ( iStart < Vec_PtrSize(vTokens2) )
+ {
+ // input literals
+ for ( i = 0; i < nInputs; i++ )
+ {
+ pToken = Vec_PtrEntry( vTokens2, iStart + i );
+ if ( !Io_MvParseLiteralMv( p, pNode, pToken, vFunc, i ) )
+ return NULL;
+ }
+ // output literal
+ pToken = Vec_PtrEntry( vTokens2, iStart + nInputs + iOut );
+ if ( !Io_MvParseLiteralMv( p, pNode, pToken, vFunc, -1 ) )
+ return NULL;
+ // update the counter
+ iStart += nInputs + nOutputs;
+ }
+ Vec_StrPush( vFunc, '\0' );
+ return Vec_StrArray( vFunc );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds reset circuitry corresponding to latch with pName.]
+
+ Description [Returns the reset node's net.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static Abc_Obj_t * Io_MvParseAddResetCircuit( Io_MvMod_t * p, char * pName )
+{
+ char Buffer[50];
+ Abc_Obj_t * pNode, * pData0Net, * pData1Net, * pResetLONet, * pOutNet;
+ Io_MvVar_t * pVar;
+ // make sure the reset latch exists
+ assert( p->pResetLatch != NULL );
+ // get the reset net
+ pResetLONet = Abc_ObjFanout0(Abc_ObjFanout0(p->pResetLatch));
+ // get the output net
+ pOutNet = Abc_NtkFindOrCreateNet( p->pNtk, pName );
+ // get the data nets
+ pData0Net = Abc_NtkFindOrCreateNet( p->pNtk, Abc_ObjNameSuffix(pOutNet, "_reset") );
+ pData1Net = Abc_NtkFindOrCreateNet( p->pNtk, Abc_ObjNameSuffix(pOutNet, "_out") );
+ // duplicate MV variables
+ if ( Abc_NtkMvVar(p->pNtk) )
+ {
+ pVar = Abc_ObjMvVar( pOutNet );
+ Abc_ObjSetMvVar( pData0Net, Abc_NtkMvVarDup(p->pNtk, pVar) );
+ Abc_ObjSetMvVar( pData1Net, Abc_NtkMvVarDup(p->pNtk, pVar) );
+ }
+ // create the node
+ pNode = Abc_NtkCreateNode( p->pNtk );
+ // create the output net
+ Abc_ObjAddFanin( pOutNet, pNode );
+ // create the function
+ if ( p->pMan->fBlifMv )
+ {
+// Vec_Att_t * p = Abc_NtkMvVar( pNtk );
+ int nValues = Abc_ObjMvVarNum(pOutNet);
+// sprintf( Buffer, "2 %d %d %d\n1 - - =1\n0 - - =2\n", nValues, nValues, nValues );
+ sprintf( Buffer, "1 - - =1\n0 - - =2\n" );
+ pNode->pData = Abc_SopRegister( p->pNtk->pManFunc, Buffer );
+ }
+ else
+ pNode->pData = Abc_SopCreateMux( p->pNtk->pManFunc );
+ // add nets
+ Abc_ObjAddFanin( pNode, pResetLONet );
+ Abc_ObjAddFanin( pNode, pData1Net );
+ Abc_ObjAddFanin( pNode, pData0Net );
+ return pData0Net;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the nodes line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLineNamesMvOne( Io_MvMod_t * p, Vec_Ptr_t * vTokens, Vec_Ptr_t * vTokens2, int nInputs, int nOutputs, int iOut, int fReset )
+{
+ Abc_Obj_t * pNet, * pNode;
+ char * pName;
+ // get the output name
+ pName = Vec_PtrEntry( vTokens, Vec_PtrSize(vTokens) - nOutputs + iOut );
+ // create the node
+ if ( fReset )
+ {
+ pNet = Abc_NtkFindNet( p->pNtk, pName );
+ if ( pNet == NULL )
+ {
+ sprintf( p->pMan->sError, "Line %d: Latch with output signal \"%s\" does not exist.", Io_MvGetLine(p->pMan, pName), pName );
+ return 0;
+ }
+/*
+ if ( !Abc_ObjIsBo(Abc_ObjFanin0(pNet)) )
+ {
+ sprintf( p->pMan->sError, "Line %d: Reset line \"%s\" defines signal that is not a latch output.", Io_MvGetLine(p->pMan, pName), pName );
+ return 0;
+ }
+*/
+ // construct the reset circuit and get the reset net feeding into it
+ pNet = Io_MvParseAddResetCircuit( p, pName );
+ // create fanins
+ pNode = Io_ReadCreateNode( p->pNtk, Abc_ObjName(pNet), (char **)(vTokens->pArray + 1), nInputs );
+ assert( nInputs == Vec_PtrSize(vTokens) - 2 );
+ }
+ else
+ {
+ pNet = Abc_NtkFindOrCreateNet( p->pNtk, pName );
+ if ( Abc_ObjFaninNum(pNet) > 0 )
+ {
+ sprintf( p->pMan->sError, "Line %d: Signal \"%s\" is defined more than once.", Io_MvGetLine(p->pMan, pName), pName );
+ return 0;
+ }
+ pNode = Io_ReadCreateNode( p->pNtk, pName, (char **)(vTokens->pArray + 1), nInputs );
+ }
+ // create the cover
+ pNode->pData = Io_MvParseTableMv( p, pNode, vTokens2, nInputs, nOutputs, iOut );
+ if ( pNode->pData == NULL )
+ return 0;
+ pNode->pData = Abc_SopRegister( p->pNtk->pManFunc, pNode->pData );
+//printf( "Finished parsing node \"%s\" with table:\n%s\n", pName, pNode->pData );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the nodes line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLineNamesMv( Io_MvMod_t * p, char * pLine, int fReset )
+{
+ Vec_Ptr_t * vTokens = p->pMan->vTokens;
+ Vec_Ptr_t * vTokens2 = p->pMan->vTokens2;
+ Abc_Obj_t * pNet;
+ char * pName, * pFirst, * pArrow;
+ int nInputs, nOutputs, nLiterals, nLines, i;
+ assert( p->pMan->fBlifMv );
+ // get the arrow if it is present
+ pArrow = Io_MvFindArrow( pLine );
+ if ( !p->pMan->fBlifMv && pArrow )
+ {
+ sprintf( p->pMan->sError, "Line %d: Multi-output node symbol (->) in binary BLIF file.", Io_MvGetLine(p->pMan, pLine) );
+ return 0;
+ }
+ // split names line into tokens
+ Io_MvSplitIntoTokens( vTokens, pLine, '\0' );
+ if ( fReset )
+ assert( !strcmp(Vec_PtrEntry(vTokens,0), "r") || !strcmp(Vec_PtrEntry(vTokens,0), "reset") );
+ else
+ assert( !strcmp(Vec_PtrEntry(vTokens,0), "names") || !strcmp(Vec_PtrEntry(vTokens,0), "table") );
+ // find the number of inputs and outputs
+ nInputs = Vec_PtrSize(vTokens) - 2;
+ nOutputs = 1;
+ if ( pArrow != NULL )
+ {
+ for ( i = Vec_PtrSize(vTokens) - 2; i >= 1; i-- )
+ if ( pArrow < (char*)Vec_PtrEntry(vTokens,i) )
+ {
+ nInputs--;
+ nOutputs++;
+ }
+ }
+ // split table into tokens
+ pName = Vec_PtrEntryLast( vTokens );
+ Io_MvSplitIntoTokensMv( vTokens2, pName + strlen(pName) );
+ pFirst = Vec_PtrEntry( vTokens2, 0 );
+ if ( pFirst[0] == '.' )
+ {
+ assert( pFirst[1] == 'd' );
+ nLiterals = Vec_PtrSize(vTokens2) - 1 - nOutputs;
+ }
+ else
+ nLiterals = Vec_PtrSize(vTokens2);
+ // check the number of lines
+ if ( nLiterals % (nInputs + nOutputs) != 0 )
+ {
+ sprintf( p->pMan->sError, "Line %d: Wrong number of literals in the table of node \"%s\". (Spaces inside literals are not allowed.)", Io_MvGetLine(p->pMan, pFirst), pName );
+ return 0;
+ }
+ // check for the ND table
+ nLines = nLiterals / (nInputs + nOutputs);
+ if ( nInputs == 0 && nLines > 1 )
+ {
+ // add the outputs to the PIs
+ for ( i = 0; i < nOutputs; i++ )
+ {
+ pName = Vec_PtrEntry( vTokens, Vec_PtrSize(vTokens) - nOutputs + i );
+ // get the net corresponding to this node
+ pNet = Abc_NtkFindOrCreateNet(p->pNtk, pName);
+ if ( fReset )
+ {
+ assert( p->pResetLatch != NULL );
+ // construct the reset circuit and get the reset net feeding into it
+ pNet = Io_MvParseAddResetCircuit( p, pName );
+ }
+ // add the new PI node
+// Abc_ObjAddFanin( pNet, Abc_NtkCreatePi(p->pNtk) );
+// fprintf( stdout, "Io_ReadBlifMv(): Adding PI for internal non-deterministic node \"%s\".\n", pName );
+ p->pMan->nNDnodes++;
+ Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst0(p->pNtk) );
+ }
+ return 1;
+ }
+ // iterate through the outputs
+ for ( i = 0; i < nOutputs; i++ )
+ {
+ if ( !Io_MvParseLineNamesMvOne( p, vTokens, vTokens2, nInputs, nOutputs, i, fReset ) )
+ return 0;
+ }
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the SOP cover from the file parsing info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static char * Io_MvParseTableBlif( Io_MvMod_t * p, char * pTable, int nFanins )
+{
+ Vec_Ptr_t * vTokens = p->pMan->vTokens;
+ Vec_Str_t * vFunc = p->pMan->vFunc;
+ char * pProduct, * pOutput;
+ int i, Polarity = -1;
+
+ p->pMan->nTablesRead++;
+ // get the tokens
+ Io_MvSplitIntoTokens( vTokens, pTable, '.' );
+ if ( Vec_PtrSize(vTokens) == 0 )
+ return Abc_SopCreateConst0( p->pNtk->pManFunc );
+ if ( Vec_PtrSize(vTokens) == 1 )
+ {
+ pOutput = Vec_PtrEntry( vTokens, 0 );
+ if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] )
+ {
+ sprintf( p->pMan->sError, "Line %d: Constant table has wrong output value \"%s\".", Io_MvGetLine(p->pMan, pOutput), pOutput );
+ return NULL;
+ }
+ return pOutput[0] == '0' ? Abc_SopCreateConst0(p->pNtk->pManFunc) : Abc_SopCreateConst1(p->pNtk->pManFunc);
+ }
+ pProduct = Vec_PtrEntry( vTokens, 0 );
+ if ( Vec_PtrSize(vTokens) % 2 == 1 )
+ {
+ sprintf( p->pMan->sError, "Line %d: Table has odd number of tokens (%d).", Io_MvGetLine(p->pMan, pProduct), Vec_PtrSize(vTokens) );
+ return NULL;
+ }
+ // parse the table
+ Vec_StrClear( vFunc );
+ for ( i = 0; i < Vec_PtrSize(vTokens)/2; i++ )
+ {
+ pProduct = Vec_PtrEntry( vTokens, 2*i + 0 );
+ pOutput = Vec_PtrEntry( vTokens, 2*i + 1 );
+ if ( strlen(pProduct) != (unsigned)nFanins )
+ {
+ sprintf( p->pMan->sError, "Line %d: Cube \"%s\" has size different from the fanin count (%d).", Io_MvGetLine(p->pMan, pProduct), pProduct, nFanins );
+ return NULL;
+ }
+ if ( ((pOutput[0] - '0') & 0x8E) || pOutput[1] )
+ {
+ sprintf( p->pMan->sError, "Line %d: Output value \"%s\" is incorrect.", Io_MvGetLine(p->pMan, pProduct), pOutput );
+ return NULL;
+ }
+ if ( Polarity == -1 )
+ Polarity = pOutput[0] - '0';
+ else if ( Polarity != pOutput[0] - '0' )
+ {
+ sprintf( p->pMan->sError, "Line %d: Output value \"%s\" differs from the value in the first line of the table (%d).", Io_MvGetLine(p->pMan, pProduct), pOutput, Polarity );
+ return NULL;
+ }
+ // parse one product
+ Vec_StrAppend( vFunc, pProduct );
+ Vec_StrPush( vFunc, ' ' );
+ Vec_StrPush( vFunc, pOutput[0] );
+ Vec_StrPush( vFunc, '\n' );
+ }
+ Vec_StrPush( vFunc, '\0' );
+ return Vec_StrArray( vFunc );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Parses the nodes line.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLineNamesBlif( Io_MvMod_t * p, char * pLine )
+{
+ Vec_Ptr_t * vTokens = p->pMan->vTokens;
+ Abc_Obj_t * pNet, * pNode;
+ char * pName;
+ assert( !p->pMan->fBlifMv );
+ Io_MvSplitIntoTokens( vTokens, pLine, '\0' );
+ // parse the mapped node
+ if ( !strcmp(Vec_PtrEntry(vTokens,0), "gate") )
+ return Io_MvParseLineGateBlif( p, vTokens );
+ // parse the regular name line
+ assert( !strcmp(Vec_PtrEntry(vTokens,0), "names") );
+ pName = Vec_PtrEntryLast( vTokens );
+ pNet = Abc_NtkFindOrCreateNet( p->pNtk, pName );
+ if ( Abc_ObjFaninNum(pNet) > 0 )
+ {
+ sprintf( p->pMan->sError, "Line %d: Signal \"%s\" is defined more than once.", Io_MvGetLine(p->pMan, pName), pName );
+ return 0;
+ }
+ // create fanins
+ pNode = Io_ReadCreateNode( p->pNtk, pName, (char **)(vTokens->pArray + 1), Vec_PtrSize(vTokens) - 2 );
+ // parse the table of this node
+ pNode->pData = Io_MvParseTableBlif( p, pName + strlen(pName), Abc_ObjFaninNum(pNode) );
+ if ( pNode->pData == NULL )
+ return 0;
+ pNode->pData = Abc_SopRegister( p->pNtk->pManFunc, pNode->pData );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicate the MV variable.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Io_MvVar_t * Abc_NtkMvVarDup( Abc_Ntk_t * pNtk, Io_MvVar_t * pVar )
+{
+ Extra_MmFlex_t * pFlex;
+ Io_MvVar_t * pVarDup;
+ int i;
+ if ( pVar == NULL )
+ return NULL;
+ pFlex = Abc_NtkMvVarMan( pNtk );
+ assert( pFlex != NULL );
+ pVarDup = (Io_MvVar_t *)Extra_MmFlexEntryFetch( pFlex, sizeof(Io_MvVar_t) );
+ pVarDup->nValues = pVar->nValues;
+ pVarDup->pNames = NULL;
+ if ( pVar->pNames == NULL )
+ return pVarDup;
+ pVarDup->pNames = (char **)Extra_MmFlexEntryFetch( pFlex, sizeof(char *) * pVar->nValues );
+ for ( i = 0; i < pVar->nValues; i++ )
+ {
+ pVarDup->pNames[i] = (char *)Extra_MmFlexEntryFetch( pFlex, strlen(pVar->pNames[i]) + 1 );
+ strcpy( pVarDup->pNames[i], pVar->pNames[i] );
+ }
+ return pVarDup;
+}
+
+
+#include "mio.h"
+#include "main.h"
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static char * Io_ReadBlifCleanName( char * pName )
+{
+ int i, Length;
+ Length = strlen(pName);
+ for ( i = 0; i < Length; i++ )
+ if ( pName[i] == '=' )
+ return pName + i + 1;
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int Io_MvParseLineGateBlif( Io_MvMod_t * p, Vec_Ptr_t * vTokens )
+{
+ Mio_Library_t * pGenlib;
+ Mio_Gate_t * pGate;
+ Abc_Obj_t * pNode;
+ char ** ppNames, * pName;
+ int i, nNames;
+
+ pName = vTokens->pArray[0];
+
+ // check that the library is available
+ pGenlib = Abc_FrameReadLibGen();
+ if ( pGenlib == NULL )
+ {
+ sprintf( p->pMan->sError, "Line %d: The current library is not available.", Io_MvGetLine(p->pMan, pName) );
+ return 0;
+ }
+
+ // create a new node and add it to the network
+ if ( vTokens->nSize < 2 )
+ {
+ sprintf( p->pMan->sError, "Line %d: The .gate line has less than two tokens.", Io_MvGetLine(p->pMan, pName) );
+ return 0;
+ }
+
+ // get the gate
+ pGate = Mio_LibraryReadGateByName( pGenlib, vTokens->pArray[1] );
+ if ( pGate == NULL )
+ {
+ sprintf( p->pMan->sError, "Line %d: Cannot find gate \"%s\" in the library.", Io_MvGetLine(p->pMan, pName), vTokens->pArray[1] );
+ return 0;
+ }
+
+ // if this is the first line with gate, update the network type
+ if ( Abc_NtkNodeNum(p->pNtk) == 0 )
+ {
+ assert( p->pNtk->ntkFunc == ABC_FUNC_SOP );
+ p->pNtk->ntkFunc = ABC_FUNC_MAP;
+ Extra_MmFlexStop( p->pNtk->pManFunc );
+ p->pNtk->pManFunc = pGenlib;
+ }
+
+ // remove the formal parameter names
+ for ( i = 2; i < vTokens->nSize; i++ )
+ {
+ vTokens->pArray[i] = Io_ReadBlifCleanName( vTokens->pArray[i] );
+ if ( vTokens->pArray[i] == NULL )
+ {
+ sprintf( p->pMan->sError, "Line %d: Invalid gate input assignment.", Io_MvGetLine(p->pMan, pName) );
+ return 0;
+ }
+ }
+
+ // create the node
+ ppNames = (char **)vTokens->pArray + 2;
+ nNames = vTokens->nSize - 3;
+ pNode = Io_ReadCreateNode( p->pNtk, ppNames[nNames], ppNames, nNames );
+
+ // set the pointer to the functionality of the node
+ Abc_ObjSetData( pNode, pGate );
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioReadDsd.c b/src/base/io/ioReadDsd.c
new file mode 100644
index 00000000..1ab726e5
--- /dev/null
+++ b/src/base/io/ioReadDsd.c
@@ -0,0 +1,308 @@
+/**CFile****************************************************************
+
+ FileName [ioReadDsd.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: ioReadDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Finds the end of the part.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Io_ReadDsdFindEnd( char * pCur )
+{
+ char * pEnd;
+ int nParts = 0;
+ assert( *pCur == '(' );
+ for ( pEnd = pCur; *pEnd; pEnd++ )
+ {
+ if ( *pEnd == '(' )
+ nParts++;
+ else if ( *pEnd == ')' )
+ nParts--;
+ if ( nParts == 0 )
+ return pEnd;
+ }
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Splits the formula into parts.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadDsdStrSplit( char * pCur, char * pParts[], int * pTypeXor )
+{
+ int fAnd = 0, fXor = 0, fPri = 0, nParts = 0;
+ assert( *pCur );
+ // process the parts
+ while ( 1 )
+ {
+ // save the current part
+ pParts[nParts++] = pCur;
+ // skip the complement
+ if ( *pCur == '!' )
+ pCur++;
+ // skip var
+ if ( *pCur >= 'a' && *pCur <= 'z' )
+ pCur++;
+ else
+ {
+ // skip hex truth table
+ while ( (*pCur >= '0' && *pCur <= '9') || (*pCur >= 'A' && *pCur <= 'F') )
+ pCur++;
+ // process parantheses
+ if ( *pCur != '(' )
+ {
+ printf( "Cannot find the opening paranthesis.\n" );
+ break;
+ }
+ // find the corresponding closing paranthesis
+ pCur = Io_ReadDsdFindEnd( pCur );
+ if ( pCur == NULL )
+ {
+ printf( "Cannot find the closing paranthesis.\n" );
+ break;
+ }
+ pCur++;
+ }
+ // check the end
+ if ( *pCur == 0 )
+ break;
+ // check symbol
+ if ( *pCur != '*' && *pCur != '+' && *pCur != ',' )
+ {
+ printf( "Wrong separating symbol.\n" );
+ break;
+ }
+ // remember the symbol
+ fAnd |= (*pCur == '*');
+ fXor |= (*pCur == '+');
+ fPri |= (*pCur == ',');
+ *pCur++ = 0;
+ }
+ // check separating symbols
+ if ( fAnd + fXor + fPri > 1 )
+ {
+ printf( "Different types of separating symbol ennPartsed.\n" );
+ return 0;
+ }
+ *pTypeXor = fXor;
+ return nParts;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively parses the formula.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Io_ReadDsd_rec( Abc_Ntk_t * pNtk, char * pCur, char * pSop )
+{
+ Abc_Obj_t * pObj, * pFanin;
+ char * pEnd, * pParts[32];
+ int i, nParts, TypeExor;
+
+ // consider complemented formula
+ if ( *pCur == '!' )
+ {
+ pObj = Io_ReadDsd_rec( pNtk, pCur + 1, NULL );
+ return Abc_NtkCreateNodeInv( pNtk, pObj );
+ }
+ if ( *pCur == '(' )
+ {
+ assert( pCur[strlen(pCur)-1] == ')' );
+ pCur[strlen(pCur)-1] = 0;
+ nParts = Io_ReadDsdStrSplit( pCur+1, pParts, &TypeExor );
+ if ( nParts == 0 )
+ {
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ pObj = Abc_NtkCreateNode( pNtk );
+ if ( pSop )
+ {
+// for ( i = nParts - 1; i >= 0; i-- )
+ for ( i = 0; i < nParts; i++ )
+ {
+ pFanin = Io_ReadDsd_rec( pNtk, pParts[i], NULL );
+ if ( pFanin == NULL )
+ return NULL;
+ Abc_ObjAddFanin( pObj, pFanin );
+ }
+ }
+ else
+ {
+ for ( i = 0; i < nParts; i++ )
+ {
+ pFanin = Io_ReadDsd_rec( pNtk, pParts[i], NULL );
+ if ( pFanin == NULL )
+ return NULL;
+ Abc_ObjAddFanin( pObj, pFanin );
+ }
+ }
+ if ( pSop )
+ pObj->pData = Abc_SopRegister( pNtk->pManFunc, pSop );
+ else if ( TypeExor )
+ pObj->pData = Abc_SopCreateXorSpecial( pNtk->pManFunc, nParts );
+ else
+ pObj->pData = Abc_SopCreateAnd( pNtk->pManFunc, nParts, NULL );
+ return pObj;
+ }
+ if ( *pCur >= 'a' && *pCur <= 'z' )
+ {
+ assert( *(pCur+1) == 0 );
+ return Abc_NtkPi( pNtk, *pCur - 'a' );
+ }
+
+ // skip hex truth table
+ pEnd = pCur;
+ while ( (*pEnd >= '0' && *pEnd <= '9') || (*pEnd >= 'A' && *pEnd <= 'F') )
+ pEnd++;
+ if ( *pEnd != '(' )
+ {
+ printf( "Cannot find the end of hexidecimal truth table.\n" );
+ return NULL;
+ }
+
+ // parse the truth table
+ *pEnd = 0;
+ pSop = Abc_SopFromTruthHex( pCur );
+ *pEnd = '(';
+ pObj = Io_ReadDsd_rec( pNtk, pEnd, pSop );
+ free( pSop );
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the DSD network of the formula.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadDsd( char * pForm )
+{
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pObj, * pTop;
+ Vec_Ptr_t * vNames;
+ char * pCur, * pFormCopy;
+ int i, nInputs;
+
+ // count the number of elementary variables
+ nInputs = 0;
+ for ( pCur = pForm; *pCur; pCur++ )
+ if ( *pCur >= 'a' && *pCur <= 'z' )
+ nInputs = ABC_MAX( nInputs, *pCur - 'a' );
+ nInputs++;
+
+ // create the network
+ pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
+ pNtk->pName = Extra_UtilStrsav( "dsd" );
+
+ // create PIs
+ vNames = Abc_NodeGetFakeNames( nInputs );
+ for ( i = 0; i < nInputs; i++ )
+ Abc_ObjAssignName( Abc_NtkCreatePi(pNtk), Vec_PtrEntry(vNames, i), NULL );
+ Abc_NodeFreeNames( vNames );
+
+ // transform the formula by inserting parantheses
+ // this transforms strings like PRIME(a,b,cd) into (PRIME((a),(b),(cd)))
+ pCur = pFormCopy = ALLOC( char, 3 * strlen(pForm) + 10 );
+ *pCur++ = '(';
+ for ( ; *pForm; pForm++ )
+ if ( *pForm == '(' )
+ {
+ *pCur++ = '(';
+ *pCur++ = '(';
+ }
+ else if ( *pForm == ')' )
+ {
+ *pCur++ = ')';
+ *pCur++ = ')';
+ }
+ else if ( *pForm == ',' )
+ {
+ *pCur++ = ')';
+ *pCur++ = ',';
+ *pCur++ = '(';
+ }
+ else
+ *pCur++ = *pForm;
+ *pCur++ = ')';
+ *pCur = 0;
+
+ // parse the formula
+ pObj = Io_ReadDsd_rec( pNtk, pFormCopy, NULL );
+ free( pFormCopy );
+ if ( pObj == NULL )
+ return NULL;
+
+ // create output
+ pTop = Abc_NtkCreatePo(pNtk);
+ Abc_ObjAssignName( pTop, "F", NULL );
+ Abc_ObjAddFanin( pTop, pObj );
+
+ // create the only PO
+ if ( !Abc_NtkCheck( pNtk ) )
+ {
+ fprintf( stdout, "Io_ReadDsd(): Network check has failed.\n" );
+ Abc_NtkDelete( pNtk );
+ return NULL;
+ }
+ return pNtk;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+
diff --git a/src/base/io/ioReadEdif.c b/src/base/io/ioReadEdif.c
index 48a1722b..188e5b8c 100644
--- a/src/base/io/ioReadEdif.c
+++ b/src/base/io/ioReadEdif.c
@@ -27,7 +27,7 @@
static Abc_Ntk_t * Io_ReadEdifNetwork( Extra_FileReader_t * p );
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
@@ -46,8 +46,11 @@ Abc_Ntk_t * Io_ReadEdif( char * pFileName, int fCheck )
Extra_FileReader_t * p;
Abc_Ntk_t * pNtk;
+ printf( "Currently this parser does not work!\n" );
+ return NULL;
+
// start the file
- p = Extra_FileReaderAlloc( pFileName, "#", "\n", " \t\r()" );
+ p = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t()" );
if ( p == NULL )
return NULL;
@@ -114,11 +117,15 @@ Abc_Ntk_t * Io_ReadEdifNetwork( Extra_FileReader_t * p )
vTokens = Extra_FileReaderGetTokens(p);
pGateName = vTokens->pArray[1];
if ( strncmp( pGateName, "Flip", 4 ) == 0 )
+ {
pObj = Abc_NtkCreateLatch( pNtk );
+ Abc_LatchSetInit0( pObj );
+ }
else
{
pObj = Abc_NtkCreateNode( pNtk );
- pObj->pData = Abc_NtkRegisterName( pNtk, pGateName );
+// pObj->pData = Abc_NtkRegisterName( pNtk, pGateName );
+ pObj->pData = Extra_UtilStrsav( pGateName ); // memory leak!!!
}
Abc_ObjAddFanin( pNet, pObj );
}
@@ -178,7 +185,7 @@ Abc_Ntk_t * Io_ReadEdifNetwork( Extra_FileReader_t * p )
else if ( strcmp( vTokens->pArray[0], "design" ) == 0 )
{
free( pNtk->pName );
- pNtk->pName = util_strsav( vTokens->pArray[3] );
+ pNtk->pName = Extra_UtilStrsav( vTokens->pArray[3] );
break;
}
}
@@ -188,7 +195,7 @@ Abc_Ntk_t * Io_ReadEdifNetwork( Extra_FileReader_t * p )
Abc_NtkForEachNode( pNtk, pObj, i )
{
if ( strncmp( pObj->pData, "And", 3 ) == 0 )
- Abc_ObjSetData( pObj, Abc_SopCreateAnd(pNtk->pManFunc, Abc_ObjFaninNum(pObj)) );
+ Abc_ObjSetData( pObj, Abc_SopCreateAnd(pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) );
else if ( strncmp( pObj->pData, "Or", 2 ) == 0 )
Abc_ObjSetData( pObj, Abc_SopCreateOr(pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) );
else if ( strncmp( pObj->pData, "Nand", 4 ) == 0 )
diff --git a/src/base/io/ioReadEqn.c b/src/base/io/ioReadEqn.c
index 20d30a1a..e04f2b1a 100644
--- a/src/base/io/ioReadEqn.c
+++ b/src/base/io/ioReadEqn.c
@@ -30,7 +30,7 @@ static int Io_ReadEqnStrFind( Vec_Ptr_t * vTokens, char * pName );
static void Io_ReadEqnStrCutAt( char * pStr, char * pStop, int fUniqueOnly, Vec_Ptr_t * vTokens );
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
@@ -85,19 +85,20 @@ Abc_Ntk_t * Io_ReadEqnNetwork( Extra_FileReader_t * p )
{
ProgressBar * pProgress;
Vec_Ptr_t * vTokens;
- Vec_Ptr_t * vCubes, * vLits, * vVars;
+ Vec_Ptr_t * vVars;
Abc_Ntk_t * pNtk;
Abc_Obj_t * pNode;
- char * pCubesCopy, * pSopCube, * pVarName;
- int iLine, iNum, i, k;
+ char * pNodeName, * pFormula, * pFormulaCopy, * pVarName;
+ int iLine, i;
// allocate the empty network
- pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) );
+ pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_AIG, 1 );
+ // set the specs
+ pNtk->pName = Extra_FileNameGeneric(Extra_FileReaderGetFileName(p));
+ pNtk->pSpec = Extra_UtilStrsav(Extra_FileReaderGetFileName(p));
// go through the lines of the file
- vCubes = Vec_PtrAlloc( 100 );
vVars = Vec_PtrAlloc( 100 );
- vLits = Vec_PtrAlloc( 100 );
pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p) );
for ( iLine = 0; vTokens = Extra_FileReaderGetTokens(p); iLine++ )
{
@@ -131,52 +132,36 @@ Abc_Ntk_t * Io_ReadEqnNetwork( Extra_FileReader_t * p )
}
else
{
- // remove spaces
- pCubesCopy = vTokens->pArray[1];
- Io_ReadEqnStrCompact( pCubesCopy );
+ extern Hop_Obj_t * Parse_FormulaParserEqn( FILE * pOutput, char * pFormInit, Vec_Ptr_t * vVarNames, Hop_Man_t * pMan );
+
+ // get hold of the node name and its formula
+ pNodeName = vTokens->pArray[0];
+ pFormula = vTokens->pArray[1];
+ // compact the formula
+ Io_ReadEqnStrCompact( pFormula );
+
// consider the case of the constant node
- if ( (pCubesCopy[0] == '0' || pCubesCopy[0] == '1') && pCubesCopy[1] == 0 )
+ if ( pFormula[1] == 0 && (pFormula[0] == '0' || pFormula[0] == '1') )
{
- pNode = Io_ReadCreateNode( pNtk, vTokens->pArray[0], NULL, 0 );
- if ( pCubesCopy[0] == '0' )
- pNode->pData = Abc_SopCreateConst0( pNtk->pManFunc );
- else
- pNode->pData = Abc_SopCreateConst1( pNtk->pManFunc );
- continue;
+ pFormulaCopy = NULL;
+ Vec_PtrClear( vVars );
}
- // determine unique variables
- pCubesCopy = util_strsav( pCubesCopy );
- // find the names of the fanins of this node
- Io_ReadEqnStrCutAt( pCubesCopy, "!*+", 1, vVars );
- // create the node
- pNode = Io_ReadCreateNode( pNtk, vTokens->pArray[0], (char **)vVars->pArray, vVars->nSize );
- // split the string into cubes
- Io_ReadEqnStrCutAt( vTokens->pArray[1], "+", 0, vCubes );
- // start the sop
- pNode->pData = Abc_SopStart( pNtk->pManFunc, vCubes->nSize, vVars->nSize );
- // read the cubes
- i = 0;
- Abc_SopForEachCube( pNode->pData, vVars->nSize, pSopCube )
+ else
{
- // split this cube into lits
- Io_ReadEqnStrCutAt( vCubes->pArray[i], "*", 0, vLits );
- // read the literals
- Vec_PtrForEachEntry( vLits, pVarName, k )
- {
- iNum = Io_ReadEqnStrFind( vVars, pVarName + (pVarName[0] == '!') );
- assert( iNum >= 0 );
- pSopCube[iNum] = '1' - (pVarName[0] == '!');
- }
- i++;
+ // make a copy of formula for names
+ pFormulaCopy = Extra_UtilStrsav( pFormula );
+ // find the names of the fanins of this node
+ Io_ReadEqnStrCutAt( pFormulaCopy, "!*+()", 1, vVars );
}
- assert( i == vCubes->nSize );
+ // create the node
+ pNode = Io_ReadCreateNode( pNtk, pNodeName, (char **)Vec_PtrArray(vVars), Vec_PtrSize(vVars) );
+ // derive the function
+ pNode->pData = Parse_FormulaParserEqn( stdout, pFormula, vVars, pNtk->pManFunc );
// remove the cubes
- free( pCubesCopy );
+ FREE( pFormulaCopy );
}
}
Extra_ProgressBarStop( pProgress );
- Vec_PtrFree( vCubes );
- Vec_PtrFree( vLits );
Vec_PtrFree( vVars );
Abc_NtkFinalizeRead( pNtk );
return pNtk;
diff --git a/src/base/io/ioReadPla.c b/src/base/io/ioReadPla.c
index 1e54db5f..fdfdb4f6 100644
--- a/src/base/io/ioReadPla.c
+++ b/src/base/io/ioReadPla.c
@@ -27,7 +27,7 @@
static Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p );
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
@@ -47,7 +47,7 @@ Abc_Ntk_t * Io_ReadPla( char * pFileName, int fCheck )
Abc_Ntk_t * pNtk;
// start the file
- p = Extra_FileReaderAlloc( pFileName, "#", "\n", " \t\r|" );
+ p = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t|" );
if ( p == NULL )
return NULL;
@@ -131,7 +131,7 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
for ( i = 1; i < vTokens->nSize; i++ )
Io_ReadCreatePo( pNtk, vTokens->pArray[i] );
}
- else
+ else
{
// check if the input/output names are given
if ( Abc_NtkPiNum(pNtk) == 0 )
@@ -229,6 +229,7 @@ Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
{
Abc_ObjRemoveFanins(pNode);
pNode->pData = Abc_SopRegister( pNtk->pManFunc, " 0\n" );
+ Vec_StrFree( ppSops[i] );
continue;
}
Vec_StrPush( ppSops[i], 0 );
diff --git a/src/base/io/ioReadVerilog.c b/src/base/io/ioReadVerilog.c
index f4855dde..c64e330c 100644
--- a/src/base/io/ioReadVerilog.c
+++ b/src/base/io/ioReadVerilog.c
@@ -6,7 +6,7 @@
PackageName [Command processing package.]
- Synopsis [Procedures to read a subset of structural Verilog from IWLS 2005 benchmark.]
+ Synopsis [Procedure to read network from file.]
Author [Alan Mishchenko]
@@ -24,144 +24,15 @@
/// 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 );
+extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck, int fUseMemMan );
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
- Synopsis [Reads the network from a Verilog file.]
-
- Description [Works only for IWLS 2005 benchmarks.]
-
- 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_NtkCheckRead( pNtk ) )
- {
- printf( "Io_ReadVerilog: The network check has failed.\n" );
- Abc_NtkDelete( pNtk );
- return NULL;
- }
- return pNtk;
-}
-
-/**Function*************************************************************
-
- Synopsis [Starts the reading data structure.]
+ Synopsis [Reads hierarchical design from the Verilog file.]
Description []
@@ -170,583 +41,45 @@ Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck )
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 )
+Abc_Ntk_t * Io_ReadVerilog( char * pFileName, int fCheck )
{
- char Buffer[1000];
- ProgressBar * pProgress;
- Ver_KeywordType_t LineType;
- Vec_Ptr_t * vTokens;
Abc_Ntk_t * pNtk;
- char * pModelName;
- int i;
+ Abc_Lib_t * pDesign;
+ int RetValue;
- // 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 );
+ // parse the verilog file
+ pDesign = Ver_ParseFile( pFileName, NULL, fCheck, 1 );
+ if ( pDesign == NULL )
return NULL;
- }
- pModelName = vTokens->pArray[1];
-
- // allocate the empty network
- pNtk = Abc_NtkAlloc( ABC_TYPE_NETLIST, ABC_FUNC_SOP );
- pNtk->pName = util_strsav( pModelName );
- pNtk->pSpec = util_strsav( p->pFileName );
-
- // create constant nodes and nets
- Abc_NtkFindOrCreateNet( pNtk, "1'b0" );
- Abc_NtkFindOrCreateNet( pNtk, "1'b1" );
- Io_ReadCreateConst( pNtk, "1'b0", 0 );
- Io_ReadCreateConst( pNtk, "1'b1", 1 );
-
- // read the inputs/outputs
- pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
- for ( i = 0; vTokens = Extra_FileReaderGetTokens(p->pReader); i++ )
- {
- 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] );
- }
- Abc_NtkFinalizeRead( pNtk );
- return pNtk;
-}
-
-/**Function*************************************************************
- Synopsis [Reads one assign directive in the verilog file.]
-
- Description []
-
- SideEffects []
+ // detect top-level model
+ RetValue = Abc_LibFindTopLevelModels( pDesign );
+ pNtk = Vec_PtrEntry( pDesign->vTops, 0 );
+ if ( RetValue > 1 )
+ printf( "Warning: The design has %d root-level modules. The first one (%s) will be used.\n",
+ Vec_PtrSize(pDesign->vTops), pNtk->pName );
- SeeAlso []
+ // extract the master network
+ pNtk->pDesign = pDesign;
+ pDesign->pManFunc = NULL;
-***********************************************************************/
-bool Io_ReadVerNetworkAssign( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens )
-{
- assert( strcmp( vTokens->pArray[0], "assign" ) == 0 );
- // make sure the driving variable exists
- if ( !Abc_NtkFindNet( pNtk, vTokens->pArray[3] ) )
- {
- p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
- sprintf( p->sError, "Cannot find net \"%s\". The assign operator is handled only for assignment to a variable and a constant.", vTokens->pArray[3] );
- Io_ReadVerPrintErrorMessage( p );
- return 0;
- }
- // make sure the driven variable exists
- if ( !Abc_NtkFindNet( pNtk, vTokens->pArray[1] ) )
+ // verify the design for cyclic dependence
+ assert( Vec_PtrSize(pDesign->vModules) > 0 );
+ if ( Vec_PtrSize(pDesign->vModules) == 1 )
{
- p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
- sprintf( p->sError, "Cannot find net \"%s\".", vTokens->pArray[1] );
- Io_ReadVerPrintErrorMessage( p );
- return 0;
- }
- // create a buffer
- Io_ReadCreateBuf( pNtk, vTokens->pArray[3], vTokens->pArray[1] );
- 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 )
-{
- Abc_Obj_t * pNet;
- char Buffer[1000];
- 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;
+// printf( "Warning: The design is not hierarchical.\n" );
+ Abc_LibFree( pDesign, pNtk );
+ pNtk->pDesign = NULL;
+ pNtk->pSpec = Extra_UtilStrsav( pFileName );
}
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 );
- if ( LineType == VER_INPUT || LineType == VER_INOUT )
- Io_ReadCreatePi( pNtk, Buffer );
- if ( LineType == VER_OUTPUT || LineType == VER_INOUT )
- Io_ReadCreatePo( pNtk, Buffer );
- if ( LineType != VER_INPUT && LineType != VER_OUTPUT && LineType != VER_INOUT )
- pNet = Abc_NtkFindOrCreateNet( pNtk, Buffer );
- }
- }
- else
- {
- if ( LineType == VER_INPUT || LineType == VER_INOUT )
- Io_ReadCreatePi( pNtk, pToken );
- if ( LineType == VER_OUTPUT || LineType == VER_INOUT )
- Io_ReadCreatePo( pNtk, pToken );
- if ( LineType != VER_INPUT && LineType != VER_OUTPUT && LineType != VER_INOUT )
- pNet = Abc_NtkFindOrCreateNet( pNtk, pToken );
- }
- }
- return 1;
-}
-
-/**Function*************************************************************
-
- Synopsis [Reads a simple gate from the verilog file.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-bool Io_ReadVerNetworkGateSimple( Io_ReadVer_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vTokens, int LineType )
-{
- Abc_Obj_t * pNet, * pNode;
- char * pToken;
- int nFanins, k;
-
- // create the node
- pNode = Abc_NtkCreateNode( pNtk );
- // add the fanin nets
- nFanins = s_CadenceGates[LineType][1][0] - '0';
- // skip the gate type and gate name
- for ( k = 2; k < vTokens->nSize - 1; k++ )
- {
- pToken = vTokens->pArray[k];
- if ( pToken[0] == '.' )
- continue;
- pNet = Abc_NtkFindNet( pNtk, pToken );
- if ( pNet )
- {
- Abc_ObjAddFanin( pNode, pNet );
- 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 );
- // set the function
- Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][3]) );
- 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 );
- pNode2 = Abc_NtkCreateNode( pNtk );
- // 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;
+ // check that there is no cyclic dependency
+ Abc_NtkIsAcyclicHierarchy( pNtk );
}
- // 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 );
- Abc_ObjSetData( pNode1, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][3]) );
- Abc_ObjSetData( pNode2, Abc_SopRegister(pNtk->pManFunc, s_CadenceGates[LineType][4]) );
- 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;
- char * pLatchName;
- char * pToken, * pToken2, * pTokenRN, * pTokenSN, * pTokenSI, * pTokenSE, * pTokenD, * pTokenQ, * pTokenQN;
- int k, fRN1, fSN1;
-
- // get the latch name
- pLatchName = vTokens->pArray[1];
-
- // 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\".", pLatchName );
- 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\".", pLatchName );
- 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\".", pLatchName );
- Io_ReadVerPrintErrorMessage( p );
- return 0;
- }
- if ( Abc_NtkFindNet( pNtk, pTokenD ) == NULL )
- {
- p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
- sprintf( p->sError, "Cannot find latch input net \"%s\".", pTokenD );
- Io_ReadVerPrintErrorMessage( p );
- return 0;
- }
-
- // create the latch
- pLatch = Io_ReadCreateLatch( pNtk, pTokenD, pLatchName );
-
- // create the buffer if Q signal is available
- if ( pTokenQ )
- {
- 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;
- }
- Io_ReadCreateBuf( pNtk, pLatchName, pTokenQ );
- }
- if ( pTokenQN )
- {
- 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;
- }
- Io_ReadCreateInv( pNtk, pLatchName, pTokenQN );
- }
-
- // set the initial value
- if ( pTokenRN == NULL && pTokenSN == NULL )
- Abc_LatchSetInitDc( pLatch );
- else
- {
- fRN1 = (strcmp( pTokenRN, "1'b1" ) == 0);
- fSN1 = (strcmp( pTokenSN, "1'b1" ) == 0);
- if ( fRN1 && fSN1 )
- Abc_LatchSetInitDc( pLatch );
- else if ( fRN1 )
- Abc_LatchSetInit1( pLatch );
- else if ( fSN1 )
- Abc_LatchSetInit0( pLatch );
- else
- {
- p->LineCur = Extra_FileReaderGetLineNumber( p->pReader, 0 );
- sprintf( p->sError, "Cannot read the initial value of latch \"%s\".", pLatchName );
- Io_ReadVerPrintErrorMessage( p );
- return 0;
- }
- }
- return 1;
+//Io_WriteVerilog( pNtk, "_temp.v" );
+ return pNtk;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c
index 132684cc..4f9f2e9f 100644
--- a/src/base/io/ioUtil.c
+++ b/src/base/io/ioUtil.c
@@ -25,11 +25,442 @@
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
+ Synopsis [Returns the file type.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Io_FileType_t Io_ReadFileType( char * pFileName )
+{
+ char * pExt;
+ if ( pFileName == NULL )
+ return IO_FILE_NONE;
+ pExt = Extra_FileNameExtension( pFileName );
+ if ( pExt == NULL )
+ return IO_FILE_NONE;
+ if ( !strcmp( pExt, "aig" ) )
+ return IO_FILE_AIGER;
+ if ( !strcmp( pExt, "baf" ) )
+ return IO_FILE_BAF;
+ if ( !strcmp( pExt, "blif" ) )
+ return IO_FILE_BLIF;
+ if ( !strcmp( pExt, "bench" ) )
+ return IO_FILE_BENCH;
+ if ( !strcmp( pExt, "cnf" ) )
+ return IO_FILE_CNF;
+ if ( !strcmp( pExt, "dot" ) )
+ return IO_FILE_DOT;
+ if ( !strcmp( pExt, "edif" ) )
+ return IO_FILE_EDIF;
+ if ( !strcmp( pExt, "eqn" ) )
+ return IO_FILE_EQN;
+ if ( !strcmp( pExt, "gml" ) )
+ return IO_FILE_GML;
+ if ( !strcmp( pExt, "list" ) )
+ return IO_FILE_LIST;
+ if ( !strcmp( pExt, "mv" ) )
+ return IO_FILE_BLIFMV;
+ if ( !strcmp( pExt, "pla" ) )
+ return IO_FILE_PLA;
+ if ( !strcmp( pExt, "v" ) )
+ return IO_FILE_VERILOG;
+ return IO_FILE_UNKNOWN;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read the network from a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_ReadNetlist( char * pFileName, Io_FileType_t FileType, int fCheck )
+{
+ FILE * pFile;
+ Abc_Ntk_t * pNtk;
+ if ( FileType == IO_FILE_NONE || FileType == IO_FILE_UNKNOWN )
+ {
+ fprintf( stdout, "The generic file reader requires a known file extension.\n" );
+ return NULL;
+ }
+ // check if the file exists
+ pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Cannot open input file \"%s\". ", pFileName );
+ if ( pFileName = Extra_FileGetSimilarName( pFileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) )
+ fprintf( stdout, "Did you mean \"%s\"?", pFileName );
+ fprintf( stdout, "\n" );
+ return NULL;
+ }
+ fclose( pFile );
+ // read the AIG
+ if ( FileType == IO_FILE_AIGER || FileType == IO_FILE_BAF )
+ {
+ if ( FileType == IO_FILE_AIGER )
+ pNtk = Io_ReadAiger( pFileName, fCheck );
+ else // if ( FileType == IO_FILE_BAF )
+ pNtk = Io_ReadBaf( pFileName, fCheck );
+ if ( pNtk == NULL )
+ {
+ fprintf( stdout, "Reading AIG from file has failed.\n" );
+ return NULL;
+ }
+ return pNtk;
+ }
+ // read the new netlist
+ if ( FileType == IO_FILE_BLIF )
+// pNtk = Io_ReadBlif( pFileName, fCheck );
+ pNtk = Io_ReadBlifMv( pFileName, 0, fCheck );
+ else if ( Io_ReadFileType(pFileName) == IO_FILE_BLIFMV )
+ pNtk = Io_ReadBlifMv( pFileName, 1, fCheck );
+ else if ( FileType == IO_FILE_BENCH )
+ pNtk = Io_ReadBench( pFileName, fCheck );
+ else if ( FileType == IO_FILE_EDIF )
+ pNtk = Io_ReadEdif( pFileName, fCheck );
+ else if ( FileType == IO_FILE_EQN )
+ pNtk = Io_ReadEqn( pFileName, fCheck );
+ else if ( FileType == IO_FILE_PLA )
+ pNtk = Io_ReadPla( pFileName, fCheck );
+ else if ( FileType == IO_FILE_VERILOG )
+ pNtk = Io_ReadVerilog( pFileName, fCheck );
+ else
+ {
+ fprintf( stderr, "Unknown file format.\n" );
+ return NULL;
+ }
+ if ( pNtk == NULL )
+ {
+ fprintf( stdout, "Reading network from file has failed.\n" );
+ return NULL;
+ }
+ if ( Abc_NtkBlackboxNum(pNtk) || Abc_NtkWhiteboxNum(pNtk) )
+ fprintf( stdout, "Warning: The network contains hierarchy.\n" );
+ return pNtk;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Read the network from a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Io_Read( char * pFileName, Io_FileType_t FileType, int fCheck )
+{
+ Abc_Ntk_t * pNtk, * pTemp;
+ // get the netlist
+ pNtk = Io_ReadNetlist( pFileName, FileType, fCheck );
+ if ( pNtk == NULL )
+ return NULL;
+ if ( !Abc_NtkIsNetlist(pNtk) )
+ return pNtk;
+ // flatten logic hierarchy
+ assert( Abc_NtkIsNetlist(pNtk) );
+ if ( Abc_NtkWhiteboxNum(pNtk) > 0 )
+ {
+ pNtk = Abc_NtkFlattenLogicHierarchy( pTemp = pNtk );
+ Abc_NtkDelete( pTemp );
+ if ( pNtk == NULL )
+ {
+ fprintf( stdout, "Flattening logic hierarchy has failed.\n" );
+ return NULL;
+ }
+ }
+ // convert blackboxes
+ if ( Abc_NtkBlackboxNum(pNtk) > 0 )
+ {
+ printf( "Hierarchy reader converted %d instances of blackboxes.\n", Abc_NtkBlackboxNum(pNtk) );
+ pNtk = Abc_NtkConvertBlackboxes( pTemp = pNtk );
+ Abc_NtkDelete( pTemp );
+ if ( pNtk == NULL )
+ {
+ fprintf( stdout, "Converting blackboxes has failed.\n" );
+ return NULL;
+ }
+ }
+ // consider the case of BLIF-MV
+ if ( Io_ReadFileType(pFileName) == IO_FILE_BLIFMV )
+ {
+//Abc_NtkPrintStats( stdout, pNtk, 0 );
+// Io_WriteBlifMv( pNtk, "_temp_.mv" );
+ pNtk = Abc_NtkStrashBlifMv( pTemp = pNtk );
+ Abc_NtkDelete( pTemp );
+ if ( pNtk == NULL )
+ {
+ fprintf( stdout, "Converting BLIF-MV to AIG has failed.\n" );
+ return NULL;
+ }
+ return pNtk;
+ }
+ // convert the netlist into the logic network
+ pNtk = Abc_NtkToLogic( pTemp = pNtk );
+ Abc_NtkDelete( pTemp );
+ if ( pNtk == NULL )
+ {
+ fprintf( stdout, "Converting netlist to logic network after reading has failed.\n" );
+ return NULL;
+ }
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write the network into file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType )
+{
+ Abc_Ntk_t * pNtkTemp, * pNtkCopy;
+ // check if the current network is available
+ if ( pNtk == NULL )
+ {
+ fprintf( stdout, "Empty network.\n" );
+ return;
+ }
+ // check if the file extension if given
+ if ( FileType == IO_FILE_NONE || FileType == IO_FILE_UNKNOWN )
+ {
+ fprintf( stdout, "The generic file writer requires a known file extension.\n" );
+ return;
+ }
+ // write the AIG formats
+ if ( FileType == IO_FILE_AIGER || FileType == IO_FILE_BAF )
+ {
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( stdout, "Writing this format is only possible for structurally hashed AIGs.\n" );
+ return;
+ }
+ if ( FileType == IO_FILE_AIGER )
+ Io_WriteAiger( pNtk, pFileName, 1, 0 );
+ else // if ( FileType == IO_FILE_BAF )
+ Io_WriteBaf( pNtk, pFileName );
+ return;
+ }
+ // write non-netlist types
+ if ( FileType == IO_FILE_CNF )
+ {
+ Io_WriteCnf( pNtk, pFileName, 0 );
+ return;
+ }
+ if ( FileType == IO_FILE_DOT )
+ {
+ Io_WriteDot( pNtk, pFileName );
+ return;
+ }
+ if ( FileType == IO_FILE_GML )
+ {
+ Io_WriteGml( pNtk, pFileName );
+ return;
+ }
+/*
+ if ( FileType == IO_FILE_BLIFMV )
+ {
+ Io_WriteBlifMv( pNtk, pFileName );
+ return;
+ }
+*/
+ // convert logic network into netlist
+ if ( FileType == IO_FILE_PLA )
+ {
+ if ( Abc_NtkLevel(pNtk) > 1 )
+ {
+ fprintf( stdout, "PLA writing is available for collapsed networks.\n" );
+ return;
+ }
+ if ( Abc_NtkIsComb(pNtk) )
+ pNtkTemp = Abc_NtkToNetlist( pNtk );
+ else
+ {
+ fprintf( stdout, "Latches are writen into the PLA file at PI/PO pairs.\n" );
+ pNtkCopy = Abc_NtkDup( pNtk );
+ Abc_NtkMakeComb( pNtkCopy );
+ pNtkTemp = Abc_NtkToNetlist( pNtk );
+ Abc_NtkDelete( pNtkCopy );
+ }
+ if ( !Abc_NtkToSop( pNtk, 1 ) )
+ return;
+ }
+ else if ( FileType == IO_FILE_BENCH )
+ {
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( stdout, "Writing traditional BENCH is available for AIGs only (use \"write_bench\").\n" );
+ return;
+ }
+ pNtkTemp = Abc_NtkToNetlistBench( pNtk );
+ }
+ else
+ pNtkTemp = Abc_NtkToNetlist( pNtk );
+
+ if ( pNtkTemp == NULL )
+ {
+ fprintf( stdout, "Converting to netlist has failed.\n" );
+ return;
+ }
+
+ if ( FileType == IO_FILE_BLIF )
+ {
+ if ( !Abc_NtkHasSop(pNtkTemp) && !Abc_NtkHasMapping(pNtkTemp) )
+ Abc_NtkToSop( pNtkTemp, 0 );
+ Io_WriteBlif( pNtkTemp, pFileName, 1 );
+ }
+ else if ( FileType == IO_FILE_BLIFMV )
+ {
+ if ( !Abc_NtkConvertToBlifMv( pNtkTemp ) )
+ return;
+ Io_WriteBlifMv( pNtkTemp, pFileName );
+ }
+ else if ( FileType == IO_FILE_BENCH )
+ Io_WriteBench( pNtkTemp, pFileName );
+ else if ( FileType == IO_FILE_PLA )
+ Io_WritePla( pNtkTemp, pFileName );
+ else if ( FileType == IO_FILE_EQN )
+ {
+ if ( !Abc_NtkHasAig(pNtkTemp) )
+ Abc_NtkToAig( pNtkTemp );
+ Io_WriteEqn( pNtkTemp, pFileName );
+ }
+ else if ( FileType == IO_FILE_VERILOG )
+ {
+ if ( !Abc_NtkHasAig(pNtkTemp) && !Abc_NtkHasMapping(pNtkTemp) )
+ Abc_NtkToAig( pNtkTemp );
+ Io_WriteVerilog( pNtkTemp, pFileName );
+ }
+ else
+ fprintf( stderr, "Unknown file format.\n" );
+ Abc_NtkDelete( pNtkTemp );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write the network into file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteHie( Abc_Ntk_t * pNtk, char * pBaseName, char * pFileName )
+{
+ Abc_Ntk_t * pNtkTemp, * pNtkResult, * pNtkBase = NULL;
+ // check if the current network is available
+ if ( pNtk == NULL )
+ {
+ fprintf( stdout, "Empty network.\n" );
+ return;
+ }
+
+ // read the base network
+ assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) );
+ if ( Io_ReadFileType(pBaseName) == IO_FILE_BLIF )
+ pNtkBase = Io_ReadBlifMv( pBaseName, 0, 1 );
+ else if ( Io_ReadFileType(pBaseName) == IO_FILE_BLIFMV )
+ pNtkBase = Io_ReadBlifMv( pBaseName, 1, 1 );
+ else if ( Io_ReadFileType(pBaseName) == IO_FILE_VERILOG )
+ pNtkBase = Io_ReadVerilog( pBaseName, 1 );
+ else
+ fprintf( stderr, "Unknown input file format.\n" );
+ if ( pNtkBase == NULL )
+ return;
+
+ // flatten logic hierarchy if present
+ if ( Abc_NtkWhiteboxNum(pNtkBase) > 0 )
+ {
+ pNtkBase = Abc_NtkFlattenLogicHierarchy( pNtkTemp = pNtkBase );
+ if ( pNtkBase == NULL )
+ return;
+ Abc_NtkDelete( pNtkTemp );
+ }
+
+ // reintroduce the boxes into the netlist
+ if ( Io_ReadFileType(pBaseName) == IO_FILE_BLIFMV )
+ {
+ if ( Abc_NtkBlackboxNum(pNtkBase) > 0 )
+ {
+ printf( "Hierarchy writer does not support BLIF-MV with blackboxes.\n" );
+ Abc_NtkDelete( pNtkBase );
+ return;
+ }
+ // convert the current network to BLIF-MV
+ assert( !Abc_NtkIsNetlist(pNtk) );
+ pNtkResult = Abc_NtkToNetlist( pNtk );
+ if ( !Abc_NtkConvertToBlifMv( pNtkResult ) )
+ return;
+ // reintroduce the network
+ pNtkResult = Abc_NtkInsertBlifMv( pNtkBase, pNtkTemp = pNtkResult );
+ Abc_NtkDelete( pNtkTemp );
+ }
+ else if ( Abc_NtkBlackboxNum(pNtkBase) > 0 )
+ {
+ // derive the netlist
+ pNtkResult = Abc_NtkToNetlist( pNtk );
+ pNtkResult = Abc_NtkInsertNewLogic( pNtkBase, pNtkTemp = pNtkResult );
+ Abc_NtkDelete( pNtkTemp );
+ if ( pNtkResult )
+ printf( "Hierarchy writer reintroduced %d instances of blackboxes.\n", Abc_NtkBlackboxNum(pNtkBase) );
+ }
+ else
+ {
+ printf( "Warning: The output network does not contain blackboxes.\n" );
+ pNtkResult = Abc_NtkToNetlist( pNtk );
+ }
+ Abc_NtkDelete( pNtkBase );
+ if ( pNtkResult == NULL )
+ return;
+
+ // write the resulting network
+ if ( Io_ReadFileType(pFileName) == IO_FILE_BLIF )
+ {
+ if ( !Abc_NtkHasSop(pNtkResult) && !Abc_NtkHasMapping(pNtkResult) )
+ Abc_NtkToSop( pNtkResult, 0 );
+ Io_WriteBlif( pNtkResult, pFileName, 1 );
+ }
+ else if ( Io_ReadFileType(pFileName) == IO_FILE_VERILOG )
+ {
+ if ( !Abc_NtkHasAig(pNtkResult) && !Abc_NtkHasMapping(pNtkResult) )
+ Abc_NtkToAig( pNtkResult );
+ Io_WriteVerilog( pNtkResult, pFileName );
+ }
+ else if ( Io_ReadFileType(pFileName) == IO_FILE_BLIFMV )
+ {
+ Io_WriteBlifMv( pNtkResult, pFileName );
+ }
+ else
+ fprintf( stderr, "Unknown output file format.\n" );
+
+ Abc_NtkDelete( pNtkResult );
+}
+
+/**Function*************************************************************
+
Synopsis [Creates PI terminal and net.]
Description []
@@ -80,7 +511,7 @@ Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName )
/**Function*************************************************************
- Synopsis [Create a latch with the given input/output.]
+ Synopsis [Creates PO terminal and net.]
Description []
@@ -89,17 +520,82 @@ Abc_Obj_t * Io_ReadCreatePo( Abc_Ntk_t * pNtk, char * pName )
SeeAlso []
***********************************************************************/
+Abc_Obj_t * Io_ReadCreateAssert( Abc_Ntk_t * pNtk, char * pName )
+{
+ Abc_Obj_t * pNet, * pTerm;
+ // get the PO net
+ pNet = Abc_NtkFindNet( pNtk, pName );
+ if ( pNet && Abc_ObjFaninNum(pNet) == 0 )
+ printf( "Warning: Assert \"%s\" appears twice in the list.\n", pName );
+ pNet = Abc_NtkFindOrCreateNet( pNtk, pName );
+ // add the PO node
+ pTerm = Abc_NtkCreateAssert( pNtk );
+ Abc_ObjAddFanin( pTerm, pNet );
+ return pTerm;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create a latch with the given input/output.]
+
+ Description [By default, the latch value is unknown (ABC_INIT_NONE).]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
Abc_Obj_t * Io_ReadCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO )
{
- Abc_Obj_t * pLatch, * pNet;
- // create a new latch and add it to the network
- pLatch = Abc_NtkCreateLatch( pNtk );
+ Abc_Obj_t * pLatch, * pTerm, * pNet;
// get the LI net
pNet = Abc_NtkFindOrCreateNet( pNtk, pNetLI );
- Abc_ObjAddFanin( pLatch, pNet );
+ // add the BO terminal
+ pTerm = Abc_NtkCreateBi( pNtk );
+ Abc_ObjAddFanin( pTerm, pNet );
+ // add the latch box
+ pLatch = Abc_NtkCreateLatch( pNtk );
+ Abc_ObjAddFanin( pLatch, pTerm );
+ // add the BI terminal
+ pTerm = Abc_NtkCreateBo( pNtk );
+ Abc_ObjAddFanin( pTerm, pLatch );
// get the LO net
pNet = Abc_NtkFindOrCreateNet( pNtk, pNetLO );
- Abc_ObjAddFanin( pNet, pLatch );
+ Abc_ObjAddFanin( pNet, pTerm );
+ // set latch name
+ Abc_ObjAssignName( pLatch, pNetLO, "L" );
+ return pLatch;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the reset latch with data=1 and init=0.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Io_ReadCreateResetLatch( Abc_Ntk_t * pNtk, int fBlifMv )
+{
+ Abc_Obj_t * pLatch, * pNode;
+ Abc_Obj_t * pNetLI, * pNetLO;
+ // create latch with 0 init value
+// pLatch = Io_ReadCreateLatch( pNtk, "_resetLI_", "_resetLO_" );
+ pNetLI = Abc_NtkCreateNet( pNtk );
+ pNetLO = Abc_NtkCreateNet( pNtk );
+ Abc_ObjAssignName( pNetLI, Abc_ObjName(pNetLI), NULL );
+ Abc_ObjAssignName( pNetLO, Abc_ObjName(pNetLO), NULL );
+ pLatch = Io_ReadCreateLatch( pNtk, Abc_ObjName(pNetLI), Abc_ObjName(pNetLO) );
+ // set the initial value
+ Abc_LatchSetInit0( pLatch );
+ // feed the latch with constant1- node
+// pNode = Abc_NtkCreateNode( pNtk );
+// pNode->pData = Abc_SopRegister( pNtk->pManFunc, "2\n1\n" );
+ pNode = Abc_NtkCreateNodeConst1( pNtk );
+ Abc_ObjAddFanin( Abc_ObjFanin0(Abc_ObjFanin0(pLatch)), pNode );
return pLatch;
}
@@ -146,7 +642,7 @@ Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, char * pNamesI
Abc_Obj_t * Io_ReadCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 )
{
Abc_Obj_t * pNet, * pTerm;
- pTerm = fConst1? Abc_NodeCreateConst1(pNtk) : Abc_NodeCreateConst0(pNtk);
+ pTerm = fConst1? Abc_NtkCreateNodeConst1(pNtk) : Abc_NtkCreateNodeConst0(pNtk);
pNet = Abc_NtkFindNet(pNtk, pName); assert( pNet );
Abc_ObjAddFanin( pNet, pTerm );
return pTerm;
@@ -167,7 +663,7 @@ Abc_Obj_t * Io_ReadCreateInv( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut
{
Abc_Obj_t * pNet, * pNode;
pNet = Abc_NtkFindNet(pNtk, pNameIn); assert( pNet );
- pNode = Abc_NodeCreateInv(pNtk, pNet);
+ pNode = Abc_NtkCreateNodeInv(pNtk, pNet);
pNet = Abc_NtkFindNet(pNtk, pNameOut); assert( pNet );
Abc_ObjAddFanin( pNet, pNode );
return pNode;
@@ -188,12 +684,67 @@ Abc_Obj_t * Io_ReadCreateBuf( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut
{
Abc_Obj_t * pNet, * pNode;
pNet = Abc_NtkFindNet(pNtk, pNameIn); assert( pNet );
- pNode = Abc_NodeCreateBuf(pNtk, pNet);
+ pNode = Abc_NtkCreateNodeBuf(pNtk, pNet);
pNet = Abc_NtkFindNet(pNtk, pNameOut); assert( pNet );
Abc_ObjAddFanin( pNet, pNode );
return pNet;
}
+
+/**Function*************************************************************
+
+ Synopsis [Provide an fopen replacement with path lookup]
+
+ Description [Provide an fopen replacement where the path stored
+ in pathvar MVSIS variable is used to look up the path
+ for name. Returns NULL if file cannot be opened.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+FILE * Io_FileOpen( const char * FileName, const char * PathVar, const char * Mode, int fVerbose )
+{
+ char * t = 0, * c = 0, * i;
+ extern char * Abc_FrameReadFlag( char * pFlag );
+
+ if ( PathVar == 0 )
+ {
+ return fopen( FileName, Mode );
+ }
+ else
+ {
+ if ( c = Abc_FrameReadFlag( (char*)PathVar ) )
+ {
+ char ActualFileName[4096];
+ FILE * fp = 0;
+ t = Extra_UtilStrsav( c );
+ for (i = strtok( t, ":" ); i != 0; i = strtok( 0, ":") )
+ {
+#ifdef WIN32
+ _snprintf ( ActualFileName, 4096, "%s/%s", i, FileName );
+#else
+ snprintf ( ActualFileName, 4096, "%s/%s", i, FileName );
+#endif
+ if ( ( fp = fopen ( ActualFileName, Mode ) ) )
+ {
+ if ( fVerbose )
+ fprintf ( stdout, "Using file %s\n", ActualFileName );
+ free( t );
+ return fp;
+ }
+ }
+ free( t );
+ return 0;
+ }
+ else
+ {
+ return fopen( FileName, Mode );
+ }
+ }
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/io/ioWriteAiger.c b/src/base/io/ioWriteAiger.c
new file mode 100644
index 00000000..758e5335
--- /dev/null
+++ b/src/base/io/ioWriteAiger.c
@@ -0,0 +1,375 @@
+/**CFile****************************************************************
+
+ FileName [ioWriteAiger.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to write binary AIGER format developed by
+ Armin Biere, Johannes Kepler University (http://fmv.jku.at/)]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - December 16, 2006.]
+
+ Revision [$Id: ioWriteAiger.c,v 1.00 2006/12/16 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*
+ The following is taken from the AIGER format description,
+ which can be found at http://fmv.jku.at/aiger
+*/
+
+
+/*
+ The AIGER And-Inverter Graph (AIG) Format Version 20061129
+ ----------------------------------------------------------
+ Armin Biere, Johannes Kepler University, 2006
+
+ This report describes the AIG file format as used by the AIGER library.
+ The purpose of this report is not only to motivate and document the
+ format, but also to allow independent implementations of writers and
+ readers by giving precise and unambiguous definitions.
+
+ ...
+
+Introduction
+
+ The name AIGER contains as one part the acronym AIG of And-Inverter
+ Graphs and also if pronounced in German sounds like the name of the
+ 'Eiger', a mountain in the Swiss alps. This choice should emphasize the
+ origin of this format. It was first openly discussed at the Alpine
+ Verification Meeting 2006 in Ascona as a way to provide a simple, compact
+ file format for a model checking competition affiliated to CAV 2007.
+
+ ...
+
+Binary Format Definition
+
+ The binary format is semantically a subset of the ASCII format with a
+ slightly different syntax. The binary format may need to reencode
+ literals, but translating a file in binary format into ASCII format and
+ then back in to binary format will result in the same file.
+
+ The main differences of the binary format to the ASCII format are as
+ follows. After the header the list of input literals and all the
+ current state literals of a latch can be omitted. Furthermore the
+ definitions of the AND gates are binary encoded. However, the symbol
+ table and the comment section are as in the ASCII format.
+
+ The header of an AIGER file in binary format has 'aig' as format
+ identifier, but otherwise is identical to the ASCII header. The standard
+ file extension for the binary format is therefore '.aig'.
+
+ A header for the binary format is still in ASCII encoding:
+
+ aig M I L O A
+
+ Constants, variables and literals are handled in the same way as in the
+ ASCII format. The first simplifying restriction is on the variable
+ indices of inputs and latches. The variable indices of inputs come first,
+ followed by the pseudo-primary inputs of the latches and then the variable
+ indices of all LHS of AND gates:
+
+ input variable indices 1, 2, ... , I
+ latch variable indices I+1, I+2, ... , (I+L)
+ AND variable indices I+L+1, I+L+2, ... , (I+L+A) == M
+
+ The corresponding unsigned literals are
+
+ input literals 2, 4, ... , 2*I
+ latch literals 2*I+2, 2*I+4, ... , 2*(I+L)
+ AND literals 2*(I+L)+2, 2*(I+L)+4, ... , 2*(I+L+A) == 2*M
+
+ All literals have to be defined, and therefore 'M = I + L + A'. With this
+ restriction it becomes possible that the inputs and the current state
+ literals of the latches do not have to be listed explicitly. Therefore,
+ after the header only the list of 'L' next state literals follows, one per
+ latch on a single line, and then the 'O' outputs, again one per line.
+
+ In the binary format we assume that the AND gates are ordered and respect
+ the child parent relation. AND gates with smaller literals on the LHS
+ come first. Therefore we can assume that the literals on the right-hand
+ side of a definition of an AND gate are smaller than the LHS literal.
+ Furthermore we can sort the literals on the RHS, such that the larger
+ literal comes first. A definition thus consists of three literals
+
+ lhs rhs0 rhs1
+
+ with 'lhs' even and 'lhs > rhs0 >= rhs1'. Also the variable indices are
+ pairwise different to avoid combinational self loops. Since the LHS
+ indices of the definitions are all consecutive (as even integers),
+ the binary format does not have to keep 'lhs'. In addition, we can use
+ the order restriction and only write the differences 'delta0' and 'delta1'
+ instead of 'rhs0' and 'rhs1', with
+
+ delta0 = lhs - rhs0, delta1 = rhs0 - rhs1
+
+ The differences will all be strictly positive, and in practice often very
+ small. We can take advantage of this fact by the simple little-endian
+ encoding of unsigned integers of the next section. After the binary delta
+ encoding of the RHSs of all AND gates, the optional symbol table and
+ optional comment section start in the same format as in the ASCII case.
+
+ ...
+
+*/
+
+static unsigned Io_ObjMakeLit( int Var, int fCompl ) { return (Var << 1) | fCompl; }
+static unsigned Io_ObjAigerNum( Abc_Obj_t * pObj ) { return (unsigned)pObj->pCopy; }
+static void Io_ObjSetAigerNum( Abc_Obj_t * pObj, unsigned Num ) { pObj->pCopy = (void *)Num; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Adds one unsigned AIG edge to the output buffer.]
+
+ Description [This procedure is a slightly modified version of Armin Biere's
+ procedure "void encode (FILE * file, unsigned x)" ]
+
+ SideEffects [Returns the current writing position.]
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_WriteAigerEncode( char * pBuffer, int Pos, unsigned x )
+{
+ unsigned char ch;
+ while (x & ~0x7f)
+ {
+ ch = (x & 0x7f) | 0x80;
+// putc (ch, file);
+ pBuffer[Pos++] = ch;
+ x >>= 7;
+ }
+ ch = x;
+// putc (ch, file);
+ pBuffer[Pos++] = ch;
+ return Pos;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the array of literals to be written.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Io_WriteAigerLiterals( Abc_Ntk_t * pNtk )
+{
+ Vec_Int_t * vLits;
+ Abc_Obj_t * pObj, * pDriver;
+ int i;
+ vLits = Vec_IntAlloc( Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachLatchInput( pNtk, pObj, i )
+ {
+ pDriver = Abc_ObjFanin0(pObj);
+ Vec_IntPush( vLits, Io_ObjMakeLit( Io_ObjAigerNum(pDriver), Abc_ObjFaninC0(pObj) ^ (Io_ObjAigerNum(pDriver) == 0) ) );
+ }
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ pDriver = Abc_ObjFanin0(pObj);
+ Vec_IntPush( vLits, Io_ObjMakeLit( Io_ObjAigerNum(pDriver), Abc_ObjFaninC0(pObj) ^ (Io_ObjAigerNum(pDriver) == 0) ) );
+ }
+ return vLits;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the binary encoded array of literals.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Str_t * Io_WriteEncodeLiterals( Vec_Int_t * vLits )
+{
+ Vec_Str_t * vBinary;
+ int Pos = 0, Lit, LitPrev, Diff, i;
+ vBinary = Vec_StrAlloc( 2 * Vec_IntSize(vLits) );
+ LitPrev = Vec_IntEntry( vLits, 0 );
+ Pos = Io_WriteAigerEncode( Vec_StrArray(vBinary), Pos, LitPrev );
+ Vec_IntForEachEntryStart( vLits, Lit, i, 1 )
+ {
+ Diff = Lit - LitPrev;
+ Diff = (Lit < LitPrev)? -Diff : Diff;
+ Diff = (Diff << 1) | (int)(Lit < LitPrev);
+ Pos = Io_WriteAigerEncode( Vec_StrArray(vBinary), Pos, Diff );
+ LitPrev = Lit;
+ if ( Pos + 10 > vBinary->nCap )
+ Vec_StrGrow( vBinary, vBinary->nCap+1 );
+ }
+ vBinary->nSize = Pos;
+/*
+ // verify
+ {
+ extern Vec_Int_t * Io_WriteDecodeLiterals( char ** ppPos, int nEntries );
+ char * pPos = Vec_StrArray( vBinary );
+ Vec_Int_t * vTemp = Io_WriteDecodeLiterals( &pPos, Vec_IntSize(vLits) );
+ for ( i = 0; i < Vec_IntSize(vLits); i++ )
+ {
+ int Entry1 = Vec_IntEntry(vLits,i);
+ int Entry2 = Vec_IntEntry(vTemp,i);
+ assert( Entry1 == Entry2 );
+ }
+ }
+*/
+ return vBinary;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the AIG in the binary AIGER format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName, int fWriteSymbols, int fCompact )
+{
+ ProgressBar * pProgress;
+ FILE * pFile;
+ Abc_Obj_t * pObj, * pDriver;
+ int i, nNodes, Pos, nBufferSize;
+ unsigned char * pBuffer;
+ unsigned uLit0, uLit1, uLit;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+ // start the output stream
+ pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Io_WriteAiger(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ if ( !Abc_LatchIsInit0(pObj) )
+ {
+ fprintf( stdout, "Io_WriteAiger(): Cannot write AIGER format with non-0 latch init values. Run \"zero\".\n" );
+ return;
+ }
+
+ // set the node numbers to be used in the output file
+ nNodes = 0;
+ Io_ObjSetAigerNum( Abc_AigConst1(pNtk), nNodes++ );
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ Io_ObjSetAigerNum( pObj, nNodes++ );
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ Io_ObjSetAigerNum( pObj, nNodes++ );
+
+ // write the header "M I L O A" where M = I + L + A
+ fprintf( pFile, "aig%s %u %u %u %u %u\n",
+ fCompact? "2" : "",
+ Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) + Abc_NtkNodeNum(pNtk),
+ Abc_NtkPiNum(pNtk),
+ Abc_NtkLatchNum(pNtk),
+ Abc_NtkPoNum(pNtk),
+ Abc_NtkNodeNum(pNtk) );
+
+ // if the driver node is a constant, we need to complement the literal below
+ // because, in the AIGER format, literal 0/1 is represented as number 0/1
+ // while, in ABC, constant 1 node has number 0 and so literal 0/1 will be 1/0
+
+ if ( !fCompact )
+ {
+ // write latch drivers
+ Abc_NtkForEachLatchInput( pNtk, pObj, i )
+ {
+ pDriver = Abc_ObjFanin0(pObj);
+ fprintf( pFile, "%u\n", Io_ObjMakeLit( Io_ObjAigerNum(pDriver), Abc_ObjFaninC0(pObj) ^ (Io_ObjAigerNum(pDriver) == 0) ) );
+ }
+ // write PO drivers
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ pDriver = Abc_ObjFanin0(pObj);
+ fprintf( pFile, "%u\n", Io_ObjMakeLit( Io_ObjAigerNum(pDriver), Abc_ObjFaninC0(pObj) ^ (Io_ObjAigerNum(pDriver) == 0) ) );
+ }
+ }
+ else
+ {
+ Vec_Int_t * vLits = Io_WriteAigerLiterals( pNtk );
+ Vec_Str_t * vBinary = Io_WriteEncodeLiterals( vLits );
+ fwrite( Vec_StrArray(vBinary), 1, Vec_StrSize(vBinary), pFile );
+ Vec_StrFree( vBinary );
+ Vec_IntFree( vLits );
+ }
+
+ // write the nodes into the buffer
+ Pos = 0;
+ nBufferSize = 6 * Abc_NtkNodeNum(pNtk) + 100; // skeptically assuming 3 chars per one AIG edge
+ pBuffer = ALLOC( unsigned char, nBufferSize );
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ uLit = Io_ObjMakeLit( Io_ObjAigerNum(pObj), 0 );
+ uLit0 = Io_ObjMakeLit( Io_ObjAigerNum(Abc_ObjFanin0(pObj)), Abc_ObjFaninC0(pObj) );
+ uLit1 = Io_ObjMakeLit( Io_ObjAigerNum(Abc_ObjFanin1(pObj)), Abc_ObjFaninC1(pObj) );
+ assert( uLit0 < uLit1 );
+ Pos = Io_WriteAigerEncode( pBuffer, Pos, (unsigned)(uLit - uLit1) );
+ Pos = Io_WriteAigerEncode( pBuffer, Pos, (unsigned)(uLit1 - uLit0) );
+ if ( Pos > nBufferSize - 10 )
+ {
+ printf( "Io_WriteAiger(): AIGER generation has failed because the allocated buffer is too small.\n" );
+ fclose( pFile );
+ return;
+ }
+ }
+ assert( Pos < nBufferSize );
+ Extra_ProgressBarStop( pProgress );
+
+ // write the buffer
+ fwrite( pBuffer, 1, Pos, pFile );
+ free( pBuffer );
+
+ // write the symbol table
+ if ( fWriteSymbols )
+ {
+ // write PIs
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ fprintf( pFile, "i%d %s\n", i, Abc_ObjName(pObj) );
+ // write latches
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ fprintf( pFile, "l%d %s\n", i, Abc_ObjName(Abc_ObjFanout0(pObj)) );
+ // write POs
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ fprintf( pFile, "o%d %s\n", i, Abc_ObjName(pObj) );
+ }
+
+ // write the comment
+ fprintf( pFile, "c\n" );
+ if ( pNtk->pName && strlen(pNtk->pName) > 0 )
+ fprintf( pFile, ".model %s\n", pNtk->pName );
+ fprintf( pFile, "This file was produced by ABC on %s\n", Extra_TimeStamp() );
+ fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
+ fclose( pFile );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioWriteBaf.c b/src/base/io/ioWriteBaf.c
new file mode 100644
index 00000000..fc0229a4
--- /dev/null
+++ b/src/base/io/ioWriteBaf.c
@@ -0,0 +1,168 @@
+/**CFile****************************************************************
+
+ FileName [ioWriteBaf.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to write AIG in the binary format.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioWriteBaf.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*
+ Binary Aig Format
+
+ The motivation for this format is to have
+ - compact binary representation of large AIGs (~10x more compact than BLIF)
+ - consequently, fast reading/writing of large AIGs (~10x faster than BLIF)
+ - representation for all tech-ind info related to an AIG
+ - human-readable file header
+
+ The header:
+ (1) May contain several lines of human-readable comments.
+ Each comment line begins with symbol '#' and ends with symbol '\n'.
+ (2) Always contains the following data.
+ - benchmark name
+ - number of primary inputs
+ - number of primary outputs
+ - number of latches
+ - number of AIG nodes (excluding the constant 1 node)
+ Each entry is followed by 0-byte (character '\0'):
+ (3) Next follow the names of the PIs, POs, and latches in this order.
+ Each name is followed by 0-byte (character '\0').
+ Inside each set of names (PIs, POs, latches) there should be no
+ identical names but the PO names may coincide with PI/latch names.
+
+ The body:
+ (1) First part of the body contains binary information about the internal AIG nodes.
+ Each internal AIG node is represented using two edges (each edge is a 4-byte integer).
+ Each integer is the fanin ID followed by 1-bit representation of the complemented attribute.
+ (For example, complemented edge to node 10 will be represented as 2*10 + 1 = 21.)
+ The IDs of the nodes are created as follows: Constant 1 node has ID=0.
+ CIs (PIs and latch outputs) have 1-based IDs assigned in that order.
+ Each node in the array of the internal AIG nodes has the ID assigned in that order.
+ The constant 1 node is not written into the file.
+ (2) Second part of the body contains binary information about the edges connecting
+ the COs (POs and latch inputs) to the internal AIG nodes.
+ Each edge is a 4-byte integer the same way as a node fanin.
+ The latch initial value (2 bits) is stored in this integer.
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Writes the AIG in the binary format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteBaf( Abc_Ntk_t * pNtk, char * pFileName )
+{
+ ProgressBar * pProgress;
+ FILE * pFile;
+ Abc_Obj_t * pObj;
+ int i, nNodes, nAnds, nBufferSize;
+ unsigned * pBufferNode;
+ assert( Abc_NtkIsStrash(pNtk) );
+ // start the output stream
+ pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Io_WriteBaf(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+
+ // write the comment
+ fprintf( pFile, "# BAF (Binary Aig Format) for \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
+
+ // write the network name
+ fprintf( pFile, "%s%c", pNtk->pName, 0 );
+ // write the number of PIs
+ fprintf( pFile, "%d%c", Abc_NtkPiNum(pNtk), 0 );
+ // write the number of POs
+ fprintf( pFile, "%d%c", Abc_NtkPoNum(pNtk), 0 );
+ // write the number of latches
+ fprintf( pFile, "%d%c", Abc_NtkLatchNum(pNtk), 0 );
+ // write the number of internal nodes
+ fprintf( pFile, "%d%c", Abc_NtkNodeNum(pNtk), 0 );
+
+ // write PIs
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ fprintf( pFile, "%s%c", Abc_ObjName(pObj), 0 );
+ // write POs
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ fprintf( pFile, "%s%c", Abc_ObjName(pObj), 0 );
+ // write latches
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ fprintf( pFile, "%s%c", Abc_ObjName(pObj), 0 );
+ fprintf( pFile, "%s%c", Abc_ObjName(Abc_ObjFanin0(pObj)), 0 );
+ fprintf( pFile, "%s%c", Abc_ObjName(Abc_ObjFanout0(pObj)), 0 );
+ }
+
+ // set the node numbers to be used in the output file
+ Abc_NtkCleanCopy( pNtk );
+ nNodes = 1;
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ pObj->pCopy = (void *)nNodes++;
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ pObj->pCopy = (void *)nNodes++;
+
+ // write the nodes into the buffer
+ nAnds = 0;
+ nBufferSize = Abc_NtkNodeNum(pNtk) * 2 + Abc_NtkCoNum(pNtk);
+ pBufferNode = ALLOC( int, nBufferSize );
+ pProgress = Extra_ProgressBarStart( stdout, nBufferSize );
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, nAnds, NULL );
+ pBufferNode[nAnds++] = (((int)Abc_ObjFanin0(pObj)->pCopy) << 1) | Abc_ObjFaninC0(pObj);
+ pBufferNode[nAnds++] = (((int)Abc_ObjFanin1(pObj)->pCopy) << 1) | Abc_ObjFaninC1(pObj);
+ }
+
+ // write the COs into the buffer
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, nAnds, NULL );
+ pBufferNode[nAnds] = (((int)Abc_ObjFanin0(pObj)->pCopy) << 1) | Abc_ObjFaninC0(pObj);
+ if ( Abc_ObjFanoutNum(pObj) > 0 && Abc_ObjIsLatch(Abc_ObjFanout0(pObj)) )
+ pBufferNode[nAnds] = (pBufferNode[nAnds] << 2) | ((unsigned)Abc_ObjData(Abc_ObjFanout0(pObj)) & 3);
+ nAnds++;
+ }
+ Extra_ProgressBarStop( pProgress );
+ assert( nBufferSize == nAnds );
+
+ // write the buffer
+ fwrite( pBufferNode, 1, sizeof(int) * nBufferSize, pFile );
+ fclose( pFile );
+ free( pBufferNode );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioWriteBench.c b/src/base/io/ioWriteBench.c
index df79227d..4b766a47 100644
--- a/src/base/io/ioWriteBench.c
+++ b/src/base/io/ioWriteBench.c
@@ -24,11 +24,16 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-static int Io_WriteBenchOne( FILE * pFile, Abc_Ntk_t * pNtk );
-static int Io_WriteBenchOneNode( FILE * pFile, Abc_Obj_t * pNode );
+static int Io_WriteBenchCheckNames( Abc_Ntk_t * pNtk );
+
+static int Io_WriteBenchOne( FILE * pFile, Abc_Ntk_t * pNtk );
+static int Io_WriteBenchOneNode( FILE * pFile, Abc_Obj_t * pNode );
+
+static int Io_WriteBenchLutOne( FILE * pFile, Abc_Ntk_t * pNtk );
+static int Io_WriteBenchLutOneNode( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vTruth );
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
@@ -47,6 +52,11 @@ int Io_WriteBench( Abc_Ntk_t * pNtk, char * pFileName )
Abc_Ntk_t * pExdc;
FILE * pFile;
assert( Abc_NtkIsSopNetlist(pNtk) );
+ if ( !Io_WriteBenchCheckNames(pNtk) )
+ {
+ fprintf( stdout, "Io_WriteBench(): Signal names in this benchmark contain parantheses making them impossible to reproduce in the BENCH format. Use \"short_names\".\n" );
+ return 0;
+ }
pFile = fopen( pFileName, "w" );
if ( pFile == NULL )
{
@@ -89,7 +99,7 @@ int Io_WriteBenchOne( FILE * pFile, Abc_Ntk_t * pNtk )
fprintf( pFile, "OUTPUT(%s)\n", Abc_ObjName(Abc_ObjFanin0(pNode)) );
Abc_NtkForEachLatch( pNtk, pNode, i )
fprintf( pFile, "%-11s = DFF(%s)\n",
- Abc_ObjName(pNode), Abc_ObjName(Abc_ObjFanin0(pNode)) );
+ Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout0(pNode))), Abc_ObjName(Abc_ObjFanin0(Abc_ObjFanin0(pNode))) );
// write internal nodes
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
@@ -148,6 +158,176 @@ int Io_WriteBenchOneNode( FILE * pFile, Abc_Obj_t * pNode )
return 1;
}
+/**Function*************************************************************
+
+ Synopsis [Writes the network in BENCH format with LUTs and DFFRSE.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_WriteBenchLut( Abc_Ntk_t * pNtk, char * pFileName )
+{
+ Abc_Ntk_t * pExdc;
+ FILE * pFile;
+ assert( Abc_NtkIsAigNetlist(pNtk) );
+ if ( !Io_WriteBenchCheckNames(pNtk) )
+ {
+ fprintf( stdout, "Io_WriteBenchLut(): Signal names in this benchmark contain parantheses making them impossible to reproduce in the BENCH format. Use \"short_names\".\n" );
+ return 0;
+ }
+ 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->pName, Extra_TimeStamp() );
+ // write the network
+ Io_WriteBenchLutOne( pFile, pNtk );
+ // write EXDC network if it exists
+ pExdc = Abc_NtkExdc( pNtk );
+ if ( pExdc )
+ printf( "Io_WriteBench: EXDC is not written (warning).\n" );
+ // finalize the file
+ fclose( pFile );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the network in BENCH format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_WriteBenchLutOne( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Obj_t * pNode;
+ Vec_Int_t * vMemory;
+ int i;
+
+ // write the PIs/POs/latches
+ Abc_NtkForEachPi( pNtk, pNode, i )
+ fprintf( pFile, "INPUT(%s)\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ fprintf( pFile, "OUTPUT(%s)\n", Abc_ObjName(Abc_ObjFanin0(pNode)) );
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ fprintf( pFile, "%-11s = DFFRSE( %s, gnd, gnd, gnd, gnd )\n",
+ Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout0(pNode))), Abc_ObjName(Abc_ObjFanin0(Abc_ObjFanin0(pNode))) );
+//Abc_NtkLevel(pNtk);
+ // write internal nodes
+ vMemory = Vec_IntAlloc( 10000 );
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ Io_WriteBenchLutOneNode( pFile, pNode, vMemory );
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_IntFree( vMemory );
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the network in BENCH format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_WriteBenchLutOneNode( FILE * pFile, Abc_Obj_t * pNode, Vec_Int_t * vTruth )
+{
+ Abc_Obj_t * pFanin;
+ unsigned * pTruth;
+ int i, nFanins;
+ assert( Abc_ObjIsNode(pNode) );
+ nFanins = Abc_ObjFaninNum(pNode);
+ assert( nFanins <= 8 );
+ // compute the truth table
+ pTruth = Abc_ConvertAigToTruth( pNode->pNtk->pManFunc, Hop_Regular(pNode->pData), nFanins, vTruth, 0 );
+ if ( Hop_IsComplement(pNode->pData) )
+ Extra_TruthNot( pTruth, pTruth, nFanins );
+ // consider simple cases
+ if ( Extra_TruthIsConst0(pTruth, nFanins) )
+ {
+ fprintf( pFile, "%-11s = gnd\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
+ return 1;
+ }
+ if ( Extra_TruthIsConst1(pTruth, nFanins) )
+ {
+ fprintf( pFile, "%-11s = vdd\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
+ return 1;
+ }
+ if ( nFanins == 1 )
+ {
+ fprintf( pFile, "%-11s = LUT 0x%d ( %s )\n",
+ Abc_ObjName(Abc_ObjFanout0(pNode)),
+ Abc_NodeIsBuf(pNode)? 2 : 1,
+ Abc_ObjName(Abc_ObjFanin0(pNode)) );
+ return 1;
+ }
+ // write it in the hexadecimal form
+ fprintf( pFile, "%-11s = LUT 0x", Abc_ObjName(Abc_ObjFanout0(pNode)) );
+ Extra_PrintHexadecimal( pFile, pTruth, nFanins );
+/*
+ {
+extern void Kit_DsdTest( unsigned * pTruth, int nVars );
+Abc_ObjForEachFanin( pNode, pFanin, i )
+printf( "%c%d ", 'a'+i, Abc_ObjFanin0(pFanin)->Level );
+printf( "\n" );
+Kit_DsdTest( pTruth, nFanins );
+ }
+ if ( pNode->Id % 1000 == 0 )
+ {
+ int x = 0;
+ }
+*/
+ // write the fanins
+ fprintf( pFile, " (" );
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ fprintf( pFile, " %s%s", Abc_ObjName(pFanin), ((i==nFanins-1)? "" : ",") );
+ fprintf( pFile, " )\n" );
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the names cannot be written into the bench file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_WriteBenchCheckNames( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ char * pName;
+ int i;
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ for ( pName = Nm_ManFindNameById(pNtk->pManName, i); pName && *pName; pName++ )
+ if ( *pName == '(' || *pName == ')' )
+ return 0;
+ return 1;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c
index 7d6815b9..c0c29d65 100644
--- a/src/base/io/ioWriteBlif.c
+++ b/src/base/io/ioWriteBlif.c
@@ -26,16 +26,19 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+static void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
-static void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode );
+static void Io_NtkWriteSubckt( FILE * pFile, Abc_Obj_t * pNode );
+static void Io_NtkWriteAsserts( FILE * pFile, Abc_Ntk_t * pNtk );
+static void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length );
static void Io_NtkWriteNodeFanins( FILE * pFile, Abc_Obj_t * pNode );
-static void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode );
+static void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length );
static void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch );
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
@@ -53,7 +56,7 @@ void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
{
Abc_Ntk_t * pNtkTemp;
// derive the netlist
- pNtkTemp = Abc_NtkLogicToNetlist(pNtk);
+ pNtkTemp = Abc_NtkToNetlist(pNtk);
if ( pNtkTemp == NULL )
{
fprintf( stdout, "Writing BLIF has failed.\n" );
@@ -76,17 +79,52 @@ void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
***********************************************************************/
void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
{
- Abc_Ntk_t * pExdc;
FILE * pFile;
+ Abc_Ntk_t * pNtkTemp;
+ int i;
assert( Abc_NtkIsNetlist(pNtk) );
+ // start writing the file
pFile = fopen( FileName, "w" );
if ( pFile == NULL )
{
fprintf( stdout, "Io_WriteBlif(): Cannot open the output file.\n" );
return;
}
- // write the model name
fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
+ // write the master network
+ Io_NtkWrite( pFile, pNtk, fWriteLatches );
+ // make sure there is no logic hierarchy
+ assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
+ // write the hierarchy if present
+ if ( Abc_NtkBlackboxNum(pNtk) > 0 )
+ {
+ Vec_PtrForEachEntry( pNtk->pDesign->vModules, pNtkTemp, i )
+ {
+ if ( pNtkTemp == pNtk )
+ continue;
+ fprintf( pFile, "\n\n" );
+ Io_NtkWrite( pFile, pNtkTemp, fWriteLatches );
+ }
+ }
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write the network into a BLIF file with the given name.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
+{
+ Abc_Ntk_t * pExdc;
+ assert( Abc_NtkIsNetlist(pNtk) );
+ // write the model name
fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
// write the network
Io_NtkWriteOne( pFile, pNtk, fWriteLatches );
@@ -100,7 +138,6 @@ void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
}
// finalize the file
fprintf( pFile, ".end\n" );
- fclose( pFile );
}
/**Function*************************************************************
@@ -118,7 +155,7 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
{
ProgressBar * pProgress;
Abc_Obj_t * pNode, * pLatch;
- int i;
+ int i, Length;
// write the PIs
fprintf( pFile, ".inputs" );
@@ -130,6 +167,21 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
Io_NtkWritePos( pFile, pNtk, fWriteLatches );
fprintf( pFile, "\n" );
+ // write the assertions
+ if ( Abc_NtkAssertNum(pNtk) )
+ {
+ fprintf( pFile, ".asserts" );
+ Io_NtkWriteAsserts( pFile, pNtk );
+ fprintf( pFile, "\n" );
+ }
+
+ // write the blackbox
+ if ( Abc_NtkHasBlackbox( pNtk ) )
+ {
+ fprintf( pFile, ".blackbox\n" );
+ return;
+ }
+
// write the timing info
Io_WriteTimingInfo( pFile, pNtk );
@@ -142,12 +194,23 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
fprintf( pFile, "\n" );
}
+ // write the subcircuits
+ assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
+ if ( Abc_NtkBlackboxNum(pNtk) > 0 )
+ {
+ fprintf( pFile, "\n" );
+ Abc_NtkForEachBlackbox( pNtk, pNode, i )
+ Io_NtkWriteSubckt( pFile, pNode );
+ fprintf( pFile, "\n" );
+ }
+
// write each internal node
+ Length = Abc_NtkHasMapping(pNtk)? Mio_LibraryReadGateNameMax(pNtk->pManFunc) : 0;
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
- Io_NtkWriteNode( pFile, pNode );
+ Io_NtkWriteNode( pFile, pNode, Length );
}
Extra_ProgressBarStop( pProgress );
}
@@ -260,6 +323,8 @@ void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
{
Abc_NtkForEachCo( pNtk, pTerm, i )
{
+ if ( Abc_ObjIsAssert(pTerm) )
+ continue;
pNet = Abc_ObjFanin0(pTerm);
// get the line length after this name is written
AddedLength = strlen(Abc_ObjName(pNet)) + 1;
@@ -277,6 +342,80 @@ void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
}
}
+/**Function*************************************************************
+
+ Synopsis [Writes the assertion list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteAsserts( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pTerm, * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i;
+
+ LineLength = 8;
+ NameCounter = 0;
+
+ Abc_NtkForEachAssert( pNtk, pTerm, i )
+ {
+ pNet = Abc_ObjFanin0(pTerm);
+ // get the line length after this name is written
+ AddedLength = strlen(Abc_ObjName(pNet)) + 1;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, " \\\n" );
+ // reset the line length
+ LineLength = 0;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s", Abc_ObjName(pNet) );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write the latch into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteSubckt( FILE * pFile, Abc_Obj_t * pNode )
+{
+ Abc_Ntk_t * pModel = pNode->pData;
+ Abc_Obj_t * pTerm;
+ int i;
+ // write the subcircuit
+// fprintf( pFile, ".subckt %s %s", Abc_NtkName(pModel), Abc_ObjName(pNode) );
+ fprintf( pFile, ".subckt %s", Abc_NtkName(pModel) );
+ // write pairs of the formal=actual names
+ Abc_NtkForEachPi( pModel, pTerm, i )
+ {
+ fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
+ pTerm = Abc_ObjFanin( pNode, i );
+ fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
+ }
+ Abc_NtkForEachPo( pModel, pTerm, i )
+ {
+ fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
+ pTerm = Abc_ObjFanout( pNode, i );
+ fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
+ }
+ fprintf( pFile, "\n" );
+}
/**Function*************************************************************
@@ -293,14 +432,14 @@ void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch )
{
Abc_Obj_t * pNetLi, * pNetLo;
int Reset;
- pNetLi = Abc_ObjFanin0( pLatch );
- pNetLo = Abc_ObjFanout0( pLatch );
+ pNetLi = Abc_ObjFanin0( Abc_ObjFanin0(pLatch) );
+ pNetLo = Abc_ObjFanout0( 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 );
+ fprintf( pFile, " %d\n", Reset-1 );
}
@@ -315,13 +454,13 @@ void Io_NtkWriteLatch( FILE * pFile, Abc_Obj_t * pLatch )
SeeAlso []
***********************************************************************/
-void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode )
+void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode, int Length )
{
if ( Abc_NtkHasMapping(pNode->pNtk) )
{
// write the .gate line
fprintf( pFile, ".gate" );
- Io_NtkWriteNodeGate( pFile, pNode );
+ Io_NtkWriteNodeGate( pFile, pNode, Length );
fprintf( pFile, "\n" );
}
else
@@ -346,17 +485,17 @@ void Io_NtkWriteNode( FILE * pFile, Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
-void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode )
+void Io_NtkWriteNodeGate( FILE * pFile, Abc_Obj_t * pNode, int Length )
{
Mio_Gate_t * pGate = pNode->pData;
Mio_Pin_t * pGatePin;
int i;
// write the node
- fprintf( pFile, " %s ", Mio_GateReadName(pGate) );
+ fprintf( pFile, " %-*s ", Length, Mio_GateReadName(pGate) );
for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
fprintf( pFile, "%s=%s ", Mio_PinReadName(pGatePin), Abc_ObjName( Abc_ObjFanin(pNode,i) ) );
assert ( i == Abc_ObjFaninNum(pNode) );
- fprintf( pFile, "%s=%s", Mio_GateReadOutName(pGate), Abc_ObjName(pNode) );
+ fprintf( pFile, "%s=%s", Mio_GateReadOutName(pGate), Abc_ObjName( Abc_ObjFanout0(pNode) ) );
}
/**Function*************************************************************
diff --git a/src/base/io/ioWriteBlifMv.c b/src/base/io/ioWriteBlifMv.c
new file mode 100644
index 00000000..775a2e07
--- /dev/null
+++ b/src/base/io/ioWriteBlifMv.c
@@ -0,0 +1,519 @@
+/**CFile****************************************************************
+
+ FileName [ioWriteBlifMv.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to write BLIF-MV files.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioWriteBlifMv.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_NtkWriteBlifMv( FILE * pFile, Abc_Ntk_t * pNtk );
+static void Io_NtkWriteBlifMvOne( FILE * pFile, Abc_Ntk_t * pNtk );
+static void Io_NtkWriteBlifMvPis( FILE * pFile, Abc_Ntk_t * pNtk );
+static void Io_NtkWriteBlifMvPos( FILE * pFile, Abc_Ntk_t * pNtk );
+static void Io_NtkWriteBlifMvAsserts( FILE * pFile, Abc_Ntk_t * pNtk );
+static void Io_NtkWriteBlifMvNodeFanins( FILE * pFile, Abc_Obj_t * pNode );
+static void Io_NtkWriteBlifMvNode( FILE * pFile, Abc_Obj_t * pNode );
+static void Io_NtkWriteBlifMvLatch( FILE * pFile, Abc_Obj_t * pLatch );
+static void Io_NtkWriteBlifMvSubckt( FILE * pFile, Abc_Obj_t * pNode );
+static void Io_NtkWriteBlifMvValues( FILE * pFile, Abc_Obj_t * pNode );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Write the network into a BLIF file with the given name.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteBlifMv( Abc_Ntk_t * pNtk, char * FileName )
+{
+ FILE * pFile;
+ Abc_Ntk_t * pNtkTemp;
+ int i;
+ assert( Abc_NtkIsNetlist(pNtk) );
+ assert( Abc_NtkHasBlifMv(pNtk) );
+ // start writing the file
+ pFile = fopen( FileName, "w" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Io_WriteBlifMv(): Cannot open the output file.\n" );
+ return;
+ }
+ fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
+ // write the master network
+ Io_NtkWriteBlifMv( pFile, pNtk );
+ // write the remaining networks
+ if ( pNtk->pDesign )
+ {
+ Vec_PtrForEachEntry( pNtk->pDesign->vModules, pNtkTemp, i )
+ {
+ if ( pNtkTemp == pNtk )
+ continue;
+ fprintf( pFile, "\n\n" );
+ Io_NtkWriteBlifMv( pFile, pNtkTemp );
+ }
+ }
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write the network into a BLIF file with the given name.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteBlifMv( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ assert( Abc_NtkIsNetlist(pNtk) );
+ // write the model name
+ fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
+ // write the network
+ Io_NtkWriteBlifMvOne( pFile, pNtk );
+ // write EXDC network if it exists
+ if ( Abc_NtkExdc(pNtk) )
+ printf( "Io_NtkWriteBlifMv(): EXDC is not written.\n" );
+ // finalize the file
+ fprintf( pFile, ".end\n\n\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write one network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteBlifMvOne( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Obj_t * pNode, * pTerm, * pLatch;
+ int i;
+
+ // write the PIs
+ fprintf( pFile, ".inputs" );
+ Io_NtkWriteBlifMvPis( pFile, pNtk );
+ fprintf( pFile, "\n" );
+
+ // write the POs
+ fprintf( pFile, ".outputs" );
+ Io_NtkWriteBlifMvPos( pFile, pNtk );
+ fprintf( pFile, "\n" );
+
+ // write the assertions
+ if ( Abc_NtkAssertNum(pNtk) )
+ {
+ fprintf( pFile, ".asserts" );
+ Io_NtkWriteBlifMvAsserts( pFile, pNtk );
+ fprintf( pFile, "\n" );
+ }
+
+ // write the MV directives
+ fprintf( pFile, "\n" );
+ Abc_NtkForEachCi( pNtk, pTerm, i )
+ if ( Abc_ObjMvVarNum(Abc_ObjFanout0(pTerm)) > 2 )
+ fprintf( pFile, ".mv %s %d\n", Abc_ObjName(Abc_ObjFanout0(pTerm)), Abc_ObjMvVarNum(Abc_ObjFanout0(pTerm)) );
+ Abc_NtkForEachCo( pNtk, pTerm, i )
+ if ( Abc_ObjMvVarNum(Abc_ObjFanin0(pTerm)) > 2 )
+ fprintf( pFile, ".mv %s %d\n", Abc_ObjName(Abc_ObjFanin0(pTerm)), Abc_ObjMvVarNum(Abc_ObjFanin0(pTerm)) );
+
+ // write the blackbox
+ if ( Abc_NtkHasBlackbox( pNtk ) )
+ {
+ fprintf( pFile, ".blackbox\n" );
+ return;
+ }
+
+ // write the timing info
+// Io_WriteTimingInfo( pFile, pNtk );
+
+ // write the latches
+ if ( !Abc_NtkIsComb(pNtk) )
+ {
+ fprintf( pFile, "\n" );
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ Io_NtkWriteBlifMvLatch( pFile, pLatch );
+ fprintf( pFile, "\n" );
+ }
+/*
+ // write the subcircuits
+ assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
+ if ( Abc_NtkBlackboxNum(pNtk) > 0 )
+ {
+ fprintf( pFile, "\n" );
+ Abc_NtkForEachBlackbox( pNtk, pNode, i )
+ Io_NtkWriteBlifMvSubckt( pFile, pNode );
+ fprintf( pFile, "\n" );
+ }
+*/
+ if ( Abc_NtkBlackboxNum(pNtk) > 0 || Abc_NtkWhiteboxNum(pNtk) > 0 )
+ {
+ fprintf( pFile, "\n" );
+ Abc_NtkForEachBox( pNtk, pNode, i )
+ {
+ if ( Abc_ObjIsLatch(pNode) )
+ continue;
+ Io_NtkWriteBlifMvSubckt( pFile, pNode );
+ }
+ fprintf( pFile, "\n" );
+ }
+
+ // write each internal node
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ Io_NtkWriteBlifMvNode( pFile, pNode );
+ }
+ Extra_ProgressBarStop( pProgress );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the primary input list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteBlifMvPis( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pTerm, * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i;
+
+ LineLength = 7;
+ NameCounter = 0;
+
+ Abc_NtkForEachPi( pNtk, pTerm, i )
+ {
+ pNet = Abc_ObjFanout0(pTerm);
+ // get the line length after this name is written
+ AddedLength = strlen(Abc_ObjName(pNet)) + 1;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, " \\\n" );
+ // reset the line length
+ LineLength = 0;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s", Abc_ObjName(pNet) );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the primary input list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteBlifMvPos( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pTerm, * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i;
+
+ LineLength = 8;
+ NameCounter = 0;
+
+ Abc_NtkForEachPo( pNtk, pTerm, i )
+ {
+ pNet = Abc_ObjFanin0(pTerm);
+ // get the line length after this name is written
+ AddedLength = strlen(Abc_ObjName(pNet)) + 1;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, " \\\n" );
+ // reset the line length
+ LineLength = 0;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s", Abc_ObjName(pNet) );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the assertion list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteBlifMvAsserts( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pTerm, * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i;
+
+ LineLength = 8;
+ NameCounter = 0;
+
+ Abc_NtkForEachAssert( pNtk, pTerm, i )
+ {
+ pNet = Abc_ObjFanin0(pTerm);
+ // get the line length after this name is written
+ AddedLength = strlen(Abc_ObjName(pNet)) + 1;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, " \\\n" );
+ // reset the line length
+ LineLength = 0;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s", Abc_ObjName(pNet) );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write the latch into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteBlifMvLatch( FILE * pFile, Abc_Obj_t * pLatch )
+{
+ Abc_Obj_t * pNetLi, * pNetLo;
+ int Reset;
+ pNetLi = Abc_ObjFanin0( Abc_ObjFanin0(pLatch) );
+ pNetLo = Abc_ObjFanout0( 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, "\n" );
+ // write the reset node
+ fprintf( pFile, ".reset %s\n", Abc_ObjName(pNetLo) );
+ fprintf( pFile, "%d\n", Reset-1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write the latch into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteBlifMvSubckt( FILE * pFile, Abc_Obj_t * pNode )
+{
+ Abc_Ntk_t * pModel = pNode->pData;
+ Abc_Obj_t * pTerm;
+ int i;
+ // write the MV directives
+ fprintf( pFile, "\n" );
+ Abc_ObjForEachFanin( pNode, pTerm, i )
+ if ( Abc_ObjMvVarNum(pTerm) > 2 )
+ fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pTerm), Abc_ObjMvVarNum(pTerm) );
+ Abc_ObjForEachFanout( pNode, pTerm, i )
+ if ( Abc_ObjMvVarNum(pTerm) > 2 )
+ fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pTerm), Abc_ObjMvVarNum(pTerm) );
+ // write the subcircuit
+ fprintf( pFile, ".subckt %s %s", Abc_NtkName(pModel), Abc_ObjName(pNode) );
+ // write pairs of the formal=actual names
+ Abc_NtkForEachPi( pModel, pTerm, i )
+ {
+ fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
+ pTerm = Abc_ObjFanin( pNode, i );
+ fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
+ }
+ Abc_NtkForEachPo( pModel, pTerm, i )
+ {
+ fprintf( pFile, " %s", Abc_ObjName(Abc_ObjFanin0(pTerm)) );
+ pTerm = Abc_ObjFanout( pNode, i );
+ fprintf( pFile, "=%s", Abc_ObjName(Abc_ObjFanout0(pTerm)) );
+ }
+ fprintf( pFile, "\n" );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Write the node into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteBlifMvNode( FILE * pFile, Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pFanin;
+ char * pCur;
+ int nValues, iFanin, i;
+
+ // write .mv directives for the fanins
+ fprintf( pFile, "\n" );
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+// nValues = atoi(pCur);
+ nValues = Abc_ObjMvVarNum( pFanin );
+ if ( nValues > 2 )
+ fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pFanin), nValues );
+// while ( *pCur++ != ' ' );
+ }
+
+ // write .mv directives for the node
+// nValues = atoi(pCur);
+ nValues = Abc_ObjMvVarNum( Abc_ObjFanout0(pNode) );
+ if ( nValues > 2 )
+ fprintf( pFile, ".mv %s %d\n", Abc_ObjName(Abc_ObjFanout0(pNode)), nValues );
+// while ( *pCur++ != '\n' );
+
+ // write the .names line
+ fprintf( pFile, ".table" );
+ Io_NtkWriteBlifMvNodeFanins( pFile, pNode );
+ fprintf( pFile, "\n" );
+
+ // write the cubes
+ pCur = Abc_ObjData(pNode);
+ if ( *pCur == 'd' )
+ {
+ fprintf( pFile, ".default " );
+ pCur++;
+ }
+ // write the literals
+ for ( ; *pCur; pCur++ )
+ {
+ fprintf( pFile, "%c", *pCur );
+ if ( *pCur != '=' )
+ continue;
+ // get the number
+ iFanin = atoi( pCur+1 );
+ fprintf( pFile, "%s", Abc_ObjName(Abc_ObjFanin(pNode,iFanin)) );
+ // scroll on to the next symbol
+ while ( *pCur != ' ' && *pCur != '\n' )
+ pCur++;
+ pCur--;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the primary input list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWriteBlifMvNodeFanins( 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 );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioWriteCnf.c b/src/base/io/ioWriteCnf.c
index 09824f38..e1b2d956 100644
--- a/src/base/io/ioWriteCnf.c
+++ b/src/base/io/ioWriteCnf.c
@@ -19,13 +19,16 @@
***********************************************************************/
#include "io.h"
+#include "satSolver.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+
+static Abc_Ntk_t * s_pNtk = NULL;
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
@@ -39,33 +42,71 @@
SeeAlso []
***********************************************************************/
-int Io_WriteCnf( Abc_Ntk_t * pNtk, char * pFileName )
+int Io_WriteCnf( Abc_Ntk_t * pNtk, char * pFileName, int fAllPrimes )
{
- solver * pSat;
- if ( !Abc_NtkIsBddLogic(pNtk) )
+ sat_solver * pSat;
+ if ( Abc_NtkIsStrash(pNtk) )
+ printf( "Io_WriteCnf() warning: Generating CNF by applying heuristic AIG to CNF conversion.\n" );
+ else
+ printf( "Io_WriteCnf() warning: Generating CNF by convering logic nodes into CNF clauses.\n" );
+ if ( Abc_NtkPoNum(pNtk) != 1 )
{
- fprintf( stdout, "Io_WriteCnf(): Currently can only process logic networks with BDDs.\n" );
+ fprintf( stdout, "Io_WriteCnf(): Currently can only process the miter (the network with one PO).\n" );
return 0;
}
- if ( Abc_NtkPoNum(pNtk) != 1 )
+ if ( Abc_NtkLatchNum(pNtk) != 0 )
{
- fprintf( stdout, "Io_WriteCnf(): Currently can only solve the miter (the network with one PO).\n" );
+ fprintf( stdout, "Io_WriteCnf(): Currently can only process the miter for combinational circuits.\n" );
return 0;
}
- if ( Abc_NtkLatchNum(pNtk) != 0 )
+ if ( Abc_NtkNodeNum(pNtk) == 0 )
{
- fprintf( stdout, "Io_WriteCnf(): Currently can only solve the miter for combinational circuits.\n" );
+ fprintf( stdout, "The network has no logic nodes. No CNF file is generaled.\n" );
return 0;
}
+ // convert to logic BDD network
+ if ( Abc_NtkIsLogic(pNtk) )
+ Abc_NtkToBdd( pNtk );
// create solver with clauses
- pSat = Abc_NtkMiterSatCreate( pNtk );
+ pSat = Abc_NtkMiterSatCreate( pNtk, fAllPrimes );
+ if ( pSat == NULL )
+ {
+ fprintf( stdout, "The problem is trivially UNSAT. No CNF file is generated.\n" );
+ return 1;
+ }
// write the clauses
- Asat_SolverWriteDimacs( pSat, pFileName );
+ s_pNtk = pNtk;
+ Sat_SolverWriteDimacs( pSat, pFileName, 0, 0, 1 );
+ s_pNtk = NULL;
// free the solver
- solver_delete( pSat );
+ sat_solver_delete( pSat );
return 1;
}
+/**Function*************************************************************
+
+ Synopsis [Output the mapping of PIs into variable numbers.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteCnfOutputPiMapping( FILE * pFile, int incrementVars )
+{
+ extern Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk );
+ Abc_Ntk_t * pNtk = s_pNtk;
+ Vec_Int_t * vCiIds;
+ Abc_Obj_t * pObj;
+ int i;
+ vCiIds = Abc_NtkGetCiSatVarNums( pNtk );
+ fprintf( pFile, "c PI variable numbers: <PI_name> <SAT_var_number>\n" );
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ fprintf( pFile, "c %s %d\n", Abc_ObjName(pObj), Vec_IntEntry(vCiIds, i) + (int)(incrementVars > 0) );
+ Vec_IntFree( vCiIds );
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/base/io/ioWriteDot.c b/src/base/io/ioWriteDot.c
index 97258c81..8ae3cc42 100644
--- a/src/base/io/ioWriteDot.c
+++ b/src/base/io/ioWriteDot.c
@@ -19,18 +19,23 @@
***********************************************************************/
#include "io.h"
+#include "main.h"
+#include "mio.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+static char * Abc_NtkPrintSop( char * pSop );
+static int Abc_NtkCountLogicNodes( Vec_Ptr_t * vNodes );
+
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
- Synopsis [Writes the graph structure of AIG in DOT.]
+ Synopsis [Writes the graph structure of network for DOT.]
Description [Useful for graph visualization using tools such as GraphViz:
http://www.graphviz.org/]
@@ -40,13 +45,36 @@
SeeAlso []
***********************************************************************/
-void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName )
+void Io_WriteDot( Abc_Ntk_t * pNtk, char * FileName )
+{
+ Vec_Ptr_t * vNodes;
+ vNodes = Abc_NtkCollectObjects( pNtk );
+ Io_WriteDotNtk( pNtk, vNodes, NULL, FileName, 0, 0 );
+ Vec_PtrFree( vNodes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the graph structure of network for DOT.]
+
+ Description [Useful for graph visualization using tools such as GraphViz:
+ http://www.graphviz.org/]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse )
{
FILE * pFile;
- Abc_Obj_t * pNode, * pTemp, * pPrev;
- int LevelMin, LevelMax, fHasCos, Level, i;
+ Abc_Obj_t * pNode, * pFanin;
+ char * pSopString;
+ int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl;
int Limit = 300;
+ assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) );
+
if ( vNodes->nSize < 1 )
{
printf( "The set has no nodes. DOT file is not written.\n" );
@@ -66,6 +94,16 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
return;
}
+ // transform logic functions from BDD to SOP
+ if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) )
+ {
+ if ( !Abc_NtkBddToSop(pNtk, 0) )
+ {
+ printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" );
+ return;
+ }
+ }
+
// mark the nodes from the set
Vec_PtrForEachEntry( vNodes, pNode, i )
pNode->fMarkC = 1;
@@ -73,6 +111,17 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
Vec_PtrForEachEntry( vNodesShow, pNode, i )
pNode->fMarkB = 1;
+ // get the levels of nodes
+ LevelMax = Abc_NtkLevel( pNtk );
+ if ( fUseReverse )
+ {
+ LevelMin = Abc_NtkLevelReverse( pNtk );
+ assert( LevelMax == LevelMin );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ if ( Abc_ObjIsNode(pNode) )
+ pNode->Level = LevelMax - pNode->Level + 1;
+ }
+
// find the largest and the smallest levels
LevelMin = 10000;
LevelMax = -1;
@@ -102,14 +151,17 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
}
// write the DOT header
- fprintf( pFile, "# %s\n", "AIG generated by ABC" );
+ fprintf( pFile, "# %s\n", "Network structure generated by ABC" );
fprintf( pFile, "\n" );
- fprintf( pFile, "digraph AIG {\n" );
+ fprintf( pFile, "digraph network {\n" );
fprintf( pFile, "size = \"7.5,10\";\n" );
+// fprintf( pFile, "size = \"10,8.5\";\n" );
+// fprintf( pFile, "size = \"14,11\";\n" );
+// fprintf( pFile, "page = \"8,11\";\n" );
// fprintf( pFile, "ranksep = 0.5;\n" );
// fprintf( pFile, "nodesep = 0.5;\n" );
fprintf( pFile, "center = true;\n" );
-// fprintf( pFile, "orientation = landscape;\n" );
+// fprintf( pFile, "orientation = landscape;\n" );
// fprintf( pFile, "edge [fontsize = 10];\n" );
// fprintf( pFile, "edge [dir = none];\n" );
fprintf( pFile, "edge [dir = back];\n" );
@@ -158,7 +210,7 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
fprintf( pFile, " fontsize=20,\n" );
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
fprintf( pFile, " label=\"" );
- fprintf( pFile, "%s", "AIG generated by ABC" );
+ fprintf( pFile, "%s", "Network structure visualized by ABC" );
fprintf( pFile, "\\n" );
fprintf( pFile, "Benchmark \\\"%s\\\". ", pNtk->pName );
fprintf( pFile, "Time was %s. ", Extra_TimeStamp() );
@@ -176,7 +228,10 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
fprintf( pFile, " fontsize=18,\n" );
fprintf( pFile, " fontname = \"Times-Roman\",\n" );
fprintf( pFile, " label=\"" );
- fprintf( pFile, "The set contains %d nodes and spans %d levels.", vNodes->nSize, LevelMax - LevelMin );
+ if ( Abc_NtkObjNum(pNtk) == Vec_PtrSize(vNodes) )
+ fprintf( pFile, "The network contains %d logic nodes and %d latches.", Abc_NtkNodeNum(pNtk), Abc_NtkLatchNum(pNtk) );
+ else
+ fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Abc_NtkCountLogicNodes(vNodes), LevelMax - LevelMin + 1 );
fprintf( pFile, "\\n" );
fprintf( pFile, "\"\n" );
fprintf( pFile, " ];\n" );
@@ -191,14 +246,16 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
fprintf( pFile, " rank = same;\n" );
// the labeling node of this level
fprintf( pFile, " Level%d;\n", LevelMax );
- // generat the PO nodes
+ // generate the PO nodes
Vec_PtrForEachEntry( vNodes, pNode, i )
{
if ( !Abc_ObjIsCo(pNode) )
continue;
- fprintf( pFile, " Node%d%s [label = \"%s%s\"", pNode->Id,
- (Abc_ObjIsLatch(pNode)? "_in":""), Abc_ObjName(pNode), (Abc_ObjIsLatch(pNode)? "_in":"") );
- fprintf( pFile, ", shape = %s", (Abc_ObjIsLatch(pNode)? "box":"invtriangle") );
+ fprintf( pFile, " Node%d [label = \"%s%s\"",
+ pNode->Id,
+ (Abc_ObjIsBi(pNode)? Abc_ObjName(Abc_ObjFanout0(pNode)):Abc_ObjName(pNode)),
+ (Abc_ObjIsBi(pNode)? "_in":"") );
+ fprintf( pFile, ", shape = %s", (Abc_ObjIsBi(pNode)? "box":"invtriangle") );
if ( pNode->fMarkB )
fprintf( pFile, ", style = filled" );
fprintf( pFile, ", color = coral, fillcolor = coral" );
@@ -220,7 +277,19 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
{
if ( (int)pNode->Level != Level )
continue;
- fprintf( pFile, " Node%d [label = \"%d\"", pNode->Id, pNode->Id );
+ if ( Abc_ObjFaninNum(pNode) == 0 )
+ continue;
+// fprintf( pFile, " Node%d [label = \"%d\"", pNode->Id, pNode->Id );
+ if ( Abc_NtkIsStrash(pNtk) )
+ pSopString = "";
+ else if ( Abc_NtkHasMapping(pNtk) && fGateNames )
+ pSopString = Mio_GateReadName(pNode->pData);
+ else if ( Abc_NtkHasMapping(pNtk) )
+ pSopString = Abc_NtkPrintSop(Mio_GateReadSop(pNode->pData));
+ else
+ pSopString = Abc_NtkPrintSop(pNode->pData);
+ fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id, pSopString );
+
fprintf( pFile, ", shape = ellipse" );
if ( pNode->fMarkB )
fprintf( pFile, ", style = filled" );
@@ -238,14 +307,27 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
fprintf( pFile, " rank = same;\n" );
// the labeling node of this level
fprintf( pFile, " Level%d;\n", LevelMin );
- // generat the PO nodes
+ // generate the PO nodes
Vec_PtrForEachEntry( vNodes, pNode, i )
{
if ( !Abc_ObjIsCi(pNode) )
+ {
+ // check if the costant node is present
+ if ( Abc_ObjFaninNum(pNode) == 0 && Abc_ObjFanoutNum(pNode) > 0 )
+ {
+ fprintf( pFile, " Node%d [label = \"Const%d\"", pNode->Id, Abc_NtkIsStrash(pNode->pNtk) || Abc_NodeIsConst1(pNode) );
+ fprintf( pFile, ", shape = ellipse" );
+ if ( pNode->fMarkB )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
continue;
- fprintf( pFile, " Node%d%s [label = \"%s%s\"", pNode->Id,
- (Abc_ObjIsLatch(pNode)? "_out":""), Abc_ObjName(pNode), (Abc_ObjIsLatch(pNode)? "_out":"") );
- fprintf( pFile, ", shape = %s", (Abc_ObjIsLatch(pNode)? "box":"triangle") );
+ }
+ fprintf( pFile, " Node%d [label = \"%s\"",
+ pNode->Id,
+ (Abc_ObjIsBo(pNode)? Abc_ObjName(Abc_ObjFanin0(pNode)):Abc_ObjName(pNode)) );
+ fprintf( pFile, ", shape = %s", (Abc_ObjIsBo(pNode)? "box":"triangle") );
if ( pNode->fMarkB )
fprintf( pFile, ", style = filled" );
fprintf( pFile, ", color = coral, fillcolor = coral" );
@@ -262,48 +344,387 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
{
if ( (int)pNode->Level != LevelMax )
continue;
- fprintf( pFile, "title2 -> Node%d%s [style = invis];\n", pNode->Id,
- (Abc_ObjIsLatch(pNode)? "_in":"") );
+ fprintf( pFile, "title2 -> Node%d [style = invis];\n", pNode->Id );
}
// generate edges
Vec_PtrForEachEntry( vNodes, pNode, i )
{
- if ( Abc_ObjFaninNum(pNode) == 0 )
+ if ( Abc_ObjIsLatch(pNode) )
continue;
- // generate the edge from this node to the next
- if ( Abc_ObjFanin0(pNode)->fMarkC )
+ Abc_ObjForEachFanin( pNode, pFanin, k )
{
- fprintf( pFile, "Node%d%s", pNode->Id, (Abc_ObjIsLatch(pNode)? "_in":"") );
+ if ( Abc_ObjIsLatch(pFanin) )
+ continue;
+ fCompl = 0;
+ if ( Abc_NtkIsStrash(pNtk) )
+ fCompl = Abc_ObjFaninC(pNode, k);
+ // generate the edge from this node to the next
+ fprintf( pFile, "Node%d", pNode->Id );
fprintf( pFile, " -> " );
- fprintf( pFile, "Node%d%s", Abc_ObjFaninId0(pNode), (Abc_ObjIsLatch(Abc_ObjFanin0(pNode))? "_out":"") );
- fprintf( pFile, " [style = %s]", Abc_ObjFaninC0(pNode)? "dotted" : "bold" );
+ fprintf( pFile, "Node%d", pFanin->Id );
+ fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" );
+// fprintf( pFile, ", label = \"%c\"", 'a' + k );
+ fprintf( pFile, "]" );
fprintf( pFile, ";\n" );
}
- if ( Abc_ObjFaninNum(pNode) == 1 )
+ }
+
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+
+ // unmark the nodes from the set
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ pNode->fMarkC = 0;
+ if ( vNodesShow )
+ Vec_PtrForEachEntry( vNodesShow, pNode, i )
+ pNode->fMarkB = 0;
+
+ // convert the network back into BDDs if this is how it was
+ if ( fHasBdds )
+ Abc_NtkSopToBdd(pNtk);
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the graph structure of network for DOT.]
+
+ Description [Useful for graph visualization using tools such as GraphViz:
+ http://www.graphviz.org/]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteDotSeq( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse )
+{
+ FILE * pFile;
+ Abc_Obj_t * pNode, * pFanin;
+ char * pSopString;
+ int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl;
+ int Limit = 300;
+
+ assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) );
+
+ if ( vNodes->nSize < 1 )
+ {
+ printf( "The set has no nodes. DOT file is not written.\n" );
+ return;
+ }
+
+ if ( vNodes->nSize > Limit )
+ {
+ printf( "The set has more than %d nodes. DOT file is not written.\n", Limit );
+ return;
+ }
+
+ // start the stream
+ if ( (pFile = fopen( pFileName, "w" )) == NULL )
+ {
+ fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName );
+ return;
+ }
+
+ // transform logic functions from BDD to SOP
+ if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) )
+ {
+ if ( !Abc_NtkBddToSop(pNtk, 0) )
+ {
+ printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" );
+ return;
+ }
+ }
+
+ // mark the nodes from the set
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ pNode->fMarkC = 1;
+ if ( vNodesShow )
+ Vec_PtrForEachEntry( vNodesShow, pNode, i )
+ pNode->fMarkB = 1;
+
+ // get the levels of nodes
+ LevelMax = Abc_NtkLevel( pNtk );
+ if ( fUseReverse )
+ {
+ LevelMin = Abc_NtkLevelReverse( pNtk );
+ assert( LevelMax == LevelMin );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ if ( Abc_ObjIsNode(pNode) )
+ pNode->Level = LevelMax - pNode->Level + 1;
+ }
+
+ // find the largest and the smallest levels
+ LevelMin = 10000;
+ LevelMax = -1;
+ fHasCos = 0;
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ if ( Abc_ObjIsCo(pNode) )
+ {
+ fHasCos = 1;
continue;
- // generate the edge from this node to the next
- if ( Abc_ObjFanin1(pNode)->fMarkC )
+ }
+ if ( LevelMin > (int)pNode->Level )
+ LevelMin = pNode->Level;
+ if ( LevelMax < (int)pNode->Level )
+ LevelMax = pNode->Level;
+ }
+
+ // set the level of the CO nodes
+ if ( fHasCos )
+ {
+ LevelMax++;
+ Vec_PtrForEachEntry( vNodes, pNode, i )
{
- fprintf( pFile, "Node%d", pNode->Id );
- fprintf( pFile, " -> " );
- fprintf( pFile, "Node%d%s", Abc_ObjFaninId1(pNode), (Abc_ObjIsLatch(Abc_ObjFanin1(pNode))? "_out":"") );
- fprintf( pFile, " [style = %s]", Abc_ObjFaninC1(pNode)? "dotted" : "bold" );
- fprintf( pFile, ";\n" );
+ if ( Abc_ObjIsCo(pNode) )
+ pNode->Level = LevelMax;
+ }
+ }
+
+ // write the DOT header
+ fprintf( pFile, "# %s\n", "Network structure generated by ABC" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "digraph network {\n" );
+ fprintf( pFile, "size = \"7.5,10\";\n" );
+// fprintf( pFile, "size = \"10,8.5\";\n" );
+// fprintf( pFile, "size = \"14,11\";\n" );
+// fprintf( pFile, "page = \"8,11\";\n" );
+// fprintf( pFile, "ranksep = 0.5;\n" );
+// fprintf( pFile, "nodesep = 0.5;\n" );
+ fprintf( pFile, "center = true;\n" );
+// fprintf( pFile, "orientation = landscape;\n" );
+// fprintf( pFile, "edge [fontsize = 10];\n" );
+// fprintf( pFile, "edge [dir = none];\n" );
+ fprintf( pFile, "edge [dir = back];\n" );
+ fprintf( pFile, "\n" );
+
+ // labels on the left of the picture
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " node [shape = plaintext];\n" );
+ fprintf( pFile, " edge [style = invis];\n" );
+ fprintf( pFile, " LevelTitle1 [label=\"\"];\n" );
+ fprintf( pFile, " LevelTitle2 [label=\"\"];\n" );
+ // generate node names with labels
+ for ( Level = LevelMax; Level >= LevelMin; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ fprintf( pFile, " [label = " );
+ // label name
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "\"" );
+ fprintf( pFile, "];\n" );
+ }
+
+ // genetate the sequence of visible/invisible nodes to mark levels
+ fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" );
+ for ( Level = LevelMax; Level >= LevelMin; Level-- )
+ {
+ // the visible node name
+ fprintf( pFile, " Level%d", Level );
+ // the connector
+ if ( Level != LevelMin )
+ fprintf( pFile, " ->" );
+ else
+ fprintf( pFile, ";" );
+ }
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate title box on top
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle1;\n" );
+ fprintf( pFile, " title1 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=20,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ fprintf( pFile, "%s", "Network structure visualized by ABC" );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "Benchmark \\\"%s\\\". ", pNtk->pName );
+ fprintf( pFile, "Time was %s. ", Extra_TimeStamp() );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate statistics box
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ fprintf( pFile, " LevelTitle2;\n" );
+ fprintf( pFile, " title2 [shape=plaintext,\n" );
+ fprintf( pFile, " fontsize=18,\n" );
+ fprintf( pFile, " fontname = \"Times-Roman\",\n" );
+ fprintf( pFile, " label=\"" );
+ if ( Abc_NtkObjNum(pNtk) == Vec_PtrSize(vNodes) )
+ fprintf( pFile, "The network contains %d logic nodes and %d latches.", Abc_NtkNodeNum(pNtk), Abc_NtkLatchNum(pNtk) );
+ else
+ fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Abc_NtkCountLogicNodes(vNodes), LevelMax - LevelMin + 1 );
+ fprintf( pFile, "\\n" );
+ fprintf( pFile, "\"\n" );
+ fprintf( pFile, " ];\n" );
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate the POs
+ if ( fHasCos )
+ {
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", LevelMax );
+ // generate the PO nodes
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ if ( !Abc_ObjIsPo(pNode) )
+ continue;
+ fprintf( pFile, " Node%d [label = \"%s\"", pNode->Id, Abc_ObjName(pNode) );
+ fprintf( pFile, ", shape = %s", "invtriangle" );
+ if ( pNode->fMarkB )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ }
+
+ // generate nodes of each rank
+ for ( Level = LevelMax - fHasCos; Level >= LevelMin && Level > 0; Level-- )
+ {
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", Level );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( (int)pNode->Level != Level )
+ continue;
+// fprintf( pFile, " Node%d [label = \"%d\"", pNode->Id, pNode->Id );
+ if ( Abc_NtkIsStrash(pNtk) )
+ pSopString = "";
+ else if ( Abc_NtkHasMapping(pNtk) && fGateNames )
+ pSopString = Mio_GateReadName(pNode->pData);
+ else if ( Abc_NtkHasMapping(pNtk) )
+ pSopString = Abc_NtkPrintSop(Mio_GateReadSop(pNode->pData));
+ else
+ pSopString = Abc_NtkPrintSop(pNode->pData);
+ fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id, pSopString );
+
+ fprintf( pFile, ", shape = ellipse" );
+ if ( pNode->fMarkB )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, "];\n" );
+ }
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ }
+
+ // generate the PI nodes if any
+ if ( LevelMin == 0 )
+ {
+ fprintf( pFile, "{\n" );
+ fprintf( pFile, " rank = same;\n" );
+ // the labeling node of this level
+ fprintf( pFile, " Level%d;\n", LevelMin );
+ // generate the PO nodes
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ if ( pNode->Level > 0 )
+ continue;
+ if ( !Abc_ObjIsPi(pNode) )
+ {
+ // check if the costant node is present
+ if ( Abc_ObjFaninNum(pNode) == 0 && Abc_ObjFanoutNum(pNode) > 0 )
+ {
+ fprintf( pFile, " Node%d [label = \"Const1\"", pNode->Id );
+ fprintf( pFile, ", shape = ellipse" );
+ if ( pNode->fMarkB )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+ continue;
+ }
+ fprintf( pFile, " Node%d [label = \"%s\"", pNode->Id, Abc_ObjName(pNode) );
+ fprintf( pFile, ", shape = %s", "triangle" );
+ if ( pNode->fMarkB )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
}
- // generate the edges between the equivalent nodes
- pPrev = pNode;
- for ( pTemp = pNode->pData; pTemp; pTemp = pTemp->pData )
+ fprintf( pFile, "}" );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+ }
+
+// fprintf( pFile, "{\n" );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ if ( !Abc_ObjIsLatch(pNode) )
+ continue;
+ fprintf( pFile, "Node%d [label = \"%s\"", pNode->Id, Abc_ObjName(pNode) );
+ fprintf( pFile, ", shape = box" );
+ if ( pNode->fMarkB )
+ fprintf( pFile, ", style = filled" );
+ fprintf( pFile, ", color = coral, fillcolor = coral" );
+ fprintf( pFile, "];\n" );
+ }
+// fprintf( pFile, "}" );
+// fprintf( pFile, "\n" );
+ fprintf( pFile, "\n" );
+
+ // generate invisible edges from the square down
+ fprintf( pFile, "title1 -> title2 [style = invis];\n" );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ if ( (int)pNode->Level != LevelMax )
+ continue;
+ if ( !Abc_ObjIsPo(pNode) )
+ continue;
+ fprintf( pFile, "title2 -> Node%d [style = invis];\n", pNode->Id );
+ }
+
+ // generate edges
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ if ( Abc_ObjIsBi(pNode) || Abc_ObjIsBo(pNode) )
+ continue;
+ Abc_ObjForEachFanin( pNode, pFanin, k )
{
- if ( pTemp->fMarkC )
+ fCompl = 0;
+ if ( Abc_NtkIsStrash(pNtk) )
{
- fprintf( pFile, "Node%d", pPrev->Id );
- fprintf( pFile, " -> " );
- fprintf( pFile, "Node%d", pTemp->Id );
- fprintf( pFile, " [style = %s]", (pPrev->fPhase ^ pTemp->fPhase)? "dotted" : "bold" );
- fprintf( pFile, ";\n" );
- pPrev = pTemp;
+ if ( Abc_ObjIsBi(pFanin) )
+ fCompl = Abc_ObjFaninC(pFanin, k);
+ else
+ fCompl = Abc_ObjFaninC(pNode, k);
}
+ if ( Abc_ObjIsBi(pFanin) || Abc_ObjIsBo(pFanin) )
+ pFanin = Abc_ObjFanin0(pFanin);
+ if ( Abc_ObjIsBi(pFanin) || Abc_ObjIsBo(pFanin) )
+ pFanin = Abc_ObjFanin0(pFanin);
+ if ( !pFanin->fMarkC )
+ continue;
+
+ // generate the edge from this node to the next
+ fprintf( pFile, "Node%d", pNode->Id );
+ fprintf( pFile, " -> " );
+ fprintf( pFile, "Node%d", pFanin->Id );
+ fprintf( pFile, " [style = %s", fCompl? "dotted" : "bold" );
+// fprintf( pFile, ", label = \"%c\"", 'a' + k );
+ fprintf( pFile, "]" );
+ fprintf( pFile, ";\n" );
}
}
@@ -318,6 +739,67 @@ void Io_WriteDot( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow,
if ( vNodesShow )
Vec_PtrForEachEntry( vNodesShow, pNode, i )
pNode->fMarkB = 0;
+
+ // convert the network back into BDDs if this is how it was
+ if ( fHasBdds )
+ Abc_NtkSopToBdd(pNtk);
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes the printable SOP form.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Abc_NtkPrintSop( char * pSop )
+{
+ static char Buffer[1000];
+ char * pGet, * pSet;
+ pSet = Buffer;
+ for ( pGet = pSop; *pGet; pGet++ )
+ {
+ if ( *pGet == '\n' )
+ {
+ *pSet++ = '\\';
+ *pSet++ = 'n';
+ }
+ else
+ *pSet++ = *pGet;
+ }
+ *(pSet-2) = 0;
+ return Buffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the printable SOP form.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkCountLogicNodes( Vec_Ptr_t * vNodes )
+{
+ Abc_Obj_t * pObj;
+ int i, Counter = 0;
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ if ( !Abc_ObjIsNode(pObj) )
+ continue;
+ if ( Abc_ObjFaninNum(pObj) == 0 && Abc_ObjFanoutNum(pObj) == 0 )
+ continue;
+ Counter ++;
+ }
+ return Counter;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/io/ioWriteEqn.c b/src/base/io/ioWriteEqn.c
index 6c2893b5..95c54577 100644
--- a/src/base/io/ioWriteEqn.c
+++ b/src/base/io/ioWriteEqn.c
@@ -25,12 +25,12 @@
////////////////////////////////////////////////////////////////////////
static void Io_NtkWriteEqnOne( FILE * pFile, Abc_Ntk_t * pNtk );
-static void Io_NtkWriteEqnPis( FILE * pFile, Abc_Ntk_t * pNtk );
-static void Io_NtkWriteEqnPos( FILE * pFile, Abc_Ntk_t * pNtk );
-static void Io_NtkWriteEqnNode( FILE * pFile, Abc_Obj_t * pNode );
+static void Io_NtkWriteEqnCis( FILE * pFile, Abc_Ntk_t * pNtk );
+static void Io_NtkWriteEqnCos( FILE * pFile, Abc_Ntk_t * pNtk );
+static int Io_NtkWriteEqnCheck( Abc_Ntk_t * pNtk );
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
@@ -48,10 +48,14 @@ void Io_WriteEqn( Abc_Ntk_t * pNtk, char * pFileName )
{
FILE * pFile;
- assert( Abc_NtkIsSopNetlist(pNtk) );
+ assert( Abc_NtkIsAigNetlist(pNtk) );
if ( Abc_NtkLatchNum(pNtk) > 0 )
printf( "Warning: only combinational portion is being written.\n" );
+ // check that the names are fine for the EQN format
+ if ( !Io_NtkWriteEqnCheck(pNtk) )
+ return;
+
// start the output stream
pFile = fopen( pFileName, "w" );
if ( pFile == NULL )
@@ -80,28 +84,37 @@ void Io_WriteEqn( Abc_Ntk_t * pNtk, char * pFileName )
***********************************************************************/
void Io_NtkWriteEqnOne( FILE * pFile, Abc_Ntk_t * pNtk )
{
+ Vec_Vec_t * vLevels;
ProgressBar * pProgress;
- Abc_Obj_t * pNode;
- int i;
+ Abc_Obj_t * pNode, * pFanin;
+ int i, k;
// write the PIs
fprintf( pFile, "INORDER =" );
- Io_NtkWriteEqnPis( pFile, pNtk );
+ Io_NtkWriteEqnCis( pFile, pNtk );
fprintf( pFile, ";\n" );
// write the POs
fprintf( pFile, "OUTORDER =" );
- Io_NtkWriteEqnPos( pFile, pNtk );
+ Io_NtkWriteEqnCos( pFile, pNtk );
fprintf( pFile, ";\n" );
// write each internal node
+ vLevels = Vec_VecAlloc( 10 );
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
- Io_NtkWriteEqnNode( pFile, pNode );
+ fprintf( pFile, "%s = ", Abc_ObjName(Abc_ObjFanout0(pNode)) );
+ // set the input names
+ Abc_ObjForEachFanin( pNode, pFanin, k )
+ Hop_IthVar(pNtk->pManFunc, k)->pData = Abc_ObjName(pFanin);
+ // write the formula
+ Hop_ObjPrintEqn( pFile, pNode->pData, vLevels, 0 );
+ fprintf( pFile, ";\n" );
}
Extra_ProgressBarStop( pProgress );
+ Vec_VecFree( vLevels );
}
@@ -116,7 +129,7 @@ void Io_NtkWriteEqnOne( FILE * pFile, Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-void Io_NtkWriteEqnPis( FILE * pFile, Abc_Ntk_t * pNtk )
+void Io_NtkWriteEqnCis( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pTerm, * pNet;
int LineLength;
@@ -156,7 +169,7 @@ void Io_NtkWriteEqnPis( FILE * pFile, Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-void Io_NtkWriteEqnPos( FILE * pFile, Abc_Ntk_t * pNtk )
+void Io_NtkWriteEqnCos( FILE * pFile, Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pTerm, * pNet;
int LineLength;
@@ -187,73 +200,51 @@ void Io_NtkWriteEqnPos( FILE * pFile, Abc_Ntk_t * pNtk )
/**Function*************************************************************
- Synopsis [Write the node into a file.]
+ Synopsis [Make sure the network does not have offending names.]
Description []
-
+
SideEffects []
SeeAlso []
***********************************************************************/
-void Io_NtkWriteEqnNode( FILE * pFile, Abc_Obj_t * pNode )
+int Io_NtkWriteEqnCheck( Abc_Ntk_t * pNtk )
{
- Abc_Obj_t * pNet;
- int LineLength;
- int AddedLength;
- int NameCounter;
- char * pCube;
- int Value, fFirstLit, i;
-
- fprintf( pFile, "%s = ", Abc_ObjName(pNode) );
-
- if ( Abc_SopIsConst0(pNode->pData) )
- {
- fprintf( pFile, "0;\n" );
- return;
- }
- if ( Abc_SopIsConst1(pNode->pData) )
- {
- fprintf( pFile, "1;\n" );
- return;
- }
+ Abc_Obj_t * pObj;
+ char * pName;
+ int i, k, Length;
+ int RetValue = 1;
- NameCounter = 0;
- LineLength = strlen(Abc_ObjName(pNode)) + 3;
- Abc_SopForEachCube( pNode->pData, Abc_ObjFaninNum(pNode), pCube )
+ // make sure the network does not have proper names, such as "0" or "1" or containing parantheses
+ Abc_NtkForEachObj( pNtk, pObj, i )
{
- if ( pCube != pNode->pData )
+ pName = Nm_ManFindNameById(pNtk->pManName, i);
+ if ( pName == NULL )
+ continue;
+ Length = strlen(pName);
+ if ( pName[0] == '0' || pName[0] == '1' )
{
- fprintf( pFile, " + " );
- LineLength += 3;
+ RetValue = 0;
+ break;
}
-
- // add the cube
- fFirstLit = 1;
- Abc_CubeForEachVar( pCube, Value, i )
- {
- if ( Value == '-' )
- continue;
- pNet = Abc_ObjFanin( pNode, i );
- // get the line length after this name is written
- AddedLength = !fFirstLit + (Value == '0') + strlen(Abc_ObjName(pNet));
- if ( NameCounter && LineLength + AddedLength + 6 > IO_WRITE_LINE_LENGTH )
- { // write the line extender
- fprintf( pFile, " \n " );
- // reset the line length
- LineLength = 0;
- NameCounter = 0;
+ for ( k = 0; k < Length; k++ )
+ if ( pName[k] == '(' || pName[k] == ')' || pName[k] == '!' || pName[k] == '*' || pName[k] == '+' )
+ {
+ RetValue = 0;
+ break;
}
- fprintf( pFile, "%s%s%s", (fFirstLit? "": "*"), ((Value == '0')? "!":""), Abc_ObjName(pNet) );
- LineLength += AddedLength;
- NameCounter++;
- fFirstLit = 0;
- }
+ if ( k < Length )
+ break;
}
- fprintf( pFile, ";\n" );
+ if ( RetValue == 0 )
+ {
+ printf( "The network cannot be written in the EQN format because object %d has name \"%s\".\n", i, pName );
+ printf( "Consider renaming the objects using command \"short_names\" and trying again.\n" );
+ }
+ return RetValue;
}
-
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/io/ioWriteGml.c b/src/base/io/ioWriteGml.c
index ab9f1143..dc897300 100644
--- a/src/base/io/ioWriteGml.c
+++ b/src/base/io/ioWriteGml.c
@@ -25,7 +25,7 @@
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
diff --git a/src/base/io/ioWriteList.c b/src/base/io/ioWriteList.c
new file mode 100644
index 00000000..71af7c53
--- /dev/null
+++ b/src/base/io/ioWriteList.c
@@ -0,0 +1,288 @@
+/**CFile****************************************************************
+
+ FileName [ioWriteList.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to write the graph structure of sequential AIG.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioWriteList.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+/*
+-------- Original Message --------
+Subject: Re: abc release and retiming
+Date: Sun, 13 Nov 2005 20:31:18 -0500 (EST)
+From: Luca Carloni <luca@cs.columbia.edu>
+To: Alan Mishchenko <alanmi@eecs.berkeley.edu>
+
+Alan,
+
+My graph-representation file format is based on an adjacency list
+representation and is indeed quite simple, in fact maybe too simple... I
+used it in order to reason on relatively small weighed direct graphs. I
+simply list all vertices, one per line and for each vertex "V_source" I
+list all vertices that are "sinks" with respect to it, i.e. such that
+there is a distinct arc between "V_source" and each of them (in
+paranthesis I list the name of the edge and its weight (number of latency
+on that path). For instance, if you look at the following graph, you have
+that vertex "v_5" is connected to vertex "v_6" through a directed arc
+called "v_5_to_v_6" whose latency is equal to 3, i.e. there are three
+flip-flops on this arc. Still, notice that I sometime interpret the graph
+also as the representation of a LIS where each node corresponds to a
+shell encapsulating a sequential core module (i.e. a module which does not
+contain any combinational path between its inputs and its outputs). With
+this representation an arc of latency 3 is interpreted as a wire where two
+relay stations have been inserted in addition to the flip-flop terminating
+the output of the core module.
+
+Finally, notice that the name of the arc does not necessarily have to be
+"v_5_to_v_6", but it could have been something like "arc_222" or "xyz" as
+long as it is a unique name in the graph.
+
+Thanks,
+Luca
+
+Example of graph representation
+-----------------------------------------------------------------------------
+v_5 > v_6 ([v_5_to_v_6] = 3), v_12 ([v_5_to_v_12] = 2).
+v_2 > v_4 ([v_2_to_v_4] = 1), v_10_s0 ([v_2_to_v_10_s0] = 6), v_12 ([v_2_to_v_12] = 3).
+v_9 > v_10_s0 ([v_9_to_v_10_s0] = 5), v_12 ([v_9_to_v_12] = 2).
+v_12 > v_13 ([v_12_to_v_13] = 5).
+v_13 > v_14 ([v_13_to_v_14] = 1).
+v_6 > v_7 ([v_6_to_v_7] = 2).
+v_4 > v_5 ([v_4_to_v_5] = 2).
+v_1 > v_2 ([v_1_to_v_2] = 1).
+v_7 > v_8 ([v_7_to_v_8] = 2).
+t > .
+v_14 > t ([v_14_to_t] = 1), v_5 ([v_14_to_v_5] = 1).
+v_8 > v_9 ([v_8_to_v_9] = 2).
+s > v_1 ([s_to_v_1] = 1).
+v_10_s0 > v_10_s1 ([v_10_s0_to_v_10_s1] = 1).
+v_10_s1 > v_4 ([v_10_s1__v_4] = 1), v_8 ([v_10_s1__v_8] = 1).
+-----------------------------------------------------------------------------
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Io_WriteListEdge( FILE * pFile, Abc_Obj_t * pObj );
+static void Io_WriteListHost( FILE * pFile, Abc_Ntk_t * pNtk );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Writes the adjacency list for a sequential AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost )
+{
+ FILE * pFile;
+ Abc_Obj_t * pObj;
+ int i;
+
+// assert( Abc_NtkIsSeq(pNtk) );
+
+ // start the output stream
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Io_WriteList(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+
+ fprintf( pFile, "# Adjacency list for sequential AIG \"%s\"\n", pNtk->pName );
+ fprintf( pFile, "# written by ABC on %s\n", Extra_TimeStamp() );
+
+ // write the constant node
+ if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk) ) > 0 )
+ Io_WriteListEdge( pFile, Abc_AigConst1(pNtk) );
+
+ // write the PI edges
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Io_WriteListEdge( pFile, pObj );
+
+ // write the internal nodes
+ Abc_AigForEachAnd( pNtk, pObj, i )
+ Io_WriteListEdge( pFile, pObj );
+
+ // write the host node
+ if ( fUseHost )
+ Io_WriteListHost( pFile, pNtk );
+ else
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ Io_WriteListEdge( pFile, pObj );
+
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the adjacency list for one edge in a sequential AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteListEdge( FILE * pFile, Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanout;
+ int i;
+ fprintf( pFile, "%-10s > ", Abc_ObjName(pObj) );
+ Abc_ObjForEachFanout( pObj, pFanout, i )
+ {
+ fprintf( pFile, " %s", Abc_ObjName(pFanout) );
+ fprintf( pFile, " ([%s_to_", Abc_ObjName(pObj) );
+// fprintf( pFile, "%s] = %d)", Abc_ObjName(pFanout), Seq_ObjFanoutL(pObj, pFanout) );
+ fprintf( pFile, "%s] = %d)", Abc_ObjName(pFanout), 0 );
+ if ( i != Abc_ObjFanoutNum(pObj) - 1 )
+ fprintf( pFile, "," );
+ }
+ fprintf( pFile, "." );
+ fprintf( pFile, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the adjacency list for one edge in a sequential AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteListHost( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int i;
+
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ fprintf( pFile, "%-10s > ", Abc_ObjName(pObj) );
+ fprintf( pFile, " %s ([%s_to_%s] = %d)", "HOST", Abc_ObjName(pObj), "HOST", 0 );
+ fprintf( pFile, "." );
+ fprintf( pFile, "\n" );
+ }
+
+ fprintf( pFile, "%-10s > ", "HOST" );
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ {
+ fprintf( pFile, " %s", Abc_ObjName(pObj) );
+ fprintf( pFile, " ([%s_to_%s] = %d)", "HOST", Abc_ObjName(pObj), 0 );
+ if ( i != Abc_NtkPiNum(pNtk) - 1 )
+ fprintf( pFile, "," );
+ }
+ fprintf( pFile, "." );
+ fprintf( pFile, "\n" );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the adjacency list for a sequential AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteCellNet( Abc_Ntk_t * pNtk, char * pFileName )
+{
+ FILE * pFile;
+ Abc_Obj_t * pObj, * pFanout;
+ int i, k;
+
+ assert( Abc_NtkIsLogic(pNtk) );
+
+ // start the output stream
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Io_WriteCellNet(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+
+ fprintf( pFile, "# CellNet file for network \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
+
+ // the only tricky part with writing is handling latches:
+ // each latch comes with (a) single-input latch-input node, (b) latch proper, (c) single-input latch-output node
+ // we arbitrarily decide to use the interger ID of the latch-input node to represent the latch in the file
+ // (this ID is used for both the cell and the net driven by that cell)
+
+ // write the PIs
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ fprintf( pFile, "cell %d is 0\n", pObj->Id );
+ // write the POs
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ fprintf( pFile, "cell %d is 1\n", pObj->Id );
+ // write the latches (use the ID of latch input)
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ fprintf( pFile, "cell %d is 2\n", Abc_ObjFanin0(pObj)->Id );
+ // write the logic nodes
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ fprintf( pFile, "cell %d is %d\n", pObj->Id, 3+Abc_ObjFaninNum(pObj) );
+
+ // write the nets driven by PIs
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ {
+ fprintf( pFile, "net %d %d 0", pObj->Id, pObj->Id );
+ Abc_ObjForEachFanout( pObj, pFanout, k )
+ fprintf( pFile, " %d %d", pFanout->Id, 1 + Abc_ObjFanoutFaninNum(pFanout, pObj) );
+ fprintf( pFile, "\n" );
+ }
+ // write the nets driven by latches
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ fprintf( pFile, "net %d %d 0", Abc_ObjFanin0(pObj)->Id, Abc_ObjFanin0(pObj)->Id );
+ pObj = Abc_ObjFanout0(pObj);
+ Abc_ObjForEachFanout( pObj, pFanout, k )
+ fprintf( pFile, " %d %d", pFanout->Id, 1 + Abc_ObjFanoutFaninNum(pFanout, pObj) );
+ fprintf( pFile, "\n" );
+ }
+ // write the nets driven by nodes
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ fprintf( pFile, "net %d %d 0", pObj->Id, pObj->Id );
+ Abc_ObjForEachFanout( pObj, pFanout, k )
+ fprintf( pFile, " %d %d", pFanout->Id, 1 + Abc_ObjFanoutFaninNum(pFanout, pObj) );
+ fprintf( pFile, "\n" );
+ }
+
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/ioWritePla.c b/src/base/io/ioWritePla.c
index 25a68978..b119751c 100644
--- a/src/base/io/ioWritePla.c
+++ b/src/base/io/ioWritePla.c
@@ -27,7 +27,7 @@
static int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk );
////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFITIONS ///
+/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
@@ -47,7 +47,7 @@ int Io_WritePla( Abc_Ntk_t * pNtk, char * pFileName )
FILE * pFile;
assert( Abc_NtkIsSopNetlist(pNtk) );
- assert( Abc_NtkGetLevelNum(pNtk) == 1 );
+ assert( Abc_NtkLevel(pNtk) == 1 );
pFile = fopen( pFileName, "w" );
if ( pFile == NULL )
@@ -88,7 +88,7 @@ int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk )
nProducts = 0;
Abc_NtkForEachCo( pNtk, pNode, i )
{
- pDriver = Abc_ObjFanin0Ntk(pNode);
+ pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pNode) );
if ( !Abc_ObjIsNode(pDriver) )
{
nProducts++;
@@ -138,9 +138,10 @@ int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk )
pCubeOut[i] = '1';
// consider special cases of nodes
- pDriver = Abc_ObjFanin0Ntk(pNode);
+ pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pNode) );
if ( !Abc_ObjIsNode(pDriver) )
{
+ assert( Abc_ObjIsCi(pDriver) );
pCubeIn[(int)pDriver->pCopy] = '1' - Abc_ObjFaninC0(pNode);
fprintf( pFile, "%s %s\n", pCubeIn, pCubeOut );
pCubeIn[(int)pDriver->pCopy] = '-';
@@ -152,17 +153,29 @@ int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk )
fprintf( pFile, "%s %s\n", pCubeIn, pCubeOut );
continue;
}
+
+ // make sure the cover is not complemented
+ assert( !Abc_SopIsComplement( pDriver->pData ) );
+
// write the cubes
nFanins = Abc_ObjFaninNum(pDriver);
Abc_SopForEachCube( pDriver->pData, nFanins, pCube )
{
Abc_ObjForEachFanin( pDriver, pFanin, k )
+ {
+ pFanin = Abc_ObjFanin0Ntk(pFanin);
+ assert( (int)pFanin->pCopy < nInputs );
pCubeIn[(int)pFanin->pCopy] = pCube[k];
+ }
fprintf( pFile, "%s %s\n", pCubeIn, pCubeOut );
}
// clean the cube for future writing
Abc_ObjForEachFanin( pDriver, pFanin, k )
+ {
+ pFanin = Abc_ObjFanin0Ntk(pFanin);
+ assert( Abc_ObjIsCi(pFanin) );
pCubeIn[(int)pFanin->pCopy] = '-';
+ }
Extra_ProgressBarUpdate( pProgress, i, NULL );
}
Extra_ProgressBarStop( pProgress );
@@ -171,6 +184,8 @@ int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk )
// clean the CI nodes
Abc_NtkForEachCi( pNtk, pNode, i )
pNode->pCopy = NULL;
+ free( pCubeIn );
+ free( pCubeOut );
return 1;
}
diff --git a/src/base/io/ioWriteVerilog.c b/src/base/io/ioWriteVerilog.c
new file mode 100644
index 00000000..9e71e3e4
--- /dev/null
+++ b/src/base/io/ioWriteVerilog.c
@@ -0,0 +1,639 @@
+/**CFile****************************************************************
+
+ FileName [ioWriteVerilog.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Command processing package.]
+
+ Synopsis [Procedures to output a special subset of Verilog.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ioWriteVerilog.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+#include "main.h"
+#include "mio.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk );
+static void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
+static void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
+static void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
+static void Io_WriteVerilogRegs( FILE * pFile, Abc_Ntk_t * pNtk, int Start );
+static void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk );
+static void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk );
+static int Io_WriteVerilogWiresCount( Abc_Ntk_t * pNtk );
+static char * Io_WriteVerilogGetName( char * pName );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Write verilog.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName )
+{
+ Abc_Ntk_t * pNetlist;
+ FILE * pFile;
+ int i;
+ // can only write nodes represented using local AIGs
+ if ( !Abc_NtkIsAigNetlist(pNtk) && !Abc_NtkIsMappedNetlist(pNtk) )
+ {
+ printf( "Io_WriteVerilog(): Can produce Verilog for mapped or AIG netlists only.\n" );
+ return;
+ }
+ // start the output stream
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "Io_WriteVerilog(): Cannot open the output file \"%s\".\n", pFileName );
+ return;
+ }
+
+ // write the equations for the network
+ fprintf( pFile, "// Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
+ fprintf( pFile, "\n" );
+
+ // write modules
+ if ( pNtk->pDesign )
+ {
+ // write the network first
+ Io_WriteVerilogInt( pFile, pNtk );
+ // write other things
+ Vec_PtrForEachEntry( pNtk->pDesign->vModules, pNetlist, i )
+ {
+ assert( Abc_NtkIsNetlist(pNetlist) );
+ if ( pNetlist == pNtk )
+ continue;
+ fprintf( pFile, "\n" );
+ Io_WriteVerilogInt( pFile, pNetlist );
+ }
+ }
+ else
+ {
+ Io_WriteVerilogInt( pFile, pNtk );
+ }
+
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes verilog.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteVerilogInt( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ // write inputs and outputs
+// fprintf( pFile, "module %s ( gclk,\n ", Abc_NtkName(pNtk) );
+ fprintf( pFile, "module %s ( ", Abc_NtkName(pNtk) );
+ // add the clock signal if it does not exist
+ if ( Abc_NtkLatchNum(pNtk) > 0 && Nm_ManFindIdByName(pNtk->pManName, "clock", ABC_OBJ_PI) == -1 )
+ fprintf( pFile, "clock, " );
+ // write other primary inputs
+ fprintf( pFile, "\n " );
+ if ( Abc_NtkPiNum(pNtk) > 0 )
+ {
+ Io_WriteVerilogPis( pFile, pNtk, 3 );
+ fprintf( pFile, ",\n " );
+ }
+ if ( Abc_NtkPoNum(pNtk) > 0 )
+ Io_WriteVerilogPos( pFile, pNtk, 3 );
+ fprintf( pFile, " );\n" );
+ // add the clock signal if it does not exist
+ if ( Abc_NtkLatchNum(pNtk) > 0 && Nm_ManFindIdByName(pNtk->pManName, "clock", ABC_OBJ_PI) == -1 )
+ fprintf( pFile, " input clock;\n" );
+ // write inputs, outputs, registers, and wires
+ if ( Abc_NtkPiNum(pNtk) > 0 )
+ {
+// fprintf( pFile, " input gclk," );
+ fprintf( pFile, " input " );
+ Io_WriteVerilogPis( pFile, pNtk, 10 );
+ fprintf( pFile, ";\n" );
+ }
+ if ( Abc_NtkPoNum(pNtk) > 0 )
+ {
+ fprintf( pFile, " output" );
+ Io_WriteVerilogPos( pFile, pNtk, 5 );
+ fprintf( pFile, ";\n" );
+ }
+ // if this is not a blackbox, write internal signals
+ if ( !Abc_NtkHasBlackbox(pNtk) )
+ {
+ if ( Abc_NtkLatchNum(pNtk) > 0 )
+ {
+ fprintf( pFile, " reg" );
+ Io_WriteVerilogRegs( pFile, pNtk, 4 );
+ fprintf( pFile, ";\n" );
+ }
+ if ( Io_WriteVerilogWiresCount(pNtk) > 0 )
+ {
+ fprintf( pFile, " wire" );
+ Io_WriteVerilogWires( pFile, pNtk, 4 );
+ fprintf( pFile, ";\n" );
+ }
+ // write nodes
+ Io_WriteVerilogObjects( pFile, pNtk );
+ // write registers
+ if ( Abc_NtkLatchNum(pNtk) > 0 )
+ Io_WriteVerilogLatches( pFile, pNtk );
+ }
+ // finalize the file
+ fprintf( pFile, "endmodule\n\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the primary inputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteVerilogPis( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
+{
+ Abc_Obj_t * pTerm, * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i;
+
+ LineLength = Start;
+ NameCounter = 0;
+ Abc_NtkForEachPi( pNtk, pTerm, i )
+ {
+ pNet = Abc_ObjFanout0(pTerm);
+ // get the line length after this name is written
+ AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, "\n " );
+ // reset the line length
+ LineLength = 3;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (i==Abc_NtkPiNum(pNtk)-1)? "" : "," );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the primary outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteVerilogPos( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
+{
+ Abc_Obj_t * pTerm, * pNet, * pSkip;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i;
+ int nskip;
+
+ pSkip = 0;
+ nskip = 0;
+
+ LineLength = Start;
+ NameCounter = 0;
+ Abc_NtkForEachPo( pNtk, pTerm, i )
+ {
+ pNet = Abc_ObjFanin0(pTerm);
+
+ if ( Abc_ObjIsPi(Abc_ObjFanin0(pNet)) )
+ {
+ // Skip this output since it is a feedthrough -- the same
+ // name will appear as an input and an output which other
+ // tools reading verilog do not like.
+
+ nskip++;
+ pSkip = pNet; // save an example of skipped net
+ continue;
+ }
+
+ // get the line length after this name is written
+ AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, "\n " );
+ // reset the line length
+ LineLength = 3;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (i==Abc_NtkPoNum(pNtk)-1)? "" : "," );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+
+ if (nskip != 0)
+ {
+ assert (pSkip);
+ printf( "Io_WriteVerilogPos(): Omitted %d feedthrough nets from output list of module (e.g. %s).\n", nskip, Abc_ObjName(pSkip) );
+ return;
+ }
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the wires.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteVerilogWires( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
+{
+ Abc_Obj_t * pObj, * pNet, * pBox, * pTerm;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i, k, Counter, nNodes;
+
+ // count the number of wires
+ nNodes = Io_WriteVerilogWiresCount( pNtk );
+
+ // write the wires
+ Counter = 0;
+ LineLength = Start;
+ NameCounter = 0;
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ if ( i == 0 )
+ continue;
+ pNet = Abc_ObjFanout0(pObj);
+ if ( Abc_ObjFanoutNum(pNet) > 0 && Abc_ObjIsCo(Abc_ObjFanout0(pNet)) )
+ continue;
+ Counter++;
+ // get the line length after this name is written
+ AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, "\n " );
+ // reset the line length
+ LineLength = 3;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (Counter==nNodes)? "" : "," );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ pNet = Abc_ObjFanin0(Abc_ObjFanin0(pObj));
+ Counter++;
+ // get the line length after this name is written
+ AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, "\n " );
+ // reset the line length
+ LineLength = 3;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (Counter==nNodes)? "" : "," );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+ Abc_NtkForEachBox( pNtk, pBox, i )
+ {
+ if ( Abc_ObjIsLatch(pBox) )
+ continue;
+ Abc_ObjForEachFanin( pBox, pTerm, k )
+ {
+ pNet = Abc_ObjFanin0(pTerm);
+ Counter++;
+ // get the line length after this name is written
+ AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, "\n " );
+ // reset the line length
+ LineLength = 3;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (Counter==nNodes)? "" : "," );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+ Abc_ObjForEachFanout( pBox, pTerm, k )
+ {
+ pNet = Abc_ObjFanout0(pTerm);
+ if ( Abc_ObjFanoutNum(pNet) > 0 && Abc_ObjIsCo(Abc_ObjFanout0(pNet)) )
+ continue;
+ Counter++;
+ // get the line length after this name is written
+ AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, "\n " );
+ // reset the line length
+ LineLength = 3;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (Counter==nNodes)? "" : "," );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+ }
+ assert( Counter == nNodes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the regs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteVerilogRegs( FILE * pFile, Abc_Ntk_t * pNtk, int Start )
+{
+ Abc_Obj_t * pLatch, * pNet;
+ int LineLength;
+ int AddedLength;
+ int NameCounter;
+ int i, Counter, nNodes;
+
+ // count the number of latches
+ nNodes = Abc_NtkLatchNum(pNtk);
+
+ // write the wires
+ Counter = 0;
+ LineLength = Start;
+ NameCounter = 0;
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ {
+ pNet = Abc_ObjFanout0(Abc_ObjFanout0(pLatch));
+ Counter++;
+ // get the line length after this name is written
+ AddedLength = strlen(Io_WriteVerilogGetName(Abc_ObjName(pNet))) + 2;
+ if ( NameCounter && LineLength + AddedLength + 3 > IO_WRITE_LINE_LENGTH )
+ { // write the line extender
+ fprintf( pFile, "\n " );
+ // reset the line length
+ LineLength = 3;
+ NameCounter = 0;
+ }
+ fprintf( pFile, " %s%s", Io_WriteVerilogGetName(Abc_ObjName(pNet)), (Counter==nNodes)? "" : "," );
+ LineLength += AddedLength;
+ NameCounter++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the latches.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteVerilogLatches( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pLatch;
+ int i;
+ if ( Abc_NtkLatchNum(pNtk) == 0 )
+ return;
+ // write the latches
+// fprintf( pFile, " always @(posedge %s) begin\n", Io_WriteVerilogGetName(Abc_ObjFanout0(Abc_NtkPi(pNtk,0))) );
+// fprintf( pFile, " always begin\n" );
+ fprintf( pFile, " always @ (posedge clock) begin\n" );
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ {
+ fprintf( pFile, " %s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout0(pLatch)))) );
+ fprintf( pFile, " <= %s;\n", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin0(Abc_ObjFanin0(pLatch)))) );
+ }
+ fprintf( pFile, " end\n" );
+ // check if there are initial values
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ if ( Abc_LatchInit(pLatch) == ABC_INIT_ZERO || Abc_LatchInit(pLatch) == ABC_INIT_ONE )
+ break;
+ if ( i == Abc_NtkLatchNum(pNtk) )
+ return;
+ // write the initial values
+ fprintf( pFile, " initial begin\n", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_NtkPi(pNtk,0)))) );
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ {
+ if ( Abc_LatchInit(pLatch) == ABC_INIT_ZERO )
+ fprintf( pFile, " %s <= 1\'b0;\n", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout0(pLatch)))) );
+ else if ( Abc_LatchInit(pLatch) == ABC_INIT_ONE )
+ fprintf( pFile, " %s <= 1\'b1;\n", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout0(pLatch)))) );
+ }
+ fprintf( pFile, " end\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the nodes and boxes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_WriteVerilogObjects( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Vec_Vec_t * vLevels;
+ Abc_Ntk_t * pNtkBox;
+ Abc_Obj_t * pObj, * pTerm, * pFanin;
+ Hop_Obj_t * pFunc;
+ int i, k, Counter, nDigits, Length;
+
+ // write boxes
+ nDigits = Extra_Base10Log( Abc_NtkBoxNum(pNtk)-Abc_NtkLatchNum(pNtk) );
+ Counter = 0;
+ Abc_NtkForEachBox( pNtk, pObj, i )
+ {
+ if ( Abc_ObjIsLatch(pObj) )
+ continue;
+ pNtkBox = pObj->pData;
+ fprintf( pFile, " %s box%0*d", pNtkBox->pName, nDigits, Counter++ );
+ fprintf( pFile, "(" );
+ Abc_NtkForEachPi( pNtkBox, pTerm, k )
+ {
+ fprintf( pFile, ".%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pTerm))) );
+ fprintf( pFile, "(%s), ", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin0(Abc_ObjFanin(pObj,k)))) );
+ }
+ Abc_NtkForEachPo( pNtkBox, pTerm, k )
+ {
+ fprintf( pFile, ".%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanin0(pTerm))) );
+ fprintf( pFile, "(%s)%s", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(Abc_ObjFanout(pObj,k)))), k==Abc_NtkPoNum(pNtkBox)-1? "":", " );
+ }
+ fprintf( pFile, ");\n" );
+ }
+ // write nodes
+ if ( Abc_NtkHasMapping(pNtk) )
+ {
+ Length = Mio_LibraryReadGateNameMax(pNtk->pManFunc);
+ nDigits = Extra_Base10Log( Abc_NtkNodeNum(pNtk) );
+ Counter = 0;
+ Abc_NtkForEachNode( pNtk, pObj, k )
+ {
+ Mio_Gate_t * pGate = pObj->pData;
+ Mio_Pin_t * pGatePin;
+ // write the node
+ fprintf( pFile, " %-*s g%0*d", Length, Mio_GateReadName(pGate), nDigits, Counter++ );
+ fprintf( pFile, "(" );
+ for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
+ {
+ fprintf( pFile, ".%s", Io_WriteVerilogGetName(Mio_PinReadName(pGatePin)) );
+ fprintf( pFile, "(%s), ", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanin(pObj,i) )) );
+ }
+ assert ( i == Abc_ObjFaninNum(pObj) );
+ fprintf( pFile, ".%s", Io_WriteVerilogGetName(Mio_GateReadOutName(pGate)) );
+ fprintf( pFile, "(%s)", Io_WriteVerilogGetName(Abc_ObjName( Abc_ObjFanout0(pObj) )) );
+ fprintf( pFile, ");\n" );
+ }
+ }
+ else
+ {
+ vLevels = Vec_VecAlloc( 10 );
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ pFunc = pObj->pData;
+ fprintf( pFile, " assign %s = ", Io_WriteVerilogGetName(Abc_ObjName(Abc_ObjFanout0(pObj))) );
+ // set the input names
+ Abc_ObjForEachFanin( pObj, pFanin, k )
+ Hop_IthVar(pNtk->pManFunc, k)->pData = Extra_UtilStrsav(Io_WriteVerilogGetName(Abc_ObjName(pFanin)));
+ // write the formula
+ Hop_ObjPrintVerilog( pFile, pFunc, vLevels, 0 );
+ fprintf( pFile, ";\n" );
+ // clear the input names
+ Abc_ObjForEachFanin( pObj, pFanin, k )
+ free( Hop_IthVar(pNtk->pManFunc, k)->pData );
+ }
+ Vec_VecFree( vLevels );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of wires.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_WriteVerilogWiresCount( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj, * pNet, * pBox;
+ int i, k, nWires;
+ nWires = Abc_NtkLatchNum(pNtk);
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ if ( i == 0 )
+ continue;
+ pNet = Abc_ObjFanout0(pObj);
+ if ( Abc_ObjFanoutNum(pNet) > 0 && Abc_ObjIsCo(Abc_ObjFanout0(pNet)) )
+ continue;
+ nWires++;
+ }
+ Abc_NtkForEachBox( pNtk, pBox, i )
+ {
+ if ( Abc_ObjIsLatch(pBox) )
+ continue;
+ nWires += Abc_ObjFaninNum(pBox);
+ Abc_ObjForEachFanout( pBox, pObj, k )
+ {
+ pNet = Abc_ObjFanout0(pObj);
+ if ( Abc_ObjFanoutNum(pNet) > 0 && Abc_ObjIsCo(Abc_ObjFanout0(pNet)) )
+ continue;
+ nWires++;
+ }
+ }
+ return nWires;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the name for writing the Verilog file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Io_WriteVerilogGetName( char * pName )
+{
+ static char Buffer[500];
+ int Length, i;
+ Length = strlen(pName);
+ // consider the case of a signal having name "0" or "1"
+ if ( !(Length == 1 && (pName[0] == '0' || pName[0] == '1')) )
+ {
+ for ( i = 0; i < Length; i++ )
+ if ( !((pName[i] >= 'a' && pName[i] <= 'z') ||
+ (pName[i] >= 'A' && pName[i] <= 'Z') ||
+ (pName[i] >= '0' && pName[i] <= '9') || pName[i] == '_') )
+ break;
+ if ( i == Length )
+ return pName;
+ }
+ // create Verilog style name
+ Buffer[0] = '\\';
+ for ( i = 0; i < Length; i++ )
+ Buffer[i+1] = pName[i];
+ Buffer[Length+1] = ' ';
+ Buffer[Length+2] = 0;
+ return Buffer;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/io/io_.c b/src/base/io/io_.c
new file mode 100644
index 00000000..62dd60e5
--- /dev/null
+++ b/src/base/io/io_.c
@@ -0,0 +1,48 @@
+/**CFile****************************************************************
+
+ FileName [io_.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: io_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "io.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+
diff --git a/src/base/io/module.make b/src/base/io/module.make
index 34582473..bb35a7fc 100644
--- a/src/base/io/module.make
+++ b/src/base/io/module.make
@@ -1,16 +1,25 @@
SRC += src/base/io/io.c \
- src/base/io/ioRead.c \
+ src/base/io/ioReadAiger.c \
+ src/base/io/ioReadBaf.c \
src/base/io/ioReadBench.c \
src/base/io/ioReadBlif.c \
+ src/base/io/ioReadBlifAig.c \
+ src/base/io/ioReadBlifMv.c \
+ src/base/io/ioReadDsd.c \
src/base/io/ioReadEdif.c \
src/base/io/ioReadEqn.c \
src/base/io/ioReadPla.c \
src/base/io/ioReadVerilog.c \
src/base/io/ioUtil.c \
+ src/base/io/ioWriteAiger.c \
+ src/base/io/ioWriteBaf.c \
src/base/io/ioWriteBench.c \
src/base/io/ioWriteBlif.c \
+ src/base/io/ioWriteBlifMv.c \
src/base/io/ioWriteCnf.c \
src/base/io/ioWriteDot.c \
src/base/io/ioWriteEqn.c \
src/base/io/ioWriteGml.c \
- src/base/io/ioWritePla.c
+ src/base/io/ioWriteList.c \
+ src/base/io/ioWritePla.c \
+ src/base/io/ioWriteVerilog.c