Table of Contents Previous page Next page Index

ModelSim

Model Technology Inc.


mti_ForceSignal()

Forces a value onto a VHDL signal.

Syntax

error_code = mti_ForceSignal( signal_id, value_string, delay, force_type,                               cancel_period, repeat_period ) 

Returns

Name
Type
Description
error_code
int
1 if successful; 0 if there is an error

Arguments

Name
Type
Description
signal_id
mtiSignalIdT
A handle to the VHDL signal to be forced
value_string
char *
The value to be forced specified as a string in the same format as would be provided to the simulator's force command
delay
mtiDelayT
The time at which the force is to be applied relative to the current time; specified in current simulator resolution units
force_type
mtiForceTypeT
Indicates whether the force is to freeze, drive, deposit, or use the default force type
cancel_period
mtiInt32T
If non-negative, specifies the period after which the force is cancelled; specified in current simulator resolution units
repeat_period
mtiInt32T
If non-negative, specifies the period in which the force is repeated; specified in current simulator resolution units

Description

mti_ForceSignal() forces the specified VHDL signal to the specified value using the specified force type and an optional delay, cancel period, and repeat period. The value must be specified in a string in the same format as would be provided to the simulator's force command and the restrictions on the type of the value are the same as for the force command.

If the delay parameter is non-negative, then the delay specifies the time at which the force is to be applied relative to the current time. If the delay parameter is negative, then the force is applied immediately.

If the cancel_period parameter is non-negative, then the force is cancelled after the specified period. If the cancel_period parameter is negative, then the force is not automatically cancelled.

If the repeat_period parameter is non-negative, then the force is repeated for the specified period. If the repeat_period parameter is negative, then the force is not automatically repeated.

To force records or arrays that are not one-dimensional arrays of character enumerations, use mti_GetSignalSubelements() to get a handle to each element and force each element individually.

Related functions

mti_ReleaseSignal()

mti_ScheduleDriver()

mti_SetSignalValue()

Example

FLI code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef WIN32
#include <unistd.h>
#endif

#include <mti.h>

typedef struct signalInfoT_tag {
  struct signalInfoT_tag * next;
  struct signalInfoT_tag * child;
  char                   * name;
  void                   * last_value;
  mtiSignalIdT             sigid;
  mtiTypeIdT               typeid;
  mtiTypeKindT             typekind;
  mtiDirectionT            direction;
  char                     granulate;
} signalInfoT;

typedef struct {
  signalInfoT     * sig_info;         /* List of signals.             */
  mtiProcessIdT     proc;             /* Test process id.             */
  int               state;            /* Current state of test.       */
} instanceInfoT;

static void forceSignal(
  mtiSignalIdT sigid,
  mtiTypeIdT   sigtypeid,
  mtiTypeKindT sigtypekind,
  int          state
)
{
  int           i;
  int           result = 1;
  mtiSignalIdT *elem_list;
  mtiSignalIdT  elem_sigid;
  mtiTypeIdT    elem_typeid;

  switch ( sigtypekind ) {
   case MTI_TYPE_SCALAR:
    switch ( state ) {
     case 0:
      result = mti_ForceSignal(sigid, "42", -1, MTI_FORCE_FREEZE, -1, -1);
      break;
     case 2:
      result = mti_ForceSignal(sigid, "120", 1, MTI_FORCE_FREEZE, 7, -1);
      break;
     case 4:
      result = mti_ForceSignal(sigid, "777", -1, MTI_FORCE_DEPOSIT, -1, 2);
      break;
     }
     break;
   case MTI_TYPE_ARRAY:
    elem_typeid = mti_GetArrayElementType( sigtypeid );
    if ( mti_GetTypeKind( elem_typeid ) == MTI_TYPE_ENUM ) {
      /* NOTE: ASSUMING ARRAY OF LENGTH 4 ! */
     if ( mti_TickLength( elem_typeid ) == 9 ) {  /* ASSUME std_logic */
      switch ( state ) {
       case 0:
        result = mti_ForceSignal( sigid, "ZW1H", -1,
                                MTI_FORCE_FREEZE, -1, -1 );
        break;
       case 2:
        result = mti_ForceSignal( sigid, "LLLL", 1,
                                MTI_FORCE_FREEZE, 7, -1 );
        break;
       case 4:
        result = mti_ForceSignal( sigid, "1-1-", -1,
                                MTI_FORCE_DEPOSIT, -1, 2 );
        break;
      }
     } else {  /* ASSUME bit */
      switch ( state ) {
       case 0:
        result = mti_ForceSignal( sigid, "0011", -1,
                                MTI_FORCE_FREEZE, -1, -1 );
        break;
       case 2:
        result = mti_ForceSignal( sigid, "1000", 1,
                                MTI_FORCE_FREEZE, 7, -1 );
        break;
       case 4:
        result = mti_ForceSignal( sigid, "0010", -1,
                                MTI_FORCE_DEPOSIT, -1, 2 );
        break;
      }
     }
    } else {
     elem_list = mti_GetSignalSubelements( sigid, 0 );
     for ( i = 0; i < mti_TickLength( sigtypeid ); i++ ) {
      elem_sigid  = elem_list[i];
      elem_typeid = mti_GetSignalType( elem_sigid );
      forceSignal( elem_sigid, elem_typeid,
                  mti_GetTypeKind( elem_typeid ), state );
      }
      mti_VsimFree( elem_list );
    }
    break;
   case MTI_TYPE_RECORD:
    elem_list = mti_GetSignalSubelements( sigid, 0 );
    for ( i = 0; i < mti_GetNumRecordElements( sigtypeid ); i++ ) {
     elem_sigid  = elem_list[i];
     elem_typeid = mti_GetSignalType( elem_sigid );
     forceSignal( elem_sigid, elem_typeid,
                 mti_GetTypeKind( elem_typeid ), state );
     }
     mti_VsimFree( elem_list );
     break; 
   case MTI_TYPE_ENUM:
    if ( mti_TickLength( sigtypeid ) == 9 ) {   /* ASSUME std_logic */
     switch ( state ) {
      case 0:
       result = mti_ForceSignal( sigid, "'W'", -1,
                                MTI_FORCE_FREEZE, -1, -1 );
       break;
      case 2:
       result = mti_ForceSignal( sigid, "'0'", 1,
                                MTI_FORCE_FREEZE, 7, -1 );
       break;
      case 4:
       result = mti_ForceSignal( sigid, "'H'", -1,
                                MTI_FORCE_DEPOSIT, -1, 2 );
       break;
     }
    } else {
     switch ( state ) {  /* ASSUME bit */ 
      case 0:
       result = mti_ForceSignal( sigid, "0", -1,
                                MTI_FORCE_FREEZE, -1, -1 );
       break;
      case 2:
       result = mti_ForceSignal( sigid, "1", 1,
                                MTI_FORCE_FREEZE, 7, -1 );
       break;
      case 4:
       result = mti_ForceSignal( sigid, "0", -1,
                                MTI_FORCE_DEPOSIT, -1, 2 );
       break;
     }
    }
    break;
   default:
    break;
  }
  if ( ! result ) {
   fprintf( stderr, "Error in signal force.\n" );
  }
}

static void releaseSignal(
  mtiSignalIdT sigid,
  mtiTypeIdT   sigtypeid,
  mtiTypeKindT sigtypekind
)
{
  int           i;
  mtiSignalIdT *elem_list;
  mtiSignalIdT  elem_sigid;
  mtiTypeIdT    elem_typeid;

  switch ( sigtypekind ) {
   case MTI_TYPE_SCALAR:
   case MTI_TYPE_ENUM:
   case MTI_TYPE_TIME:
    if ( ! mti_ReleaseSignal( sigid ) ) {
     fprintf( stderr, "Error in signal release.\n" );
    }
    break;
   case MTI_TYPE_ARRAY:
    elem_typeid = mti_GetArrayElementType( sigtypeid );
    if ( mti_GetTypeKind( elem_typeid ) == MTI_TYPE_ENUM ) {
     if ( ! mti_ReleaseSignal( sigid ) ) {
      fprintf( stderr, "Error in signal release.\n" );
     }
    } else {
     elem_list = mti_GetSignalSubelements( sigid, 0 );
     for ( i = 0; i < mti_TickLength( sigtypeid ); i++ ) {
      elem_sigid  = elem_list[i];
      elem_typeid = mti_GetSignalType( elem_sigid );
      releaseSignal( elem_sigid, elem_typeid,
                    mti_GetTypeKind( elem_typeid ) );
     }
     mti_VsimFree( elem_list );
    }
    break;
   case MTI_TYPE_RECORD:
    elem_list = mti_GetSignalSubelements( sigid, 0 );
    for ( i = 0; i < mti_GetNumRecordElements( sigtypeid ); i++ ) {
     elem_sigid  = elem_list[i];
     elem_typeid = mti_GetSignalType( elem_sigid );
     releaseSignal( elem_sigid, elem_typeid,
                   mti_GetTypeKind( elem_typeid ) );
    }
    mti_VsimFree( elem_list );
    break;
   default:
    break;
  }
}

