blob: 35d7b7b279bc8d831dce41239b5b4a2ff841102a [file] [log] [blame]
/**CFile****************************************************************
FileName [saigIoa.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Sequential AIG package.]
Synopsis [Input/output for sequential AIGs using BLIF files.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: saigIoa.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include <math.h>
#include "saig.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Saig_ObjName( Aig_Man_t * p, Aig_Obj_t * pObj )
{
static char Buffer[16];
if ( Aig_ObjIsNode(pObj) || Aig_ObjIsConst1(pObj) )
sprintf( Buffer, "n%0*d", Abc_Base10Log(Aig_ManObjNumMax(p)), Aig_ObjId(pObj) );
else if ( Saig_ObjIsPi(p, pObj) )
sprintf( Buffer, "pi%0*d", Abc_Base10Log(Saig_ManPiNum(p)), Aig_ObjCioId(pObj) );
else if ( Saig_ObjIsPo(p, pObj) )
sprintf( Buffer, "po%0*d", Abc_Base10Log(Saig_ManPoNum(p)), Aig_ObjCioId(pObj) );
else if ( Saig_ObjIsLo(p, pObj) )
sprintf( Buffer, "lo%0*d", Abc_Base10Log(Saig_ManRegNum(p)), Aig_ObjCioId(pObj) - Saig_ManPiNum(p) );
else if ( Saig_ObjIsLi(p, pObj) )
sprintf( Buffer, "li%0*d", Abc_Base10Log(Saig_ManRegNum(p)), Aig_ObjCioId(pObj) - Saig_ManPoNum(p) );
else
assert( 0 );
return Buffer;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Saig_ManDumpBlif( Aig_Man_t * p, char * pFileName )
{
FILE * pFile;
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int i;
if ( Aig_ManCoNum(p) == 0 )
{
printf( "Aig_ManDumpBlif(): AIG manager does not have POs.\n" );
return;
}
Aig_ManSetCioIds( p );
// write input file
pFile = fopen( pFileName, "w" );
if ( pFile == NULL )
{
printf( "Saig_ManDumpBlif(): Cannot open file for writing.\n" );
return;
}
fprintf( pFile, "# BLIF file written by procedure Saig_ManDumpBlif()\n" );
fprintf( pFile, "# If unedited, this file can be read by Saig_ManReadBlif()\n" );
fprintf( pFile, "# AIG stats: pi=%d po=%d reg=%d and=%d obj=%d maxid=%d\n",
Saig_ManPiNum(p), Saig_ManPoNum(p), Saig_ManRegNum(p),
Aig_ManNodeNum(p), Aig_ManObjNum(p), Aig_ManObjNumMax(p) );
fprintf( pFile, ".model %s\n", p->pName );
// write primary inputs
fprintf( pFile, ".inputs" );
Aig_ManForEachPiSeq( p, pObj, i )
fprintf( pFile, " %s", Saig_ObjName(p, pObj) );
fprintf( pFile, "\n" );
// write primary outputs
fprintf( pFile, ".outputs" );
Aig_ManForEachPoSeq( p, pObj, i )
fprintf( pFile, " %s", Saig_ObjName(p, pObj) );
fprintf( pFile, "\n" );
// write registers
if ( Aig_ManRegNum(p) )
{
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
{
fprintf( pFile, ".latch" );
fprintf( pFile, " %s", Saig_ObjName(p, pObjLi) );
fprintf( pFile, " %s", Saig_ObjName(p, pObjLo) );
fprintf( pFile, " 0\n" );
}
}
// check if constant is used
if ( Aig_ObjRefs(Aig_ManConst1(p)) )
fprintf( pFile, ".names %s\n 1\n", Saig_ObjName(p, Aig_ManConst1(p)) );
// write the nodes in the DFS order
Aig_ManForEachNode( p, pObj, i )
{
fprintf( pFile, ".names" );
fprintf( pFile, " %s", Saig_ObjName(p, Aig_ObjFanin0(pObj)) );
fprintf( pFile, " %s", Saig_ObjName(p, Aig_ObjFanin1(pObj)) );
fprintf( pFile, " %s", Saig_ObjName(p, pObj) );
fprintf( pFile, "\n%d%d 1\n", !Aig_ObjFaninC0(pObj), !Aig_ObjFaninC1(pObj) );
}
// write the POs
Aig_ManForEachCo( p, pObj, i )
{
fprintf( pFile, ".names" );
fprintf( pFile, " %s", Saig_ObjName(p, Aig_ObjFanin0(pObj)) );
fprintf( pFile, " %s", Saig_ObjName(p, pObj) );
fprintf( pFile, "\n%d 1\n", !Aig_ObjFaninC0(pObj) );
}
fprintf( pFile, ".end\n" );
fclose( pFile );
}
/**Function*************************************************************
Synopsis [Reads one token from file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Saig_ManReadToken( FILE * pFile )
{
static char Buffer[1000];
if ( fscanf( pFile, "%s", Buffer ) == 1 )
return Buffer;
return NULL;
}
/**Function*************************************************************
Synopsis [Returns the corresponding number.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Saig_ManReadNumber( Aig_Man_t * p, char * pToken )
{
if ( pToken[0] == 'n' )
return atoi( pToken + 1 );
if ( pToken[0] == 'p' )
return atoi( pToken + 2 );
if ( pToken[0] == 'l' )
return atoi( pToken + 2 );
assert( 0 );
return -1;
}
/**Function*************************************************************
Synopsis [Returns the corresponding node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Obj_t * Saig_ManReadNode( Aig_Man_t * p, int * pNum2Id, char * pToken )
{
int Num;
if ( pToken[0] == 'n' )
{
Num = atoi( pToken + 1 );
return Aig_ManObj( p, pNum2Id[Num] );
}
if ( pToken[0] == 'p' )
{
pToken++;
if ( pToken[0] == 'i' )
{
Num = atoi( pToken + 1 );
return Aig_ManCi( p, Num );
}
if ( pToken[0] == 'o' )
return NULL;
assert( 0 );
return NULL;
}
if ( pToken[0] == 'l' )
{
pToken++;
if ( pToken[0] == 'o' )
{
Num = atoi( pToken + 1 );
return Saig_ManLo( p, Num );
}
if ( pToken[0] == 'i' )
return NULL;
assert( 0 );
return NULL;
}
assert( 0 );
return NULL;
}
/**Function*************************************************************
Synopsis [Reads BLIF previously dumped by Saig_ManDumpBlif().]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Saig_ManReadBlif( char * pFileName )
{
FILE * pFile;
Aig_Man_t * p;
Aig_Obj_t * pFanin0, * pFanin1, * pNode;
char * pToken;
int i, nPis, nPos, nRegs, Number;
int * pNum2Id = NULL; // mapping of node numbers in the file into AIG node IDs
// open the file
pFile = fopen( pFileName, "r" );
if ( pFile == NULL )
{
printf( "Saig_ManReadBlif(): Cannot open file for reading.\n" );
return NULL;
}
// skip through the comments
for ( i = 0; (pToken = Saig_ManReadToken( pFile )) && pToken[0] != '.'; i++ );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 1.\n" ); return NULL; }
// get he model
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 2.\n" ); return NULL; }
// start the package
p = Aig_ManStart( 10000 );
p->pName = Abc_UtilStrsav( pToken );
p->pSpec = Abc_UtilStrsav( pFileName );
// count PIs
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL || strcmp( pToken, ".inputs" ) )
{ printf( "Saig_ManReadBlif(): Error 3.\n" ); Aig_ManStop(p); return NULL; }
for ( nPis = 0; (pToken = Saig_ManReadToken( pFile )) && pToken[0] != '.'; nPis++ );
// count POs
if ( pToken == NULL || strcmp( pToken, ".outputs" ) )
{ printf( "Saig_ManReadBlif(): Error 4.\n" ); Aig_ManStop(p); return NULL; }
for ( nPos = 0; (pToken = Saig_ManReadToken( pFile )) && pToken[0] != '.'; nPos++ );
// count latches
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 5.\n" ); Aig_ManStop(p); return NULL; }
for ( nRegs = 0; strcmp( pToken, ".latch" ) == 0; nRegs++ )
{
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 6.\n" ); Aig_ManStop(p); return NULL; }
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 7.\n" ); Aig_ManStop(p); return NULL; }
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 8.\n" ); Aig_ManStop(p); return NULL; }
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 9.\n" ); Aig_ManStop(p); return NULL; }
}
// create PIs and LOs
for ( i = 0; i < nPis + nRegs; i++ )
Aig_ObjCreateCi( p );
Aig_ManSetRegNum( p, nRegs );
// create nodes
for ( i = 0; strcmp( pToken, ".names" ) == 0; i++ )
{
// first token
pToken = Saig_ManReadToken( pFile );
if ( i == 0 && pToken[0] == 'n' )
{ // constant node
// read 1
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL || strcmp( pToken, "1" ) )
{ printf( "Saig_ManReadBlif(): Error 10.\n" ); Aig_ManStop(p); return NULL; }
// read next
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 11.\n" ); Aig_ManStop(p); return NULL; }
continue;
}
pFanin0 = Saig_ManReadNode( p, pNum2Id, pToken );
// second token
pToken = Saig_ManReadToken( pFile );
if ( (pToken[0] == 'p' && pToken[1] == 'o') || (pToken[0] == 'l' && pToken[1] == 'i') )
{ // buffer
// read complemented attribute
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 12.\n" ); Aig_ManStop(p); return NULL; }
if ( pToken[0] == '0' )
pFanin0 = Aig_Not(pFanin0);
// read 1
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL || strcmp( pToken, "1" ) )
{ printf( "Saig_ManReadBlif(): Error 13.\n" ); Aig_ManStop(p); return NULL; }
Aig_ObjCreateCo( p, pFanin0 );
// read next
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 14.\n" ); Aig_ManStop(p); return NULL; }
continue;
}
// third token
// regular node
pFanin1 = Saig_ManReadNode( p, pNum2Id, pToken );
pToken = Saig_ManReadToken( pFile );
Number = Saig_ManReadNumber( p, pToken );
// allocate mapping
if ( pNum2Id == NULL )
{
// extern double pow( double x, double y );
int Size = (int)pow(10.0, (double)(strlen(pToken) - 1));
pNum2Id = ABC_CALLOC( int, Size );
}
// other tokens
// get the complemented attributes
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 15.\n" ); Aig_ManStop(p); return NULL; }
if ( pToken[0] == '0' )
pFanin0 = Aig_Not(pFanin0);
if ( pToken[1] == '0' )
pFanin1 = Aig_Not(pFanin1);
// read 1
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL || strcmp( pToken, "1" ) )
{ printf( "Saig_ManReadBlif(): Error 16.\n" ); Aig_ManStop(p); return NULL; }
// read next
pToken = Saig_ManReadToken( pFile );
if ( pToken == NULL )
{ printf( "Saig_ManReadBlif(): Error 17.\n" ); Aig_ManStop(p); return NULL; }
// create new node
pNode = Aig_And( p, pFanin0, pFanin1 );
if ( Aig_IsComplement(pNode) )
{ printf( "Saig_ManReadBlif(): Error 18.\n" ); Aig_ManStop(p); return NULL; }
// set mapping
pNum2Id[ Number ] = pNode->Id;
}
if ( pToken == NULL || strcmp( pToken, ".end" ) )
{ printf( "Saig_ManReadBlif(): Error 19.\n" ); Aig_ManStop(p); return NULL; }
if ( nPos + nRegs != Aig_ManCoNum(p) )
{ printf( "Saig_ManReadBlif(): Error 20.\n" ); Aig_ManStop(p); return NULL; }
// add non-node objects to the mapping
Aig_ManForEachCi( p, pNode, i )
pNum2Id[pNode->Id] = pNode->Id;
// ABC_FREE( pNum2Id );
p->pData = pNum2Id;
// check the new manager
Aig_ManSetRegNum( p, nRegs );
if ( !Aig_ManCheck(p) )
printf( "Saig_ManReadBlif(): Check has failed.\n" );
return p;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END