diff --git a/elab_expr.cc b/elab_expr.cc index f0618b4c3..eae0a0df5 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -3446,6 +3446,18 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, return 0; } + if (const netdarray_t*array_type = dynamic_cast (ntype)) { + if (array_type->type_compatible(net->net_type())) { + NetESignal*tmp = new NetESignal(net); + tmp->set_line(*this); + return tmp; + } + + // Icarus allows a dynamic array to be initialised with a + // single elementary value, so try that next. + ntype = array_type->element_type(); + } + if (! ntype->type_compatible(net->net_type())) { cerr << get_fileline() << ": error: the type of the variable '" << path_ << "' doesn't match the context type." << endl; @@ -5318,9 +5330,8 @@ NetExpr* PENewArray::elaborate_expr(Design*des, NetScope*scope, // expression. Elaborate the expression as an element // type. The run-time will assign this value to each element. const netarray_t*array_type = dynamic_cast (ntype); - ivl_type_t elem_type = array_type->element_type(); - init_val = init_->elaborate_expr(des, scope, elem_type, flags); + init_val = init_->elaborate_expr(des, scope, array_type, flags); } NetENew*tmp = new NetENew(ntype, size, init_val); @@ -5571,6 +5582,10 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode) NetExpr* PENumber::elaborate_expr(Design*des, NetScope*, ivl_type_t ntype, unsigned) const { + // Icarus allows dynamic arrays to be initialised with a single value. + if (const netdarray_t*array_type = dynamic_cast (ntype)) + ntype = array_type->element_type(); + const netvector_t*use_type = dynamic_cast (ntype); if (use_type == 0) { cerr << get_fileline() << ": internal error: " diff --git a/tgt-vvp/eval_object.c b/tgt-vvp/eval_object.c index 2bcd1500e..7a307b150 100644 --- a/tgt-vvp/eval_object.c +++ b/tgt-vvp/eval_object.c @@ -111,6 +111,11 @@ static int eval_darray_new(ivl_expr_t ex) errors += 1; break; } + } else if (init_expr && (ivl_expr_value(init_expr) == IVL_VT_DARRAY)) { + ivl_signal_t sig = ivl_expr_signal(init_expr); + fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); + fprintf(vvp_out, " %%scopy;\n"); + } else if (init_expr && number_is_immediate(size_expr,32,0)) { /* In this case, there is an init expression, the expression is NOT an array_pattern, and the size diff --git a/vvp/vvp_darray.cc b/vvp/vvp_darray.cc index 3c8086c03..94e940f45 100644 --- a/vvp/vvp_darray.cc +++ b/vvp/vvp_darray.cc @@ -67,6 +67,11 @@ void vvp_darray::get_word(unsigned, vvp_object_t&) cerr << "XXXX get_word(vvp_object_t) not implemented for " << typeid(*this).name() << endl; } +void vvp_darray::shallow_copy(const vvp_object*) +{ + cerr << "XXXX shallow_copy(vvp_object_t) not implemented for " << typeid(*this).name() << endl; +} + template vvp_darray_atom::~vvp_darray_atom() { } @@ -101,6 +106,16 @@ template void vvp_darray_atom::get_word(unsigned adr, vvp_vec value = tmp; } +template void vvp_darray_atom::shallow_copy(const vvp_object*obj) +{ + const vvp_darray_atom*that = dynamic_cast*>(obj); + assert(that); + + unsigned num_items = min(array_.size(), that->array_.size()); + for (unsigned idx = 0 ; idx < num_items ; idx += 1) + array_[idx] = that->array_[idx]; +} + template class vvp_darray_atom; template class vvp_darray_atom; template class vvp_darray_atom; @@ -140,6 +155,16 @@ void vvp_darray_vec4::get_word(unsigned adr, vvp_vector4_t&value) assert(value.size() == word_wid_); } +void vvp_darray_vec4::shallow_copy(const vvp_object*obj) +{ + const vvp_darray_vec4*that = dynamic_cast(obj); + assert(that); + + unsigned num_items = min(array_.size(), that->array_.size()); + for (unsigned idx = 0 ; idx < num_items ; idx += 1) + array_[idx] = that->array_[idx]; +} + vvp_darray_vec2::~vvp_darray_vec2() { } @@ -173,6 +198,15 @@ void vvp_darray_vec2::get_word(unsigned adr, vvp_vector4_t&value) } } +void vvp_darray_vec2::shallow_copy(const vvp_object*obj) +{ + const vvp_darray_vec2*that = dynamic_cast(obj); + assert(that); + + unsigned num_items = min(array_.size(), that->array_.size()); + for (unsigned idx = 0 ; idx < num_items ; idx += 1) + array_[idx] = that->array_[idx]; +} vvp_darray_object::~vvp_darray_object() { @@ -200,6 +234,16 @@ void vvp_darray_object::get_word(unsigned adr, vvp_object_t&value) value = array_[adr]; } +void vvp_darray_object::shallow_copy(const vvp_object*obj) +{ + const vvp_darray_object*that = dynamic_cast(obj); + assert(that); + + unsigned num_items = min(array_.size(), that->array_.size()); + for (unsigned idx = 0 ; idx < num_items ; idx += 1) + array_[idx] = that->array_[idx]; +} + vvp_darray_real::~vvp_darray_real() { } @@ -226,6 +270,16 @@ void vvp_darray_real::get_word(unsigned adr, double&value) value = array_[adr]; } +void vvp_darray_real::shallow_copy(const vvp_object*obj) +{ + const vvp_darray_real*that = dynamic_cast(obj); + assert(that); + + unsigned num_items = min(array_.size(), that->array_.size()); + for (unsigned idx = 0 ; idx < num_items ; idx += 1) + array_[idx] = that->array_[idx]; +} + vvp_darray_string::~vvp_darray_string() { } @@ -252,6 +306,16 @@ void vvp_darray_string::get_word(unsigned adr, string&value) value = array_[adr]; } +void vvp_darray_string::shallow_copy(const vvp_object*obj) +{ + const vvp_darray_string*that = dynamic_cast(obj); + assert(that); + + unsigned num_items = min(array_.size(), that->array_.size()); + for (unsigned idx = 0 ; idx < num_items ; idx += 1) + array_[idx] = that->array_[idx]; +} + vvp_queue::~vvp_queue() { } diff --git a/vvp/vvp_darray.h b/vvp/vvp_darray.h index e6d164698..4de0f9a13 100644 --- a/vvp/vvp_darray.h +++ b/vvp/vvp_darray.h @@ -44,6 +44,8 @@ class vvp_darray : public vvp_object { virtual void set_word(unsigned adr, const vvp_object_t&value); virtual void get_word(unsigned adr, vvp_object_t&value); + + virtual void shallow_copy(const vvp_object*obj); }; template class vvp_darray_atom : public vvp_darray { @@ -55,6 +57,7 @@ template class vvp_darray_atom : public vvp_darray { size_t get_size(void) const; void set_word(unsigned adr, const vvp_vector4_t&value); void get_word(unsigned adr, vvp_vector4_t&value); + void shallow_copy(const vvp_object*obj); private: std::vector array_; @@ -70,6 +73,7 @@ class vvp_darray_vec4 : public vvp_darray { size_t get_size(void) const; void set_word(unsigned adr, const vvp_vector4_t&value); void get_word(unsigned adr, vvp_vector4_t&value); + void shallow_copy(const vvp_object*obj); private: std::vector array_; @@ -86,6 +90,7 @@ class vvp_darray_vec2 : public vvp_darray { size_t get_size(void) const; void set_word(unsigned adr, const vvp_vector4_t&value); void get_word(unsigned adr, vvp_vector4_t&value); + void shallow_copy(const vvp_object*obj); private: std::vector array_; @@ -101,6 +106,7 @@ class vvp_darray_real : public vvp_darray { size_t get_size(void) const; void set_word(unsigned adr, double value); void get_word(unsigned adr, double&value); + void shallow_copy(const vvp_object*obj); private: std::vector array_; @@ -115,6 +121,7 @@ class vvp_darray_string : public vvp_darray { size_t get_size(void) const; void set_word(unsigned adr, const std::string&value); void get_word(unsigned adr, std::string&value); + void shallow_copy(const vvp_object*obj); private: std::vector array_; @@ -129,6 +136,7 @@ class vvp_darray_object : public vvp_darray { size_t get_size(void) const; void set_word(unsigned adr, const vvp_object_t&value); void get_word(unsigned adr, vvp_object_t&value); + void shallow_copy(const vvp_object*obj); private: std::vector array_;