[sv-bc] Definition of `s_vpi_vecval' in `svdpi.h' and `vpi_user.h'

From: Brad Pierce <Brad.Pierce_at_.....>
Date: Sat Jun 16 2007 - 09:44:19 PDT
----- Non-member submission from Will Adams -----

Date: Fri, 15 Jun 2007 17:33:12 -0500

[I could not see a reference to this issue in the `sv-bc' mail archive. 
My apologies if it has already been addressed.']

Logic vectors (ie, four-state bit vectors) passed between SystemVerilog
and C code using DPI are represented in C as a pointer to an array of
`svLogicVecVal'. This type is defined in IEEE 1800-2005 (Appendix G
`Include file svdpi.h') as follows.

   #ifndef VPI_VECVAL
   #define VPI_VECVAL
   typedef struct vpi_vecval {
     uint32_t a;
     uint32_t b;
   } s_vpi_vecval, *p_vpi_vecval;
   #endif

   /* (a chunk of) packed logic array */
   typedef s_vpi_vecval svLogicVecVal;

Type `uint32_t' is defined to be an unsigned 32-bit integer. The header
file defines type `svLogicVecVal' (which is used to pass logic vectors
via DPI) to be the same as the type `s_vpi_vecval' (which is used to
pass logic vectors to VPI routines).

Type `s_vpi_vecval' is also defined in IEEE 1364-2005 (Appendix G
`vpi_user.h'), as follows.

   #ifndef VPI_VECVAL /* added in 1364-2005 */
   #define VPI_VECVAL
   typedef struct t_vpi_vecval
   {
     /* following fields are repeated enough times to contain vector */
     PLI_INT32 aval, bval; /* bit encoding: ab: 00=0, 10=1, 11=X, 01=Z
*/
   } s_vpi_vecval, *p_vpi_vecval;
   #endif

Type `PLI_INT32' is a signed 32-bit integer.

There is an inconsistency in the two definitions of `s_vpi_vecval'. In
`svdpi.h' the fields are called `a' and `b', and are unsigned. In
`vpi_user.h', the fields are called `aval' and `bval', and are signed.
The structure tag is `vpi_vecval' in `svdpi.h', but `t_vpi_vecval' in
`vpi_user.h'. Because of the `#ifndef' guards protecting against
multiple definitions, the definition of type `s_vpi_vecval' seen by C
code depends on the order in which `svdpi.h'
and `vpi_user.h' are included by the user.

Header file `vpi_user.h' also includes the following definition.

   typedef struct t_vpi_value
   {
     PLI_INT32 format; /*
vpi[[Bin,Oct,Dec,Hex]Str,Scalar,Int,Real,String,
                              Vector,Strength,Suppress,Time,ObjType]Val
*/
     union
       {
         PLI_BYTE8                *str;       /* string value */
         PLI_INT32                 scalar;    /* vpi[0,1,X,Z] */
         PLI_INT32                 integer;   /* integer value */
         double                    real;      /* real value */
         struct t_vpi_time        *time;      /* time value */
         struct t_vpi_vecval      *vector;    /* vector value */
         struct t_vpi_strengthval *strength;  /* strength value */
         PLI_BYTE8                *misc;      /* ...other */
       } value;
   } s_vpi_value, *p_vpi_value;

This uses type `struct t_vpi_vecval' for field `value.vector'. This type
is only defined if the definition of `s_vpi_vecval' in `vpi_user.h' is
read before that in `svdpi.h'. If a user file includes `svdpi.h' before
`vpi_user.h', then their code cannot use type `s_vpi_value'.

This case illustrates most of the problems that are caused by having two
definitions of the same type in the source code. All the problems noted
above are solved if there is only a single definition of the type. The
simplest way to ensure this is to replace the definition of
`s_vpi_vecval' in `svdpi.h' with `#include "vpi_user.h"'. In this case,
the `#ifndef VPI_VECVAL' guard around the definition can be removed.

Regards
will adams
Freescale Semiconductor, Inc


--

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Sat Jun 16 09:44:53 2007

This archive was generated by hypermail 2.1.8 : Sat Jun 16 2007 - 09:45:22 PDT