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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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
|
* bit select. If the bit select base is non-constant, then the
|
||||||
* ivl_lval_mux will contain an expression. If there is a mux
|
* ivl_lval_mux will contain an expression. If there is a mux
|
||||||
* expression, then the ivl_lval_part_off result can be ignored.
|
* 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);
|
extern unsigned ivl_lval_width(ivl_lval_t net);
|
||||||
|
|
@ -1537,6 +1544,9 @@ _END_DECL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: ivl_target.h,v $
|
* $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
|
* Revision 1.144 2005/03/03 04:34:42 steve
|
||||||
* Rearrange how memories are supported as vvp_vector4 arrays.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include <ivl_target.h>
|
# 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_expression(ivl_expr_t net, unsigned ind);
|
||||||
|
|
||||||
|
extern void show_memory(ivl_memory_t mem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show the statement.
|
* Show the statement.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -33,11 +33,20 @@ static unsigned show_assign_lval(ivl_lval_t lval, unsigned ind)
|
||||||
if ( (mem = ivl_lval_mem(lval)) ) {
|
if ( (mem = ivl_lval_mem(lval)) ) {
|
||||||
|
|
||||||
ivl_scope_t scope = ivl_memory_scope(mem);
|
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_scope_name(scope),
|
||||||
ivl_memory_basename(mem));
|
ivl_memory_basename(mem));
|
||||||
show_expression(ivl_lval_idx(lval), ind+4);
|
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)) ) {
|
} else if ( (var = ivl_lval_var(lval)) ) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -50,6 +50,14 @@ unsigned width_of_nexus(ivl_nexus_t nex)
|
||||||
return 0;
|
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
|
* This is a sample target module. All this does is write to the
|
||||||
* output file some information about each object handle when each of
|
* 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;
|
break;
|
||||||
|
|
||||||
|
case IVL_EX_MEMORY:
|
||||||
|
show_memory_expression(net, ind);
|
||||||
|
break;
|
||||||
|
|
||||||
case IVL_EX_NUMBER: {
|
case IVL_EX_NUMBER: {
|
||||||
const char*bits = ivl_expr_bits(net);
|
const char*bits = ivl_expr_bits(net);
|
||||||
|
|
||||||
|
|
@ -1125,6 +1137,9 @@ int target_design(ivl_design_t des)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: stub.c,v $
|
* $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
|
* Revision 1.112 2005/03/03 04:34:42 steve
|
||||||
* Rearrange how memories are supported as vvp_vector4 arrays.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#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
|
#endif
|
||||||
|
|
||||||
# include "vvp_priv.h"
|
# 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
|
* 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
|
* 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) {
|
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
|
||||||
unsigned skip_set = transient_id++;
|
unsigned skip_set = transient_id++;
|
||||||
unsigned skip_set_flag = 0;
|
unsigned skip_set_flag = 0;
|
||||||
|
unsigned bidx;
|
||||||
unsigned bit_limit = wid - cur_rbit;
|
unsigned bit_limit = wid - cur_rbit;
|
||||||
lval = ivl_stmt_lval(net, lidx);
|
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;
|
skip_set_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reduce bit_limit to the width of this l-value. */
|
||||||
if (bit_limit > ivl_lval_width(lval))
|
if (bit_limit > ivl_lval_width(lval))
|
||||||
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) {
|
if (mem) {
|
||||||
set_to_memory_word(mem, 3, res.base, res.wid);
|
set_to_memory_word(mem, 3, bidx, bit_limit);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
unsigned bidx = res.base < 4
|
|
||||||
? res.base
|
|
||||||
: (res.base+cur_rbit);
|
|
||||||
set_to_lvariable(lval, bidx, bit_limit);
|
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) {
|
if (skip_set_flag) {
|
||||||
fprintf(vvp_out, "t_%u ;\n", skip_set);
|
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)
|
static int show_stmt_assign_vector(ivl_statement_t net)
|
||||||
{
|
{
|
||||||
ivl_lval_t lval;
|
|
||||||
ivl_expr_t rval = ivl_stmt_rval(net);
|
ivl_expr_t rval = ivl_stmt_rval(net);
|
||||||
ivl_memory_t mem;
|
|
||||||
|
|
||||||
/* Handle the special case that the expression is a real
|
/* Handle the special case that the expression is a real
|
||||||
value. Evaluate the real expression, then convert the
|
value. Evaluate the real expression, then convert the
|
||||||
|
|
@ -311,102 +302,6 @@ static int show_stmt_assign_vector(ivl_statement_t net)
|
||||||
return 0;
|
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);
|
{ struct vector_info res = draw_eval_expr(rval, 0);
|
||||||
set_vec_to_lval(net, res);
|
set_vec_to_lval(net, res);
|
||||||
|
|
@ -1566,6 +1461,9 @@ int draw_func_definition(ivl_scope_t scope)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vvp_process.c,v $
|
* $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
|
* Revision 1.102 2005/03/03 04:34:42 steve
|
||||||
* Rearrange how memories are supported as vvp_vector4 arrays.
|
* Rearrange how memories are supported as vvp_vector4 arrays.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue