@@ -109,6 +109,7 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
109109 int context_wid = -1 ;
110110 switch (lv_type) {
111111 case IVL_VT_DARRAY:
112+ case IVL_VT_UARRAY:
112113 case IVL_VT_QUEUE:
113114 case IVL_VT_CLASS:
114115 // For these types, use a different elab_and_eval that
@@ -186,11 +187,11 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
186187 */
187188unsigned PEAssignPattern::test_width (Design*, NetScope*, width_mode_t &)
188189{
189- expr_type_ = IVL_VT_DARRAY ;
190- expr_width_ = 1 ;
191- min_width_ = 1 ;
190+ expr_type_ = IVL_VT_UARRAY ;
191+ expr_width_ = parms_. size () ;
192+ min_width_ = expr_width_ ;
192193 signed_flag_= false ;
193- return 1 ;
194+ return expr_width_ ;
194195}
195196
196197NetExpr*PEAssignPattern::elaborate_expr (Design*des, NetScope*scope,
@@ -208,7 +209,8 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
208209 }
209210
210211 if (ntype->base_type ()==IVL_VT_DARRAY ||
211- ntype->base_type ()==IVL_VT_QUEUE)
212+ ntype->base_type ()==IVL_VT_QUEUE ||
213+ ntype->base_type ()==IVL_VT_UARRAY)
212214 return elaborate_expr_darray_ (des, scope, ntype, flags);
213215
214216 cerr << get_fileline () << " : sorry: I don't know how to elaborate "
@@ -222,7 +224,7 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
222224NetExpr*PEAssignPattern::elaborate_expr_darray_ (Design*des, NetScope*scope,
223225 ivl_type_t ntype, unsigned flags) const
224226{
225- const netdarray_t *array_type = dynamic_cast <const netdarray_t *> (ntype);
227+ const netarray_t *array_type = dynamic_cast <const netarray_t *> (ntype);
226228 ivl_assert (*this , array_type);
227229
228230 // This is an array pattern, so run through the elements of
@@ -240,15 +242,12 @@ NetExpr*PEAssignPattern::elaborate_expr_darray_(Design*des, NetScope*scope,
240242 return res;
241243}
242244
243- NetExpr* PEAssignPattern::elaborate_expr (Design*des, NetScope*, unsigned , unsigned ) const
245+ NetExpr* PEAssignPattern::elaborate_expr (Design*des, NetScope*scope , unsigned width , unsigned flags ) const
244246{
245247 cerr << get_fileline () << " : sorry: I do not know how to"
246248 << " elaborate assignment patterns using old method." << endl;
247249 cerr << get_fileline () << " : : Expression is: " << *this
248250 << endl;
249- des->errors += 1 ;
250- ivl_assert (*this , 0 );
251- return 0 ;
252251}
253252
254253unsigned PEBinary::test_width (Design*des, NetScope*scope, width_mode_t &mode)
@@ -3728,6 +3727,7 @@ bool PEIdent::calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net,
37283727 switch (net->data_type ()) {
37293728 case IVL_VT_STRING:
37303729 case IVL_VT_DARRAY:
3730+ case IVL_VT_UARRAY:
37313731 case IVL_VT_QUEUE:
37323732 dimensions += 1 ;
37333733 default :
@@ -4606,9 +4606,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
46064606 NetExpr*tmp = elaborate_expr_param_ (des, scope, par, found_in,
46074607 par_type, expr_wid, flags);
46084608
4609- if (!tmp) return 0 ;
4609+ if (!tmp) return 0 ;
46104610
4611- return pad_to_width (tmp, expr_wid, signed_flag_, *this );
4611+ return pad_to_width (tmp, expr_wid, signed_flag_, *this );
46124612 }
46134613
46144614 // If the identifier names a signal (a variable or a net)
@@ -5123,6 +5123,77 @@ NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
51235123 return tmp;
51245124}
51255125
5126+ NetExpr* PEIdent::elaborate_expr_param_word_ (Design*des, NetScope*scope,
5127+ const NetExpr*par,
5128+ NetScope*found_in,
5129+ ivl_type_t par_type,
5130+ bool need_const) const
5131+ {
5132+ const NetEArrayPattern*par_ex = dynamic_cast <const NetEArrayPattern*> (par);
5133+ ivl_assert (*this , par_ex);
5134+ const netuarray_t *array = dynamic_cast <const netuarray_t *> (par->net_type ());
5135+ if (!array) {
5136+ cerr << get_fileline () << " tried to get a word from non-array expression" << endl;
5137+ return 0 ;
5138+ }
5139+
5140+ long par_msv, par_lsv;
5141+ if (! calculate_param_range (*this , par_type, par_msv, par_lsv,
5142+ par_ex->item_size ())) return 0 ;
5143+
5144+ const name_component_t &name_tail = path_.back ();
5145+ ivl_assert (*this , !name_tail.index .empty ());
5146+ const index_component_t &index_tail = name_tail.index .back ();
5147+ ivl_assert (*this , index_tail.msb );
5148+ ivl_assert (*this , !index_tail.lsb );
5149+
5150+ NetExpr*sel = elab_and_eval (des, scope, index_tail.msb , -1 , need_const);
5151+ if (sel == 0 ) return 0 ;
5152+
5153+ if (debug_elaborate)
5154+ cerr << get_fileline () << " : debug: Calculate bit select "
5155+ << " [" << *sel << " ] from range "
5156+ << " [" << par_msv << " :" << par_lsv << " ]." << endl;
5157+
5158+ perm_string name = peek_tail_name (path_);
5159+
5160+ // Handle the special case that the selection is constant. In this
5161+ // case, just precalculate the entire constant result.
5162+ NetEConst*sel_c = dynamic_cast <NetEConst*> (sel);
5163+ if (!sel_c) {
5164+ cerr << get_fileline () << " tried to get a word with non constant selector" << endl;
5165+ return 0 ;
5166+ }
5167+ // Special case: If the bit select is constant and not fully
5168+ // defined, then we know that the result must be 1'bx.
5169+ if (! sel_c->value ().is_defined ()) {
5170+ if (warn_ob_select) {
5171+ cerr << get_fileline () << " : warning: "
5172+ " Constant undefined bit select ["
5173+ << sel_c->value () << " ] for parameter '"
5174+ << name << " '." << endl;
5175+ cerr << get_fileline () << " : : "
5176+ " Replacing select with a constant 1'bx."
5177+ << endl;
5178+ }
5179+
5180+ // This is a convenience function for getting the width of an
5181+ // element. Strictly speaking it's not necessary.
5182+ NetEConst*res = make_const_x (array->element_type ()->packed_width ());
5183+ res->set_line (*this );
5184+ return res;
5185+ }
5186+ // Calculate the canonical index value.
5187+ long sel_v = sel_c->value ().as_long ();
5188+ sel_v -= par_msv;
5189+
5190+ // Select a bit from the parameter.
5191+ NetExpr*res = (NetExpr *)par_ex->item (sel_v);
5192+ // NetEConst*res = new NetEConst(rtn);
5193+ res->set_line (*this );
5194+ return res;
5195+ }
5196+
51265197NetExpr* PEIdent::elaborate_expr_param_part_ (Design*des, NetScope*scope,
51275198 const NetExpr*par,
51285199 NetScope*,
@@ -5449,6 +5520,7 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
54495520
54505521 const name_component_t &name_tail = path_.back ();
54515522 index_component_t ::ctype_t use_sel = index_component_t ::SEL_NONE;
5523+ // FIXME: this won't work with multidimensional array
54525524 if (!name_tail.index .empty ())
54535525 use_sel = name_tail.index .back ().sel ;
54545526
@@ -5464,8 +5536,13 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
54645536 ivl_assert (*this , use_sel != index_component_t ::SEL_BIT_LAST);
54655537
54665538 if (use_sel == index_component_t ::SEL_BIT)
5467- return elaborate_expr_param_bit_ (des, scope, par, found_in,
5468- par_type, need_const);
5539+ if (par->expr_type () == IVL_VT_UARRAY) {
5540+ return elaborate_expr_param_word_ (des, scope, par, found_in,
5541+ par_type, need_const);
5542+ } else {
5543+ return elaborate_expr_param_bit_ (des, scope, par, found_in,
5544+ par_type, need_const);
5545+ }
54695546
54705547 if (use_sel == index_component_t ::SEL_PART)
54715548 return elaborate_expr_param_part_ (des, scope, par, found_in,
@@ -5521,6 +5598,19 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
55215598 << " Elaborate parameter <" << name
55225599 << " > as constant " << *tmp << endl;
55235600 }
5601+
5602+ const NetEArrayPattern*atmp = dynamic_cast <const NetEArrayPattern*>(par);
5603+ if (atmp) {
5604+ std::vector<NetExpr*> items (atmp->item_size ());
5605+ for (int i = 0 ; i < atmp->item_size (); i++) {
5606+ items[i] = (NetExpr*)atmp->item (i);
5607+ }
5608+ tmp = new NetEArrayPatternParam (found_in, name, atmp->net_type (), items);
5609+ if (debug_elaborate)
5610+ cerr << get_fileline () << " : debug: "
5611+ << " Elaborate parameter <" << name
5612+ << " > as constant " << *tmp << endl;
5613+ }
55245614 /* The numeric parameter value needs to have the file and line
55255615 * information for the actual parameter not the expression. */
55265616 assert (tmp);
0 commit comments