diff --git a/Netlist/File.pm b/Netlist/File.pm index b52e87d..00b8dea 100644 --- a/Netlist/File.pm +++ b/Netlist/File.pm @@ -493,6 +493,7 @@ sub read { use_cb_operator => 0, use_cb_string => 0, use_cb_symbol => 0, + infer_missing_types => $params{infer_missing_types}, ); return $fileref; } diff --git a/Parser/Parser.pm b/Parser/Parser.pm index 15f9273..e3e9daa 100644 --- a/Parser/Parser.pm +++ b/Parser/Parser.pm @@ -60,6 +60,7 @@ sub new { use_protected => 1, # Backward compatibility use_pinselects => 0, # Backward compatibility use_std => undef, # Undef = silent + infer_missing_types => 0, #use_cb_{callback-name} => 0/1 # #_debug # Don't set, use debug() accessor to change level @@ -74,6 +75,7 @@ sub new { $self->{use_unreadback}, $self->{use_protected}, $self->{use_pinselects}, # Undocumented as for use in SigParser only + $self->{infer_missing_types}, ); $self->{use_cb_contassign} = $self->{use_vars} if !exists $self->{use_cb_contassign}; diff --git a/Parser/Parser.xs b/Parser/Parser.xs index 33296f7..ab1bb12 100644 --- a/Parser/Parser.xs +++ b/Parser/Parser.xs @@ -108,8 +108,8 @@ public: void cbFileline(VFileLine* filelinep) { m_cbFilelinep = filelinep; } VParserXs(VFileLine* filelinep, av* symsp, - bool sigparser, bool useUnreadback, bool useProtected, bool usePinselects) - : VParse(filelinep, symsp, sigparser, useUnreadback, useProtected, usePinselects) + bool sigparser, bool useUnreadback, bool useProtected, bool usePinselects, bool inferMissingTypes) + : VParse(filelinep, symsp, sigparser, useUnreadback, useProtected, usePinselects, inferMissingTypes) , m_cbFilelinep(filelinep) { set_cb_use(); } virtual ~VParserXs(); @@ -344,14 +344,14 @@ MODULE = Verilog::Parser PACKAGE = Verilog::Parser #// self->_new (class, sigparser) static VParserXs * -VParserXs::_new(SV* SELF, AV* symsp, bool sigparser, bool useUnreadback, bool useProtected, bool usePinselects) +VParserXs::_new(SV* SELF, AV* symsp, bool sigparser, bool useUnreadback, bool useProtected, bool usePinselects, bool inferMissingTypes) PROTOTYPE: $$$$ CODE: { if (CLASS) {} /* Prevent unused warning */ if (!SvROK(SELF)) { warn("${Package}::$func_name() -- SELF is not a hash reference"); } VFileLineParseXs* filelinep = new VFileLineParseXs(NULL/*ok,for initial*/); - VParserXs* parserp = new VParserXs(filelinep, symsp, sigparser, useUnreadback, useProtected, usePinselects); + VParserXs* parserp = new VParserXs(filelinep, symsp, sigparser, useUnreadback, useProtected, usePinselects, inferMissingTypes); filelinep->setParser(parserp); parserp->m_self = SvRV(SELF); RETVAL = parserp; diff --git a/Parser/VParse.cpp b/Parser/VParse.cpp index dbf78ca..a978add 100644 --- a/Parser/VParse.cpp +++ b/Parser/VParse.cpp @@ -39,7 +39,7 @@ VParseGrammar* VParseGrammar::s_grammarp = NULL; //************************************************************************* VParse::VParse(VFileLine* filelinep, av* symsp, - bool sigParser, bool useUnreadbackFlag, bool useProtected, bool usePinselects) + bool sigParser, bool useUnreadbackFlag, bool useProtected, bool usePinselects, bool inferMissingTypes) : m_syms(filelinep, symsp) { m_inFilelinep = filelinep; @@ -47,6 +47,7 @@ VParse::VParse(VFileLine* filelinep, av* symsp, m_useUnreadback = useUnreadbackFlag; m_useProtected = useProtected; m_usePinselects = usePinselects; + m_inferMissingTypes = inferMissingTypes; m_debug = 0; m_lexp = new VParseLex(this); m_grammarp = new VParseGrammar(this); diff --git a/Parser/VParse.h b/Parser/VParse.h index 3a7a817..95a10dd 100644 --- a/Parser/VParse.h +++ b/Parser/VParse.h @@ -67,6 +67,7 @@ class VParse { bool m_useUnreadback;///< Need m_unreadback tracking bool m_useProtected; ///< Need `protected tracking bool m_usePinselects;///< Need bit-select parsing + bool m_inferMissingTypes; string m_unreadback; ///< Otherwise unprocessed whitespace before current token deque m_buffers; ///< Buffer of characters to process @@ -123,7 +124,7 @@ class VParse { public: // CONSTRUCTORS VParse(VFileLine* filelinep, av* symsp, - bool sigParser, bool useUnreadbackFlag, bool useProtected, bool usePinselects); + bool sigParser, bool useUnreadbackFlag, bool useProtected, bool usePinselects, bool inferMissingTypes); virtual ~VParse(); // ACCESSORS @@ -138,6 +139,7 @@ class VParse { bool callbackMasterEna() const { return m_callbackMasterEna; } bool useProtected() const { return m_useProtected; } bool usePinSelects() const { return m_usePinselects; } + bool inferMissingTypes() const { return m_inferMissingTypes; } VFileLine* inFilelinep() const; ///< File/Line number for last callback void inFileline(const string& filename, int lineno) { m_inFilelinep = m_inFilelinep->create(filename, lineno); } diff --git a/Parser/VParseLex.h b/Parser/VParseLex.h index 40c4ea1..cad2324 100644 --- a/Parser/VParseLex.h +++ b/Parser/VParseLex.h @@ -77,9 +77,10 @@ class VParseLex { bool m_inCellDefine; ///< In a `celldefine int m_prevLexToken; ///< previous parsed token (for lexer) - bool m_ahead; ///< aheadToken is valid - int m_aheadToken; ///< Token we read ahead - VParseBisonYYSType m_aheadVal; ///< aheadToken's value + static const int k_aheadLimit = 100; + int m_aheadCount; ///< aheadToken is valid + int m_aheadToken[k_aheadLimit]; ///< Token we read ahead + VParseBisonYYSType m_aheadVal[k_aheadLimit]; ///< aheadToken's value int m_pvstate; ///< "pure virtual" detection @@ -96,7 +97,7 @@ class VParseLex { m_parsep = parsep; m_inCellDefine = false; m_prevLexToken = 0; - m_ahead = false; + m_aheadCount = 0; m_pvstate = 0; m_yyState = yy_create_buffer(NULL, YY_BUF_SIZE); diff --git a/Parser/VParseLex.l b/Parser/VParseLex.l index 1bce5bd..ceead48 100644 --- a/Parser/VParseLex.l +++ b/Parser/VParseLex.l @@ -727,17 +727,25 @@ int VParseLex::lexToken(VParseBisonYYSType* yylvalp) { // Fetch next token from prefetch or real lexer s_currentLexp = this; int token; - if (m_ahead) { + int prevtok = LEXP->prevLexToken(); + if (m_aheadCount) { // We prefetched an extra token, give it back - m_ahead = false; - token = m_aheadToken; - *yylvalp = m_aheadVal; + m_aheadCount--; + token = m_aheadToken[0]; + *yylvalp = m_aheadVal[0]; + for (int i=0; iinferMissingTypes()) { + while (m_aheadCount < 2) { + m_aheadToken[m_aheadCount] = yylex(); + m_aheadVal[m_aheadCount] = *s_yylvalp; + m_aheadCount++; + *s_yylvalp = curValue; + } + + if (m_aheadToken[0] == yP_COLONCOLON) { + LPARSEP->symPushNew(VAstType::PACKAGE, s_yylvalp->str); + LPARSEP->symPopScope(VAstType::PACKAGE); + token = yaID__aPACKAGE; + } + else if ((m_aheadToken[0] == yaID__LEX && m_aheadToken[1] != '(') || m_aheadToken[0] == '[') { + if (prevtok == '(' + || prevtok == ',' + || prevtok == ';' + || prevtok == '{' + || prevtok == yBEGIN + || prevtok == yEND + || prevtok == yINOUT + || prevtok == yINPUT + || prevtok == yOUTPUT + || prevtok == yWIRE + || prevtok == yP_COLONCOLON) { + if (m_aheadToken[0] == '[') { + for (int i=1; i= m_aheadCount) { + m_aheadToken[m_aheadCount] = yylex(); + m_aheadVal[m_aheadCount] = *s_yylvalp; + m_aheadCount++; + *s_yylvalp = curValue; + } + + if (m_aheadToken[i] == ']') { + if (m_aheadToken[i+1] == yaID__LEX) { + token = yaID__aTYPE; + } + break; + } + } + } else { + token = yaID__aTYPE; + } + } + } + } + + if (token == yaID__LEX) { token = yaID__ETC; } } diff --git a/vhier b/vhier index d42fe19..08af619 100755 --- a/vhier +++ b/vhier @@ -37,6 +37,7 @@ my $Opt_ModFiles; my $Opt_InFiles; my $Opt_Missing = 1; my $Opt_Missing_Modules; +my $Opt_InferMissingTypes; my $Opt_TopModule; my $Opt_ResolveFiles; my $Opt_Synthesis; @@ -65,6 +66,7 @@ if (! GetOptions ( "language=s" => sub { shift; Verilog::Language::language_standard(shift); }, "missing!" => \$Opt_Missing, "missing-modules!" => \$Opt_Missing_Modules, + "infer-missing-types!"=> \$Opt_InferMissingTypes, "synthesis!" => \$Opt_Synthesis, "top-module=s" => \$Opt_TopModule, "version" => sub { print "Version $VERSION\n"; exit(0); }, @@ -144,7 +146,7 @@ sub vhier { } foreach my $file (@files) { print " Reading $file\n" if $Debug; - $nl->read_file(filename=>$file); + $nl->read_file(filename=>$file, infer_missing_types=>$Opt_InferMissingTypes); } # Read in any sub-modules $nl->link();