Fix generated inouts with duplicated modules, bug498.

This commit is contained in:
Wilson Snyder 2012-04-27 19:41:13 -04:00
parent d9598db117
commit 641024c235
6 changed files with 74 additions and 6 deletions

View File

@ -632,6 +632,8 @@ void AstVar::dump(ostream& str) {
else if (isOutput()) str<<" [O]";
}
if (isConst()) str<<" [CONST]";
if (isPullup()) str<<" [PULLUP]";
if (isPulldown()) str<<" [PULLDOWN]";
if (isUsedClock()) str<<" [CLK]";
if (isSigPublic()) str<<" [P]";
if (isUsedLoopIdx()) str<<" [LOOP]";

View File

@ -237,7 +237,7 @@ public:
//######################################################################
// Inst class functions
AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* modp, bool forTristate) {
AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule*, bool forTristate) {
// If a pin connection is "simple" leave it as-is
// Else create a intermediate wire to perform the interconnect
// Return the new assignment, if one was made
@ -269,7 +269,8 @@ AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModu
AstNode* pinexprp = pinp->exprp()->unlinkFrBack();
string newvarname = "__Vcellinp__"+cellp->name()+"__"+pinp->name();
AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
modp->addStmtp(newvarp);
// Important to add statement next to cell, in case there is a generate with same named cell
cellp->addNextHere(newvarp);
if (pinVarp->isInout()) {
pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)");
} else if (pinVarp->isOutput()) {
@ -296,7 +297,7 @@ AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModu
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false));
}
pinp->widthSignedFrom(pinp->exprp());
if (assignp) modp->addStmtp(assignp);
if (assignp) cellp->addNextHere(assignp);
//if (1||debug()) { pinp->dumpTree(cout," out:"); }
//if (1||debug()) { assignp->dumpTree(cout," aout:"); }
}

View File

@ -591,6 +591,7 @@ class TristateVisitor : public TristateBaseVisitor {
// Propagate any pullups/pulldowns upwards if necessary
if (refp) {
if (AstPull* pullp = (AstPull*) nodep->modVarp()->user3p()) {
UINFO(9, "propagate pull to "<<refp->varp());
if (!refp->varp()->user3p()) {
refp->varp()->user3p(pullp);
} else {
@ -636,6 +637,7 @@ class TristateVisitor : public TristateBaseVisitor {
AstNode* newp = new AstPull(nodep->fileline(),
new AstVarRef(nodep->fileline(), nodep, true),
nodep->isPullup());
UINFO(9,"New pull "<<newp);
m_modp->addStmtp(newp);
// We'll iterate on the new AstPull later
}
@ -725,6 +727,7 @@ class TristateVisitor : public TristateBaseVisitor {
//
outvarp->user1p(envarp);
outvarp->user3p(invarp->user3p());
if (invarp->user3p()) UINFO(9, "propagate pull to "<<outvarp);
} else if (invarp->user1p()) {
envarp = invarp->user1p()->castNode()->castVar(); // From CASEEQ, foo === 1'bz
}
@ -788,6 +791,7 @@ class TristateVisitor : public TristateBaseVisitor {
AstPull* pullp = (AstPull*)lhsp->user3p();
if (pullp && pullp->direction() == 1) {
pull.setAllBits1();
UINFO(9,"Has pullup "<<pullp<<endl);
} else {
pull.setAllBits0(); // default pull direction is down.
}

View File

@ -868,9 +868,9 @@ portDirNetE: // IEEE: part of port, optional net type and/or direction
/* empty */ { }
// // Per spec, if direction given default the nettype.
// // The higher level rule may override this VARDTYPE with one later in the parse.
| port_direction { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); }
| port_direction net_type { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); } // net_type calls VARNET
| net_type { } // net_type calls VARNET
| port_direction { VARDECL(PORT); VARDTYPE(NULL/*default_nettype*/); }
| port_direction { VARDECL(PORT); } net_type { VARDTYPE(NULL/*default_nettype*/); } // net_type calls VARNET
| net_type { } // net_type calls VARNET
;
port_declNetE: // IEEE: part of port_declaration, optional net type

18
test_regress/t/t_tri_gen.pl Executable file
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,43 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2012 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
tri z0;
tri z1;
updown #(0) updown0 (.z(z0));
updown #(1) updown1 (.z(z1));
always @ (posedge clk) begin
if (z0 !== 0) $stop;
if (z1 !== 1) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
module updown #(parameter UP=0)
(inout z);
generate
if (UP) begin
t_up sub (.z);
end
else begin
t_down sub (.z);
end
endgenerate
endmodule
module t_up (inout tri1 z);
endmodule
module t_down (inout tri0 z);
endmodule