Modpath delay chooses correct delay for edge.

This commit is contained in:
steve 2006-09-29 03:57:01 +00:00
parent 852d10500d
commit 6593b603ad
3 changed files with 64 additions and 20 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compile.cc,v 1.224 2006/09/23 04:57:19 steve Exp $"
#ident "$Id: compile.cc,v 1.225 2006/09/29 03:57:01 steve Exp $"
#endif
# include "arith.h"
@ -1066,14 +1066,12 @@ void compile_modpath_src(vvp_fun_modpath*dst,
struct symb_s src,
struct numbv_s vals)
{
vvp_time64_t use_delay = 0;
vvp_time64_t use_delay[12];
assert(vals.cnt == 12);
// FIXME: For now, only support single uniform time value.
use_delay = vals.nvec[0];
for (unsigned idx = 1 ; idx < vals.cnt ; idx += 1) {
assert(use_delay == vals.nvec[idx]);
for (unsigned idx = 0 ; idx < vals.cnt ; idx += 1) {
use_delay[idx] = vals.nvec[idx];
}
numbv_clear(&vals);
@ -1536,6 +1534,9 @@ void compile_param_string(char*label, char*name, char*value)
/*
* $Log: compile.cc,v $
* Revision 1.225 2006/09/29 03:57:01 steve
* Modpath delay chooses correct delay for edge.
*
* Revision 1.224 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: delay.cc,v 1.14 2006/09/23 04:57:19 steve Exp $"
#ident "$Id: delay.cc,v 1.15 2006/09/29 03:57:01 steve Exp $"
#endif
#include "delay.h"
@ -298,6 +298,19 @@ void vvp_fun_modpath::add_modpath_src(vvp_fun_modpath_src*that)
src_list_ = that;
}
static vvp_time64_t delay_from_edge(vvp_bit4_t a, vvp_bit4_t b, vvp_time64_t array[12])
{
typedef delay_edge_t bit4_table4[4];
const static bit4_table4 edge_table[4] = {
{ DELAY_EDGE_01, DELAY_EDGE_01, DELAY_EDGE_0x, DELAY_EDGE_0z },
{ DELAY_EDGE_10, DELAY_EDGE_10, DELAY_EDGE_1x, DELAY_EDGE_1z },
{ DELAY_EDGE_x0, DELAY_EDGE_x1, DELAY_EDGE_x0, DELAY_EDGE_xz },
{ DELAY_EDGE_z0, DELAY_EDGE_z1, DELAY_EDGE_zx, DELAY_EDGE_z0 }
};
return array[ edge_table[a][b] ];
}
void vvp_fun_modpath::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
{
/* Only the first port is used. */
@ -309,7 +322,6 @@ void vvp_fun_modpath::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
/* Select a time delay source that applies. */
vvp_fun_modpath_src*src = 0;
vvp_time64_t out_at = 0;
for (vvp_fun_modpath_src*cur = src_list_ ; cur ; cur=cur->next_) {
if (src == 0) {
src = cur;
@ -318,17 +330,32 @@ void vvp_fun_modpath::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
} else {
continue; /* Skip this entry. */
}
}
out_at = src->wake_time_ + src->delay_;
vvp_time64_t out_at[12];
vvp_time64_t now = schedule_simtime();
for (unsigned idx = 0 ; idx < 12 ; idx += 1) {
out_at[idx] = src->wake_time_ + src->delay_[idx];
if (out_at[idx] <= now)
out_at[idx] = 0;
else
out_at[idx] -= now;
}
/* Given the scheduled output time, create an output event. */
vvp_time64_t use_delay = 0;
vvp_time64_t now = schedule_simtime();
if (out_at <= now)
use_delay = 0;
else
use_delay = out_at - now;
vvp_time64_t use_delay = delay_from_edge(cur_vec4_.value(0),
bit.value(0),
out_at);
/* FIXME: This bases the edge delay on only the least
bit. This is WRONG! I need to find all the possible delays,
and schedule an event for each partial change. Hard! */
for (unsigned idx = 1 ; idx < bit.size() ; idx += 1) {
vvp_time64_t tmp = delay_from_edge(cur_vec4_.value(idx),
bit.value(0),
out_at);
assert(tmp == use_delay);
}
cur_vec4_ = bit;
schedule_generic(this, use_delay, false);
@ -339,9 +366,11 @@ void vvp_fun_modpath::run_run()
vvp_send_vec4(net_->out, cur_vec4_);
}
vvp_fun_modpath_src::vvp_fun_modpath_src(vvp_time64_t del)
vvp_fun_modpath_src::vvp_fun_modpath_src(vvp_time64_t del[12])
{
delay_ = del;
for (unsigned idx = 0 ; idx < 12 ; idx += 1)
delay_[idx] = del[idx];
next_ = 0;
wake_time_ = 0;
}
@ -360,6 +389,9 @@ void vvp_fun_modpath_src::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit)
/*
* $Log: delay.cc,v $
* Revision 1.15 2006/09/29 03:57:01 steve
* Modpath delay chooses correct delay for edge.
*
* Revision 1.14 2006/09/23 04:57:19 steve
* Basic support for specify timing.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: delay.h,v 1.11 2006/09/23 04:57:20 steve Exp $"
#ident "$Id: delay.h,v 1.12 2006/09/29 03:57:01 steve Exp $"
#endif
/*
@ -28,6 +28,14 @@
# include "vvp_net.h"
# include "schedule.h"
enum delay_edge_t {
DELAY_EDGE_01 = 0, DELAY_EDGE_10, DELAY_EDGE_0z,
DELAY_EDGE_z1, DELAY_EDGE_1z, DELAY_EDGE_z0,
DELAY_EDGE_0x, DELAY_EDGE_x1, DELAY_EDGE_1x,
DELAY_EDGE_x0, DELAY_EDGE_xz, DELAY_EDGE_zx,
DELAY_EDGE_COUNT
};
/*
* Instances of this object are functions that calculate the delay for
* the transition from the source vvp_bit4_t value to the destination
@ -129,7 +137,7 @@ class vvp_fun_modpath_src : public vvp_net_fun_t {
friend class vvp_fun_modpath;
public:
vvp_fun_modpath_src(vvp_time64_t d);
vvp_fun_modpath_src(vvp_time64_t d[12]);
private:
~vvp_fun_modpath_src();
@ -138,7 +146,7 @@ class vvp_fun_modpath_src : public vvp_net_fun_t {
private:
// FIXME: Needs to be a 12-value array
vvp_time64_t delay_;
vvp_time64_t delay_[12];
// Used by vvp_fun_modpath to keep a list of modpath_src objects.
vvp_fun_modpath_src*next_;
@ -151,6 +159,9 @@ class vvp_fun_modpath_src : public vvp_net_fun_t {
/*
* $Log: delay.h,v $
* Revision 1.12 2006/09/29 03:57:01 steve
* Modpath delay chooses correct delay for edge.
*
* Revision 1.11 2006/09/23 04:57:20 steve
* Basic support for specify timing.
*