From 074ca9330d75433728c97febad7b06aab38befe2 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 18 Feb 2011 20:52:26 -0500 Subject: [PATCH] Make width violation on function outputs a fatal error --- src/V3Width.cpp | 9 +++++++++ test_regress/t/t_func_wide_out_bad.pl | 19 ++++++++++++++++++ test_regress/t/t_func_wide_out_bad.v | 29 +++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100755 test_regress/t/t_func_wide_out_bad.pl create mode 100644 test_regress/t/t_func_wide_out_bad.v diff --git a/src/V3Width.cpp b/src/V3Width.cpp index ce8d87149..23856cb91 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1007,6 +1007,15 @@ private: } else { // Do PRELIM again, because above accept may have exited early due to node replacement pinp->accept(*this,WidthVP(portp->width(),portp->widthMin(),BOTH).p()); + if ((portp->isOutput() || portp->isInout()) + && pinp->width() != portp->width()) { + pinp->v3error("Unsupported: Function output argument '"<prettyName()<<"'" + <<" requires "<width() + <<" bits, but connection's "<prettyTypeName() + <<" generates "<width()<<" bits."); + // otherwise would need some mess to force both sides to proper size + // (get an ASSIGN with EXTEND on the lhs instead of rhs) + } if (portp->basicp() && !portp->basicp()->isOpaque()) { widthCheck(nodep,"Function Argument",pinp,portp->width(),portp->widthMin()); } diff --git a/test_regress/t/t_func_wide_out_bad.pl b/test_regress/t/t_func_wide_out_bad.pl new file mode 100755 index 000000000..b5d361523 --- /dev/null +++ b/test_regress/t/t_func_wide_out_bad.pl @@ -0,0 +1,19 @@ +#!/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 ( + v_flags2 => ["--lint-only"], + fails=>1, + expect=> +q{%Error: t/t_func_wide_out_bad.v:\d+: Unsupported: Function output argument 'data' requires 4350 bits, but connection's VARREF 'msg' generates 4352 bits. +%Error: Exiting due to.*}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_func_wide_out_bad.v b/test_regress/t/t_func_wide_out_bad.v new file mode 100644 index 000000000..c23808845 --- /dev/null +++ b/test_regress/t/t_func_wide_out_bad.v @@ -0,0 +1,29 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2003 by Wilson Snyder. + +module t (); + + parameter MSG_PORT_WIDTH = 4350; + localparam PAYLOAD_MAX_BITS = 4352; + + reg [MSG_PORT_WIDTH-1:0] msg; + + initial begin + // Operator TASKREF 'func' expects 4352 bits on the Function Argument, but Function Argument's VARREF 'msg' generates 4350 bits. + // verilator lint_off WIDTH + func(msg); + // verilator lint_on WIDTH + if (msg !== {MSG_PORT_WIDTH{1'b1}}) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + + function integer func (output bit [PAYLOAD_MAX_BITS-1:0] data); + /*verilator no_inline_task*/ + data = {PAYLOAD_MAX_BITS{1'b1}}; + return (1); + endfunction + +endmodule