4 * Copyright (c) 1998-2000 Stephen Williams <steve@icarus.com>
6 * This source code is free software; you can redistribute it
7 * and/or modify it in source code form under the terms of the GNU
8 * General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 #ident "$Id: PExpr.h,v 1.90 2007/06/04 19:14:06 steve Exp $"
29 # include "LineInfo.h"
30 # include "pform_types.h"
39 * The PExpr class hierarchy supports the description of
40 * expressions. The parser can generate expression objects from the
41 * source, possibly reducing things that it knows how to reduce.
43 * The elaborate_net method is used by structural elaboration to build
44 * up a netlist interpretation of the expression.
47 class PExpr
: public LineInfo
{
53 virtual void dump(ostream
&) const;
55 // This method tests the width that the expression wants to
56 // be. It is used by elaboration of assignments to figure out
57 // the width of the expression.
59 // The "min" is the width of the local context, so it the
60 // minimum width that this function should return. Initially
61 // this is the same as the lval width.
63 // The "lval" is the width of the destination where this
64 // result is going to go. This can be used to constrain the
65 // amount that an expression can reasonably expand. For
66 // example, there is no point expanding an addition to beyond
67 // the lval. This extra bit of information allows the
68 // expression to optimize itself a bit. If the lval==0, then
69 // the subexpression should not make l-value related
72 // The unsigned_flag is set to true if the expression is
73 // unsized and therefore expandable. This happens if a
74 // sub-expression is an unsized literal. Some expressions make
75 // special use of that.
76 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
77 unsigned min
, unsigned lval
,
78 bool&unsized_flag
) const;
80 // Procedural elaboration of the expression. The expr_width is
81 // the width of the context of the expression (i.e. the
82 // l-value width of an assignment),
84 // ... or -1 if the expression is self-determined. or
85 // ... or -2 if the expression is losslessly
86 // self-determined. This can happen in situations where the
87 // result is going to a pseudo-infinitely wide context.
89 // The sys_task_arg flag is true if expressions are allowed to
91 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*scope
,
92 int expr_width
, bool sys_task_arg
) const;
94 // Elaborate expressions that are the r-value of parameter
95 // assignments. This elaboration follows the restrictions of
96 // constant expressions and supports later overriding and
97 // evaluation of parameters.
98 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
100 // This method elaborate the expression as gates, for use in a
101 // continuous assign or other wholly structural context.
102 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
106 const NetExpr
* decay
,
107 Link::strength_t drive0
=Link::STRONG
,
108 Link::strength_t drive1
=Link::STRONG
)
111 // This method elaborates the expression as gates, but
112 // restricted for use as l-values of continuous assignments.
113 virtual NetNet
* elaborate_lnet(Design
*des
, NetScope
*scope
,
114 bool implicit_net_ok
=false) const;
116 // This is similar to elaborate_lnet, except that the
117 // expression is evaluated to be bi-directional. This is
118 // useful for arguments to inout ports of module instances and
119 // ports of tran primitives.
120 virtual NetNet
* elaborate_bi_net(Design
*des
, NetScope
*scope
) const;
122 // Expressions that can be in the l-value of procedural
123 // assignments can be elaborated with this method. If the
124 // is_force flag is true, then the set of valid l-value types
125 // is slightly modified to accomodate the Verilog force
127 virtual NetAssign_
* elaborate_lval(Design
*des
,
129 bool is_force
) const;
131 // This attempts to evaluate a constant expression, and return
132 // a verinum as a result. If the expression cannot be
133 // evaluated, return 0.
134 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
136 // This method returns true if that expression is the same as
137 // this expression. This method is used for comparing
138 // expressions that must be structurally "identical".
139 virtual bool is_the_same(const PExpr
*that
) const;
141 // Return true if this expression is a valid constant
142 // expression. the Module pointer is needed to find parameter
143 // identifiers and any other module specific interpretations
145 virtual bool is_constant(Module
*) const;
147 private: // not implemented
149 PExpr
& operator= (const PExpr
&);
152 ostream
& operator << (ostream
&, const PExpr
&);
154 class PEConcat
: public PExpr
{
157 PEConcat(const svector
<PExpr
*>&p
, PExpr
*r
=0);
160 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
161 virtual void dump(ostream
&) const;
163 virtual NetNet
* elaborate_lnet(Design
*des
, NetScope
*scope
,
164 bool implicit_net_ok
=false) const;
165 virtual NetNet
* elaborate_bi_net(Design
*des
, NetScope
*scope
) const;
166 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
170 const NetExpr
* decay
,
171 Link::strength_t drive0
,
172 Link::strength_t drive1
) const;
173 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*,
174 int expr_width
, bool sys_task_arg
) const;
175 virtual NetEConcat
*elaborate_pexpr(Design
*des
, NetScope
*) const;
176 virtual NetAssign_
* elaborate_lval(Design
*des
,
178 bool is_force
) const;
179 virtual bool is_constant(Module
*) const;
182 NetNet
* elaborate_lnet_common_(Design
*des
, NetScope
*scope
,
183 bool implicit_net_ok
,
184 bool bidirectional_flag
) const;
186 svector
<PExpr
*>parms_
;
191 * Event expressions are expressions that can be combined with the
192 * event "or" operator. These include "posedge foo" and similar, and
193 * also include named events. "edge" events are associated with an
194 * expression, whereas named events simply have a name, which
195 * represents an event variable.
197 class PEEvent
: public PExpr
{
200 enum edge_t
{ANYEDGE
, POSEDGE
, NEGEDGE
, POSITIVE
};
202 // Use this constructor to create events based on edges or levels.
203 PEEvent(edge_t t
, PExpr
*e
);
210 virtual void dump(ostream
&) const;
218 * This holds a floating point constant in the source.
220 class PEFNumber
: public PExpr
{
223 explicit PEFNumber(verireal
*vp
);
226 const verireal
& value() const;
228 /* The eval_const method as applied to a floating point number
229 gets the *integer* value of the number. This accounts for
230 any rounding that is needed to get the value. */
231 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
233 /* A PEFNumber is a constant, so this returns true. */
234 virtual bool is_constant(Module
*) const;
236 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*,
237 int expr_width
, bool sys_task_arg
) const;
238 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
240 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
244 const NetExpr
* decay
,
245 Link::strength_t drive0
,
246 Link::strength_t drive1
) const;
248 virtual void dump(ostream
&) const;
254 class PEIdent
: public PExpr
{
257 explicit PEIdent(perm_string
);
258 explicit PEIdent(const pform_name_t
&);
261 // Add another name to the string of heirarchy that is the
262 // current identifier.
263 void append_name(perm_string
);
265 virtual void dump(ostream
&) const;
266 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
267 unsigned min
, unsigned lval
,
268 bool&unsized_flag
) const;
270 // Identifiers are allowed (with restrictions) is assign l-values.
271 virtual NetNet
* elaborate_lnet(Design
*des
, NetScope
*scope
,
272 bool implicit_net_ok
=false) const;
274 virtual NetNet
* elaborate_bi_net(Design
*des
, NetScope
*scope
) const;
276 // Identifiers are also allowed as procedural assignment l-values.
277 virtual NetAssign_
* elaborate_lval(Design
*des
,
279 bool is_force
) const;
281 // Structural r-values are OK.
282 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
286 const NetExpr
* decay
,
287 Link::strength_t drive0
,
288 Link::strength_t drive1
) const;
290 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*,
291 int expr_width
, bool sys_task_arg
) const;
292 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
294 // Elaborate the PEIdent as a port to a module. This method
295 // only applies to Ident expressions.
296 NetNet
* elaborate_port(Design
*des
, NetScope
*sc
) const;
298 virtual bool is_constant(Module
*) const;
299 verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
301 const pform_name_t
& path() const { return path_
; }
307 // Common functions to calculate parts of part/bit selects.
308 bool calculate_parts_(Design
*, NetScope
*, long&msb
, long&lsb
) const;
309 bool calculate_up_do_width_(Design
*, NetScope
*, unsigned long&wid
) const;
312 NetAssign_
*elaborate_lval_net_word_(Design
*, NetScope
*, NetNet
*) const;
313 bool elaborate_lval_net_part_(Design
*, NetScope
*, NetAssign_
*) const;
314 bool elaborate_lval_net_idx_up_(Design
*, NetScope
*, NetAssign_
*) const;
315 bool elaborate_lval_net_idx_do_(Design
*, NetScope
*, NetAssign_
*) const;
318 NetExpr
*elaborate_expr_param(Design
*des
,
322 const NetExpr
*par_msb
,
323 const NetExpr
*par_lsb
) const;
324 NetExpr
*elaborate_expr_net(Design
*des
,
328 bool sys_task_arg
) const;
329 NetExpr
*elaborate_expr_net_word_(Design
*des
,
333 bool sys_task_arg
) const;
334 NetExpr
*elaborate_expr_net_part_(Design
*des
,
337 NetScope
*found
) const;
338 NetExpr
*elaborate_expr_net_idx_up_(Design
*des
,
341 NetScope
*found
) const;
342 NetExpr
*elaborate_expr_net_idx_do_(Design
*des
,
345 NetScope
*found
) const;
346 NetExpr
*elaborate_expr_net_bit_(Design
*des
,
349 NetScope
*found
) const;
353 NetNet
* elaborate_net_array_(Design
*des
, NetScope
*scope
,
354 NetNet
*sig
, unsigned lwidth
,
357 const NetExpr
* decay
,
358 Link::strength_t drive0
,
359 Link::strength_t drive1
) const;
361 NetNet
* elaborate_net_net_(Design
*des
, NetScope
*scope
,
362 NetNet
*sig
, unsigned lwidth
,
365 const NetExpr
* decay
,
366 Link::strength_t drive0
,
367 Link::strength_t drive1
) const;
368 NetNet
* elaborate_net_net_idx_up_(Design
*des
, NetScope
*scope
,
369 NetNet
*sig
, unsigned lwidth
,
372 const NetExpr
* decay
,
373 Link::strength_t drive0
,
374 Link::strength_t drive1
) const;
375 NetNet
* elaborate_net_bitmux_(Design
*des
, NetScope
*scope
,
379 const NetExpr
* decay
,
380 Link::strength_t drive0
,
381 Link::strength_t drive1
) const;
384 NetNet
* elaborate_lnet_common_(Design
*des
, NetScope
*scope
,
385 bool implicit_net_ok
,
386 bool bidirectional_flag
) const;
388 NetNet
*make_implicit_net_(Design
*des
, NetScope
*scope
) const;
390 bool eval_part_select_(Design
*des
, NetScope
*scope
, NetNet
*sig
,
391 unsigned&midx
, unsigned&lidx
) const;
392 NetNet
*process_select_(Design
*des
, NetScope
*scope
, NetNet
*sig
) const;
396 class PENumber
: public PExpr
{
399 explicit PENumber(verinum
*vp
);
402 const verinum
& value() const;
404 virtual void dump(ostream
&) const;
405 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
406 unsigned min
, unsigned lval
,
407 bool&unsized_flag
) const;
409 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
413 const NetExpr
* decay
,
414 Link::strength_t drive0
,
415 Link::strength_t drive1
) const;
416 virtual NetEConst
*elaborate_expr(Design
*des
, NetScope
*,
417 int expr_width
, bool) const;
418 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
419 virtual NetAssign_
* elaborate_lval(Design
*des
,
421 bool is_force
) const;
423 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
425 virtual bool is_the_same(const PExpr
*that
) const;
426 virtual bool is_constant(Module
*) const;
429 verinum
*const value_
;
433 * This represents a string constant in an expression.
435 * The s parameter to the PEString constructor is a C string that this
436 * class instance will take for its own. The caller should not delete
437 * the string, the destructor will do it.
439 class PEString
: public PExpr
{
442 explicit PEString(char*s
);
445 string
value() const;
446 virtual void dump(ostream
&) const;
448 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
449 unsigned min
, unsigned lval
,
450 bool&unsized_flag
) const;
452 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
456 const NetExpr
* decay
,
457 Link::strength_t drive0
,
458 Link::strength_t drive1
) const;
459 virtual NetEConst
*elaborate_expr(Design
*des
, NetScope
*,
460 int expr_width
, bool) const;
461 virtual NetEConst
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
462 verinum
* eval_const(Design
*, NetScope
*) const;
464 virtual bool is_constant(Module
*) const;
470 class PEUnary
: public PExpr
{
473 explicit PEUnary(char op
, PExpr
*ex
);
476 virtual void dump(ostream
&out
) const;
478 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
482 const NetExpr
* decay
,
483 Link::strength_t drive0
,
484 Link::strength_t drive1
) const;
485 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*,
486 int expr_width
, bool sys_task_arg
) const;
487 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
488 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
490 virtual bool is_constant(Module
*) const;
497 class PEBinary
: public PExpr
{
500 explicit PEBinary(char op
, PExpr
*l
, PExpr
*r
);
503 virtual bool is_constant(Module
*) const;
505 virtual void dump(ostream
&out
) const;
507 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
508 unsigned min
, unsigned lval
,
509 bool&unsized_flag
) const;
511 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
515 const NetExpr
* decay
,
516 Link::strength_t drive0
,
517 Link::strength_t drive1
) const;
518 virtual NetEBinary
*elaborate_expr(Design
*des
, NetScope
*,
519 int expr_width
, bool sys_task_arg
) const;
520 virtual NetExpr
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
521 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
528 NetEBinary
*elaborate_expr_base_(Design
*, NetExpr
*lp
, NetExpr
*rp
, int use_wid
) const;
529 NetEBinary
*elaborate_eval_expr_base_(Design
*, NetExpr
*lp
, NetExpr
*rp
, int use_wid
) const;
532 NetNet
* elaborate_net_add_(Design
*des
, NetScope
*scope
,
536 const NetExpr
* decay
) const;
537 NetNet
* elaborate_net_bit_(Design
*des
, NetScope
*scope
,
541 const NetExpr
* decay
) const;
542 NetNet
* elaborate_net_cmp_(Design
*des
, NetScope
*scope
,
546 const NetExpr
* decay
) const;
547 NetNet
* elaborate_net_div_(Design
*des
, NetScope
*scope
,
551 const NetExpr
* decay
) const;
552 NetNet
* elaborate_net_mod_(Design
*des
, NetScope
*scope
,
556 const NetExpr
* decay
) const;
557 NetNet
* elaborate_net_log_(Design
*des
, NetScope
*scope
,
561 const NetExpr
* decay
) const;
562 NetNet
* elaborate_net_mul_(Design
*des
, NetScope
*scope
,
566 const NetExpr
* decay
) const;
567 NetNet
* elaborate_net_shift_(Design
*des
, NetScope
*scope
,
571 const NetExpr
* decay
) const;
575 * Here are a few specilized classes for handling specific binary
578 class PEBComp
: public PEBinary
{
581 explicit PEBComp(char op
, PExpr
*l
, PExpr
*r
);
584 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
585 unsigned min
, unsigned lval
,
588 NetEBinary
* elaborate_expr(Design
*des
, NetScope
*scope
,
589 int expr_width
, bool sys_task_arg
) const;
592 class PEBShift
: public PEBinary
{
595 explicit PEBShift(char op
, PExpr
*l
, PExpr
*r
);
598 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
599 unsigned min
, unsigned lval
, bool&flag
) const;
603 * This class supports the ternary (?:) operator. The operator takes
604 * three expressions, the test, the true result and the false result.
606 class PETernary
: public PExpr
{
609 explicit PETernary(PExpr
*e
, PExpr
*t
, PExpr
*f
);
612 virtual bool is_constant(Module
*) const;
614 virtual void dump(ostream
&out
) const;
615 virtual unsigned test_width(Design
*des
, NetScope
*scope
,
616 unsigned min
, unsigned lval
,
617 bool&unsized_flag
) const;
619 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
623 const NetExpr
* decay
,
624 Link::strength_t drive0
,
625 Link::strength_t drive1
) const;
626 virtual NetETernary
*elaborate_expr(Design
*des
, NetScope
*,
627 int expr_width
, bool sys_task_arg
) const;
628 virtual NetETernary
*elaborate_pexpr(Design
*des
, NetScope
*sc
) const;
629 virtual verinum
* eval_const(Design
*des
, NetScope
*sc
) const;
638 * This class represents a parsed call to a function, including calls
639 * to system functions. The parameters in the parms list are the
640 * expressions that are passed as input to the ports of the function.
642 class PECallFunction
: public PExpr
{
644 explicit PECallFunction(const pform_name_t
&n
, const svector
<PExpr
*> &parms
);
645 // Call of system function (name is not heirarchical)
646 explicit PECallFunction(perm_string n
, const svector
<PExpr
*> &parms
);
647 explicit PECallFunction(perm_string n
);
650 virtual void dump(ostream
&) const;
652 virtual NetNet
* elaborate_net(Design
*des
, NetScope
*scope
,
656 const NetExpr
* decay
,
657 Link::strength_t drive0
,
658 Link::strength_t drive1
) const;
659 virtual NetExpr
*elaborate_expr(Design
*des
, NetScope
*scope
,
660 int expr_wid
, bool sys_task_arg
) const;
664 svector
<PExpr
*> parms_
;
666 bool check_call_matches_definition_(Design
*des
, NetScope
*dscope
) const;
668 NetExpr
* elaborate_sfunc_(Design
*des
, NetScope
*scope
) const;
669 NetNet
* elaborate_net_sfunc_(Design
*des
, NetScope
*scope
,
673 const NetExpr
* decay
,
674 Link::strength_t drive0
,
675 Link::strength_t drive1
) const;
680 * Revision 1.90 2007/06/04 19:14:06 steve
681 * Build errors in picky GCC compilers.
683 * Revision 1.89 2007/06/04 02:19:07 steve
684 * Handle bit/part select of array words in nets.
686 * Revision 1.88 2007/05/24 04:07:11 steve
687 * Rework the heirarchical identifier parse syntax and pform
688 * to handle more general combinations of heirarch and bit selects.
690 * Revision 1.87 2007/01/16 05:44:14 steve
691 * Major rework of array handling. Memories are replaced with the
692 * more general concept of arrays. The NetMemory and NetEMemory
693 * classes are removed from the ivl core program, and the IVL_LPM_RAM
694 * lpm type is removed from the ivl_target API.
696 * Revision 1.86 2006/11/10 04:54:26 steve
697 * Add test_width methods for PETernary and PEString.
699 * Revision 1.85 2006/11/04 06:19:24 steve
700 * Remove last bits of relax_width methods, and use test_width
701 * to calculate the width of an r-value expression that may
702 * contain unsized numbers.
704 * Revision 1.84 2006/10/30 05:44:49 steve
705 * Expression widths with unsized literals are pseudo-infinite width.
707 * Revision 1.83 2006/06/18 04:15:50 steve
708 * Add support for system functions in continuous assignments.
710 * Revision 1.82 2006/06/02 04:48:49 steve
711 * Make elaborate_expr methods aware of the width that the context
712 * requires of it. In the process, fix sizing of the width of unary
713 * minus is context determined sizes.
715 * Revision 1.81 2006/04/28 04:28:35 steve
716 * Allow concatenations as arguments to inout ports.
718 * Revision 1.80 2006/04/16 00:54:04 steve
719 * Cleanup lval part select handling.
721 * Revision 1.79 2006/04/16 00:15:43 steve
722 * Fix part selects in l-values.
724 * Revision 1.78 2006/03/25 02:36:26 steve
725 * Get rid of excess PESTring:: prefix within class declaration.
727 * Revision 1.77 2006/02/02 02:43:57 steve
728 * Allow part selects of memory words in l-values.
730 * Revision 1.76 2006/01/02 05:33:19 steve
731 * Node delays can be more general expressions in structural contexts.
733 * Revision 1.75 2005/12/07 04:04:23 steve
734 * Allow constant concat expressions.
736 * Revision 1.74 2005/11/27 17:01:56 steve
737 * Fix for stubborn compiler.
739 * Revision 1.73 2005/11/27 05:56:20 steve
740 * Handle bit select of parameter with ranges.
742 * Revision 1.72 2005/11/10 13:28:11 steve
743 * Reorganize signal part select handling, and add support for
744 * indexed part selects.
746 * Expand expression constant propagation to eliminate extra
747 * sums in certain cases.
749 * Revision 1.71 2005/10/04 04:09:25 steve
750 * Add support for indexed select attached to parameters.
752 * Revision 1.70 2005/08/06 17:58:16 steve
753 * Implement bi-directional part selects.
755 * Revision 1.69 2005/07/07 16:22:49 steve
756 * Generalize signals to carry types.
758 * Revision 1.68 2005/01/09 20:16:00 steve
759 * Use PartSelect/PV and VP to handle part selects through ports.
761 * Revision 1.67 2004/12/29 23:55:43 steve
762 * Unify elaboration of l-values for all proceedural assignments,
763 * including assing, cassign and force.
765 * Generate NetConcat devices for gate outputs that feed into a
766 * vector results. Use this to hande gate arrays. Also let gate
767 * arrays handle vectors of gates when the outputs allow for it.
769 * Revision 1.66 2004/10/04 01:10:51 steve
770 * Clean up spurious trailing white space.
772 * Revision 1.65 2003/02/08 19:49:21 steve
773 * Calculate delay statement delays using elaborated
774 * expressions instead of pre-elaborated expression
777 * Remove the eval_pexpr methods from PExpr.
779 * Revision 1.64 2003/01/30 16:23:07 steve
782 * Revision 1.63 2002/11/09 19:20:48 steve
783 * Port expressions for output ports are lnets, not nets.
785 * Revision 1.62 2002/08/12 01:34:58 steve
786 * conditional ident string using autoconfig.
788 * Revision 1.61 2002/06/04 05:38:43 steve
789 * Add support for memory words in l-value of
790 * blocking assignments, and remove the special
791 * NetAssignMem class.
793 * Revision 1.60 2002/05/23 03:08:51 steve
794 * Add language support for Verilog-2001 attribute
795 * syntax. Hook this support into existing $attribute
796 * handling, and add number and void value types.
798 * Add to the ivl_target API new functions for access
799 * of complex attributes attached to gates.
801 * Revision 1.59 2002/04/23 03:53:59 steve
802 * Add support for non-constant bit select.
804 * Revision 1.58 2002/04/14 03:55:25 steve
805 * Precalculate unary - if possible.
807 * Revision 1.57 2002/04/13 02:33:17 steve
808 * Detect missing indices to memories (PR#421)
810 * Revision 1.56 2002/03/09 04:02:26 steve
811 * Constant expressions are not l-values for task ports.
813 * Revision 1.55 2002/03/09 02:10:22 steve
814 * Add the NetUserFunc netlist node.
816 * Revision 1.54 2001/12/30 21:32:03 steve
817 * Support elaborate_net for PEString objects.
819 * Revision 1.53 2001/12/03 04:47:14 steve
820 * Parser and pform use hierarchical names as hname_t
821 * objects instead of encoded strings.
823 * Revision 1.52 2001/11/08 05:15:50 steve
824 * Remove string paths from PExpr elaboration.
826 * Revision 1.51 2001/11/07 04:26:46 steve
827 * elaborate_lnet uses scope instead of string path.
829 * Revision 1.50 2001/11/07 04:01:59 steve
830 * eval_const uses scope instead of a string path.