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;
/* 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);

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_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);

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/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} },

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
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
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 <vpi-label>, <delay>, <index>
* %assign/wr/d <vpi-label>, <delayx>, <index>
This instruction causes a non-blocking assign of the indexed value to
the real object addressed by the <vpi-label> label.
This instruction provides a non-blocking assign of the real value
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)

View File

@ -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