Add %assign/av/d opcode.

This patch adds a %assign/av/d opcode. This is a version of %assign/av
that allows a delay expression. Ultimately this allows a dynamically
indexed array to have a delay expression (non-constant delay value).
This commit is contained in:
Cary R 2008-04-07 15:20:16 -07:00 committed by Stephen Williams
parent 8cece424d1
commit 2be8534021
6 changed files with 67 additions and 15 deletions

View File

@ -1751,7 +1751,7 @@ static void draw_signal_dest(ivl_expr_t exp, struct vector_info res,
if (!number_is_immediate(ix, 8*sizeof(unsigned long))) { if (!number_is_immediate(ix, 8*sizeof(unsigned long))) {
draw_eval_expr_into_integer(ix, 3); draw_eval_expr_into_integer(ix, 3);
if (add_index < 0) { if (add_index < 0) {
fprintf(vvp_out, " %%load/av %u, v%p, %u;\n", fprintf(vvp_out, " %%load/av %u, v%p, %u;\n",
res.base, sig, swid); res.base, sig, swid);
} else { } else {
assert(add_index == 0); assert(add_index == 0);

View File

@ -184,22 +184,44 @@ static void set_to_lvariable(ivl_lval_t lval,
} }
static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix, static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
unsigned bit, unsigned delay, unsigned width) unsigned bit, unsigned delay, ivl_expr_t dexp,
unsigned width)
{ {
unsigned skip_assign = transient_id++; unsigned skip_assign = transient_id++;
/* Calculate array word index into index register 3 */ if (dexp == 0) {
draw_eval_expr_into_integer(word_ix, 3); /* Constant delay... */
/* Skip assignment if word expression is not defined. */ /* Calculate array word index into index register 3 */
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign); draw_eval_expr_into_integer(word_ix, 3);
/* Skip assignment if word expression is not defined. */
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign);
/* Store expression width into index word 0 */ /* Store expression width into index word 0 */
fprintf(vvp_out, " %%ix/load 0, %u; // word width\n", width); fprintf(vvp_out, " %%ix/load 0, %u; // word width\n", width);
/* Store constant (0) word part select into index 1 */ /* Store constant (0) word part select into index 1 */
fprintf(vvp_out, " %%ix/load 1, 0;\n"); fprintf(vvp_out, " %%ix/load 1, 0;\n");
fprintf(vvp_out, " %%assign/av v%p, %u, %u;\n", lsig, delay, bit); fprintf(vvp_out, " %%assign/av v%p, %u, %u;\n", lsig,
fprintf(vvp_out, "t_%u ;\n", skip_assign); delay, bit);
fprintf(vvp_out, "t_%u ;\n", skip_assign);
} else {
/* Calculated delay... */
int delay_index = allocate_word();
draw_eval_expr_into_integer(dexp, delay_index);
/* Calculate array word index into index register 3 */
draw_eval_expr_into_integer(word_ix, 3);
/* Skip assignment if word expression is not defined. */
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign);
/* Store expression width into index word 0 */
fprintf(vvp_out, " %%ix/load 0, %u; // word width\n", width);
/* Store constant (0) word part select into index 1 */
fprintf(vvp_out, " %%ix/load 1, 0;\n");
fprintf(vvp_out, " %%assign/av/d v%p, %d, %u;\n", lsig,
delay_index, bit);
fprintf(vvp_out, "t_%u ;\n", skip_assign);
}
clear_expression_lookaside(); clear_expression_lookaside();
} }
@ -218,8 +240,7 @@ static void assign_to_lvector(ivl_lval_t lval, unsigned bit,
if (ivl_signal_array_count(sig) > 1) { if (ivl_signal_array_count(sig) > 1) {
assert(word_ix); assert(word_ix);
if (! number_is_immediate(word_ix, 8*sizeof(use_word))) { if (! number_is_immediate(word_ix, 8*sizeof(use_word))) {
assert(!dexp); assign_to_array_word(sig, word_ix, bit, delay, dexp, width);
assign_to_array_word(sig, word_ix, bit, delay, width);
return; return;
} }
@ -280,7 +301,7 @@ static void assign_to_lvector(ivl_lval_t lval, unsigned bit,
draw_eval_expr_into_integer(dexp, delay_index); draw_eval_expr_into_integer(dexp, delay_index);
fprintf(vvp_out, " %%ix/load 0, %u;\n", width); fprintf(vvp_out, " %%ix/load 0, %u;\n", width);
fprintf(vvp_out, " %%ix/load 1, %u;\n", part_off); fprintf(vvp_out, " %%ix/load 1, %u;\n", part_off);
fprintf(vvp_out, " %%assign/v0/x1/d v%p_%lu, %u, %u;\n", fprintf(vvp_out, " %%assign/v0/x1/d v%p_%lu, %d, %u;\n",
sig, use_word, delay_index, bit); sig, use_word, delay_index, bit);
clr_word(delay_index); clr_word(delay_index);
} }

View File

@ -38,6 +38,7 @@ extern bool of_ADDI(vthread_t thr, vvp_code_t code);
extern bool of_AND(vthread_t thr, vvp_code_t code); extern bool of_AND(vthread_t thr, vvp_code_t code);
extern bool of_ANDR(vthread_t thr, vvp_code_t code); extern bool of_ANDR(vthread_t thr, vvp_code_t code);
extern bool of_ASSIGN_AV(vthread_t thr, vvp_code_t code); extern bool of_ASSIGN_AV(vthread_t thr, vvp_code_t code);
extern bool of_ASSIGN_AVD(vthread_t thr, vvp_code_t code);
extern bool of_ASSIGN_D(vthread_t thr, vvp_code_t code); extern bool of_ASSIGN_D(vthread_t thr, vvp_code_t code);
extern bool of_ASSIGN_MV(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_V0(vthread_t thr, vvp_code_t code);

View File

@ -88,6 +88,7 @@ const static struct opcode_table_s opcode_table[] = {
{ "%and", of_AND, 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} }, { "%and/r", of_ANDR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%assign/av",of_ASSIGN_AV,3,{OA_ARR_PTR,OA_BIT1, OA_BIT2} }, { "%assign/av",of_ASSIGN_AV,3,{OA_ARR_PTR,OA_BIT1, OA_BIT2} },
{ "%assign/av/d",of_ASSIGN_AVD,3,{OA_ARR_PTR,OA_BIT1, OA_BIT2} },
{ "%assign/mv",of_ASSIGN_MV,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",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/d",of_ASSIGN_V0D,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },

View File

@ -57,6 +57,7 @@ means the following:
otherwise x otherwise x
* %assign/av <array-label>, <delay>, <bit> * %assign/av <array-label>, <delay>, <bit>
* %assign/av/d <array-label>, <delayx>, <bit>
The %assign/av instruction assigns a vector value to a word in the The %assign/av instruction assigns a vector value to a word in the
labeled array. The <delay> is the delay in simulation time to the labeled array. The <delay> is the delay in simulation time to the
@ -70,6 +71,11 @@ The base of a part select is retrieved from index register 1.
The address of the word in the memory is from index register 3. The The address of the word in the memory is from index register 3. The
address is canonical form. address is canonical form.
The %assign/av/d variation reads the delay from an integer register that
is given by the <delayx> value. This should not be 0, 1 or 3, of course,
since these registers contain the vector width, base part select and
word address.
* %assign/mv <memory-label>, <delay>, <bit> (DEPRECATED) * %assign/mv <memory-label>, <delay>, <bit> (DEPRECATED)
the %assign/mv instruction assigns a vector value to a word in the the %assign/mv instruction assigns a vector value to a word in the

View File

@ -564,6 +564,29 @@ bool of_ASSIGN_AV(vthread_t thr, vvp_code_t cp)
return true; return true;
} }
/* %assign/av/d <array>, <delay_idx>, <bit>
* This generates an assignment event to an array. Index register 0
* contains the width of the vector (and the word) and index register
* 3 contains the canonical address of the word in memory. The named
* index register contains the delay.
*/
bool of_ASSIGN_AVD(vthread_t thr, vvp_code_t cp)
{
unsigned wid = thr->words[0].w_int;
unsigned off = thr->words[1].w_int;
unsigned adr = thr->words[3].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);
schedule_assign_array_word(cp->array, adr, off, value, delay);
return true;
}
/* /*
* This is %assign/v0 <label>, <delay>, <bit> * This is %assign/v0 <label>, <delay>, <bit>
* Index register 0 contains a vector width. * Index register 0 contains a vector width.