Table of Contents Previous page Next page Index

ModelSim

Model Technology Inc.


mti_GetVarAddr()

Gets a pointer to a VHDL variable's value space.

Syntax

value = mti_GetVarAddr( var_name ) 

Returns

Name
Type
Description
value
void *
A pointer to the value space of the specified variable

Arguments

Name
Type
Description
var_name
char *
The name of a VHDL variable

Description

mti_GetVarAddr() returns a pointer to the value space of a VHDL variable of any type except record.

The variable name must be specified according to the following rules:

NULL is returned if the variable is not found or if the variable is of a record type. The value pointer must not be freed.

The value of the variable can be read and written at any time directly via the value pointer. The value pointer is interpreted as follows:

For a scalar signal or an array signal with a subelement of type
The value should be cast to
Enum
(char *) if <= 256 values
(mtiInt32T *) if > 256 values
Physical
(mtiInt32T *)
Real
(double *)
Scalar (Integer)
(mtiInt32T *)
Time
(mtiTime64T *)

The number of subelements of an array variable can be determined by calling mti_TickLength() on the type of the array variable.

mti_GetVarAddr() can be called successfully only after the end of elaboration.

Related functions

mti_GetVarValue()

mti_SetVarValue()

Example

FLI code

#include <stdio.h>
#include <mti.h>

#define NAME_MAX 1024

typedef struct varInfoT_tag {
  struct varInfoT_tag  * next;
  char                 * name;
  void                 * var_addr;
  mtiVariableIdT         varid;
  mtiTypeIdT             typeid;
} varInfoT;

typedef struct {
  varInfoT      * var_info;     /* List of variables. */
  mtiProcessIdT   proc;         /* Test process id. */
} instanceInfoT;

static void setValue( varInfoT * varinfo, int indent )
{
  switch ( mti_GetTypeKind( varinfo->typeid ) ) {
    case MTI_TYPE_ENUM:
      {
        char ** enum_values;
        enum_values = mti_GetEnumValues( varinfo->typeid );
        if ( mti_TickLength( varinfo->typeid ) <= 256 ) {
          char var_val = *(char *)(varinfo->var_addr);
          mti_PrintFormatted( "  %s\n", enum_values[(int)var_val] );
          var_val += 1;
          if (( var_val > mti_TickHigh( varinfo->typeid ) ) ||
              ( var_val < mti_TickLow( varinfo->typeid ) )) {
            var_val = mti_TickLeft( varinfo->typeid );
          }
          *(char *)(varinfo->var_addr) = var_val;
        } else {
          mtiInt32T var_val = *(mtiInt32T *)(varinfo->var_addr);
          mti_PrintFormatted( "  %s\n", enum_values[var_val] );
          var_val += 1;
          if (( var_val > mti_TickHigh( varinfo->typeid ) ) ||
              ( var_val < mti_TickLow( varinfo->typeid ) )) {
            var_val = mti_TickLeft( varinfo->typeid );
          }
          *(mtiInt32T *)(varinfo->var_addr) = var_val;
        }
      }
      break;
    case MTI_TYPE_PHYSICAL:
    case MTI_TYPE_SCALAR:
      {
        mtiInt32T var_val = *(mtiInt32T *)(varinfo->var_addr);
        mti_PrintFormatted( "  %d\n", var_val );
        var_val += 1;
        *(mtiInt32T *)(varinfo->var_addr) = var_val;
      }
      break;
    case MTI_TYPE_ARRAY:
      {
        int            i;
        mtiInt32T      num_elems;
        mtiTypeIdT     elem_type;
        mtiTypeKindT   elem_typekind;
        void         * array_val;

        array_val = varinfo->var_addr;
        num_elems = mti_TickLength( varinfo->typeid );
        elem_type = mti_GetArrayElementType( varinfo->typeid );
        elem_typekind = mti_GetTypeKind( elem_type );
        switch ( elem_typekind ) {
          case MTI_TYPE_ENUM:
            {
              char ** enum_values;
              enum_values = mti_GetEnumValues( elem_type );
              if ( mti_TickLength( elem_type ) > 256 ) {
                mtiInt32T * val = array_val;
                for ( i = 0; i < num_elems; i++ ) {
                  mti_PrintFormatted( "  %s", enum_values[val[i]] );
                  val[i] += 1;
                  if (( val[i] > mti_TickHigh( elem_type )) ||
                      ( val[i] < mti_TickLow( elem_type ))) {
                    val[i] = mti_TickLeft( elem_type );
                  }
                }
              } else {
                char * val = array_val;
                for ( i = 0; i < num_elems; i++ ) {
                  mti_PrintFormatted( "  %s", enum_values[val[i]] );
                  val[i] += 1;
                  if (( val[i] > mti_TickHigh( elem_type )) ||
                      ( val[i] < mti_TickLow( elem_type ))) {
                    val[i] = mti_TickLeft( elem_type );
                  }
                }
              }
            }
            break;
          case MTI_TYPE_PHYSICAL:
          case MTI_TYPE_SCALAR:
            {
              mtiInt32T * val = array_val;
              for ( i = 0; i < num_elems; i++ ) {
                mti_PrintFormatted( "  %d", val[i] );
                val[i] += 1;
              }
            }
            break;
          case MTI_TYPE_ARRAY:
            mti_PrintMessage( "  ARRAY" );
            break;
          case MTI_TYPE_RECORD:
            mti_PrintMessage( "  RECORD" );
            break;
          case MTI_TYPE_REAL:
            {
              double * val = array_val;
              for ( i = 0; i < num_elems; i++ ) {
                mti_PrintFormatted( "  %g", val[i] );
                val[i] += 1.1;
              }
            }
            break;
          case MTI_TYPE_TIME:
            {
              mtiTime64T * val = array_val;
              for ( i = 0; i < num_elems; i++ ) {
                mti_PrintFormatted( "  [%d,%d]",
                                   MTI_TIME64_HI32(val[i]),
                                   MTI_TIME64_LO32(val[i]) );
                MTI_TIME64_ASGN( val[i],
                                   MTI_TIME64_HI32(val[i]),
                                   MTI_TIME64_LO32(val[i]) + 1 );
              }
            }
            break;
          default:
            break;
        }
        mti_PrintFormatted( "\n" );
      }
      break;
    case MTI_TYPE_RECORD:
      mti_PrintFormatted( "  RECORD" );
      break;
    case MTI_TYPE_REAL:
      mti_PrintFormatted( "  %g\n", *(double *)(varinfo->var_addr) );
      *(double *)(varinfo->var_addr) += 1.1;
      break;
    case MTI_TYPE_TIME:
      {
        mtiTime64T time_val = *(mtiTime64T *)(varinfo->var_addr);
        mti_PrintFormatted( "  [%d,%d]\n",
                           MTI_TIME64_HI32(time_val),
                           MTI_TIME64_LO32(time_val) );
        MTI_TIME64_ASGN( *(mtiTime64T *)(varinfo->var_addr),
                           MTI_TIME64_HI32(time_val) + 1,
                           MTI_TIME64_LO32(time_val) + 1 );
      }
      break;
    default:
      mti_PrintMessage( "\n" );
      break;
  }
}

