@@ -109,7 +109,6 @@ 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:
113112 case IVL_VT_QUEUE:
114113 case IVL_VT_CLASS:
115114 // For these types, use a different elab_and_eval that
@@ -185,12 +184,20 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
185184 * supported, can assign to packed arrays and structs, unpacked arrays
186185 * and dynamic arrays.
187186 */
188- unsigned PEAssignPattern::test_width (Design*, NetScope*, width_mode_t &)
187+ unsigned PEAssignPattern::test_width (Design*des , NetScope*scope , width_mode_t &mode )
189188{
190- expr_type_ = IVL_VT_UARRAY;
191- expr_width_ = parms_.size ();
192- min_width_ = expr_width_;
193- signed_flag_= false ;
189+ if (parms_.size () > 0 ) {
190+ parms_[0 ]->test_width (des, scope, mode);
191+ expr_type_ = parms_[0 ]->expr_type ();
192+ expr_width_ = parms_.size ();
193+ min_width_ = expr_width_;
194+ signed_flag_= parms_[0 ]->has_sign ();
195+ } else {
196+ expr_type_ = IVL_VT_DARRAY;
197+ expr_width_ = 1 ;
198+ min_width_ = 1 ;
199+ signed_flag_= false ;
200+ }
194201 return expr_width_;
195202}
196203
@@ -208,10 +215,23 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
208215 return tmp;
209216 }
210217
211- if (ntype->base_type ()==IVL_VT_DARRAY ||
212- ntype->base_type ()==IVL_VT_QUEUE ||
213- ntype->base_type ()==IVL_VT_UARRAY)
214- return elaborate_expr_darray_ (des, scope, ntype, flags);
218+ const netarray_t *array_type = dynamic_cast <const netarray_t *> (ntype);
219+ if (array_type) {
220+
221+ // This is an array pattern, so run through the elements of
222+ // the expression and elaborate each as if they are
223+ // element_type expressions.
224+ ivl_type_t elem_type = array_type->element_type ();
225+ vector<NetExpr*> elem_exprs (parms_.size ());
226+ for (size_t idx = 0 ; idx < parms_.size () ; idx += 1 ) {
227+ NetExpr*tmp = parms_[idx]->elaborate_expr (des, scope, elem_type, flags);
228+ elem_exprs[idx] = tmp;
229+ }
230+
231+ NetEArrayPattern*res = new NetEArrayPattern (array_type, elem_exprs);
232+ res->set_line (*this );
233+ return res;
234+ }
215235
216236 cerr << get_fileline () << " : sorry: I don't know how to elaborate "
217237 << " assignment_pattern expressions yet." << endl;
@@ -221,27 +241,6 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
221241 return 0 ;
222242}
223243
224- NetExpr*PEAssignPattern::elaborate_expr_darray_ (Design*des, NetScope*scope,
225- ivl_type_t ntype, unsigned flags) const
226- {
227- const netarray_t *array_type = dynamic_cast <const netarray_t *> (ntype);
228- ivl_assert (*this , array_type);
229-
230- // This is an array pattern, so run through the elements of
231- // the expression and elaborate each as if they are
232- // element_type expressions.
233- ivl_type_t elem_type = array_type->element_type ();
234- vector<NetExpr*> elem_exprs (parms_.size ());
235- for (size_t idx = 0 ; idx < parms_.size () ; idx += 1 ) {
236- NetExpr*tmp = parms_[idx]->elaborate_expr (des, scope, elem_type, flags);
237- elem_exprs[idx] = tmp;
238- }
239-
240- NetEArrayPattern*res = new NetEArrayPattern (array_type, elem_exprs);
241- res->set_line (*this );
242- return res;
243- }
244-
245244NetExpr* PEAssignPattern::elaborate_expr (Design*des, NetScope*, unsigned , unsigned ) const
246245{
247246 cerr << get_fileline () << " : sorry: I do not know how to"
@@ -3560,7 +3559,6 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
35603559 switch (ntype->base_type ()) {
35613560 case IVL_VT_QUEUE:
35623561// FIXME: Does a DARRAY support a zero size?
3563- case IVL_VT_UARRAY:
35643562 case IVL_VT_DARRAY:
35653563 if (parms_.size () == 0 ) {
35663564 NetENull*tmp = new NetENull;
@@ -3731,7 +3729,6 @@ bool PEIdent::calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net,
37313729 switch (net->data_type ()) {
37323730 case IVL_VT_STRING:
37333731 case IVL_VT_DARRAY:
3734- case IVL_VT_UARRAY:
37353732 case IVL_VT_QUEUE:
37363733 dimensions += 1 ;
37373734 default :
@@ -4065,26 +4062,27 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
40654062 return expr_width_;
40664063 }
40674064
4068- if (par != 0 && par-> expr_type () == IVL_VT_UARRAY ) {
4065+ if (par != 0 ) {
40694066 const netuarray_t *array = dynamic_cast <const netuarray_t *> (par->net_type ());
4070- ivl_assert (*this , array);
4071- switch (use_sel) {
4072- case index_component_t ::SEL_BIT:
4073- case index_component_t ::SEL_BIT_LAST:
4074- expr_type_ = array->element_type ()->base_type ();
4075- expr_width_ = array->element_type ()->packed_width ();
4076- min_width_ = expr_width_;
4077- signed_flag_ = array->element_type ()->get_signed ();
4078- break ;
4079- default :
4080- expr_type_ = array->base_type ();
4081- expr_width_ = array->static_dimensions ()[0 ].width ();
4082- min_width_ = expr_width_;
4083- signed_flag_ = false ;
4084- break ;
4085- }
4086- return expr_width_;
4087- }
4067+ if (array) {
4068+ switch (use_sel) {
4069+ case index_component_t ::SEL_BIT:
4070+ case index_component_t ::SEL_BIT_LAST:
4071+ expr_type_ = array->element_type ()->base_type ();
4072+ expr_width_ = array->element_type ()->packed_width ();
4073+ min_width_ = expr_width_;
4074+ signed_flag_ = array->element_type ()->get_signed ();
4075+ break ;
4076+ default :
4077+ expr_type_ = array->base_type ();
4078+ expr_width_ = array->static_dimensions ()[0 ].width ();
4079+ min_width_ = expr_width_;
4080+ signed_flag_ = false ;
4081+ break ;
4082+ }
4083+ return expr_width_;
4084+ }
4085+ }
40884086
40894087 // Look for a class property.
40904088 if (gn_system_verilog () && cls_val) {
@@ -5073,12 +5071,25 @@ NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
50735071 ivl_type_t par_type,
50745072 bool need_const) const
50755073{
5076- const NetEConst*par_ex = dynamic_cast <const NetEConst*> (par);
5077- ivl_assert (*this , par_ex);
5078-
50795074 long par_msv, par_lsv;
5080- if (! calculate_param_range (*this , par_type, par_msv, par_lsv,
5081- par_ex->value ().len ())) return 0 ;
5075+ const NetEArrayPattern*par_aex;
5076+ const NetEConst*par_cex = dynamic_cast <const NetEConst*> (par);
5077+ if (!par_cex) {
5078+ par_aex = dynamic_cast <const NetEArrayPattern*> (par);
5079+ if (par_aex) {
5080+ const netuarray_t *array = dynamic_cast <const netuarray_t *> (par->net_type ());
5081+ if (!array) {
5082+ cerr << get_fileline () << " tried to get a word from non-array expression" << endl;
5083+ return 0 ;
5084+ }
5085+ } else {
5086+ cerr << get_fileline () << " cannot select element from provided expression" << endl;
5087+ }
5088+ }
5089+ int par_len = par_cex ? par_cex->value ().len () : par_aex->item_size ();
5090+
5091+ if (! calculate_param_range (*this , par_type, par_msv, par_lsv, par_len))
5092+ return 0 ;
50825093
50835094 const name_component_t &name_tail = path_.back ();
50845095 ivl_assert (*this , !name_tail.index .empty ());
@@ -5116,43 +5127,55 @@ NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
51165127 return res;
51175128 }
51185129 // Calculate the canonical index value.
5119- long sel_v = sel_c->value ().as_long ();
5120- if (par_msv >= par_lsv) sel_v -= par_lsv;
5121- else sel_v = par_lsv - sel_v;
5122-
5123- // Select a bit from the parameter.
5124- verinum par_v = par_ex->value ();
5125- verinum::V rtn = verinum::Vx;
5126-
5127- // A constant in range select.
5128- if ((sel_v >= 0 ) && ((unsigned long ) sel_v < par_v.len ())) {
5129- rtn = par_v[sel_v];
5130- // An unsized after select.
5131- } else if ((sel_v >= 0 ) && (! par_v.has_len ())) {
5132- if (par_v.has_sign ()) rtn = par_v[par_v.len ()-1 ];
5133- else rtn = verinum::V0;
5134- } else if (warn_ob_select) {
5135- cerr << get_fileline () << " : warning: "
5136- " Constant bit select [" << sel_c->value ().as_long ()
5137- << " ] is " ;
5138- if (sel_v < 0 ) cerr << " before " ;
5139- else cerr << " after " ;
5140- cerr << name << " [" ;
5141- if (par_v.has_len ()) cerr << par_msv;
5142- else cerr << " <inf>" ;
5143- cerr << " :" << par_lsv << " ]." << endl;
5144- cerr << get_fileline () << " : : "
5145- " Replacing select with a constant 1'bx." << endl;
5130+ if (par_cex) {
5131+ long sel_v = sel_c->value ().as_long ();
5132+ if (par_msv >= par_lsv) sel_v -= par_lsv;
5133+ else sel_v = par_lsv - sel_v;
5134+
5135+ // Select a bit from the parameter.
5136+ verinum par_v = par_cex->value ();
5137+ verinum::V rtn = verinum::Vx;
5138+
5139+ // A constant in range select.
5140+ if ((sel_v >= 0 ) && ((unsigned long ) sel_v < par_v.len ())) {
5141+ rtn = par_v[sel_v];
5142+ // An unsized after select.
5143+ } else if ((sel_v >= 0 ) && (! par_v.has_len ())) {
5144+ if (par_v.has_sign ()) rtn = par_v[par_v.len ()-1 ];
5145+ else rtn = verinum::V0;
5146+ } else if (warn_ob_select) {
5147+ cerr << get_fileline () << " : warning: "
5148+ " Constant bit select [" << sel_c->value ().as_long ()
5149+ << " ] is " ;
5150+ if (sel_v < 0 ) cerr << " before " ;
5151+ else cerr << " after " ;
5152+ cerr << name << " [" ;
5153+ if (par_v.has_len ()) cerr << par_msv;
5154+ else cerr << " <inf>" ;
5155+ cerr << " :" << par_lsv << " ]." << endl;
5156+ cerr << get_fileline () << " : : "
5157+ " Replacing select with a constant 1'bx." << endl;
5158+ }
5159+ NetEConst*res = new NetEConst (verinum (rtn, 1 ));
5160+ res->set_line (*this );
5161+ return res;
5162+ } else {
5163+ long sel_v = sel_c->value ().as_long ();
5164+ if (par_msv >= par_lsv) sel_v = par_msv - sel_v - par_lsv;
5165+ else sel_v -= par_msv;
5166+
5167+ // Select a bit from the parameter.
5168+ NetExpr*res = (NetExpr *)(par_aex->item (sel_v)->dup_expr ());
5169+ // NetEConst*res = new NetEConst(rtn);
5170+ res->set_line (*this );
5171+ return res;
51465172 }
5147- NetEConst*res = new NetEConst (verinum (rtn, 1 ));
5148- res->set_line (*this );
5149- return res;
51505173 }
51515174
51525175 sel = normalize_variable_base (sel, par_msv, par_lsv, 1 , true );
51535176
51545177 /* Create a parameter reference for the variable select. */
5155- NetEConstParam*ptmp = new NetEConstParam (found_in, name, par_ex ->value ());
5178+ NetEConstParam*ptmp = new NetEConstParam (found_in, name, par_cex ->value ());
51565179 NetScope::param_ref_t pref = found_in->find_parameter (name);
51575180 ptmp->set_line ((*pref).second );
51585181
@@ -5161,78 +5184,6 @@ NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
51615184 return tmp;
51625185}
51635186
5164- NetExpr* PEIdent::elaborate_expr_param_word_ (Design*des, NetScope*scope,
5165- const NetExpr*par,
5166- NetScope*found_in,
5167- ivl_type_t par_type,
5168- bool need_const) const
5169- {
5170- const NetEArrayPattern*par_ex = dynamic_cast <const NetEArrayPattern*> (par);
5171- ivl_assert (*this , par_ex);
5172- const netuarray_t *array = dynamic_cast <const netuarray_t *> (par->net_type ());
5173- if (!array) {
5174- cerr << get_fileline () << " tried to get a word from non-array expression" << endl;
5175- return 0 ;
5176- }
5177-
5178- long par_msv, par_lsv;
5179- if (! calculate_param_range (*this , par_type, par_msv, par_lsv,
5180- par_ex->item_size ())) return 0 ;
5181-
5182- const name_component_t &name_tail = path_.back ();
5183- ivl_assert (*this , !name_tail.index .empty ());
5184- const index_component_t &index_tail = name_tail.index .back ();
5185- ivl_assert (*this , index_tail.msb );
5186- ivl_assert (*this , !index_tail.lsb );
5187-
5188- NetExpr*sel = elab_and_eval (des, scope, index_tail.msb , -1 , need_const);
5189- if (sel == 0 ) return 0 ;
5190-
5191- if (debug_elaborate)
5192- cerr << get_fileline () << " : debug: Calculate bit select "
5193- << " [" << *sel << " ] from range "
5194- << " [" << par_msv << " :" << par_lsv << " ]." << endl;
5195-
5196- perm_string name = peek_tail_name (path_);
5197-
5198- // Handle the special case that the selection is constant. In this
5199- // case, just precalculate the entire constant result.
5200- NetEConst*sel_c = dynamic_cast <NetEConst*> (sel);
5201- if (!sel_c) {
5202- cerr << get_fileline () << " tried to get a word with non constant selector" << endl;
5203- return 0 ;
5204- }
5205- // Special case: If the bit select is constant and not fully
5206- // defined, then we know that the result must be 1'bx.
5207- if (! sel_c->value ().is_defined ()) {
5208- if (warn_ob_select) {
5209- cerr << get_fileline () << " : warning: "
5210- " Constant undefined bit select ["
5211- << sel_c->value () << " ] for parameter '"
5212- << name << " '." << endl;
5213- cerr << get_fileline () << " : : "
5214- " Replacing select with a constant 1'bx."
5215- << endl;
5216- }
5217-
5218- // This is a convenience function for getting the width of an
5219- // element. Strictly speaking it's not necessary.
5220- NetEConst*res = make_const_x (array->element_type ()->packed_width ());
5221- res->set_line (*this );
5222- return res;
5223- }
5224- // Calculate the canonical index value.
5225- long sel_v = sel_c->value ().as_long ();
5226- if (par_msv >= par_lsv) sel_v = par_msv - sel_v - par_lsv;
5227- else sel_v -= par_msv;
5228-
5229- // Select a bit from the parameter.
5230- NetExpr*res = (NetExpr *)(par_ex->item (sel_v)->dup_expr ());
5231- // NetEConst*res = new NetEConst(rtn);
5232- res->set_line (*this );
5233- return res;
5234- }
5235-
52365187NetExpr* PEIdent::elaborate_expr_param_part_ (Design*des, NetScope*scope,
52375188 const NetExpr*par,
52385189 NetScope*,
@@ -5575,13 +5526,8 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
55755526 ivl_assert (*this , use_sel != index_component_t ::SEL_BIT_LAST);
55765527
55775528 if (use_sel == index_component_t ::SEL_BIT)
5578- if (par->expr_type () == IVL_VT_UARRAY) {
5579- return elaborate_expr_param_word_ (des, scope, par, found_in,
5580- par_type, need_const);
5581- } else {
55825529 return elaborate_expr_param_bit_ (des, scope, par, found_in,
55835530 par_type, need_const);
5584- }
55855531
55865532 if (use_sel == index_component_t ::SEL_PART)
55875533 return elaborate_expr_param_part_ (des, scope, par, found_in,
0 commit comments