#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. | |
| 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. | |
| 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. | |
| 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. | |
| expression * | expression_get_first_line_expr (expression *expr) |
| Returns first line in this expression tree. | |
| expression * | expression_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. | |
| expression * | expression_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. | |
| statement * | expression_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. | |
|
||||||||||||
|
Assigns each expression in the given tree a unique identifier.
01481 { PROFILE(EXPRESSION_ASSIGN_EXPR_IDS);
01482
01483 if( root != NULL ) {
01484
01485 /* Traverse children first */
01486 expression_assign_expr_ids( root->left, funit );
01487 expression_assign_expr_ids( root->right, funit );
01488
01489 /* Assign our expression a unique ID value */
01490 root->ulid = curr_expr_id;
01491 curr_expr_id++;
01492
01493 /* Resize ourselves */
01494 expression_resize( root, funit, FALSE, FALSE );
01495
01496 }
01497
01498 PROFILE_END;
01499
01500 }
|
|
||||||||||||
|
Searches for an expression that calls the given statement.
01432 { PROFILE(EXPRESSION_CONTAINS_EXPR_CALLING_STMT);
01433
01434 bool retval = (expr != NULL) &&
01435 (((ESUPPL_TYPE( expr->suppl ) == ETYPE_FUNIT) && (expr->elem.funit->first_stmt == stmt)) ||
01436 expression_contains_expr_calling_stmt( expr->left, stmt ) ||
01437 expression_contains_expr_calling_stmt( expr->right, stmt ));
01438
01439 PROFILE_END;
01440
01441 return( retval );
01442
01443 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
Creates new expression.
00634 { PROFILE(EXPRESSION_CREATE);
00635
00636 expression* new_expr; /* Pointer to newly created expression */
00637 int rwidth = 0; /* Bit width of expression on right */
00638 int lwidth = 0; /* Bit width of expression on left */
00639
00640 new_expr = (expression*)malloc_safe( sizeof( expression ) );
00641
00642 new_expr->suppl.all = 0;
00643 new_expr->suppl.part.lhs = (uint8)lhs & 0x1;
00644 new_expr->suppl.part.gen_expr = (generate_expr_mode > 0) ? 1 : 0;
00645 new_expr->suppl.part.root = 1;
00646 new_expr->op = op;
00647 new_expr->id = id;
00648 new_expr->ulid = -1;
00649 new_expr->line = line;
00650 new_expr->col = ((first & 0xffff) << 16) | (last & 0xffff);
00651 new_expr->exec_num = 0;
00652 new_expr->sig = NULL;
00653 new_expr->parent = (expr_stmt*)malloc_safe( sizeof( expr_stmt ) );
00654 new_expr->parent->expr = NULL;
00655 new_expr->right = right;
00656 new_expr->left = left;
00657 new_expr->value = (vector*)malloc_safe( sizeof( vector ) );
00658 new_expr->suppl.part.owns_vec = 1;
00659 new_expr->value->value.ul = NULL;
00660 new_expr->value->suppl.all = 0;
00661 new_expr->table = NULL;
00662 new_expr->elem.funit = NULL;
00663 new_expr->name = NULL;
00664
00665 if( EXPR_OP_HAS_DIM( op ) ) {
00666 new_expr->elem.dim = (exp_dim*)malloc_safe( sizeof( exp_dim ) );
00667 new_expr->elem.dim->curr_lsb = -1;
00668 }
00669
00670 if( right != NULL ) {
00671
00672 /* Get information from right */
00673 assert( right->value != NULL );
00674 rwidth = right->value->width;
00675
00676 /* Set right expression parent to this expression */
00677 assert( right->parent->expr == NULL );
00678 right->parent->expr = new_expr;
00679
00680 /* Reset root bit of right expression */
00681 right->suppl.part.root = 0;
00682
00683 }
00684
00685 if( left != NULL ) {
00686
00687 /* Get information from left */
00688 assert( left->value != NULL );
00689 lwidth = left->value->width;
00690
00691 /* Set left expression parent to this expression (if this is not a case expression) */
00692 if( (op != EXP_OP_CASE) && (op != EXP_OP_CASEX) && (op != EXP_OP_CASEZ) ) {
00693 assert( left->parent->expr == NULL );
00694 left->parent->expr = new_expr;
00695 left->suppl.part.root = 0;
00696 }
00697
00698 }
00699
00700 Try {
00701
00702 /* Create value vector */
00703 if( ((op == EXP_OP_MULTIPLY) || (op == EXP_OP_LIST)) && (rwidth > 0) && (lwidth > 0) ) {
00704
00705 /* For multiplication, we need a width the sum of the left and right expressions */
00706 expression_create_value( new_expr, (lwidth + rwidth), data );
00707
00708 } else if( (op == EXP_OP_CONCAT) && (rwidth > 0) ) {
00709
00710 expression_create_value( new_expr, rwidth, data );
00711
00712 } else if( (op == EXP_OP_EXPAND) && (rwidth > 0) && (lwidth > 0) && (left->value->value.ul != NULL) ) {
00713
00714 /*
00715 If the left-hand expression is a known value, go ahead and create the value here; otherwise,
00716 hold off because our vector value will be coming.
00717 */
00718 if( !vector_is_unknown( left->value ) ) {
00719 expression_create_value( new_expr, (vector_to_int( left->value ) * rwidth), data );
00720 } else {
00721 expression_create_value( new_expr, 1, data );
00722 }
00723
00724 /* $time, $realtobits, $bitstoreal, $itor and $rtoi expressions are always 64-bits wide */
00725 } else if( (op == EXP_OP_STIME) || (op == EXP_OP_SR2B) || (op == EXP_OP_SB2R) || (op == EXP_OP_SI2R) || (op == EXP_OP_SR2I) ) {
00726
00727 expression_create_value( new_expr, 64, data );
00728
00729 /* $random, $urandom, $urandom_range, $shortrealtobits and $bitstoshortreal expressions are always 32-bits wide */
00730 } else if( (op == EXP_OP_SRANDOM) || (op == EXP_OP_SURANDOM) || (op == EXP_OP_SURAND_RANGE) || (op == EXP_OP_SSR2B) || (op == EXP_OP_SB2SR) ) {
00731
00732 expression_create_value( new_expr, 32, data );
00733
00734 } else if( (op == EXP_OP_LT) ||
00735 (op == EXP_OP_GT) ||
00736 (op == EXP_OP_EQ) ||
00737 (op == EXP_OP_CEQ) ||
00738 (op == EXP_OP_LE) ||
00739 (op == EXP_OP_GE) ||
00740 (op == EXP_OP_NE) ||
00741 (op == EXP_OP_CNE) ||
00742 (op == EXP_OP_LOR) ||
00743 (op == EXP_OP_LAND) ||
00744 (op == EXP_OP_UAND) ||
00745 (op == EXP_OP_UNOT) ||
00746 (op == EXP_OP_UOR) ||
00747 (op == EXP_OP_UXOR) ||
00748 (op == EXP_OP_UNAND) ||
00749 (op == EXP_OP_UNOR) ||
00750 (op == EXP_OP_UNXOR) ||
00751 (op == EXP_OP_EOR) ||
00752 (op == EXP_OP_NEDGE) ||
00753 (op == EXP_OP_PEDGE) ||
00754 (op == EXP_OP_AEDGE) ||
00755 (op == EXP_OP_CASE) ||
00756 (op == EXP_OP_CASEX) ||
00757 (op == EXP_OP_CASEZ) ||
00758 (op == EXP_OP_DEFAULT) ||
00759 (op == EXP_OP_REPEAT) ||
00760 (op == EXP_OP_RPT_DLY) ||
00761 (op == EXP_OP_WAIT) ||
00762 (op == EXP_OP_SFINISH) ||
00763 (op == EXP_OP_SSTOP) ||
00764 (op == EXP_OP_SSRANDOM) ||
00765 (op == EXP_OP_STESTARGS) ||
00766 (op == EXP_OP_SVALARGS) ) {
00767
00768 /* If this expression will evaluate to a single bit, create vector now */
00769 expression_create_value( new_expr, 1, data );
00770
00771 } else {
00772
00773 /* If both right and left values have their width values set. */
00774 if( (rwidth > 0) && (lwidth > 0) &&
00775 (op != EXP_OP_MBIT_SEL) &&
00776 (op != EXP_OP_MBIT_POS) &&
00777 (op != EXP_OP_MBIT_NEG) &&
00778 (op != EXP_OP_PARAM_MBIT) &&
00779 (op != EXP_OP_PARAM_MBIT_POS) &&
00780 (op != EXP_OP_PARAM_MBIT_NEG) ) {
00781
00782 if( rwidth >= lwidth ) {
00783 /* Check to make sure that nothing has gone drastically wrong */
00784 expression_create_value( new_expr, rwidth, data );
00785 } else {
00786 /* Check to make sure that nothing has gone drastically wrong */
00787 expression_create_value( new_expr, lwidth, data );
00788 }
00789
00790 } else {
00791
00792 expression_create_value( new_expr, 0, FALSE );
00793
00794 }
00795
00796 }
00797
00798 } Catch_anonymous {
00799 expression_dealloc( new_expr, TRUE );
00800 Throw 0;
00801 }
00802
00803 /*
00804 if( (data == FALSE) && (generate_expr_mode == 0) ) {
00805 assert( new_expr->value->value.ul == NULL );
00806 }
00807 */
00808
00809 PROFILE_END;
00810
00811 return( new_expr );
00812
00813 }
|
|
||||||||||||||||
|
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.
00492 { PROFILE(EXPRESSION_CREATE_NBA);
00493
00494 exp_dim* dim = expr->elem.dim;
00495
00496 /* Allocate memory */
00497 nonblock_assign* nba = (nonblock_assign*)malloc_safe( sizeof( nonblock_assign ) );
00498
00499 /* Initialize the structure */
00500 nba->lhs_sig = lhs_sig;
00501 nba->rhs_vec = rhs_vec;
00502 nba->suppl.is_signed = (expr->op == EXP_OP_SIG) ? rhs_vec->suppl.part.is_signed : FALSE;
00503 nba->suppl.added = 0;
00504
00505 /* Now change the elem pointer from a dim to a dim_nba */
00506 expr->elem.dim_nba = (dim_and_nba*)malloc_safe( sizeof( dim_and_nba ) );
00507 expr->elem.dim_nba->dim = dim;
00508 expr->elem.dim_nba->nba = nba;
00509
00510 /* Set the nba supplemental bit */
00511 expr->suppl.part.nba = 1;
00512
00513 /* Increment the number of nba structures */
00514 nba_queue_size++;
00515
00516 PROFILE_END;
00517
00518 }
|
|
||||||||||||||||
|
Reads and merges two expressions and stores result in base expression.
01739 { PROFILE(EXPRESSION_DB_MERGE);
01740
01741 int id; /* Expression ID field */
01742 int linenum; /* Expression line number */
01743 unsigned int column; /* Column information */
01744 uint32 exec_num; /* Execution number */
01745 uint32 op; /* Expression operation */
01746 esuppl suppl; /* Supplemental field */
01747 int right_id; /* ID of right child */
01748 int left_id; /* ID of left child */
01749 int chars_read; /* Number of characters read */
01750
01751 assert( base != NULL );
01752
01753 if( sscanf( *line, "%d %d %x %x %x %x %d %d%n", &id, &linenum, &column, &exec_num, &op, &(suppl.all), &right_id, &left_id, &chars_read ) == 8 ) {
01754
01755 *line = *line + chars_read;
01756
01757 if( (base->op != op) || (base->line != linenum) || (base->col != column) ) {
01758
01759 print_output( "Attempting to merge databases derived from different designs. Unable to merge",
01760 FATAL, __FILE__, __LINE__ );
01761 Throw 0;
01762
01763 } else {
01764
01765 /* Merge expression supplemental fields */
01766 base->suppl.all = (base->suppl.all & ESUPPL_MERGE_MASK) | (suppl.all & ESUPPL_MERGE_MASK);
01767
01768 /* Merge execution number information */
01769 if( base->exec_num < exec_num ) {
01770 base->exec_num = exec_num;
01771 }
01772
01773 if( ESUPPL_OWNS_VEC( suppl ) ) {
01774
01775 /* Merge expression vectors */
01776 vector_db_merge( base->value, line, same );
01777
01778 }
01779
01780 }
01781
01782 } else {
01783
01784 print_output( "Unable to parse expression line in database. Unable to merge.", FATAL, __FILE__, __LINE__ );
01785 Throw 0;
01786
01787 }
01788
01789 PROFILE_END;
01790
01791 }
|
|
||||||||||||||||
|
Reads current line of specified file and parses for expression information.
01586 { PROFILE(EXPRESSION_DB_READ);
01587
01588 expression* expr; /* Pointer to newly created expression */
01589 int linenum; /* Holder of current line for this expression */
01590 unsigned int column; /* Holder of column alignment information */
01591 uint32 exec_num; /* Holder of expression's execution number */
01592 uint32 op; /* Holder of expression operation */
01593 esuppl suppl; /* Holder of supplemental value of this expression */
01594 int right_id; /* Holder of expression ID to the right */
01595 int left_id; /* Holder of expression ID to the left */
01596 expression* right; /* Pointer to current expression's right expression */
01597 expression* left; /* Pointer to current expression's left expression */
01598 int chars_read; /* Number of characters scanned in from line */
01599 vector* vec; /* Holders vector value of this expression */
01600 exp_link* expl; /* Pointer to found expression in functional unit */
01601
01602 if( sscanf( *line, "%d %d %x %x %x %x %d %d%n", &curr_expr_id, &linenum, &column, &exec_num, &op, &(suppl.all), &right_id, &left_id, &chars_read ) == 8 ) {
01603
01604 *line = *line + chars_read;
01605
01606 /* Find functional unit instance name */
01607 if( curr_funit == NULL ) {
01608
01609 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Internal error: expression (%d) in database written before its functional unit", curr_expr_id );
01610 assert( rv < USER_MSG_LENGTH );
01611 print_output( user_msg, FATAL, __FILE__, __LINE__ );
01612 Throw 0;
01613
01614 } else {
01615
01616 /* Find right expression */
01617 if( right_id == 0 ) {
01618 right = NULL;
01619 } else if( (expl = exp_link_find( right_id, curr_funit->exp_head )) == NULL ) {
01620 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 );
01621 assert( rv < USER_MSG_LENGTH );
01622 print_output( user_msg, FATAL, __FILE__, __LINE__ );
01623 Throw 0;
01624 } else {
01625 right = expl->exp;
01626 }
01627
01628 /* Find left expression */
01629 if( left_id == 0 ) {
01630 left = NULL;
01631 } else if( (expl = exp_link_find( left_id, curr_funit->exp_head )) == NULL ) {
01632 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 );
01633 assert( rv < USER_MSG_LENGTH );
01634 print_output( user_msg, FATAL, __FILE__, __LINE__ );
01635 Throw 0;
01636 } else {
01637 left = expl->exp;
01638 }
01639
01640 /* Create new expression */
01641 expr = expression_create( right, left, op, ESUPPL_IS_LHS( suppl ), curr_expr_id, linenum,
01642 ((column >> 16) & 0xffff), (column & 0xffff), ESUPPL_OWNS_VEC( suppl ) );
01643
01644 expr->suppl.all = suppl.all;
01645 expr->exec_num = exec_num;
01646
01647 if( op == EXP_OP_DELAY ) {
01648 expr->suppl.part.type = ETYPE_DELAY;
01649 expr->elem.scale = &(curr_funit->timescale);
01650 }
01651
01652 if( ESUPPL_OWNS_VEC( suppl ) ) {
01653
01654 Try {
01655
01656 /* Read in vector information */
01657 vector_db_read( &vec, line );
01658
01659 } Catch_anonymous {
01660 expression_dealloc( expr, TRUE );
01661 Throw 0;
01662 }
01663
01664 /* Copy expression value */
01665 vector_dealloc( expr->value );
01666 expr->value = vec;
01667
01668 }
01669
01670 /* Create temporary vectors if necessary */
01671 expression_create_tmp_vecs( expr, expr->value->width );
01672
01673 /* Check to see if we are bound to a signal or functional unit */
01674 if( ((*line)[0] != '\n') && ((*line)[0] != '\0') ) {
01675 (*line)++; /* Remove space */
01676 switch( op ) {
01677 case EXP_OP_FUNC_CALL : bind_add( FUNIT_FUNCTION, *line, expr, curr_funit ); break;
01678 case EXP_OP_TASK_CALL : bind_add( FUNIT_TASK, *line, expr, curr_funit ); break;
01679 case EXP_OP_FORK :
01680 case EXP_OP_NB_CALL : bind_add( FUNIT_NAMED_BLOCK, *line, expr, curr_funit ); break;
01681 case EXP_OP_DISABLE : bind_add( 1, *line, expr, curr_funit ); break;
01682 default : bind_add( 0, *line, expr, curr_funit ); break;
01683 }
01684 }
01685
01686 /* If we are an assignment operator, set our vector value to that of the right child */
01687 if( (op == EXP_OP_ASSIGN) ||
01688 (op == EXP_OP_DASSIGN) ||
01689 (op == EXP_OP_BASSIGN) ||
01690 (op == EXP_OP_RASSIGN) ||
01691 (op == EXP_OP_NASSIGN) ||
01692 (op == EXP_OP_DLY_ASSIGN) ||
01693 (op == EXP_OP_IF) ||
01694 (op == EXP_OP_WHILE) ||
01695 (op == EXP_OP_DIM) ) {
01696
01697 vector_dealloc( expr->value );
01698 expr->value = right->value;
01699
01700 }
01701
01702 exp_link_add( expr, &(curr_funit->exp_head), &(curr_funit->exp_tail) );
01703
01704 /*
01705 If this expression is a constant expression, force the simulator to evaluate
01706 this expression and all parent expressions of it.
01707 */
01708 if( eval && EXPR_IS_STATIC( expr ) && (ESUPPL_IS_LHS( suppl ) == 0) ) {
01709 exp_link_add( expr, &static_expr_head, &static_expr_tail );
01710 }
01711
01712 }
01713
01714 } else {
01715
01716 print_output( "Unable to read expression value", FATAL, __FILE__, __LINE__ );
01717 Throw 0;
01718
01719 }
01720
01721 PROFILE_END;
01722
01723 }
|
|
||||||||||||||||||||
|
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.
01512 { PROFILE(EXPRESSION_DB_WRITE);
01513
01514 assert( expr != NULL );
01515
01516 fprintf( file, "%d %d %d %x %x %x %x %d %d",
01517 DB_TYPE_EXPRESSION,
01518 expression_get_id( expr, ids_issued ),
01519 expr->line,
01520 expr->col,
01521 ((((expr->op == EXP_OP_DASSIGN) || (expr->op == EXP_OP_ASSIGN)) && (expr->exec_num == 0)) ? (uint32)1 : expr->exec_num),
01522 expr->op,
01523 (expr->suppl.all & ESUPPL_MERGE_MASK),
01524 ((expr->op == EXP_OP_STATIC) ? 0 : expression_get_id( expr->right, ids_issued )),
01525 ((expr->op == EXP_OP_STATIC) ? 0 : expression_get_id( expr->left, ids_issued ))
01526 );
01527
01528 if( ESUPPL_OWNS_VEC( expr->suppl ) ) {
01529 fprintf( file, " " );
01530 if( parse_mode && EXPR_OWNS_VEC( expr->op ) && (expr->value->suppl.part.owns_data == 0) ) {
01531 expr->value->suppl.part.owns_data = 1;
01532 }
01533 vector_db_write( expr->value, file, (expr->op == EXP_OP_STATIC), FALSE );
01534 }
01535
01536 if( expr->name != NULL ) {
01537 fprintf( file, " %s", expr->name );
01538 } else if( expr->sig != NULL ) {
01539 fprintf( file, " %s", expr->sig->name ); /* This will be valid for parameters */
01540 }
01541
01542 fprintf( file, "\n" );
01543
01544 PROFILE_END;
01545
01546 }
|
|
||||||||||||
|
Writes the entire expression tree to the specified data file. Recursively iterates through the specified expression tree, outputting the expressions to the specified file.
01555 { PROFILE(EXPRESSION_DB_WRITE_TREE);
01556
01557 if( root != NULL ) {
01558
01559 /* Print children first */
01560 if( EXPR_LEFT_DEALLOCABLE( root ) ) {
01561 expression_db_write_tree( root->left, ofile );
01562 }
01563 expression_db_write_tree( root->right, ofile );
01564
01565 /* Now write ourselves */
01566 expression_db_write( root, ofile, TRUE, TRUE );
01567
01568 }
01569
01570 PROFILE_END;
01571
01572 }
|
|
||||||||||||
|
Deallocates memory used for expression. Deallocates all heap memory allocated with the malloc routine.
06167 { PROFILE(EXPRESSION_DEALLOC);
06168
06169 int op; /* Temporary operation holder */
06170 exp_link* tmp_expl; /* Temporary pointer to expression list */
06171 statement* tmp_stmt; /* Temporary pointer to statement */
06172
06173 if( expr != NULL ) {
06174
06175 op = expr->op;
06176
06177 if( ESUPPL_OWNS_VEC( expr->suppl ) ) {
06178
06179 /* Free up memory from vector value storage */
06180 vector_dealloc( expr->value );
06181 expr->value = NULL;
06182
06183 /* If this is a named block call or fork call, remove the statement that this expression points to */
06184 if( (expr->op == EXP_OP_NB_CALL) || (expr->op == EXP_OP_FORK) ) {
06185
06186 if( !exp_only && (expr->elem.funit != NULL) ) {
06187 #ifdef DEBUG_MODE
06188 if( debug_mode ) {
06189 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",
06190 expr->elem.funit->first_stmt->exp->line );
06191 assert( rv < USER_MSG_LENGTH );
06192 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
06193 }
06194 #endif
06195 stmt_blk_add_to_remove_list( expr->elem.funit->first_stmt );
06196 } else {
06197 bind_remove( expr->id, FALSE );
06198 }
06199
06200 /* If this is a task call, remove the bind */
06201 } else if( expr->op == EXP_OP_TASK_CALL ) {
06202
06203 bind_remove( expr->id, FALSE );
06204
06205 } else if( expr->op == EXP_OP_FUNC_CALL ) {
06206
06207 /* Remove this expression from the attached signal's expression list (if the signal has not been deallocated yet) */
06208 if( expr->sig != NULL ) {
06209 exp_link_remove( expr, &(expr->sig->exp_head), &(expr->sig->exp_tail), FALSE );
06210 }
06211
06212 bind_remove( expr->id, FALSE );
06213
06214 /* Otherwise, we assume (for now) that the expression is a signal */
06215 } else {
06216
06217 if( expr->sig == NULL ) {
06218
06219 /* Remove this expression from the binding list */
06220 bind_remove( expr->id, expression_is_assigned( expr ) );
06221
06222 } else {
06223
06224 /* Remove this expression from the attached signal's expression list */
06225 exp_link_remove( expr, &(expr->sig->exp_head), &(expr->sig->exp_tail), FALSE );
06226
06227 /* Clear the assigned bit of the attached signal */
06228 if( expression_is_assigned( expr ) ) {
06229
06230 expr->sig->suppl.part.assigned = 0;
06231
06232 /* If this signal must be assigned, remove all statement blocks that reference this signal */
06233 if( (expr->sig->suppl.part.mba == 1) && !exp_only ) {
06234 tmp_expl = expr->sig->exp_head;
06235 while( tmp_expl != NULL ) {
06236 if( (tmp_stmt = expression_get_root_statement( tmp_expl->exp )) != NULL ) {
06237 #ifdef DEBUG_MODE
06238 if( debug_mode ) {
06239 print_output( "Removing statement block because a statement block is being removed that assigns an MBA", DEBUG, __FILE__, __LINE__ );
06240 }
06241 #endif
06242 stmt_blk_add_to_remove_list( tmp_stmt );
06243 }
06244 tmp_expl = tmp_expl->next;
06245 }
06246 }
06247
06248 }
06249
06250 }
06251
06252 }
06253
06254 } else {
06255
06256 /* Remove our expression from its signal, if we have one */
06257 if( expr->sig != NULL ) {
06258 exp_link_remove( expr, &(expr->sig->exp_head), &(expr->sig->exp_tail), FALSE );
06259 }
06260
06261 }
06262
06263 /* Deallocate children */
06264 if( !exp_only ) {
06265
06266 if( EXPR_RIGHT_DEALLOCABLE( expr ) ) {
06267 expression_dealloc( expr->right, FALSE );
06268 expr->right = NULL;
06269 }
06270
06271 if( EXPR_LEFT_DEALLOCABLE( expr ) ) {
06272 expression_dealloc( expr->left, FALSE );
06273 expr->left = NULL;
06274 }
06275
06276 }
06277
06278 /* If we have temporary vectors to deallocate, do so now */
06279 if( (expr->elem.tvecs != NULL) && (EXPR_TMP_VECS( expr->op ) > 0) ) {
06280 unsigned int i;
06281 for( i=0; i<EXPR_TMP_VECS( expr->op ); i++ ) {
06282 vector_dealloc_value( &(expr->elem.tvecs->vec[i]) );
06283 }
06284 free_safe( expr->elem.tvecs, sizeof( vecblk ) );
06285 }
06286
06287 /* If we have expression dimensional information, deallocate it now */
06288 if( (expr->elem.dim != NULL) && EXPR_OP_HAS_DIM( expr->op ) ) {
06289 if( expr->suppl.part.nba == 1 ) {
06290 free_safe( expr->elem.dim_nba->dim, sizeof( exp_dim ) );
06291 free_safe( expr->elem.dim_nba->nba, sizeof( nonblock_assign ) );
06292 free_safe( expr->elem.dim_nba, sizeof( dim_and_nba ) );
06293 } else {
06294 free_safe( expr->elem.dim, sizeof( exp_dim ) );
06295 }
06296 }
06297
06298 /* Free up memory for the parent pointer */
06299 free_safe( expr->parent, sizeof( expr_stmt ) );
06300
06301 /* If name contains data, free it */
06302 free_safe( expr->name, (strlen( expr->name ) + 1) );
06303
06304 /* Remove this expression memory */
06305 free_safe( expr, sizeof( expression ) );
06306
06307 }
06308
06309 PROFILE_END;
06310
06311 }
|
|
|
Displays the specified expression information. Displays contents of the specified expression to standard output. This function is called by the funit_display function.
01862 {
01863
01864 int right_id; /* Value of right expression ID */
01865 int left_id; /* Value of left expression ID */
01866
01867 assert( expr != NULL );
01868
01869 if( expr->left == NULL ) {
01870 left_id = 0;
01871 } else {
01872 left_id = expr->left->id;
01873 }
01874
01875 if( expr->right == NULL ) {
01876 right_id = 0;
01877 } else {
01878 right_id = expr->right->id;
01879 }
01880
01881 printf( " Expression (%p) => id: %d, op: %s, line: %d, col: %x, suppl: %x, exec_num: %u, left: %d, right: %d, ",
01882 expr,
01883 expr->id,
01884 expression_string_op( expr->op ),
01885 expr->line,
01886 expr->col,
01887 expr->suppl.all,
01888 expr->exec_num,
01889 left_id,
01890 right_id );
01891
01892 if( expr->value->value.ul == NULL ) {
01893 printf( "NO DATA VECTOR" );
01894 } else {
01895 switch( expr->value->suppl.part.data_type ) {
01896 case VDATA_UL : vector_display_value_ulong( expr->value->value.ul, expr->value->width ); break;
01897 case VDATA_R64 :
01898 if( expr->value->value.r64->str != NULL ) {
01899 printf( "%s", expr->value->value.r64->str );
01900 } else {
01901 printf( "%.16lf", expr->value->value.r64->val );
01902 }
01903 break;
01904 case VDATA_R32 :
01905 if( expr->value->value.r32->str != NULL ) {
01906 printf( "%s", expr->value->value.r32->str );
01907 } else {
01908 printf( "%.16f", expr->value->value.r32->val );
01909 }
01910 break;
01911 default : assert( 0 ); break;
01912 }
01913 }
01914 printf( "\n" );
01915
01916 }
|
|
||||||||||||
|
Returns TRUE if the specified expression exists within the given root expression tree.
01416 { PROFILE(EXPRESSION_FIND_EXPR);
01417
01418 bool retval = (root != NULL) && ((root == expr) || expression_find_expr( root->left, expr ) || expression_find_expr( root->right, expr ));
01419
01420 PROFILE_END;
01421
01422 return( retval );
01423
01424 }
|
|
||||||||||||||||
|
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.
01304 { PROFILE(EXPRESSION_FIND_RHS_SIGS);
01305
01306 char* sig_name; /* Name of signal found */
01307
01308 /* Only continue if our expression is valid and it is an RHS */
01309 if( (expr != NULL) && (ESUPPL_IS_LHS( expr->suppl ) == 0) ) {
01310
01311 if( (expr->op == EXP_OP_SIG) ||
01312 (expr->op == EXP_OP_TRIGGER) ||
01313 (expr->op == EXP_OP_SBIT_SEL) ||
01314 (expr->op == EXP_OP_MBIT_SEL) ||
01315 (expr->op == EXP_OP_MBIT_POS) ||
01316 (expr->op == EXP_OP_MBIT_NEG) ) {
01317
01318 /* Get the signal name from the binder */
01319 sig_name = bind_find_sig_name( expr );
01320
01321 assert( sig_name != NULL );
01322
01323 /* If the signal isn't already in the list, add it */
01324 if( str_link_find( sig_name, *head ) == NULL ) {
01325 (void)str_link_add( sig_name, head, tail );
01326 } else {
01327 free_safe( sig_name, (strlen( sig_name ) + 1) );
01328 }
01329
01330 }
01331
01332 /* If this expression operation is neither a SIG or TRIGGER, keep searching tree */
01333 if( (expr->op != EXP_OP_SIG) && (expr->op != EXP_OP_TRIGGER) ) {
01334
01335 expression_find_rhs_sigs( expr->right, head, tail );
01336 expression_find_rhs_sigs( expr->left, head, tail );
01337
01338 }
01339
01340 }
01341
01342 PROFILE_END;
01343
01344 }
|
|
||||||||||||
|
Finds the expression in this expression tree with the specified underline id.
01387 { PROFILE(EXPRESSION_FIND_ULINE_ID);
01388
01389 expression* found_exp = NULL; /* Pointer to found expression */
01390
01391 if( expr != NULL ) {
01392
01393 if( expr->ulid == ulid ) {
01394 found_exp = expr;
01395 } else {
01396 if( (found_exp = expression_find_uline_id( expr->left, ulid )) == NULL ) {
01397 found_exp = expression_find_uline_id( expr->right, ulid );
01398 }
01399 }
01400
01401 }
01402
01403 PROFILE_END;
01404
01405 return( found_exp );
01406
01407 }
|
|
|
Returns the current dimension of the given expression.
01267 { PROFILE(EXPRESSION_GET_CURR_DIMENSION);
01268
01269 unsigned int dim; /* Return value for this function */
01270
01271 assert( expr != NULL );
01272
01273 if( expr->op == EXP_OP_DIM ) {
01274
01275 dim = expression_get_curr_dimension( expr->left ) + 1;
01276
01277 } else {
01278
01279 if( (ESUPPL_IS_ROOT( expr->suppl ) == 0) &&
01280 (expr->parent->expr->op == EXP_OP_DIM) &&
01281 (expr->parent->expr->right == expr) ) {
01282 dim = expression_get_curr_dimension( expr->parent->expr );
01283 } else {
01284 dim = 0;
01285 }
01286
01287 }
01288
01289 PROFILE_END;
01290
01291 return( dim );
01292
01293 }
|
|
|
Returns first line in this expression tree.
01216 { PROFILE(EXPRESSION_GET_FIRST_LINE_EXPR);
01217
01218 expression* first = NULL;
01219
01220 if( expr != NULL ) {
01221
01222 first = expression_get_first_line_expr( expr->left );
01223 if( (first == NULL) || (first->line > expr->line) ) {
01224 first = expr;
01225 }
01226
01227 }
01228
01229 PROFILE_END;
01230
01231 return( first );
01232
01233 }
|
|
||||||||||||
|
Returns expression ID of this expression.
01195 { PROFILE(EXPRESSION_GET_ID);
01196
01197 int id;
01198
01199 if( expr == NULL ) {
01200 id = 0;
01201 } else {
01202 id = parse_mode ? expr->ulid : expr->id;
01203 }
01204
01205 PROFILE_END;
01206
01207 return( id );
01208
01209 }
|
|
|
Returns last line in this expression tree.
01240 { PROFILE(EXPRESSION_GET_LAST_LINE_EXPR);
01241
01242 expression* last = NULL;
01243
01244 if( expr != NULL ) {
01245
01246 last = expression_get_last_line_expr( expr->right );
01247 if( (last == NULL) || (last->line < expr->line) ) {
01248 last = expr;
01249 }
01250
01251 }
01252
01253 PROFILE_END;
01254
01255 return( last );
01256
01257 }
|
|
|
Finds the root statement for the given expression.
01455 { PROFILE(EXPRESSION_GET_ROOT_STATEMENT);
01456
01457 statement* stmt; /* Pointer to root statement */
01458
01459 if( exp == NULL ) {
01460 stmt = NULL;
01461 } else if( ESUPPL_IS_ROOT( exp->suppl ) == 1 ) {
01462 stmt = exp->parent->stmt;
01463 } else {
01464 stmt = expression_get_root_statement( exp->parent->expr );
01465 }
01466
01467 PROFILE_END;
01468
01469 return( stmt );
01470
01471 }
|
|
|
Returns TRUE if specified expression is a part of an bit select expression tree.
05771 { PROFILE(EXPRESSION_IS_BIT_SELECT);
05772
05773 bool retval = FALSE; /* Return value for this function */
05774
05775 if( (expr != NULL) && (ESUPPL_IS_ROOT( expr->suppl ) == 0) ) {
05776
05777 if( (expr->parent->expr->op == EXP_OP_SBIT_SEL) ||
05778 (expr->parent->expr->op == EXP_OP_MBIT_SEL) ||
05779 (expr->parent->expr->op == EXP_OP_MBIT_POS) ||
05780 (expr->parent->expr->op == EXP_OP_MBIT_NEG) ) {
05781 retval = TRUE;
05782 } else {
05783 retval = expression_is_bit_select( expr->parent->expr );
05784 }
05785
05786 }
05787
05788 PROFILE_END;
05789
05790 return( retval );
05791
05792 }
|
|
|
Returns TRUE if specified expression is in an RASSIGN expression tree.
05821 { PROFILE(EXPRESSION_IS_IN_RASSIGN);
05822
05823 bool retval = FALSE; /* Return value for this function */
05824
05825 if( expr != NULL ) {
05826
05827 if( expr->op == EXP_OP_RASSIGN ) {
05828 retval = TRUE;
05829 } else if( ESUPPL_IS_ROOT( expr->suppl ) == 0 ) {
05830 retval = expression_is_in_rassign( expr->parent->expr );
05831 }
05832
05833 }
05834
05835 PROFILE_END;
05836
05837 return( retval );
05838
05839 }
|
|
|
Returns TRUE if specified expression is the last select of a signal.
05800 { PROFILE(EXPRESSION_IS_LAST_SELECT);
05801
05802 bool retval = (ESUPPL_IS_ROOT( expr->suppl ) == 1) ||
05803 ( ((expr->parent->expr->op == EXP_OP_DIM) &&
05804 (expr->parent->expr->right == expr) &&
05805 (ESUPPL_IS_ROOT( expr->parent->expr->suppl ) == 0) &&
05806 (expr->parent->expr->parent->expr->op != EXP_OP_DIM)) ||
05807 (expr->parent->expr->op != EXP_OP_DIM) );
05808
05809 PROFILE_END;
05810
05811 return( retval );
05812
05813 }
|
|
|
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.
00526 { PROFILE(EXPRESSION_IS_NBA_LHS);
00527
00528 while( (exp->op != EXP_OP_NASSIGN) &&
00529 (ESUPPL_IS_ROOT( exp->suppl ) == 0) &&
00530 (exp->parent->expr->op != EXP_OP_SBIT_SEL) &&
00531 (exp->parent->expr->op != EXP_OP_MBIT_SEL) &&
00532 (exp->parent->expr->op != EXP_OP_MBIT_POS) &&
00533 (exp->parent->expr->op != EXP_OP_MBIT_NEG) ) {
00534 exp = exp->parent->expr;
00535 }
00536
00537 PROFILE_END;
00538
00539 return( (exp->op == EXP_OP_NASSIGN) ? exp : NULL );
00540
00541 }
|
|
|
Returns TRUE if specified expression is found to contain all static leaf expressions.
05716 {
05717
05718 return( expression_is_static_only_helper( expr, NULL ) );
05719
05720 }
|
|
||||||||||||
|
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.
01800 { PROFILE(EXPRESSION_MERGE);
01801
01802 assert( base != NULL );
01803 assert( base->op == other->op );
01804 assert( base->line == other->line );
01805 assert( base->col == other->col );
01806
01807 /* Merge expression supplemental fields */
01808 base->suppl.all = (base->suppl.all & ESUPPL_MERGE_MASK) | (other->suppl.all & ESUPPL_MERGE_MASK);
01809
01810 /* Merge execution number information */
01811 if( base->exec_num < other->exec_num ) {
01812 base->exec_num = other->exec_num;
01813 }
01814
01815 if( ESUPPL_OWNS_VEC( base->suppl ) ) {
01816 vector_merge( base->value, other->value );
01817 }
01818
01819 PROFILE_END;
01820
01821 }
|
|
||||||||||||||||
|
Performs operation specified by parameter expression.
05565 { PROFILE(EXPRESSION_OPERATE);
05566
05567 bool retval = TRUE; /* Return value for this function */
05568
05569 if( expr != NULL ) {
05570
05571 #ifdef DEBUG_MODE
05572 if( debug_mode ) {
05573 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, " In expression_operate, id: %d, op: %s, line: %d, addr: %p",
05574 expr->id, expression_string_op( expr->op ), expr->line, expr );
05575 assert( rv < USER_MSG_LENGTH );
05576 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
05577 }
05578 #endif
05579
05580 assert( expr->value != NULL );
05581
05582 /* Call expression operation */
05583 retval = exp_op_info[expr->op].func( expr, thr, time );
05584
05585 /* If this expression is attached to an FSM, perform the FSM calculation now */
05586 if( expr->table != NULL ) {
05587 fsm_table_set( expr, time );
05588 }
05589
05590 /* Specify that we have executed this expression */
05591 (expr->exec_num)++;
05592
05593 }
05594
05595 PROFILE_END;
05596
05597 return( retval );
05598
05599 }
|
|
||||||||||||||||
|
Performs recursive expression operation (parse mode only).
05613 { PROFILE(EXPRESSION_OPERATE_RECURSIVELY);
05614
05615 if( expr != NULL ) {
05616
05617 /* Create dummy time */
05618 sim_time time = {0,0,0,FALSE};
05619
05620 /* Evaluate children */
05621 expression_operate_recursively( expr->left, funit, sizing );
05622 expression_operate_recursively( expr->right, funit, sizing );
05623
05624 if( sizing ) {
05625
05626 /*
05627 Non-static expression found where static expression required. Simulator
05628 should catch this error before us, so no user error (too much work to find
05629 expression in functional unit expression list for now.
05630 */
05631 assert( (expr->op != EXP_OP_SBIT_SEL) &&
05632 (expr->op != EXP_OP_MBIT_SEL) &&
05633 (expr->op != EXP_OP_MBIT_POS) &&
05634 (expr->op != EXP_OP_MBIT_NEG) );
05635
05636 /* Resize current expression only */
05637 expression_resize( expr, funit, FALSE, TRUE );
05638
05639 }
05640
05641 /* Perform operation */
05642 (void)expression_operate( expr, NULL, &time );
05643
05644 if( sizing ) {
05645
05646 /* Clear out the execution number value since we aren't really simulating this */
05647 expr->exec_num = 0;
05648
05649 }
05650
05651 }
05652
05653 PROFILE_END;
05654
05655 }
|
|
||||||||||||||||||||
|
Recursively resizes specified expression tree leaf node.
00979 { PROFILE(EXPRESSION_RESIZE);
00980
00981 unsigned int largest_width; /* Holds larger width of left and right children */
00982 uint8 old_vec_suppl; /* Holds original vector supplemental field as this will be erased */
00983 funit_inst* tmp_inst; /* Pointer to temporary instance */
00984 int ignore = 0; /* Specifies the number of instances to ignore */
00985
00986 if( expr != NULL ) {
00987
00988 uint8 new_owns_data;
00989 uint8 new_data_type;
00990
00991 if( recursive ) {
00992 expression_resize( expr->left, funit, recursive, alloc );
00993 expression_resize( expr->right, funit, recursive, alloc );
00994 }
00995
00996 /* Get vector supplemental field */
00997 old_vec_suppl = expr->value->suppl.all;
00998
00999 switch( expr->op ) {
01000
01001 /* Only resize these values if we are recursively resizing */
01002 case EXP_OP_PARAM :
01003 case EXP_OP_PARAM_SBIT :
01004 case EXP_OP_PARAM_MBIT :
01005 case EXP_OP_PARAM_MBIT_POS :
01006 case EXP_OP_PARAM_MBIT_NEG :
01007 case EXP_OP_SIG :
01008 case EXP_OP_SBIT_SEL :
01009 case EXP_OP_MBIT_SEL :
01010 case EXP_OP_MBIT_POS :
01011 case EXP_OP_MBIT_NEG :
01012 if( recursive && (expr->sig != NULL) ) {
01013 expression_set_value( expr, expr->sig, funit );
01014 assert( expr->value->value.ul != NULL );
01015 }
01016 break;
01017
01018 /* These operations will already be sized so nothing to do here */
01019 case EXP_OP_STATIC :
01020 case EXP_OP_TRIGGER :
01021 case EXP_OP_ASSIGN :
01022 case EXP_OP_DASSIGN :
01023 case EXP_OP_BASSIGN :
01024 case EXP_OP_NASSIGN :
01025 case EXP_OP_PASSIGN :
01026 case EXP_OP_RASSIGN :
01027 case EXP_OP_DLY_ASSIGN :
01028 case EXP_OP_IF :
01029 case EXP_OP_WHILE :
01030 case EXP_OP_LAST :
01031 case EXP_OP_DIM :
01032 case EXP_OP_STIME :
01033 case EXP_OP_SRANDOM :
01034 case EXP_OP_SURANDOM :
01035 case EXP_OP_SURAND_RANGE :
01036 break;
01037
01038 /* These operations should always be set to a width 1 */
01039 case EXP_OP_LT :
01040 case EXP_OP_GT :
01041 case EXP_OP_EQ :
01042 case EXP_OP_CEQ :
01043 case EXP_OP_LE :
01044 case EXP_OP_GE :
01045 case EXP_OP_NE :
01046 case EXP_OP_CNE :
01047 case EXP_OP_LOR :
01048 case EXP_OP_LAND :
01049 case EXP_OP_UAND :
01050 case EXP_OP_UNOT :
01051 case EXP_OP_UOR :
01052 case EXP_OP_UXOR :
01053 case EXP_OP_UNAND :
01054 case EXP_OP_UNOR :
01055 case EXP_OP_UNXOR :
01056 case EXP_OP_EOR :
01057 case EXP_OP_CASE :
01058 case EXP_OP_CASEX :
01059 case EXP_OP_CASEZ :
01060 case EXP_OP_DEFAULT :
01061 case EXP_OP_REPEAT :
01062 case EXP_OP_RPT_DLY :
01063 case EXP_OP_WAIT :
01064 case EXP_OP_SFINISH :
01065 case EXP_OP_SSTOP :
01066 case EXP_OP_NEDGE :
01067 case EXP_OP_PEDGE :
01068 case EXP_OP_AEDGE :
01069 case EXP_OP_PLIST :
01070 case EXP_OP_SSRANDOM :
01071 case EXP_OP_STESTARGS :
01072 case EXP_OP_SVALARGS :
01073 if( (expr->value->width != 1) || (expr->value->value.ul == NULL) ) {
01074 assert( expr->value->value.ul == NULL );
01075 expression_create_value( expr, 1, alloc );
01076 }
01077 break;
01078
01079 /*
01080 In the case of an EXPAND, we need to set the width to be the product of the value of
01081 the left child and the bit-width of the right child.
01082 */
01083 case EXP_OP_EXPAND :
01084 expression_operate_recursively( expr->left, funit, TRUE );
01085 if( vector_is_unknown( expr->left->value ) ) {
01086 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unknown value used for concatenation multiplier, file: %s, line: %d", funit->filename, expr->line );
01087 assert( rv < USER_MSG_LENGTH );
01088 print_output( user_msg, FATAL, __FILE__, __LINE__ );
01089 Throw 0;
01090 }
01091 if( (expr->value->width != (vector_to_int( expr->left->value ) * expr->right->value->width)) ||
01092 (expr->value->value.ul == NULL) ) {
01093 assert( expr->value->value.ul == NULL );
01094 expression_create_value( expr, (vector_to_int( expr->left->value ) * expr->right->value->width), alloc );
01095 }
01096 break;
01097
01098 /*
01099 In the case of a MULTIPLY or LIST (for concatenation) operation, its expression width must be the sum of its
01100 children's width. Remove the current vector and replace it with the appropriately
01101 sized vector.
01102 */
01103 case EXP_OP_LIST :
01104 if( (expr->value->width != (expr->left->value->width + expr->right->value->width)) ||
01105 (expr->value->value.ul == NULL) ) {
01106 assert( expr->value->value.ul == NULL );
01107 expression_create_value( expr, (expr->left->value->width + expr->right->value->width), alloc );
01108 }
01109 break;
01110
01111 /*
01112 A FUNC_CALL expression width is set to the same width as that of the function's return value.
01113 */
01114 case EXP_OP_FUNC_CALL :
01115 if( expr->sig != NULL ) {
01116 assert( funit != NULL );
01117 if( (funit->type != FUNIT_AFUNCTION) && (funit->type != FUNIT_ANAMED_BLOCK) ) {
01118 assert( expr->elem.funit != NULL );
01119 tmp_inst = inst_link_find_by_funit( expr->elem.funit, db_list[curr_db]->inst_head, &ignore );
01120 funit_size_elements( expr->elem.funit, tmp_inst, FALSE, FALSE );
01121 }
01122 if( (expr->value->width != expr->sig->value->width) || (expr->value->value.ul == NULL) ) {
01123 assert( expr->value->value.ul == NULL );
01124 expression_create_value( expr, expr->sig->value->width, alloc );
01125 }
01126 }
01127 break;
01128
01129 default :
01130 /*
01131 If this expression is either the root, an LHS expression or a lower-level RHS expression,
01132 get its size from the largest of its children.
01133 */
01134 if( (ESUPPL_IS_ROOT( expr->suppl ) == 1) ||
01135 (ESUPPL_IS_LHS( expr->suppl ) == 1) ||
01136 ((expr->parent->expr->op != EXP_OP_ASSIGN) &&
01137 (expr->parent->expr->op != EXP_OP_DASSIGN) &&
01138 (expr->parent->expr->op != EXP_OP_BASSIGN) &&
01139 (expr->parent->expr->op != EXP_OP_NASSIGN) &&
01140 (expr->parent->expr->op != EXP_OP_RASSIGN) &&
01141 (expr->parent->expr->op != EXP_OP_DLY_OP)) ) {
01142 if( (expr->left != NULL) && ((expr->right == NULL) || (expr->left->value->width > expr->right->value->width)) ) {
01143 largest_width = expr->left->value->width;
01144 } else if( expr->right != NULL ) {
01145 largest_width = expr->right->value->width;
01146 } else {
01147 largest_width = 1;
01148 }
01149 if( (expr->value->width != largest_width) || (expr->value->value.ul == NULL) ) {
01150 assert( expr->value->value.ul == NULL );
01151 expression_create_value( expr, largest_width, alloc );
01152 }
01153
01154 /* If our parent is a DLY_OP, we need to get our value from the LHS of the DLY_ASSIGN expression */
01155 } else if( expr->parent->expr->op == EXP_OP_DLY_OP ) {
01156 if( (expr->parent->expr->parent->expr->left->value->width != expr->value->width) || (expr->value->value.ul == NULL) ) {
01157 assert( expr->value->value.ul == NULL );
01158 expression_create_value( expr, expr->parent->expr->parent->expr->left->value->width, alloc );
01159 }
01160
01161 /* Otherwise, get our value from the size of the expression on the left-hand-side of the assignment */
01162 } else {
01163 if( (expr->parent->expr->left->value->width != expr->value->width) || (expr->value->value.ul == NULL) ) {
01164 assert( expr->value->value.ul == NULL );
01165 expression_create_value( expr, expr->parent->expr->left->value->width, alloc );
01166 }
01167 }
01168 break;
01169
01170 }
01171
01172 /* Reapply original supplemental field (preserving the owns_data bit) now that expression has been resized */
01173 new_owns_data = expr->value->suppl.part.owns_data;
01174 new_data_type = expr->value->suppl.part.data_type;
01175 expr->value->suppl.all = old_vec_suppl;
01176 expr->value->suppl.part.owns_data = new_owns_data;
01177 expr->value->suppl.part.data_type = new_data_type;
01178
01179 }
01180
01181 PROFILE_END;
01182
01183 }
|
|
|
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).
05849 { PROFILE(EXPRESSION_SET_ASSIGNED);
05850
05851 expression* curr; /* Pointer to current expression */
05852
05853 assert( expr != NULL );
05854
05855 if( ESUPPL_IS_LHS( expr->suppl ) == 1 ) {
05856
05857 curr = expr;
05858 while( (ESUPPL_IS_ROOT( curr->suppl ) == 0) &&
05859 (curr->op != EXP_OP_BASSIGN) &&
05860 (curr->op != EXP_OP_RASSIGN) &&
05861 (curr->parent->expr->op != EXP_OP_SBIT_SEL) &&
05862 (curr->parent->expr->op != EXP_OP_MBIT_SEL) &&
05863 (curr->parent->expr->op != EXP_OP_MBIT_POS) &&
05864 (curr->parent->expr->op != EXP_OP_MBIT_NEG) ) {
05865 curr = curr->parent->expr;
05866 }
05867
05868 /*
05869 If we are on the LHS of a BASSIGN operator, set the assigned bit to indicate that
05870 this signal will be assigned by Covered and not the dumpfile.
05871 */
05872 if( (curr->op == EXP_OP_BASSIGN) || (curr->op == EXP_OP_RASSIGN) ) {
05873 expr->sig->suppl.part.assigned = 1;
05874 }
05875
05876 }
05877
05878 PROFILE_END;
05879
05880 }
|
|
|
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).
05889 { PROFILE(EXPRESSION_SET_CHANGED);
05890
05891 if( expr != NULL ) {
05892
05893 /* Set the children expressions */
05894 expression_set_changed( expr->left );
05895 expression_set_changed( expr->right );
05896
05897 /* Now set our bits */
05898 expr->suppl.part.left_changed = 1;
05899 expr->suppl.part.right_changed = 1;
05900
05901 }
05902
05903 PROFILE_END;
05904
05905 }
|
|
|
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.
00919 { PROFILE(EXPRESSION_SET_SIGNED);
00920
00921 if( exp != NULL ) {
00922
00923 /*
00924 If this expression is attached to a signal that has the signed bit set (which is not a bit select) or
00925 the valid left and right expressions have the signed bit set, set our is_signed bit
00926 and continue traversing up expression tree.
00927 */
00928 if( ((exp->sig != NULL) && (exp->sig->value->suppl.part.is_signed == 1) &&
00929 (exp->op != EXP_OP_SBIT_SEL) &&
00930 (exp->op != EXP_OP_MBIT_SEL) &&
00931 (exp->op != EXP_OP_PARAM_SBIT) &&
00932 (exp->op != EXP_OP_PARAM_MBIT)) ||
00933 ((((exp->left != NULL) && (exp->left->value->suppl.part.is_signed == 1)) || (exp->left == NULL)) &&
00934 (((exp->right != NULL) && (exp->right->value->suppl.part.is_signed == 1)) || (exp->right == NULL)) &&
00935 ((exp->op == EXP_OP_ADD) ||
00936 (exp->op == EXP_OP_SUBTRACT) ||
00937 (exp->op == EXP_OP_MULTIPLY) ||
00938 (exp->op == EXP_OP_DIVIDE) ||
00939 (exp->op == EXP_OP_MOD) ||
00940 (exp->op == EXP_OP_STATIC) ||
00941 (exp->op == EXP_OP_LT) ||
00942 (exp->op == EXP_OP_GT) ||
00943 (exp->op == EXP_OP_LE) ||
00944 (exp->op == EXP_OP_GE) ||
00945 (exp->op == EXP_OP_EQ) ||
00946 (exp->op == EXP_OP_NE))) ||
00947 (exp->value->suppl.part.is_signed == 1) ) {
00948
00949 exp->value->suppl.part.is_signed = 1;
00950
00951 /* If we are not the root expression, traverse up */
00952 if( ESUPPL_IS_ROOT( exp->suppl ) == 0 ) {
00953 expression_set_signed( exp->parent->expr );
00954 }
00955
00956 }
00957
00958 }
00959
00960 PROFILE_END;
00961
00962 }
|
|
||||||||||||||||
|
Sets the specified expression value to the specified vector value.
00825 { PROFILE(EXPRESSION_SET_VALUE);
00826
00827 assert( exp != NULL );
00828 assert( exp->value != NULL );
00829 assert( sig != NULL );
00830 assert( sig->value != NULL );
00831
00832 /* Set our vector type to match the signal type */
00833 exp->value->suppl.part.data_type = sig->value->suppl.part.data_type;
00834
00835 /* If we are a SIG, PARAM or TRIGGER type, set our value to the signal's value */
00836 if( (exp->op == EXP_OP_SIG) || (exp->op == EXP_OP_PARAM) || (exp->op == EXP_OP_TRIGGER) ) {
00837
00838 exp->value->suppl = sig->value->suppl;
00839 exp->value->width = sig->value->width;
00840 exp->value->value.ul = sig->value->value.ul;
00841 exp->value->suppl.part.owns_data = 0;
00842
00843 /* Otherwise, create our own vector to store the part select */
00844 } else {
00845
00846 unsigned int edim = expression_get_curr_dimension( exp );
00847 int exp_width = vsignal_calc_width_for_expr( exp, sig );
00848 exp_dim* dim;
00849
00850 /* Allocate dimensional structure (if needed) and populate it with static information */
00851 if( exp->elem.dim == NULL ) {
00852 exp->elem.dim = dim = (exp_dim*)malloc_safe( sizeof( exp_dim ) );
00853 } else if( exp->suppl.part.nba == 1 ) {
00854 dim = exp->elem.dim_nba->dim;
00855 } else {
00856 dim = exp->elem.dim;
00857 }
00858
00859 dim->curr_lsb = -1;
00860 if( sig->dim[edim].lsb < sig->dim[edim].msb ) {
00861 dim->dim_lsb = sig->dim[edim].lsb;
00862 dim->dim_be = FALSE;
00863 } else {
00864 dim->dim_lsb = sig->dim[edim].msb;
00865 dim->dim_be = TRUE;
00866 }
00867 dim->dim_width = exp_width;
00868 dim->last = expression_is_last_select( exp );
00869
00870 /* Set the expression width */
00871 switch( exp->op ) {
00872 case EXP_OP_SBIT_SEL :
00873 case EXP_OP_PARAM_SBIT :
00874 break;
00875 case EXP_OP_MBIT_SEL :
00876 case EXP_OP_PARAM_MBIT :
00877 {
00878 int lbit, rbit;
00879 expression_operate_recursively( exp->left, funit, TRUE );
00880 expression_operate_recursively( exp->right, funit, TRUE );
00881 lbit = vector_to_int( exp->left->value );
00882 rbit = vector_to_int( exp->right->value );
00883 if( lbit <= rbit ) {
00884 exp_width = ((rbit - lbit) + 1) * exp_width;
00885 } else {
00886 exp_width = ((lbit - rbit) + 1) * exp_width;
00887 }
00888 }
00889 break;
00890 case EXP_OP_MBIT_POS :
00891 case EXP_OP_MBIT_NEG :
00892 case EXP_OP_PARAM_MBIT_POS :
00893 case EXP_OP_PARAM_MBIT_NEG :
00894 expression_operate_recursively( exp->right, funit, TRUE );
00895 exp_width = vector_to_int( exp->right->value ) * exp_width;
00896 break;
00897 default : break;
00898 }
00899
00900 /* Allocate a vector for this expression */
00901 if( exp->value->value.ul != NULL ) {
00902 vector_dealloc_value( exp->value );
00903 }
00904 expression_create_value( exp, exp_width, TRUE );
00905
00906 }
00907
00908 PROFILE_END;
00909
00910 }
|
|
|
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
01845 { PROFILE(EXPRESSION_STRING);
01846
01847 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "%d (%s line %d)", exp->id, expression_string_op( exp->op ), exp->line );
01848 assert( rv < USER_MSG_LENGTH );
01849
01850 PROFILE_END;
01851
01852 return( user_msg );
01853
01854 }
|
|
|
Returns user-readable name of specified expression operation.
01829 { PROFILE(EXPRESSION_STRING_OP);
01830
01831 assert( (op >= 0) && (op < EXP_OP_NUM) );
01832
01833 PROFILE_END;
01834
01835 return( exp_op_info[op].name );
01836
01837 }
|
1.3.4