Table of Contents Previous page Next page Index

ModelSim

Model Technology Inc.


mti_CreateArrayType()

Creates an array type.

Syntax

type_id = mti_CreateArrayType( left, right, element_type ) 

Returns

Name
Type
Description
type_id
mtiTypeIdT
A handle to the new array type

Arguments

Name
Type
Description
left
mtiInt32T
The left bound of the new array type
right
mtiInt32T
The right bound of the new array type
element_type
mtiTypeIdT
The type of the elements of the new array type

Description

mti_CreateArrayType() creates a new type ID that describes a VHDL array type whose bounds are the specified left and right values and whose elements are of the specified element type.

Related functions

mti_CreateEnumType()

mti_CreateRealType()

mti_CreateScalarType()

mti_CreateTimeType()

mti_GetArrayElementType()

mti_TickLeft()

mti_TickRight()

Example

FLI code

#include <stdlib.h>
#include <mti.h>

typedef enum {
  SIGVAL_0,
  SIGVAL_1,
  SIGVAL_X
} mySigType;

char *enum_lits[3] = { "0", "1", "X" };

typedef struct {
  mtiSignalIdT sigid1;
  mtiSignalIdT sigid2;
  mtiSignalIdT sigid3;
  mtiDriverIdT drvid1;
  mtiDriverIdT drvid2;
  mtiDriverIdT drvid3;
} instanceInfoT;

/* This function inverts mySig(2) every 5 ns. */
void driveSignal1( void * param )
{
  char          * region_name;
  char          * signal_name;
  instanceInfoT * inst = (instanceInfoT*)param;
  mtiInt32T       sigval;

  sigval = mti_GetSignalValue( inst->sigid1 );

  switch ( sigval ) {
    case SIGVAL_0:
      mti_ScheduleDriver( inst->drvid1, SIGVAL_1, 5, MTI_INERTIAL );
    break;
    case SIGVAL_1:
      mti_ScheduleDriver( inst->drvid1, SIGVAL_0, 5, MTI_INERTIAL );
      break;
    case SIGVAL_X:
      signal_name = mti_GetSignalNameIndirect( inst->sigid1, NULL, 0 );
      region_name =
        mti_GetRegionFullName(mti_GetSignalRegion(inst->sigid1));
      mti_PrintFormatted( "Time [%d,%d] delta %d: Signal %s/%s is UNKNOWN\n",
                         mti_NowUpper(), mti_Now(), mti_Delta(),
                         region_name, signal_name );
      mti_VsimFree( signal_name );
      mti_VsimFree( region_name );
      break;
    default:
      signal_name = mti_GetSignalNameIndirect( inst->sigid1, NULL, 0 );
      region_name = 
        mti_GetRegionFullName(mti_GetSignalRegion(inst->sigid1));
      mti_PrintFormatted( "Time [%d,%d] delta %d: "
                         "Unexpected value %d on signal %s/%s\n",
                         mti_NowUpper(), mti_Now(), mti_Delta(),
                         sigval, region_name, signal_name );
      mti_VsimFree( signal_name );
      mti_VsimFree( region_name );
      break;
  }
}

/* This function inverts mySig(1) every 10 ns. */

void driveSignal2( void * param )
{
  char          * region_name;
  char          * signal_name;
  instanceInfoT * inst = (instanceInfoT*)param;
  mtiInt32T       sigval;

  sigval = mti_GetSignalValue( inst->sigid2 );

  switch ( sigval ) {
    case SIGVAL_0:
      mti_ScheduleDriver( inst->drvid2, SIGVAL_1, 10, MTI_INERTIAL );
    break;
    case SIGVAL_1:
      mti_ScheduleDriver( inst->drvid2, SIGVAL_0, 10, MTI_INERTIAL );
      break;
    case SIGVAL_X:
      signal_name = mti_GetSignalNameIndirect( inst->sigid2, NULL, 0 );
      region_name =
        mti_GetRegionFullName(mti_GetSignalRegion(inst->sigid2));
      mti_PrintFormatted( "Time [%d,%d] delta %d: Signal %s/%s is UNKNOWN\n",
                         mti_NowUpper(), mti_Now(), mti_Delta(),
                         region_name, signal_name );
      mti_VsimFree( signal_name );
      mti_VsimFree( region_name );
      break;
    default:
      signal_name = mti_GetSignalNameIndirect( inst->sigid2, NULL, 0 );
      region_name = 
        mti_GetRegionFullName(mti_GetSignalRegion
(inst->sigid1));
      mti_PrintFormatted( "Time [%d,%d] delta %d: "
                         "Unexpected value %d on signal %s/%s\n",
                         mti_NowUpper(), mti_Now(), mti_Delta(),
                         sigval, region_name, signal_name );
      mti_VsimFree( signal_name );
      mti_VsimFree( region_name );
      break;
  }
}

