2012-04-13 03:08:20 +02:00
// -*- mode: C++; c-file-style: "cc-mode" -*-
2006-08-26 13:35:28 +02:00
//*************************************************************************
// DESCRIPTION: Verilator: Ast node structure
//
2008-04-25 14:14:27 +02:00
// Code available from: http://www.veripool.org/verilator
2006-08-26 13:35:28 +02:00
//
//*************************************************************************
//
2014-01-07 01:28:57 +01:00
// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
2006-08-26 13:35:28 +02:00
// redistribute it and/or modify it under the terms of either the GNU
2009-05-04 23:07:57 +02:00
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
2006-08-26 13:35:28 +02:00
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
# ifndef _V3ASTNODES_H_
# define _V3ASTNODES_H_ 1
# ifndef _V3AST_H_
# error "Use V3Ast.h as the include"
# endif
2008-11-20 02:15:05 +01:00
//######################################################################
// Standard defines for all AstNode final classes
# define ASTNODE_NODE_FUNCS(name,ucname) \
virtual ~ Ast # # name ( ) { } \
2010-01-22 00:04:36 +01:00
virtual AstType type ( ) const { return AstType : : at # # ucname ; } \
2008-11-20 02:15:05 +01:00
virtual AstNode * clone ( ) { return new Ast # # name ( * this ) ; } \
virtual void accept ( AstNVisitor & v , AstNUser * vup = NULL ) { v . visit ( this , vup ) ; } \
Ast # # name * cloneTree ( bool cloneNext ) { return AstNode : : cloneTree ( cloneNext ) - > cast # # name ( ) ; }
2006-08-26 13:35:28 +02:00
//######################################################################
//=== Ast* : Specific types
// Netlist interconnect
struct AstConst : public AstNodeMath {
// A constant
private :
V3Number m_num ; // Constant value
public :
AstConst ( FileLine * fl , const V3Number & num )
: AstNodeMath ( fl )
2012-03-03 18:10:29 +01:00
, m_num ( num ) {
if ( m_num . isDouble ( ) ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ;
2012-03-03 18:10:29 +01:00
} else {
2012-03-31 16:53:53 +02:00
dtypeSetLogicSized ( m_num . width ( ) , m_num . sized ( ) ? 0 : m_num . widthMin ( ) ,
m_num . isSigned ( ) ? AstNumeric : : SIGNED
: AstNumeric : : UNSIGNED ) ;
2012-03-03 18:10:29 +01:00
}
2006-08-26 13:35:28 +02:00
}
AstConst ( FileLine * fl , uint32_t num )
: AstNodeMath ( fl )
2012-03-31 16:53:53 +02:00
, m_num ( V3Number ( fl , 32 , num ) ) { dtypeSetLogicSized ( m_num . width ( ) ,
m_num . sized ( ) ? 0 : m_num . widthMin ( ) ,
AstNumeric : : UNSIGNED ) ; }
2011-07-24 21:01:51 +02:00
class Unsized32 { } ; // for creator type-overload selection
2009-09-24 05:10:46 +02:00
AstConst ( FileLine * fl , Unsized32 , uint32_t num ) // Unsized 32-bit integer of specified value
: AstNodeMath ( fl )
2012-03-31 16:53:53 +02:00
, m_num ( V3Number ( fl , 32 , num ) ) { m_num . width ( 32 , false ) ; dtypeSetLogicSized ( 32 , m_num . widthMin ( ) ,
AstNumeric : : UNSIGNED ) ; }
2013-01-20 18:19:22 +01:00
class Signed32 { } ; // for creator type-overload selection
AstConst ( FileLine * fl , Signed32 , int32_t num ) // Signed 32-bit integer of specified value
: AstNodeMath ( fl )
, m_num ( V3Number ( fl , 32 , num ) ) { m_num . width ( 32 , 32 ) ; dtypeSetLogicSized ( 32 , m_num . widthMin ( ) ,
AstNumeric : : SIGNED ) ; }
2011-07-24 21:01:51 +02:00
class RealDouble { } ; // for creator type-overload selection
AstConst ( FileLine * fl , RealDouble , double num )
: AstNodeMath ( fl )
2012-03-31 16:19:27 +02:00
, m_num ( V3Number ( fl , 64 ) ) { m_num . setDouble ( num ) ; dtypeSetDouble ( ) ; }
2009-11-23 01:57:41 +01:00
class LogicFalse { } ;
AstConst ( FileLine * fl , LogicFalse ) // Shorthand const 0, know the dtype should be a logic of size 1
: AstNodeMath ( fl )
2012-03-31 16:19:27 +02:00
, m_num ( V3Number ( fl , 1 , 0 ) ) { dtypeSetLogicBool ( ) ; }
2009-11-23 01:57:41 +01:00
class LogicTrue { } ;
AstConst ( FileLine * fl , LogicTrue ) // Shorthand const 1, know the dtype should be a logic of size 1
: AstNodeMath ( fl )
2012-03-31 16:19:27 +02:00
, m_num ( V3Number ( fl , 1 , 1 ) ) { dtypeSetLogicBool ( ) ; }
2009-11-23 01:57:41 +01:00
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Const , CONST )
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return num ( ) . ascii ( ) ; } // * = Value
virtual const V3Number & num ( ) const { return m_num ; } // * = Value
2008-09-04 17:03:46 +02:00
uint32_t toUInt ( ) const { return num ( ) . toUInt ( ) ; }
2008-10-06 15:59:22 +02:00
vlsint32_t toSInt ( ) const { return num ( ) . toSInt ( ) ; }
2008-09-03 23:40:01 +02:00
vluint64_t toUQuad ( ) const { return num ( ) . toUQuad ( ) ; }
2006-08-26 13:35:28 +02:00
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; } // Implemented specially
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; }
2008-09-03 23:40:01 +02:00
virtual V3Hash sameHash ( ) const { return V3Hash ( num ( ) . toHash ( ) ) ; }
2006-08-26 13:35:28 +02:00
virtual bool same ( AstNode * samep ) const {
return num ( ) . isCaseEq ( samep - > castConst ( ) - > num ( ) ) ; }
virtual int instrCount ( ) const { return widthInstrs ( ) ; }
2011-12-01 00:50:21 +01:00
bool isEqAllOnes ( ) const { return num ( ) . isEqAllOnes ( width ( ) ) ; }
bool isEqAllOnesV ( ) const { return num ( ) . isEqAllOnes ( widthMin ( ) ) ; }
2006-08-26 13:35:28 +02:00
} ;
2010-01-18 02:06:08 +01:00
struct AstConstString : public AstNodeMath {
// A constant string
private :
string m_name ;
public :
AstConstString ( FileLine * fl , const string & name )
: AstNodeMath ( fl ) , m_name ( name ) {
rewidth ( ) ;
}
void rewidth ( ) {
if ( m_name . length ( ) = = 0 ) {
2012-03-31 16:53:53 +02:00
dtypeSetLogicSized ( 1 , 1 , AstNumeric : : UNSIGNED ) ; // 0 width isn't allowed due to historic special cases
2010-01-18 02:06:08 +01:00
} else {
2012-03-31 16:53:53 +02:00
dtypeSetLogicSized ( ( ( int ) m_name . length ( ) ) * 8 , ( ( int ) m_name . length ( ) ) * 8 , AstNumeric : : UNSIGNED ) ;
2010-01-18 02:06:08 +01:00
}
}
ASTNODE_NODE_FUNCS ( ConstString , CONSTSTRING )
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; } // Implemented specially
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool cleanOut ( ) { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( name ( ) ) ; }
virtual bool same ( AstNode * samep ) const {
return name ( ) = = samep - > castConstString ( ) - > name ( ) ; }
virtual int instrCount ( ) const { return 2 ; } // C just loads a pointer
virtual string name ( ) const { return m_name ; }
void name ( const string & flag ) { m_name = flag ; rewidth ( ) ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstRange : public AstNode {
// Range specification, for use under variables and cells
2009-10-25 21:53:55 +01:00
private :
bool m_littleEndian : 1 ; // Bit vector is little endian
public :
2006-08-26 13:35:28 +02:00
AstRange ( FileLine * fl , AstNode * msbp , AstNode * lsbp )
: AstNode ( fl ) {
2009-10-25 21:53:55 +01:00
m_littleEndian = false ;
2006-08-26 13:35:28 +02:00
setOp2p ( msbp ) ; setOp3p ( lsbp ) ; }
AstRange ( FileLine * fl , int msb , int lsb )
: AstNode ( fl ) {
2009-10-25 21:53:55 +01:00
m_littleEndian = false ;
2006-08-26 13:35:28 +02:00
setOp2p ( new AstConst ( fl , msb ) ) ; setOp3p ( new AstConst ( fl , lsb ) ) ;
}
2013-02-02 22:52:08 +01:00
AstRange ( FileLine * fl , VNumRange range )
: AstNode ( fl ) {
m_littleEndian = range . littleEndian ( ) ;
setOp2p ( new AstConst ( fl , range . hi ( ) ) ) ; setOp3p ( new AstConst ( fl , range . lo ( ) ) ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Range , RANGE )
2009-10-25 21:53:55 +01:00
AstNode * msbp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2 = Msb expression
AstNode * lsbp ( ) const { return op3p ( ) - > castNode ( ) ; } // op3 = Lsb expression
2012-03-20 01:25:35 +01:00
AstNode * leftp ( ) const { return littleEndian ( ) ? lsbp ( ) : msbp ( ) ; } // How to show a declaration
AstNode * rightp ( ) const { return littleEndian ( ) ? msbp ( ) : lsbp ( ) ; }
2008-10-06 15:59:22 +02:00
int msbConst ( ) const { AstConst * constp = msbp ( ) - > castConst ( ) ; return ( constp ? constp - > toSInt ( ) : 0 ) ; }
int lsbConst ( ) const { AstConst * constp = lsbp ( ) - > castConst ( ) ; return ( constp ? constp - > toSInt ( ) : 0 ) ; }
2009-10-25 21:53:55 +01:00
int elementsConst ( ) const { return ( msbConst ( ) > lsbConst ( ) ) ? msbConst ( ) - lsbConst ( ) + 1 : lsbConst ( ) - msbConst ( ) + 1 ; }
bool littleEndian ( ) const { return m_littleEndian ; }
void littleEndian ( bool flag ) { m_littleEndian = flag ; }
virtual void dump ( ostream & str ) ;
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2006-08-26 13:35:28 +02:00
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
2009-11-05 04:31:53 +01:00
//######################################################################
//==== Data Types
2009-11-07 05:16:06 +01:00
struct AstTypedef : public AstNode {
2009-11-09 14:20:28 +01:00
private :
2009-11-07 05:16:06 +01:00
string m_name ;
public :
2012-03-31 17:22:19 +02:00
AstTypedef ( FileLine * fl , const string & name , VFlagChildDType , AstNodeDType * dtp )
2009-11-07 05:16:06 +01:00
: AstNode ( fl ) , m_name ( name ) {
2012-04-29 16:14:13 +02:00
childDTypep ( dtp ) ; // Only for parser
dtypep ( NULL ) ; // V3Width will resolve
2009-11-07 05:16:06 +01:00
}
ASTNODE_NODE_FUNCS ( Typedef , TYPEDEF )
2012-04-29 16:14:13 +02:00
AstNodeDType * getChildDTypep ( ) const { return childDTypep ( ) ; }
AstNodeDType * childDTypep ( ) const { return op1p ( ) - > castNodeDType ( ) ; } // op1 = Type assigning to
void childDTypep ( AstNodeDType * nodep ) { setOp1p ( nodep ) ; }
AstNodeDType * subDTypep ( ) const { return dtypep ( ) ? dtypep ( ) : childDTypep ( ) ; }
2009-11-07 05:16:06 +01:00
// METHODS
virtual string name ( ) const { return m_name ; }
virtual bool maybePointedTo ( ) const { return true ; }
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; }
2009-11-07 05:16:06 +01:00
void name ( const string & flag ) { m_name = flag ; }
} ;
struct AstTypedefFwd : public AstNode {
// Forward declaration of a type; stripped after netlist parsing is complete
2009-11-09 14:20:28 +01:00
private :
2009-11-07 05:16:06 +01:00
string m_name ;
public :
AstTypedefFwd ( FileLine * fl , const string & name )
: AstNode ( fl ) , m_name ( name ) { }
ASTNODE_NODE_FUNCS ( TypedefFwd , TYPEDEFFWD )
// METHODS
virtual string name ( ) const { return m_name ; }
} ;
2010-01-07 01:04:20 +01:00
struct AstDefImplicitDType : public AstNodeDType {
// For parsing enum/struct/unions that are declared with a variable rather than typedef
// This allows "var enum {...} a,b" to share the enum definition for both variables
// After link, these become typedefs
private :
string m_name ;
void * m_containerp ; // In what scope is the name unique, so we can know what are duplicate definitions (arbitrary value)
2012-04-29 16:14:13 +02:00
int m_uniqueNum ;
2010-01-07 01:04:20 +01:00
public :
2012-03-31 17:22:19 +02:00
AstDefImplicitDType ( FileLine * fl , const string & name , AstNode * containerp ,
VFlagChildDType , AstNodeDType * dtp )
2010-01-07 01:04:20 +01:00
: AstNodeDType ( fl ) , m_name ( name ) , m_containerp ( containerp ) {
2012-04-29 16:14:13 +02:00
childDTypep ( dtp ) ; // Only for parser
dtypep ( NULL ) ; // V3Width will resolve
m_uniqueNum = uniqueNumInc ( ) ;
2010-01-07 01:04:20 +01:00
}
ASTNODE_NODE_FUNCS ( DefImplicitDType , DEFIMPLICITDTYPE )
2012-04-29 16:14:13 +02:00
virtual bool same ( AstNode * samep ) const { return m_uniqueNum = = samep - > castDefImplicitDType ( ) - > m_uniqueNum ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( m_uniqueNum ) ; }
AstNodeDType * getChildDTypep ( ) const { return childDTypep ( ) ; }
AstNodeDType * childDTypep ( ) const { return op1p ( ) - > castNodeDType ( ) ; } // op1 = Range of variable
void childDTypep ( AstNodeDType * nodep ) { setOp1p ( nodep ) ; }
AstNodeDType * subDTypep ( ) const { return dtypep ( ) ? dtypep ( ) : childDTypep ( ) ; }
2010-01-07 01:04:20 +01:00
void * containerp ( ) const { return m_containerp ; }
// METHODS
2012-04-29 16:14:13 +02:00
AstNodeDType * dtypeSkipRefp ( ) const { return dtypep ( ) - > skipRefp ( ) ; } // op1 = Range of variable
virtual AstBasicDType * basicp ( ) const { return subDTypep ( ) - > basicp ( ) ; } // (Slow) recurse down to find basic data type
2010-01-07 01:04:20 +01:00
virtual AstNodeDType * skipRefp ( ) const { return ( AstNodeDType * ) this ; }
2013-11-01 03:39:26 +01:00
virtual AstNodeDType * skipRefToConstp ( ) const { return ( AstNodeDType * ) this ; }
2010-01-07 01:04:20 +01:00
virtual int widthAlignBytes ( ) const { return dtypep ( ) - > widthAlignBytes ( ) ; }
virtual int widthTotalBytes ( ) const { return dtypep ( ) - > widthTotalBytes ( ) ; }
virtual string name ( ) const { return m_name ; }
void name ( const string & flag ) { m_name = flag ; }
} ;
2013-01-12 22:19:25 +01:00
struct AstPackArrayDType : public AstNodeArrayDType {
2009-11-07 05:16:06 +01:00
// Array data type, ie "some_dtype var_name [2:0]"
2012-04-29 16:14:13 +02:00
// Children: DTYPE (moved to refDTypep() in V3Width)
// Children: RANGE (array bounds)
2010-04-10 02:40:41 +02:00
public :
2013-01-12 22:19:25 +01:00
AstPackArrayDType ( FileLine * fl , VFlagChildDType , AstNodeDType * dtp , AstRange * rangep )
: AstNodeArrayDType ( fl ) {
2012-04-29 16:14:13 +02:00
childDTypep ( dtp ) ; // Only for parser
refDTypep ( NULL ) ;
2012-03-31 17:22:19 +02:00
setOp2p ( rangep ) ;
2012-04-29 16:14:13 +02:00
dtypep ( NULL ) ; // V3Width will resolve
2013-05-25 03:14:42 +02:00
int width = subDTypep ( ) - > width ( ) * rangep - > elementsConst ( ) ;
widthForce ( width , width ) ;
2012-03-31 17:22:19 +02:00
}
2013-01-12 22:19:25 +01:00
AstPackArrayDType ( FileLine * fl , AstNodeDType * dtp , AstRange * rangep )
: AstNodeArrayDType ( fl ) {
2012-04-29 16:14:13 +02:00
refDTypep ( dtp ) ;
2009-11-05 04:31:53 +01:00
setOp2p ( rangep ) ;
2012-04-29 16:14:13 +02:00
dtypep ( this ) ;
2013-05-25 03:14:42 +02:00
int width = subDTypep ( ) - > width ( ) * rangep - > elementsConst ( ) ;
widthForce ( width , width ) ;
2009-11-05 04:31:53 +01:00
}
2013-01-12 22:19:25 +01:00
ASTNODE_NODE_FUNCS ( PackArrayDType , PACKARRAYDTYPE )
} ;
struct AstUnpackArrayDType : public AstNodeArrayDType {
// Array data type, ie "some_dtype var_name [2:0]"
// Children: DTYPE (moved to refDTypep() in V3Width)
// Children: RANGE (array bounds)
public :
AstUnpackArrayDType ( FileLine * fl , VFlagChildDType , AstNodeDType * dtp , AstRange * rangep )
: AstNodeArrayDType ( fl ) {
childDTypep ( dtp ) ; // Only for parser
refDTypep ( NULL ) ;
setOp2p ( rangep ) ;
dtypep ( NULL ) ; // V3Width will resolve
// For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type
widthFromSub ( subDTypep ( ) ) ;
}
AstUnpackArrayDType ( FileLine * fl , AstNodeDType * dtp , AstRange * rangep )
: AstNodeArrayDType ( fl ) {
refDTypep ( dtp ) ;
setOp2p ( rangep ) ;
dtypep ( this ) ;
// For backward compatibility AstNodeArrayDType and others inherit width and signing from the subDType/base type
widthFromSub ( subDTypep ( ) ) ;
}
ASTNODE_NODE_FUNCS ( UnpackArrayDType , UNPACKARRAYDTYPE )
2009-11-05 04:31:53 +01:00
} ;
2009-11-02 14:06:04 +01:00
struct AstBasicDType : public AstNodeDType {
// Builtin atomic/vectored data type
2012-03-02 12:58:19 +01:00
// Children: RANGE (converted to constant in V3Width)
2009-11-02 14:06:04 +01:00
private :
2012-04-29 16:14:13 +02:00
struct Members {
AstBasicDTypeKwd m_keyword ; // (also in VBasicTypeKey) What keyword created basic type
VNumRange m_nrange ; // (also in VBasicTypeKey) Numeric msb/lsb (if non-opaque keyword)
bool operator = = ( const Members & rhs ) const {
return rhs . m_keyword = = m_keyword
& & rhs . m_nrange = = m_nrange ; }
} m ;
// See also in AstNodeDtype: m_width, m_widthMin, m_numeric(issigned)
2009-11-02 14:06:04 +01:00
public :
2012-04-29 14:30:02 +02:00
AstBasicDType ( FileLine * fl , AstBasicDTypeKwd kwd , VSignedState signst = signedst_NOSIGN )
2009-11-05 04:31:53 +01:00
: AstNodeDType ( fl ) {
2012-04-29 16:14:13 +02:00
init ( kwd , AstNumeric ( signst ) , 0 , - 1 , NULL ) ;
2009-11-05 04:31:53 +01:00
}
2012-03-31 17:10:34 +02:00
AstBasicDType ( FileLine * fl , VFlagLogicPacked , int wantwidth )
2009-11-05 04:31:53 +01:00
: AstNodeDType ( fl ) {
2012-04-29 16:14:13 +02:00
init ( AstBasicDTypeKwd : : LOGIC , AstNumeric : : NOSIGN , wantwidth , - 1 , NULL ) ;
2009-11-02 14:06:04 +01:00
}
2012-03-31 17:10:34 +02:00
AstBasicDType ( FileLine * fl , VFlagBitPacked , int wantwidth )
2012-01-26 14:29:55 +01:00
: AstNodeDType ( fl ) {
2012-04-29 16:14:13 +02:00
init ( AstBasicDTypeKwd : : BIT , AstNumeric : : NOSIGN , wantwidth , - 1 , NULL ) ;
}
AstBasicDType ( FileLine * fl , AstBasicDTypeKwd kwd , AstNumeric numer , int wantwidth , int widthmin )
: AstNodeDType ( fl ) {
init ( kwd , numer , wantwidth , widthmin , NULL ) ;
2012-01-26 14:29:55 +01:00
}
2013-01-17 02:58:48 +01:00
AstBasicDType ( FileLine * fl , AstBasicDTypeKwd kwd , AstNumeric numer , VNumRange range , int widthmin )
: AstNodeDType ( fl ) {
init ( kwd , numer , range . elements ( ) , widthmin , NULL ) ;
m . m_nrange = range ; // as init() presumes lsb==0, but range.lsb() might not be
}
2009-11-05 15:57:23 +01:00
// See also addRange in verilog.y
2009-11-02 14:06:04 +01:00
private :
2012-04-29 16:14:13 +02:00
void init ( AstBasicDTypeKwd kwd , AstNumeric numer ,
int wantwidth , int wantwidthmin , AstRange * rangep ) {
// wantwidth=0 means figure it out, but if a widthmin is >=0
// we allow width 0 so that {{0{x}},y} works properly
// wantwidthmin=-1: default, use wantwidth if it is non zero
m . m_keyword = kwd ;
2009-11-03 04:14:11 +01:00
// Implicitness: // "parameter X" is implicit and sized from initial value, "parameter reg x" not
if ( keyword ( ) = = AstBasicDTypeKwd : : LOGIC_IMPLICIT ) {
2012-04-29 16:14:13 +02:00
if ( rangep | | wantwidth ) m . m_keyword = AstBasicDTypeKwd : : LOGIC ;
2009-11-02 14:06:04 +01:00
}
2012-04-29 16:14:13 +02:00
if ( numer = = AstNumeric : : NOSIGN ) {
if ( keyword ( ) . isSigned ( ) ) numer = AstNumeric : : SIGNED ;
else if ( keyword ( ) . isUnsigned ( ) ) numer = AstNumeric : : UNSIGNED ;
2012-03-04 03:03:34 +01:00
}
2012-04-29 16:14:13 +02:00
numeric ( numer ) ;
if ( ! rangep & & ( wantwidth | | wantwidthmin > = 0 ) ) { // Constant width
if ( wantwidth > 1 ) m . m_nrange . init ( wantwidth - 1 , 0 , false ) ;
int wmin = wantwidthmin > = 0 ? wantwidthmin : wantwidth ;
widthForce ( wantwidth , wmin ) ;
2012-02-20 17:48:31 +01:00
} else if ( ! rangep ) { // Set based on keyword properties
2009-11-03 04:14:11 +01:00
// V3Width will pull from this width
2012-04-29 16:14:13 +02:00
if ( keyword ( ) . width ( ) > 1 & & ! isOpaque ( ) ) {
m . m_nrange . init ( keyword ( ) . width ( ) - 1 , 0 , false ) ;
}
widthForce ( keyword ( ) . width ( ) , keyword ( ) . width ( ) ) ;
2009-11-03 04:14:11 +01:00
} else {
2012-04-29 16:14:13 +02:00
widthForce ( rangep - > elementsConst ( ) , rangep - > elementsConst ( ) ) ; // Maybe unknown if parameters underneath it
2009-11-03 04:14:11 +01:00
}
setNOp1p ( rangep ) ;
2012-04-29 16:14:13 +02:00
dtypep ( this ) ;
2009-11-02 14:06:04 +01:00
}
public :
ASTNODE_NODE_FUNCS ( BasicDType , BASICDTYPE )
virtual void dump ( ostream & str ) ;
2013-01-18 02:29:20 +01:00
virtual V3Hash sameHash ( ) const { return V3Hash ( V3Hash ( m . m_keyword ) , V3Hash ( m . m_nrange . hi ( ) ) ) ; }
2012-04-29 16:14:13 +02:00
virtual bool same ( AstNode * samep ) const { // width/widthMin/numeric compared elsewhere
return samep - > castBasicDType ( ) - > m = = m ; }
virtual string name ( ) const { return m . m_keyword . ascii ( ) ; }
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( dtypep ( ) ! = this ) ; return NULL ; }
2009-11-02 14:06:04 +01:00
AstRange * rangep ( ) const { return op1p ( ) - > castRange ( ) ; } // op1 = Range of variable
void rangep ( AstRange * nodep ) { setNOp1p ( nodep ) ; }
2012-04-29 16:14:13 +02:00
void setSignedState ( VSignedState signst ) {
// Note NOSIGN does NOT change the state; this is required by the parser
if ( signst = = signedst_UNSIGNED ) numeric ( VSignedState ( signst ) ) ;
else if ( signst = = signedst_SIGNED ) numeric ( VSignedState ( signst ) ) ;
2009-11-02 14:06:04 +01:00
}
// METHODS
2009-11-15 14:52:19 +01:00
virtual AstBasicDType * basicp ( ) const { return ( AstBasicDType * ) this ; } // (Slow) recurse down to find basic data type
virtual AstNodeDType * skipRefp ( ) const { return ( AstNodeDType * ) this ; }
2013-11-01 03:39:26 +01:00
virtual AstNodeDType * skipRefToConstp ( ) const { return ( AstNodeDType * ) this ; }
2009-11-05 04:31:53 +01:00
virtual int widthAlignBytes ( ) const ; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
virtual int widthTotalBytes ( ) const ; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
2012-04-29 16:14:13 +02:00
AstBasicDTypeKwd keyword ( ) const { return m . m_keyword ; } // Avoid using - use isSomething accessors instead
2009-11-03 04:14:11 +01:00
bool isBitLogic ( ) const { return keyword ( ) . isBitLogic ( ) ; }
2012-02-20 15:55:20 +01:00
bool isDouble ( ) const { return keyword ( ) . isDouble ( ) ; }
2010-01-17 21:10:37 +01:00
bool isOpaque ( ) const { return keyword ( ) . isOpaque ( ) ; }
2009-11-03 04:14:11 +01:00
bool isSloppy ( ) const { return keyword ( ) . isSloppy ( ) ; }
2009-11-24 01:08:25 +01:00
bool isZeroInit ( ) const { return keyword ( ) . isZeroInit ( ) ; }
2012-04-29 16:14:13 +02:00
bool isRanged ( ) const { return rangep ( ) | | m . m_nrange . ranged ( ) ; }
const VNumRange & nrange ( ) const { return m . m_nrange ; } // Generally the msb/lsb/etc funcs should be used instead
2013-01-18 02:29:20 +01:00
int msb ( ) const { return ( rangep ( ) ? rangep ( ) - > msbConst ( ) : m . m_nrange . hi ( ) ) ; }
int lsb ( ) const { return ( rangep ( ) ? rangep ( ) - > lsbConst ( ) : m . m_nrange . lo ( ) ) ; }
2012-04-29 16:14:13 +02:00
int left ( ) const { return littleEndian ( ) ? lsb ( ) : msb ( ) ; } // How to show a declaration
int right ( ) const { return littleEndian ( ) ? msb ( ) : lsb ( ) ; }
bool littleEndian ( ) const { return ( rangep ( ) ? rangep ( ) - > littleEndian ( ) : m . m_nrange . littleEndian ( ) ) ; }
bool implicit ( ) const { return keyword ( ) = = AstBasicDTypeKwd : : LOGIC_IMPLICIT ; }
2013-01-18 02:41:45 +01:00
VNumRange declRange ( ) const { return isRanged ( ) ? VNumRange ( msb ( ) , lsb ( ) , littleEndian ( ) ) : VNumRange ( ) ; }
2012-04-29 16:14:13 +02:00
void cvtRangeConst ( ) { // Convert to smaller represenation
if ( rangep ( ) & & rangep ( ) - > msbp ( ) - > castConst ( ) & & rangep ( ) - > lsbp ( ) - > castConst ( ) ) {
m . m_nrange . init ( rangep ( ) - > msbConst ( ) , rangep ( ) - > lsbConst ( ) ,
rangep ( ) - > littleEndian ( ) ) ;
rangep ( ) - > unlinkFrBackWithNext ( ) - > deleteTree ( ) ;
rangep ( NULL ) ;
}
}
2009-11-02 14:06:04 +01:00
} ;
2011-07-02 18:45:26 +02:00
struct AstConstDType : public AstNodeDType {
// const data type, ie "const some_dtype var_name [2:0]"
// ConstDType are removed in V3LinkLValue and become AstVar::isConst.
// When more generic types are supported AstConstDType will be propagated further.
2012-04-29 16:14:13 +02:00
private :
AstNodeDType * m_refDTypep ; // Inherit from this base data type
2012-03-31 17:22:19 +02:00
public :
AstConstDType ( FileLine * fl , VFlagChildDType , AstNodeDType * dtp )
2011-07-02 18:45:26 +02:00
: AstNodeDType ( fl ) {
2012-04-29 16:14:13 +02:00
childDTypep ( dtp ) ; // Only for parser
refDTypep ( NULL ) ; // V3Width will resolve
dtypep ( NULL ) ; // V3Width will resolve
widthFromSub ( subDTypep ( ) ) ;
2011-07-02 18:45:26 +02:00
}
ASTNODE_NODE_FUNCS ( ConstDType , CONSTDTYPE )
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ! ( ( m_refDTypep & & ! childDTypep ( ) & & m_refDTypep - > brokeExists ( ) )
| | ( ! m_refDTypep & & childDTypep ( ) ) ) ) ; return NULL ; }
2012-04-29 16:14:13 +02:00
virtual void cloneRelink ( ) { if ( m_refDTypep & & m_refDTypep - > clonep ( ) ) {
m_refDTypep = m_refDTypep - > clonep ( ) - > castNodeDType ( ) ;
} }
virtual bool same ( AstNode * samep ) const {
return ( m_refDTypep = = samep - > castConstDType ( ) - > m_refDTypep ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( m_refDTypep ) ; } // node's type() included elsewhere
AstNodeDType * getChildDTypep ( ) const { return childDTypep ( ) ; }
AstNodeDType * childDTypep ( ) const { return op1p ( ) - > castNodeDType ( ) ; } // op1 = Range of variable
void childDTypep ( AstNodeDType * nodep ) { setOp1p ( nodep ) ; }
AstNodeDType * subDTypep ( ) const { return m_refDTypep ? m_refDTypep : childDTypep ( ) ; } // op1 = Range of variable
void refDTypep ( AstNodeDType * nodep ) { m_refDTypep = nodep ; }
virtual AstNodeDType * virtRefDTypep ( ) const { return m_refDTypep ; }
virtual void virtRefDTypep ( AstNodeDType * nodep ) { refDTypep ( nodep ) ; }
2011-07-02 18:45:26 +02:00
// METHODS
2012-04-29 16:14:13 +02:00
virtual AstBasicDType * basicp ( ) const { return subDTypep ( ) - > basicp ( ) ; } // (Slow) recurse down to find basic data type
2013-11-01 03:39:26 +01:00
virtual AstNodeDType * skipRefp ( ) const { return subDTypep ( ) - > skipRefp ( ) ; }
virtual AstNodeDType * skipRefToConstp ( ) const { return ( AstNodeDType * ) this ; }
2012-04-29 16:14:13 +02:00
virtual int widthAlignBytes ( ) const { return subDTypep ( ) - > widthAlignBytes ( ) ; }
virtual int widthTotalBytes ( ) const { return subDTypep ( ) - > widthTotalBytes ( ) ; }
2011-07-02 18:45:26 +02:00
} ;
2013-05-28 03:39:19 +02:00
struct AstIfaceRefDType : public AstNodeDType {
// Reference to an interface, either for a port, or inside parent cell
private :
string m_cellName ; // "" = no cell, such as when connects to 'input' iface
string m_ifaceName ; // Interface name
string m_modportName ; // "" = no modport
AstIface * m_ifacep ; // Pointer to interface; note cellp() should override
AstCell * m_cellp ; // When exact parent cell known; not a guess
AstModport * m_modportp ; // NULL = unlinked or no modport
public :
AstIfaceRefDType ( FileLine * fl , const string & cellName , const string & ifaceName )
: AstNodeDType ( fl ) , m_cellName ( cellName ) , m_ifaceName ( ifaceName ) , m_modportName ( " " ) ,
m_ifacep ( NULL ) , m_cellp ( NULL ) , m_modportp ( NULL ) { }
AstIfaceRefDType ( FileLine * fl , const string & cellName , const string & ifaceName , const string & modport )
: AstNodeDType ( fl ) , m_cellName ( cellName ) , m_ifaceName ( ifaceName ) , m_modportName ( modport ) ,
m_ifacep ( NULL ) , m_cellp ( NULL ) , m_modportp ( NULL ) { }
ASTNODE_NODE_FUNCS ( IfaceRefDType , IFACEREFDTYPE )
// METHODS
virtual const char * broken ( ) const ;
virtual void dump ( ostream & str = cout ) ;
virtual void dumpSmall ( ostream & str ) ;
virtual void cloneRelink ( ) ;
virtual AstBasicDType * basicp ( ) const { return NULL ; }
virtual AstNodeDType * skipRefp ( ) const { return ( AstNodeDType * ) this ; }
2013-11-01 03:39:26 +01:00
virtual AstNodeDType * skipRefToConstp ( ) const { return ( AstNodeDType * ) this ; }
2013-05-28 03:39:19 +02:00
virtual int widthAlignBytes ( ) const { return 1 ; }
virtual int widthTotalBytes ( ) const { return 1 ; }
string cellName ( ) const { return m_cellName ; }
void cellName ( const string & name ) { m_cellName = name ; }
string ifaceName ( ) const { return m_ifaceName ; }
void ifaceName ( const string & name ) { m_ifaceName = name ; }
string modportName ( ) const { return m_modportName ; }
void modportName ( const string & name ) { m_modportName = name ; }
AstIface * ifaceViaCellp ( ) const ; // Use cellp or ifacep
AstIface * ifacep ( ) const { return m_ifacep ; }
void ifacep ( AstIface * nodep ) { m_ifacep = nodep ; }
AstCell * cellp ( ) const { return m_cellp ; }
void cellp ( AstCell * nodep ) { m_cellp = nodep ; }
AstModport * modportp ( ) const { return m_modportp ; }
void modportp ( AstModport * modportp ) { m_modportp = modportp ; }
bool isModport ( ) { return ! m_modportName . empty ( ) ; }
} ;
2009-11-07 05:16:06 +01:00
struct AstRefDType : public AstNodeDType {
2009-11-09 14:20:28 +01:00
private :
2012-04-29 14:38:53 +02:00
AstNodeDType * m_refDTypep ; // data type pointed to, BELOW the AstTypedef
2012-02-21 02:48:13 +01:00
string m_name ; // Name of an AstTypedef
2009-11-08 03:05:02 +01:00
AstPackage * m_packagep ; // Package hierarchy
2009-11-07 05:16:06 +01:00
public :
AstRefDType ( FileLine * fl , const string & name )
2012-04-29 14:38:53 +02:00
: AstNodeDType ( fl ) , m_refDTypep ( NULL ) , m_name ( name ) , m_packagep ( NULL ) { }
2012-02-21 02:48:13 +01:00
AstRefDType ( FileLine * fl , AstNodeDType * defp )
2012-04-29 14:38:53 +02:00
: AstNodeDType ( fl ) , m_refDTypep ( defp ) , m_packagep ( NULL ) {
2012-04-29 16:14:13 +02:00
dtypeFrom ( defp - > dtypep ( ) ) ;
widthFromSub ( subDTypep ( ) ) ;
2009-11-07 05:16:06 +01:00
}
ASTNODE_NODE_FUNCS ( RefDType , REFDTYPE )
// METHODS
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( m_refDTypep & & ! m_refDTypep - > brokeExists ( ) ) ; return NULL ; }
2012-04-29 14:38:53 +02:00
virtual void cloneRelink ( ) { if ( m_refDTypep & & m_refDTypep - > clonep ( ) ) {
m_refDTypep = m_refDTypep - > clonep ( ) - > castNodeDType ( ) ;
2009-11-07 05:16:06 +01:00
} }
2009-11-15 14:52:19 +01:00
virtual bool same ( AstNode * samep ) const {
2012-04-29 16:14:13 +02:00
return ( m_refDTypep = = samep - > castRefDType ( ) - > m_refDTypep
& & m_name = = samep - > castRefDType ( ) - > m_name
& & m_packagep = = samep - > castRefDType ( ) - > m_packagep ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( V3Hash ( m_refDTypep ) , V3Hash ( m_packagep ) ) ; }
2009-11-07 05:16:06 +01:00
virtual void dump ( ostream & str = cout ) ;
virtual string name ( ) const { return m_name ; }
2012-04-29 16:14:13 +02:00
virtual AstBasicDType * basicp ( ) const { return subDTypep ( ) ? subDTypep ( ) - > basicp ( ) : NULL ; }
2009-11-15 14:52:19 +01:00
virtual AstNodeDType * skipRefp ( ) const {
2009-11-07 05:16:06 +01:00
// Skip past both the Ref and the Typedef
2012-02-21 02:48:13 +01:00
if ( defp ( ) ) return defp ( ) - > skipRefp ( ) ;
2009-11-07 05:16:06 +01:00
else { v3fatalSrc ( " Typedef not linked " ) ; return NULL ; }
}
2013-11-01 03:39:26 +01:00
virtual AstNodeDType * skipRefToConstp ( ) const {
if ( defp ( ) ) return defp ( ) - > skipRefToConstp ( ) ;
else { v3fatalSrc ( " Typedef not linked " ) ; return NULL ; }
}
2012-02-21 02:48:13 +01:00
virtual int widthAlignBytes ( ) const { return dtypeSkipRefp ( ) - > widthAlignBytes ( ) ; }
virtual int widthTotalBytes ( ) const { return dtypeSkipRefp ( ) - > widthTotalBytes ( ) ; }
2009-11-07 05:16:06 +01:00
void name ( const string & flag ) { m_name = flag ; }
2012-03-03 18:10:29 +01:00
AstNodeDType * dtypeSkipRefp ( ) const { return defp ( ) - > skipRefp ( ) ; } // op1 = Range of variable
2012-04-29 14:38:53 +02:00
AstNodeDType * defp ( ) const { return m_refDTypep ; } // Code backward compatibility name for refDTypep
AstNodeDType * refDTypep ( ) const { return m_refDTypep ; }
void refDTypep ( AstNodeDType * nodep ) { m_refDTypep = nodep ; }
2012-04-29 16:14:13 +02:00
virtual AstNodeDType * virtRefDTypep ( ) const { return refDTypep ( ) ; }
virtual void virtRefDTypep ( AstNodeDType * nodep ) { refDTypep ( nodep ) ; }
2012-04-29 14:38:53 +02:00
AstNodeDType * subDTypep ( ) const { return m_refDTypep ; }
2009-11-08 03:05:02 +01:00
AstPackage * packagep ( ) const { return m_packagep ; }
void packagep ( AstPackage * nodep ) { m_packagep = nodep ; }
2009-11-07 05:16:06 +01:00
} ;
2012-07-29 16:16:20 +02:00
struct AstStructDType : public AstNodeClassDType {
AstStructDType ( FileLine * fl , AstNumeric numericUnpack )
: AstNodeClassDType ( fl , numericUnpack ) { }
ASTNODE_NODE_FUNCS ( StructDType , STRUCTDTYPE )
virtual string verilogKwd ( ) const { return " struct " ; } ;
} ;
struct AstUnionDType : public AstNodeClassDType {
//UNSUP: bool isTagged;
AstUnionDType ( FileLine * fl , AstNumeric numericUnpack )
: AstNodeClassDType ( fl , numericUnpack ) { }
ASTNODE_NODE_FUNCS ( UnionDType , UNIONDTYPE )
virtual string verilogKwd ( ) const { return " union " ; } ;
} ;
struct AstMemberDType : public AstNodeDType {
// A member of a struct/union
// PARENT: AstClassDType
private :
AstNodeDType * m_refDTypep ; // Elements of this type (after widthing)
string m_name ; // Name of variable
int m_lsb ; // Within this level's packed struct, the LSB of the first bit of the member
//UNSUP: int m_randType; // Randomization type (IEEE)
public :
AstMemberDType ( FileLine * fl , const string & name , VFlagChildDType , AstNodeDType * dtp )
: AstNodeDType ( fl )
, m_name ( name ) , m_lsb ( - 1 ) {
childDTypep ( dtp ) ; // Only for parser
dtypep ( NULL ) ; // V3Width will resolve
refDTypep ( NULL ) ;
}
AstMemberDType ( FileLine * fl , const string & name , AstNodeDType * dtp )
: AstNodeDType ( fl )
, m_name ( name ) , m_lsb ( - 1 ) {
UASSERT ( dtp , " AstMember created with no dtype " ) ;
refDTypep ( dtp ) ;
dtypep ( this ) ;
widthFromSub ( subDTypep ( ) ) ;
}
ASTNODE_NODE_FUNCS ( MemberDType , MEMBERDTYPE )
virtual string name ( ) const { return m_name ; } // * = Var name
virtual bool hasDType ( ) const { return true ; }
virtual bool maybePointedTo ( ) const { return true ; }
AstNodeDType * getChildDTypep ( ) const { return childDTypep ( ) ; }
AstNodeDType * childDTypep ( ) const { return op1p ( ) - > castNodeDType ( ) ; } // op1 = Range of variable
void childDTypep ( AstNodeDType * nodep ) { setOp1p ( nodep ) ; }
AstNodeDType * subDTypep ( ) const { return m_refDTypep ? m_refDTypep : childDTypep ( ) ; }
void refDTypep ( AstNodeDType * nodep ) { m_refDTypep = nodep ; }
virtual AstNodeDType * virtRefDTypep ( ) const { return m_refDTypep ; }
virtual void virtRefDTypep ( AstNodeDType * nodep ) { refDTypep ( nodep ) ; }
//
virtual AstBasicDType * basicp ( ) const { return subDTypep ( ) - > basicp ( ) ; } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
AstNodeDType * dtypeSkipRefp ( ) const { return subDTypep ( ) - > skipRefp ( ) ; } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
2013-11-01 03:39:26 +01:00
virtual AstNodeDType * skipRefp ( ) const { return subDTypep ( ) - > skipRefp ( ) ; }
virtual AstNodeDType * skipRefToConstp ( ) const { return subDTypep ( ) - > skipRefToConstp ( ) ; }
2012-07-29 16:16:20 +02:00
virtual int widthAlignBytes ( ) const { return subDTypep ( ) - > widthAlignBytes ( ) ; } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
virtual int widthTotalBytes ( ) const { return subDTypep ( ) - > widthTotalBytes ( ) ; } // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
// METHODS
virtual void name ( const string & name ) { m_name = name ; }
int lsb ( ) const { return m_lsb ; }
void lsb ( int lsb ) { m_lsb = lsb ; }
} ;
2009-12-27 14:29:55 +01:00
struct AstEnumItem : public AstNode {
private :
string m_name ;
public :
// Parents: ENUM
AstEnumItem ( FileLine * fl , const string & name , AstNode * rangep , AstNode * initp )
: AstNode ( fl ) , m_name ( name )
{ addNOp1p ( rangep ) ; addNOp2p ( initp ) ; }
ASTNODE_NODE_FUNCS ( EnumItem , ENUMITEM )
virtual string name ( ) const { return m_name ; }
virtual bool maybePointedTo ( ) const { return true ; }
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; }
2009-12-27 14:29:55 +01:00
void name ( const string & flag ) { m_name = flag ; }
AstRange * rangep ( ) const { return op1p ( ) - > castRange ( ) ; } // op1 = Range for name appending
void rangep ( AstNode * nodep ) { addOp1p ( nodep ) ; }
2010-01-22 00:20:47 +01:00
AstNode * valuep ( ) const { return op2p ( ) ; } // op2 = Value
void valuep ( AstNode * nodep ) { addOp2p ( nodep ) ; }
2009-12-27 14:29:55 +01:00
} ;
struct AstEnumItemRef : public AstNodeMath {
private :
AstEnumItem * m_itemp ; // [AfterLink] Pointer to item
2011-04-14 01:34:14 +02:00
AstPackage * m_packagep ; // Package hierarchy
2009-12-27 14:29:55 +01:00
public :
2011-04-14 01:34:14 +02:00
AstEnumItemRef ( FileLine * fl , AstEnumItem * itemp , AstPackage * packagep )
: AstNodeMath ( fl ) , m_itemp ( itemp ) , m_packagep ( packagep ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( m_itemp ) ;
2009-12-27 14:29:55 +01:00
}
ASTNODE_NODE_FUNCS ( EnumItemRef , ENUMITEMREF )
virtual void dump ( ostream & str ) ;
virtual string name ( ) const { return itemp ( ) - > name ( ) ; }
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ! itemp ( ) ) ; return NULL ; }
2009-12-27 14:29:55 +01:00
virtual int instrCount ( ) const { return 0 ; }
virtual void cloneRelink ( ) { if ( m_itemp - > clonep ( ) ) m_itemp = m_itemp - > clonep ( ) - > castEnumItem ( ) ; }
virtual bool same ( AstNode * samep ) const {
return itemp ( ) = = samep - > castEnumItemRef ( ) - > itemp ( ) ; }
AstEnumItem * itemp ( ) const { return m_itemp ; }
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; } // Implemented specially
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool cleanOut ( ) { return true ; }
2011-04-14 01:34:14 +02:00
AstPackage * packagep ( ) const { return m_packagep ; }
void packagep ( AstPackage * nodep ) { m_packagep = nodep ; }
2009-12-27 14:29:55 +01:00
} ;
struct AstEnumDType : public AstNodeDType {
// Parents: TYPEDEF/MODULE
// Children: ENUMVALUEs
2012-04-29 16:14:13 +02:00
private :
AstNodeDType * m_refDTypep ; // Elements are of this type after V3Width
int m_uniqueNum ;
2012-03-31 17:22:19 +02:00
public :
AstEnumDType ( FileLine * fl , VFlagChildDType , AstNodeDType * dtp , AstNode * itemsp )
2012-04-29 16:14:13 +02:00
: AstNodeDType ( fl ) {
childDTypep ( dtp ) ; // Only for parser
refDTypep ( NULL ) ;
addNOp2p ( itemsp ) ;
dtypep ( NULL ) ; // V3Width will resolve
widthFromSub ( subDTypep ( ) ) ;
m_uniqueNum = uniqueNumInc ( ) ;
}
2009-12-27 14:29:55 +01:00
ASTNODE_NODE_FUNCS ( EnumDType , ENUMDTYPE )
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ! ( ( m_refDTypep & & ! childDTypep ( ) & & m_refDTypep - > brokeExists ( ) )
| | ( ! m_refDTypep & & childDTypep ( ) ) ) ) ; return NULL ; }
2012-04-29 16:14:13 +02:00
virtual void cloneRelink ( ) { if ( m_refDTypep & & m_refDTypep - > clonep ( ) ) {
m_refDTypep = m_refDTypep - > clonep ( ) - > castNodeDType ( ) ;
} }
virtual bool same ( AstNode * samep ) const { return m_uniqueNum = = samep - > castEnumDType ( ) - > m_uniqueNum ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( m_uniqueNum ) ; }
AstNodeDType * getChildDTypep ( ) const { return childDTypep ( ) ; }
AstNodeDType * childDTypep ( ) const { return op1p ( ) - > castNodeDType ( ) ; } // op1 = Data type
void childDTypep ( AstNodeDType * nodep ) { setOp1p ( nodep ) ; }
AstNodeDType * subDTypep ( ) const { return m_refDTypep ? m_refDTypep : childDTypep ( ) ; } // op1 = Range of variable
void refDTypep ( AstNodeDType * nodep ) { m_refDTypep = nodep ; }
virtual AstNodeDType * virtRefDTypep ( ) const { return m_refDTypep ; }
virtual void virtRefDTypep ( AstNodeDType * nodep ) { refDTypep ( nodep ) ; }
2009-12-27 14:29:55 +01:00
AstEnumItem * itemsp ( ) const { return op2p ( ) - > castEnumItem ( ) ; } // op2 = AstEnumItem's
void addValuesp ( AstNode * nodep ) { addOp2p ( nodep ) ; }
// METHODS
2012-04-29 16:14:13 +02:00
virtual AstBasicDType * basicp ( ) const { return subDTypep ( ) - > basicp ( ) ; } // (Slow) recurse down to find basic data type
virtual AstNodeDType * skipRefp ( ) const { return subDTypep ( ) - > skipRefp ( ) ; }
2013-11-01 03:39:26 +01:00
virtual AstNodeDType * skipRefToConstp ( ) const { return subDTypep ( ) - > skipRefToConstp ( ) ; }
2012-04-29 16:14:13 +02:00
virtual int widthAlignBytes ( ) const { return subDTypep ( ) - > widthAlignBytes ( ) ; }
virtual int widthTotalBytes ( ) const { return subDTypep ( ) - > widthTotalBytes ( ) ; }
2009-12-27 14:29:55 +01:00
} ;
2009-11-05 04:31:53 +01:00
//######################################################################
2006-08-26 13:35:28 +02:00
struct AstArraySel : public AstNodeSel {
// Parents: math|stmt
// Children: varref|arraysel, math
2010-01-19 16:52:11 +01:00
private :
unsigned m_start ;
unsigned m_length ;
2012-02-20 15:55:20 +01:00
void init ( AstNode * fromp ) {
2013-12-14 16:32:44 +01:00
if ( fromp & & fromp - > dtypep ( ) - > skipRefp ( ) - > castNodeArrayDType ( ) ) {
2012-04-29 16:14:13 +02:00
// Strip off array to find what array references
2013-12-14 16:32:44 +01:00
dtypeFrom ( fromp - > dtypep ( ) - > skipRefp ( ) - > castNodeArrayDType ( ) - > subDTypep ( ) ) ;
2012-04-29 16:14:13 +02:00
}
2012-02-20 15:55:20 +01:00
}
2010-01-19 16:52:11 +01:00
public :
2006-08-26 13:35:28 +02:00
AstArraySel ( FileLine * fl , AstNode * fromp , AstNode * bitp )
2010-01-19 16:52:11 +01:00
: AstNodeSel ( fl , fromp , bitp ) , m_start ( 0 ) , m_length ( 1 ) {
2012-02-20 15:55:20 +01:00
init ( fromp ) ;
2006-08-26 13:35:28 +02:00
}
2008-12-12 21:34:02 +01:00
AstArraySel ( FileLine * fl , AstNode * fromp , int bit )
2010-01-19 16:52:11 +01:00
: AstNodeSel ( fl , fromp , new AstConst ( fl , bit ) ) , m_start ( 0 ) , m_length ( 1 ) {
2012-02-20 15:55:20 +01:00
init ( fromp ) ;
2008-12-12 21:34:02 +01:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ArraySel , ARRAYSEL )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) {
V3ERROR_NA ; /* How can from be a const? */ }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l%f[%r]) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " %li%k[%ri] " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
virtual int instrCount ( ) const { return widthInstrs ( ) ; }
2011-08-05 03:58:45 +02:00
unsigned length ( ) const { return m_length ; }
2010-01-19 16:52:11 +01:00
void length ( unsigned length ) { m_length = length ; }
void start ( unsigned start ) { m_start = start ; }
2011-08-05 03:58:45 +02:00
unsigned start ( ) const { return m_start ; }
2006-08-26 13:35:28 +02:00
// Special operators
2009-10-25 21:53:55 +01:00
static AstNode * baseFromp ( AstNode * nodep ) ; ///< What is the base variable (or const) this dereferences?
2010-01-19 16:52:11 +01:00
virtual void dump ( ostream & str ) ;
2006-08-26 13:35:28 +02:00
} ;
struct AstWordSel : public AstNodeSel {
// Select a single word from a multi-word wide value
AstWordSel ( FileLine * fl , AstNode * fromp , AstNode * bitp )
: AstNodeSel ( fl , fromp , bitp ) {
2012-03-31 16:19:27 +02:00
dtypeSetUInt32 ( ) ; // Always used on IData arrays so returns word entities
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( WordSel , WORDSEL )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & from , const V3Number & bit ) { V3ERROR_NA ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l%f[%r]) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " %li[%ri] " ; } // Not %k, as usually it's a small constant rhsp
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
struct AstSelExtract : public AstNodePreSel {
// Range extraction, gets replaced with AstSel
AstSelExtract ( FileLine * fl , AstNode * fromp , AstNode * msbp , AstNode * lsbp )
: AstNodePreSel ( fl , fromp , msbp , lsbp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( SelExtract , SELEXTRACT )
2009-10-25 21:53:55 +01:00
AstNode * msbp ( ) const { return rhsp ( ) ; }
AstNode * lsbp ( ) const { return thsp ( ) ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstSelBit : public AstNodePreSel {
// Single bit range extraction, perhaps with non-constant selection or array selection
// Gets replaced during link with AstArraySel or AstSel
AstSelBit ( FileLine * fl , AstNode * fromp , AstNode * bitp )
: AstNodePreSel ( fl , fromp , bitp , NULL ) {
2011-12-01 01:32:33 +01:00
if ( v3Global . assertDTypesResolved ( ) ) { v3fatalSrc ( " not coded to create after dtypes resolved " ) ; }
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( SelBit , SELBIT )
2009-10-25 21:53:55 +01:00
AstNode * bitp ( ) const { return rhsp ( ) ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstSelPlus : public AstNodePreSel {
// +: range extraction, perhaps with non-constant selection
// Gets replaced during link with AstSel
AstSelPlus ( FileLine * fl , AstNode * fromp , AstNode * bitp , AstNode * widthp )
: AstNodePreSel ( fl , fromp , bitp , widthp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( SelPlus , SELPLUS )
2009-10-25 21:53:55 +01:00
AstNode * bitp ( ) const { return rhsp ( ) ; }
AstNode * widthp ( ) const { return thsp ( ) ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstSelMinus : public AstNodePreSel {
// -: range extraction, perhaps with non-constant selection
// Gets replaced during link with AstSel
AstSelMinus ( FileLine * fl , AstNode * fromp , AstNode * bitp , AstNode * widthp )
: AstNodePreSel ( fl , fromp , bitp , widthp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( SelMinus , SELMINUS )
2009-10-25 21:53:55 +01:00
AstNode * bitp ( ) const { return rhsp ( ) ; }
AstNode * widthp ( ) const { return thsp ( ) ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstSel : public AstNodeTriop {
// Multiple bit range extraction
// Parents: math|stmt
// Children: varref|arraysel, math, constant math
2013-01-13 15:48:12 +01:00
// Tempting to have an lvalue() style method here as LHS selects are quite
// different, but that doesn't play well with V3Inst and bidirects which don't know direction
2013-01-15 03:49:22 +01:00
private :
VNumRange m_declRange ; // Range of the 'from' array if isRanged() is set, else invalid
int m_declElWidth ; // If a packed array, the number of bits per element
public :
2006-08-26 13:35:28 +02:00
AstSel ( FileLine * fl , AstNode * fromp , AstNode * lsbp , AstNode * widthp )
: AstNodeTriop ( fl , fromp , lsbp , widthp ) {
2013-01-15 03:49:22 +01:00
m_declElWidth = 1 ;
2012-03-03 18:10:29 +01:00
if ( widthp - > castConst ( ) ) {
2012-04-29 16:14:13 +02:00
dtypeSetLogicSized ( widthp - > castConst ( ) - > toUInt ( ) ,
widthp - > castConst ( ) - > toUInt ( ) ,
AstNumeric : : UNSIGNED ) ;
2012-03-03 18:10:29 +01:00
}
2006-08-26 13:35:28 +02:00
}
2009-12-03 12:55:29 +01:00
AstSel ( FileLine * fl , AstNode * fromp , int lsb , int bitwidth )
2006-08-26 13:35:28 +02:00
: AstNodeTriop ( fl , fromp ,
2009-12-03 12:55:29 +01:00
new AstConst ( fl , lsb ) , new AstConst ( fl , bitwidth ) ) {
2013-01-15 03:49:22 +01:00
m_declElWidth = 1 ;
2012-04-29 16:14:13 +02:00
dtypeSetLogicSized ( bitwidth , bitwidth , AstNumeric : : UNSIGNED ) ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Sel , SEL )
2013-01-15 03:49:22 +01:00
virtual void dump ( ostream & str ) ;
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & from , const V3Number & bit , const V3Number & width ) {
2009-09-20 15:30:39 +02:00
out . opSel ( from , bit . toUInt ( ) + width . toUInt ( ) - 1 , bit . toUInt ( ) ) ; }
2006-08-26 13:35:28 +02:00
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; } // Implemented specially
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) {
return this - > widthp ( ) - > isOne ( )
? " VL_BITSEL_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri) "
: " VL_SEL_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool cleanThs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual bool sizeMattersThs ( ) { return false ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * ) const { return true ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * ( lsbp ( ) - > castConst ( ) ? 3 : 10 ) ; }
AstNode * fromp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Extracting what (NULL=TBD during parsing)
AstNode * lsbp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2 = Msb selection expression
AstNode * widthp ( ) const { return op3p ( ) - > castNode ( ) ; } // op3 = Width
2008-10-06 15:59:22 +02:00
int widthConst ( ) const { return widthp ( ) - > castConst ( ) - > toSInt ( ) ; }
int lsbConst ( ) const { return lsbp ( ) - > castConst ( ) - > toSInt ( ) ; }
int msbConst ( ) const { return lsbConst ( ) + widthConst ( ) - 1 ; }
2013-01-15 03:49:22 +01:00
VNumRange & declRange ( ) { return m_declRange ; }
void declRange ( const VNumRange & flag ) { m_declRange = flag ; }
int declElWidth ( ) const { return m_declElWidth ; }
void declElWidth ( int flag ) { m_declElWidth = flag ; }
2006-08-26 13:35:28 +02:00
} ;
2012-07-29 16:16:20 +02:00
struct AstMemberSel : public AstNodeMath {
// Parents: math|stmt
// Children: varref|arraysel, math
private :
// Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it
string m_name ;
public :
AstMemberSel ( FileLine * fl , AstNode * fromp , VFlagChildDType , const string & name )
: AstNodeMath ( fl ) , m_name ( name ) {
setOp1p ( fromp ) ;
dtypep ( NULL ) ; // V3Width will resolve
}
AstMemberSel ( FileLine * fl , AstNode * fromp , AstMemberDType * dtp )
: AstNodeMath ( fl ) {
setOp1p ( fromp ) ;
dtypep ( dtp ) ;
m_name = dtp - > name ( ) ;
}
ASTNODE_NODE_FUNCS ( MemberSel , MEMBERSEL )
virtual string name ( ) const { return m_name ; }
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) {
V3ERROR_NA ; /* How can from be a const? */ }
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; } // Implemented specially
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool cleanOut ( ) { return false ; }
virtual bool same ( AstNode * samep ) const { return true ; } // dtype comparison does it all for us
virtual int instrCount ( ) const { return widthInstrs ( ) ; }
AstNode * fromp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Extracting what (NULL=TBD during parsing)
void fromp ( AstNode * nodep ) { setOp1p ( nodep ) ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstVar : public AstNode {
// A variable (in/out/wire/reg/param) inside a module
private :
string m_name ; // Name of variable
2013-02-18 17:22:24 +01:00
string m_origName ; // Original name before dot addition
2006-08-26 13:35:28 +02:00
AstVarType m_varType ; // Type of variable
bool m_input : 1 ; // Input or inout
bool m_output : 1 ; // Output or inout
bool m_tristate : 1 ; // Inout or triwire or trireg
2012-05-09 02:05:43 +02:00
bool m_declOutput : 1 ; // Inout or output before tristate resolution
2006-08-26 13:35:28 +02:00
bool m_primaryIO : 1 ; // In/out to top level (or directly assigned from same)
bool m_sc : 1 ; // SystemC variable
bool m_scClocked : 1 ; // SystemC sc_clk<> needed
bool m_scSensitive : 1 ; // SystemC sensitive() needed
2010-03-17 13:22:49 +01:00
bool m_sigPublic : 1 ; // User C code accesses this signal or is top signal
2007-03-02 23:24:51 +01:00
bool m_sigModPublic : 1 ; // User C code accesses this signal and module
2010-04-06 02:01:17 +02:00
bool m_sigUserRdPublic : 1 ; // User C code accesses this signal, read only
bool m_sigUserRWPublic : 1 ; // User C code accesses this signal, read-write
2006-08-26 13:35:28 +02:00
bool m_usedClock : 1 ; // Signal used as a clock
bool m_usedParam : 1 ; // Parameter is referenced (on link; later signals not setup)
2011-01-01 02:18:21 +01:00
bool m_usedLoopIdx : 1 ; // Variable subject of for unrolling
2006-08-26 13:35:28 +02:00
bool m_funcLocal : 1 ; // Local variable for a function
bool m_funcReturn : 1 ; // Return variable for a function
bool m_attrClockEn : 1 ; // User clock enable attribute
2011-10-26 14:57:27 +02:00
bool m_attrScBv : 1 ; // User force bit vector attribute
2007-01-23 19:11:26 +01:00
bool m_attrIsolateAssign : 1 ; // User isolate_assignments attribute
2010-01-18 01:13:44 +01:00
bool m_attrSFormat : 1 ; // User sformat attribute
2006-08-26 13:35:28 +02:00
bool m_fileDescr : 1 ; // File descriptor
bool m_isConst : 1 ; // Table contains constant data
bool m_isStatic : 1 ; // Static variable
2012-04-24 13:45:02 +02:00
bool m_isPulldown : 1 ; // Tri0
bool m_isPullup : 1 ; // Tri1
2013-05-28 03:39:19 +02:00
bool m_isIfaceParent : 1 ; // dtype is reference to interface present in this module
2006-08-26 13:35:28 +02:00
bool m_trace : 1 ; // Trace this variable
void init ( ) {
2012-05-09 02:05:43 +02:00
m_input = false ; m_output = false ; m_tristate = false ; m_declOutput = false ;
2006-08-26 13:35:28 +02:00
m_primaryIO = false ;
m_sc = false ; m_scClocked = false ; m_scSensitive = false ;
2011-01-01 02:18:21 +01:00
m_usedClock = false ; m_usedParam = false ; m_usedLoopIdx = false ;
2010-04-06 02:01:17 +02:00
m_sigPublic = false ; m_sigModPublic = false ; m_sigUserRdPublic = false ; m_sigUserRWPublic = false ;
2008-06-10 03:25:10 +02:00
m_funcLocal = false ; m_funcReturn = false ;
2011-10-26 14:57:27 +02:00
m_attrClockEn = false ; m_attrScBv = false ; m_attrIsolateAssign = false ; m_attrSFormat = false ;
2012-04-24 13:45:02 +02:00
m_fileDescr = false ; m_isConst = false ; m_isStatic = false ; m_isPulldown = false ; m_isPullup = false ;
2013-05-28 03:39:19 +02:00
m_isIfaceParent = false ;
2006-08-26 13:35:28 +02:00
m_trace = false ;
}
public :
2012-03-31 17:22:19 +02:00
AstVar ( FileLine * fl , AstVarType type , const string & name , VFlagChildDType , AstNodeDType * dtp )
: AstNode ( fl )
2013-02-18 17:22:24 +01:00
, m_name ( name ) , m_origName ( name ) {
2012-03-31 17:22:19 +02:00
init ( ) ;
2012-04-29 16:14:13 +02:00
combineType ( type ) ;
childDTypep ( dtp ) ; // Only for parser
dtypep ( NULL ) ; // V3Width will resolve
2012-03-31 17:22:19 +02:00
}
2011-11-30 04:36:51 +01:00
AstVar ( FileLine * fl , AstVarType type , const string & name , AstNodeDType * dtp )
2006-08-26 13:35:28 +02:00
: AstNode ( fl )
2013-02-18 17:22:24 +01:00
, m_name ( name ) , m_origName ( name ) {
2006-08-26 13:35:28 +02:00
init ( ) ;
2012-04-29 16:14:13 +02:00
combineType ( type ) ;
UASSERT ( dtp , " AstVar created with no dtype " ) ;
dtypep ( dtp ) ;
2006-08-26 13:35:28 +02:00
}
2012-03-31 17:10:34 +02:00
AstVar ( FileLine * fl , AstVarType type , const string & name , VFlagLogicPacked , int wantwidth )
2009-11-02 14:06:04 +01:00
: AstNode ( fl )
2013-02-18 17:22:24 +01:00
, m_name ( name ) , m_origName ( name ) {
2009-11-02 14:06:04 +01:00
init ( ) ;
combineType ( type ) ;
2012-05-10 04:12:57 +02:00
dtypeSetLogicSized ( wantwidth , wantwidth , AstNumeric : : UNSIGNED ) ;
2009-11-02 14:06:04 +01:00
}
2012-03-31 17:10:34 +02:00
AstVar ( FileLine * fl , AstVarType type , const string & name , VFlagBitPacked , int wantwidth )
2012-01-26 14:29:55 +01:00
: AstNode ( fl )
2013-02-18 17:22:24 +01:00
, m_name ( name ) , m_origName ( name ) {
2012-01-26 14:29:55 +01:00
init ( ) ;
combineType ( type ) ;
2012-05-10 04:12:57 +02:00
dtypeSetLogicSized ( wantwidth , wantwidth , AstNumeric : : UNSIGNED ) ;
2012-01-26 14:29:55 +01:00
}
2006-08-26 13:35:28 +02:00
AstVar ( FileLine * fl , AstVarType type , const string & name , AstVar * examplep )
: AstNode ( fl )
2013-02-18 17:22:24 +01:00
, m_name ( name ) , m_origName ( name ) {
2006-08-26 13:35:28 +02:00
init ( ) ;
combineType ( type ) ;
2012-04-29 16:14:13 +02:00
if ( examplep - > childDTypep ( ) ) {
childDTypep ( examplep - > childDTypep ( ) - > cloneTree ( true ) ) ;
2006-08-26 13:35:28 +02:00
}
2012-04-29 16:14:13 +02:00
dtypeFrom ( examplep ) ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Var , VAR )
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str ) ;
2013-02-18 17:22:24 +01:00
virtual string name ( ) const { return m_name ; } // * = Var name
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; }
2006-10-05 02:45:39 +02:00
virtual bool maybePointedTo ( ) const { return true ; }
2013-02-18 17:22:24 +01:00
string origName ( ) const { return m_origName ; } // * = Original name
void origName ( const string & name ) { m_origName = name ; }
AstVarType varType ( ) const { return m_varType ; } // * = Type of variable
void varType ( AstVarType type ) { m_varType = type ; }
2009-01-06 17:03:57 +01:00
void varType2Out ( ) { m_tristate = 0 ; m_input = 0 ; m_output = 1 ; }
void varType2In ( ) { m_tristate = 0 ; m_input = 1 ; m_output = 0 ; }
2009-12-03 12:55:29 +01:00
string scType ( ) const ; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
2009-12-09 03:35:15 +01:00
string cPubArgType ( bool named , bool forReturn ) const ; // Return C /*public*/ type for argument: bool, uint32_t, uint64_t, etc.
2009-12-03 12:55:29 +01:00
string dpiArgType ( bool named , bool forReturn ) const ; // Return DPI-C type for argument
string vlArgType ( bool named , bool forReturn ) const ; // Return Verilator internal type for argument: CData, SData, IData, WData
2010-04-06 02:01:17 +02:00
string vlEnumType ( ) const ; // Return VerilatorVarType: VLVT_UINT32, etc
string vlEnumDir ( ) const ; // Return VerilatorVarDir: VLVD_INOUT, etc
2006-08-26 13:35:28 +02:00
void combineType ( AstVarType type ) ;
2012-04-29 16:14:13 +02:00
AstNodeDType * getChildDTypep ( ) const { return childDTypep ( ) ; }
AstNodeDType * childDTypep ( ) const { return op1p ( ) - > castNodeDType ( ) ; } // op1 = Range of variable
2013-11-01 03:39:26 +01:00
AstNodeDType * dtypeSkipRefp ( ) const { return subDTypep ( ) - > skipRefp ( ) ; }
2012-04-29 16:14:13 +02:00
AstBasicDType * basicp ( ) const { return subDTypep ( ) - > basicp ( ) ; } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType)
2010-01-22 00:20:47 +01:00
AstNode * valuep ( ) const { return op3p ( ) - > castNode ( ) ; } // op3 = Initial value that never changes (static const)
2011-11-30 04:36:51 +01:00
void valuep ( AstNode * nodep ) { setOp3p ( nodep ) ; } // It's valuep, not constp, as may be more complicated than an AstConst
2009-05-08 00:28:05 +02:00
void addAttrsp ( AstNode * nodep ) { addNOp4p ( nodep ) ; }
2012-04-29 14:38:53 +02:00
AstNode * attrsp ( ) const { return op4p ( ) - > castNode ( ) ; } // op4 = Attributes during early parse
2006-08-26 13:35:28 +02:00
bool hasSimpleInit ( ) const { return ( op3p ( ) & & ! op3p ( ) - > castInitArray ( ) ) ; }
2012-05-03 02:53:38 +02:00
void childDTypep ( AstNodeDType * nodep ) { setOp1p ( nodep ) ; }
2012-04-29 16:14:13 +02:00
AstNodeDType * subDTypep ( ) const { return dtypep ( ) ? dtypep ( ) : childDTypep ( ) ; }
2006-08-26 13:35:28 +02:00
void attrClockEn ( bool flag ) { m_attrClockEn = flag ; }
void attrFileDescr ( bool flag ) { m_fileDescr = flag ; }
void attrScClocked ( bool flag ) { m_scClocked = flag ; }
2011-10-26 14:57:27 +02:00
void attrScBv ( bool flag ) { m_attrScBv = flag ; }
2007-01-18 01:51:26 +01:00
void attrIsolateAssign ( bool flag ) { m_attrIsolateAssign = flag ; }
2010-01-18 01:13:44 +01:00
void attrSFormat ( bool flag ) { m_attrSFormat = flag ; }
2006-08-26 13:35:28 +02:00
void usedClock ( bool flag ) { m_usedClock = flag ; }
void usedParam ( bool flag ) { m_usedParam = flag ; }
2011-01-01 02:18:21 +01:00
void usedLoopIdx ( bool flag ) { m_usedLoopIdx = flag ; }
2006-08-26 13:35:28 +02:00
void sigPublic ( bool flag ) { m_sigPublic = flag ; }
2007-03-02 23:24:51 +01:00
void sigModPublic ( bool flag ) { m_sigModPublic = flag ; }
2010-04-06 02:01:17 +02:00
void sigUserRdPublic ( bool flag ) { m_sigUserRdPublic = flag ; if ( flag ) sigPublic ( true ) ; }
void sigUserRWPublic ( bool flag ) { m_sigUserRWPublic = flag ; if ( flag ) sigUserRdPublic ( true ) ; }
2006-08-26 13:35:28 +02:00
void sc ( bool flag ) { m_sc = flag ; }
void scSensitive ( bool flag ) { m_scSensitive = flag ; }
void primaryIO ( bool flag ) { m_primaryIO = flag ; }
void isConst ( bool flag ) { m_isConst = flag ; }
void isStatic ( bool flag ) { m_isStatic = flag ; }
2013-05-28 03:39:19 +02:00
void isIfaceParent ( bool flag ) { m_isIfaceParent = flag ; }
2006-08-26 13:35:28 +02:00
void funcLocal ( bool flag ) { m_funcLocal = flag ; }
void funcReturn ( bool flag ) { m_funcReturn = flag ; }
void trace ( bool flag ) { m_trace = flag ; }
// METHODS
2009-07-22 21:21:41 +02:00
virtual void name ( const string & name ) { m_name = name ; }
2006-08-26 13:35:28 +02:00
bool isInput ( ) const { return m_input ; }
bool isOutput ( ) const { return m_output ; }
2006-09-25 22:40:52 +02:00
bool isInOnly ( ) const { return m_input & & ! m_output ; }
bool isOutOnly ( ) const { return m_output & & ! m_input ; }
bool isInout ( ) const { return m_input & & m_output ; }
bool isTristate ( ) const { return m_tristate ; }
2012-05-09 02:05:43 +02:00
bool isDeclOutput ( ) const { return m_declOutput ; }
2006-08-26 13:35:28 +02:00
bool isPrimaryIO ( ) const { return m_primaryIO ; }
bool isPrimaryIn ( ) const { return isPrimaryIO ( ) & & isInput ( ) ; }
2006-09-25 22:40:52 +02:00
bool isIO ( ) const { return ( m_input | | m_output ) ; }
2013-05-28 03:39:19 +02:00
bool isIfaceRef ( ) const { return ( varType ( ) = = AstVarType : : IFACEREF ) ; }
bool isIfaceParent ( ) const { return m_isIfaceParent ; }
2012-04-24 13:12:51 +02:00
bool isSignal ( ) const { return varType ( ) . isSignal ( ) ; }
2006-08-26 13:35:28 +02:00
bool isTemp ( ) const { return ( varType ( ) = = AstVarType : : BLOCKTEMP | | varType ( ) = = AstVarType : : MODULETEMP
2008-07-14 16:42:58 +02:00
| | varType ( ) = = AstVarType : : STMTTEMP | | varType ( ) = = AstVarType : : XTEMP ) ; }
2008-12-12 21:34:02 +01:00
bool isToggleCoverable ( ) const { return ( ( isIO ( ) | | isSignal ( ) )
2009-11-03 04:14:11 +01:00
& & ( isIO ( ) | | isBitLogic ( ) )
2008-12-12 21:34:02 +01:00
// Wrapper would otherwise duplicate wrapped module's coverage
2011-07-02 18:45:26 +02:00
& & ! isSc ( ) & & ! isPrimaryIO ( ) & & ! isConst ( ) ) ; }
2006-08-26 13:35:28 +02:00
bool isStatementTemp ( ) const { return ( varType ( ) = = AstVarType : : STMTTEMP ) ; }
bool isMovableToBlock ( ) const { return ( varType ( ) = = AstVarType : : BLOCKTEMP | | isFuncLocal ( ) ) ; }
2011-12-16 01:13:54 +01:00
bool isXTemp ( ) const { return ( varType ( ) = = AstVarType : : XTEMP ) ; }
2006-08-26 13:35:28 +02:00
bool isParam ( ) const { return ( varType ( ) = = AstVarType : : LPARAM | | varType ( ) = = AstVarType : : GPARAM ) ; }
bool isGParam ( ) const { return ( varType ( ) = = AstVarType : : GPARAM ) ; }
bool isGenVar ( ) const { return ( varType ( ) = = AstVarType : : GENVAR ) ; }
2009-11-05 04:31:53 +01:00
bool isBitLogic ( ) const { AstBasicDType * bdtypep = basicp ( ) ; return bdtypep & & bdtypep - > isBitLogic ( ) ; }
2006-08-26 13:35:28 +02:00
bool isUsedClock ( ) const { return m_usedClock ; }
bool isUsedParam ( ) const { return m_usedParam ; }
2011-01-01 02:18:21 +01:00
bool isUsedLoopIdx ( ) const { return m_usedLoopIdx ; }
2006-08-26 13:35:28 +02:00
bool isSc ( ) const { return m_sc ; }
bool isScQuad ( ) const ;
2009-03-13 19:17:30 +01:00
bool isScBv ( ) const ;
2013-04-27 03:02:32 +02:00
bool isScUint ( ) const ;
bool isScBigUint ( ) const ;
2006-08-26 13:35:28 +02:00
bool isScSensitive ( ) const { return m_scSensitive ; }
bool isSigPublic ( ) const ;
2007-03-02 23:24:51 +01:00
bool isSigModPublic ( ) const { return m_sigModPublic ; }
2010-04-06 02:01:17 +02:00
bool isSigUserRdPublic ( ) const { return m_sigUserRdPublic ; }
bool isSigUserRWPublic ( ) const { return m_sigUserRWPublic ; }
2006-08-26 13:35:28 +02:00
bool isTrace ( ) const { return m_trace ; }
bool isConst ( ) const { return m_isConst ; }
bool isStatic ( ) const { return m_isStatic ; }
bool isFuncLocal ( ) const { return m_funcLocal ; }
bool isFuncReturn ( ) const { return m_funcReturn ; }
2012-04-24 13:45:02 +02:00
bool isPullup ( ) const { return m_isPullup ; }
bool isPulldown ( ) const { return m_isPulldown ; }
2006-08-26 13:35:28 +02:00
bool attrClockEn ( ) const { return m_attrClockEn ; }
2011-10-26 14:57:27 +02:00
bool attrScBv ( ) const { return m_attrScBv ; }
2006-08-26 13:35:28 +02:00
bool attrFileDescr ( ) const { return m_fileDescr ; }
bool attrScClocked ( ) const { return m_scClocked ; }
2010-01-18 01:13:44 +01:00
bool attrSFormat ( ) const { return m_attrSFormat ; }
2007-01-18 01:51:26 +01:00
bool attrIsolateAssign ( ) const { return m_attrIsolateAssign ; }
2006-08-26 13:35:28 +02:00
virtual string verilogKwd ( ) const ;
void propagateAttrFrom ( AstVar * fromp ) {
// This is getting connected to fromp; keep attributes
// Note the method below too
if ( fromp - > attrClockEn ( ) ) attrClockEn ( true ) ;
if ( fromp - > attrFileDescr ( ) ) attrFileDescr ( true ) ;
2007-01-18 01:51:26 +01:00
if ( fromp - > attrIsolateAssign ( ) ) attrIsolateAssign ( true ) ;
2006-08-26 13:35:28 +02:00
}
bool gateMultiInputOptimizable ( ) const {
// Ok to gate optimize; must return false if propagateAttrFrom would do anything
return ( ! attrClockEn ( ) & & ! isUsedClock ( ) ) ;
}
void combineType ( AstVar * typevarp ) {
// This is same as typevarp (for combining input & reg decls)
propagateAttrFrom ( typevarp ) ;
combineType ( typevarp - > varType ( ) ) ;
if ( typevarp - > isSigPublic ( ) ) sigPublic ( true ) ;
2007-03-02 23:24:51 +01:00
if ( typevarp - > isSigModPublic ( ) ) sigModPublic ( true ) ;
2010-04-06 02:01:17 +02:00
if ( typevarp - > isSigUserRdPublic ( ) ) sigUserRdPublic ( true ) ;
if ( typevarp - > isSigUserRWPublic ( ) ) sigUserRWPublic ( true ) ;
2006-08-26 13:35:28 +02:00
if ( typevarp - > attrScClocked ( ) ) attrScClocked ( true ) ;
}
void inlineAttrReset ( const string & name ) {
m_input = m_output = false ; m_name = name ;
if ( varType ( ) = = AstVarType : : INOUT ) m_varType = AstVarType : : TRIWIRE ;
if ( varType ( ) = = AstVarType : : INPUT | | varType ( ) = = AstVarType : : OUTPUT ) m_varType = AstVarType : : WIRE ;
}
} ;
struct AstDefParam : public AstNode {
// A defparam assignment
// Parents: MODULE
// Children: math
private :
string m_name ; // Name of variable getting set
string m_path ; // Dotted cellname to set parameter of
public :
AstDefParam ( FileLine * fl , const string & path , const string & name , AstNode * rhsp )
: AstNode ( fl ) {
setOp1p ( rhsp ) ;
m_name = name ;
m_path = path ;
}
virtual string name ( ) const { return m_name ; } // * = Scope name
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( DefParam , DEFPARAM )
2006-08-26 13:35:28 +02:00
virtual bool cleanRhs ( ) { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * ) const { return true ; }
AstNode * rhsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Assign from
string path ( ) const { return m_path ; }
} ;
2010-01-08 04:08:48 +01:00
struct AstImplicit : public AstNode {
// Create implicit wires and do nothing else, for gates that are ignored
// Parents: MODULE
AstImplicit ( FileLine * fl , AstNode * exprsp )
: AstNode ( fl ) {
addNOp1p ( exprsp ) ;
}
ASTNODE_NODE_FUNCS ( Implicit , IMPLICIT )
AstNode * exprsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Assign from
} ;
2006-08-26 13:35:28 +02:00
struct AstScope : public AstNode {
// A particular usage of a cell
// Parents: MODULE
// Children: NODEBLOCK
private :
2009-12-05 16:38:49 +01:00
// An AstScope->name() is special: . indicates an uninlined scope, __DOT__ an inlined scope
2006-08-26 13:35:28 +02:00
string m_name ; // Name
AstScope * m_aboveScopep ; // Scope above this one in the hierarchy (NULL if top)
2007-05-22 14:15:01 +02:00
AstCell * m_aboveCellp ; // Cell above this in the hierarchy (NULL if top)
2009-11-07 12:20:20 +01:00
AstNodeModule * m_modp ; // Module scope corresponds to
2006-08-26 13:35:28 +02:00
public :
2009-11-07 12:20:20 +01:00
AstScope ( FileLine * fl , AstNodeModule * modp , const string & name ,
2006-08-26 13:35:28 +02:00
AstScope * aboveScopep , AstCell * aboveCellp )
: AstNode ( fl )
, m_name ( name ) , m_aboveScopep ( aboveScopep ) , m_aboveCellp ( aboveCellp ) , m_modp ( modp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Scope , SCOPE )
2006-08-26 13:35:28 +02:00
virtual void cloneRelink ( ) ;
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const ;
2006-10-05 02:45:39 +02:00
virtual bool maybePointedTo ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return m_name ; } // * = Scope name
2009-07-22 21:21:41 +02:00
virtual void name ( const string & name ) { m_name = name ; }
2006-08-26 13:35:28 +02:00
string nameDotless ( ) const ;
2006-08-30 23:07:55 +02:00
string nameVlSym ( ) const { return ( ( ( string ) " vlSymsp-> " ) + nameDotless ( ) ) ; }
2009-11-07 12:20:20 +01:00
AstNodeModule * modp ( ) const { return m_modp ; }
2006-08-26 13:35:28 +02:00
void addVarp ( AstNode * nodep ) { addOp1p ( nodep ) ; }
AstNode * varsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = AstVarScope's
void addActivep ( AstNode * nodep ) { addOp2p ( nodep ) ; }
AstNode * blocksp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2 = Block names
void addFinalClkp ( AstNode * nodep ) { addOp3p ( nodep ) ; }
AstNode * finalClksp ( ) const { return op3p ( ) - > castNode ( ) ; } // op3 = Final assigns for clock correction
AstScope * aboveScopep ( ) const { return m_aboveScopep ; }
AstCell * aboveCellp ( ) const { return m_aboveCellp ; }
bool isTop ( ) const { return aboveScopep ( ) = = NULL ; } // At top of hierarchy
} ;
struct AstTopScope : public AstNode {
// In the top level netlist, a complete scope tree
// There may be two of these, when we support "rare" and "usual" splitting
// Parents: topMODULE
// Children: SCOPEs
AstTopScope ( FileLine * fl , AstScope * ascopep )
: AstNode ( fl )
{ addNOp2p ( ascopep ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( TopScope , TOPSCOPE )
2006-08-26 13:35:28 +02:00
AstNode * stmtsp ( ) const { return op1p ( ) - > castNode ( ) ; }
void addStmtsp ( AstNode * nodep ) { addOp1p ( nodep ) ; }
2006-08-29 21:10:55 +02:00
AstScope * scopep ( ) const { return op2p ( ) - > castScope ( ) ; } // op1 = AstVarScope's
2006-08-26 13:35:28 +02:00
} ;
struct AstVarScope : public AstNode {
// A particular scoped usage of a variable
// That is, as a module is used under multiple cells, we get a different varscope for each var in the module
// Parents: MODULE
// Children: none
private :
AstScope * m_scopep ; // Scope variable is underneath
AstVar * m_varp ; // [AfterLink] Pointer to variable itself
bool m_circular : 1 ; // Used in circular ordering dependency, need change detect
public :
AstVarScope ( FileLine * fl , AstScope * scopep , AstVar * varp )
: AstNode ( fl )
, m_scopep ( scopep ) , m_varp ( varp ) {
m_circular = false ;
2012-04-29 15:42:17 +02:00
dtypeFrom ( varp ) ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( VarScope , VARSCOPE )
2006-08-26 13:35:28 +02:00
virtual void cloneRelink ( ) { if ( m_varp & & m_varp - > clonep ( ) ) {
m_varp = m_varp - > clonep ( ) - > castVar ( ) ;
UASSERT ( m_scopep - > clonep ( ) , " No clone cross link: " < < this ) ;
m_scopep = m_scopep - > clonep ( ) - > castScope ( ) ;
} }
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( m_varp & & ! m_varp - > brokeExists ( ) ) ;
BROKEN_RTN ( m_scopep & & ! m_scopep - > brokeExists ( ) ) ; return NULL ; }
2006-10-05 02:45:39 +02:00
virtual bool maybePointedTo ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return scopep ( ) - > name ( ) + " -> " + varp ( ) - > name ( ) ; } // * = Var name
virtual void dump ( ostream & str ) ;
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
AstVar * varp ( ) const { return m_varp ; } // [After Link] Pointer to variable
AstScope * scopep ( ) const { return m_scopep ; } // Pointer to scope it's under
AstNode * valuep ( ) const { return op1p ( ) ; } // op1 = Calculation of value of variable, NULL=complicated
void valuep ( AstNode * valuep ) { addOp1p ( valuep ) ; }
bool isCircular ( ) const { return m_circular ; }
void circular ( bool flag ) { m_circular = flag ; }
} ;
struct AstVarRef : public AstNodeVarRef {
// A reference to a variable (lvalue or rvalue)
AstVarRef ( FileLine * fl , const string & name , bool lvalue )
: AstNodeVarRef ( fl , name , NULL , lvalue ) { }
AstVarRef ( FileLine * fl , AstVar * varp , bool lvalue ) // This form only allowed post-link
: AstNodeVarRef ( fl , varp - > name ( ) , varp , lvalue ) { } // because output/wire compression may lead to deletion of AstVar's
AstVarRef ( FileLine * fl , AstVarScope * varscp , bool lvalue ) // This form only allowed post-link
: AstNodeVarRef ( fl , varscp - > varp ( ) - > name ( ) , varscp - > varp ( ) , lvalue ) { // because output/wire compression may lead to deletion of AstVar's
varScopep ( varscp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( VarRef , VARREF )
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str ) ;
virtual V3Hash sameHash ( ) const { return V3Hash ( V3Hash ( varp ( ) - > name ( ) ) , V3Hash ( hiername ( ) ) ) ; }
2012-11-29 02:18:41 +01:00
virtual bool same ( AstNode * samep ) const { return same ( samep - > castVarRef ( ) ) ; }
inline bool same ( AstVarRef * samep ) const {
if ( varScopep ( ) ) return ( varScopep ( ) = = samep - > varScopep ( )
& & lvalue ( ) = = samep - > lvalue ( ) ) ;
else return ( hiername ( ) = = samep - > hiername ( )
& & varp ( ) - > name ( ) = = samep - > varp ( ) - > name ( )
& & lvalue ( ) = = samep - > lvalue ( ) ) ; }
inline bool sameNoLvalue ( AstVarRef * samep ) const {
if ( varScopep ( ) ) return ( varScopep ( ) = = samep - > varScopep ( ) ) ;
else return ( hiername ( ) = = samep - > hiername ( )
& & varp ( ) - > name ( ) = = samep - > varp ( ) - > name ( ) ) ; }
2006-08-26 13:35:28 +02:00
virtual int instrCount ( ) const { return widthInstrs ( ) * ( lvalue ( ) ? 1 : instrCountLd ( ) ) ; }
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; } // Implemented specially
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; }
} ;
struct AstVarXRef : public AstNodeVarRef {
// A VarRef to something in another module before AstScope.
// Includes pin on a cell, as part of a ASSIGN statement to connect I/Os until AstScope
private :
string m_dotted ; // Scope name to connected to
2007-05-22 14:15:01 +02:00
string m_inlinedDots ; // Dotted hierarchy flattened out
2006-08-26 13:35:28 +02:00
public :
AstVarXRef ( FileLine * fl , const string & name , const string & dotted , bool lvalue )
: AstNodeVarRef ( fl , name , NULL , lvalue )
, m_dotted ( dotted ) { }
AstVarXRef ( FileLine * fl , AstVar * varp , const string & dotted , bool lvalue )
: AstNodeVarRef ( fl , varp - > name ( ) , varp , lvalue )
, m_dotted ( dotted ) {
2012-04-29 16:14:13 +02:00
dtypeFrom ( varp ) ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( VarXRef , VARXREF )
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str ) ;
2008-06-10 03:25:10 +02:00
string dotted ( ) const { return m_dotted ; }
2006-08-26 13:35:28 +02:00
string prettyDotted ( ) const { return prettyName ( dotted ( ) ) ; }
string inlinedDots ( ) const { return m_inlinedDots ; }
void inlinedDots ( const string & flag ) { m_inlinedDots = flag ; }
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; }
virtual int instrCount ( ) const { return widthInstrs ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( V3Hash ( varp ( ) ) , V3Hash ( dotted ( ) ) ) ; }
virtual bool same ( AstNode * samep ) const {
return ( hiername ( ) = = samep - > castVarXRef ( ) - > hiername ( )
& & varp ( ) = = samep - > castVarXRef ( ) - > varp ( )
& & name ( ) = = samep - > castVarXRef ( ) - > name ( )
& & dotted ( ) = = samep - > castVarXRef ( ) - > dotted ( ) ) ; }
} ;
struct AstPin : public AstNode {
// A pin on a cell
private :
int m_pinNum ; // Pin number
string m_name ; // Pin name, or "" for number based interconnect
AstVar * m_modVarp ; // Input/output this pin connects to on submodule.
2013-12-15 00:04:10 +01:00
bool m_param ; // Pin connects to parameter
2007-03-14 14:06:08 +01:00
bool m_svImplicit ; // Pin is SystemVerilog .name'ed
2006-08-26 13:35:28 +02:00
public :
AstPin ( FileLine * fl , int pinNum , const string & name , AstNode * exprp )
: AstNode ( fl )
2013-12-15 00:04:10 +01:00
, m_name ( name ) , m_param ( false ) , m_svImplicit ( false ) {
2006-08-26 13:35:28 +02:00
m_pinNum = pinNum ;
m_modVarp = NULL ;
2011-02-08 01:15:58 +01:00
setNOp1p ( exprp ) ;
}
2012-02-12 02:40:58 +01:00
AstPin ( FileLine * fl , int pinNum , AstVarRef * varname , AstNode * exprp )
2013-12-15 00:04:10 +01:00
: AstNode ( fl ) , m_param ( false ) , m_svImplicit ( false ) {
2012-02-12 02:40:58 +01:00
m_name = varname - > name ( ) ;
m_pinNum = pinNum ;
m_modVarp = NULL ;
setNOp1p ( exprp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Pin , PIN )
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str ) ;
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( m_modVarp & & ! m_modVarp - > brokeExists ( ) ) ; return NULL ; }
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return m_name ; } // * = Pin name, ""=go by number
2009-07-22 21:21:41 +02:00
virtual void name ( const string & name ) { m_name = name ; }
2009-05-08 00:28:05 +02:00
bool dotStar ( ) const { return name ( ) = = " .* " ; } // Special fake name for .* connections until linked
2006-08-26 13:35:28 +02:00
int pinNum ( ) const { return m_pinNum ; }
void exprp ( AstNode * nodep ) { addOp1p ( nodep ) ; }
2011-01-30 00:00:48 +01:00
AstNode * exprp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Expression connected to pin, NULL if unconnected
2006-08-26 13:35:28 +02:00
AstVar * modVarp ( ) const { return m_modVarp ; } // [After Link] Pointer to variable
void modVarp ( AstVar * varp ) { m_modVarp = varp ; }
2013-12-15 00:04:10 +01:00
bool param ( ) const { return m_param ; }
void param ( bool flag ) { m_param = flag ; }
bool svImplicit ( ) const { return m_svImplicit ; }
2007-03-14 14:06:08 +01:00
void svImplicit ( bool flag ) { m_svImplicit = flag ; }
2006-08-26 13:35:28 +02:00
} ;
2013-08-18 02:34:49 +02:00
struct AstArg : public AstNode {
// An argument to a function/task
private :
string m_name ; // Pin name, or "" for number based interconnect
public :
AstArg ( FileLine * fl , const string & name , AstNode * exprp )
: AstNode ( fl )
, m_name ( name ) {
setNOp1p ( exprp ) ;
}
ASTNODE_NODE_FUNCS ( Arg , ARG )
virtual string name ( ) const { return m_name ; } // * = Pin name, ""=go by number
virtual void name ( const string & name ) { m_name = name ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
void exprp ( AstNode * nodep ) { addOp1p ( nodep ) ; }
AstNode * exprp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Expression connected to pin, NULL if unconnected
bool emptyConnectNoNext ( ) const { return ! exprp ( ) & & name ( ) = = " " & & ! nextp ( ) ; }
} ;
2009-11-07 12:20:20 +01:00
struct AstModule : public AstNodeModule {
2006-08-26 13:35:28 +02:00
// A module declaration
AstModule ( FileLine * fl , const string & name )
2009-11-07 12:20:20 +01:00
: AstNodeModule ( fl , name ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Module , MODULE )
2010-01-08 04:44:30 +01:00
virtual string verilogKwd ( ) const { return " module " ; }
2006-08-26 13:35:28 +02:00
} ;
2011-10-28 02:56:38 +02:00
struct AstNotFoundModule : public AstNodeModule {
// A missing module declaration
AstNotFoundModule ( FileLine * fl , const string & name )
: AstNodeModule ( fl , name ) { }
ASTNODE_NODE_FUNCS ( NotFoundModule , NOTFOUNDMODULE )
virtual string verilogKwd ( ) const { return " /*not-found-*/ module " ; }
} ;
2009-11-08 03:05:02 +01:00
struct AstPackage : public AstNodeModule {
// A package declaration
AstPackage ( FileLine * fl , const string & name )
: AstNodeModule ( fl , name ) { }
ASTNODE_NODE_FUNCS ( Package , PACKAGE )
2010-01-08 04:44:30 +01:00
virtual string verilogKwd ( ) const { return " package " ; }
2009-11-08 03:05:02 +01:00
static string dollarUnitName ( ) { return AstNode : : encodeName ( " $unit " ) ; }
bool isDollarUnit ( ) const { return name ( ) = = dollarUnitName ( ) ; }
} ;
2010-01-08 04:44:30 +01:00
struct AstPrimitive : public AstNodeModule {
// A primitive declaration
AstPrimitive ( FileLine * fl , const string & name )
: AstNodeModule ( fl , name ) { }
ASTNODE_NODE_FUNCS ( Primitive , PRIMITIVE )
virtual string verilogKwd ( ) const { return " primitive " ; }
} ;
2009-11-10 01:07:59 +01:00
struct AstPackageImport : public AstNode {
private :
// A package import declaration
string m_name ;
AstPackage * m_packagep ; // Package hierarchy
public :
AstPackageImport ( FileLine * fl , AstPackage * packagep , const string & name )
: AstNode ( fl ) , m_name ( name ) , m_packagep ( packagep ) { }
ASTNODE_NODE_FUNCS ( PackageImport , PACKAGEIMPORT )
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ! m_packagep | | ! m_packagep - > brokeExists ( ) ) ; return NULL ; }
2009-11-10 01:07:59 +01:00
virtual void cloneRelink ( ) { if ( m_packagep & & m_packagep - > clonep ( ) ) m_packagep = m_packagep - > clonep ( ) - > castPackage ( ) ; }
virtual void dump ( ostream & str ) ;
virtual string name ( ) const { return m_name ; }
AstPackage * packagep ( ) const { return m_packagep ; }
void packagep ( AstPackage * nodep ) { m_packagep = nodep ; }
} ;
2013-05-28 03:39:19 +02:00
struct AstIface : public AstNodeModule {
// A module declaration
AstIface ( FileLine * fl , const string & name )
: AstNodeModule ( fl , name ) { }
ASTNODE_NODE_FUNCS ( Iface , IFACE )
} ;
2013-12-21 12:51:15 +01:00
struct AstModportFTaskRef : public AstNode {
// An import/export referenced under a modport
// The storage for the function itself is inside the interface/instantiator, thus this is a reference
// PARENT: AstModport
private :
string m_name ; // Name of the variable referenced
bool m_export ; // Type of the function (import/export)
AstNodeFTask * m_ftaskp ; // Link to the function
public :
AstModportFTaskRef ( FileLine * fl , const string & name , bool isExport )
: AstNode ( fl ) , m_name ( name ) , m_export ( isExport ) , m_ftaskp ( NULL ) { }
ASTNODE_NODE_FUNCS ( ModportFTaskRef , MODPORTFTASKREF )
virtual const char * broken ( ) const { BROKEN_RTN ( m_ftaskp & & ! m_ftaskp - > brokeExists ( ) ) ; return NULL ; }
virtual void dump ( ostream & str ) ;
virtual string name ( ) const { return m_name ; }
virtual void cloneRelink ( ) { if ( m_ftaskp & & m_ftaskp - > clonep ( ) ) m_ftaskp = m_ftaskp - > clonep ( ) - > castNodeFTask ( ) ; }
bool isImport ( ) const { return ! m_export ; }
bool isExport ( ) const { return m_export ; }
AstNodeFTask * ftaskp ( ) const { return m_ftaskp ; } // [After Link] Pointer to variable
void ftaskp ( AstNodeFTask * ftaskp ) { m_ftaskp = ftaskp ; }
} ;
2013-05-28 03:39:19 +02:00
struct AstModportVarRef : public AstNode {
// A input/output/etc variable referenced under a modport
// The storage for the variable itself is inside the interface, thus this is a reference
2013-12-21 12:51:15 +01:00
// PARENT: AstModport
2013-05-28 03:39:19 +02:00
private :
string m_name ; // Name of the variable referenced
AstVarType m_type ; // Type of the variable (in/out)
AstVar * m_varp ; // Link to the actual Var
public :
AstModportVarRef ( FileLine * fl , const string & name , AstVarType : : en type )
: AstNode ( fl ) , m_name ( name ) , m_type ( type ) , m_varp ( NULL ) { }
ASTNODE_NODE_FUNCS ( ModportVarRef , MODPORTVARREF )
virtual const char * broken ( ) const { BROKEN_RTN ( m_varp & & ! m_varp - > brokeExists ( ) ) ; return NULL ; }
virtual void dump ( ostream & str ) ;
2013-12-21 12:51:15 +01:00
virtual void cloneRelink ( ) { if ( m_varp & & m_varp - > clonep ( ) ) m_varp = m_varp - > clonep ( ) - > castVar ( ) ; }
2013-05-28 03:39:19 +02:00
virtual string name ( ) const { return m_name ; }
2013-12-21 12:51:15 +01:00
AstVarType varType ( ) const { return m_type ; } // * = Type of variable
2013-05-28 03:39:19 +02:00
bool isInput ( ) const { return ( varType ( ) = = AstVarType : : INPUT | | varType ( ) = = AstVarType : : INOUT ) ; }
bool isOutput ( ) const { return ( varType ( ) = = AstVarType : : OUTPUT | | varType ( ) = = AstVarType : : INOUT ) ; }
AstVar * varp ( ) const { return m_varp ; } // [After Link] Pointer to variable
void varp ( AstVar * varp ) { m_varp = varp ; }
} ;
struct AstModport : public AstNode {
// A modport in an interface
private :
string m_name ; // Name of the modport
public :
2013-12-21 12:51:15 +01:00
AstModport ( FileLine * fl , const string & name , AstNode * varsp )
2013-05-28 03:39:19 +02:00
: AstNode ( fl ) , m_name ( name ) {
addNOp1p ( varsp ) ; }
virtual string name ( ) const { return m_name ; }
virtual bool maybePointedTo ( ) const { return true ; }
ASTNODE_NODE_FUNCS ( Modport , MODPORT )
2013-12-21 12:51:15 +01:00
AstNode * varsp ( ) const { return op1p ( ) ; } // op1 = List of Vars
2013-05-28 03:39:19 +02:00
} ;
2006-08-26 13:35:28 +02:00
struct AstCell : public AstNode {
2009-11-07 12:20:20 +01:00
// A instantiation cell or interface call (don't know which until link)
2006-08-26 13:35:28 +02:00
private :
string m_name ; // Cell name
string m_origName ; // Original name before dot addition
string m_modName ; // Module the cell instances
2013-01-19 20:40:35 +01:00
AstNodeModule * m_modp ; // [AfterLink] Pointer to module instanced
2013-05-28 03:39:19 +02:00
bool m_hasIfaceVar ; // True if a Var has been created for this cell
2006-08-26 13:35:28 +02:00
public :
AstCell ( FileLine * fl , const string & instName , const string & modName ,
AstPin * pinsp , AstPin * paramsp , AstRange * rangep )
: AstNode ( fl )
2007-03-14 14:06:08 +01:00
, m_name ( instName ) , m_origName ( instName ) , m_modName ( modName )
2013-05-28 03:39:19 +02:00
, m_modp ( NULL ) , m_hasIfaceVar ( false ) {
2006-08-26 13:35:28 +02:00
addNOp1p ( pinsp ) ; addNOp2p ( paramsp ) ; setNOp3p ( rangep ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Cell , CELL )
2006-08-26 13:35:28 +02:00
// No cloneRelink, we presume cloneee's want the same module linkages
virtual void dump ( ostream & str ) ;
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( m_modp & & ! m_modp - > brokeExists ( ) ) ; return NULL ; }
2006-10-05 02:45:39 +02:00
virtual bool maybePointedTo ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
// ACCESSORS
virtual string name ( ) const { return m_name ; } // * = Cell name
2009-07-22 21:21:41 +02:00
virtual void name ( const string & name ) { m_name = name ; }
2006-08-26 13:35:28 +02:00
string origName ( ) const { return m_origName ; } // * = Original name
2006-09-01 17:31:07 +02:00
void origName ( const string & name ) { m_origName = name ; }
2006-08-26 13:35:28 +02:00
string modName ( ) const { return m_modName ; } // * = Instance name
2006-09-01 17:31:07 +02:00
void modName ( const string & name ) { m_modName = name ; }
2006-08-26 13:35:28 +02:00
AstPin * pinsp ( ) const { return op1p ( ) - > castPin ( ) ; } // op1 = List of cell ports
AstPin * paramsp ( ) const { return op2p ( ) - > castPin ( ) ; } // op2 = List of parameter #(##) values
AstRange * rangep ( ) const { return op3p ( ) - > castRange ( ) ; } // op3 = Range of arrayed instants (NULL=not ranged)
2009-11-07 12:20:20 +01:00
AstNodeModule * modp ( ) const { return m_modp ; } // [AfterLink] = Pointer to module instantiated
2006-09-01 17:31:07 +02:00
void addPinsp ( AstPin * nodep ) { addOp1p ( nodep ) ; }
void addParamsp ( AstPin * nodep ) { addOp2p ( nodep ) ; }
2009-11-07 12:20:20 +01:00
void modp ( AstNodeModule * nodep ) { m_modp = nodep ; }
2013-05-28 03:39:19 +02:00
bool hasIfaceVar ( ) const { return m_hasIfaceVar ; }
void hasIfaceVar ( bool flag ) { m_hasIfaceVar = flag ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstCellInline : public AstNode {
// A instantiation cell that was removed by inlining
// For communication between V3Inline and V3LinkDot only
// Children: When 2 levels inlined, other CellInline under this
private :
string m_name ; // Cell name, possibly {a}__DOT__{b}...
string m_origModName ; // Original name of the module, ignoring name() changes, for dot lookup
public :
AstCellInline ( FileLine * fl , const string & name , const string & origModName )
: AstNode ( fl )
, m_name ( name ) , m_origModName ( origModName ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CellInline , CELLINLINE )
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str ) ;
// ACCESSORS
virtual string name ( ) const { return m_name ; } // * = Cell name
string origModName ( ) const { return m_origModName ; } // * = modp()->origName() before inlining
2009-07-22 21:21:41 +02:00
virtual void name ( const string & name ) { m_name = name ; }
2006-08-26 13:35:28 +02:00
} ;
2013-01-15 05:19:44 +01:00
struct AstBind : public AstNode {
// Parents: MODULE
// Children: CELL
private :
string m_name ; // Binding to name
public :
AstBind ( FileLine * fl , const string & name , AstNode * cellsp )
: AstNode ( fl )
, m_name ( name ) {
if ( ! cellsp - > castCell ( ) ) cellsp - > v3fatalSrc ( " Only cells allowed to be bound " ) ;
addNOp1p ( cellsp ) ;
}
ASTNODE_NODE_FUNCS ( Bind , BIND )
// ACCESSORS
virtual string name ( ) const { return m_name ; } // * = Bind Target name
virtual void name ( const string & name ) { m_name = name ; }
AstNode * cellsp ( ) const { return op1p ( ) ; } // op1= cells
} ;
2006-08-26 13:35:28 +02:00
struct AstPort : public AstNode {
// A port (in/out/inout) on a module
private :
int m_pinNum ; // Pin number
string m_name ; // Name of pin
public :
AstPort ( FileLine * fl , int pinnum , const string & name )
: AstNode ( fl )
, m_pinNum ( pinnum ) , m_name ( name ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Port , PORT )
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return m_name ; } // * = Port name
int pinNum ( ) const { return m_pinNum ; } // * = Pin number, for order based instantiation
AstNode * exprp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Expression connected to port
} ;
//######################################################################
struct AstGenerate : public AstNode {
// A Generate/end block
// Parents: MODULE
// Children: modItems
AstGenerate ( FileLine * fileline , AstNode * stmtsp )
: AstNode ( fileline ) {
addNOp1p ( stmtsp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Generate , GENERATE )
2006-08-26 13:35:28 +02:00
// op1 = Statements
AstNode * stmtsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = List of statements
void addStmtp ( AstNode * nodep ) { addOp1p ( nodep ) ; }
} ;
2006-12-21 22:53:51 +01:00
struct AstParseRef : public AstNode {
// A reference to a variable, function or task
// We don't know which at parse time due to bison constraints
// The link stages will replace this with AstVarRef, or AstTaskRef, etc.
// Parents: math|stmt
2012-07-24 12:26:35 +02:00
// Children: TEXT|DOT|SEL*|TASK|FUNC (or expression under sel)
2006-12-21 22:53:51 +01:00
private :
AstParseRefExp m_expect ; // Type we think it should resolve to
2012-07-24 12:26:35 +02:00
string m_name ;
2006-12-21 22:53:51 +01:00
public :
2012-07-24 12:26:35 +02:00
AstParseRef ( FileLine * fl , AstParseRefExp expect , const string & name , AstNode * lhsp , AstNodeFTaskRef * ftaskrefp )
2012-12-31 23:05:13 +01:00
: AstNode ( fl ) , m_expect ( expect ) , m_name ( name ) { setNOp1p ( lhsp ) ; setNOp2p ( ftaskrefp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ParseRef , PARSEREF )
2006-12-21 22:53:51 +01:00
virtual void dump ( ostream & str ) ;
2012-07-24 12:26:35 +02:00
virtual string name ( ) const { return m_name ; } // * = Var name
virtual V3Hash sameHash ( ) const { return V3Hash ( V3Hash ( m_expect ) , V3Hash ( m_name ) ) ; }
2012-12-31 23:05:13 +01:00
virtual bool same ( AstNode * samep ) const {
return ( expect ( ) = = samep - > castParseRef ( ) - > expect ( )
& & m_name = = samep - > castParseRef ( ) - > m_name ) ; }
2006-12-21 22:53:51 +01:00
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2012-07-24 12:26:35 +02:00
virtual void name ( const string & name ) { m_name = name ; }
2006-12-21 22:53:51 +01:00
AstParseRefExp expect ( ) const { return m_expect ; }
2012-07-24 12:26:35 +02:00
void expect ( AstParseRefExp exp ) { m_expect = exp ; }
2006-12-21 22:53:51 +01:00
// op1 = Components
AstNode * lhsp ( ) const { return op1p ( ) ; } // op1 = List of statements
2012-07-24 12:26:35 +02:00
AstNode * ftaskrefp ( ) const { return op2p ( ) ; } // op2 = Function/task reference
void ftaskrefp ( AstNodeFTaskRef * nodep ) { setNOp2p ( nodep ) ; } // op2 = Function/task reference
2012-12-31 23:05:13 +01:00
} ;
struct AstPackageRef : public AstNode {
private :
AstPackage * m_packagep ; // Package hierarchy
public :
AstPackageRef ( FileLine * fl , AstPackage * packagep )
: AstNode ( fl ) , m_packagep ( packagep ) { }
ASTNODE_NODE_FUNCS ( PackageRef , PACKAGEREF )
// METHODS
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ! m_packagep | | ! m_packagep - > brokeExists ( ) ) ; return NULL ; }
2012-12-31 23:05:13 +01:00
virtual void cloneRelink ( ) { if ( m_packagep & & m_packagep - > clonep ( ) ) {
m_packagep = m_packagep - > clonep ( ) - > castPackage ( ) ;
} }
virtual bool same ( AstNode * samep ) const {
return ( m_packagep = = samep - > castPackageRef ( ) - > m_packagep ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( V3Hash ( m_packagep ) ) ; }
virtual void dump ( ostream & str = cout ) ;
AstPackage * packagep ( ) const { return m_packagep ; }
void packagep ( AstPackage * nodep ) { m_packagep = nodep ; }
2006-12-21 22:53:51 +01:00
} ;
struct AstDot : public AstNode {
2011-11-30 04:36:51 +01:00
// A dot separating paths in an AstXRef, AstFuncRef or AstTaskRef
2012-07-24 12:26:35 +02:00
// These are eliminated in the link stage
public :
2006-12-21 22:53:51 +01:00
AstDot ( FileLine * fl , AstNode * lhsp , AstNode * rhsp )
2012-12-31 23:05:13 +01:00
: AstNode ( fl ) { setOp1p ( lhsp ) ; setOp2p ( rhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Dot , DOT )
2012-12-31 23:05:13 +01:00
static AstNode * newIfPkg ( FileLine * fl , AstPackage * packagep , AstNode * rhsp ) { // For parser, make only if non-null package
if ( ! packagep ) return rhsp ;
return new AstDot ( fl , new AstPackageRef ( fl , packagep ) , rhsp ) ;
}
2012-07-24 12:26:35 +02:00
virtual void dump ( ostream & str ) ;
2006-12-21 22:53:51 +01:00
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2006-12-21 22:53:51 +01:00
AstNode * lhsp ( ) const { return op1p ( ) ; }
AstNode * rhsp ( ) const { return op2p ( ) ; }
} ;
2006-08-26 13:35:28 +02:00
//######################################################################
struct AstTask : public AstNodeFTask {
// A task inside a module
AstTask ( FileLine * fl , const string & name , AstNode * stmtp )
: AstNodeFTask ( fl , name , stmtp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Task , TASK )
2006-08-26 13:35:28 +02:00
} ;
struct AstFunc : public AstNodeFTask {
// A function inside a module
AstFunc ( FileLine * fl , const string & name , AstNode * stmtp , AstNode * fvarsp )
: AstNodeFTask ( fl , name , stmtp ) {
addNOp1p ( fvarsp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Func , FUNC )
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstTaskRef : public AstNodeFTaskRef {
// A reference to a task
2006-12-21 22:53:51 +01:00
AstTaskRef ( FileLine * fl , AstParseRef * namep , AstNode * pinsp )
: AstNodeFTaskRef ( fl , namep , pinsp ) { }
2009-12-04 13:05:44 +01:00
AstTaskRef ( FileLine * fl , const string & name , AstNode * pinsp )
: AstNodeFTaskRef ( fl , name , pinsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( TaskRef , TASKREF )
2006-08-26 13:35:28 +02:00
} ;
struct AstFuncRef : public AstNodeFTaskRef {
// A reference to a function
2006-12-21 22:53:51 +01:00
AstFuncRef ( FileLine * fl , AstParseRef * namep , AstNode * pinsp )
: AstNodeFTaskRef ( fl , namep , pinsp ) { }
2009-12-04 13:05:44 +01:00
AstFuncRef ( FileLine * fl , const string & name , AstNode * pinsp )
: AstNodeFTaskRef ( fl , name , pinsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( FuncRef , FUNCREF )
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
} ;
2009-12-03 12:55:29 +01:00
struct AstDpiExport : public AstNode {
2011-11-30 04:36:51 +01:00
// We could put an AstNodeFTaskRef instead of the verilog function name,
2009-12-03 12:55:29 +01:00
// however we're not *calling* it, so that seems somehow wrong.
// (Probably AstNodeFTaskRef should be renamed AstNodeFTaskCall and have-a AstNodeFTaskRef)
private :
string m_name ; // Name of function
string m_cname ; // Name of function on c side
public :
AstDpiExport ( FileLine * fl , const string & vname , const string & cname )
: AstNode ( fl ) , m_name ( vname ) , m_cname ( cname ) { }
ASTNODE_NODE_FUNCS ( DpiExport , DPIEXPORT )
virtual string name ( ) const { return m_name ; }
virtual void name ( const string & name ) { m_name = name ; }
string cname ( ) const { return m_cname ; }
void cname ( const string & cname ) { m_cname = cname ; }
} ;
2006-08-26 13:35:28 +02:00
//######################################################################
2008-11-20 13:55:54 +01:00
struct AstSenItem : public AstNodeSenItem {
2006-08-26 13:35:28 +02:00
// Parents: SENTREE
2009-01-07 15:37:59 +01:00
// Children: (optional) VARREF SENGATE
2006-08-26 13:35:28 +02:00
private :
AstEdgeType m_edgeType ; // Edge type
public :
class Combo { } ; // for creator type-overload selection
class Initial { } ; // for creator type-overload selection
class Settle { } ; // for creator type-overload selection
class Never { } ; // for creator type-overload selection
2012-12-31 23:05:13 +01:00
AstSenItem ( FileLine * fl , AstEdgeType edgeType , AstNode * varrefp )
2008-11-20 13:55:54 +01:00
: AstNodeSenItem ( fl ) , m_edgeType ( edgeType ) {
2006-08-26 13:35:28 +02:00
setOp1p ( varrefp ) ;
}
AstSenItem ( FileLine * fl , Combo )
2008-11-20 13:55:54 +01:00
: AstNodeSenItem ( fl ) {
2010-02-02 02:15:48 +01:00
m_edgeType = AstEdgeType : : ET_COMBO ;
2006-08-26 13:35:28 +02:00
}
AstSenItem ( FileLine * fl , Initial )
2008-11-20 13:55:54 +01:00
: AstNodeSenItem ( fl ) {
2010-02-02 02:15:48 +01:00
m_edgeType = AstEdgeType : : ET_INITIAL ;
2006-08-26 13:35:28 +02:00
}
AstSenItem ( FileLine * fl , Settle )
2008-11-20 13:55:54 +01:00
: AstNodeSenItem ( fl ) {
2010-02-02 02:15:48 +01:00
m_edgeType = AstEdgeType : : ET_SETTLE ;
2006-08-26 13:35:28 +02:00
}
AstSenItem ( FileLine * fl , Never )
2008-11-20 13:55:54 +01:00
: AstNodeSenItem ( fl ) {
2010-02-02 02:15:48 +01:00
m_edgeType = AstEdgeType : : ET_NEVER ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( SenItem , SENITEM )
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str ) ;
virtual V3Hash sameHash ( ) const { return V3Hash ( V3Hash ( edgeType ( ) ) ) ; }
virtual bool same ( AstNode * samep ) const {
return edgeType ( ) = = samep - > castSenItem ( ) - > edgeType ( ) ; }
AstEdgeType edgeType ( ) const { return m_edgeType ; } // * = Posedge/negedge
void edgeType ( AstEdgeType type ) { m_edgeType = type ; editCountInc ( ) ; } // * = Posedge/negedge
AstNode * sensp ( ) const { return op1p ( ) ; } // op1 = Signal sensitized
2006-10-03 15:02:21 +02:00
AstNodeVarRef * varrefp ( ) const { return op1p ( ) - > castNodeVarRef ( ) ; } // op1 = Signal sensitized
2006-08-26 13:35:28 +02:00
//
2008-11-20 13:55:54 +01:00
virtual bool isClocked ( ) const { return edgeType ( ) . clockedStmt ( ) ; }
2010-02-02 02:15:48 +01:00
virtual bool isCombo ( ) const { return edgeType ( ) = = AstEdgeType : : ET_COMBO ; }
virtual bool isInitial ( ) const { return edgeType ( ) = = AstEdgeType : : ET_INITIAL ; }
virtual bool isSettle ( ) const { return edgeType ( ) = = AstEdgeType : : ET_SETTLE ; }
virtual bool isNever ( ) const { return edgeType ( ) = = AstEdgeType : : ET_NEVER ; }
2006-08-26 13:35:28 +02:00
bool hasVar ( ) const { return ! ( isCombo ( ) | | isInitial ( ) | | isSettle ( ) | | isNever ( ) ) ; }
} ;
2009-01-07 15:37:59 +01:00
struct AstSenGate : public AstNodeSenItem {
// Parents: SENTREE
// Children: SENITEM expr
// AND as applied to a sensitivity list and a gating expression
// Performing this gating is optional; it may be removed by later optimizations
AstSenGate ( FileLine * fl , AstSenItem * sensesp , AstNode * rhsp ) : AstNodeSenItem ( fl ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; addOp1p ( sensesp ) ; setOp2p ( rhsp ) ;
2009-01-07 15:37:59 +01:00
}
ASTNODE_NODE_FUNCS ( SenGate , SENGATE )
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " (%l) %f&& (%r) " ; }
2009-01-07 15:37:59 +01:00
AstSenItem * sensesp ( ) const { return op1p ( ) - > castSenItem ( ) ; }
AstNode * rhsp ( ) const { return op2p ( ) - > castNode ( ) ; }
void sensesp ( AstSenItem * nodep ) { addOp1p ( nodep ) ; }
void rhsp ( AstNode * nodep ) { setOp2p ( nodep ) ; }
//
virtual bool isClocked ( ) const { return true ; }
virtual bool isCombo ( ) const { return false ; }
virtual bool isInitial ( ) const { return false ; }
virtual bool isSettle ( ) const { return false ; }
virtual bool isNever ( ) const { return false ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstSenTree : public AstNode {
// A list of senitems
// Parents: MODULE | SBLOCK
// Children: SENITEM list
private :
bool m_multi ; // Created from combo logic by ORing multiple clock domains
public :
2008-11-20 13:55:54 +01:00
AstSenTree ( FileLine * fl , AstNodeSenItem * sensesp )
2006-08-26 13:35:28 +02:00
: AstNode ( fl ) , m_multi ( false ) {
addNOp1p ( sensesp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( SenTree , SENTREE )
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str ) ;
2006-10-05 02:45:39 +02:00
virtual bool maybePointedTo ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
bool isMulti ( ) const { return m_multi ; }
2008-11-20 13:55:54 +01:00
AstNodeSenItem * sensesp ( ) const { return op1p ( ) - > castNodeSenItem ( ) ; } // op1 = Sensitivity list
void addSensesp ( AstNodeSenItem * nodep ) { addOp1p ( nodep ) ; }
2006-08-26 13:35:28 +02:00
void multi ( bool flag ) { m_multi = true ; }
// METHODS
bool hasClocked ( ) ; // Includes a clocked statement
bool hasSettle ( ) ; // Includes a SETTLE SenItem
bool hasInitial ( ) ; // Includes a INITIAL SenItem
bool hasCombo ( ) ; // Includes a COMBO SenItem
} ;
struct AstAlways : public AstNode {
2013-05-01 04:55:28 +02:00
VAlwaysKwd m_keyword ;
public :
AstAlways ( FileLine * fl , VAlwaysKwd keyword , AstSenTree * sensesp , AstNode * bodysp )
: AstNode ( fl ) , m_keyword ( keyword ) {
2006-08-26 13:35:28 +02:00
addNOp1p ( sensesp ) ; addNOp2p ( bodysp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Always , ALWAYS )
2006-08-26 13:35:28 +02:00
//
2013-05-01 04:55:28 +02:00
virtual void dump ( ostream & str ) ;
2006-08-26 13:35:28 +02:00
AstSenTree * sensesp ( ) const { return op1p ( ) - > castSenTree ( ) ; } // op1 = Sensitivity list
AstNode * bodysp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2 = Statements to evaluate
void addStmtp ( AstNode * nodep ) { addOp2p ( nodep ) ; }
2013-05-01 04:55:28 +02:00
VAlwaysKwd keyword ( ) const { return m_keyword ; }
2006-08-26 13:35:28 +02:00
// Special accessors
bool isJustOneBodyStmt ( ) const { return bodysp ( ) & & ! bodysp ( ) - > nextp ( ) ; }
} ;
2010-04-06 02:01:17 +02:00
struct AstAlwaysPublic : public AstNodeStmt {
// "Fake" sensitivity created by /*verilator public_flat_rw @(edgelist)*/
// Body statements are just AstVarRefs to the public signals
AstAlwaysPublic ( FileLine * fl , AstSenTree * sensesp , AstNode * bodysp )
: AstNodeStmt ( fl ) {
addNOp1p ( sensesp ) ; addNOp2p ( bodysp ) ;
}
ASTNODE_NODE_FUNCS ( AlwaysPublic , ALWAYSPUBLIC )
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
//
AstSenTree * sensesp ( ) const { return op1p ( ) - > castSenTree ( ) ; } // op1 = Sensitivity list
AstNode * bodysp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2 = Statements to evaluate
void addStmtp ( AstNode * nodep ) { addOp2p ( nodep ) ; }
// Special accessors
bool isJustOneBodyStmt ( ) const { return bodysp ( ) & & ! bodysp ( ) - > nextp ( ) ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstAlwaysPost : public AstNode {
// Like always but post assignments for memory assignment IFs
AstAlwaysPost ( FileLine * fl , AstSenTree * sensesp , AstNode * bodysp )
: AstNode ( fl ) {
addNOp1p ( sensesp ) ; addNOp2p ( bodysp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( AlwaysPost , ALWAYSPOST )
2006-08-26 13:35:28 +02:00
//
AstNode * bodysp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2 = Statements to evaluate
void addBodysp ( AstNode * newp ) { addOp2p ( newp ) ; }
} ;
struct AstAssign : public AstNodeAssign {
AstAssign ( FileLine * fileline , AstNode * lhsp , AstNode * rhsp )
: AstNodeAssign ( fileline , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Assign , ASSIGN )
2006-08-26 13:35:28 +02:00
virtual AstNode * cloneType ( AstNode * lhsp , AstNode * rhsp ) { return new AstAssign ( this - > fileline ( ) , lhsp , rhsp ) ; }
} ;
struct AstAssignAlias : public AstNodeAssign {
// Like AstAssignW, but a true bidirect interconnection alias
// If both sides are wires, there's no LHS vs RHS,
AstAssignAlias ( FileLine * fileline , AstVarRef * lhsp , AstVarRef * rhsp )
: AstNodeAssign ( fileline , lhsp , rhsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( AssignAlias , ASSIGNALIAS )
2006-08-26 13:35:28 +02:00
virtual AstNode * cloneType ( AstNode * lhsp , AstNode * rhsp ) { V3ERROR_NA ; return NULL ; }
} ;
struct AstAssignDly : public AstNodeAssign {
AstAssignDly ( FileLine * fileline , AstNode * lhsp , AstNode * rhsp )
: AstNodeAssign ( fileline , lhsp , rhsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( AssignDly , ASSIGNDLY )
2006-08-26 13:35:28 +02:00
virtual AstNode * cloneType ( AstNode * lhsp , AstNode * rhsp ) { return new AstAssignDly ( this - > fileline ( ) , lhsp , rhsp ) ; }
virtual bool isGateOptimizable ( ) const { return false ; }
2009-07-22 20:38:20 +02:00
virtual string verilogKwd ( ) const { return " <= " ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstAssignW : public AstNodeAssign {
// Like assign, but wire/assign's in verilog, the only setting of the specified variable
AstAssignW ( FileLine * fileline , AstNode * lhsp , AstNode * rhsp )
2009-10-07 03:58:00 +02:00
: AstNodeAssign ( fileline , lhsp , rhsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( AssignW , ASSIGNW )
2006-08-26 13:35:28 +02:00
virtual AstNode * cloneType ( AstNode * lhsp , AstNode * rhsp ) { return new AstAssignW ( this - > fileline ( ) , lhsp , rhsp ) ; }
2009-10-09 02:42:45 +02:00
AstAlways * convertToAlways ( ) {
AstNode * lhs1p = lhsp ( ) - > unlinkFrBack ( ) ;
AstNode * rhs1p = rhsp ( ) - > unlinkFrBack ( ) ;
2013-05-01 04:55:28 +02:00
AstAlways * newp = new AstAlways ( fileline ( ) , VAlwaysKwd : : ALWAYS , NULL ,
2009-10-09 02:42:45 +02:00
new AstAssign ( fileline ( ) , lhs1p , rhs1p ) ) ;
replaceWith ( newp ) ; // User expected to then deleteTree();
return newp ;
}
2006-08-26 13:35:28 +02:00
} ;
2013-05-28 03:39:19 +02:00
struct AstAssignVarScope : public AstNodeAssign {
// Assign two VarScopes to each other
AstAssignVarScope ( FileLine * fileline , AstNode * lhsp , AstNode * rhsp )
: AstNodeAssign ( fileline , lhsp , rhsp ) {
dtypeFrom ( rhsp ) ;
}
ASTNODE_NODE_FUNCS ( AssignVarScope , ASSIGNVARSCOPE )
virtual AstNode * cloneType ( AstNode * lhsp , AstNode * rhsp ) { return new AstAssignVarScope ( this - > fileline ( ) , lhsp , rhsp ) ; }
} ;
2009-01-06 17:03:57 +01:00
struct AstPull : public AstNode {
private :
bool m_direction ;
public :
2012-03-20 21:01:53 +01:00
AstPull ( FileLine * fileline , AstNode * lhsp , bool direction )
2009-01-06 17:03:57 +01:00
: AstNode ( fileline ) {
setOp1p ( lhsp ) ;
m_direction = direction ;
}
ASTNODE_NODE_FUNCS ( Pull , PULL )
virtual bool same ( AstNode * samep ) const {
return direction ( ) = = samep - > castPull ( ) - > direction ( ) ; }
void lhsp ( AstNode * np ) { setOp1p ( np ) ; }
AstNode * lhsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Assign to
uint32_t direction ( ) const { return ( uint32_t ) m_direction ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstAssignPre : public AstNodeAssign {
// Like Assign, but predelayed assignment requiring special order handling
AstAssignPre ( FileLine * fileline , AstNode * lhsp , AstNode * rhsp )
: AstNodeAssign ( fileline , lhsp , rhsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( AssignPre , ASSIGNPRE )
2006-08-26 13:35:28 +02:00
virtual AstNode * cloneType ( AstNode * lhsp , AstNode * rhsp ) { return new AstAssignPre ( this - > fileline ( ) , lhsp , rhsp ) ; }
} ;
struct AstAssignPost : public AstNodeAssign {
// Like Assign, but predelayed assignment requiring special order handling
AstAssignPost ( FileLine * fileline , AstNode * lhsp , AstNode * rhsp )
: AstNodeAssign ( fileline , lhsp , rhsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( AssignPost , ASSIGNPOST )
2006-08-26 13:35:28 +02:00
virtual AstNode * cloneType ( AstNode * lhsp , AstNode * rhsp ) { return new AstAssignPost ( this - > fileline ( ) , lhsp , rhsp ) ; }
} ;
struct AstComment : public AstNodeStmt {
// Some comment to put into the output stream
// Parents: {statement list}
// Children: none
private :
string m_name ; // Name of variable
public :
AstComment ( FileLine * fl , const string & name )
: AstNodeStmt ( fl )
, m_name ( name ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Comment , COMMENT )
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return m_name ; } // * = Var name
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; } // Ignore name in comments
virtual bool same ( AstNode * samep ) const { return true ; } // Ignore name in comments
} ;
struct AstCond : public AstNodeCond {
// Conditional ?: statement
// Parents: MATH
// Children: MATH
AstCond ( FileLine * fl , AstNode * condp , AstNode * expr1p , AstNode * expr2p )
: AstNodeCond ( fl , condp , expr1p , expr2p ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Cond , COND )
2006-08-26 13:35:28 +02:00
} ;
struct AstCondBound : public AstNodeCond {
// Conditional ?: statement, specially made for saftey checking of array bounds
// Parents: MATH
// Children: MATH
AstCondBound ( FileLine * fl , AstNode * condp , AstNode * expr1p , AstNode * expr2p )
: AstNodeCond ( fl , condp , expr1p , expr2p ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CondBound , CONDBOUND )
2006-08-26 13:35:28 +02:00
} ;
struct AstCoverDecl : public AstNodeStmt {
// Coverage analysis point declaration
// Parents: {statement list}
// Children: none
private :
2008-12-12 21:34:02 +01:00
AstCoverDecl * m_dataDeclp ; // [After V3CoverageJoin] Pointer to duplicate declaration to get data from instead
2008-12-12 22:04:56 +01:00
string m_page ;
2006-08-26 13:35:28 +02:00
string m_text ;
string m_hier ;
int m_column ;
2008-12-05 16:54:14 +01:00
int m_binNum ; // Set by V3EmitCSyms to tell final V3Emit what to increment
2006-08-26 13:35:28 +02:00
public :
2008-12-12 22:04:56 +01:00
AstCoverDecl ( FileLine * fl , int column , const string & page , const string & comment )
2006-08-26 13:35:28 +02:00
: AstNodeStmt ( fl ) {
2008-12-12 22:04:56 +01:00
m_text = comment ; m_page = page ; m_column = column ;
2008-12-05 16:54:14 +01:00
m_binNum = 0 ;
2008-12-12 21:34:02 +01:00
m_dataDeclp = NULL ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CoverDecl , COVERDECL )
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const {
BROKEN_RTN ( m_dataDeclp & & ! m_dataDeclp - > brokeExists ( ) ) ;
2008-12-12 21:34:02 +01:00
if ( m_dataDeclp & & m_dataDeclp - > m_dataDeclp ) v3fatalSrc ( " dataDeclp should point to real data, not be a list " ) ; // Avoid O(n^2) accessing
2013-05-25 23:05:22 +02:00
return NULL ; }
2008-12-12 21:34:02 +01:00
virtual void cloneRelink ( ) { if ( m_dataDeclp & & m_dataDeclp - > clonep ( ) ) m_dataDeclp = m_dataDeclp - > clonep ( ) - > castCoverDecl ( ) ; }
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str ) ;
virtual int instrCount ( ) const { return 1 + 2 * instrCountLd ( ) ; }
2006-10-05 02:45:39 +02:00
virtual bool maybePointedTo ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
int column ( ) const { return m_column ; }
2008-12-05 16:54:14 +01:00
void binNum ( int flag ) { m_binNum = flag ; }
int binNum ( ) const { return m_binNum ; }
2006-08-26 13:35:28 +02:00
const string & comment ( ) const { return m_text ; } // text to insert in code
2008-12-12 22:04:56 +01:00
const string & page ( ) const { return m_page ; }
2006-08-26 13:35:28 +02:00
const string & hier ( ) const { return m_hier ; }
void hier ( const string & flag ) { m_hier = flag ; }
void comment ( const string & flag ) { m_text = flag ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const {
return ( fileline ( ) = = samep - > castCoverDecl ( ) - > fileline ( )
& & hier ( ) = = samep - > castCoverDecl ( ) - > hier ( )
& & comment ( ) = = samep - > castCoverDecl ( ) - > comment ( )
& & column ( ) = = samep - > castCoverDecl ( ) - > column ( ) ) ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2008-12-12 21:34:02 +01:00
void dataDeclp ( AstCoverDecl * nodep ) { m_dataDeclp = nodep ; }
// dataDecl NULL means "use this one", but often you want "this" to indicate to get data from here
AstCoverDecl * dataDeclNullp ( ) const { return m_dataDeclp ; }
AstCoverDecl * dataDeclThisp ( ) { return dataDeclNullp ( ) ? dataDeclNullp ( ) : this ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstCoverInc : public AstNodeStmt {
// Coverage analysis point; increment coverage count
// Parents: {statement list}
// Children: none
private :
AstCoverDecl * m_declp ; // [After V3Coverage] Pointer to declaration
public :
AstCoverInc ( FileLine * fl , AstCoverDecl * declp )
: AstNodeStmt ( fl ) {
m_declp = declp ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CoverInc , COVERINC )
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ! declp ( ) - > brokeExists ( ) ) ; return NULL ; }
2006-08-26 13:35:28 +02:00
virtual void cloneRelink ( ) { if ( m_declp - > clonep ( ) ) m_declp = m_declp - > clonep ( ) - > castCoverDecl ( ) ; }
virtual void dump ( ostream & str ) ;
virtual int instrCount ( ) const { return 1 + 2 * instrCountLd ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( declp ( ) ) ; }
virtual bool same ( AstNode * samep ) const {
return declp ( ) = = samep - > castCoverInc ( ) - > declp ( ) ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual bool isOutputter ( ) const { return true ; }
2011-12-16 01:13:54 +01:00
// but isPure() true
2006-08-26 13:35:28 +02:00
AstCoverDecl * declp ( ) const { return m_declp ; } // Where defined
} ;
2008-12-12 21:34:02 +01:00
struct AstCoverToggle : public AstNodeStmt {
// Toggle analysis of given signal
// Parents: MODULE
// Children: AstCoverInc, orig var, change det var
AstCoverToggle ( FileLine * fl , AstCoverInc * incp , AstNode * origp , AstNode * changep )
: AstNodeStmt ( fl ) {
setOp1p ( incp ) ;
setOp2p ( origp ) ;
setOp3p ( changep ) ;
}
ASTNODE_NODE_FUNCS ( CoverToggle , COVERTOGGLE )
virtual int instrCount ( ) const { return 3 + instrCountBranch ( ) + instrCountLd ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * ) const { return true ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return true ; }
virtual bool isOutputter ( ) const { return false ; } // Though the AstCoverInc under this is an outputter
2011-12-16 01:13:54 +01:00
// but isPure() true
2008-12-12 21:34:02 +01:00
AstCoverInc * incp ( ) const { return op1p ( ) - > castCoverInc ( ) ; }
void incp ( AstCoverInc * nodep ) { setOp1p ( nodep ) ; }
AstNode * origp ( ) const { return op2p ( ) ; }
AstNode * changep ( ) const { return op3p ( ) ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstGenCase : public AstNodeCase {
// Generate Case statement
// Parents: {statement list}
// exprp Children: MATHs
// casesp Children: CASEITEMs
AstGenCase ( FileLine * fileline , AstNode * exprp , AstNode * casesp )
: AstNodeCase ( fileline , exprp , casesp ) {
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( GenCase , GENCASE )
2006-08-26 13:35:28 +02:00
} ;
struct AstCase : public AstNodeCase {
// Case statement
// Parents: {statement list}
// exprp Children: MATHs
// casesp Children: CASEITEMs
private :
2014-01-21 03:59:53 +01:00
VCaseType m_casex ; // 0=case, 1=casex, 2=casez
2006-08-26 13:35:28 +02:00
bool m_fullPragma ; // Synthesis full_case
bool m_parallelPragma ; // Synthesis parallel_case
2010-12-26 03:58:28 +01:00
bool m_uniquePragma ; // unique case
bool m_unique0Pragma ; // unique0 case
bool m_priorityPragma ; // priority case
2006-08-26 13:35:28 +02:00
public :
2014-01-21 03:59:53 +01:00
AstCase ( FileLine * fileline , VCaseType casex , AstNode * exprp , AstNode * casesp )
2006-08-26 13:35:28 +02:00
: AstNodeCase ( fileline , exprp , casesp ) {
m_casex = casex ;
m_fullPragma = false ; m_parallelPragma = false ;
2010-12-26 03:58:28 +01:00
m_uniquePragma = false ; m_unique0Pragma = false ; m_priorityPragma = false ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Case , CASE )
2008-07-22 19:07:19 +02:00
virtual string verilogKwd ( ) const { return casez ( ) ? " casez " : casex ( ) ? " casex " : " case " ; }
virtual bool same ( AstNode * samep ) const {
return m_casex = = samep - > castCase ( ) - > m_casex ; }
2014-01-21 03:59:53 +01:00
bool casex ( ) const { return m_casex = = VCaseType : : CT_CASEX ; }
bool casez ( ) const { return m_casex = = VCaseType : : CT_CASEZ ; }
bool caseInside ( ) const { return m_casex = = VCaseType : : CT_CASEINSIDE ; }
bool caseSimple ( ) const { return m_casex = = VCaseType : : CT_CASE ; }
void caseInsideSet ( ) { m_casex = VCaseType : : CT_CASEINSIDE ; }
2006-08-26 13:35:28 +02:00
bool fullPragma ( ) const { return m_fullPragma ; }
void fullPragma ( bool flag ) { m_fullPragma = flag ; }
2008-07-22 19:07:19 +02:00
bool parallelPragma ( ) const { return m_parallelPragma ; }
2006-08-26 13:35:28 +02:00
void parallelPragma ( bool flag ) { m_parallelPragma = flag ; }
2010-12-26 03:58:28 +01:00
bool uniquePragma ( ) const { return m_uniquePragma ; }
void uniquePragma ( bool flag ) { m_uniquePragma = flag ; }
bool unique0Pragma ( ) const { return m_unique0Pragma ; }
void unique0Pragma ( bool flag ) { m_unique0Pragma = flag ; }
bool priorityPragma ( ) const { return m_priorityPragma ; }
void priorityPragma ( bool flag ) { m_priorityPragma = flag ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstCaseItem : public AstNode {
// Single item of a case statement
// Parents: CASE
// condsp Children: MATH (Null condition used for default block)
// bodysp Children: Statements
private :
bool m_ignoreOverlap ; // Default created by assertions; ignore overlaps
public :
AstCaseItem ( FileLine * fileline , AstNode * condsp , AstNode * bodysp )
: AstNode ( fileline ) {
addNOp1p ( condsp ) ; addNOp2p ( bodysp ) ;
m_ignoreOverlap = false ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CaseItem , CASEITEM )
2006-08-26 13:35:28 +02:00
virtual int instrCount ( ) const { return widthInstrs ( ) + instrCountBranch ( ) ; }
AstNode * condsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1= list of possible matching expressions
AstNode * bodysp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2= what to do
2006-12-19 17:26:49 +01:00
void condsp ( AstNode * nodep ) { setOp1p ( nodep ) ; }
2006-08-26 13:35:28 +02:00
void addBodysp ( AstNode * newp ) { addOp2p ( newp ) ; }
bool isDefault ( ) const { return condsp ( ) = = NULL ; }
bool ignoreOverlap ( ) const { return m_ignoreOverlap ; }
void ignoreOverlap ( bool flag ) { m_ignoreOverlap = flag ; }
} ;
2011-07-23 14:25:41 +02:00
struct AstSFormatF : public AstNode {
2011-11-30 04:36:51 +01:00
// Convert format to string, generally under an AstDisplay or AstSFormat
2010-01-18 02:06:08 +01:00
// Also used as "real" function for /*verilator sformat*/ functions
2010-01-17 21:53:12 +01:00
string m_text ;
2010-01-18 02:06:08 +01:00
bool m_hidden ; // Under display, etc
2010-01-17 21:53:12 +01:00
public :
2010-01-18 02:06:08 +01:00
AstSFormatF ( FileLine * fl , const string & text , bool hidden , AstNode * exprsp )
: AstNode ( fl ) , m_text ( text ) , m_hidden ( hidden ) {
2010-01-17 21:53:12 +01:00
addNOp1p ( exprsp ) ; addNOp2p ( NULL ) ; }
ASTNODE_NODE_FUNCS ( SFormatF , SFORMATF )
virtual string name ( ) const { return m_text ; }
virtual int instrCount ( ) const { return instrCountPli ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( text ( ) ) ; }
virtual bool same ( AstNode * samep ) const { return text ( ) = = samep - > castSFormatF ( ) - > text ( ) ; }
2010-01-18 01:13:44 +01:00
virtual string verilogKwd ( ) const { return " $sformatf " ; }
2010-01-17 21:53:12 +01:00
void exprsp ( AstNode * nodep ) { addOp1p ( nodep ) ; } // op1 = Expressions to output
AstNode * exprsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Expressions to output
string text ( ) const { return m_text ; } // * = Text to display
void text ( const string & text ) { m_text = text ; }
AstScopeName * scopeNamep ( ) const { return op2p ( ) - > castScopeName ( ) ; }
void scopeNamep ( AstNode * nodep ) { setNOp2p ( nodep ) ; }
bool formatScopeTracking ( ) const { // Track scopeNamep(); Ok if false positive
return ( name ( ) . find ( " %m " ) ! = string : : npos | | name ( ) . find ( " %M " ) ! = string : : npos ) ; }
2010-01-18 02:06:08 +01:00
bool hidden ( ) const { return m_hidden ; }
2010-01-17 21:53:12 +01:00
} ;
2012-12-16 03:41:37 +01:00
struct AstDisplay : public AstNodeStmt {
2006-12-21 22:53:51 +01:00
// Parents: stmtlist
2010-01-17 21:53:12 +01:00
// Children: file which must be a varref
// Children: SFORMATF to generate print string
2006-08-26 13:35:28 +02:00
private :
2007-03-06 22:43:38 +01:00
AstDisplayType m_displayType ;
2006-08-26 13:35:28 +02:00
public :
2007-03-06 22:43:38 +01:00
AstDisplay ( FileLine * fileline , AstDisplayType dispType , const string & text , AstNode * filep , AstNode * exprsp )
2012-12-16 03:41:37 +01:00
: AstNodeStmt ( fileline ) {
2010-01-18 02:06:08 +01:00
setOp1p ( new AstSFormatF ( fileline , text , true , exprsp ) ) ;
2009-11-24 03:24:55 +01:00
setNOp3p ( filep ) ;
2007-03-06 22:43:38 +01:00
m_displayType = dispType ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Display , DISPLAY )
2008-03-26 15:58:30 +01:00
virtual void dump ( ostream & str ) ;
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ! fmtp ( ) ) ; return NULL ; }
2007-03-06 22:43:38 +01:00
virtual string verilogKwd ( ) const { return ( filep ( ) ? ( string ) " $f " + ( string ) displayType ( ) . ascii ( )
: ( string ) " $ " + ( string ) displayType ( ) . ascii ( ) ) ; }
2006-08-26 13:35:28 +02:00
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: $display has 'visual' ordering
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; } // SPECIAL: $display makes output
virtual bool isUnlikely ( ) const { return true ; }
2010-01-17 21:53:12 +01:00
virtual V3Hash sameHash ( ) const { return V3Hash ( displayType ( ) ) ; }
virtual bool same ( AstNode * samep ) const { return displayType ( ) = = samep - > castDisplay ( ) - > displayType ( ) ; }
virtual int instrCount ( ) const { return instrCountPli ( ) ; }
2007-03-06 22:43:38 +01:00
AstDisplayType displayType ( ) const { return m_displayType ; }
void displayType ( AstDisplayType type ) { m_displayType = type ; }
bool addNewline ( ) const { return displayType ( ) . addNewline ( ) ; } // * = Add a newline for $display
2010-01-17 21:53:12 +01:00
void fmtp ( AstSFormatF * nodep ) { addOp1p ( nodep ) ; } // op1 = To-String formatter
AstSFormatF * fmtp ( ) const { return op1p ( ) - > castSFormatF ( ) ; }
2009-11-24 03:24:55 +01:00
AstNode * filep ( ) const { return op3p ( ) ; }
void filep ( AstNodeVarRef * nodep ) { setNOp3p ( nodep ) ; }
} ;
2010-01-17 21:53:12 +01:00
struct AstSFormat : public AstNode {
2009-11-24 03:24:55 +01:00
// Parents: statement container
// Children: string to load
2010-01-17 21:53:12 +01:00
// Children: SFORMATF to generate print string
2009-11-24 03:24:55 +01:00
AstSFormat ( FileLine * fileline , AstNode * lhsp , const string & text , AstNode * exprsp )
2010-01-17 21:53:12 +01:00
: AstNode ( fileline ) {
2010-01-18 02:06:08 +01:00
setOp1p ( new AstSFormatF ( fileline , text , true , exprsp ) ) ;
2009-11-24 03:24:55 +01:00
setOp3p ( lhsp ) ;
}
ASTNODE_NODE_FUNCS ( SFormat , SFORMAT )
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ! fmtp ( ) ) ; return NULL ; }
2009-11-24 03:24:55 +01:00
virtual string verilogKwd ( ) const { return " $sformat " ; }
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return true ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return true ; }
2009-11-24 03:24:55 +01:00
virtual bool isOutputter ( ) const { return false ; }
virtual bool cleanOut ( ) { return false ; }
2010-01-17 21:53:12 +01:00
virtual int instrCount ( ) const { return instrCountPli ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
void fmtp ( AstSFormatF * nodep ) { addOp1p ( nodep ) ; } // op1 = To-String formatter
AstSFormatF * fmtp ( ) const { return op1p ( ) - > castSFormatF ( ) ; }
2009-11-24 03:24:55 +01:00
AstNode * lhsp ( ) const { return op3p ( ) ; }
void lhsp ( AstNode * nodep ) { setOp3p ( nodep ) ; }
2006-08-26 13:35:28 +02:00
} ;
2012-12-16 03:41:37 +01:00
struct AstSysIgnore : public AstNodeStmt {
2010-12-30 13:55:31 +01:00
// Parents: stmtlist
// Children: varrefs or exprs
AstSysIgnore ( FileLine * fileline , AstNode * exprsp )
2012-12-16 03:41:37 +01:00
: AstNodeStmt ( fileline ) { addNOp1p ( exprsp ) ; }
2010-12-30 13:55:31 +01:00
ASTNODE_NODE_FUNCS ( SysIgnore , SYSIGNORE )
virtual string verilogKwd ( ) const { return " $ignored " ; }
virtual bool isGateOptimizable ( ) const { return false ; } // Though deleted before opt
virtual bool isPredictOptimizable ( ) const { return false ; } // Though deleted before opt
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // Though deleted before opt
2010-12-30 13:55:31 +01:00
virtual bool isOutputter ( ) const { return true ; } // Though deleted before opt
virtual int instrCount ( ) const { return instrCountPli ( ) ; }
AstNode * exprsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Expressions to output
void exprsp ( AstNode * nodep ) { addOp1p ( nodep ) ; } // op1 = Expressions to output
} ;
2006-08-26 13:35:28 +02:00
struct AstFClose : public AstNodeStmt {
2006-12-21 22:53:51 +01:00
// Parents: stmtlist
// Children: file which must be a varref
AstFClose ( FileLine * fileline , AstNode * filep )
2006-08-26 13:35:28 +02:00
: AstNodeStmt ( fileline ) {
setNOp2p ( filep ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( FClose , FCLOSE )
2009-07-22 20:38:20 +02:00
virtual string verilogKwd ( ) const { return " $fclose " ; }
2006-08-26 13:35:28 +02:00
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; }
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; }
virtual bool isUnlikely ( ) const { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
2006-12-21 22:53:51 +01:00
AstNode * filep ( ) const { return op2p ( ) ; }
2006-08-26 13:35:28 +02:00
void filep ( AstNodeVarRef * nodep ) { setNOp2p ( nodep ) ; }
} ;
struct AstFOpen : public AstNodeStmt {
AstFOpen ( FileLine * fileline , AstNode * filep , AstNode * filenamep , AstNode * modep )
: AstNodeStmt ( fileline ) {
setOp1p ( filep ) ;
setOp2p ( filenamep ) ;
setOp3p ( modep ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( FOpen , FOPEN )
2010-01-15 14:20:25 +01:00
virtual string verilogKwd ( ) const { return " $fopen " ; }
2006-08-26 13:35:28 +02:00
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; }
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; }
virtual bool isUnlikely ( ) const { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
2006-12-21 22:53:51 +01:00
AstNode * filep ( ) const { return op1p ( ) ; }
2006-08-26 13:35:28 +02:00
AstNode * filenamep ( ) const { return op2p ( ) ; }
AstNode * modep ( ) const { return op3p ( ) ; }
} ;
2008-06-27 14:45:05 +02:00
struct AstFFlush : public AstNodeStmt {
// Parents: stmtlist
// Children: file which must be a varref
AstFFlush ( FileLine * fileline , AstNode * filep )
: AstNodeStmt ( fileline ) {
setNOp2p ( filep ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( FFlush , FFLUSH )
2009-07-22 20:38:20 +02:00
virtual string verilogKwd ( ) const { return " $fflush " ; }
2008-06-27 14:45:05 +02:00
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; }
2008-06-27 14:45:05 +02:00
virtual bool isOutputter ( ) const { return true ; }
virtual bool isUnlikely ( ) const { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
AstNode * filep ( ) const { return op2p ( ) ; }
void filep ( AstNodeVarRef * nodep ) { setNOp2p ( nodep ) ; }
} ;
2008-07-01 20:15:10 +02:00
struct AstFScanF : public AstNodeMath {
// Parents: expr
// Children: file which must be a varref
// Children: varrefs to load
private :
string m_text ;
public :
AstFScanF ( FileLine * fileline , const string & text , AstNode * filep , AstNode * exprsp )
: AstNodeMath ( fileline ) , m_text ( text ) {
addNOp1p ( exprsp ) ;
setNOp2p ( filep ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( FScanF , FSCANF )
2008-07-01 20:15:10 +02:00
virtual string name ( ) const { return m_text ; }
virtual string verilogKwd ( ) const { return " $fscanf " ; }
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: has 'visual' ordering
2008-07-01 20:15:10 +02:00
virtual bool isOutputter ( ) const { return true ; } // SPECIAL: makes output
virtual bool cleanOut ( ) { return false ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( text ( ) ) ; }
virtual bool same ( AstNode * samep ) const {
return text ( ) = = samep - > castFScanF ( ) - > text ( ) ; }
AstNode * exprsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Expressions to output
void exprsp ( AstNode * nodep ) { addOp1p ( nodep ) ; } // op1 = Expressions to output
string text ( ) const { return m_text ; } // * = Text to display
void text ( const string & text ) { m_text = text ; }
AstNode * filep ( ) const { return op2p ( ) ; }
void filep ( AstNodeVarRef * nodep ) { setNOp2p ( nodep ) ; }
} ;
struct AstSScanF : public AstNodeMath {
// Parents: expr
// Children: file which must be a varref
// Children: varrefs to load
private :
string m_text ;
public :
AstSScanF ( FileLine * fileline , const string & text , AstNode * fromp , AstNode * exprsp )
: AstNodeMath ( fileline ) , m_text ( text ) {
addNOp1p ( exprsp ) ;
setOp2p ( fromp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( SScanF , SSCANF )
2008-07-01 20:15:10 +02:00
virtual string name ( ) const { return m_text ; }
virtual string verilogKwd ( ) const { return " $sscanf " ; }
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: has 'visual' ordering
2008-07-01 20:15:10 +02:00
virtual bool isOutputter ( ) const { return true ; } // SPECIAL: makes output
virtual bool cleanOut ( ) { return false ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( text ( ) ) ; }
virtual bool same ( AstNode * samep ) const {
return text ( ) = = samep - > castSScanF ( ) - > text ( ) ; }
AstNode * exprsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Expressions to output
void exprsp ( AstNode * nodep ) { addOp1p ( nodep ) ; } // op1 = Expressions to output
string text ( ) const { return m_text ; } // * = Text to display
void text ( const string & text ) { m_text = text ; }
AstNode * fromp ( ) const { return op2p ( ) ; }
void fromp ( AstNode * nodep ) { setOp2p ( nodep ) ; }
} ;
2006-12-19 15:09:57 +01:00
struct AstReadMem : public AstNodeStmt {
private :
bool m_isHex ; // readmemh, not readmemb
public :
AstReadMem ( FileLine * fileline , bool hex ,
AstNode * filenamep , AstNode * memp , AstNode * lsbp , AstNode * msbp )
: AstNodeStmt ( fileline ) , m_isHex ( hex ) {
setOp1p ( filenamep ) ; setOp2p ( memp ) ; setNOp3p ( lsbp ) ; setNOp4p ( msbp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ReadMem , READMEM )
2009-07-22 20:38:20 +02:00
virtual string verilogKwd ( ) const { return ( isHex ( ) ? " $readmemh " : " $readmemb " ) ; }
2006-12-19 15:09:57 +01:00
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; }
2006-12-19 15:09:57 +01:00
virtual bool isOutputter ( ) const { return true ; }
virtual bool isUnlikely ( ) const { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return isHex ( ) = = samep - > castReadMem ( ) - > isHex ( ) ; }
bool isHex ( ) const { return m_isHex ; }
AstNode * filenamep ( ) const { return op1p ( ) - > castNode ( ) ; }
AstNode * memp ( ) const { return op2p ( ) - > castNode ( ) ; }
AstNode * lsbp ( ) const { return op3p ( ) - > castNode ( ) ; }
AstNode * msbp ( ) const { return op4p ( ) - > castNode ( ) ; }
} ;
2011-11-20 08:01:48 +01:00
struct AstSystemT : public AstNodeStmt {
// $system used as task
AstSystemT ( FileLine * fileline , AstNode * lhsp )
: AstNodeStmt ( fileline ) {
setOp1p ( lhsp ) ;
}
ASTNODE_NODE_FUNCS ( SystemT , SYSTEMT )
virtual string verilogKwd ( ) const { return " $system " ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; }
2011-11-20 08:01:48 +01:00
virtual bool isOutputter ( ) const { return true ; }
virtual bool isUnlikely ( ) const { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
AstNode * lhsp ( ) const { return op1p ( ) ; }
} ;
struct AstSystemF : public AstNodeMath {
// $system used as function
AstSystemF ( FileLine * fileline , AstNode * lhsp )
: AstNodeMath ( fileline ) {
setOp1p ( lhsp ) ;
}
ASTNODE_NODE_FUNCS ( SystemF , SYSTEMF )
virtual string verilogKwd ( ) const { return " $system " ; }
virtual string emitVerilog ( ) { return verilogKwd ( ) ; }
virtual string emitC ( ) { return " VL_SYSTEM_%nq(%lw, %P) " ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; }
2011-11-20 08:01:48 +01:00
virtual bool isOutputter ( ) const { return true ; }
virtual bool isUnlikely ( ) const { return true ; }
virtual bool cleanOut ( ) { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
AstNode * lhsp ( ) const { return op1p ( ) ; }
} ;
2009-11-19 23:04:21 +01:00
struct AstValuePlusArgs : public AstNodeMath {
// Parents: expr
// Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs
private :
string m_text ;
public :
AstValuePlusArgs ( FileLine * fileline , const string & text , AstNode * exprsp )
: AstNodeMath ( fileline ) , m_text ( text ) {
setOp1p ( exprsp ) ;
}
ASTNODE_NODE_FUNCS ( ValuePlusArgs , VALUEPLUSARGS )
virtual string name ( ) const { return m_text ; }
virtual string verilogKwd ( ) const { return " $value$plusargs " ; }
virtual string emitVerilog ( ) { return verilogKwd ( ) ; }
virtual string emitC ( ) { return " VL_VALUEPLUSARGS_%nq(%lw, %P, NULL) " ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual bool cleanOut ( ) { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( text ( ) ) ; }
virtual bool same ( AstNode * samep ) const {
return text ( ) = = samep - > castValuePlusArgs ( ) - > text ( ) ; }
AstNode * exprsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Expressions to output
void exprsp ( AstNode * nodep ) { setOp1p ( nodep ) ; } // op1 = Expressions to output
string text ( ) const { return m_text ; } // * = Text to display
void text ( const string & text ) { m_text = text ; }
} ;
struct AstTestPlusArgs : public AstNodeMath {
// Parents: expr
// Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs
private :
string m_text ;
public :
AstTestPlusArgs ( FileLine * fileline , const string & text )
: AstNodeMath ( fileline ) , m_text ( text ) { }
ASTNODE_NODE_FUNCS ( TestPlusArgs , TESTPLUSARGS )
virtual string name ( ) const { return m_text ; }
virtual string verilogKwd ( ) const { return " $test$plusargs " ; }
virtual string emitVerilog ( ) { return verilogKwd ( ) ; }
virtual string emitC ( ) { return " VL_VALUEPLUSARGS_%nq(%lw, %P, NULL) " ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual bool cleanOut ( ) { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( text ( ) ) ; }
virtual bool same ( AstNode * samep ) const {
return text ( ) = = samep - > castTestPlusArgs ( ) - > text ( ) ; }
string text ( ) const { return m_text ; } // * = Text to display
void text ( const string & text ) { m_text = text ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstGenFor : public AstNodeFor {
AstGenFor ( FileLine * fileline , AstNode * initsp , AstNode * condp ,
2006-09-05 22:06:23 +02:00
AstNode * incsp , AstNode * bodysp )
: AstNodeFor ( fileline , initsp , condp , incsp , bodysp ) {
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( GenFor , GENFOR )
2006-08-26 13:35:28 +02:00
} ;
2009-02-26 04:06:59 +01:00
struct AstRepeat : public AstNodeStmt {
AstRepeat ( FileLine * fileline , AstNode * countp , AstNode * bodysp )
: AstNodeStmt ( fileline ) {
setOp2p ( countp ) ; addNOp3p ( bodysp ) ;
}
ASTNODE_NODE_FUNCS ( Repeat , REPEAT )
AstNode * countp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2= condition to continue
AstNode * bodysp ( ) const { return op3p ( ) - > castNode ( ) ; } // op3= body of loop
2009-07-21 20:31:16 +02:00
virtual bool isGateOptimizable ( ) const { return false ; } // Not releavant - converted to FOR
2009-02-26 04:06:59 +01:00
virtual int instrCount ( ) const { return instrCountBranch ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstWhile : public AstNodeStmt {
2010-02-14 16:01:21 +01:00
AstWhile ( FileLine * fileline , AstNode * condp , AstNode * bodysp , AstNode * incsp = NULL )
2006-08-26 13:35:28 +02:00
: AstNodeStmt ( fileline ) {
2010-02-14 16:01:21 +01:00
setOp2p ( condp ) ; addNOp3p ( bodysp ) ; addNOp4p ( incsp ) ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( While , WHILE )
2006-08-26 13:35:28 +02:00
AstNode * precondsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1= prepare statements for condition (exec every loop)
AstNode * condp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2= condition to continue
AstNode * bodysp ( ) const { return op3p ( ) - > castNode ( ) ; } // op3= body of loop
2010-02-14 16:01:21 +01:00
AstNode * incsp ( ) const { return op4p ( ) - > castNode ( ) ; } // op4= increment (if from a FOR loop)
2006-08-26 13:35:28 +02:00
void addPrecondsp ( AstNode * newp ) { addOp1p ( newp ) ; }
void addBodysp ( AstNode * newp ) { addOp3p ( newp ) ; }
2010-02-14 16:01:21 +01:00
void addIncsp ( AstNode * newp ) { addOp4p ( newp ) ; }
2006-08-26 13:35:28 +02:00
virtual bool isGateOptimizable ( ) const { return false ; }
virtual int instrCount ( ) const { return instrCountBranch ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
2012-03-20 21:01:53 +01:00
virtual void addBeforeStmt ( AstNode * newp , AstNode * belowp ) ; // Stop statement searchback here
virtual void addNextStmt ( AstNode * newp , AstNode * belowp ) ; // Stop statement searchback here
2006-08-26 13:35:28 +02:00
} ;
2010-02-14 16:01:21 +01:00
struct AstBreak : public AstNodeStmt {
AstBreak ( FileLine * fileline )
: AstNodeStmt ( fileline ) { }
ASTNODE_NODE_FUNCS ( Break , BREAK )
virtual string verilogKwd ( ) const { return " break " ; } ;
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
2011-12-16 04:23:11 +01:00
virtual bool isBrancher ( ) const { return true ; } // SPECIAL: We don't process code after breaks
2010-02-14 16:01:21 +01:00
} ;
struct AstContinue : public AstNodeStmt {
AstContinue ( FileLine * fileline )
: AstNodeStmt ( fileline ) { }
ASTNODE_NODE_FUNCS ( Continue , CONTINUE )
virtual string verilogKwd ( ) const { return " continue " ; } ;
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
2011-12-16 04:23:11 +01:00
virtual bool isBrancher ( ) const { return true ; } // SPECIAL: We don't process code after breaks
2010-02-14 16:01:21 +01:00
} ;
2011-06-29 03:26:49 +02:00
struct AstDisable : public AstNodeStmt {
private :
string m_name ; // Name of block
public :
AstDisable ( FileLine * fileline , const string & name )
: AstNodeStmt ( fileline ) , m_name ( name ) { }
ASTNODE_NODE_FUNCS ( Disable , DISABLE )
virtual string name ( ) const { return m_name ; } // * = Block name
void name ( const string & flag ) { m_name = flag ; }
2011-12-16 04:23:11 +01:00
virtual bool isBrancher ( ) const { return true ; } // SPECIAL: We don't process code after breaks
2011-06-29 03:26:49 +02:00
} ;
2010-02-14 16:01:21 +01:00
struct AstReturn : public AstNodeStmt {
AstReturn ( FileLine * fileline , AstNode * lhsp = NULL )
: AstNodeStmt ( fileline ) {
setNOp1p ( lhsp ) ;
}
ASTNODE_NODE_FUNCS ( Return , RETURN )
virtual string verilogKwd ( ) const { return " return " ; } ;
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
AstNode * lhsp ( ) const { return op1p ( ) ; }
2011-12-16 04:23:11 +01:00
virtual bool isBrancher ( ) const { return true ; } // SPECIAL: We don't process code after breaks
2010-02-14 16:01:21 +01:00
} ;
2006-08-26 13:35:28 +02:00
struct AstGenIf : public AstNodeIf {
AstGenIf ( FileLine * fileline , AstNode * condp , AstNode * ifsp , AstNode * elsesp )
: AstNodeIf ( fileline , condp , ifsp , elsesp ) {
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( GenIf , GENIF )
2006-08-26 13:35:28 +02:00
} ;
struct AstIf : public AstNodeIf {
2010-12-26 03:58:28 +01:00
private :
bool m_uniquePragma ; // unique case
bool m_unique0Pragma ; // unique0 case
bool m_priorityPragma ; // priority case
public :
2006-08-26 13:35:28 +02:00
AstIf ( FileLine * fileline , AstNode * condp , AstNode * ifsp , AstNode * elsesp )
: AstNodeIf ( fileline , condp , ifsp , elsesp ) {
2010-12-26 03:58:28 +01:00
m_uniquePragma = false ; m_unique0Pragma = false ; m_priorityPragma = false ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( If , IF )
2010-12-26 03:58:28 +01:00
bool uniquePragma ( ) const { return m_uniquePragma ; }
void uniquePragma ( bool flag ) { m_uniquePragma = flag ; }
bool unique0Pragma ( ) const { return m_unique0Pragma ; }
void unique0Pragma ( bool flag ) { m_unique0Pragma = flag ; }
bool priorityPragma ( ) const { return m_priorityPragma ; }
void priorityPragma ( bool flag ) { m_priorityPragma = flag ; }
2006-08-26 13:35:28 +02:00
} ;
2010-02-14 16:01:21 +01:00
struct AstJumpLabel : public AstNodeStmt {
// Jump point declaration
// Separate from AstJumpGo; as a declaration can't be deleted
// Parents: {statement list}
// Children: {statement list, with JumpGo below}
private :
int m_labelNum ; // Set by V3EmitCSyms to tell final V3Emit what to increment
public :
AstJumpLabel ( FileLine * fl , AstNode * stmtsp )
: AstNodeStmt ( fl ) , m_labelNum ( 0 ) {
addNOp1p ( stmtsp ) ;
}
virtual int instrCount ( ) const { return 0 ; }
ASTNODE_NODE_FUNCS ( JumpLabel , JUMPLABEL )
virtual bool maybePointedTo ( ) const { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
// op1 = Statements
AstNode * stmtsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = List of statements
void addStmtsp ( AstNode * nodep ) { addNOp1p ( nodep ) ; }
int labelNum ( ) const { return m_labelNum ; }
void labelNum ( int flag ) { m_labelNum = flag ; }
} ;
struct AstJumpGo : public AstNodeStmt {
// Jump point; branch up to the JumpLabel
// Parents: {statement list}
private :
AstJumpLabel * m_labelp ; // [After V3Jump] Pointer to declaration
public :
AstJumpGo ( FileLine * fl , AstJumpLabel * labelp )
: AstNodeStmt ( fl ) {
m_labelp = labelp ;
}
ASTNODE_NODE_FUNCS ( JumpGo , JUMPGO )
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ! labelp ( ) - > brokeExistsAbove ( ) ) ; return NULL ; }
2010-02-14 16:01:21 +01:00
virtual void cloneRelink ( ) { if ( m_labelp - > clonep ( ) ) m_labelp = m_labelp - > clonep ( ) - > castJumpLabel ( ) ; }
virtual void dump ( ostream & str ) ;
virtual int instrCount ( ) const { return instrCountBranch ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( labelp ( ) ) ; }
virtual bool same ( AstNode * samep ) const { // Also same if identical tree structure all the way down, but hard to detect
return labelp ( ) = = samep - > castJumpGo ( ) - > labelp ( ) ; }
virtual bool isGateOptimizable ( ) const { return false ; }
2011-12-16 04:23:11 +01:00
virtual bool isBrancher ( ) const { return true ; } // SPECIAL: We don't process code after breaks
2010-02-14 16:01:21 +01:00
AstJumpLabel * labelp ( ) const { return m_labelp ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstUntilStable : public AstNodeStmt {
// Quasi-while loop until given signals are stable
// Parents: CFUNC (generally)
// Children: VARREF, statements
AstUntilStable ( FileLine * fileline , AstVarRef * stablesp , AstNode * bodysp )
: AstNodeStmt ( fileline ) {
addNOp2p ( stablesp ) ; addNOp3p ( bodysp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( UntilStable , UNTILSTABLE )
2006-08-26 13:35:28 +02:00
AstVarRef * stablesp ( ) const { return op2p ( ) - > castVarRef ( ) ; } // op2= list of variables that must become stable
AstNode * bodysp ( ) const { return op3p ( ) - > castNode ( ) ; } // op3= body of loop
void addStablesp ( AstVarRef * newp ) { addOp2p ( newp ) ; }
void addBodysp ( AstNode * newp ) { addOp3p ( newp ) ; }
virtual bool isGateOptimizable ( ) const { return false ; } // Not relevant
virtual bool isPredictOptimizable ( ) const { return false ; } // Not relevant
virtual int instrCount ( ) const { return instrCountBranch ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
struct AstChangeXor : public AstNodeBiComAsv {
// A comparison to determine change detection, common & must be fast.
// Returns 32-bit or 64-bit value where 0 indicates no change.
// Parents: OR or LOGOR
// Children: VARREF
AstChangeXor ( FileLine * fl , AstNode * lhsp , AstNode * rhsp )
: AstNodeBiComAsv ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetUInt32 ( ) ; // Always used on, and returns word entities
2012-02-20 15:55:20 +01:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ChangeXor , CHANGEXOR )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opChangeXor ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f^ %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_CHANGEXOR_%li(%lw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " ^ " ; }
virtual bool cleanOut ( ) { return false ; } // Lclean && Rclean
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) ; }
} ;
struct AstChangeDet : public AstNodeStmt {
// A comparison to determine change detection, common & must be fast.
private :
bool m_clockReq ; // Type of detection
public :
// Null lhs+rhs used to indicate change needed with no spec vars
AstChangeDet ( FileLine * fl , AstNode * lhsp , AstNode * rhsp , bool clockReq )
: AstNodeStmt ( fl ) {
setNOp1p ( lhsp ) ; setNOp2p ( rhsp ) ; m_clockReq = clockReq ;
2012-04-29 16:14:13 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ChangeDet , CHANGEDET )
2006-08-26 13:35:28 +02:00
AstNode * lhsp ( ) const { return op1p ( ) ; }
AstNode * rhsp ( ) const { return op2p ( ) ; }
bool isClockReq ( ) const { return m_clockReq ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
2012-07-21 13:28:39 +02:00
struct AstBegin : public AstNode {
// A Begin/end named block, only exists shortly after parsing until linking
// Parents: statement
// Children: statements
private :
string m_name ; // Name of block
bool m_unnamed ; // Originally unnamed
bool m_generate ; // Underneath a generate
public :
// Node that simply puts name into the output stream
AstBegin ( FileLine * fileline , const string & name , AstNode * stmtsp , bool generate = false )
: AstNode ( fileline )
, m_name ( name ) {
addNOp1p ( stmtsp ) ;
m_unnamed = ( name = = " " ) ;
m_generate = generate ;
}
ASTNODE_NODE_FUNCS ( Begin , BEGIN )
virtual void dump ( ostream & str ) ;
virtual string name ( ) const { return m_name ; } // * = Block name
virtual void name ( const string & name ) { m_name = name ; }
// op1 = Statements
2012-07-21 23:12:42 +02:00
AstNode * stmtsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = List of statements
2012-07-21 13:28:39 +02:00
void addStmtsp ( AstNode * nodep ) { addNOp1p ( nodep ) ; }
2012-07-21 23:12:42 +02:00
AstNode * genforp ( ) const { return op2p ( ) ; } // op2 = GENFOR, if applicable,
// might NOT be a GenFor, as loop unrolling replaces with Begin
void addGenforp ( AstGenFor * nodep ) { addOp2p ( nodep ) ; }
2012-07-21 13:28:39 +02:00
bool unnamed ( ) const { return m_unnamed ; }
void generate ( bool flag ) { m_generate = flag ; }
bool generate ( ) const { return m_generate ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstInitial : public AstNode {
AstInitial ( FileLine * fl , AstNode * bodysp )
: AstNode ( fl ) {
addNOp1p ( bodysp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Initial , INITIAL )
2006-08-26 13:35:28 +02:00
AstNode * bodysp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Expressions to evaluate
// Special accessors
bool isJustOneBodyStmt ( ) const { return bodysp ( ) & & ! bodysp ( ) - > nextp ( ) ; }
} ;
struct AstFinal : public AstNode {
AstFinal ( FileLine * fl , AstNode * bodysp )
: AstNode ( fl ) {
addNOp1p ( bodysp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Final , FINAL )
2006-08-26 13:35:28 +02:00
AstNode * bodysp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Expressions to evaluate
} ;
2013-02-02 18:55:28 +01:00
struct AstInside : public AstNodeMath {
AstInside ( FileLine * fl , AstNode * exprp , AstNode * itemsp )
: AstNodeMath ( fl ) {
addOp1p ( exprp ) ; addOp2p ( itemsp ) ;
dtypeSetLogicBool ( ) ;
}
ASTNODE_NODE_FUNCS ( Inside , INSIDE )
AstNode * exprp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = LHS expression to compare with
AstNode * itemsp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2 = RHS, possibly a list of expr or AstInsideRange
virtual string emitVerilog ( ) { return " %l inside { %r } " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool cleanOut ( ) { return false ; } // NA
} ;
struct AstInsideRange : public AstNodeMath {
AstInsideRange ( FileLine * fl , AstNode * lhsp , AstNode * rhsp )
: AstNodeMath ( fl ) {
addOp1p ( lhsp ) ; addOp2p ( rhsp ) ;
}
ASTNODE_NODE_FUNCS ( InsideRange , INSIDERANGE )
AstNode * lhsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = LHS
AstNode * rhsp ( ) const { return op2p ( ) - > castNode ( ) ; } // op2 = RHS
virtual string emitVerilog ( ) { return " [%l:%r] " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool cleanOut ( ) { return false ; } // NA
} ;
2006-08-26 13:35:28 +02:00
struct AstInitArray : public AstNode {
// Set a var to a large list of values
// The values must be in sorted order, and not exceed the size of the var's array.
// Parents: ASTVAR::init()
// Children: CONSTs...
AstInitArray ( FileLine * fl , AstNode * initsp )
: AstNode ( fl ) {
addNOp1p ( initsp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( InitArray , INITARRAY )
2006-08-26 13:35:28 +02:00
AstNode * initsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1 = Initial value expressions
void addInitsp ( AstNode * newp ) { addOp1p ( newp ) ; }
} ;
struct AstPragma : public AstNode {
private :
AstPragmaType m_pragType ; // Type of pragma
public :
// Pragmas don't result in any output code, they're just flags that affect
// other processing in verilator.
AstPragma ( FileLine * fl , AstPragmaType pragType )
: AstNode ( fl ) {
m_pragType = pragType ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Pragma , PRAGMA )
2006-08-26 13:35:28 +02:00
AstPragmaType pragType ( ) const { return m_pragType ; } // *=type of the pragma
virtual V3Hash sameHash ( ) const { return V3Hash ( pragType ( ) ) ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual bool same ( AstNode * samep ) const {
return pragType ( ) = = samep - > castPragma ( ) - > pragType ( ) ; }
} ;
struct AstStop : public AstNodeStmt {
AstStop ( FileLine * fl )
: AstNodeStmt ( fl ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Stop , STOP )
2006-08-26 13:35:28 +02:00
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: $display has 'visual' ordering
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; } // SPECIAL: $display makes output
virtual bool isUnlikely ( ) const { return true ; }
virtual int instrCount ( ) const { return 0 ; } // Rarely executes
virtual V3Hash sameHash ( ) const { return V3Hash ( fileline ( ) - > lineno ( ) ) ; }
virtual bool same ( AstNode * samep ) const {
return fileline ( ) = = samep - > fileline ( ) ; }
} ;
struct AstFinish : public AstNodeStmt {
AstFinish ( FileLine * fl )
: AstNodeStmt ( fl ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Finish , FINISH )
2006-08-26 13:35:28 +02:00
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: $display has 'visual' ordering
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; } // SPECIAL: $display makes output
virtual bool isUnlikely ( ) const { return true ; }
virtual int instrCount ( ) const { return 0 ; } // Rarely executes
virtual V3Hash sameHash ( ) const { return V3Hash ( fileline ( ) - > lineno ( ) ) ; }
virtual bool same ( AstNode * samep ) const {
return fileline ( ) = = samep - > fileline ( ) ; }
} ;
struct AstTraceDecl : public AstNodeStmt {
// Trace point declaration
// Separate from AstTraceInc; as a declaration can't be deleted
// Parents: {statement list}
// Children: none
private :
string m_showname ; // Name of variable
uint32_t m_code ; // Trace identifier code; converted to ASCII by trace routines
2013-12-14 18:17:31 +01:00
VNumRange m_bitRange ; // Property of var the trace details
VNumRange m_arrayRange ; // Property of var the trace details
2006-08-26 13:35:28 +02:00
uint32_t m_codeInc ; // Code increment
public :
2013-12-14 22:51:08 +01:00
AstTraceDecl ( FileLine * fl , const string & showname , AstNode * valuep ,
const VNumRange & bitRange , const VNumRange & arrayRange )
2006-08-26 13:35:28 +02:00
: AstNodeStmt ( fl )
2013-12-14 22:51:08 +01:00
, m_showname ( showname ) , m_bitRange ( bitRange ) , m_arrayRange ( arrayRange ) {
dtypeFrom ( valuep ) ;
2006-08-26 13:35:28 +02:00
m_code = 0 ;
2013-12-14 22:51:08 +01:00
m_codeInc = ( ( arrayRange . ranged ( ) ? arrayRange . elements ( ) : 1 )
* valuep - > dtypep ( ) - > widthWords ( ) ) ;
2006-08-26 13:35:28 +02:00
}
virtual int instrCount ( ) const { return 100 ; } // Large...
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( TraceDecl , TRACEDECL )
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return m_showname ; }
2006-10-05 02:45:39 +02:00
virtual bool maybePointedTo ( ) const { return true ; }
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
virtual bool same ( AstNode * samep ) const { return false ; }
2012-02-21 02:48:13 +01:00
string showname ( ) const { return m_showname ; } // * = Var name
2006-08-26 13:35:28 +02:00
// Details on what we're tracing
uint32_t code ( ) const { return m_code ; }
void code ( uint32_t code ) { m_code = code ; }
uint32_t codeInc ( ) const { return m_codeInc ; }
2013-12-14 18:17:31 +01:00
const VNumRange & bitRange ( ) const { return m_bitRange ; }
const VNumRange & arrayRange ( ) const { return m_arrayRange ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstTraceInc : public AstNodeStmt {
// Trace point; incremental change detect and dump
// Parents: {statement list}
// Children: incremental value
private :
AstTraceDecl * m_declp ; // [After V3Trace] Pointer to declaration
public :
AstTraceInc ( FileLine * fl , AstTraceDecl * declp , AstNode * valuep )
: AstNodeStmt ( fl ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( declp ) ;
2006-08-26 13:35:28 +02:00
m_declp = declp ;
addNOp2p ( valuep ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( TraceInc , TRACEINC )
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ! declp ( ) - > brokeExists ( ) ) ; return NULL ; }
2006-08-26 13:35:28 +02:00
virtual void cloneRelink ( ) { if ( m_declp - > clonep ( ) ) m_declp = m_declp - > clonep ( ) - > castTraceDecl ( ) ; }
virtual void dump ( ostream & str ) ;
virtual int instrCount ( ) const { return 10 + 2 * instrCountLd ( ) ; }
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
virtual V3Hash sameHash ( ) const { return V3Hash ( declp ( ) ) ; }
virtual bool same ( AstNode * samep ) const {
return declp ( ) = = samep - > castTraceInc ( ) - > declp ( ) ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual bool isOutputter ( ) const { return true ; }
2011-12-16 01:13:54 +01:00
// but isPure() true
2006-08-26 13:35:28 +02:00
// op1 = Statements before the value
AstNode * precondsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1= prepare statements for condition (exec every loop)
void addPrecondsp ( AstNode * newp ) { addOp1p ( newp ) ; }
// op2 = Value to trace
AstTraceDecl * declp ( ) const { return m_declp ; } // Where defined
AstNode * valuep ( ) const { return op2p ( ) - > castNode ( ) ; }
} ;
struct AstActive : public AstNode {
// Block of code with sensitivity activation
// Parents: MODULE | CFUNC
// Children: SENTREE, statements
private :
string m_name ;
AstSenTree * m_sensesp ;
public :
AstActive ( FileLine * fileline , const string & name , AstSenTree * sensesp )
: AstNode ( fileline ) {
m_name = name ; // Copy it
UASSERT ( sensesp , " Sensesp required arg " ) ;
m_sensesp = sensesp ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Active , ACTIVE )
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str = cout ) ;
virtual string name ( ) const { return m_name ; }
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( m_sensesp & & ! m_sensesp - > brokeExists ( ) ) ; return NULL ; }
2006-08-26 13:35:28 +02:00
virtual void cloneRelink ( ) {
if ( m_sensesp - > clonep ( ) ) {
m_sensesp = m_sensesp - > clonep ( ) - > castSenTree ( ) ;
UASSERT ( m_sensesp , " Bad clone cross link: " < < this ) ;
}
}
// Statements are broken into pieces, as some must come before others.
void sensesp ( AstSenTree * nodep ) { m_sensesp = nodep ; }
AstSenTree * sensesp ( ) const { return m_sensesp ; }
// op1 = Sensitivity tree, if a clocked block in early stages
void sensesStorep ( AstSenTree * nodep ) { addOp1p ( nodep ) ; }
AstSenTree * sensesStorep ( ) const { return op1p ( ) - > castSenTree ( ) ; }
// op2 = Combo logic
AstNode * stmtsp ( ) const { return op2p ( ) - > castNode ( ) ; }
void addStmtsp ( AstNode * nodep ) { addOp2p ( nodep ) ; }
// METHODS
bool hasInitial ( ) const { return m_sensesp - > hasInitial ( ) ; }
bool hasSettle ( ) const { return m_sensesp - > hasSettle ( ) ; }
bool hasClocked ( ) const { return m_sensesp - > hasClocked ( ) ; }
} ;
2006-09-27 20:00:53 +02:00
struct AstAttrOf : public AstNode {
private :
2006-08-26 13:35:28 +02:00
// Return a value of a attribute, for example a LSB or array LSB of a signal
AstAttrType m_attrType ; // What sort of extraction
public :
2013-01-20 18:19:22 +01:00
AstAttrOf ( FileLine * fl , AstAttrType attrtype , AstNode * fromp = NULL , AstNode * dimp = NULL )
2006-08-26 13:35:28 +02:00
: AstNode ( fl ) {
2009-10-25 21:53:55 +01:00
setNOp1p ( fromp ) ;
2013-01-20 18:19:22 +01:00
setNOp2p ( dimp ) ;
2009-10-25 21:53:55 +01:00
m_attrType = attrtype ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( AttrOf , ATTROF )
2006-08-26 13:35:28 +02:00
AstNode * fromp ( ) const { return op1p ( ) ; }
2013-01-20 18:19:22 +01:00
AstNode * dimp ( ) const { return op2p ( ) ; }
2006-08-26 13:35:28 +02:00
AstAttrType attrType ( ) const { return m_attrType ; }
2009-05-08 00:28:05 +02:00
virtual void dump ( ostream & str = cout ) ;
2006-08-26 13:35:28 +02:00
} ;
2009-12-05 16:38:49 +01:00
struct AstScopeName : public AstNodeMath {
// For display %m and DPI context imports
2007-06-14 18:41:32 +02:00
// Parents: DISPLAY
// Children: TEXT
2009-12-20 14:27:00 +01:00
private :
bool m_dpiExport ; // Is for dpiExport
public :
AstScopeName ( FileLine * fl ) : AstNodeMath ( fl ) , m_dpiExport ( false ) {
2012-03-31 16:19:27 +02:00
dtypeSetUInt64 ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ScopeName , SCOPENAME )
2007-06-14 18:41:32 +02:00
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
2009-12-20 14:27:00 +01:00
virtual bool same ( AstNode * samep ) const { return m_dpiExport = = samep - > castScopeName ( ) - > m_dpiExport ; }
2009-12-05 16:38:49 +01:00
virtual string emitVerilog ( ) { return " " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool cleanOut ( ) { return true ; }
2007-06-14 18:41:32 +02:00
AstText * scopeAttrp ( ) const { return op1p ( ) - > castText ( ) ; }
void scopeAttrp ( AstNode * nodep ) { addOp1p ( nodep ) ; }
2009-12-05 16:38:49 +01:00
string scopeSymName ( ) const ; // Name for __Vscope variable including children
string scopePrettyName ( ) const ; // Name for __Vscope printing
2009-12-20 14:27:00 +01:00
bool dpiExport ( ) const { return m_dpiExport ; }
void dpiExport ( bool flag ) { m_dpiExport = flag ; }
2007-06-14 18:41:32 +02:00
} ;
2009-11-21 01:53:40 +01:00
struct AstUdpTable : public AstNode {
AstUdpTable ( FileLine * fl , AstNode * bodysp )
: AstNode ( fl ) {
addNOp1p ( bodysp ) ;
}
ASTNODE_NODE_FUNCS ( UdpTable , UDPTABLE )
AstUdpTableLine * bodysp ( ) const { return op1p ( ) - > castUdpTableLine ( ) ; } // op1 = List of UdpTableLines
} ;
struct AstUdpTableLine : public AstNode {
string m_text ;
public :
AstUdpTableLine ( FileLine * fl , const string & text )
: AstNode ( fl ) , m_text ( text ) { }
ASTNODE_NODE_FUNCS ( UdpTableLine , UDPTABLELINE )
virtual string name ( ) const { return m_text ; }
string text ( ) const { return m_text ; }
} ;
2006-08-26 13:35:28 +02:00
//======================================================================
// non-ary ops
struct AstRand : public AstNodeTermop {
// Return a random number, based upon width()
2008-06-27 17:36:25 +02:00
private :
bool m_reset ; // Random reset, versus always random
public :
2012-04-29 16:14:13 +02:00
AstRand ( FileLine * fl , AstNodeDType * dtp , bool reset ) : AstNodeTermop ( fl ) {
dtypep ( dtp ) ; m_reset = reset ; }
2008-06-27 17:36:25 +02:00
AstRand ( FileLine * fl ) : AstNodeTermop ( fl ) , m_reset ( false ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Rand , RAND )
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$random " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) {
return ( m_reset ?
" VL_RAND_RESET_%nq(%nw, %P) "
: " VL_RANDOM_%nq(%nw, %P) " ) ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual int instrCount ( ) const { return instrCountPli ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
struct AstTime : public AstNodeTermop {
AstTime ( FileLine * fl ) : AstNodeTermop ( fl ) {
2012-03-31 16:19:27 +02:00
dtypeSetUInt64 ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Time , TIME )
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$time " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_TIME_%nq() " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual int instrCount ( ) const { return instrCountTime ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstTimeD : public AstNodeTermop {
AstTimeD ( FileLine * fl ) : AstNodeTermop ( fl ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( TimeD , TIMED )
virtual string emitVerilog ( ) { return " %f$realtime " ; }
virtual string emitC ( ) { return " VL_TIME_D() " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual int instrCount ( ) const { return instrCountTime ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
2008-11-22 21:28:29 +01:00
struct AstUCFunc : public AstNodeMath {
2006-08-26 13:35:28 +02:00
// User's $c function
2011-11-30 04:36:51 +01:00
// Perhaps this should be an AstNodeListop; but there's only one list math right now
2006-08-26 13:35:28 +02:00
AstUCFunc ( FileLine * fl , AstNode * exprsp )
2008-11-22 21:28:29 +01:00
: AstNodeMath ( fl ) {
2006-08-26 13:35:28 +02:00
addNOp1p ( exprsp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( UCFunc , UCFUNC )
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; }
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; } // Implemented specially
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2006-08-26 13:35:28 +02:00
AstNode * bodysp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1= expressions to print
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: User may order w/other sigs
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; }
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isSubstOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual int instrCount ( ) const { return instrCountPli ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
//======================================================================
// Unary ops
2011-07-08 12:03:07 +02:00
struct AstNegate : public AstNodeUniop {
AstNegate ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2011-07-08 12:03:07 +02:00
ASTNODE_NODE_FUNCS ( Negate , NEGATE )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opNegate ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f(- %l) " ; }
2011-07-08 12:03:07 +02:00
virtual string emitC ( ) { return " VL_NEGATE_%lq(%lW, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return true ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstNegateD : public AstNodeUniop {
AstNegateD ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( NegateD , NEGATED )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opNegateD ( lhs ) ; }
virtual string emitVerilog ( ) { return " %f(- %l) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " - " ; }
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstRedAnd : public AstNodeUniop {
AstRedAnd ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( RedAnd , REDAND )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opRedAnd ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f(& %l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_REDAND_%nq%lq(%nw,%lw, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
} ;
struct AstRedOr : public AstNodeUniop {
AstRedOr ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( RedOr , REDOR )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opRedOr ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f(| %l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_REDOR_%lq(%lW, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
} ;
struct AstRedXor : public AstNodeUniop {
AstRedXor ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( RedXor , REDXOR )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opRedXor ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f(^ %l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_REDXOR_%lq(%lW, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; }
2011-12-01 00:50:21 +01:00
virtual bool cleanLhs ( ) { int w = lhsp ( ) - > width ( ) ;
return ( w ! = 1 & & w ! = 2 & & w ! = 4 & & w ! = 8 & & w ! = 16 ) ; }
2006-08-26 13:35:28 +02:00
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return 1 + V3Number : : log2b ( width ( ) ) ; }
} ;
struct AstRedXnor : public AstNodeUniop {
2006-09-27 20:00:53 +02:00
// AstRedXnors are replaced with AstRedXors in V3Const.
2006-08-26 13:35:28 +02:00
AstRedXnor ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( RedXnor , REDXNOR )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opRedXnor ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f(~^ %l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { v3fatalSrc ( " REDXNOR should have became REDXOR " ) ; return " " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return 1 + V3Number : : log2b ( width ( ) ) ; }
} ;
struct AstLogNot : public AstNodeUniop {
AstLogNot ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( LogNot , LOGNOT )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opLogNot ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f(! %l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_LOGNOT_%nq%lq(%nw,%lw, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " ! " ; }
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
} ;
struct AstNot : public AstNodeUniop {
AstNot ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Not , NOT )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opNot ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f(~ %l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_NOT_%lq(%lW, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " ~ " ; }
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return true ; }
} ;
struct AstExtend : public AstNodeUniop {
// Expand a value into a wider entity by 0 extension. Width is implied from nodep->width()
AstExtend ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) { }
2012-04-22 01:30:08 +02:00
AstExtend ( FileLine * fl , AstNode * lhsp , int width ) : AstNodeUniop ( fl , lhsp ) {
dtypeSetLogicSized ( width , width , AstNumeric : : UNSIGNED ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Extend , EXTEND )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opAssign ( lhs ) ; }
virtual string emitVerilog ( ) { return " %l " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_EXTEND_%nq%lq(%nw,%lw, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } // Because the EXTEND operator self-casts
virtual int instrCount ( ) const { return 0 ; }
} ;
struct AstExtendS : public AstNodeUniop {
// Expand a value into a wider entity by sign extension. Width is implied from nodep->width()
AstExtendS ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) { }
2012-04-22 01:30:08 +02:00
AstExtendS ( FileLine * fl , AstNode * lhsp , int width ) : AstNodeUniop ( fl , lhsp ) {
dtypeSetLogicSized ( width , width , AstNumeric : : UNSIGNED ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ExtendS , EXTENDS )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opExtendS ( lhs ) ; }
virtual string emitVerilog ( ) { return " %l " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_EXTENDS_%nq%lq(%nw,%lw, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } // Because the EXTEND operator self-casts
virtual int instrCount ( ) const { return 0 ; }
virtual bool signedFlavor ( ) const { return true ; }
} ;
struct AstSigned : public AstNodeUniop {
// $signed(lhs)
AstSigned ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2011-12-01 01:32:33 +01:00
if ( v3Global . assertDTypesResolved ( ) ) { v3fatalSrc ( " not coded to create after dtypes resolved " ) ; }
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Signed , SIGNED )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opAssign ( lhs ) ; out . isSigned ( false ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$signed(%l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return false ; } // Eliminated before matters
virtual bool sizeMattersLhs ( ) { return true ; } // Eliminated before matters
virtual int instrCount ( ) const { return 0 ; }
} ;
struct AstUnsigned : public AstNodeUniop {
// $unsigned(lhs)
AstUnsigned ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2011-12-01 01:32:33 +01:00
if ( v3Global . assertDTypesResolved ( ) ) { v3fatalSrc ( " not coded to create after dtypes resolved " ) ; }
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Unsigned , UNSIGNED )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opAssign ( lhs ) ; out . isSigned ( false ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$unsigned(%l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return false ; } // Eliminated before matters
virtual bool sizeMattersLhs ( ) { return true ; } // Eliminated before matters
virtual int instrCount ( ) const { return 0 ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstRToIS : public AstNodeUniop {
// $rtoi(lhs)
AstRToIS ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetSigned32 ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( RToIS , RTOIS )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opRToIS ( lhs ) ; }
virtual string emitVerilog ( ) { return " %f$rtoi(%l) " ; }
virtual string emitC ( ) { return " VL_RTOI_I_D(%li) " ; }
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return false ; } // Eliminated before matters
virtual bool sizeMattersLhs ( ) { return false ; } // Eliminated before matters
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
} ;
struct AstRToIRoundS : public AstNodeUniop {
AstRToIRoundS ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetSigned32 ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( RToIRoundS , RTOIROUNDS )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opRToIRoundS ( lhs ) ; }
virtual string emitVerilog ( ) { return " %f$rtoi_rounded(%l) " ; }
virtual string emitC ( ) { return " VL_RTOIROUND_I_D(%li) " ; }
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return false ; } // Eliminated before matters
virtual bool sizeMattersLhs ( ) { return false ; } // Eliminated before matters
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
} ;
struct AstIToRD : public AstNodeUniop {
AstIToRD ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( IToRD , ITORD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opIToRD ( lhs ) ; }
virtual string emitVerilog ( ) { return " %f$itor(%l) " ; }
virtual string emitC ( ) { return " VL_ITOR_D_I(%li) " ; }
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return false ; } // Eliminated before matters
virtual bool sizeMattersLhs ( ) { return false ; } // Eliminated before matters
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
} ;
struct AstRealToBits : public AstNodeUniop {
AstRealToBits ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetUInt64 ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( RealToBits , REALTOBITS )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opRealToBits ( lhs ) ; }
virtual string emitVerilog ( ) { return " %f$realtobits(%l) " ; }
virtual string emitC ( ) { return " VL_CVT_Q_D(%li) " ; }
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return false ; } // Eliminated before matters
virtual bool sizeMattersLhs ( ) { return false ; } // Eliminated before matters
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
} ;
struct AstBitsToRealD : public AstNodeUniop {
AstBitsToRealD ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( BitsToRealD , BITSTOREALD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opBitsToRealD ( lhs ) ; }
virtual string emitVerilog ( ) { return " %f$bitstoreal(%l) " ; }
virtual string emitC ( ) { return " VL_CVT_D_Q(%li) " ; }
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return false ; } // Eliminated before matters
virtual bool sizeMattersLhs ( ) { return false ; } // Eliminated before matters
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
} ;
2008-04-24 15:52:51 +02:00
struct AstCLog2 : public AstNodeUniop {
AstCLog2 ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CLog2 , CLOG2 )
2008-04-24 15:52:51 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opCLog2 ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$clog2(%l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_CLOG2_%lq(%lW, %P, %li) " ; }
2008-04-24 15:52:51 +02:00
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * 16 ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstCountOnes : public AstNodeUniop {
// Number of bits set in vector
AstCountOnes ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CountOnes , COUNTONES )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opCountOnes ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$countones(%l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_COUNTONES_%lq(%lW, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * 16 ; }
} ;
struct AstIsUnknown : public AstNodeUniop {
// True if any unknown bits
AstIsUnknown ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( IsUnknown , ISUNKNOWN )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opIsUnknown ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$isunknown(%l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; }
} ;
struct AstOneHot : public AstNodeUniop {
// True if only single bit set in vector
AstOneHot ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( OneHot , ONEHOT )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opOneHot ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$onehot(%l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_ONEHOT_%lq(%lW, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * 4 ; }
} ;
struct AstOneHot0 : public AstNodeUniop {
// True if only single bit, or no bits set in vector
AstOneHot0 ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( OneHot0 , ONEHOT0 )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opOneHot0 ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$onehot0(%l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_ONEHOT0_%lq(%lW, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * 3 ; }
} ;
2011-03-18 03:25:49 +01:00
struct AstCast : public AstNode {
// Cast to appropriate data type - note lhsp is value, to match AstTypedef, AstCCast, etc
2011-11-30 04:36:51 +01:00
AstCast ( FileLine * fl , AstNode * lhsp , AstNodeDType * dtp ) : AstNode ( fl ) {
setOp1p ( lhsp ) ; setOp2p ( dtp ) ;
2012-04-29 15:42:17 +02:00
dtypeFrom ( dtp ) ;
2011-03-18 03:25:49 +01:00
}
ASTNODE_NODE_FUNCS ( Cast , CAST )
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; }
2012-04-29 16:14:13 +02:00
virtual string emitVerilog ( ) { return " ((%d)'(%l)) " ; }
2011-03-18 03:25:49 +01:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool cleanOut ( ) { V3ERROR_NA ; return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
AstNode * lhsp ( ) const { return op1p ( ) ; }
2012-04-29 16:14:13 +02:00
AstNodeDType * getChildDTypep ( ) const { return childDTypep ( ) ; }
AstNodeDType * childDTypep ( ) const { return op2p ( ) - > castNodeDType ( ) ; }
2011-03-18 03:25:49 +01:00
} ;
2013-03-06 04:13:22 +01:00
struct AstCastSize : public AstNode {
// Cast to specific size; signed/twostate inherited from lower element per IEEE
AstCastSize ( FileLine * fl , AstNode * lhsp , AstConst * rhsp ) : AstNode ( fl ) {
setOp1p ( lhsp ) ; setOp2p ( rhsp ) ;
}
ASTNODE_NODE_FUNCS ( CastSize , CASTSIZE )
virtual string emitVerilog ( ) { return " ((%r)'(%l)) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual bool cleanOut ( ) { V3ERROR_NA ; return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
AstNode * lhsp ( ) const { return op1p ( ) ; }
AstNode * rhsp ( ) const { return op2p ( ) ; }
} ;
2011-03-18 02:09:52 +01:00
struct AstCCast : public AstNodeUniop {
2011-03-18 03:25:49 +01:00
// Cast to C-based data type
2006-08-26 13:35:28 +02:00
private :
int m_size ;
public :
2012-04-02 03:17:58 +02:00
AstCCast ( FileLine * fl , AstNode * lhsp , int setwidth , int minwidth = - 1 ) : AstNodeUniop ( fl , lhsp ) {
2006-08-26 13:35:28 +02:00
m_size = setwidth ;
2012-03-31 16:53:53 +02:00
if ( setwidth ) {
2012-04-02 03:17:58 +02:00
if ( minwidth = = - 1 ) minwidth = setwidth ;
dtypeSetLogicSized ( setwidth , minwidth , AstNumeric : : UNSIGNED ) ;
2012-03-31 16:53:53 +02:00
}
2006-08-26 13:35:28 +02:00
}
2012-03-08 03:48:02 +01:00
AstCCast ( FileLine * fl , AstNode * lhsp , AstNode * typeFromp ) : AstNodeUniop ( fl , lhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( typeFromp ) ;
2006-08-26 13:35:28 +02:00
m_size = width ( ) ;
}
2011-03-18 02:09:52 +01:00
ASTNODE_NODE_FUNCS ( CCast , CCAST )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { out . opAssign ( lhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$_CAST(%l) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_CAST_%nq%lq(%nw,%lw, %P, %li) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } // Special cased in V3Cast
virtual V3Hash sameHash ( ) const { return V3Hash ( size ( ) ) ; }
2011-03-18 02:09:52 +01:00
virtual bool same ( AstNode * samep ) const { return size ( ) = = samep - > castCCast ( ) - > size ( ) ; }
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str = cout ) ;
//
int size ( ) const { return m_size ; }
} ;
2010-01-17 21:10:37 +01:00
struct AstCvtPackString : public AstNodeUniop {
// Convert to Verilator Packed Pack (aka Pack)
AstCvtPackString ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetUInt64 ( ) ; } // Really, width should be dtypep -> STRING
2010-01-17 21:10:37 +01:00
ASTNODE_NODE_FUNCS ( CvtPackString , CVTPACKSTRING )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { V3ERROR_NA ; }
virtual string emitVerilog ( ) { return " %f$_CAST(%l) " ; }
virtual string emitC ( ) { return " VL_CVT_PACK_STR_N%lq(%lW, %li) " ; }
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
2008-06-26 14:52:02 +02:00
struct AstFEof : public AstNodeUniop {
AstFEof ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( FEof , FEOF )
2008-06-26 14:52:02 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { V3ERROR_NA ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$feof(%l) " ; }
2011-07-01 19:41:21 +02:00
virtual string emitC ( ) { return " (%li ? feof(VL_CVT_I_FP(%li)) : true) " ; }
2008-06-26 14:52:02 +02:00
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * 16 ; }
2013-09-07 22:43:43 +02:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: $display has 'visual' ordering
2008-06-26 14:52:02 +02:00
AstNode * filep ( ) const { return lhsp ( ) ; }
} ;
2008-06-28 02:04:20 +02:00
struct AstFGetC : public AstNodeUniop {
AstFGetC ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( FGetC , FGETC )
2008-06-28 02:04:20 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) { V3ERROR_NA ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$fgetc(%l) " ; }
2009-12-17 03:28:35 +01:00
// Non-existent filehandle returns EOF
2011-07-01 19:41:21 +02:00
virtual string emitC ( ) { return " (%li ? fgetc(VL_CVT_I_FP(%li)) : -1) " ; }
2008-06-28 02:04:20 +02:00
virtual bool cleanOut ( ) { return false ; } virtual bool cleanLhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * 64 ; }
2013-09-07 22:43:43 +02:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: $display has 'visual' ordering
2008-06-28 02:04:20 +02:00
AstNode * filep ( ) const { return lhsp ( ) ; }
} ;
2011-09-29 03:35:16 +02:00
struct AstCeilD : public AstNodeUniop {
AstCeilD ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-09-29 03:35:16 +02:00
ASTNODE_NODE_FUNCS ( CeilD , CEILD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) {
out . setDouble ( ceil ( lhs . toDouble ( ) ) ) ; }
virtual string emitVerilog ( ) { return " %f$ceil(%l) " ; }
virtual string emitC ( ) { return " ceil(%li) " ; }
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDoubleTrig ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
struct AstExpD : public AstNodeUniop {
AstExpD ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-09-29 03:35:16 +02:00
ASTNODE_NODE_FUNCS ( ExpD , EXPD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) {
out . setDouble ( exp ( lhs . toDouble ( ) ) ) ; }
virtual string emitVerilog ( ) { return " %f$exp(%l) " ; }
virtual string emitC ( ) { return " exp(%li) " ; }
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDoubleTrig ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
struct AstFloorD : public AstNodeUniop {
AstFloorD ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-09-29 03:35:16 +02:00
ASTNODE_NODE_FUNCS ( FloorD , FLOORD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) {
out . setDouble ( floor ( lhs . toDouble ( ) ) ) ; }
virtual string emitVerilog ( ) { return " %f$floor(%l) " ; }
virtual string emitC ( ) { return " floor(%li) " ; }
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDoubleTrig ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
struct AstLogD : public AstNodeUniop {
AstLogD ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-09-29 03:35:16 +02:00
ASTNODE_NODE_FUNCS ( LogD , LOGD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) {
out . setDouble ( log ( lhs . toDouble ( ) ) ) ; }
virtual string emitVerilog ( ) { return " %f$ln(%l) " ; }
virtual string emitC ( ) { return " log(%li) " ; }
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDoubleTrig ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
struct AstLog10D : public AstNodeUniop {
AstLog10D ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-09-29 03:35:16 +02:00
ASTNODE_NODE_FUNCS ( Log10D , LOG10D )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) {
out . setDouble ( log10 ( lhs . toDouble ( ) ) ) ; }
virtual string emitVerilog ( ) { return " %f$log10(%l) " ; }
virtual string emitC ( ) { return " log10(%li) " ; }
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDoubleTrig ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
struct AstSqrtD : public AstNodeUniop {
AstSqrtD ( FileLine * fl , AstNode * lhsp ) : AstNodeUniop ( fl , lhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-09-29 03:35:16 +02:00
ASTNODE_NODE_FUNCS ( SqrtD , SQRTD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs ) {
out . setDouble ( sqrt ( lhs . toDouble ( ) ) ) ; }
virtual string emitVerilog ( ) { return " %f$sqrt(%l) " ; }
virtual string emitC ( ) { return " sqrt(%li) " ; }
virtual bool cleanOut ( ) { return true ; } virtual bool cleanLhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDoubleTrig ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
//======================================================================
// Binary ops
2011-12-22 14:33:16 +01:00
struct AstLogOr : public AstNodeBiop {
AstLogOr ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( LogOr , LOGOR )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opLogOr ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f|| %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_LOGOR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " || " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) + instrCountBranch ( ) ; }
} ;
2011-12-22 14:33:16 +01:00
struct AstLogAnd : public AstNodeBiop {
AstLogAnd ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( LogAnd , LOGAND )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opLogAnd ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f&& %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_LOGAND_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " && " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) + instrCountBranch ( ) ; }
} ;
struct AstLogIf : public AstNodeBiop {
AstLogIf ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( LogIf , LOGIF )
2012-04-20 03:02:08 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opLogIf ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f-> %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_LOGIF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " -> " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) + instrCountBranch ( ) ; }
} ;
struct AstLogIff : public AstNodeBiCom {
AstLogIff ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiCom ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( LogIff , LOGIFF )
2012-04-20 03:02:08 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opLogIff ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f<-> %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_LOGIFF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " <-> " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) + instrCountBranch ( ) ; }
} ;
struct AstOr : public AstNodeBiComAsv {
AstOr ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiComAsv ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Or , OR )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opOr ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f| %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_OR_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " | " ; }
virtual bool cleanOut ( ) { V3ERROR_NA ; return false ; } // Lclean && Rclean
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
struct AstAnd : public AstNodeBiComAsv {
AstAnd ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiComAsv ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( And , AND )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opAnd ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f& %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_AND_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " & " ; }
virtual bool cleanOut ( ) { V3ERROR_NA ; return false ; } // Lclean || Rclean
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
struct AstXor : public AstNodeBiComAsv {
AstXor ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiComAsv ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Xor , XOR )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opXor ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f^ %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_XOR_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " ^ " ; }
virtual bool cleanOut ( ) { return false ; } // Lclean && Rclean
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
struct AstXnor : public AstNodeBiComAsv {
AstXnor ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiComAsv ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Xnor , XNOR )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opXnor ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f^ ~ %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_XNOR_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " ^ ~ " ; }
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return true ; }
} ;
struct AstEq : public AstNodeBiCom {
AstEq ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiCom ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Eq , EQ )
2014-01-21 03:59:53 +01:00
static AstNodeBiop * newTyped ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) ; // Return AstEq/AstEqD
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opEq ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f== %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_EQ_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " == " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstEqD : public AstNodeBiCom {
AstEqD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiCom ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( EqD , EQD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opEqD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f== %r) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " == " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstNeq : public AstNodeBiCom {
AstNeq ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiCom ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Neq , NEQ )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opNeq ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f!= %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_NEQ_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " != " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstNeqD : public AstNodeBiCom {
AstNeqD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiCom ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( NeqD , NEQD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opNeqD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f!= %r) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " != " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstLt : public AstNodeBiop {
AstLt ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Lt , LT )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opLt ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f< %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_LT_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " < " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstLtD : public AstNodeBiop {
AstLtD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( LtD , LTD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opLtD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f< %r) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " < " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstLtS : public AstNodeBiop {
AstLtS ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( LtS , LTS )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opLtS ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f< %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_LTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual bool signedFlavor ( ) const { return true ; }
} ;
struct AstGt : public AstNodeBiop {
AstGt ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Gt , GT )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opGt ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f> %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_GT_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " > " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstGtD : public AstNodeBiop {
AstGtD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( GtD , GTD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opGtD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f> %r) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " > " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstGtS : public AstNodeBiop {
AstGtS ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( GtS , GTS )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opGtS ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f> %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_GTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual bool signedFlavor ( ) const { return true ; }
} ;
struct AstGte : public AstNodeBiop {
AstGte ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Gte , GTE )
2014-01-21 03:59:53 +01:00
static AstNodeBiop * newTyped ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) ; // Return AstGte/AstGteS/AstGteD
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opGte ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f>= %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_GTE_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " >= " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstGteD : public AstNodeBiop {
AstGteD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( GteD , GTED )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opGteD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f>= %r) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " >= " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstGteS : public AstNodeBiop {
AstGteS ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( GteS , GTES )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opGteS ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f>= %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_GTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual bool signedFlavor ( ) const { return true ; }
} ;
struct AstLte : public AstNodeBiop {
AstLte ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Lte , LTE )
2014-01-21 03:59:53 +01:00
static AstNodeBiop * newTyped ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) ; // Return AstLte/AstLteS/AstLteD
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opLte ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f<= %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_LTE_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " <= " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstLteD : public AstNodeBiop {
AstLteD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( LteD , LTED )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opLteD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f<= %r) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " <= " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstLteS : public AstNodeBiop {
AstLteS ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( LteS , LTES )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opLteS ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f<= %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_LTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual bool signedFlavor ( ) const { return true ; }
} ;
struct AstShiftL : public AstNodeBiop {
AstShiftL ( FileLine * fl , AstNode * lhsp , AstNode * rhsp , int setwidth = 0 )
: AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:53:53 +02:00
if ( setwidth ) { dtypeSetLogicSized ( setwidth , setwidth , AstNumeric : : UNSIGNED ) ; }
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ShiftL , SHIFTL )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opShiftL ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f<< %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_SHIFTL_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " << " ; }
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
struct AstShiftR : public AstNodeBiop {
AstShiftR ( FileLine * fl , AstNode * lhsp , AstNode * rhsp , int setwidth = 0 )
: AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:53:53 +02:00
if ( setwidth ) { dtypeSetLogicSized ( setwidth , setwidth , AstNumeric : : UNSIGNED ) ; }
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ShiftR , SHIFTR )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opShiftR ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f>> %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_SHIFTR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " >> " ; }
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; } // LHS size might be > output size, so don't want to force size
} ;
struct AstShiftRS : public AstNodeBiop {
2014-03-10 02:28:28 +01:00
// Shift right with sign extension, >>> operator
// Output data type's width determines which bit is used for sign extension
2006-08-26 13:35:28 +02:00
AstShiftRS ( FileLine * fl , AstNode * lhsp , AstNode * rhsp , int setwidth = 0 )
: AstNodeBiop ( fl , lhsp , rhsp ) {
2012-04-29 16:14:13 +02:00
if ( setwidth ) { dtypeSetLogicSized ( setwidth , setwidth , AstNumeric : : SIGNED ) ; }
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ShiftRS , SHIFTRS )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opShiftRS ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f>>> %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_SHIFTRS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " " ; }
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual bool signedFlavor ( ) const { return true ; }
} ;
struct AstAdd : public AstNodeBiComAsv {
AstAdd ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiComAsv ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Add , ADD )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opAdd ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f+ %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_ADD_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " + " ; }
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return true ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstAddD : public AstNodeBiComAsv {
AstAddD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiComAsv ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( AddD , ADDD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opAddD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f+ %r) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " + " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstSub : public AstNodeBiop {
AstSub ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Sub , SUB )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opSub ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f- %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_SUB_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " - " ; }
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return true ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstSubD : public AstNodeBiop {
AstSubD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( SubD , SUBD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opSubD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f- %r) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " - " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstMul : public AstNodeBiComAsv {
AstMul ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiComAsv ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Mul , MUL )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opMul ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f* %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_MUL_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " * " ; }
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return true ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * instrCountMul ( ) ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstMulD : public AstNodeBiComAsv {
AstMulD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiComAsv ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( MulD , MULD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opMulD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f* %r) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " * " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return true ; }
virtual int instrCount ( ) const { return instrCountDouble ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstMulS : public AstNodeBiComAsv {
AstMulS ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiComAsv ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( MulS , MULS )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opMulS ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f* %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_MULS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " " ; }
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return true ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * instrCountMul ( ) ; }
virtual bool signedFlavor ( ) const { return true ; }
} ;
struct AstDiv : public AstNodeBiop {
AstDiv ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Div , DIV )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opDiv ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f/ %r) " ; }
2009-10-27 01:12:09 +01:00
virtual string emitC ( ) { return " VL_DIV_%nq%lq%rq(%lw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return true ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * instrCountDiv ( ) ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstDivD : public AstNodeBiop {
AstDivD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( DivD , DIVD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opDivD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f/ %r) " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { return " / " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDoubleDiv ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstDivS : public AstNodeBiop {
AstDivS ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( DivS , DIVS )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opDivS ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f/ %r) " ; }
2009-10-27 01:12:09 +01:00
virtual string emitC ( ) { return " VL_DIVS_%nq%lq%rq(%lw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return true ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * instrCountDiv ( ) ; }
virtual bool signedFlavor ( ) const { return true ; }
} ;
struct AstModDiv : public AstNodeBiop {
AstModDiv ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ModDiv , MODDIV )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opModDiv ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f%% %r) " ; }
2009-10-27 01:12:09 +01:00
virtual string emitC ( ) { return " VL_MODDIV_%nq%lq%rq(%lw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return true ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * instrCountDiv ( ) ; }
} ;
struct AstModDivS : public AstNodeBiop {
AstModDivS ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ModDivS , MODDIVS )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opModDivS ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f%% %r) " ; }
2009-10-27 01:12:09 +01:00
virtual string emitC ( ) { return " VL_MODDIVS_%nq%lq%rq(%lw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return true ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * instrCountDiv ( ) ; }
virtual bool signedFlavor ( ) const { return true ; }
} ;
struct AstPow : public AstNodeBiop {
AstPow ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Pow , POW )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opPow ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f** %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_POW_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * instrCountMul ( ) ; }
} ;
2011-07-24 21:01:51 +02:00
struct AstPowD : public AstNodeBiop {
AstPowD ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetDouble ( ) ; }
2011-07-24 21:01:51 +02:00
ASTNODE_NODE_FUNCS ( PowD , POWD )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opPowD ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " %k(%l %f** %r) " ; }
virtual string emitC ( ) { return " pow(%li,%ri) " ; }
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return instrCountDoubleDiv ( ) ; }
virtual bool doubleFlavor ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstPowS : public AstNodeBiop {
AstPowS ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( PowS , POWS )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opPowS ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f** %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_POWS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return true ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * instrCountMul ( ) ; }
virtual bool signedFlavor ( ) const { return true ; }
} ;
struct AstEqCase : public AstNodeBiCom {
AstEqCase ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiCom ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( EqCase , EQCASE )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opCaseEq ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f=== %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_EQ_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " == " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
struct AstNeqCase : public AstNodeBiCom {
AstNeqCase ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiCom ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( NeqCase , NEQCASE )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opCaseNeq ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f!== %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_NEQ_%lq(%lW, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual string emitSimpleOperator ( ) { return " != " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
2007-07-18 17:01:39 +02:00
struct AstEqWild : public AstNodeBiop {
// Note wildcard operator rhs differs from lhs
AstEqWild ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( EqWild , EQWILD )
2007-07-18 17:01:39 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opWildEq ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f==? %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_EQ_%lq(%lW, %P, %li, %ri) " ; }
2007-07-18 17:01:39 +02:00
virtual string emitSimpleOperator ( ) { return " == " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
struct AstNeqWild : public AstNodeBiop {
AstNeqWild ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-03-31 16:19:27 +02:00
dtypeSetLogicBool ( ) ; }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( NeqWild , NEQWILD )
2007-07-18 17:01:39 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opWildNeq ( lhs , rhs ) ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %k(%l %f!=? %r) " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_NEQ_%lq(%lW, %P, %li, %ri) " ; }
2007-07-18 17:01:39 +02:00
virtual string emitSimpleOperator ( ) { return " != " ; }
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstConcat : public AstNodeBiop {
// If you're looking for {#{}}, see AstReplicate
AstConcat ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-04-29 16:14:13 +02:00
if ( lhsp - > dtypep ( ) & & rhsp - > dtypep ( ) ) {
dtypeSetLogicSized ( lhsp - > dtypep ( ) - > width ( ) + rhsp - > dtypep ( ) - > width ( ) ,
lhsp - > dtypep ( ) - > width ( ) + rhsp - > dtypep ( ) - > width ( ) ,
AstNumeric : : UNSIGNED ) ;
}
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Concat , CONCAT )
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f{%l, %k%r} " ; }
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opConcat ( lhs , rhs ) ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_CONCAT_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return true ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * 2 ; }
} ;
struct AstReplicate : public AstNodeBiop {
2012-07-28 14:25:27 +02:00
// Verilog {rhs{lhs}} - Note rhsp() is the replicate value, not the lhsp()
2012-04-29 16:14:13 +02:00
AstReplicate ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
if ( AstConst * constp = rhsp - > castConst ( ) ) {
dtypeSetLogicSized ( lhsp - > width ( ) * constp - > toUInt ( ) , lhsp - > width ( ) * constp - > toUInt ( ) , AstNumeric : : UNSIGNED ) ;
}
}
2006-08-26 13:35:28 +02:00
AstReplicate ( FileLine * fl , AstNode * lhsp , uint32_t repCount )
: AstNodeBiop ( fl , lhsp , new AstConst ( fl , repCount ) ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Replicate , REPLICATE )
2006-08-26 13:35:28 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opRepl ( lhs , rhs ) ; }
2012-07-28 14:25:27 +02:00
virtual string emitVerilog ( ) { return " %f{%r{%k%l}} " ; }
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { return " VL_REPLICATE_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri) " ; }
2006-08-26 13:35:28 +02:00
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * 2 ; }
} ;
2011-02-24 03:21:59 +01:00
struct AstBufIf1 : public AstNodeBiop {
// lhs is enable, rhs is data to drive
2012-04-22 01:30:08 +02:00
// Note unlike the Verilog bufif1() UDP, this allows any width; each lhsp bit enables respective rhsp bit
2011-02-24 03:21:59 +01:00
AstBufIf1 ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) {
2012-04-29 15:42:17 +02:00
dtypeFrom ( lhsp ) ; }
2011-02-24 03:21:59 +01:00
ASTNODE_NODE_FUNCS ( BufIf1 , BUFIF1 )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { out . opBufIf1 ( lhs , rhs ) ; }
virtual string emitVerilog ( ) { return " bufif(%r,%l) " ; }
2011-05-10 05:49:17 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; } // Lclean || Rclean
2011-08-23 03:02:09 +02:00
virtual string emitSimpleOperator ( ) { V3ERROR_NA ; return " " ; } // Lclean || Rclean
2011-05-10 05:49:17 +02:00
virtual bool cleanOut ( ) { V3ERROR_NA ; return " " ; } // Lclean || Rclean
2011-02-24 03:21:59 +01:00
virtual bool cleanLhs ( ) { return false ; } virtual bool cleanRhs ( ) { return false ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
} ;
2008-06-28 02:04:20 +02:00
struct AstFGetS : public AstNodeBiop {
AstFGetS ( FileLine * fl , AstNode * lhsp , AstNode * rhsp ) : AstNodeBiop ( fl , lhsp , rhsp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( FGetS , FGETS )
2008-06-28 02:04:20 +02:00
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { V3ERROR_NA ; }
2009-12-29 04:19:03 +01:00
virtual string emitVerilog ( ) { return " %f$fgets(%l,%r) " ; }
2008-06-30 13:10:23 +02:00
virtual string emitC ( ) { return " VL_FGETS_%nqX%rq(%lw, %P, &(%li), %ri) " ; }
2008-06-28 02:04:20 +02:00
virtual bool cleanOut ( ) { return false ; }
virtual bool cleanLhs ( ) { return true ; } virtual bool cleanRhs ( ) { return true ; }
virtual bool sizeMattersLhs ( ) { return false ; } virtual bool sizeMattersRhs ( ) { return false ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * 64 ; }
AstNode * strgp ( ) const { return lhsp ( ) ; }
AstNode * filep ( ) const { return rhsp ( ) ; }
} ;
2006-08-26 13:35:28 +02:00
2012-08-12 21:15:21 +02:00
struct AstPattern : public AstNodeMath {
// Verilog '{a,b,c,d...}
// Parents: AstNodeAssign, AstPattern, ...
// Children: expression, AstPattern, AstPatReplicate
AstPattern ( FileLine * fl , AstNode * itemsp ) : AstNodeMath ( fl ) {
2013-02-14 02:52:38 +01:00
addNOp2p ( itemsp ) ;
2012-08-12 21:15:21 +02:00
}
ASTNODE_NODE_FUNCS ( Pattern , PATTERN )
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; } // Implemented specially
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { V3ERROR_NA ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { V3ERROR_NA ; return " " ; }
virtual bool cleanOut ( ) { V3ERROR_NA ; return " " ; }
virtual int instrCount ( ) const { return widthInstrs ( ) ; }
2013-02-14 02:52:38 +01:00
AstNodeDType * getChildDTypep ( ) const { return childDTypep ( ) ; }
AstNodeDType * childDTypep ( ) const { return op1p ( ) - > castNodeDType ( ) ; } // op1 = Type assigning to
void childDTypep ( AstNodeDType * nodep ) { setOp1p ( nodep ) ; }
AstNodeDType * subDTypep ( ) const { return dtypep ( ) ? dtypep ( ) : childDTypep ( ) ; }
AstNode * itemsp ( ) const { return op2p ( ) ; } // op2 = AstPatReplicate, AstPatMember, etc
2012-08-12 21:15:21 +02:00
} ;
struct AstPatMember : public AstNodeMath {
// Verilog '{a} or '{a{b}}
// Parents: AstPattern
// Children: expression, AstPattern, replication count
private :
bool m_default ;
public :
AstPatMember ( FileLine * fl , AstNode * lhsp , AstNode * keyp , AstNode * repp ) : AstNodeMath ( fl ) {
setOp1p ( lhsp ) , setNOp2p ( keyp ) , setNOp3p ( repp ) ; m_default = false ; }
ASTNODE_NODE_FUNCS ( PatMember , PATMEMBER )
virtual void numberOperate ( V3Number & out , const V3Number & lhs , const V3Number & rhs ) { V3ERROR_NA ; }
virtual string emitVerilog ( ) { return lhsp ( ) ? " %f{%r{%k%l}} " : " %l " ; }
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
virtual string emitSimpleOperator ( ) { V3ERROR_NA ; return " " ; }
virtual bool cleanOut ( ) { V3ERROR_NA ; return " " ; }
virtual int instrCount ( ) const { return widthInstrs ( ) * 2 ; }
AstNode * lhsp ( ) const { return op1p ( ) ; } // op1 = expression to assign or another AstPattern
AstNode * keyp ( ) const { return op2p ( ) ; } // op2 = assignment key (Const, id Text)
AstNode * repp ( ) const { return op3p ( ) ; } // op3 = replication count, or NULL for count 1
bool isDefault ( ) const { return m_default ; }
void isDefault ( bool flag ) { m_default = flag ; }
} ;
2007-03-06 22:43:38 +01:00
//======================================================================
// SysVerilog assertions
struct AstVAssert : public AstNodeStmt {
// Verilog Assertion
// Parents: {statement list}
// Children: expression, if pass statements, if fail statements
AstVAssert ( FileLine * fl , AstNode * propp , AstNode * passsp , AstNode * failsp )
: AstNodeStmt ( fl ) {
addOp1p ( propp ) ;
addNOp2p ( passsp ) ;
addNOp3p ( failsp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( VAssert , VASSERT )
2007-03-06 22:43:38 +01:00
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
AstNode * propp ( ) const { return op1p ( ) ; } // op1 = property
AstNode * passsp ( ) const { return op2p ( ) ; } // op2 = if passes
AstNode * failsp ( ) const { return op3p ( ) ; } // op3 = if fails
} ;
2008-08-06 18:52:39 +02:00
//======================================================================
// Assertions
struct AstClocking : public AstNode {
// Set default clock region
// Parents: MODULE
// Children: Assertions
2008-11-20 13:55:54 +01:00
AstClocking ( FileLine * fl , AstNodeSenItem * sensesp , AstNode * bodysp )
2008-08-06 18:52:39 +02:00
: AstNode ( fl ) {
addOp1p ( sensesp ) ;
addNOp2p ( bodysp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Clocking , CLOCKING )
2008-11-20 13:55:54 +01:00
AstNodeSenItem * sensesp ( ) const { return op1p ( ) - > castNodeSenItem ( ) ; } // op1 = Sensitivity list
2008-08-06 18:52:39 +02:00
AstNode * bodysp ( ) const { return op2p ( ) ; } // op2 = Body
} ;
2006-08-26 13:35:28 +02:00
//======================================================================
// PSL
struct AstPslDefClock : public AstNode {
// Set default PSL clock
// Parents: MODULE
// Children: SENITEM
2008-11-20 13:55:54 +01:00
AstPslDefClock ( FileLine * fl , AstNodeSenItem * sensesp )
2006-08-26 13:35:28 +02:00
: AstNode ( fl ) {
addNOp1p ( sensesp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( PslDefClock , PSLDEFCLOCK )
2008-11-20 13:55:54 +01:00
AstNodeSenItem * sensesp ( ) const { return op1p ( ) - > castNodeSenItem ( ) ; } // op1 = Sensitivity list
2006-08-26 13:35:28 +02:00
} ;
struct AstPslClocked : public AstNode {
// A clocked property
// Parents: ASSERT|COVER (property)
// Children: SENITEM, Properties
2008-11-20 13:55:54 +01:00
AstPslClocked ( FileLine * fl , AstNodeSenItem * sensesp , AstNode * disablep , AstNode * propp )
2006-08-26 13:35:28 +02:00
: AstNode ( fl ) {
addNOp1p ( sensesp ) ;
2008-08-06 18:52:39 +02:00
addNOp2p ( disablep ) ;
addOp3p ( propp ) ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( PslClocked , PSLCLOCKED )
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; } // Used under PslCover, which expects a bool child
2008-11-20 13:55:54 +01:00
AstNodeSenItem * sensesp ( ) const { return op1p ( ) - > castNodeSenItem ( ) ; } // op1 = Sensitivity list
2008-08-06 18:52:39 +02:00
AstNode * disablep ( ) const { return op2p ( ) ; } // op2 = disable
AstNode * propp ( ) const { return op3p ( ) ; } // op3 = property
2006-08-26 13:35:28 +02:00
} ;
struct AstPslAssert : public AstNodeStmt {
// Psl Assertion
// Parents: {statement list}
// Children: expression, report string
private :
string m_name ; // Name to report
public :
AstPslAssert ( FileLine * fl , AstNode * propp , const string & name = " " )
: AstNodeStmt ( fl )
, m_name ( name ) {
addOp1p ( propp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( PslAssert , PSLASSERT )
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return m_name ; } // * = Var name
virtual V3Hash sameHash ( ) const { return V3Hash ( name ( ) ) ; }
virtual bool same ( AstNode * samep ) const { return samep - > name ( ) = = name ( ) ; }
AstNode * propp ( ) const { return op1p ( ) ; } // op1 = property
AstSenTree * sentreep ( ) const { return op2p ( ) - > castSenTree ( ) ; } // op2 = clock domain
void sentreep ( AstSenTree * sentreep ) { addOp2p ( sentreep ) ; } // op2 = clock domain
} ;
struct AstPslCover : public AstNodeStmt {
// Psl Cover
// Parents: {statement list}
// Children: expression, report string
private :
string m_name ; // Name to report
public :
2008-08-06 18:52:39 +02:00
AstPslCover ( FileLine * fl , AstNode * propp , AstNode * stmtsp , const string & name = " " )
2006-08-26 13:35:28 +02:00
: AstNodeStmt ( fl )
, m_name ( name ) {
addOp1p ( propp ) ;
2008-08-06 18:52:39 +02:00
addNOp4p ( stmtsp ) ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( PslCover , PSLCOVER )
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return m_name ; } // * = Var name
virtual V3Hash sameHash ( ) const { return V3Hash ( name ( ) ) ; }
virtual bool same ( AstNode * samep ) const { return samep - > name ( ) = = name ( ) ; }
2009-07-22 21:21:41 +02:00
virtual void name ( const string & name ) { m_name = name ; }
2006-08-26 13:35:28 +02:00
AstNode * propp ( ) const { return op1p ( ) ; } // op1 = property
AstSenTree * sentreep ( ) const { return op2p ( ) - > castSenTree ( ) ; } // op2 = clock domain
void sentreep ( AstSenTree * sentreep ) { addOp2p ( sentreep ) ; } // op2 = clock domain
AstNode * coverincp ( ) const { return op3p ( ) ; } // op3 = coverage node
void coverincp ( AstCoverInc * nodep ) { addOp3p ( nodep ) ; } // op3 = coverage node
2008-08-06 18:52:39 +02:00
AstNode * stmtsp ( ) const { return op4p ( ) ; } // op4 = statements
2006-08-26 13:35:28 +02:00
} ;
//======================================================================
// PSL Expressions
struct AstPslBool : public AstNode {
// Separates PSL Sere/sequences from the normal expression boolean layer below.
// Note this excludes next() and similar functions; they are time domain, so not under AstPslBool.
// Parents: Sequences, etc.
// Children: math
AstPslBool ( FileLine * fileline , AstNode * exprp )
: AstNode ( fileline ) {
addOp1p ( exprp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( PslBool , PSLBOOL )
2006-08-26 13:35:28 +02:00
AstNode * exprp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1= expression
2012-04-14 17:03:38 +02:00
virtual bool hasDType ( ) const { return true ; }
2006-08-26 13:35:28 +02:00
virtual bool isGateOptimizable ( ) const { return false ; } // Not relevant
virtual bool isPredictOptimizable ( ) const { return false ; } // Not relevant
virtual int instrCount ( ) const { return 0 ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
//======================================================================
// Text based nodes
struct AstText : public AstNodeText {
2009-12-03 01:32:41 +01:00
private :
bool m_tracking ; // When emit, it's ok to parse the string to do indentation
public :
AstText ( FileLine * fl , const string & textp , bool tracking = false )
: AstNodeText ( fl , textp ) , m_tracking ( tracking ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Text , TEXT )
2009-12-03 01:32:41 +01:00
void tracking ( bool flag ) { m_tracking = flag ; }
bool tracking ( ) const { return m_tracking ; }
2006-08-26 13:35:28 +02:00
} ;
struct AstScCtor : public AstNodeText {
AstScCtor ( FileLine * fl , const string & textp )
: AstNodeText ( fl , textp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ScCtor , SCCTOR )
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: User may order w/other sigs
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; }
} ;
2006-08-30 19:27:53 +02:00
struct AstScDtor : public AstNodeText {
AstScDtor ( FileLine * fl , const string & textp )
: AstNodeText ( fl , textp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ScDtor , SCDTOR )
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: User may order w/other sigs
2006-08-30 19:27:53 +02:00
virtual bool isOutputter ( ) const { return true ; }
} ;
2006-08-26 13:35:28 +02:00
struct AstScHdr : public AstNodeText {
AstScHdr ( FileLine * fl , const string & textp )
: AstNodeText ( fl , textp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ScHdr , SCHDR )
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: User may order w/other sigs
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; }
} ;
struct AstScImp : public AstNodeText {
AstScImp ( FileLine * fl , const string & textp )
: AstNodeText ( fl , textp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ScImp , SCIMP )
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: User may order w/other sigs
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; }
} ;
struct AstScImpHdr : public AstNodeText {
AstScImpHdr ( FileLine * fl , const string & textp )
: AstNodeText ( fl , textp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ScImpHdr , SCIMPHDR )
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: User may order w/other sigs
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; }
} ;
struct AstScInt : public AstNodeText {
AstScInt ( FileLine * fl , const string & textp )
: AstNodeText ( fl , textp ) { }
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( ScInt , SCINT )
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; } // SPECIAL: User may order w/other sigs
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; }
} ;
struct AstUCStmt : public AstNodeStmt {
// User $c statement
AstUCStmt ( FileLine * fl , AstNode * exprsp )
: AstNodeStmt ( fl ) {
addNOp1p ( exprsp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( UCStmt , UCSTMT )
2006-08-26 13:35:28 +02:00
AstNode * bodysp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1= expressions to print
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return false ; }
2006-08-26 13:35:28 +02:00
virtual bool isOutputter ( ) const { return true ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
} ;
//======================================================================
// Emit C nodes
struct AstCFile : public AstNode {
// C++ output file
// Parents: NETLIST
// Children: nothing yet
private :
string m_name ; ///< Filename
bool m_slow : 1 ; ///< Compile w/o optimization
bool m_source : 1 ; ///< Source file (vs header file)
bool m_support : 1 ; ///< Support file (non systemc)
public :
AstCFile ( FileLine * fl , const string & name )
: AstNode ( fl ) {
m_name = name ;
m_slow = false ;
m_source = false ;
m_support = false ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CFile , CFILE )
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return m_name ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
virtual void dump ( ostream & str = cout ) ;
bool slow ( ) const { return m_slow ; }
void slow ( bool flag ) { m_slow = flag ; }
bool source ( ) const { return m_source ; }
void source ( bool flag ) { m_source = flag ; }
bool support ( ) const { return m_support ; }
void support ( bool flag ) { m_support = flag ; }
} ;
struct AstCFunc : public AstNode {
// C++ function
// Parents: MODULE/SCOPE
// Children: VAR/statements
private :
AstCFuncType m_funcType ;
AstScope * m_scopep ;
string m_name ;
2009-12-20 14:27:00 +01:00
string m_cname ; // C name, for dpiExports
2006-08-26 13:35:28 +02:00
string m_rtnType ; // void, bool, or other return type
string m_argTypes ;
bool m_dontCombine : 1 ; // V3Combine shouldn't compare this func tree, it's special
bool m_skipDecl : 1 ; // Don't declare it
bool m_declPrivate : 1 ; // Declare it private
bool m_formCallTree : 1 ; // Make a global function to call entire tree of functions
bool m_slow : 1 ; // Slow routine, called once or just at init time
bool m_funcPublic : 1 ; // From user public task/function
2006-08-29 14:01:02 +02:00
bool m_isStatic : 1 ; // Function is declared static (no this)
2006-08-30 23:07:55 +02:00
bool m_symProlog : 1 ; // Setup symbol table for later instructions
2006-09-26 17:05:35 +02:00
bool m_entryPoint : 1 ; // User may call into this top level function
2009-12-03 12:55:29 +01:00
bool m_pure : 1 ; // Pure function
2009-12-20 14:27:00 +01:00
bool m_dpiExport : 1 ; // From dpi export
bool m_dpiExportWrapper : 1 ; // From dpi export; static function with dispatch table
2009-12-03 12:55:29 +01:00
bool m_dpiImport : 1 ; // From dpi import
2006-08-26 13:35:28 +02:00
public :
AstCFunc ( FileLine * fl , const string & name , AstScope * scopep , const string & rtnType = " " )
: AstNode ( fl ) {
2010-02-02 02:15:48 +01:00
m_funcType = AstCFuncType : : FT_NORMAL ;
2006-08-26 13:35:28 +02:00
m_scopep = scopep ;
m_name = name ;
m_rtnType = rtnType ;
m_dontCombine = false ;
m_skipDecl = false ;
m_declPrivate = false ;
m_formCallTree = false ;
m_slow = false ;
m_funcPublic = false ;
2006-08-31 00:00:55 +02:00
m_isStatic = true ; // Note defaults to static, later we see where thisp is needed
2006-08-30 23:07:55 +02:00
m_symProlog = false ;
2006-09-26 17:05:35 +02:00
m_entryPoint = false ;
2009-12-03 12:55:29 +01:00
m_pure = false ;
2009-12-20 14:27:00 +01:00
m_dpiExport = false ;
m_dpiExportWrapper = false ;
2009-12-03 12:55:29 +01:00
m_dpiImport = false ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CFunc , CFUNC )
2006-08-26 13:35:28 +02:00
virtual string name ( ) const { return m_name ; }
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( ( m_scopep & & ! m_scopep - > brokeExists ( ) ) ) ; return NULL ; }
2006-10-05 02:45:39 +02:00
virtual bool maybePointedTo ( ) const { return true ; }
2008-08-06 23:09:33 +02:00
virtual void dump ( ostream & str = cout ) ;
2006-08-26 13:35:28 +02:00
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
2006-08-30 23:07:55 +02:00
virtual bool same ( AstNode * samep ) const { return ( ( funcType ( ) = = samep - > castCFunc ( ) - > funcType ( ) )
& & ( rtnTypeVoid ( ) = = samep - > castCFunc ( ) - > rtnTypeVoid ( ) )
2009-12-03 12:55:29 +01:00
& & ( argTypes ( ) = = samep - > castCFunc ( ) - > argTypes ( ) )
2009-12-20 14:27:00 +01:00
& & ( ! ( dpiImport ( ) | | dpiExport ( ) )
| | name ( ) = = samep - > castCFunc ( ) - > name ( ) ) ) ; }
2006-08-26 13:35:28 +02:00
//
2009-07-22 21:21:41 +02:00
virtual void name ( const string & name ) { m_name = name ; }
2009-12-03 12:55:29 +01:00
virtual int instrCount ( ) const { return dpiImport ( ) ? instrCountDpi ( ) : 0 ; }
2009-12-20 14:27:00 +01:00
void cname ( const string & name ) { m_cname = name ; }
string cname ( ) const { return m_cname ; }
2006-08-26 13:35:28 +02:00
AstScope * scopep ( ) const { return m_scopep ; }
void scopep ( AstScope * nodep ) { m_scopep = nodep ; }
string rtnTypeVoid ( ) const { return ( ( m_rtnType = = " " ) ? " void " : m_rtnType ) ; }
2010-02-02 02:15:48 +01:00
bool dontCombine ( ) const { return m_dontCombine | | funcType ( ) ! = AstCFuncType : : FT_NORMAL ; }
2006-08-26 13:35:28 +02:00
void dontCombine ( bool flag ) { m_dontCombine = flag ; }
bool skipDecl ( ) const { return m_skipDecl ; }
void skipDecl ( bool flag ) { m_skipDecl = flag ; }
bool declPrivate ( ) const { return m_declPrivate ; }
void declPrivate ( bool flag ) { m_declPrivate = flag ; }
bool formCallTree ( ) const { return m_formCallTree ; }
void formCallTree ( bool flag ) { m_formCallTree = flag ; }
bool slow ( ) const { return m_slow ; }
void slow ( bool flag ) { m_slow = flag ; }
bool funcPublic ( ) const { return m_funcPublic ; }
void funcPublic ( bool flag ) { m_funcPublic = flag ; }
void argTypes ( const string & str ) { m_argTypes = str ; }
string argTypes ( ) const { return m_argTypes ; }
void funcType ( AstCFuncType flag ) { m_funcType = flag ; }
AstCFuncType funcType ( ) const { return m_funcType ; }
2006-08-29 14:01:02 +02:00
bool isStatic ( ) const { return m_isStatic ; }
void isStatic ( bool flag ) { m_isStatic = flag ; }
2006-08-30 23:07:55 +02:00
bool symProlog ( ) const { return m_symProlog ; }
void symProlog ( bool flag ) { m_symProlog = flag ; }
2006-09-26 17:05:35 +02:00
bool entryPoint ( ) const { return m_entryPoint ; }
void entryPoint ( bool flag ) { m_entryPoint = flag ; }
2009-12-03 12:55:29 +01:00
bool pure ( ) const { return m_pure ; }
void pure ( bool flag ) { m_pure = flag ; }
2009-12-20 14:27:00 +01:00
bool dpiExport ( ) const { return m_dpiExport ; }
void dpiExport ( bool flag ) { m_dpiExport = flag ; }
bool dpiExportWrapper ( ) const { return m_dpiExportWrapper ; }
void dpiExportWrapper ( bool flag ) { m_dpiExportWrapper = flag ; }
2009-12-03 12:55:29 +01:00
bool dpiImport ( ) const { return m_dpiImport ; }
void dpiImport ( bool flag ) { m_dpiImport = flag ; }
2006-08-26 13:35:28 +02:00
//
2009-12-03 12:55:29 +01:00
// If adding node accessors, see below emptyBody
2006-08-26 13:35:28 +02:00
AstNode * argsp ( ) const { return op1p ( ) - > castNode ( ) ; }
void addArgsp ( AstNode * nodep ) { addOp1p ( nodep ) ; }
AstNode * initsp ( ) const { return op2p ( ) - > castNode ( ) ; }
void addInitsp ( AstNode * nodep ) { addOp2p ( nodep ) ; }
AstNode * stmtsp ( ) const { return op3p ( ) - > castNode ( ) ; }
void addStmtsp ( AstNode * nodep ) { addOp3p ( nodep ) ; }
AstNode * finalsp ( ) const { return op4p ( ) - > castNode ( ) ; }
void addFinalsp ( AstNode * nodep ) { addOp4p ( nodep ) ; }
// Special methods
bool emptyBody ( ) const { return argsp ( ) = = NULL & & initsp ( ) = = NULL & & stmtsp ( ) = = NULL & & finalsp ( ) = = NULL ; }
} ;
struct AstCCall : public AstNodeStmt {
// C++ function call
// Parents: Anything above a statement
// Children: Args to the function
private :
AstCFunc * m_funcp ;
string m_hiername ;
2006-08-30 23:07:55 +02:00
string m_argTypes ;
2006-08-26 13:35:28 +02:00
public :
AstCCall ( FileLine * fl , AstCFunc * funcp , AstNode * argsp = NULL )
: AstNodeStmt ( fl ) {
m_funcp = funcp ;
addNOp1p ( argsp ) ;
}
AstCCall ( AstCCall * oldp , AstCFunc * funcp ) // Replacement form for V3Combine
2009-12-05 16:38:49 +01:00
// Note this removes old attachments from the oldp
2006-08-26 13:35:28 +02:00
: AstNodeStmt ( oldp - > fileline ( ) ) {
m_funcp = funcp ;
m_hiername = oldp - > hiername ( ) ;
2009-12-05 16:38:49 +01:00
m_argTypes = oldp - > argTypes ( ) ;
if ( oldp - > argsp ( ) ) addNOp1p ( oldp - > argsp ( ) - > unlinkFrBackWithNext ( ) ) ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CCall , CCALL )
2006-08-26 13:35:28 +02:00
virtual void dump ( ostream & str = cout ) ;
virtual void cloneRelink ( ) { if ( m_funcp & & m_funcp - > clonep ( ) ) {
m_funcp = m_funcp - > clonep ( ) - > castCFunc ( ) ;
} }
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( m_funcp & & ! m_funcp - > brokeExists ( ) ) ; return NULL ; }
2006-08-26 13:35:28 +02:00
virtual int instrCount ( ) const { return instrCountCall ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( funcp ( ) ) ; }
virtual bool same ( AstNode * samep ) const {
2006-08-30 23:07:55 +02:00
return ( funcp ( ) = = samep - > castCCall ( ) - > funcp ( )
& & argTypes ( ) = = samep - > castCCall ( ) - > argTypes ( ) ) ; }
2006-08-26 13:35:28 +02:00
AstNode * exprsp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1= expressions to print
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2011-12-16 01:13:54 +01:00
virtual bool isPure ( ) const { return funcp ( ) - > pure ( ) ; }
2009-12-03 12:55:29 +01:00
virtual bool isOutputter ( ) const { return ! ( funcp ( ) - > pure ( ) ) ; }
2006-08-26 13:35:28 +02:00
AstCFunc * funcp ( ) const { return m_funcp ; }
string hiername ( ) const { return m_hiername ; }
void hiername ( const string & hn ) { m_hiername = hn ; }
2006-08-30 23:07:55 +02:00
void argTypes ( const string & str ) { m_argTypes = str ; }
string argTypes ( ) const { return m_argTypes ; }
2006-08-26 13:35:28 +02:00
//
AstNode * argsp ( ) const { return op1p ( ) - > castNode ( ) ; }
void addArgsp ( AstNode * nodep ) { addOp1p ( nodep ) ; }
} ;
struct AstCReturn : public AstNodeStmt {
// C++ return from a function
// Parents: CFUNC/statement
// Children: Math
AstCReturn ( FileLine * fl , AstNode * lhsp )
: AstNodeStmt ( fl ) {
setOp1p ( lhsp ) ;
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CReturn , CRETURN )
2006-08-26 13:35:28 +02:00
virtual int instrCount ( ) const { return widthInstrs ( ) ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * ) const { return true ; }
//
AstNode * lhsp ( ) const { return op1p ( ) ; }
} ;
struct AstCMath : public AstNodeMath {
2009-12-03 01:32:41 +01:00
private :
bool m_cleanOut ;
public :
2006-08-26 13:35:28 +02:00
// Emit C textual math function (like AstUCFunc)
AstCMath ( FileLine * fl , AstNode * exprsp )
2009-12-03 01:32:41 +01:00
: AstNodeMath ( fl ) , m_cleanOut ( true ) {
2006-08-26 13:35:28 +02:00
addOp1p ( exprsp ) ;
2012-04-29 15:42:17 +02:00
dtypeFrom ( exprsp ) ;
2006-08-26 13:35:28 +02:00
}
2009-12-03 01:32:41 +01:00
AstCMath ( FileLine * fl , const string & textStmt , int setwidth , bool cleanOut = true )
: AstNodeMath ( fl ) , m_cleanOut ( cleanOut ) {
addNOp1p ( new AstText ( fl , textStmt , true ) ) ;
2012-03-31 16:53:53 +02:00
if ( setwidth ) { dtypeSetLogicSized ( setwidth , setwidth , AstNumeric : : UNSIGNED ) ; }
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CMath , CMATH )
2006-08-26 13:35:28 +02:00
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
2009-12-03 01:32:41 +01:00
virtual bool cleanOut ( ) { return m_cleanOut ; }
2006-08-26 13:35:28 +02:00
virtual string emitVerilog ( ) { V3ERROR_NA ; return " " ; } // Implemented specially
2008-06-30 02:02:24 +02:00
virtual string emitC ( ) { V3ERROR_NA ; return " " ; }
2006-08-26 13:35:28 +02:00
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
2009-12-17 03:28:35 +01:00
void addBodysp ( AstNode * nodep ) { addNOp1p ( nodep ) ; }
AstNode * bodysp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1= expressions to print
2006-08-26 13:35:28 +02:00
} ;
struct AstCStmt : public AstNodeStmt {
// Emit C statement
AstCStmt ( FileLine * fl , AstNode * exprsp )
: AstNodeStmt ( fl ) {
addNOp1p ( exprsp ) ;
}
AstCStmt ( FileLine * fl , const string & textStmt )
: AstNodeStmt ( fl ) {
2009-12-03 01:32:41 +01:00
addNOp1p ( new AstText ( fl , textStmt , true ) ) ;
2006-08-26 13:35:28 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( CStmt , CSTMT )
2006-08-26 13:35:28 +02:00
virtual bool isGateOptimizable ( ) const { return false ; }
virtual bool isPredictOptimizable ( ) const { return false ; }
virtual V3Hash sameHash ( ) const { return V3Hash ( ) ; }
virtual bool same ( AstNode * samep ) const { return true ; }
2009-12-17 03:28:35 +01:00
void addBodysp ( AstNode * nodep ) { addNOp1p ( nodep ) ; }
AstNode * bodysp ( ) const { return op1p ( ) - > castNode ( ) ; } // op1= expressions to print
2006-08-26 13:35:28 +02:00
} ;
2012-04-29 16:14:13 +02:00
//######################################################################
// Right below top
struct AstTypeTable : public AstNode {
// Container for hash of standard data types
// Children: NODEDTYPEs
typedef map < pair < int , int > , AstBasicDType * > LogicMap ;
AstBasicDType * m_basicps [ AstBasicDTypeKwd : : _ENUM_MAX ] ;
//
enum { IDX0_LOGIC , IDX0_BIT , _IDX0_MAX } ;
LogicMap m_logicMap [ _IDX0_MAX ] [ AstNumeric : : _ENUM_MAX ] ; // uses above IDX enums
//
typedef map < VBasicTypeKey , AstBasicDType * > DetailedMap ;
DetailedMap m_detailedMap ;
public :
AstTypeTable ( FileLine * fl ) : AstNode ( fl ) {
for ( int i = 0 ; i < AstBasicDTypeKwd : : _ENUM_MAX ; + + i ) m_basicps [ i ] = NULL ;
}
ASTNODE_NODE_FUNCS ( TypeTable , TYPETABLE )
AstNodeDType * typesp ( ) const { return op1p ( ) - > castNodeDType ( ) ; } // op1 = List of dtypes
void addTypesp ( AstNodeDType * nodep ) { addOp1p ( nodep ) ; }
AstBasicDType * findBasicDType ( FileLine * fl , AstBasicDTypeKwd kwd ) ;
AstBasicDType * findLogicBitDType ( FileLine * fl , AstBasicDTypeKwd kwd ,
int width , int widthMin , AstNumeric numeric ) ;
2013-01-17 02:58:48 +01:00
AstBasicDType * findLogicBitDType ( FileLine * fl , AstBasicDTypeKwd kwd ,
VNumRange range , int widthMin , AstNumeric numeric ) ;
2012-04-29 16:14:13 +02:00
AstBasicDType * findInsertSameDType ( AstBasicDType * nodep ) ;
void clearCache ( ) ;
void repairCache ( ) ;
virtual void dump ( ostream & str = cout ) ;
} ;
2006-08-26 13:35:28 +02:00
//######################################################################
// Top
struct AstNetlist : public AstNode {
// All modules are under this single top node.
// Parents: none
// Children: MODULEs & CFILEs
2012-04-29 16:14:13 +02:00
private :
AstTypeTable * m_typeTablep ; // Reference to top type table, for faster lookup
2013-01-18 00:36:20 +01:00
AstPackage * m_dollarUnitPkgp ;
2012-04-29 16:14:13 +02:00
public :
AstNetlist ( ) : AstNode ( new FileLine ( " AstRoot " , 0 ) ) {
m_typeTablep = NULL ;
2013-01-18 00:36:20 +01:00
m_dollarUnitPkgp = NULL ;
2012-04-29 16:14:13 +02:00
}
2008-11-20 02:15:05 +01:00
ASTNODE_NODE_FUNCS ( Netlist , NETLIST )
2013-05-25 23:05:22 +02:00
virtual const char * broken ( ) const { BROKEN_RTN ( m_dollarUnitPkgp & & ! m_dollarUnitPkgp - > brokeExists ( ) ) ; return NULL ; }
2009-11-07 12:20:20 +01:00
AstNodeModule * modulesp ( ) const { return op1p ( ) - > castNodeModule ( ) ; } // op1 = List of modules
AstNodeModule * topModulep ( ) const { return op1p ( ) - > castNodeModule ( ) ; } // * = Top module in hierarchy (first one added, for now)
void addModulep ( AstNodeModule * modulep ) { addOp1p ( modulep ) ; }
2006-08-26 13:35:28 +02:00
AstCFile * filesp ( ) const { return op2p ( ) - > castCFile ( ) ; } // op2 = List of files
void addFilesp ( AstCFile * filep ) { addOp2p ( filep ) ; }
2012-04-29 16:14:13 +02:00
AstNode * miscsp ( ) const { return op3p ( ) ; } // op3 = List of dtypes etc
void addMiscsp ( AstNode * nodep ) { addOp3p ( nodep ) ; }
AstTypeTable * typeTablep ( ) { return m_typeTablep ; }
void addTypeTablep ( AstTypeTable * nodep ) { m_typeTablep = nodep ; addMiscsp ( nodep ) ; }
2013-01-18 00:36:20 +01:00
AstPackage * dollarUnitPkgp ( ) const { return m_dollarUnitPkgp ; }
AstPackage * dollarUnitPkgAddp ( ) {
if ( ! m_dollarUnitPkgp ) {
m_dollarUnitPkgp = new AstPackage ( fileline ( ) , AstPackage : : dollarUnitName ( ) ) ;
m_dollarUnitPkgp - > inLibrary ( true ) ; // packages are always libraries; don't want to make them a "top"
m_dollarUnitPkgp - > modTrace ( false ) ; // may reconsider later
m_dollarUnitPkgp - > internal ( true ) ;
addModulep ( m_dollarUnitPkgp ) ;
}
return m_dollarUnitPkgp ; }
2006-08-26 13:35:28 +02:00
} ;
//######################################################################
# endif // Guard