vhdlpp: shift_left/right() functions.

This commit is contained in:
Maciej Suminski 2016-01-18 14:38:59 +01:00
parent 03434efed3
commit 2e6fb9b3f6
4 changed files with 88 additions and 1 deletions

View File

@ -199,6 +199,28 @@ void preload_std_funcs(void)
fn_std_logic_vector_args, &primitive_STDLOGIC_VECTOR);
register_std_subprogram(fn_std_logic_vector);
/* numeric_std library
* function shift_left (arg: unsigned; count: natural) return unsigned;
*/
std::list<InterfacePort*>*fn_shift_left_args = new std::list<InterfacePort*>();
fn_shift_left_args->push_back(new InterfacePort(&primitive_UNSIGNED));
fn_shift_left_args->push_back(new InterfacePort(&primitive_UNSIGNED));
SubprogramBuiltin*fn_shift_left = new SubprogramBuiltin(perm_string::literal("shift_left"),
perm_string::literal("$ivlh_shift_left"),
fn_shift_left_args, &primitive_UNSIGNED);
register_std_subprogram(fn_shift_left);
/* numeric_std library
* function shift_right (arg: unsigned; count: natural) return unsigned;
*/
std::list<InterfacePort*>*fn_shift_right_args = new std::list<InterfacePort*>();
fn_shift_right_args->push_back(new InterfacePort(&primitive_UNSIGNED));
fn_shift_right_args->push_back(new InterfacePort(&primitive_UNSIGNED));
SubprogramBuiltin*fn_shift_right = new SubprogramBuiltin(perm_string::literal("shift_right"),
perm_string::literal("$ivlh_shift_right"),
fn_shift_right_args, &primitive_UNSIGNED);
register_std_subprogram(fn_shift_right);
/* function resize
*/
fn_resize = new SubprogramSizeCast(perm_string::literal("resize"));

View File

@ -75,7 +75,7 @@ V = va_math.o
V2009 = v2009_table.o v2009_array.o v2009_enum.o v2009_string.o
VHDL_SYS = vhdl_table.o
VHDL_SYS = vhdl_table.o sys_priv.o
VHDL_TEXTIO = vhdl_textio.o sys_priv.o

View File

@ -1,3 +1,6 @@
$ivlh_attribute_event vpiSysFuncSized 1 unsigned
$ivlh_rising_edge vpiSysFuncSized 1 unsigned
$ivlh_falling_edge vpiSysFuncSized 1 unsigned
$ivlh_shift_left vpiSysFuncSized 32 unsigned
$ivlh_shift_right vpiSysFuncSized 32 unsigned

View File

@ -21,6 +21,7 @@
# include "vpi_user.h"
# include <assert.h>
# include "ivl_alloc.h"
# include "sys_priv.h"
/*
* The $ivlh_attribute_event implements the VHDL <varname>'event
@ -50,6 +51,14 @@ static const char* attr_func_names[] = {
"$ivlh_rising_edge",
"$ivlh_falling_edge"
};
typedef enum {
SHIFT_LEFT = 0,
SHIFT_RIGHT = 1,
} shift_type_t;
static const char* shift_func_names[] = {
"$ivlh_shift_left",
"$ivlh_shift_right",
};
/* To keep valgrind happy free the allocated memory. */
@ -185,6 +194,43 @@ static PLI_INT32 ivlh_attribute_event_sizetf(ICARUS_VPI_CONST PLI_BYTE8*type)
return 1;
}
static PLI_INT32 ivlh_shift_calltf(ICARUS_VPI_CONST PLI_BYTE8*data)
{
shift_type_t shift_type = (shift_type_t) data;
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
vpiHandle argv = vpi_iterate(vpiArgument, callh);
vpiHandle argh = vpi_scan(argv);
vpiHandle counth = vpi_scan(argv);
s_vpi_value val;
PLI_INT32 count;
vpi_free_object(argv);
val.format = vpiIntVal;
vpi_get_value(counth, &val);
count = val.value.integer;
val.format = vpiIntVal;
vpi_get_value(argh, &val);
if(shift_type == SHIFT_LEFT)
val.value.integer <<= count;
else if(shift_type == SHIFT_RIGHT)
val.value.integer >>= count;
else
assert(0);
vpi_put_value(callh, &val, 0, vpiNoDelay);
return 0;
}
static PLI_INT32 ivlh_shift_sizetf(ICARUS_VPI_CONST PLI_BYTE8*type)
{
(void) type; /* Parameter is not used. */
return 32;
}
static void vhdl_register(void)
{
s_vpi_systf_data tf_data;
@ -210,6 +256,22 @@ static void vhdl_register(void)
tf_data.tfname = attr_func_names[FALLING_EDGE];
tf_data.user_data = (PLI_BYTE8*) FALLING_EDGE;
res = vpi_register_systf(&tf_data);
vpip_make_systf_system_defined(res);
/* Shift functions */
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSizedFunc;
tf_data.calltf = ivlh_shift_calltf;
tf_data.compiletf = sys_two_numeric_args_compiletf;
tf_data.sizetf = ivlh_shift_sizetf;
tf_data.tfname = shift_func_names[SHIFT_LEFT];
tf_data.user_data = (PLI_BYTE8*) SHIFT_LEFT;
res = vpi_register_systf(&tf_data);
vpip_make_systf_system_defined(res);
tf_data.tfname = shift_func_names[SHIFT_RIGHT];
tf_data.user_data = (PLI_BYTE8*) SHIFT_RIGHT;
res = vpi_register_systf(&tf_data);
vpip_make_systf_system_defined(res);
/* Create a callback to clear the monitor data memory when the