/* This function drives mySig(0) with the values of mySig(2) and mySig(1). */
void driveSignal3( void * param )
{
  instanceInfoT * inst = (instanceInfoT*)param;
  mtiInt32T       sigval1;
  mtiInt32T       sigval2;

  sigval1 = mti_GetSignalValue( inst->sigid1 );
  sigval2 = mti_GetSignalValue( inst->sigid2 );
  if ( sigval1 == sigval2 ) {
    mti_ScheduleDriver( inst->drvid3, sigval1, 0, MTI_INERTIAL );
  } else {
    mti_ScheduleDriver( inst->drvid3, SIGVAL_X, 0, MTI_INERTIAL );
  }
}

void cleanupCallback( void * param )
{
  mti_PrintMessage( "Cleaning up...\n" );
  free( param );
}

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.   */
)
{
  instanceInfoT * inst;
  mtiProcessIdT   procid;
  mtiSignalIdT  * elem_list;
  mtiSignalIdT    sigid;
  mtiTypeIdT      array_type;
  mtiTypeIdT      enum_type;

  inst         = (instanceInfoT *)malloc( sizeof(instanceInfoT) );
  enum_type    = mti_CreateEnumType( 1, 3, enum_lits );
  array_type   = mti_CreateArrayType( 2, 0, enum_type );
  sigid        = mti_CreateSignal( "mySig", region, array_type );
  elem_list    = mti_GetSignalSubelements( sigid, NULL );

  inst->sigid1 = elem_list[0];
  inst->drvid1 = mti_CreateDriver( inst->sigid1 );
  procid       = mti_CreateProcess( "mySig1Driver", driveSignal1, inst );
  mti_Sensitize( procid, inst->sigid1, MTI_EVENT );
  mti_ScheduleWakeup( procid, 0 );
  mti_SetDriverOwner( inst->drvid1, procid );

  inst->sigid2 = elem_list[1];
  inst->drvid2 = mti_CreateDriver( inst->sigid2 );
  procid       = mti_CreateProcess( "mySig2Driver", driveSignal2, inst );
  mti_Sensitize( procid, inst->sigid2, MTI_EVENT );
  mti_ScheduleWakeup( procid, 0 );
  mti_SetDriverOwner( inst->drvid2, procid );

  inst->sigid3 = elem_list[2];
  inst->drvid3 = mti_CreateDriver( inst->sigid3 );
  procid       = mti_CreateProcess( "mySig3Driver", driveSignal3, inst );
  mti_Sensitize( procid, inst->sigid1, MTI_EVENT );
  mti_Sensitize( procid, inst->sigid2, MTI_EVENT );
  mti_ScheduleWakeup( procid, 0 );
  mti_SetDriverOwner( inst->drvid3, procid );

  mti_AddQuitCB( cleanupCallback, inst );
  mti_AddRestartCB( cleanupCallback, inst );

  mti_VsimFree( elem_list );
} 

HDL code

entity top is
end top;

architecture a of top is
  signal s1 : bit := '0';
begin
  s1 <= not s1 after 5 ns;
end a; 

Simulation output

% vsim -c top -foreign "initForeign for_model.sl"
Reading .../modeltech/sunos5/../tcl/vsim/pref.tcl 

# 5.4b

# vsim -foreign {initForeign for_model.sl} -c top 
# Loading .../modeltech/sunos5/../std.standard
# Loading work.top(a)
# Loading ./for_model.sl
VSIM 1> examine mysig
# {{0} {0} {0}}
VSIM 2> run 5
VSIM 3> examine mysig
# {{1} {0} {X}}
VSIM 4> run 5
VSIM 5> examine mysig
# {{0} {1} {X}}
VSIM 6> run 5
VSIM 7> examine mysig
# {{1} {1} {1}}
VSIM 8> quit
# Cleaning up... 


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

ModelSim