static void checkValues( void *inst_info )
{
  instanceInfoT *inst_data = (instanceInfoT *)inst_info;
  varInfoT      *varinfo;

  mti_PrintFormatted( "Time [%d,%d]:\n", mti_NowUpper(), mti_Now() );

  for ( varinfo = inst_data->var_info; varinfo; varinfo = varinfo->next ) {
    mti_PrintFormatted( "  Variable %s:", varinfo->name );
    setValue( varinfo, 4 );
  }

  mti_ScheduleWakeup( inst_data->proc, 5 );
}

static varInfoT * setupVariable(
  mtiVariableIdT varid,
  mtiRegionIdT   regid,
  mtiProcessIdT  procid
)
{
  char       var_name[NAME_MAX];
  char     * region_name;
  varInfoT * varinfo;

  varinfo           = (varInfoT *) mti_Malloc( sizeof(varInfoT) );
  varinfo->varid    = varid;
  varinfo->name     = mti_GetVarName( varid );
  varinfo->typeid   = mti_GetVarType( varid );
  region_name       = mti_GetRegionFullName( regid );
  sprintf( var_name, "%s/%s/%s", region_name, mti_GetProcessName( procid ),
          varinfo->name );
  varinfo->var_addr = mti_GetVarAddr( var_name );
  mti_VsimFree( region_name );
  varinfo->next     = 0;

  return( varinfo );
}

