forked from github/verilator
Fix interface functions returning wrong parameters, bug996.
This commit is contained in:
parent
b032fce962
commit
7fb29621c3
2
Changes
2
Changes
@ -19,6 +19,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
**** Add warning on mis-sized literal, bug1156. [Todd Strader]
|
||||
|
||||
**** Fix interface functions returning wrong parameters, bug996. [Todd Strader]
|
||||
|
||||
**** Fix non-arrayed cells with interface arrays, bug1153. [John Stevenson]
|
||||
|
||||
**** Fix --assert with complex case statements, bug1164. [Enzo Chi]
|
||||
|
@ -283,7 +283,59 @@ private:
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (nodep->varp()) nodep->varp()->iterate(*this);
|
||||
}
|
||||
bool ifaceParamReplace(AstVarXRef* nodep, AstNode* candp) {
|
||||
for (; candp; candp = candp->nextp()) {
|
||||
if (nodep->name() == candp->name()) {
|
||||
if (AstVar* varp = candp->castVar()) {
|
||||
UINFO(9,"Found interface parameter: "<<varp<<endl);
|
||||
nodep->varp(varp);
|
||||
return true;
|
||||
} else if (AstPin* pinp = candp->castPin()) {
|
||||
UINFO(9,"Found interface parameter: "<<pinp<<endl);
|
||||
if (!pinp->exprp()) pinp->v3fatalSrc("Interface parameter pin missing expression");
|
||||
nodep->replaceWith(pinp->exprp()->cloneTree(false)); VL_DANGLING(nodep);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep) {
|
||||
// Check to see if the scope is just an interface because interfaces are special
|
||||
string dotted = nodep->dotted();
|
||||
if (!dotted.empty() && nodep->varp() && nodep->varp()->isParam()) {
|
||||
AstNode* backp = nodep;
|
||||
while ((backp = backp->backp())) {
|
||||
if (backp->castNodeModule()) {
|
||||
UINFO(9,"Hit module boundary, done looking for interface"<<endl);
|
||||
break;
|
||||
}
|
||||
if (backp->castVar()
|
||||
&& backp->castVar()->isIfaceRef()
|
||||
&& backp->castVar()->childDTypep()
|
||||
&& backp->castVar()->childDTypep()->castIfaceRefDType()) {
|
||||
AstIfaceRefDType* ifacerefp = backp->castVar()->childDTypep()->castIfaceRefDType();
|
||||
// Interfaces passed in on the port map have ifaces
|
||||
if (AstIface* ifacep = ifacerefp->ifacep()) {
|
||||
if (dotted == backp->name()) {
|
||||
UINFO(9,"Iface matching scope: "<<ifacep<<endl);
|
||||
if (ifaceParamReplace(nodep, ifacep->stmtsp())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Interfaces declared in this module have cells
|
||||
else if (AstCell* cellp = ifacerefp->cellp()) {
|
||||
if (dotted == cellp->name()) {
|
||||
UINFO(9,"Iface matching scope: "<<cellp<<endl);
|
||||
if (ifaceParamReplace(nodep, cellp->paramsp())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nodep->varp(NULL); // Needs relink, as may remove pointed-to var
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,10 @@ interface test_if #(parameter integer FOO = 1);
|
||||
|
||||
endinterface // test_if
|
||||
|
||||
function integer identity (input integer x);
|
||||
return x;
|
||||
endfunction
|
||||
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
@ -29,13 +33,22 @@ module t (/*AUTOARG*/
|
||||
);
|
||||
input clk;
|
||||
|
||||
test_if #( .FOO (5) ) the_interface ();
|
||||
test_if #( .FOO (identity(5)) ) the_interface ();
|
||||
|
||||
testmod testmod_i (.clk (clk),
|
||||
.intf (the_interface),
|
||||
.intf_no_mp (the_interface)
|
||||
);
|
||||
|
||||
localparam THE_TOP_FOO = the_interface.FOO;
|
||||
|
||||
initial begin
|
||||
if (THE_TOP_FOO != 5) begin
|
||||
$display("%%Error: THE_TOP_FOO = %0d", THE_TOP_FOO);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
@ -46,30 +59,26 @@ module testmod
|
||||
test_if intf_no_mp
|
||||
);
|
||||
|
||||
`ifdef ELAB_TIME
|
||||
localparam THE_FOO = intf.FOO;
|
||||
// localparam THE_OTHER_FOO = intf_no_mp.FOO;
|
||||
`endif
|
||||
localparam THE_OTHER_FOO = intf_no_mp.FOO;
|
||||
|
||||
always @(posedge clk) begin
|
||||
`ifdef ELAB_TIME
|
||||
if (THE_FOO != 5) begin
|
||||
$display("%%Error: THE_FOO = %0d", THE_FOO);
|
||||
$stop;
|
||||
end
|
||||
// if (THE_OTHER_FOO != 5) begin
|
||||
// $display("%%Error: THE_OTHER_FOO = %0d", THE_OTHER_FOO);
|
||||
// $stop;
|
||||
// end
|
||||
`endif
|
||||
if (THE_OTHER_FOO != 5) begin
|
||||
$display("%%Error: THE_OTHER_FOO = %0d", THE_OTHER_FOO);
|
||||
$stop;
|
||||
end
|
||||
if (intf.FOO != 5) begin
|
||||
$display("%%Error: intf.FOO = %0d", intf.FOO);
|
||||
$stop;
|
||||
end
|
||||
// if (intf_no_mp.FOO != 5) begin
|
||||
// $display("%%Error: intf_no_mp.FOO = %0d", intf_no_mp.FOO);
|
||||
// $stop;
|
||||
// end
|
||||
if (intf_no_mp.FOO != 5) begin
|
||||
$display("%%Error: intf_no_mp.FOO = %0d", intf_no_mp.FOO);
|
||||
$stop;
|
||||
end
|
||||
// if (i.getFoo() != 5) begin
|
||||
// $display("%%Error: i.getFoo() = %0d", i.getFoo());
|
||||
// $stop;
|
||||
|
Loading…
Reference in New Issue
Block a user