I have a multidimensional dynamic unpacked array in my SystemVerilog testbench and am passing this into C code as an argument using DPI-C. I am using Questasim 10.4b. Following the flow of Questa, I ran -dpiheader to generate the header file and included it in my C code.
SystemVerilog:
// C function declaration
import "DPI-C" function void modulate_my_frame (input byte data[][]);
// multidimensional array
byte unsigned frame_packed[][];
// assume this is randomized in my testbench
int num_frames = 5;
// init 1st dimension
frame_packed = new[num_frames];
// iterate through num_frames
for (int num_frame = 0; num_frame < num_frames; num_frame++) begin
// item
noob_frame fr = noob_frame::type_id::create("noob_frame");
// randomize
if (!noob_frame.randomize()) `uvm_error(get_name(), "Cannot randomize noob_frame");
// pack noob_frame
// I am casting this to void to simplify this example
// This can return a variable sized array for frame_packed[num_frame]
void'(fr.pack_bytes(frame_packed[num_frame]);
end
// fr[][] now contains all 5 noob_frames packed into byte arrays
// call DPI-C function
modulate_my_frame( frame_packed );
This is my C code:
void modulate_my_frame (const svOpenArrayHandle data)
{
printf( "svLeft1 = %0d\n", svLeft ( data, 1));
printf( "svRight1 = %0d\n", svRight ( data, 1));
printf( "svLow1 = %0d\n", svLow ( data, 1));
printf( "svHigh1 = %0d\n", svHigh ( data, 1));
printf( "svIncrement1 = %0d\n", svIncrement ( data, 1));
printf( "svSize1 = %0d\n", svSize ( data, 1));
printf( "svLeft2 = %0d\n", svLeft ( data, 2));
printf( "svRight2 = %0d\n", svRight ( data, 2));
printf( "svLow2 = %0d\n", svLow ( data, 2));
printf( "svHigh2 = %0d\n", svHigh ( data, 2));
printf( "svIncrement2 = %0d\n", svIncrement ( data, 2));
printf( "svSize2 = %0d\n", svSize ( data, 2));
printf( "svDimensions = %0d\n", svDimensions( data ));
}
The printout that I get:
# svLeft1 = 0
# svRight1 = 2
# svLow1 = 0
# svHigh1 = 2
# svIncrement1 = -1
# svSize1 = 3
# svLeft2 = -1
# svRight2 = -1
# svLow2 = -1
# svHigh2 = -1
# svIncrement2 = 0
# svSize2 = -2
# svDimensions = 2
I don't understand how to possibly get the dimensions of my subarrays?
The strange part is, I can use svGetArrElemPtr2
to access elements of my entire array. I just dont know what the dimensions are. At this point, my workaround is to pass another int array into the C code that contains the dimensions of the subarray.
Your 2-dimensional array is built of arrays of (potentially) different lengths. If you want to get the second dimension, you have to do it element-wise. Something like:
I've used
0
for an initial value ofi
instead ofsvLeft(data, 1)
, because dynamic arrays always start at0
and containtsize
elements.The code doesn't seem to work for me, because
sub_array
is alwaysNULL
. It looks just like an example from the LRM and I don't see anything wrong with it, so it could be due to a tool bug. Maybe it can get you started and you'll have better luck.