Merge branch 'master' of ssh://steve-icarus@icarus.com/home/u/icarus/steve/git/verilog
This commit is contained in:
commit
a919ee385d
|
|
@ -95,6 +95,11 @@ vvp_gen_event_s::~vvp_gen_event_s()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vvp_gen_event_s::single_step_display(void)
|
||||||
|
{
|
||||||
|
cerr << "vvp_gen_event_s: Step into event " << typeid(*this).name() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Derived event types
|
* Derived event types
|
||||||
*/
|
*/
|
||||||
|
|
@ -327,6 +332,7 @@ struct propagate_vector4_event_s : public event_s {
|
||||||
vvp_vector4_t val;
|
vvp_vector4_t val;
|
||||||
/* Action */
|
/* Action */
|
||||||
void run_run(void);
|
void run_run(void);
|
||||||
|
void single_step_display(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
void propagate_vector4_event_s::run_run(void)
|
void propagate_vector4_event_s::run_run(void)
|
||||||
|
|
@ -334,6 +340,11 @@ void propagate_vector4_event_s::run_run(void)
|
||||||
net->send_vec4(val, 0);
|
net->send_vec4(val, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void propagate_vector4_event_s::single_step_display(void)
|
||||||
|
{
|
||||||
|
cerr << "propagate_vector4_event: Propagate val=" << val << endl;
|
||||||
|
}
|
||||||
|
|
||||||
struct assign_array_r_word_s : public event_s {
|
struct assign_array_r_word_s : public event_s {
|
||||||
vvp_array_t mem;
|
vvp_array_t mem;
|
||||||
unsigned adr;
|
unsigned adr;
|
||||||
|
|
@ -369,6 +380,7 @@ struct generic_event_s : public event_s {
|
||||||
vvp_gen_event_t obj;
|
vvp_gen_event_t obj;
|
||||||
bool delete_obj_when_done;
|
bool delete_obj_when_done;
|
||||||
void run_run(void);
|
void run_run(void);
|
||||||
|
void single_step_display(void);
|
||||||
|
|
||||||
static void* operator new(size_t);
|
static void* operator new(size_t);
|
||||||
static void operator delete(void*);
|
static void operator delete(void*);
|
||||||
|
|
@ -384,6 +396,11 @@ void generic_event_s::run_run(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void generic_event_s::single_step_display(void)
|
||||||
|
{
|
||||||
|
obj->single_step_display();
|
||||||
|
}
|
||||||
|
|
||||||
static const size_t GENERIC_CHUNK_COUNT = 131072 / sizeof(struct generic_event_s);
|
static const size_t GENERIC_CHUNK_COUNT = 131072 / sizeof(struct generic_event_s);
|
||||||
static slab_t<sizeof(generic_event_s),GENERIC_CHUNK_COUNT> generic_event_heap;
|
static slab_t<sizeof(generic_event_s),GENERIC_CHUNK_COUNT> generic_event_heap;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ struct vvp_gen_event_s
|
||||||
{
|
{
|
||||||
virtual ~vvp_gen_event_s() =0;
|
virtual ~vvp_gen_event_s() =0;
|
||||||
virtual void run_run() =0;
|
virtual void run_run() =0;
|
||||||
|
virtual void single_step_display(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
# include "vvp_net.h"
|
# include "vvp_net.h"
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
||||||
|
# include <set>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Added to use some "vvp_fun_modpath_src"
|
* Added to use some "vvp_fun_modpath_src"
|
||||||
* and "vvp_fun_modpath" classes definitions
|
* and "vvp_fun_modpath" classes definitions
|
||||||
|
|
@ -204,7 +206,7 @@ struct __vpiScope {
|
||||||
/* Keep a list of freed contexts. */
|
/* Keep a list of freed contexts. */
|
||||||
vvp_context_t free_contexts;
|
vvp_context_t free_contexts;
|
||||||
/* Keep a list of threads in the scope. */
|
/* Keep a list of threads in the scope. */
|
||||||
vthread_t threads;
|
std::set<vthread_t> threads;
|
||||||
signed int time_units :8;
|
signed int time_units :8;
|
||||||
signed int time_precision :8;
|
signed int time_precision :8;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -447,7 +447,6 @@ compile_scope_decl(char*label, char*type, char*name, char*tname,
|
||||||
scope->nitem = 0;
|
scope->nitem = 0;
|
||||||
scope->live_contexts = 0;
|
scope->live_contexts = 0;
|
||||||
scope->free_contexts = 0;
|
scope->free_contexts = 0;
|
||||||
scope->threads = 0;
|
|
||||||
|
|
||||||
current_scope = scope;
|
current_scope = scope;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,17 +116,12 @@ struct vthread_s {
|
||||||
unsigned fork_count :8;
|
unsigned fork_count :8;
|
||||||
/* This points to the sole child of the thread. */
|
/* This points to the sole child of the thread. */
|
||||||
struct vthread_s*child;
|
struct vthread_s*child;
|
||||||
union {
|
/* This points to my parent, if I have one. */
|
||||||
/* This points to my parent, if I have one. */
|
struct vthread_s*parent;
|
||||||
struct vthread_s*parent;
|
/* This points to the containing scope. */
|
||||||
/* If this is a header cell, then point to the
|
struct __vpiScope*parent_scope;
|
||||||
containing scope. */
|
|
||||||
struct __vpiScope*parent_scope;
|
|
||||||
};
|
|
||||||
/* This is used for keeping wait queues. */
|
/* This is used for keeping wait queues. */
|
||||||
struct vthread_s*wait_next;
|
struct vthread_s*wait_next;
|
||||||
/* These are used to keep the thread in a scope. */
|
|
||||||
struct vthread_s*scope_next, *scope_prev;
|
|
||||||
/* These are used to access automatically allocated items. */
|
/* These are used to access automatically allocated items. */
|
||||||
vvp_context_t wt_context, rd_context;
|
vvp_context_t wt_context, rd_context;
|
||||||
/* These are used to pass non-blocking event control information. */
|
/* These are used to pass non-blocking event control information. */
|
||||||
|
|
@ -136,10 +131,6 @@ struct vthread_s {
|
||||||
|
|
||||||
struct __vpiScope* vthread_scope(struct vthread_s*thr)
|
struct __vpiScope* vthread_scope(struct vthread_s*thr)
|
||||||
{
|
{
|
||||||
while (thr->bits4.size() > 0) {
|
|
||||||
thr = thr->scope_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return thr->parent_scope;
|
return thr->parent_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,31 +404,11 @@ vthread_t vthread_new(vvp_code_t pc, struct __vpiScope*scope)
|
||||||
thr->bits4 = vvp_vector4_t(32);
|
thr->bits4 = vvp_vector4_t(32);
|
||||||
thr->child = 0;
|
thr->child = 0;
|
||||||
thr->parent = 0;
|
thr->parent = 0;
|
||||||
|
thr->parent_scope = scope;
|
||||||
thr->wait_next = 0;
|
thr->wait_next = 0;
|
||||||
thr->wt_context = 0;
|
thr->wt_context = 0;
|
||||||
thr->rd_context = 0;
|
thr->rd_context = 0;
|
||||||
|
|
||||||
/* If the target scope never held a thread, then create a
|
|
||||||
header cell for it. This is a stub to make circular lists
|
|
||||||
easier to work with. */
|
|
||||||
if (scope->threads == 0) {
|
|
||||||
scope->threads = new struct vthread_s;
|
|
||||||
scope->threads->pc = codespace_null();
|
|
||||||
scope->threads->bits4 = vvp_vector4_t();
|
|
||||||
scope->threads->child = 0;
|
|
||||||
scope->threads->parent = 0;
|
|
||||||
scope->threads->parent_scope = scope;
|
|
||||||
scope->threads->scope_prev = scope->threads;
|
|
||||||
scope->threads->scope_next = scope->threads;
|
|
||||||
}
|
|
||||||
|
|
||||||
{ vthread_t tmp = scope->threads;
|
|
||||||
thr->scope_next = tmp->scope_next;
|
|
||||||
thr->scope_prev = tmp;
|
|
||||||
thr->scope_next->scope_prev = thr;
|
|
||||||
thr->scope_prev->scope_next = thr;
|
|
||||||
}
|
|
||||||
|
|
||||||
thr->schedule_parent_on_end = 0;
|
thr->schedule_parent_on_end = 0;
|
||||||
thr->is_scheduled = 0;
|
thr->is_scheduled = 0;
|
||||||
thr->i_have_ended = 0;
|
thr->i_have_ended = 0;
|
||||||
|
|
@ -452,6 +423,7 @@ vthread_t vthread_new(vvp_code_t pc, struct __vpiScope*scope)
|
||||||
thr_put_bit(thr, 2, BIT4_X);
|
thr_put_bit(thr, 2, BIT4_X);
|
||||||
thr_put_bit(thr, 3, BIT4_Z);
|
thr_put_bit(thr, 3, BIT4_Z);
|
||||||
|
|
||||||
|
scope->threads .insert(thr);
|
||||||
return thr;
|
return thr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -518,8 +490,8 @@ static void vthread_reap(vthread_t thr)
|
||||||
thr->child = 0;
|
thr->child = 0;
|
||||||
thr->parent = 0;
|
thr->parent = 0;
|
||||||
|
|
||||||
thr->scope_next->scope_prev = thr->scope_prev;
|
// Remove myself from the containing scope.
|
||||||
thr->scope_prev->scope_next = thr->scope_next;
|
thr->parent_scope->threads.erase(thr);
|
||||||
|
|
||||||
thr->pc = codespace_null();
|
thr->pc = codespace_null();
|
||||||
|
|
||||||
|
|
@ -1955,8 +1927,7 @@ static bool do_disable(vthread_t thr, vthread_t match)
|
||||||
bool flag = false;
|
bool flag = false;
|
||||||
|
|
||||||
/* Pull the target thread out of its scope. */
|
/* Pull the target thread out of its scope. */
|
||||||
thr->scope_next->scope_prev = thr->scope_prev;
|
thr->parent_scope->threads.erase(thr);
|
||||||
thr->scope_prev->scope_next = thr->scope_next;
|
|
||||||
|
|
||||||
/* Turn the thread off by setting is program counter to
|
/* Turn the thread off by setting is program counter to
|
||||||
zero and setting an OFF bit. */
|
zero and setting an OFF bit. */
|
||||||
|
|
@ -2011,23 +1982,18 @@ static bool do_disable(vthread_t thr, vthread_t match)
|
||||||
bool of_DISABLE(vthread_t thr, vvp_code_t cp)
|
bool of_DISABLE(vthread_t thr, vvp_code_t cp)
|
||||||
{
|
{
|
||||||
struct __vpiScope*scope = (struct __vpiScope*)cp->handle;
|
struct __vpiScope*scope = (struct __vpiScope*)cp->handle;
|
||||||
if (scope->threads == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
struct vthread_s*head = scope->threads;
|
|
||||||
|
|
||||||
bool disabled_myself_flag = false;
|
bool disabled_myself_flag = false;
|
||||||
|
|
||||||
while (head->scope_next != head) {
|
while (scope->threads.size() > 0) {
|
||||||
vthread_t tmp = head->scope_next;
|
set<vthread_t>::iterator cur = scope->threads.begin();
|
||||||
|
|
||||||
/* If I am disabling myself, that remember that fact so
|
/* If I am disabling myself, that remember that fact so
|
||||||
that I can finish this statement differently. */
|
that I can finish this statement differently. */
|
||||||
if (tmp == thr)
|
if (*cur == thr)
|
||||||
disabled_myself_flag = true;
|
disabled_myself_flag = true;
|
||||||
|
|
||||||
|
if (do_disable(*cur, thr))
|
||||||
if (do_disable(tmp, thr))
|
|
||||||
disabled_myself_flag = true;
|
disabled_myself_flag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue