1
0
mirror of https://github.com/pConst/basic_verilog.git synced 2025-01-28 07:02:55 +08:00
Konstantin Pavlov (pt) 40533743d7 Added altera cookbook
2015-12-15 22:44:58 +03:00

249 lines
5.9 KiB
C++

// Copyright 2007 Altera Corporation. All rights reserved.
// Altera products are protected under numerous U.S. and foreign patents,
// maskwork rights, copyrights and other intellectual property laws.
//
// This reference design file, and your use thereof, is subject to and governed
// by the terms and conditions of the applicable Altera Reference Design
// License Agreement (either as signed by you or found at www.altera.com). By
// using this reference design file, you indicate your acceptance of such terms
// and conditions between you and Altera Corporation. In the event that you do
// not agree with such terms and conditions, you may not use the reference
// design file and please promptly destroy any copies you have made.
//
// This reference design file is being provided on an "as-is" basis and as an
// accommodation and therefore all warranties, representations or guarantees of
// any kind (whether express, implied or statutory) including, without
// limitation, warranties of merchantability, non-infringement, or fitness for
// a particular purpose, are specifically disclaimed. By making this reference
// design file available, Altera expressly does not recommend, suggest or
// require that this reference design file be used in combination with any
// other product not provided by Altera.
/////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include "vpi_user.h"
void rand_float_register();
unsigned int float_to_int (float f)
{
void * foo = &f;
unsigned int out = *((unsigned int *)foo);
return (out);
}
float int_to_float (int n)
{
void * foo = &n;
float out = *((float *)foo);
return (out);
}
////////////////////////////////////////////////////
// make a random float (single)
////////////////////////////////////////////////////
PLI_INT32 rand_float_calltf(PLI_BYTE8 * user_dat)
{
vpiHandle systf_handle;
s_vpi_value value_s;
float a, b, c, d, out;
unsigned int n;
systf_handle = vpi_handle (vpiSysTfCall,NULL);
n = rand();
a = n;
n = rand();
b = n;
a = a * b;
n = rand();
if (n == 0) n++;
c = n;
n = rand();
if (n == 0) n++;
d = n;
c = c * d;
out = a / c;
n = float_to_int (out);
// vpi_printf ("%08x\n",n);
value_s.format = vpiIntVal;
value_s.value.integer = (PLI_INT32)n;
vpi_put_value (systf_handle,&value_s,NULL,vpiNoDelay);
return(0);
}
void rand_float_register(void)
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSysFuncSized;
tf_data.tfname = "$rand_float";
tf_data.calltf = rand_float_calltf;
tf_data.compiletf = NULL;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
}
////////////////////////////////////////////////////
// divide two floats (single)
////////////////////////////////////////////////////
PLI_INT32 float_div_calltf(PLI_BYTE8 * user_dat)
{
vpiHandle systf_handle, arg_iter, arg_handle;
s_vpi_value value_s;
unsigned int n,d;
float nf,df;
float outf;
unsigned int out;
systf_handle = vpi_handle (vpiSysTfCall,NULL);
arg_iter = vpi_iterate (vpiArgument, systf_handle);
if (!arg_iter)
{
vpi_printf ("Error: fpdiv failed to obtain arg handles");
return (0);
}
arg_handle = vpi_scan (arg_iter);
value_s.format = vpiIntVal;
vpi_get_value (arg_handle,&value_s);
n = value_s.value.integer;
arg_handle = vpi_scan (arg_iter);
value_s.format = vpiIntVal;
vpi_get_value (arg_handle,&value_s);
d = value_s.value.integer;
// vpi_printf ("n=%08x\n",n);
// vpi_printf ("d=%08x\n",d);
vpi_free_object (arg_iter);
nf = int_to_float(n);
df = int_to_float(d);
outf = nf / df;
out = float_to_int (outf);
// vpi_printf ("q = %08x\n",out);
value_s.format = vpiIntVal;
value_s.value.integer = (PLI_INT32)out;
vpi_put_value (systf_handle,&value_s,NULL,vpiNoDelay);
return(0);
}
void float_div_register(void)
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSysFuncSized;
tf_data.tfname = "$float_div";
tf_data.calltf = float_div_calltf;
tf_data.compiletf = NULL;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
}
////////////////////////////////////////////////////
// error
////////////////////////////////////////////////////
PLI_INT32 float_err_bar_calltf(PLI_BYTE8 * user_dat)
{
vpiHandle systf_handle, arg_iter, arg_handle;
s_vpi_value value_s;
unsigned int n,d;
float nf,df;
float outf;
int out;
systf_handle = vpi_handle (vpiSysTfCall,NULL);
arg_iter = vpi_iterate (vpiArgument, systf_handle);
if (!arg_iter)
{
vpi_printf ("Error: fp error bar failed to obtain arg handles");
return (0);
}
arg_handle = vpi_scan (arg_iter);
value_s.format = vpiIntVal;
vpi_get_value (arg_handle,&value_s);
n = value_s.value.integer;
arg_handle = vpi_scan (arg_iter);
value_s.format = vpiIntVal;
vpi_get_value (arg_handle,&value_s);
d = value_s.value.integer;
// vpi_printf ("n=%08x\n",n);
// vpi_printf ("d=%08x\n",d);
vpi_free_object (arg_iter);
nf = int_to_float(n);
df = int_to_float(d);
if (d == 0)
{
outf = 0;
}
else
{
outf = (nf - df) / df;
}
// vpi_printf ("float err = %f\n",outf);
if (outf < 0.0) outf = - outf;
outf = outf * 100 * 100;
// vpi_printf ("scaled float err = %f\n",outf);
out = outf;
// vpi_printf ("int = %08x\n",out);
value_s.format = vpiIntVal;
value_s.value.integer = (PLI_INT32)out;
vpi_put_value (systf_handle,&value_s,NULL,vpiNoDelay);
return(0);
}
void float_err_bar_register(void)
{
s_vpi_systf_data tf_data;
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSysFuncSized;
tf_data.tfname = "$float_err_bar";
tf_data.calltf = float_err_bar_calltf;
tf_data.compiletf = NULL;
tf_data.sizetf = NULL;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
}
/////////////////////////////////////////////
void (*vlog_startup_routines[])() =
{
rand_float_register,
float_div_register,
float_err_bar_register,
0
};