OpenCores
URL https://opencores.org/ocsvn/wf3d/wf3d/trunk

Subversion Repositories wf3d

[/] [wf3d/] [trunk/] [bin/] [vpi/] [vpi.c] - Rev 9

Compare with Previous | Blame | View Log

//=======================================================================
// Project Monophony
//   Wire-Frame 3D Graphics Accelerator IP Core
//
// File:
//   vpi.c
//
// Abstract:
//   VPI source code for Icarus Verilog
//
// Author:
//   Kenji Ishimaru (info.info.wf3d@gmail.com)
//
//======================================================================
//
// Copyright (c) 2015, Kenji Ishimaru
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//  -Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
//  -Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Revision History
 
#include <stdio.h>
#include <string.h>
 
#include "vpi_user.h"
 
#define TRUE 1
#define FALSE 0
 
/* local prototypes */
static int count_systf_args(vpiHandle);
 
/* global prototypes */
PLI_INT32 hello(void);
PLI_INT32 to_float32(void);
PLI_INT32 to_real32(void);
PLI_INT32 to_float22(void);
extern void register_my_systfs(void); 
extern void register_my_systfs(void);
 
/*
 * possible pattern for register vpi_ system tasks and functions
 */
 
/*
 * this is routine to implement registered systf call back
 *
 * notice vpi_user.h requires function return int so using dummy 0
 */
PLI_INT32 hello(void)
{
 vpiHandle href, iref;
 
 href = vpi_handle(vpiSysTfCall, NULL); 
 if (href == NULL) 
  {
   vpi_printf("** ERR: $hello PLI 2.0 can not access systf call handle\n");
   return(0);
  }
 if ((iref = vpi_iterate(vpiArgument, href)) != NULL)
  { 
   vpi_printf(
    "**ERR: $hello PLI 2.0 task called with %d arguments but none allowed\n",
    count_systf_args(iref));
   return(0);
  }
 vpi_printf("hello world\n");
 return(0);
}
 
 
PLI_INT32 to_float32(void)
{
  vpiHandle href, iref , ret_ref, in_ref;
  int numargs;
  s_vpi_value tmpval;
  union {
    float f;
    unsigned int u;
  } _uf;
 
 href = vpi_handle(vpiSysTfCall, NULL); 
 if (href == NULL) 
  {
   vpi_printf("** ERR: $to_float32 PLI 2.0 can not access systf call handle\n");
   return(0);
  }
 if ((iref = vpi_iterate(vpiArgument, href)) != NULL)
  { 
   numargs = vpi_get(vpiSize, iref);
   /* vpi_printf("numargs = %d\n",numargs); */
   ret_ref = vpi_scan(iref);
 
   in_ref = vpi_scan(iref);
   tmpval.format = vpiRealVal; 
   vpi_get_value(in_ref, &tmpval);
   /*
   vpi_printf(
    "$to_float32 float %f\n",tmpval.value.real);
   */
   _uf.f = tmpval.value.real;
   tmpval.format = vpiIntVal;
   tmpval.value.integer = _uf.u;
   vpi_put_value (ret_ref, &tmpval, NULL, vpiNoDelay);
   return(0);
  }
 return(0);
}
 
PLI_INT32 to_real32(void)
{
  vpiHandle href, iref , ret_ref, in_ref;
  int numargs;
  s_vpi_value tmpval;
  union {
    float f;
    unsigned int u;
  } _uf;
 
 href = vpi_handle(vpiSysTfCall, NULL); 
 if (href == NULL) 
  {
   vpi_printf("** ERR: $to_real32 PLI 2.0 can not access systf call handle\n");
   return(0);
  }
 if ((iref = vpi_iterate(vpiArgument, href)) != NULL)
  { 
   numargs = vpi_get(vpiSize, iref);
   /* vpi_printf("numargs = %d\n",numargs); */
   ret_ref = vpi_scan(iref);
 
   in_ref = vpi_scan(iref);
   tmpval.format = vpiIntVal; 
   vpi_get_value(in_ref, &tmpval);
   /*
   vpi_printf(
    "$to_float32 float %f\n",tmpval.value.real);
   */
   _uf.u = tmpval.value.integer;
   tmpval.format = vpiRealVal;
   tmpval.value.real = (double)_uf.f;
   vpi_put_value (ret_ref, &tmpval, NULL, vpiNoDelay);
   return(0);
  }
 return(0);
}
 
 
// float32 to float 22
//   float32 : s = 1bit, e = 8bit, m = 23bit (bias:127)
//   float22 : s = 1bit, e = 5bit, m = 16bit (bias:15)
unsigned int cnv_f32_to_f22(unsigned int a) {
  // extract sign
  unsigned int tmp_s = (a >> 31) & 1;
  // extract exp
  int tmp_e = (a >> 23) & 0xff;
  tmp_e -= 127;
  tmp_e += 15;
  if (tmp_e < 0) tmp_e = 0;
  // extract fraction
  unsigned int rbit = (a >> 7) & 1;// bit 7
  unsigned int tmp_m = (a >> 8)& 0x7fff;
  if (rbit) tmp_m++;
  if (tmp_e != 0) tmp_m |= 0x8000;
  return  (tmp_s << 21) | (tmp_e << 16) | tmp_m;
}
 
 
PLI_INT32 to_float22(void)
{
  vpiHandle href, iref , ret_ref, in_ref;
  int numargs;
  s_vpi_value tmpval;
  union {
    float f;
    unsigned int u;
  } _uf;
 
 href = vpi_handle(vpiSysTfCall, NULL); 
 if (href == NULL) 
  {
   vpi_printf("** ERR: $to_float22 PLI 2.0 can not access systf call handle\n");
   return(0);
  }
 if ((iref = vpi_iterate(vpiArgument, href)) != NULL)
  { 
   numargs = vpi_get(vpiSize, iref);
   /* vpi_printf("numargs = %d\n",numargs); */
   ret_ref = vpi_scan(iref);
 
   in_ref = vpi_scan(iref);
   tmpval.format = vpiRealVal; 
   vpi_get_value(in_ref, &tmpval);
   /*
   vpi_printf(
    "$to_float32 float %f\n",tmpval.value.real);
   */
   _uf.f = tmpval.value.real;
   tmpval.format = vpiIntVal;
   tmpval.value.integer =  cnv_f32_to_f22(_uf.u);
   vpi_put_value (ret_ref, &tmpval, NULL, vpiNoDelay);
   return(0);
  }
 return(0);
}
 
 
/*
 * count arguments
 */
static int count_systf_args(vpiHandle iref)
{
 int anum = 0;
 
 while (vpi_scan(iref) != NULL) anum++;
 return(anum);
}
 
/* Template functin table for added user systf tasks and functions.
   See file vpi_user.h for structure definition
   Note only vpi_register_systf and vpi_ or tf_ utility routines that 
   do not access the simulation data base may be called from these routines
*/ 
 
/* all routines are called to register system tasks */
/* called just after all PLI 1.0 tf_ veriusertfs table routines are set up */
/* before source is read */ 
void (*vlog_startup_routines[]) () =
{
 register_my_systfs, 
 0
};
 
/* routine to do the systf registering - probably should go in other file */
/* usually only vpi_ PLI 2.0 systf registering is done here */
 
/*
 * register all vpi_ PLI 2.0 style user system tasks and functions
 */
void register_my_systfs(void)
{
 p_vpi_systf_data systf_data_p;
 
 /* use predefined table form - could fill systf_data_list dynamically */
 static s_vpi_systf_data systf_data_list[] = {
  { vpiSysTask, 0, "$hello", hello, NULL, NULL, NULL },
  { vpiSysTask, 0, "$to_float32", to_float32, NULL, NULL, NULL },
  { vpiSysTask, 0, "$to_real32", to_real32, NULL, NULL, NULL },
  { vpiSysTask, 0, "$to_float22", to_float22, NULL, NULL, NULL },
  { 0, 0, NULL, NULL, NULL, NULL, NULL }
 };
 
 systf_data_p = &(systf_data_list[0]);
 while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++);
}
 
void vpi_compat_bootstrap(void)
{
 int i;
 
 for (i = 0;; i++) 
  {
   if (vlog_startup_routines[i] == NULL) break; 
   vlog_startup_routines[i]();
  }
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.