summaryrefslogtreecommitdiffstats
path: root/src/base/cba/cbaReadBlif.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2014-11-29 14:36:26 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2014-11-29 14:36:26 -0800
commit24f1ca07030c1246280dea98bb0975cfec8d5ea4 (patch)
tree464415cd3f653f22860e4ff4e3f108299ab70f5b /src/base/cba/cbaReadBlif.c
parentc30a0ca0b973faf136b309600f03b32b78d0a733 (diff)
downloadabc-24f1ca07030c1246280dea98bb0975cfec8d5ea4.tar.gz
abc-24f1ca07030c1246280dea98bb0975cfec8d5ea4.tar.bz2
abc-24f1ca07030c1246280dea98bb0975cfec8d5ea4.zip
New parser and framework.
Diffstat (limited to 'src/base/cba/cbaReadBlif.c')
-rw-r--r--src/base/cba/cbaReadBlif.c330
1 files changed, 330 insertions, 0 deletions
diff --git a/src/base/cba/cbaReadBlif.c b/src/base/cba/cbaReadBlif.c
new file mode 100644
index 00000000..c324b37f
--- /dev/null
+++ b/src/base/cba/cbaReadBlif.c
@@ -0,0 +1,330 @@
+/**CFile****************************************************************
+
+ FileName [cbaReadBlif.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Verilog parser.]
+
+ Synopsis [Parses several flavors of word-level Verilog.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 29, 2014.]
+
+ Revision [$Id: cbaReadBlif.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cba.h"
+#include "cbaPrs.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// BLIF keywords
+typedef enum {
+ CBA_BLIF_NONE = 0, // 0: unused
+ CBA_BLIF_MODEL, // 1: .model
+ CBA_BLIF_INPUTS, // 2: .inputs
+ CBA_BLIF_OUTPUTS, // 3: .outputs
+ CBA_BLIF_NAMES, // 4: .names
+ CBA_BLIF_SUBCKT, // 5: .subckt
+ CBA_BLIF_GATE, // 6: .gate
+ CBA_BLIF_LATCH, // 7: .latch
+ CBA_BLIF_END, // 8: .end
+ CBA_BLIF_UNKNOWN // 9: unknown
+} Cba_BlifType_t;
+
+const char * s_BlifTypes[CBA_BLIF_UNKNOWN+1] = {
+ NULL, // 0: unused
+ ".model", // 1: .model
+ ".inputs", // 2: .inputs
+ ".outputs", // 3: .outputs
+ ".names", // 4: .names
+ ".subckt", // 5: .subckt
+ ".gate", // 6: .gate
+ ".latch", // 7: .latch
+ ".end", // 8: .end
+ NULL // 9: unknown
+};
+
+static inline void Cba_PrsAddBlifDirectives( Cba_Prs_t * p )
+{
+ int i;
+ for ( i = 1; s_BlifTypes[i]; i++ )
+ Abc_NamStrFindOrAdd( p->pDesign->pNames, (char *)s_BlifTypes[i], NULL );
+ assert( Abc_NamObjNumMax(p->pDesign->pNames) == i );
+}
+
+static inline int Cba_PrsIsSpace( char c ) { return c == ' ' || c == '\t' || c == '\r'; }
+static inline int Cba_PrsIsOk( Cba_Prs_t * p ) { return (int)(p->pCur < p->pLimit); }
+static inline int Cba_PrsIsChar( Cba_Prs_t * p, char c ) { return *p->pCur == 'c'; }
+static inline int Cba_PrsIsLit( Cba_Prs_t * p ) { return *p->pCur == '0' || *p->pCur == '1' || *p->pCur == '-'; }
+static inline void Cba_PrsSkipToChar( Cba_Prs_t * p, char c ) { while ( *p->pCur != c ) p->pCur++; }
+static inline char Cba_PrsSkip( Cba_Prs_t * p ) { return *p->pCur++; }
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Reading names.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Cba_PrsSkipSpaces( Cba_Prs_t * p )
+{
+ while ( Cba_PrsIsSpace(*p->pCur) )
+ Cba_PrsSkip(p);
+ if ( Cba_PrsIsChar(p, '#') )
+ Cba_PrsSkipToChar( p, '\n' );
+ else if ( Cba_PrsIsChar(p, '\\') )
+ {
+ Cba_PrsSkipToChar( p, '\n' );
+ Cba_PrsSkip(p);
+ Cba_PrsSkipSpaces( p );
+ }
+}
+static inline int Cba_PrsReadName( Cba_Prs_t * p )
+{
+ char * pStart = p->pCur;
+ while ( !Cba_PrsIsSpace(*p->pCur) && !Cba_PrsIsChar(p, '\\') )
+ Cba_PrsSkip(p);
+ if ( pStart == p->pCur )
+ return 0;
+ return Abc_NamStrFindOrAddLim( p->pDesign->pNames, pStart, p->pCur, NULL );
+}
+static inline int Cba_PrsReadName2( Cba_Prs_t * p )
+{
+ char * pStart = p->pCur;
+ while ( !Cba_PrsIsSpace(*p->pCur) && !Cba_PrsIsChar(p, '\\') && !Cba_PrsIsChar(p, '=') )
+ Cba_PrsSkip(p);
+ if ( pStart == p->pCur )
+ return 0;
+ return Abc_NamStrFindOrAddLim( p->pDesign->pNames, pStart, p->pCur, NULL );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cba_PrsReadCube( Cba_Prs_t * p )
+{
+ while ( Cba_PrsIsLit(p) )
+ Vec_StrPush( p->vCover, Cba_PrsSkip(p) );
+ Cba_PrsSkipSpaces( p );
+ Vec_StrPush( p->vCover, ' ' );
+ if ( !Cba_PrsIsLit(p) ) return Cba_PrsErrorSet(p, "Cannot detect output literal.", 1);
+ Vec_StrPush( p->vCover, Cba_PrsSkip(p) );
+ return 1;
+}
+static inline void Cba_PrsSaveCover( Cba_Prs_t * p )
+{
+ int iToken;
+ assert( Vec_StrSize(p->vCover) > 0 );
+ Vec_StrPush( p->vCover, '\0' );
+ iToken = Abc_NamStrFindOrAdd( p->pDesign->pFuncs, Vec_StrArray(p->vCover), NULL );
+ Vec_StrClear( p->vCover );
+ assert( Vec_IntEntryLast(p->vFuncsCur) == 1 );
+ Vec_IntWriteEntry( p->vFuncsCur, Vec_IntSize(p->vFuncsCur)-1, iToken );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cba_PrsReadSignals( Cba_Prs_t * p, int fSkipFirst )
+{
+ Cba_PrsSkipSpaces( p );
+ Vec_IntFill( p->vTemp, fSkipFirst, -1 );
+ while ( !Cba_PrsIsChar(p, '\n') )
+ {
+ Vec_IntPush( p->vTemp, Cba_PrsReadName(p) );
+ Cba_PrsSkipSpaces( p );
+ }
+ if ( Vec_IntSize(p->vTemp) == 0 ) return Cba_PrsErrorSet(p, "List of signals is empty.", 1);
+ if ( Vec_IntCountZero(p->vTemp) ) return Cba_PrsErrorSet(p, "Cannot read names in the list.", 1);
+ return 0;
+}
+static inline int Cba_PrsReadInputs( Cba_Prs_t * p )
+{
+ if ( Cba_PrsReadSignals(p, 0) ) return 1;
+ Vec_IntAppend( p->vInputsCur, p->vTemp );
+ return 0;
+}
+static inline int Cba_PrsReadOutputs( Cba_Prs_t * p )
+{
+ if ( Cba_PrsReadSignals(p, 0) ) return 1;
+ Vec_IntAppend( p->vOutputsCur, p->vTemp );
+ return 0;
+}
+static inline int Cba_PrsReadNode( Cba_Prs_t * p )
+{
+ if ( Cba_PrsReadSignals(p, 1) ) return 1;
+ Vec_IntWriteEntry( p->vTemp, 0, Vec_IntPop(p->vTemp) );
+ // save results
+ Vec_IntPush( p->vFuncsCur, 1 );
+ Vec_IntPush( p->vTypesCur, CBA_PRS_NODE );
+ Cba_PrsSetupVecInt( p, Vec_WecPushLevel(p->vFaninsCur), p->vTemp );
+ return 0;
+}
+static inline int Cba_PrsReadBox( Cba_Prs_t * p, int fGate )
+{
+ Cba_PrsSkipSpaces( p );
+ if ( Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Cannot read model name.", 1);
+ Vec_IntPush( p->vFuncsCur, Cba_PrsReadName(p) );
+ Cba_PrsSkipSpaces( p );
+ if ( Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Cannot read formal/actual inputs.", 1);
+ while ( !Cba_PrsIsChar(p, '\n') )
+ {
+ Vec_IntPush( p->vTemp, Cba_PrsReadName(p) );
+ Cba_PrsSkipSpaces( p );
+ if ( !Cba_PrsIsChar(p, '=') ) return Cba_PrsErrorSet(p, "Cannot find symbol \'=\'.", 1);
+ p->pCur++;
+ Cba_PrsSkipSpaces( p );
+ Vec_IntPush( p->vTemp, Cba_PrsReadName(p) );
+ Cba_PrsSkipSpaces( p );
+ }
+ // save results
+ Vec_IntPush( p->vTypesCur, CBA_PRS_BOX );
+ Cba_PrsSetupVecInt( p, Vec_WecPushLevel(p->vFaninsCur), p->vTemp );
+ return 0;
+}
+static inline int Cba_PrsReadLatch( Cba_Prs_t * p )
+{
+ Vec_IntFill( p->vTemp, 2, -1 );
+ Cba_PrsSkipSpaces( p );
+ if ( Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Cannot read latch input.", 1);
+ Vec_IntWriteEntry( p->vTemp, 1, Cba_PrsReadName(p) );
+ Cba_PrsSkipSpaces( p );
+ if ( Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Cannot read latch output.", 1);
+ Vec_IntWriteEntry( p->vTemp, 0, Cba_PrsReadName(p) );
+ if ( Cba_PrsIsChar(p, '0') )
+ Vec_IntPush( p->vFuncsCur, 0 );
+ else if ( Cba_PrsIsChar(p, '1') )
+ Vec_IntPush( p->vFuncsCur, 1 );
+ else if ( Cba_PrsIsChar(p, '2') || Cba_PrsIsChar(p, '\n') )
+ Vec_IntPush( p->vFuncsCur, 2 );
+ else return Cba_PrsErrorSet(p, "Cannot read latch init value.", 1);
+ // save results
+ Vec_IntPush( p->vTypesCur, CBA_PRS_LATCH );
+ Cba_PrsSetupVecInt( p, Vec_WecPushLevel(p->vFaninsCur), p->vTemp );
+ return 0;
+}
+static inline int Cba_PrsReadModel( Cba_Prs_t * p )
+{
+ Cba_PrsSkipSpaces( p );
+ if ( Vec_IntSize(p->vInputsCur) > 0 ) return Cba_PrsErrorSet(p, "Parsing previous model is unfinished.", 1);
+ p->iModuleName = Cba_PrsReadName( p );
+ if ( p->iModuleName == 0 ) return Cba_PrsErrorSet(p, "Cannot read model name.", 1);
+ Cba_PrsSkipSpaces( p );
+ if ( !Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Trailing symbols on .model line.", 1);
+ return 0;
+}
+static inline int Cba_PrsReadEnd( Cba_Prs_t * p )
+{
+ if ( Vec_IntSize(p->vInputsCur) == 0 ) return Cba_PrsErrorSet(p, "Directive .end without .model.", 1);
+ Cba_PrsAddCurrentModel( p, p->iModuleName );
+ return 0;
+}
+
+static inline int Cba_PrsReadDirective( Cba_Prs_t * p )
+{
+ int iToken;
+ if ( !Cba_PrsIsChar(p, '.') )
+ return Cba_PrsReadCube( p );
+ if ( Vec_StrSize(p->vCover) > 0 ) // SOP was specified for the previous node
+ Cba_PrsSaveCover( p );
+ iToken = Cba_PrsReadName( p );
+ if ( iToken == CBA_BLIF_MODEL )
+ return Cba_PrsReadModel( p );
+ if ( iToken == CBA_BLIF_INPUTS )
+ return Cba_PrsReadInputs( p );
+ if ( iToken == CBA_BLIF_OUTPUTS )
+ return Cba_PrsReadOutputs( p );
+ if ( iToken == CBA_BLIF_NAMES )
+ return Cba_PrsReadNode( p );
+ if ( iToken == CBA_BLIF_SUBCKT )
+ return Cba_PrsReadBox( p, 0 );
+ if ( iToken == CBA_BLIF_GATE )
+ return Cba_PrsReadBox( p, 1 );
+ if ( iToken == CBA_BLIF_LATCH )
+ return Cba_PrsReadLatch( p );
+ if ( iToken == CBA_BLIF_END )
+ return Cba_PrsReadEnd( p );
+ assert( 0 );
+ return 1;
+}
+static inline int Cba_PrsReadLines( Cba_Prs_t * p )
+{
+ while ( Cba_PrsIsChar(p, '\n') )
+ {
+ p->pCur++; Cba_PrsSkipSpaces( p );
+ if ( Cba_PrsIsChar(p, '\n') )
+ continue;
+ if ( Cba_PrsReadDirective( p ) )
+ return 1;
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cba_Man_t * Cba_PrsReadBlif( char * pFileName )
+{
+ Cba_Man_t * pDesign = NULL;
+ Cba_Prs_t * p = Cba_PrsAlloc( pFileName );
+ if ( p == NULL )
+ return NULL;
+ Cba_PrsAddBlifDirectives( p );
+ Cba_PrsReadLines( p );
+ if ( Cba_PrsErrorPrint(p) )
+ ABC_SWAP( Cba_Man_t *, pDesign, p->pDesign );
+ Cba_PrsFree( p );
+ return pDesign;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+