static void testForce( void *inst_info )
{
  instanceInfoT *inst_data = (instanceInfoT *)inst_info;
  signalInfoT   *siginfo;

  switch ( inst_data->state ) {
   case 0:
   case 2:
   case 4:
    for (siginfo = inst_data->sig_info; siginfo; siginfo = siginfo->next) {
     forceSignal( siginfo->sigid, siginfo->typeid,
                 siginfo->typekind, inst_data->state );
    }
    break;
   case 1:
   case 3:
   case 5:
    for (siginfo = inst_data->sig_info; siginfo; siginfo = siginfo->next) {
     releaseSignal( siginfo->sigid, siginfo->typeid, siginfo->typekind );
    }
    break;
   default:
    break;
  }

  inst_data->state++;
  mti_ScheduleWakeup( inst_data->proc, 10 );
}

static signalInfoT * setupSignal( mtiSignalIdT sigid )
{
  signalInfoT * siginfo;

  siginfo = (signalInfoT *) mti_Malloc( sizeof(signalInfoT) );
  siginfo->sigid       = sigid;
  siginfo->name        = mti_GetSignalNameIndirect( sigid, 0, 0 );
  siginfo->typeid      = mti_GetSignalType( sigid );
  siginfo->typekind    = mti_GetTypeKind( siginfo->typeid );
  siginfo->direction   = mti_GetSignalMode( sigid );
  siginfo->last_value  = mti_GetSignalValueIndirect( sigid, 0 );
  siginfo->child       = 0;
  siginfo->next        = 0;

  /* For records and arrays of composites, we want to set/drive
  * values at the subelement level.  For scalars and arrays of
  * scalars, we want to set/drive values at the top level.
  */
  switch ( siginfo->typekind ) { 
   case MTI_TYPE_ARRAY:
    switch( mti_GetTypeKind(mti_GetArrayElementType(siginfo->typeid)) ) {
     case MTI_TYPE_ARRAY:
     case MTI_TYPE_RECORD:
      siginfo->granulate = 1;
      break;
     default:
      siginfo->granulate = 0;
      break;
    }
    break;
   case MTI_TYPE_RECORD:
    siginfo->granulate = 1;
    break;
   default:
    siginfo->granulate = 0;
    break;
  }

  if ( siginfo->granulate ) {
    signalInfoT  * eleminfo;
    signalInfoT  * currinfo;
    int            i;
    mtiSignalIdT * subelem;

    subelem = mti_GetSignalSubelements( siginfo->sigid, 0 );
    for ( i = 0; i < mti_TickLength(siginfo->typeid); i++ ) {
     eleminfo = setupSignal( subelem[i] );
     if ( siginfo->child == 0 ) {
      siginfo->child = eleminfo;
     } else {
      currinfo->next = eleminfo;
     }
     currinfo = eleminfo;
    }
    mti_VsimFree( subelem );
  }

  return( siginfo );
}

static void initInstance( void )
{
  instanceInfoT * inst_data;
  mtiRegionIdT    region;
  mtiSignalIdT    sigid;
  signalInfoT   * curr_info;
  signalInfoT   * siginfo;

  inst_data           = mti_Malloc( sizeof(instanceInfoT) );
  inst_data->sig_info = 0;
  inst_data->state    = 0;
  region              = mti_GetTopRegion();

  for (sigid = mti_FirstSignal( region ); sigid; sigid = mti_NextSignal()) {
   siginfo = setupSignal( sigid );
   if ( inst_data->sig_info == 0 ) {
    inst_data->sig_info = siginfo;
   }
   else {
    curr_info->next = siginfo;
   }
    curr_info = siginfo;
  }

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

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

library ieee;
use ieee.std_logic_1164.all;

package typepkg is

  type bitarray  is array( 3 downto 0 ) of bit;
  type intarray  is array( 1 to 3 )     of integer;

  type rectype is record
    a : bit;
    b : integer;
    c : std_logic;
  end record;

end package typepkg;

-- -- --

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;

use work.typepkg.all;

entity top is
end top;

architecture a of top is

  signal bitsig1      : bit       := '1';
  signal intsig1      : integer   := 21;
  signal stdlogicsig1 : std_logic := 'H';

  signal bitarr1      : bitarray  := "0110";
  signal stdlogicarr1 : std_logic_vector( 1 to 4 ) := "-X0U";
  signal intarr1      : intarray  := ( 10, 11, 12 );

  signal rec1         : rectype   := ( '0', 1, 'X' );

  component for_model
  end component;

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

begin

  inst1 : for_model;

  bitsig1      <= not bitsig1 after 5 ns;
  intsig1      <= intsig1 + 1 after 5 ns;
  stdlogicsig1 <= '-' after 5 ns when stdlogicsig1 = 'H' else
                  'U' after 5 ns when stdlogicsig1 = '-' else
                  'X' after 5 ns when stdlogicsig1 = 'U' else
                  '0' after 5 ns when stdlogicsig1 = 'X' else
                  '1' after 5 ns when stdlogicsig1 = '0' else
                  'Z' after 5 ns when stdlogicsig1 = '1' else
                  'W' after 5 ns when stdlogicsig1 = 'Z' else
                  'L' after 5 ns when stdlogicsig1 = 'W' else
                  'H' after 5 ns;

bitarr1           <= not bitarr1 after 5 ns;

intarr1(1)        <= intarr1(1) + 1 after 5 ns;
intarr1(2)        <= intarr1(2) + 1 after 5 ns;
intarr1(3)        <= intarr1(3) + 1 after 5 ns;

stdlogicarr1(1) <= '-' after 5 ns when stdlogicarr1(1) = 'H' else
                  'U' after 5 ns when stdlogicarr1(1) = '-' else
                  'X' after 5 ns when stdlogicarr1(1) = 'U' else
                  '0' after 5 ns when stdlogicarr1(1) = 'X' else
                  '1' after 5 ns when stdlogicarr1(1) = '0' else
                  'Z' after 5 ns when stdlogicarr1(1) = '1' else
                  'W' after 5 ns when stdlogicarr1(1) = 'Z' else
                  'L' after 5 ns when stdlogicarr1(1) = 'W' else
                  'H' after 5 ns;

stdlogicarr1(2) <= '-' after 5 ns when stdlogicarr1(2) = 'H' else
                  'U' after 5 ns when stdlogicarr1(2) = '-' else
                  'X' after 5 ns when stdlogicarr1(2) = 'U' else
                  '0' after 5 ns when stdlogicarr1(2) = 'X' else
                  '1' after 5 ns when stdlogicarr1(2) = '0' else
                  'Z' after 5 ns when stdlogicarr1(2) = '1' else
                  'W' after 5 ns when stdlogicarr1(2) = 'Z' else
                  'L' after 5 ns when stdlogicarr1(2) = 'W' else
                  'H' after 5 ns;

stdlogicarr1(3) <= '-' after 5 ns when stdlogicarr1(3) = 'H' else
                  'U' after 5 ns when stdlogicarr1(3) = '-' else
                  'X' after 5 ns when stdlogicarr1(3) = 'U' else
                  '0' after 5 ns when stdlogicarr1(3) = 'X' else
                  '1' after 5 ns when stdlogicarr1(3) = '0' else
                  'Z' after 5 ns when stdlogicarr1(3) = '1' else
                  'W' after 5 ns when stdlogicarr1(3) = 'Z' else
                  'L' after 5 ns when stdlogicarr1(3) = 'W' else
                  'H' after 5 ns;

stdlogicarr1(4) <= '-' after 5 ns when stdlogicarr1(4) = 'H' else
                  'U' after 5 ns when stdlogicarr1(4) = '-' else
                  'X' after 5 ns when stdlogicarr1(4) = 'U' else
                  '0' after 5 ns when stdlogicarr1(4) = 'X' else
                  '1' after 5 ns when stdlogicarr1(4) = '0' else
                  'Z' after 5 ns when stdlogicarr1(4) = '1' else
                  'W' after 5 ns when stdlogicarr1(4) = 'Z' else
                  'L' after 5 ns when stdlogicarr1(4) = 'W' else
                  'H' after 5 ns;

rec1.a <= not rec1.a after 5 ns;
rec1.b <= rec1.b + 1 after 5 ns;
rec1.c <= '-' after 5 ns when rec1.c = 'H' else
          'U' after 5 ns when rec1.c = '-' else
          'X' after 5 ns when rec1.c = 'U' else
          '0' after 5 ns when rec1.c = 'X' else
          '1' after 5 ns when rec1.c = '0' else
          'Z' after 5 ns when rec1.c = '1' else
          'W' after 5 ns when rec1.c = 'Z' else
          'L' after 5 ns when rec1.c = 'W' else
          'H' after 5 ns;

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.typepkg
# Loading work.top(a)
# Loading work.for_model(a)
# Loading ./for_model.sl
VSIM 1> add list -w 1 /top/bitsig1
VSIM 2> add list -w 3 /top/intsig1
VSIM 3> add list -w 1 /top/stdlogicsig1
VSIM 4> add list -w 4 /top/bitarr1
VSIM 5> add list -w 4 /top/stdlogicarr1
VSIM 6> add list -w 15 /top/intarr1
VSIM 7> add list -w 10 /top/rec1
VSIM 8> run 70
VSIM 9> write list list.out
VSIM 10> quit -f
% cat list.out
 ns       /top/bitsig1                    /top/intarr1  /top/rec1
  delta       /top/intsig1
           /top/stdlogicsig1
                     /top/bitarr1
                     /top/stdlogicarr1
  0  +0              1  21 H 0110 -X0U      {10 11 12}    {0 1 X} 
  5  +0              0  22 - 1001 U01X      {11 12 13}    {1 2 0} 
 10  +0              1  23 U 0110 X1Z0      {12 13 14}    {0 3 1} 
 11  +0              0  42 W 0011 ZW1H      {42 42 42}   {0 42 W} 
 21  +1              1  43 L 1100 WLZ-      {43 43 43}   {1 43 L} 
 26  +0              0  44 H 0011 LHWU      {44 44 44}   {0 44 H} 
 31  +0              1  45 - 1100 H-LX      {45 45 45}   {1 45 -} 
 32  +0              1 120 0 1000 LLLL   {120 120 120}  {1 120 0} 
 38  +1              0 121 1 0111 HHHH   {121 121 121}  {0 121 1} 
 43  +0              1 122 Z 1000 ----   {122 122 122}  {1 122 Z} 
 48  +0              0 123 W 0111 UUUU   {123 123 123}  {0 123 W} 
 51  +0              0 777 H 0010 1-1-   {777 777 777}  {0 777 H} 
 53  +0              0 777 H 0010 1-1-   {777 777 777}  {0 777 H} 
 56  +0              0 778 - 1101 ZUZU   {778 778 778}  {0 778 -} 
 57  +0              0 777 H 0010 1-1-   {777 777 777}  {0 777 H} 
 58  +0              1 777 H 0010 1-1-   {777 777 777}  {1 777 H} 
 59  +0              0 777 H 0010 1-1-   {777 777 777}  {0 777 H} 
 61  +1              1 778 - 1101 ZUZU   {778 778 778}  {1 778 -} 
 66  +0              0 779 U 0010 WXWX   {779 779 779}  {0 779 U}  


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

ModelSim