Implement assign/vec4/off/e
This commit is contained in:
parent
8bebe59e20
commit
9cfb15a302
|
|
@ -117,7 +117,7 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
|
|||
{
|
||||
unsigned skip_assign = transient_id++;
|
||||
int word_ix_reg = 3;
|
||||
int part_off_reg = 1;
|
||||
int part_off_reg = 0;
|
||||
int delay_index;
|
||||
unsigned long part_off = 0;
|
||||
|
||||
|
|
@ -138,7 +138,6 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
|
|||
|
||||
if (dexp != 0) {
|
||||
word_ix_reg = allocate_word();
|
||||
part_off_reg = allocate_word();
|
||||
} else if (part_off_ex) {
|
||||
word_ix_reg = allocate_word();
|
||||
}
|
||||
|
|
@ -148,11 +147,13 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
|
|||
fprintf(vvp_out, " %%flag_or %d, 4;\n", error_flag);
|
||||
|
||||
if (part_off_ex) {
|
||||
part_off_reg = allocate_word();
|
||||
draw_eval_expr_into_integer(part_off_ex, part_off_reg);
|
||||
fprintf(vvp_out, " %%flag_or %d, 4;\n", error_flag);
|
||||
|
||||
} else {
|
||||
} else if (part_off != 0) {
|
||||
/* Store word part select into part_off_reg */
|
||||
part_off_reg = allocate_word();
|
||||
fprintf(vvp_out, " %%ix/load %d, %lu, 0; part off\n",
|
||||
part_off_reg, part_off);
|
||||
}
|
||||
|
|
@ -161,19 +162,18 @@ 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);
|
||||
fprintf(vvp_out, " %%flag_mov 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);
|
||||
}
|
||||
fprintf(vvp_out, " %%assign/vec4/a/d v%p, %d, %d;\n",
|
||||
lsig, part_off_reg, delay_index);
|
||||
clr_word(part_off_reg);
|
||||
clr_word(delay_index);
|
||||
|
||||
} else if (nevents != 0) {
|
||||
/* Event control delay... */
|
||||
fprintf(vvp_out, " %%assign/vec4/a/e v%p, 0;\n", lsig);
|
||||
fprintf(vvp_out, " %%assign/vec4/a/e v%p, %d;\n", lsig, part_off_reg);
|
||||
|
||||
} else {
|
||||
/* Constant delay... */
|
||||
|
|
@ -196,6 +196,8 @@ static void assign_to_array_word(ivl_signal_t lsig, ivl_expr_t word_ix,
|
|||
if (nevents != 0) fprintf(vvp_out, " %%evctl/c;\n");
|
||||
|
||||
clr_flag(error_flag);
|
||||
if (part_off_reg)
|
||||
clr_word(part_off_reg);
|
||||
clear_expression_lookaside();
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +242,6 @@ static void assign_to_lvector(ivl_lval_t lval,
|
|||
// so in these cases we'll need to use
|
||||
// %assign/vec4/off/... variants.
|
||||
|
||||
unsigned skip_assign = transient_id++;
|
||||
if (dexp != 0) {
|
||||
/* Calculated offset... */
|
||||
int offset_index = allocate_word();
|
||||
|
|
@ -260,19 +261,15 @@ static void assign_to_lvector(ivl_lval_t lval,
|
|||
clr_word(delay_index);
|
||||
|
||||
} else if (nevents != 0) {
|
||||
int offset_index = allocate_word();
|
||||
/* Event control delay... */
|
||||
draw_eval_expr_into_integer(part_off_ex, 1);
|
||||
/* If the index expression has XZ bits, skip the assign. */
|
||||
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_assign);
|
||||
#if 0
|
||||
fprintf(vvp_out, " %%ix/load 0, %u, 0;\n", width);
|
||||
fprintf(vvp_out, " %%assign/v0/x1/e v%p_%lu, %u;\n",
|
||||
sig, use_word, bit);
|
||||
#else
|
||||
assert(0); // XXXX
|
||||
#endif
|
||||
fprintf(vvp_out, "t_%u ;\n", skip_assign);
|
||||
draw_eval_expr_into_integer(part_off_ex, offset_index);
|
||||
fprintf(vvp_out, " %%assign/vec4/off/e v%p_%lu, %d;\n",
|
||||
sig, use_word, offset_index);
|
||||
fprintf(vvp_out, " %%evctl/c;\n");
|
||||
|
||||
clr_word(offset_index);
|
||||
|
||||
} else {
|
||||
int offset_index = allocate_word();
|
||||
int delay_index = allocate_word();
|
||||
|
|
@ -338,7 +335,15 @@ static void assign_to_lvector(ivl_lval_t lval,
|
|||
}
|
||||
#else
|
||||
if (nevents != 0) {
|
||||
assert(0); // XXXX
|
||||
assert(dexp==0);
|
||||
int offset_index = allocate_word();
|
||||
fprintf(vvp_out, " %%ix/load %d, %lu, 0;\n",
|
||||
offset_index, part_off);
|
||||
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||
fprintf(vvp_out, " %%assign/vec4/off/e v%p_%lu, %d;\n",
|
||||
sig, use_word, offset_index);
|
||||
fprintf(vvp_out, " %%evctl/c;\n");
|
||||
clr_word(offset_index);
|
||||
|
||||
} else {
|
||||
// Constant part offset, non-constant (calculated)
|
||||
|
|
@ -372,6 +377,8 @@ static void assign_to_lvector(ivl_lval_t lval,
|
|||
/* Event control delay... */
|
||||
fprintf(vvp_out, " %%assign/vec4/e v%p_%lu;\n",
|
||||
sig, use_word);
|
||||
fprintf(vvp_out, " %%evctl/c;\n");
|
||||
|
||||
} else {
|
||||
/*
|
||||
* The %assign can only take a 32 bit delay. For a larger
|
||||
|
|
|
|||
|
|
@ -44,14 +44,15 @@ extern bool of_ASSIGN_ARD(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_ASSIGN_ARE(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_AVE(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_VEC4(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_VEC4D(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_VEC4E(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_VEC4_A_D(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_VEC4_A_E(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_VEC4_OFF_D(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_VEC4_OFF_E(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_V0X1(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_V0X1D(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_ASSIGN_V0X1E(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -97,15 +97,16 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%assign/ar/e",of_ASSIGN_ARE,1,{OA_ARR_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%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/av/e",of_ASSIGN_AVE,2,{OA_ARR_PTR,OA_BIT1, OA_NONE} },
|
||||
{ "%assign/v0/x1",of_ASSIGN_V0X1,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
|
||||
{ "%assign/v0/x1/d",of_ASSIGN_V0X1D,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
|
||||
{ "%assign/v0/x1/e",of_ASSIGN_V0X1E,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} },
|
||||
{ "%assign/vec4", of_ASSIGN_VEC4, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%assign/vec4/a/d", of_ASSIGN_VEC4_A_D, 3, {OA_ARR_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%assign/vec4/a/e", of_ASSIGN_VEC4_A_E, 2, {OA_ARR_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%assign/vec4/d", of_ASSIGN_VEC4D, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%assign/vec4/e", of_ASSIGN_VEC4E, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%assign/vec4/off/d",of_ASSIGN_VEC4_OFF_D, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%assign/vec4/off/e",of_ASSIGN_VEC4_OFF_E, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%assign/wr", of_ASSIGN_WR, 2,{OA_VPI_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%assign/wr/d",of_ASSIGN_WRD,2,{OA_VPI_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%assign/wr/e",of_ASSIGN_WRE,1,{OA_VPI_PTR, OA_NONE, OA_NONE} },
|
||||
|
|
|
|||
127
vvp/vthread.cc
127
vvp/vthread.cc
|
|
@ -1168,6 +1168,7 @@ bool of_ASSIGN_AVD(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool of_ASSIGN_AVE(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned wid = thr->words[0].w_int;
|
||||
|
|
@ -1194,7 +1195,6 @@ bool of_ASSIGN_AVE(vthread_t thr, vvp_code_t cp)
|
|||
|
||||
assert(wid > 0);
|
||||
|
||||
#if 0
|
||||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
// If the count is zero then just put the value.
|
||||
if (thr->ecount == 0) {
|
||||
|
|
@ -1202,12 +1202,10 @@ bool of_ASSIGN_AVE(vthread_t thr, vvp_code_t cp)
|
|||
} else {
|
||||
schedule_evctl(cp->array, adr, value, off, thr->event, thr->ecount);
|
||||
}
|
||||
#else
|
||||
fprintf(stderr, "XXXX NOT IMPLEMENTED: %%assign/av/e ...\n");
|
||||
assert(0);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*
|
||||
|
|
@ -1261,14 +1259,82 @@ bool of_ASSIGN_VEC4_A_D(vthread_t thr, vvp_code_t cp)
|
|||
vvp_time64_t del = del_idx? thr->words[del_idx].w_uint : 0;
|
||||
long adr = thr->words[adr_idx].w_int;
|
||||
|
||||
vvp_vector4_t value = thr->pop_vec4();
|
||||
vvp_vector4_t val = thr->pop_vec4();
|
||||
unsigned wid = val.size();
|
||||
const unsigned array_wid = get_array_word_size(cp->array);
|
||||
|
||||
// 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);
|
||||
if (off >= (long)array_wid)
|
||||
return true;
|
||||
if (off < 0) {
|
||||
if ((unsigned)-off >= array_wid)
|
||||
return true;
|
||||
|
||||
int use_off = -off;
|
||||
assert(wid > use_off);
|
||||
unsigned use_wid = wid - use_off;
|
||||
val = val.subvalue(use_off, use_wid);
|
||||
off = 0;
|
||||
wid = use_wid;
|
||||
}
|
||||
if (off+wid > array_wid) {
|
||||
val = val.subvalue(0, array_wid-off);
|
||||
wid = val.size();
|
||||
}
|
||||
|
||||
schedule_assign_array_word(cp->array, adr, off, val, del);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %assign/vec4/a/e <arr>, <offx>
|
||||
*/
|
||||
bool of_ASSIGN_VEC4_A_E(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
int off_idx = cp->bit_idx[0];
|
||||
int adr_idx = 3;
|
||||
|
||||
long off = off_idx? thr->words[off_idx].w_int : 0;
|
||||
long adr = thr->words[adr_idx].w_int;
|
||||
|
||||
vvp_vector4_t val = thr->pop_vec4();
|
||||
unsigned wid = val.size();
|
||||
const unsigned array_wid = get_array_word_size(cp->array);
|
||||
|
||||
// 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;
|
||||
|
||||
if (off >= (long)array_wid)
|
||||
return true;
|
||||
if (off < 0) {
|
||||
if ((unsigned)-off >= array_wid)
|
||||
return true;
|
||||
|
||||
int use_off = -off;
|
||||
assert(wid > (unsigned)use_off);
|
||||
unsigned use_wid = wid - use_off;
|
||||
val = val.subvalue(use_off, use_wid);
|
||||
off = 0;
|
||||
wid = use_wid;
|
||||
}
|
||||
if (off+wid > array_wid) {
|
||||
val = val.subvalue(0, array_wid-off);
|
||||
wid = val.size();
|
||||
}
|
||||
|
||||
if (thr->ecount == 0) {
|
||||
schedule_assign_array_word(cp->array, adr, off, val, 0);
|
||||
} else {
|
||||
schedule_evctl(cp->array, adr, val, off, thr->event, thr->ecount);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1309,6 +1375,53 @@ bool of_ASSIGN_VEC4_OFF_D(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %assign/vec4/off/e <var>, <off>
|
||||
*/
|
||||
bool of_ASSIGN_VEC4_OFF_E(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
unsigned off_index = cp->bit_idx[0];
|
||||
vvp_vector4_t val = thr->pop_vec4();
|
||||
unsigned wid = val.size();
|
||||
|
||||
int off = thr->words[off_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);
|
||||
|
||||
if (off >= (long)sig->value_size())
|
||||
return true;
|
||||
if (off < 0) {
|
||||
if ((unsigned)-off >= sig->value_size())
|
||||
return true;
|
||||
|
||||
int use_off = -off;
|
||||
assert(wid > use_off);
|
||||
unsigned use_wid = wid - use_off;
|
||||
val = val.subvalue(use_off, use_wid);
|
||||
off = 0;
|
||||
wid = use_wid;
|
||||
}
|
||||
if (off+wid > sig->value_size()) {
|
||||
val = val.subvalue(0, sig->value_size()-off);
|
||||
wid = val.size();
|
||||
}
|
||||
|
||||
if (thr->ecount == 0) {
|
||||
schedule_assign_vector(ptr, off, sig->value_size(), val, 0);
|
||||
} else {
|
||||
schedule_evctl(ptr, val, off, sig->value_size(), thr->event, thr->ecount);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This is %assign/v0/d <label>, <delay_idx>, <bit>
|
||||
|
|
|
|||
Loading…
Reference in New Issue