forked from github/verilator
Fix constant function assigned to packed structs, bug997.
Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
parent
c7e0f2e196
commit
4e4bc7b90f
4
Changes
4
Changes
@ -5,13 +5,15 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.879 devel
|
||||
|
||||
**** Fix display %u, %v, %p, %z, bug989. [Johan Bjork]
|
||||
|
||||
**** Fix real parameters causing bad module names, bug992. [Johan Bjork]
|
||||
|
||||
**** Fix size-changing cast on packed struct, bug993. [Johan Bjork]
|
||||
|
||||
**** Fix function calls on arrayed interface, bug994. [Johan Bjork]
|
||||
|
||||
**** Fix display %u, %v, %p, %z, bug989. [Johan Bjork]
|
||||
**** Fix constant function assigned to packed structs, bug997. [Johan Bjork]
|
||||
|
||||
|
||||
* Verilator 3.878 2015-11-01
|
||||
|
@ -451,6 +451,56 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool handleAssignSel(AstNodeAssign* nodep, AstSel* selp, AstVarRef** outVarrefp, int depth) {
|
||||
checkNodeInfo(selp);
|
||||
AstVarRef* varrefp = selp->fromp()->castVarRef();
|
||||
if (!varrefp) {
|
||||
selp = selp->lhsp()->castSel();
|
||||
if (selp) {
|
||||
if (!handleAssignSel(nodep, selp, &varrefp, depth+1)) {
|
||||
clearOptimizable(nodep, "Select LHS isn't simple variable");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_checkOnly) {
|
||||
nodep->iterateChildren(*this);
|
||||
} else {
|
||||
selp->lsbp()->iterateAndNext(*this);
|
||||
nodep->rhsp()->iterateAndNext(*this);
|
||||
|
||||
if (optimizable()) {
|
||||
AstNode* vscp;
|
||||
if (varrefp) {
|
||||
vscp = varOrScope(varrefp);
|
||||
V3Number outnum = V3Number(nodep->fileline());
|
||||
if (V3Number* vscpnump = fetchOutNumberNull(vscp)) {
|
||||
outnum = *vscpnump;
|
||||
} else if (V3Number* vscpnump = fetchNumberNull(vscp)) {
|
||||
outnum = *vscpnump;
|
||||
} else { // Assignment to unassigned variable, all bits are X or 0
|
||||
outnum = V3Number(nodep->fileline(), varrefp->varp()->widthMin());
|
||||
if (varrefp->varp()->basicp() && varrefp->varp()->basicp()->isZeroInit()) {
|
||||
outnum.setAllBits0();
|
||||
} else {
|
||||
outnum.setAllBitsX();
|
||||
}
|
||||
}
|
||||
if (depth == 0) {
|
||||
outnum.opSelInto(*fetchNumber(nodep->rhsp()),
|
||||
*fetchNumber(selp->lsbp()),
|
||||
selp->widthConst());
|
||||
assignOutNumber(nodep, vscp, &outnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (outVarrefp) *outVarrefp = varrefp;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||
if (jumpingOver(nodep)) return;
|
||||
if (!optimizable()) return; // Accelerate
|
||||
@ -462,41 +512,10 @@ private:
|
||||
if (m_anyAssignDly) clearOptimizable(nodep, "Mix of dly/non-dly assigns");
|
||||
m_anyAssignComb = true;
|
||||
}
|
||||
|
||||
if (AstSel* selp = nodep->lhsp()->castSel()) {
|
||||
if (!m_params) { clearOptimizable(nodep, "LHS has select"); return; }
|
||||
checkNodeInfo(selp);
|
||||
AstVarRef* varrefp = selp->fromp()->castVarRef();
|
||||
if (!varrefp) {
|
||||
clearOptimizable(nodep, "Select LHS isn't simple variable");
|
||||
return;
|
||||
}
|
||||
if (m_checkOnly) {
|
||||
nodep->iterateChildren(*this);
|
||||
} else {
|
||||
selp->lsbp()->iterateAndNext(*this);
|
||||
nodep->rhsp()->iterateAndNext(*this);
|
||||
if (optimizable()) {
|
||||
AstNode* vscp = varOrScope(varrefp);
|
||||
if (optimizable()) {
|
||||
V3Number outnum (nodep->fileline(), varrefp->varp()->widthMin());
|
||||
if (V3Number* outnump = fetchOutNumberNull(vscp)) {
|
||||
outnum = *outnump;
|
||||
} else if (V3Number* outnump = fetchNumberNull(vscp)) {
|
||||
outnum = *outnump;
|
||||
} else { // Assignment to unassigned variable, all bits are X or 0
|
||||
if (varrefp->varp()->basicp() && varrefp->varp()->basicp()->isZeroInit()) {
|
||||
outnum.setAllBits0();
|
||||
} else {
|
||||
outnum.setAllBitsX();
|
||||
}
|
||||
}
|
||||
outnum.opSelInto(*fetchNumber(nodep->rhsp()),
|
||||
*fetchNumber(selp->lsbp()),
|
||||
selp->widthConst());
|
||||
assignOutNumber(nodep, vscp, &outnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
handleAssignSel(nodep, selp, NULL, 0);
|
||||
}
|
||||
else if (!nodep->lhsp()->castVarRef()) {
|
||||
clearOptimizable(nodep, "LHS isn't simple variable");
|
||||
|
@ -13,6 +13,19 @@ module t;
|
||||
localparam P6 = f_return(P4);
|
||||
localparam P3 = 3;
|
||||
|
||||
typedef struct packed {
|
||||
logic [7:0] data;
|
||||
} type_t;
|
||||
typedef type_t [1:0] flist;
|
||||
localparam flist PLIST = {8'd4,8'd8};
|
||||
localparam flist PARR = f_list_swap_2(PLIST);
|
||||
typedef struct packed {
|
||||
logic first;
|
||||
logic second;
|
||||
logic [31:0] data;
|
||||
} bigstruct_t;
|
||||
localparam bigstruct_t bigparam = f_return_struct(1'b1, 1'b0, 32'hfff12fff);
|
||||
|
||||
initial begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$display("P5=%0d P8=%0d P16=%0d P18=%0d",P5,P8,P16,P18);
|
||||
@ -24,6 +37,11 @@ module t;
|
||||
if (P8 !== 8) $stop;
|
||||
if (P16 !== 16) $stop;
|
||||
if (P18 !== 18) $stop;
|
||||
if (PARR[0] != PLIST[1]) $stop;
|
||||
if (PARR[1] != PLIST[0]) $stop;
|
||||
if (bigparam.first != 1'b1) $stop;
|
||||
if (bigparam.second != 1'b0) $stop;
|
||||
if (bigparam.data != 32'hfff12fff) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
@ -36,7 +54,7 @@ module t;
|
||||
function integer f_add2(input [31:0] a, input [31:0] b, input [31:0] c);
|
||||
f_add2 = f_add(a,b)+c;
|
||||
endfunction
|
||||
|
||||
|
||||
// Speced ok: local variables
|
||||
function integer f_for(input [31:0] a);
|
||||
integer i;
|
||||
@ -84,4 +102,17 @@ module t;
|
||||
end
|
||||
f_return = 0;
|
||||
endfunction
|
||||
|
||||
function flist f_list_swap_2(input flist in_list);
|
||||
f_list_swap_2[0].data = in_list[1].data;
|
||||
f_list_swap_2[1].data = in_list[0].data;
|
||||
endfunction
|
||||
|
||||
function bigstruct_t f_return_struct(input first, input second, input [31:0] data);
|
||||
bigstruct_t result;
|
||||
result.data = data;
|
||||
result.first = first;
|
||||
result.second = second;
|
||||
return result;
|
||||
endfunction
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue
Block a user