From e0fbc15bd4aba759bfa0f495894cf225b9cde762 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Mon, 10 Mar 2008 21:54:58 -0700 Subject: [PATCH] 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. --- vpi_user.h | 2 +- vvp/delay.cc | 4 ++-- vvp/vpi_memory.cc | 2 +- vvp/vpi_priv.cc | 11 ++++++--- vvp/vpi_priv.h | 2 +- vvp/vpi_real.cc | 2 +- vvp/vpi_signal.cc | 52 +++++++++++++++--------------------------- vvp/vpi_tasks.cc | 8 +++---- vvp/vpi_vthr_vector.cc | 2 +- 9 files changed, 38 insertions(+), 47 deletions(-) diff --git a/vpi_user.h b/vpi_user.h index 037648621..561ba5164 100644 --- a/vpi_user.h +++ b/vpi_user.h @@ -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); diff --git a/vvp/delay.cc b/vvp/delay.cc index 327c27118..1b4d96aa3 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -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; diff --git a/vvp/vpi_memory.cc b/vvp/vpi_memory.cc index efcae4e8e..b96cb5e76 100644 --- a/vvp/vpi_memory.cc +++ b/vvp/vpi_memory.cc @@ -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); diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index 841538998..62ac996a5 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -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; } diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index c9d9727ee..e9d373d98 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -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); diff --git a/vvp/vpi_real.cc b/vvp/vpi_real.cc index f1ee8c82e..8cf030bd2 100644 --- a/vvp/vpi_real.cc +++ b/vvp/vpi_real.cc @@ -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); diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index c601e84ca..a94cd768a 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -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; diff --git a/vvp/vpi_tasks.cc b/vvp/vpi_tasks.cc index 7cace3ae3..e54b68210 100644 --- a/vvp/vpi_tasks.cc +++ b/vvp/vpi_tasks.cc @@ -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); diff --git a/vvp/vpi_vthr_vector.cc b/vvp/vpi_vthr_vector.cc index cc5b87e5a..d4feea42e 100644 --- a/vvp/vpi_vthr_vector.cc +++ b/vvp/vpi_vthr_vector.cc @@ -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));