Skip to content

Commit d44fd89

Browse files
author
Pierre-Henri Horrein
committed
Preliminary unpacked support for localparam
1 parent d8cb29f commit d44fd89

File tree

18 files changed

+336
-57
lines changed

18 files changed

+336
-57
lines changed

PExpr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,12 @@ class PEIdent : public PExpr {
456456
NetScope*found_in,
457457
ivl_type_t par_type,
458458
bool need_const) const;
459+
NetExpr*elaborate_expr_param_word_(Design*des,
460+
NetScope*scope,
461+
const NetExpr*par,
462+
NetScope*found_in,
463+
ivl_type_t par_type,
464+
bool need_const) const;
459465
NetExpr*elaborate_expr_param_part_(Design*des,
460466
NetScope*scope,
461467
const NetExpr*par,

design_dump.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
109109
case IVL_VT_STRING:
110110
o << "string";
111111
break;
112+
case IVL_VT_UARRAY:
113+
o << "uarray";
114+
break;
112115
case IVL_VT_DARRAY:
113116
o << "darray";
114117
break;
@@ -1673,6 +1676,19 @@ void NetEArrayPattern::dump(ostream&fd) const
16731676
fd << "}";
16741677
}
16751678

1679+
void NetEArrayPatternParam::dump(ostream&fd) const
1680+
{
1681+
fd << "'{";
1682+
if (items_.size() >= 1) {
1683+
if (items_[0]) fd << *items_[0];
1684+
}
1685+
for (size_t idx = 1 ; idx < items_.size() ; idx += 1) {
1686+
fd << ", ";
1687+
if (items_[idx]) fd << *items_[idx];
1688+
}
1689+
fd << "}";
1690+
}
1691+
16761692
void NetEBinary::dump(ostream&o) const
16771693
{
16781694
if (op_ == 'm' || op_ == 'M') {

dup_expr.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ NetEArrayPattern*NetEArrayPattern::dup_expr() const
4343
return res;
4444
}
4545

46+
NetEArrayPatternParam*NetEArrayPatternParam::dup_expr() const
47+
{
48+
vector<NetExpr*>tmp (items_.size());
49+
for (size_t idx = 0 ; idx < tmp.size() ; idx += 1)
50+
tmp[idx] = items_[idx]->dup_expr();
51+
52+
NetEArrayPatternParam*res = new NetEArrayPatternParam(scope_, name_, net_type(), tmp);
53+
res->set_line(*this);
54+
return res;
55+
}
56+
4657
NetEBinary* NetEBinary::dup_expr() const
4758
{
4859
ivl_assert(*this, 0);

elab_expr.cc

Lines changed: 104 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
187188
unsigned 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

196197
NetExpr*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,
222224
NetExpr*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

254253
unsigned 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+
51265197
NetExpr* 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);

emit.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,11 @@ void NetEArrayPattern::expr_scan(struct expr_scan_t*tgt) const
593593
tgt->expr_array_pattern(this);
594594
}
595595

596+
void NetEArrayPatternParam::expr_scan(struct expr_scan_t*tgt) const
597+
{
598+
tgt->expr_array_pattern(this);
599+
}
600+
596601
void NetEBinary::expr_scan(struct expr_scan_t*tgt) const
597602
{
598603
tgt->expr_binary(this);

ivl_target.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,10 @@ typedef enum ivl_variable_type_e ENUM_UNSIGNED_INT {
460460
IVL_VT_BOOL = 3,
461461
IVL_VT_LOGIC = 4,
462462
IVL_VT_STRING = 5,
463-
IVL_VT_DARRAY = 6, /* Array (esp. dynamic array) */
464-
IVL_VT_CLASS = 7, /* SystemVerilog class instances */
465-
IVL_VT_QUEUE = 8, /* SystemVerilog queue instances */
463+
IVL_VT_UARRAY = 6, /* Array (esp. unpacked array) */
464+
IVL_VT_DARRAY = 7, /* Array (esp. dynamic array) */
465+
IVL_VT_CLASS = 8, /* SystemVerilog class instances */
466+
IVL_VT_QUEUE = 9, /* SystemVerilog queue instances */
466467
IVL_VT_VECTOR = IVL_VT_LOGIC /* For compatibility */
467468
} ivl_variable_type_t;
468469

main.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ bool ignore_missing_modules = false;
178178
*/
179179
bool debug_scopes = false;
180180
bool debug_eval_tree = false;
181-
bool debug_elaborate = false;
181+
bool debug_elaborate = true;
182182
bool debug_emit = false;
183183
bool debug_synth2 = false;
184184
bool debug_optimizer = false;

net_design.cc

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,31 @@ void Design::evaluate_parameters()
508508
}
509509
}
510510

511+
void NetScope::evaluate_parameter_array_(Design*des, param_ref_t cur)
512+
{
513+
PExpr*val_expr = (*cur).second.val_expr;
514+
NetScope*val_scope = (*cur).second.val_scope;
515+
ivl_type_t param_type = cur->second.ivl_type;
516+
517+
ivl_assert(cur->second, val_expr);
518+
ivl_assert(cur->second, param_type);
519+
520+
NetExpr*expr = elab_and_eval(des, val_scope, val_expr, param_type, true);
521+
if (! expr)
522+
return;
523+
524+
cur->second.val = expr;
525+
526+
if (debug_elaborate) {
527+
cerr << cur->second.get_fileline() << ": " << __func__ << ": "
528+
<< "Parameter type: " << *param_type << endl;
529+
cerr << cur->second.get_fileline() << ": " << __func__ << ": "
530+
<< "Parameter value: " << *val_expr << endl;
531+
cerr << cur->second.get_fileline() << ": " << __func__ << ": "
532+
<< "Elaborated value: " << *expr << endl;
533+
}
534+
535+
}
511536
void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
512537
{
513538
/* Evaluate the parameter expression. */
@@ -840,7 +865,7 @@ void NetScope::evaluate_parameter_(Design*des, param_ref_t cur)
840865
if (cur->second.val_expr == 0)
841866
return;
842867

843-
// Guess the varaiable type of the parameter. If the parameter has no
868+
// Guess the variable type of the parameter. If the parameter has no
844869
// given type, then guess the type from the expression and use that to
845870
// evaluate.
846871
ivl_variable_type_t use_type;
@@ -849,6 +874,14 @@ void NetScope::evaluate_parameter_(Design*des, param_ref_t cur)
849874
else
850875
use_type = cur->second.val_expr->expr_type();
851876

877+
if (debug_elaborate) {
878+
cerr << cur->second.get_fileline() << ": evaluating parameter " << cur->first
879+
<< ", param_type: " << param_type;
880+
if (param_type)
881+
cerr << "(base type: " << param_type->base_type() << ")";
882+
cerr << ", use_type: " << use_type
883+
<< "." << endl;
884+
}
852885
if (cur->second.solving) {
853886
cerr << cur->second.get_fileline() << ": error: "
854887
<< "Recursive parameter reference found involving "
@@ -868,9 +901,13 @@ void NetScope::evaluate_parameter_(Design*des, param_ref_t cur)
868901
evaluate_parameter_real_(des, cur);
869902
break;
870903

871-
case IVL_VT_STRING:
872-
evaluate_parameter_string_(des, cur);
873-
break;
904+
case IVL_VT_UARRAY:
905+
evaluate_parameter_array_(des, cur);
906+
break;
907+
908+
case IVL_VT_STRING:
909+
evaluate_parameter_string_(des, cur);
910+
break;
874911

875912
default:
876913
cerr << cur->second.get_fileline() << ": internal error: "

0 commit comments

Comments
 (0)