summaryrefslogtreecommitdiffstats
path: root/src/base/io
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2006-04-12 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2006-04-12 08:01:00 -0700
commitc1710767b298a8acae16421a660a0874255636a5 (patch)
tree308ec887b66bcd608a1d7f448d45c27b3b2e93fb /src/base/io
parent3f4fc5e4507f7fb9df431fc116529b4c209ab97c (diff)
downloadabc-c1710767b298a8acae16421a660a0874255636a5.tar.gz
abc-c1710767b298a8acae16421a660a0874255636a5.tar.bz2
abc-c1710767b298a8acae16421a660a0874255636a5.zip
Version abc60412
Diffstat (limited to 'src/base/io')
-rw-r--r--src/base/io/io.c2
-rw-r--r--src/base/io/io.h2
-rw-r--r--src/base/io/ioReadBlif.c686
-rw-r--r--src/base/io/ioWriteBlif.c48
4 files changed, 540 insertions, 198 deletions
diff --git a/src/base/io/io.c b/src/base/io/io.c
index 0aa5e415..614fa812 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -912,7 +912,7 @@ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
return 0;
}
Io_WriteBlifLogic( pNtk, FileName, fWriteLatches );
-// Io_WriteBlif( pNtk, FileName, fWriteLatches );
+// Io_WriteBlifNetlist( pNtk, FileName, fWriteLatches );
return 0;
usage:
diff --git a/src/base/io/io.h b/src/base/io/io.h
index a9a61040..b408293e 100644
--- a/src/base/io/io.h
+++ b/src/base/io/io.h
@@ -77,8 +77,8 @@ extern FILE * Io_FileOpen( const char * FileName, const char * PathV
/*=== abcWriteBaf.c ==========================================================*/
extern void Io_WriteBaf( Abc_Ntk_t * pNtk, char * pFileName );
/*=== abcWriteBlif.c ==========================================================*/
-extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
+extern void Io_WriteBlifNetlist( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk );
/*=== abcWriteBench.c ==========================================================*/
extern int Io_WriteBench( Abc_Ntk_t * pNtk, char * FileName );
diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c
index 39b85a10..9d74a782 100644
--- a/src/base/io/ioReadBlif.c
+++ b/src/base/io/ioReadBlif.c
@@ -33,11 +33,10 @@ struct Io_ReadBlif_t_
char * pFileName; // the name of the file
Extra_FileReader_t * pReader; // the input file reader
// current processing info
- Abc_Ntk_t * pNtk; // the primary network
- Abc_Ntk_t * pNtkExdc; // the exdc network
- int fParsingExdc; // this flag is on, when we are parsing EXDC network
+ Abc_Ntk_t * pNtkCur; // the primary network
int LineCur; // the line currently parsed
// temporary storage for tokens
+ Vec_Ptr_t * vTokens; // the current tokens
Vec_Ptr_t * vNewTokens; // the temporary storage for the tokens
Vec_Str_t * vCubes; // the temporary storage for the tokens
// the error message
@@ -49,16 +48,19 @@ static Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName );
static void Io_ReadBlifFree( Io_ReadBlif_t * p );
static void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p );
static Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p );
-static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p );
static char * Io_ReadBlifCleanName( char * pName );
+static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p );
+static Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p );
static int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens );
static int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
+static int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
+static int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -66,9 +68,9 @@ static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t *
/**Function*************************************************************
- Synopsis [Reads the network from a BLIF file.]
+ Synopsis [Reads the (hierarchical) network from the BLIF file.]
- Description [Works only for flat (non-hierarchical) BLIF.]
+ Description []
SideEffects []
@@ -78,34 +80,22 @@ static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t *
Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
{
Io_ReadBlif_t * p;
- Abc_Ntk_t * pNtk, * pNtkExdc;
+ Abc_Ntk_t * pNtk;
// start the file
p = Io_ReadBlifFile( pFileName );
if ( p == NULL )
return NULL;
- // read the network
+ // read the hierarchical network
pNtk = Io_ReadBlifNetwork( p );
if ( pNtk == NULL )
{
Io_ReadBlifFree( p );
return NULL;
}
+ pNtk->pSpec = Extra_UtilStrsav( pFileName );
Abc_NtkTimeInitialize( pNtk );
-
- // read the EXDC network
- if ( p->fParsingExdc )
- {
- pNtkExdc = Io_ReadBlifNetwork( p );
- if ( pNtkExdc == NULL )
- {
- Abc_NtkDelete( pNtk );
- Io_ReadBlifFree( p );
- return NULL;
- }
- pNtk->pExdc = pNtkExdc;
- }
Io_ReadBlifFree( p );
// make sure that everything is okay with the network structure
@@ -120,7 +110,7 @@ Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
/**Function*************************************************************
- Synopsis [Starts the reading data structure.]
+ Synopsis [Iteratively reads several networks in the hierarchical design.]
Description []
@@ -129,141 +119,76 @@ Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
SeeAlso []
***********************************************************************/
-Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName )
+Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
{
- Extra_FileReader_t * pReader;
- Io_ReadBlif_t * p;
-
- // start the reader
- pReader = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t" );
+ Abc_Ntk_t * pNtk, * pNtkMaster;
- if ( pReader == NULL )
+ // read the name of the master network
+ p->vTokens = Io_ReadBlifGetTokens(p);
+ if ( p->vTokens == NULL || strcmp( p->vTokens->pArray[0], ".model" ) )
+ {
+ p->LineCur = 0;
+ sprintf( p->sError, "Wrong input file format." );
+ Io_ReadBlifPrintErrorMessage( p );
return NULL;
+ }
- // start the reading data structure
- p = ALLOC( Io_ReadBlif_t, 1 );
- memset( p, 0, sizeof(Io_ReadBlif_t) );
- p->pFileName = pFileName;
- p->pReader = pReader;
- p->Output = stdout;
- p->vNewTokens = Vec_PtrAlloc( 100 );
- p->vCubes = Vec_StrAlloc( 100 );
- return p;
-}
-
-/**Function*************************************************************
-
- Synopsis [Frees the data structure.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Io_ReadBlifFree( Io_ReadBlif_t * p )
-{
- Extra_FileReaderFree( p->pReader );
- Vec_PtrFree( p->vNewTokens );
- Vec_StrFree( p->vCubes );
- free( p );
-}
-
-/**Function*************************************************************
-
- Synopsis [Prints the error message including the file name and line number.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p )
-{
- if ( p->LineCur == 0 ) // the line number is not given
- fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError );
- else // print the error message with the line number
- fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError );
-}
-
-/**Function*************************************************************
-
- Synopsis [Gets the tokens taking into account the line breaks.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p )
-{
- Vec_Ptr_t * vTokens;
- char * pLastToken;
- int i;
-
- // get rid of the old tokens
- if ( p->vNewTokens->nSize > 0 )
+ // read networks (with EXDC)
+ pNtkMaster = NULL;
+ while ( p->vTokens )
{
- for ( i = 0; i < p->vNewTokens->nSize; i++ )
- free( p->vNewTokens->pArray[i] );
- p->vNewTokens->nSize = 0;
+ // read the network and its EXDC if present
+ pNtk = Io_ReadBlifNetworkOne( p );
+ if ( pNtk == NULL )
+ break;
+ if ( p->vTokens && strcmp(p->vTokens->pArray[0], ".exdc") == 0 )
+ {
+ pNtk->pExdc = Io_ReadBlifNetworkOne( p );
+ Abc_NtkFinalizeRead( pNtk->pExdc );
+ if ( pNtk->pExdc == NULL )
+ break;
+ }
+ // add this network as part of the hierarchy
+ if ( pNtkMaster == NULL ) // no master network so far
+ {
+ pNtkMaster = pNtk;
+ continue;
+ }
+ // make sure hierarchy does not have the network with this name
+ if ( pNtkMaster->tName2Model && stmm_is_member( pNtkMaster->tName2Model, pNtk->pName ) )
+ {
+ p->LineCur = 0;
+ sprintf( p->sError, "Model %s is multiply defined in the file.", pNtk->pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ Abc_NtkDelete( pNtk );
+ Abc_NtkDelete( pNtkMaster );
+ pNtkMaster = NULL;
+ return NULL;
+ }
+ // add the network to the hierarchy
+ if ( pNtkMaster->tName2Model == NULL )
+ pNtkMaster->tName2Model = stmm_init_table(strcmp, stmm_strhash);
+ stmm_insert( pNtkMaster->tName2Model, pNtk->pName, (char *)pNtk );
}
- // get the new tokens
- vTokens = Extra_FileReaderGetTokens(p->pReader);
- if ( vTokens == NULL )
- return vTokens;
-
- // check if there is a transfer to another line
- pLastToken = vTokens->pArray[vTokens->nSize - 1];
- if ( pLastToken[ strlen(pLastToken)-1 ] != '\\' )
- return vTokens;
-
- // remove the slash
- pLastToken[ strlen(pLastToken)-1 ] = 0;
- if ( pLastToken[0] == 0 )
- vTokens->nSize--;
- // load them into the new array
- for ( i = 0; i < vTokens->nSize; i++ )
- Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
-
- // load as long as there is the line break
- while ( 1 )
+ // if there is a hierarchy, connect the boxes
+ if ( pNtkMaster && pNtkMaster->tName2Model )
{
- // get the new tokens
- vTokens = Extra_FileReaderGetTokens(p->pReader);
- if ( vTokens->nSize == 0 )
- return p->vNewTokens;
- // check if there is a transfer to another line
- pLastToken = vTokens->pArray[vTokens->nSize - 1];
- if ( pLastToken[ strlen(pLastToken)-1 ] == '\\' )
+ if ( Io_ReadBlifNetworkConnectBoxes( p, pNtkMaster ) )
{
- // remove the slash
- pLastToken[ strlen(pLastToken)-1 ] = 0;
- if ( pLastToken[0] == 0 )
- vTokens->nSize--;
- // load them into the new array
- for ( i = 0; i < vTokens->nSize; i++ )
- Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
- continue;
+ Abc_NtkDelete( pNtkMaster );
+ return NULL;
}
- // otherwise, load them and break
- for ( i = 0; i < vTokens->nSize; i++ )
- Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
- break;
}
- return p->vNewTokens;
+ else
+ Abc_NtkFinalizeRead( pNtkMaster );
+ // return the master network
+ return pNtkMaster;
}
-
/**Function*************************************************************
- Synopsis [Reads the BLIF file.]
+ Synopsis [Reads one (main or exdc) network from the BLIF file.]
Description []
@@ -272,74 +197,71 @@ Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p )
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
+Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
{
ProgressBar * pProgress;
- Vec_Ptr_t * vTokens;
- char * pModelName, * pDirective;
+ Abc_Ntk_t * pNtk;
+ char * pDirective;
int iLine, fTokensReady, fStatus;
+ // make sure the tokens are present
+ assert( p->vTokens != NULL );
+
+ // create the new network
+ p->pNtkCur = pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP );
// read the model name
- if ( !p->fParsingExdc )
- {
- // read the model name
- vTokens = Io_ReadBlifGetTokens(p);
- if ( vTokens == NULL || strcmp( vTokens->pArray[0], ".model" ) )
- {
- p->LineCur = 0;
- sprintf( p->sError, "Wrong input file format." );
- Io_ReadBlifPrintErrorMessage( p );
- return NULL;
- }
- pModelName = vTokens->pArray[1];
- // allocate the empty network
- p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP );
- p->pNtk->pName = Extra_UtilStrsav( pModelName );
- p->pNtk->pSpec = Extra_UtilStrsav( p->pFileName );
- }
- else
- p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP );
+ if ( strcmp( p->vTokens->pArray[0], ".model" ) == 0 )
+ pNtk->pName = Extra_UtilStrsav( p->vTokens->pArray[1] );
// read the inputs/outputs
pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
fTokensReady = fStatus = 0;
- for ( iLine = 0; fTokensReady || (vTokens = Io_ReadBlifGetTokens(p)); iLine++ )
+ for ( iLine = 0; fTokensReady || (p->vTokens = Io_ReadBlifGetTokens(p)); iLine++ )
{
if ( iLine % 1000 == 0 )
Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL );
// consider different line types
fTokensReady = 0;
- pDirective = vTokens->pArray[0];
+ pDirective = p->vTokens->pArray[0];
if ( !strcmp( pDirective, ".names" ) )
- { fStatus = Io_ReadBlifNetworkNames( p, &vTokens ); fTokensReady = 1; }
+ { fStatus = Io_ReadBlifNetworkNames( p, &p->vTokens ); fTokensReady = 1; }
else if ( !strcmp( pDirective, ".gate" ) )
- fStatus = Io_ReadBlifNetworkGate( p, vTokens );
+ fStatus = Io_ReadBlifNetworkGate( p, p->vTokens );
else if ( !strcmp( pDirective, ".latch" ) )
- fStatus = Io_ReadBlifNetworkLatch( p, vTokens );
+ fStatus = Io_ReadBlifNetworkLatch( p, p->vTokens );
else if ( !strcmp( pDirective, ".inputs" ) )
- fStatus = Io_ReadBlifNetworkInputs( p, vTokens );
+ fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens );
else if ( !strcmp( pDirective, ".outputs" ) )
- fStatus = Io_ReadBlifNetworkOutputs( p, vTokens );
+ fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens );
else if ( !strcmp( pDirective, ".input_arrival" ) )
- fStatus = Io_ReadBlifNetworkInputArrival( p, vTokens );
+ fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens );
else if ( !strcmp( pDirective, ".default_input_arrival" ) )
- fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, vTokens );
+ fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens );
+ else if ( !strcmp( pDirective, ".subckt" ) )
+ fStatus = Io_ReadBlifNetworkSubcircuit( p, p->vTokens );
else if ( !strcmp( pDirective, ".exdc" ) )
- { p->fParsingExdc = 1; break; }
+ break;
else if ( !strcmp( pDirective, ".end" ) )
+ {
+ p->vTokens = Io_ReadBlifGetTokens(p);
break;
+ }
+ else if ( !strcmp( pDirective, ".blackbox" ) )
+ {
+ pNtk->ntkType = ABC_NTK_BLACKBOX;
+ pNtk->ntkFunc = ABC_FUNC_BLACKBOX;
+ }
else
printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName,
Extra_FileReaderGetLineNumber(p->pReader, 0), pDirective );
- if ( vTokens == NULL ) // some files do not have ".end" in the end
+ if ( p->vTokens == NULL ) // some files do not have ".end" in the end
break;
if ( fStatus == 1 )
return NULL;
}
Extra_ProgressBarStop( pProgress );
- Abc_NtkFinalizeRead( p->pNtk );
- return p->pNtk;
+ return pNtk;
}
/**Function*************************************************************
@@ -357,7 +279,7 @@ int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
int i;
for ( i = 1; i < vTokens->nSize; i++ )
- Io_ReadCreatePi( p->pNtk, vTokens->pArray[i] );
+ Io_ReadCreatePi( p->pNtkCur, vTokens->pArray[i] );
return 0;
}
@@ -376,7 +298,7 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
int i;
for ( i = 1; i < vTokens->nSize; i++ )
- Io_ReadCreatePo( p->pNtk, vTokens->pArray[i] );
+ Io_ReadCreatePo( p->pNtkCur, vTokens->pArray[i] );
return 0;
}
@@ -393,7 +315,7 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
***********************************************************************/
int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
- Abc_Ntk_t * pNtk = p->pNtk;
+ Abc_Ntk_t * pNtk = p->pNtkCur;
Abc_Obj_t * pLatch;
int ResetValue;
if ( vTokens->nSize < 3 )
@@ -442,7 +364,7 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
{
Vec_Ptr_t * vTokens = *pvTokens;
- Abc_Ntk_t * pNtk = p->pNtk;
+ Abc_Ntk_t * pNtk = p->pNtkCur;
Abc_Obj_t * pNode;
char * pToken, Char, ** ppNames;
int nFanins, nNames;
@@ -584,12 +506,12 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
}
// if this is the first line with gate, update the network type
- if ( Abc_NtkNodeNum(p->pNtk) == 0 )
+ if ( Abc_NtkNodeNum(p->pNtkCur) == 0 )
{
- assert( p->pNtk->ntkFunc == ABC_FUNC_SOP );
- p->pNtk->ntkFunc = ABC_FUNC_MAP;
- Extra_MmFlexStop( p->pNtk->pManFunc, 0 );
- p->pNtk->pManFunc = pGenlib;
+ assert( p->pNtkCur->ntkFunc == ABC_FUNC_SOP );
+ p->pNtkCur->ntkFunc = ABC_FUNC_MAP;
+ Extra_MmFlexStop( p->pNtkCur->pManFunc, 0 );
+ p->pNtkCur->pManFunc = pGenlib;
}
// remove the formal parameter names
@@ -608,13 +530,53 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
// create the node
ppNames = (char **)vTokens->pArray + 2;
nNames = vTokens->nSize - 3;
- pNode = Io_ReadCreateNode( p->pNtk, ppNames[nNames], ppNames, nNames );
+ pNode = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames], ppNames, nNames );
// set the pointer to the functionality of the node
Abc_ObjSetData( pNode, pGate );
return 0;
}
+/**Function*************************************************************
+
+ Synopsis [Creates a multi-input multi-output box in the hierarchical design.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
+{
+ Abc_Obj_t * pBox;
+ Vec_Ptr_t * vNames;
+ char * pName;
+ int i;
+
+ // create a new node and add it to the network
+ if ( vTokens->nSize < 3 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "The .subcircuit line has less than three tokens." );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+
+ // store the names of formal/actual inputs/outputs of the box
+ vNames = Vec_PtrAlloc( 10 );
+ Vec_PtrForEachEntryStart( vTokens, pName, i, 1 )
+ Vec_PtrPush( vNames, Abc_NtkRegisterName(p->pNtkCur, pName) );
+
+ // create a new box and add it to the network
+ pBox = Abc_NtkCreateBox( p->pNtkCur );
+ // set the pointer to the node names
+ Abc_ObjSetData( pBox, vNames );
+ // remember the line of the file
+ pBox->pCopy = (void *)Extra_FileReaderGetLineNumber(p->pReader, 0);
+ return 0;
+}
/**Function*************************************************************
@@ -663,7 +625,7 @@ int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
- pNet = Abc_NtkFindNet( p->pNtk, vTokens->pArray[1] );
+ pNet = Abc_NtkFindNet( p->pNtkCur, vTokens->pArray[1] );
if ( pNet == NULL )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
@@ -681,7 +643,7 @@ int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
return 1;
}
// set the arrival time
- Abc_NtkTimeSetArrival( p->pNtk, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall );
+ Abc_NtkTimeSetArrival( p->pNtkCur, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall );
return 0;
}
@@ -720,10 +682,354 @@ int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vToken
return 1;
}
// set the arrival time
- Abc_NtkTimeSetDefaultArrival( p->pNtk, (float)TimeRise, (float)TimeFall );
+ Abc_NtkTimeSetDefaultArrival( p->pNtkCur, (float)TimeRise, (float)TimeFall );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the error message including the file name and line number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p )
+{
+ if ( p->LineCur == 0 ) // the line number is not given
+ fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError );
+ else // print the error message with the line number
+ fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Gets the tokens taking into account the line breaks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p )
+{
+ Vec_Ptr_t * vTokens;
+ char * pLastToken;
+ int i;
+
+ // get rid of the old tokens
+ if ( p->vNewTokens->nSize > 0 )
+ {
+ for ( i = 0; i < p->vNewTokens->nSize; i++ )
+ free( p->vNewTokens->pArray[i] );
+ p->vNewTokens->nSize = 0;
+ }
+
+ // get the new tokens
+ vTokens = Extra_FileReaderGetTokens(p->pReader);
+ if ( vTokens == NULL )
+ return vTokens;
+
+ // check if there is a transfer to another line
+ pLastToken = vTokens->pArray[vTokens->nSize - 1];
+ if ( pLastToken[ strlen(pLastToken)-1 ] != '\\' )
+ return vTokens;
+
+ // remove the slash
+ pLastToken[ strlen(pLastToken)-1 ] = 0;
+ if ( pLastToken[0] == 0 )
+ vTokens->nSize--;
+ // load them into the new array
+ for ( i = 0; i < vTokens->nSize; i++ )
+ Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
+
+ // load as long as there is the line break
+ while ( 1 )
+ {
+ // get the new tokens
+ vTokens = Extra_FileReaderGetTokens(p->pReader);
+ if ( vTokens->nSize == 0 )
+ return p->vNewTokens;
+ // check if there is a transfer to another line
+ pLastToken = vTokens->pArray[vTokens->nSize - 1];
+ if ( pLastToken[ strlen(pLastToken)-1 ] == '\\' )
+ {
+ // remove the slash
+ pLastToken[ strlen(pLastToken)-1 ] = 0;
+ if ( pLastToken[0] == 0 )
+ vTokens->nSize--;
+ // load them into the new array
+ for ( i = 0; i < vTokens->nSize; i++ )
+ Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
+ continue;
+ }
+ // otherwise, load them and break
+ for ( i = 0; i < vTokens->nSize; i++ )
+ Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
+ break;
+ }
+ return p->vNewTokens;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts the reading data structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName )
+{
+ Extra_FileReader_t * pReader;
+ Io_ReadBlif_t * p;
+
+ // start the reader
+ pReader = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t" );
+
+ if ( pReader == NULL )
+ return NULL;
+
+ // start the reading data structure
+ p = ALLOC( Io_ReadBlif_t, 1 );
+ memset( p, 0, sizeof(Io_ReadBlif_t) );
+ p->pFileName = pFileName;
+ p->pReader = pReader;
+ p->Output = stdout;
+ p->vNewTokens = Vec_PtrAlloc( 100 );
+ p->vCubes = Vec_StrAlloc( 100 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the data structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadBlifFree( Io_ReadBlif_t * p )
+{
+ Extra_FileReaderFree( p->pReader );
+ Vec_PtrFree( p->vNewTokens );
+ Vec_StrFree( p->vCubes );
+ free( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Connect one box.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, stmm_table * tName2Model )
+{
+ Vec_Ptr_t * pNames;
+ Abc_Ntk_t * pNtkModel;
+ Abc_Obj_t * pObj, * pNet;
+ char * pName, * pActual;
+ int i, Length, Start;
+
+ // get the model for this box
+ pNames = pBox->pData;
+ if ( !stmm_lookup( tName2Model, Vec_PtrEntry(pNames, 0), (char **)&pNtkModel ) )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot find the model for subcircuit %s.", Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+
+ // create the fanins of the box
+ Abc_NtkForEachPi( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+ Vec_PtrForEachEntryStart( pNames, pName, i, 1 )
+ {
+ pActual = Io_ReadBlifCleanName(pName);
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ Length = pActual - pName - 1;
+ pName[Length] = 0;
+ // find the PI net with this name
+ pObj = Abc_NtkFindNet( pNtkModel, pName );
+ if ( pObj == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // get the PI
+ pObj = Abc_ObjFanin0(pObj);
+ // quit if this is not a PI net
+ if ( !Abc_ObjIsPi(pObj) )
+ {
+ pName[Length] = '=';
+ Start = i;
+ break;
+ }
+ // remember the actual name in the net
+ if ( pObj->pCopy != NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pObj->pCopy = (void *)pActual;
+ // quit if we processed all PIs
+ if ( i == Abc_NtkPiNum(pNtkModel) )
+ {
+ Start = i+1;
+ break;
+ }
+ }
+ // create the fanins of the box
+ Abc_NtkForEachPi( pNtkModel, pObj, i )
+ {
+ pActual = (void *)pObj->pCopy;
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal input \"%s\" of model %s is not driven.", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual );
+ Abc_ObjAddFanin( pBox, pNet );
+ }
+ Abc_NtkForEachPi( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+
+ // create the fanouts of the box
+ Abc_NtkForEachPo( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+ Vec_PtrForEachEntryStart( pNames, pName, i, Start )
+ {
+ pActual = Io_ReadBlifCleanName(pName);
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ Length = pActual - pName - 1;
+ pName[Length] = 0;
+ // find the PO net with this name
+ pObj = Abc_NtkFindNet( pNtkModel, pName );
+ if ( pObj == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot find formal output \"%s\" as an PO of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // get the PO
+ pObj = Abc_ObjFanout0(pObj);
+ if ( pObj->pCopy != NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal output \"%s\" is used more than once.", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pObj->pCopy = (void *)pActual;
+ }
+ // create the fanouts of the box
+ Abc_NtkForEachPo( pNtkModel, pObj, i )
+ {
+ pActual = (void *)pObj->pCopy;
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal output \"%s\" of model %s is not driven.", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual );
+ Abc_ObjAddFanin( pNet, pBox );
+ }
+ Abc_NtkForEachPo( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+
+ // remove the array of names, assign the pointer to the model
+ Vec_PtrFree( pBox->pData );
+ pBox->pData = pNtkModel;
return 0;
}
+/**Function*************************************************************
+
+ Synopsis [Connect the boxes in the hierarchy of networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkConnectBoxesOne( Io_ReadBlif_t * p, Abc_Ntk_t * pNtk, stmm_table * tName2Model )
+{
+ Abc_Obj_t * pBox;
+ int i;
+ // go through the boxes
+ Abc_NtkForEachBox( pNtk, pBox, i )
+ if ( Io_ReadBlifNetworkConnectBoxesOneBox( p, pBox, tName2Model ) )
+ return 1;
+ Abc_NtkFinalizeRead( pNtk );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Connect the boxes in the hierarchy of networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster )
+{
+ stmm_generator * gen;
+ Abc_Ntk_t * pNtk;
+ char * pName;
+ // connect the master network
+ if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtkMaster, pNtkMaster->tName2Model ) )
+ return 1;
+ // connect other networks
+ stmm_foreach_item( pNtkMaster->tName2Model, gen, &pName, (char **)&pNtk )
+ if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtk, pNtkMaster->tName2Model ) )
+ return 1;
+ return 0;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c
index 1b515a1e..1e27498d 100644
--- a/src/base/io/ioWriteBlif.c
+++ b/src/base/io/ioWriteBlif.c
@@ -26,6 +26,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+static void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
@@ -59,7 +60,7 @@ void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
fprintf( stdout, "Writing BLIF has failed.\n" );
return;
}
- Io_WriteBlif( pNtkTemp, FileName, fWriteLatches );
+ Io_WriteBlifNetlist( pNtkTemp, FileName, fWriteLatches );
Abc_NtkDelete( pNtkTemp );
}
@@ -74,19 +75,48 @@ void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
SeeAlso []
***********************************************************************/
-void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
+void Io_WriteBlifNetlist( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
{
- Abc_Ntk_t * pExdc;
+ stmm_generator * gen;
+ Abc_Ntk_t * pNtkTemp;
FILE * pFile;
assert( Abc_NtkIsNetlist(pNtk) );
+ // start writing the file
pFile = fopen( FileName, "w" );
if ( pFile == NULL )
{
- fprintf( stdout, "Io_WriteBlif(): Cannot open the output file.\n" );
+ fprintf( stdout, "Io_WriteBlifNetlist(): Cannot open the output file.\n" );
return;
}
- // write the model name
fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
+ // write the master network
+ Io_NtkWrite( pFile, pNtk, fWriteLatches );
+ // write the hierarchy if present
+ if ( pNtk->tName2Model )
+ {
+ fprintf( pFile, "\n\n" );
+ stmm_foreach_item( pNtk->tName2Model, gen, NULL, (char **)&pNtkTemp )
+ Io_NtkWrite( pFile, pNtkTemp, fWriteLatches );
+ }
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write the network into a BLIF file with the given name.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
+{
+ Abc_Ntk_t * pExdc;
+ assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsBlackbox(pNtk) );
+ // write the model name
fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
// write the network
Io_NtkWriteOne( pFile, pNtk, fWriteLatches );
@@ -100,7 +130,6 @@ void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
}
// finalize the file
fprintf( pFile, ".end\n" );
- fclose( pFile );
}
/**Function*************************************************************
@@ -130,6 +159,13 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
Io_NtkWritePos( pFile, pNtk, fWriteLatches );
fprintf( pFile, "\n" );
+ // write the blackbox
+ if ( Abc_NtkIsBlackbox( pNtk ) )
+ {
+ fprintf( pFile, ".blackbox\n" );
+ return;
+ }
+
// write the timing info
Io_WriteTimingInfo( pFile, pNtk );