diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index b3a9f3b99..46b916fbb 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: eval_expr.c,v 1.70 2002/08/22 03:38:40 steve Exp $" +#ident "$Id: eval_expr.c,v 1.71 2002/08/27 05:39:57 steve Exp $" #endif # include "vvp_priv.h" @@ -1123,6 +1123,7 @@ void draw_memory_index_expr(ivl_memory_t mem, ivl_expr_t ae) unsigned nbits = ivl_expr_width(ae); const char*bits = ivl_expr_bits(ae); unsigned long v = 0; + int unknown_flag = 0; unsigned idx; for (idx = 0 ; idx < nbits ; idx += 1) switch (bits[idx]) { @@ -1134,14 +1135,18 @@ void draw_memory_index_expr(ivl_memory_t mem, ivl_expr_t ae) break; default: v = ~0UL; + unknown_flag = 1; break; } fprintf(vvp_out, " %%ix/load 3, %lu;\n", (v-root)*width); + fprintf(vvp_out, " %%mov 4, %c, 1;\n", + unknown_flag?'1':'0'); break; } case IVL_EX_ULONG: { unsigned v = ivl_expr_uvalue(ae); fprintf(vvp_out, " %%ix/load 3, %u;\n", (v-root)*width); + fprintf(vvp_out, " %%mov 4, 0, 1;\n"); break; } default: { @@ -1745,6 +1750,13 @@ struct vector_info draw_eval_expr(ivl_expr_t exp) /* * $Log: eval_expr.c,v $ + * Revision 1.71 2002/08/27 05:39:57 steve + * Fix l-value indexing of memories and vectors so that + * an unknown (x) index causes so cell to be addresses. + * + * Fix tangling of label identifiers in the fork-join + * code generator. + * * Revision 1.70 2002/08/22 03:38:40 steve * Fix behavioral eval of x?a:b expressions. * diff --git a/tgt-vvp/vvp_priv.h b/tgt-vvp/vvp_priv.h index afb415a4e..c067d51a6 100644 --- a/tgt-vvp/vvp_priv.h +++ b/tgt-vvp/vvp_priv.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vvp_priv.h,v 1.18 2002/08/12 01:35:04 steve Exp $" +#ident "$Id: vvp_priv.h,v 1.19 2002/08/27 05:39:57 steve Exp $" #endif # include "ivl_target.h" @@ -91,6 +91,13 @@ struct vector_info { extern struct vector_info draw_eval_expr(ivl_expr_t exp); extern struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned w); + +/* + * This function draws code to evaluate the index expression exp for + * the memory mem. The result is loaded into index register i3, and + * the flag bit 4 is set to 0 if the numerical value is defined, or 1 + * if not. + */ extern void draw_memory_index_expr(ivl_memory_t mem, ivl_expr_t exp); extern unsigned short allocate_vector(unsigned short wid); @@ -108,6 +115,13 @@ extern unsigned thread_count; /* * $Log: vvp_priv.h,v $ + * Revision 1.19 2002/08/27 05:39:57 steve + * Fix l-value indexing of memories and vectors so that + * an unknown (x) index causes so cell to be addresses. + * + * Fix tangling of label identifiers in the fork-join + * code generator. + * * Revision 1.18 2002/08/12 01:35:04 steve * conditional ident string using autoconfig. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index efcb30245..98e70a25c 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.64 2002/08/19 00:06:12 steve Exp $" +#ident "$Id: vvp_process.c,v 1.65 2002/08/27 05:39:57 steve Exp $" #endif # include "vvp_priv.h" @@ -125,6 +125,10 @@ static void assign_to_memory(ivl_memory_t mem, unsigned idx, vvp_memory_label(mem), delay, bit); } +/* + * This function, in addition to setting the value into index 0, sets + * bit 4 to 1 if the value is unknown. + */ static void calculate_into_x0(ivl_expr_t expr) { struct vector_info vec = draw_eval_expr(expr); @@ -156,39 +160,58 @@ static int show_stmt_assign(ivl_statement_t net) unsigned cur_rbit = 0; for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { + unsigned skip_set = transient_id++; + unsigned skip_set_flag = 0; unsigned idx; unsigned bit_limit = wid - cur_rbit; lval = ivl_stmt_lval(net, lidx); /* If there is a mux for the lval, calculate the value and write it into index0. */ - if (ivl_lval_mux(lval)) + if (ivl_lval_mux(lval)) { calculate_into_x0(ivl_lval_mux(lval)); + fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); + skip_set_flag = 1; + } mem = ivl_lval_mem(lval); - if (mem) + if (mem) { draw_memory_index_expr(mem, ivl_lval_idx(lval)); + fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); + skip_set_flag = 1; + } if (bit_limit > ivl_lval_pins(lval)) bit_limit = ivl_lval_pins(lval); - for (idx = 0 ; idx < bit_limit ; idx += 1) { - if (mem) + if (mem) { + for (idx = 0 ; idx < bit_limit ; idx += 1) { set_to_memory(mem, idx, bitchar_to_idx(bits[cur_rbit])); - else + + cur_rbit += 1; + } + + for (idx = bit_limit + ; idx < ivl_lval_pins(lval) ; idx += 1) + set_to_memory(mem, idx, 0); + + + } else { + for (idx = 0 ; idx < bit_limit ; idx += 1) { set_to_lvariable(lval, idx, bitchar_to_idx(bits[cur_rbit])); - cur_rbit += 1; + cur_rbit += 1; + } + + for (idx = bit_limit + ; idx < ivl_lval_pins(lval) ; idx += 1) + set_to_lvariable(lval, idx, 0); } - for (idx = bit_limit ; idx < ivl_lval_pins(lval) ; idx += 1) - if (mem) - set_to_memory(mem, idx, 0); - else - set_to_lvariable(lval, idx, 0); - + if (skip_set_flag) + fprintf(vvp_out, "t_%u ;\n", skip_set); } return 0; @@ -200,18 +223,26 @@ static int show_stmt_assign(ivl_statement_t net) unsigned cur_rbit = 0; for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { + unsigned skip_set = transient_id++; + unsigned skip_set_flag = 0; unsigned idx; unsigned bit_limit = wid - cur_rbit; lval = ivl_stmt_lval(net, lidx); /* If there is a mux for the lval, calculate the value and write it into index0. */ - if (ivl_lval_mux(lval)) + if (ivl_lval_mux(lval)) { calculate_into_x0(ivl_lval_mux(lval)); + fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); + skip_set_flag = 1; + } mem = ivl_lval_mem(lval); - if (mem) + if (mem) { draw_memory_index_expr(mem, ivl_lval_idx(lval)); + fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); + skip_set_flag = 1; + } if (bit_limit > ivl_lval_pins(lval)) bit_limit = ivl_lval_pins(lval); @@ -234,6 +265,9 @@ static int show_stmt_assign(ivl_statement_t net) else set_to_lvariable(lval, idx, 0); + if (skip_set_flag) + fprintf(vvp_out, "t_%u ;\n", skip_set); + } clr_vector(res); @@ -715,13 +749,16 @@ static int show_stmt_fork(ivl_statement_t net, ivl_scope_t sscope) unsigned cnt = ivl_stmt_block_count(net); unsigned out = transient_id++; + unsigned id_base = transient_id; + transient_id += cnt-1; + /* Draw a fork statement for all but one of the threads of the fork/join. Send the threads off to a bit of code where they are implemented. */ for (idx = 0 ; idx < cnt-1 ; idx += 1) { fprintf(vvp_out, " %%fork t_%u, S_%s;\n", - transient_id+idx, + id_base+idx, vvp_mangle_id(ivl_scope_name(sscope))); } @@ -735,7 +772,7 @@ static int show_stmt_fork(ivl_statement_t net, ivl_scope_t sscope) fprintf(vvp_out, " %%jmp t_%u;\n", out); for (idx = 0 ; idx < cnt-1 ; idx += 1) { - fprintf(vvp_out, "t_%u ;\n", transient_id+idx); + fprintf(vvp_out, "t_%u ;\n", id_base+idx); rc += show_statement(ivl_stmt_block_stmt(net, idx), sscope); fprintf(vvp_out, " %%end;\n"); } @@ -744,8 +781,6 @@ static int show_stmt_fork(ivl_statement_t net, ivl_scope_t sscope) the implementations of all the child threads. */ fprintf(vvp_out, "t_%u ;\n", out); - transient_id += cnt-1; - return rc; } @@ -1232,6 +1267,13 @@ int draw_func_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.65 2002/08/27 05:39:57 steve + * Fix l-value indexing of memories and vectors so that + * an unknown (x) index causes so cell to be addresses. + * + * Fix tangling of label identifiers in the fork-join + * code generator. + * * Revision 1.64 2002/08/19 00:06:12 steve * Allow release to handle removal of target net. * diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index c21751b5d..81fe55232 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1,7 +1,7 @@ /* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * - * $Id: opcodes.txt,v 1.37 2002/08/22 03:38:40 steve Exp $ + * $Id: opcodes.txt,v 1.38 2002/08/27 05:39:57 steve Exp $ */ @@ -234,7 +234,16 @@ thread bit space, and is the width of the vector. The function converts the 4-value bits into a binary number, without sign extension. If any of the bits of the vector is x or z, then the -index register gets the value (-1). +index register gets the value 0. + +The function also writes into bit 4 a 1 if any of the bits of the +input vector are x or z. This is a flag that the 0 value written into +the index register is really the result of calculating from unknown +bits. + + 4: unknown value + 5: (reserved) + 6: (reserved) * %ix/load , diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 11fc9c17a..54e97a271 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.81 2002/08/22 03:38:40 steve Exp $" +#ident "$Id: vthread.cc,v 1.82 2002/08/27 05:39:57 steve Exp $" #endif # include "vthread.h" @@ -1260,21 +1260,26 @@ bool of_IX_LOAD(vthread_t thr, vvp_code_t cp) * vector and is the width in bits. * * Index registers only hold binary values, so if any of the - * bits of the vector are x or z, then set the value to 0 - * and give up. + * bits of the vector are x or z, then set the value to 0, + * set bit[4] to 1, and give up. */ bool of_IX_GET(vthread_t thr, vvp_code_t cp) { unsigned long v = 0; + bool unknown_flag = false; + for (unsigned i = 0; inumber; i++) { unsigned char vv = thr_get_bit(thr, cp->bit_idx[1] + i); if (vv&2) { v = 0UL; + unknown_flag = true; break; } v |= vv << i; } thr->index[cp->bit_idx[0] & 3] = v; + /* Set bit 4 as a flag if the input is unknown. */ + thr_put_bit(thr, 4, unknown_flag? 1 : 0); return true; } @@ -2243,6 +2248,13 @@ bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp) /* * $Log: vthread.cc,v $ + * Revision 1.82 2002/08/27 05:39:57 steve + * Fix l-value indexing of memories and vectors so that + * an unknown (x) index causes so cell to be addresses. + * + * Fix tangling of label identifiers in the fork-join + * code generator. + * * Revision 1.81 2002/08/22 03:38:40 steve * Fix behavioral eval of x?a:b expressions. *