From 6593b603adc2c97c5207efcec88a739fce7b3764 Mon Sep 17 00:00:00 2001 From: steve Date: Fri, 29 Sep 2006 03:57:01 +0000 Subject: [PATCH] Modpath delay chooses correct delay for edge. --- vvp/compile.cc | 13 ++++++------ vvp/delay.cc | 54 ++++++++++++++++++++++++++++++++++++++++---------- vvp/delay.h | 17 +++++++++++++--- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/vvp/compile.cc b/vvp/compile.cc index 2d78f260f..406d97874 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -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. * diff --git a/vvp/delay.cc b/vvp/delay.cc index b4e573460..5be398fb3 100644 --- a/vvp/delay.cc +++ b/vvp/delay.cc @@ -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. * diff --git a/vvp/delay.h b/vvp/delay.h index 448004daf..daecfc0ca 100644 --- a/vvp/delay.h +++ b/vvp/delay.h @@ -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. *