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:
parent
8cece424d1
commit
2be8534021
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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} },
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue