Add thread expression lookaside map.
This commit is contained in:
parent
e3eb89fb12
commit
778e96330d
|
|
@ -16,7 +16,7 @@
|
|||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.10 2002/08/12 00:27:10 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.11 2002/09/27 16:33:34 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
|
@ -50,7 +50,7 @@ all: vvp.tgt
|
|||
$(CC) -Wall @ident_support@ -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep
|
||||
|
||||
O = vvp.o draw_mux.o eval_expr.o vvp_process.o vvp_scope.o
|
||||
O = vvp.o draw_mux.o eval_expr.o vector.o vvp_process.o vvp_scope.o
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
TGTLDFLAGS=-L.. -livl
|
||||
|
|
|
|||
|
|
@ -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.79 2002/09/24 04:20:32 steve Exp $"
|
||||
#ident "$Id: eval_expr.c,v 1.80 2002/09/27 16:33:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -29,70 +29,6 @@
|
|||
# include <assert.h>
|
||||
|
||||
|
||||
static unsigned char allocation_map[0x10000/8];
|
||||
|
||||
static inline int peek_bit(unsigned addr)
|
||||
{
|
||||
unsigned bit = addr % 8;
|
||||
addr /= 8;
|
||||
return 1 & (allocation_map[addr] >> bit);
|
||||
}
|
||||
|
||||
static inline void set_bit(unsigned addr)
|
||||
{
|
||||
unsigned bit = addr % 8;
|
||||
addr /= 8;
|
||||
allocation_map[addr] |= (1 << bit);
|
||||
}
|
||||
|
||||
static inline void clr_bit(unsigned addr)
|
||||
{
|
||||
unsigned bit = addr % 8;
|
||||
addr /= 8;
|
||||
allocation_map[addr] &= ~(1 << bit);
|
||||
}
|
||||
|
||||
/*
|
||||
* This clears a vector that was previously allocated by
|
||||
* allocate_vector. That is, it unmarks all the bits of the map that
|
||||
* represent this vector.
|
||||
*
|
||||
* If the vector is based in one of 4 constant bit values, then there
|
||||
* are no bits to clear. If the vector is based in the 4-8 result
|
||||
* area, then someone is broken.
|
||||
*/
|
||||
void clr_vector(struct vector_info vec)
|
||||
{
|
||||
unsigned idx;
|
||||
if (vec.base < 4)
|
||||
return;
|
||||
assert(vec.base >= 8);
|
||||
for (idx = 0 ; idx < vec.wid ; idx += 1)
|
||||
clr_bit(vec.base + idx);
|
||||
}
|
||||
|
||||
unsigned short allocate_vector(unsigned short wid)
|
||||
{
|
||||
unsigned short base = 8;
|
||||
|
||||
unsigned short idx = 0;
|
||||
while (idx < wid) {
|
||||
assert((base + idx) < 0x10000);
|
||||
if (peek_bit(base+idx)) {
|
||||
base = base + idx + 1;
|
||||
idx = 0;
|
||||
|
||||
} else {
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0 ; idx < wid ; idx += 1)
|
||||
set_bit(base+idx);
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
int number_is_unknown(ivl_expr_t ex)
|
||||
{
|
||||
const char*bits;
|
||||
|
|
@ -958,6 +894,8 @@ static struct vector_info draw_binary_expr(ivl_expr_t exp,
|
|||
assert(0);
|
||||
}
|
||||
|
||||
if (rv.base >= 8)
|
||||
save_expression_lookaside(rv.base, exp, wid);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -989,6 +927,8 @@ static struct vector_info draw_bitsel_expr(ivl_expr_t exp, unsigned wid)
|
|||
break;
|
||||
}
|
||||
|
||||
if (res.base >= 8)
|
||||
save_expression_lookaside(res.base, exp, wid);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1026,10 +966,22 @@ static struct vector_info draw_concat_expr(ivl_expr_t exp, unsigned wid)
|
|||
ivl_expr_t arg = ivl_expr_parm(exp, idx-1);
|
||||
unsigned awid = ivl_expr_width(arg);
|
||||
|
||||
/* Evaluate this sub expression. */
|
||||
struct vector_info avec = draw_eval_expr_wid(arg, awid, 0);
|
||||
unsigned trans;
|
||||
struct vector_info avec;
|
||||
|
||||
unsigned trans = awid;
|
||||
/* Try to locate the subexpression in the
|
||||
lookaside map. */
|
||||
avec.base = allocate_vector_exp(arg, awid);
|
||||
avec.wid = awid;
|
||||
|
||||
/* If it's not in the lookaside map, then
|
||||
evaluate the expression here. */
|
||||
if (avec.base == 0) {
|
||||
/* Evaluate this sub expression. */
|
||||
avec = draw_eval_expr_wid(arg, awid, 0);
|
||||
}
|
||||
|
||||
trans = awid;
|
||||
if ((off + awid) > wid)
|
||||
trans = wid - off;
|
||||
|
||||
|
|
@ -1052,6 +1004,10 @@ static struct vector_info draw_concat_expr(ivl_expr_t exp, unsigned wid)
|
|||
res.base+off, wid-off);
|
||||
}
|
||||
|
||||
/* Save the accumulated result in the lookaside map. */
|
||||
if (res.base >= 8)
|
||||
save_expression_lookaside(res.base, exp, wid);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1137,6 +1093,9 @@ static struct vector_info draw_number_expr(ivl_expr_t exp, unsigned wid)
|
|||
if (idx < wid)
|
||||
fprintf(vvp_out, " %%mov %u, 0, %u;\n", res.base+idx, wid-idx);
|
||||
|
||||
if (res.base >= 8)
|
||||
save_expression_lookaside(res.base, exp, wid);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1184,6 +1143,9 @@ static struct vector_info draw_string_expr(ivl_expr_t exp, unsigned wid)
|
|||
if (idx < wid)
|
||||
fprintf(vvp_out, " %%mov %u, 0, %u;\n", res.base+idx, wid-idx);
|
||||
|
||||
if (res.base >= 8)
|
||||
save_expression_lookaside(res.base, exp, wid);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1204,8 +1166,16 @@ static struct vector_info draw_signal_expr(ivl_expr_t exp, unsigned wid)
|
|||
if (swid > wid)
|
||||
swid = wid;
|
||||
|
||||
res.base = allocate_vector(wid);
|
||||
res.wid = wid;
|
||||
res.base = allocate_vector_exp(exp, wid);
|
||||
res.wid = wid;
|
||||
if (res.base != 0)
|
||||
return res;
|
||||
|
||||
if (res.base == 0) {
|
||||
res.base = allocate_vector(wid);
|
||||
res.wid = wid;
|
||||
save_expression_lookaside(res.base, exp, wid);
|
||||
}
|
||||
|
||||
for (idx = 0 ; idx < swid ; idx += 1)
|
||||
fprintf(vvp_out, " %%load %u, V_%s[%u];\n",
|
||||
|
|
@ -1296,6 +1266,9 @@ static struct vector_info draw_memory_expr(ivl_expr_t exp, unsigned wid)
|
|||
fprintf(vvp_out, " %%mov %u, 0, %u;\n",
|
||||
res.base+swid, wid-swid);
|
||||
|
||||
if (res.base >= 8)
|
||||
save_expression_lookaside(res.base, exp, wid);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1345,6 +1318,9 @@ static struct vector_info draw_select_expr(ivl_expr_t exp, unsigned wid)
|
|||
res = subv;
|
||||
}
|
||||
|
||||
if (res.base >= 8)
|
||||
save_expression_lookaside(res.base, exp, wid);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1412,6 +1388,9 @@ static struct vector_info draw_ternary_expr(ivl_expr_t exp, unsigned wid)
|
|||
/* This is the out label. */
|
||||
fprintf(vvp_out, "T_%d.%d ;\n", thread_count, lab_out);
|
||||
|
||||
if (res.base >= 8)
|
||||
save_expression_lookaside(res.base, exp, wid);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1541,6 +1520,9 @@ static struct vector_info draw_sfunc_expr(ivl_expr_t exp, unsigned wid)
|
|||
free(vec);
|
||||
}
|
||||
|
||||
/* New basic block starts after VPI calls. */
|
||||
clear_expression_lookaside();
|
||||
|
||||
fprintf(vvp_out, ";\n");
|
||||
|
||||
|
||||
|
|
@ -1595,6 +1577,9 @@ static struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid)
|
|||
fprintf(vvp_out, ", S_%s;\n", vvp_mangle_id(ivl_scope_name(def)));
|
||||
fprintf(vvp_out, " %%join;\n");
|
||||
|
||||
/* Fresh basic block starts after the join. */
|
||||
clear_expression_lookaside();
|
||||
|
||||
/* The return value is in a signal that has the name of the
|
||||
expression. Load that into the thread and return the
|
||||
vector result. */
|
||||
|
|
@ -1784,6 +1769,9 @@ static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid)
|
|||
assert(0);
|
||||
}
|
||||
|
||||
if (res.base >= 8)
|
||||
save_expression_lookaside(res.base, exp, wid);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -1792,6 +1780,10 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned wid,
|
|||
{
|
||||
struct vector_info res;
|
||||
|
||||
/* This is too conservative, but is certainly safe. Relaxing
|
||||
this will require extensive testing. */
|
||||
clear_expression_lookaside();
|
||||
|
||||
switch (ivl_expr_type(exp)) {
|
||||
default:
|
||||
fprintf(stderr, "vvp error: unhandled expr type: %u\n",
|
||||
|
|
@ -1861,6 +1853,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag)
|
|||
|
||||
/*
|
||||
* $Log: eval_expr.c,v $
|
||||
* Revision 1.80 2002/09/27 16:33:34 steve
|
||||
* Add thread expression lookaside map.
|
||||
*
|
||||
* Revision 1.79 2002/09/24 04:20:32 steve
|
||||
* Allow results in register bits 47 in certain cases.
|
||||
*
|
||||
|
|
@ -1907,93 +1902,5 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag)
|
|||
* generate vvp labels. -tdll target does not
|
||||
* used hierarchical name string to look up the
|
||||
* memory objects in the design.
|
||||
*
|
||||
* Revision 1.66 2002/08/03 22:30:48 steve
|
||||
* Eliminate use of ivl_signal_name for signal labels.
|
||||
*
|
||||
* Revision 1.65 2002/07/12 18:10:45 steve
|
||||
* Use all bits of ?: condit expression.
|
||||
*
|
||||
* Revision 1.64 2002/07/01 00:52:47 steve
|
||||
* Carry can propagate to the otp in addi.
|
||||
*
|
||||
* Revision 1.63 2002/06/02 18:57:17 steve
|
||||
* Generate %cmpi/u where appropriate.
|
||||
*
|
||||
* Revision 1.62 2002/05/31 20:04:57 steve
|
||||
* Generate %muli instructions when possible.
|
||||
*
|
||||
* Revision 1.61 2002/05/30 01:57:23 steve
|
||||
* Use addi with wide immediate values.
|
||||
*
|
||||
* Revision 1.60 2002/05/29 16:29:34 steve
|
||||
* Add %addi, which is faster to simulate.
|
||||
*
|
||||
* Revision 1.59 2002/05/07 03:49:58 steve
|
||||
* Handle x case of unary ! properly.
|
||||
*
|
||||
* Revision 1.58 2002/04/22 02:41:30 steve
|
||||
* Reduce the while loop expression if needed.
|
||||
*
|
||||
* Revision 1.57 2002/04/14 18:41:34 steve
|
||||
* Support signed integer division.
|
||||
*
|
||||
* Revision 1.56 2002/02/03 05:53:00 steve
|
||||
* Fix parameter bit select check for magic constants.
|
||||
*
|
||||
* Revision 1.55 2002/01/28 00:52:42 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.54 2002/01/11 05:23:05 steve
|
||||
* Handle certain special cases of stime.
|
||||
*
|
||||
* Revision 1.53 2001/11/19 04:25:46 steve
|
||||
* Handle padding out of logical values.
|
||||
*
|
||||
* Revision 1.52 2001/10/24 05:06:54 steve
|
||||
* The ! expression returns 0 to x and z values.
|
||||
*
|
||||
* Revision 1.51 2001/10/18 16:41:49 steve
|
||||
* Evaluate string expressions (Philip Blundell)
|
||||
*
|
||||
* Revision 1.50 2001/10/16 01:27:17 steve
|
||||
* Generate %div instructions for binary /.
|
||||
*
|
||||
* Revision 1.49 2001/10/14 03:24:35 steve
|
||||
* Handle constant bits in arithmetic expressions.
|
||||
*
|
||||
* Revision 1.48 2001/10/10 04:47:43 steve
|
||||
* Support vectors as operands to logical and.
|
||||
*
|
||||
* Revision 1.47 2001/09/29 04:37:44 steve
|
||||
* Generate code for unary minus (PR#272)
|
||||
*
|
||||
* Revision 1.46 2001/09/29 01:53:22 steve
|
||||
* Fix the size of unsized constant operants to compare (PR#274)
|
||||
*
|
||||
* Revision 1.45 2001/09/20 03:46:38 steve
|
||||
* Handle short l-values to concatenation.
|
||||
*
|
||||
* Revision 1.44 2001/09/15 18:27:04 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
* Revision 1.43 2001/08/31 01:37:56 steve
|
||||
* Handle update in place of repeat constants.
|
||||
*
|
||||
* Revision 1.42 2001/08/23 02:54:15 steve
|
||||
* Handle wide assignment to narrow return value.
|
||||
*
|
||||
* Revision 1.41 2001/08/03 17:06:10 steve
|
||||
* More detailed messages about unsupported things.
|
||||
*
|
||||
* Revision 1.40 2001/07/27 04:51:45 steve
|
||||
* Handle part select expressions as variants of
|
||||
* NetESignal/IVL_EX_SIGNAL objects, instead of
|
||||
* creating new and useless temporary signals.
|
||||
*
|
||||
* Revision 1.39 2001/07/27 02:41:56 steve
|
||||
* Fix binding of dangling function ports. do not elide them.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: vector.c,v 1.1 2002/09/27 16:33:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
# include <assert.h>
|
||||
|
||||
static struct allocation_score_s {
|
||||
ivl_expr_t exp;
|
||||
unsigned bit :16;
|
||||
unsigned alloc : 1;
|
||||
} allocation_map[0x10000] = { {0} };
|
||||
|
||||
/* This is the largest bit to have lookaside values. */
|
||||
static unsigned lookaside_top = 0;
|
||||
|
||||
static inline int peek_bit(unsigned addr)
|
||||
{
|
||||
return allocation_map[addr].alloc;
|
||||
}
|
||||
|
||||
static inline void set_bit(unsigned addr)
|
||||
{
|
||||
allocation_map[addr].alloc = 1;
|
||||
}
|
||||
|
||||
static inline void clr_bit(unsigned addr)
|
||||
{
|
||||
allocation_map[addr].alloc = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This clears a vector that was previously allocated by
|
||||
* allocate_vector. That is, it unmarks all the bits of the map that
|
||||
* represent this vector.
|
||||
*
|
||||
* If the vector is based in one of 4 constant bit values, then there
|
||||
* are no bits to clear. If the vector is based in the 4-8 result
|
||||
* area, then someone is broken.
|
||||
*/
|
||||
void clr_vector(struct vector_info vec)
|
||||
{
|
||||
unsigned idx;
|
||||
if (vec.base < 4)
|
||||
return;
|
||||
assert(vec.base >= 8);
|
||||
for (idx = 0 ; idx < vec.wid ; idx += 1)
|
||||
clr_bit(vec.base + idx);
|
||||
}
|
||||
|
||||
/*
|
||||
* This unconditionally allocates a stretch of bits from the register
|
||||
* set. It never returns a bit addressed <8 (0-3 are constant, 4-7 are
|
||||
* condition codes).
|
||||
*/
|
||||
unsigned short allocate_vector(unsigned short wid)
|
||||
{
|
||||
unsigned short base = 8;
|
||||
|
||||
unsigned short idx = 0;
|
||||
while (idx < wid) {
|
||||
assert((base + idx) < 0x10000);
|
||||
if (peek_bit(base+idx)) {
|
||||
base = base + idx + 1;
|
||||
idx = 0;
|
||||
|
||||
} else {
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0 ; idx < wid ; idx += 1) {
|
||||
allocation_map[base+idx].alloc = 1;
|
||||
allocation_map[base+idx].exp = 0;
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
/*
|
||||
* This clears the expression cache of the allocation map. It is
|
||||
* called to prevent reuse of existing expressions, normally at the
|
||||
* start of a basic block.
|
||||
*/
|
||||
void clear_expression_lookaside(void)
|
||||
{
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < lookaside_top ; idx += 1) {
|
||||
allocation_map[idx].exp = 0;
|
||||
}
|
||||
|
||||
lookaside_top = 0;
|
||||
}
|
||||
|
||||
void save_expression_lookaside(unsigned short addr, ivl_expr_t exp,
|
||||
unsigned short wid)
|
||||
{
|
||||
unsigned idx;
|
||||
assert(addr >= 8);
|
||||
assert((addr+wid) <= 0x10000);
|
||||
|
||||
for (idx = 0 ; idx < wid ; idx += 1) {
|
||||
allocation_map[addr+idx].exp = exp;
|
||||
allocation_map[addr+idx].bit = idx;
|
||||
}
|
||||
|
||||
if ((addr+wid) > lookaside_top)
|
||||
lookaside_top = addr+wid;
|
||||
}
|
||||
|
||||
static int compare_exp(ivl_expr_t l, ivl_expr_t r)
|
||||
{
|
||||
if (! (l && r))
|
||||
return 0;
|
||||
if (l == r)
|
||||
return 1;
|
||||
|
||||
if (ivl_expr_type(l) != ivl_expr_type(r))
|
||||
return 0;
|
||||
|
||||
switch (ivl_expr_type(l)) {
|
||||
case IVL_EX_SIGNAL:
|
||||
if (ivl_expr_signal(l) != ivl_expr_signal(r))
|
||||
return 0;
|
||||
|
||||
if (ivl_expr_lsi(l) != ivl_expr_lsi(r))
|
||||
return 0;
|
||||
|
||||
if (ivl_expr_width(l) != ivl_expr_width(r))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned short find_expression_lookaside(ivl_expr_t exp,
|
||||
unsigned short wid)
|
||||
{
|
||||
unsigned top;
|
||||
unsigned idx, match;
|
||||
|
||||
if (lookaside_top <= wid)
|
||||
return 0;
|
||||
|
||||
top = lookaside_top - wid + 1;
|
||||
|
||||
assert(exp);
|
||||
match = 0;
|
||||
for (idx = 8 ; idx < top ; idx += 1) {
|
||||
if (! compare_exp(allocation_map[idx].exp, exp)) {
|
||||
match = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (allocation_map[idx].bit != match) {
|
||||
match = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
match += 1;
|
||||
if (match == wid)
|
||||
return idx-match+1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned short allocate_vector_exp(ivl_expr_t exp, unsigned short wid)
|
||||
{
|
||||
unsigned idx;
|
||||
unsigned short la = find_expression_lookaside(exp, wid);
|
||||
|
||||
for (idx = 0 ; idx < wid ; idx += 1)
|
||||
if (allocation_map[la+idx].alloc)
|
||||
return 0;
|
||||
|
||||
for (idx = 0 ; idx < wid ; idx += 1)
|
||||
allocation_map[la+idx].alloc = 1;
|
||||
|
||||
return la;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: vector.c,v $
|
||||
* Revision 1.1 2002/09/27 16:33:34 steve
|
||||
* Add thread expression lookaside map.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -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.21 2002/09/24 04:20:32 steve Exp $"
|
||||
#ident "$Id: vvp_priv.h,v 1.22 2002/09/27 16:33:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "ivl_target.h"
|
||||
|
|
@ -114,9 +114,46 @@ extern struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned w,
|
|||
*/
|
||||
extern void draw_memory_index_expr(ivl_memory_t mem, ivl_expr_t exp);
|
||||
|
||||
/*
|
||||
* These functions manage vector allocation in the thread register
|
||||
* space. They presume that we work on one thread at a time, to
|
||||
* completion.
|
||||
*
|
||||
* allocate_vector
|
||||
* Return the base of an allocated vector in the thread. The bits
|
||||
* are marked allocated in the process.
|
||||
*
|
||||
* clr_bector
|
||||
* Clear a vector previously allocated.
|
||||
*
|
||||
* The thread vector allocator also keeps a lookaside of expression
|
||||
* results that are stored in register bit. This lookaside can be used
|
||||
* by the code generator to notice that certain expression bits are
|
||||
* already calculated, and can be reused.
|
||||
*
|
||||
* clear_expression_lookaside
|
||||
* Clear the lookaside tables for the current thread.
|
||||
*
|
||||
* save_expression_lookaside
|
||||
* Mark the given expression as available in the given register
|
||||
* bits. This remains until the lookaside is cleared.
|
||||
*
|
||||
* allocate_vector_exp
|
||||
* This function attempts to locate the expression in the
|
||||
* lookaside. If it finds it, return a reallocated base for the
|
||||
* expression. Otherwise, return 0.
|
||||
*/
|
||||
extern unsigned short allocate_vector(unsigned short wid);
|
||||
extern void clr_vector(struct vector_info vec);
|
||||
|
||||
extern void clear_expression_lookaside(void);
|
||||
extern void save_expression_lookaside(unsigned short addr,
|
||||
ivl_expr_t exp,
|
||||
unsigned short wid);
|
||||
|
||||
extern unsigned short allocate_vector_exp(ivl_expr_t exp,
|
||||
unsigned short wid);
|
||||
|
||||
extern int number_is_unknown(ivl_expr_t ex);
|
||||
extern int number_is_immediate(ivl_expr_t ex, unsigned lim_wid);
|
||||
extern unsigned long get_number_immediate(ivl_expr_t ex);
|
||||
|
|
@ -129,6 +166,9 @@ extern unsigned thread_count;
|
|||
|
||||
/*
|
||||
* $Log: vvp_priv.h,v $
|
||||
* Revision 1.22 2002/09/27 16:33:34 steve
|
||||
* Add thread expression lookaside map.
|
||||
*
|
||||
* Revision 1.21 2002/09/24 04:20:32 steve
|
||||
* Allow results in register bits 47 in certain cases.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.69 2002/09/24 04:20:32 steve Exp $"
|
||||
#ident "$Id: vvp_process.c,v 1.70 2002/09/27 16:33:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -480,6 +480,7 @@ static int show_stmt_block_named(ivl_statement_t net, ivl_scope_t scope)
|
|||
fprintf(vvp_out, " %%end;\n");
|
||||
|
||||
fprintf(vvp_out, "t_%u %%join;\n", out_id);
|
||||
clear_expression_lookaside();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -584,6 +585,8 @@ static int show_stmt_case(ivl_statement_t net, ivl_scope_t sscope)
|
|||
if (idx == default_case)
|
||||
continue;
|
||||
|
||||
clear_expression_lookaside();
|
||||
|
||||
fprintf(vvp_out, "T_%d.%d ;\n", thread_count, local_base+idx);
|
||||
show_statement(cst, sscope);
|
||||
|
||||
|
|
@ -592,6 +595,8 @@ static int show_stmt_case(ivl_statement_t net, ivl_scope_t sscope)
|
|||
|
||||
}
|
||||
|
||||
clear_expression_lookaside();
|
||||
|
||||
/* The out of the case. */
|
||||
fprintf(vvp_out, "T_%d.%d ;\n", thread_count, local_base+count);
|
||||
|
||||
|
|
@ -668,12 +673,15 @@ static int show_stmt_condit(ivl_statement_t net, ivl_scope_t sscope)
|
|||
if (ivl_stmt_cond_true(net))
|
||||
rc += show_statement(ivl_stmt_cond_true(net), sscope);
|
||||
|
||||
clear_expression_lookaside();
|
||||
|
||||
if (ivl_stmt_cond_false(net)) {
|
||||
fprintf(vvp_out, " %%jmp T_%d.%d;\n", thread_count, lab_out);
|
||||
fprintf(vvp_out, "T_%d.%u ;\n", thread_count, lab_false);
|
||||
|
||||
rc += show_statement(ivl_stmt_cond_false(net), sscope);
|
||||
|
||||
clear_expression_lookaside();
|
||||
fprintf(vvp_out, "T_%d.%u ;\n", thread_count, lab_out);
|
||||
|
||||
} else {
|
||||
|
|
@ -698,6 +706,9 @@ static int show_stmt_delay(ivl_statement_t net, ivl_scope_t sscope)
|
|||
ivl_statement_t stmt = ivl_stmt_sub_stmt(net);
|
||||
|
||||
fprintf(vvp_out, " %%delay %lu;\n", delay);
|
||||
/* Lots of things can happen during a delay. */
|
||||
clear_expression_lookaside();
|
||||
|
||||
rc += show_statement(stmt, sscope);
|
||||
|
||||
return rc;
|
||||
|
|
@ -721,6 +732,8 @@ static int show_stmt_delayx(ivl_statement_t net, ivl_scope_t sscope)
|
|||
}
|
||||
|
||||
fprintf(vvp_out, " %%delayx 0;\n");
|
||||
/* Lots of things can happen during a delay. */
|
||||
clear_expression_lookaside();
|
||||
|
||||
rc += show_statement(stmt, sscope);
|
||||
return rc;
|
||||
|
|
@ -809,12 +822,14 @@ static int show_stmt_fork(ivl_statement_t net, ivl_scope_t sscope)
|
|||
|
||||
for (idx = 0 ; idx < cnt-1 ; idx += 1) {
|
||||
fprintf(vvp_out, "t_%u ;\n", id_base+idx);
|
||||
clear_expression_lookaside();
|
||||
rc += show_statement(ivl_stmt_block_stmt(net, idx), sscope);
|
||||
fprintf(vvp_out, " %%end;\n");
|
||||
}
|
||||
|
||||
/* This is the label for the out. Use this to branch around
|
||||
the implementations of all the child threads. */
|
||||
clear_expression_lookaside();
|
||||
fprintf(vvp_out, "t_%u ;\n", out);
|
||||
|
||||
return rc;
|
||||
|
|
@ -881,6 +896,7 @@ static int show_stmt_repeat(ivl_statement_t net, ivl_scope_t sscope)
|
|||
rc += show_statement(ivl_stmt_sub_stmt(net), sscope);
|
||||
|
||||
fprintf(vvp_out, " %%jmp T_%u.%u;\n", thread_count, lab_top);
|
||||
clear_expression_lookaside();
|
||||
fprintf(vvp_out, "T_%u.%u ;\n", thread_count, lab_out);
|
||||
|
||||
clr_vector(cnt);
|
||||
|
|
@ -906,6 +922,7 @@ static int show_stmt_utask(ivl_statement_t net)
|
|||
fprintf(vvp_out, ", S_%s;\n",
|
||||
vvp_mangle_id(ivl_scope_name(task)));
|
||||
fprintf(vvp_out, " %%join;\n");
|
||||
clear_expression_lookaside();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -915,6 +932,8 @@ static int show_stmt_wait(ivl_statement_t net, ivl_scope_t sscope)
|
|||
fprintf(vvp_out, " %%wait E_%s;\n",
|
||||
vvp_mangle_id(ivl_event_name(ev)));
|
||||
|
||||
clear_expression_lookaside();
|
||||
|
||||
return show_statement(ivl_stmt_sub_stmt(net), sscope);
|
||||
}
|
||||
|
||||
|
|
@ -976,6 +995,7 @@ static int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope)
|
|||
/* This is the bottom of the loop. branch to the top where the
|
||||
test is repeased, and also draw the out label. */
|
||||
fprintf(vvp_out, " %%jmp T_%d.%d;\n", thread_count, top_label);
|
||||
clear_expression_lookaside();
|
||||
fprintf(vvp_out, "T_%d.%d ;\n", thread_count, out_label);
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -990,6 +1010,7 @@ static int show_system_task_call(ivl_statement_t net)
|
|||
|
||||
if (parm_count == 0) {
|
||||
fprintf(vvp_out, " %%vpi_call \"%s\";\n", ivl_stmt_name(net));
|
||||
clear_expression_lookaside();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1108,6 +1129,8 @@ static int show_system_task_call(ivl_statement_t net)
|
|||
|
||||
fprintf(vvp_out, ";\n");
|
||||
|
||||
clear_expression_lookaside();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1121,6 +1144,10 @@ static int show_statement(ivl_statement_t net, ivl_scope_t sscope)
|
|||
const ivl_statement_type_t code = ivl_statement_type(net);
|
||||
int rc = 0;
|
||||
|
||||
/* This is more conservitive then it needs to be, but
|
||||
relaxing this will require extensive testing. */
|
||||
clear_expression_lookaside();
|
||||
|
||||
switch (code) {
|
||||
|
||||
case IVL_ST_ASSIGN:
|
||||
|
|
@ -1242,6 +1269,7 @@ int draw_process(ivl_process_t net, void*x)
|
|||
/* Generate the entry label. Just give the thread a number so
|
||||
that we ar certain the label is unique. */
|
||||
fprintf(vvp_out, "T_%d ;\n", thread_count);
|
||||
clear_expression_lookaside();
|
||||
|
||||
/* Draw the contents of the thread. */
|
||||
rc += show_statement(stmt, scope);
|
||||
|
|
@ -1276,6 +1304,7 @@ int draw_task_definition(ivl_scope_t scope)
|
|||
ivl_statement_t def = ivl_scope_def(scope);
|
||||
|
||||
fprintf(vvp_out, "TD_%s ;\n", vvp_mangle_id(ivl_scope_name(scope)));
|
||||
clear_expression_lookaside();
|
||||
|
||||
assert(def);
|
||||
rc += show_statement(def, scope);
|
||||
|
|
@ -1292,6 +1321,7 @@ int draw_func_definition(ivl_scope_t scope)
|
|||
ivl_statement_t def = ivl_scope_def(scope);
|
||||
|
||||
fprintf(vvp_out, "TD_%s ;\n", vvp_mangle_id(ivl_scope_name(scope)));
|
||||
clear_expression_lookaside();
|
||||
|
||||
assert(def);
|
||||
rc += show_statement(def, scope);
|
||||
|
|
@ -1304,6 +1334,9 @@ int draw_func_definition(ivl_scope_t scope)
|
|||
|
||||
/*
|
||||
* $Log: vvp_process.c,v $
|
||||
* Revision 1.70 2002/09/27 16:33:34 steve
|
||||
* Add thread expression lookaside map.
|
||||
*
|
||||
* Revision 1.69 2002/09/24 04:20:32 steve
|
||||
* Allow results in register bits 47 in certain cases.
|
||||
*
|
||||
|
|
@ -1392,99 +1425,5 @@ int draw_func_definition(ivl_scope_t scope)
|
|||
*
|
||||
* Revision 1.44 2001/09/01 00:58:16 steve
|
||||
* dead comments.
|
||||
*
|
||||
* Revision 1.43 2001/08/26 23:00:13 steve
|
||||
* Generate code for l-value bit selects.
|
||||
*
|
||||
* Revision 1.42 2001/08/25 23:50:03 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.41 2001/08/16 03:45:17 steve
|
||||
* statement ends after while loop labels.
|
||||
*
|
||||
* Revision 1.40 2001/07/28 01:18:07 steve
|
||||
* Evaluate part selects when passed to system tasks.
|
||||
*
|
||||
* Revision 1.39 2001/07/19 04:55:06 steve
|
||||
* Support calculated delays in vvp.tgt.
|
||||
*
|
||||
* Revision 1.38 2001/06/29 02:41:05 steve
|
||||
* Handle null parameters to system tasks.
|
||||
*
|
||||
* Revision 1.37 2001/06/23 00:30:42 steve
|
||||
* Handle short inputs to tasks. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.36 2001/06/18 03:10:34 steve
|
||||
* 1. Logic with more than 4 inputs
|
||||
* 2. Id and name mangling
|
||||
* 3. A memory leak in draw_net_in_scope()
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.35 2001/05/24 04:31:00 steve
|
||||
* Attach noops to case labels.
|
||||
*
|
||||
* Revision 1.34 2001/05/17 04:37:02 steve
|
||||
* Behavioral ternary operators for vvp.
|
||||
*
|
||||
* Revision 1.33 2001/05/10 00:26:53 steve
|
||||
* VVP support for memories in expressions,
|
||||
* including general support for thread bit
|
||||
* vectors as system task parameters.
|
||||
* (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.32 2001/05/08 23:59:33 steve
|
||||
* Add ivl and vvp.tgt support for memories in
|
||||
* expressions and l-values. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.31 2001/05/03 04:55:28 steve
|
||||
* Generate null statements for conditional labels.
|
||||
*
|
||||
* Revision 1.30 2001/04/21 03:26:23 steve
|
||||
* Right shift by constant.
|
||||
*
|
||||
* Revision 1.29 2001/04/21 00:55:46 steve
|
||||
* Generate code for disable.
|
||||
*
|
||||
* Revision 1.28 2001/04/18 05:12:03 steve
|
||||
* Use the new %fork syntax.
|
||||
*
|
||||
* Revision 1.27 2001/04/15 02:58:11 steve
|
||||
* vvp support for <= with internal delay.
|
||||
*
|
||||
* Revision 1.26 2001/04/06 02:28:03 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
*
|
||||
* Revision 1.25 2001/04/05 03:20:58 steve
|
||||
* Generate vvp code for the repeat statement.
|
||||
*
|
||||
* Revision 1.24 2001/04/04 04:50:35 steve
|
||||
* Support forever loops in the tgt-vvp target.
|
||||
*
|
||||
* Revision 1.23 2001/04/04 04:28:41 steve
|
||||
* Fix broken look scanning down bits of number.
|
||||
*
|
||||
* Revision 1.22 2001/04/04 04:14:09 steve
|
||||
* emit vpi parameters values as vectors.
|
||||
*
|
||||
* Revision 1.21 2001/04/03 04:50:37 steve
|
||||
* Support non-blocking assignments.
|
||||
*
|
||||
* Revision 1.20 2001/04/02 04:09:20 steve
|
||||
* thread bit allocation leak in assign.
|
||||
*
|
||||
* Revision 1.19 2001/04/02 02:28:13 steve
|
||||
* Generate code for task calls.
|
||||
*
|
||||
* Revision 1.18 2001/04/02 00:27:53 steve
|
||||
* Scopes and numbers as vpi_call parameters.
|
||||
*
|
||||
* Revision 1.17 2001/04/01 06:49:04 steve
|
||||
* Generate code for while statements.
|
||||
*/
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue