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. | |
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. |
Contains functions for handling expressions.
void expression_assign_expr_ids | ( | expression * | root, | |
func_unit * | funit | |||
) |
Assigns each expression in the given tree a unique identifier.
anonymous | expression_resize expression_assign_expr_ids expression_assign_expr_ids |
Recursively iterates down the specified expression tree assigning unique IDs to each expression.
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.
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.
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.
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.
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.
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.
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 }
Reads current line of specified file and parses for expression information.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Recursively iterates up expression tree, counting the number of dimensions deep that the given expression is.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.
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).
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).
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.
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.
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.
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
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.
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 }