From c73925e775e7f611f0bdcb15dd687d1ef7a566a9 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Thu, 26 Nov 2009 09:34:45 -0800 Subject: [PATCH 1/3] Handle word aligned bit moves more efficiently If the source and destination of a subvector to be moved in the vvp_vector4_t::mov method is nicely word aligned, and the transfer size is a full word, then we ar much better off handling that as a special case. This makes the move faster, and also avoids some shift overflow errors. --- vvp/vvp_net.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 075eafcbf..79734325b 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -1162,6 +1162,22 @@ void vvp_vector4_t::mov(unsigned dst, unsigned src, unsigned cnt) if ((doff+trans) > BITS_PER_WORD) trans = BITS_PER_WORD - doff; + if (trans == BITS_PER_WORD) { + // Special case: the transfer count is + // exactly an entire word. For this to be + // true, it must also be true that the + // pointers are aligned. The work is easy, + abits_ptr_[dptr] = abits_ptr_[sptr]; + bbits_ptr_[dptr] = bbits_ptr_[sptr]; + dptr += 1; + sptr += 1; + cnt -= BITS_PER_WORD; + continue; + } + + // Here we know that either the source or + // destination is unaligned, and also we know that + // the count is less then a full word. unsigned long vmask = (1UL << trans) - 1; unsigned long tmp; From 1ada697e4527a161da7bacb436f9a5e6f6c6d416 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Thu, 26 Nov 2009 09:43:35 -0800 Subject: [PATCH 2/3] Fix signed/unsigned errors in %shiftl/x0 and %shiftr/x0 Fix these warnings once and for all. Just use only signed integers for all the variables and arithmetic. --- vvp/vthread.cc | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 6ff26126e..d15e61cd2 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -4205,9 +4205,9 @@ bool of_SET_X0(vthread_t thr, vvp_code_t cp) bool of_SHIFTL_I0(vthread_t thr, vvp_code_t cp) { - unsigned base = cp->bit_idx[0]; - unsigned wid = cp->number; - long shift = thr->words[0].w_int; + int base = cp->bit_idx[0]; + int wid = cp->number; + int shift = thr->words[0].w_int; assert(base >= 4); thr_check_addr(thr, base+wid-1); @@ -4217,7 +4217,7 @@ bool of_SHIFTL_I0(vthread_t thr, vvp_code_t cp) vvp_vector4_t tmp (wid, BIT4_X); thr->bits4.set_vec(base, tmp); - } else if (shift >= (long)wid) { + } else if (shift >= wid) { // Shift is so far that all value is shifted out. Write // in a constant 0 result. vvp_vector4_t tmp (wid, BIT4_0); @@ -4231,9 +4231,13 @@ bool of_SHIFTL_I0(vthread_t thr, vvp_code_t cp) vvp_vector4_t fil (shift, BIT4_0); thr->bits4.set_vec(base, fil); + } else if (shift <= -wid) { + vvp_vector4_t tmp (wid, BIT4_X); + thr->bits4.set_vec(base, tmp); + } else if (shift < 0) { // For a negative shift we pad with 'bx. - unsigned idx; + int idx; for (idx = 0 ; (idx-shift) < wid ; idx += 1) { unsigned src = base + idx - shift; unsigned dst = base + idx; @@ -4255,9 +4259,9 @@ bool of_SHIFTL_I0(vthread_t thr, vvp_code_t cp) */ bool of_SHIFTR_I0(vthread_t thr, vvp_code_t cp) { - unsigned base = cp->bit_idx[0]; - unsigned wid = cp->number; - long shift = thr->words[0].w_int; + int base = cp->bit_idx[0]; + int wid = cp->number; + int shift = thr->words[0].w_int; assert(base >= 4); thr_check_addr(thr, base+wid-1); @@ -4279,7 +4283,7 @@ bool of_SHIFTR_I0(vthread_t thr, vvp_code_t cp) vvp_vector4_t tmp (shift, BIT4_0); thr->bits4.set_vec(base+wid-shift, tmp); - } else if (shift < -(long)wid) { + } else if (shift < -wid) { // Negative shift is so far that all the value is shifted out. // Write in a constant 'bx result. vvp_vector4_t tmp (wid, BIT4_X); From de1f17d42963ed5b8374fcd7779b3e1cae9d40f0 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Thu, 26 Nov 2009 18:28:19 -0800 Subject: [PATCH 3/3] Fix delays in continuous assignment to support 64bit delays. Remove the 32bit restriction on a few cases of delays in continuous assignment expressions. --- tgt-vvp/draw_mux.c | 18 +++++++++--------- tgt-vvp/vvp_scope.c | 40 ++++++++++++++++++++-------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/tgt-vvp/draw_mux.c b/tgt-vvp/draw_mux.c index 3858a4deb..ded4732a7 100644 --- a/tgt-vvp/draw_mux.c +++ b/tgt-vvp/draw_mux.c @@ -53,21 +53,21 @@ static void draw_lpm_mux_ab(ivl_lpm_t net, const char*muxz) assert( ! number_is_unknown(d_fall)); assert( ! number_is_unknown(d_decay)); - // For now .delay (x,y,z) only supports a 32 bit delay value. - if ((! number_is_immediate(d_rise, 32, 0)) || - (! number_is_immediate(d_fall, 32, 0)) || - (! number_is_immediate(d_decay, 32, 0))) { - fprintf(stderr, "%s:%u: vvp-tgt sorry: only 32 bit " + // .delay (x,y,z) only supports a 64 bit delay value. + if ((! number_is_immediate(d_rise, 64, 0)) || + (! number_is_immediate(d_fall, 64, 0)) || + (! number_is_immediate(d_decay, 64, 0))) { + fprintf(stderr, "%s:%u: vvp-tgt sorry: only 64 bit " "delays are supported in a continuous " "assignment.\n", ivl_expr_file(d_rise), ivl_expr_lineno(d_rise)); exit(1); } - fprintf(vvp_out, "L_%p .delay (%lu,%lu,%lu) L_%p/d;\n", - net, get_number_immediate(d_rise), - get_number_immediate(d_fall), - get_number_immediate(d_decay), net); + fprintf(vvp_out, "L_%p .delay (%" PRIu64 ",%" PRIu64 ",%" PRIu64 ") L_%p/d;\n", + net, get_number_immediate64(d_rise), + get_number_immediate64(d_fall), + get_number_immediate64(d_decay), net); } else { ivl_signal_t sig; // We do not currently support calculating the decay from diff --git a/tgt-vvp/vvp_scope.c b/tgt-vvp/vvp_scope.c index 3ec7fa8d4..dbe82333e 100644 --- a/tgt-vvp/vvp_scope.c +++ b/tgt-vvp/vvp_scope.c @@ -900,21 +900,21 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr) assert(! number_is_unknown(fall_exp)); assert(! number_is_unknown(decay_exp)); - // For now .delay (x,y,z) only supports a 32 bit delay value. - if ((! number_is_immediate(rise_exp, 32, 0)) || - (! number_is_immediate(fall_exp, 32, 0)) || - (! number_is_immediate(decay_exp, 32, 0))) { - fprintf(stderr, "%s:%u: vvp-tgt sorry: only 32 bit " + // .delay (x,y,z) only supports a 64 bit delay value. + if ((! number_is_immediate(rise_exp, 64, 0)) || + (! number_is_immediate(fall_exp, 64, 0)) || + (! number_is_immediate(decay_exp, 64, 0))) { + fprintf(stderr, "%s:%u: vvp-tgt sorry: only 64 bit " "delays are supported in a continuous " "assignment.\n", ivl_expr_file(rise_exp), ivl_expr_lineno(rise_exp)); - exit(1); + assert(0); } - fprintf(vvp_out, "L_%p .delay (%lu,%lu,%lu) L_%p/d;\n", - lptr, get_number_immediate(rise_exp), - get_number_immediate(fall_exp), - get_number_immediate(decay_exp), lptr); + fprintf(vvp_out, "L_%p .delay (%" PRIu64 ",%" PRIu64 ",%" PRIu64 ") L_%p/d;\n", + lptr, get_number_immediate64(rise_exp), + get_number_immediate64(fall_exp), + get_number_immediate64(decay_exp), lptr); } else { ivl_signal_t sig; // We do not currently support calculating the decay from @@ -1121,22 +1121,22 @@ static const char* draw_lpm_output_delay(ivl_lpm_t net) assert(! number_is_unknown(d_fall)); assert(! number_is_unknown(d_decay)); - // For now .delay (x,y,z) only supports a 32 bit delay value. - if ((! number_is_immediate(d_rise, 32, 0)) || - (! number_is_immediate(d_fall, 32, 0)) || - (! number_is_immediate(d_decay, 32, 0))) { - fprintf(stderr, "%s:%u: vvp-tgt sorry: only 32 bit " + // .delay (x,y,z) only supports a 64 bit delay value. + if ((! number_is_immediate(d_rise, 64, 0)) || + (! number_is_immediate(d_fall, 64, 0)) || + (! number_is_immediate(d_decay, 64, 0))) { + fprintf(stderr, "%s:%u: vvp-tgt sorry: only 64 bit " "delays are supported in a continuous " "assignment.\n", ivl_expr_file(d_rise), ivl_expr_lineno(d_rise)); - exit(1); + assert(0); } dly = "/d"; - fprintf(vvp_out, "L_%p .delay (%lu,%lu,%lu) L_%p/d;\n", - net, get_number_immediate(d_rise), - get_number_immediate(d_fall), - get_number_immediate(d_decay), net); + fprintf(vvp_out, "L_%p .delay (%" PRIu64 ",%" PRIu64 ",%" PRIu64 ")" + "L_%p/d;\n", net, get_number_immediate64(d_rise), + get_number_immediate64(d_fall), + get_number_immediate64(d_decay), net); } return dly;