diff --git a/ivl_target.h b/ivl_target.h index 9a0cf99ca..bb01a6426 100644 --- a/ivl_target.h +++ b/ivl_target.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: ivl_target.h,v 1.144 2005/03/03 04:34:42 steve Exp $" +#ident "$Id: ivl_target.h,v 1.145 2005/03/05 05:47:42 steve Exp $" #endif #ifdef __cplusplus @@ -954,6 +954,13 @@ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net); * bit select. If the bit select base is non-constant, then the * ivl_lval_mux will contain an expression. If there is a mux * expression, then the ivl_lval_part_off result can be ignored. + * + * - Memory words + * If the l-value is a memory word, the ivl_lval_mem function returns + * a non-nil value. The ivl_lval_idx function will return an + * expression that calculates an address for the memory. The compiler + * will assure that the ivl_lval_width will exactly match the + * ivl_memory_width of the memory word. */ extern unsigned ivl_lval_width(ivl_lval_t net); @@ -1537,6 +1544,9 @@ _END_DECL /* * $Log: ivl_target.h,v $ + * Revision 1.145 2005/03/05 05:47:42 steve + * Handle memory words in l-value concatenations. + * * Revision 1.144 2005/03/03 04:34:42 steve * Rearrange how memories are supported as vvp_vector4 arrays. * diff --git a/tgt-stub/priv.h b/tgt-stub/priv.h index 7205a32b2..6e61dc1e2 100644 --- a/tgt-stub/priv.h +++ b/tgt-stub/priv.h @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: priv.h,v 1.2 2005/01/22 01:06:55 steve Exp $" +#ident "$Id: priv.h,v 1.3 2005/03/05 05:47:42 steve Exp $" #endif # include @@ -40,6 +40,8 @@ extern int stub_errors; */ extern void show_expression(ivl_expr_t net, unsigned ind); +extern void show_memory(ivl_memory_t mem); + /* * Show the statement. */ diff --git a/tgt-stub/statement.c b/tgt-stub/statement.c index f922f9e62..344e067bf 100644 --- a/tgt-stub/statement.c +++ b/tgt-stub/statement.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: statement.c,v 1.4 2005/02/14 01:51:39 steve Exp $" +#ident "$Id: statement.c,v 1.5 2005/03/05 05:47:42 steve Exp $" #endif # include "config.h" @@ -33,11 +33,20 @@ static unsigned show_assign_lval(ivl_lval_t lval, unsigned ind) if ( (mem = ivl_lval_mem(lval)) ) { ivl_scope_t scope = ivl_memory_scope(mem); - fprintf(out, "%*s%s . %s[\n", ind, "", + fprintf(out, "%*s{ %s . %s [\n", ind, "", ivl_scope_name(scope), ivl_memory_basename(mem)); show_expression(ivl_lval_idx(lval), ind+4); - fprintf(out, "%*s]\n", ind, ""); + fprintf(out, "%*s] width=%u }\n", ind, "", ivl_lval_width(lval)); + + /* When the l-value is a memory word, the lval_width + must exactly match the word width. */ + if (ivl_lval_width(lval) != ivl_memory_width(mem)) { + fprintf(out, "%*sERROR: l-value width mismatch with " + " memory word width=%u\n", ind, "", + ivl_memory_width(mem)); + stub_errors += 1; + } } else if ( (var = ivl_lval_var(lval)) ) { diff --git a/tgt-stub/stub.c b/tgt-stub/stub.c index 6a05fa44e..a012a9cb4 100644 --- a/tgt-stub/stub.c +++ b/tgt-stub/stub.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: stub.c,v 1.112 2005/03/03 04:34:42 steve Exp $" +#ident "$Id: stub.c,v 1.113 2005/03/05 05:47:42 steve Exp $" #endif # include "config.h" @@ -50,6 +50,14 @@ unsigned width_of_nexus(ivl_nexus_t nex) return 0; } +void show_memory_expression(ivl_expr_t net, unsigned ind) +{ + unsigned width = ivl_expr_width(net); + + fprintf(out, "%*s\n", ind, "", + width); +} + /* * This is a sample target module. All this does is write to the * output file some information about each object handle when each of @@ -118,6 +126,10 @@ void show_expression(ivl_expr_t net, unsigned ind) break; + case IVL_EX_MEMORY: + show_memory_expression(net, ind); + break; + case IVL_EX_NUMBER: { const char*bits = ivl_expr_bits(net); @@ -1125,6 +1137,9 @@ int target_design(ivl_design_t des) /* * $Log: stub.c,v $ + * Revision 1.113 2005/03/05 05:47:42 steve + * Handle memory words in l-value concatenations. + * * Revision 1.112 2005/03/03 04:34:42 steve * Rearrange how memories are supported as vvp_vector4 arrays. * diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 78976e566..24bbc88ba 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.102 2005/03/03 04:34:42 steve Exp $" +#ident "$Id: vvp_process.c,v 1.103 2005/03/05 05:47:42 steve Exp $" #endif # include "vvp_priv.h" @@ -111,17 +111,6 @@ static void set_to_lvariable(ivl_lval_t lval, } } -#if 0 -/* OBSOLETE */ -static void set_to_memory(ivl_memory_t mem, unsigned idx, unsigned bit) -{ - if (idx) - fprintf(vvp_out, " %%ix/add 3, 1;\n"); - fprintf(vvp_out, " %%set/m M_%s, %u;\n", - vvp_memory_label(mem), bit); -} -#endif - /* * This function writes the code to set a vector to a memory word. The * idx is the thread register that contains the address of the word in @@ -241,6 +230,7 @@ static void set_vec_to_lval(ivl_statement_t net, struct vector_info res) for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) { unsigned skip_set = transient_id++; unsigned skip_set_flag = 0; + unsigned bidx; unsigned bit_limit = wid - cur_rbit; lval = ivl_stmt_lval(net, lidx); @@ -256,21 +246,24 @@ static void set_vec_to_lval(ivl_statement_t net, struct vector_info res) skip_set_flag = 1; } + /* Reduce bit_limit to the width of this l-value. */ if (bit_limit > ivl_lval_width(lval)) bit_limit = ivl_lval_width(lval); + /* This is the address within the larger r-value of the + bit that this l-value takes. */ + bidx = res.base < 4? res.base : (res.base+cur_rbit); + if (mem) { - set_to_memory_word(mem, 3, res.base, res.wid); + set_to_memory_word(mem, 3, bidx, bit_limit); } else { - - unsigned bidx = res.base < 4 - ? res.base - : (res.base+cur_rbit); set_to_lvariable(lval, bidx, bit_limit); - cur_rbit += bit_limit; } + /* Now we've consumed this many r-value bits for the + current l-value. */ + cur_rbit += bit_limit; if (skip_set_flag) { fprintf(vvp_out, "t_%u ;\n", skip_set); @@ -281,9 +274,7 @@ static void set_vec_to_lval(ivl_statement_t net, struct vector_info res) static int show_stmt_assign_vector(ivl_statement_t net) { - ivl_lval_t lval; ivl_expr_t rval = ivl_stmt_rval(net); - ivl_memory_t mem; /* Handle the special case that the expression is a real value. Evaluate the real expression, then convert the @@ -311,102 +302,6 @@ static int show_stmt_assign_vector(ivl_statement_t net) return 0; } - /* Handle the special case that the r-value is a constant. We - can generate the %set statement directly, without any worry - about generating code to evaluate the r-value expressions. */ - - if (ivl_expr_type(rval) == IVL_EX_NUMBER) { - unsigned lidx; - const char*bits = ivl_expr_bits(rval); - unsigned wid = ivl_expr_width(rval); - 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); - - mem = ivl_lval_mem(lval); - if (mem) { - /* Memory index is the ivl_lval_idx - expression, ivl_lval_mux should be - clear. */ - assert(! ivl_lval_mux(lval)); - draw_memory_index_expr(mem, ivl_lval_idx(lval)); - /* Generate code to skip around the set - if the index has X values. */ - fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set); - skip_set_flag = 1; - } - - if (bit_limit > ivl_lval_width(lval)) - bit_limit = ivl_lval_width(lval); - - if (mem) { -#if 0 - for (idx = 0 ; idx < bit_limit ; idx += 1) { - set_to_memory(mem, idx, - bitchar_to_idx(bits[cur_rbit])); - - cur_rbit += 1; - } - - for (idx = bit_limit - ; idx < ivl_lval_width(lval) ; idx += 1) - set_to_memory(mem, idx, 0); -#else - assert(0); -#endif - - } else { - /* Here we have the case of a blocking - assign of a number to a signal: - - = NUMBER; - - Collect the number value into thread - bits, and use a %set/v to write the reg - variable. */ - - struct vector_info vect; - vect.wid = ivl_lval_width(lval); - vect.base = allocate_vector(vect.wid); - - /* This loop makes the value into thread - bits. Use the constant thread bits 0-3 to - generate the values of the vector. */ - idx = 0; - while (idx < bit_limit) { - unsigned cnt = 1; - while (((idx + cnt) < bit_limit) - && (bits[cur_rbit] == bits[cur_rbit+cnt])) - cnt += 1; - - fprintf(vvp_out, " %%mov %u, %u, %u;\n", - vect.base+idx, - bitchar_to_idx(bits[cur_rbit]), - cnt); - - cur_rbit += cnt; - idx += cnt; - } - - /* write out the value into the .var. */ - set_to_lvariable(lval, vect.base, vect.wid); - - clr_vector(vect); - } - - if (skip_set_flag) { - fprintf(vvp_out, "t_%u ;\n", skip_set); - clear_expression_lookaside(); - } - } - - return 0; - } { struct vector_info res = draw_eval_expr(rval, 0); set_vec_to_lval(net, res); @@ -1566,6 +1461,9 @@ int draw_func_definition(ivl_scope_t scope) /* * $Log: vvp_process.c,v $ + * Revision 1.103 2005/03/05 05:47:42 steve + * Handle memory words in l-value concatenations. + * * Revision 1.102 2005/03/03 04:34:42 steve * Rearrange how memories are supported as vvp_vector4 arrays. *