expr.h File Reference

Contains functions for handling expressions. More...

#include <stdio.h>
#include "defines.h"

Go to the source code of this file.

Functions

void expression_create_nba (expression *expr, vsignal *lhs_sig, vector *rhs_vec)
 Creates, initializes and adds a non-blocking assignment structure to the given expression's element pointer.
expressionexpression_is_nba_lhs (expression *exp)
 Returns a pointer to the non-blocking assignment expression if the given expression is an assignable expression on the LHS of a non-blocking assignment.
expressionexpression_create (expression *right, expression *left, exp_op_type op, bool lhs, int id, int line, unsigned int first, unsigned int last, bool data)
 Creates new expression.
void expression_set_value (expression *exp, vsignal *sig, func_unit *funit)
 Sets the specified expression value to the specified vector value.
void expression_set_signed (expression *exp)
 Sets the signed bit for all appropriate parent expressions.
void expression_resize (expression *expr, func_unit *funit, bool recursive, bool alloc)
 Recursively resizes specified expression tree leaf node.
int expression_get_id (expression *expr, bool parse_mode)
 Returns expression ID of this expression.
expressionexpression_get_first_line_expr (expression *expr)
 Returns first line in this expression tree.
expressionexpression_get_last_line_expr (expression *expr)
 Returns last line in this expression tree.
unsigned int expression_get_curr_dimension (expression *expr)
 Returns the current dimension of the given expression.
void expression_find_rhs_sigs (expression *expr, str_link **head, str_link **tail)
 Finds all RHS signals in given expression tree.
expressionexpression_find_uline_id (expression *expr, int ulid)
 Finds the expression in this expression tree with the specified underline id.
bool expression_find_expr (expression *root, expression *expr)
 Returns TRUE if the specified expression exists within the given root expression tree.
bool expression_contains_expr_calling_stmt (expression *expr, statement *stmt)
 Searches for an expression that calls the given statement.
statementexpression_get_root_statement (expression *exp)
 Finds the root statement for the given expression.
void expression_assign_expr_ids (expression *root, func_unit *funit)
 Assigns each expression in the given tree a unique identifier.
void expression_db_write (expression *expr, FILE *file, bool parse_mode, bool ids_issued)
 Writes this expression to the specified database file.
void expression_db_write_tree (expression *root, FILE *file)
 Writes the entire expression tree to the specified data file.
void expression_db_read (char **line, func_unit *curr_mod, bool eval)
 Reads current line of specified file and parses for expression information.
void expression_db_merge (expression *base, char **line, bool same)
 Reads and merges two expressions and stores result in base expression.
void expression_merge (expression *base, expression *other)
 Merges two expressions into the base expression.
const char * expression_string_op (int op)
 Returns user-readable name of specified expression operation.
char * expression_string (expression *exp)
 Returns user-readable version of the supplied expression.
void expression_display (expression *expr)
 Displays the specified expression information.
bool expression_operate (expression *expr, thread *thr, const sim_time *time)
 Performs operation specified by parameter expression.
void expression_operate_recursively (expression *expr, func_unit *funit, bool sizing)
 Performs recursive expression operation (parse mode only).
bool expression_is_static_only (expression *expr)
 Returns TRUE if specified expression is found to contain all static leaf expressions.
bool expression_is_bit_select (expression *expr)
 Returns TRUE if specified expression is a part of an bit select expression tree.
bool expression_is_in_rassign (expression *expr)
 Returns TRUE if specified expression is in an RASSIGN expression tree.
bool expression_is_last_select (expression *expr)
 Returns TRUE if specified expression is the last select of a signal.
void expression_set_assigned (expression *expr)
 Sets the expression signal supplemental field assigned bit if the given expression is an RHS of an assignment.
void expression_set_changed (expression *expr)
 Sets the left/right changed expression bits for each expression in the tree.
void expression_dealloc (expression *expr, bool exp_only)
 Deallocates memory used for expression.

Detailed Description

Contains functions for handling expressions.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
12/1/2001

Function Documentation

void expression_assign_expr_ids ( expression root,
func_unit funit 
)

Assigns each expression in the given tree a unique identifier.

Exceptions:
anonymous expression_resize expression_assign_expr_ids expression_assign_expr_ids

Recursively iterates down the specified expression tree assigning unique IDs to each expression.

Parameters:
root Pointer to root of the expression tree to assign unique IDs for
funit Pointer to functional unit containing this expression tree

References curr_expr_id, expression_assign_expr_ids(), expression_resize(), FALSE, expression_s::left, PROFILE, PROFILE_END, expression_s::right, and expression_s::ulid.

Referenced by expression_assign_expr_ids(), and statement_assign_expr_ids().

01495   { PROFILE(EXPRESSION_ASSIGN_EXPR_IDS);
01496 
01497   if( root != NULL ) {
01498 
01499     /* Traverse children first */
01500     expression_assign_expr_ids( root->left, funit );
01501     expression_assign_expr_ids( root->right, funit );
01502 
01503     /* Assign our expression a unique ID value */
01504     root->ulid = curr_expr_id;
01505     curr_expr_id++;
01506 
01507     /* Resize ourselves */
01508     expression_resize( root, funit, FALSE, FALSE );
01509 
01510   }
01511 
01512   PROFILE_END;
01513 
01514 }

bool expression_contains_expr_calling_stmt ( expression expr,
statement stmt 
)

Searches for an expression that calls the given statement.

Returns:
Returns TRUE if the given expression tree contains an expression that calls the given statement.
Parameters:
expr Pointer to root of expression tree to search
stmt Pointer to statement to search for

References expression_s::elem, ESUPPL_TYPE, ETYPE_FUNIT, expression_contains_expr_calling_stmt(), func_unit_s::first_stmt, expression_s::funit, expression_s::left, PROFILE, PROFILE_END, expression_s::right, and expression_s::suppl.

Referenced by expression_contains_expr_calling_stmt(), and statement_contains_expr_calling_stmt().

01446   { PROFILE(EXPRESSION_CONTAINS_EXPR_CALLING_STMT);
01447 
01448   bool retval = (expr != NULL) &&
01449                 (((ESUPPL_TYPE( expr->suppl ) == ETYPE_FUNIT) && (expr->elem.funit->first_stmt == stmt)) ||
01450                  expression_contains_expr_calling_stmt( expr->left, stmt ) ||
01451                  expression_contains_expr_calling_stmt( expr->right, stmt ));
01452 
01453   PROFILE_END;
01454 
01455   return( retval );
01456 
01457 }

expression* expression_create ( expression right,
expression left,
exp_op_type  op,
bool  lhs,
int  id,
int  line,
unsigned int  first,
unsigned int  last,
bool  data 
)

Creates new expression.

Returns:
Returns pointer to newly created expression.
Exceptions:
anonymous Throw expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value

Creates a new expression from heap memory and initializes its values for usage. Right and left expressions need to be created before this function is called.

Parameters:
right Pointer to expression on right
left Pointer to expression on left
op Operation to perform for this expression
lhs Specifies this expression is a left-hand-side assignment expression
id ID for this expression as determined by the parent
line Line number this expression is on
first First column index of expression
last Last column index of expression
data Specifies if we should create a uint8 array for the vector value

References vsuppl_u::all, esuppl_u::all, Catch_anonymous, expression_s::col, exp_dim_s::curr_lsb, expression_s::dim, expression_s::elem, expression_s::exec_num, EXP_OP_AEDGE, EXP_OP_CASE, EXP_OP_CASEX, EXP_OP_CASEZ, EXP_OP_CEQ, EXP_OP_CNE, EXP_OP_CONCAT, EXP_OP_DEFAULT, EXP_OP_EOR, EXP_OP_EQ, EXP_OP_EXPAND, EXP_OP_GE, EXP_OP_GT, EXP_OP_LAND, EXP_OP_LE, EXP_OP_LIST, EXP_OP_LOR, EXP_OP_LT, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_MULTIPLY, EXP_OP_NE, EXP_OP_NEDGE, EXP_OP_PARAM_MBIT, EXP_OP_PARAM_MBIT_NEG, EXP_OP_PARAM_MBIT_POS, EXP_OP_PEDGE, EXP_OP_REPEAT, EXP_OP_RPT_DLY, EXP_OP_SB2R, EXP_OP_SB2SR, EXP_OP_SCLOG2, EXP_OP_SFINISH, EXP_OP_SI2R, EXP_OP_SR2B, EXP_OP_SR2I, EXP_OP_SRANDOM, EXP_OP_SREALTIME, EXP_OP_SSR2B, EXP_OP_SSRANDOM, EXP_OP_SSTOP, EXP_OP_STESTARGS, EXP_OP_STIME, EXP_OP_SURAND_RANGE, EXP_OP_SURANDOM, EXP_OP_SVALARGS, EXP_OP_UAND, EXP_OP_UNAND, EXP_OP_UNOR, EXP_OP_UNOT, EXP_OP_UNXOR, EXP_OP_UOR, EXP_OP_UXOR, EXP_OP_WAIT, expr_stmt_u::expr, EXPR_OP_HAS_DIM, expression_create_value(), expression_dealloc(), FALSE, expression_s::funit, esuppl_u::gen_expr, generate_expr_mode, expression_s::id, expression_s::left, esuppl_u::lhs, expression_s::line, malloc_safe, expression_s::name, expression_s::op, esuppl_u::owns_vec, expression_s::parent, expression_s::part, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, esuppl_u::root, expression_s::sig, vector_s::suppl, expression_s::suppl, expression_s::table, Throw, TRUE, Try, vector_s::ul, expression_s::ulid, vector_s::value, expression_s::value, vector_is_unknown(), vector_to_int(), and vector_s::width.

Referenced by db_create_expression(), expression_db_read(), fsm_arg_parse_state(), fsm_arg_parse_value(), fsm_db_read(), static_expr_gen(), and static_expr_gen_unary().