static void initInstance( void )
{
  instanceInfoT * inst_data;
  mtiProcessIdT   procid;
  mtiRegionIdT    regid;
  mtiVariableIdT  varid;
  varInfoT      * curr_info;
  varInfoT      * varinfo;

  inst_data           = mti_Malloc( sizeof(instanceInfoT) );
  inst_data->var_info = 0;

  regid = mti_GetTopRegion();
  for ( procid = mti_FirstProcess( regid );
        procid; procid = mti_NextProcess() ) {
    for ( varid = mti_FirstVar( procid ); varid; varid = mti_NextVar() ) {
      varinfo = setupVariable( varid, regid, procid );
      if ( inst_data->var_info == 0 ) {
        inst_data->var_info = varinfo;
      }
      else {
        curr_info->next = varinfo;
      }
      curr_info = varinfo;
    }
  }

  inst_data->proc = mti_CreateProcess( "Test Process", checkValues,
                                      (void *)inst_data );
  mti_ScheduleWakeup( inst_data->proc, 5 );
}

void initForeign(
  mtiRegionIdT       region,   /* The ID of the region in which this     */
                               /* foreign architecture is instantiated.  */
  char              *param,    /* The last part of the string in the     */
                               /* foreign attribute.                     */
  mtiInterfaceListT *generics, /* A list of generics for the foreign model.*/
  mtiInterfaceListT *ports     /* A list of ports for the foreign model.   */
)
{
  mti_AddLoadDoneCB( initInstance, 0 );
} 

HDL code

entity for_model is
end for_model;

architecture a of for_model is
  attribute foreign of a : architecture is "initForeign for_model.sl;";
begin
end a;

library ieee;
use ieee.std_logic_1164.all;

entity top is

  type bitarray  is array( 3 downto 0 ) of bit;
  type intarray  is array( 1 to 3 )     of integer;
  type realarray is array( 1 to 2 )     of real;
  type timearray is array( -1 to 0 )    of time;

end top;

architecture a of top is

  component for_model
  end component;

  for all : for_model use entity work.for_model(a);

begin

  inst1 : for_model;

  p1 : process

    variable bitsig      : bit       := '1';
    variable intsig      : integer   := 21;
    variable realsig     : real      := 16.35;
    variable timesig     : time      := 5 ns;
    variable stdlogicsig : std_logic := 'H';

    variable bitarr      : bitarray  := "0110";
    variable stdlogicarr : std_logic_vector( 1 to 4 ) := "01LH";
    variable intarr      : intarray  := ( 10, 11, 12 );
    variable realarr     : realarray := ( 11.6, 101.22 );
    variable timearr     : timearray := ( 15 ns, 6 ns );

  begin

    wait for 5 ns;

  end process;

end a; 

Simulation output

% vsim -c top
Reading .../modeltech/sunos5/../tcl/vsim/pref.tcl 

# 5.4b

# vsim -c top 
# Loading .../modeltech/sunos5/../std.standard
# Loading .../modeltech/sunos5/../ieee.std_logic_1164(body)
# Loading work.top(a)
# Loading work.for_model(a)
# Loading ./for_model.sl
VSIM 1> run 16
# Time [0,5]:
#   Variable bitsig:  '1'
#   Variable intsig:  21
#   Variable realsig:  16.35
#   Variable timesig:  [0,5]
#   Variable stdlogicsig:  'H'
#   Variable bitarr:  '0'  '1'  '1'  '0'
#   Variable stdlogicarr:  '0'  '1'  'L'  'H'
#   Variable intarr:  10  11  12
#   Variable realarr:  11.6  101.22
#   Variable timearr:  [0,15]  [0,6]
# Time [0,10]:
#   Variable bitsig:  '0'
#   Variable intsig:  22
#   Variable realsig:  17.45
#   Variable timesig:  [1,6]
#   Variable stdlogicsig:  '-'
#   Variable bitarr:  '1'  '0'  '0'  '1'
#   Variable stdlogicarr:  '1'  'Z'  'H'  '-'
#   Variable intarr:  11  12  13
#   Variable realarr:  12.7  102.32
#   Variable timearr:  [0,16]  [0,7]
# Time [0,15]:
#   Variable bitsig:  '1'
#   Variable intsig:  23
#   Variable realsig:  18.55
#   Variable timesig:  [2,7]
#   Variable stdlogicsig:  'U'
#   Variable bitarr:  '0'  '1'  '1'  '0'
#   Variable stdlogicarr:  'Z'  'W'  '-'  'U'
#   Variable intarr:  12  13  14
#   Variable realarr:  13.8  103.42
#   Variable timearr:  [0,17]  [0,8]
VSIM 2> quit 


Model Technology Inc.
Voice: (503) 641-1340
Fax: (503)526-5410
http://www.model.com
sales@model.com
TOC PREV NEXT INDEX

ModelSim