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:
parent
3982781e97
commit
088c7f3feb
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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} },
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue