Fix DPI open array handling issues, and do internal coverage (#2350).

This commit is contained in:
Wilson Snyder 2020-12-09 22:15:34 -05:00
parent 2273fa62d9
commit ab4ad9965c
15 changed files with 1101 additions and 142 deletions

View File

@ -15,6 +15,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
**** Fix passing parameter type instantiations by position number.
**** Fix DPI open array handling issues.
* Verilator 4.106 2020-12-02

View File

@ -37,11 +37,6 @@
//======================================================================
// Internal macros
// Not supported yet
#define _VL_SVDPI_UNIMP() \
VL_FATAL_MT(__FILE__, __LINE__, "", \
(std::string("%%Error: Unsupported DPI function: ") + VL_FUNC).c_str())
#define _VL_SVDPI_WARN(...) VL_PRINTF_MT(__VA_ARGS__)
// Function requires a "context" in the import declaration
@ -258,16 +253,6 @@ static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp, int nargs, i
return datap;
}
static int _vl_sv_adjusted_bit(const VerilatedDpiOpenVar* varp, int indx) {
if (VL_UNLIKELY(indx < varp->low(0) || indx > varp->high(0))) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function packed index out of bounds; %d "
"outside [%d:%d].\n",
indx, varp->left(0), varp->right(0));
return 0;
}
return indx - varp->low(0);
}
/// Return pointer to simulator open array element, or nullptr if outside range
static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h, int nargs, int indx1, int indx2,
int indx3) VL_MT_SAFE {
@ -299,10 +284,10 @@ static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) d[i] = wdatap[i];
return;
}
default:
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
return; // LCOV_EXCL_STOP
}
}
/// Copy to user logic array from simulator open array
@ -330,7 +315,7 @@ static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandl
d[0].aval = lwp[0];
d[0].bval = 0;
d[1].aval = lwp[1];
d[0].bval = 0;
d[1].bval = 0;
break;
}
case VLVT_WDATA: {
@ -341,10 +326,10 @@ static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandl
}
return;
}
default:
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
return; // LCOV_EXCL_STOP
}
}
@ -364,10 +349,10 @@ static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecV
for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i];
return;
}
default:
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
return; // LCOV_EXCL_STOP
}
}
/// Copy to simulator open array from from user logic array
@ -388,10 +373,10 @@ static void _vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogic
for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i].aval;
return;
}
default:
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
return; // LCOV_EXCL_STOP
}
}
@ -400,31 +385,14 @@ static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s, int nargs, int indx1
int indx3, int indx4) VL_MT_SAFE {
// One extra index supported, as need bit number
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
void* datap;
int lsb;
if (varp->packed().elements()) {
datap = _vl_sv_adjusted_datap(varp, nargs - 1, indx1, indx2, indx3);
lsb = _vl_sv_adjusted_bit(
varp, ((nargs == 1) ? indx1 : (nargs == 2) ? indx2 : (nargs == 3) ? indx3 : indx4));
} else {
datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
lsb = 0;
}
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return 0;
switch (varp->vltype()) {
case VLVT_UINT8: return (*(reinterpret_cast<CData*>(datap)) >> lsb) & 1;
case VLVT_UINT16: return (*(reinterpret_cast<SData*>(datap)) >> lsb) & 1;
case VLVT_UINT32: return (*(reinterpret_cast<IData*>(datap)) >> lsb) & 1;
case VLVT_UINT64:
return (*(reinterpret_cast<QData*>(datap)) >> static_cast<QData>(lsb)) & 1ULL;
case VLVT_WDATA: {
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
return VL_BITRSHIFT_W(wdatap, lsb) & 1;
}
default:
case VLVT_UINT8: return (*(reinterpret_cast<CData*>(datap))) & 1;
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return 0;
return 0; // LCOV_EXCL_STOP
}
}
/// Update simulator open array from bit
@ -433,27 +401,14 @@ static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value, int narg
// One extra index supported, as need bit number
value &= 1; // Make sure clean
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
void* datap;
int lsb;
if (varp->packed().elements()) {
datap = _vl_sv_adjusted_datap(varp, nargs - 1, indx1, indx2, indx3);
lsb = _vl_sv_adjusted_bit(
varp, ((nargs == 1) ? indx1 : (nargs == 2) ? indx2 : (nargs == 3) ? indx3 : indx4));
} else {
datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
lsb = 0;
}
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return;
switch (varp->vltype()) {
case VLVT_UINT8: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast<CData*>(datap)), value); return;
case VLVT_UINT16: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast<SData*>(datap)), value); return;
case VLVT_UINT32: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast<IData*>(datap)), value); return;
case VLVT_UINT64: VL_ASSIGNBIT_QI(-1, lsb, *(reinterpret_cast<QData*>(datap)), value); return;
case VLVT_WDATA: VL_ASSIGNBIT_WI(-1, lsb, (reinterpret_cast<WDataOutP>(datap)), value); return;
default:
case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = value; return;
default: // LCOV_EXCL_START // Errored earlier
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
return; // LCOV_EXCL_STOP
}
}
@ -643,13 +598,6 @@ svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...) {
out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4);
break;
}
default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
@ -683,13 +631,6 @@ svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...) {
out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4);
break;
}
default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
@ -725,13 +666,6 @@ void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...) {
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
_vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4);
break;
}
default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
@ -763,13 +697,6 @@ void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...)
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
_vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4);
break;
}
default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);

View File

@ -102,7 +102,7 @@ typedef uint32_t svBitVecVal;
* Because the contents of the unused bits is undetermined,
* the following macros can be handy.
*/
#define SV_MASK(N) (~(-1 << (N)))
#define SV_MASK(N) (~(0xffffffffU << (N)))
#define SV_GET_UNSIGNED_BITS(VALUE, N) \
((N) == 32 ? (VALUE) : ((VALUE) & SV_MASK(N)))

View File

@ -6,11 +6,11 @@
// Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
`ifdef VERILATOR
//`ifdef VERILATOR
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0)
`else
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); end while(0)
`endif
//`else
// `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); end while(0)
//`endif
module t (/*AUTOARG*/);
@ -48,11 +48,8 @@ module t (/*AUTOARG*/);
logic o_logic [1:0];
byte i_byte [1:0];
byte o_byte [1:0];
int i_int [1:0];
int o_int [1:0];
integer i_integer [1:0];
integer o_integer [1:0];
// verilator lint_on UNUSED
import "DPI-C" function int dpii_failure();
@ -60,6 +57,7 @@ module t (/*AUTOARG*/);
// [] on packed arrays is unsupported in VCS & NC, so not supporting this
// p is number of packed dimensions, u is number of unpacked dimensions
import "DPI-C" function void dpii_open_p0_u1(input int c,p,u, input reg i [], output reg o []);
import "DPI-C" function void dpii_open_p1_u1(input int c,p,u, input reg [1:-1] i [], output reg [1:-1] o []);
import "DPI-C" function void dpii_open_p1_u2(input int c,p,u, input reg [1:-1] i [] [], output reg [1:-1] o [] []);
@ -72,10 +70,19 @@ module t (/*AUTOARG*/);
import "DPI-C" function void dpii_open_bit(input bit i [], output bit o []);
import "DPI-C" function void dpii_open_logic(input logic i [], output logic o []);
import "DPI-C" function void dpii_open_byte(input byte i [], output byte o []);
import "DPI-C" function void dpii_open_int(input int i [], output int o []);
import "DPI-C" function void dpii_open_integer(input integer i [], output integer o []);
import "DPI-C" function int dpii_failed();
int i_int_u1 [2:-2];
int o_int_u1 [2:-2];
int i_int_u2 [2:-2] [-3:3];
int o_int_u2 [2:-2] [-3:3];
int i_int_u3 [2:-2] [-3:3] [4:-4];
int o_int_u3 [2:-2] [-3:3] [4:-4];
import "DPI-C" function void dpii_open_int_u1(int u, input int i [], output int o []);
import "DPI-C" function void dpii_open_int_u2(int u, input int i [] [], output int o [] []);
import "DPI-C" function void dpii_open_int_u3(int u, input int i [] [] [], output int o [] [] []);
// verilator lint_on UNUSED
reg [95:0] crc;
@ -86,7 +93,6 @@ module t (/*AUTOARG*/);
i_bit[a] = crc[0];
i_logic[a] = crc[0];
i_byte[a] = crc[7:0];
i_int[a] = crc[31:0];
i_integer[a] = crc[31:0];
crc = {crc[94:0], crc[95]^crc[2]^crc[0]};
end
@ -94,7 +100,6 @@ module t (/*AUTOARG*/);
dpii_open_bit(i_bit, o_bit);
dpii_open_logic(i_logic, o_logic);
dpii_open_byte(i_byte, o_byte);
dpii_open_int(i_int, o_int);
dpii_open_integer(i_integer, o_integer);
for (int a=-2; a<=2; a=a+1) begin
@ -104,14 +109,17 @@ module t (/*AUTOARG*/);
i_rl_p1_u1[a] = crc[2:0];
i_rb_p1_u1[a] = crc[2:0];
i_rw_p1_u1[a] = crc[94:0];
i_int_u1[a] = crc[31:0];
for (int b=-3; b<=3; b=b+1) begin
i_rl_p1_u2[a][b] = crc[2:0];
i_rb_p1_u2[a][b] = crc[2:0];
i_rw_p1_u2[a][b] = crc[94:0];
i_int_u2[a][b] = crc[31:0];
for (int c=-4; c<=4; c=c+1) begin
i_rl_p1_u3[a][b][c] = crc[2:0];
i_rb_p1_u3[a][b][c] = crc[2:0];
i_rw_p1_u3[a][b][c] = crc[94:0];
i_int_u3[a][b][c] = crc[31:0];
crc = {crc[94:0], crc[95]^crc[2]^crc[0]};
end
end
@ -138,6 +146,19 @@ module t (/*AUTOARG*/);
end
end
dpii_open_int_u1(1, i_int_u1, o_int_u1);
dpii_open_int_u2(2, i_int_u2, o_int_u2);
dpii_open_int_u3(3, i_int_u3, o_int_u3);
for (int a=-2; a<=2; a=a+1) begin
`checkh(o_int_u1[a], ~i_int_u1[a]);
for (int b=-3; b<=3; b=b+1) begin
`checkh(o_int_u2[a][b], ~i_int_u2[a][b]);
for (int c=-4; c<=4; c=c+1) begin
`checkh(o_int_u3[a][b][c], ~i_int_u3[a][b][c]);
end
end
end
if (dpii_failure()!=0) begin
$write("%%Error: Failure in DPI tests\n");
$stop;

View File

@ -62,44 +62,17 @@ extern void dpii_open_int(const svOpenArrayHandle i, const svOpenArrayHandle o);
extern void dpii_open_integer(const svOpenArrayHandle i, const svOpenArrayHandle o);
extern void dpii_open_logic(const svOpenArrayHandle i, const svOpenArrayHandle o);
extern void dpii_open_int_u1(int u, const svOpenArrayHandle i, const svOpenArrayHandle o);
extern void dpii_open_int_u2(int u, const svOpenArrayHandle i, const svOpenArrayHandle o);
extern void dpii_open_int_u3(int u, const svOpenArrayHandle i, const svOpenArrayHandle o);
extern int dpii_failure();
}
#endif
//======================================================================
// Untested:
// void *svGetArrElemPtr(const svOpenArrayHandle, int indx1, ...);
// void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, ...);
// void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1);
// void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, ...);
// void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1);
// void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, ...);
// void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1);
// void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, ...);
// void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1);
// svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...);
// svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1);
// svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...);
// svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1);
// void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...);
// void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1);
// void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...);
// void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1);
//======================================================================
int failure = 0;
int dpii_failure() { return failure; }
// clang-format off
#ifdef _WIN32
# define T_PRI64 "I64"
#else // Linux or compliant Unix flavors
# define T_PRI64 "ll"
#endif
// clang-format on
#define CHECK_RESULT_HEX(got, exp) \
do { \
if ((got) != (exp)) { \
@ -122,7 +95,7 @@ void dpii_unused(const svOpenArrayHandle u) {}
void _dpii_all(int c, int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o) {
#ifdef TEST_VERBOSE
printf("-:%s:%d: For case c=%d p=%d u=%d data=%p\n", //
fprintf(stderr, "-:%s:%d: For case c=%d p=%d u=%d data=%p\n", //
__FILE__, __LINE__, c, p, u, svGetArrayPtr(i));
#endif
(void)svGetArrayPtr(i);
@ -260,18 +233,63 @@ void dpii_open_byte(const svOpenArrayHandle i, const svOpenArrayHandle o) {
#endif
}
void dpii_open_int(const svOpenArrayHandle i, const svOpenArrayHandle o) {
void dpii_open_integer(const svOpenArrayHandle i, const svOpenArrayHandle o) {}
void dpii_open_logic(const svOpenArrayHandle i, const svOpenArrayHandle o) {}
static void _dpii_open_int_ux(int u, const svOpenArrayHandle i, const svOpenArrayHandle o) {
intptr_t arrPtr = (intptr_t)svGetArrayPtr(i);
CHECK_RESULT_HEX_NE(arrPtr, 0); // All the arrays should actually exist
#ifndef NC
// NC always returns zero and warns
int sizeInputOfArray = svSizeOfArray(i);
CHECK_RESULT_HEX_NE(sizeInputOfArray, 0); // None of the test cases have zero size
CHECK_RESULT_HEX_NE(svDimensions(i), 0); // All the test cases are unpacked arrays
CHECK_RESULT_HEX(svDimensions(i), u);
#endif
int dim = svDimensions(i);
for (int a = svLow(i, 1); a <= svHigh(i, 1); ++a) {
if (dim == 1) {
intptr_t ip = (intptr_t)svGetArrElemPtr(i, a);
intptr_t i2p = (intptr_t)svGetArrElemPtr1(i, a);
CHECK_RESULT_HEX(ip, i2p);
CHECK_RESULT_HEX_NE(ip, 0);
intptr_t op = (intptr_t)svGetArrElemPtr(o, a);
CHECK_RESULT_HEX_NE(op, 0);
*reinterpret_cast<int*>(op) = ~*reinterpret_cast<int*>(ip);
} else {
for (int b = svLow(i, 2); b <= svHigh(i, 2); ++b) {
if (dim == 2) {
intptr_t ip = (intptr_t)svGetArrElemPtr(i, a, b);
intptr_t i2p = (intptr_t)svGetArrElemPtr2(i, a, b);
CHECK_RESULT_HEX(ip, i2p);
CHECK_RESULT_HEX_NE(ip, 0);
intptr_t op = (intptr_t)svGetArrElemPtr(o, a, b);
CHECK_RESULT_HEX_NE(op, 0);
*reinterpret_cast<int*>(op) = ~*reinterpret_cast<int*>(ip);
} else {
for (int c = svLow(i, 3); c <= svHigh(i, 3); ++c) {
if (dim == 3) {
intptr_t ip = (intptr_t)svGetArrElemPtr(i, a, b, c);
intptr_t i2p = (intptr_t)svGetArrElemPtr3(i, a, b, c);
CHECK_RESULT_HEX(ip, i2p);
CHECK_RESULT_HEX_NE(ip, 0);
intptr_t op = (intptr_t)svGetArrElemPtr(o, a, b, c);
CHECK_RESULT_HEX_NE(op, 0);
*reinterpret_cast<int*>(op) = ~*reinterpret_cast<int*>(ip);
}
}
}
}
}
}
}
void dpii_open_int_u1(int u, const svOpenArrayHandle i, const svOpenArrayHandle o) {
_dpii_open_int_ux(u, i, o);
}
void dpii_open_int_u2(int u, const svOpenArrayHandle i, const svOpenArrayHandle o) {
_dpii_open_int_ux(u, i, o);
}
void dpii_open_int_u3(int u, const svOpenArrayHandle i, const svOpenArrayHandle o) {
_dpii_open_int_ux(u, i, o);
}
void dpii_open_integer(const svOpenArrayHandle i, const svOpenArrayHandle o) {}
void dpii_open_logic(const svOpenArrayHandle i, const svOpenArrayHandle o) {}
int dpii_failed() { return failure; }

View File

@ -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 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.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(simulator => 1);
compile(
v_flags2 => ["t/t_dpi_open_elem_c.cpp"],
verilator_flags2 => ["-Wall -Wno-DECLFILENAME -unroll-count 1"],
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,118 @@
// 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.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0)
module t (/*AUTOARG*/);
bit i_bit_p0_u1 [2:-2];
bit o_bit_p0_u1 [2:-2];
bit q_bit_p0_u1 [2:-2];
bit i_bit_p0_u2 [2:-2] [-3:3];
bit o_bit_p0_u2 [2:-2] [-3:3];
bit q_bit_p0_u2 [2:-2] [-3:3];
bit i_bit_p0_u3 [2:-2] [-3:3] [4:-4];
bit o_bit_p0_u3 [2:-2] [-3:3] [4:-4];
bit q_bit_p0_u3 [2:-2] [-3:3] [4:-4];
import "DPI-C" function void dpii_bit_elem_p0_u1
(int p, int u, input bit i [], output bit o [], output bit q []);
import "DPI-C" function void dpii_bit_elem_p0_u2
(int p, int u, input bit i [] [], output bit o [] [], output bit q [] []);
import "DPI-C" function void dpii_bit_elem_p0_u3
(int p, int u, input bit i [] [] [], output bit o [] [] [], output bit q [] [] []);
logic i_logic_p0_u1 [2:-2];
logic o_logic_p0_u1 [2:-2];
logic q_logic_p0_u1 [2:-2];
logic i_logic_p0_u2 [2:-2] [-3:3];
logic o_logic_p0_u2 [2:-2] [-3:3];
logic q_logic_p0_u2 [2:-2] [-3:3];
logic i_logic_p0_u3 [2:-2] [-3:3] [4:-4];
logic o_logic_p0_u3 [2:-2] [-3:3] [4:-4];
logic q_logic_p0_u3 [2:-2] [-3:3] [4:-4];
import "DPI-C" function void dpii_logic_elem_p0_u1(int p, int u, input logic i [],
output logic o [], output logic q []);
import "DPI-C" function void dpii_logic_elem_p0_u2(int p, int u, input logic i [] [],
output logic o [] [], output logic q [] []);
import "DPI-C" function void dpii_logic_elem_p0_u3(int p, int u, input logic i [] [] [],
output logic o [] [] [], output logic q [] [] []);
import "DPI-C" function int dpii_failure();
reg [95:0] crc;
initial begin
crc = 96'h8a10a572_5aef0c8d_d70a4497;
begin
for (int a=-2; a<=2; a=a+1) begin
i_bit_p0_u1[a] = crc[0];
for (int b=-3; b<=3; b=b+1) begin
i_bit_p0_u2[a][b] = crc[0];
for (int c=-4; c<=4; c=c+1) begin
i_bit_p0_u3[a][b][c] = crc[0];
crc = {crc[94:0], crc[95]^crc[2]^crc[0]};
end
end
end
dpii_bit_elem_p0_u1(0, 1, i_bit_p0_u1, o_bit_p0_u1, q_bit_p0_u1);
dpii_bit_elem_p0_u2(0, 2, i_bit_p0_u2, o_bit_p0_u2, q_bit_p0_u2);
dpii_bit_elem_p0_u3(0, 3, i_bit_p0_u3, o_bit_p0_u3, q_bit_p0_u3);
for (int a=-2; a<=2; a=a+1) begin
`checkh(o_bit_p0_u1[a], ~i_bit_p0_u1[a]);
`checkh(q_bit_p0_u1[a], ~i_bit_p0_u1[a]);
for (int b=-3; b<=3; b=b+1) begin
`checkh(o_bit_p0_u2[a][b], ~i_bit_p0_u2[a][b]);
`checkh(q_bit_p0_u2[a][b], ~i_bit_p0_u2[a][b]);
for (int c=-4; c<=4; c=c+1) begin
`checkh(o_bit_p0_u3[a][b][c], ~i_bit_p0_u3[a][b][c]);
`checkh(q_bit_p0_u3[a][b][c], ~i_bit_p0_u3[a][b][c]);
end
end
end
end
begin
for (int a=-2; a<=2; a=a+1) begin
i_logic_p0_u1[a] = crc[0];
for (int b=-3; b<=3; b=b+1) begin
i_logic_p0_u2[a][b] = crc[0];
for (int c=-4; c<=4; c=c+1) begin
i_logic_p0_u3[a][b][c] = crc[0];
crc = {crc[94:0], crc[95]^crc[2]^crc[0]};
end
end
end
dpii_logic_elem_p0_u1(0, 1, i_logic_p0_u1, o_logic_p0_u1, q_logic_p0_u1);
dpii_logic_elem_p0_u2(0, 2, i_logic_p0_u2, o_logic_p0_u2, q_logic_p0_u2);
dpii_logic_elem_p0_u3(0, 3, i_logic_p0_u3, o_logic_p0_u3, q_logic_p0_u3);
for (int a=-2; a<=2; a=a+1) begin
`checkh(o_logic_p0_u1[a], ~i_logic_p0_u1[a]);
`checkh(q_logic_p0_u1[a], ~i_logic_p0_u1[a]);
for (int b=-3; b<=3; b=b+1) begin
`checkh(o_logic_p0_u2[a][b], ~i_logic_p0_u2[a][b]);
`checkh(q_logic_p0_u2[a][b], ~i_logic_p0_u2[a][b]);
for (int c=-4; c<=4; c=c+1) begin
`checkh(o_logic_p0_u3[a][b][c], ~i_logic_p0_u3[a][b][c]);
`checkh(q_logic_p0_u3[a][b][c], ~i_logic_p0_u3[a][b][c]);
end
end
end
end
if (dpii_failure()!=0) begin
$write("%%Error: Failure in DPI tests\n");
$stop;
end
else begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule

View File

@ -0,0 +1,188 @@
// -*- 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.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//*************************************************************************
#include <cstdio>
#include <cstring>
#include <iostream>
#include "svdpi.h"
//======================================================================
// clang-format off
#if defined(VERILATOR)
# include "Vt_dpi_open_elem__Dpi.h"
#elif defined(VCS)
# include "../vc_hdrs.h"
#elif defined(NC)
# define NEED_EXTERNS
// #elif defined(MS)
// # define NEED_EXTERNS
#else
# error "Unknown simulator for DPI test"
#endif
// clang-format on
#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.
void dpii_bit_elem_p0_u1(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q);
void dpii_bit_elem_p0_u2(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q);
void dpii_bit_elem_p0_u3(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q);
void dpii_logic_elem_p0_u1(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q);
void dpii_logic_elem_p0_u2(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q);
void dpii_logic_elem_p0_u3(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q);
extern int dpii_failure();
}
#endif
int failure = 0;
int dpii_failure() { return failure; }
#define CHECK_RESULT_HEX(got, exp) \
do { \
if ((got) != (exp)) { \
std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << std::hex \
<< ": GOT=" << (got) << " EXP=" << (exp) << std::endl; \
failure = __LINE__; \
} \
} while (0)
#define CHECK_RESULT_HEX_NE(got, exp) \
do { \
if ((got) == (exp)) { \
std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << std::hex \
<< ": GOT=" << (got) << " EXP!=" << (exp) << std::endl; \
failure = __LINE__; \
} \
} while (0)
void dpii_unused(const svOpenArrayHandle u) {}
//======================================================================
static void _dpii_bit_elem_ux(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q) {
int dim = svDimensions(i);
#ifndef NC
// NC always returns zero and warns
CHECK_RESULT_HEX(dim, u);
// svSizeOfArray(i) undeterministic as not in C representation
#endif
for (int a = svLow(i, 1); a <= svHigh(i, 1); ++a) {
fflush(stdout);
if (dim == 1) {
svBit v = svGetBitArrElem(i, a);
svBit v2 = svGetBitArrElem1(i, a);
CHECK_RESULT_HEX(v, v2);
svPutBitArrElem(o, v ? 0 : 1, a);
svPutBitArrElem1(q, v ? 0 : 1, a);
} else {
for (int b = svLow(i, 2); b <= svHigh(i, 2); ++b) {
if (dim == 2) {
svBit v = svGetBitArrElem(i, a, b);
svBit v2 = svGetBitArrElem2(i, a, b);
CHECK_RESULT_HEX(v, v2);
svPutBitArrElem(o, v ? 0 : 1, a, b);
svPutBitArrElem2(q, v ? 0 : 1, a, b);
} else {
for (int c = svLow(i, 3); c <= svHigh(i, 3); ++c) {
if (dim == 3) {
svBit v = svGetBitArrElem(i, a, b, c);
svBit v2 = svGetBitArrElem3(i, a, b, c);
CHECK_RESULT_HEX(v, v2);
svPutBitArrElem(o, v ? 0 : 1, a, b, c);
svPutBitArrElem3(q, v ? 0 : 1, a, b, c);
}
}
}
}
}
}
fflush(stdout);
}
void dpii_bit_elem_p0_u1(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q) {
_dpii_bit_elem_ux(p, u, i, o, q);
}
void dpii_bit_elem_p0_u2(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q) {
_dpii_bit_elem_ux(p, u, i, o, q);
}
void dpii_bit_elem_p0_u3(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q) {
_dpii_bit_elem_ux(p, u, i, o, q);
}
//======================================================================
static void _dpii_logic_elem_ux(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q) {
int sizeInputOfArray = svSizeOfArray(i);
int dim = svDimensions(i);
#ifndef NC
// NC always returns zero and warns
CHECK_RESULT_HEX(dim, u);
// svSizeOfArray(i) undeterministic as not in C representation
#endif
for (int a = svLow(i, 1); a <= svHigh(i, 1); ++a) {
if (dim == 1) {
svLogic v = svGetLogicArrElem(i, a);
svLogic v2 = svGetLogicArrElem1(i, a);
CHECK_RESULT_HEX(v, v2);
svPutLogicArrElem(o, v ? 0 : 1, a);
svPutLogicArrElem1(q, v ? 0 : 1, a);
} else {
for (int b = svLow(i, 2); b <= svHigh(i, 2); ++b) {
if (dim == 2) {
svLogic v = svGetLogicArrElem(i, a, b);
svLogic v2 = svGetLogicArrElem2(i, a, b);
CHECK_RESULT_HEX(v, v2);
svPutLogicArrElem(o, v ? 0 : 1, a, b);
svPutLogicArrElem2(q, v ? 0 : 1, a, b);
} else {
for (int c = svLow(i, 3); c <= svHigh(i, 3); ++c) {
if (dim == 3) {
svLogic v = svGetLogicArrElem(i, a, b, c);
svLogic v2 = svGetLogicArrElem3(i, a, b, c);
CHECK_RESULT_HEX(v, v2);
svPutLogicArrElem(o, v ? 0 : 1, a, b, c);
svPutLogicArrElem3(q, v ? 0 : 1, a, b, c);
}
}
}
}
}
}
fflush(stdout);
}
void dpii_logic_elem_p0_u1(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q) {
_dpii_logic_elem_ux(p, u, i, o, q);
}
void dpii_logic_elem_p0_u2(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q) {
_dpii_logic_elem_ux(p, u, i, o, q);
}
void dpii_logic_elem_p0_u3(int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o,
const svOpenArrayHandle q) {
_dpii_logic_elem_ux(p, u, i, o, q);
}

View File

@ -0,0 +1,27 @@
dpii_nullptr:
dpii_int_u3:
%Warning: DPI svOpenArrayHandle function index 3 out of bounds; 1 outside [4:-4].
%Warning: DPI svOpenArrayHandle function index 2 out of bounds; 20 outside [-3:3].
%Warning: DPI svOpenArrayHandle function index 1 out of bounds; 10 outside [2:-2].
%Warning: DPI svOpenArrayHandle function called on 3 dimensional array using 1 dimensional function.
dpii_real_u1:
%Warning: DPI svOpenArrayHandle function unsupported datatype (5).
%Warning: DPI svOpenArrayHandle function unsupported datatype (5).
%Warning: DPI svOpenArrayHandle function unsupported datatype (5).
%Warning: DPI svOpenArrayHandle function unsupported datatype (5).
%Warning: DPI svOpenArrayHandle function unsupported datatype (5).
%Warning: DPI svOpenArrayHandle function unsupported datatype (5).
%Warning: DPI svOpenArrayHandle function unsupported datatype (5).
%Warning: DPI svOpenArrayHandle function unsupported datatype (5).
dpii_bit_u6:
%Warning: DPI svOpenArrayHandle function called on 6 dimensional array using -1 dimensional function.
%Warning: DPI svOpenArrayHandle function called on 6 dimensional array using -1 dimensional function.
%Warning: DPI svOpenArrayHandle function called on 6 dimensional array using -1 dimensional function.
%Warning: DPI svOpenArrayHandle function called on 6 dimensional array using -1 dimensional function.
%Warning: DPI svOpenArrayHandle function called on 6 dimensional array using -1 dimensional function.
%Warning: DPI svOpenArrayHandle function called on 6 dimensional array using -1 dimensional function.
%Warning: DPI svOpenArrayHandle function called on 6 dimensional array using -1 dimensional function.
%Warning: DPI svOpenArrayHandle function called on 6 dimensional array using -1 dimensional function.
dpii_real_u6:
%Warning: DPI svOpenArrayHandle function called on 6 dimensional array using -1 dimensional function.
*-* All Finished *-*

View File

@ -0,0 +1,24 @@
#!/usr/bin/env 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.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(vlt => 1);
compile(
v_flags2 => ["t/t_dpi_open_oob_bad_c.cpp"],
verilator_flags2 => ["-Wall -Wno-DECLFILENAME -unroll-count 1"],
);
execute(
fails => 0, # DPI warnings are not errors
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,40 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// Copyright 2020 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
module t (/*AUTOARG*/);
import "DPI-C" function void dpii_nullptr();
// verilator lint_off UNDRIVEN
int i_int_u3 [2:-2] [-3:3] [4:-4];
import "DPI-C" function void dpii_int_u3(input int i [] [] []);
real i_real_u1 [1:0];
import "DPI-C" function void dpii_real_u1(input real i []);
bit i_u6 [2][2][2][2][2][2];
import "DPI-C" function void dpii_bit_u6(input bit i [][][][][][]);
real i_real_u6 [2][2][2][2][2][2];
import "DPI-C" function void dpii_real_u6(input real i [][][][][][]);
initial begin
i_int_u3[0][0][0] = 32'hbad;
i_real_u1[0] = 1.1;
i_u6[0][0][0][0][0][0] = 1'b1;
dpii_nullptr();
dpii_int_u3(i_int_u3);
dpii_real_u1(i_real_u1);
dpii_bit_u6(i_u6);
dpii_real_u6(i_real_u6);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,156 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2020 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
//
//*************************************************************************
#include <cstdio>
#include <cstring>
#include <iostream>
#include "svdpi.h"
//======================================================================
// clang-format off
#if defined(VERILATOR)
# include "Vt_dpi_open_oob_bad__Dpi.h"
#else
# error "Unknown simulator for DPI test"
#endif
// clang-format on
#define CHECK_RESULT_HEX(got, exp) \
do { \
if ((got) != (exp)) { \
std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << std::hex \
<< ": GOT=" << (got) << " EXP=" << (exp) << std::endl; \
failure = __LINE__; \
} \
} while (0)
#define CHECK_RESULT_HEX_NE(got, exp) \
do { \
if ((got) == (exp)) { \
std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << std::hex \
<< ": GOT=" << (got) << " EXP!=" << (exp) << std::endl; \
failure = __LINE__; \
} \
} while (0)
//======================================================================
int failure = 0;
void dpii_nullptr() {
printf("%s:\n", __func__);
// These cause fatal errors, so each would need a separate run
// svOpenArrayHandle h = nullptr;
// svBitVecVal bit_vec_val[2];
// svLogicVecVal logic_vec_val[2];
// svDimensions(h);
// svGetArrayPtr(h);
// svHigh(h, 0);
// svIncrement(h, 0);
// svLeft(h, 0);
// svLow(h, 0);
// svRight(h, 0);
// svSize(h, 0);
// svSizeOfArray(h);
//
// svGetArrElemPtr(h, 0);
// svGetArrElemPtr1(h, 0);
// svGetArrElemPtr2(h, 0, 0);
// svGetArrElemPtr3(h, 0, 0, 0);
// svGetBitArrElem(h, 0);
// svGetBitArrElem1(h, 0);
// svGetBitArrElem1VecVal(bit_vec_val, h, 0);
// svGetBitArrElem2(h, 0, 0);
// svGetBitArrElem2VecVal(bit_vec_val, h, 0, 0);
// svGetBitArrElem3(h, 0, 0, 0);
// svGetBitArrElem3VecVal(bit_vec_val, h, 0, 0, 0);
// svGetBitArrElemVecVal(bit_vec_val, h, 0);
// svGetLogicArrElem(h, 0);
// svGetLogicArrElem1(h, 0);
// svGetLogicArrElem1VecVal(logic_vec_val, h, 0);
// svGetLogicArrElem2(h, 0, 0);
// svGetLogicArrElem2VecVal(logic_vec_val, h, 0, 0);
// svGetLogicArrElem3(h, 0, 0, 0);
// svGetLogicArrElem3VecVal(logic_vec_val, h, 0, 0, 0);
// svGetLogicArrElemVecVal(logic_vec_val, h, 0);
// svPutBitArrElem(h, 0, 0);
// svPutBitArrElem1(h, 0, 0);
// svPutBitArrElem1VecVal(h, bit_vec_val, 0);
// svPutBitArrElem2(h, 0, 0, 0);
// svPutBitArrElem2VecVal(h, bit_vec_val, 0, 0);
// svPutBitArrElem3(h, 0, 0, 0, 0);
// svPutBitArrElem3VecVal(h, bit_vec_val, 0, 0, 0);
// svPutBitArrElemVecVal(h, bit_vec_val, 0);
// svPutLogicArrElem(h, 0, 0);
// svPutLogicArrElem1(h, 0, 0);
// svPutLogicArrElem1VecVal(h, logic_vec_val, 0);
// svPutLogicArrElem2(h, 0, 0, 0);
// svPutLogicArrElem2VecVal(h, logic_vec_val, 0, 0);
// svPutLogicArrElem3(h, 0, 0, 0, 0);
// svPutLogicArrElem3VecVal(h, logic_vec_val, 0, 0, 0);
// svPutLogicArrElemVecVal(h, logic_vec_val, 0);
}
void dpii_int_u3(const svOpenArrayHandle i) {
printf("%s:\n", __func__);
// Correct usage
intptr_t ip = (intptr_t)svGetArrElemPtr3(i, 1, 2, 3);
CHECK_RESULT_HEX_NE(ip, 0);
// Out of bounds
ip = (intptr_t)svGetArrElemPtr3(i, 1, 2, 30);
ip = (intptr_t)svGetArrElemPtr3(i, 1, 20, 3);
ip = (intptr_t)svGetArrElemPtr3(i, 10, 2, 3);
ip = (intptr_t)svGetArrElemPtr1(i, 30);
}
void dpii_real_u1(const svOpenArrayHandle i) {
printf("%s:\n", __func__);
svBitVecVal bit_vec_val[4];
svLogicVecVal logic_vec_val[4];
svGetBitArrElem(i, 0);
svGetBitArrElem1(i, 0);
svGetBitArrElem1VecVal(bit_vec_val, i, 0);
svGetBitArrElemVecVal(bit_vec_val, i, 0);
svGetLogicArrElem(i, 0);
svGetLogicArrElem1(i, 0);
svGetLogicArrElem1VecVal(logic_vec_val, i, 0);
svGetLogicArrElemVecVal(logic_vec_val, i, 0);
svPutBitArrElem(i, 0, 0);
svPutBitArrElem1(i, 0, 0);
svPutBitArrElem1VecVal(i, bit_vec_val, 0);
svPutBitArrElemVecVal(i, bit_vec_val, 0);
svPutLogicArrElem(i, 0, 0);
svPutLogicArrElem1(i, 0, 0);
svPutLogicArrElem1VecVal(i, logic_vec_val, 0);
svPutLogicArrElemVecVal(i, logic_vec_val, 0);
}
void dpii_bit_u6(const svOpenArrayHandle i) {
printf("%s:\n", __func__);
svBitVecVal bit_vec_val[4];
svLogicVecVal logic_vec_val[4];
svGetBitArrElem(i, 0, 0, 0, 0, 0, 0);
svGetBitArrElemVecVal(bit_vec_val, i, 0, 0, 0, 0, 0, 0);
svGetLogicArrElem(i, 0, 0, 0, 0, 0, 0);
svGetLogicArrElemVecVal(logic_vec_val, i, 0, 0, 0, 0, 0, 0);
svPutBitArrElem(i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
svPutBitArrElemVecVal(i, bit_vec_val, 0, 0, 0, 0, 0, 0);
svPutLogicArrElem(i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
svPutLogicArrElemVecVal(i, logic_vec_val, 0, 0, 0, 0, 0, 0);
}
void dpii_real_u6(const svOpenArrayHandle i) {
printf("%s:\n", __func__);
svGetArrElemPtr(i, 0, 0, 0, 0, 0, 0);
}

View File

@ -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 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.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(simulator => 1);
compile(
v_flags2 => ["t/t_dpi_open_vecval_c.cpp"],
verilator_flags2 => ["-Wall -Wno-DECLFILENAME -unroll-count 1"],
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,156 @@
// 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.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0)
module t (/*AUTOARG*/);
// Note that a packed array is required, otherwise some simulators will return bad
// results using *ElemVecVal() routines instead of scalar *Elem() routines.
bit [0:0] i_bit_p1_u1 [2:-2];
bit [0:0] o_bit_p1_u1 [2:-2];
bit [0:0] q_bit_p1_u1 [2:-2];
bit [60:0] i_bit61_p1_u1 [2:-2];
bit [60:0] o_bit61_p1_u1 [2:-2];
bit [60:0] q_bit61_p1_u1 [2:-2];
bit [91:0] i_bit92_p1_u1 [2:-2];
bit [91:0] o_bit92_p1_u1 [2:-2];
bit [91:0] q_bit92_p1_u1 [2:-2];
bit [11:0] i_bit12_p1_u2 [2:-2] [-3:3];
bit [11:0] o_bit12_p1_u2 [2:-2] [-3:3];
bit [11:0] q_bit12_p1_u2 [2:-2] [-3:3];
bit [29:1] i_bit29_p1_u3 [2:-2] [-3:3] [4:-4];
bit [29:1] o_bit29_p1_u3 [2:-2] [-3:3] [4:-4];
bit [29:1] q_bit29_p1_u3 [2:-2] [-3:3] [4:-4];
import "DPI-C" function void dpii_bit_vecval_p1_u1
(int bits, int p, int u, input bit [0:0] i [], output bit [0:0] o [], output bit [0:0] q []);
import "DPI-C" function void dpii_bit61_vecval_p1_u1
(int bits, int p, int u, input bit [60:0] i [], output bit [60:0] o [], output bit [60:0] q []);
import "DPI-C" function void dpii_bit92_vecval_p1_u1
(int bits, int p, int u, input bit [91:0] i [], output bit [91:0] o [], output bit [91:0] q []);
import "DPI-C" function void dpii_bit12_vecval_p1_u2
(int bits, int p, int u, input bit [11:0] i [] [], output bit [11:0] o [] [], output bit [11:0] q [] []);
import "DPI-C" function void dpii_bit29_vecval_p1_u3
(int bits, int p, int u, input bit [29:1] i [] [] [], output bit [29:1] o [] [] [], output bit [29:1] q [] [] []);
logic [0:0] i_logic_p1_u1 [2:-2];
logic [0:0] o_logic_p1_u1 [2:-2];
logic [0:0] q_logic_p1_u1 [2:-2];
logic [60:0] i_logic61_p1_u1 [2:-2];
logic [60:0] o_logic61_p1_u1 [2:-2];
logic [60:0] q_logic61_p1_u1 [2:-2];
logic [91:0] i_logic92_p1_u1 [2:-2];
logic [91:0] o_logic92_p1_u1 [2:-2];
logic [91:0] q_logic92_p1_u1 [2:-2];
logic [11:0] i_logic12_p1_u2 [2:-2] [-3:3];
logic [11:0] o_logic12_p1_u2 [2:-2] [-3:3];
logic [11:0] q_logic12_p1_u2 [2:-2] [-3:3];
logic [29:1] i_logic29_p1_u3 [2:-2] [-3:3] [4:-4];
logic [29:1] o_logic29_p1_u3 [2:-2] [-3:3] [4:-4];
logic [29:1] q_logic29_p1_u3 [2:-2] [-3:3] [4:-4];
import "DPI-C" function void dpii_logic_vecval_p1_u1
(int logics, int p, int u, input logic [0:0] i [], output logic [0:0] o [], output logic [0:0] q []);
import "DPI-C" function void dpii_logic61_vecval_p1_u1
(int logics, int p, int u, input logic [60:0] i [], output logic [60:0] o [], output logic [60:0] q []);
import "DPI-C" function void dpii_logic92_vecval_p1_u1
(int logics, int p, int u, input logic [91:0] i [], output logic [91:0] o [], output logic [91:0] q []);
import "DPI-C" function void dpii_logic12_vecval_p1_u2
(int logics, int p, int u, input logic [11:0] i [] [], output logic [11:0] o [] [], output logic [11:0] q [] []);
import "DPI-C" function void dpii_logic29_vecval_p1_u3
(int logics, int p, int u, input logic [29:1] i [] [] [], output logic [29:1] o [] [] [], output logic [29:1] q [] [] []);
import "DPI-C" function int dpii_failure();
reg [95:0] crc;
initial begin
crc = 96'h8a10a572_5aef0c8d_d70a4497;
begin
for (int a=-2; a<=2; a=a+1) begin
i_bit_p1_u1[a] = crc[0];
i_bit61_p1_u1[a] = crc[60:0];
i_bit92_p1_u1[a] = crc[91:0];
for (int b=-3; b<=3; b=b+1) begin
i_bit12_p1_u2[a][b] = crc[11:0];
for (int c=-4; c<=4; c=c+1) begin
i_bit29_p1_u3[a][b][c] = crc[29:1];
crc = {crc[94:0], crc[95]^crc[2]^crc[0]};
end
end
end
dpii_bit_vecval_p1_u1(1, 1, 1, i_bit_p1_u1, o_bit_p1_u1, q_bit_p1_u1);
dpii_bit61_vecval_p1_u1(61, 1, 1, i_bit61_p1_u1, o_bit61_p1_u1, q_bit61_p1_u1);
dpii_bit92_vecval_p1_u1(92, 1, 1, i_bit92_p1_u1, o_bit92_p1_u1, q_bit92_p1_u1);
dpii_bit12_vecval_p1_u2(12, 1, 2, i_bit12_p1_u2, o_bit12_p1_u2, q_bit12_p1_u2);
dpii_bit29_vecval_p1_u3(29, 1, 3, i_bit29_p1_u3, o_bit29_p1_u3, q_bit29_p1_u3);
for (int a=-2; a<=2; a=a+1) begin
`checkh(o_bit_p1_u1[a], ~i_bit_p1_u1[a]);
`checkh(q_bit_p1_u1[a], ~i_bit_p1_u1[a]);
`checkh(o_bit61_p1_u1[a], ~i_bit61_p1_u1[a]);
`checkh(q_bit61_p1_u1[a], ~i_bit61_p1_u1[a]);
`checkh(o_bit92_p1_u1[a], ~i_bit92_p1_u1[a]);
`checkh(q_bit92_p1_u1[a], ~i_bit92_p1_u1[a]);
for (int b=-3; b<=3; b=b+1) begin
`checkh(o_bit12_p1_u2[a][b], ~i_bit12_p1_u2[a][b]);
`checkh(q_bit12_p1_u2[a][b], ~i_bit12_p1_u2[a][b]);
for (int c=-4; c<=4; c=c+1) begin
`checkh(o_bit29_p1_u3[a][b][c], ~i_bit29_p1_u3[a][b][c]);
`checkh(q_bit29_p1_u3[a][b][c], ~i_bit29_p1_u3[a][b][c]);
end
end
end
end
begin
for (int a=-2; a<=2; a=a+1) begin
i_logic_p1_u1[a] = crc[0];
i_logic61_p1_u1[a] = crc[60:0];
i_logic92_p1_u1[a] = crc[91:0];
for (int b=-3; b<=3; b=b+1) begin
i_logic12_p1_u2[a][b] = crc[11:0];
for (int c=-4; c<=4; c=c+1) begin
i_logic29_p1_u3[a][b][c] = crc[29:1];
crc = {crc[94:0], crc[95]^crc[2]^crc[0]};
end
end
end
dpii_logic_vecval_p1_u1(1, 1, 1, i_logic_p1_u1, o_logic_p1_u1, q_logic_p1_u1);
dpii_logic61_vecval_p1_u1(61, 1, 1, i_logic61_p1_u1, o_logic61_p1_u1, q_logic61_p1_u1);
dpii_logic92_vecval_p1_u1(92, 1, 1, i_logic92_p1_u1, o_logic92_p1_u1, q_logic92_p1_u1);
dpii_logic12_vecval_p1_u2(12, 1, 2, i_logic12_p1_u2, o_logic12_p1_u2, q_logic12_p1_u2);
dpii_logic29_vecval_p1_u3(29, 1, 3, i_logic29_p1_u3, o_logic29_p1_u3, q_logic29_p1_u3);
for (int a=-2; a<=2; a=a+1) begin
`checkh(o_logic_p1_u1[a], ~i_logic_p1_u1[a]);
`checkh(q_logic_p1_u1[a], ~i_logic_p1_u1[a]);
`checkh(o_logic61_p1_u1[a], ~i_logic61_p1_u1[a]);
`checkh(q_logic61_p1_u1[a], ~i_logic61_p1_u1[a]);
`checkh(o_logic92_p1_u1[a], ~i_logic92_p1_u1[a]);
`checkh(q_logic92_p1_u1[a], ~i_logic92_p1_u1[a]);
for (int b=-3; b<=3; b=b+1) begin
`checkh(o_logic12_p1_u2[a][b], ~i_logic12_p1_u2[a][b]);
`checkh(q_logic12_p1_u2[a][b], ~i_logic12_p1_u2[a][b]);
for (int c=-4; c<=4; c=c+1) begin
`checkh(o_logic29_p1_u3[a][b][c], ~i_logic29_p1_u3[a][b][c]);
`checkh(q_logic29_p1_u3[a][b][c], ~i_logic29_p1_u3[a][b][c]);
end
end
end
end
if (dpii_failure()!=0) begin
$write("%%Error: Failure in DPI tests\n");
$stop;
end
else begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule

View File

@ -0,0 +1,236 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2020 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
//
//*************************************************************************
#include <cstdio>
#include <cstring>
#include <iostream>
#include "svdpi.h"
//======================================================================
// clang-format off
#if defined(VERILATOR)
# include "Vt_dpi_open_vecval__Dpi.h"
#elif defined(VCS)
# include "../vc_hdrs.h"
#elif defined(NC)
# define NEED_EXTERNS
// #elif defined(MS)
// # define NEED_EXTERNS
#else
# error "Unknown simulator for DPI test"
#endif
// clang-format on
#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();
}
#endif
int failure = 0;
int dpii_failure() { return failure; }
#define CHECK_RESULT_HEX(got, exp) \
do { \
if ((got) != (exp)) { \
std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << std::hex \
<< ": GOT=" << (got) << " EXP=" << (exp) << std::endl; \
failure = __LINE__; \
} \
} while (0)
#define CHECK_RESULT_HEX_NE(got, exp) \
do { \
if ((got) == (exp)) { \
std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << std::hex \
<< ": GOT=" << (got) << " EXP!=" << (exp) << std::endl; \
failure = __LINE__; \
} \
} while (0)
static void _invert(int bits, svBitVecVal o[], const svBitVecVal i[]) {
for (int w = 0; w < SV_PACKED_DATA_NELEMS(bits); ++w) o[w] = ~i[w];
o[SV_PACKED_DATA_NELEMS(bits) - 1] &= SV_MASK(bits & 31);
}
static void _invert(int bits, svLogicVecVal o[], const svLogicVecVal i[]) {
for (int w = 0; w < SV_PACKED_DATA_NELEMS(bits); ++w) {
o[w].aval = ~i[w].aval;
o[w].bval = 0;
}
o[SV_PACKED_DATA_NELEMS(bits) - 1].aval &= SV_MASK(bits & 31);
o[SV_PACKED_DATA_NELEMS(bits) - 1].bval &= SV_MASK(bits & 31);
}
static bool _same(int bits, const svBitVecVal o[], const svBitVecVal i[]) {
for (int w = 0; w < SV_PACKED_DATA_NELEMS(bits); ++w) {
svBitVecVal mask = 0xffffffff;
if (w == SV_PACKED_DATA_NELEMS(bits) - 1) mask = SV_MASK(bits & 31);
if ((o[w] & mask) != (i[w] & mask)) return false;
}
return true;
}
static bool _same(int bits, const svLogicVecVal o[], const svLogicVecVal i[]) {
for (int w = 0; w < SV_PACKED_DATA_NELEMS(bits); ++w) {
svBitVecVal mask = 0xffffffff;
if (w == SV_PACKED_DATA_NELEMS(bits) - 1) mask = SV_MASK(bits & 31);
if ((o[w].aval & mask) != (i[w].aval & mask)) return false;
if ((o[w].bval & mask) != (i[w].bval & mask)) return false;
}
return true;
}
void dpii_unused(const svOpenArrayHandle u) {}
//======================================================================
static void _dpii_bit_vecval_ux(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
printf("%s: bits=%d p=%d u=%d\n", __func__, bits, p, u);
int dim = svDimensions(i);
#ifndef NC
// NC always returns zero and warns
CHECK_RESULT_HEX(dim, u);
#endif
svBitVecVal vv[SV_PACKED_DATA_NELEMS(bits)];
svBitVecVal vv2[SV_PACKED_DATA_NELEMS(bits)];
svBitVecVal vo[SV_PACKED_DATA_NELEMS(bits)];
for (int a = svLow(i, 1); a <= svHigh(i, 1); ++a) {
fflush(stdout);
if (dim == 1) {
svGetBitArrElemVecVal(vv, i, a);
svGetBitArrElem1VecVal(vv2, i, a);
CHECK_RESULT_HEX(_same(bits, vv, vv2), true);
_invert(bits, vo, vv);
svPutBitArrElemVecVal(o, vo, a);
svPutBitArrElem1VecVal(q, vo, a);
} else {
for (int b = svLow(i, 2); b <= svHigh(i, 2); ++b) {
if (dim == 2) {
svGetBitArrElemVecVal(vv, i, a, b);
svGetBitArrElem2VecVal(vv2, i, a, b);
CHECK_RESULT_HEX(_same(bits, vv, vv2), true);
_invert(bits, vo, vv);
svPutBitArrElemVecVal(o, vo, a, b);
svPutBitArrElem2VecVal(q, vo, a, b);
} else {
for (int c = svLow(i, 3); c <= svHigh(i, 3); ++c) {
if (dim == 3) {
svGetBitArrElemVecVal(vv, i, a, b, c);
svGetBitArrElem3VecVal(vv2, i, a, b, c);
CHECK_RESULT_HEX(_same(bits, vv, vv2), true);
_invert(bits, vo, vv);
svPutBitArrElemVecVal(o, vo, a, b, c);
svPutBitArrElem3VecVal(q, vo, a, b, c);
}
}
}
}
}
}
fflush(stdout);
}
void dpii_bit_vecval_p1_u1(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
_dpii_bit_vecval_ux(bits, p, u, i, o, q);
}
void dpii_bit61_vecval_p1_u1(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
_dpii_bit_vecval_ux(bits, p, u, i, o, q);
}
void dpii_bit92_vecval_p1_u1(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
_dpii_bit_vecval_ux(bits, p, u, i, o, q);
}
void dpii_bit12_vecval_p1_u2(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
_dpii_bit_vecval_ux(bits, p, u, i, o, q);
}
void dpii_bit29_vecval_p1_u3(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
_dpii_bit_vecval_ux(bits, p, u, i, o, q);
}
//======================================================================
static void _dpii_logic_vecval_ux(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
printf("%s: bits=%d p=%d u=%d\n", __func__, bits, p, u);
int dim = svDimensions(i);
#ifndef NC
// NC always returns zero and warns
CHECK_RESULT_HEX(dim, u);
#endif
svLogicVecVal vv[SV_PACKED_DATA_NELEMS(bits)];
svLogicVecVal vv2[SV_PACKED_DATA_NELEMS(bits)];
svLogicVecVal vo[SV_PACKED_DATA_NELEMS(bits)];
for (int a = svLow(i, 1); a <= svHigh(i, 1); ++a) {
fflush(stdout);
if (dim == 1) {
svGetLogicArrElemVecVal(vv, i, a);
svGetLogicArrElem1VecVal(vv2, i, a);
CHECK_RESULT_HEX(_same(bits, vv, vv2), true);
_invert(bits, vo, vv);
svPutLogicArrElemVecVal(o, vo, a);
svPutLogicArrElem1VecVal(q, vo, a);
} else {
for (int b = svLow(i, 2); b <= svHigh(i, 2); ++b) {
if (dim == 2) {
svGetLogicArrElemVecVal(vv, i, a, b);
svGetLogicArrElem2VecVal(vv2, i, a, b);
CHECK_RESULT_HEX(_same(bits, vv, vv2), true);
_invert(bits, vo, vv);
svPutLogicArrElemVecVal(o, vo, a, b);
svPutLogicArrElem2VecVal(q, vo, a, b);
} else {
for (int c = svLow(i, 3); c <= svHigh(i, 3); ++c) {
if (dim == 3) {
svGetLogicArrElemVecVal(vv, i, a, b, c);
svGetLogicArrElem3VecVal(vv2, i, a, b, c);
CHECK_RESULT_HEX(_same(bits, vv, vv2), true);
_invert(bits, vo, vv);
svPutLogicArrElemVecVal(o, vo, a, b, c);
svPutLogicArrElem3VecVal(q, vo, a, b, c);
}
}
}
}
}
}
fflush(stdout);
}
void dpii_logic_vecval_p1_u1(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
_dpii_logic_vecval_ux(bits, p, u, i, o, q);
}
void dpii_logic61_vecval_p1_u1(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
_dpii_logic_vecval_ux(bits, p, u, i, o, q);
}
void dpii_logic92_vecval_p1_u1(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
_dpii_logic_vecval_ux(bits, p, u, i, o, q);
}
void dpii_logic12_vecval_p1_u2(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
_dpii_logic_vecval_ux(bits, p, u, i, o, q);
}
void dpii_logic29_vecval_p1_u3(int bits, int p, int u, const svOpenArrayHandle i,
const svOpenArrayHandle o, const svOpenArrayHandle q) {
_dpii_logic_vecval_ux(bits, p, u, i, o, q);
}