Subject: RE: [sv-cc] RE: Feedback on Read API (VPI enhancement)
From: Francoise Martinolle (fm@cadence.com)
Date: Wed Dec 17 2003 - 08:47:17 PST
Joao,
your proposal does not cover the case where there are 2 simulators vcs and
ncverilog and an application wants to use both VPI from vcs and VPI from
NCV. Yours is very specific to the read API.
My proposal is to add a specific tool routine to invoke in order to get the
VPI function tray supported by that tool.
My proposal is general enough that it can be extended to cover any situation.
Also your proposal cannot support the case when the tools need to be
statically linked together?
Francoise
'
At 11:23 AM 12/17/2003 -0500, Joao Geada wrote:
>Francoise,
>
>I think you're making it unnecessarily complex: vpi_read_init could itself
>be the bootstrapper routine and belong to
>the "simulator" system. Note that as I said/implied in my comments, the
>intent for vpi_read_init is to:
>
>1- load the appropriate reader library (dlopen)
>2- use a well defined entry point in the newly loaded library (eg library
>name itself as a function,
> so the "vpd" reader library would define "vpd()" as it's entry point)
> to create the function vector
>3- indirectiving via the just created function vector, invoke the routine
>to load the requested waveform
>4- if all the above was successful, return the function vector.
>
>For standalone applications the above "vpi_read_init" functionality would
>need to be provided in a standalone library,
>so that the simulator was not required to be linked into the standalone
>executable.
>
>I believe in keeping things as simple as possible (but no simpler ;-)
>
>Joao
>
>==============================================================================
>Joao Geada, PhD Principal Engineer Verif Tech Group
>Synopsys, Inc TEL: (508) 263-8083
>377 Simarano Drive, Suite 300, FAX: (508) 263-8069
>Marlboro, MA 01752, USA
>==============================================================================
>
>-----Original Message-----
>From: owner-sv-cc@eda.org [mailto:owner-sv-cc@eda.org]On Behalf Of
>Francoise Martinolle
>Sent: Wednesday, December 17, 2003 10:01 AM
>To: Joao.Geada@synopsys.COM; bassam@novas.com; Sv-Cc
>Cc: Ghassan Khoory
>Subject: Re: [sv-cc] RE: Feedback on Read API (VPI enhancement)
>
>Joao,
>
>the problem which still remains is which vpi_read_init do you call if
>there are multiple ones present.
>
>If you have multiple tools providing the READ API, the only way I think to
>solve this problem
>is to have each tool provide a bootstrap function of their READ
>api. Essentially there would be a vpi_read_init for ncverilog, a
>vpi_read_init for debussy, a vpi_read_init for vcs.
>
>An application would then need to call these bootstrap functions before
>starting any processing.
>myapp -vpiload debussy/libreadapi.so:vpi_read_init -vpiload
>ncv/libs/libreadapi.so:vpi_read_init - vpiload vcs/libreadapi.so:vpi_read_init
>
>The first thing that myapp will do is to dlopen debussy/libreadapi.so and
>invoke vpi_read_init, then dlopen ncv/libs/libreadapi.so and call
>vpi_read_init and so on.
>
>This does not work for static linking. where only one symbol vpi_read_init
>can exits.
>For static linking, each tool would need to provide a bootstrap function
>which name is different.
>
>Bassam and I worked out something similar which will work in dynamic or
>static linking.
>A tool specific routine is provided which serves as a bootstrap function.
>This can be use in the general case where 2 VPI libraries are present
>because of 2 simulators.
>It can be extended to support the new VPI routines added with the vpi read
>API.
>
>We propose to add the following routine:
>p_vpi_routine_array *vpi_get_routines_* ()
>
>where the routine name would be tool specific after
>vpi_get_routines_. For example, NC-Verilog might create a routine
>vpi_get_routines_ncv(), and VCS could create a routine
>vpi_get_routines_vcs(). These routines would return an array of
>vpi_routine_array_p structs:
>typedef struct vpi_routine_array *p_vpi_routine_array;
>typedef struct vpi_routine_array {
> char *name;
> union {
> PLI_INT32 int_routine();
> PLI_BYTE8 str_routine();
> vpiHandle handle_routine();
> void void_routine();
> VPI_UINT32 uint_routine();
> PLI_LNG64 long_routine();
>...etc
> } routine;
>} s_vpi_routine_array;
>The array of structures returned by vpi_get_routines_*() would return a
>NULL terminated array of routines. The application would then resolve
>each reference itself, for example:
>list = vpi_get_routines_ncv();
>assert(list);
>cur = *list;
>while (cur && (!strcmp(cur->name,vpi_get))
> cur++;
>assert(cur);
>ncv_vpi_get = cur->routine->int_routine;
>Similarly a waveform database tool would provide such a routine:
>vpi_get_routines_debussy(), or vpi_get_routines_sst2. The user application
>which desires to read that database produced by the waveform tool would
>call this routine and then resolve each VPI function reference and then
>be able to use the VPI read API implementation of that database.
>Note that this indirection is only required if a user application is used
>in the context of multiple tools, each tool having its own VPI implementation.
> Example
>As an example, and proof of concept, consider the following code:
>example.h file:
>#define NULL 0L
>
>typedef struct vpi_routine_array *p_vpi_routine_array;
>typedef struct vpi_routine_array {
> char *name;
> union {
> int (*int_routine)();
> char *(*str_routine)();
> } routine;
>} s_vpi_routine_array;
>
>#define vpiName 1
>ncv.c file:
>#include <stdarg.h>
>#include <ctype.h>
>#include example.h
>
>static char *vpi_get_str(int type, int RH)
>{
> return(Called NCV vpi_get_str()\n);
>}
>
>static int vpi_handle(int type, int RH)
>{
> return(NULL);
>}
>
>p_vpi_routine_array *vpi_get_routine_ncv()
>{
> static p_vpi_routine_array retVal[3];
>
> retVal[0] =
> (p_vpi_routine_array)malloc(sizeof(s_vpi_routine_array));
> (retVal[0])->name = (char *)malloc((strlen(vpi_get_str) + 1) *
> sizeof(char));
> strcpy((retVal[0])->name,vpi_get_str);
> (retVal[0])->routine.str_routine = vpi_get_str;
>
> retVal[1] =
> (p_vpi_routine_array)malloc(sizeof(s_vpi_routine_array));
> (retVal[1])->name = (char *)malloc((strlen(vpi_handle) + 1) *
> sizeof(char));
> strcpy((retVal[1])->name,vpi_handle);
> (retVal[1])->routine.int_routine = vpi_handle;
>
> retVal[2] = NULL;
>
> return(retVal);
>}
>vcs.c file:
>#include <stdarg.h>
>#include <ctype.h>
>#include example.h
>
>static char *vpi_get_str(int type, int RH)
>{
> return(Called VCS vpi_get_str()\n);
>}
>
>static int vpi_handle(int type, int RH)
>{
> return(NULL);
>}
>
>p_vpi_routine_array *vpi_get_routine_vcs()
>{
> static p_vpi_routine_array retVal[3];
>
> retVal[0] =
> (p_vpi_routine_array)malloc(sizeof(s_vpi_routine_array));
> (retVal[0])->name = (char *)malloc((strlen(vpi_get_str) + 1) *
> sizeof(char));
> strcpy((retVal[0])->name,vpi_get_str);
> (retVal[0])->routine.str_routine = vpi_get_str;
>
> retVal[1] =
> (p_vpi_routine_array)malloc(sizeof(s_vpi_routine_array));
> (retVal[1])->name = (char *)malloc((strlen(vpi_handle) + 1) *
> sizeof(char));
> strcpy((retVal[1])->name,vpi_handle);
> (retVal[1])->routine.int_routine = vpi_handle;
>
> retVal[2] = NULL;
>
> return(retVal);
>}
>main.c file:
>#include <stdarg.h>
>#include <ctype.h>
>#include example.h
>
>extern p_vpi_routine_array *vpi_get_routine_ncv();
>extern p_vpi_routine_array *vpi_get_routine_vcs();
>
>int main(int argc,char *argv[])
>{
> p_vpi_routine_array *ncv = vpi_get_routine_ncv();
> p_vpi_routine_array *vcs = vpi_get_routine_vcs();
> p_vpi_routine_array ptr;
>
> char *(*strFunc)();
>
> ptr = *ncv;
> while (strcmp(ptr->name,vpi_get_str))
> ptr++;
> strFunc = ptr->routine.str_routine;
>
> printf((*strFunc)(vpiName,NULL));
>
> ptr = *vcs;
> while (strcmp(ptr->name,vpi_get_str))
> ptr++;
> strFunc = ptr->routine.str_routine;
>
> printf((*strFunc)(vpiName,NULL));
>}
>This code compiles and when run produces the following output:
>Called NCV vpi_get_str()
>Called VCS vpi_get_str()
>Of course, vpi_get_str() and vpi_handle() are not currently static
>routines in NC-Verilog or VCS. This issue will need to be resolved by the
>various tools.
>
>
>
>
>
>
>
>
>
>At 07:19 PM 12/16/2003 -0500, Joao Geada wrote:
>>Bassam,
>>
>>I still have the same problem as before with the new revision. Basically
>>the issue is that, without explicit indirection,
>>all the VPI routines you use (vpi_handle et all) belong to the simulator
>>and will always reflect the model present in
>>the simulator, rather than any information loaded from the waveform file.
>>
>>I realize that this latest revision has made some effort towards this,
>>but without completely insulating the read vpi
>>from the simulator vpi I do not feel that the effort is sufficient.
>>
>>Personally I would much prefer something with the following form:
>>
>>reader_handle = vpi_read_init(access_mode, "read library to be used",
>>"file to be opened")
>>
>>where:
>>access mode: is the open mode as per your vpi_read_init spec
>>"read library" (string) specifies the reader to be used (eg vcd, vpd,
>>fsdb, dai, etc). If NULL uses
>> vendor's default form. Basically
>> indicates the name of a shared library to be
>> loaded that provides the waveform reading
>> services
>>"file" (string) the name of the waveform file to be opened. Can be NULL
>>if using interactive access
>>
>>If reader_handle is non-NULL then the read initialization was successful.
>> From that point on, all read calls
>>are made following the pattern:
>>
>> reader_handle->vpi_xxxx(args)
>>
>>This approach allows:
>>1) reader API to be kept separate from vendor's tool API
>>2) multiple separate readers to be present simultaneously
>>3) multiple databases (using same or different readers) to be opened
>>simultaneously
>>4) does not (in my opinion) make the interface any harder to use or
>>require any other changes to
>> the existing proposal.
>>I firmly believe that such an approach is essential for the reader API to
>>become viable.
>>
>>Joao
>>
>>==============================================================================
>>
>>Joao Geada, PhD Principal Engineer Verif Tech
>>Group
>>Synopsys, Inc TEL: (508)
>>263-8083
>>377 Simarano Drive, Suite 300, FAX: (508)
>>263-8069
>>Marlboro, MA 01752, USA
>>==============================================================================
>>
>>-----Original Message-----
>>From: Bassam Tabbara [mailto:bassam@novas.com]
>>Sent: Tuesday, December 16, 2003 6:44 PM
>>To: Joao.Geada@synopsys.COM
>>Subject: Feedback on Read API (VPI enhancement)
>>
>>Hi Joao,
>>Swapnajit said you may have some feedback on the Read API ? Can you
>>please send my way, if so ?
>>Thx.
>>-Bassam.
>>
>>--
>>Dr. Bassam Tabbara
>>Technical Manager, R&D
>>Novas Software, Inc.
>>
>><http://www.novas.com/>http://www.novas.com
>>(408) 467-7893
This archive was generated by hypermail 2b28 : Wed Dec 17 2003 - 08:48:08 PST