From 8dfe404863427d5e7b18d055ffd78b453835f959 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 10 Jan 2007 08:01:00 -0800 Subject: Version abc70110 --- src/base/io/io.c | 1205 +++++++++++++---------------------- src/base/io/io.h | 84 ++- src/base/io/ioRead.c | 88 --- src/base/io/ioReadAiger.c | 8 +- src/base/io/ioReadBench.c | 16 +- src/base/io/ioReadBlif.c | 4 +- src/base/io/ioReadBlifAig.c | 1013 +++++++++++++++++++++++++++++ src/base/io/ioReadBlifMv.c | 1469 +++++++++++++++++++++++++++++++++++++++++++ src/base/io/ioReadEqn.c | 71 +-- src/base/io/ioUtil.c | 330 ++++++++++ src/base/io/ioWriteBlifMv.c | 515 +++++++++++++++ src/base/io/ioWriteDot.c | 20 + src/base/io/ioWriteEqn.c | 115 ++-- src/base/io/ioWriteList.c | 3 +- src/base/io/ioWriteVer.c | 6 + src/base/io/io_.c | 36 ++ src/base/io/module.make | 5 +- 17 files changed, 3986 insertions(+), 1002 deletions(-) delete mode 100644 src/base/io/ioRead.c create mode 100644 src/base/io/ioReadBlifAig.c create mode 100644 src/base/io/ioReadBlifMv.c create mode 100644 src/base/io/ioWriteBlifMv.c create mode 100644 src/base/io/io_.c (limited to 'src/base/io') diff --git a/src/base/io/io.c b/src/base/io/io.c index f6d71d52..f50faa11 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -26,24 +26,27 @@ //////////////////////////////////////////////////////////////////////// static int IoCommandRead ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int IoCommandReadHie ( 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 IoCommandReadBench ( 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 IoCommandReadVer ( Abc_Frame_t * pAbc, int argc, char **argv ); -static int IoCommandReadVerLib ( 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 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 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 ); @@ -51,7 +54,6 @@ 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 ); -static int IoCommandWriteCounter( Abc_Frame_t * pAbc, int argc, char **argv ); extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fCheck, int fUseMemMan ); @@ -73,32 +75,34 @@ extern Abc_Lib_t * Ver_ParseFile( char * pFileName, Abc_Lib_t * pGateLib, int fC void Io_Init( Abc_Frame_t * pAbc ) { Cmd_CommandAdd( pAbc, "I/O", "read", IoCommandRead, 1 ); + Cmd_CommandAdd( pAbc, "I/O", "rh", IoCommandReadHie, 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_bench", IoCommandReadBench, 1 ); - Cmd_CommandAdd( pAbc, "I/O", "read_edif", IoCommandReadEdif, 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_ver", IoCommandReadVer, 1 ); - Cmd_CommandAdd( pAbc, "I/O", "read_verlib", IoCommandReadVerLib, 0 ); 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_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_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_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 ); - Cmd_CommandAdd( pAbc, "I/O", "write_counter", IoCommandWriteCounter, 0 ); +// Cmd_CommandAdd( pAbc, "I/O", "write_verilog", IoCommandWriteVerilog, 0 ); +// Cmd_CommandAdd( pAbc, "I/O", "write_verlib", IoCommandWriteVerLib, 0 ); } /**Function************************************************************* @@ -130,8 +134,7 @@ 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; @@ -150,38 +153,22 @@ int IoCommandRead( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); - if ( FileName = Extra_FileGetSimilarName( FileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); - fprintf( pAbc->Err, "\n" ); - return 1; - } - fclose( pFile ); - - // set the new network - pNtk = Io_Read( FileName, fCheck ); + pFileName = argv[globalUtilOptind]; + // read the file using the corresponding file reader + pNtk = Io_Read( pFileName, Io_ReadFileType(pFileName), 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] \n" ); - fprintf( pAbc->Err, "\t read the network from file in BLIF/BENCH/PLA/BAF/AIGER format\n" ); + fprintf( pAbc->Err, "\t replaces the current network by the network read from \n" ); + fprintf( pAbc->Err, "\t by calling the parser that matches the extension of \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" ); @@ -199,12 +186,11 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadAiger( Abc_Frame_t * pAbc, int argc, char ** argv ) +int IoCommandReadHie( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk; - char * FileName; - FILE * pFile; - int fCheck; + char * pFileName; + int fCheck, fBlifMv; int c; fCheck = 1; @@ -222,39 +208,33 @@ int IoCommandReadAiger( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - if ( (pFile = fopen( FileName, "r" )) == NULL ) + pFileName = argv[globalUtilOptind]; + // read the file using the corresponding file reader +// pNtk = Io_Read( pFileName, Io_ReadFileType(pFileName), fCheck ); + if ( Io_ReadFileType(pFileName) == IO_FILE_BLIFMV ) + fBlifMv = 1; + else if ( Io_ReadFileType(pFileName) == IO_FILE_BLIF ) + fBlifMv = 0; + else { - fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); - if ( FileName = Extra_FileGetSimilarName( FileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); - fprintf( pAbc->Err, "\n" ); + printf( "Wrong file type.\n" ); return 1; } - fclose( pFile ); - - // set the new network - pNtk = Io_ReadAiger( FileName, fCheck ); + Io_ReadBlifMv( pFileName, fBlifMv, fCheck ); + pNtk = NULL; if ( pNtk == NULL ) - { - fprintf( pAbc->Err, "Reading network from the AIGER file has failed.\n" ); - return 1; - } - + return 0; // replace the current network Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); return 0; usage: - fprintf( pAbc->Err, "usage: read_aiger [-ch] \n" ); - fprintf( pAbc->Err, "\t read the network in the AIGER format (http://fmv.jku.at/aiger)\n" ); + fprintf( pAbc->Err, "usage: rh [-ch] \n" ); + fprintf( pAbc->Err, "\t reads hierarchical design represented in BLIF or BLIF-MV\n" ); + fprintf( pAbc->Err, "\t by calling the parser that matches the extension of \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" ); @@ -272,11 +252,10 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadBaf( Abc_Frame_t * pAbc, int argc, char ** argv ) +int IoCommandReadAiger( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk; - char * FileName; - FILE * pFile; + char * pFileName; int fCheck; int c; @@ -295,39 +274,21 @@ int IoCommandReadBaf( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); - if ( FileName = Extra_FileGetSimilarName( FileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); - fprintf( pAbc->Err, "\n" ); - return 1; - } - fclose( pFile ); - - // set the new network - pNtk = Io_ReadBaf( FileName, fCheck ); + pFileName = argv[globalUtilOptind]; + // read the file using the corresponding file reader + pNtk = Io_Read( pFileName, IO_FILE_AIGER, fCheck ); if ( pNtk == NULL ) - { - fprintf( pAbc->Err, "Reading network from the BAF file has failed.\n" ); return 1; - } - // replace the current network Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); return 0; usage: - fprintf( pAbc->Err, "usage: read_baf [-ch] \n" ); - fprintf( pAbc->Err, "\t read the network in Binary Aig Format (BAF)\n" ); + fprintf( pAbc->Err, "usage: read_aiger [-ch] \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" ); @@ -345,11 +306,10 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadBlif( Abc_Frame_t * pAbc, int argc, char ** argv ) +int IoCommandReadBaf( 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; @@ -368,47 +328,21 @@ int IoCommandReadBlif( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); - if ( FileName = Extra_FileGetSimilarName( FileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); - fprintf( pAbc->Err, "\n" ); - return 1; - } - fclose( pFile ); - - // set the new network - pNtk = Io_ReadBlif( FileName, fCheck ); - if ( pNtk == NULL ) - { - fprintf( pAbc->Err, "Reading network from BLIF file has failed.\n" ); - return 1; - } - - pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk ); - Abc_NtkDelete( pTemp ); + 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, "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] \n" ); - fprintf( pAbc->Err, "\t read the network in binary BLIF format\n" ); + fprintf( pAbc->Err, "usage: read_baf [-ch] \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" ); @@ -426,20 +360,25 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadBench( Abc_Frame_t * pAbc, int argc, char ** argv ) +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; + fReadAsAig = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ach" ) ) != EOF ) { switch ( c ) { + case 'a': + fReadAsAig ^= 1; + break; case 'c': fCheck ^= 1; break; @@ -449,46 +388,25 @@ int IoCommandReadBench( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); - if ( FileName = Extra_FileGetSimilarName( FileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); - fprintf( pAbc->Err, "\n" ); - return 1; - } - fclose( pFile ); - - // set the new network - pNtk = Io_ReadBench( FileName, fCheck ); - if ( pNtk == NULL ) - { - fprintf( pAbc->Err, "Reading network from BENCH file has failed.\n" ); - return 1; - } - - pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk ); - Abc_NtkDelete( pTemp ); + 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 ); if ( pNtk == NULL ) - { - fprintf( pAbc->Err, "Converting to logic network after reading has failed.\n" ); return 1; - } // replace the current network Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); return 0; usage: - fprintf( pAbc->Err, "usage: read_bench [-ch] \n" ); - fprintf( pAbc->Err, "\t read the network in BENCH format\n" ); + fprintf( pAbc->Err, "usage: read_blif [-ach] \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" ); @@ -506,11 +424,10 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadEdif( Abc_Frame_t * pAbc, int argc, char ** argv ) +int IoCommandReadBench( 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; @@ -529,46 +446,21 @@ int IoCommandReadEdif( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); - if ( FileName = Extra_FileGetSimilarName( FileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); - fprintf( pAbc->Err, "\n" ); - return 1; - } - fclose( pFile ); - - // set the new network - pNtk = Io_ReadEdif( FileName, fCheck ); - if ( pNtk == NULL ) - { - fprintf( pAbc->Err, "Reading network from EDIF file has failed.\n" ); - return 1; - } - - pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk ); - Abc_NtkDelete( pTemp ); + 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; usage: - fprintf( pAbc->Err, "usage: read_edif [-ch] \n" ); - fprintf( pAbc->Err, "\t read the network in EDIF (works only for ISCAS benchmarks)\n" ); + fprintf( pAbc->Err, "usage: read_bench [-ch] \n" ); + fprintf( pAbc->Err, "\t read the network in BENCH format\n" ); fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" ); fprintf( pAbc->Err, "\t-h : prints the command summary\n" ); fprintf( pAbc->Err, "\tfile : the name of a file to read\n" ); @@ -586,11 +478,10 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadEqn( Abc_Frame_t * pAbc, int argc, char ** argv ) +int IoCommandReadEdif( 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; @@ -609,46 +500,21 @@ int IoCommandReadEqn( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); - if ( FileName = Extra_FileGetSimilarName( FileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); - fprintf( pAbc->Err, "\n" ); - return 1; - } - fclose( pFile ); - - // set the new network - pNtk = Io_ReadEqn( FileName, fCheck ); - if ( pNtk == NULL ) - { - fprintf( pAbc->Err, "Reading network from the equation file has failed.\n" ); - return 1; - } - - pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk ); - Abc_NtkDelete( pTemp ); + pFileName = argv[globalUtilOptind]; + // read the file using the corresponding file reader + pNtk = Io_Read( pFileName, IO_FILE_EDIF, 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; usage: - fprintf( pAbc->Err, "usage: read_eqn [-ch] \n" ); - fprintf( pAbc->Err, "\t read the network in equation format\n" ); + fprintf( pAbc->Err, "usage: read_edif [-ch] \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" ); @@ -666,17 +532,13 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadVerilog( Abc_Frame_t * pAbc, int argc, char ** argv ) +int IoCommandReadEqn( 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; - printf( "Stand-alone structural Verilog reader is now available as command \"read_ver\".\n" ); - return 0; - fCheck = 1; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF ) @@ -692,47 +554,21 @@ int IoCommandReadVerilog( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); - if ( FileName = Extra_FileGetSimilarName( FileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); - fprintf( pAbc->Err, "\n" ); - return 1; - } - fclose( pFile ); - - // set the new network -// pNtk = Io_ReadVerilog( FileName, fCheck ); - pNtk = NULL; - if ( pNtk == NULL ) - { - fprintf( pAbc->Err, "Reading network from the verilog file has failed.\n" ); - return 1; - } - - pNtk = Abc_NtkNetlistToLogic( pTemp = pNtk ); - Abc_NtkDelete( pTemp ); + pFileName = argv[globalUtilOptind]; + // read the file using the corresponding file reader + pNtk = Io_Read( pFileName, IO_FILE_EQN, 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; usage: - fprintf( pAbc->Err, "usage: read_verilog [-ch] \n" ); - fprintf( pAbc->Err, "\t read the network in Verilog (IWLS 2005 subset)\n" ); + fprintf( pAbc->Err, "usage: read_eqn [-ch] \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" ); @@ -750,15 +586,12 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadVer( Abc_Frame_t * pAbc, int argc, char ** argv ) +int IoCommandReadPla( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Abc_Ntk_t * pNtk, * pNtkNew; - Abc_Lib_t * pDesign; - char * FileName; - FILE * pFile; + Abc_Ntk_t * pNtk; + char * pFileName; int fCheck; int c; - extern Abc_Ntk_t * Abc_LibDeriveAig( Abc_Ntk_t * pNtk, Abc_Lib_t * pLib ); fCheck = 1; Extra_UtilGetoptReset(); @@ -775,56 +608,21 @@ int IoCommandReadVer( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - if ( (pFile = fopen( FileName, "r" )) == NULL ) - { - fprintf( pAbc->Err, "Cannot open input file \"%s\". ", FileName ); - if ( FileName = Extra_FileGetSimilarName( FileName, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - fprintf( pAbc->Err, "Did you mean \"%s\"?", FileName ); - fprintf( pAbc->Err, "\n" ); - return 1; - } - fclose( pFile ); - - // set the new network - pDesign = Ver_ParseFile( FileName, Abc_FrameReadLibVer(), fCheck, 1 ); - if ( pDesign == NULL ) - { - fprintf( pAbc->Err, "Reading network from the verilog file has failed.\n" ); - return 1; - } - - // derive root design - pNtk = Abc_LibDeriveRoot( pDesign ); - Abc_LibFree( pDesign ); + pFileName = argv[globalUtilOptind]; + // read the file using the corresponding file reader + pNtk = Io_Read( pFileName, IO_FILE_PLA, fCheck ); if ( pNtk == NULL ) - { - 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, pNtkNew ); + Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); return 0; usage: - fprintf( pAbc->Err, "usage: read_ver [-ch] \n" ); - fprintf( pAbc->Err, "\t read a network in structural verilog (using current library)\n" ); + fprintf( pAbc->Err, "usage: read_pla [-ch] \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" ); @@ -842,22 +640,21 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadVerLib( Abc_Frame_t * pAbc, int argc, char ** argv ) +int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Abc_Lib_t * pLibrary; - char * FileName; - FILE * pFile; - int fCheck; + Abc_Ntk_t * pNtk; + char * pSopCover; + int fHex; int c; - fCheck = 1; + fHex = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "xh" ) ) != EOF ) { switch ( c ) { - case 'c': - fCheck ^= 1; + case 'x': + fHex ^= 1; break; case 'h': goto usage; @@ -871,36 +668,88 @@ int IoCommandReadVerLib( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } - // get the input file name - FileName = argv[globalUtilOptind]; - 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, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - 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 - pLibrary = Ver_ParseFile( FileName, NULL, fCheck, 0 ); - if ( pLibrary == NULL ) + pNtk = Abc_NtkCreateWithNode( pSopCover ); + free( pSopCover ); + if ( pNtk == NULL ) { - fprintf( pAbc->Err, "Reading library from the verilog file has failed.\n" ); + fprintf( pAbc->Err, "Deriving the network has failed.\n" ); return 1; } - printf( "The library contains %d gates.\n", st_count(pLibrary->tModules) ); - // free old library - if ( Abc_FrameReadLibVer() ) - Abc_LibFree( Abc_FrameReadLibVer() ); - // read new library - Abc_FrameSetLibVer( pLibrary ); + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); return 0; usage: - fprintf( pAbc->Err, "usage: read_verlib [-ch] \n" ); - fprintf( pAbc->Err, "\t read a gate library in structural verilog\n" ); + fprintf( pAbc->Err, "usage: read_truth [-xh] \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; + + printf( "Stand-alone structural Verilog reader is now available as command \"read_ver\".\n" ); + return 0; + + 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; + } + } + 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_verilog [-ch] \n" ); + fprintf( pAbc->Err, "\t read the network in Verilog (IWLS 2005 subset)\n" ); fprintf( pAbc->Err, "\t-c : toggle network check after reading [default = %s]\n", fCheck? "yes":"no" ); fprintf( pAbc->Err, "\t-h : prints the command summary\n" ); fprintf( pAbc->Err, "\tfile : the name of a file to read\n" ); @@ -918,13 +767,15 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadPla( 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 ); fCheck = 1; Extra_UtilGetoptReset(); @@ -948,39 +799,49 @@ int IoCommandReadPla( Abc_Frame_t * pAbc, int argc, char ** argv ) } // get the input file name - FileName = argv[globalUtilOptind]; - 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, ".blif", ".bench", ".pla", ".baf", ".aig" ) ) - 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 ) + pDesign = Ver_ParseFile( pFileName, Abc_FrameReadLibVer(), fCheck, 1 ); + if ( pDesign == NULL ) { - fprintf( pAbc->Err, "Reading network from PLA file has failed.\n" ); + 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 ); 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_pla [-ch] \n" ); - fprintf( pAbc->Err, "\t read the network in PLA\n" ); + fprintf( pAbc->Err, "usage: read_ver [-ch] \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" ); @@ -998,21 +859,22 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv ) +int IoCommandReadVerLib( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Abc_Ntk_t * pNtk; - char * pSopCover; - int fHex; + Abc_Lib_t * pLibrary; + char * pFileName; + FILE * pFile; + int fCheck; int c; - fHex = 0; + fCheck = 1; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "xh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF ) { switch ( c ) { - case 'x': - fHex ^= 1; + case 'c': + fCheck ^= 1; break; case 'h': goto usage; @@ -1026,34 +888,39 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } - // convert truth table to SOP - if ( fHex ) - pSopCover = Abc_SopFromTruthHex(argv[globalUtilOptind]); - else - pSopCover = Abc_SopFromTruthBin(argv[globalUtilOptind]); - if ( pSopCover == NULL ) + // get the input file name + pFileName = argv[globalUtilOptind]; + if ( (pFile = fopen( pFileName, "r" )) == NULL ) { - fprintf( pAbc->Err, "Reading truth table has failed.\n" ); + 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 ); - pNtk = Abc_NtkCreateWithNode( pSopCover ); - free( pSopCover ); - if ( pNtk == NULL ) + // set the new network + pLibrary = Ver_ParseFile( pFileName, NULL, fCheck, 0 ); + if ( pLibrary == NULL ) { - fprintf( pAbc->Err, "Deriving the network has failed.\n" ); + fprintf( pAbc->Err, "Reading library from the verilog file 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() ); + // read new library + Abc_FrameSetLibVer( pLibrary ); return 0; usage: - fprintf( pAbc->Err, "usage: read_truth [-xh] \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, "usage: read_verlib [-ch] \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, "\ttruth : truth table with most signficant bit first (e.g. 1000 for AND(a,b))\n" ); + fprintf( pAbc->Err, "\tfile : the name of a file to read\n" ); return 1; } @@ -1069,14 +936,13 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandWriteAiger( Abc_Frame_t * pAbc, int argc, char **argv ) +int IoCommandWrite( Abc_Frame_t * pAbc, int argc, char **argv ) { - Abc_Ntk_t * pNtk; - char * FileName; + char * pFileName; int c; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "lh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) { switch ( c ) { @@ -1086,31 +952,60 @@ int IoCommandWriteAiger( Abc_Frame_t * pAbc, int argc, char **argv ) goto usage; } } - - pNtk = pAbc->pNtkCur; - if ( pNtk == NULL ) - { - fprintf( pAbc->Out, "Empty network.\n" ); - return 0; - } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - FileName = argv[globalUtilOptind]; + // get the output file name + pFileName = argv[globalUtilOptind]; + // call the corresponding file writer + Io_Write( pAbc->pNtkCur, pFileName, Io_ReadFileType(pFileName) ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: write [-h] \n" ); + fprintf( pAbc->Err, "\t writes the current network into by calling\n" ); + fprintf( pAbc->Err, "\t the writer that matches the extension of \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************************************************************* - // check the network type - if ( !Abc_NtkIsStrash(pNtk) ) + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IoCommandWriteAiger( 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, "Writing AIGER is only possible for structurally hashed AIGs.\n" ); - return 0; + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } } - Io_WriteAiger( pNtk, FileName ); + 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_AIGER ); return 0; usage: - fprintf( pAbc->Err, "usage: write_aiger [-lh] \n" ); + fprintf( pAbc->Err, "usage: write_aiger [-h] \n" ); fprintf( pAbc->Err, "\t write the network in the AIGER format (http://fmv.jku.at/aiger)\n" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" ); fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .aig)\n" ); @@ -1130,12 +1025,11 @@ usage: ***********************************************************************/ int IoCommandWriteBaf( Abc_Frame_t * pAbc, int argc, char **argv ) { - Abc_Ntk_t * pNtk; - char * FileName; + char * pFileName; int c; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "lh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) { switch ( c ) { @@ -1145,31 +1039,16 @@ int IoCommandWriteBaf( Abc_Frame_t * pAbc, int argc, char **argv ) goto usage; } } - - pNtk = pAbc->pNtkCur; - if ( pNtk == NULL ) - { - fprintf( pAbc->Out, "Empty network.\n" ); - return 0; - } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - FileName = argv[globalUtilOptind]; - - // check the network type - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pAbc->Out, "Writing BAF is only possible for structurally hashed AIGs.\n" ); - return 0; - } - Io_WriteBaf( pNtk, FileName ); + // 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 [-lh] \n" ); + fprintf( pAbc->Err, "usage: write_baf [-h] \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" ); @@ -1189,54 +1068,31 @@ usage: ***********************************************************************/ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv ) { - Abc_Ntk_t * pNtk; - char * FileName; - int fWriteLatches; + char * pFileName; int c; - fWriteLatches = 1; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "lh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) { switch ( c ) { - case 'l': - fWriteLatches ^= 1; - break; case 'h': goto usage; default: goto usage; } } - - pNtk = pAbc->pNtkCur; - if ( pNtk == NULL ) - { - fprintf( pAbc->Out, "Empty network.\n" ); - return 0; - } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - FileName = argv[globalUtilOptind]; - - // check the network type - if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsSeq(pNtk) ) - { - fprintf( pAbc->Out, "Currently can only write logic networks, AIGs, and seq AIGs.\n" ); - return 0; - } - Io_WriteBlifLogic( pNtk, FileName, fWriteLatches ); -// Io_WriteBlifNetlist( pNtk, FileName, fWriteLatches ); + // 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 [-lh] \n" ); fprintf( pAbc->Err, "\t write the network into a BLIF file\n" ); - fprintf( pAbc->Err, "\t-l : toggle writing latches [default = %s]\n", fWriteLatches? "yes":"no" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" ); fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .blif)\n" ); return 1; @@ -1255,62 +1111,31 @@ usage: ***********************************************************************/ int IoCommandWriteBench( Abc_Frame_t * pAbc, int argc, char **argv ) { - Abc_Ntk_t * pNtk, * pNtkTemp; - char * FileName; - int fWriteLatches; + char * pFileName; int c; - fWriteLatches = 1; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "lh" ) ) != EOF ) { switch ( c ) { - case 'l': - fWriteLatches ^= 1; - break; case 'h': goto usage; default: goto usage; } } - - pNtk = pAbc->pNtkCur; - if ( pNtk == NULL ) - { - fprintf( pAbc->Out, "Empty network.\n" ); - return 0; - } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - - if ( !Abc_NtkIsStrash(pNtk) ) - { - fprintf( pAbc->Out, "The network should be an AIG.\n" ); - return 0; - } - - // derive the netlist - pNtkTemp = Abc_NtkLogicToNetlistBench(pNtk); - if ( pNtkTemp == NULL ) - { - fprintf( pAbc->Out, "Writing BENCH has failed.\n" ); - return 0; - } - Io_WriteBench( pNtkTemp, FileName ); - Abc_NtkDelete( pNtkTemp ); + // get the output file name + pFileName = argv[globalUtilOptind]; + // call the corresponding file writer + Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_BENCH ); return 0; usage: fprintf( pAbc->Err, "usage: write_bench [-h] \n" ); fprintf( pAbc->Err, "\t write the network in BENCH format\n" ); -// fprintf( pAbc->Err, "\t-l : toggle writing latches [default = %s]\n", fWriteLatches? "yes":"no" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" ); fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .bench)\n" ); return 1; @@ -1330,7 +1155,7 @@ usage: int IoCommandWriteCellNet( Abc_Frame_t * pAbc, int argc, char **argv ) { Abc_Ntk_t * pNtk; - char * FileName; + char * pFileName; int c; extern void Io_WriteCellNet( Abc_Ntk_t * pNtk, char * pFileName ); @@ -1345,29 +1170,23 @@ int IoCommandWriteCellNet( Abc_Frame_t * pAbc, int argc, char **argv ) goto usage; } } - + if ( argc != globalUtilOptind + 1 ) + goto usage; pNtk = pAbc->pNtkCur; if ( pNtk == NULL ) { fprintf( pAbc->Out, "Empty network.\n" ); return 0; } - - if ( argc != globalUtilOptind + 1 ) - { - goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - + // get the output file name + pFileName = argv[globalUtilOptind]; + // call the corresponding file writer if ( !Abc_NtkIsLogic(pNtk) ) { fprintf( pAbc->Out, "The network should be a logic network (if it an AIG, use command \"logic\")\n" ); return 0; } - - // derive the netlist - Io_WriteCellNet( pNtk, FileName ); + Io_WriteCellNet( pNtk, pFileName ); return 0; usage: @@ -1391,7 +1210,7 @@ usage: ***********************************************************************/ int IoCommandWriteCnf( Abc_Frame_t * pAbc, int argc, char **argv ) { - char * FileName; + char * pFileName; int c; Extra_UtilGetoptReset(); @@ -1405,31 +1224,12 @@ int IoCommandWriteCnf( Abc_Frame_t * pAbc, int argc, char **argv ) goto usage; } } - - if ( pAbc->pNtkCur == NULL ) - { - printf( "Empty network.\n" ); - return 0; - } - if ( !Abc_NtkIsStrash(pAbc->pNtkCur) ) - { - printf( "This command can only be applied to an AIG (run \"strash\").\n" ); - return 1; - } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - - // get the input file name - FileName = argv[globalUtilOptind]; - // write the file - if ( !Io_WriteCnf( pAbc->pNtkCur, FileName ) ) - { - printf( "Writing CNF has failed.\n" ); - return 1; - } + // get the output file name + pFileName = argv[globalUtilOptind]; + // call the corresponding file writer + Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_CNF ); return 0; usage: @@ -1453,8 +1253,7 @@ usage: ***********************************************************************/ int IoCommandWriteDot( Abc_Frame_t * pAbc, int argc, char **argv ) { - char * FileName; - Vec_Ptr_t * vNodes; + char * pFileName; int c; Extra_UtilGetoptReset(); @@ -1468,24 +1267,12 @@ 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 ( argc != globalUtilOptind + 1 ) - { goto usage; - } - - // get the input file name - FileName = argv[globalUtilOptind]; - // write the file - vNodes = Abc_NtkCollectObjects( pAbc->pNtkCur ); - Io_WriteDotNtk( pAbc->pNtkCur, vNodes, NULL, FileName, 0, 0 ); - 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: @@ -1507,17 +1294,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; + fNames = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "nh" ) ) != EOF ) { switch ( c ) { + case 'n': + fNames ^= 1; + break; case 'h': goto usage; default: @@ -1536,38 +1328,52 @@ int IoCommandWriteEqn( Abc_Frame_t * pAbc, int argc, char **argv ) { goto usage; } + // get the input file name + pFileName = argv[globalUtilOptind]; - if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) + if ( pNtk->pModel == 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[globalUtilOptind]; - // write the file - // get rid of complemented covers if present - if ( Abc_NtkIsSopLogic(pNtk) ) - Abc_NtkLogicMakeDirectSops(pNtk); - // derive the netlist - pNtkTemp = Abc_NtkLogicToNetlist(pNtk,1); - if ( pNtkTemp == NULL ) + // write the counter-example into the file { - 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 ); } - Io_WriteEqn( pNtkTemp, FileName ); - Abc_NtkDelete( pNtkTemp ); + return 0; usage: - fprintf( pAbc->Err, "usage: write_eqn [-h] \n" ); - fprintf( pAbc->Err, "\t write the current network in the equation format\n" ); + fprintf( pAbc->Err, "usage: write_counter [-nh] \n" ); + fprintf( pAbc->Err, "\t writes the counter-example derived by \"prove\" or \"sat\"\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 [] @@ -1579,9 +1385,9 @@ usage: SeeAlso [] ***********************************************************************/ -int IoCommandWriteGml( Abc_Frame_t * pAbc, int argc, char **argv ) +int IoCommandWriteEqn( Abc_Frame_t * pAbc, int argc, char **argv ) { - char * FileName; + char * pFileName; int c; Extra_UtilGetoptReset(); @@ -1595,28 +1401,55 @@ 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_EQN ); + return 0; - if ( pAbc->pNtkCur == NULL ) - { - fprintf( pAbc->Out, "Empty network.\n" ); - return 0; - } +usage: + fprintf( pAbc->Err, "usage: write_eqn [-h] \n" ); + fprintf( pAbc->Err, "\t write the current network in the equation 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 IoCommandWriteGml( Abc_Frame_t * pAbc, int argc, char **argv ) +{ + char * pFileName; + int c; - if ( !Abc_NtkIsLogic(pAbc->pNtkCur) && !Abc_NtkIsStrash(pAbc->pNtkCur) ) + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) { - fprintf( stdout, "IoCommandWriteGml(): Currently can only process logic networks with BDDs.\n" ); - return 0; + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - - // get the input file name - FileName = argv[globalUtilOptind]; - // write the file - Io_WriteGml( pAbc->pNtkCur, FileName ); + // get the output file name + pFileName = argv[globalUtilOptind]; + // call the corresponding file writer + Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_GML ); return 0; usage: @@ -1640,10 +1473,13 @@ usage: ***********************************************************************/ int IoCommandWriteList( Abc_Frame_t * pAbc, int argc, char **argv ) { - char * FileName; + 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 ) @@ -1659,28 +1495,24 @@ int IoCommandWriteList( Abc_Frame_t * pAbc, int argc, char **argv ) goto usage; } } - + if ( argc != globalUtilOptind + 1 ) + goto usage; if ( pAbc->pNtkCur == NULL ) { fprintf( pAbc->Out, "Empty network.\n" ); return 0; } - +/* if ( !Abc_NtkIsSeq(pAbc->pNtkCur) ) { fprintf( stdout, "IoCommandWriteList(): Can write adjacency list for sequential AIGs only.\n" ); return 0; } - - if ( argc != globalUtilOptind + 1 ) - { - goto usage; - } - +*/ // get the input file name - FileName = argv[globalUtilOptind]; + pFileName = argv[globalUtilOptind]; // write the file - Io_WriteList( pAbc->pNtkCur, FileName, fUseHost ); + Io_WriteList( pAbc->pNtkCur, pFileName, fUseHost ); return 0; usage: @@ -1705,8 +1537,7 @@ usage: ***********************************************************************/ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv ) { - Abc_Ntk_t * pNtk, * pNtkTemp; - char * FileName; + char * pFileName; int c; Extra_UtilGetoptReset(); @@ -1720,49 +1551,12 @@ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv ) goto usage; } } - - pNtk = pAbc->pNtkCur; - if ( pNtk == NULL ) - { - fprintf( pAbc->Out, "Empty network.\n" ); - return 0; - } - - if ( Abc_NtkLevel(pNtk) > 1 ) - { - fprintf( pAbc->Out, "PLA writing is available for collapsed networks.\n" ); - return 0; - } - - if ( Abc_NtkLevel(pNtk) > 1 ) - { - fprintf( pAbc->Out, "PLA writing is available for collapsed networks.\n" ); - return 0; - } - - if ( Abc_NtkLatchNum(pNtk) > 0 ) - { - fprintf( pAbc->Out, "Latches are writed at PI/PO pairs in the PLA file.\n" ); - return 0; - } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - - // get the input file name - FileName = argv[globalUtilOptind]; - - // derive the netlist - pNtkTemp = Abc_NtkLogicToNetlist(pNtk,1); - if ( pNtkTemp == NULL ) - { - fprintf( pAbc->Out, "Writing PLA has failed.\n" ); - return 0; - } - Io_WritePla( pNtkTemp, FileName ); - Abc_NtkDelete( pNtkTemp ); + // get the output file name + pFileName = argv[globalUtilOptind]; + // call the corresponding file writer + Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_PLA ); return 0; usage: @@ -1786,8 +1580,7 @@ usage: ***********************************************************************/ int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv ) { - Abc_Ntk_t * pNtk, * pNtkTemp; - char * FileName; + char * pFileName; int c; Extra_UtilGetoptReset(); @@ -1801,37 +1594,12 @@ int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv ) goto usage; } } - - pNtk = pAbc->pNtkCur; - if ( pNtk == NULL ) - { - fprintf( pAbc->Out, "Empty network.\n" ); - return 0; - } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - - if ( Abc_NtkLatchNum(pNtk) > 0 ) - { - fprintf( pAbc->Out, "Currently cannot write verilog for sequential networks.\n" ); - return 0; - } - - // derive the netlist - pNtkTemp = Abc_NtkLogicToNetlist(pNtk,0); - Abc_NtkSopToAig( pNtkTemp ); - if ( pNtkTemp == NULL ) - { - fprintf( pAbc->Out, "Writing PLA has failed.\n" ); - return 0; - } - Io_WriteVerilog( pNtkTemp, FileName, 1 ); - Abc_NtkDelete( pNtkTemp ); + // get the output file name + pFileName = argv[globalUtilOptind]; + // call the corresponding file writer + Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_VERILOG ); return 0; usage: @@ -1856,7 +1624,7 @@ usage: int IoCommandWriteVerLib( Abc_Frame_t * pAbc, int argc, char **argv ) { Abc_Lib_t * pLibrary; - char * FileName; + char * pFileName; int c; extern void Io_WriteVerilogLibrary( Abc_Lib_t * pLibrary, char * pFileName ); @@ -1871,14 +1639,10 @@ int IoCommandWriteVerLib( Abc_Frame_t * pAbc, int argc, char **argv ) goto usage; } } - if ( argc != globalUtilOptind + 1 ) - { goto usage; - } // get the input file name - FileName = argv[globalUtilOptind]; - + pFileName = argv[globalUtilOptind]; // derive the netlist pLibrary = Abc_FrameReadLibVer(); if ( pLibrary == NULL ) @@ -1886,7 +1650,7 @@ int IoCommandWriteVerLib( Abc_Frame_t * pAbc, int argc, char **argv ) fprintf( pAbc->Out, "Verilog library is not specified.\n" ); return 0; } - Io_WriteVerilogLibrary( pLibrary, FileName ); + Io_WriteVerilogLibrary( pLibrary, pFileName ); return 0; usage: @@ -1897,97 +1661,6 @@ usage: return 1; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int IoCommandWriteCounter( Abc_Frame_t * pAbc, int argc, char **argv ) -{ - Abc_Ntk_t * pNtk; - char * FileName; - int c; - int fNames; - - fNames = 0; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "nh" ) ) != EOF ) - { - switch ( c ) - { - case 'n': - fNames ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - - pNtk = pAbc->pNtkCur; - if ( pNtk == NULL ) - { - fprintf( pAbc->Out, "Empty network.\n" ); - return 0; - } - - if ( argc != globalUtilOptind + 1 ) - { - goto usage; - } - // get the input file name - FileName = argv[globalUtilOptind]; - - if ( pNtk->pModel == NULL ) - { - fprintf( pAbc->Out, "Counter-example is not available.\n" ); - return 0; - } - - // write the counter-example into the file - { - Abc_Obj_t * pObj; - FILE * pFile = fopen( FileName, "w" ); - int i; - if ( pFile == NULL ) - { - fprintf( stdout, "IoCommandWriteCounter(): Cannot open the output file \"%s\".\n", FileName ); - 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 ); - } - - return 0; - -usage: - fprintf( pAbc->Err, "usage: write_counter [-nh] \n" ); - fprintf( pAbc->Err, "\t writes the counter-example derived by \"prove\" or \"sat\"\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; -} - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/io/io.h b/src/base/io/io.h index 776a1b2d..55339790 100644 --- a/src/base/io/io.h +++ b/src/base/io/io.h @@ -39,6 +39,25 @@ extern "C" { /// 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 DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -49,59 +68,70 @@ extern "C" { /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== abcRead.c ==========================================================*/ -extern Abc_Ntk_t * Io_Read( char * pFileName, int fCheck ); /*=== abcReadAiger.c ==========================================================*/ extern Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck ); -/*=== abcReadBaf.c ==========================================================*/ +/*=== abcReadBaf.c ============================================================*/ extern Abc_Ntk_t * Io_ReadBaf( char * pFileName, int fCheck ); -/*=== abcReadBlif.c ==========================================================*/ +/*=== abcReadBlif.c ===========================================================*/ extern Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck ); +/*=== abcReadBlifMv.c =========================================================*/ +extern Abc_Lib_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 ==========================================================*/ +/*=== 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_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_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 ); -/*=== abcWriteAiger.c ==========================================================*/ +/*=== abcWriteAiger.c =========================================================*/ extern void Io_WriteAiger( Abc_Ntk_t * pNtk, char * pFileName ); -/*=== abcWriteBaf.c ==========================================================*/ +/*=== abcWriteBaf.c ===========================================================*/ extern void Io_WriteBaf( Abc_Ntk_t * pNtk, char * pFileName ); /*=== abcWriteBlif.c ==========================================================*/ extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches ); extern void Io_WriteBlifNetlist( 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_WriteBlifMvDesign( Abc_Lib_t * pLib, char * FileName ); +extern void Io_WriteBlifMvNetlist( Abc_Ntk_t * pNtk, char * FileName ); +/*=== abcWriteBench.c =========================================================*/ extern int Io_WriteBench( Abc_Ntk_t * pNtk, char * FileName ); -/*=== abcWriteCnf.c ==========================================================*/ +/*=== abcWriteCnf.c ===========================================================*/ extern int Io_WriteCnf( Abc_Ntk_t * pNtk, char * FileName ); -/*=== abcWriteDot.c ==========================================================*/ +/*=== 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 ==========================================================*/ +/*=== 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 ); /*=== abcWriteList.c ==========================================================*/ extern void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost ); -/*=== abcWritePla.c ==========================================================*/ +/*=== abcWritePla.c ===========================================================*/ extern int Io_WritePla( Abc_Ntk_t * pNtk, char * FileName ); -/*=== abcWriteVerilog.c ==========================================================*/ +/*=== abcWriteVerilog.c =======================================================*/ extern void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * FileName, int fVerLibStyle ); +/*=== 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 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 } diff --git a/src/base/io/ioRead.c b/src/base/io/ioRead.c deleted file mode 100644 index 36619a19..00000000 --- a/src/base/io/ioRead.c +++ /dev/null @@ -1,88 +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 DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**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; -// extern int s_TotalNodes; -// extern int s_TotalChanges; -// s_TotalNodes = s_TotalChanges = 0; - // set the new network - if ( Extra_FileNameCheckExtension( pFileName, "blif" ) ) - pNtk = Io_ReadBlif( pFileName, fCheck ); - else if ( Extra_FileNameCheckExtension( pFileName, "v" ) ) - pNtk = NULL; //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 if ( Extra_FileNameCheckExtension( pFileName, "baf" ) ) - return Io_ReadBaf( pFileName, fCheck ); - else if ( Extra_FileNameCheckExtension( pFileName, "aig" ) ) - return Io_ReadAiger( 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 index b581aa0f..48738903 100644 --- a/src/base/io/ioReadAiger.c +++ b/src/base/io/ioReadAiger.c @@ -63,7 +63,7 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck ) // check if the input file format is correct if ( strncmp(pContents, "aig", 3) != 0 ) { - fprintf( stdout, "Wrong input file format." ); + fprintf( stdout, "Wrong input file format.\n" ); return NULL; } @@ -90,7 +90,7 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck ) // check the parameters if ( nTotal != nInputs + nLatches + nAnds ) { - fprintf( stdout, "The paramters are wrong." ); + fprintf( stdout, "The paramters are wrong.\n" ); return NULL; } @@ -181,7 +181,7 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck ) vTerms = pNtkNew->vPos; else { - fprintf( stdout, "Wrong terminal type." ); + fprintf( stdout, "Wrong terminal type.\n" ); return NULL; } // get the terminal number @@ -189,7 +189,7 @@ Abc_Ntk_t * Io_ReadAiger( char * pFileName, int fCheck ) // get the node if ( iTerm >= Vec_PtrSize(vTerms) ) { - fprintf( stdout, "The number of terminal is out of bound." ); + fprintf( stdout, "The number of terminal is out of bound.\n" ); return NULL; } pObj = Vec_PtrEntry( vTerms, iTerm ); diff --git a/src/base/io/ioReadBench.c b/src/base/io/ioReadBench.c index 72dd2b52..d8213994 100644 --- a/src/base/io/ioReadBench.c +++ b/src/base/io/ioReadBench.c @@ -82,7 +82,7 @@ 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; Vec_Str_t * vString; char * pType, ** ppNames; int iLine, nNames; @@ -144,7 +144,11 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p ) Abc_ObjSetData( pNode, Abc_SopCreateInv(pNtk->pManFunc) ); else if ( strncmp(pType, "MUX", 3) == 0 ) Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "1-0 1\n-11 1\n") ); - else + else if ( strncmp(pType, "vdd", 3) == 0 ) + Abc_ObjSetData( pNode, Abc_SopRegister( pNtk->pManFunc, " 1\n" ) ); + else if ( strncmp(pType, "gnd", 3) == 0 ) + Abc_ObjSetData( pNode, Abc_SopRegister( pNtk->pManFunc, " 0\n" ) ); + else { printf( "Cannot determine gate type \"%s\" in line %d.\n", pType, Extra_FileReaderGetLineNumber(p, 0) ); Vec_StrFree( vString ); @@ -158,10 +162,10 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p ) 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 ); +// if ( pNet = Abc_NtkFindNet( pNtk, "vdd" ) ) +// Io_ReadCreateConst( pNtk, "vdd", 1 ); +// if ( pNet = Abc_NtkFindNet( pNtk, "gnd" ) ) +// Io_ReadCreateConst( pNtk, "gnd", 0 ); Abc_NtkFinalizeRead( pNtk ); return pNtk; diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c index d7f456ff..5eb9a4ce 100644 --- a/src/base/io/ioReadBlif.c +++ b/src/base/io/ioReadBlif.c @@ -265,7 +265,7 @@ Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p ) { pNtk->ntkType = ABC_NTK_NETLIST; pNtk->ntkFunc = ABC_FUNC_BLACKBOX; - Extra_MmFlexStop( pNtk->pManFunc, 0 ); + Extra_MmFlexStop( pNtk->pManFunc ); pNtk->pManFunc = NULL; } else @@ -560,7 +560,7 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens ) { assert( p->pNtkCur->ntkFunc == ABC_FUNC_SOP ); p->pNtkCur->ntkFunc = ABC_FUNC_MAP; - Extra_MmFlexStop( p->pNtkCur->pManFunc, 0 ); + Extra_MmFlexStop( p->pNtkCur->pManFunc ); p->pNtkCur->pManFunc = pGenlib; } 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..c55cc4c9 --- /dev/null +++ b/src/base/io/ioReadBlifMv.c @@ -0,0 +1,1469 @@ +/**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 + 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 + // 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_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_Lib_t * Io_ReadBlifMv( char * pFileName, int fBlifMv, int fCheck ) +{ + FILE * pFile; + Io_MvMan_t * p; + Abc_Lib_t * pDesign; + Abc_Ntk_t * pNtk; + char * pDesignName; + int 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->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 ); + // 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 ); + if ( pDesign == NULL ) + return NULL; + Io_MvFree( p ); + + // 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 ); + return NULL; + } + } + } +Io_WriteBlifMvDesign( pDesign, "_temp_.mv" ); +Abc_LibPrint( pDesign ); +Abc_LibFree( pDesign ); +return NULL; +// return pDesign; +} + +/**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 ); + 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) ) + 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 + { + 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 [Reads the AIG in the binary AIGER format.] + + 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 + 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 + 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 ); + } + // 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, * pMux, * 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 ( Vec_PtrSize(vTokens) > 3 ) + Init = atoi( Vec_PtrEntry(vTokens,3) ); + 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 output of reset latch + pNet = Abc_ObjFanout0(Abc_ObjFanout0(p->pResetLatch)); + assert( Abc_ObjIsNet(pNet) ); + // create mux + pMux = Io_ReadCreateResetMux( p->pNtk, Abc_ObjName(pNet), Vec_PtrEntry(vTokens,1), p->pMan->fBlifMv ); + // get the net of mux output + pNet = Abc_ObjFanout0(pMux); + // create latch + pObj = Io_ReadCreateLatch( p->pNtk, Abc_ObjName(pNet), Vec_PtrEntry(vTokens,2) ); + 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 + pBox = Abc_NtkCreateBlackbox( 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 [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; + } + // get the latch input + pNode = Abc_ObjFanin0(Abc_ObjFanin0(Abc_ObjFanin0(pNet))); + assert( Abc_ObjIsBi(pNode) ); + // get the MUX feeding into the latch + pNode = Abc_ObjFanin0(Abc_ObjFanin0(pNode)); + assert( Abc_ObjFaninNum(pNode) == 3 ); + // get the corresponding fanin net + pNet = Abc_ObjFanin( pNode, 2 ); + // 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; + 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") ); + 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 ) + { + Abc_Obj_t * pNode, * pNet; + // add the outputs to the PIs + for ( i = 0; i < nOutputs; i++ ) + { + pName = Vec_PtrEntry( vTokens, Vec_PtrSize(vTokens) - nOutputs + i ); + fprintf( stdout, "Io_ReadBlifMv(): Adding PI for internal non-deterministic node \"%s\".\n", pName ); + // get the net corresponding to this node + pNet = Abc_NtkFindOrCreateNet(p->pNtk, pName); + if ( fReset ) + { + // get the latch input + pNode = Abc_ObjFanin0(Abc_ObjFanin0(Abc_ObjFanin0(pNet))); + assert( Abc_ObjIsBi(pNode) ); + // get the MUX feeding into the latch + pNode = Abc_ObjFanin0(Abc_ObjFanin0(pNode)); + assert( Abc_ObjFaninNum(pNode) == 3 ); + // get the corresponding fanin net + pNet = Abc_ObjFanin( pNode, 2 ); + } +// Io_ReadCreatePi( p->pNtk, pName ); + Abc_ObjAddFanin( pNet, Abc_NtkCreatePi(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 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' ); + 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; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/io/ioReadEqn.c b/src/base/io/ioReadEqn.c index 4fb313f4..e04f2b1a 100644 --- a/src/base/io/ioReadEqn.c +++ b/src/base/io/ioReadEqn.c @@ -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 = Extra_UtilStrsav( 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/ioUtil.c b/src/base/io/ioUtil.c index fa2d6f25..ba390a2f 100644 --- a/src/base/io/ioUtil.c +++ b/src/base/io/ioUtil.c @@ -28,6 +28,269 @@ /// 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 ); + 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 + { + fprintf( stderr, "Unknown file format.\n" ); + return NULL; + } + if ( pNtk == NULL ) + { + fprintf( stdout, "Reading network from file has failed.\n" ); + return NULL; + } + 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; + // convert the netlist into the logic network + pNtk = Abc_NtkNetlistToLogic( 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 ); + else // if ( FileType == IO_FILE_BAF ) + Io_WriteBaf( pNtk, pFileName ); + return; + } + // write non-netlist types + if ( FileType == IO_FILE_CNF ) + { + Io_WriteCnf( pNtk, pFileName ); + return; + } + if ( FileType == IO_FILE_DOT ) + { + Io_WriteDot( pNtk, pFileName ); + return; + } + if ( FileType == IO_FILE_GML ) + { + Io_WriteGml( 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_NtkLogicToNetlist( pNtk, 1 ); + else + { + fprintf( stdout, "Latches are writen into the PLA file at PI/PO pairs.\n" ); + pNtkCopy = Abc_NtkDup( pNtk ); + Abc_NtkMakeComb( pNtkCopy ); + pNtkTemp = Abc_NtkLogicToNetlist( pNtk, 1 ); + Abc_NtkDelete( pNtkCopy ); + } + } + else if ( FileType == IO_FILE_BENCH ) + { + if ( !Abc_NtkIsStrash(pNtk) ) + { + fprintf( stdout, "Writing BENCH is available for AIGs.\n" ); + return; + } + pNtkTemp = Abc_NtkLogicToNetlistBench( pNtk ); + } + else + pNtkTemp = Abc_NtkLogicToNetlist( pNtk, 0 ); + if ( pNtkTemp == NULL ) + { + fprintf( stdout, "Converting to netlist has failed.\n" ); + return; + } + if ( FileType == IO_FILE_BLIF ) + Io_WriteBlifNetlist( pNtkTemp, pFileName, 1 ); + 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_NtkIsSopNetlist(pNtkTemp) ) + Abc_NtkSopToAig( pNtkTemp ); + Io_WriteEqn( pNtkTemp, pFileName ); + } + else if ( FileType == IO_FILE_VERILOG ) + { + if ( Abc_NtkIsSopNetlist(pNtkTemp) ) + Abc_NtkSopToAig( pNtkTemp ); + Io_WriteVerilog( pNtkTemp, pFileName, 1 ); + } + else + fprintf( stderr, "Unknown file format.\n" ); + Abc_NtkDelete( pNtkTemp ); +} + /**Function************************************************************* Synopsis [Creates PI terminal and net.] @@ -136,6 +399,73 @@ Abc_Obj_t * Io_ReadCreateLatch( Abc_Ntk_t * pNtk, char * pNetLI, char * pNetLO ) 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; + // create latch with 0 init value + pLatch = Io_ReadCreateLatch( pNtk, "_resetLI_", "_resetLO_" ); + Abc_LatchSetInit0( pLatch ); + // feed the latch with constant1- node + pNode = Abc_NtkCreateNode( pNtk ); + pNode->pData = Abc_SopRegister( pNtk->pManFunc, "2\n1\n" ); + Abc_ObjAddFanin( Abc_ObjFanin0(Abc_ObjFanin0(pLatch)), pNode ); + return pLatch; +} + +/**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_ReadCreateResetMux( Abc_Ntk_t * pNtk, char * pResetLO, char * pDataLI, int fBlifMv ) +{ + char Buffer[50]; + Abc_Obj_t * pNode, * pData0Net, * pData1Net, * pResetLONet, * pLINet; + // get the reset output net + pResetLONet = Abc_NtkFindNet( pNtk, pResetLO ); + assert( pResetLONet ); + // get the latch input net + pData1Net = Abc_NtkFindOrCreateNet( pNtk, pDataLI ); + // create Data0 net (coming from reset node) + pData0Net = Abc_NtkFindOrCreateNet( pNtk, Abc_ObjNameSuffix(pData1Net, "_reset") ); + // create the node + pNode = Abc_NtkCreateNode( pNtk ); + if ( fBlifMv ) + { +// Vec_Att_t * p = Abc_NtkMvVar( pNtk ); + int nValues = Abc_ObjMvVarNum(pData1Net); + sprintf( Buffer, "2 %d %d %d\n1 - - =1\n0 - - =2\n", nValues, nValues, nValues ); + pNode->pData = Abc_SopRegister( pNtk->pManFunc, Buffer ); + } + else + pNode->pData = Abc_SopCreateMux( pNtk->pManFunc ); + // add nets + Abc_ObjAddFanin( pNode, pResetLONet ); + Abc_ObjAddFanin( pNode, pData1Net ); + Abc_ObjAddFanin( pNode, pData0Net ); + // create the output net + pLINet = Abc_NtkFindOrCreateNet( pNtk, Abc_ObjNameSuffix(pData1Net, "_mux") ); + Abc_ObjAddFanin( pLINet, pNode ); + return pNode; +} + /**Function************************************************************* Synopsis [Create node and the net driven by it.] diff --git a/src/base/io/ioWriteBlifMv.c b/src/base/io/ioWriteBlifMv.c new file mode 100644 index 00000000..dc3a8b2d --- /dev/null +++ b/src/base/io/ioWriteBlifMv.c @@ -0,0 +1,515 @@ +/**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_WriteBlifMvDesign( Abc_Lib_t * pLib, char * FileName ) +{ + FILE * pFile; + Abc_Ntk_t * pNtk; + int i; + // start writing the file + pFile = fopen( FileName, "w" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Io_WriteBlifMvDesign(): Cannot open the output file.\n" ); + return; + } + fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pLib->pName, Extra_TimeStamp() ); + // write the master network + Vec_PtrForEachEntry( pLib->vModules, pNtk, i ) + Io_NtkWriteBlifMv( pFile, pNtk ); + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [Write the network into a BLIF file with the given name.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Io_WriteBlifMvNetlist( Abc_Ntk_t * pNtk, char * FileName ) +{ + FILE * pFile; + // start writing the file + pFile = fopen( FileName, "w" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Io_WriteMvNetlist(): 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 ); + 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 + if ( !Abc_NtkBlackboxNum(pNtk) ) + { + fprintf( pFile, "\n" ); + Abc_NtkForEachBlackbox( pNtk, pNode, i ) + 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; + fprintf( pFile, "\n" ); + // write .mv directives for the fanins + pCur = Abc_ObjData(pNode); + Abc_ObjForEachFanin( pNode, pFanin, i ) + { + nValues = atoi(pCur); + if ( nValues > 2 ) + fprintf( pFile, ".mv %s %d\n", Abc_ObjName(pFanin), nValues ); + while ( *pCur++ != ' ' ); + } + // write .mv directives for the node + nValues = atoi(pCur); + 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 + 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/ioWriteDot.c b/src/base/io/ioWriteDot.c index 084bd111..d8bb1855 100644 --- a/src/base/io/ioWriteDot.c +++ b/src/base/io/ioWriteDot.c @@ -33,6 +33,26 @@ static int Abc_NtkCountLogicNodes( Vec_Ptr_t * vNodes ); /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// +/**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_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.] diff --git a/src/base/io/ioWriteEqn.c b/src/base/io/ioWriteEqn.c index 11bef488..95c54577 100644 --- a/src/base/io/ioWriteEqn.c +++ b/src/base/io/ioWriteEqn.c @@ -25,9 +25,9 @@ //////////////////////////////////////////////////////////////////////// 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 DEFINITIONS /// @@ -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/ioWriteList.c b/src/base/io/ioWriteList.c index a92c2eff..71af7c53 100644 --- a/src/base/io/ioWriteList.c +++ b/src/base/io/ioWriteList.c @@ -19,7 +19,6 @@ ***********************************************************************/ #include "io.h" -//#include "seqInt.h" /* -------- Original Message -------- @@ -103,7 +102,7 @@ void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost ) Abc_Obj_t * pObj; int i; - assert( Abc_NtkIsSeq(pNtk) ); +// assert( Abc_NtkIsSeq(pNtk) ); // start the output stream pFile = fopen( pFileName, "w" ); diff --git a/src/base/io/ioWriteVer.c b/src/base/io/ioWriteVer.c index 9be3d8b3..20e10583 100644 --- a/src/base/io/ioWriteVer.c +++ b/src/base/io/ioWriteVer.c @@ -62,6 +62,12 @@ void Io_WriteVerilog( Abc_Ntk_t * pNtk, char * pFileName, int fVerLibStyle ) printf( "Io_WriteVerilog(): Can produce Verilog for AIG netlists only.\n" ); return; } + if ( Abc_NtkLatchNum(pNtk) > 0 ) + { + printf( "Io_WriteVerilog(): Currently cannot write verilog for sequential networks.\n" ); + return; + } + /* if ( !(Abc_NtkIsNetlist(pNtk) && (Abc_NtkHasMapping(pNtk) || Io_WriteVerilogCheckNtk(pNtk))) ) { diff --git a/src/base/io/io_.c b/src/base/io/io_.c new file mode 100644 index 00000000..7721545a --- /dev/null +++ b/src/base/io/io_.c @@ -0,0 +1,36 @@ +/**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 /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + + diff --git a/src/base/io/module.make b/src/base/io/module.make index 1feffa0b..fd66dd22 100644 --- a/src/base/io/module.make +++ b/src/base/io/module.make @@ -1,18 +1,19 @@ 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/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 \ -- cgit v1.2.3