From 1b911ad87a0e3bb117d4ed7f5e5d23fa4496cb32 Mon Sep 17 00:00:00 2001 From: steve Date: Sun, 5 Mar 2006 05:45:58 +0000 Subject: [PATCH] Add support for memory value change callbacks. --- vvp/memory.cc | 16 +++++++++- vvp/memory.h | 8 ++++- vvp/vpi_callback.cc | 9 +++++- vvp/vpi_memory.cc | 77 +++++++++++++++++++++++++++++++++++++++------ vvp/vpi_priv.h | 9 +++++- 5 files changed, 105 insertions(+), 14 deletions(-) diff --git a/vvp/memory.cc b/vvp/memory.cc index a453bc0ed..96f237eae 100644 --- a/vvp/memory.cc +++ b/vvp/memory.cc @@ -19,12 +19,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: memory.cc,v 1.28 2006/02/02 02:44:00 steve Exp $" +#ident "$Id: memory.cc,v 1.29 2006/03/05 05:45:58 steve Exp $" #endif #include "memory.h" #include "symbols.h" #include "schedule.h" +#include "vpi_priv.h" #include #ifdef HAVE_MALLOC_H #include @@ -52,6 +53,7 @@ struct vvp_memory_s // List of ports into this memory. class vvp_fun_memport* port_list; + vpiHandle vpi_self; }; #define VVP_MEMORY_NO_ADDR ((int)0x80000000) @@ -119,6 +121,13 @@ void memory_configure(vvp_memory_t mem, assert(mem->words); mem->port_list = 0; + mem->vpi_self = 0; +} + +void memory_attach_self(vvp_memory_t mem, vpiHandle self) +{ + assert(mem->vpi_self == 0); + mem->vpi_self = self; } unsigned memory_word_width(vvp_memory_t mem) @@ -208,6 +217,8 @@ void memory_set_word(vvp_memory_t mem, unsigned addr, ; cur ; cur = cur->next_) { cur->check_word_change(addr); } + + vpip_run_memory_value_change(mem->vpi_self, addr); } void schedule_memory(vvp_memory_t mem, unsigned addr, @@ -264,6 +275,9 @@ void vvp_fun_memport::check_word_change(unsigned long addr) /* * $Log: memory.cc,v $ + * Revision 1.29 2006/03/05 05:45:58 steve + * Add support for memory value change callbacks. + * * Revision 1.28 2006/02/02 02:44:00 steve * Allow part selects of memory words in l-values. * diff --git a/vvp/memory.h b/vvp/memory.h index 39b2d7771..2841aef91 100644 --- a/vvp/memory.h +++ b/vvp/memory.h @@ -20,10 +20,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: memory.h,v 1.11 2006/02/02 02:44:00 steve Exp $" +#ident "$Id: memory.h,v 1.12 2006/03/05 05:45:58 steve Exp $" #endif #include "vvp_net.h" +#include "vpi_user.h" /* ** vvp_memory_t is a memory @@ -52,6 +53,7 @@ struct memory_address_range { extern void memory_configure(vvp_memory_t mem, int msb, int lsb, unsigned idxs, const struct memory_address_range *idx); +extern void memory_attach_self(vvp_memory_t mem, vpiHandle self); /* * init_word and set_word functions take the memory to be manipulated @@ -98,6 +100,7 @@ long memory_right_range(vvp_memory_t mem, unsigned ix); long memory_word_left_range(vvp_memory_t mem); long memory_word_right_range(vvp_memory_t mem); + /* vvp_fun_memport * The vvp_fum_memport is a structural port into a vvp_memory_t * object. The output is the word that is read from the addressed @@ -154,6 +157,9 @@ vvp_memory_t memory_create(char *label); /* * $Log: memory.h,v $ + * Revision 1.12 2006/03/05 05:45:58 steve + * Add support for memory value change callbacks. + * * Revision 1.11 2006/02/02 02:44:00 steve * Allow part selects of memory words in l-values. * diff --git a/vvp/vpi_callback.cc b/vvp/vpi_callback.cc index 78406a6f0..a2af6942b 100644 --- a/vvp/vpi_callback.cc +++ b/vvp/vpi_callback.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpi_callback.cc,v 1.42 2006/02/22 03:08:53 steve Exp $" +#ident "$Id: vpi_callback.cc,v 1.43 2006/03/05 05:45:58 steve Exp $" #endif /* @@ -151,6 +151,10 @@ static struct __vpiCallback* make_value_change(p_cb_data data) nev->callbacks = obj; break; + case vpiMemory: + vpip_memory_value_change(obj, data->obj); + break; + case vpiModule: case vpiConstant: case vpiParameter: @@ -572,6 +576,9 @@ void vvp_fun_signal_real::get_value(struct t_vpi_value*vp) /* * $Log: vpi_callback.cc,v $ + * Revision 1.43 2006/03/05 05:45:58 steve + * Add support for memory value change callbacks. + * * Revision 1.42 2006/02/22 03:08:53 steve * Some trivial log message improvements. * diff --git a/vvp/vpi_memory.cc b/vvp/vpi_memory.cc index db9d0c05c..a821e3923 100644 --- a/vvp/vpi_memory.cc +++ b/vvp/vpi_memory.cc @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpi_memory.cc,v 1.31 2006/02/21 03:19:03 steve Exp $" +#ident "$Id: vpi_memory.cc,v 1.32 2006/03/05 05:45:58 steve Exp $" #endif # include "vpi_priv.h" @@ -52,6 +52,7 @@ struct __vpiMemory { struct __vpiDecConst word_left_range; struct __vpiDecConst word_right_range; + struct __vpiCallback*value_change_cb; }; struct __vpiMemWordIterator { @@ -360,16 +361,15 @@ static char* memory_word_get_str(int code, vpiHandle ref) return 0; } -static void memory_word_get_value(vpiHandle ref, s_vpi_value*vp) +/* + * This is a generic function to convert a vvp_vector4_t value into a + * vpi_value structure. The format is selected by the format of the + * value pointer. The width is the real width of the word, in case the + * word_val width is not accurate. + */ +void vec4_get_value(const vvp_vector4_t word_val, unsigned width, + s_vpi_value*vp) { - struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref; - assert(rfp->base.vpi_type->type_code==vpiMemoryWord); - - unsigned width = memory_word_width(rfp->mem->mem); - unsigned word_address = rfp->index.value; - - vvp_vector4_t word_val = memory_get_word(rfp->mem->mem, word_address); - char *rbuf = 0; switch (vp->format) { @@ -459,6 +459,19 @@ static void memory_word_get_value(vpiHandle ref, s_vpi_value*vp) } } +static void memory_word_get_value(vpiHandle ref, s_vpi_value*vp) +{ + struct __vpiMemoryWord*rfp = (struct __vpiMemoryWord*)ref; + assert(rfp->base.vpi_type->type_code==vpiMemoryWord); + + unsigned width = memory_word_width(rfp->mem->mem); + unsigned word_address = rfp->index.value; + + vvp_vector4_t word_val = memory_get_word(rfp->mem->mem, word_address); + + vec4_get_value(word_val, width, vp); +} + static const struct __vpirt vpip_memory_rt = { vpiMemory, vpi_memory_get, @@ -499,6 +512,45 @@ static void memory_make_word_handles(struct __vpiMemory*rfp) } } +/* + * Run the callbacks for a memory value change. The memory.cc methods + * call this method with the canonical address of the word that + * changed, and we here run through all the callbacks for the memory, + * passing the translated index through. + */ +void vpip_run_memory_value_change(vpiHandle ref, unsigned addr) +{ + struct __vpiMemory*obj = reinterpret_cast(ref); + + vvp_vector4_t word_val = memory_get_word(obj->mem, addr); + unsigned width = memory_word_width(obj->mem); + + for (struct __vpiCallback*cur=obj->value_change_cb; + cur != 0 ; cur = cur->next) { + + if (cur->cb_data.cb_rtn == 0) + continue; + + if (cur->cb_data.value) + vec4_get_value(word_val, width, cur->cb_data.value); + + cur->cb_data.index = addr; + vpi_mode_flag = VPI_MODE_RWSYNC; + (cur->cb_data.cb_rtn) (&cur->cb_data); + vpi_mode_flag = VPI_MODE_NONE; + } +} + +/* + * Attach the callback to the memory. + */ +void vpip_memory_value_change(struct __vpiCallback*cbh, vpiHandle ref) +{ + struct __vpiMemory*obj = reinterpret_cast(ref); + cbh->next = obj->value_change_cb; + obj->value_change_cb = cbh; +} + vpiHandle vpip_make_memory(vvp_memory_t mem, const char*name) { struct __vpiMemory*obj = (struct __vpiMemory*) @@ -509,7 +561,9 @@ vpiHandle vpip_make_memory(vvp_memory_t mem, const char*name) obj->scope = vpip_peek_current_scope(); obj->mem = mem; obj->name = vpip_name_string(name); + obj->value_change_cb = 0; + memory_attach_self(mem, &(obj->base)); vpip_make_dec_const(&obj->left_range, memory_left_range(mem, 0)); vpip_make_dec_const(&obj->right_range, memory_right_range(mem, 0)); vpip_make_dec_const(&obj->word_left_range, memory_word_left_range(mem)); @@ -522,6 +576,9 @@ vpiHandle vpip_make_memory(vvp_memory_t mem, const char*name) /* * $Log: vpi_memory.cc,v $ + * Revision 1.32 2006/03/05 05:45:58 steve + * Add support for memory value change callbacks. + * * Revision 1.31 2006/02/21 03:19:03 steve * Remove dead code. * diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index dba74f57f..52c49af06 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vpi_priv.h,v 1.66 2006/02/21 05:31:54 steve Exp $" +#ident "$Id: vpi_priv.h,v 1.67 2006/03/05 05:45:58 steve Exp $" #endif # include "vpi_user.h" @@ -218,6 +218,10 @@ extern void vpip_real_value_change(struct __vpiCallback*cbh, */ extern vpiHandle vpip_make_memory(vvp_memory_t mem, const char*name); +extern void vpip_memory_value_change(struct __vpiCallback*cbh, + vpiHandle ref); + +extern void vpip_run_memory_value_change(vpiHandle ref, unsigned adr); /* * These are the various variable types. @@ -429,6 +433,9 @@ extern char *need_result_buf(unsigned cnt, vpi_rbuf_t type); /* * $Log: vpi_priv.h,v $ + * Revision 1.67 2006/03/05 05:45:58 steve + * Add support for memory value change callbacks. + * * Revision 1.66 2006/02/21 05:31:54 steve * Put strings for reg objects. *