Add the assign_v0_d instruction.
This commit is contained in:
parent
21c7abf090
commit
cd14ee77ae
|
|
@ -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.111 2005/06/02 16:03:47 steve Exp $"
|
||||
#ident "$Id: vvp_process.c,v 1.112 2005/06/14 01:45:05 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -123,41 +123,18 @@ static void set_to_memory_word(ivl_memory_t mem, unsigned idx,
|
|||
vvp_memory_label(mem), bit, wid);
|
||||
}
|
||||
|
||||
/*
|
||||
* This generates an assign to a single bit of an lvalue variable. If
|
||||
* the bit is a part select, then index the label to set the right
|
||||
* bit. If there is an lvalue mux, then use the indexed assign to make
|
||||
* a calculated assign.
|
||||
*/
|
||||
static void assign_to_lvariable(ivl_lval_t lval, unsigned idx,
|
||||
unsigned bit, unsigned delay,
|
||||
int delay_in_index_flag)
|
||||
{
|
||||
ivl_signal_t sig = ivl_lval_sig(lval);
|
||||
unsigned part_off = ivl_lval_part_off(lval);
|
||||
|
||||
char *delay_suffix = delay_in_index_flag? "/d" : "";
|
||||
|
||||
if (ivl_lval_mux(lval))
|
||||
fprintf(vvp_out, " %%assign/x0%s V_%s, %u, %u;\n",
|
||||
delay_suffix, vvp_signal_label(sig), delay, bit);
|
||||
else
|
||||
fprintf(vvp_out, " %%assign%s V_%s[%u], %u, %u;\n",
|
||||
delay_suffix, vvp_signal_label(sig),
|
||||
idx+part_off, delay, bit);
|
||||
}
|
||||
|
||||
static void assign_to_lvector(ivl_lval_t lval, unsigned idx,
|
||||
unsigned bit, unsigned delay, unsigned width)
|
||||
static void assign_to_lvector(ivl_lval_t lval, unsigned bit,
|
||||
unsigned delay, ivl_expr_t dexp,
|
||||
unsigned width)
|
||||
{
|
||||
ivl_signal_t sig = ivl_lval_sig(lval);
|
||||
unsigned part_off = ivl_lval_part_off(lval);
|
||||
ivl_expr_t mux = ivl_lval_mux(lval);
|
||||
|
||||
assert(idx == 0);
|
||||
|
||||
if (mux != 0) {
|
||||
unsigned skip_assign = transient_id++;
|
||||
assert(dexp == 0);
|
||||
draw_eval_expr_into_integer(mux, 1);
|
||||
/* If the index expression has XZ bits, skip the assign. */
|
||||
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign);
|
||||
|
|
@ -171,12 +148,18 @@ static void assign_to_lvector(ivl_lval_t lval, unsigned idx,
|
|||
offset. Load that into index x1 and generate a
|
||||
single-bit set instruction. */
|
||||
assert(ivl_lval_width(lval) == width);
|
||||
assert(dexp == 0);
|
||||
|
||||
fprintf(vvp_out, " %%ix/load 0, %u;\n", width);
|
||||
fprintf(vvp_out, " %%ix/load 1, %u;\n", part_off);
|
||||
fprintf(vvp_out, " %%assign/v0/x1 V_%s, %u, %u;\n",
|
||||
vvp_signal_label(sig), delay, bit);
|
||||
|
||||
} else if (dexp != 0) {
|
||||
draw_eval_expr_into_integer(dexp, 1);
|
||||
fprintf(vvp_out, " %%ix/load 0, %u;\n", width);
|
||||
fprintf(vvp_out, " %%assign/v0/d V_%s, 1, %u;\n",
|
||||
vvp_signal_label(sig), bit);
|
||||
} else {
|
||||
fprintf(vvp_out, " %%ix/load 0, %u;\n", width);
|
||||
fprintf(vvp_out, " %%assign/v0 V_%s, %u, %u;\n",
|
||||
|
|
@ -223,11 +206,6 @@ static void draw_eval_expr_into_integer(ivl_expr_t expr, unsigned ix)
|
|||
}
|
||||
}
|
||||
|
||||
static void calculate_into_x0(ivl_expr_t expr)
|
||||
{
|
||||
draw_eval_expr_into_integer(expr, 0);
|
||||
}
|
||||
|
||||
static void calculate_into_x1(ivl_expr_t expr)
|
||||
{
|
||||
draw_eval_expr_into_integer(expr, 1);
|
||||
|
|
@ -463,7 +441,6 @@ static int show_stmt_assign_nb(ivl_statement_t net)
|
|||
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);
|
||||
|
||||
|
|
@ -477,54 +454,21 @@ static int show_stmt_assign_nb(ivl_statement_t net)
|
|||
if (bit_limit > ivl_lval_width(lval))
|
||||
bit_limit = ivl_lval_width(lval);
|
||||
|
||||
if ((mem == 0) && (del == 0)) {
|
||||
if (mem == 0) {
|
||||
|
||||
unsigned bidx = res.base < 4
|
||||
? res.base
|
||||
: (res.base+cur_rbit);
|
||||
assign_to_lvector(lval, 0, bidx, delay, bit_limit);
|
||||
assign_to_lvector(lval, bidx, delay, del, bit_limit);
|
||||
cur_rbit += bit_limit;
|
||||
|
||||
} else if (mem) {
|
||||
} else {
|
||||
assert(mem);
|
||||
/* XXXX don't yes know what to do with a delay
|
||||
in an index variable. */
|
||||
assert(del == 0);
|
||||
assign_to_memory_word(mem, res.base, delay, bit_limit);
|
||||
|
||||
} else {
|
||||
assert(!mem);
|
||||
/* XXXX This is obsolete, the
|
||||
assign_to_lvariable should be removed for the
|
||||
vector version. */
|
||||
|
||||
/* If there is a mux for the lval, calculate the
|
||||
value and write it into index0. */
|
||||
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;
|
||||
}
|
||||
|
||||
for (idx = 0 ; idx < bit_limit ; idx += 1) {
|
||||
unsigned bidx = res.base < 4
|
||||
? res.base
|
||||
: (res.base+cur_rbit);
|
||||
if (del != 0)
|
||||
assign_to_lvariable(lval, idx, bidx,
|
||||
1, 1);
|
||||
else
|
||||
assign_to_lvariable(lval, idx, bidx,
|
||||
delay, 0);
|
||||
|
||||
cur_rbit += 1;
|
||||
}
|
||||
|
||||
for (idx = bit_limit; idx < ivl_lval_width(lval); idx += 1)
|
||||
if (del != 0)
|
||||
assign_to_lvariable(lval, idx, 0, 1, 1);
|
||||
else
|
||||
assign_to_lvariable(lval, idx, 0, delay, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1515,6 +1459,9 @@ int draw_func_definition(ivl_scope_t scope)
|
|||
|
||||
/*
|
||||
* $Log: vvp_process.c,v $
|
||||
* Revision 1.112 2005/06/14 01:45:05 steve
|
||||
* Add the assign_v0_d instruction.
|
||||
*
|
||||
* Revision 1.111 2005/06/02 16:03:47 steve
|
||||
* Support %force/link
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: codes.h,v 1.73 2005/06/02 16:02:11 steve Exp $"
|
||||
#ident "$Id: codes.h,v 1.74 2005/06/14 01:44:09 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -44,6 +44,7 @@ extern bool of_ASSIGN_D(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_ASSIGN_MEM(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_MV(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_V0(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_V0D(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_V0X1(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_WR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_X0(vthread_t thr, vvp_code_t code);
|
||||
|
|
@ -174,6 +175,9 @@ extern vvp_code_t codespace_null(void);
|
|||
|
||||
/*
|
||||
* $Log: codes.h,v $
|
||||
* Revision 1.74 2005/06/14 01:44:09 steve
|
||||
* Add the assign_v0_d instruction.
|
||||
*
|
||||
* Revision 1.73 2005/06/02 16:02:11 steve
|
||||
* Add support for notif0/1 gates.
|
||||
* Make delay nodes support inertial delay.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: compile.cc,v 1.208 2005/06/14 00:42:06 steve Exp $"
|
||||
#ident "$Id: compile.cc,v 1.209 2005/06/14 01:44:09 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "arith.h"
|
||||
|
|
@ -87,10 +87,10 @@ const static struct opcode_table_s opcode_table[] = {
|
|||
{ "%addi", of_ADDI, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%and", of_AND, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%and/r", of_ANDR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%assign/d", of_ASSIGN_D, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%assign/m",of_ASSIGN_MEM,3,{OA_MEM_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%assign/mv",of_ASSIGN_MV,3,{OA_MEM_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%assign/v0",of_ASSIGN_V0,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%assign/v0/d",of_ASSIGN_V0D,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%assign/v0/x1",of_ASSIGN_V0X1,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
|
||||
{ "%assign/wr",of_ASSIGN_WR,3,{OA_VPI_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%assign/x0",of_ASSIGN_X0,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
|
||||
|
|
@ -1498,6 +1498,9 @@ void compile_param_string(char*label, char*name, char*str, char*value)
|
|||
|
||||
/*
|
||||
* $Log: compile.cc,v $
|
||||
* Revision 1.209 2005/06/14 01:44:09 steve
|
||||
* Add the assign_v0_d instruction.
|
||||
*
|
||||
* Revision 1.208 2005/06/14 00:42:06 steve
|
||||
* Accomodate fussy compilers.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2003 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* $Id: opcodes.txt,v 1.64 2005/05/17 20:54:00 steve Exp $
|
||||
* $Id: opcodes.txt,v 1.65 2005/06/14 01:44:10 steve Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -57,19 +57,6 @@ means the following:
|
|||
1 and 1 --> 1
|
||||
otherwise x
|
||||
|
||||
* %assign <var-label>, <delay>, <bit> (DEPRECATED -- use %assign/v0)
|
||||
* %assign/d <var-label>, <delay>, <bit> (DEPRECATED -- need %assign/v0/d)
|
||||
|
||||
This does a non-blocking assignment to a variable. The <label>
|
||||
identifies the affected variable, and the <delay> gives the delay when
|
||||
the assignment takes place. The delay may be 0. For blocking
|
||||
assignments, see %set. The <bit> is the address of the thread register
|
||||
that contains the bit value to assign.
|
||||
|
||||
The %assign/d instruction is exactly the same as the %assign
|
||||
instruction, except that the <delay> specifies one of the index
|
||||
registers, that contain a calculated delay.
|
||||
|
||||
* %assign/m <memory-label>, <delay>, <bit> (OBSOLETE)
|
||||
|
||||
This instruction does a non-blocking assignment to a bit in a memory
|
||||
|
|
@ -90,6 +77,7 @@ The address of the word in the memory is from index register 3. The
|
|||
address is cannonical form.
|
||||
|
||||
* %assign/v0 <var-label>, <delay>, <bit>
|
||||
* %assign/v0/d <var-label>, <delayx>, <bit>
|
||||
|
||||
The %assign/v0 instruction is a vector version of non-blocking
|
||||
assignment. The <delay> is the number of clock ticks in the future
|
||||
|
|
@ -97,6 +85,10 @@ where the assignment should be schedule, and the <bit> is the base of
|
|||
the vector to be assigned to the destination. The vector width is in
|
||||
index register 0.
|
||||
|
||||
The %assign/v0/d variation puts the delay instead into an integer
|
||||
register that is given by the <delayx> value. This should not be 0, of
|
||||
course, because integer 0 is taken with the vector width.
|
||||
|
||||
The <var-label> references a .var object that can receive non-blocking
|
||||
assignments. For blocking assignments, see %set/v.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.138 2005/06/12 01:25:27 steve Exp $"
|
||||
#ident "$Id: vthread.cc,v 1.139 2005/06/14 01:44:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
|
@ -542,18 +542,6 @@ bool of_ADDI(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool of_ASSIGN_D(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
#if 0
|
||||
assert(cp->bit_idx[0] < 4);
|
||||
unsigned char bit_val = thr_get_bit(thr, cp->bit_idx[1]);
|
||||
schedule_assign(cp->iptr, bit_val, thr->words[cp->bit_idx[0]].w_int);
|
||||
#else
|
||||
fprintf(stderr, "XXXX forgot how to implemented %%assign/d\n");
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is %assign/v0 <label>, <delay>, <bit>
|
||||
* Index register 0 contains a vector width.
|
||||
|
|
@ -574,6 +562,27 @@ bool of_ASSIGN_V0(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is %assign/v0/d <label>, <delay_idx>, <bit>
|
||||
* Index register 0 contains a vector width, and the named index
|
||||
* register contains the delay.
|
||||
*/
|
||||
bool of_ASSIGN_V0D(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned wid = thr->words[0].w_int;
|
||||
assert(wid > 0);
|
||||
|
||||
unsigned long delay = thr->words[cp->bit_idx[0]].w_int;
|
||||
unsigned bit = cp->bit_idx[1];
|
||||
|
||||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
|
||||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
schedule_assign_vector(ptr, value, delay);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is %assign/v0/x1 <label>, <delay>, <bit>
|
||||
* Index register 0 contains a vector part width.
|
||||
|
|
@ -3220,6 +3229,9 @@ bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
/*
|
||||
* $Log: vthread.cc,v $
|
||||
* Revision 1.139 2005/06/14 01:44:10 steve
|
||||
* Add the assign_v0_d instruction.
|
||||
*
|
||||
* Revision 1.138 2005/06/12 01:25:27 steve
|
||||
* Remove useless references to functor.h
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue