/*
 * This is vpi_presentation_app_2001.c
 * EITHER you have to define the macro BEFORE including vpi_user.h
 * OR you have to define the macro on the compilation line using 
 * the appropriate compiler method to do this, for example:
 * gcc  -c -g -fPIC -DVPI_VERSION_COMPATIBILITY_REQUEST_2001 -DLINUX -I./ ./vpi_presentation_app_2001.c
 * OR you can accept the tool default by not defining any macros. If you do this, the macros can
 * still be defined at compilation.
 * This example defines the macro VPI_VERSION_COMPATIBILITY_REQUEST_2001 in the source code.
 */
#define VPI_VERSION_COMPATIBILITY_REQUEST_2001 1
#include "vpi_user.h" 
#include "sv_vpi_user.h" 

/*
 * Caution! Bad habits are exhibited in this code! No error checking!
 * Fixed length strings! Ugh!
 * Intended as an absolutely minimal example.
 */

int cbStartOfSimulation_function()
{
    vpiHandle module_handle;
    vpiHandle iter_handle;
    vpiHandle scan_handle;
    int i;
    char type_string[100]; /* have to copy strings to local storage */
    char name_string[100]; /* have to copy strings to local storage */

    vpi_printf("hello! here we are at the start of simulation\n");

    vpi_printf("The VPI application will now iterate for vpiRegArray (which is the same as vpiArrayVar)\n");
    vpi_printf("If you are running in 2001 mode you will see only the variable called \"reg_array\".\n");
    vpi_printf("If you are running in 2005 mode you will see both \"reg_array\" and \"integer_array\".\n");

    module_handle = vpi_handle_by_name("/top",0);
    iter_handle=vpi_iterate(vpiRegArray, module_handle);
    scan_handle=vpi_scan(iter_handle);
    
    i = 0; /* just counting how many things we find */
    while (scan_handle) {
	i++;
	strcpy(type_string,vpi_get_str(vpiType, scan_handle));
	strcpy(name_string,vpi_get_str(vpiName, scan_handle));
	vpi_printf("   Object #%d:   Name \"%s\" Type \"%s\"\n", 
		   i, &name_string,&type_string);
	scan_handle = vpi_scan(iter_handle);
    }
    vpi_printf("I found %d objects\n", i);
    vpi_printf("Now let's try that again except lets look for our integer var, which we do with vpiVariables:\n");
    vpi_printf("If you are running in 2001 mode you will see only \"integer_array\" and its type will be vpiIntegerVar.\n");
    vpi_printf("If you are running in 2005 mode you will again see both \"reg_array\" and \"integer_array\",\n and both have type vpiArrayVar.\n");

    /*
     *
     */

    iter_handle=vpi_iterate(vpiVariables, module_handle);
    scan_handle=vpi_scan(iter_handle);
    i = 0;
    while (scan_handle) {
	i++;
	strcpy(type_string,vpi_get_str(vpiType, scan_handle));
	strcpy(name_string,vpi_get_str(vpiName, scan_handle));
	vpi_printf("   Object #%d:   Name \"%s\" Type \"%s\"\n", 
		   i, &name_string,&type_string);
	scan_handle = vpi_scan(iter_handle);
    }
    vpi_printf("I found %d objects\n", i);
}

void RegisterMyTfs( void ) 
{
  s_cb_data cbstart_data;
  vpiHandle cbstart_handle;

  /*
   * Register a callback routine for start of simulation
   */

  cbstart_data.reason = cbStartOfSimulation;
  cbstart_data.cb_rtn = cbStartOfSimulation_function;
  cbstart_data.obj = 0;
  cbstart_data.time = 0;
  cbstart_data.value = 0;
  cbstart_data.user_data = 0;
  cbstart_handle = vpi_register_cb( &cbstart_data );
}

void (*vlog_startup_routines[])() = {
  RegisterMyTfs,
  0
};
