From 37a3a7cdcede7f6b8a567dbdfac8eb14cc9fb2bd Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 9 May 2012 20:34:15 -0400 Subject: [PATCH] Fix tristate bug512, broken with tristate commit. --- src/V3Tristate.cpp | 13 +++++---- test_regress/t/t_tri_ifbegin.pl | 16 ++++++++++ test_regress/t/t_tri_ifbegin.v | 52 +++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 5 deletions(-) create mode 100755 test_regress/t/t_tri_ifbegin.pl create mode 100644 test_regress/t/t_tri_ifbegin.v diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 74ec2b09d..805417659 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -456,13 +456,16 @@ class TristateVisitor : public TristateBaseVisitor { // Check for unsupported tristate constructs. This is not a 100% check. // The best way would be to visit the tree again and find any user1p() // pointers that did not get picked up and expanded. - if (m_alhs && nodep->user1p()) + if (m_alhs && nodep->user1p()) { nodep->v3error("Unsupported LHS tristate construct: "<prettyTypeName()); - if ((nodep->op1p() && nodep->op1p()->user1p()) - || (nodep->op2p() && nodep->op2p()->user1p()) - || (nodep->op3p() && nodep->op3p()->user1p()) - || (nodep->op4p() && nodep->op4p()->user1p())) + } + // Ignore Var's because they end up adjacent to statements + if ((nodep->op1p() && nodep->op1p()->user1p() && !nodep->op1p()->castVar()) + || (nodep->op2p() && nodep->op2p()->user1p() && !nodep->op1p()->castVar()) + || (nodep->op3p() && nodep->op3p()->user1p() && !nodep->op1p()->castVar()) + || (nodep->op4p() && nodep->op4p()->user1p() && !nodep->op1p()->castVar())) { nodep->v3error("Unsupported tristate construct: "<prettyTypeName()); + } } void insertTristates(AstNodeModule* nodep) { diff --git a/test_regress/t/t_tri_ifbegin.pl b/test_regress/t/t_tri_ifbegin.pl new file mode 100755 index 000000000..fb2f3bf0c --- /dev/null +++ b/test_regress/t/t_tri_ifbegin.pl @@ -0,0 +1,16 @@ +#!/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 ( + ); + +# No exeecution + +ok(1); +1; diff --git a/test_regress/t/t_tri_ifbegin.v b/test_regress/t/t_tri_ifbegin.v new file mode 100644 index 000000000..21f1f104b --- /dev/null +++ b/test_regress/t/t_tri_ifbegin.v @@ -0,0 +1,52 @@ +// DESCRIPTION: Verilator: Verilog Test module + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + tri pad_io_h; + tri pad_io_l; + + sub sub (.*); + +endmodule + + +module sub (/*AUTOARG*/ + // Inouts + pad_io_h, pad_io_l + ); + + parameter USE = 1'b1; + parameter DIFFERENTIAL = 1'b1; + parameter BIDIR = 1'b1; + + inout pad_io_h; + inout pad_io_l; + + wire [31:0] dqs_out_dtap_delay; + + generate + if (USE) begin: output_strobe + wire aligned_os_oe; + wire aligned_strobe; + + if (BIDIR) begin + reg sig_h_r = 1'b0; + reg sig_l_r = 1'b0; + always @* begin + sig_h_r = ~aligned_os_oe ? aligned_strobe : 1'bz; + if (DIFFERENTIAL) + sig_l_r = ~aligned_os_oe ? ~aligned_strobe : 1'bz; + end + assign pad_io_h = sig_h_r; + if (DIFFERENTIAL) + assign pad_io_l = sig_l_r; + end + end + endgenerate + +endmodule +