00638   { PROFILE(EXPRESSION_CREATE);
00639 
00640   expression* new_expr;    /* Pointer to newly created expression */
00641   int         rwidth = 0;  /* Bit width of expression on right */
00642   int         lwidth = 0;  /* Bit width of expression on left */
00643 
00644   new_expr = (expression*)malloc_safe( sizeof( expression ) );
00645 
00646   new_expr->suppl.all           = 0;
00647   new_expr->suppl.part.lhs      = (uint8)lhs & 0x1;
00648   new_expr->suppl.part.gen_expr = (generate_expr_mode > 0) ? 1 : 0;
00649   new_expr->suppl.part.root     = 1;
00650   new_expr->op                  = op;
00651   new_expr->id                  = id;
00652   new_expr->ulid                = -1;
00653   new_expr->line                = line;
00654   new_expr->col.part.first      = first;
00655   new_expr->col.part.last       = last;
00656   new_expr->exec_num            = 0;
00657   new_expr->sig                 = NULL;
00658   new_expr->parent              = (expr_stmt*)malloc_safe( sizeof( expr_stmt ) );
00659   new_expr->parent->expr        = NULL;
00660   new_expr->right               = right;
00661   new_expr->left                = left;
00662   new_expr->value               = (vector*)malloc_safe( sizeof( vector ) );
00663   new_expr->suppl.part.owns_vec = 1;
00664   new_expr->value->value.ul     = NULL;
00665   new_expr->value->suppl.all    = 0;
00666   new_expr->table               = NULL;
00667   new_expr->elem.funit          = NULL;
00668   new_expr->name                = NULL;
00669 
00670   if( EXPR_OP_HAS_DIM( op ) ) {
00671     new_expr->elem.dim           = (exp_dim*)malloc_safe( sizeof( exp_dim ) );
00672     new_expr->elem.dim->curr_lsb = -1;
00673   }
00674 
00675   if( right != NULL ) {
00676 
00677     /* Get information from right */
00678     assert( right->value != NULL );
00679     rwidth = right->value->width;
00680 
00681     /* Set right expression parent to this expression */
00682     assert( right->parent->expr == NULL );
00683     right->parent->expr = new_expr;
00684 
00685     /* Reset root bit of right expression */
00686     right->suppl.part.root = 0;
00687 
00688   }
00689 
00690   if( left != NULL ) {
00691 
00692     /* Get information from left */
00693     assert( left->value != NULL );
00694     lwidth = left->value->width;
00695 
00696     /* Set left expression parent to this expression (if this is not a case expression) */
00697     if( (op != EXP_OP_CASE) && (op != EXP_OP_CASEX) && (op != EXP_OP_CASEZ) ) {
00698       assert( left->parent->expr == NULL );
00699       left->parent->expr    = new_expr;
00700       left->suppl.part.root = 0;
00701     }
00702 
00703   }
00704 
00705   Try {
00706 
00707     /* Create value vector */
00708     if( ((op == EXP_OP_MULTIPLY) || (op == EXP_OP_LIST)) && (rwidth > 0) && (lwidth > 0) ) {
00709 
00710       /* For multiplication, we need a width the sum of the left and right expressions */
00711       expression_create_value( new_expr, (lwidth + rwidth), data );
00712 
00713     } else if( (op == EXP_OP_CONCAT) && (rwidth > 0) ) {
00714 
00715       expression_create_value( new_expr, rwidth, data );
00716 
00717     } else if( (op == EXP_OP_EXPAND) && (rwidth > 0) && (lwidth > 0) && (left->value->value.ul != NULL) ) {
00718 
00719       /*
00720        If the left-hand expression is a known value, go ahead and create the value here; otherwise,
00721        hold off because our vector value will be coming.
00722       */
00723       if( !vector_is_unknown( left->value ) ) {
00724         expression_create_value( new_expr, (vector_to_int( left->value ) * rwidth), data );
00725       } else {
00726         expression_create_value( new_expr, 1, data );
00727       }
00728 
00729     /* $time, $realtime, $realtobits, $bitstoreal, $itor and $rtoi expressions are always 64-bits wide */
00730     } else if( (op == EXP_OP_STIME) || (op == EXP_OP_SREALTIME) || (op == EXP_OP_SR2B) || (op == EXP_OP_SB2R) || (op == EXP_OP_SI2R) || (op == EXP_OP_SR2I) ) {
00731 
00732       expression_create_value( new_expr, 64, data );
00733 
00734     /* $random, $urandom, $urandom_range, $shortrealtobits and $bitstoshortreal expressions are always 32-bits wide */
00735     } else if( (op == EXP_OP_SRANDOM) || (op == EXP_OP_SURANDOM) || (op == EXP_OP_SURAND_RANGE) || (op == EXP_OP_SSR2B) || (op == EXP_OP_SB2SR) || (op == EXP_OP_SCLOG2) ) {
00736 
00737       expression_create_value( new_expr, 32, data );
00738 
00739     } else if( (op == EXP_OP_LT)        ||
00740                (op == EXP_OP_GT)        ||
00741                (op == EXP_OP_EQ)        ||
00742                (op == EXP_OP_CEQ)       ||
00743                (op == EXP_OP_LE)        ||
00744                (op == EXP_OP_GE)        ||
00745                (op == EXP_OP_NE)        ||
00746                (op == EXP_OP_CNE)       ||
00747                (op == EXP_OP_LOR)       ||
00748                (op == EXP_OP_LAND)      ||
00749                (op == EXP_OP_UAND)      ||
00750                (op == EXP_OP_UNOT)      ||
00751                (op == EXP_OP_UOR)       ||
00752                (op == EXP_OP_UXOR)      ||
00753                (op == EXP_OP_UNAND)     ||
00754                (op == EXP_OP_UNOR)      ||
00755                (op == EXP_OP_UNXOR)     ||
00756                (op == EXP_OP_EOR)       ||
00757                (op == EXP_OP_NEDGE)     ||
00758                (op == EXP_OP_PEDGE)     ||
00759                (op == EXP_OP_AEDGE)     ||
00760                (op == EXP_OP_CASE)      ||
00761                (op == EXP_OP_CASEX)     ||
00762                (op == EXP_OP_CASEZ)     ||
00763                (op == EXP_OP_DEFAULT)   ||
00764                (op == EXP_OP_REPEAT)    ||
00765                (op == EXP_OP_RPT_DLY)   ||
00766                (op == EXP_OP_WAIT)      ||
00767                (op == EXP_OP_SFINISH)   ||
00768                (op == EXP_OP_SSTOP)     ||
00769                (op == EXP_OP_SSRANDOM)  ||
00770                (op == EXP_OP_STESTARGS) ||
00771                (op == EXP_OP_SVALARGS) ) {
00772   
00773       /* If this expression will evaluate to a single bit, create vector now */
00774       expression_create_value( new_expr, 1, data );
00775 
00776     } else {
00777 
00778       /* If both right and left values have their width values set. */
00779       if( (rwidth > 0) && (lwidth > 0) && 
00780           (op != EXP_OP_MBIT_SEL)       &&
00781           (op != EXP_OP_MBIT_POS)       &&
00782           (op != EXP_OP_MBIT_NEG)       &&
00783           (op != EXP_OP_PARAM_MBIT)     &&
00784           (op != EXP_OP_PARAM_MBIT_POS) &&
00785           (op != EXP_OP_PARAM_MBIT_NEG) ) {
00786 
00787         if( rwidth >= lwidth ) {
00788           /* Check to make sure that nothing has gone drastically wrong */
00789           expression_create_value( new_expr, rwidth, data );
00790         } else {
00791           /* Check to make sure that nothing has gone drastically wrong */
00792           expression_create_value( new_expr, lwidth, data );
00793         }
00794 
00795       } else {
00796  
00797         expression_create_value( new_expr, 0, FALSE );
00798  
00799       }
00800 
00801     }
00802 
00803   } Catch_anonymous {
00804     expression_dealloc( new_expr, TRUE );
00805     Throw 0;
00806   }
00807 
00808 /*
00809   if( (data == FALSE) && (generate_expr_mode == 0) ) {
00810     assert( new_expr->value->value.ul == NULL );
00811   }
00812 */
00813 
00814   PROFILE_END;
00815 
00816   return( new_expr );
00817 
00818 }

void expression_create_nba ( expression expr,
vsignal lhs_sig,
vector rhs_vec 
)

Creates, initializes and adds a non-blocking assignment structure to the given expression's element pointer.

Allocates a non-blocking assignment structure to the given expression and initializes it.

Parameters:
expr Pointer to expression to add non-blocking assignment structure to
lhs_sig Pointer to left-hand-side signal
rhs_vec Pointer to right-hand-side vector

References nonblock_assign_s::added, dim_and_nba_s::dim, expression_s::dim, expression_s::dim_nba, expression_s::elem, EXP_OP_SIG, FALSE, vsuppl_u::is_signed, nonblock_assign_s::is_signed, nonblock_assign_s::lhs_sig, malloc_safe, esuppl_u::nba, dim_and_nba_s::nba, nba_queue_size, expression_s::op, esuppl_u::part, vsuppl_u::part, PROFILE, PROFILE_END, nonblock_assign_s::rhs_vec, expression_s::suppl, vector_s::suppl, and nonblock_assign_s::suppl.

Referenced by bind_signal().

00496   { PROFILE(EXPRESSION_CREATE_NBA);
00497 
00498   exp_dim* dim = expr->elem.dim;
00499 
00500   /* Allocate memory */
00501   nonblock_assign* nba = (nonblock_assign*)malloc_safe( sizeof( nonblock_assign ) );
00502 
00503   /* Initialize the structure */
00504   nba->lhs_sig         = lhs_sig;
00505   nba->rhs_vec         = rhs_vec;
00506   nba->suppl.is_signed = (expr->op == EXP_OP_SIG) ? rhs_vec->suppl.part.is_signed : FALSE;
00507   nba->suppl.added     = 0;
00508 
00509   /* Now change the elem pointer from a dim to a dim_nba */
00510   expr->elem.dim_nba      = (dim_and_nba*)malloc_safe( sizeof( dim_and_nba ) );
00511   expr->elem.dim_nba->dim = dim;
00512   expr->elem.dim_nba->nba = nba;
00513 
00514   /* Set the nba supplemental bit */
00515   expr->suppl.part.nba = 1;
00516 
00517   /* Increment the number of nba structures */
00518   nba_queue_size++;
00519 
00520   PROFILE_END;
00521 
00522 }

void expression_db_merge ( expression base,
char **  line,
bool  same 
)

Reads and merges two expressions and stores result in base expression.

Exceptions:
anonymous Throw vector_db_merge

Parses specified line for expression information and merges contents into the base expression. If the two expressions given are not the same (IDs, op, and/or line position differ) we know that the database files being merged were not created from the same design; therefore, display an error message to the user in this case. If both expressions are the same, perform the merge.

Parameters:
base Expression to merge data into
line Pointer to CDD line to parse
same Specifies if expression to be merged needs to be exactly the same as the existing expression

References expression_s::all, esuppl_u::all, expression_s::col, ESUPPL_MERGE_MASK, ESUPPL_OWNS_VEC, expression_s::exec_num, FATAL, expression_s::line, expression_s::op, print_output(), PROFILE, PROFILE_END, expression_s::suppl, Throw, expression_s::value, and vector_db_merge().

Referenced by funit_db_inst_merge(), and funit_db_mod_merge().

01754   { PROFILE(EXPRESSION_DB_MERGE);
01755 
01756   int          id;             /* Expression ID field */
01757   int          linenum;        /* Expression line number */
01758   unsigned int column;         /* Column information */
01759   uint32       exec_num;       /* Execution number */
01760   uint32       op;             /* Expression operation */
01761   esuppl       suppl;          /* Supplemental field */
01762   int          right_id;       /* ID of right child */
01763   int          left_id;        /* ID of left child */
01764   int          chars_read;     /* Number of characters read */
01765 
01766   assert( base != NULL );
01767 
01768   if( sscanf( *line, "%d %x %d %x %x %x %d %d%n", &id, &op, &linenum, &column, &exec_num, &(suppl.all), &right_id, &left_id, &chars_read ) == 8 ) {
01769 
01770     *line = *line + chars_read;
01771 
01772     if( (base->op != op) || (base->line != linenum) || (base->col.all != column) ) {
01773 
01774       print_output( "Attempting to merge databases derived from different designs.  Unable to merge",
01775                     FATAL, __FILE__, __LINE__ );
01776       Throw 0;
01777 
01778     } else {
01779 
01780       /* Merge expression supplemental fields */
01781       base->suppl.all = (base->suppl.all & ESUPPL_MERGE_MASK) | (suppl.all & ESUPPL_MERGE_MASK);
01782 
01783       /* Merge execution number information */
01784       if( base->exec_num < exec_num ) {
01785         base->exec_num = exec_num;
01786       }
01787 
01788       if( ESUPPL_OWNS_VEC( suppl ) ) {
01789 
01790         /* Merge expression vectors */
01791         vector_db_merge( base->value, line, same );
01792 
01793       }
01794 
01795     }
01796 
01797   } else {
01798 
01799     print_output( "Unable to parse expression line in database.  Unable to merge.", FATAL, __FILE__, __LINE__ );
01800     Throw 0;
01801 
01802   }
01803 
01804   PROFILE_END;
01805 
01806 }

void expression_db_read ( char **  line,
func_unit curr_funit,
bool  eval 
)

Reads current line of specified file and parses for expression information.

Exceptions:
anonymous expression_create Throw Throw Throw Throw Throw vector_db_read

Reads in the specified expression information, creates new expression from heap, populates the expression with specified information from file and returns that value in the specified expression pointer. If all is successful, returns TRUE; otherwise, returns FALSE.

