Add support for memory value change callbacks.
This commit is contained in:
parent
b0b614ae0e
commit
1b911ad87a
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue