forked from github/verilator
Fix range inheritance on port without data type (#2753).
This commit is contained in:
parent
e88dff6929
commit
29ed866061
2
Changes
2
Changes
@ -16,6 +16,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
**** Fix slice-assign overflow (#2803) (#2811). [David Turner]
|
||||
|
||||
**** Fix interface array connection ordering broken in v4.110 (#2827). [Don Owen]
|
||||
|
||||
**** Fix or-reduction on different scopes broken in 4.110 (#2828). [Yinan Xu]
|
||||
|
||||
|
||||
|
@ -396,7 +396,7 @@ private:
|
||||
AstNode* prevPinp = nullptr;
|
||||
// Clone the var referenced by the pin, and clone each var referenced by the varref
|
||||
// Clone pin varp:
|
||||
for (int in = 0; in < pinArrp->elementsConst(); ++in) {
|
||||
for (int in = 0; in < pinArrp->elementsConst(); ++in) { // 0 = leftmost
|
||||
int i = pinArrp->left() + in * pinArrp->declRange().leftToRightInc();
|
||||
string varNewName = pinVarp->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
||||
AstVar* varNewp = nullptr;
|
||||
@ -430,19 +430,22 @@ private:
|
||||
newp->modVarp(varNewp);
|
||||
newp->name(newp->name() + "__BRA__" + cvtToStr(i) + "__KET__");
|
||||
// And replace exprp with a new varxref
|
||||
const AstVarRef* varrefp = VN_CAST(newp->exprp(), VarRef);
|
||||
int offset = 0;
|
||||
if (varrefp) {
|
||||
} else if (AstSliceSel* slicep = VN_CAST(newp->exprp(), SliceSel)) {
|
||||
const AstVarRef* varrefp = VN_CAST(newp->exprp(), VarRef); // Maybe null
|
||||
int expr_i = i;
|
||||
if (AstSliceSel* slicep = VN_CAST(newp->exprp(), SliceSel)) {
|
||||
varrefp = VN_CAST(slicep->fromp(), VarRef);
|
||||
UASSERT(VN_IS(slicep->rhsp(), Const), "Slices should be constant");
|
||||
offset = VN_CAST(slicep->rhsp(), Const)->toSInt();
|
||||
int slice_index
|
||||
= slicep->declRange().left() + in * slicep->declRange().leftToRightInc();
|
||||
auto* exprArrp = VN_CAST(varrefp->dtypep(), UnpackArrayDType);
|
||||
UASSERT_OBJ(exprArrp, slicep, "Slice of non-array");
|
||||
expr_i = slice_index + exprArrp->lo();
|
||||
} else if (!varrefp) {
|
||||
newp->exprp()->v3error("Unexpected connection to arrayed port");
|
||||
} else if (auto* exprArrp = VN_CAST(varrefp->dtypep(), UnpackArrayDType)) {
|
||||
expr_i = exprArrp->left() + in * exprArrp->declRange().leftToRightInc();
|
||||
}
|
||||
int expr_i = i;
|
||||
if (auto* exprArrp = VN_CAST(newp->exprp()->dtypep(), UnpackArrayDType))
|
||||
expr_i = exprArrp->left()
|
||||
+ (in + offset) * exprArrp->declRange().leftToRightInc();
|
||||
if (!varrefp) newp->exprp()->v3error("Unexpected connection to arrayed port");
|
||||
|
||||
string newname = varrefp->name() + "__BRA__" + cvtToStr(expr_i) + "__KET__";
|
||||
AstVarXRef* newVarXRefp
|
||||
= new AstVarXRef(nodep->fileline(), newname, "", VAccess::WRITE);
|
||||
|
@ -76,4 +76,3 @@ module sub
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
24
test_regress/t/t_mod_interface_array4_noinl.pl
Executable file
24
test_regress/t/t_mod_interface_array4_noinl.pl
Executable file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_mod_interface_array4.v");
|
||||
|
||||
compile(
|
||||
v_flags2 => ["-Oi"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
21
test_regress/t/t_mod_interface_array5.pl
Executable file
21
test_regress/t/t_mod_interface_array5.pl
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2021 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
112
test_regress/t/t_mod_interface_array5.v
Normal file
112
test_regress/t/t_mod_interface_array5.v
Normal file
@ -0,0 +1,112 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2021 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`define stop $stop
|
||||
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0)
|
||||
|
||||
interface intf ();
|
||||
integer value;
|
||||
endinterface
|
||||
|
||||
module fanout
|
||||
#(parameter int N = 1)
|
||||
(
|
||||
intf upstream,
|
||||
intf downstream[N-1:0]
|
||||
);
|
||||
|
||||
genvar i;
|
||||
for (i = 0; i < N; i = i + 1)
|
||||
assign downstream[i].value = upstream.value;
|
||||
|
||||
endmodule
|
||||
|
||||
module xbar
|
||||
(
|
||||
input logic clk,
|
||||
input int cyc,
|
||||
intf Masters[1:0]
|
||||
);
|
||||
|
||||
localparam NUM_DEMUX_OUT = 2 * 4;
|
||||
localparam NUM_MUX_IN = 2 * 4;
|
||||
intf demuxOut[NUM_DEMUX_OUT-1:0]();
|
||||
intf muxIn[NUM_MUX_IN-1:0]();
|
||||
|
||||
//fan out master connections to the crossbar matrix
|
||||
fanout #(.N(4)) fanout_inst0
|
||||
(.upstream(Masters[0]),
|
||||
.downstream(demuxOut[3:0]));
|
||||
|
||||
fanout #(.N(4)) fanout_inst1
|
||||
(.upstream(Masters[1]),
|
||||
.downstream(demuxOut[7:4]));
|
||||
|
||||
//the crossbar matrix assignments, done as 1D arrays because verilator doesn't currently support >1D arrays of interfaces
|
||||
genvar slv, mst;
|
||||
for (slv = 0; slv < 4; slv = slv + 1) begin
|
||||
for (mst = 0; mst < 2; mst = mst + 1) begin
|
||||
localparam int muxIdx = (slv*2)+mst;
|
||||
localparam int demuxIdx = slv+(mst*4);
|
||||
assign muxIn[muxIdx].value = demuxOut[demuxIdx].value;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (cyc == 5) begin
|
||||
`checkh(Masters[0].value, 2);
|
||||
`checkh(Masters[1].value, 1);
|
||||
// The first 4 demuxOut values should have the value of the first Master
|
||||
`checkh(demuxOut[0].value, Masters[0].value);
|
||||
`checkh(demuxOut[1].value, Masters[0].value);
|
||||
`checkh(demuxOut[2].value, Masters[0].value);
|
||||
`checkh(demuxOut[3].value, Masters[0].value);
|
||||
// The next 4 demuxOut values should have the value of the second Master
|
||||
`checkh(demuxOut[4].value, Masters[1].value);
|
||||
`checkh(demuxOut[5].value, Masters[1].value);
|
||||
`checkh(demuxOut[6].value, Masters[1].value);
|
||||
`checkh(demuxOut[7].value, Masters[1].value);
|
||||
// Each 2 mux inputs should have one input from each master, in order from low to high
|
||||
`checkh(muxIn[0].value, Masters[0].value);
|
||||
`checkh(muxIn[1].value, Masters[1].value);
|
||||
`checkh(muxIn[2].value, Masters[0].value);
|
||||
`checkh(muxIn[3].value, Masters[1].value);
|
||||
`checkh(muxIn[4].value, Masters[0].value);
|
||||
`checkh(muxIn[5].value, Masters[1].value);
|
||||
`checkh(muxIn[6].value, Masters[0].value);
|
||||
`checkh(muxIn[7].value, Masters[1].value);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module t
|
||||
(
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
intf masters[1:0]();
|
||||
|
||||
int cyc;
|
||||
|
||||
xbar sub
|
||||
(.clk,
|
||||
.cyc,
|
||||
.Masters(masters));
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc == 1) begin
|
||||
masters[0].value <= 2;
|
||||
masters[1].value <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
21
test_regress/t/t_mod_interface_array6.pl
Executable file
21
test_regress/t/t_mod_interface_array6.pl
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2021 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
158
test_regress/t/t_mod_interface_array6.v
Normal file
158
test_regress/t/t_mod_interface_array6.v
Normal file
@ -0,0 +1,158 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2021 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
`define stop $stop
|
||||
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0)
|
||||
|
||||
interface intf ();
|
||||
integer index;
|
||||
endinterface
|
||||
|
||||
module t
|
||||
(
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
intf ifa1_intf[4:1]();
|
||||
intf ifa2_intf[4:1]();
|
||||
intf ifb1_intf[1:4]();
|
||||
intf ifb2_intf[1:4]();
|
||||
|
||||
int cyc;
|
||||
|
||||
sub sub0
|
||||
(
|
||||
.n(0),
|
||||
.clk,
|
||||
.cyc,
|
||||
.alh(ifa1_intf[2:1]),
|
||||
.ahl(ifa2_intf[2:1]),
|
||||
.blh(ifb1_intf[1:2]),
|
||||
.bhl(ifb2_intf[1:2])
|
||||
);
|
||||
|
||||
sub sub1
|
||||
(
|
||||
.n(1),
|
||||
.clk,
|
||||
.cyc,
|
||||
.alh(ifa1_intf[4:3]),
|
||||
.ahl(ifa2_intf[4:3]),
|
||||
.blh(ifb1_intf[3:4]),
|
||||
.bhl(ifb2_intf[3:4])
|
||||
);
|
||||
|
||||
`ifndef verilator // Backwards slicing not supported
|
||||
sub sub2
|
||||
(
|
||||
.n(2),
|
||||
.clk,
|
||||
.cyc,
|
||||
.alh(ifa1_intf[1:2]), // backwards vs decl
|
||||
.ahl(ifa2_intf[1:2]), // backwards vs decl
|
||||
.blh(ifb1_intf[2:1]), // backwards vs decl
|
||||
.bhl(ifb2_intf[2:1]) // backwards vs decl
|
||||
);
|
||||
|
||||
sub sub3
|
||||
(
|
||||
.n(3),
|
||||
.clk,
|
||||
.cyc,
|
||||
.alh(ifa1_intf[3:4]), // backwards vs decl
|
||||
.ahl(ifa2_intf[3:4]), // backwards vs decl
|
||||
.blh(ifb1_intf[4:3]), // backwards vs decl
|
||||
.bhl(ifb2_intf[4:3]) // backwards vs decl
|
||||
);
|
||||
`endif
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc == 1) begin
|
||||
ifa1_intf[1].index = 'h101;
|
||||
ifa1_intf[2].index = 'h102;
|
||||
ifa1_intf[3].index = 'h103;
|
||||
ifa1_intf[4].index = 'h104;
|
||||
ifa2_intf[1].index = 'h201;
|
||||
ifa2_intf[2].index = 'h202;
|
||||
ifa2_intf[3].index = 'h203;
|
||||
ifa2_intf[4].index = 'h204;
|
||||
ifb1_intf[1].index = 'h301;
|
||||
ifb1_intf[2].index = 'h302;
|
||||
ifb1_intf[3].index = 'h303;
|
||||
ifb1_intf[4].index = 'h304;
|
||||
ifb2_intf[1].index = 'h401;
|
||||
ifb2_intf[2].index = 'h402;
|
||||
ifb2_intf[3].index = 'h403;
|
||||
ifb2_intf[4].index = 'h404;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module sub
|
||||
(
|
||||
input logic clk,
|
||||
input int cyc,
|
||||
input int n,
|
||||
intf alh[1:2],
|
||||
intf ahl[2:1],
|
||||
intf blh[1:2],
|
||||
intf bhl[2:1]
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
|
||||
if (cyc == 5) begin
|
||||
if (n == 0) begin
|
||||
`checkh(alh[1].index, 'h102);
|
||||
`checkh(alh[2].index, 'h101);
|
||||
`checkh(ahl[1].index, 'h201);
|
||||
`checkh(ahl[2].index, 'h202);
|
||||
`checkh(blh[1].index, 'h301);
|
||||
`checkh(blh[2].index, 'h302);
|
||||
`checkh(bhl[1].index, 'h402);
|
||||
`checkh(bhl[2].index, 'h401);
|
||||
end
|
||||
else if (n == 1) begin
|
||||
`checkh(alh[1].index, 'h104);
|
||||
`checkh(alh[2].index, 'h103);
|
||||
`checkh(ahl[1].index, 'h203);
|
||||
`checkh(ahl[2].index, 'h204);
|
||||
`checkh(blh[1].index, 'h303);
|
||||
`checkh(blh[2].index, 'h304);
|
||||
`checkh(bhl[1].index, 'h404);
|
||||
`checkh(bhl[2].index, 'h403);
|
||||
end
|
||||
else if (n == 2) begin
|
||||
`checkh(alh[1].index, 'h101);
|
||||
`checkh(alh[2].index, 'h102);
|
||||
`checkh(ahl[1].index, 'h202);
|
||||
`checkh(ahl[2].index, 'h201);
|
||||
`checkh(blh[1].index, 'h302);
|
||||
`checkh(blh[2].index, 'h301);
|
||||
`checkh(bhl[1].index, 'h401);
|
||||
`checkh(bhl[2].index, 'h402);
|
||||
end
|
||||
else if (n == 3) begin
|
||||
`checkh(alh[1].index, 'h103);
|
||||
`checkh(alh[2].index, 'h104);
|
||||
`checkh(ahl[1].index, 'h204);
|
||||
`checkh(ahl[2].index, 'h203);
|
||||
`checkh(blh[1].index, 'h304);
|
||||
`checkh(blh[2].index, 'h303);
|
||||
`checkh(bhl[1].index, 'h403);
|
||||
`checkh(bhl[2].index, 'h404);
|
||||
end
|
||||
end
|
||||
if (cyc == 9 && n == 0) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
24
test_regress/t/t_mod_interface_array6_noinl.pl
Executable file
24
test_regress/t/t_mod_interface_array6_noinl.pl
Executable file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env 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.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_mod_interface_array6.v");
|
||||
|
||||
compile(
|
||||
v_flags2 => ["-Oi"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
Loading…
Reference in New Issue
Block a user