Parameters:
line String containing database line to read information from
curr_funit Pointer to current functional unit that instantiates this expression
eval If TRUE, evaluate expression if children are static

References esuppl_u::all, bind_add(), Catch_anonymous, curr_expr_id, expression_s::elem, ESUPPL_IS_LHS, ESUPPL_OWNS_VEC, ETYPE_DELAY, expression_s::exec_num, exp_link_s::exp, func_unit_s::exp_head, exp_link_add(), exp_link_find(), EXP_OP_ASSIGN, EXP_OP_BASSIGN, EXP_OP_DASSIGN, EXP_OP_DELAY, EXP_OP_DIM, EXP_OP_DISABLE, EXP_OP_DLY_ASSIGN, EXP_OP_FORK, EXP_OP_FUNC_CALL, EXP_OP_IF, EXP_OP_NASSIGN, EXP_OP_NB_CALL, EXP_OP_RASSIGN, EXP_OP_TASK_CALL, EXP_OP_WHILE, func_unit_s::exp_tail, EXPR_IS_STATIC, expression_create(), expression_create_tmp_vecs(), expression_dealloc(), FATAL, FUNIT_FUNCTION, FUNIT_NAMED_BLOCK, FUNIT_TASK, esuppl_u::part, print_output(), PROFILE, PROFILE_END, expression_s::scale, expression_s::suppl, Throw, func_unit_s::timescale, TRUE, Try, esuppl_u::type, user_msg, USER_MSG_LENGTH, expression_s::value, vector_db_read(), vector_dealloc(), and vector_s::width.

Referenced by db_read(), and funit_db_mod_merge().

01600   { PROFILE(EXPRESSION_DB_READ);
01601 
01602   expression*  expr;        /* Pointer to newly created expression */
01603   int          linenum;     /* Holder of current line for this expression */
01604   uint32       column;      /* Holder of column alignment information */
01605   uint32       exec_num;    /* Holder of expression's execution number */
01606   uint32       op;          /* Holder of expression operation */
01607   esuppl       suppl;       /* Holder of supplemental value of this expression */
01608   int          right_id;    /* Holder of expression ID to the right */
01609   int          left_id;     /* Holder of expression ID to the left */
01610   expression*  right;       /* Pointer to current expression's right expression */
01611   expression*  left;        /* Pointer to current expression's left expression */
01612   int          chars_read;  /* Number of characters scanned in from line */
01613   vector*      vec;         /* Holders vector value of this expression */
01614   exp_link*    expl;        /* Pointer to found expression in functional unit */
01615 
01616   if( sscanf( *line, "%d %x %d %x %x %x %d %d%n", &curr_expr_id, &op, &linenum, &column, &exec_num, &(suppl.all), &right_id, &left_id, &chars_read ) == 8 ) {
01617 
01618     *line += chars_read;
01619 
01620     /* Find functional unit instance name */
01621     if( curr_funit == NULL ) {
01622 
01623       unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Internal error:  expression (%d) in database written before its functional unit", curr_expr_id );
01624       assert( rv < USER_MSG_LENGTH );
01625       print_output( user_msg, FATAL, __FILE__, __LINE__ );
01626       Throw 0;
01627 
01628     } else {
01629 
01630       /* Find right expression */
01631       if( right_id == 0 ) {
01632         right = NULL;
01633       } else if( (expl = exp_link_find( right_id, curr_funit->exp_head )) == NULL ) {
01634         unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Internal error:  root expression (%d) found before leaf expression (%d) in database file", curr_expr_id, right_id );
01635         assert( rv < USER_MSG_LENGTH );
01636         print_output( user_msg, FATAL, __FILE__, __LINE__ );
01637         Throw 0;
01638       } else {
01639         right = expl->exp;
01640       }
01641 
01642       /* Find left expression */
01643       if( left_id == 0 ) {
01644         left = NULL;
01645       } else if( (expl = exp_link_find( left_id, curr_funit->exp_head )) == NULL ) {
01646         unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Internal error:  root expression (%d) found before leaf expression (%d) in database file", curr_expr_id, left_id );
01647         assert( rv < USER_MSG_LENGTH );
01648         print_output( user_msg, FATAL, __FILE__, __LINE__ );
01649         Throw 0;
01650       } else {
01651         left = expl->exp;
01652       }
01653 
01654       /* Create new expression */
01655       expr = expression_create( right, left, op, ESUPPL_IS_LHS( suppl ), curr_expr_id, linenum,
01656                                 ((column >> 16) & 0xffff), (column & 0xffff), ESUPPL_OWNS_VEC( suppl ) );
01657 
01658       expr->suppl.all = suppl.all;
01659       expr->exec_num  = exec_num;
01660 
01661       if( op == EXP_OP_DELAY ) {
01662         expr->suppl.part.type = ETYPE_DELAY;
01663         expr->elem.scale = &(curr_funit->timescale);
01664       }
01665 
01666       if( ESUPPL_OWNS_VEC( suppl ) ) {
01667 
01668         Try {
01669 
01670           /* Read in vector information */
01671           vector_db_read( &vec, line );
01672 
01673         } Catch_anonymous {
01674           expression_dealloc( expr, TRUE );
01675           Throw 0;
01676         }
01677 
01678         /* Copy expression value */
01679         vector_dealloc( expr->value );
01680         expr->value = vec;
01681 
01682       }
01683 
01684       /* Create temporary vectors if necessary */
01685       expression_create_tmp_vecs( expr, expr->value->width );
01686 
01687       /* Check to see if we are bound to a signal or functional unit */
01688       if( ((*line)[0] != '\n') && ((*line)[0] != '\0') ) {
01689         (*line)++;   /* Remove space */
01690         switch( op ) {
01691           case EXP_OP_FUNC_CALL :  bind_add( FUNIT_FUNCTION,    *line, expr, curr_funit );  break;
01692           case EXP_OP_TASK_CALL :  bind_add( FUNIT_TASK,        *line, expr, curr_funit );  break;
01693           case EXP_OP_FORK      :
01694           case EXP_OP_NB_CALL   :  bind_add( FUNIT_NAMED_BLOCK, *line, expr, curr_funit );  break;
01695           case EXP_OP_DISABLE   :  bind_add( 1,                 *line, expr, curr_funit );  break;
01696           default               :  bind_add( 0,                 *line, expr, curr_funit );  break;
01697         }
01698       }
01699 
01700       /* If we are an assignment operator, set our vector value to that of the right child */
01701       if( (op == EXP_OP_ASSIGN)     ||
01702           (op == EXP_OP_DASSIGN)    ||
01703           (op == EXP_OP_BASSIGN)    ||
01704           (op == EXP_OP_RASSIGN)    ||
01705           (op == EXP_OP_NASSIGN)    ||
01706           (op == EXP_OP_DLY_ASSIGN) ||
01707           (op == EXP_OP_IF)         ||
01708           (op == EXP_OP_WHILE)      ||
01709           (op == EXP_OP_DIM) ) {
01710 
01711         assert( right != NULL );
01712         vector_dealloc( expr->value );
01713         expr->value = right->value;
01714 
01715       }
01716 
01717       exp_link_add( expr, &(curr_funit->exp_head), &(curr_funit->exp_tail) );
01718 
01719       /*
01720        If this expression is a constant expression, force the simulator to evaluate
01721        this expression and all parent expressions of it.
01722       */
01723       if( eval && EXPR_IS_STATIC( expr ) && (ESUPPL_IS_LHS( suppl ) == 0) ) {
01724         exp_link_add( expr, &static_expr_head, &static_expr_tail );
01725       }
01726       
01727     }
01728 
01729   } else {
01730 
01731     print_output( "Unable to read expression value", FATAL, __FILE__, __LINE__ );
01732     Throw 0;
01733 
01734   }
01735 
01736   PROFILE_END;
01737 
01738 }

void expression_db_write ( expression expr,
FILE *  file,
bool  parse_mode,
bool  ids_issued 
)

Writes this expression to the specified database file.

This function recursively displays the expression information for the specified expression tree to the coverage database specified by file.

Parameters:
expr Pointer to expression to write to database file
file Pointer to database file to write to
parse_mode Set to TRUE when we are writing after just parsing the design (causes ulid value to be output instead of id)
ids_issued Set to TRUE if IDs were issued prior to calling this function

References esuppl_u::all, expression_s::all, expression_s::col, DB_TYPE_EXPRESSION, ESUPPL_MERGE_MASK, ESUPPL_OWNS_VEC, expression_s::exec_num, EXP_OP_ASSIGN, EXP_OP_DASSIGN, EXP_OP_STATIC, EXPR_OWNS_VEC, expression_get_id(), FALSE, expression_s::left, expression_s::line, vsignal_s::name, expression_s::name, expression_s::op, vsuppl_u::owns_data, vsuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::sig, vector_s::suppl, expression_s::suppl, expression_s::value, vector_db_write(), and vector_s::width.

Referenced by expression_db_write_tree(), and funit_db_write().

01526   { PROFILE(EXPRESSION_DB_WRITE);
01527 
01528   assert( expr != NULL );
01529 
01530   fprintf( file, "%d %d %x %d %x %x %x %d %d",
01531     DB_TYPE_EXPRESSION,
01532     expression_get_id( expr, ids_issued ),
01533     expr->op,
01534     expr->line,
01535     expr->col.all,
01536     ((((expr->op == EXP_OP_DASSIGN) || (expr->op == EXP_OP_ASSIGN)) && (expr->exec_num == 0)) ? (uint32)1 : expr->exec_num),
01537     (expr->suppl.all & ESUPPL_MERGE_MASK),
01538     ((expr->op == EXP_OP_STATIC) ? 0 : expression_get_id( expr->right, ids_issued )),
01539     ((expr->op == EXP_OP_STATIC) ? 0 : expression_get_id( expr->left,  ids_issued ))
01540   );
01541 
01542   if( ESUPPL_OWNS_VEC( expr->suppl ) ) {
01543     fprintf( file, " " );
01544     if( parse_mode && EXPR_OWNS_VEC( expr->op ) && (expr->value->suppl.part.owns_data == 0) && (expr->value->width > 0) ) {
01545       expr->value->suppl.part.owns_data = 1;
01546     }
01547     vector_db_write( expr->value, file, (expr->op == EXP_OP_STATIC), FALSE );
01548   }
01549 
01550   if( expr->name != NULL ) {
01551     fprintf( file, " %s", expr->name );
01552   } else if( expr->sig != NULL ) {
01553     fprintf( file, " %s", expr->sig->name );  /* This will be valid for parameters */
01554   }
01555 
01556   fprintf( file, "\n" );
01557 
01558   PROFILE_END;
01559 
01560 }

void expression_db_write_tree ( expression root,
FILE *  ofile 
)

Writes the entire expression tree to the specified data file.

Recursively iterates through the specified expression tree, outputting the expressions to the specified file.

Parameters:
root Pointer to the root expression to display
ofile Output file to write expression tree to

