diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 812447b93..f319ccfa2 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_process.c,v 1.104 2005/03/06 17:07:48 steve Exp $" +#ident "$Id: vvp_process.c,v 1.105 2005/03/22 05:18:34 steve Exp $" #endif # include "vvp_priv.h" @@ -85,24 +85,23 @@ static void set_to_lvariable(ivl_lval_t lval, a bit-select leval. Presumably, the x0 index register has been loaded wit the result of the evaluated ivl_lval_mux expression. */ - assert(wid == 1); draw_eval_expr_into_integer(ivl_lval_mux(lval), 0); fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); - fprintf(vvp_out, " %%set/x0 V_%s, %u;\n", - vvp_signal_label(sig), bit); + fprintf(vvp_out, " %%set/x0 V_%s, %u, %u;\n", + vvp_signal_label(sig), bit, wid); fprintf(vvp_out, "t_%u ;\n", skip_set); } else if (part_off > 0) { /* There is no mux expression, but a constant part offset. Load that into index x0 and generate a single-bit set instruction. */ - assert(wid == 1); + assert(ivl_lval_width(lval) == wid); fprintf(vvp_out, " %%ix/load 0, %u;\n", part_off); - fprintf(vvp_out, " %%set/x0 V_%s, %u;\n", - vvp_signal_label(sig), bit); + fprintf(vvp_out, " %%set/x0 V_%s, %u, %u;\n", + vvp_signal_label(sig), bit, wid); } else { fprintf(vvp_out, " %%set/v V_%s, %u, %u;\n", @@ -1469,6 +1468,9 @@ int draw_func_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.105 2005/03/22 05:18:34 steve + * The indexed set can write a vector, not just a bit. + * * Revision 1.104 2005/03/06 17:07:48 steve * Non blocking assign to memory words. * diff --git a/vvp/compile.cc b/vvp/compile.cc index a10865aab..1ba004f33 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.194 2005/03/19 06:23:49 steve Exp $" +#ident "$Id: compile.cc,v 1.195 2005/03/22 05:18:34 steve Exp $" #endif # include "arith.h" @@ -150,7 +150,7 @@ const static struct opcode_table_s opcode_table[] = { { "%set/mv", of_SET_MV, 3, {OA_MEM_PTR, OA_BIT1, OA_BIT2} }, { "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, { "%set/wr", of_SET_WORDR,2,{OA_VPI_PTR, OA_BIT1, OA_NONE} }, - { "%set/x0", of_SET_X0, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, + { "%set/x0", of_SET_X0, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, // { "%set/x0/x",of_SET_X0_X,3,{OA_FUNC_PTR, OA_BIT1, OA_BIT2} }, { "%shiftl/i0", of_SHIFTL_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} }, { "%shiftr/i0", of_SHIFTR_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} }, @@ -1587,6 +1587,9 @@ void compile_param_string(char*label, char*name, char*str, char*value) /* * $Log: compile.cc,v $ + * Revision 1.195 2005/03/22 05:18:34 steve + * The indexed set can write a vector, not just a bit. + * * Revision 1.194 2005/03/19 06:23:49 steve * Handle LPM shifts. * diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index d64c7ae5a..7d64dd0fc 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1,7 +1,7 @@ /* * Copyright (c) 2001-2003 Stephen Williams (steve@icarus.com) * - * $Id: opcodes.txt,v 1.61 2005/03/03 04:33:10 steve Exp $ + * $Id: opcodes.txt,v 1.62 2005/03/22 05:18:34 steve Exp $ */ @@ -538,18 +538,20 @@ into index register 3. This instruction writes a real word to the specified VPI-like object. -* %set/x0 , +* %set/x0 , , -This sets the bit of a signal vector, the address calculated by -using the index register 0 to index the bit within the vector of +This sets the part of a signal vector, the address calculated by +using the index register 0 to index the base within the vector of . The destination must be a signal of some sort. Otherwise, the instrution will fail. -If the index value in index register is <0 (for example if %ix/get -converted an unknown value into the register) then the set is not -performed. Also, if the index value is beyond the width of the target -signal, then the set is not performed. The instruction gets the -dimensions of the target signal from the signal itself. +The addressing is cannonical (0-based) so the compiler must figure out +non-zero offsets, if any. The width is the width of the part being +written. The other bits of the vector are not touched. + +The index may be signed, and if less then 0, the beginning bits are +not assigned. Also, if the bits go beyond the end of the signal, those +bits are not written anywhere. * %shiftl/i0 , diff --git a/vvp/vthread.cc b/vvp/vthread.cc index faca3d1b7..eb0be7396 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vthread.cc,v 1.132 2005/03/06 17:07:48 steve Exp $" +#ident "$Id: vthread.cc,v 1.133 2005/03/22 05:18:34 steve Exp $" #endif # include "config.h" @@ -2729,39 +2729,49 @@ bool of_SET_WORDR(vthread_t thr, vvp_code_t cp) /* * Implement the %set/x instruction: * - * %set/x , + * %set/x , , * - * The single bit goes into the indexed functor. Abort the instruction - * if the index is outside the target vector dimensions. Get the - * target vector dimensions from the vvp_fun_signal addressed by the - * vvp_net pointer. + * The bit value of a vector go into the addressed functor. Do not + * transfer bits that are outside the signal range. Get the target + * vector dimensions from the vvp_fun_signal addressed by the vvp_net + * pointer. */ bool of_SET_X0(vthread_t thr, vvp_code_t cp) { vvp_net_t*net = cp->net; - vvp_bit4_t bit_val = thr_get_bit(thr, cp->bit_idx[0]); + unsigned bit = cp->bit_idx[0]; + unsigned wid = cp->bit_idx[1]; // Implicitly, we get the base into the target vector from the // X0 register. - long idx = thr->words[0].w_int; + long index = thr->words[0].w_int; vvp_fun_signal*sig = dynamic_cast (net->fun); - /* If idx < 0, then the index value is probably generated from - an undefined value. At any rate, this is defined to have no - effect so quit now. */ - if (idx < 0) + if (index < 0 && (wid <= (unsigned)-index)) return true; - if ((unsigned)idx >= sig->size()) + if (index >= (long)sig->size()) return true; - // Make a 1-bit vector that will go to the target - vvp_vector4_t bit (1); - bit.set_bit(0, bit_val); + if (index < 0) { + wid -= (unsigned) -index; + index = 0; + } + + if (index+wid > sig->size()) + wid = sig->size() - index; + + vvp_vector4_t bit_vec(wid); + for (unsigned idx = 0 ; idx < wid ; idx += 1) { + vvp_bit4_t bit_val = thr_get_bit(thr, bit); + bit_vec.set_bit(idx, bit_val); + if (bit >= 4) + bit += 1; + } vvp_net_ptr_t ptr (net, 0); - vvp_send_vec4_pv(ptr, bit, idx, 1, sig->size()); + vvp_send_vec4_pv(ptr, bit_vec, index, wid, sig->size()); return true; } @@ -3114,6 +3124,9 @@ bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t cp) /* * $Log: vthread.cc,v $ + * Revision 1.133 2005/03/22 05:18:34 steve + * The indexed set can write a vector, not just a bit. + * * Revision 1.132 2005/03/06 17:07:48 steve * Non blocking assign to memory words. *