From 24f1ca07030c1246280dea98bb0975cfec8d5ea4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 29 Nov 2014 14:36:26 -0800 Subject: New parser and framework. --- src/base/cba/cbaReadBlif.c | 330 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 src/base/cba/cbaReadBlif.c (limited to 'src/base/cba/cbaReadBlif.c') 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 + -- cgit v1.2.3