Fix non-arrayed cells with interface arrays, bug1153.

Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Todd Strader 2017-05-10 19:05:42 -04:00 committed by Wilson Snyder
parent 54bc8608e3
commit 2fa16708b7
5 changed files with 113 additions and 6 deletions

View File

@ -11,12 +11,14 @@ The contributors that suggested a given feature are shown in []. Thanks!
*** Support arrayed parameter overrides, bug1153. [John Stevenson]
**** Fix non-arrayed cells with interface arrays, bug1153. [John Stevenson]
**** Support modport access to un-modport objects, bug1161. [Todd Strader]
**** Add stack trace when can't optimize function, bug1158. [Todd Strader]
**** Add warning on mis-sized literal, bug1156. [Todd Strader]
**** Fix non-arrayed cells with interface arrays, bug1153. [John Stevenson]
* Verilator 3.902 2017-04-02

View File

@ -445,6 +445,10 @@ public:
<<") <- se"<<srcp<<" "<<srcp->nodep()<<endl);
// srcp should be an interface reference pointing to the interface we want to import
lhsp->importFromIface(symsp(), srcp);
// Allow access to objects not permissible to be listed in a modport
if (srcp->nodep()->castModport()) {
lhsp->importFromIface(symsp(), srcp->parentp(), true);
}
}
//m_scopeAliasMap[samn].clear(); // Done with it, but put into debug file
}

View File

@ -183,16 +183,19 @@ public:
}
return any;
}
void importFromIface(VSymGraph* graphp, const VSymEnt* srcp) {
void importFromIface(VSymGraph* graphp, const VSymEnt* srcp, bool onlyUnmodportable = false) {
// Import interface tokens from source symbol table into this symbol table, recursively
UINFO(9, " importIf se"<<(void*)this<<" from se"<<(void*)srcp<<endl);
for (IdNameMap::const_iterator it=srcp->m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) {
const string& name = it->first;
VSymEnt* subSrcp = it->second;
VSymEnt* subSymp = new VSymEnt(graphp, subSrcp);
reinsert(name, subSymp);
// And recurse to create children
subSymp->importFromIface(graphp, subSrcp);
AstVar* varp = subSrcp->nodep()->castVar();
if (!onlyUnmodportable || (varp && varp->varType() == AstVarType::GPARAM)) {
VSymEnt* subSymp = new VSymEnt(graphp, subSrcp);
reinsert(name, subSymp);
// And recurse to create children
subSymp->importFromIface(graphp, subSrcp);
}
}
}
void cellErrorScopes(AstNode* lookp, string prettyName="") {

View 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;

View File

@ -0,0 +1,80 @@
// DESCRIPTION: Verilator: Interface parameter getter
//
// A test of the import parameter used with modport
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2015 by Todd Strader
interface test_if #(parameter integer FOO = 1);
// Interface variable
logic data;
// Modport
modport mp(
import getFoo,
output data
);
function integer getFoo ();
return FOO;
endfunction
endinterface // test_if
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
test_if #( .FOO (5) ) the_interface ();
testmod testmod_i (.clk (clk),
.intf (the_interface),
.intf_no_mp (the_interface)
);
endmodule
module testmod
(
input clk,
test_if.mp intf,
test_if intf_no_mp
);
`ifdef ELAB_TIME
localparam THE_FOO = intf.FOO;
// localparam THE_OTHER_FOO = intf_no_mp.FOO;
`endif
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 (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 (i.getFoo() != 5) begin
// $display("%%Error: i.getFoo() = %0d", i.getFoo());
// $stop;
// end
$write("*-* All Finished *-*\n");
$finish;
end
endmodule