Add calculated delay, real valued, non-blocking assignments.

This patch add the ability to do a non-blocking assignment
for real values using a non-constant (calculated) delay.
This commit is contained in:
Cary R 2008-09-08 19:49:52 -07:00 committed by Stephen Williams
parent 3982781e97
commit 088c7f3feb
5 changed files with 41 additions and 10 deletions

View File

@ -531,7 +531,7 @@ static int show_stmt_assign_nb_real(ivl_statement_t net)
unsigned long use_word = 0; unsigned long use_word = 0;
/* thread address for a word value. */ /* thread address for a word value. */
int word; int word;
unsigned long delay; unsigned long delay = 0;
/* Must be exactly 1 l-value. */ /* Must be exactly 1 l-value. */
assert(ivl_stmt_lvals(net) == 1); 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); use_word = get_number_immediate(word_ix);
} }
delay = 0;
if (del && (ivl_expr_type(del) == IVL_EX_ULONG)) { if (del && (ivl_expr_type(del) == IVL_EX_ULONG)) {
delay = ivl_expr_uvalue(del); delay = ivl_expr_uvalue(del);
del = 0; del = 0;
} }
/* XXXX For now, presume delays are constant. */
assert(del == 0);
/* Evaluate the r-value */ /* Evaluate the r-value */
word = draw_eval_real(rval); word = draw_eval_real(rval);
/* 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", fprintf(vvp_out, " %%assign/wr v%p_%lu, %lu, %u;\n",
sig, use_word, delay, word); sig, use_word, delay, word);
}
clr_word(word); clr_word(word);

View File

@ -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_V0X1(vthread_t thr, vvp_code_t code);
extern bool of_ASSIGN_V0X1D(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_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_ASSIGN_X0(vthread_t thr, vvp_code_t code);
extern bool of_BLEND(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); extern bool of_BLEND_WR(vthread_t thr, vvp_code_t code);

View File

@ -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",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/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",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} }, { "%assign/x0",of_ASSIGN_X0,3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
{ "%blend", of_BLEND, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%blend", of_BLEND, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%blend/wr", of_BLEND_WR,2, {OA_BIT1, OA_BIT2, OA_NONE} }, { "%blend/wr", of_BLEND_WR,2, {OA_BIT1, OA_BIT2, OA_NONE} },

View File

@ -89,7 +89,7 @@ where the assignment should be schedule, and the <bit> is the base of
the vector to be assigned to the destination. The vector width is in the vector to be assigned to the destination. The vector width is in
index register 0. 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 <delayx> value. This should not be 0, of register that is given by the <delayx> value. This should not be 0, of
course, because integer 0 is taken with the vector width. 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. vector is to be written. This allows for part writes into the vector.
* %assign/wr <vpi-label>, <delay>, <index> * %assign/wr <vpi-label>, <delay>, <index>
* %assign/wr/d <vpi-label>, <delayx>, <index>
This instruction causes a non-blocking assign of the indexed value to This instruction provides a non-blocking assign of the real value
the real object addressed by the <vpi-label> label. given in <index> to the real object addressed by the <vpi-label>
label after the given <delay>.
The %assign/wr/d variation gets the delay from integer register
<delayx>.
* %assign/x0 <var-label>, <delay>, <bit> (OBSOLETE -- See %assign/v0x) * %assign/x0 <var-label>, <delay>, <bit> (OBSOLETE -- See %assign/v0x)

View File

@ -820,6 +820,25 @@ bool of_ASSIGN_WR(vthread_t thr, vvp_code_t cp)
return true; 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) bool of_ASSIGN_X0(vthread_t thr, vvp_code_t cp)
{ {
#if 0 #if 0