Skip to content
This repository
Browse code

Add support for passing variable indexed part select type information

This patch modifies the compiler and the ivl interface to pass the
type of indexed part select that is being represented (up/down) in
a procedural L-value or R-value. This is needed by any back end that
wants to correctly denormalize the (zero based) base expression.
  • Loading branch information...
commit a6220fe562555ccedd519e2a8611d7515379bfb6 1 parent 026fe92
Cary R. caryr authored committed
4 dup_expr.cc
... ... @@ -1,5 +1,5 @@
1 1 /*
2   - * Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
  2 + * Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
3 3 *
4 4 * This source code is free software; you can redistribute it
5 5 * and/or modify it in source code form under the terms of the GNU
@@ -95,7 +95,7 @@ NetESelect* NetESelect::dup_expr() const
95 95 {
96 96 NetESelect*tmp = new NetESelect(expr_->dup_expr(),
97 97 base_? base_->dup_expr() : 0,
98   - expr_width());
  98 + expr_width(), sel_type_);
99 99 assert(tmp);
100 100 tmp->set_line(*this);
101 101 return tmp;
10 elab_expr.cc
... ... @@ -1,5 +1,5 @@
1 1 /*
2   - * Copyright (c) 1999-2010 Stephen Williams (steve@icarus.com)
  2 + * Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
3 3 *
4 4 * This source code is free software; you can redistribute it
5 5 * and/or modify it in source code form under the terms of the GNU
@@ -2587,7 +2587,7 @@ NetExpr* PEIdent::elaborate_expr_param_idx_up_(Design*des, NetScope*scope,
2587 2587 base = normalize_variable_base(base, par_msv, par_lsv, wid, true);
2588 2588
2589 2589 NetExpr*tmp = par->dup_expr();
2590   - tmp = new NetESelect(tmp, base, wid);
  2590 + tmp = new NetESelect(tmp, base, wid, IVL_SEL_IDX_UP);
2591 2591 tmp->set_line(*this);
2592 2592 return tmp;
2593 2593 }
@@ -2667,7 +2667,7 @@ NetExpr* PEIdent::elaborate_expr_param_idx_do_(Design*des, NetScope*scope,
2667 2667 base = normalize_variable_base(base, par_msv, par_lsv, wid, false);
2668 2668
2669 2669 NetExpr*tmp = par->dup_expr();
2670   - tmp = new NetESelect(tmp, base, wid);
  2670 + tmp = new NetESelect(tmp, base, wid, IVL_SEL_IDX_DOWN);
2671 2671 tmp->set_line(*this);
2672 2672 return tmp;
2673 2673 }
@@ -3176,7 +3176,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_up_(Design*des, NetScope*scope,
3176 3176
3177 3177 base = normalize_variable_base(base, net->msi(), net->lsi(), wid, true);
3178 3178
3179   - NetESelect*ss = new NetESelect(net, base, wid);
  3179 + NetESelect*ss = new NetESelect(net, base, wid, IVL_SEL_IDX_UP);
3180 3180 ss->set_line(*this);
3181 3181
3182 3182 if (debug_elaborate) {
@@ -3263,7 +3263,7 @@ NetExpr* PEIdent::elaborate_expr_net_idx_do_(Design*des, NetScope*scope,
3263 3263
3264 3264 base = normalize_variable_base(base, net->msi(), net->lsi(), wid, false);
3265 3265
3266   - NetESelect*ss = new NetESelect(net, base, wid);
  3266 + NetESelect*ss = new NetESelect(net, base, wid, IVL_SEL_IDX_DOWN);
3267 3267 ss->set_line(*this);
3268 3268
3269 3269 if (debug_elaborate) {
5 elab_lval.cc
@@ -470,6 +470,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
470 470 expr_type_tmp, unsized_flag_tmp);
471 471
472 472 NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
  473 + ivl_select_type_t sel_type = IVL_SEL_OTHER;
473 474
474 475 // Handle the special case that the base is constant. For this
475 476 // case we can reduce the expression.
@@ -532,10 +533,12 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
532 533 if (use_sel == index_component_t::SEL_IDX_UP) {
533 534 base = normalize_variable_base(base, reg->msb(), reg->lsb(),
534 535 wid, true);
  536 + sel_type = IVL_SEL_IDX_UP;
535 537 } else {
536 538 // This is assumed to be a SEL_IDX_DO.
537 539 base = normalize_variable_base(base, reg->msb(), reg->lsb(),
538 540 wid, false);
  541 + sel_type = IVL_SEL_IDX_DOWN;
539 542 }
540 543 }
541 544
@@ -543,7 +546,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
543 546 cerr << get_fileline() << ": debug: Set part select width="
544 547 << wid << ", base=" << *base << endl;
545 548
546   - lv->set_part(base, wid);
  549 + lv->set_part(base, wid, sel_type);
547 550
548 551 return true;
549 552 }
2  ivl.def
@@ -68,6 +68,7 @@ ivl_expr_parm
68 68 ivl_expr_parms
69 69 ivl_expr_repeat
70 70 ivl_expr_scope
  71 +ivl_expr_sel_type
71 72 ivl_expr_signal
72 73 ivl_expr_signed
73 74 ivl_expr_sized
@@ -134,6 +135,7 @@ ivl_lpm_width
134 135 ivl_lval_idx
135 136 ivl_lval_mux
136 137 ivl_lval_part_off
  138 +ivl_lval_sel_type
137 139 ivl_lval_sig
138 140 ivl_lval_width
139 141
9 ivl_target.h
@@ -229,6 +229,12 @@ typedef enum ivl_expr_type_e {
229 229 IVL_EX_UNARY = 14
230 230 } ivl_expr_type_t;
231 231
  232 +typedef enum ivl_select_type_e {
  233 + IVL_SEL_OTHER = 0,
  234 + IVL_SEL_IDX_UP = 1,
  235 + IVL_SEL_IDX_DOWN = 2
  236 +} ivl_select_type_t;
  237 +
232 238 /* This is the type code for an ivl_net_logic_t object. */
233 239 typedef enum ivl_logic_e {
234 240 IVL_LO_NONE = 0,
@@ -844,6 +850,8 @@ extern ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx);
844 850 extern unsigned ivl_expr_parms(ivl_expr_t net);
845 851 /* IVL_EX_CONCAT */
846 852 extern unsigned ivl_expr_repeat(ivl_expr_t net);
  853 + /* IVL_EX_SELECT */
  854 +extern ivl_select_type_t ivl_expr_sel_type(ivl_expr_t net);
