diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 6147b5225..861ce2232 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -531,7 +531,7 @@ static int show_stmt_assign_nb_real(ivl_statement_t net) unsigned long use_word = 0; /* thread address for a word value. */ int word; - unsigned long delay; + unsigned long delay = 0; /* Must be exactly 1 l-value. */ assert(ivl_stmt_lvals(net) == 1); @@ -547,20 +547,25 @@ static int show_stmt_assign_nb_real(ivl_statement_t net) use_word = get_number_immediate(word_ix); } - delay = 0; if (del && (ivl_expr_type(del) == IVL_EX_ULONG)) { delay = ivl_expr_uvalue(del); del = 0; } - /* XXXX For now, presume delays are constant. */ - assert(del == 0); - /* Evaluate the r-value */ word = draw_eval_real(rval); - fprintf(vvp_out, " %%assign/wr v%p_%lu, %lu, %u;\n", - sig, use_word, delay, word); + /* We need to calculate the delay expression. */ + if (del) { + int delay_index = allocate_word(); + draw_eval_expr_into_integer(del, delay_index); + fprintf(vvp_out, " %%assign/wr/d v%p_%lu, %d, %u;\n", + sig, use_word, delay_index, word); + clr_word(delay_index); + } else { + fprintf(vvp_out, " %%assign/wr v%p_%lu, %lu, %u;\n", + sig, use_word, delay, word); + } clr_word(word); diff --git a/vvp/codes.h b/vvp/codes.h index 6fe3f2489..3a803b5e6 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -48,6 +48,7 @@ extern bool of_ASSIGN_V0D(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_WR(vthread_t thr, vvp_code_t code); +extern bool of_ASSIGN_WRD(vthread_t thr, vvp_code_t code); extern bool of_ASSIGN_X0(vthread_t thr, vvp_code_t code); extern bool of_BLEND(vthread_t thr, vvp_code_t code); extern bool of_BLEND_WR(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index 09cdbaeee..bdf8d9262 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -93,6 +93,7 @@ const static struct opcode_table_s opcode_table[] = { { "%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/wr",of_ASSIGN_WR,3,{OA_VPI_PTR,OA_BIT1, OA_BIT2} }, + { "%assign/wr/d",of_ASSIGN_WRD,3,{OA_VPI_PTR,OA_BIT1, OA_BIT2} }, { "%assign/x0",of_ASSIGN_X0,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} }, { "%blend", of_BLEND, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%blend/wr", of_BLEND_WR,2, {OA_BIT1, OA_BIT2, OA_NONE} }, diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index 56652e713..556c0cb27 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -89,7 +89,7 @@ where the assignment should be schedule, and the is the base of the vector to be assigned to the destination. The vector width is in index register 0. -The %assign/v0/d variation puts the delay instead into an integer +The %assign/v0/d variation gets the delay instead from an integer register that is given by the value. This should not be 0, of course, because integer 0 is taken with the vector width. @@ -104,9 +104,14 @@ index register with the canonical index of the destination where the vector is to be written. This allows for part writes into the vector. * %assign/wr , , +* %assign/wr/d , , -This instruction causes a non-blocking assign of the indexed value to -the real object addressed by the label. +This instruction provides a non-blocking assign of the real value +given in to the real object addressed by the +label after the given . + +The %assign/wr/d variation gets the delay from integer register +. * %assign/x0 , , (OBSOLETE -- See %assign/v0x) diff --git a/vvp/vthread.cc b/vvp/vthread.cc index f467bf468..d2fbb9650 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -820,6 +820,25 @@ bool of_ASSIGN_WR(vthread_t thr, vvp_code_t cp) return true; } +bool of_ASSIGN_WRD(vthread_t thr, vvp_code_t cp) +{ + unsigned delay = thr->words[cp->bit_idx[0]].w_int; + unsigned index = cp->bit_idx[1]; + s_vpi_time del; + + del.type = vpiSimTime; + vpip_time_to_timestruct(&del, delay); + + struct __vpiHandle*tmp = cp->handle; + + t_vpi_value val; + val.format = vpiRealVal; + val.value.real = thr->words[index].w_real; + vpi_put_value(tmp, &val, &del, vpiInertialDelay); + + return true; +} + bool of_ASSIGN_X0(vthread_t thr, vvp_code_t cp) { #if 0