forked from github/verilator
Fix non-arrayed cells with interface arrays, bug1153.
Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
parent
54bc8608e3
commit
2fa16708b7
4
Changes
4
Changes
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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="") {
|
||||
|
18
test_regress/t/t_interface_parameter_access.pl
Executable file
18
test_regress/t/t_interface_parameter_access.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;
|
80
test_regress/t/t_interface_parameter_access.v
Normal file
80
test_regress/t/t_interface_parameter_access.v
Normal 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
|
Loading…
Reference in New Issue
Block a user