Compare commits

...
11 Commits
Author SHA1 Message Date
Wilson Snyder a77b58dba9 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@957 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-18 16:32:16 +00:00
Wilson Snyder c300ab6dd9 Match up with Verilog-Perl: add specify operators
git-svn-id: file://localhost/svn/verilator/trunk/verilator@956 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-10-18 16:29:19 +00:00
Wilson Snyder 9ac0f1accb Fix parsing system functions with empty parens
git-svn-id: file://localhost/svn/verilator/trunk/verilator@955 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-09-17 17:54:02 +00:00
Wilson Snyder 7990e5d4b1 Fix parsing module #(parameter x,y) declarations.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@954 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-09-11 13:35:02 +00:00
Wilson Snyder fb2cb3c49d Don't exit early if many warnings but no errors are found. [Stan Mayer]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@953 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-08-23 13:21:58 +00:00
Wilson Snyder c4b1bc2506 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@950 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-08-01 13:44:45 +00:00
Wilson Snyder 551393d443 Fix SC_LIBS missing from generated makefiles. [Ding Xiaoliang]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@949 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-31 14:47:21 +00:00
Wilson Snyder 79d305f3e8 Match Verilog-Perl: Remove preprocessor adding newlines before `line.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@948 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-30 15:00:21 +00:00
Wilson Snyder 822956e769 Add SystemVerilog end labels
git-svn-id: file://localhost/svn/verilator/trunk/verilator@947 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-18 17:58:53 +00:00
Wilson Snyder a681a6a6d5 Make -> a token to match verilog-perl
git-svn-id: file://localhost/svn/verilator/trunk/verilator@946 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-18 17:26:12 +00:00
Wilson Snyder 5f6d69affd Support SystemVerilog ==? and !=? operators.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@945 77ca24e4-aefa-0310-84f0-b9a241c72d87
2007-07-18 15:01:39 +00:00
25 changed files with 373 additions and 75 deletions
+14
View File
@@ -3,6 +3,20 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...] The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks! indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.654 10/18/2007
**** Don't exit early if many warnings but no errors are found. [Stan Mayer]
**** Fix parsing module #(parameter x,y) declarations. [Oleg Rodionov]
**** Fix parsing system functions with empty parens. [Oleg Rodionov]
* Verilator 3.653 8/1/2007
**** Support SystemVerilog ==? and !=? operators.
**** Fix SC_LIBS missing from generated makefiles. [Ding Xiaoliang]
* Verilator 3.652 6/21/2007 * Verilator 3.652 6/21/2007
**** Report as many warning types as possible before exiting. **** Report as many warning types as possible before exiting.
+1 -1
View File
@@ -4,7 +4,7 @@
# #
# This file is part of Verilator. # This file is part of Verilator.
# #
# Author: Wilson Snyder <[email protected]> or <[email protected]> # Author: Wilson Snyder <[email protected]>
# #
# Code available from: http://www.veripool.com/verilator # Code available from: http://www.veripool.com/verilator
# #
+7
View File
@@ -25,6 +25,7 @@ Features:
Coverage Coverage
Points should be per-scope like everything else rather then per-module Points should be per-scope like everything else rather then per-module
Expression coverage (see notes) Expression coverage (see notes)
Constant functions for widths, etc, IE "input [log2(PARAM):0] xx;"
More Verilog 2001 Support More Verilog 2001 Support
(* *) Attributes (just ignore -- preprocessor?) (* *) Attributes (just ignore -- preprocessor?)
Real numbers (NEVER) Real numbers (NEVER)
@@ -103,6 +104,12 @@ Performance:
If floped(a) & flopped(b) and no other a&b, then instead flop(a&b). If floped(a) & flopped(b) and no other a&b, then instead flop(a&b).
Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal) Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal)
All of the temp vars that get set, exp pre_ vars and never feedback
(not flops) don't need to be stored in the structs, but instead can
be per-invocation, and even better register-colored-like to reuse
the space. This will greatly reduce the data footprint.
//********************************************************************** //**********************************************************************
//* Detailed notes on 'todo' features //* Detailed notes on 'todo' features
+17 -4
View File
@@ -1010,12 +1010,14 @@ Verilator currently has very minimal support for SystemVerilog. As
SystemVerilog features enter common usage they will be added. Contact the SystemVerilog features enter common usage they will be added. Contact the
author if a feature you need is missing. author if a feature you need is missing.
Verilator implements the full SystemVerilog 1800-2005 preprocessor subset, Verilator implements the full SystemVerilog 1800-2005 preprocessor,
including function call-like preprocessor defines. including function call-like preprocessor defines.
Verilator supports $bits, $countones, $error, $fatal, $info, $isunknown, Verilator supports ==? and !=? operators, $bits, $countones, $error,
$onehot, $onehot0, $warning, always_comb, always_ff, always_latch, $fatal, $info, $isunknown, $onehot, $onehot0, $warning, always_comb,
do-while, and final. It also supports .name and .* interconnection. always_ff, always_latch, do-while, and final.
It also supports .name and .* interconnection.
Verilator partially supports assert. Verilator partially supports assert.
@@ -1999,6 +2001,17 @@ the "verilator" define for you, so just wrap the code in a ifndef region:
Something_Verilator_Dislikes; Something_Verilator_Dislikes;
`endif `endif
=item Why do I get "unexpected `do'" or "unexpected `bit'" errors?
Do, bit, ref, and other words are now SystemVerilog keywords. You should
change your code to not use them to insure it works with newer tools.
Alternatively, surround them by the Verilog 2005/SystemVerilog
begin_keywords pragma to indicate Verilog 2001 code.
`begin_keywords "1364-2001"
integer bit; initial bit = 1;
`end_keywords
=item How do I prevent my assertions from firing during reset? =item How do I prevent my assertions from firing during reset?
Call Verilated::assertOn(false) before you first call the model, then turn Call Verilated::assertOn(false) before you first call the model, then turn
+33
View File
@@ -2606,6 +2606,39 @@ struct AstNeqCase : public AstNodeBiCom {
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;} virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
}; };
struct AstEqWild : public AstNodeBiop {
// Note wildcard operator rhs differs from lhs
AstEqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
width(1,1); }
virtual ~AstEqWild() {}
virtual AstType type() const { return AstType::EQWILD;}
virtual AstNode* clone() { return new AstEqWild(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k==? %r)"; }
virtual string emitOperator() { return "VL_EQ"; } // Until have 4 state anyways
virtual string emitSimpleOperator() { return "=="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
};
struct AstNeqWild : public AstNodeBiop {
AstNeqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
width(1,1); }
virtual ~AstNeqWild() {}
virtual AstType type() const { return AstType::NEQWILD;}
virtual AstNode* clone() { return new AstNeqWild(*this); }
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildNeq(lhs,rhs); }
virtual string emitVerilog() { return "%k(%l %k!=? %r)"; }
virtual string emitOperator() { return "VL_NEQ"; } // Until have 4 state anyways
virtual string emitSimpleOperator() { return "!="; }
virtual bool emitWordForm() { return true; }
virtual bool cleanOut() {return true;}
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
};
struct AstConcat : public AstNodeBiop { struct AstConcat : public AstNodeBiop {
// If you're looking for {#{}}, see AstReplicate // If you're looking for {#{}}, see AstReplicate
AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) { AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
+6
View File
@@ -1110,6 +1110,10 @@ private:
TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEqCase}", "AstNeqCase{$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeqCase, $lhsp.width1}","AstEqCase {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castNeqCase}", "AstEqCase {$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castEqWild, $lhsp.width1}","AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castEqWild}", "AstNeqWild{$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeqWild, $lhsp.width1}","AstEqWild {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castNeqWild}", "AstEqWild {$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castEq, $lhsp.width1}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}");
TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOP ("AstLogNot{$lhsp.castEq}", "AstNeq {$lhsp->op1p(),$lhsp->op2p()}");
TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}"); TREEOPV("AstNot {$lhsp.castNeq, $lhsp.width1}", "AstEq {$lhsp->op1p(),$lhsp->op2p()}");
@@ -1151,6 +1155,7 @@ private:
TREEOP("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X. TREEOP("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
TREEOP("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
@@ -1161,6 +1166,7 @@ private:
TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); TREEOP("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)"); TREEOP("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstNeqWild{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)"); TREEOP("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
TREEOP("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)"); TREEOP("AstLogOr {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
///=== Verilog operators ///=== Verilog operators
+1 -1
View File
@@ -138,7 +138,7 @@ public:
of.puts("\n# Link rules...\n"); of.puts("\n# Link rules...\n");
of.puts(v3Global.opt.prefix()+": $(VK_USER_OBJS) $(SP_SRCS) $(VM_PREFIX)__ALL.a\n"); of.puts(v3Global.opt.prefix()+": $(VK_USER_OBJS) $(SP_SRCS) $(VM_PREFIX)__ALL.a\n");
of.puts("\t$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) 2>&1 | c++filt\n"); of.puts("\t$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LIBS) $(SC_LIBS) 2>&1 | c++filt\n");
of.puts("\n"); of.puts("\n");
} }
+2 -4
View File
@@ -190,14 +190,12 @@ string V3Error::lineStr (const char* filename, int lineno) {
void V3Error::incWarnings() { void V3Error::incWarnings() {
s_warnCount++; s_warnCount++;
if (errorOrWarnCount() == MAX_ERRORS) { // Not >= as would otherwise recurse // We don't exit on a lot of warnings.
v3fatal ("Exiting due to too many errors encountered\n");
}
} }
void V3Error::incErrors() { void V3Error::incErrors() {
s_errCount++; s_errCount++;
if (errorOrWarnCount() == MAX_ERRORS) { // Not >= as would otherwise recurse if (errorCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
v3fatal ("Exiting due to too many errors encountered\n"); v3fatal ("Exiting due to too many errors encountered\n");
} }
} }
+22
View File
@@ -814,6 +814,28 @@ last:
return setSingleBits(outc); return setSingleBits(outc);
} }
V3Number& V3Number::opWildEq (const V3Number& lhs, const V3Number& rhs) {
char outc = 1;
for (int bit=0; bit<max(lhs.width(),rhs.width()); bit++) {
if (!rhs.bitIsXZ(bit)
&& lhs.bitIs(bit) != rhs.bitIs(bit)) { outc=0; goto last; }
if (lhs.bitIsXZ(bit)) outc='x';
}
last:
return setSingleBits(outc);
}
V3Number& V3Number::opWildNeq (const V3Number& lhs, const V3Number& rhs) {
char outc = 0;
for (int bit=0; bit<max(lhs.width(),rhs.width()); bit++) {
if (!rhs.bitIsXZ(bit)
&& lhs.bitIs(bit) != rhs.bitIs(bit)) { outc=1; goto last; }
if (lhs.bitIsXZ(bit)) outc='x';
}
last:
return setSingleBits(outc);
}
V3Number& V3Number::opGt (const V3Number& lhs, const V3Number& rhs) { V3Number& V3Number::opGt (const V3Number& lhs, const V3Number& rhs) {
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend. // i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
char outc = 0; char outc = 0;
+2
View File
@@ -174,6 +174,8 @@ public:
V3Number& opCond (const V3Number& lhs, const V3Number& rhs, const V3Number& ths); V3Number& opCond (const V3Number& lhs, const V3Number& rhs, const V3Number& ths);
V3Number& opCaseEq (const V3Number& lhs, const V3Number& rhs); V3Number& opCaseEq (const V3Number& lhs, const V3Number& rhs);
V3Number& opCaseNeq (const V3Number& lhs, const V3Number& rhs); V3Number& opCaseNeq (const V3Number& lhs, const V3Number& rhs);
V3Number& opWildEq (const V3Number& lhs, const V3Number& rhs);
V3Number& opWildNeq (const V3Number& lhs, const V3Number& rhs);
// "standard" math // "standard" math
V3Number& opNot (const V3Number& lhs); V3Number& opNot (const V3Number& lhs);
V3Number& opLogNot (const V3Number& lhs); V3Number& opLogNot (const V3Number& lhs);
+3
View File
@@ -65,7 +65,10 @@ void test(string lhss, string op, string rhss, string exps) {
else if (op=="<<") gotnum.opShiftL (lhnum,rhnum); else if (op=="<<") gotnum.opShiftL (lhnum,rhnum);
else if (op=="==") gotnum.opEq (lhnum,rhnum); else if (op=="==") gotnum.opEq (lhnum,rhnum);
else if (op=="===") gotnum.opCaseEq (lhnum,rhnum); else if (op=="===") gotnum.opCaseEq (lhnum,rhnum);
else if (op=="==?") gotnum.opWildEq (lhnum,rhnum);
else if (op=="!=") gotnum.opNeq (lhnum,rhnum); else if (op=="!=") gotnum.opNeq (lhnum,rhnum);
else if (op=="!==") gotnum.opCaseNeq (lhnum,rhnum);
else if (op=="!=?") gotnum.opWildNeq (lhnum,rhnum);
else if (op=="<=") gotnum.opLte (lhnum,rhnum); else if (op=="<=") gotnum.opLte (lhnum,rhnum);
else if (op==">=") gotnum.opGte (lhnum,rhnum); else if (op==">=") gotnum.opGte (lhnum,rhnum);
else if (op=="&&") gotnum.opLogAnd (lhnum,rhnum); else if (op=="&&") gotnum.opLogAnd (lhnum,rhnum);
+34 -6
View File
@@ -83,7 +83,9 @@ struct V3PreProcImp : public V3PreProc {
// For getRawToken/ `line insertion // For getRawToken/ `line insertion
string m_lineCmt; // Line comment(s) to be returned string m_lineCmt; // Line comment(s) to be returned
int m_lineAdd; // Empty lines to return to maintain line count bool m_lineCmtNl; ///< Newline needed before inserting lineCmt
int m_lineAdd; ///< Empty lines to return to maintain line count
bool m_rawAtBol; ///< Last rawToken left us at beginning of line
// For defines // For defines
string m_defName; // Define last name being defined string m_defName; // Define last name being defined
@@ -134,6 +136,7 @@ public:
virtual bool isEof() const { return (m_lexp==NULL); } virtual bool isEof() const { return (m_lexp==NULL); }
virtual string getline(); virtual string getline();
virtual void insertUnreadback(const string& text) { m_lineCmt += text; } virtual void insertUnreadback(const string& text) { m_lineCmt += text; }
void insertUnreadbackAtBol(const string& text);
// METHODS, callbacks // METHODS, callbacks
virtual void comment(const string& cmt); // Comment detected (if keepComments==2) virtual void comment(const string& cmt); // Comment detected (if keepComments==2)
@@ -151,6 +154,8 @@ public:
m_lineChars = ""; m_lineChars = "";
m_lastSym = ""; m_lastSym = "";
m_lineAdd = 0; m_lineAdd = 0;
m_lineCmtNl = false;
m_rawAtBol = true;
m_defDepth = 0; m_defDepth = 0;
} }
}; };
@@ -486,14 +491,24 @@ void V3PreProcImp::openFile(FileLine* fl, const string& filename) {
yy_switch_to_buffer(m_lexp->m_yyState); yy_switch_to_buffer(m_lexp->m_yyState);
} }
void V3PreProcImp::insertUnreadbackAtBol(const string& text) {
// Insert insuring we're at the beginning of line, for `line
// We don't always add a leading newline, as it may result in extra unreadback(newlines).
if (m_lineCmt == "") { m_lineCmtNl = true; }
else if (m_lineCmt[m_lineCmt.length()-1]!='\n') {
insertUnreadback("\n");
}
insertUnreadback(text);
}
void V3PreProcImp::addLineComment(int enter_exit_level) { void V3PreProcImp::addLineComment(int enter_exit_level) {
if (lineDirectives()) { if (lineDirectives()) {
char numbuf[20]; sprintf(numbuf, "%d", m_lexp->m_curFilelinep->lineno()); char numbuf[20]; sprintf(numbuf, "%d", m_lexp->m_curFilelinep->lineno());
char levelbuf[20]; sprintf(levelbuf, "%d", enter_exit_level); char levelbuf[20]; sprintf(levelbuf, "%d", enter_exit_level);
string cmt = ((string)"\n`line "+numbuf string cmt = ((string)"`line "+numbuf
+" \""+m_lexp->m_curFilelinep->filename()+"\" " +" \""+m_lexp->m_curFilelinep->filename()+"\" "
+levelbuf+"\n"); +levelbuf+"\n");
insertUnreadback(cmt); insertUnreadbackAtBol(cmt);
} }
} }
@@ -517,6 +532,7 @@ int V3PreProcImp::getRawToken() {
next_tok: next_tok:
if (m_lineAdd) { if (m_lineAdd) {
m_lineAdd--; m_lineAdd--;
m_rawAtBol = true;
yytext="\n"; yyleng=1; yytext="\n"; yyleng=1;
return (VP_TEXT); return (VP_TEXT);
} }
@@ -524,8 +540,13 @@ int V3PreProcImp::getRawToken() {
// We have some `line directive to return to the user. Do it. // We have some `line directive to return to the user. Do it.
static string rtncmt; // Keep the c string till next call static string rtncmt; // Keep the c string till next call
rtncmt = m_lineCmt; rtncmt = m_lineCmt;
if (m_lineCmtNl) {
if (!m_rawAtBol) rtncmt = "\n"+rtncmt;
m_lineCmtNl = false;
}
yytext=(char*)rtncmt.c_str(); yyleng=rtncmt.length(); yytext=(char*)rtncmt.c_str(); yyleng=rtncmt.length();
m_lineCmt = ""; m_lineCmt = "";
if (yyleng) m_rawAtBol = (yytext[yyleng-1]=='\n');
if (m_state!=ps_DEFVALUE) return (VP_TEXT); if (m_state!=ps_DEFVALUE) return (VP_TEXT);
else { else {
V3PreLex::s_currentLexp->appendDefValue(yytext,yyleng); V3PreLex::s_currentLexp->appendDefValue(yytext,yyleng);
@@ -533,6 +554,7 @@ int V3PreProcImp::getRawToken() {
} }
} }
if (isEof()) return (VP_EOF); if (isEof()) return (VP_EOF);
// Snarf next token from the file // Snarf next token from the file
m_fileline = m_lexp->m_curFilelinep; // Remember token start location m_fileline = m_lexp->m_curFilelinep; // Remember token start location
V3PreLex::s_currentLexp = m_lexp; // Tell parser where to get/put data V3PreLex::s_currentLexp = m_lexp; // Tell parser where to get/put data
@@ -553,6 +575,7 @@ int V3PreProcImp::getRawToken() {
goto next_tok; // Parse parent, or find the EOF. goto next_tok; // Parse parent, or find the EOF.
} }
if (yyleng) m_rawAtBol = (yytext[yyleng-1]=='\n');
return tok; return tok;
} }
} }
@@ -872,7 +895,8 @@ string V3PreProcImp::getline() {
// Get a single line from the parse stream. Buffer unreturned text until the newline. // Get a single line from the parse stream. Buffer unreturned text until the newline.
if (isEof()) return ""; if (isEof()) return "";
char* rtnp; char* rtnp;
while (NULL==(rtnp=strchr(m_lineChars.c_str(),'\n'))) { bool gotEof = false;
while (NULL==(rtnp=strchr(m_lineChars.c_str(),'\n')) && !gotEof) {
int tok = getToken(); int tok = getToken();
if (debug()>4) { if (debug()>4) {
string buf = string (yytext, yyleng); string buf = string (yytext, yyleng);
@@ -883,8 +907,12 @@ string V3PreProcImp::getline() {
fileline()->lineno(), tokenName(tok), buf.c_str()); fileline()->lineno(), tokenName(tok), buf.c_str());
} }
if (tok==VP_EOF) { if (tok==VP_EOF) {
// Add a final newline, in case the user forgot the final \n. // Add a final newline, if the user forgot the final \n.
m_lineChars.append("\n"); // Note tok==VP_EOF isn't always seen by us, as isEof() may be set earlier
if (m_lineChars != "" && m_lineChars[m_lineChars.length()-1] != '\n') {
m_lineChars.append("\n");
}
gotEof = true;
} }
else if (tok==VP_PSL) { else if (tok==VP_PSL) {
m_lineChars.append(" psl "); m_lineChars.append(" psl ");
+2
View File
@@ -98,8 +98,10 @@ private:
// ... (Though they should match. We don't check.) // ... (Though they should match. We don't check.)
virtual void visit(AstEq* nodep, AstNUser*) { signed_Ou_Ix(nodep); } virtual void visit(AstEq* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstEqCase* nodep, AstNUser*) { signed_Ou_Ix(nodep); } virtual void visit(AstEqCase* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstEqWild* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstNeq* nodep, AstNUser*) { signed_Ou_Ix(nodep); } virtual void visit(AstNeq* nodep, AstNUser*) { signed_Ou_Ix(nodep); }
virtual void visit(AstNeqCase* nodep, AstNUser*){ signed_Ou_Ix(nodep); } virtual void visit(AstNeqCase* nodep, AstNUser*){ signed_Ou_Ix(nodep); }
virtual void visit(AstNeqWild* nodep, AstNUser*){ signed_Ou_Ix(nodep); }
//======= //=======
// Signed: Output signed iff LHS signed; unary operator // Signed: Output signed iff LHS signed; unary operator
+42
View File
@@ -106,6 +106,42 @@ private:
newp->iterateChildren(*this); newp->iterateChildren(*this);
} }
} }
void visitEqNeqWild(AstNodeBiop* nodep) {
UINFO(4," N/EQWILD->EQ "<<nodep<<endl);
V3Const::constifyTree(nodep->lhsp());
V3Const::constifyTree(nodep->rhsp());
if (nodep->lhsp()->castConst() && nodep->rhsp()->castConst()) {
// Both sides are constant, node can be constant
V3Const::constifyTree(nodep); nodep=NULL;
return;
} else {
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
AstNode* newp;
if (!rhsp->castConst()) {
nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); // Says spec.
// Replace with anything that won't cause more errors
newp = new AstEq (nodep->fileline(), lhsp, rhsp);
} else {
// X or Z's become mask, ala case statements.
V3Number nummask (rhsp->fileline(), rhsp->width());
nummask.opBitsNonX(rhsp->castConst()->num());
V3Number numval (rhsp->fileline(), rhsp->width());
numval.opBitsOne (rhsp->castConst()->num());
AstNode* and1p = new AstAnd(nodep->fileline(), lhsp,
new AstConst(nodep->fileline(), nummask));
AstNode* and2p = new AstConst(nodep->fileline(), numval);
if (nodep->castEqWild())
newp = new AstEq (nodep->fileline(), and1p, and2p);
else newp = new AstNeq (nodep->fileline(), and1p, and2p);
rhsp->deleteTree(); rhsp=NULL;
}
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
// Iterate tree now that we may have gotten rid of the compare
newp->iterateChildren(*this);
}
}
virtual void visit(AstEqCase* nodep, AstNUser*) { virtual void visit(AstEqCase* nodep, AstNUser*) {
visitEqNeqCase(nodep); visitEqNeqCase(nodep);
@@ -113,6 +149,12 @@ private:
virtual void visit(AstNeqCase* nodep, AstNUser*) { virtual void visit(AstNeqCase* nodep, AstNUser*) {
visitEqNeqCase(nodep); visitEqNeqCase(nodep);
} }
virtual void visit(AstEqWild* nodep, AstNUser*) {
visitEqNeqWild(nodep);
}
virtual void visit(AstNeqWild* nodep, AstNUser*) {
visitEqNeqWild(nodep);
}
virtual void visit(AstIsUnknown* nodep, AstNUser*) { virtual void visit(AstIsUnknown* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
// Ahh, we're two state, so this is easy // Ahh, we're two state, so this is easy
+2
View File
@@ -117,6 +117,7 @@ private:
void width_O1_L_Rlhs(AstNode* nodep, AstNUser* vup); void width_O1_L_Rlhs(AstNode* nodep, AstNUser* vup);
virtual void visit(AstEq* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstEq* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstEqCase* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstEqCase* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstEqWild* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstGt* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstGt* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstGtS* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstGtS* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstGte* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstGte* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
@@ -127,6 +128,7 @@ private:
virtual void visit(AstLteS* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstLteS* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstNeq* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstNeq* nodep, AstNUser* vup) { width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstNeqCase* nodep, AstNUser* vup){ width_O1_L_Rlhs(nodep,vup); } virtual void visit(AstNeqCase* nodep, AstNUser* vup){ width_O1_L_Rlhs(nodep,vup); }
virtual void visit(AstNeqWild* nodep, AstNUser* vup){ width_O1_L_Rlhs(nodep,vup); }
// Widths: out width = lhs width = rhs width // Widths: out width = lhs width = rhs width
void width_Omax_L_Rlhs(AstNode* nodep, AstNUser* vup); void width_Omax_L_Rlhs(AstNode* nodep, AstNUser* vup);
+2 -2
View File
@@ -4,7 +4,7 @@
// //
// This file is part of Verilator. // This file is part of Verilator.
// //
// Author: Wilson Snyder <[email protected]> or <[email protected]> // Author: Wilson Snyder <[email protected]>
// //
// Code available from: http://www.veripool.com/verilator // Code available from: http://www.veripool.com/verilator
// //
@@ -24,7 +24,7 @@
//********************************************************************** //**********************************************************************
//**** Version and host name //**** Version and host name
#define DTVERSION "Verilator 3.652 6/21/2007" #define DTVERSION "Verilator 3.654 8/1/2007"
//********************************************************************** //**********************************************************************
//**** Functions //**** Functions
+15 -3
View File
@@ -567,6 +567,13 @@ escid \\[^ \t\f\r\n]+
"~^" {yylval.fileline = CRELINE(); return yP_XNOR;} "~^" {yylval.fileline = CRELINE(); return yP_XNOR;}
"~&" {yylval.fileline = CRELINE(); return yP_NAND;} "~&" {yylval.fileline = CRELINE(); return yP_NAND;}
"~|" {yylval.fileline = CRELINE(); return yP_NOR;} "~|" {yylval.fileline = CRELINE(); return yP_NOR;}
"->" {yylval.fileline = CRELINE(); return yP_MINUSGT;}
"=>" {yylval.fileline = CRELINE(); return yP_EQGT; }
"*>" {yylval.fileline = CRELINE(); return yP_ASTGT; }
"+=>" {yylval.fileline = CRELINE(); return yP_PLUSEQGT; }
"+*>" {yylval.fileline = CRELINE(); return yP_PLUSASTGT; }
"-=>" {yylval.fileline = CRELINE(); return yP_MINUSEQGT; }
"-*>" {yylval.fileline = CRELINE(); return yP_MINUSASTGT; }
} }
/* Verilog 2001 Operators */ /* Verilog 2001 Operators */
@@ -578,11 +585,16 @@ escid \\[^ \t\f\r\n]+
"-:" {yylval.fileline = CRELINE(); return yP_MINUSCOLON;} "-:" {yylval.fileline = CRELINE(); return yP_MINUSCOLON;}
} }
/* SystemVerilog Operators */
<S05>{
"==?" {yylval.fileline = CRELINE(); return yP_WILDEQUAL;}
"!=?" {yylval.fileline = CRELINE(); return yP_WILDNOTEQUAL;}
}
/* PSL Operators */ /* PSL Operators */
<PSL>{ <PSL>{
"{" {yylval.fileline = CRELINE(); return yPSL_BRA;} // Avoid parser hitting concatenate. "{" {yylval.fileline = CRELINE(); return yPSL_BRA;} // Avoid parser hitting concatenate.
"}" {yylval.fileline = CRELINE(); return yPSL_KET;} // Avoid parser hitting concatenate. "}" {yylval.fileline = CRELINE(); return yPSL_KET;} // Avoid parser hitting concatenate.
"->" {yylval.fileline = CRELINE(); return yP_LOGIF;}
"<->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} //Unsup in other tools "<->" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} //Unsup in other tools
"[*" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_STAR "[*" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_STAR
"[*]" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_STAR_KET "[*]" {yyerrorf("Unsupported: PSL operator not implemented: %s",yytext);} // yP_BRA_STAR_KET
@@ -659,7 +671,7 @@ escid \\[^ \t\f\r\n]+
<ATTRMODE>"*)" { yy_pop_state(); } <ATTRMODE>"*)" { yy_pop_state(); }
<ATTRMODE>. { yymore(); } <ATTRMODE>. { yymore(); }
<ATTRMODE><<EOF>> { yyerror("EOF in (*"); <ATTRMODE><<EOF>> { yyerror("EOF in (*");
yyleng = 0; } yyleng = 0; yy_pop_state(); }
/************************************************************************/ /************************************************************************/
/* Attributes */ /* Attributes */
@@ -695,7 +707,7 @@ escid \\[^ \t\f\r\n]+
"`begin_keywords"[ \t]*\"1364-2001-noconfig\" { yy_push_state(V01); V3Read::pushBeginKeywords(YY_START);} "`begin_keywords"[ \t]*\"1364-2001-noconfig\" { yy_push_state(V01); V3Read::pushBeginKeywords(YY_START);}
"`begin_keywords"[ \t]*\"1364-2005\" { yy_push_state(V05); V3Read::pushBeginKeywords(YY_START);} "`begin_keywords"[ \t]*\"1364-2005\" { yy_push_state(V05); V3Read::pushBeginKeywords(YY_START);}
"`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); V3Read::pushBeginKeywords(YY_START);} "`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); V3Read::pushBeginKeywords(YY_START);}
"`end_keywords" { yy_pop_state(); if (!V3Read::popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); } "`end_keywords" { yy_pop_state(); if (!V3Read::popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); }
} }
<SYSCHDR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCHDR;} <SYSCHDR>[ \t]*[^` \t\n][^\n]*\n { NEXTLINE(); yylval.strp = V3Read::newString(yytext); return yaSCHDR;}
+56 -27
View File
@@ -248,6 +248,12 @@ class AstSenTree;
%token<fileline> yP_PLUSCOLON "+:" %token<fileline> yP_PLUSCOLON "+:"
%token<fileline> yP_MINUSCOLON "-:" %token<fileline> yP_MINUSCOLON "-:"
%token<fileline> yP_EQGT "=>"
%token<fileline> yP_ASTGT "*>"
%token<fileline> yP_PLUSEQGT "+=>"
%token<fileline> yP_PLUSASTGT "+*>"
%token<fileline> yP_MINUSEQGT "-=>"
%token<fileline> yP_MINUSASTGT "-*>"
%token<fileline> yPSL_BRA "{" %token<fileline> yPSL_BRA "{"
%token<fileline> yPSL_KET "}" %token<fileline> yPSL_KET "}"
@@ -256,7 +262,7 @@ class AstSenTree;
//******************** //********************
// PSL op precedence // PSL op precedence
%right<fileline> yP_LOGIF yP_LOGIFF %right<fileline> yP_MINUSGT yP_LOGIFF /* MinusGT == -> == PSL LogIf operator */
%right<fileline> yP_OR_MINUS_GT yP_OR_EQ_GT %right<fileline> yP_OR_MINUS_GT yP_OR_EQ_GT
%left<fileline> prPSLCLK %left<fileline> prPSLCLK
@@ -269,7 +275,7 @@ class AstSenTree;
%left<fileline> '^' %left<fileline> '^'
%left<fileline> yP_XNOR %left<fileline> yP_XNOR
%left<fileline> '&' yP_NAND %left<fileline> '&' yP_NAND
%left<fileline> yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL %left<fileline> yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL
%left<fileline> '>' '<' yP_GTE yP_LTE %left<fileline> '>' '<' yP_GTE yP_LTE
%left<fileline> yP_SLEFT yP_SRIGHT yP_SSRIGHT %left<fileline> yP_SLEFT yP_SRIGHT yP_SSRIGHT
%left<fileline> '+' '-' %left<fileline> '+' '-'
@@ -290,7 +296,7 @@ class AstSenTree;
%type<nodep> modPortsE portList port %type<nodep> modPortsE portList port
%type<nodep> portV2kArgs portV2kList portV2kSecond portV2kSig %type<nodep> portV2kArgs portV2kList portV2kSecond portV2kSig
%type<nodep> portV2kDecl ioDecl varDecl %type<nodep> portV2kDecl ioDecl varDecl
%type<nodep> modParDecl modParList modParE %type<nodep> modParArgs modParSecond modParDecl modParList modParE
%type<nodep> modItem modItemList modItemListE modOrGenItem %type<nodep> modItem modItemList modItemListE modOrGenItem
%type<nodep> genItem genItemList genItemBegin genItemBlock genTopBlock genCaseListE genCaseList %type<nodep> genItem genItemList genItemBegin genItemBlock genTopBlock genCaseListE genCaseList
%type<nodep> dlyTerm %type<nodep> dlyTerm
@@ -362,7 +368,7 @@ file: mod { }
//********************************************************************** //**********************************************************************
// Module headers // Module headers
mod: modHdr modParE modPortsE ';' modItemListE yENDMODULE mod: modHdr modParE modPortsE ';' modItemListE yENDMODULE endLabelE
{ $1->modTrace(V3Parse::s_trace); // Stash for implicit wires, etc { $1->modTrace(V3Parse::s_trace); // Stash for implicit wires, etc
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); } if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); if ($5) $1->addStmtp($5); }
; ;
@@ -375,12 +381,20 @@ modHdr: yMODULE { V3Parse::s_trace=v3Global.opt.trace();}
modParE: /* empty */ { $$ = NULL; } modParE: /* empty */ { $$ = NULL; }
| '#' '(' ')' { $$ = NULL; } | '#' '(' ')' { $$ = NULL; }
| '#' '(' modParList ')' { $$ = $3; } | '#' '(' modParArgs ')' { $$ = $3; }
| '#' '(' modParList ';' ')' { $$ = $3; }
; ;
modParList: modParDecl { $$ = $1; } modParArgs: modParDecl { $$ = $1; }
| modParList ';' modParDecl { $$ = $1->addNext($3); } | modParDecl ',' modParList { $$ = $1->addNext($3); }
;
modParList: modParSecond { $$ = $1; }
| modParList ',' modParSecond { $$ = $1->addNext($3); }
;
// Called only after a comma in a v2k list, to allow parsing "parameter a,b, parameter x"
modParSecond: modParDecl { $$ = $1; }
| param { $$ = $1; }
; ;
modPortsE: /* empty */ { $$ = NULL; } modPortsE: /* empty */ { $$ = NULL; }
@@ -440,7 +454,7 @@ varDecl: varRESET varReg varSignedE regrangeE regsigList ';' { $$ = $5; }
| varRESET varGenVar varSignedE regsigList ';' { $$ = $4; } | varRESET varGenVar varSignedE regsigList ';' { $$ = $4; }
; ;
modParDecl: varRESET varGParam varSignedE regrangeE paramList { $$ = $5; } /* No semicolon*/ modParDecl: varRESET varGParam varSignedE regrangeE param { $$ = $5; }
; ;
varRESET: /* empty */ { VARRESET(); } varRESET: /* empty */ { VARRESET(); }
@@ -537,8 +551,8 @@ genTopBlock: genItemList { $$ = $1; }
genItemBegin: yBEGIN genItemList yEND { $$ = new AstBegin($1,"genblk",$2); } genItemBegin: yBEGIN genItemList yEND { $$ = new AstBegin($1,"genblk",$2); }
| yBEGIN yEND { $$ = NULL; } | yBEGIN yEND { $$ = NULL; }
| yBEGIN ':' yaID genItemList yEND { $$ = new AstBegin($2,*$3,$4); } | yBEGIN ':' yaID genItemList yEND endLabelE { $$ = new AstBegin($2,*$3,$4); }
| yBEGIN ':' yaID yEND { $$ = NULL; } | yBEGIN ':' yaID yEND endLabelE { $$ = NULL; }
; ;
genItemList: genItem { $$ = $1; } genItemList: genItem { $$ = $1; }
@@ -755,8 +769,8 @@ senitemEdge: yPOSEDGE varRefDotBit { $$ = new AstSenItem($1,AstEdgeType::POSED
stmtBlock: stmt { $$ = $1; } stmtBlock: stmt { $$ = $1; }
| yBEGIN stmtList yEND { $$ = $2; } | yBEGIN stmtList yEND { $$ = $2; }
| yBEGIN yEND { $$ = NULL; } | yBEGIN yEND { $$ = NULL; }
| beginNamed stmtList yEND { $$ = $1; $1->addStmtp($2); } | beginNamed stmtList yEND endLabelE { $$ = $1; $1->addStmtp($2); }
| beginNamed yEND { $$ = $1; } | beginNamed yEND endLabelE { $$ = $1; }
; ;
beginNamed: yBEGIN ':' yaID varDeclList { $$ = new AstBegin($2,*$3,$4); } beginNamed: yBEGIN ':' yaID varDeclList { $$ = new AstBegin($2,*$3,$4); }
@@ -779,24 +793,24 @@ stmt: ';' { $$ = NULL; }
| '{' concIdList '}' '=' delayE expr ';' { $$ = new AstAssign($4,$2,$6); } | '{' concIdList '}' '=' delayE expr ';' { $$ = new AstAssign($4,$2,$6); }
| yD_C '(' cStrList ')' ';' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); } | yD_C '(' cStrList ')' ';' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
| yD_FCLOSE '(' varRefDotBit ')' ';' { $$ = new AstFClose($1, $3); } | yD_FCLOSE '(' varRefDotBit ')' ';' { $$ = new AstFClose($1, $3); }
| yD_FINISH ';' { $$ = new AstFinish($1); } | yD_FINISH parenE ';' { $$ = new AstFinish($1); }
| yD_STOP ';' { $$ = new AstStop($1); } | yD_STOP parenE ';' { $$ = new AstStop($1); }
| yVL_COVER_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_BLOCK_OFF); } | yVL_COVER_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_BLOCK_OFF); }
| stateCaseForIf { $$ = $1; } | stateCaseForIf { $$ = $1; }
| taskRef ';' { $$ = $1; } | taskRef ';' { $$ = $1; }
| yD_DISPLAY ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,"", NULL,NULL); } | yD_DISPLAY parenE ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,"", NULL,NULL); }
| yD_DISPLAY '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,*$3,NULL,$4); } | yD_DISPLAY '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,*$3,NULL,$4); }
| yD_WRITE '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WRITE, *$3,NULL,$4); } | yD_WRITE '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WRITE, *$3,NULL,$4); }
| yD_FDISPLAY '(' varRefDotBit ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,*$5,$3,$6); } | yD_FDISPLAY '(' varRefDotBit ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,*$5,$3,$6); }
| yD_FWRITE '(' varRefDotBit ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WRITE, *$5,$3,$6); } | yD_FWRITE '(' varRefDotBit ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WRITE, *$5,$3,$6); }
| yD_INFO ';' { $$ = new AstDisplay($1,AstDisplayType::INFO, "", NULL,NULL); } | yD_INFO parenE ';' { $$ = new AstDisplay($1,AstDisplayType::INFO, "", NULL,NULL); }
| yD_INFO '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::INFO, *$3,NULL,$4); } | yD_INFO '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::INFO, *$3,NULL,$4); }
| yD_WARNING ';' { $$ = new AstDisplay($1,AstDisplayType::WARNING,"", NULL,NULL); } | yD_WARNING parenE ';' { $$ = new AstDisplay($1,AstDisplayType::WARNING,"", NULL,NULL); }
| yD_WARNING '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WARNING,*$3,NULL,$4); } | yD_WARNING '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WARNING,*$3,NULL,$4); }
| yD_ERROR ';' { $$ = V3Parse::createDisplayError($1); } | yD_ERROR parenE ';' { $$ = V3Parse::createDisplayError($1); }
| yD_ERROR '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); } | yD_ERROR '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::ERROR, *$3,NULL,$4); $$->addNext(new AstStop($1)); }
| yD_FATAL ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); } | yD_FATAL parenE ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); }
| yD_FATAL '(' expr ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); } | yD_FATAL '(' expr ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); }
| yD_FATAL '(' expr ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); } | yD_FATAL '(' expr ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); }
@@ -858,13 +872,14 @@ taskRef: idDotted { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileli
funcRef: idDotted '(' exprList ')' { $$ = new AstFuncRef($2,new AstParseRef($1->fileline(), AstParseRefExp::FUNC, $1), $3); } funcRef: idDotted '(' exprList ')' { $$ = new AstFuncRef($2,new AstParseRef($1->fileline(), AstParseRefExp::FUNC, $1), $3); }
; ;
taskDecl: yTASK taskAutoE yaID funcGuts yENDTASK { $$ = new AstTask ($1,*$3,$4);} taskDecl: yTASK taskAutoE yaID funcGuts yENDTASK endLabelE
{ $$ = new AstTask ($1,*$3,$4);}
; ;
funcDecl: yFUNCTION taskAutoE funcTypeE yaID funcGuts yENDFUNCTION { $$ = new AstFunc ($1,*$4,$5,$3); } funcDecl: yFUNCTION taskAutoE funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$5,$3); }
| yFUNCTION taskAutoE ySIGNED funcTypeE yaID funcGuts yENDFUNCTION { $$ = new AstFunc ($1,*$5,$6,$4); $$->isSigned(true); } | yFUNCTION taskAutoE ySIGNED funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$6,$4); $$->isSigned(true); }
| yFUNCTION taskAutoE funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION { $$ = new AstFunc ($1,*$4,$6,$3); $$->attrIsolateAssign(true);} | yFUNCTION taskAutoE funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$6,$3); $$->attrIsolateAssign(true);}
| yFUNCTION taskAutoE ySIGNED funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION { $$ = new AstFunc ($1,*$5,$7,$4); $$->attrIsolateAssign(true); $$->isSigned(true); } | yFUNCTION taskAutoE ySIGNED funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$7,$4); $$->attrIsolateAssign(true); $$->isSigned(true); }
; ;
taskAutoE: /* empty */ { } taskAutoE: /* empty */ { }
@@ -894,6 +909,10 @@ funcVar: ioDecl { $$ = $1; }
| yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); } | yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); }
; ;
parenE: /* empty */ { }
| '(' ')' { }
;
//************************************************ //************************************************
// Expressions // Expressions
@@ -912,6 +931,8 @@ exprNoStr: expr yP_OROR expr { $$ = new AstLogOr ($2,$1,$3); }
| expr yP_NOTEQUAL expr { $$ = new AstNeq ($2,$1,$3); } | expr yP_NOTEQUAL expr { $$ = new AstNeq ($2,$1,$3); }
| expr yP_CASEEQUAL expr { $$ = new AstEqCase ($2,$1,$3); } | expr yP_CASEEQUAL expr { $$ = new AstEqCase ($2,$1,$3); }
| expr yP_CASENOTEQUAL expr { $$ = new AstNeqCase ($2,$1,$3); } | expr yP_CASENOTEQUAL expr { $$ = new AstNeqCase ($2,$1,$3); }
| expr yP_WILDEQUAL expr { $$ = new AstEqWild ($2,$1,$3); }
| expr yP_WILDNOTEQUAL expr { $$ = new AstNeqWild ($2,$1,$3); }
| expr '>' expr { $$ = new AstGt ($2,$1,$3); } | expr '>' expr { $$ = new AstGt ($2,$1,$3); }
| expr '<' expr { $$ = new AstLt ($2,$1,$3); } | expr '<' expr { $$ = new AstLt ($2,$1,$3); }
| expr yP_GTE expr { $$ = new AstGte ($2,$1,$3); } | expr yP_GTE expr { $$ = new AstGte ($2,$1,$3); }
@@ -925,7 +946,7 @@ exprNoStr: expr yP_OROR expr { $$ = new AstLogOr ($2,$1,$3); }
| expr '/' expr { $$ = new AstDiv ($2,$1,$3); } | expr '/' expr { $$ = new AstDiv ($2,$1,$3); }
| expr '%' expr { $$ = new AstModDiv ($2,$1,$3); } | expr '%' expr { $$ = new AstModDiv ($2,$1,$3); }
| expr yP_POW expr { $$ = new AstPow ($2,$1,$3); } | expr yP_POW expr { $$ = new AstPow ($2,$1,$3); }
| expr yP_LOGIF expr { $$ = new AstLogIf ($2,$1,$3); } | expr yP_MINUSGT expr { $$ = new AstLogIf ($2,$1,$3); }
| expr yP_LOGIFF expr { $$ = new AstLogIff ($2,$1,$3); } | expr yP_LOGIFF expr { $$ = new AstLogIff ($2,$1,$3); }
| '-' expr %prec prUNARYARITH { $$ = new AstUnaryMin ($1,$2); } | '-' expr %prec prUNARYARITH { $$ = new AstUnaryMin ($1,$2); }
@@ -1104,18 +1125,22 @@ specifyJunk: dlyTerm {} /* ignored */
| yP_ANDAND {} | yP_GTE {} | yP_LTE {} | yP_ANDAND {} | yP_GTE {} | yP_LTE {}
| yP_EQUAL {} | yP_NOTEQUAL {} | yP_EQUAL {} | yP_NOTEQUAL {}
| yP_CASEEQUAL {} | yP_CASENOTEQUAL {} | yP_CASEEQUAL {} | yP_CASENOTEQUAL {}
| yP_WILDEQUAL {} | yP_WILDNOTEQUAL {}
| yP_XNOR {} | yP_NOR {} | yP_NAND {} | yP_XNOR {} | yP_NOR {} | yP_NAND {}
| yP_OROR {} | yP_OROR {}
| yP_SLEFT {} | yP_SRIGHT {} | yP_SSRIGHT {} | yP_SLEFT {} | yP_SRIGHT {} | yP_SSRIGHT {}
| yP_PLUSCOLON {} | yP_MINUSCOLON {} | yP_PLUSCOLON {} | yP_MINUSCOLON {}
| yP_POW {} | yP_POW {}
| yP_LOGIF {} | yP_MINUSGT {}
| yP_LOGIFF {} | yP_LOGIFF {}
| yPSL_BRA {} | yPSL_BRA {}
| yPSL_KET {} | yPSL_KET {}
| yP_OR_MINUS_GT {} | yP_OR_MINUS_GT {}
| yP_OR_EQ_GT {} | yP_OR_EQ_GT {}
| yP_EQGT {} | yP_ASTGT {}
| yP_PLUSEQGT {} | yP_PLUSASTGT {}
| yP_MINUSEQGT {} | yP_MINUSASTGT {}
| error {} | error {}
; ;
@@ -1159,6 +1184,10 @@ concIdList: varRefDotBit { $$ = $1; }
| concIdList ',' varRefDotBit { $$ = new AstConcat($2,$1,$3); } | concIdList ',' varRefDotBit { $$ = new AstConcat($2,$1,$3); }
; ;
endLabelE: /* empty */ { }
| ':' yaID { }
;
//************************************************ //************************************************
// Asserts // Asserts
+1 -1
View File
@@ -44,7 +44,7 @@ module t;
reg [31:0] flocal; reg [31:0] flocal;
flocal = 1; flocal = 1;
global = global + flocal; global = global + flocal;
end end : named // SystemVerilog end labels
end end
endfunction endfunction
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# $Id$
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# General Public License or the Perl Artistic License.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;
+81
View File
@@ -0,0 +1,81 @@
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2007 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc=0;
reg [63:0] crc;
reg [63:0] sum;
// Take CRC data and apply to testblock inputs
wire [31:0] in = crc[31:0];
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [3:0] out; // From test of Test.v
// End of automatics
Test test (/*AUTOINST*/
// Outputs
.out (out[3:0]),
// Inputs
.clk (clk),
.in (in[31:0]));
// Aggregate outputs into a single result vector
wire [63:0] result = {60'h0, out};
// What checksum will we end up with
`define EXPECTED_SUM 64'h1a0d07009b6a30d2
// Test loop
always @ (posedge clk) begin
`ifdef TEST_VERBOSE
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
`endif
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
if (cyc==0) begin
// Setup
crc <= 64'h5aef0c8d_d70a4497;
end
else if (cyc<10) begin
sum <= 64'h0;
end
else if (cyc<90) begin
end
else if (cyc==99) begin
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
if (crc !== 64'hc77bb9b3784ea091) $stop;
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module Test (/*AUTOARG*/
// Outputs
out,
// Inputs
clk, in
);
input clk;
input [31:0] in;
output [3:0] out;
assign out[0] = in[3:0] ==? 4'b1001;
assign out[1] = in[3:0] !=? 4'b1001;
assign out[2] = in[3:0] ==? 4'bx01x;
assign out[3] = in[3:0] !=? 4'bx01x;
endmodule
+9 -13
View File
@@ -1,4 +1,4 @@
// $Id:$ // $Id$
// DESCRIPTION: Verilator: Verilog Test module // DESCRIPTION: Verilator: Verilog Test module
// //
// This file ONLY is placed into the Public Domain, for any use, // This file ONLY is placed into the Public Domain, for any use,
@@ -11,7 +11,10 @@ module t (/*AUTOARG*/
parameter PAR = 3; parameter PAR = 3;
input clk; input clk;
`ifdef verilator
// Else it becomes a localparam, per IEEE 4.10.1, but we don't check it
defparam m3.FROMDEFP = 19; defparam m3.FROMDEFP = 19;
`endif
m3 #(.P3(PAR), m3 #(.P3(PAR),
.P2(2)) .P2(2))
@@ -29,14 +32,12 @@ module t (/*AUTOARG*/
endmodule endmodule
module m3 module m3
`ifdef verilator
#( #(
parameter UNCH = 99; parameter UNCH = 99,
parameter P1 = 10; parameter P1 = 10,
parameter P2 = 20, parameter P2 = 20,
P3 = 30; P3 = 30
) )
`endif
(/*AUTOARG*/ (/*AUTOARG*/
// Inputs // Inputs
clk clk
@@ -44,13 +45,6 @@ module m3
input clk; input clk;
localparam LOC = 13; localparam LOC = 13;
`ifndef verilator // Vcs not compliant yet
parameter UNCH = 99;
parameter P1 = 10;
parameter P2 = 20;
parameter P3 = 30;
`endif
parameter FROMDEFP = 11; parameter FROMDEFP = 11;
initial begin initial begin
@@ -61,6 +55,8 @@ module m3
if (P1 !== 10) $stop; if (P1 !== 10) $stop;
if (P2 !== 2) $stop; if (P2 !== 2) $stop;
if (P3 !== 3) $stop; if (P3 !== 3) $stop;
`ifdef verilator
if (FROMDEFP !== 19) $stop; if (FROMDEFP !== 19) $stop;
`endif
end end
endmodule endmodule
+1 -9
View File
@@ -1,4 +1,3 @@
`line 1 "t/t_preproc.v" 1 `line 1 "t/t_preproc.v" 1
@@ -10,7 +9,6 @@
`line 9 "t/t_preproc.v" 0 `line 9 "t/t_preproc.v" 0
`line 1 "t/t_preproc_inc2.v" 1 `line 1 "t/t_preproc_inc2.v" 1
@@ -19,9 +17,7 @@ At file t/t_preproc_inc2.v line 4
`line 6 "t/t_preproc_inc2.v" 0 `line 6 "t/t_preproc_inc2.v" 0
`line 1 "t/t_preproc_inc3.v" 1 `line 1 "t/t_preproc_inc3.v" 1
`line 2 "inc3_a_filename_from_line_directive" 0 `line 2 "inc3_a_filename_from_line_directive" 0
@@ -43,14 +39,10 @@ At file t/t_preproc_inc2.v line 4
`line 17 "inc3_a_filename_from_line_directive" 0 `line 17 "inc3_a_filename_from_line_directive" 0
`line 18 "inc3_a_filename_from_line_directive" 2 `line 18 "inc3_a_filename_from_line_directive" 2
`line 6 "t/t_preproc_inc2.v" 0 `line 6 "t/t_preproc_inc2.v" 0
`line 7 "t/t_preproc_inc2.v" 2 `line 7 "t/t_preproc_inc2.v" 2
`line 9 "t/t_preproc.v" 0 `line 9 "t/t_preproc.v" 0
@@ -150,4 +142,4 @@ $display( "left side: \" right side\"" )
`line 95 "t/t_preproc.v" 0 `line 95 "t/t_preproc.v" 0
Line_Preproc_Check 96 Line_Preproc_Check 96
`line 97 "t/t_preproc.v" 2
+1 -2
View File
@@ -1,4 +1,3 @@
`line 1 "t/t_preproc_psl.v" 1 `line 1 "t/t_preproc_psl.v" 1
@@ -74,4 +73,4 @@ psl assert always sig!=90;
72 72
`line 73 "t/t_preproc_psl.v" 2
+1 -2
View File
@@ -1,4 +1,3 @@
`line 1 "t/t_preproc_psl.v" 1 `line 1 "t/t_preproc_psl.v" 1
@@ -74,4 +73,4 @@ psl assert always sig!=90;
72 72
`line 73 "t/t_preproc_psl.v" 2