diff --git a/Changes b/Changes index 60ee08374..d90693a1c 100644 --- a/Changes +++ b/Changes @@ -13,6 +13,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Report UNUSED on parameters, localparam and genvars (#2627). [Charles Eric LaForest] +**** Add error on real to non-real output pins (#2690). [Peter Monsson] + **** Fix passing parameter type instantiations by position number. **** Fix DPI open array handling issues. diff --git a/src/V3Width.cpp b/src/V3Width.cpp index f2bac55e0..4a1207dbd 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -4183,6 +4183,8 @@ private: << conDTypep->prettyDTypeNameQ() << " data type."); } else if (nodep->modVarp()->isTristate()) { if (pinwidth != conwidth) { + // Ideally should call pinReconnectSimple which would tolerate this + // then have a conversion warning nodep->v3warn(E_UNSUPPORTED, "Unsupported: " << ucfirst(nodep->prettyOperatorName()) << " to inout signal requires " << pinwidth @@ -4191,7 +4193,14 @@ private: << " generates " << conwidth << " bits."); // otherwise would need some mess to force both sides to proper size } + } else if (nodep->modVarp()->direction().isWritable() + && ((conDTypep->isDouble() && !modDTypep->isDouble()) + || (!conDTypep->isDouble() && modDTypep->isDouble()))) { + nodep->v3warn(E_UNSUPPORTED, + "Unsupported: " << ucfirst(nodep->prettyOperatorName()) + << " connects real to non-real"); } + // Check if an interface is connected to a non-interface and vice versa if ((VN_IS(modDTypep, IfaceRefDType) && !VN_IS(conDTypep, IfaceRefDType)) || (VN_IS(conDTypep, IfaceRefDType) && !VN_IS(modDTypep, IfaceRefDType))) { diff --git a/test_regress/t/t_inst_pin_realnreal.out b/test_regress/t/t_inst_pin_realnreal.out new file mode 100755 index 000000000..34eade000 --- /dev/null +++ b/test_regress/t/t_inst_pin_realnreal.out @@ -0,0 +1,5 @@ +%Error-UNSUPPORTED: t/t_inst_pin_realnreal.v:51:32: Unsupported: Output port connection 'out' connects real to non-real + : ... In instance t.netlist + 51 | pga_model pga0(.in, .gain, .out(pga_out)); + | ^~~ +%Error: Exiting due to diff --git a/test_regress/t/t_inst_pin_realnreal.pl b/test_regress/t/t_inst_pin_realnreal.pl new file mode 100755 index 000000000..40f69d41d --- /dev/null +++ b/test_regress/t/t_inst_pin_realnreal.pl @@ -0,0 +1,23 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2019 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. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +compile( + fails => $Self->{vlt_all}, + expect_filename => $Self->{golden_filename}, + ); + +execute( + check_finished => 1, + ) if !$Self->{vlt_all}; + +ok(1); +1; diff --git a/test_regress/t/t_inst_pin_realnreal.v b/test_regress/t/t_inst_pin_realnreal.v new file mode 100644 index 000000000..5c5539661 --- /dev/null +++ b/test_regress/t/t_inst_pin_realnreal.v @@ -0,0 +1,76 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2020 by Peter Monsson. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + integer cyc; initial cyc=1; + + wire gain = 1'b0; + real in; + always_comb in = (cyc-4) * 1.0; + wire cmp; + + adc_netlist netlist(.clk, .in, .gain, .cmp); + + always @ (posedge clk) begin + if (cyc!=0) begin + cyc <= cyc + 1; + $display("cyc=%0d cmp=%d", cyc, cmp); + if (cyc == 3) begin + if (cmp != 0) $stop; + end + else if (cyc == 4) begin + if (cmp != 1) $stop; + end + else if (cyc == 5) begin + if (cmp != 0) $stop; + end + else if (cyc == 10) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + end + +endmodule + +module adc_netlist(clk, in, gain, cmp); + input clk; + input real in; + input gain; + output cmp; + + wire pga_out; //TODO: convert to real or support real + pga_model pga0(.in, .gain, .out(pga_out)); + comparator_model cmp0(.clk, .in(pga_out), .cmp); + +endmodule + +module pga_model(in, gain, out); + input real in; + input gain; + output real out; + + always_comb begin + out = in * 3.0; + end + +endmodule + +module comparator_model(clk, in, cmp); + input clk; + input real in; + output logic cmp; + + always_ff @(posedge clk) begin + cmp <= in > 0.0; + end + +endmodule