Table of Contents Previous page Next page Index

ModelSim

Model Technology Inc.


mti_CreateSignal()

Creates a new VHDL signal.

Syntax

signal_id = mti_CreateSignal( name, region, type ) 

Returns

Name
Type
Description
signal_id
mtiSignalIdT
A handle to the new VHDL signal or NULL if there is an error

Arguments

Name
Type
Description
name
char *
The name of the new VHDL signal; OPTIONAL - can be NULL
region
mtiRegionIdT
The design region into which the new signal is to be placed
type
mtiTypeIdT
The type of the new signal

Description

mti_CreateSignal() creates a new VHDL signal of the specified type in the specified region. If the name is not NULL, then the signal will appear in the simulator's Signals window.

Signal names must conform to VHDL identifier rules; otherwise they can cause problems for commands like "add wave", "add list", and "examine". All signal names that do not start and end with a '\' are converted to lower case. Signal names starting and ending with '\' are treated as VHDL extended identifiers and are used unchanged.

Related functions

mti_FindSignal()

mti_GetSignalName()

mti_GetSignalRegion()

mti_GetSignalType()

Example

FLI code

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

typedef enum {
  STD_LOGIC_U,
  STD_LOGIC_X,
  STD_LOGIC_0,
  STD_LOGIC_1,
  STD_LOGIC_Z,
  STD_LOGIC_W,
  STD_LOGIC_L,
  STD_LOGIC_H,
  STD_LOGIC_D
} mySigType;

char *std_logic_lits[9] =
{ "'U'", "'X'", "'0'", "'1'", "'Z'", "'W'", "'L'", "'H'", "'-'" };

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 STD_LOGIC_U:
    mti_ScheduleDriver( inst->drvid1, STD_LOGIC_0, 0, MTI_INERTIAL );
    break;
   case STD_LOGIC_0:
    mti_ScheduleDriver( inst->drvid1, STD_LOGIC_1, 5, MTI_INERTIAL );
    break;
   case STD_LOGIC_1:
    mti_ScheduleDriver( inst->drvid1, STD_LOGIC_0, 5, MTI_INERTIAL );
    break;
   case STD_LOGIC_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 STD_LOGIC_U:
    mti_ScheduleDriver( inst->drvid2, STD_LOGIC_0, 0, MTI_INERTIAL );
    break;
   case STD_LOGIC_0:
    mti_ScheduleDriver( inst->drvid2, STD_LOGIC_1, 10, MTI_INERTIAL );
    break;
   case STD_LOGIC_1:
    mti_ScheduleDriver( inst->drvid2, STD_LOGIC_0, 10, MTI_INERTIAL );
    break;
   case STD_LOGIC_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, STD_LOGIC_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, 9, std_logic_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> run 0
VSIM 2> examine mySig1 mySig2 mySig3
# 0 0 0
VSIM 3> run 5
VSIM 4> examine mySig1 mySig2 mySig3
# 1 0 X
VSIM 5> run 5
VSIM 6> examine mySig1 mySig2 mySig3
# 0 1 X
VSIM 7> run 5
VSIM 8> examine mySig1 mySig2 mySig3
# 1 1 1
VSIM 9> 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