Site hosted by Angelfire.com: Build your free website today!



How to implement math.h functions in Verilog

Contributed by
Steve Meyer
Pragmatic C Software Corp.




Here is a PLI 2.0 example. The code below shows a set of functions, used by their respective system calls. Together they achieve the same functionality that of their corresponding library function of math.h in C.

The most useful feature to learn from this code is, perhaps, its simplicity. There are not more than 10-12 lines of actual code in the application. This shows the power of PLI when it comes to writing application within Verilog.

This code has been created and run using PLI2.0. For implementation using PLI1.0 in VCS, click here.


#include <stdio.h>
#include <math.h>

#include "veriuser.h"
#include "cv_veriuser.h"
#include "vpi_user.h"
#include "cv_vpi_user.h"

/* prototypes */
static int my_log10(void);
extern void register_my_systfs(void); 

static int my_log10(void)
{
 double d1, d2;
 vpiHandle systfref, argsiter, argh;
 struct t_vpi_value wrkval;

 /* get system function that invoked C routine */
 systfref = vpi_handle(vpiSysTfCall, NULL); 
 /* get iterator (list) of passed arguments */
 argsiter = vpi_iterate(vpiArgument, systfref);
 /* get the one argument - add loop for more args */
 argh = vpi_scan(argsiter);

 /* get the argument value */
 wrkval.format = vpiRealVal;
 vpi_get_value(argh, &wrkval);
 d1 =  wrkval.value.real;

 /* any C library function can go here */
 d2 = log10(d1);

 /* return value by assigning to calling systf handle */
 wrkval.value.real = d2;
 vpi_put_value(systfref, &wrkval, NULL, vpiNoDelay);
 return(0);
}

/* my boiler plate for registering system tasks */
void (*vlog_startup_routines[]) () =
{
 register_my_systfs, 
 0
};

/*
 * register my user system tasks and functions
 */
void register_my_systfs(void)
{
 p_vpi_systf_data systf_data_p;

 static s_vpi_systf_data systf_data_list[] = {
  { vpiSysFunc, vpiSysFuncReal, "$log10", my_log10, 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++);
}


module top;
 initial
  begin
   // try some easy logs
   $display("log 1.0 = %g", $log10(1.0)); 
   $display("log 10.0 = %g", $log10(10.0)); 
   $display("log 100.0 = %g", $log10(100.0)); 
  end
endmodule

List1 : The sample verilog file using the system call


CVER_1.80_1 of 05/22/98 (Linux-elf).
Copyright (c) 1991-1998 Pragmatic C Software Corp.
Compiling source file "vlog10.v"
Highest level modules:
top

log 1.0 = 0
log 10.0 = 1
log 100.0 = 2
1 simulation events and 0 declarative immediate assigns processed.
3 behavioral statements executed (0 procedural suspends).

List2 : Running the simulation


Vineyard Research