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:
Stephen Williams 2008-03-10 21:54:58 -07:00
parent e141d2bb37
commit e0fbc15bd4
9 changed files with 38 additions and 47 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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));