References EXPR_LEFT_DEALLOCABLE, expression_db_write(), expression_db_write_tree(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, and TRUE.

Referenced by expression_db_write_tree(), and statement_db_write_expr_tree().

01569   { PROFILE(EXPRESSION_DB_WRITE_TREE);
01570 
01571   if( root != NULL ) {
01572 
01573     /* Print children first */
01574     if( EXPR_LEFT_DEALLOCABLE( root ) ) {
01575       expression_db_write_tree( root->left, ofile );
01576     }
01577     expression_db_write_tree( root->right, ofile );
01578 
01579     /* Now write ourselves */
01580     expression_db_write( root, ofile, TRUE, TRUE );
01581 
01582   }
01583 
01584   PROFILE_END;
01585 
01586 }

void expression_dealloc ( expression expr,
bool  exp_only 
)

Deallocates memory used for expression.

Deallocates all heap memory allocated with the malloc routine.

Parameters:
expr Pointer to root expression to deallocate
exp_only Removes only the specified expression and not its children

References ssuppl_u::assigned, bind_remove(), DEBUG, debug_mode, dim_and_nba_s::dim, expression_s::dim, expression_s::dim_nba, expression_s::elem, ESUPPL_OWNS_VEC, exp_link_s::exp, statement_s::exp, vsignal_s::exp_head, exp_link_remove(), EXP_OP_FORK, EXP_OP_FUNC_CALL, EXP_OP_NB_CALL, EXP_OP_TASK_CALL, vsignal_s::exp_tail, EXPR_LEFT_DEALLOCABLE, EXPR_OP_HAS_DIM, EXPR_RIGHT_DEALLOCABLE, EXPR_TMP_VECS, expression_dealloc(), expression_get_root_statement(), expression_is_assigned(), FALSE, func_unit_s::first_stmt, free_safe, expression_s::funit, expression_s::id, expression_s::left, expression_s::line, ssuppl_u::mba, expression_s::name, dim_and_nba_s::nba, esuppl_u::nba, exp_link_s::next, expression_s::op, expression_s::parent, esuppl_u::part, ssuppl_u::part, print_output(), PROFILE, PROFILE_END, expression_s::right, expression_s::sig, stmt_blk_add_to_remove_list(), vsignal_s::suppl, expression_s::suppl, expression_s::tvecs, user_msg, USER_MSG_LENGTH, expression_s::value, vecblk_s::vec, vector_dealloc(), and vector_dealloc_value().

Referenced by attribute_dealloc(), db_add_defparam(), db_create_statement(), db_parallelize_statement(), exp_link_delete_list(), exp_link_remove(), expression_create(), expression_db_read(), expression_dealloc(), fsm_arg_parse_state(), fsm_arg_parse_value(), fsm_dealloc(), fsm_var_cleanup(), gen_item_dealloc(), mod_parm_dealloc(), parser_handle_case_statement_list(), parser_handle_generate_case_statement_list(), and static_expr_dealloc().

06177   { PROFILE(EXPRESSION_DEALLOC);
06178 
06179   exp_link*  tmp_expl;  /* Temporary pointer to expression list */
06180   statement* tmp_stmt;  /* Temporary pointer to statement */
06181 
06182   if( expr != NULL ) {
06183 
06184     if( ESUPPL_OWNS_VEC( expr->suppl ) ) {
06185 
06186       /* Free up memory from vector value storage */
06187       vector_dealloc( expr->value );
06188       expr->value = NULL;
06189 
06190       /* If this is a named block call or fork call, remove the statement that this expression points to */
06191       if( (expr->op == EXP_OP_NB_CALL) || (expr->op == EXP_OP_FORK) ) {
06192 
06193         if( !exp_only && (expr->elem.funit != NULL) ) {
06194 #ifdef DEBUG_MODE
06195           if( debug_mode ) {
06196             unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Removing statement block starting at line %d because it is a NB_CALL and its calling expression is being removed",
06197                                         expr->elem.funit->first_stmt->exp->line );
06198             assert( rv < USER_MSG_LENGTH );
06199             print_output( user_msg, DEBUG, __FILE__, __LINE__ );
06200           }
06201 #endif
06202           stmt_blk_add_to_remove_list( expr->elem.funit->first_stmt );
06203         } else {
06204           bind_remove( expr->id, FALSE );
06205         }
06206 
06207       /* If this is a task call, remove the bind */
06208       } else if( expr->op == EXP_OP_TASK_CALL ) {
06209          
06210         bind_remove( expr->id, FALSE );
06211 
06212       } else if( expr->op == EXP_OP_FUNC_CALL ) {
06213 
06214         /* Remove this expression from the attached signal's expression list (if the signal has not been deallocated yet) */
06215         if( expr->sig != NULL ) {
06216           exp_link_remove( expr, &(expr->sig->exp_head), &(expr->sig->exp_tail), FALSE );
06217         }
06218 
06219         bind_remove( expr->id, FALSE );
06220 
06221       /* Otherwise, we assume (for now) that the expression is a signal */
06222       } else {
06223 
06224         if( expr->sig == NULL ) {
06225 
06226           /* Remove this expression from the binding list */
06227           bind_remove( expr->id, expression_is_assigned( expr ) );
06228 
06229         } else {
06230 
06231           /* Remove this expression from the attached signal's expression list */
06232           exp_link_remove( expr, &(expr->sig->exp_head), &(expr->sig->exp_tail), FALSE );
06233 
06234           /* Clear the assigned bit of the attached signal */
06235           if( expression_is_assigned( expr ) ) {
06236   
06237             expr->sig->suppl.part.assigned = 0;
06238 
06239             /* If this signal must be assigned, remove all statement blocks that reference this signal */
06240             if( (expr->sig->suppl.part.mba == 1) && !exp_only ) {
06241               tmp_expl = expr->sig->exp_head;
06242               while( tmp_expl != NULL ) {
06243                 if( (tmp_stmt = expression_get_root_statement( tmp_expl->exp )) != NULL ) {
06244 #ifdef DEBUG_MODE
06245                   if( debug_mode ) {
06246                     print_output( "Removing statement block because a statement block is being removed that assigns an MBA", DEBUG, __FILE__, __LINE__ );
06247                   }
06248 #endif
06249                   stmt_blk_add_to_remove_list( tmp_stmt );
06250                 }
06251                 tmp_expl = tmp_expl->next;
06252               }
06253             }
06254 
06255           }
06256         
06257         }
06258 
06259       }
06260 
06261     } else {
06262 
06263       /* Remove our expression from its signal, if we have one */
06264       if( expr->sig != NULL ) {
06265         exp_link_remove( expr, &(expr->sig->exp_head), &(expr->sig->exp_tail), FALSE );
06266       }
06267 
06268     }
06269 
06270     /* Deallocate children */
06271     if( !exp_only ) {
06272 
06273       if( EXPR_RIGHT_DEALLOCABLE( expr ) ) {
06274         expression_dealloc( expr->right, FALSE );
06275         expr->right = NULL;
06276       }
06277 
06278       if( EXPR_LEFT_DEALLOCABLE( expr ) ) {
06279         expression_dealloc( expr->left, FALSE );
06280         expr->left = NULL;
06281       }
06282 
06283     }
06284 
06285     /* If we have temporary vectors to deallocate, do so now */
06286     if( (expr->elem.tvecs != NULL) && (EXPR_TMP_VECS( expr->op ) > 0) ) {
06287       unsigned int i;
06288       for( i=0; i<EXPR_TMP_VECS( expr->op ); i++ ) {
06289         vector_dealloc_value( &(expr->elem.tvecs->vec[i]) );
06290       }
06291       free_safe( expr->elem.tvecs, sizeof( vecblk ) );
06292     }
06293 
06294     /* If we have expression dimensional information, deallocate it now */
06295     if( (expr->elem.dim != NULL) && EXPR_OP_HAS_DIM( expr->op ) ) {
06296       if( expr->suppl.part.nba == 1 ) {
06297         free_safe( expr->elem.dim_nba->dim, sizeof( exp_dim ) );
06298         free_safe( expr->elem.dim_nba->nba, sizeof( nonblock_assign ) );
06299         free_safe( expr->elem.dim_nba, sizeof( dim_and_nba ) );
06300       } else {
06301         free_safe( expr->elem.dim, sizeof( exp_dim ) );
06302       }
06303     }
06304 
06305     /* Free up memory for the parent pointer */
06306     free_safe( expr->parent, sizeof( expr_stmt ) );
06307 
06308     /* If name contains data, free it */
06309     free_safe( expr->name, (strlen( expr->name ) + 1) );
06310 
06311     /* Remove this expression memory */
06312     free_safe( expr, sizeof( expression ) );
06313 
06314   }
06315 
06316   PROFILE_END;
06317 
06318 }

void expression_display ( expression expr  ) 

Displays the specified expression information.

Displays contents of the specified expression to standard output. This function is called by the funit_display function.

Parameters:
expr Pointer to expression to display

References esuppl_u::all, expression_s::all, expression_s::col, vsuppl_u::data_type, expression_s::exec_num, expression_string_op(), expression_s::id, expression_s::left, expression_s::line, expression_s::op, vsuppl_u::part, vector_s::r32, vector_s::r64, expression_s::right, rv32_s::str, rv64_s::str, vector_s::suppl, expression_s::suppl, vector_s::ul, rv32_s::val, rv64_s::val, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_display_value_ulong(), and vector_s::width.

Referenced by expression_op_func__pdec(), and funit_display_expressions().

01877   {
01878 
01879   int right_id;  /* Value of right expression ID */
01880   int left_id;   /* Value of left expression ID */
01881 
01882   assert( expr != NULL );
01883 
01884   if( expr->left == NULL ) {
01885     left_id = 0;
01886   } else {
01887     left_id = expr->left->id;
01888   }
01889 
01890   if( expr->right == NULL ) {
01891     right_id = 0;
01892   } else {
01893     right_id = expr->right->id;
01894   }
01895 
01896   printf( "  Expression (%p) =>  id: %d, op: %s, line: %d, col: %x, suppl: %x, exec_num: %u, left: %d, right: %d, ", 
01897           expr,
01898           expr->id,
01899           expression_string_op( expr->op ),
01900           expr->line,
01901           expr->col.all,
01902           expr->suppl.all,
01903           expr->exec_num,
01904           left_id, 
01905           right_id );
01906 
01907   if( expr->value->value.ul == NULL ) {
01908     printf( "NO DATA VECTOR" );
01909   } else {
01910     switch( expr->value->suppl.part.data_type ) {
01911       case VDATA_UL  :  vector_display_value_ulong( expr->value->value.ul, expr->value->width );  break;
01912       case VDATA_R64 :
01913         if( expr->value->value.r64->str != NULL ) {
01914           printf( "%s", expr->value->value.r64->str );
01915         } else {
01916           printf( "%.16lf", expr->value->value.r64->val );
01917         }
01918         break;
01919       case VDATA_R32 :
01920         if( expr->value->value.r32->str != NULL ) {
01921           printf( "%s", expr->value->value.r32->str );
01922         } else {
01923           printf( "%.16f", expr->value->value.r32->val );
01924         }
01925         break;
01926       default :  assert( 0 );  break;
01927     }
01928   }
01929   printf( "\n" );
01930 
01931 }

bool expression_find_expr ( expression root,
expression expr 
)

Returns TRUE if the specified expression exists within the given root expression tree.

Returns:
Returns TRUE if the given expression exists within the given expression tree; otherwise, returns FALSE
Parameters:
root Pointer to root of expression tree to search
expr Pointer to expression to search for

References expression_find_expr(), expression_s::left, PROFILE, PROFILE_END, and expression_s::right.

Referenced by expression_find_expr(), and instance_remove_parms_with_expr().

01430   { PROFILE(EXPRESSION_FIND_EXPR);
01431 
01432   bool retval = (root != NULL) && ((root == expr) || expression_find_expr( root->left, expr ) || expression_find_expr( root->right, expr ));
01433 
01434   PROFILE_END;
01435 
01436   return( retval );
01437 
01438 }

void expression_find_rhs_sigs ( expression expr,
str_link **  head,
str_link **  tail 
)

Finds all RHS signals in given expression tree.

Recursively parses specified expression list in search of RHS signals. When a signal name is found, it is added to the signal name list specified by head and tail.

Parameters:
expr Pointer to expression tree to parse
head Pointer to head of signal name list to populate
tail Pointer to tail of signal name list to populate

References bind_find_sig_name(), ESUPPL_IS_LHS, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_SBIT_SEL, EXP_OP_SIG, EXP_OP_TRIGGER, expression_find_rhs_sigs(), free_safe, expression_s::left, expression_s::op, PROFILE, PROFILE_END, expression_s::right, str_link_add(), str_link_find(), and expression_s::suppl.

Referenced by expression_find_rhs_sigs(), and statement_find_rhs_sigs().

01318   { PROFILE(EXPRESSION_FIND_RHS_SIGS);
01319 
01320   char* sig_name;  /* Name of signal found */
01321 
01322   /* Only continue if our expression is valid and it is an RHS */
01323   if( (expr != NULL) && (ESUPPL_IS_LHS( expr->suppl ) == 0) ) {
01324 
01325     if( (expr->op == EXP_OP_SIG)      ||
01326         (expr->op == EXP_OP_TRIGGER)  ||
01327         (expr->op == EXP_OP_SBIT_SEL) ||
01328         (expr->op == EXP_OP_MBIT_SEL) ||
01329         (expr->op == EXP_OP_MBIT_POS) ||
01330         (expr->op == EXP_OP_MBIT_NEG) ) {
01331  
01332       /* Get the signal name from the binder */
01333       sig_name = bind_find_sig_name( expr );
01334        
01335       assert( sig_name != NULL );
01336     
01337       /* If the signal isn't already in the list, add it */
01338       if( str_link_find( sig_name, *head ) == NULL ) {
01339         (void)str_link_add( sig_name, head, tail );
01340       } else {
01341         free_safe( sig_name, (strlen( sig_name ) + 1) );
01342       }
01343 
01344     }
01345 
01346     /* If this expression operation is neither a SIG or TRIGGER, keep searching tree */
01347     if( (expr->op != EXP_OP_SIG) && (expr->op != EXP_OP_TRIGGER) ) {
01348 
01349       expression_find_rhs_sigs( expr->right, head, tail );
01350       expression_find_rhs_sigs( expr->left,  head, tail );
01351 
01352     }
01353 
01354   }
01355 
01356   PROFILE_END;
01357 
01358 }

expression* expression_find_uline_id ( expression expr,
int  ulid 
)

Finds the expression in this expression tree with the specified underline id.

Returns:
Returns a pointer to the found expression; otherwise, returns NULL if the expression could not be found.

Recursively searches the given expression tree for the specified underline ID. If the expression is found, a pointer to it is returned; otherwise, returns NULL.

Parameters:
expr Pointer to root expression to search under
ulid Underline ID to search for

References expression_find_uline_id(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, and expression_s::ulid.

Referenced by combination_get_coverage(), exclude_is_comb_excluded(), exclude_set_comb_exclude(), and expression_find_uline_id().

01401   { PROFILE(EXPRESSION_FIND_ULINE_ID);
01402 
01403   expression* found_exp = NULL;  /* Pointer to found expression */
01404 
01405   if( expr != NULL ) {
01406 
01407     if( expr->ulid == ulid ) {
01408       found_exp = expr;
01409     } else {
01410       if( (found_exp = expression_find_uline_id( expr->left, ulid )) == NULL ) {
01411         found_exp = expression_find_uline_id( expr->right, ulid );
01412       }
01413     }
01414 
01415   }
01416 
01417   PROFILE_END;
01418 
01419   return( found_exp );
01420 
01421 }

unsigned int expression_get_curr_dimension ( expression expr  ) 

Returns the current dimension of the given expression.

Returns:
Returns the dimension index for the given expression

Recursively iterates up expression tree, counting the number of dimensions deep that the given expression is.

Parameters:
expr Pointer to expression to get dimension for

References ESUPPL_IS_ROOT, EXP_OP_DIM, expr_stmt_u::expr, expression_get_curr_dimension(), expression_s::left, expression_s::op, expression_s::parent, PROFILE, PROFILE_END, expression_s::right, and expression_s::suppl.

Referenced by expression_get_curr_dimension(), expression_set_value(), race_check_one_block_assignment(), and vsignal_calc_width_for_expr().

01281   { PROFILE(EXPRESSION_GET_CURR_DIMENSION);
01282   
01283   unsigned int dim;  /* Return value for this function */
01284 
01285   assert( expr != NULL );
01286 
01287   if( expr->op == EXP_OP_DIM ) {
01288 
01289     dim = expression_get_curr_dimension( expr->left ) + 1;
01290 
01291   } else {
01292 
01293     if( (ESUPPL_IS_ROOT( expr->suppl ) == 0) &&
01294         (expr->parent->expr->op == EXP_OP_DIM) && 
01295         (expr->parent->expr->right == expr) ) {
01296       dim = expression_get_curr_dimension( expr->parent->expr );
01297     } else {
01298       dim = 0;
01299     }
01300 
01301   }
01302 
01303   PROFILE_END;
01304 
01305   return( dim );
01306 
01307 }

expression* expression_get_first_line_expr ( expression expr  ) 

Returns first line in this expression tree.

Returns:
Returns the line number of the first line in this expression.
Parameters:
expr Pointer to root expression to extract first line from

References expression_get_first_line_expr(), expression_s::left, expression_s::line, PROFILE, and PROFILE_END.

Referenced by codegen_create_expr(), and expression_get_first_line_expr().

01230   { PROFILE(EXPRESSION_GET_FIRST_LINE_EXPR);
01231 
01232   expression* first = NULL;
01233 
01234   if( expr != NULL ) {
01235 
01236     first = expression_get_first_line_expr( expr->left );
01237     if( (first == NULL) || (first->line > expr->line) ) {
01238       first = expr;
01239     }
01240 
01241   }
01242 
01243   PROFILE_END;
01244 
01245   return( first );
01246 
01247 }

int expression_get_id ( expression expr,
bool  parse_mode 
)

Returns expression ID of this expression.

Returns:
Returns expression ID for this expression.

If specified expression is non-NULL, return expression ID of this expression; otherwise, return a value of 0 to indicate that this is a leaf node.

Parameters:
expr Pointer to expression to get ID from
parse_mode Specifies if ulid (TRUE) or id (FALSE) should be used

References expression_s::id, PROFILE, PROFILE_END, and expression_s::ulid.

Referenced by expression_db_write(), fsm_db_write(), and statement_db_write().

01209   { PROFILE(EXPRESSION_GET_ID);
01210 
01211   int id;
01212 
01213   if( expr == NULL ) {
01214     id = 0;
01215   } else {
01216     id = parse_mode ? expr->ulid : expr->id;
01217   }
01218 
01219   PROFILE_END;
01220 
01221   return( id );
01222 
01223 }

expression* expression_get_last_line_expr ( expression expr  ) 

Returns last line in this expression tree.

Returns:
Returns the line number of the last line in this expression.
Parameters:
expr Pointer to root expression to extract last line from

References expression_get_last_line_expr(), expression_s::line, PROFILE, PROFILE_END, and expression_s::right.

Referenced by codegen_create_expr(), expression_get_last_line_expr(), line_collect(), and statement_get_last_line_helper().

01254   { PROFILE(EXPRESSION_GET_LAST_LINE_EXPR);
01255 
01256   expression* last = NULL;
01257 
01258   if( expr != NULL ) {
01259 
01260     last = expression_get_last_line_expr( expr->right );
01261     if( (last == NULL) || (last->line < expr->line) ) {
01262       last = expr;
01263     }
01264       
01265   }
01266 
01267   PROFILE_END;
01268 
01269   return( last );
01270 
01271 }

statement* expression_get_root_statement ( expression exp  ) 

Finds the root statement for the given expression.

Returns:
Returns a pointer to the root statement of the specified expression if one exists; otherwise, returns NULL.

Recursively traverses up expression tree that contains exp until the root expression is found (if one exists). If the root expression is found, return the pointer to the statement pointing to this root expression. If the root expression was not found, return NULL.

Parameters:
exp Pointer to expression to get root statement for

References ESUPPL_IS_ROOT, expr_stmt_u::expr, expression_get_root_statement(), expression_s::parent, PROFILE, PROFILE_END, expr_stmt_u::stmt, and expression_s::suppl.

Referenced by bind_perform(), bind_signal(), expression_dealloc(), expression_get_root_statement(), and race_get_head_statement().

01469   { PROFILE(EXPRESSION_GET_ROOT_STATEMENT);
01470 
01471   statement* stmt;  /* Pointer to root statement */
01472 
01473   if( exp == NULL ) {
01474     stmt = NULL;
01475   } else if( ESUPPL_IS_ROOT( exp->suppl ) == 1 ) {
01476     stmt = exp->parent->stmt;
01477   } else {
01478     stmt = expression_get_root_statement( exp->parent->expr );
01479   }
01480 
01481   PROFILE_END;
01482 
01483   return( stmt );
01484 
01485 }

bool expression_is_bit_select ( expression expr  ) 

Returns TRUE if specified expression is a part of an bit select expression tree.

Returns:
Returns TRUE if the specifies expression belongs in a single or mult-bit select expression
Parameters:
expr Pointer to expression to check

References ESUPPL_IS_ROOT, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_SBIT_SEL, expr_stmt_u::expr, expression_is_bit_select(), FALSE, expression_s::op, expression_s::parent, PROFILE, PROFILE_END, expression_s::suppl, and TRUE.

Referenced by expression_is_bit_select(), and race_check_one_block_assignment().

05760   { PROFILE(EXPRESSION_IS_BIT_SELECT);
05761 
05762   bool retval = FALSE;  /* Return value for this function */
05763 
05764   if( (expr != NULL) && (ESUPPL_IS_ROOT( expr->suppl ) == 0) ) {
05765 
05766     if( (expr->parent->expr->op == EXP_OP_SBIT_SEL) ||
05767         (expr->parent->expr->op == EXP_OP_MBIT_SEL) ||
05768         (expr->parent->expr->op == EXP_OP_MBIT_POS) ||
05769         (expr->parent->expr->op == EXP_OP_MBIT_NEG) ) {
05770       retval = TRUE;
05771     } else {
05772       retval = expression_is_bit_select( expr->parent->expr );
05773     }
05774 
05775   }
05776 
05777   PROFILE_END;
05778 
05779   return( retval );
05780 
05781 }

bool expression_is_in_rassign ( expression expr  ) 

Returns TRUE if specified expression is in an RASSIGN expression tree.

Returns:
Returns TRUE if the specified expression is in an RASSIGN expression tree; otherwise, returns FALSE.
Parameters:
expr Pointer to expression to examine

References ESUPPL_IS_ROOT, EXP_OP_RASSIGN, expr_stmt_u::expr, expression_is_in_rassign(), FALSE, expression_s::op, expression_s::parent, PROFILE, PROFILE_END, expression_s::suppl, and TRUE.

Referenced by expression_is_in_rassign(), and race_check_one_block_assignment().

05810   { PROFILE(EXPRESSION_IS_IN_RASSIGN);
05811 
05812   bool retval = FALSE;  /* Return value for this function */
05813 
05814   if( expr != NULL ) {
05815 
05816     if( expr->op == EXP_OP_RASSIGN ) {
05817       retval = TRUE;
05818     } else if( ESUPPL_IS_ROOT( expr->suppl ) == 0 ) {
05819       retval = expression_is_in_rassign( expr->parent->expr );
05820     }
05821 
05822   }
05823 
05824   PROFILE_END;
05825 
05826   return( retval );
05827 
05828 }

bool expression_is_last_select ( expression expr  ) 

Returns TRUE if specified expression is the last select of a signal.

Returns:
Returns TRUE if the specified expression is the last (most right-hand) part/bit select of a signal; otherwise, returns FALSE.
Parameters:
expr Pointer to expression to check for last select

References ESUPPL_IS_ROOT, EXP_OP_DIM, expr_stmt_u::expr, expression_s::op, expression_s::parent, PROFILE, PROFILE_END, expression_s::right, and expression_s::suppl.

Referenced by expression_set_value(), and race_check_one_block_assignment().

05789   { PROFILE(EXPRESSION_IS_LAST_SELECT);
05790 
05791   bool retval = (ESUPPL_IS_ROOT( expr->suppl ) == 1) ||
05792                 ( ((expr->parent->expr->op == EXP_OP_DIM) &&
05793                    (expr->parent->expr->right == expr) &&
05794                    (ESUPPL_IS_ROOT( expr->parent->expr->suppl ) == 0) &&
05795                    (expr->parent->expr->parent->expr->op != EXP_OP_DIM)) ||
05796                   (expr->parent->expr->op != EXP_OP_DIM) );
05797 
05798   PROFILE_END;
05799 
05800   return( retval );
05801 
05802 }

expression* expression_is_nba_lhs ( expression exp  ) 

Returns a pointer to the non-blocking assignment expression if the given expression is an assignable expression on the LHS of a non-blocking assignment.

Returns:
Returns a pointer to the non-blocking assignment if this expression is a child of the LHS that will be assigned via a non-blocking assignment; otherwise, returns a value of NULL.
Parameters:
exp Pointer to child expression to check

References ESUPPL_IS_ROOT, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_NASSIGN, EXP_OP_SBIT_SEL, expr_stmt_u::expr, expression_s::op, expression_s::parent, PROFILE, PROFILE_END, and expression_s::suppl.

Referenced by bind_signal().

00530   { PROFILE(EXPRESSION_IS_NBA_LHS);
00531 
00532   while( (exp->op != EXP_OP_NASSIGN)                &&
00533          (ESUPPL_IS_ROOT( exp->suppl ) == 0)        &&
00534          (exp->parent->expr->op != EXP_OP_SBIT_SEL) &&
00535          (exp->parent->expr->op != EXP_OP_MBIT_SEL) &&
00536          (exp->parent->expr->op != EXP_OP_MBIT_POS) &&
00537          (exp->parent->expr->op != EXP_OP_MBIT_NEG) ) {
00538     exp = exp->parent->expr;
00539   }
00540 
00541   PROFILE_END;
00542 
00543   return( (exp->op == EXP_OP_NASSIGN) ? exp : NULL );
00544 
00545 }

bool expression_is_static_only ( expression expr  ) 

Returns TRUE if specified expression is found to contain all static leaf expressions.

Parameters:
expr Pointer to expression to evaluate

References expression_is_static_only_helper().

Referenced by combination_get_tree_stats(), combination_output_expr(), and rank_gather_comb_cov().

05705   {
05706 
05707   return( expression_is_static_only_helper( expr, NULL ) ); 
05708 
05709 }

void expression_merge ( expression base,
expression other 
)

Merges two expressions into the base expression.

Performs an expression merge of two expressions, storing the result into the base expression. This function is used by the GUI for calculating module coverage.

Parameters:
base Base expression that will contain merged results
other Other expression that will merge its results with the base results

References esuppl_u::all, expression_s::all, expression_s::col, ESUPPL_MERGE_MASK, ESUPPL_OWNS_VEC, expression_s::exec_num, expression_s::line, expression_s::op, PROFILE, PROFILE_END, expression_s::suppl, expression_s::value, and vector_merge().

Referenced by funit_merge().

01815   { PROFILE(EXPRESSION_MERGE);
01816 
01817   assert( base != NULL );
01818   assert( base->op      == other->op );
01819   assert( base->line    == other->line );
01820   assert( base->col.all == other->col.all );
01821 
01822   /* Merge expression supplemental fields */
01823   base->suppl.all = (base->suppl.all & ESUPPL_MERGE_MASK) | (other->suppl.all & ESUPPL_MERGE_MASK);
01824 
01825   /* Merge execution number information */
01826   if( base->exec_num < other->exec_num ) {
01827     base->exec_num = other->exec_num;
01828   }
01829 
01830   if( ESUPPL_OWNS_VEC( base->suppl ) ) {
01831     vector_merge( base->value, other->value );
01832   }
01833 
01834   PROFILE_END;
01835 
01836 }

bool expression_operate ( expression expr,
thread thr,
const sim_time time 
)

Performs operation specified by parameter expression.

Returns:
Returns TRUE if the assigned expression value was different than the previously stored value; otherwise, returns FALSE.
Exceptions:
anonymous func

Performs expression operation. This function must only be run after its left and right expressions have been calculated during this clock period. Sets the value of the operation in its own vector value and updates the suppl uint8 as necessary.

Parameters:
expr Pointer to expression to set value to
thr Pointer to current thread being simulated
time Pointer to current simulation time

References DEBUG, debug_mode, expression_s::exec_num, expression_string_op(), fsm_table_set(), exp_info_s::func, expression_s::id, expression_s::line, expression_s::op, print_output(), PROFILE, PROFILE_END, expression_s::table, TRUE, user_msg, USER_MSG_LENGTH, and expression_s::value.

Referenced by expression_operate_recursively(), fsm_create_tables(), param_expr_eval(), and sim_expression().

05554   { PROFILE(EXPRESSION_OPERATE);
05555 
05556   bool retval = TRUE;  /* Return value for this function */
05557 
05558   if( expr != NULL ) {
05559 
05560 #ifdef DEBUG_MODE
05561     if( debug_mode ) {
05562       unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "      In expression_operate, id: %d, op: %s, line: %d, addr: %p",
05563                                   expr->id, expression_string_op( expr->op ), expr->line, expr );
05564       assert( rv < USER_MSG_LENGTH );
05565       print_output( user_msg, DEBUG, __FILE__, __LINE__ );
05566     }
05567 #endif
05568 
05569     assert( expr->value != NULL );
05570 
05571     /* Call expression operation */
05572     retval = exp_op_info[expr->op].func( expr, thr, time );
05573 
05574     /* If this expression is attached to an FSM, perform the FSM calculation now */
05575     if( expr->table != NULL ) {
05576       fsm_table_set( expr, time );
05577     }
05578 
05579     /* Specify that we have executed this expression */
05580     (expr->exec_num)++;
05581 
05582   }
05583 
05584   PROFILE_END;
05585 
05586   return( retval );
05587 
05588 }

