Add support for memory value change callbacks.

This commit is contained in:
steve 2006-03-05 05:45:58 +00:00
parent b0b614ae0e
commit 1b911ad87a
5 changed files with 105 additions and 14 deletions

View File

@ -19,12 +19,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #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 #endif
#include "memory.h" #include "memory.h"
#include "symbols.h" #include "symbols.h"
#include "schedule.h" #include "schedule.h"
#include "vpi_priv.h"
#include <assert.h> #include <assert.h>
#ifdef HAVE_MALLOC_H #ifdef HAVE_MALLOC_H
#include <malloc.h> #include <malloc.h>
@ -52,6 +53,7 @@ struct vvp_memory_s
// List of ports into this memory. // List of ports into this memory.
class vvp_fun_memport* port_list; class vvp_fun_memport* port_list;
vpiHandle vpi_self;
}; };
#define VVP_MEMORY_NO_ADDR ((int)0x80000000) #define VVP_MEMORY_NO_ADDR ((int)0x80000000)
@ -119,6 +121,13 @@ void memory_configure(vvp_memory_t mem,
assert(mem->words); assert(mem->words);
mem->port_list = 0; 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) 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 ; cur = cur->next_) {
cur->check_word_change(addr); cur->check_word_change(addr);
} }
vpip_run_memory_value_change(mem->vpi_self, addr);
} }
void schedule_memory(vvp_memory_t mem, unsigned 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 $ * $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 * Revision 1.28 2006/02/02 02:44:00 steve
* Allow part selects of memory words in l-values. * Allow part selects of memory words in l-values.
* *

View File

@ -20,10 +20,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #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 #endif
#include "vvp_net.h" #include "vvp_net.h"
#include "vpi_user.h"
/* /*
** vvp_memory_t is a memory ** 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, extern void memory_configure(vvp_memory_t mem, int msb, int lsb,
unsigned idxs, unsigned idxs,
const struct memory_address_range *idx); 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 * 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_left_range(vvp_memory_t mem);
long memory_word_right_range(vvp_memory_t mem); long memory_word_right_range(vvp_memory_t mem);
/* vvp_fun_memport /* vvp_fun_memport
* The vvp_fum_memport is a structural port into a vvp_memory_t * 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 * 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 $ * $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 * Revision 1.11 2006/02/02 02:44:00 steve
* Allow part selects of memory words in l-values. * Allow part selects of memory words in l-values.
* *

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #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 #endif
/* /*
@ -151,6 +151,10 @@ static struct __vpiCallback* make_value_change(p_cb_data data)
nev->callbacks = obj; nev->callbacks = obj;
break; break;
case vpiMemory:
vpip_memory_value_change(obj, data->obj);
break;
case vpiModule: case vpiModule:
case vpiConstant: case vpiConstant:
case vpiParameter: case vpiParameter:
@ -572,6 +576,9 @@ void vvp_fun_signal_real::get_value(struct t_vpi_value*vp)
/* /*
* $Log: vpi_callback.cc,v $ * $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 * Revision 1.42 2006/02/22 03:08:53 steve
* Some trivial log message improvements. * Some trivial log message improvements.
* *

View File

@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #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 #endif
# include "vpi_priv.h" # include "vpi_priv.h"
@ -52,6 +52,7 @@ struct __vpiMemory {
struct __vpiDecConst word_left_range; struct __vpiDecConst word_left_range;
struct __vpiDecConst word_right_range; struct __vpiDecConst word_right_range;
struct __vpiCallback*value_change_cb;
}; };
struct __vpiMemWordIterator { struct __vpiMemWordIterator {
@ -360,16 +361,15 @@ static char* memory_word_get_str(int code, vpiHandle ref)
return 0; 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; char *rbuf = 0;
switch (vp->format) { 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 = { static const struct __vpirt vpip_memory_rt = {
vpiMemory, vpiMemory,
vpi_memory_get, 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<struct __vpiMemory*>(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<struct __vpiMemory*>(ref);
cbh->next = obj->value_change_cb;
obj->value_change_cb = cbh;
}
vpiHandle vpip_make_memory(vvp_memory_t mem, const char*name) vpiHandle vpip_make_memory(vvp_memory_t mem, const char*name)
{ {
struct __vpiMemory*obj = (struct __vpiMemory*) 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->scope = vpip_peek_current_scope();
obj->mem = mem; obj->mem = mem;
obj->name = vpip_name_string(name); 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->left_range, memory_left_range(mem, 0));
vpip_make_dec_const(&obj->right_range, memory_right_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)); 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 $ * $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 * Revision 1.31 2006/02/21 03:19:03 steve
* Remove dead code. * Remove dead code.
* *

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifdef HAVE_CVS_IDENT #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 #endif
# include "vpi_user.h" # 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 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. * 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 $ * $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 * Revision 1.66 2006/02/21 05:31:54 steve
* Put strings for reg objects. * Put strings for reg objects.
* *