vhdlpp: shift_left/right() functions.
This commit is contained in:
parent
03434efed3
commit
2e6fb9b3f6
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue