Cleanup vec4 handling of suppressed store/assign due to bad offset/index math.
This commit is contained in:
parent
c6c697bdb7
commit
d8533104b0
|
|
@ -578,10 +578,14 @@ static void store_vec4_to_lval(ivl_statement_t net)
|
|||
int part_index = 0;
|
||||
/* Calculate the word address into word_index */
|
||||
draw_eval_expr_into_integer(word_ex, word_index);
|
||||
/* If there is a part_offset, calcualte it into part_index. */
|
||||
/* If there is a part_offset, calculate it into part_index. */
|
||||
if (part_off_ex) {
|
||||
int flag_index = allocate_flag();
|
||||
part_index = allocate_word();
|
||||
fprintf(vvp_out, " %%flag_mov %d, 4;\n", flag_index);
|
||||
draw_eval_expr_into_integer(part_off_ex, part_index);
|
||||
fprintf(vvp_out, " %%flag_or 4, %d;\n", flag_index);
|
||||
clr_flag(flag_index);
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%store/vec4a v%p, %d, %d;\n",
|
||||
|
|
@ -595,6 +599,7 @@ static void store_vec4_to_lval(ivl_statement_t net)
|
|||
/* Dynamically calculated part offset */
|
||||
int offset_index = allocate_word();
|
||||
draw_eval_expr_into_integer(part_off_ex, offset_index);
|
||||
/* Note that flag4 is set by the eval above. */
|
||||
fprintf(vvp_out, " %%store/vec4 v%p_0, %d, %u;\n",
|
||||
lsig, offset_index, lwid);
|
||||
clr_word(offset_index);
|
||||
|
|
|
|||
|
|
@ -121,6 +121,9 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
|
|||
int delay_index;
|
||||
unsigned long part_off = 0;
|
||||
|
||||
int error_flag = allocate_flag();
|
||||
fprintf(vvp_out, " %%flag_set/imm %d, 0;\n", error_flag);
|
||||
|
||||
/* Figure the constant part offset, if possible. If we can do
|
||||
so, then forget about the expression and use the calculated
|
||||
value. After this block, if the part_off_ex!=0, then the
|
||||
|
|
@ -142,13 +145,11 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
|
|||
|
||||
/* Calculate array word index into word index register */
|
||||
draw_eval_expr_into_integer(word_ix, word_ix_reg);
|
||||
/* Skip assignment if word expression is not defined. */
|
||||
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign);
|
||||
fprintf(vvp_out, " %%flag_or %d, 4;\n", error_flag);
|
||||
|
||||
if (part_off_ex) {
|
||||
draw_eval_expr_into_integer(part_off_ex, part_off_reg);
|
||||
/* If the index expression has XZ bits, skip the assign. */
|
||||
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign);
|
||||
fprintf(vvp_out, " %%flag_or %d, 4;\n", error_flag);
|
||||
|
||||
} else {
|
||||
/* Store word part select into part_off_reg */
|
||||
|
|
@ -160,6 +161,7 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
|
|||
/* Calculated delay... */
|
||||
delay_index = allocate_word();
|
||||
draw_eval_expr_into_integer(dexp, delay_index);
|
||||
fprintf(vvp_out, " %%flag_or 4, %d;\n", error_flag);
|
||||
if (word_ix_reg != 3) {
|
||||
fprintf(vvp_out, " %%ix/mov 3, %u;\n", word_ix_reg);
|
||||
clr_word(word_ix_reg);
|
||||
|
|
@ -193,6 +195,7 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
|
|||
fprintf(vvp_out, "t_%u ;\n", skip_assign);
|
||||
if (nevents != 0) fprintf(vvp_out, " %%evctl/c;\n");
|
||||
|
||||
clr_flag(error_flag);
|
||||
clear_expression_lookaside();
|
||||
}
|
||||
|
||||
|
|
@ -275,15 +278,16 @@ static void assign_to_lvector(ivl_lval_t lval,
|
|||
/* Constant delay... */
|
||||
fprintf(vvp_out, " %%ix/load %d, %lu, %lu;\n",
|
||||
delay_index, low_d, hig_d);
|
||||
/* Calculated part offset... */
|
||||
/* Calculated part offset. This will leave flag
|
||||
bit 4 set to 1 if the copy into the index
|
||||
detected xz values. The %assign will use that
|
||||
to know to skip the assign. */
|
||||
draw_eval_expr_into_integer(part_off_ex, offset_index);
|
||||
/* If the index expression has XZ bits, skip the assign. */
|
||||
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign);
|
||||
fprintf(vvp_out, " %%assign/vec4/off/d v%p_%lu, %d, %d;\n",
|
||||
sig, use_word, offset_index, delay_index);
|
||||
clr_word(offset_index);
|
||||
clr_word(delay_index);
|
||||
fprintf(vvp_out, "t_%u ;\n", skip_assign);
|
||||
}
|
||||
|
||||
} else if (part_off>0 || ivl_lval_width(lval)!=ivl_signal_width(sig)) {
|
||||
|
|
@ -344,11 +348,13 @@ static void assign_to_lvector(ivl_lval_t lval,
|
|||
int offset_index = allocate_word();
|
||||
int delay_index = allocate_word();
|
||||
fprintf(vvp_out, " %%ix/load %d, %lu, 0;\n", offset_index, part_off);
|
||||
if (dexp)
|
||||
if (dexp) {
|
||||
draw_eval_expr_into_integer(dexp,delay_index);
|
||||
else
|
||||
} else {
|
||||
fprintf(vvp_out, " %%ix/load %d, %lu, %lu;\n",
|
||||
delay_index, low_d, hig_d);
|
||||
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||
}
|
||||
fprintf(vvp_out, " %%assign/vec4/off/d v%p_%lu, %d, %d;\n",
|
||||
sig, use_word, offset_index, delay_index);
|
||||
clr_word(offset_index);
|
||||
|
|
|
|||
|
|
@ -108,6 +108,8 @@ extern bool of_EVCTLI(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_EVCTLS(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_FILE_LINE(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_FLAG_GET_VEC4(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_FLAG_MOV(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_FLAG_OR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_FLAG_SET_IMM(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_FLAG_SET_VEC4(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_FORCE_LINK(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -157,6 +157,8 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%evctl/s",of_EVCTLS, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%event", of_EVENT, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%flag_get/vec4", of_FLAG_GET_VEC4, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%flag_mov", of_FLAG_MOV, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
{ "%flag_or", of_FLAG_OR, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
{ "%flag_set/imm", of_FLAG_SET_IMM, 2, {OA_NUMBER, OA_BIT1, OA_NONE} },
|
||||
{ "%flag_set/vec4", of_FLAG_SET_VEC4, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%force/link", of_FORCE_LINK,2,{OA_FUNC_PTR, OA_FUNC_PTR2, OA_NONE} },
|
||||
|
|
|
|||
|
|
@ -199,6 +199,10 @@ contains the word address.
|
|||
The <off-index> and <delay-index> index registers can be 0, which
|
||||
means a zero value instead of the contents of index register 0.
|
||||
|
||||
If flag bit 4 is set, then the value will be popped from the stack,
|
||||
but it will not be assigned. This handles the case that the index
|
||||
values is undefined.
|
||||
|
||||
* %assign/vec4/off/d <var-label>, <off-index>, <delay-index>
|
||||
|
||||
This is for writing parts to the target variable. The <var-label> is
|
||||
|
|
@ -208,6 +212,9 @@ register that holds the offset into the target variable, and the
|
|||
offset is in canonical bits. The width that is written is taken from
|
||||
the width of the value on the stack.
|
||||
|
||||
The actual assignment is suppressed if flags-4 is 1. This is so that
|
||||
calculations of offset can set the flag on errors.
|
||||
|
||||
* %assign/wr <vpi-label>, <delay>
|
||||
* %assign/wr/d <vpi-label>, <delayx>
|
||||
* %assign/wr/e <vpi-label>
|
||||
|
|
@ -543,6 +550,15 @@ the format of the output is:
|
|||
<description> is a string, if string is 0 then the following default
|
||||
message is used: "Procedural tracing.".
|
||||
|
||||
* %flag_mov <flag1>, <flag2>
|
||||
|
||||
This instruction copies the flag bit from <flag2> to <flag1>.
|
||||
|
||||
* %flag_or <flag1>, <flag2>
|
||||
|
||||
This instruction calculates the verilog OR of the flag bits in <flag1>
|
||||
and <flag2>, and leaves the result in <flag1>.
|
||||
|
||||
* %flag_set/imm <flag>, <value>
|
||||
|
||||
This instruction sets an immediate value into a flag bit. This is a
|
||||
|
|
@ -625,7 +641,7 @@ bits.
|
|||
* %ix/getv <idx>, <functor-label>
|
||||
* %ix/getv/s <idx>, <functor-label>
|
||||
|
||||
These instructions are like the %ix/get instructions, except that they
|
||||
These instructions are like the %ix/vec4 instructions, except that they
|
||||
read directly from a functor label instead of from thread bits. They
|
||||
set bit 4 just like %ix/get.
|
||||
|
||||
|
|
@ -1245,6 +1261,14 @@ offset.
|
|||
Both index registers can be 0, to mean a zero value instead of a zero
|
||||
register.
|
||||
|
||||
The %store/vec4a will check flag bit 4, and if it is true, it will
|
||||
suppress the actual assignment. This is so that the context can
|
||||
indicate that the address is invalid.
|
||||
|
||||
The %store/vec4 will check flag bit 4, only if the <offset> is a
|
||||
non-zero index register. A 0 index is a fixed constant and cannot
|
||||
fail.
|
||||
|
||||
NOTE: The <wid> is not necessary, and should be removed.
|
||||
|
||||
* %sub <bit-l>, <bit-r>, <wid> (XXXX Old version)
|
||||
|
|
|
|||
|
|
@ -1263,6 +1263,11 @@ bool of_ASSIGN_VEC4_A_D(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
vvp_vector4_t value = thr->pop_vec4();
|
||||
|
||||
// Abort if flags[4] is set. This can happen if the calulation
|
||||
// into an index register failed.
|
||||
if (thr->flags[4] == BIT4_1)
|
||||
return true;
|
||||
|
||||
schedule_assign_array_word(cp->array, adr, off, value, del);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1280,6 +1285,11 @@ bool of_ASSIGN_VEC4_OFF_D(vthread_t thr, vvp_code_t cp)
|
|||
int off = thr->words[off_index].w_int;
|
||||
int del = thr->words[del_index].w_int;
|
||||
|
||||
// Abort if flags[4] is set. This can happen if the calulation
|
||||
// into an index register failed.
|
||||
if (thr->flags[4] == BIT4_1)
|
||||
return true;
|
||||
|
||||
vvp_signal_value*sig = dynamic_cast<vvp_signal_value*> (cp->net->fil);
|
||||
assert(sig);
|
||||
|
||||
|
|
@ -2937,6 +2947,30 @@ bool of_FLAG_GET_VEC4(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %flag_mov <flag1>, <flag2)
|
||||
*/
|
||||
bool of_FLAG_MOV(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
int flag1 = cp->bit_idx[0];
|
||||
int flag2 = cp->bit_idx[1];
|
||||
|
||||
thr->flags[flag1] = thr->flags[flag2];
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %flag_or <flag1>, <flag2>
|
||||
*/
|
||||
bool of_FLAG_OR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
int flag1 = cp->bit_idx[0];
|
||||
int flag2 = cp->bit_idx[1];
|
||||
|
||||
thr->flags[flag1] = thr->flags[flag1] | thr->flags[flag2];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_FLAG_SET_IMM(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
int flag = cp->number;
|
||||
|
|
@ -5836,6 +5870,11 @@ bool of_STORE_VEC4(vthread_t thr, vvp_code_t cp)
|
|||
if (val.size() > wid)
|
||||
val.resize(wid);
|
||||
|
||||
// If there is a problem loading the index register, flags-4
|
||||
// will be set to 1, and we know here to skip the actual assignment.
|
||||
if (off_index!=0 && thr->flags[4] == BIT4_1)
|
||||
return true;
|
||||
|
||||
if (off==0 && val.size()==sig->value_size())
|
||||
vvp_send_vec4(ptr, val, thr->wt_context);
|
||||
else
|
||||
|
|
@ -5857,6 +5896,10 @@ bool of_STORE_VEC4A(vthread_t thr, vvp_code_t cp)
|
|||
long adr = adr_index? thr->words[adr_index].w_int : 0;
|
||||
long off = off_index? thr->words[off_index].w_int : 0;
|
||||
|
||||
// Suppress action if flags-4 is true.
|
||||
if (thr->flags[4] == BIT4_1)
|
||||
return true;
|
||||
|
||||
array_set_word(cp->array, adr, off, value);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue