Table of Contents Previous page Next page Index

ModelSim

Model Technology Inc.


mti_AddSocketInputReadyCB()

Adds or removes a socket input ready callback.

Syntax

mti_AddSocketInputReadyCB( socket_desc, func, param ) 

Returns

Nothing

Arguments

Name
Type
Description
socket_desc
int
A socket descriptor
func
mtiVoidFuncPtrT
A pointer to a function to be called whenever there is data available for reading on the socket descriptor
param
void *
A parameter to be passed to the function; OPTIONAL - can be NULL

Description

mti_AddSocketInputReadyCB() puts a watch on the specified socket descriptor. Whenever the socket descriptor has data available for reading, the specified function is called along with its parameter.

To remove a previously added callback, call mti_AddSocketInputReadyCB() with the same socket descriptor but with a NULL function pointer.

mti_AddSocketInputReadyCB() and mti_AddSocketOutputReadyCB() are useful in setting up cosimulation environments where FLI code uses sockets to communicate with other processes. In the course of initialization, a cosimulation application typically would use standard system library routines to create or open a socket and obtain a socket descriptor and then call mti_AddSocketInputReadyCB() and mti_AddSocketOutputReadyCB() to set up the callback functions. During simulation, FLI code may initiate a non-blocking I/O operation on the socket (again using standard system library routines) and immediately return control to the simulator. When the I/O is completed, the simulator invokes the callback function which could check for errors, handle received data, or initiate another non-blocking I/O operation before returning to the simulator.

Related functions

mti_AddInputReadyCB()

mti_AddOutputReadyCB()

mti_AddSocketOutputReadyCB()

Example

FLI code

#include <mti.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdlib.h>

#ifdef WIN32
#include <winsock.h>
#else
#include <unistd.h>
#include <sys/time.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>   /* gethostbyname() */
#endif

#ifdef HP700
#include <resolv.h>
#endif

#ifdef WIN32
#define MAXHOSTNAMELEN MAXGETHOSTSTRUCT
#else
#define SOCKET_ERROR -1
#define INVALID_SOCKET -1
typedef int SOCKET;
#endif

void sockCB( void * sock )
{
  int  i;
  char buf[1];

#ifdef WIN32
  i = recv( (SOCKET)sock, buf, sizeof(buf), 0 );
#else
  i = read( (SOCKET)sock, buf, sizeof(buf) );
#endif
  mti_PrintFormatted( "Read returned %d - Read %c\n", i, buf[0] );

  if ( (i == 0) || (buf[0] == 'C') ) {
      /* Remove the callback. */
      mti_AddSocketInputReadyCB( (SOCKET)sock, (mtiVoidFuncPtrT)0, 0 );       mti_PrintMessage("Closing socket\n");
      close( (SOCKET)sock );
  }
}

void loadDoneCB( void * sock )
{
  mti_PrintMessage( "Load Done: Adding socket callback.\n" );
  mti_AddSocketInputReadyCB( (SOCKET)sock, (mtiVoidFuncPtrT)sockCB, sock );
}

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.   */
)
{
  char   hostname[MAXHOSTNAMELEN] = "localhost";
  int    statusFlags;
  int    server_length;
  int    status;
  int    retry_cnt = 0;
  short  portNum = 0;
  struct sockaddr_in server;
  struct hostent *hp;
  SOCKET sock = INVALID_SOCKET;
  #ifdef WIN32
  WORD    wVersionRequested;
  WSADATA wsaData;
  int     err;

  wVersionRequested = MAKEWORD( 1, 1 );
  err = WSAStartup( wVersionRequested, &wsaData );

  if ( err != 0 ) {
    mti_PrintMessage( "Cannot find a useable winsock.dll.\n" );
    return;
  }

/* Confirm that the Windows Sockets DLL supports 1.1.  Note that if
 * the DLL supports versions greater than 1.1 in addition to 1.1,
 * it will still return 1.1 in wVersion since that is the version
 * we requested.
 */

  if ( (LOBYTE( wsaData.wVersion ) != 1) ||
       (HIBYTE( wsaData.wVersion ) != 1) ) { 
      mti_PrintMessage( "Cannot find a useable winsock.dll.\n" );
      WSACleanup();
      return;
  }
/* The Windows Sockets DLL is acceptable. Proceed. */

#endif

  sock = socket( AF_INET, SOCK_STREAM, 0 );

  if ( sock == INVALID_SOCKET ) {
#ifdef WIN32
    DWORD le = GetLastError();
    mti_PrintFormatted( "Error opening socket. Error=%d\n", le );
#else
    mti_PrintMessage( "Error opening socket.\n" );
#endif
    return;
  }

  while ( retry_cnt < 2 ) {
    memset( (char *)&server, 0, sizeof(server) );
    server.sin_family = AF_INET;
    if ( (hp = gethostbyname(hostname)) == 0 ) {
      mti_PrintFormatted( "%s: Unknown host.\n", hostname );
      close( sock );
      return;
    }
    memcpy( (char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length );
    portNum         = 19; /* 'chargen' */
    server.sin_port = htons(portNum);
    server_length   = sizeof(server);
    status = connect( sock, (struct sockaddr *)&server, server_length );
    if ( status < 0 ) {
      if ( retry_cnt++ > 1 ) {
        mti_PrintFormatted( "Error connecting to server %s:%d\n",
                           hostname, portNum );
        close( sock );
      } else {
        strcpy( hostname, "map" );  /* Put your hostname here. */
      }
    }
  }

#ifdef WIN32
  {
    unsigned long non_blocking = 1;
    status = ioctlsocket( sock, FIONBIO, &non_blocking );
    if ( status == SOCKET_ERROR ) {
      perror( "Setting socket status" );
    }
  }
#else
  statusFlags = fcntl( sock, F_GETFL );
  if ( statusFlags == SOCKET_ERROR ) {
    perror( "Getting socket status" );
  } else {
    int ctlValue;
    statusFlags |= O_NONBLOCK;
    ctlValue = fcntl( sock, F_SETFL, statusFlags );
    if ( ctlValue == SOCKET_ERROR ) {
      perror( "Setting socket status" );
    }
  }
#endif
  mti_AddLoadDoneCB( (mtiVoidFuncPtrT)loadDoneCB, (void *)sock );
} 

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 -foreign "initForeign ./for_model.sl" top
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
# Load Done: Adding socket callback.
# Read returned 1 - Read 
# Read returned 1 - Read !
# Read returned 1 - Read "
# Read returned 1 - Read #
# Read returned 1 - Read $
# Read returned 1 - Read %
# Read returned 1 - Read &
# Read returned 1 - Read '
# Read returned 1 - Read (
# Read returned 1 - Read )
# Read returned 1 - Read *
# Read returned 1 - Read +
# Read returned 1 - Read ,
# Read returned 1 - Read -
# Read returned 1 - Read .
# Read returned 1 - Read /
# Read returned 1 - Read 0
# Read returned 1 - Read 1
# Read returned 1 - Read 2
# Read returned 1 - Read 3
# Read returned 1 - Read 4
# Read returned 1 - Read 5
# Read returned 1 - Read 6
# Read returned 1 - Read 7
# Read returned 1 - Read 8
# Read returned 1 - Read 9
# Read returned 1 - Read :
# Read returned 1 - Read ;
# Read returned 1 - Read <
# Read returned 1 - Read =
# Read returned 1 - Read >
# Read returned 1 - Read ?
# Read returned 1 - Read @
# Read returned 1 - Read A
# Read returned 1 - Read B
# Read returned 1 - Read C
# Closing socket
VSIM 1> quit 


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

ModelSim