forked from github/verilator
Fix pullup/pulldowns on bit selects, bug1274.
This commit is contained in:
parent
7f5b1a402c
commit
1376e5de92
2
Changes
2
Changes
@ -6,6 +6,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
**** Fix GCC 8.0 issues, bug1273.
|
||||
|
||||
**** Fix pullup/pulldowns on bit selects, bug1274. [Rob Stoddard]
|
||||
|
||||
|
||||
* Verilator 3.920 2018-02-01
|
||||
|
||||
|
@ -984,32 +984,37 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||
|
||||
virtual void visit(AstPull* nodep) {
|
||||
UINFO(9,dbgState()<<nodep<<endl);
|
||||
if (m_graphing) {
|
||||
if (AstVarRef* lhsp = nodep->lhsp()->castVarRef()) {
|
||||
lhsp->lvalue(true);
|
||||
m_logicp = nodep;
|
||||
m_tgraph.setTristate(nodep);
|
||||
associateLogic(nodep, lhsp->varp());
|
||||
m_logicp = NULL;
|
||||
} else {
|
||||
nodep->v3error("Unsupported pullup/down (weak driver) construct.");
|
||||
}
|
||||
} else {
|
||||
// Replace any pullup/pulldowns with assignw logic and set the
|
||||
// direction of the pull in the user3() data on the var. Given
|
||||
// the complexity of merging tristate drivers at any level, the
|
||||
// current limitation of this implementation is that a pullup/down
|
||||
// gets applied to all bits of a bus and a bus cannot have drivers
|
||||
// in opposite directions on indvidual pins.
|
||||
if (AstVarRef* lhsp = nodep->lhsp()->castVarRef()) {
|
||||
lhsp->lvalue(true);
|
||||
m_tgraph.didProcess(nodep);
|
||||
m_tgraph.didProcess(lhsp->varp());
|
||||
AstVar* varp = lhsp->varp();
|
||||
setPullDirection(varp, nodep);
|
||||
} else {
|
||||
nodep->v3error("Unsupported pullup/down (weak driver) construct.");
|
||||
}
|
||||
AstVarRef* varrefp = NULL;
|
||||
if (nodep->lhsp()->castVarRef()) {
|
||||
varrefp = nodep->lhsp()->castVarRef();
|
||||
} else if (nodep->lhsp()->castSel()
|
||||
&& nodep->lhsp()->castSel()->fromp()->castVarRef()) {
|
||||
varrefp = nodep->lhsp()->castSel()->fromp()->castVarRef();
|
||||
}
|
||||
if (!varrefp) {
|
||||
if (debug()>=4) nodep->dumpTree(cout, "- ");
|
||||
nodep->v3error("Unsupported pullup/down (weak driver) construct.");
|
||||
} else {
|
||||
if (m_graphing) {
|
||||
varrefp->lvalue(true);
|
||||
m_logicp = nodep;
|
||||
m_tgraph.setTristate(nodep);
|
||||
associateLogic(nodep, varrefp->varp());
|
||||
m_logicp = NULL;
|
||||
} else {
|
||||
// Replace any pullup/pulldowns with assignw logic and set the
|
||||
// direction of the pull in the user3() data on the var. Given
|
||||
// the complexity of merging tristate drivers at any level, the
|
||||
// current limitation of this implementation is that a pullup/down
|
||||
// gets applied to all bits of a bus and a bus cannot have drivers
|
||||
// in opposite directions on indvidual pins.
|
||||
varrefp->lvalue(true);
|
||||
m_tgraph.didProcess(nodep);
|
||||
m_tgraph.didProcess(varrefp->varp());
|
||||
setPullDirection(varrefp->varp(), nodep);
|
||||
}
|
||||
}
|
||||
if (!m_graphing) {
|
||||
nodep->unlinkFrBack();
|
||||
pushDeletep(nodep); VL_DANGLING(nodep); // Node must persist as user3p points to it
|
||||
}
|
||||
|
@ -556,6 +556,7 @@ private:
|
||||
// LSB is self-determined (IEEE 2012 11.5.1)
|
||||
// We also use SELs to shorten a signed constant etc, in this case they are signed.
|
||||
if (nodep->didWidth()) return;
|
||||
if (!m_vup) nodep->v3fatalSrc("Select under an unexpected context");
|
||||
if (m_vup->prelim()) {
|
||||
if (debug()>=9) nodep->dumpTree(cout,"-selWidth: ");
|
||||
userIterateAndNext(nodep->fromp(), WidthVP(CONTEXT,PRELIM).p());
|
||||
@ -949,6 +950,10 @@ private:
|
||||
}
|
||||
m_attrp = oldAttr;
|
||||
}
|
||||
virtual void visit(AstPull* nodep) {
|
||||
// May have select underneath, let seek natural size
|
||||
userIterateChildren(nodep, WidthVP(SELF,BOTH).p());
|
||||
}
|
||||
virtual void visit(AstText* nodep) {
|
||||
// Only used in CStmts which don't care....
|
||||
}
|
||||
|
18
test_regress/t/t_tri_array_pull.pl
Executable file
18
test_regress/t/t_tri_array_pull.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;
|
43
test_regress/t/t_tri_array_pull.v
Normal file
43
test_regress/t/t_tri_array_pull.v
Normal file
@ -0,0 +1,43 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2018 by Rod Steward.
|
||||
|
||||
module IOBUF ( input T, input I, output O, inout IO );
|
||||
assign O = IO;
|
||||
assign IO = T ? 1'bz : I;
|
||||
endmodule
|
||||
|
||||
module t
|
||||
(
|
||||
input [7:0] inlines,
|
||||
output [7:0] outlines,
|
||||
inout [7:0] iolines,
|
||||
|
||||
input inctrl
|
||||
);
|
||||
|
||||
generate for (genvar i = 4; i < 8; i = i+1) begin: Gen_D
|
||||
IOBUF d ( .T(inctrl), .I(inlines[i]), .O(outlines[i]), .IO(iolines[i]) );
|
||||
pullup d_pup (iolines[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
IOBUF d_0 ( .T(inctrl), .I(inlines[0]), .O(outlines[0]), .IO(iolines[0]) );
|
||||
pullup d_0_pup (iolines[0]);
|
||||
|
||||
IOBUF d_1 ( .T(inctrl), .I(inlines[1]), .O(outlines[1]), .IO(iolines[1]) );
|
||||
pullup d_1_pup (iolines[1]);
|
||||
|
||||
IOBUF d_2 ( .T(inctrl), .I(inlines[2]), .O(outlines[2]), .IO(iolines[2]) );
|
||||
pullup d_2_pup (iolines[2]);
|
||||
|
||||
IOBUF d_3 ( .T(inctrl), .I(inlines[3]), .O(outlines[3]), .IO(iolines[3]) );
|
||||
pullup d_3_pup (iolines[3]);
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
23
test_regress/t/t_tri_pullvec_bad.pl
Executable file
23
test_regress/t/t_tri_pullvec_bad.pl
Executable file
@ -0,0 +1,23 @@
|
||||
#!/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.
|
||||
|
||||
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--lint-only"],
|
||||
fails=>$Self->{v3},
|
||||
expect=>
|
||||
'%Error: t/t_tri_pullvec_bad.v:\d+: Unsupported: Conflicting pull directions.
|
||||
%Error: t/t_tri_pullvec_bad.v:\d+: ... Location of conflicting pull.
|
||||
%Error: t/t_tri_pullvec_bad.v:\d+: Unsupported: Conflicting pull directions.
|
||||
%Error: Exiting due to .*'
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
19
test_regress/t/t_tri_pullvec_bad.v
Normal file
19
test_regress/t/t_tri_pullvec_bad.v
Normal file
@ -0,0 +1,19 @@
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2018 by Wilson Snyder
|
||||
|
||||
module t (clk);
|
||||
input clk;
|
||||
|
||||
tri [3:0] w;
|
||||
|
||||
pullup p0 (w[0]);
|
||||
pulldown p1 (w[1]);
|
||||
pulldown p2 (w[2]);
|
||||
pullup p3 (w[3]);
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (w != 4'b1001) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user