From 8281ee1520df0f0d1d4f9f10eaa2fbe708f253ef Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 4 Oct 2017 22:10:44 -0400 Subject: [PATCH] Optimize arrayed if assignments --- src/V3AstNodes.h | 2 +- src/V3Const.cpp | 6 +--- test_regress/t/t_optm_if_array.pl | 20 ++++++++++++ test_regress/t/t_optm_if_array.v | 51 +++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 6 deletions(-) create mode 100755 test_regress/t/t_optm_if_array.pl create mode 100644 test_regress/t/t_optm_if_array.v diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 02de11a47..cd9232d63 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -790,7 +790,7 @@ public: virtual bool cleanOut() { return true; } virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;} virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;} - virtual bool isGateOptimizable() const { return false; } + virtual bool isGateOptimizable() const { return true; } // esp for V3Const::ifSameAssign virtual bool isPredictOptimizable() const { return false; } virtual V3Hash sameHash() const { return V3Hash(); } virtual bool same(AstNode* samep) const { return true; } diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 3540a8967..39df8c73b 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -485,11 +485,7 @@ private: if (!ifp || ifp->nextp()) return false; // Must be SINGLE statement if (!elsep || elsep->nextp()) return false; if (ifp->type() != elsep->type()) return false; // Can't mix an assigndly and an assign - AstVarRef* ifvarp = ifp->lhsp()->castVarRef(); - AstVarRef* elsevarp = elsep->lhsp()->castVarRef(); - if (!ifvarp || !elsevarp) return false; - if (ifvarp->isWide()) return false; // Would need temporaries, so not worth it - if (!ifvarp->sameGateTree(elsevarp)) return false; + if (!ifp->lhsp()->sameGateTree(elsep->lhsp())) return false; if (!ifp->rhsp()->gateTree()) return false; if (!elsep->rhsp()->gateTree()) return false; return true; diff --git a/test_regress/t/t_optm_if_array.pl b/test_regress/t/t_optm_if_array.pl new file mode 100755 index 000000000..c39ed396f --- /dev/null +++ b/test_regress/t/t_optm_if_array.pl @@ -0,0 +1,20 @@ +#!/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, + ); + +file_grep_not ("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/rstn_r/); + +ok(1); +1; diff --git a/test_regress/t/t_optm_if_array.v b/test_regress/t/t_optm_if_array.v new file mode 100644 index 000000000..bfcd1f03e --- /dev/null +++ b/test_regress/t/t_optm_if_array.v @@ -0,0 +1,51 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2017 by Wilson Snyder. + +module t (/*AUTOARG*/ + // Outputs + dinitout, + // Inputs + clk, rstn + ); + + input clk; + input rstn; + output [31:0] dinitout; + + wire zero; + assign zero = 1'd0; + + reg [31:0] dinit [0:1]; + wire [31:0] dinitout = dinit[0] | dinit[1]; + + reg rstn_r; // .pl file checks that this signal gets optimized away + always @(posedge clk) begin + rstn_r <= rstn; + end + + always @(posedge clk) begin + if ((rstn_r == 0)) begin // Will optimize away + dinit[0] <= '0; + end + else begin + dinit[0] <= {31'd0, zero}; + end + end + + always @(posedge clk) begin + if ((rstn_r == 0)) begin // Will optimize away + dinit[1] <= 1234; + end + else begin + dinit[1] <= 1234; + end + end + + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule