1 #ifndef IVL_PExpr_H 2 #define IVL_PExpr_H 3 /* 4 * Copyright (c) 1998-2019 Stephen Williams <steve@icarus.com> 5 * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) 6 * 7 * This source code is free software; you can redistribute it 8 * and/or modify it in source code form under the terms of the GNU 9 * General Public License as published by the Free Software 10 * Foundation; either version 2 of the License, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 */ 22 23 # include <string> 24 # include <vector> 25 # include <valarray> 26 # include "netlist.h" 27 # include "verinum.h" 28 # include "LineInfo.h" 29 # include "pform_types.h" 30 31 class Design; 32 class Module; 33 class LexicalScope; 34 class NetNet; 35 class NetExpr; 36 class NetScope; 37 class PPackage; 38 39 /* 40 * The PExpr class hierarchy supports the description of 41 * expressions. The parser can generate expression objects from the 42 * source, possibly reducing things that it knows how to reduce. 43 */ 44 45 class PExpr : public LineInfo { 46 47 public: 48 // Mode values used by test_width() (see below for description). 49 enum width_mode_t { SIZED, UNSIZED, EXPAND, LOSSLESS, UPSIZE }; 50 51 // Flag values that can be passed to elaborate_expr(). 52 static const unsigned NO_FLAGS = 0x0; 53 static const unsigned NEED_CONST = 0x1; 54 static const unsigned SYS_TASK_ARG = 0x2; 55 static const unsigned ANNOTATABLE = 0x4; 56 57 // Convert width mode to human-readable form. 58 static const char*width_mode_name(width_mode_t mode); 59 60 PExpr(); 61 virtual ~PExpr(); 62 63 virtual void dump(ostream&) const; 64 65 // This method tests whether the expression contains any identifiers 66 // that have not been previously declared in the specified scope or 67 // in any containing scope. Any such identifiers are added to the 68 // specified scope as scalar nets of the specified type. 69 // 70 // This operation must be performed by the parser, to ensure that 71 // subsequent declarations do not affect the decision to create an 72 // implicit net. 73 virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); 74 75 // This method tests whether the expression contains any 76 // references to automatically allocated variables. 77 virtual bool has_aa_term(Design*des, NetScope*scope) const; 78 79 // This method tests the type and width that the expression wants 80 // to be. It should be called before elaborating an expression to 81 // figure out the type and width of the expression. It also figures 82 // out the minimum width that can be used to evaluate the expression 83 // without changing the result. This allows the expression width to 84 // be pruned when not all bits of the result are used. 85 // 86 // Normally mode should be initialized to SIZED before starting to 87 // test the width of an expression. In SIZED mode the expression 88 // width will be calculated strictly according to the IEEE standard 89 // rules for expression width. 90 // 91 // If the expression is found to contain an unsized literal number 92 // and gn_strict_expr_width_flag is set, mode will be changed to 93 // UNSIZED. In UNSIZED mode the expression width will be calculated 94 // exactly as in SIZED mode - the change in mode simply flags that 95 // the expression contains an unsized numbers. 96 // 97 // If the expression is found to contain an unsized literal number 98 // and gn_strict_expr_width_flag is not set, mode will be changed 99 // to LOSSLESS. In LOSSLESS mode the expression width will be 100 // calculated as the minimum width necessary to avoid arithmetic 101 // overflow or underflow. 102 // 103 // Once in LOSSLESS mode, if the expression is found to contain 104 // an operation that coerces a vector operand to a different type 105 // (signed <-> unsigned), mode will be changed to UPSIZE. UPSIZE 106 // mode is the same as LOSSLESS, except that the final expression 107 // width will be forced to be at least integer_width. This is 108 // necessary to ensure compatibility with the IEEE standard, which 109 // requires unsized numbers to be treated as having the same width 110 // as an integer. The lossless width calculation is inadequate in 111 // this case because coercing an operand to a different type means 112 // that the expression no longer obeys the normal rules of arithmetic. 113 // 114 // If mode is initialized to EXPAND instead of SIZED, the expression 115 // width will be calculated as the minimum width necessary to avoid 116 // arithmetic overflow or underflow, even if it contains no unsized 117 // literals. mode will be changed LOSSLESS or UPSIZE as described 118 // above. This supports a non-standard mode of expression width 119 // calculation. 120 // 121 // When the final value of mode is UPSIZE, the width returned by 122 // this method is the calculated lossless width, but the width 123 // returned by a subsequent call to the expr_width method will be 124 // the final expression width. 125 virtual unsigned test_width(Design*des, NetScope*scope, 126 width_mode_t&mode); 127 128 // After the test_width method is complete, these methods 129 // return valid results. expr_type()130 ivl_variable_type_t expr_type() const { return expr_type_; } expr_width()131 unsigned expr_width() const { return expr_width_; } min_width()132 unsigned min_width() const { return min_width_; } has_sign()133 bool has_sign() const { return signed_flag_; } 134 135 // This method allows the expression type (signed/unsigned) 136 // to be propagated down to any context-dependant operands. cast_signed(bool flag)137 void cast_signed(bool flag) { signed_flag_ = flag; } 138 139 // This is the more generic form of the elaborate_expr method 140 // below. The plan is to replace the simpler elaborate_expr 141 // method with this version, which can handle more advanced 142 // types. But for now, this is only implemented in special cases. 143 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 144 ivl_type_t type, unsigned flags) const; 145 146 // Procedural elaboration of the expression. The expr_width is 147 // the required width of the expression. 148 // 149 // The sys_task_arg flag is true if expressions are allowed to 150 // be incomplete. 151 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 152 unsigned expr_wid, 153 unsigned flags) const; 154 155 // This method elaborates the expression as gates, but 156 // restricted for use as l-values of continuous assignments. 157 virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; 158 159 // This is similar to elaborate_lnet, except that the 160 // expression is evaluated to be bi-directional. This is 161 // useful for arguments to inout ports of module instances and 162 // ports of tran primitives. 163 virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; 164 165 // Expressions that can be in the l-value of procedural 166 // assignments can be elaborated with this method. If the 167 // is_cassign or is_force flags are true, then the set of 168 // valid l-value types is slightly modified to accommodate 169 // the Verilog procedural continuous assignment statements. 170 virtual NetAssign_* elaborate_lval(Design*des, 171 NetScope*scope, 172 bool is_cassign, 173 bool is_force) const; 174 175 // This attempts to evaluate a constant expression, and return 176 // a verinum as a result. If the expression cannot be 177 // evaluated, return 0. 178 virtual verinum* eval_const(Design*des, NetScope*sc) const; 179 180 // This method returns true if the expression represents a 181 // structural net that can have multiple drivers. This is 182 // used to test whether an input port connection can be 183 // collapsed to a single wire. 184 virtual bool is_collapsible_net(Design*des, NetScope*scope) const; 185 186 // This method returns true if that expression is the same as 187 // this expression. This method is used for comparing 188 // expressions that must be structurally "identical". 189 virtual bool is_the_same(const PExpr*that) const; 190 191 protected: 192 unsigned fix_width_(width_mode_t mode); 193 194 // The derived class test_width methods should fill these in. 195 ivl_variable_type_t expr_type_; 196 unsigned expr_width_; 197 unsigned min_width_; 198 bool signed_flag_; 199 200 private: // not implemented 201 PExpr(const PExpr&); 202 PExpr& operator= (const PExpr&); 203 }; 204 205 ostream& operator << (ostream&, const PExpr&); 206 207 class PEAssignPattern : public PExpr { 208 public: 209 explicit PEAssignPattern(); 210 explicit PEAssignPattern(const std::list<PExpr*>&p); 211 ~PEAssignPattern(); 212 213 void dump(std::ostream&) const; 214 215 virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode); 216 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 217 ivl_type_t type, unsigned flags) const; 218 219 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 220 unsigned expr_wid, 221 unsigned flags) const; 222 private: 223 NetExpr* elaborate_expr_darray_(Design*des, NetScope*scope, 224 ivl_type_t type, unsigned flags) const; 225 226 private: 227 std::vector<PExpr*>parms_; 228 }; 229 230 class PEConcat : public PExpr { 231 232 public: 233 PEConcat(const list<PExpr*>&p, PExpr*r =0); 234 ~PEConcat(); 235 236 virtual verinum* eval_const(Design*des, NetScope*sc) const; 237 virtual void dump(ostream&) const; 238 239 virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); 240 241 virtual bool has_aa_term(Design*des, NetScope*scope) const; 242 243 virtual unsigned test_width(Design*des, NetScope*scope, 244 width_mode_t&mode); 245 246 virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; 247 virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; 248 249 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 250 ivl_type_t type, unsigned flags) const; 251 252 virtual NetExpr*elaborate_expr(Design*des, NetScope*, 253 unsigned expr_wid, 254 unsigned flags) const; 255 virtual NetAssign_* elaborate_lval(Design*des, 256 NetScope*scope, 257 bool is_cassign, 258 bool is_force) const; 259 virtual bool is_collapsible_net(Design*des, NetScope*scope) const; 260 private: 261 NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, 262 bool bidirectional_flag) const; 263 private: 264 vector<PExpr*>parms_; 265 std::valarray<width_mode_t>width_modes_; 266 267 PExpr*repeat_; 268 NetScope*tested_scope_; 269 unsigned repeat_count_; 270 }; 271 272 /* 273 * Event expressions are expressions that can be combined with the 274 * event "or" operator. These include "posedge foo" and similar, and 275 * also include named events. "edge" events are associated with an 276 * expression, whereas named events simply have a name, which 277 * represents an event variable. 278 */ 279 class PEEvent : public PExpr { 280 281 public: 282 enum edge_t {ANYEDGE, POSEDGE, NEGEDGE, POSITIVE}; 283 284 // Use this constructor to create events based on edges or levels. 285 PEEvent(edge_t t, PExpr*e); 286 287 ~PEEvent(); 288 289 edge_t type() const; 290 PExpr* expr() const; 291 292 virtual void dump(ostream&) const; 293 294 virtual bool has_aa_term(Design*des, NetScope*scope) const; 295 296 private: 297 edge_t type_; 298 PExpr *expr_; 299 }; 300 301 /* 302 * This holds a floating point constant in the source. 303 */ 304 class PEFNumber : public PExpr { 305 306 public: 307 explicit PEFNumber(verireal*vp); 308 ~PEFNumber(); 309 310 const verireal& value() const; 311 312 /* The eval_const method as applied to a floating point number 313 gets the *integer* value of the number. This accounts for 314 any rounding that is needed to get the value. */ 315 virtual verinum* eval_const(Design*des, NetScope*sc) const; 316 317 virtual unsigned test_width(Design*des, NetScope*scope, 318 width_mode_t&mode); 319 virtual NetExpr*elaborate_expr(Design*des, NetScope*, 320 ivl_type_t type, unsigned flags) const; 321 virtual NetExpr*elaborate_expr(Design*des, NetScope*, 322 unsigned expr_wid, 323 unsigned flags) const; 324 325 virtual void dump(ostream&) const; 326 327 private: 328 verireal*value_; 329 }; 330 331 class PEIdent : public PExpr { 332 333 public: 334 explicit PEIdent(perm_string, bool no_implicit_sig=false); 335 explicit PEIdent(PPackage*pkg, const pform_name_t&name); 336 explicit PEIdent(const pform_name_t&); 337 ~PEIdent(); 338 339 // Add another name to the string of hierarchy that is the 340 // current identifier. 341 void append_name(perm_string); 342 343 virtual void dump(ostream&) const; 344 345 virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); 346 347 virtual bool has_aa_term(Design*des, NetScope*scope) const; 348 349 virtual unsigned test_width(Design*des, NetScope*scope, 350 width_mode_t&mode); 351 352 // Identifiers are allowed (with restrictions) is assign l-values. 353 virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const; 354 355 virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const; 356 357 // Identifiers are also allowed as procedural assignment l-values. 358 virtual NetAssign_* elaborate_lval(Design*des, 359 NetScope*scope, 360 bool is_cassign, 361 bool is_force) const; 362 363 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 364 ivl_type_t type, unsigned flags) const; 365 virtual NetExpr*elaborate_expr(Design*des, NetScope*, 366 unsigned expr_wid, 367 unsigned flags) const; 368 369 // Elaborate the PEIdent as a port to a module. This method 370 // only applies to Ident expressions. 371 NetNet* elaborate_subport(Design*des, NetScope*sc) const; 372 373 // Elaborate the identifier allowing for unpacked arrays. This 374 // method only applies to Ident expressions because only Ident 375 // expressions can can be unpacked arrays. 376 NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const; 377 378 verinum* eval_const(Design*des, NetScope*sc) const; 379 380 virtual bool is_collapsible_net(Design*des, NetScope*scope) const; 381 package()382 const PPackage* package() const { return package_; } 383 path()384 const pform_name_t& path() const { return path_; } 385 386 private: 387 PPackage*package_; 388 pform_name_t path_; 389 bool no_implicit_sig_; 390 391 private: 392 // Common functions to calculate parts of part/bit 393 // selects. These methods return true if the expressions 394 // elaborate/calculate, or false if there is some sort of 395 // source error. 396 397 bool calculate_bits_(Design*, NetScope*, long&msb, bool&defined) const; 398 399 // The calculate_parts_ method calculates the range 400 // expressions of a part select for the current object. The 401 // part select expressions are elaborated and evaluated, and 402 // the values written to the msb/lsb arguments. If there are 403 // invalid bits (xz) in either expression, then the defined 404 // flag is set to *false*. 405 bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const; 406 NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const; 407 bool calculate_param_range_(Design*, NetScope*, 408 const NetExpr*msb_ex, long&msb, 409 const NetExpr*lsb_ex, long&lsb, 410 long length) const; 411 412 bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const; 413 414 // Evaluate the prefix indices. All but the final index in a 415 // chain of indices must be a single value and must evaluate 416 // to constants at compile time. For example: 417 // [x] - OK 418 // [1][2][x] - OK 419 // [1][x:y] - OK 420 // [2:0][x] - BAD 421 // [y][x] - BAD 422 // Leave the last index for special handling. 423 bool calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net, 424 std::list<long>&prefix_indices) const; 425 426 private: 427 NetAssign_*elaborate_lval_method_class_member_(Design*, NetScope*) const; 428 NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*, 429 bool need_const_idx) const; 430 bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*, 431 bool need_const_idx) const; 432 bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const; 433 bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*, 434 index_component_t::ctype_t, 435 bool need_const_idx) const; 436 NetAssign_*elaborate_lval_net_class_member_(Design*, NetScope*, 437 NetNet*, 438 pform_name_t) const; 439 bool elaborate_lval_net_packed_member_(Design*, NetScope*, 440 NetAssign_*, 441 pform_name_t member_path) const; 442 bool elaborate_lval_darray_bit_(Design*, NetScope*, 443 NetAssign_*) const; 444 445 private: 446 NetExpr*elaborate_expr_param_(Design*des, 447 NetScope*scope, 448 const NetExpr*par, 449 NetScope*found_in, 450 const NetExpr*par_msb, 451 const NetExpr*par_lsb, 452 unsigned expr_wid, 453 unsigned flags) const; 454 NetExpr*elaborate_expr_param_bit_(Design*des, 455 NetScope*scope, 456 const NetExpr*par, 457 NetScope*found_in, 458 const NetExpr*par_msb, 459 const NetExpr*par_lsb, 460 bool need_const) const; 461 NetExpr*elaborate_expr_param_part_(Design*des, 462 NetScope*scope, 463 const NetExpr*par, 464 NetScope*found_in, 465 const NetExpr*par_msb, 466 const NetExpr*par_lsb, 467 unsigned expr_wid) const; 468 NetExpr*elaborate_expr_param_idx_up_(Design*des, 469 NetScope*scope, 470 const NetExpr*par, 471 NetScope*found_in, 472 const NetExpr*par_msb, 473 const NetExpr*par_lsb, 474 bool need_const) const; 475 NetExpr*elaborate_expr_param_idx_do_(Design*des, 476 NetScope*scope, 477 const NetExpr*par, 478 NetScope*found_in, 479 const NetExpr*par_msb, 480 const NetExpr*par_lsb, 481 bool need_const) const; 482 NetExpr*elaborate_expr_net(Design*des, 483 NetScope*scope, 484 NetNet*net, 485 NetScope*found, 486 unsigned expr_wid, 487 unsigned flags) const; 488 NetExpr*elaborate_expr_net_word_(Design*des, 489 NetScope*scope, 490 NetNet*net, 491 NetScope*found, 492 unsigned expr_wid, 493 unsigned flags) const; 494 NetExpr*elaborate_expr_net_part_(Design*des, 495 NetScope*scope, 496 NetESignal*net, 497 NetScope*found, 498 unsigned expr_wid) const; 499 NetExpr*elaborate_expr_net_idx_up_(Design*des, 500 NetScope*scope, 501 NetESignal*net, 502 NetScope*found, 503 bool need_const) const; 504 NetExpr*elaborate_expr_net_idx_do_(Design*des, 505 NetScope*scope, 506 NetESignal*net, 507 NetScope*found, 508 bool need_const) const; 509 NetExpr*elaborate_expr_net_bit_(Design*des, 510 NetScope*scope, 511 NetESignal*net, 512 NetScope*found, 513 bool need_const) const; 514 NetExpr*elaborate_expr_net_bit_last_(Design*des, 515 NetScope*scope, 516 NetESignal*net, 517 NetScope*found, 518 bool need_const) const; 519 520 NetExpr*elaborate_expr_class_member_(Design*des, 521 NetScope*scope, 522 unsigned expr_wid, 523 unsigned flags) const; 524 525 unsigned test_width_method_(Design*des, NetScope*scope, width_mode_t&mode); 526 527 528 private: 529 NetNet* elaborate_lnet_common_(Design*des, NetScope*scope, 530 bool bidirectional_flag) const; 531 532 533 bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig, 534 long&midx, long&lidx) const; 535 }; 536 537 class PENewArray : public PExpr { 538 539 public: 540 explicit PENewArray (PExpr*s, PExpr*i); 541 ~PENewArray(); 542 543 virtual void dump(ostream&) const; 544 virtual unsigned test_width(Design*des, NetScope*scope, 545 width_mode_t&mode); 546 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 547 ivl_type_t type, unsigned flags) const; 548 virtual NetExpr*elaborate_expr(Design*des, NetScope*, 549 unsigned expr_wid, 550 unsigned flags) const; 551 552 private: 553 PExpr*size_; 554 PExpr*init_; 555 }; 556 557 class PENewClass : public PExpr { 558 559 public: 560 // New without (or with default) constructor 561 explicit PENewClass (); 562 // New with constructor arguments 563 explicit PENewClass (const std::list<PExpr*>&p); 564 565 ~PENewClass(); 566 567 virtual void dump(ostream&) const; 568 // Class objects don't have a useful width, but the expression 569 // is IVL_VT_CLASS. 570 virtual unsigned test_width(Design*des, NetScope*scope, 571 width_mode_t&mode); 572 // Note that class (new) expressions only appear in context 573 // that uses this form of the elaborate_expr method. In fact, 574 // the type argument is going to be a netclass_t object. 575 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 576 ivl_type_t type, unsigned flags) const; 577 578 private: 579 NetExpr* elaborate_expr_constructor_(Design*des, NetScope*scope, 580 const netclass_t*ctype, 581 NetExpr*obj, unsigned flags) const; 582 583 private: 584 std::vector<PExpr*>parms_; 585 }; 586 587 class PENewCopy : public PExpr { 588 public: 589 explicit PENewCopy(PExpr*src); 590 ~PENewCopy(); 591 592 virtual void dump(ostream&) const; 593 // Class objects don't have a useful width, but the expression 594 // is IVL_VT_CLASS. 595 virtual unsigned test_width(Design*des, NetScope*scope, 596 width_mode_t&mode); 597 // Note that class (new) expressions only appear in context 598 // that uses this form of the elaborate_expr method. In fact, 599 // the type argument is going to be a netclass_t object. 600 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 601 ivl_type_t type, unsigned flags) const; 602 603 private: 604 PExpr*src_; 605 }; 606 607 class PENull : public PExpr { 608 public: 609 explicit PENull(); 610 ~PENull(); 611 612 virtual void dump(ostream&) const; 613 virtual unsigned test_width(Design*des, NetScope*scope, 614 width_mode_t&mode); 615 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 616 ivl_type_t type, unsigned flags) const; 617 virtual NetExpr*elaborate_expr(Design*des, NetScope*, 618 unsigned expr_wid, 619 unsigned flags) const; 620 }; 621 622 class PENumber : public PExpr { 623 624 public: 625 explicit PENumber(verinum*vp); 626 ~PENumber(); 627 628 const verinum& value() const; 629 630 virtual void dump(ostream&) const; 631 virtual unsigned test_width(Design*des, NetScope*scope, 632 width_mode_t&mode); 633 634 virtual NetExpr *elaborate_expr(Design*des, NetScope*scope, 635 ivl_type_t type, unsigned flags) const; 636 virtual NetEConst*elaborate_expr(Design*des, NetScope*, 637 unsigned expr_wid, unsigned) const; 638 virtual NetAssign_* elaborate_lval(Design*des, 639 NetScope*scope, 640 bool is_cassign, 641 bool is_force) const; 642 643 virtual verinum* eval_const(Design*des, NetScope*sc) const; 644 645 virtual bool is_the_same(const PExpr*that) const; 646 647 private: 648 verinum*const value_; 649 }; 650 651 /* 652 * This represents a string constant in an expression. 653 * 654 * The s parameter to the PEString constructor is a C string that this 655 * class instance will take for its own. The caller should not delete 656 * the string, the destructor will do it. 657 */ 658 class PEString : public PExpr { 659 660 public: 661 explicit PEString(char*s); 662 ~PEString(); 663 664 string value() const; 665 virtual void dump(ostream&) const; 666 667 virtual unsigned test_width(Design*des, NetScope*scope, 668 width_mode_t&mode); 669 670 virtual NetEConst*elaborate_expr(Design*des, NetScope*scope, 671 ivl_type_t type, unsigned flags) const; 672 673 virtual NetEConst*elaborate_expr(Design*des, NetScope*, 674 unsigned expr_wid, unsigned) const; 675 verinum* eval_const(Design*, NetScope*) const; 676 677 private: 678 char*text_; 679 }; 680 681 class PETypename : public PExpr { 682 public: 683 explicit PETypename(data_type_t*data_type); 684 ~PETypename(); 685 686 virtual void dump(ostream&) const; 687 virtual unsigned test_width(Design*des, NetScope*scope, 688 width_mode_t&mode); 689 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 690 ivl_type_t type, unsigned flags) const; 691 get_type()692 inline data_type_t* get_type() const { return data_type_; } 693 694 private: 695 data_type_t*data_type_; 696 }; 697 698 class PEUnary : public PExpr { 699 700 public: 701 explicit PEUnary(char op, PExpr*ex); 702 ~PEUnary(); 703 704 virtual void dump(ostream&out) const; 705 706 virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); 707 708 virtual bool has_aa_term(Design*des, NetScope*scope) const; 709 710 virtual unsigned test_width(Design*des, NetScope*scope, 711 width_mode_t&mode); 712 713 virtual NetExpr*elaborate_expr(Design*des, NetScope*, 714 unsigned expr_wid, 715 unsigned flags) const; 716 virtual verinum* eval_const(Design*des, NetScope*sc) const; 717 718 public: get_op()719 inline char get_op() const { return op_; } get_expr()720 inline PExpr*get_expr() const { return expr_; } 721 722 private: 723 NetExpr* elaborate_expr_bits_(NetExpr*operand, unsigned expr_wid) const; 724 725 private: 726 char op_; 727 PExpr*expr_; 728 }; 729 730 class PEBinary : public PExpr { 731 732 public: 733 explicit PEBinary(char op, PExpr*l, PExpr*r); 734 ~PEBinary(); 735 736 virtual void dump(ostream&out) const; 737 738 virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); 739 740 virtual bool has_aa_term(Design*des, NetScope*scope) const; 741 742 virtual unsigned test_width(Design*des, NetScope*scope, 743 width_mode_t&mode); 744 745 virtual NetExpr*elaborate_expr(Design*des, NetScope*, 746 unsigned expr_wid, 747 unsigned flags) const; 748 virtual verinum* eval_const(Design*des, NetScope*sc) const; 749 750 protected: 751 char op_; 752 PExpr*left_; 753 PExpr*right_; 754 755 NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, 756 unsigned expr_wid) const; 757 NetExpr*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, 758 unsigned expr_wid) const; 759 760 NetExpr*elaborate_expr_base_bits_(Design*, NetExpr*lp, NetExpr*rp, 761 unsigned expr_wid) const; 762 NetExpr*elaborate_expr_base_div_(Design*, NetExpr*lp, NetExpr*rp, 763 unsigned expr_wid) const; 764 NetExpr*elaborate_expr_base_mult_(Design*, NetExpr*lp, NetExpr*rp, 765 unsigned expr_wid) const; 766 NetExpr*elaborate_expr_base_add_(Design*, NetExpr*lp, NetExpr*rp, 767 unsigned expr_wid) const; 768 769 }; 770 771 /* 772 * Here are a few specialized classes for handling specific binary 773 * operators. 774 */ 775 class PEBComp : public PEBinary { 776 777 public: 778 explicit PEBComp(char op, PExpr*l, PExpr*r); 779 ~PEBComp(); 780 781 virtual unsigned test_width(Design*des, NetScope*scope, 782 width_mode_t&mode); 783 784 NetExpr* elaborate_expr(Design*des, NetScope*scope, 785 unsigned expr_wid, unsigned flags) const; 786 787 private: 788 unsigned l_width_; 789 unsigned r_width_; 790 }; 791 792 /* 793 * This derived class is for handling logical expressions: && and ||. 794 */ 795 class PEBLogic : public PEBinary { 796 797 public: 798 explicit PEBLogic(char op, PExpr*l, PExpr*r); 799 ~PEBLogic(); 800 801 virtual unsigned test_width(Design*des, NetScope*scope, 802 width_mode_t&mode); 803 804 NetExpr* elaborate_expr(Design*des, NetScope*scope, 805 unsigned expr_wid, unsigned flags) const; 806 }; 807 808 /* 809 * A couple of the binary operands have a special sub-expression rule 810 * where the expression width is carried entirely by the left 811 * expression, and the right operand is self-determined. 812 */ 813 class PEBLeftWidth : public PEBinary { 814 815 public: 816 explicit PEBLeftWidth(char op, PExpr*l, PExpr*r); 817 ~PEBLeftWidth() =0; 818 819 virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, 820 unsigned expr_wid) const =0; 821 822 protected: 823 virtual unsigned test_width(Design*des, NetScope*scope, 824 width_mode_t&mode); 825 826 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 827 unsigned expr_wid, 828 unsigned flags) const; 829 }; 830 831 class PEBPower : public PEBLeftWidth { 832 833 public: 834 explicit PEBPower(char op, PExpr*l, PExpr*r); 835 ~PEBPower(); 836 837 NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, 838 unsigned expr_wid) const; 839 }; 840 841 class PEBShift : public PEBLeftWidth { 842 843 public: 844 explicit PEBShift(char op, PExpr*l, PExpr*r); 845 ~PEBShift(); 846 847 NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp, 848 unsigned expr_wid) const; 849 }; 850 851 /* 852 * This class supports the ternary (?:) operator. The operator takes 853 * three expressions, the test, the true result and the false result. 854 */ 855 class PETernary : public PExpr { 856 857 public: 858 explicit PETernary(PExpr*e, PExpr*t, PExpr*f); 859 ~PETernary(); 860 861 virtual void dump(ostream&out) const; 862 863 virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); 864 865 virtual bool has_aa_term(Design*des, NetScope*scope) const; 866 867 virtual unsigned test_width(Design*des, NetScope*scope, 868 width_mode_t&mode); 869 870 virtual NetExpr*elaborate_expr(Design*des, NetScope*, 871 unsigned expr_wid, 872 unsigned flags) const; 873 virtual verinum* eval_const(Design*des, NetScope*sc) const; 874 875 private: 876 NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope, 877 PExpr*expr, unsigned expr_wid, 878 unsigned flags, bool short_cct) const; 879 880 private: 881 PExpr*expr_; 882 PExpr*tru_; 883 PExpr*fal_; 884 }; 885 886 /* 887 * This class represents a parsed call to a function, including calls 888 * to system functions. The parameters in the parms list are the 889 * expressions that are passed as input to the ports of the function. 890 */ 891 class PECallFunction : public PExpr { 892 public: 893 explicit PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms); 894 // Call function defined in package. 895 explicit PECallFunction(PPackage*pkg, perm_string n, const std::vector<PExpr *> &parms); 896 explicit PECallFunction(PPackage*pkg, perm_string n, const std::list<PExpr *> &parms); 897 898 // Used to convert a user function called as a task 899 explicit PECallFunction(PPackage*pkg, const pform_name_t&n, const std::vector<PExpr *> &parms); 900 901 // Call of system function (name is not hierarchical) 902 explicit PECallFunction(perm_string n, const vector<PExpr *> &parms); 903 explicit PECallFunction(perm_string n); 904 905 // std::list versions. Should be removed! 906 explicit PECallFunction(const pform_name_t&n, const list<PExpr *> &parms); 907 explicit PECallFunction(perm_string n, const list<PExpr *> &parms); 908 909 ~PECallFunction(); 910 911 virtual void dump(ostream &) const; 912 913 virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type); 914 915 virtual bool has_aa_term(Design*des, NetScope*scope) const; 916 917 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 918 ivl_type_t type, unsigned flags) const; 919 920 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 921 unsigned expr_wid, unsigned flags) const; 922 923 virtual unsigned test_width(Design*des, NetScope*scope, 924 width_mode_t&mode); 925 926 private: 927 PPackage*package_; 928 pform_name_t path_; 929 std::vector<PExpr *> parms_; 930 931 // For system functions. 932 bool is_overridden_; 933 934 bool check_call_matches_definition_(Design*des, NetScope*dscope) const; 935 936 937 NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const; 938 939 NetExpr*elaborate_expr_pkg_(Design*des, NetScope*scope, 940 unsigned expr_wid, unsigned flags)const; 941 NetExpr*elaborate_expr_method_(Design*des, NetScope*scope, 942 unsigned expr_wid, 943 bool add_this_flag = false) const; 944 #if 0 945 NetExpr*elaborate_expr_string_method_(Design*des, NetScope*scope) const; 946 NetExpr*elaborate_expr_enum_method_(Design*des, NetScope*scope, 947 unsigned expr_wid) const; 948 #endif 949 950 NetExpr* elaborate_sfunc_(Design*des, NetScope*scope, 951 unsigned expr_wid, 952 unsigned flags) const; 953 NetExpr* elaborate_access_func_(Design*des, NetScope*scope, ivl_nature_t, 954 unsigned expr_wid) const; 955 unsigned test_width_sfunc_(Design*des, NetScope*scope, 956 width_mode_t&mode); 957 unsigned test_width_method_(Design*des, NetScope*scope, 958 width_mode_t&mode); 959 960 NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope, 961 unsigned expr_wid, unsigned flags) const; 962 963 unsigned elaborate_arguments_(Design*des, NetScope*scope, 964 NetFuncDef*def, bool need_const, 965 std::vector<NetExpr*>&parms, 966 unsigned parm_off) const; 967 }; 968 969 /* 970 * Support the SystemVerilog cast to size. 971 */ 972 class PECastSize : public PExpr { 973 974 public: 975 explicit PECastSize(PExpr*size, PExpr*base); 976 ~PECastSize(); 977 978 void dump(ostream &out) const; 979 980 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 981 unsigned expr_wid, 982 unsigned flags) const; 983 984 virtual unsigned test_width(Design*des, NetScope*scope, 985 width_mode_t&mode); 986 987 private: 988 PExpr* size_; 989 PExpr* base_; 990 }; 991 992 /* 993 * Support the SystemVerilog cast to a different type. 994 */ 995 class PECastType : public PExpr { 996 997 public: 998 explicit PECastType(data_type_t*target, PExpr*base); 999 ~PECastType(); 1000 1001 void dump(ostream &out) const; 1002 1003 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 1004 ivl_type_t type, unsigned flags) const; 1005 1006 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 1007 unsigned expr_wid, unsigned flags) const; 1008 1009 virtual unsigned test_width(Design*des, NetScope*scope, 1010 width_mode_t&mode); 1011 1012 private: 1013 data_type_t* target_; 1014 PExpr* base_; 1015 }; 1016 1017 /* 1018 * This class is used for error recovery. All methods do nothing and return 1019 * null or default values. 1020 */ 1021 class PEVoid : public PExpr { 1022 1023 public: 1024 explicit PEVoid(); 1025 ~PEVoid(); 1026 1027 virtual NetExpr*elaborate_expr(Design*des, NetScope*scope, 1028 unsigned expr_wid, 1029 unsigned flags) const; 1030 }; 1031 1032 #endif /* IVL_PExpr_H */ 1033