void expression_operate_recursively ( expression expr,
func_unit funit,
bool  sizing 
)

Performs recursive expression operation (parse mode only).

Exceptions:
anonymous expression_resize expression_operate_recursively expression_operate_recursively

Recursively performs the proper operations to cause the top-level expression to be set to a value. This function is called during the parse stage to derive pre-CDD widths of multi-bit expressions. Each MSB/LSB is an expression tree that needs to be evaluated to set the width properly on the MBIT_SEL expression.

Parameters:
expr Pointer to top of expression tree to perform recursive operations
funit Pointer to functional unit containing this expression
sizing Set to TRUE if we are evaluating for purposes of sizing

References expression_s::exec_num, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_SBIT_SEL, expression_operate(), expression_operate_recursively(), expression_resize(), FALSE, expression_s::left, expression_s::op, PROFILE, PROFILE_END, expression_s::right, and TRUE.

Referenced by expression_operate_recursively(), expression_resize(), expression_set_value(), and gen_item_resolve().

05602   { PROFILE(EXPRESSION_OPERATE_RECURSIVELY);
05603     
05604   if( expr != NULL ) {
05605     
05606     /* Create dummy time */
05607     sim_time time = {0,0,0,FALSE};
05608 
05609     /* Evaluate children */
05610     expression_operate_recursively( expr->left,  funit, sizing );
05611     expression_operate_recursively( expr->right, funit, sizing );
05612     
05613     if( sizing ) {
05614 
05615       /*
05616        Non-static expression found where static expression required.  Simulator
05617        should catch this error before us, so no user error (too much work to find
05618        expression in functional unit expression list for now.
05619       */
05620       assert( (expr->op != EXP_OP_SBIT_SEL) &&
05621               (expr->op != EXP_OP_MBIT_SEL) &&
05622               (expr->op != EXP_OP_MBIT_POS) &&
05623               (expr->op != EXP_OP_MBIT_NEG) );
05624 
05625       /* Resize current expression only */
05626       expression_resize( expr, funit, FALSE, TRUE );
05627     
05628     }
05629     
05630     /* Perform operation */
05631     (void)expression_operate( expr, NULL, &time );
05632 
05633     if( sizing ) {
05634 
05635       /* Clear out the execution number value since we aren't really simulating this */
05636       expr->exec_num = 0;
05637 
05638     }
05639     
05640   }
05641   
05642   PROFILE_END;
05643 
05644 }

void expression_resize ( expression expr,
func_unit funit,
bool  recursive,
bool  alloc 
)

Recursively resizes specified expression tree leaf node.

Exceptions:
anonymous expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value expression_create_value funit_size_elements expression_resize expression_resize expression_operate_recursively expression_set_value

Resizes the given expression depending on the expression operation and its children's sizes. If recursive is TRUE, performs the resize in a depth-first fashion, resizing the children before resizing the current expression. If recursive is FALSE, only the given expression is evaluated and resized.

Parameters:
expr Pointer to expression to potentially resize
funit Pointer to functional unit containing expression
recursive Specifies if we should perform a recursive depth-first resize
alloc If set to TRUE, allocates vector data for all expressions

References vsuppl_u::all, curr_db, vsuppl_u::data_type, expression_s::elem, ESUPPL_IS_LHS, ESUPPL_IS_ROOT, EXP_OP_AEDGE, EXP_OP_ASSIGN, EXP_OP_BASSIGN, EXP_OP_CASE, EXP_OP_CASEX, EXP_OP_CASEZ, EXP_OP_CEQ, EXP_OP_CNE, EXP_OP_DASSIGN, EXP_OP_DEFAULT, EXP_OP_DIM, EXP_OP_DLY_ASSIGN, EXP_OP_DLY_OP, EXP_OP_EOR, EXP_OP_EQ, EXP_OP_EXPAND, EXP_OP_FUNC_CALL, EXP_OP_GE, EXP_OP_GT, EXP_OP_IF, EXP_OP_LAND, EXP_OP_LAST, EXP_OP_LE, EXP_OP_LIST, EXP_OP_LOR, EXP_OP_LT, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_NASSIGN, EXP_OP_NE, EXP_OP_NEDGE, EXP_OP_PARAM, EXP_OP_PARAM_MBIT, EXP_OP_PARAM_MBIT_NEG, EXP_OP_PARAM_MBIT_POS, EXP_OP_PARAM_SBIT, EXP_OP_PASSIGN, EXP_OP_PEDGE, EXP_OP_PLIST, EXP_OP_RASSIGN, EXP_OP_REPEAT, EXP_OP_RPT_DLY, EXP_OP_SBIT_SEL, EXP_OP_SCLOG2, EXP_OP_SFINISH, EXP_OP_SIG, EXP_OP_SRANDOM, EXP_OP_SREALTIME, EXP_OP_SSRANDOM, EXP_OP_SSTOP, EXP_OP_STATIC, EXP_OP_STESTARGS, EXP_OP_STIME, EXP_OP_SURAND_RANGE, EXP_OP_SURANDOM, EXP_OP_SVALARGS, EXP_OP_TRIGGER, EXP_OP_UAND, EXP_OP_UNAND, EXP_OP_UNOR, EXP_OP_UNOT, EXP_OP_UNXOR, EXP_OP_UOR, EXP_OP_UXOR, EXP_OP_WAIT, EXP_OP_WHILE, expr_stmt_u::expr, expression_create_value(), expression_operate_recursively(), expression_resize(), expression_set_value(), FALSE, FATAL, func_unit_s::filename, expression_s::funit, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, funit_size_elements(), db_s::inst_head, inst_link_find_by_funit(), expression_s::left, expression_s::line, expression_s::op, vsuppl_u::owns_data, expression_s::parent, vsuppl_u::part, print_output(), PROFILE, PROFILE_END, expression_s::right, expression_s::sig, expression_s::suppl, vector_s::suppl, Throw, TRUE, func_unit_s::type, vector_s::ul, user_msg, USER_MSG_LENGTH, vsignal_s::value, vector_s::value, expression_s::value, vector_is_unknown(), vector_to_int(), and vector_s::width.

