Merge from master
This commit is contained in:
commit
4d034d774d
4
Changes
4
Changes
|
|
@ -28,13 +28,15 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||||
|
|
||||||
**** Add OBJCACHE envvar support to examples and generated Makefiles.
|
**** Add OBJCACHE envvar support to examples and generated Makefiles.
|
||||||
|
|
||||||
|
**** Change MODDUP errors to warnings, msg2588. [Marshal Qiao]
|
||||||
|
|
||||||
**** Fix define argument stringification (`"), broke since 3.914. [Joe DErrico]
|
**** Fix define argument stringification (`"), broke since 3.914. [Joe DErrico]
|
||||||
|
|
||||||
**** Fix to ignore Unicode UTF-8 BOM sequences, msg2576. [HyungKi Jeong]
|
**** Fix to ignore Unicode UTF-8 BOM sequences, msg2576. [HyungKi Jeong]
|
||||||
|
|
||||||
**** Fix std:: build error, bug1322.
|
**** Fix std:: build error, bug1322.
|
||||||
|
|
||||||
**** Change MODDUP errors to warnings, msg2588. [Marshal Qiao]
|
**** Fix function inlining inside certain while loops, bug1330. [Julien Margetts]
|
||||||
|
|
||||||
|
|
||||||
* Verilator 3.924 2018-06-12
|
* Verilator 3.924 2018-06-12
|
||||||
|
|
|
||||||
|
|
@ -336,7 +336,7 @@ public:
|
||||||
virtual void visit(AstNodeReadWriteMem* nodep) {
|
virtual void visit(AstNodeReadWriteMem* nodep) {
|
||||||
puts(nodep->cFuncPrefixp());
|
puts(nodep->cFuncPrefixp());
|
||||||
emitIQW(nodep->filenamep());
|
emitIQW(nodep->filenamep());
|
||||||
puts(" ("); // We take a void* rather than emitIQW(nodep->memp());
|
puts("("); // We take a void* rather than emitIQW(nodep->memp());
|
||||||
puts(nodep->isHex()?"true":"false");
|
puts(nodep->isHex()?"true":"false");
|
||||||
putbs(",");
|
putbs(",");
|
||||||
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
|
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
|
||||||
|
|
|
||||||
|
|
@ -1079,10 +1079,12 @@ private:
|
||||||
m_insMode = prevInsMode;
|
m_insMode = prevInsMode;
|
||||||
m_insStmtp = prevInsStmtp;
|
m_insStmtp = prevInsStmtp;
|
||||||
}
|
}
|
||||||
void insertBeforeStmt(AstNode* nodep, AstNode* newp) {
|
AstNode* insertBeforeStmt(AstNode* nodep, AstNode* newp) {
|
||||||
|
// Return node that must be visited, if any
|
||||||
// See also AstNode::addBeforeStmt; this predates that function
|
// See also AstNode::addBeforeStmt; this predates that function
|
||||||
if (debug()>=9) { nodep->dumpTree(cout,"-newstmt:"); }
|
if (debug()>=9) { nodep->dumpTree(cout,"-newstmt:"); }
|
||||||
if (!m_insStmtp) nodep->v3fatalSrc("Function not underneath a statement");
|
if (!m_insStmtp) nodep->v3fatalSrc("Function not underneath a statement");
|
||||||
|
AstNode* visitp = NULL;
|
||||||
if (m_insMode == IM_BEFORE) {
|
if (m_insMode == IM_BEFORE) {
|
||||||
// Add the whole thing before insertAt
|
// Add the whole thing before insertAt
|
||||||
UINFO(5," IM_Before "<<m_insStmtp<<endl);
|
UINFO(5," IM_Before "<<m_insStmtp<<endl);
|
||||||
|
|
@ -1090,20 +1092,22 @@ private:
|
||||||
m_insStmtp->addHereThisAsNext(newp);
|
m_insStmtp->addHereThisAsNext(newp);
|
||||||
}
|
}
|
||||||
else if (m_insMode == IM_AFTER) {
|
else if (m_insMode == IM_AFTER) {
|
||||||
UINFO(5," IM_After "<<m_insStmtp);
|
UINFO(5," IM_After "<<m_insStmtp<<endl);
|
||||||
m_insStmtp->addNextHere(newp);
|
m_insStmtp->addNextHere(newp);
|
||||||
}
|
}
|
||||||
else if (m_insMode == IM_WHILE_PRECOND) {
|
else if (m_insMode == IM_WHILE_PRECOND) {
|
||||||
UINFO(5," IM_While_Precond "<<m_insStmtp);
|
UINFO(5," IM_While_Precond "<<m_insStmtp<<endl);
|
||||||
AstWhile* whilep = VN_CAST(m_insStmtp, While);
|
AstWhile* whilep = VN_CAST(m_insStmtp, While);
|
||||||
if (!whilep) nodep->v3fatalSrc("Insert should be under WHILE");
|
if (!whilep) nodep->v3fatalSrc("Insert should be under WHILE");
|
||||||
whilep->addPrecondsp(newp);
|
whilep->addPrecondsp(newp);
|
||||||
|
visitp = newp;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nodep->v3fatalSrc("Unknown InsertMode");
|
nodep->v3fatalSrc("Unknown InsertMode");
|
||||||
}
|
}
|
||||||
m_insMode = IM_AFTER;
|
m_insMode = IM_AFTER;
|
||||||
m_insStmtp = newp;
|
m_insStmtp = newp;
|
||||||
|
return visitp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VISITORS
|
// VISITORS
|
||||||
|
|
@ -1148,12 +1152,13 @@ private:
|
||||||
beginp = createInlinedFTask(nodep, namePrefix, outvscp);
|
beginp = createInlinedFTask(nodep, namePrefix, outvscp);
|
||||||
}
|
}
|
||||||
// Replace the ref
|
// Replace the ref
|
||||||
|
AstNode* visitp = NULL;
|
||||||
if (VN_IS(nodep, FuncRef)) {
|
if (VN_IS(nodep, FuncRef)) {
|
||||||
if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function");
|
if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function");
|
||||||
AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false);
|
AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false);
|
||||||
nodep->replaceWith(outrefp);
|
nodep->replaceWith(outrefp);
|
||||||
// Insert new statements
|
// Insert new statements
|
||||||
insertBeforeStmt(nodep, beginp);
|
visitp = insertBeforeStmt(nodep, beginp);
|
||||||
} else {
|
} else {
|
||||||
// outvscp maybe non-NULL if calling a function in a taskref,
|
// outvscp maybe non-NULL if calling a function in a taskref,
|
||||||
// but if so we want to simply ignore the function result
|
// but if so we want to simply ignore the function result
|
||||||
|
|
@ -1162,6 +1167,8 @@ private:
|
||||||
// Cleanup
|
// Cleanup
|
||||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
UINFO(4," FTask REF Done.\n");
|
UINFO(4," FTask REF Done.\n");
|
||||||
|
// Visit nodes that normal iteration won't find
|
||||||
|
if (visitp) iterateAndNextNull(visitp);
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeFTask* nodep) {
|
virtual void visit(AstNodeFTask* nodep) {
|
||||||
UINFO(4," Inline "<<nodep<<endl);
|
UINFO(4," Inline "<<nodep<<endl);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
|
# 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
|
||||||
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
# Version 2.0.
|
||||||
|
|
||||||
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
|
compile(
|
||||||
|
verilator_flags2 => ["--trace"],
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2018 by Julien Margetts.
|
||||||
|
|
||||||
|
module t #(parameter sz = 4096)
|
||||||
|
(
|
||||||
|
input wire clk,
|
||||||
|
output reg [tdw(sz)-1:0] data
|
||||||
|
);
|
||||||
|
|
||||||
|
// bug1330
|
||||||
|
function integer clog2(input integer value);
|
||||||
|
integer tmp;
|
||||||
|
tmp = value-1;
|
||||||
|
clog2 = 0;
|
||||||
|
for (clog2=0; (tmp>0) && (clog2<32); clog2=clog2+1)
|
||||||
|
tmp = tmp>>1;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function integer tdw(input integer sz);
|
||||||
|
tdw = clog2(sz);
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
integer b;
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
for (b=0; b<tdw(sz); b=b+1)
|
||||||
|
if ((data[b] === 1'bx))
|
||||||
|
$display("WARNING: %1t Writing X's to tag RAM [%m]", $time);
|
||||||
|
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue