Add VPI examples
This commit is contained in:
parent
d298a14bff
commit
2c8c60429c
2
examples/log2-vpi-common-vpi/.gitignore
vendored
Normal file
2
examples/log2-vpi-common-vpi/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.o
|
||||
*.vpi
|
||||
16
examples/log2-vpi-common-vpi/utest.vh
Normal file
16
examples/log2-vpi-common-vpi/utest.vh
Normal file
@ -0,0 +1,16 @@
|
||||
`ifndef UTEST_VERILOG_DEFINES
|
||||
`define UTEST_VERILOG_DEFINES
|
||||
|
||||
// Log level string prefixes for use with $display function.
|
||||
// Example usage: $display("%sError message", `LOG_ERR);
|
||||
`define LOG_INFO "INFO#"
|
||||
`define LOG_WARN "WARN#"
|
||||
`define LOG_ERR "FAIL#"
|
||||
|
||||
// Dirty hacked redefine of $display function. Must be used with two parentheses.
|
||||
// Example usage: `log_info(("Information message"));
|
||||
`define log_quiet(msg) begin $display({$sformatf msg}); end
|
||||
`define log_info(msg) begin $display({`LOG_INFO, $sformatf msg}); end
|
||||
`define log_warn(msg) begin $display({`LOG_WARN, $sformatf msg}); end
|
||||
`define log_error(msg) begin $display({`LOG_ERR, $sformatf msg}); end
|
||||
`endif
|
||||
67
examples/log2-vpi-common-vpi/vpi_log2.c
Normal file
67
examples/log2-vpi-common-vpi/vpi_log2.c
Normal file
@ -0,0 +1,67 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <vpi_user.h>
|
||||
|
||||
/* --------------------------- VPI INTERFACE -------------------------------- */
|
||||
|
||||
#define MAX_ARGS 8
|
||||
|
||||
static int calltf(char *user_data)
|
||||
{
|
||||
vpiHandle systfref, arg_iter;
|
||||
vpiHandle arg_hndl[MAX_ARGS];
|
||||
struct t_vpi_value argval;
|
||||
int arg_cnt = 0;
|
||||
|
||||
for (int i = 0; i < MAX_ARGS; i++)
|
||||
arg_hndl[i] = NULL;
|
||||
|
||||
systfref = vpi_handle(vpiSysTfCall, NULL);
|
||||
arg_iter = vpi_iterate(vpiArgument, systfref);
|
||||
|
||||
/* ---- Get agruments ---- */
|
||||
if (arg_iter != NULL)
|
||||
while (arg_cnt < MAX_ARGS &&
|
||||
NULL != (arg_hndl[arg_cnt] = vpi_scan(arg_iter)))
|
||||
arg_cnt++;
|
||||
|
||||
// function $log2
|
||||
if (arg_cnt != 1)
|
||||
vpi_printf("ERROR: $log2() wrong argument count\n");
|
||||
else {
|
||||
double arg, ret;
|
||||
|
||||
// get argument
|
||||
argval.format = vpiRealVal;
|
||||
vpi_get_value(arg_hndl[0], &argval);
|
||||
arg = argval.value.real;
|
||||
|
||||
ret = log2(arg);
|
||||
|
||||
// put return value
|
||||
argval.format = vpiRealVal;
|
||||
argval.value.real = ret;
|
||||
vpi_put_value(systfref, &argval, NULL, vpiNoDelay);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_ARGS; i++)
|
||||
if (arg_hndl[i]) vpi_free_object(arg_hndl[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void register_interface(void)
|
||||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiRealFunc;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.calltf = calltf;
|
||||
tf_data.tfname = "$log2";
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
typedef void (*stfunc)(void);
|
||||
stfunc vlog_startup_routines[] = {register_interface, 0};
|
||||
22
examples/log2-vpi-common-vpi/vpi_log2.sv
Normal file
22
examples/log2-vpi-common-vpi/vpi_log2.sv
Normal file
@ -0,0 +1,22 @@
|
||||
`timescale 1ps/1ps
|
||||
|
||||
`include "utest.vh"
|
||||
|
||||
module vpi_log2 #(parameter ARGUMENT = 1.0,
|
||||
parameter SIGMA = 1e-6);
|
||||
real dut, gold;
|
||||
|
||||
initial begin
|
||||
gold = $ln(ARGUMENT) / $ln(2);
|
||||
dut = $log2(ARGUMENT);
|
||||
|
||||
`log_info(("Gold: %0f", gold));
|
||||
`log_info((" DUT: %0f", dut));
|
||||
|
||||
if ($abs(gold - dut) > SIGMA)
|
||||
`log_error(("FAIL"));
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule // vpi_log2
|
||||
25
examples/log2-vpi-common-vpi/vpi_log2.utest
Normal file
25
examples/log2-vpi-common-vpi/vpi_log2.utest
Normal file
@ -0,0 +1,25 @@
|
||||
;; -*- scheme -*-
|
||||
|
||||
;; Uses one common VPI module compiled in the testbench base directory
|
||||
|
||||
(let ((top "vpi_log2"))
|
||||
;; compile VPI module in the base directory
|
||||
(if (utest/iverilog-compile-vpi "vpi_log2.c"
|
||||
#:output-dir (utest/base-path)
|
||||
#:name top #:libs "m")
|
||||
(map
|
||||
(lambda (arg)
|
||||
(utest/tb
|
||||
((format "log2_~a" arg))
|
||||
|
||||
(utest/run-simulation-iverilog
|
||||
"vpi_log2.sv"
|
||||
top
|
||||
|
||||
#:parameters `((ARGUMENT ,arg))
|
||||
#:vpimods top
|
||||
;; VPI modules search path
|
||||
#:vpipaths (utest/base-path))))
|
||||
(iota 20))
|
||||
|
||||
#f))
|
||||
16
examples/log2-vpi/utest.vh
Normal file
16
examples/log2-vpi/utest.vh
Normal file
@ -0,0 +1,16 @@
|
||||
`ifndef UTEST_VERILOG_DEFINES
|
||||
`define UTEST_VERILOG_DEFINES
|
||||
|
||||
// Log level string prefixes for use with $display function.
|
||||
// Example usage: $display("%sError message", `LOG_ERR);
|
||||
`define LOG_INFO "INFO#"
|
||||
`define LOG_WARN "WARN#"
|
||||
`define LOG_ERR "FAIL#"
|
||||
|
||||
// Dirty hacked redefine of $display function. Must be used with two parentheses.
|
||||
// Example usage: `log_info(("Information message"));
|
||||
`define log_quiet(msg) begin $display({$sformatf msg}); end
|
||||
`define log_info(msg) begin $display({`LOG_INFO, $sformatf msg}); end
|
||||
`define log_warn(msg) begin $display({`LOG_WARN, $sformatf msg}); end
|
||||
`define log_error(msg) begin $display({`LOG_ERR, $sformatf msg}); end
|
||||
`endif
|
||||
67
examples/log2-vpi/vpi_log2.c
Normal file
67
examples/log2-vpi/vpi_log2.c
Normal file
@ -0,0 +1,67 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <vpi_user.h>
|
||||
|
||||
/* --------------------------- VPI INTERFACE -------------------------------- */
|
||||
|
||||
#define MAX_ARGS 8
|
||||
|
||||
static int calltf(char *user_data)
|
||||
{
|
||||
vpiHandle systfref, arg_iter;
|
||||
vpiHandle arg_hndl[MAX_ARGS];
|
||||
struct t_vpi_value argval;
|
||||
int arg_cnt = 0;
|
||||
|
||||
for (int i = 0; i < MAX_ARGS; i++)
|
||||
arg_hndl[i] = NULL;
|
||||
|
||||
systfref = vpi_handle(vpiSysTfCall, NULL);
|
||||
arg_iter = vpi_iterate(vpiArgument, systfref);
|
||||
|
||||
/* ---- Get agruments ---- */
|
||||
if (arg_iter != NULL)
|
||||
while (arg_cnt < MAX_ARGS &&
|
||||
NULL != (arg_hndl[arg_cnt] = vpi_scan(arg_iter)))
|
||||
arg_cnt++;
|
||||
|
||||
// function $log2
|
||||
if (arg_cnt != 1)
|
||||
vpi_printf("ERROR: $log2() wrong argument count\n");
|
||||
else {
|
||||
double arg, ret;
|
||||
|
||||
// get argument
|
||||
argval.format = vpiRealVal;
|
||||
vpi_get_value(arg_hndl[0], &argval);
|
||||
arg = argval.value.real;
|
||||
|
||||
ret = log2(arg);
|
||||
|
||||
// put return value
|
||||
argval.format = vpiRealVal;
|
||||
argval.value.real = ret;
|
||||
vpi_put_value(systfref, &argval, NULL, vpiNoDelay);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_ARGS; i++)
|
||||
if (arg_hndl[i]) vpi_free_object(arg_hndl[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void register_interface(void)
|
||||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiRealFunc;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.calltf = calltf;
|
||||
tf_data.tfname = "$log2";
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
typedef void (*stfunc)(void);
|
||||
stfunc vlog_startup_routines[] = {register_interface, 0};
|
||||
22
examples/log2-vpi/vpi_log2.sv
Normal file
22
examples/log2-vpi/vpi_log2.sv
Normal file
@ -0,0 +1,22 @@
|
||||
`timescale 1ps/1ps
|
||||
|
||||
`include "utest.vh"
|
||||
|
||||
module vpi_log2 #(parameter ARGUMENT = 1.0,
|
||||
parameter SIGMA = 1e-6);
|
||||
real dut, gold;
|
||||
|
||||
initial begin
|
||||
gold = $ln(ARGUMENT) / $ln(2);
|
||||
dut = $log2(ARGUMENT);
|
||||
|
||||
`log_info(("Gold: %0f", gold));
|
||||
`log_info((" DUT: %0f", dut));
|
||||
|
||||
if ($abs(gold - dut) > SIGMA)
|
||||
`log_error(("FAIL"));
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule // vpi_log2
|
||||
19
examples/log2-vpi/vpi_log2.utest
Normal file
19
examples/log2-vpi/vpi_log2.utest
Normal file
@ -0,0 +1,19 @@
|
||||
;; -*- scheme -*-
|
||||
|
||||
;; Compile VPI module for each test
|
||||
|
||||
(let ((top "vpi_log2"))
|
||||
(map
|
||||
(lambda (arg)
|
||||
(utest/tb
|
||||
((format "log2_~a" arg))
|
||||
|
||||
(if (utest/iverilog-compile-vpi "vpi_log2.c" #:name top #:libs "m")
|
||||
(utest/run-simulation-iverilog
|
||||
"vpi_log2.sv"
|
||||
top
|
||||
#:parameters `((ARGUMENT ,arg))
|
||||
#:vpimods top)
|
||||
|
||||
#f)))
|
||||
(iota 20)))
|
||||
1
examples/simple-counter/.gitignore
vendored
Normal file
1
examples/simple-counter/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/work
|
||||
Loading…
x
Reference in New Issue
Block a user