From 5a747bad7d347074dc10e1fc7e924e16406baddd Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 13 May 2015 20:59:13 -0400 Subject: [PATCH] Fix width extension on mis-width ports, bug918. --- Changes | 2 ++ src/V3Inst.cpp | 10 +++++-- test_regress/t/t_inst_implicit.pl | 18 +++++++++++ test_regress/t/t_inst_implicit.v | 50 +++++++++++++++++++++++++++++++ test_regress/t/t_inst_signed.v | 4 --- 5 files changed, 77 insertions(+), 7 deletions(-) create mode 100755 test_regress/t/t_inst_implicit.pl create mode 100644 test_regress/t/t_inst_implicit.v diff --git a/Changes b/Changes index 19bd0f854..5b88d6a03 100644 --- a/Changes +++ b/Changes @@ -17,6 +17,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix part-select in constant function, bug916. [Andrew Bardsley] +**** Fix width extension on mis-width ports, bug918. [Patrick Maupin] + * Verilator 3.872 2015-04-05 diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index 42af23709..8a9007775 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -256,10 +256,12 @@ private: rhsp = (rhsp->isSigned() ? (new AstExtendS(fl, rhsp))->castNode() : (new AstExtend (fl, rhsp))->castNode()); + rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above } else if (cmpWidthp->width() < rhsp->width()) { rhsp = new AstSel (fl, rhsp, 0, cmpWidthp->width()); + rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above } - rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above + // else don't change dtype, as might be e.g. array of something return rhsp; } @@ -312,9 +314,11 @@ public: } else if (pinVarp->isOutput()) { // See also V3Inst AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false); + UINFO(5,"pinRecon width "<width()<<" >? "<width()<<" >? "<width()<fileline(), rhsp, pinVarp); - assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsp); - pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, true)); + pinp->exprp(new AstVarRef (newvarp->fileline(), newvarp, true)); + AstNode* rhsSelp = extendOrSel (pinp->fileline(), rhsp, pinexprp); + assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsSelp); } else { // V3 width should have range/extended to make the widths correct assignp = new AstAssignW (pinp->fileline(), diff --git a/test_regress/t/t_inst_implicit.pl b/test_regress/t/t_inst_implicit.pl new file mode 100755 index 000000000..f91289753 --- /dev/null +++ b/test_regress/t/t_inst_implicit.pl @@ -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; diff --git a/test_regress/t/t_inst_implicit.v b/test_regress/t/t_inst_implicit.v new file mode 100644 index 000000000..f1875ce2a --- /dev/null +++ b/test_regress/t/t_inst_implicit.v @@ -0,0 +1,50 @@ +// DESCRIPTION:tor:ilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2015 by Wilson Snyder. + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + wire [31:0] o; + wire [31:0] oe; + + Test test (/*AUTOINST*/ + // Outputs + .o (o[31:0]), + .oe (oe[31:0])); + + // Test loop + always @ (posedge clk) begin + if (o !== 32'h00000001) $stop; + if (oe !== 32'h00000001) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule + +module subimp(o,oe); + output [31:0] o; + assign o = 32'h12345679; + output [31:0] oe; + assign oe = 32'hab345679; +endmodule + +module Test(o,oe); + output [31:0] o; + output [31:0] oe; + wire [31:0] xe; + assign xe[31:1] = 0; + // verilator lint_off IMPLICIT + // verilator lint_off WIDTH + subimp subimp(x, // x is implicit and one bit + xe[0]); // xe explicit one bit + assign o = x; + assign oe = xe; + // verilator lint_on WIDTH + // verilator lint_on IMPLICIT +endmodule diff --git a/test_regress/t/t_inst_signed.v b/test_regress/t/t_inst_signed.v index de9fc8547..acea72eb0 100644 --- a/test_regress/t/t_inst_signed.v +++ b/test_regress/t/t_inst_signed.v @@ -29,12 +29,8 @@ module t (/*AUTOARG*/ `endif if (sgn_wide[2:0] != 3'sh7) $stop; if (unsgn_wide[2:0] != 3'h7) $stop; - if (sgn_wide !== 8'sh7) $stop; // Simulators differ here. if (sgn_wide !== 8'sbzzzzz111 // z-extension - NC -`ifdef VERILATOR - && sgn_wide !== 8'sb00000111 // 0-extension - verilator as it doesn't have Z -`endif && sgn_wide !== 8'sb11111111) $stop; // sign extension - VCS if (unsgn_wide !== 8'sbzzzzz111 && unsgn_wide!== 8'sb00000111) $stop;