mirror of
https://github.com/verilator/verilator.git
synced 2025-01-31 18:54:03 +00:00
Fix generate unrolling with function call, bug830.
This commit is contained in:
parent
6ba90e3a50
commit
b73edc0564
2
Changes
2
Changes
@ -5,6 +5,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||||||
|
|
||||||
* Verilator 3.865 devel
|
* Verilator 3.865 devel
|
||||||
|
|
||||||
|
**** Fix generate unrolling with function call, bug830. [Steven Slatter]
|
||||||
|
|
||||||
|
|
||||||
* Verilator 3.864 2014-09-21
|
* Verilator 3.864 2014-09-21
|
||||||
|
|
||||||
|
@ -164,15 +164,27 @@ private:
|
|||||||
bool gt = condp->castGt() || condp->castGtS();
|
bool gt = condp->castGt() || condp->castGtS();
|
||||||
bool gte = condp->castGte() || condp->castGteS();
|
bool gte = condp->castGte() || condp->castGteS();
|
||||||
if (!lt && !lte && !gt && !gte)
|
if (!lt && !lte && !gt && !gte)
|
||||||
return cantUnroll(nodep, "condition not <= or <");
|
return cantUnroll(nodep, "condition not <=, <, >= or >");
|
||||||
AstNodeBiop* condBip = condp->castNodeBiop();
|
AstNodeBiop* cmpInstrp = condp->castNodeBiop();
|
||||||
if (!condBip->rhsp()->castVarRef())
|
bool cmpVarLhs;
|
||||||
|
if (cmpInstrp->lhsp()->castVarRef()
|
||||||
|
&& cmpInstrp->lhsp()->castVarRef()->varp() == m_forVarp
|
||||||
|
&& cmpInstrp->lhsp()->castVarRef()->varScopep() == m_forVscp) {
|
||||||
|
cmpVarLhs = true;
|
||||||
|
} else if (cmpInstrp->rhsp()->castVarRef()
|
||||||
|
&& cmpInstrp->rhsp()->castVarRef()->varp() == m_forVarp
|
||||||
|
&& cmpInstrp->rhsp()->castVarRef()->varScopep() == m_forVscp) {
|
||||||
|
cmpVarLhs = false;
|
||||||
|
} else if (!cmpInstrp->rhsp()->castVarRef()) {
|
||||||
return cantUnroll(nodep, "no variable on rhs of condition");
|
return cantUnroll(nodep, "no variable on rhs of condition");
|
||||||
if (condBip->rhsp()->castVarRef()->varp() != m_forVarp
|
} else {
|
||||||
|| condBip->rhsp()->castVarRef()->varScopep() != m_forVscp)
|
|
||||||
return cantUnroll(nodep, "different variable in condition");
|
return cantUnroll(nodep, "different variable in condition");
|
||||||
if (m_generate) V3Const::constifyParamsEdit(condBip->lhsp()); // rhsp may change
|
}
|
||||||
AstConst* constStopp = condBip->lhsp()->castConst();
|
|
||||||
|
if (m_generate) V3Const::constifyParamsEdit(cmpVarLhs ? cmpInstrp->rhsp()
|
||||||
|
: cmpInstrp->lhsp()); // rhsp/lhsp may change
|
||||||
|
AstConst* constStopp = (cmpVarLhs ? cmpInstrp->rhsp()->castConst()
|
||||||
|
: cmpInstrp->lhsp()->castConst());
|
||||||
if (!constStopp) return cantUnroll(nodep, "non-constant final value");
|
if (!constStopp) return cantUnroll(nodep, "non-constant final value");
|
||||||
UINFO(8, " Stop expr ok: "<<constStopp<<endl);
|
UINFO(8, " Stop expr ok: "<<constStopp<<endl);
|
||||||
//
|
//
|
||||||
@ -217,9 +229,9 @@ private:
|
|||||||
if (m_varAssignHit) return cantUnroll(nodep, "genvar assigned *inside* loop");
|
if (m_varAssignHit) return cantUnroll(nodep, "genvar assigned *inside* loop");
|
||||||
//
|
//
|
||||||
// Finally, we can do it
|
// Finally, we can do it
|
||||||
forUnroller(nodep, initp, precondsp, condp, incp, bodysp,
|
forUnroller(nodep, initp, precondsp, incp, bodysp,
|
||||||
constInitp->num(),
|
constInitp->num(),
|
||||||
condBip, constStopp->num(),
|
cmpInstrp, constStopp->num(), cmpVarLhs,
|
||||||
incInstrp, constIncp->num()); nodep = NULL;
|
incInstrp, constIncp->num()); nodep = NULL;
|
||||||
// Cleanup
|
// Cleanup
|
||||||
return true;
|
return true;
|
||||||
@ -227,10 +239,10 @@ private:
|
|||||||
|
|
||||||
void forUnroller(AstNode* nodep,
|
void forUnroller(AstNode* nodep,
|
||||||
AstNode* initp,
|
AstNode* initp,
|
||||||
AstNode* precondsp, AstNode* condp,
|
AstNode* precondsp,
|
||||||
AstNode* incp, AstNode* bodysp,
|
AstNode* incp, AstNode* bodysp,
|
||||||
const V3Number& numInit,
|
const V3Number& numInit,
|
||||||
AstNodeBiop* cmpInstrp, const V3Number& numStop,
|
AstNodeBiop* cmpInstrp, const V3Number& numStop, bool cmpVarLhs,
|
||||||
AstNodeBiop* incInstrp, const V3Number& numInc) {
|
AstNodeBiop* incInstrp, const V3Number& numInc) {
|
||||||
UINFO(4, " Unroll for var="<<numInit<<"; var<"<<numStop<<"; var+="<<numInc<<endl);
|
UINFO(4, " Unroll for var="<<numInit<<"; var<"<<numStop<<"; var+="<<numInc<<endl);
|
||||||
UINFO(6, " cmpI "<<cmpInstrp<<endl);
|
UINFO(6, " cmpI "<<cmpInstrp<<endl);
|
||||||
@ -270,7 +282,11 @@ private:
|
|||||||
UINFO(8," Looping "<<loopValue<<endl);
|
UINFO(8," Looping "<<loopValue<<endl);
|
||||||
// if loopValue<valStop
|
// if loopValue<valStop
|
||||||
V3Number contin (nodep->fileline(), 1);
|
V3Number contin (nodep->fileline(), 1);
|
||||||
cmpInstrp->numberOperate(contin, numStop, loopValue);
|
if (cmpVarLhs) {
|
||||||
|
cmpInstrp->numberOperate(contin, loopValue, numStop);
|
||||||
|
} else {
|
||||||
|
cmpInstrp->numberOperate(contin, numStop, loopValue);
|
||||||
|
}
|
||||||
if (contin.isEqZero()) {
|
if (contin.isEqZero()) {
|
||||||
break; // Done with the loop
|
break; // Done with the loop
|
||||||
} else {
|
} else {
|
||||||
|
18
test_regress/t/t_unroll_genf.pl
Executable file
18
test_regress/t/t_unroll_genf.pl
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/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.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
29
test_regress/t/t_unroll_genf.v
Normal file
29
test_regress/t/t_unroll_genf.v
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2004 by Wilson Snyder.
|
||||||
|
|
||||||
|
//bug830
|
||||||
|
module sub();
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
function integer cdiv(input integer x);
|
||||||
|
begin
|
||||||
|
cdiv = 10;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/);
|
||||||
|
|
||||||
|
genvar j;
|
||||||
|
generate
|
||||||
|
for (j = 0; j < cdiv(10); j=j+1)
|
||||||
|
sub sub();
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
Loading…
Reference in New Issue
Block a user