mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a77b58dba9 | ||
|
|
c300ab6dd9 | ||
|
|
9ac0f1accb | ||
|
|
7990e5d4b1 | ||
|
|
fb2cb3c49d | ||
|
|
c4b1bc2506 | ||
|
|
551393d443 | ||
|
|
79d305f3e8 | ||
|
|
822956e769 | ||
|
|
a681a6a6d5 | ||
|
|
5f6d69affd |
@@ -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
@@ -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
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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 ");
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Executable
+18
@@ -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;
|
||||||
@@ -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
|
||||||
@@ -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,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,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,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
|
||||||
|
|||||||
Reference in New Issue
Block a user