Handle memory words in l-value concatenations.
This commit is contained in:
parent
e7c2e06260
commit
0fb1fd36ee
12
ivl_target.h
12
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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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 <ivl_target.h>
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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)) ) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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<memory width=%u>\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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
<lval> = 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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue