help on passing arguments with VPI

S

skyworld

Guest
Hi,

I'm trying to pass some values from verilog simulation to my c program
with vpi. I found one examples from wiki as this:

// from verilog simulator:
val = 41;
$increment(val);

// from example c program
static int increment(char *userdata) {
vpiHandle systfref, args_iter, argh;
struct t_vpi_value argval;
int value;

systfref = vpi_handle(vpiSysTfCall, NULL);
args_iter = vpi_iterate(vpiArgument, systfref);

argh = vpi_scan(args_iter);
argval.format = vpiIntVal;
vpi_get_value(argh, &argval);
value = argval.value.integer;
vpi_printf("VPI routine received %d\n", value);

This examples works, but how can I pass an array from verilog to c?
for example, how can I access array as follows in c?
reg[7:0] test_data[0:127];
$increment(test_data);
 
skyworld wrote:

This examples works, but how can I pass an array from verilog to c?
for example, how can I access array as follows in c?
reg[7:0] test_data[0:127];
$increment(test_data);
If your simulator allows this to be accessed as a memory then try
something like the following:

int left_addr, right_addr;

argh = vpi_scan(args_iter);
argval.format = vpiIntVal;
vpi_get_value(vpi_handle(vpiLeftRange, argh), &val);
left_addr = argval.value.integer;
argval.format = vpipIntVal;
vpi_get_value(vpi_handle(vpiRightRange, argh), &val);
right_addr = argval.value.integer;

<loop over the array addresses>
vpiHandle word_index;
word_index = vpi_handle_by_index(argh, <address>);
<process the word handle like any other vector>

You still need to add error checking (a compiletf routine). The generic
multiple dimension array code is much more complex and I'm not going to
include an example for it here. It's basically get all the index ranges
and then use vpi_handle_by_multi_index() to get the individual words.

Having a copy of the standard while not the easiest to learn from does
provide enough information for a motivated person to figure out how this
all works. Look at the figures, determine what you need, figure out the
access method, iterate. "The Verilog PLI Handbook, 2nd Edition" is
fairly good. With a copy of it for clarity and the standard for
completeness you should have enough information to do about anything
from the PLI.

FYI Icarus Verilog implements all the system functions/tasks using the
PLI so it has a bunch of example code in the vpi directory.

Cary
 
On Jun 13, 12:02 am, "Cary R." <no-s...@host.spam> wrote:
skyworld wrote:
This examples works, but how can I pass an array from verilog to c?
for example, how can I access array as follows in c?
reg[7:0]   test_data[0:127];
$increment(test_data);

If your simulator allows this to be accessed as a memory then try
something like the following:

   int left_addr, right_addr;

   argh = vpi_scan(args_iter);
   argval.format = vpiIntVal;
   vpi_get_value(vpi_handle(vpiLeftRange, argh), &val);
   left_addr = argval.value.integer;
   argval.format = vpipIntVal;
   vpi_get_value(vpi_handle(vpiRightRange, argh), &val);
   right_addr = argval.value.integer;

   <loop over the array addresses
     vpiHandle word_index;
     word_index = vpi_handle_by_index(argh, <address>);
     <process the word handle like any other vector

You still need to add error checking (a compiletf routine). The generic
multiple dimension array code is much more complex and I'm not going to
include an example for it here. It's basically get all the index ranges
and then use vpi_handle_by_multi_index() to get the individual words.

Having a copy of the standard while not the easiest to learn from does
provide enough information for a motivated person to figure out how this
all works. Look at the figures, determine what you need, figure out the
access method, iterate. "The Verilog PLI Handbook, 2nd Edition" is
fairly good. With a copy of it for clarity and the standard for
completeness you should have enough information to do about anything
from the PLI.

FYI Icarus Verilog implements all the system functions/tasks using the
PLI so it has a bunch of example code in the vpi directory.

Cary
Hi Cary,

thanks for your help. Your reply works. Thanks very much.


regards
 
On Jun 13, 9:18 am, skyworld <chenyong20...@gmail.com> wrote:
On Jun 13, 12:02 am, "Cary R." <no-s...@host.spam> wrote:





skyworldwrote:
This examples works, but how can I pass an array from verilog to c?
for example, how can I access array as follows in c?
reg[7:0]   test_data[0:127];
$increment(test_data);

If your simulator allows this to be accessed as a memory then try
something like the following:

   int left_addr, right_addr;

   argh = vpi_scan(args_iter);
   argval.format = vpiIntVal;
   vpi_get_value(vpi_handle(vpiLeftRange, argh), &val);
   left_addr = argval.value.integer;
   argval.format = vpipIntVal;
   vpi_get_value(vpi_handle(vpiRightRange, argh), &val);
   right_addr = argval.value.integer;

   <loop over the array addresses
     vpiHandle word_index;
     word_index = vpi_handle_by_index(argh, <address>);
     <process the word handle like any other vector

You still need to add error checking (a compiletf routine). The generic
multiple dimension array code is much more complex and I'm not going to
include an example for it here. It's basically get all the index ranges
and then use vpi_handle_by_multi_index() to get the individual words.

Having a copy of the standard while not the easiest to learn from does
provide enough information for a motivated person to figure out how this
all works. Look at the figures, determine what you need, figure out the
access method, iterate. "The Verilog PLI Handbook, 2nd Edition" is
fairly good. With a copy of it for clarity and the standard for
completeness you should have enough information to do about anything
from the PLI.

FYI Icarus Verilog implements all the system functions/tasks using the
PLI so it has a bunch of example code in the vpi directory.

Cary

Hi Cary,

thanks for your help. Your reply works. Thanks very much.

regards- Hide quoted text -

- Show quoted text -
Hi,

is there a way to get a vector from VPI routine? for example,
reg[7:0] data[0:127]

data[0:127] = $get_data(arg...)

is this possible? I checked VPI handbooks, only found return value
could be one data and it is only data indicates returned size, which
is no use to me. Is there a way to use user_data field to bypass array
to verilog? thanks
 
skyworld wrote:

is there a way to get a vector from VPI routine? for example,
reg[7:0] data[0:127]

data[0:127] = $get_data(arg...)

is this possible? I checked VPI handbooks, only found return value
could be one data and it is only data indicates returned size, which
is no use to me. Is there a way to use user_data field to bypass array
to verilog? thanks
I don't know about SV, but in 1364-2005 you can't assign to an array
slice. Only an individual array word can be assigned to. Also system
functions can not dynamically size their result to match a calling
requirement. If you pass the array as an argument to $get_data() you can
access the individual array words along with the other information
needed to fill the words as you like. That's how the $readmem routines work.

Using the code I previously posted you would add a vpi_put_value() call
to put a new value to the given array word. You will also likely want to
get the array word size. This can be done by getting the size of a word
handle. They must all be the same size so you only need to do this
once. It's easy just to check the first or last word in the array since
you will likely already have that index information.

Cary
 
On Jun 24, 2:08 am, "Cary R." <no-s...@host.spam> wrote:
skyworld wrote:
is there a way to get a vector from VPI routine? for example,
  reg[7:0]  data[0:127]

  data[0:127] = $get_data(arg...)

is this possible? I checked VPI handbooks, only found return value
could be one data and it is only data indicates returned size, which
is no use to me. Is there a way to use user_data field to bypass array
to verilog? thanks

I don't know about SV, but in 1364-2005 you can't assign to an array
slice. Only an individual array word can be assigned to. Also system
functions can not dynamically size their result to match a calling
requirement. If you pass the array as an argument to $get_data() you can
access the individual array words along with the other information
needed to fill the words as you like. That's how the $readmem routines work.

Using the code I previously posted you would add a vpi_put_value() call
to put a new value to the given array word. You will also likely want to
get the array word size. This can be done by getting the size of a word
  handle. They must all be the same size so you only need to do this
once. It's easy just to check the first or last word in the array since
you will likely already have that index information.

Cary
Hi Cary,

thanks for your guides. I will try this. Thanks.


regards
skyworld
 

Welcome to EDABoard.com

Sponsor

Back
Top