From c03d76a0d75160a5e747eade67a10d568a497430 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Mon, 9 Jun 2008 16:46:06 -0700 Subject: [PATCH] Do not do lazy processing of part selects. It doesn't really make any sense to do lazy processing of part selects, but it is possible to use the part select position to more toroughly check for changes in output and suppress non-changes. In particular, we only need to check that the output part actually changes, and by the way we only need to save those bits for the next go-round. We do want to make sure that the very first input causes an output, though, so that time-0 values get propagated. --- vvp/part.cc | 45 ++++++++++++++++++++++++--------------------- vvp/part.h | 14 ++++---------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/vvp/part.cc b/vvp/part.cc index 7e53f34c9..21e5d37c4 100644 --- a/vvp/part.cc +++ b/vvp/part.cc @@ -30,7 +30,7 @@ vvp_fun_part::vvp_fun_part(unsigned base, unsigned wid) : base_(base), val_(wid) { - net_ = 0; + needs_push_ = true; } vvp_fun_part::~vvp_fun_part() @@ -41,23 +41,20 @@ void vvp_fun_part::recv_vec4(vvp_net_ptr_t port, const vvp_vector4_t&bit) { assert(port.port() == 0); - vvp_vector4_t tmp = val_; + vvp_vector4_t tmp (val_.size()); for (unsigned idx = 0 ; idx < tmp.size() ; idx += 1) { if ((idx + base_) < bit.size()) tmp.set_bit(idx, bit.value(base_+idx)); else - tmp.set_bit(idx, BIT4_X); + tmp.set_bit(idx, val_.value(idx)); } - if (val_ .eeq( tmp )) + if (val_ .eeq(tmp) && !needs_push_) return; val_ = tmp; - - if (net_ == 0) { - net_ = port.ptr(); - schedule_generic(this, 0, false); - } + needs_push_ = false; + vvp_send_vec4(port.ptr()->out, val_); } /* @@ -71,25 +68,31 @@ void vvp_fun_part::recv_vec4_pv(vvp_net_ptr_t port, const vvp_vector4_t&bit, { assert(bit.size() == wid); + // If there is no overlap between input part select and output + // part select, then do nothing. if (base >= base_+val_.size()) return; if ((base+wid) <= base_) return; - vvp_vector4_t tmp = val_; - if (tmp.size() == 0) - tmp = vvp_vector4_t(vwid); + // There is at least some overlap, so build a new output part + // select from the previous output and the new input. + vvp_vector4_t tmp (val_.size()); + for (unsigned idx = 0 ; idx < tmp.size() ; idx += 1) { + if ((idx + base_) < base) + tmp.set_bit(idx, val_.value(idx)); + else if ((idx + base_) < (base+bit.size())) + tmp.set_bit(idx, bit.value(base_+idx)); + else + tmp.set_bit(idx, val_.value(idx)); + } - assert(tmp.size() == vwid); - tmp.set_vec(base, bit); - recv_vec4(port, tmp); -} + if (val_ .eeq(tmp) && !needs_push_) + return; -void vvp_fun_part::run_run() -{ - vvp_net_t*ptr = net_; - net_ = 0; - vvp_send_vec4(ptr->out, val_); + val_ = tmp; + needs_push_ = false; + vvp_send_vec4(port.ptr()->out, val_); } vvp_fun_part_pv::vvp_fun_part_pv(unsigned b, unsigned w, unsigned v) diff --git a/vvp/part.h b/vvp/part.h index 8fa861b1a..2b95eb976 100644 --- a/vvp/part.h +++ b/vvp/part.h @@ -19,15 +19,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -# include "schedule.h" - /* vvp_fun_part * This node takes a part select of the input vector. Input 0 is the - * vector to be selected from, and input 1 is the location where the - * select starts. Input 2, which is typically constant, is the width - * of the result. + * vector to be selected from, and the base and wid are where to pull + * the part from. */ -class vvp_fun_part : public vvp_net_fun_t, private vvp_gen_event_s { +class vvp_fun_part : public vvp_net_fun_t { public: vvp_fun_part(unsigned base, unsigned wid); @@ -40,13 +37,10 @@ class vvp_fun_part : public vvp_net_fun_t, private vvp_gen_event_s { unsigned, unsigned, unsigned); private: - void run_run(); - - private: + bool needs_push_; unsigned base_; unsigned wid_; vvp_vector4_t val_; - vvp_net_t*net_; }; /* vvp_fun_part_pv