Fix SystemVerilog parameterized defines and whitespace
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1013 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
parent
f6fb2362c6
commit
a16477d84f
3
Changes
3
Changes
|
@ -7,6 +7,9 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
*** Add --top-module option to select between multiple tops. [Stefan Thiede]
|
||||
|
||||
**** Fix SystemVerilog parameterized defines with `` expansion,
|
||||
and fix extra whitespace inserted on substitution. [Vladimir Matveyenko]
|
||||
|
||||
**** Fix no-module include files on command line. [Stefan Thiede]
|
||||
|
||||
**** Fix dropping of backslash quoted-quote at end of $display.
|
||||
|
|
|
@ -133,9 +133,9 @@ class V3PreLex {
|
|||
void lineDirective(const char* text);
|
||||
void incLineno() { m_curFilelinep->incLineno(); }
|
||||
// Called by V3PreProc.cpp to inform lexer
|
||||
void setStateDefArg();
|
||||
void setStateDefValue();
|
||||
void setStateIncFilename();
|
||||
void pushStateDefArg();
|
||||
void pushStateDefValue();
|
||||
void pushStateIncFilename();
|
||||
void unputString(const char* textp);
|
||||
};
|
||||
|
||||
|
|
|
@ -140,14 +140,25 @@ psl [p]sl
|
|||
<ARGMODE><<EOF>> { yyerror("EOF in define argument list\n"); yyleng = 0; yyterminate(); }
|
||||
<ARGMODE>{crnl} { linenoInc(); yytext="\n"; yyleng=1; return(VP_WHITE); }
|
||||
<ARGMODE>{quote} { yy_push_state(STRMODE); yymore(); }
|
||||
<ARGMODE>[(] { V3PreLex::s_currentLexp->m_parenLevel++; appendDefValue(yytext,yyleng); }
|
||||
<ARGMODE>[,)] { if (V3PreLex::s_currentLexp->m_parenLevel>1) {
|
||||
<ARGMODE>[(] { V3PreLex::s_currentLexp->m_parenLevel++;
|
||||
if (V3PreLex::s_currentLexp->m_parenLevel>1) {
|
||||
appendDefValue(yytext,yyleng);
|
||||
if (yytext[0]==')') V3PreLex::s_currentLexp->m_parenLevel--;
|
||||
} else {
|
||||
unput(yytext[0]); yy_pop_state(); return (VP_DEFARG);
|
||||
return (VP_TEXT);
|
||||
}}
|
||||
<ARGMODE>[^\/\*\n\r\\(,)\"]+ |
|
||||
<ARGMODE>[)] { V3PreLex::s_currentLexp->m_parenLevel--;
|
||||
if (V3PreLex::s_currentLexp->m_parenLevel>0) {
|
||||
appendDefValue(yytext,yyleng);
|
||||
} else {
|
||||
yy_pop_state(); return (VP_DEFARG);
|
||||
}}
|
||||
<ARGMODE>[,] { if (V3PreLex::s_currentLexp->m_parenLevel>1) {
|
||||
appendDefValue(yytext,yyleng);
|
||||
} else {
|
||||
yy_pop_state(); return (VP_DEFARG);
|
||||
}}
|
||||
<ARGMODE>"`"{symb} { return (VP_DEFREF); } /* defref in defref */
|
||||
<ARGMODE>[^\/\*\n\r\\(,)\"`]+ |
|
||||
<ARGMODE>. { appendDefValue(yytext,yyleng); }
|
||||
|
||||
/* One line comments. */
|
||||
|
@ -199,21 +210,21 @@ psl [p]sl
|
|||
<INITIAL,PSLMULM,PSLONEM>. { return (VP_TEXT); }
|
||||
%%
|
||||
|
||||
void V3PreLex::setStateDefArg() {
|
||||
void V3PreLex::pushStateDefArg() {
|
||||
// Enter define substitution argument state
|
||||
yy_push_state(ARGMODE);
|
||||
m_parenLevel = 1;
|
||||
m_parenLevel = 0;
|
||||
m_defValue = "";
|
||||
}
|
||||
|
||||
void V3PreLex::setStateDefValue() {
|
||||
void V3PreLex::pushStateDefValue() {
|
||||
// Enter define value state
|
||||
yy_push_state(DEFMODE);
|
||||
m_parenLevel = 0;
|
||||
m_defValue = "";
|
||||
}
|
||||
|
||||
void V3PreLex::setStateIncFilename() {
|
||||
void V3PreLex::pushStateIncFilename() {
|
||||
// Enter include <> filename state
|
||||
yy_push_state(INCMODE);
|
||||
yymore();
|
||||
|
|
|
@ -61,6 +61,28 @@ public:
|
|||
string params() const { return m_params; }
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
class V3DefineRef {
|
||||
// One for each pending define substitution
|
||||
string m_name; // Define last name being defined
|
||||
string m_params; // Define parameter list for next expansion
|
||||
string m_nextarg; // String being built for next argument
|
||||
int m_parenLevel; // Parenthesis counting inside def args
|
||||
|
||||
vector<string> m_args; // List of define arguments
|
||||
public:
|
||||
string name() const { return m_name; }
|
||||
string params() const { return m_params; }
|
||||
string nextarg() const { return m_nextarg; }
|
||||
void nextarg(const string& value) { m_nextarg = value; }
|
||||
int parenLevel() const { return m_parenLevel; }
|
||||
vector<string>& args() { return m_args; }
|
||||
V3DefineRef(const string& name, const string& params, int pl)
|
||||
: m_name(name), m_params(params), m_parenLevel(pl) {}
|
||||
~V3DefineRef() {}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
// Data for a preprocessor instantiation.
|
||||
|
||||
|
@ -88,14 +110,12 @@ struct V3PreProcImp : public V3PreProc {
|
|||
bool m_rawAtBol; ///< Last rawToken left us at beginning of line
|
||||
|
||||
// For defines
|
||||
string m_defName; // Define last name being defined
|
||||
string m_defParams; // Define parameter list for next expansion
|
||||
stack<V3DefineRef> m_defRefs; // Pending definine substitution
|
||||
stack<bool> m_ifdefStack; // Stack of true/false emitting evaluations
|
||||
vector<string> m_defArgs; // List of define arguments
|
||||
unsigned m_defDepth; // How many `defines deep
|
||||
|
||||
// Defines list
|
||||
DefinesMap m_defines; // Map of defines
|
||||
DefinesMap m_defines; // Map of defines
|
||||
|
||||
// For getline()
|
||||
string m_lineChars; // Characters left for next line
|
||||
|
@ -113,7 +133,7 @@ struct V3PreProcImp : public V3PreProc {
|
|||
private:
|
||||
// Internal methods
|
||||
void eof();
|
||||
string defineSubst();
|
||||
string defineSubst(V3DefineRef* refp);
|
||||
void addLineComment(int enter_exit_level);
|
||||
|
||||
bool defExists(const string& name);
|
||||
|
@ -122,6 +142,7 @@ private:
|
|||
FileLine* defFileline(const string& name);
|
||||
|
||||
bool commentTokenMatch(string& cmdr, const char* strg);
|
||||
string trimWhitespace(const string& strg);
|
||||
|
||||
void parsingOn() {
|
||||
m_off--;
|
||||
|
@ -149,7 +170,6 @@ public:
|
|||
V3PreProcImp(FileLine* fl) : V3PreProc(fl) {
|
||||
m_lexp = NULL; // Closed.
|
||||
m_state = ps_TOP;
|
||||
m_defName = "";
|
||||
m_off = 0;
|
||||
m_lineChars = "";
|
||||
m_lastSym = "";
|
||||
|
@ -348,7 +368,15 @@ const char* V3PreProcImp::tokenName(int tok) {
|
|||
}
|
||||
}
|
||||
|
||||
string V3PreProcImp::defineSubst() {
|
||||
string V3PreProcImp::trimWhitespace(const string& strg) {
|
||||
string out = strg;
|
||||
while (out.length()>0 && isspace(out[0])) {
|
||||
out.erase(0,1);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
string V3PreProcImp::defineSubst(V3DefineRef* refp) {
|
||||
// Substitute out defines in a argumented define reference.
|
||||
// We could push the define text back into the lexer, but that's slow
|
||||
// and would make recursive definitions and parameter handling nasty.
|
||||
|
@ -356,25 +384,27 @@ string V3PreProcImp::defineSubst() {
|
|||
// Note we parse the definition parameters and value here. If a
|
||||
// parameterized define is used many, many times, we could cache the
|
||||
// parsed result.
|
||||
UINFO(4,"defineSubstIn `"<<m_defName<<" "<<m_defParams<<endl);
|
||||
for (unsigned i=0; i<m_defArgs.size(); i++) {
|
||||
UINFO(4,"defineArg["<<i<<"] = "<<m_defArgs[i]<<endl);
|
||||
UINFO(4,"defineSubstIn `"<<refp->name()<<" "<<refp->params()<<endl);
|
||||
for (unsigned i=0; i<refp->args().size(); i++) {
|
||||
UINFO(4,"defineArg["<<i<<"] = "<<refp->args()[i]<<endl);
|
||||
}
|
||||
// Grab value
|
||||
string value = defValue(m_defName);
|
||||
UINFO(4,"defineValue `"<<value<<endl);
|
||||
string value = defValue(refp->name());
|
||||
UINFO(4,"defineValue '"<<value<<"'"<<endl);
|
||||
|
||||
map<string,string> argValueByName;
|
||||
{ // Parse argument list into map
|
||||
unsigned numArgs=0;
|
||||
string argName;
|
||||
for (const char* cp=m_defParams.c_str(); *cp; cp++) {
|
||||
for (const char* cp=refp->params().c_str(); *cp; cp++) {
|
||||
if (*cp=='(') {
|
||||
} else if (argName=="" && isspace(*cp)) {
|
||||
} else if (isspace(*cp) || *cp==')' || *cp==',') {
|
||||
if (argName!="") {
|
||||
if (m_defArgs.size() >= numArgs) {
|
||||
argValueByName[argName] = m_defArgs[numArgs];
|
||||
if (refp->args().size() > numArgs) {
|
||||
// A call `def( a ) must be equivelent to `def(a ), so trimWhitespace
|
||||
// Note other sims don't trim trailing whitespace, so we don't either.
|
||||
argValueByName[argName] = trimWhitespace(refp->args()[numArgs]);
|
||||
}
|
||||
numArgs++;
|
||||
//cout << " arg "<<argName<<endl;
|
||||
|
@ -385,13 +415,13 @@ string V3PreProcImp::defineSubst() {
|
|||
argName += *cp;
|
||||
}
|
||||
}
|
||||
if (m_defArgs.size() != numArgs) {
|
||||
fileline()->v3error("Define passed wrong number of arguments: "+m_defName+"\n");
|
||||
return " `"+m_defName+" ";
|
||||
if (refp->args().size() != numArgs) {
|
||||
fileline()->v3error("Define passed wrong number of arguments: "+refp->name()+"\n");
|
||||
return " `"+refp->name()+" ";
|
||||
}
|
||||
}
|
||||
|
||||
string out = " ";
|
||||
string out = "";
|
||||
{ // Parse substitution define using arguments
|
||||
string argName;
|
||||
string prev;
|
||||
|
@ -447,8 +477,7 @@ string V3PreProcImp::defineSubst() {
|
|||
}
|
||||
}
|
||||
|
||||
out += " ";
|
||||
UINFO(4,"defineSubstOut "<<out<<endl);
|
||||
UINFO(4,"defineSubstOut '"<<out<<"'"<<endl);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -565,8 +594,9 @@ int V3PreProcImp::getRawToken() {
|
|||
string::size_type pos;
|
||||
while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); }
|
||||
while ((pos=buf.find("\r")) != string::npos) { buf.replace(pos, 1, "\\r"); }
|
||||
fprintf (stderr, "%d: RAW %d %d: %-10s: %s\n",
|
||||
fileline()->lineno(), m_off, m_state, tokenName(tok), buf.c_str());
|
||||
fprintf (stderr, "%d: RAW %s s%d dr%d: %-10s: %s\n",
|
||||
fileline()->lineno(), m_off?"of":"on", m_state, m_defRefs.size(),
|
||||
tokenName(tok), buf.c_str());
|
||||
}
|
||||
|
||||
// On EOF, try to pop to upper level includes, as needed.
|
||||
|
@ -651,7 +681,7 @@ int V3PreProcImp::getToken() {
|
|||
else if (m_stateFor==VP_DEFINE) {
|
||||
// m_lastSym already set.
|
||||
m_state = ps_DEFVALUE;
|
||||
m_lexp->setStateDefValue();
|
||||
m_lexp->pushStateDefValue();
|
||||
}
|
||||
else fileline()->v3fatalSrc("Bad case\n");
|
||||
goto next_tok;
|
||||
|
@ -698,7 +728,7 @@ int V3PreProcImp::getToken() {
|
|||
&& isspace(m_lexp->m_defValue[m_lexp->m_defValue.length()-1-trailspace])) trailspace++;
|
||||
if (trailspace) m_lexp->m_defValue.erase(m_lexp->m_defValue.length()-trailspace,trailspace);
|
||||
// Define it
|
||||
UINFO(4,"Define "<<m_lastSym<<" = "<<m_lexp->m_defValue<<endl);
|
||||
UINFO(4,"Define "<<m_lastSym<<" = '"<<m_lexp->m_defValue<<"'"<<endl);
|
||||
define(fileline(), m_lastSym, m_lexp->m_defValue, params);
|
||||
}
|
||||
} else {
|
||||
|
@ -712,40 +742,57 @@ int V3PreProcImp::getToken() {
|
|||
}
|
||||
case ps_DEFPAREN: {
|
||||
if (tok==VP_TEXT && yyleng==1 && yytext[0]=='(') {
|
||||
m_defArgs.clear();
|
||||
m_state = ps_DEFARG;
|
||||
m_lexp->setStateDefArg();
|
||||
goto next_tok;
|
||||
} else {
|
||||
m_state = ps_TOP;
|
||||
fileline()->v3error("Expecting ( to begin argument list for define reference `"<<m_defName);
|
||||
if (m_defRefs.empty()) v3fatalSrc("Shouldn't be in DEFPAREN w/o active defref");
|
||||
V3DefineRef* refp = &(m_defRefs.top());
|
||||
fileline()->v3error("Expecting ( to begin argument list for define reference `"<<refp->name());
|
||||
goto next_tok;
|
||||
}
|
||||
}
|
||||
case ps_DEFARG: {
|
||||
if (tok==VP_DEFARG) {
|
||||
UINFO(4," Defarg "<<m_defName<<" arg="<<m_lexp->m_defValue<<endl);
|
||||
goto next_tok; // Next is a , or )
|
||||
} else if (tok==VP_TEXT && yyleng==1 && yytext[0]==',') {
|
||||
m_defArgs.push_back(m_lexp->m_defValue);
|
||||
if (m_defRefs.empty()) v3fatalSrc("Shouldn't be in DEFARG w/o active defref");
|
||||
V3DefineRef* refp = &(m_defRefs.top());
|
||||
refp->nextarg(refp->nextarg()+m_lexp->m_defValue); m_lexp->m_defValue="";
|
||||
if (tok==VP_DEFARG && yyleng==1 && yytext[0]==',') {
|
||||
refp->args().push_back(refp->nextarg());
|
||||
m_state = ps_DEFARG;
|
||||
m_lexp->setStateDefArg();
|
||||
m_lexp->pushStateDefArg();
|
||||
refp->nextarg("");
|
||||
goto next_tok;
|
||||
} else if (tok==VP_TEXT && yyleng==1 && yytext[0]==')') {
|
||||
m_defArgs.push_back(m_lexp->m_defValue);
|
||||
string out = defineSubst();
|
||||
m_lexp->m_parenLevel = 0;
|
||||
} else if (tok==VP_DEFARG && yyleng==1 && yytext[0]==')') {
|
||||
refp->args().push_back(refp->nextarg());
|
||||
string out = defineSubst(refp);
|
||||
// Substitute in and prepare for next action
|
||||
// Similar code in non-parenthesized define (Search for END_OF_DEFARG)
|
||||
m_defRefs.pop();
|
||||
m_lexp->unputString(out.c_str());
|
||||
// Prepare for next action
|
||||
m_defArgs.clear();
|
||||
m_state = ps_TOP;
|
||||
if (m_defRefs.empty()) {
|
||||
m_state = ps_TOP;
|
||||
m_lexp->m_parenLevel = 0;
|
||||
}
|
||||
else { // Finished a defref inside a upper defref
|
||||
refp = &(m_defRefs.top()); // We popped, so new top
|
||||
m_lexp->m_parenLevel = refp->parenLevel();
|
||||
m_state = ps_DEFARG;
|
||||
}
|
||||
goto next_tok;
|
||||
} else if (tok==VP_DEFREF) {
|
||||
// Expand it, then state will come back here
|
||||
// Value of building argument is data before the lower defref
|
||||
// we'll append it when we push the argument.
|
||||
break;
|
||||
} else if (tok==VP_SYMBOL || tok==VP_STRING || VP_TEXT || VP_WHITE || VP_PSL) {
|
||||
string rtn; rtn.assign(yytext,yyleng);
|
||||
refp->nextarg(refp->nextarg()+rtn);
|
||||
goto next_tok;
|
||||
} else {
|
||||
fileline()->v3error("Expecting ) or , to end argument list for define reference. Found: "<<tokenName(tok));
|
||||
m_state = ps_TOP;
|
||||
goto next_tok;
|
||||
}
|
||||
goto next_tok;
|
||||
}
|
||||
case ps_INCNAME: {
|
||||
if (tok==VP_STRING) {
|
||||
|
@ -763,7 +810,7 @@ int V3PreProcImp::getToken() {
|
|||
else if (tok==VP_TEXT && yyleng==1 && yytext[0]=='<') {
|
||||
// include <filename>
|
||||
m_state = ps_INCNAME; // Still
|
||||
m_lexp->setStateIncFilename();
|
||||
m_lexp->pushStateIncFilename();
|
||||
goto next_tok;
|
||||
}
|
||||
else if (tok==VP_DEFREF) {
|
||||
|
@ -844,18 +891,17 @@ int V3PreProcImp::getToken() {
|
|||
else {
|
||||
string params = defParams(name);
|
||||
if (params=="0" || params=="") { // Found, as simple substitution
|
||||
// Pack spaces around the define value, as there must be token boundaries around it.
|
||||
// It also makes it more obvious where defines got substituted.
|
||||
string out = " "+defValue(name)+" ";
|
||||
UINFO(4,"Defref `"<<name<<" => "<<out<<endl);
|
||||
string out = defValue(name);
|
||||
UINFO(4,"Defref `"<<name<<" => '"<<out<<"'"<<endl);
|
||||
// Similar code in parenthesized define (Search for END_OF_DEFARG)
|
||||
m_lexp->unputString(out.c_str());
|
||||
goto next_tok;
|
||||
}
|
||||
else { // Found, with parameters
|
||||
UINFO(4,"Defref `"<<name<<" => parameterized"<<endl);
|
||||
m_defName = name;
|
||||
m_defParams = params;
|
||||
m_defRefs.push(V3DefineRef(name, params, m_lexp->m_parenLevel));
|
||||
m_state = ps_DEFPAREN; m_stateFor = tok;
|
||||
m_lexp->pushStateDefArg();
|
||||
goto next_tok;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id: t_delay.pl 965 2007-10-31 20:29:07Z wsnyder $
|
||||
# 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,
|
||||
expect=>quotemeta(
|
||||
'pre thrupre thrumid thrupost post: "right side"
|
||||
left side: "right side"
|
||||
left side : "right side "
|
||||
left_side : "left_side "
|
||||
na : "left_side "
|
||||
prep ( midp1 left_side midp2 ( outp ) ) : "left_side "
|
||||
na: "nana"
|
||||
left_side left_side : "left_side left_side "
|
||||
: ""
|
||||
left side: "right side"
|
||||
left side : "right side "
|
||||
twoline: "first second"
|
||||
*-* All Finished *-*
|
||||
'));
|
||||
|
||||
ok(1);
|
||||
1;
|
|
@ -0,0 +1,56 @@
|
|||
// $Id: t_delay.v 965 2007-10-31 20:29:07Z wsnyder $
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
wire d1 = 1'b1;
|
||||
wire d2 = 1'b1;
|
||||
wire d3 = 1'b1;
|
||||
wire o1,o2,o3;
|
||||
add1 add1 (d1,o1);
|
||||
add2 add2 (d2,o2);
|
||||
|
||||
`define ls left_side
|
||||
`define rs left_side
|
||||
`define noarg na
|
||||
`define thru(x) x
|
||||
`define thruthru `ls `rs // Doesn't expand
|
||||
`define msg(x,y) `"x: `\`"y`\`"`"
|
||||
initial begin
|
||||
//$display(`msg( \`, \`)); // Illegal
|
||||
$display(`msg(pre `thru(thrupre `thru(thrumid) thrupost) post,right side));
|
||||
$display(`msg(left side,right side));
|
||||
$display(`msg( left side , right side ));
|
||||
$display(`msg( `ls , `rs ));
|
||||
$display(`msg( `noarg , `rs ));
|
||||
$display(`msg( prep ( midp1 `ls midp2 ( outp ) ) , `rs ));
|
||||
$display(`msg(`noarg,`noarg`noarg));
|
||||
$display(`msg( `thruthru , `thruthru )); // Results vary between simulators
|
||||
$display(`msg(`thru(),)); // Empty
|
||||
$display(`msg(`thru(left side),`thru(right side)));
|
||||
$display(`msg( `thru( left side ) , `thru( right side ) ));
|
||||
|
||||
`define twoline first \
|
||||
second
|
||||
$display(`msg(twoline, `twoline));
|
||||
|
||||
//$display(`msg(left side, \ right side \ )); // Not sure \{space} is legal.
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
||||
`define ADD_UP(a,c) \
|
||||
wire tmp_``a = a; \
|
||||
wire tmp_``c = tmp_``a + 1; \
|
||||
assign c = tmp_``c ;
|
||||
|
||||
module add1 ( input wire d1, output wire o1);
|
||||
`ADD_UP(d1,o1) // expansion is OK
|
||||
endmodule
|
||||
module add2 ( input wire d2, output wire o2);
|
||||
`ADD_UP( d2 , o2 ) // expansion is bad
|
||||
endmodule
|
||||
// `ADD_UP( \d3 , \o3 ) // This really is illegal
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
At file t/t_preproc_inc2.v line 4
|
||||
|
||||
|
||||
|
||||
`line 6 "t/t_preproc_inc2.v" 0
|
||||
`line 1 "t/t_preproc_inc3.v" 1
|
||||
`line 2 "inc3_a_filename_from_line_directive" 0
|
||||
|
@ -41,7 +41,7 @@ At file t/t_preproc_inc2.v line 4
|
|||
|
||||
`line 18 "inc3_a_filename_from_line_directive" 2
|
||||
`line 6 "t/t_preproc_inc2.v" 0
|
||||
|
||||
|
||||
`line 7 "t/t_preproc_inc2.v" 2
|
||||
`line 9 "t/t_preproc.v" 0
|
||||
|
||||
|
@ -78,8 +78,8 @@ text.
|
|||
|
||||
|
||||
|
||||
foo bar
|
||||
foobar2
|
||||
foo bar
|
||||
foobar2
|
||||
|
||||
|
||||
|
||||
|
@ -91,7 +91,7 @@ text.
|
|||
|
||||
|
||||
|
||||
first part second part third part
|
||||
first part second part third part
|
||||
Line_Preproc_Check 49
|
||||
|
||||
|
||||
|
@ -100,37 +100,46 @@ Line_Preproc_Check 49
|
|||
|
||||
|
||||
|
||||
deep deep
|
||||
deep deep
|
||||
|
||||
|
||||
|
||||
"Inside: `nosubst"
|
||||
"`nosubst"
|
||||
"`nosubst"
|
||||
|
||||
|
||||
x y LLZZ x y
|
||||
p q LLZZ p q r s LLZZ r s LLZZ p q LLZZ p q r s LLZZ r s
|
||||
x y LLZZ x y
|
||||
p q LLZZ p q r s LLZZ r s LLZZ p q LLZZ p q r s LLZZ r s
|
||||
|
||||
|
||||
|
||||
firstline comma","line LLZZ firstline comma","line
|
||||
firstline comma","line LLZZ firstline comma","line
|
||||
|
||||
|
||||
x y LLZZ "a" y
|
||||
x y LLZZ "a" y
|
||||
|
||||
|
||||
(a,b) (a,b)
|
||||
(a,b)(a,b)
|
||||
|
||||
|
||||
$display( "left side: \" right side\"" )
|
||||
$display("left side: \"right side\"")
|
||||
|
||||
|
||||
bar_suffix
|
||||
bar_suffix
|
||||
|
||||
|
||||
|
||||
$c("Zap(\"",bug1,"\");"); ;
|
||||
$c("Zap(\"","bug2","\");"); ;
|
||||
$c("Zap(\"",bug1,"\");");;
|
||||
$c("Zap(\"","bug2","\");");;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
wire tmp_d1 = d1; wire tmp_o1 = tmp_d1 + 1; assign o1 = tmp_o1 ;
|
||||
wire tmp_d2 = d2 ; wire tmp_o2 = tmp_d2 + 1; assign o2 = tmp_o2 ;
|
||||
|
||||
|
||||
|
||||
|
@ -139,7 +148,7 @@ $display( "left side: \" right side\"" )
|
|||
|
||||
|
||||
|
||||
`line 95 "t/t_preproc.v" 0
|
||||
`line 104 "t/t_preproc.v" 0
|
||||
|
||||
Line_Preproc_Check 96
|
||||
`line 97 "t/t_preproc.v" 2
|
||||
Line_Preproc_Check 105
|
||||
`line 106 "t/t_preproc.v" 2
|
||||
|
|
|
@ -86,6 +86,15 @@ $display(`msg(left side, right side))
|
|||
`zap(bug1);
|
||||
`zap("bug2");
|
||||
|
||||
// rt.cpan.org bug34429
|
||||
`define ADD_UP(a,c) \
|
||||
wire tmp_``a = a; \
|
||||
wire tmp_``c = tmp_``a + 1; \
|
||||
assign c = tmp_``c ;
|
||||
|
||||
`ADD_UP(d1,o1) // expansion is OK
|
||||
`ADD_UP( d2 , o2 ) // expansion is bad
|
||||
|
||||
//===========================================================================
|
||||
// Ifdef
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ Hello in t_preproc_psl.v
|
|||
|
||||
|
||||
|
||||
psl assert always cyc !=10;
|
||||
psl assert always cyc!=10;
|
||||
|
||||
|
||||
`psl
|
||||
|
|
Loading…
Reference in New Issue