@@ -109,7 +109,6 @@ NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
109
109
int context_wid = -1 ;
110
110
switch (lv_type) {
111
111
case IVL_VT_DARRAY:
112
- case IVL_VT_UARRAY:
113
112
case IVL_VT_QUEUE:
114
113
case IVL_VT_CLASS:
115
114
// For these types, use a different elab_and_eval that
@@ -185,12 +184,20 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
185
184
* supported, can assign to packed arrays and structs, unpacked arrays
186
185
* and dynamic arrays.
187
186
*/
188
- unsigned PEAssignPattern::test_width (Design*, NetScope*, width_mode_t &)
187
+ unsigned PEAssignPattern::test_width (Design*des , NetScope*scope , width_mode_t &mode )
189
188
{
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
+ }
194
201
return expr_width_;
195
202
}
196
203
@@ -208,10 +215,23 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
208
215
return tmp;
209
216
}
210
217
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
+ }
215
235
216
236
cerr << get_fileline () << " : sorry: I don't know how to elaborate "
217
237
<< " assignment_pattern expressions yet." << endl;
@@ -221,27 +241,6 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope,
221
241
return 0 ;
222
242
}
223
243
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
-
245
244
NetExpr* PEAssignPattern::elaborate_expr (Design*des, NetScope*, unsigned , unsigned ) const
246
245
{
247
246
cerr << get_fileline () << " : sorry: I do not know how to"
@@ -3560,7 +3559,6 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
3560
3559
switch (ntype->base_type ()) {
3561
3560
case IVL_VT_QUEUE:
3562
3561
// FIXME: Does a DARRAY support a zero size?
3563
- case IVL_VT_UARRAY:
3564
3562
case IVL_VT_DARRAY:
3565
3563
if (parms_.size () == 0 ) {
3566
3564
NetENull*tmp = new NetENull;
@@ -3731,7 +3729,6 @@ bool PEIdent::calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net,
3731
3729
switch (net->data_type ()) {
3732
3730
case IVL_VT_STRING:
3733
3731
case IVL_VT_DARRAY:
3734
- case IVL_VT_UARRAY:
3735
3732
case IVL_VT_QUEUE:
3736
3733
dimensions += 1 ;
3737
3734
default :
@@ -4065,26 +4062,27 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
4065
4062
return expr_width_;
4066
4063
}
4067
4064
4068
- if (par != 0 && par-> expr_type () == IVL_VT_UARRAY ) {
4065
+ if (par != 0 ) {
4069
4066
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
+ }
4088
4086
4089
4087
// Look for a class property.
4090
4088
if (gn_system_verilog () && cls_val) {
@@ -5073,12 +5071,25 @@ NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
5073
5071
ivl_type_t par_type,
5074
5072
bool need_const) const
5075
5073
{
5076
- const NetEConst*par_ex = dynamic_cast <const NetEConst*> (par);
5077
- ivl_assert (*this , par_ex);
5078
-
5079
5074
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 ;
5082
5093
5083
5094
const name_component_t &name_tail = path_.back ();
5084
5095
ivl_assert (*this , !name_tail.index .empty ());
@@ -5116,43 +5127,55 @@ NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
5116
5127
return res;
5117
5128
}
5118
5129
// 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;
5146
5172
}
5147
- NetEConst*res = new NetEConst (verinum (rtn, 1 ));
5148
- res->set_line (*this );
5149
- return res;
5150
5173
}
5151
5174
5152
5175
sel = normalize_variable_base (sel, par_msv, par_lsv, 1 , true );
5153
5176
5154
5177
/* 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 ());
5156
5179
NetScope::param_ref_t pref = found_in->find_parameter (name);
5157
5180
ptmp->set_line ((*pref).second );
5158
5181
@@ -5161,78 +5184,6 @@ NetExpr* PEIdent::elaborate_expr_param_bit_(Design*des, NetScope*scope,
5161
5184
return tmp;
5162
5185
}
5163
5186
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
-
5236
5187
NetExpr* PEIdent::elaborate_expr_param_part_ (Design*des, NetScope*scope,
5237
5188
const NetExpr*par,
5238
5189
NetScope*,
@@ -5575,13 +5526,8 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
5575
5526
ivl_assert (*this , use_sel != index_component_t ::SEL_BIT_LAST);
5576
5527
5577
5528
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 {
5582
5529
return elaborate_expr_param_bit_ (des, scope, par, found_in,
5583
5530
par_type, need_const);
5584
- }
5585
5531
5586
5532
if (use_sel == index_component_t ::SEL_PART)
5587
5533
return elaborate_expr_param_part_ (des, scope, par, found_in,
0 commit comments