diff --git a/include/verilated_dpi.cpp b/include/verilated_dpi.cpp index fa619e7b1..83c65c368 100644 --- a/include/verilated_dpi.cpp +++ b/include/verilated_dpi.cpp @@ -72,7 +72,8 @@ svBit svGetBitselBit(const svBitVecVal* sp, int bit) { svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) { // Not VL_BITRSHIFT_W as sp is a different structure type // Verilator doesn't support X/Z so only aval - return (sp[VL_BITWORD_I(bit)].aval >> VL_BITBIT_I(bit)) & 1; + return (((sp[VL_BITWORD_I(bit)].aval >> VL_BITBIT_I(bit)) & 1) + | (((sp[VL_BITWORD_I(bit)].bval >> VL_BITBIT_I(bit)) & 1)<<1)); } void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) { @@ -83,6 +84,9 @@ void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) { dp[VL_BITWORD_I(bit)].aval = ((dp[VL_BITWORD_I(bit)].aval & ~(VL_UL(1)<>1<>nbitsonright; - IData od = (d & ~linsmask) | (dp[oword] & linsmask); - if (oword==hword) dp[oword] = (dp[oword] & ~hinsmask) | (od & hinsmask); - else dp[oword] = od; - } - } + int lword = VL_BITWORD_I(lbit); + if (hword==lword) { // know < 32 bits because above checks it + IData insmask = (VL_MASK_I(hoffset-loffset+1))<>nbitsonright) & hinsmask); } } } -void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int lbit, int width) { +void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal s, int lbit, int width) { int hbit = lbit+width-1; - int hoffset = hbit & VL_SIZEBITS_I; - int loffset = lbit & VL_SIZEBITS_I; - int lword = VL_BITWORD_I(lbit); - int words = VL_WORDS_I(hbit-lbit+1); + int hoffset = VL_BITBIT_I(hbit); + int loffset = VL_BITBIT_I(lbit); if (hoffset==VL_SIZEBITS_I && loffset==0) { // Fast and common case, word based insertion - for (int i=0; i> nbitsonright; - IData d_b = sp[i].bval >> nbitsonright; - IData od_a = (d_a & ~linsmask) | (dp[oword].aval & linsmask); - IData od_b = (d_b & ~linsmask) | (dp[oword].bval & linsmask); - if (oword==hword) { - dp[oword].aval = (dp[oword].aval & ~hinsmask) | (od_a & hinsmask); - dp[oword].bval = (dp[oword].bval & ~hinsmask) | (od_b & hinsmask); - } else { - dp[oword].aval = od_a; - dp[oword].bval = od_b; - } - } - } + int lword = VL_BITWORD_I(lbit); + if (hword==lword) { // know < 32 bits because above checks it + IData insmask = (VL_MASK_I(hoffset-loffset+1))<>nbitsonright) & hinsmask); + dp[hword].bval = (dp[hword].bval & ~hinsmask) | ((s.bval>>nbitsonright) & hinsmask); } } } diff --git a/include/vltstd/svdpi.h b/include/vltstd/svdpi.h index dbfc9db3a..69597926d 100644 --- a/include/vltstd/svdpi.h +++ b/include/vltstd/svdpi.h @@ -155,7 +155,7 @@ XXTERN void svGetPartselBit(svBitVecVal* d, const svBitVecVal* s, int i, int w); XXTERN void svGetPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w); XXTERN void svPutPartselBit(svBitVecVal* d, const svBitVecVal s, int i, int w); -XXTERN void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w); +XXTERN void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal s, int i, int w); /* * Open array querying functions diff --git a/test_regress/t/t_dpi_lib.pl b/test_regress/t/t_dpi_lib.pl new file mode 100755 index 000000000..28a0c4bb3 --- /dev/null +++ b/test_regress/t/t_dpi_lib.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 ( + v_flags2 => ["t/t_dpi_lib_c.cpp"], + verilator_flags2 => ["-Wall -Wno-DECLFILENAME"], + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_dpi_lib.v b/test_regress/t/t_dpi_lib.v new file mode 100644 index 000000000..480331199 --- /dev/null +++ b/test_regress/t/t_dpi_lib.v @@ -0,0 +1,25 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2017 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. + +module t (/*AUTOARG*/); + + import "DPI-C" function int dpii_failure(); + import "DPI-C" function void dpii_check(); + + initial begin + dpii_check(); + + if (dpii_failure()!=0) begin + $write("%%Error: Failure in DPI tests\n"); + $stop; + end + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_dpi_lib_c.cpp b/test_regress/t/t_dpi_lib_c.cpp new file mode 100644 index 000000000..06572c831 --- /dev/null +++ b/test_regress/t/t_dpi_lib_c.cpp @@ -0,0 +1,137 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2009-2017 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. +// +// Verilator is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +//************************************************************************* + +#include +#include +#include +#include "svdpi.h" + +//====================================================================== + +#if defined(VERILATOR) +# include "Vt_dpi_lib__Dpi.h" +#elif defined(VCS) +# include "../vc_hdrs.h" +#elif defined(NC) +# define NEED_EXTERNS +#else +# error "Unknown simulator for DPI test" +#endif + +#ifdef NEED_EXTERNS +extern "C" { + // If get ncsim: *F,NOFDPI: Function {foo} not found in default libdpi. + // Then probably forgot to list a function here. + + extern int dpii_failure(); + extern void dpii_check(); +} +#endif + +//====================================================================== + +int failure = 0; + +#define CHECK_RESULT_HEX(got, exp) \ + do { if ((got) != (exp)) { \ + std::cout<