Table of Contents Previous page Next page Index

ModelSim

Model Technology Inc.


mti_CreateEnumType()

Creates an enumeration type.

Syntax

type_id = mti_CreateEnumType( size, count, literals ) 

Returns

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

Arguments

Name
Type
Description
size
mtiInt32T
The number of bytes to be used to store the values of the new enumeration type; if the count parameter is greater than 256 then size must be 4; otherwise size can be either 1 or 4
count
mtiInt32T
The number of literals/values in the new enumeration type
literals
char **
An array of strings that define the enumeration literals for the new enumeration type

Description

mti_CreateEnumType() creates a new type ID that describes a VHDL enumeration type. The new type consists of the specified enumeration literals and its values are of the specified size. The count parameter indicates the number of strings in the literals parameter. The left-most value of the enumeration type is 0 and is associated with the first literal string, the next value is 1 and is associated with the next literal string, and so on.

If there are more than 256 values in the enumeration type, then 4 bytes must be used to store the values; otherwise either 1 or 4 bytes can be used.

Related functions

mti_CreateArrayType()

mti_CreateRealType()

mti_CreateScalarType()

mti_CreateTimeType()

mti_GetEnumValues()

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 mySig1 every 5 ns. */
void driveSignal1( void * param )
{
  char          * region_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:
    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, mti_GetSignalName( inst->sigid1 ) );
    mti_VsimFree( region_name );
    break;
   default:
    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,
                       mti_GetSignalName( inst->sigid1 ) );
    mti_VsimFree( region_name );
    break;
  }
}

/* This function inverts mySig2 every 10 ns. */
void driveSignal2( void * param )
{
  char          * region_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:
    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, mti_GetSignalName( inst->sigid2 ) );
    mti_VsimFree( region_name );
    break;
   default:
    region_name = mti_GetRegionFullName(mti_GetSignalRegion(inst->sigid2));
    mti_PrintFormatted( "Time [%d,%d] delta %d: "
                       "Unexpected value %d on signal %s/%s\n",
                       mti_NowUpper(), mti_Now(), mti_Delta(),
                       sigval, region_name,
                       mti_GetSignalName( inst->sigid2 ) );
    mti_VsimFree( region_name );
    break;
  }
}

/* This function drives mySig3 with the values of mySig1 and mySig2. */
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;
  mtiTypeIdT      enum_type;

  inst         = (instanceInfoT *)malloc( sizeof(instanceInfoT) );
  enum_type    = mti_CreateEnumType( 1, 3, enum_lits );

  inst->sigid1 = mti_CreateSignal( "mySig1", region, enum_type );
  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 = mti_CreateSignal( "mySig2", region, enum_type );
  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 = mti_CreateSignal( "mySig3", region, enum_type );
  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 );
} 

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 mySig1 mySig2 mySig3
# 0 0 0
VSIM 2> run 5
VSIM 3> examine mySig1 mySig2 mySig3
# 1 0 X
VSIM 4> run 5
VSIM 5> examine mySig1 mySig2 mySig3
# 0 1 X
VSIM 6> run 5
VSIM 7> examine mySig1 mySig2 mySig3
# 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