Generate code to implement new element initializers.

This commit is contained in:
Stephen Williams 2013-10-18 18:32:56 -07:00
parent 3945b9df45
commit 82ebf6372c
8 changed files with 101 additions and 5 deletions

View File

@ -302,6 +302,8 @@ class PEFNumber : public PExpr {
virtual unsigned test_width(Design*des, NetScope*scope,
width_mode_t&mode);
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
ivl_type_t type, unsigned flags) const;
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
unsigned expr_wid,
unsigned flags) const;

View File

@ -2537,6 +2537,13 @@ unsigned PEFNumber::test_width(Design*, NetScope*, width_mode_t&)
return expr_width_;
}
NetExpr* PEFNumber::elaborate_expr(Design*, NetScope*, ivl_type_t type, unsigned) const
{
NetECReal*tmp = new NetECReal(*value_);
tmp->set_line(*this);
return tmp;
}
NetExpr* PEFNumber::elaborate_expr(Design*, NetScope*, unsigned, unsigned) const
{
NetECReal*tmp = new NetECReal(*value_);

View File

@ -23,8 +23,10 @@
static int eval_darray_new(ivl_expr_t ex)
{
int errors = 0;
unsigned size_reg = allocate_word();
ivl_expr_t size_expr = ivl_expr_oper1(ex);
ivl_expr_t init_expr = ivl_expr_oper2(ex);
draw_eval_expr_into_integer(size_expr, size_reg);
clr_word(size_reg);
@ -64,7 +66,41 @@ static int eval_darray_new(ivl_expr_t ex)
break;
}
return 0;
if (init_expr && ivl_expr_type(init_expr)==IVL_EX_ARRAY_PATTERN) {
int idx;
struct vector_info rvec;
unsigned wid;
switch (ivl_type_base(element_type)) {
case IVL_VT_BOOL:
wid = width_of_packed_type(element_type);
for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) {
rvec = draw_eval_expr_wid(ivl_expr_parm(init_expr,idx),
wid, STUFF_OK_XZ);
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%set/dar/obj 3, %u, %u;\n",
rvec.base, rvec.wid);
if (rvec.base >= 4) clr_vector(rvec);
}
break;
case IVL_VT_REAL:
for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) {
draw_eval_real(ivl_expr_parm(init_expr,idx));
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%set/dar/obj/real 3;\n");
fprintf(vvp_out, " %%pop/real 1;\n");
}
break;
default:
fprintf(vvp_out, "; ERROR: Sorry, this type not supported here.\n");
errors += 1;
break;
}
} else if (init_expr) {
fprintf(vvp_out, "; ERROR: Init_expr not supported here\n");
errors += 1;
}
return errors;
}
static int eval_class_new(ivl_expr_t ex)

View File

@ -687,7 +687,7 @@ static int show_stmt_assign_vector(ivl_statement_t net)
}
/*
* This function assigns a value to a real .variable. This is destined
* This function assigns a value to a real variable. This is destined
* for /dev/null when typed ivl_signal_t takes over all the real
* variable support.
*/

View File

@ -181,6 +181,8 @@ extern bool of_RELEASE_WR(vthread_t thr, vvp_code_t code);
extern bool of_SCOPY(vthread_t thr, vvp_code_t code);
extern bool of_SET_AV(vthread_t thr, vvp_code_t code);
extern bool of_SET_DAR(vthread_t thr, vvp_code_t code);
extern bool of_SET_DAR_OBJ(vthread_t thr, vvp_code_t code);
extern bool of_SET_DAR_OBJ_REAL(vthread_t thr, vvp_code_t code);
extern bool of_SET_VEC(vthread_t thr, vvp_code_t code);
extern bool of_SET_X0(vthread_t thr, vvp_code_t code);
extern bool of_SET_X0_X(vthread_t thr, vvp_code_t code);

View File

@ -229,6 +229,8 @@ static const struct opcode_table_s opcode_table[] = {
{ "%scopy", of_SCOPY, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%set/av", of_SET_AV, 3, {OA_ARR_PTR, OA_BIT1, OA_BIT2} },
{ "%set/dar",of_SET_DAR,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%set/dar/obj", of_SET_DAR_OBJ, 3,{OA_NUMBER,OA_BIT1,OA_BIT2} },
{ "%set/dar/obj/real",of_SET_DAR_OBJ_REAL,1,{OA_NUMBER,OA_NONE,OA_NONE} },
{ "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%set/x0", of_SET_X0, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%shiftl/i0", of_SHIFTL_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} },

View File

@ -952,10 +952,21 @@ statement. The <type> is 0 for nets and 1 for registers. See the other
%release commands above.
* %set/dar <var-label>, <bit>, <wid>
* %set/dar/obj <index>, <bit>, <wid>
This sets a vector to a word of the dynamic array. Index register 3
contains the word address within the dynamic array, and <bit>,<wid>
specifies the thread vector to be written.
The "%set/dar" opcode sets a vector to a word of the dynamic
array. Index register 3 contains the word address within the dynamic
array, and <bit>,<wid> specifies the thread vector to be written.
The "%set/dar/obj" opcode is similar, except that it sets elements of
a dynamic array that is in the top of the object stack. Instead of
using a fixed index register, use the register addressed by <index>.
* %set/dar/obj/real <index>
The "%set/dar/obj/real" opcode sets the top value from the real-value
stack to the index. This does NOT pop the real value off the
stack. The intent is that this value may be written to a bunch of values.
* %set/v <var-label>, <bit>, <wid>

View File

@ -4921,6 +4921,42 @@ bool of_SET_DAR(vthread_t thr, vvp_code_t cp)
return true;
}
/*
* %set/dar/obj <index>, <bit>, <wid>
*/
bool of_SET_DAR_OBJ(vthread_t thr, vvp_code_t cp)
{
unsigned adr = thr->words[cp->number].w_int;
unsigned bit = cp->bit_idx[0];
unsigned wid = cp->bit_idx[1];
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
vvp_object_t&top = thr->peek_object();
vvp_darray*darray = top.peek<vvp_darray>();
assert(darray);
darray->set_word(adr, value);
return true;
}
/*
* %set/dar/obj/real <index>
*/
bool of_SET_DAR_OBJ_REAL(vthread_t thr, vvp_code_t cp)
{
unsigned adr = thr->words[cp->number].w_int;
double value = thr->peek_real(0);
vvp_object_t&top = thr->peek_object();
vvp_darray*darray = top.peek<vvp_darray>();
assert(darray);
darray->set_word(adr, value);
return true;
}
/*
* This implements the "%set/v <label>, <bit>, <wid>" instruction.
*