Referenced by expression_assign_expr_ids(), expression_operate_recursively(), expression_resize(), funit_size_elements(), gen_item_resolve(), param_expr_eval(), and statement_size_elements().

00984   { PROFILE(EXPRESSION_RESIZE);
00985 
00986   unsigned int largest_width;  /* Holds larger width of left and right children */
00987   uint8        old_vec_suppl;  /* Holds original vector supplemental field as this will be erased */
00988   funit_inst*  tmp_inst;       /* Pointer to temporary instance */
00989   int          ignore = 0;     /* Specifies the number of instances to ignore */
00990 
00991   if( expr != NULL ) {
00992 
00993     uint8 new_owns_data;
00994     uint8 new_data_type;
00995 
00996     if( recursive ) {
00997       expression_resize( expr->left, funit, recursive, alloc );
00998       expression_resize( expr->right, funit, recursive, alloc );
00999     }
01000 
01001     /* Get vector supplemental field */
01002     old_vec_suppl = expr->value->suppl.all;
01003 
01004     switch( expr->op ) {
01005 
01006       /* Only resize these values if we are recursively resizing */
01007       case EXP_OP_PARAM          :
01008       case EXP_OP_PARAM_SBIT     :
01009       case EXP_OP_PARAM_MBIT     :
01010       case EXP_OP_PARAM_MBIT_POS :
01011       case EXP_OP_PARAM_MBIT_NEG :
01012       case EXP_OP_SIG            :
01013       case EXP_OP_SBIT_SEL       :
01014       case EXP_OP_MBIT_SEL       :
01015       case EXP_OP_MBIT_POS       :
01016       case EXP_OP_MBIT_NEG       :
01017         if( recursive && (expr->sig != NULL) ) {
01018           expression_set_value( expr, expr->sig, funit );
01019           assert( expr->value->value.ul != NULL );
01020         }
01021         break;
01022 
01023       /* These operations will already be sized so nothing to do here */
01024       case EXP_OP_STATIC         :
01025       case EXP_OP_TRIGGER        :
01026       case EXP_OP_ASSIGN         :
01027       case EXP_OP_DASSIGN        :
01028       case EXP_OP_BASSIGN        :
01029       case EXP_OP_NASSIGN        :
01030       case EXP_OP_PASSIGN        :
01031       case EXP_OP_RASSIGN        :
01032       case EXP_OP_DLY_ASSIGN     :
01033       case EXP_OP_IF             :
01034       case EXP_OP_WHILE          :
01035       case EXP_OP_LAST           :
01036       case EXP_OP_DIM            :
01037       case EXP_OP_STIME          :
01038       case EXP_OP_SREALTIME      :
01039       case EXP_OP_SRANDOM        :
01040       case EXP_OP_SURANDOM       :
01041       case EXP_OP_SURAND_RANGE   :
01042         break;
01043 
01044       /* These operations should always be set to a width 1 */
01045       case EXP_OP_LT        :
01046       case EXP_OP_GT        :
01047       case EXP_OP_EQ        :
01048       case EXP_OP_CEQ       :
01049       case EXP_OP_LE        :
01050       case EXP_OP_GE        :
01051       case EXP_OP_NE        :
01052       case EXP_OP_CNE       :
01053       case EXP_OP_LOR       :
01054       case EXP_OP_LAND      :
01055       case EXP_OP_UAND      :
01056       case EXP_OP_UNOT      :
01057       case EXP_OP_UOR       :
01058       case EXP_OP_UXOR      :
01059       case EXP_OP_UNAND     :
01060       case EXP_OP_UNOR      :
01061       case EXP_OP_UNXOR     :
01062       case EXP_OP_EOR       :
01063       case EXP_OP_CASE      :
01064       case EXP_OP_CASEX     :
01065       case EXP_OP_CASEZ     :
01066       case EXP_OP_DEFAULT   :
01067       case EXP_OP_REPEAT    :
01068       case EXP_OP_RPT_DLY   :
01069       case EXP_OP_WAIT      :
01070       case EXP_OP_SFINISH   :
01071       case EXP_OP_SSTOP     :
01072       case EXP_OP_NEDGE     :
01073       case EXP_OP_PEDGE     :
01074       case EXP_OP_AEDGE     :
01075       case EXP_OP_PLIST     :
01076       case EXP_OP_SSRANDOM  :
01077       case EXP_OP_STESTARGS :
01078       case EXP_OP_SVALARGS  : 
01079         if( (expr->value->width != 1) || (expr->value->value.ul == NULL) ) {
01080           assert( expr->value->value.ul == NULL );
01081           expression_create_value( expr, 1, alloc );
01082         }
01083         break;
01084 
01085       /* These operations should always be set to a width of 32 */
01086       case EXP_OP_SCLOG2 :
01087         if( (expr->value->width != 32) || (expr->value->value.ul == NULL) ) {
01088           assert( expr->value->value.ul == NULL );
01089           expression_create_value( expr, 32, alloc );
01090         }
01091         break;
01092 
01093       /*
01094        In the case of an EXPAND, we need to set the width to be the product of the value of
01095        the left child and the bit-width of the right child.
01096       */
01097       case EXP_OP_EXPAND :
01098         expression_operate_recursively( expr->left, funit, TRUE );
01099         if( vector_is_unknown( expr->left->value ) ) {
01100           unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unknown value used for concatenation multiplier, file: %s, line: %d", funit->filename, expr->line );
01101           assert( rv < USER_MSG_LENGTH );
01102           print_output( user_msg, FATAL, __FILE__, __LINE__ );
01103           Throw 0;
01104         }
01105         if( (expr->value->width != (vector_to_int( expr->left->value ) * expr->right->value->width)) ||
01106             (expr->value->value.ul == NULL) ) {
01107           assert( expr->value->value.ul == NULL );
01108           expression_create_value( expr, (vector_to_int( expr->left->value ) * expr->right->value->width), alloc );
01109         }
01110         break;
01111 
01112       /* 
01113        In the case of a MULTIPLY or LIST (for concatenation) operation, its expression width must be the sum of its
01114        children's width.  Remove the current vector and replace it with the appropriately
01115        sized vector.
01116       */
01117       case EXP_OP_LIST :
01118         if( (expr->value->width != (expr->left->value->width + expr->right->value->width)) ||
01119             (expr->value->value.ul == NULL) ) {
01120           assert( expr->value->value.ul == NULL );
01121           expression_create_value( expr, (expr->left->value->width + expr->right->value->width), alloc );
01122         }
01123         break;
01124 
01125       /*
01126        A FUNC_CALL expression width is set to the same width as that of the function's return value.
01127       */
01128       case EXP_OP_FUNC_CALL :
01129         if( expr->sig != NULL ) {
01130           assert( funit != NULL );
01131           if( (funit->type != FUNIT_AFUNCTION) && (funit->type != FUNIT_ANAMED_BLOCK) ) {
01132             assert( expr->elem.funit != NULL );
01133             tmp_inst = inst_link_find_by_funit( expr->elem.funit, db_list[curr_db]->inst_head, &ignore );
01134             funit_size_elements( expr->elem.funit, tmp_inst, FALSE, FALSE );
01135           }
01136           if( (expr->value->width != expr->sig->value->width) || (expr->value->value.ul == NULL) ) {
01137             assert( expr->value->value.ul == NULL );
01138             expression_create_value( expr, expr->sig->value->width, alloc );
01139           }
01140         }
01141         break;
01142 
01143       default :
01144         /*
01145          If this expression is either the root, an LHS expression or a lower-level RHS expression,
01146          get its size from the largest of its children.
01147         */
01148         if( (ESUPPL_IS_ROOT( expr->suppl ) == 1) ||
01149             (ESUPPL_IS_LHS( expr->suppl ) == 1) ||
01150             ((expr->parent->expr->op != EXP_OP_ASSIGN) &&
01151              (expr->parent->expr->op != EXP_OP_DASSIGN) &&
01152              (expr->parent->expr->op != EXP_OP_BASSIGN) &&
01153              (expr->parent->expr->op != EXP_OP_NASSIGN) &&
01154              (expr->parent->expr->op != EXP_OP_RASSIGN) &&
01155              (expr->parent->expr->op != EXP_OP_DLY_OP)) ) {
01156           if( (expr->left != NULL) && ((expr->right == NULL) || (expr->left->value->width > expr->right->value->width)) ) {
01157             largest_width = expr->left->value->width;
01158           } else if( expr->right != NULL ) {
01159             largest_width = expr->right->value->width;
01160           } else {
01161             largest_width = 1;
01162           }
01163           if( (expr->value->width != largest_width) || (expr->value->value.ul == NULL) ) {
01164             assert( expr->value->value.ul == NULL );
01165             expression_create_value( expr, largest_width, alloc );
01166           }
01167 
01168         /* If our parent is a DLY_OP, we need to get our value from the LHS of the DLY_ASSIGN expression */
01169         } else if( expr->parent->expr->op == EXP_OP_DLY_OP ) {
01170           if( (expr->parent->expr->parent->expr->left->value->width != expr->value->width) || (expr->value->value.ul == NULL) ) {
01171             assert( expr->value->value.ul == NULL );
01172             expression_create_value( expr, expr->parent->expr->parent->expr->left->value->width, alloc );
01173           }
01174 
01175         /* Otherwise, get our value from the size of the expression on the left-hand-side of the assignment */
01176         } else {
01177           if( (expr->parent->expr->left->value->width != expr->value->width) || (expr->value->value.ul == NULL) ) {
01178             assert( expr->value->value.ul == NULL );
01179             expression_create_value( expr, expr->parent->expr->left->value->width, alloc );
01180           }
01181         }
01182         break;
01183 
01184     }
01185 
01186     /* Reapply original supplemental field (preserving the owns_data bit) now that expression has been resized */
01187     new_owns_data                     = expr->value->suppl.part.owns_data;
01188     new_data_type                     = expr->value->suppl.part.data_type;
01189     expr->value->suppl.all            = old_vec_suppl;
01190     expr->value->suppl.part.owns_data = new_owns_data;
01191     expr->value->suppl.part.data_type = new_data_type;
01192 
01193   }
01194 
01195   PROFILE_END;
01196 
01197 }

void expression_set_assigned ( expression expr  ) 

Sets the expression signal supplemental field assigned bit if the given expression is an RHS of an assignment.

Checks to see if the expression is in the LHS of a BASSIGN expression tree. If it is, it sets the assigned supplemental field of the expression's signal vector to indicate the the value of this signal will come from Covered instead of the dumpfile. This is called in the bind_signal function after the expression and signal have been bound (only in parsing stage).

Parameters:
expr Pointer to current expression to evaluate

References ssuppl_u::assigned, ESUPPL_IS_LHS, ESUPPL_IS_ROOT, EXP_OP_BASSIGN, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_RASSIGN, EXP_OP_SBIT_SEL, expr_stmt_u::expr, expression_s::op, expression_s::parent, ssuppl_u::part, PROFILE, PROFILE_END, expression_s::sig, vsignal_s::suppl, and expression_s::suppl.

Referenced by bind_signal().

05838   { PROFILE(EXPRESSION_SET_ASSIGNED);
05839 
05840   expression* curr;  /* Pointer to current expression */
05841 
05842   assert( expr != NULL );
05843 
05844   if( ESUPPL_IS_LHS( expr->suppl ) == 1 ) {
05845 
05846     curr = expr;
05847     while( (ESUPPL_IS_ROOT( curr->suppl ) == 0)        &&
05848            (curr->op != EXP_OP_BASSIGN)                &&
05849            (curr->op != EXP_OP_RASSIGN)                &&
05850            (curr->parent->expr->op != EXP_OP_SBIT_SEL) &&
05851            (curr->parent->expr->op != EXP_OP_MBIT_SEL) &&
05852            (curr->parent->expr->op != EXP_OP_MBIT_POS) &&
05853            (curr->parent->expr->op != EXP_OP_MBIT_NEG) ) {
05854       curr = curr->parent->expr;
05855     }
05856 
05857     /*
05858      If we are on the LHS of a BASSIGN operator, set the assigned bit to indicate that
05859      this signal will be assigned by Covered and not the dumpfile.
05860     */
05861     if( (curr->op == EXP_OP_BASSIGN) || (curr->op == EXP_OP_RASSIGN) ) {
05862       expr->sig->suppl.part.assigned = 1;
05863     }
05864 
05865   }
05866 
05867   PROFILE_END;
05868 
05869 }