847 855 /* IVL_EX_EVENT */
848 856 extern ivl_event_t ivl_expr_event(ivl_expr_t net);
849 857 /* IVL_EX_SCOPE */
@@ -1409,6 +1417,7 @@ extern unsigned ivl_lval_width(ivl_lval_t net);
1409 1417 extern ivl_expr_t ivl_lval_mux(ivl_lval_t net); /* XXXX Obsolete? */
1410 1418 extern ivl_expr_t ivl_lval_idx(ivl_lval_t net);
1411 1419 extern ivl_expr_t ivl_lval_part_off(ivl_lval_t net);
  1420 +extern ivl_select_type_t ivl_lval_sel_type(ivl_lval_t net);
1412 1421 extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
1413 1422
1414 1423
9 net_assign.cc
@@ -77,6 +77,11 @@ const NetExpr* NetAssign_::get_base() const
77 77 return base_;
78 78 }
79 79
  80 +ivl_select_type_t NetAssign_::select_type() const
  81 +{
  82 + return sel_type_;
  83 +}
  84 +
80 85 unsigned NetAssign_::lwidth() const
81 86 {
82 87 return lwid_;
@@ -120,10 +125,12 @@ NetNet* NetAssign_::sig() const
120 125 return sig_;
121 126 }
122 127
123   -void NetAssign_::set_part(NetExpr*base, unsigned wid)
  128 +void NetAssign_::set_part(NetExpr*base, unsigned wid,
  129 + ivl_select_type_t sel_type)
124 130 {
125 131 base_ = base;
126 132 lwid_ = wid;
  133 + sel_type_ = sel_type;
127 134 }
128 135
129 136 /*
10 net_expr.cc
@@ -524,8 +524,9 @@ netenum_t* NetENetenum::netenum() const
524 524 return netenum_;
525 525 }
526 526
527   -NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid)
528   -: expr_(exp), base_(base)
  527 +NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
  528 + ivl_select_type_t sel_type)
  529 +: expr_(exp), base_(base), sel_type_(sel_type)
529 530 {
530 531 expr_width(wid);
531 532 }
@@ -546,6 +547,11 @@ const NetExpr*NetESelect::select() const
546 547 return base_;
547 548 }
548 549
  550 +ivl_select_type_t NetESelect::select_type() const
  551 +{
  552 + return sel_type_;
  553 +}
  554 +
549 555 bool NetESelect::has_width() const
550 556 {
551 557 return true;
10 netlist.h
@@ -2301,9 +2301,11 @@ class NetAssign_ {
2301 2301 // Get the base index of the part select, or 0 if there is no
2302 2302 // part select.
2303 2303 const NetExpr* get_base() const;
  2304 + ivl_select_type_t select_type() const;
2304 2305
2305 2306 void set_word(NetExpr*);
2306   - void set_part(NetExpr* loff, unsigned wid);
  2307 + void set_part(NetExpr* loff, unsigned wid,
  2308 + ivl_select_type_t = IVL_SEL_OTHER);
2307 2309
2308 2310 // Get the width of the r-value that this node expects. This
2309 2311 // method accounts for the presence of the mux, so it is not
@@ -2345,6 +2347,7 @@ class NetAssign_ {
2345 2347 // indexed part select base
2346 2348 NetExpr*base_;
2347 2349 unsigned lwid_;
  2350 + ivl_select_type_t sel_type_;
2348 2351 };
2349 2352
2350 2353 class NetAssignBase : public NetProc {
@@ -3644,11 +3647,13 @@ class NetEConcat : public NetExpr {
3644 3647 class NetESelect : public NetExpr {
3645 3648
3646 3649 public:
3647   - NetESelect(NetExpr*exp, NetExpr*base, unsigned wid);
  3650 + NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
  3651 + ivl_select_type_t sel_type = IVL_SEL_OTHER);
3648 3652 ~NetESelect();
3649 3653
3650 3654 const NetExpr*sub_expr() const;
3651 3655 const NetExpr*select() const;
  3656 + ivl_select_type_t select_type() const;
3652 3657
3653 3658 virtual NexusSet* nex_input(bool rem_out = true);
3654 3659 virtual bool set_width(unsigned w, bool last_chance =false);
@@ -3662,6 +3667,7 @@ class NetESelect : public NetExpr {
3662 3667 private:
3663 3668 NetExpr*expr_;
3664 3669 NetExpr*base_;
  3670 + ivl_select_type_t sel_type_;
3665 3671 };
3666 3672
3667 3673 /*
21 t-dll-api.cc
@@ -436,9 +436,11 @@ extern "C" ivl_expr_t ivl_expr_oper1(ivl_expr_t net)
436 436 assert(net);
437 437 switch (net->type_) {
438 438 case IVL_EX_BINARY:
439   - case IVL_EX_SELECT:
440 439 return net->u_.binary_.lef_;
441 440
  441 + case IVL_EX_SELECT:
  442 + return net->u_.select_.expr_;
  443 +
442 444 case IVL_EX_UNARY:
443 445 return net->u_.unary_.sub_;
444 446
@@ -463,9 +465,11 @@ extern "C" ivl_expr_t ivl_expr_oper2(ivl_expr_t net)
463 465 assert(net);
464 466 switch (net->type_) {
465 467 case IVL_EX_BINARY:
466   - case IVL_EX_SELECT:
467 468 return net->u_.binary_.rig_;
468 469
  470 + case IVL_EX_SELECT:
  471 + return net->u_.select_.base_;
  472 +
469 473 case IVL_EX_TERNARY:
470 474 return net->u_.ternary_.true_e;
471 475
@@ -569,6 +573,13 @@ extern "C" ivl_scope_t ivl_expr_scope(ivl_expr_t net)
569 573 return net->u_.scope_.scope;
570 574 }
571 575
  576 +extern "C" ivl_select_type_t ivl_expr_sel_type(ivl_expr_t net)
  577 +{
  578 + assert(net);
  579 + assert(net->type_ == IVL_EX_SELECT);
  580 + return net->u_.select_.sel_type_;
  581 +}
  582 +
572 583 extern "C" ivl_signal_t ivl_expr_signal(ivl_expr_t net)
573 584 {
574 585 assert(net);
@@ -1467,6 +1478,12 @@ extern "C" ivl_expr_t ivl_lval_part_off(ivl_lval_t net)
1467 1478 return net->loff;
1468 1479 }
1469 1480
  1481 +extern "C" ivl_select_type_t ivl_lval_sel_type(ivl_lval_t net)
  1482 +{
  1483 + assert(net);
  1484 + return net->sel_type;
  1485 +}
  1486 +
1470 1487 extern "C" unsigned ivl_lval_width(ivl_lval_t net)
1471 1488 {
1472 1489 assert(net);
9 t-dll-expr.cc
@@ -359,13 +359,13 @@ void dll_target::expr_select(const NetESelect*net)
359 359 assert(expr_ == 0);
360 360
361 361 net->sub_expr()->expr_scan(this);
362   - ivl_expr_t left = expr_;
  362 + ivl_expr_t expr = expr_;
363 363
364 364 expr_ = 0;
365 365 if (net->select())
366 366 net->select()->expr_scan(this);
367 367
368   - ivl_expr_t rght = expr_;
  368 + ivl_expr_t base = expr_;
369 369
370 370 expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
371 371
@@ -376,8 +376,9 @@ void dll_target::expr_select(const NetESelect*net)
376 376 expr_->sized_= 1;
377 377 FILE_NAME(expr_, net);
378 378
379   - expr_->u_.binary_.lef_ = left;
380   - expr_->u_.binary_.rig_ = rght;
  379 + expr_->u_.select_.sel_type_ = net->select_type();
  380 + expr_->u_.select_.expr_ = expr;
  381 + expr_->u_.select_.base_ = base;
381 382 }
382 383
383 384 void dll_target::expr_sfunc(const NetESFunc*net)
2  t-dll-proc.cc
@@ -153,9 +153,11 @@ void dll_target::make_assign_lvals_(const NetAssignBase*net)
153 153
154 154 if (loff == 0) {
155 155 cur->loff = 0;
  156 + cur->sel_type = IVL_SEL_OTHER;
156 157 } else {
157 158 loff->expr_scan(this);
158 159 cur->loff = expr_;
  160 + cur->sel_type = asn->select_type();
159 161 expr_ = 0;
160 162 }
161 163
7 t-dll.h
@@ -232,6 +232,12 @@ struct ivl_expr_s {
232 232 } binary_;
233 233
234 234 struct {
  235 + ivl_select_type_t sel_type_;
  236 + ivl_expr_t expr_;
  237 + ivl_expr_t base_;
  238 + } select_;
  239 +
  240 + struct {
235 241 ivl_branch_t branch;
236 242 ivl_nature_t nature;
237 243 } branch_;
@@ -427,6 +433,7 @@ enum ivl_lval_type_t {
427 433
428 434 struct ivl_lval_s {
429 435 ivl_expr_t loff;
  436 + ivl_select_type_t sel_type;
430 437 ivl_expr_t idx;
431 438 unsigned width_;
432 439 unsigned type_ : 8;

0 comments on commit a6220fe

Please sign in to comment.
Something went wrong with that request. Please try again.