Support vpiForceFlag and vpiReleaseFlag for nets.
vpi_put_value can mimic force and release with vpiForceFlag and vpiReleaseFlag flags to the vpi_put_value call. With this patch, the infrastructure is added to allow the flags argument to be passed to the dispatched put_value function, and for signals handle those flags as force/release of a net.
This commit is contained in:
parent
e141d2bb37
commit
e0fbc15bd4
|
|
@ -357,7 +357,7 @@ typedef struct t_vpi_delay {
|
|||
|
||||
#define vpiForceFlag 5
|
||||
#define vpiReleaseFlag 6
|
||||
|
||||
#define vpiReturnEvent 0x1000
|
||||
|
||||
/* VPI FUNCTIONS */
|
||||
extern void vpi_register_systf(const struct t_vpi_systf_data*ss);
|
||||
|
|
|
|||
|
|
@ -544,7 +544,7 @@ static void modpath_src_get_value(vpiHandle ref, p_vpi_value vp)
|
|||
return ;
|
||||
}
|
||||
|
||||
static vpiHandle modpath_src_put_value(vpiHandle ref, s_vpi_value *vp )
|
||||
static vpiHandle modpath_src_put_value(vpiHandle ref, s_vpi_value *vp, int )
|
||||
{
|
||||
assert((ref->vpi_type->type_code == vpiModPathIn));
|
||||
struct __vpiModPathSrc* modpathsrc = vpip_modpath_src_from_handle( ref) ;
|
||||
|
|
@ -599,7 +599,7 @@ static int modpath_src_free_object( vpiHandle ref )
|
|||
* specific delays values in a vpiModPathIn object
|
||||
*
|
||||
*/
|
||||
static void modpath_src_put_delays ( vpiHandle ref, p_vpi_delay delays )
|
||||
static void modpath_src_put_delays (vpiHandle ref, p_vpi_delay delays)
|
||||
{
|
||||
vvp_time64_t tmp[12];
|
||||
int idx;
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ static int memory_word_get(int code, vpiHandle ref)
|
|||
}
|
||||
}
|
||||
|
||||
static vpiHandle memory_word_put(vpiHandle ref, p_vpi_value val)
|
||||
static vpiHandle memory_word_put(vpiHandle ref, p_vpi_value val, int)
|
||||
{
|
||||
struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref;
|
||||
assert(ref->vpi_type->type_code==vpiMemoryWord);
|
||||
|
|
|
|||
|
|
@ -640,13 +640,14 @@ void vpi_get_value(vpiHandle expr, s_vpi_value*vp)
|
|||
struct vpip_put_value_event : vvp_gen_event_s {
|
||||
vpiHandle handle;
|
||||
s_vpi_value value;
|
||||
int flags;
|
||||
virtual void run_run();
|
||||
~vpip_put_value_event() { }
|
||||
};
|
||||
|
||||
void vpip_put_value_event::run_run()
|
||||
{
|
||||
handle->vpi_type->vpi_put_value_ (handle, &value);
|
||||
handle->vpi_type->vpi_put_value_ (handle, &value, flags);
|
||||
}
|
||||
|
||||
vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp,
|
||||
|
|
@ -657,7 +658,10 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp,
|
|||
if (obj->vpi_type->vpi_put_value_ == 0)
|
||||
return 0;
|
||||
|
||||
if (flags != vpiNoDelay) {
|
||||
int return_event_flag = flags & vpiReturnEvent;
|
||||
flags &= ~vpiReturnEvent;
|
||||
|
||||
if (flags!=vpiNoDelay && flags!=vpiForceFlag && flags!=vpiReleaseFlag) {
|
||||
vvp_time64_t dly;
|
||||
|
||||
assert(when != 0);
|
||||
|
|
@ -680,11 +684,12 @@ vpiHandle vpi_put_value(vpiHandle obj, s_vpi_value*vp,
|
|||
vpip_put_value_event*put = new vpip_put_value_event;
|
||||
put->handle = obj;
|
||||
put->value = *vp;
|
||||
put->flags = flags;
|
||||
schedule_generic(put, dly, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
(obj->vpi_type->vpi_put_value_)(obj, vp);
|
||||
(obj->vpi_type->vpi_put_value_)(obj, vp, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ struct __vpirt {
|
|||
int (*vpi_get_)(int, vpiHandle);
|
||||
char* (*vpi_get_str_)(int, vpiHandle);
|
||||
void (*vpi_get_value_)(vpiHandle, p_vpi_value);
|
||||
vpiHandle (*vpi_put_value_)(vpiHandle, p_vpi_value);
|
||||
vpiHandle (*vpi_put_value_)(vpiHandle, p_vpi_value, int flags);
|
||||
|
||||
/* These methods follow references. */
|
||||
vpiHandle (*handle_)(int, vpiHandle);
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ static void real_var_get_value(vpiHandle ref, s_vpi_value*vp)
|
|||
fun->get_value(vp);
|
||||
}
|
||||
|
||||
static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp)
|
||||
static vpiHandle real_var_put_value(vpiHandle ref, p_vpi_value vp, int)
|
||||
{
|
||||
assert(ref->vpi_type->type_code == vpiRealVar);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2007 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -594,20 +594,11 @@ static vvp_vector4_t from_stringval(const char*str, unsigned wid)
|
|||
return val;
|
||||
}
|
||||
|
||||
static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp)
|
||||
static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp, int flags)
|
||||
{
|
||||
unsigned wid;
|
||||
struct __vpiSignal*rfp;
|
||||
|
||||
assert((ref->vpi_type->type_code==vpiNet)
|
||||
|| (ref->vpi_type->type_code==vpiReg));
|
||||
|
||||
rfp = (struct __vpiSignal*)ref;
|
||||
|
||||
/* This is the destination that I'm going to poke into. Make
|
||||
it from the vvp_net_t pointer, and assume a write to
|
||||
port-0. This is the port where signals receive input. */
|
||||
vvp_net_ptr_t destination (rfp->node, 0);
|
||||
struct __vpiSignal*rfp = vpip_signal_from_handle(ref);
|
||||
assert(rfp);
|
||||
|
||||
/* Make a vvp_vector4_t vector to receive the translated value
|
||||
that we are going to poke. This will get populated
|
||||
|
|
@ -630,26 +621,6 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp)
|
|||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case vpiScalarVal:
|
||||
switch (vp->value.scalar) {
|
||||
case vpi0:
|
||||
functor_poke(rfp, 0, 0, St0, 0);
|
||||
break;
|
||||
case vpi1:
|
||||
functor_poke(rfp, 0, 1, St1, 0);
|
||||
break;
|
||||
case vpiX:
|
||||
functor_poke(rfp, 0, 2, StX, 0);
|
||||
break;
|
||||
case vpiZ:
|
||||
functor_poke(rfp, 0, 3, HiZ, 0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case vpiVectorVal:
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||
unsigned long aval = vp->value.vector[idx/32].aval;
|
||||
|
|
@ -688,6 +659,21 @@ static vpiHandle signal_put_value(vpiHandle ref, s_vpi_value*vp)
|
|||
|
||||
}
|
||||
|
||||
if (flags == vpiReleaseFlag) {
|
||||
vvp_net_ptr_t dest_cmd(rfp->node, 3);
|
||||
vvp_send_long(dest_cmd, 2 /* release/net */);
|
||||
return ref;
|
||||
}
|
||||
|
||||
int dest_port = 0;
|
||||
if (flags == vpiForceFlag)
|
||||
dest_port = 2;
|
||||
|
||||
/* This is the destination that I'm going to poke into. Make
|
||||
it from the vvp_net_t pointer, and assume a write to
|
||||
port-0. This is the port where signals receive input. */
|
||||
vvp_net_ptr_t destination (rfp->node, dest_port);
|
||||
|
||||
vvp_send_vec4(destination, val);
|
||||
|
||||
return ref;
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ static const struct __vpirt vpip_systask_rt = {
|
|||
* bits and set into the thread space bits that were selected at
|
||||
* compile time.
|
||||
*/
|
||||
static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp)
|
||||
static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp, int)
|
||||
{
|
||||
assert(ref->vpi_type->type_code == vpiSysFuncCall);
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ static vpiHandle sysfunc_put_value(vpiHandle ref, p_vpi_value vp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static vpiHandle sysfunc_put_real_value(vpiHandle ref, p_vpi_value vp)
|
||||
static vpiHandle sysfunc_put_real_value(vpiHandle ref, p_vpi_value vp, int)
|
||||
{
|
||||
assert(ref->vpi_type->type_code == vpiSysFuncCall);
|
||||
|
||||
|
|
@ -291,7 +291,7 @@ static vpiHandle sysfunc_put_real_value(vpiHandle ref, p_vpi_value vp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static vpiHandle sysfunc_put_4net_value(vpiHandle ref, p_vpi_value vp)
|
||||
static vpiHandle sysfunc_put_4net_value(vpiHandle ref, p_vpi_value vp, int)
|
||||
{
|
||||
assert(ref->vpi_type->type_code == vpiSysFuncCall);
|
||||
|
||||
|
|
@ -379,7 +379,7 @@ static vpiHandle sysfunc_put_4net_value(vpiHandle ref, p_vpi_value vp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static vpiHandle sysfunc_put_rnet_value(vpiHandle ref, p_vpi_value vp)
|
||||
static vpiHandle sysfunc_put_rnet_value(vpiHandle ref, p_vpi_value vp, int)
|
||||
{
|
||||
assert(ref->vpi_type->type_code == vpiSysFuncCall);
|
||||
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ static void vthr_vec_get_value(vpiHandle ref, s_vpi_value*vp)
|
|||
/*
|
||||
* The put_value method writes the value into the vector.
|
||||
*/
|
||||
static vpiHandle vthr_vec_put_value(vpiHandle ref, s_vpi_value*vp)
|
||||
static vpiHandle vthr_vec_put_value(vpiHandle ref, s_vpi_value*vp, int)
|
||||
{
|
||||
assert((ref->vpi_type->type_code==vpiNet)
|
||||
|| (ref->vpi_type->type_code==vpiReg));
|
||||
|
|
|
|||
Loading…
Reference in New Issue