void expression_set_changed ( expression expr  ) 

Sets the left/right changed expression bits for each expression in the tree.

Recursively iterates down expression tree, setting the left/right changed bits in each expression. This is necessary to get continuous assignments and FSM statements to simulate (even if their driving signals have not changed).

Parameters:
expr Pointer to expression to set changed bits for

References expression_set_changed(), expression_s::left, esuppl_u::left_changed, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, esuppl_u::right_changed, and expression_s::suppl.

Referenced by expression_set_changed().

05878   { PROFILE(EXPRESSION_SET_CHANGED);
05879 
05880   if( expr != NULL ) {
05881 
05882     /* Set the children expressions */
05883     expression_set_changed( expr->left );
05884     expression_set_changed( expr->right );
05885 
05886     /* Now set our bits */
05887     expr->suppl.part.left_changed  = 1;
05888     expr->suppl.part.right_changed = 1;
05889 
05890   }
05891 
05892   PROFILE_END;
05893 
05894 }

void expression_set_signed ( expression exp  ) 

Sets the signed bit for all appropriate parent expressions.

Recursively sets the signed bit for all parent expressions if both the left and right expressions have the signed bit set. This function is called by the bind() function after an expression has been set to a signal.

Parameters:
exp Pointer to current expression

References ESUPPL_IS_ROOT, EXP_OP_ADD, EXP_OP_DIVIDE, EXP_OP_EQ, EXP_OP_GE, EXP_OP_GT, EXP_OP_LE, EXP_OP_LT, EXP_OP_MBIT_SEL, EXP_OP_MOD, EXP_OP_MULTIPLY, EXP_OP_NE, EXP_OP_PARAM_MBIT, EXP_OP_PARAM_SBIT, EXP_OP_SBIT_SEL, EXP_OP_STATIC, EXP_OP_SUBTRACT, expr_stmt_u::expr, expression_set_signed(), vsuppl_u::is_signed, expression_s::left, expression_s::op, expression_s::parent, vsuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::sig, expression_s::suppl, vector_s::suppl, expression_s::value, and vsignal_s::value.

Referenced by bind_signal(), and expression_set_signed().

00924   { PROFILE(EXPRESSION_SET_SIGNED);
00925 
00926   if( exp != NULL ) {
00927 
00928     /*
00929      If this expression is attached to a signal that has the signed bit set (which is not a bit select) or
00930      the valid left and right expressions have the signed bit set, set our is_signed bit
00931      and continue traversing up expression tree.
00932     */
00933     if( ((exp->sig != NULL) && (exp->sig->value->suppl.part.is_signed == 1) &&
00934          (exp->op != EXP_OP_SBIT_SEL)   &&
00935          (exp->op != EXP_OP_MBIT_SEL)   &&
00936          (exp->op != EXP_OP_PARAM_SBIT) &&
00937          (exp->op != EXP_OP_PARAM_MBIT)) ||
00938         ((((exp->left  != NULL) && (exp->left->value->suppl.part.is_signed  == 1)) || (exp->left  == NULL)) &&
00939          (((exp->right != NULL) && (exp->right->value->suppl.part.is_signed == 1)) || (exp->right == NULL)) &&
00940          ((exp->op == EXP_OP_ADD)      ||
00941           (exp->op == EXP_OP_SUBTRACT) ||
00942           (exp->op == EXP_OP_MULTIPLY) ||
00943           (exp->op == EXP_OP_DIVIDE)   ||
00944           (exp->op == EXP_OP_MOD)      ||
00945           (exp->op == EXP_OP_STATIC)   ||
00946           (exp->op == EXP_OP_LT)       ||
00947           (exp->op == EXP_OP_GT)       ||
00948           (exp->op == EXP_OP_LE)       ||
00949           (exp->op == EXP_OP_GE)       ||
00950           (exp->op == EXP_OP_EQ)       ||
00951           (exp->op == EXP_OP_NE))) ||
00952         (exp->value->suppl.part.is_signed == 1) ) {
00953 
00954       exp->value->suppl.part.is_signed = 1;
00955 
00956       /* If we are not the root expression, traverse up */
00957       if( ESUPPL_IS_ROOT( exp->suppl ) == 0 ) {
00958         expression_set_signed( exp->parent->expr );
00959       }
00960 
00961     }
00962     
00963   }
00964 
00965   PROFILE_END;
00966 
00967 }

void expression_set_value ( expression exp,
vsignal sig,
func_unit funit 
)

Sets the specified expression value to the specified vector value.

Exceptions:
anonymous expression_operate_recursively expression_operate_recursively expression_operate_recursively

Sets the specified expression (if necessary) to the value of the specified signal's vector value.

Parameters:
exp Pointer to expression to set value to
sig Pointer to signal containing vector value to set expression to
funit Pointer to functional unit containing expression

References exp_dim_s::curr_lsb, vsuppl_u::data_type, vsignal_s::dim, dim_and_nba_s::dim, expression_s::dim, exp_dim_s::dim_be, exp_dim_s::dim_lsb, expression_s::dim_nba, exp_dim_s::dim_width, expression_s::elem, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_PARAM, EXP_OP_PARAM_MBIT, EXP_OP_PARAM_MBIT_NEG, EXP_OP_PARAM_MBIT_POS, EXP_OP_PARAM_SBIT, EXP_OP_SBIT_SEL, EXP_OP_SIG, EXP_OP_TRIGGER, expression_create_value(), expression_get_curr_dimension(), expression_is_last_select(), expression_operate_recursively(), FALSE, exp_dim_s::last, expression_s::left, dim_range_s::lsb, malloc_safe, dim_range_s::msb, esuppl_u::nba, expression_s::op, vsuppl_u::owns_data, esuppl_u::part, vsuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, vector_s::suppl, TRUE, vector_s::ul, vector_s::value, vsignal_s::value, expression_s::value, vector_dealloc_value(), vector_to_int(), vsignal_calc_width_for_expr(), and vector_s::width.

Referenced by bind_signal(), expression_resize(), funit_size_elements(), inst_parm_add(), param_find_and_set_expr_value(), and vsignal_create_vec().

00830   { PROFILE(EXPRESSION_SET_VALUE);
00831   
00832   assert( exp != NULL );
00833   assert( exp->value != NULL );
00834   assert( sig != NULL );
00835   assert( sig->value != NULL );
00836 
00837   /* Set our vector type to match the signal type */
00838   exp->value->suppl.part.data_type = sig->value->suppl.part.data_type;
00839 
00840   /* If we are a SIG, PARAM or TRIGGER type, set our value to the signal's value */
00841   if( (exp->op == EXP_OP_SIG) || (exp->op == EXP_OP_PARAM) || (exp->op == EXP_OP_TRIGGER) ) {
00842 
00843     exp->value->suppl                = sig->value->suppl;
00844     exp->value->width                = sig->value->width;
00845     exp->value->value.ul             = sig->value->value.ul;
00846     exp->value->suppl.part.owns_data = 0;
00847 
00848   /* Otherwise, create our own vector to store the part select */
00849   } else {
00850 
00851     unsigned int edim      = expression_get_curr_dimension( exp );
00852     int          exp_width = vsignal_calc_width_for_expr( exp, sig );
00853     exp_dim*     dim;
00854 
00855     /* Allocate dimensional structure (if needed) and populate it with static information */
00856     if( exp->elem.dim == NULL ) {
00857       exp->elem.dim = dim = (exp_dim*)malloc_safe( sizeof( exp_dim ) );
00858     } else if( exp->suppl.part.nba == 1 ) {
00859       dim = exp->elem.dim_nba->dim;
00860     } else {
00861       dim = exp->elem.dim;
00862     }
00863       
00864     dim->curr_lsb = -1;
00865     if( sig->dim[edim].lsb < sig->dim[edim].msb ) {
00866       dim->dim_lsb = sig->dim[edim].lsb;
00867       dim->dim_be  = FALSE;
00868     } else {
00869       dim->dim_lsb = sig->dim[edim].msb;
00870       dim->dim_be  = TRUE;
00871     }
00872     dim->dim_width = exp_width;
00873     dim->last      = expression_is_last_select( exp );
00874 
00875     /* Set the expression width */
00876     switch( exp->op ) {
00877       case EXP_OP_SBIT_SEL   :
00878       case EXP_OP_PARAM_SBIT :
00879         break;
00880       case EXP_OP_MBIT_SEL   :
00881       case EXP_OP_PARAM_MBIT :
00882         {
00883           int lbit, rbit;
00884           expression_operate_recursively( exp->left,  funit, TRUE );
00885           expression_operate_recursively( exp->right, funit, TRUE );
00886           lbit = vector_to_int( exp->left->value  );
00887           rbit = vector_to_int( exp->right->value );
00888           if( lbit <= rbit ) {
00889             exp_width = ((rbit - lbit) + 1) * exp_width;
00890           } else {
00891             exp_width = ((lbit - rbit) + 1) * exp_width;
00892           }
00893         }
00894         break;
00895       case EXP_OP_MBIT_POS :
00896       case EXP_OP_MBIT_NEG :
00897       case EXP_OP_PARAM_MBIT_POS :
00898       case EXP_OP_PARAM_MBIT_NEG :
00899         expression_operate_recursively( exp->right, funit, TRUE );
00900         exp_width = vector_to_int( exp->right->value ) * exp_width;
00901         break;
00902       default :  break;
00903     }
00904 
00905     /* Allocate a vector for this expression */
00906     if( exp->value->value.ul != NULL ) {
00907       vector_dealloc_value( exp->value );
00908     }
00909     expression_create_value( exp, exp_width, TRUE );
00910 
00911   }
00912 
00913   PROFILE_END;
00914 
00915 }

char* expression_string ( expression exp  ) 

Returns user-readable version of the supplied expression.

Returns a pointer to user_msg that will contain a user-friendly string version of the given expression

Parameters:
exp Pointer to expression to display

References expression_string_op(), expression_s::id, expression_s::line, expression_s::op, PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.

Referenced by gen_item_stringify(), and statement_queue_display().

01860   { PROFILE(EXPRESSION_STRING);
01861 
01862   unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "%d (%s line %d)", exp->id, expression_string_op( exp->op ), exp->line );
01863   assert( rv < USER_MSG_LENGTH );
01864 
01865   PROFILE_END;
01866 
01867   return( user_msg );
01868 
01869 }

const char* expression_string_op ( int  op  ) 

Returns user-readable name of specified expression operation.

Returns:
Returns a non-writable string that contains the user-readable name of the specified expression operation.
Parameters:
op Expression operation to get string representation of

References EXP_OP_NUM, PROFILE, and PROFILE_END.

Referenced by bind_display_list(), db_add_expression(), db_create_expression(), db_parallelize_statement(), db_remove_statement_from_current_funit(), exp_link_display(), expression_assign(), expression_display(), expression_operate(), expression_string(), perf_output_mod_stats(), sim_display_thread(), and sim_expr_changed().

01844   { PROFILE(EXPRESSION_STRING_OP);
01845 
01846   assert( (op >= 0) && (op < EXP_OP_NUM) );
01847 
01848   PROFILE_END;
01849 
01850   return( exp_op_info[op].name );
01851 
01852 }

Generated on Sun Nov 21 00:55:38 2010 for Covered by  doxygen 1.6.3