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))) {
draw_eval_expr_into_integer(ix, 3);
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);
} else {
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,
unsigned bit, unsigned delay, unsigned width)
unsigned bit, unsigned delay, ivl_expr_t dexp,
unsigned width)
{
unsigned skip_assign = transient_id++;
/* 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);
if (dexp == 0) {
/* Constant delay... */
/* 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");
/* 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 v%p, %u, %u;\n", lsig, delay, bit);
fprintf(vvp_out, "t_%u ;\n", skip_assign);
fprintf(vvp_out, " %%assign/av v%p, %u, %u;\n", lsig,
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();
}
@ -218,8 +240,7 @@ static void assign_to_lvector(ivl_lval_t lval, unsigned bit,
if (ivl_signal_array_count(sig) > 1) {
assert(word_ix);
if (! number_is_immediate(word_ix, 8*sizeof(use_word))) {
assert(!dexp);
assign_to_array_word(sig, word_ix, bit, delay, width);
assign_to_array_word(sig, word_ix, bit, delay, dexp, width);
return;
}
@ -280,7 +301,7 @@ static void assign_to_lvector(ivl_lval_t lval, unsigned bit,
draw_eval_expr_into_integer(dexp, delay_index);
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/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);
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_ANDR(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_MV(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/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/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/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} },

View File

@ -57,6 +57,7 @@ means the following:
otherwise x
* %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
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
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)
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;
}
/* %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>
* Index register 0 contains a vector width.