#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "binding.h"
#include "db.h"
#include "defines.h"
#include "expr.h"
#include "fsm.h"
#include "func_unit.h"
#include "instance.h"
#include "link.h"
#include "reentrant.h"
#include "sim.h"
#include "stmt_blk.h"
#include "util.h"
#include "vector.h"
#include "vsignal.h"
void expression_assign | ( | expression * | lhs, | |
expression * | rhs, | |||
int * | lsb, | |||
thread * | thr, | |||
const sim_time * | time, | |||
bool | eval_lhs, | |||
bool | nb | |||
) | [static] |
Recursively iterates through specified LHS expression, assigning the value from the RHS expression. This is called whenever a blocking assignment expression is found during simulation.
lhs | Pointer to current expression on left-hand-side of assignment to calculate for | |
rhs | Pointer to the right-hand-expression that will be assigned from | |
lsb | Current least-significant bit in rhs value to start assigning | |
thr | Pointer to thread for the given expressions | |
time | Specifies current simulation time when expression assignment occurs | |
eval_lhs | If TRUE, allows the left-hand expression to be evaluated, if necessary (should be set to TRUE unless for specific cases where it is not necessary and would be redundant to do so -- i.e., op-and-assign cases) | |
nb | If TRUE, this assignment should be a non-blocking assignment |
References ssuppl_u::assigned, cli_debug_mode, exp_dim_s::curr_lsb, DEBUG, debug_mode, 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, ESUPPL_IS_LEFT_CHANGED, EXP_OP_CONCAT, EXP_OP_DIM, EXP_OP_LIST, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_SBIT_SEL, EXP_OP_SIG, EXP_OP_STATIC, expr_stmt_u::expr, expression_string_op(), FALSE, flag_use_command_line_debug, sim_time_s::full, vsuppl_u::is_signed, exp_dim_s::last, expression_s::left, dim_and_nba_s::nba, esuppl_u::nba, expression_s::op, expression_s::parent, vsuppl_u::part, ssuppl_u::part, esuppl_u::part, print_output(), PROFILE, PROFILE_END, expression_s::right, vsuppl_u::set, expression_s::sig, sim_add_nonblock_assign(), sim_expression(), vector_s::suppl, vsignal_s::suppl, expression_s::suppl, TRUE, user_msg, USER_MSG_LENGTH, vsignal_s::value, expression_s::value, vector_is_unknown(), vector_part_select_push(), vector_to_int(), vsignal_display(), vsignal_propagate(), and vector_s::width.
Referenced by expression_op_func__add_a(), expression_op_func__and_a(), expression_op_func__arshift_a(), expression_op_func__assign(), expression_op_func__divide_a(), expression_op_func__dly_assign(), expression_op_func__lshift_a(), expression_op_func__mod_a(), expression_op_func__multiply_a(), expression_op_func__or_a(), expression_op_func__passign(), expression_op_func__random(), expression_op_func__rshift_a(), expression_op_func__sub_a(), expression_op_func__urandom(), expression_op_func__value_plusargs(), and expression_op_func__xor_a().
05910 { PROFILE(EXPRESSION_ASSIGN); 05911 05912 if( lhs != NULL ) { 05913 05914 exp_dim* dim = (lhs->suppl.part.nba == 0) ? lhs->elem.dim : lhs->elem.dim_nba->dim; 05915 int vwidth = 0; 05916 int prev_lsb = 0; 05917 05918 /* Calculate starting vector value bit and signal LSB/BE for LHS */ 05919 if( lhs->sig != NULL ) { 05920 if( (lhs->parent->expr->op == EXP_OP_DIM) && (lhs->parent->expr->right == lhs) ) { 05921 vwidth = lhs->parent->expr->left->value->width; 05922 prev_lsb = lhs->parent->expr->left->elem.dim->curr_lsb; 05923 } else { 05924 vwidth = lhs->sig->value->width; 05925 prev_lsb = 0; 05926 } 05927 } 05928 05929 #ifdef DEBUG_MODE 05930 if( debug_mode ) { 05931 if( ((dim != NULL) && dim->last) || (lhs->op == EXP_OP_SIG) ) { 05932 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, " In expression_assign, lhs_op: %s, rhs_op: %s, lsb: %d, time: %" FMT64 "u, nb: %d", 05933 expression_string_op( lhs->op ), expression_string_op( rhs->op ), *lsb, time->full, nb ); 05934 assert( rv < USER_MSG_LENGTH ); 05935 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 05936 } 05937 } 05938 #endif 05939 05940 switch( lhs->op ) { 05941 case EXP_OP_SIG : 05942 assert( lhs->sig != NULL ); 05943 if( lhs->sig->suppl.part.assigned == 1 ) { 05944 if( nb ) { 05945 if( lhs->suppl.part.nba == 1 ) { 05946 sim_add_nonblock_assign( lhs->elem.dim_nba->nba, 0, (lhs->value->width - 1), *lsb, (rhs->value->width - 1) ); 05947 } 05948 } else { 05949 bool changed = vector_part_select_push( lhs->sig->value, 0, (lhs->value->width - 1), rhs->value, *lsb, (rhs->value->width - 1), rhs->value->suppl.part.is_signed ); 05950 lhs->sig->value->suppl.part.set = 1; 05951 #ifdef DEBUG_MODE 05952 if( debug_mode && (!flag_use_command_line_debug || cli_debug_mode) ) { 05953 printf( " " ); vsignal_display( lhs->sig ); 05954 } 05955 #endif 05956 if( changed ) { 05957 vsignal_propagate( lhs->sig, time ); 05958 } 05959 } 05960 } 05961 *lsb += lhs->value->width; 05962 break; 05963 case EXP_OP_SBIT_SEL : 05964 assert( lhs->sig != NULL ); 05965 assert( dim != NULL ); 05966 if( eval_lhs && (ESUPPL_IS_LEFT_CHANGED( lhs->suppl ) == 1) ) { 05967 (void)sim_expression( lhs->left, thr, time, TRUE ); 05968 } 05969 if( lhs->sig->suppl.part.assigned == 1 ) { 05970 bool changed = FALSE; 05971 if( !vector_is_unknown( lhs->left->value ) ) { 05972 int intval = (vector_to_int( lhs->left->value ) - dim->dim_lsb) * dim->dim_width; 05973 if( intval >= 0 ) { // Only perform assignment if selected bit is within range 05974 if( dim->dim_be ) { 05975 dim->curr_lsb = ((intval > vwidth) || (prev_lsb == -1)) ? -1 : (prev_lsb + (vwidth - (intval + (int)lhs->value->width))); 05976 } else { 05977 dim->curr_lsb = ((intval >= vwidth) || (prev_lsb == -1)) ? -1 : (prev_lsb + intval); 05978 } 05979 } else { 05980 dim->curr_lsb = -1; 05981 } 05982 } 05983 if( dim->last && (dim->curr_lsb != -1) ) { 05984 if( nb ) { 05985 if( lhs->suppl.part.nba == 1 ) { 05986 sim_add_nonblock_assign( lhs->elem.dim_nba->nba, dim->curr_lsb, ((dim->curr_lsb + lhs->value->width) - 1), *lsb, (rhs->value->width - 1) ); 05987 } 05988 } else { 05989 changed = vector_part_select_push( lhs->sig->value, dim->curr_lsb, ((dim->curr_lsb + lhs->value->width) - 1), rhs->value, *lsb, (rhs->value->width - 1), FALSE ); 05990 lhs->sig->value->suppl.part.set = 1; 05991 #ifdef DEBUG_MODE 05992 if( debug_mode && (!flag_use_command_line_debug || cli_debug_mode) ) { 05993 printf( " " ); vsignal_display( lhs->sig ); 05994 } 05995 #endif 05996 if( changed ) { 05997 vsignal_propagate( lhs->sig, time ); 05998 } 05999 } 06000 } 06001 } 06002 if( dim->last && (dim->curr_lsb != -1) ) { 06003 *lsb += lhs->value->width; 06004 } 06005 break; 06006 case EXP_OP_MBIT_SEL : 06007 assert( lhs->sig != NULL ); 06008 assert( dim != NULL ); 06009 if( lhs->sig->suppl.part.assigned == 1 ) { 06010 bool changed = FALSE; 06011 int intval = ((dim->dim_be ? vector_to_int( lhs->left->value ) : vector_to_int( lhs->right->value )) - dim->dim_lsb) * dim->dim_width; 06012 assert( intval >= 0 ); 06013 if( dim->dim_be ) { 06014 assert( intval <= vwidth ); 06015 dim->curr_lsb = (prev_lsb == -1) ? -1 : (prev_lsb + (vwidth - (intval + (int)lhs->value->width))); 06016 } else { 06017 assert( intval < vwidth ); 06018 dim->curr_lsb = (prev_lsb == -1) ? -1 : (prev_lsb + intval); 06019 } 06020 if( dim->last && (dim->curr_lsb != -1) ) { 06021 if( nb ) { 06022 if( lhs->suppl.part.nba == 1 ) { 06023 sim_add_nonblock_assign( lhs->elem.dim_nba->nba, dim->curr_lsb, ((dim->curr_lsb + lhs->value->width) - 1), *lsb, (rhs->value->width - 1) ); 06024 } 06025 } else { 06026 changed = vector_part_select_push( lhs->sig->value, dim->curr_lsb, ((dim->curr_lsb + lhs->value->width) - 1), rhs->value, *lsb, (rhs->value->width - 1), FALSE ); 06027 lhs->sig->value->suppl.part.set = 1; 06028 #ifdef DEBUG_MODE 06029 if( debug_mode && (!flag_use_command_line_debug || cli_debug_mode) ) { 06030 printf( " " ); vsignal_display( lhs->sig ); 06031 } 06032 #endif 06033 if( changed ) { 06034 vsignal_propagate( lhs->sig, time ); 06035 } 06036 } 06037 } 06038 } 06039 if( dim->last && (dim->curr_lsb != -1) ) { 06040 *lsb += lhs->value->width; 06041 } 06042 break; 06043 case EXP_OP_MBIT_POS : 06044 assert( lhs->sig != NULL ); 06045 assert( dim != NULL ); 06046 if( eval_lhs && (ESUPPL_IS_LEFT_CHANGED( lhs->suppl ) == 1) ) { 06047 (void)sim_expression( lhs->left, thr, time, TRUE ); 06048 } 06049 if( lhs->sig->suppl.part.assigned == 1 ) { 06050 int intval; 06051 int tgt_lsb, tgt_msb; 06052 int src_lsb, src_msb; 06053 if( !vector_is_unknown( lhs->left->value ) ) { 06054 intval = (vector_to_int( lhs->left->value ) - dim->dim_lsb) * dim->dim_width; 06055 dim->curr_lsb = (prev_lsb + intval); 06056 } 06057 if( dim->curr_lsb >= 0 ) { 06058 tgt_lsb = dim->curr_lsb; 06059 src_lsb = *lsb; 06060 } else if( (0 - dim->curr_lsb) < lhs->value->width ) { 06061 tgt_lsb = 0; 06062 src_lsb = *lsb + (0 - dim->curr_lsb); 06063 } else { 06064 tgt_lsb = -1; 06065 } 06066 tgt_msb = (dim->curr_lsb + lhs->value->width) - 1; 06067 src_msb = (*lsb + rhs->value->width) - 1; 06068 if( dim->last && (tgt_lsb != -1) ) { 06069 if( nb ) { 06070 if( lhs->suppl.part.nba == 1 ) { 06071 sim_add_nonblock_assign( lhs->elem.dim_nba->nba, tgt_lsb, tgt_msb, src_lsb, src_msb ); 06072 } 06073 } else { 06074 bool changed = vector_part_select_push( lhs->sig->value, tgt_lsb, tgt_msb, rhs->value, src_lsb, src_msb, FALSE ); 06075 lhs->sig->value->suppl.part.set = 1; 06076 #ifdef DEBUG_MODE 06077 if( debug_mode && (!flag_use_command_line_debug || cli_debug_mode) ) { 06078 printf( " " ); vsignal_display( lhs->sig ); 06079 } 06080 #endif 06081 if( changed ) { 06082 vsignal_propagate( lhs->sig, time ); 06083 } 06084 } 06085 } 06086 } 06087 if( (dim != NULL) && dim->last ) { 06088 *lsb = *lsb + lhs->value->width; 06089 } 06090 break; 06091 case EXP_OP_MBIT_NEG : 06092 assert( lhs->sig != NULL ); 06093 assert( dim != NULL ); 06094 if( eval_lhs && (ESUPPL_IS_LEFT_CHANGED( lhs->suppl ) == 1) ) { 06095 (void)sim_expression( lhs->left, thr, time, TRUE ); 06096 } 06097 if( lhs->sig->suppl.part.assigned == 1 ) { 06098 int intval1, intval2; 06099 int tgt_lsb, tgt_msb; 06100 int src_lsb, src_msb; 06101 if( !vector_is_unknown( lhs->left->value ) ) { 06102 intval1 = vector_to_int( lhs->left->value ) - dim->dim_lsb; 06103 intval2 = vector_to_int( lhs->right->value ); 06104 dim->curr_lsb = (prev_lsb + ((intval1 - intval2) + 1)); 06105 } 06106 if( dim->curr_lsb >= 0 ) { 06107 tgt_lsb = dim->curr_lsb; 06108 src_lsb = *lsb; 06109 } else if( (0 - dim->curr_lsb) < lhs->value->width ) { 06110 tgt_lsb = 0; 06111 src_lsb = *lsb + (0 - dim->curr_lsb); 06112 } else { 06113 tgt_lsb = -1; 06114 } 06115 tgt_msb = (dim->curr_lsb + lhs->value->width) - 1; 06116 src_msb = (*lsb + rhs->value->width) - 1; 06117 if( dim->last ) { 06118 if( nb ) { 06119 if( lhs->suppl.part.nba == 1 ) { 06120 sim_add_nonblock_assign( lhs->elem.dim_nba->nba, tgt_lsb, tgt_msb, src_lsb, src_msb ); 06121 } 06122 } else { 06123 bool changed = vector_part_select_push( lhs->sig->value, tgt_lsb, tgt_msb, rhs->value, src_lsb, src_msb, FALSE ); 06124 lhs->sig->value->suppl.part.set = 1; 06125 #ifdef DEBUG_MODE 06126 if( debug_mode && (!flag_use_command_line_debug || cli_debug_mode) ) { 06127 printf( " " ); vsignal_display( lhs->sig ); 06128 } 06129 #endif 06130 if( changed ) { 06131 vsignal_propagate( lhs->sig, time ); 06132 } 06133 } 06134 } 06135 } 06136 if( (dim != NULL) && dim->last ) { 06137 *lsb = *lsb + lhs->value->width; 06138 } 06139 break; 06140 case EXP_OP_CONCAT : 06141 case EXP_OP_LIST : 06142 expression_assign( lhs->right, rhs, lsb, thr, time, eval_lhs, nb ); 06143 expression_assign( lhs->left, rhs, lsb, thr, time, eval_lhs, nb ); 06144 break; 06145 case EXP_OP_DIM : 06146 expression_assign( lhs->left, rhs, lsb, thr, time, eval_lhs, nb ); 06147 expression_assign( lhs->right, rhs, lsb, thr, time, eval_lhs, nb ); 06148 lhs->elem.dim->curr_lsb = lhs->right->elem.dim->curr_lsb; 06149 break; 06150 case EXP_OP_STATIC : 06151 break; 06152 default: 06153 /* This is an illegal expression to have on the left-hand-side of an expression */ 06154 assert( (lhs->op == EXP_OP_SIG) || 06155 (lhs->op == EXP_OP_SBIT_SEL) || 06156 (lhs->op == EXP_OP_MBIT_SEL) || 06157 (lhs->op == EXP_OP_MBIT_POS) || 06158 (lhs->op == EXP_OP_MBIT_NEG) || 06159 (lhs->op == EXP_OP_CONCAT) || 06160 (lhs->op == EXP_OP_LIST) || 06161 (lhs->op == EXP_OP_DIM) ); 06162 break; 06163 } 06164 06165 } 06166 06167 PROFILE_END; 06168 06169 }
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 }
static void expression_create_tmp_vecs | ( | expression * | exp, | |
int | width | |||
) | [static] |
Allocates the appropriate amount of memory for the temporary vectors for the given expression. This function should only be called when memory is required to be allocated and when ourselves and our children expressions within the same tree have been sized.
exp | Pointer to expression to allocate temporary vectors for | |
width | Number of bits wide the given expression will contain |
References vsuppl_u::data_type, expression_s::elem, EXP_OP_ADD_A, EXP_OP_AEDGE, EXP_OP_ALS_A, EXP_OP_AND_A, EXP_OP_ARS_A, EXP_OP_DIV_A, EXP_OP_LS_A, EXP_OP_MLT_A, EXP_OP_MOD_A, EXP_OP_NEDGE, EXP_OP_OR_A, EXP_OP_PEDGE, EXP_OP_RS_A, EXP_OP_SUB_A, EXP_OP_XOR_A, EXPR_TMP_VECS, free_safe, expression_s::left, malloc_safe, expression_s::op, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, expression_s::right, vector_s::suppl, TRUE, expression_s::tvecs, vector_s::ul, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vecblk_s::vec, vector_create(), vector_init_r32(), vector_init_r64(), vector_init_ulong(), VTYPE_VAL, and vector_s::width.
Referenced by expression_create_value(), and expression_db_read().
00415 { PROFILE(EXPRESSION_CREATE_TMP_VECS); 00416 00417 /* 00418 Only create temporary vectors for expressions that require them and who have not already have had 00419 temporary vectors created. 00420 */ 00421 if( (EXPR_TMP_VECS( exp->op ) > 0) && (exp->elem.tvecs == NULL) ) { 00422 00423 switch( exp->value->suppl.part.data_type ) { 00424 case VDATA_UL : 00425 { 00426 ulong hdata; 00427 unsigned i; 00428 00429 /* Calculate the width that we need to allocate */ 00430 switch( exp->op ) { 00431 case EXP_OP_PEDGE : 00432 case EXP_OP_NEDGE : hdata = UL_SET; width = 1; break; 00433 case EXP_OP_AEDGE : hdata = UL_SET; width = exp->right->value->width; break; 00434 case EXP_OP_ADD_A : 00435 case EXP_OP_SUB_A : 00436 case EXP_OP_MLT_A : 00437 case EXP_OP_DIV_A : 00438 case EXP_OP_MOD_A : 00439 case EXP_OP_AND_A : 00440 case EXP_OP_OR_A : 00441 case EXP_OP_XOR_A : 00442 case EXP_OP_LS_A : 00443 case EXP_OP_RS_A : 00444 case EXP_OP_ALS_A : 00445 case EXP_OP_ARS_A : hdata = 0x0; width = exp->left->value->width; break; 00446 default : hdata = 0x0; break; 00447 } 00448 00449 /* Allocate the memory */ 00450 exp->elem.tvecs = (vecblk*)malloc_safe( sizeof( vecblk ) ); 00451 for( i=0; i<EXPR_TMP_VECS( exp->op ); i++ ) { 00452 vector* vec = vector_create( width, VTYPE_VAL, VDATA_UL, TRUE ); 00453 vector_init_ulong( &(exp->elem.tvecs->vec[i]), vec->value.ul, 0, hdata, TRUE, width, VTYPE_VAL ); 00454 free_safe( vec, sizeof( vector ) ); 00455 } 00456 } 00457 break; 00458 case VDATA_R64 : 00459 { 00460 unsigned int i; 00461 exp->elem.tvecs = (vecblk*)malloc_safe( sizeof( vecblk ) ); 00462 for( i=0; i<EXPR_TMP_VECS( exp->op ); i++ ) { 00463 vector* vec = vector_create( 64, VTYPE_VAL, VDATA_R64, TRUE ); 00464 vector_init_r64( &(exp->elem.tvecs->vec[i]), vec->value.r64, 0.0, NULL, TRUE, VTYPE_VAL ); 00465 free_safe( vec, sizeof( vector ) ); 00466 } 00467 } 00468 break; 00469 case VDATA_R32 : 00470 { 00471 unsigned int i; 00472 exp->elem.tvecs = (vecblk*)malloc_safe( sizeof( vecblk ) ); 00473 for( i=0; i<EXPR_TMP_VECS( exp->op ); i++ ) { 00474 vector* vec = vector_create( 32, VTYPE_VAL, VDATA_R32, TRUE ); 00475 vector_init_r32( &(exp->elem.tvecs->vec[i]), vec->value.r32, 0.0, NULL, TRUE, VTYPE_VAL ); 00476 free_safe( vec, sizeof( vector ) ); 00477 } 00478 } 00479 break; 00480 default : assert( 0 ); break; 00481 } 00482 00483 } 00484 00485 PROFILE_END; 00486 00487 }
static void expression_create_value | ( | expression * | exp, | |
int | width, | |||
bool | data | |||
) | [static] |
anonymous | Throw |
Creates a value vector that is large enough to store width number of bits in value and sets the specified expression value to this value. This function should be called by either the expression_create function, the bind function, or the signal db_read function.
exp | Pointer to expression to add value to | |
width | Width of value to create | |
data | Specifies if uint8 array should be allocated for vector |
References vsuppl_u::data_type, expression_create_tmp_vecs(), FALSE, FATAL, free_safe, esuppl_u::gen_expr, expression_s::left, malloc_safe, MAX_BIT_WIDTH, expression_s::op, esuppl_u::part, vsuppl_u::part, print_output(), PROFILE, PROFILE_END, exp_info_s::real_op, expression_s::right, expression_s::suppl, vector_s::suppl, exp_info_s::suppl, Throw, TRUE, vsuppl_u::type, vector_s::ul, user_msg, USER_MSG_LENGTH, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_create(), vector_init_r32(), vector_init_r64(), vector_init_ulong(), and VTYPE_EXP.
Referenced by expression_create(), expression_resize(), and expression_set_value().
00559 { PROFILE(EXPRESSION_CREATE_VALUE); 00560 00561 /* If the left or right expressions are storing real numbers, create real number storage for this expression */ 00562 if( ((exp_op_info[exp->op].suppl.real_op & 0x2) && (exp->left->value->suppl.part.data_type == VDATA_R64)) || 00563 ((exp_op_info[exp->op].suppl.real_op & 0x1) && (exp->right->value->suppl.part.data_type == VDATA_R64)) || 00564 (exp->value->suppl.part.data_type == VDATA_R64) ) { 00565 00566 if( (data == TRUE) || ((exp->suppl.part.gen_expr == 1) && (width > 0)) ) { 00567 vector_init_r64( exp->value, (rv64*)malloc_safe( sizeof( rv64 ) ), 0.0, NULL, TRUE, VTYPE_EXP ); 00568 expression_create_tmp_vecs( exp, 64 ); 00569 } else { 00570 vector_init_r64( exp->value, NULL, 0.0, NULL, FALSE, VTYPE_EXP ); 00571 } 00572 00573 /* If the left or right expressions are storing shortreal numbers, create shortreal number storage for this expression */ 00574 } else if( ((exp_op_info[exp->op].suppl.real_op & 0x2) && (exp->left->value->suppl.part.data_type == VDATA_R32)) || 00575 ((exp_op_info[exp->op].suppl.real_op & 0x1) && (exp->right->value->suppl.part.data_type == VDATA_R32)) || 00576 (exp->value->suppl.part.data_type == VDATA_R32) ) { 00577 00578 if( (data == TRUE) || ((exp->suppl.part.gen_expr == 1) && (width > 0)) ) { 00579 vector_init_r32( exp->value, (rv32*)malloc_safe( sizeof( rv32 ) ), 0.0, NULL, TRUE, VTYPE_EXP ); 00580 expression_create_tmp_vecs( exp, 32 ); 00581 } else { 00582 vector_init_r32( exp->value, NULL, 0.0, NULL, FALSE, VTYPE_EXP ); 00583 } 00584 00585 /* Otherwise, create a ulong vector */ 00586 } else { 00587 00588 if( ((data == TRUE) || (exp->suppl.part.gen_expr == 1)) && (width > 0) ) { 00589 00590 vector* vec = NULL; 00591 00592 if( width > MAX_BIT_WIDTH ) { 00593 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Found an expression width (%d) that exceeds the maximum currently allowed by Covered (%d)", 00594 width, MAX_BIT_WIDTH ); 00595 assert( rv < USER_MSG_LENGTH ); 00596 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00597 Throw 0; 00598 } 00599 00600 vec = vector_create( width, VTYPE_EXP, VDATA_UL, TRUE ); 00601 assert( exp->value->value.ul == NULL ); 00602 vector_init_ulong( exp->value, vec->value.ul, 0x0, 0x0, TRUE, width, vec->suppl.part.type ); 00603 free_safe( vec, sizeof( vector ) ); 00604 00605 /* Create the temporary vectors now, if needed */ 00606 expression_create_tmp_vecs( exp, width ); 00607 00608 } else { 00609 00610 vector_init_ulong( exp->value, NULL, 0x0, 0x0, FALSE, width, VTYPE_EXP ); 00611 00612 } 00613 00614 } 00615 00616 PROFILE_END; 00617 00618 }
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 }
static void expression_find_params | ( | expression * | expr, | |
exp_link ** | head, | |||
exp_link ** | tail | |||
) | [static] |
Recursively traverses given expression tree, adding any expressions found that point to parameter values.
expr | Pointer to expression tree to search | |
head | Pointer to head of expression list containing expressions that use parameter values | |
tail | Pointer to tail of expression list containing expressions that use parameter values |
References exp_link_add(), EXP_OP_PARAM, EXP_OP_PARAM_MBIT, EXP_OP_PARAM_MBIT_NEG, EXP_OP_PARAM_MBIT_POS, EXP_OP_PARAM_SBIT, expression_s::left, expression_s::op, PROFILE, PROFILE_END, and expression_s::right.
01368 { PROFILE(EXPRESSION_FIND_PARAMS); 01369 01370 if( expr != NULL ) { 01371 01372 /* If we call a parameter, add ourselves to the expression list */ 01373 if( (expr->op == EXP_OP_PARAM) || 01374 (expr->op == EXP_OP_PARAM_SBIT) || 01375 (expr->op == EXP_OP_PARAM_MBIT) || 01376 (expr->op == EXP_OP_PARAM_MBIT_POS) || 01377 (expr->op == EXP_OP_PARAM_MBIT_NEG) ) { 01378 exp_link_add( expr, head, tail ); 01379 } 01380 01381 /* Search children */ 01382 expression_find_params( expr->left, head, tail ); 01383 expression_find_params( expr->right, head, tail ); 01384 01385 } 01386 01387 PROFILE_END; 01388 01389 }
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 }
static bool expression_is_assigned | ( | expression * | expr | ) | [static] |
expr | Pointer to expression to check |
References 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, EXP_OP_SIG, EXP_OP_TRIGGER, expr_stmt_u::expr, FALSE, expression_s::op, expression_s::parent, PROFILE, PROFILE_END, expression_s::suppl, and TRUE.
Referenced by expression_dealloc().
05716 { PROFILE(EXPRESSION_IS_ASSIGNED); 05717 05718 bool retval = FALSE; /* Return value for this function */ 05719 05720 assert( expr != NULL ); 05721 05722 /* If this expression is a trigger then this is an assigned expression */ 05723 if( expr->op == EXP_OP_TRIGGER ) { 05724 05725 retval = TRUE; 05726 05727 } else if( (ESUPPL_IS_LHS( expr->suppl ) == 1) && 05728 ((expr->op == EXP_OP_SIG) || 05729 (expr->op == EXP_OP_SBIT_SEL) || 05730 (expr->op == EXP_OP_MBIT_SEL) || 05731 (expr->op == EXP_OP_MBIT_POS) || 05732 (expr->op == EXP_OP_MBIT_NEG)) ) { 05733 05734 while( (expr != NULL) && 05735 (ESUPPL_IS_ROOT( expr->suppl ) == 0) && 05736 (expr->op != EXP_OP_BASSIGN) && 05737 (expr->op != EXP_OP_RASSIGN) && 05738 (expr->parent->expr->op != EXP_OP_SBIT_SEL) && 05739 (expr->parent->expr->op != EXP_OP_MBIT_SEL) && 05740 (expr->parent->expr->op != EXP_OP_MBIT_POS) && 05741 (expr->parent->expr->op != EXP_OP_MBIT_NEG) ) { 05742 expr = expr->parent->expr; 05743 } 05744 05745 retval = (expr != NULL) && ((expr->op == EXP_OP_BASSIGN) || (expr->op == EXP_OP_RASSIGN)) ; 05746 05747 } 05748 05749 PROFILE_END; 05750 05751 return( retval ); 05752 05753 }
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 }
static bool expression_is_static_only_helper | ( | expression * | expr, | |
bool * | one | |||
) | [static] |
Recursively iterates through specified expression tree and returns TRUE if all of the leaf expressions are static expressions (STATIC or parameters).
expr | Pointer to expression to evaluate | |
one | Pointer to value that holds whether a static value of zero was found |
References ESUPPL_IS_LHS, EXP_OP_CONCAT, EXP_OP_COND, EXP_OP_FUNC_CALL, EXP_OP_MBIT_SEL, EXP_OP_SBIT_SEL, EXP_OP_SIG, EXPR_IS_OP_AND_ASSIGN, EXPR_IS_STATIC, FALSE, expression_s::left, expression_s::op, ssuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::sig, SSUPPL_TYPE_ENUM, SSUPPL_TYPE_PARAM, SSUPPL_TYPE_PARAM_REAL, vsignal_s::suppl, expression_s::suppl, TRUE, ssuppl_u::type, expression_s::value, and vector_is_not_zero().
Referenced by expression_is_static_only().
05655 { PROFILE(EXPRESSION_IS_STATIC_ONLY_HELPER); 05656 05657 bool retval; /* Return value for this function */ 05658 05659 if( expr != NULL ) { 05660 05661 if( (EXPR_IS_STATIC( expr ) == 1) || 05662 (ESUPPL_IS_LHS( expr->suppl ) == 1) || 05663 ((expr->op == EXP_OP_SIG) && (expr->sig != NULL) && 05664 ((expr->sig->suppl.part.type == SSUPPL_TYPE_PARAM) || 05665 (expr->sig->suppl.part.type == SSUPPL_TYPE_PARAM_REAL) || 05666 (expr->sig->suppl.part.type == SSUPPL_TYPE_ENUM))) ) { 05667 retval = TRUE; 05668 if( one != NULL ) { 05669 *one |= vector_is_not_zero( expr->value ); 05670 } 05671 } else if( expr->op == EXP_OP_CONCAT ) { 05672 bool curr_one = FALSE; 05673 bool all_static = expression_is_static_only_helper( expr->right, &curr_one ); 05674 retval = (!curr_one && all_static) || curr_one; 05675 } else if( expr->op == EXP_OP_COND ) { 05676 retval = expression_is_static_only_helper( expr->right, one ); 05677 } else { 05678 if( (expr->op != EXP_OP_MBIT_SEL) && 05679 (expr->op != EXP_OP_SBIT_SEL) && 05680 (expr->op != EXP_OP_SIG) && 05681 (expr->op != EXP_OP_FUNC_CALL) && 05682 (EXPR_IS_OP_AND_ASSIGN( expr ) == 0) ) { 05683 bool lstatic = expression_is_static_only_helper( expr->left, one ); 05684 bool rstatic = expression_is_static_only_helper( expr->right, one ); 05685 retval = lstatic && rstatic; 05686 } else { 05687 retval = FALSE; 05688 } 05689 } 05690 05691 } else { 05692 05693 retval = TRUE; 05694 05695 } 05696 05697 PROFILE_END; 05698 05699 return( retval ); 05700 05701 }
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_op_func__add | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an addition operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_add(), and vector_set_other_comb_evals().
02315 { PROFILE(EXPRESSION_OP_FUNC__ADD); 02316 02317 /* Perform add operation */ 02318 bool retval = vector_op_add( expr->value, expr->left->value, expr->right->value ); 02319 02320 /* Gather coverage information */ 02321 expression_set_tf_preclear( expr, retval ); 02322 vector_set_other_comb_evals( expr->value, expr->left->value, expr->right->value ); 02323 expression_set_eval_NN( expr ); 02324 02325 PROFILE_END; 02326 02327 return( retval ); 02328 02329 }
bool expression_op_func__add_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an add-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, vsuppl_u::data_type, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, expression_s::right, expression_s::sig, sim_expression(), vector_s::suppl, TRUE, expression_s::tvecs, rv32_s::val, rv64_s::val, vector_s::value, vsignal_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vecblk_s::vec, vector_copy(), vector_from_real64(), vector_op_add(), vector_set_other_comb_evals(), and vsignal_propagate().
02340 { PROFILE(EXPRESSION_OP_FUNC__ADD_A); 02341 02342 bool retval; /* Return value for this function */ 02343 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02344 int intval = 0; /* Integer value */ 02345 02346 /* Evaluate the left expression */ 02347 (void)sim_expression( expr->left, thr, time, TRUE ); 02348 02349 /* Second, copy the value of the left expression into a temporary vector */ 02350 vector_copy( expr->left->value, tmp ); 02351 02352 /* Third, perform addition */ 02353 retval = vector_op_add( expr->value, tmp, expr->right->value ); 02354 02355 /* Gather coverage information */ 02356 expression_set_tf_preclear( expr, retval ); 02357 vector_set_other_comb_evals( expr->value, expr->left->value, expr->right->value ); 02358 expression_set_eval_NN( expr ); 02359 02360 /* Finally, assign the new value to the left expression */ 02361 switch( expr->value->suppl.part.data_type ) { 02362 case VDATA_UL : 02363 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02364 break; 02365 case VDATA_R64 : 02366 if( vector_from_real64( expr->left->sig->value, expr->value->value.r64->val ) ) { 02367 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 02368 } 02369 break; 02370 case VDATA_R32 : 02371 if( vector_from_real64( expr->left->sig->value, (double)expr->value->value.r32->val ) ) { 02372 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 02373 } 02374 break; 02375 default : assert( 0 ); break; 02376 } 02377 02378 PROFILE_END; 02379 02380 return( retval ); 02381 02382 }
bool expression_op_func__aedge | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an any-edge event operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::elem, esuppl_u::eval_t, EXP_OP_SIG, FALSE, expression_s::op, thread_s::part, esuppl_u::part, ssuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::sig, SSUPPL_TYPE_EVENT, thread_s::suppl, expression_s::suppl, vsignal_s::suppl, TRUE, esuppl_u::true, expression_s::tvecs, ssuppl_u::type, expression_s::value, vecblk_s::vec, vector_ceq_ulong(), and vector_copy().
04422 { PROFILE(EXPRESSION_OP_FUNC__AEDGE); 04423 04424 bool retval; /* Return value of this function */ 04425 04426 /* If our signal is an event that has been triggered, automatically set ourselves to true */ 04427 if( (expr->right->sig != NULL) && (expr->right->sig->suppl.part.type == SSUPPL_TYPE_EVENT) ) { 04428 04429 if( expr->right->suppl.part.eval_t == 1 ) { 04430 if( thr->suppl.part.exec_first ) { 04431 expr->suppl.part.true = 1; 04432 expr->suppl.part.eval_t = 1; 04433 retval = TRUE; 04434 } else { 04435 expr->suppl.part.eval_t = 0; 04436 retval = FALSE; 04437 } 04438 } else { 04439 retval = FALSE; 04440 } 04441 04442 } else { 04443 04444 /* We only need to do full value comparison if the right expression is something other than a signal */ 04445 if( thr->suppl.part.exec_first && ((expr->right->op == EXP_OP_SIG) || !vector_ceq_ulong( &(expr->elem.tvecs->vec[0]), expr->right->value )) ) { 04446 expr->suppl.part.true = 1; 04447 expr->suppl.part.eval_t = 1; 04448 vector_copy( expr->right->value, &(expr->elem.tvecs->vec[0]) ); 04449 retval = TRUE; 04450 } else { 04451 expr->suppl.part.eval_t = 0; 04452 retval = FALSE; 04453 } 04454 04455 } 04456 04457 PROFILE_END; 04458 04459 return( retval ); 04460 04461 }
bool expression_op_func__and | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a bitwise AND operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_bitwise_and_op(), and vector_set_and_comb_evals().
02475 { PROFILE(EXPRESSION_OP_FUNC__AND); 02476 02477 /* Perform bitwise AND operation */ 02478 bool retval = vector_bitwise_and_op( expr->value, expr->left->value, expr->right->value ); 02479 02480 /* Gather coverage information */ 02481 expression_set_tf_preclear( expr, retval ); 02482 vector_set_and_comb_evals( expr->value, expr->left->value, expr->right->value ); 02483 expression_set_eval_NN( expr ); 02484 02485 PROFILE_END; 02486 02487 return( retval ); 02488 02489 }
bool expression_op_func__and_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an AND-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, PROFILE, PROFILE_END, expression_s::right, sim_expression(), TRUE, expression_s::tvecs, expression_s::value, vecblk_s::vec, vector_bitwise_and_op(), vector_copy(), and vector_set_and_comb_evals().
02500 { PROFILE(EXPRESSION_OP_FUNC__AND_A); 02501 02502 bool retval; /* Return value for this function */ 02503 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02504 int intval = 0; /* Integer value */ 02505 02506 /* First, evaluate the left-hand expression */ 02507 (void)sim_expression( expr->left, thr, time, TRUE ); 02508 02509 /* Second, copy the value of the left expression into a temporary vector */ 02510 vector_copy( expr->left->value, tmp ); 02511 02512 /* Third, perform AND operation */ 02513 retval = vector_bitwise_and_op( expr->value, tmp, expr->right->value ); 02514 02515 /* Gather coverage information */ 02516 expression_set_tf_preclear( expr, retval ); 02517 vector_set_and_comb_evals( expr->value, expr->left->value, expr->right->value ); 02518 expression_set_eval_NN( expr ); 02519 02520 /* Finally, assign the new value to the left expression */ 02521 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02522 02523 PROFILE_END; 02524 02525 return( retval ); 02526 02527 }
bool expression_op_func__arshift | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an arithmetic right shift operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_arshift(), and vector_set_unary_evals().
02852 { PROFILE(EXPRESSION_OP_FUNC__ARSHIFT); 02853 02854 /* Perform arithmetic right-shift operation */ 02855 bool retval = vector_op_arshift( expr->value, expr->left->value, expr->right->value ); 02856 02857 /* Gather coverage information */ 02858 expression_set_tf_preclear( expr, retval ); 02859 vector_set_unary_evals( expr->value ); 02860 expression_set_eval_NN( expr ); 02861 02862 PROFILE_END; 02863 02864 return( retval ); 02865 02866 }
bool expression_op_func__arshift_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an arithmetic right-shift-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, PROFILE, PROFILE_END, expression_s::right, sim_expression(), TRUE, expression_s::tvecs, expression_s::value, vecblk_s::vec, vector_copy(), vector_op_arshift(), and vector_set_unary_evals().
02877 { PROFILE(EXPRESSION_OP_FUNC__ARSHIFT_A); 02878 02879 bool retval; /* Return value for this function */ 02880 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02881 int intval = 0; /* Integer value */ 02882 02883 /* First, evaluate the left-hand expression */ 02884 (void)sim_expression( expr->left, thr, time, TRUE ); 02885 02886 /* Second, copy the value of the left expression into a temporary vector */ 02887 vector_copy( expr->left->value, tmp ); 02888 02889 /* Third, perform arithmetic right-shift and collect coverage information */ 02890 retval = vector_op_arshift( expr->value, tmp, expr->right->value ); 02891 02892 /* Gather coverage information */ 02893 expression_set_tf_preclear( expr, retval ); 02894 vector_set_unary_evals( expr->value ); 02895 expression_set_eval_NN( expr ); 02896 02897 /* Finally, assign the new value to the left expression */ 02898 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02899 02900 PROFILE_END; 02901 02902 return( retval ); 02903 02904 }
bool expression_op_func__assign | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a non-blocking or blocking assignment operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, vsuppl_u::data_type, EXP_OP_NASSIGN, expression_assign(), expression_set_tf_preclear(), expression_s::left, expression_s::op, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, expression_s::right, vsuppl_u::set, expression_s::sig, vector_s::suppl, TRUE, rv32_s::val, rv64_s::val, vsignal_s::value, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_from_real64(), vector_to_real64(), and vsignal_propagate().
04720 { PROFILE(EXPRESSION_OP_FUNC__BASSIGN); 04721 04722 bool nb = (expr->op == EXP_OP_NASSIGN); 04723 04724 /* Perform assignment */ 04725 switch( expr->right->value->suppl.part.data_type ) { 04726 case VDATA_UL : 04727 switch( expr->left->value->suppl.part.data_type ) { 04728 case VDATA_UL : 04729 { 04730 int intval = 0; 04731 expression_assign( expr->left, expr->right, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), TRUE, nb ); 04732 } 04733 break; 04734 case VDATA_R64 : 04735 if( !nb ) { 04736 expr->left->value->value.r64->val = vector_to_real64( expr->right->value ); 04737 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 04738 } 04739 break; 04740 case VDATA_R32 : 04741 if( !nb ) { 04742 expr->left->value->value.r32->val = (float)vector_to_real64( expr->right->value ); 04743 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 04744 } 04745 break; 04746 default : assert( 0 ); break; 04747 } 04748 break; 04749 case VDATA_R64 : 04750 if( !nb ) { 04751 assert( expr->left->sig != NULL ); 04752 (void)vector_from_real64( expr->left->sig->value, (real64)expr->right->value->value.r64->val ); 04753 expr->left->sig->value->suppl.part.set = 1; 04754 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 04755 } 04756 break; 04757 case VDATA_R32 : 04758 if( !nb ) { 04759 assert( expr->left->sig != NULL ); 04760 (void)vector_from_real64( expr->left->sig->value, (real64)expr->right->value->value.r32->val ); 04761 expr->left->sig->value->suppl.part.set = 1; 04762 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 04763 } 04764 break; 04765 default : assert( 0 ); break; 04766 } 04767 04768 /* Gather coverage information */ 04769 expression_set_tf_preclear( expr, TRUE ); 04770 04771 PROFILE_END; 04772 04773 return( TRUE ); 04774 04775 }
bool expression_op_func__bitstoreal | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $bitstoreal system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References vsuppl_u::data_type, EXP_OP_SASSIGN, FATAL, func_unit_s::filename, thread_s::funit, expression_s::left, expression_s::line, expression_s::op, vsuppl_u::part, print_output(), PROFILE, PROFILE_END, vector_s::suppl, sys_task_bitstoreal(), Throw, user_msg, USER_MSG_LENGTH, expression_s::value, VDATA_UL, vector_from_real64(), and vector_to_uint64().
03210 { PROFILE(EXPRESSION_OP_FUNC__BITSTOREAL); 03211 03212 expression* left = expr->left; 03213 uint64 u64; 03214 bool retval; 03215 03216 /* Check to make sure that there is exactly one parameter */ 03217 if( (left == NULL) || (left->op != EXP_OP_SASSIGN) ) { 03218 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$bitstoreal called with incorrect number of parameters (file: %s, line: %d)", thr->funit->filename, expr->line ); 03219 assert( rv < USER_MSG_LENGTH ); 03220 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03221 Throw 0; 03222 } 03223 03224 /* Check to make sure that the parameter is a real */ 03225 if( left->value->suppl.part.data_type != VDATA_UL ) { 03226 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$bitstoreal called without non-real parameter (file: %s, line: %d)", thr->funit->filename, expr->line ); 03227 assert( rv < USER_MSG_LENGTH ); 03228 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03229 Throw 0; 03230 } 03231 03232 /* Convert and store the data */ 03233 retval = vector_from_real64( expr->value, sys_task_bitstoreal( vector_to_uint64( left->value ) ) ); 03234 03235 PROFILE_END; 03236 03237 return( retval ); 03238 03239 }
bool expression_op_func__bitstoshortreal | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $bitstoshortreal system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References vsuppl_u::data_type, EXP_OP_SASSIGN, FATAL, func_unit_s::filename, thread_s::funit, expression_s::left, expression_s::line, expression_s::op, vsuppl_u::part, print_output(), PROFILE, PROFILE_END, vector_s::suppl, sys_task_bitstoshortreal(), Throw, user_msg, USER_MSG_LENGTH, expression_s::value, VDATA_UL, vector_from_real64(), and vector_to_uint64().
03293 { PROFILE(EXPRESSION_OP_FUNC__BITSTOSHORTREAL); 03294 03295 expression* left = expr->left; 03296 uint64 u64; 03297 bool retval; 03298 03299 /* Check to make sure that there is exactly one parameter */ 03300 if( (left == NULL) || (left->op != EXP_OP_SASSIGN) ) { 03301 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$bitstoshortreal called with incorrect number of parameters (file: %s, line: %d)", thr->funit->filename, expr->line ); 03302 assert( rv < USER_MSG_LENGTH ); 03303 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03304 Throw 0; 03305 } 03306 03307 /* Check to make sure that the parameter is a real */ 03308 if( left->value->suppl.part.data_type != VDATA_UL ) { 03309 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$bitstoshortreal called without non-real parameter (file: %s, line: %d)", thr->funit->filename, expr->line ); 03310 assert( rv < USER_MSG_LENGTH ); 03311 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03312 Throw 0; 03313 } 03314 03315 /* Convert and store the data */ 03316 retval = vector_from_real64( expr->value, sys_task_bitstoshortreal( vector_to_uint64( left->value ) ) ); 03317 03318 PROFILE_END; 03319 03320 return( retval ); 03321 03322 }
bool expression_op_func__case | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a case comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_ceq(), and vector_set_unary_evals().
04617 { PROFILE(EXPRESSION_OP_FUNC__CASE); 04618 04619 /* Perform case comparison operation */ 04620 bool retval = vector_op_ceq( expr->value, expr->left->value, expr->right->value ); 04621 04622 /* Gather coverage information */ 04623 expression_set_tf_preclear( expr, retval ); 04624 vector_set_unary_evals( expr->value ); 04625 expression_set_eval_NN( expr ); 04626 04627 PROFILE_END; 04628 04629 return( retval ); 04630 04631 }
bool expression_op_func__casex | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a casex comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_cxeq(), and vector_set_unary_evals().
04642 { PROFILE(EXPRESSION_OP_FUNC__CASEX); 04643 04644 /* Perform casex comparison operation */ 04645 bool retval = vector_op_cxeq( expr->value, expr->left->value, expr->right->value ); 04646 04647 /* Gather coverage inforamtion */ 04648 expression_set_tf_preclear( expr, retval ); 04649 vector_set_unary_evals( expr->value ); 04650 expression_set_eval_NN( expr ); 04651 04652 PROFILE_END; 04653 04654 return( retval ); 04655 04656 }
bool expression_op_func__casez | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a casez comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_czeq(), and vector_set_unary_evals().
04667 { PROFILE(EXPRESSION_OP_FUNC__CASEZ); 04668 04669 /* Perform casez comparison operation */ 04670 bool retval = vector_op_czeq( expr->value, expr->left->value, expr->right->value ); 04671 04672 /* Gather coverage information */ 04673 expression_set_tf_preclear( expr, retval ); 04674 vector_set_unary_evals( expr->value ); 04675 expression_set_eval_NN( expr ); 04676 04677 PROFILE_END; 04678 04679 return( retval ); 04680 04681 }
bool expression_op_func__ceq | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an equality (===) comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_ceq(), and vector_set_unary_evals().
03628 { PROFILE(EXPRESSION_OP_FUNC__CEQ); 03629 03630 /* Perform case equality operation */ 03631 bool retval = vector_op_ceq( expr->value, expr->left->value, expr->right->value ); 03632 03633 /* Gather coverage information */ 03634 expression_set_tf_preclear( expr, retval ); 03635 vector_set_unary_evals( expr->value ); 03636 expression_set_eval_NN( expr ); 03637 03638 PROFILE_END; 03639 03640 return( retval ); 03641 03642 }
bool expression_op_func__clog2 | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $clog2 system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::left, PROFILE, PROFILE_END, expression_s::value, and vector_op_clog2().
03583 { PROFILE(EXPRESSION_OP_FUNC__CLOG2); 03584 03585 /* Perform the operation */ 03586 bool retval = vector_op_clog2( expr->value, expr->left->value ); 03587 03588 PROFILE_END; 03589 03590 return( retval ); 03591 03592 }
bool expression_op_func__cne | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a not-equal (!==) comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_cne(), and vector_set_unary_evals().
03728 { PROFILE(EXPRESSION_OP_FUNC__CNE); 03729 03730 /* Perform case not-equal operation */ 03731 bool retval = vector_op_cne( expr->value, expr->left->value, expr->right->value ); 03732 03733 /* Gather coverage information */ 03734 expression_set_tf_preclear( expr, retval ); 03735 vector_set_unary_evals( expr->value ); 03736 expression_set_eval_NN( expr ); 03737 03738 PROFILE_END; 03739 03740 return( retval ); 03741 03742 }
bool expression_op_func__concat | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a concatenation ({}) operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), PROFILE, PROFILE_END, expression_s::right, vector_s::ul, vector_s::value, expression_s::value, vector_set_unary_evals(), vector_set_value_ulong(), and vector_s::width.
04326 { PROFILE(EXPRESSION_OP_FUNC__CONCAT); 04327 04328 /* Perform concatenation operation */ 04329 bool retval = vector_set_value_ulong( expr->value, expr->right->value->value.ul, expr->right->value->width ); 04330 04331 /* Gather coverage information */ 04332 expression_set_tf_preclear( expr, retval ); 04333 vector_set_unary_evals( expr->value ); 04334 04335 PROFILE_END; 04336 04337 return( retval ); 04338 04339 }
bool expression_op_func__cond | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a conditional (?:) operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References vsuppl_u::data_type, DEQ, expression_set_tf_preclear(), FEQ, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, expression_s::right, vector_s::suppl, vector_s::ul, rv32_s::val, rv64_s::val, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_set_unary_evals(), vector_set_value_ulong(), and vector_s::width.
03803 { PROFILE(EXPRESSION_OP_FUNC__COND); 03804 03805 bool retval; 03806 03807 /* Simple vector copy from right side and gather coverage information */ 03808 switch( expr->value->suppl.part.data_type ) { 03809 case VDATA_UL : 03810 retval = vector_set_value_ulong( expr->value, expr->right->value->value.ul, expr->right->value->width ); 03811 break; 03812 case VDATA_R64 : 03813 retval = !DEQ( expr->value->value.r64->val, expr->right->value->value.r64->val ); 03814 expr->value->value.r64->val = expr->right->value->value.r64->val; 03815 break; 03816 case VDATA_R32 : 03817 retval = !FEQ( expr->value->value.r32->val, expr->right->value->value.r32->val ); 03818 expr->value->value.r32->val = expr->right->value->value.r32->val; 03819 break; 03820 default : assert( 0 ); break; 03821 } 03822 03823 /* Gather coverage information */ 03824 expression_set_tf_preclear( expr, retval ); 03825 vector_set_unary_evals( expr->value ); 03826 03827 PROFILE_END; 03828 03829 return( retval ); 03830 03831 }
bool expression_op_func__cond_sel | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a conditional select (?:) operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References vsuppl_u::data_type, DEQ, expr_stmt_u::expr, expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, expression_s::parent, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, expression_s::right, vector_s::suppl, vector_s::ul, rv32_s::val, rv64_s::val, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_is_not_zero(), vector_is_unknown(), vector_set_to_x(), vector_set_unary_evals(), vector_set_value_ulong(), vector_to_uint64(), and vector_s::width.
03842 { PROFILE(EXPRESSION_OP_FUNC__COND_SEL); 03843 03844 bool retval; /* Return value for this function */ 03845 03846 switch( expr->value->suppl.part.data_type ) { 03847 case VDATA_UL : 03848 if( !vector_is_unknown( expr->parent->expr->left->value ) ) { 03849 if( !vector_is_not_zero( expr->parent->expr->left->value ) ) { 03850 retval = vector_set_value_ulong( expr->value, expr->right->value->value.ul, expr->right->value->width ); 03851 } else { 03852 retval = vector_set_value_ulong( expr->value, expr->left->value->value.ul, expr->left->value->width ); 03853 } 03854 } else { 03855 retval = vector_set_to_x( expr->value ); 03856 } 03857 break; 03858 case VDATA_R64 : 03859 if( !vector_is_unknown( expr->parent->expr->left->value ) ) { 03860 if( !vector_is_not_zero( expr->parent->expr->left->value ) ) { 03861 real64 rval = (expr->right->value->suppl.part.data_type == VDATA_UL) ? (double)vector_to_uint64( expr->right->value ) : expr->right->value->value.r64->val; 03862 retval = !DEQ( expr->value->value.r64->val, rval ); 03863 expr->value->value.r64->val = rval; 03864 } else { 03865 real64 lval = (expr->left->value->suppl.part.data_type == VDATA_UL) ? (double)vector_to_uint64( expr->left->value ) : expr->left->value->value.r64->val; 03866 retval = !DEQ( expr->value->value.r64->val, lval ); 03867 expr->value->value.r64->val = lval; 03868 } 03869 } else { 03870 retval = !DEQ( expr->value->value.r64->val, 0.0 ); 03871 expr->value->value.r64->val = 0.0; 03872 } 03873 break; 03874 case VDATA_R32 : 03875 if( !vector_is_unknown( expr->parent->expr->left->value ) ) { 03876 if( !vector_is_not_zero( expr->parent->expr->left->value ) ) { 03877 real32 rval = (expr->right->value->suppl.part.data_type == VDATA_UL) ? (float)vector_to_uint64( expr->right->value ) : expr->right->value->value.r32->val; 03878 retval = !DEQ( expr->value->value.r32->val, rval ); 03879 expr->value->value.r64->val = rval; 03880 } else { 03881 real32 lval = (expr->left->value->suppl.part.data_type == VDATA_UL) ? (float)vector_to_uint64( expr->left->value ) : expr->left->value->value.r32->val; 03882 retval = !DEQ( expr->value->value.r32->val, lval ); 03883 expr->value->value.r32->val = lval; 03884 } 03885 } else { 03886 retval = !DEQ( expr->value->value.r32->val, 0.0 ); 03887 expr->value->value.r32->val = 0.0; 03888 } 03889 break; 03890 default : 03891 assert( 0 ); 03892 break; 03893 } 03894 03895 /* Gather coverage information */ 03896 expression_set_tf_preclear( expr, retval ); 03897 vector_set_unary_evals( expr->value ); 03898 expression_set_eval_NN( expr ); 03899 03900 PROFILE_END; 03901 03902 return( retval ); 03903 03904 }
bool expression_op_func__default | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a case default comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), PROFILE, PROFILE_END, expression_s::value, vector_set_coverage_and_assign_ulong(), and vector_set_unary_evals().
04692 { PROFILE(EXPRESSION_OP_FUNC__DEFAULT); 04693 04694 bool retval; /* Return value for this function */ 04695 ulong valh = 0; /* High value to store */ 04696 ulong vall = 1; /* Low value to store */ 04697 04698 /* Perform default case operation */ 04699 retval = vector_set_coverage_and_assign_ulong( expr->value, &vall, &valh, 0, 0 ); 04700 04701 /* Gather coverage information */ 04702 expression_set_tf_preclear( expr, retval ); 04703 vector_set_unary_evals( expr->value ); 04704 04705 PROFILE_END; 04706 04707 return( retval ); 04708 04709 }
bool expression_op_func__delay | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a delay operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, expression_s::elem, esuppl_u::eval_t, FALSE, sim_time_s::final, thread_s::part, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::scale, sim_thread_insert_into_delay_queue(), thread_s::suppl, expression_s::suppl, TIME_CMP_LE, TIME_INC, TRUE, esuppl_u::true, expression_s::value, and vector_to_sim_time().
04543 { PROFILE(EXPRESSION_OP_FUNC__DELAY); 04544 04545 bool retval = FALSE; /* Return value for this function */ 04546 04547 /* Clear the evaluated TRUE indicator */ 04548 expr->suppl.part.eval_t = 0; 04549 04550 /* If this is the first statement in the current thread, we are executing for the first time */ 04551 if( thr->suppl.part.exec_first ) { 04552 04553 if( TIME_CMP_LE( thr->curr_time, *time ) || time->final ) { 04554 expr->suppl.part.eval_t = 1; 04555 expr->suppl.part.true = 1; 04556 retval = TRUE; 04557 } 04558 04559 } else { 04560 04561 sim_time tmp_time; /* Contains the time that the delay is set for */ 04562 uint64 intval; /* 64-bit value */ 04563 04564 /* Get number of clocks to delay */ 04565 vector_to_sim_time( expr->right->value, *(expr->elem.scale), &tmp_time ); 04566 04567 /* Make sure that we set the final value to FALSE */ 04568 tmp_time.final = FALSE; 04569 04570 /* Add this delay into the delay queue if this is not the final simulation step */ 04571 if( !time->final ) { 04572 TIME_INC(tmp_time, thr->curr_time); 04573 sim_thread_insert_into_delay_queue( thr, &tmp_time ); 04574 } 04575 04576 } 04577 04578 PROFILE_END; 04579 04580 return( retval ); 04581 04582 }
bool expression_op_func__dim | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a multi-array dimension operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References exp_dim_s::curr_lsb, expression_s::dim, expression_s::elem, expression_set_tf_preclear(), PROFILE, PROFILE_END, and expression_s::right.
05454 { PROFILE(EXPRESSION_OP_FUNC__DIM); 05455 05456 bool retval; /* Return value for this function */ 05457 int rlsb = expr->right->elem.dim->curr_lsb; /* Right dimensional LSB value */ 05458 05459 /* If the right-hand dimensional LSB value is different than our own, set it to the new value and return TRUE */ 05460 retval = (rlsb != expr->elem.dim->curr_lsb); 05461 expr->elem.dim->curr_lsb = rlsb; 05462 05463 /* Get coverage information */ 05464 expression_set_tf_preclear( expr, retval ); 05465 05466 PROFILE_END; 05467 05468 return( retval ); 05469 05470 }
bool expression_op_func__disable | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a block disable operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::elem, expression_set_tf_preclear(), expression_s::funit, PROFILE, PROFILE_END, sim_kill_thread_with_funit(), and TRUE.
04919 { PROFILE(EXPRESSION_OP_FUNC__DISABLE); 04920 04921 sim_kill_thread_with_funit( expr->elem.funit ); 04922 04923 /* Gather coverage information */ 04924 expression_set_tf_preclear( expr, TRUE ); 04925 04926 PROFILE_END; 04927 04928 return( TRUE ); 04929 04930 }
bool expression_op_func__divide | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
anonymous | Throw |
Performs a 32-bit divide operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_divide(), and vector_set_unary_evals().
02172 { PROFILE(EXPRESSION_OP_FUNC__DIVIDE); 02173 02174 /* Perform divide operation */ 02175 bool retval = vector_op_divide( expr->value, expr->left->value, expr->right->value ); 02176 02177 /* Gather coverage information */ 02178 expression_set_tf_preclear( expr, retval ); 02179 vector_set_unary_evals( expr->value ); 02180 expression_set_eval_NN( expr ); 02181 02182 PROFILE_END; 02183 02184 return( retval ); 02185 02186 }
bool expression_op_func__divide_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an divide-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, vsuppl_u::data_type, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, expression_s::right, expression_s::sig, sim_expression(), vector_s::suppl, TRUE, expression_s::tvecs, rv32_s::val, rv64_s::val, vector_s::value, vsignal_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vecblk_s::vec, vector_copy(), vector_from_real64(), vector_op_divide(), vector_set_unary_evals(), and vsignal_propagate().
02197 { PROFILE(EXPRESSION_OP_FUNC__DIVIDE_A); 02198 02199 bool retval = FALSE; /* Return value for this function */ 02200 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02201 int intval = 0; /* Integer value */ 02202 02203 /* First, evaluate the left-hand expression */ 02204 (void)sim_expression( expr->left, thr, time, TRUE ); 02205 02206 /* Second, copy the value of the left expression into a temporary vector */ 02207 vector_copy( expr->left->value, tmp ); 02208 02209 /* Perform division operation */ 02210 retval = vector_op_divide( expr->value, expr->left->value, expr->right->value ); 02211 02212 /* Gather coverage information */ 02213 expression_set_tf_preclear( expr, retval ); 02214 vector_set_unary_evals( expr->value ); 02215 expression_set_eval_NN( expr ); 02216 02217 /* Finally, assign the new value to the left expression */ 02218 switch( expr->value->suppl.part.data_type ) { 02219 case VDATA_UL : 02220 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02221 break; 02222 case VDATA_R64 : 02223 if( vector_from_real64( expr->left->sig->value, expr->value->value.r64->val ) ) { 02224 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 02225 } 02226 break; 02227 case VDATA_R32 : 02228 if( vector_from_real64( expr->left->sig->value, (double)expr->value->value.r32->val ) ) { 02229 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 02230 } 02231 break; 02232 default : assert( 0 ); break; 02233 } 02234 02235 PROFILE_END; 02236 02237 return( retval ); 02238 02239 }
bool expression_op_func__dly_assign | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a delayed assignment.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, ESUPPL_IS_TRUE, esuppl_u::eval_t, EXP_OP_DELAY, expression_assign(), expression_op_func__dly_op(), FALSE, expression_s::left, expression_s::op, esuppl_u::part, thread_s::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, thread_s::suppl, and TRUE.
05352 { PROFILE(EXPRESSION_OP_FUNC__DLY_ASSIGN); 05353 05354 bool retval; /* Return value for this function */ 05355 int intval = 0; /* Integer value */ 05356 05357 /* If we are the first statement in the queue, perform the dly_op manually */ 05358 if( thr->suppl.part.exec_first && (expr->right->left->op == EXP_OP_DELAY) ) { 05359 (void)expression_op_func__dly_op( expr->right, thr, time ); 05360 } 05361 05362 /* Check the dly_op expression. If eval_t is set to 1, perform the assignment */ 05363 if( ESUPPL_IS_TRUE( expr->right->suppl ) == 1 ) { 05364 expression_assign( expr->left, expr->right, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), TRUE, FALSE ); 05365 expr->suppl.part.eval_t = 1; 05366 retval = TRUE; 05367 } else { 05368 expr->suppl.part.eval_t = 0; 05369 retval = FALSE; 05370 } 05371 05372 PROFILE_END; 05373 05374 return( retval ); 05375 05376 }
bool expression_op_func__dly_op | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an assignment and delay for a delayed assignment.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References esuppl_u::eval_t, EXP_OP_DELAY, exp_info_s::func, expression_s::left, expression_s::op, esuppl_u::part, thread_s::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, thread_s::suppl, TRUE, vector_s::ul, vector_s::value, expression_s::value, vector_set_value_ulong(), and vector_s::width.
Referenced by expression_op_func__dly_assign().
05387 { PROFILE(EXPRESSION_OP_FUNC__DLY_OP); 05388 05389 /* If we are not waiting for the delay to occur, copy the contents of the operation */ 05390 if( !thr->suppl.part.exec_first ) { 05391 (void)vector_set_value_ulong( expr->value, expr->right->value->value.ul, expr->right->value->width ); 05392 } 05393 05394 /* Explicitly call the delay/event. If the delay is complete, set eval_t to TRUE */ 05395 if( expr->left->op == EXP_OP_DELAY ) { 05396 expr->suppl.part.eval_t = exp_op_info[expr->left->op].func( expr->left, thr, time ); 05397 } else { 05398 expr->suppl.part.eval_t = expr->left->suppl.part.eval_t; 05399 } 05400 05401 PROFILE_END; 05402 05403 return( TRUE ); 05404 05405 }
bool expression_op_func__eor | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a event OR operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References ESUPPL_IS_TRUE, esuppl_u::eval_t, FALSE, expression_s::left, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, TRUE, and esuppl_u::true.
04472 { PROFILE(EXPRESSION_OP_FUNC__EOR); 04473 04474 bool retval; /* Return value for this function */ 04475 04476 if( (ESUPPL_IS_TRUE( expr->left->suppl ) == 1) || (ESUPPL_IS_TRUE( expr->right->suppl ) == 1) ) { 04477 04478 expr->suppl.part.eval_t = 1; 04479 expr->suppl.part.true = 1; 04480 retval = TRUE; 04481 04482 /* Clear eval_t bits in left and right expressions */ 04483 expr->left->suppl.part.eval_t = 0; 04484 expr->right->suppl.part.eval_t = 0; 04485 04486 } else { 04487 04488 expr->suppl.part.eval_t = 0; 04489 retval = FALSE; 04490 04491 } 04492 04493 PROFILE_END; 04494 04495 return( retval ); 04496 04497 }
bool expression_op_func__eq | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an equality (==) comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_eq(), and vector_set_unary_evals().
03603 { PROFILE(EXPRESSION_OP_FUNC__EQ); 03604 03605 /* Perform equality operation */ 03606 bool retval = vector_op_eq( expr->value, expr->left->value, expr->right->value ); 03607 03608 /* Gather coverage information */ 03609 expression_set_tf_preclear( expr, retval ); 03610 vector_set_unary_evals( expr->value ); 03611 expression_set_eval_NN( expr ); 03612 03613 PROFILE_END; 03614 03615 return( retval ); 03616 03617 }
bool expression_op_func__expand | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a expansion ({{}}) operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_expand(), vector_set_unary_evals(), and vector_s::width.
04263 { PROFILE(EXPRESSION_OP_FUNC__EXPAND); 04264 04265 /* Perform expansion operation */ 04266 bool retval = FALSE; 04267 04268 if( expr->value->width > 0 ) { 04269 04270 /* Perform vector expansion */ 04271 retval = vector_op_expand( expr->value, expr->left->value, expr->right->value ); 04272 04273 /* Gather coverage information */ 04274 expression_set_tf_preclear( expr, retval ); 04275 vector_set_unary_evals( expr->value ); 04276 expression_set_eval_NN( expr ); 04277 04278 } 04279 04280 PROFILE_END; 04281 04282 return( retval ); 04283 04284 }
bool expression_op_func__exponent | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an exponential power operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_is_unknown(), vector_set_coverage_and_assign_ulong(), vector_set_to_x(), vector_set_unary_evals(), and vector_to_int().
04972 { PROFILE(EXPRESSION_OP_FUNC__EXPONENT); 04973 04974 bool retval; /* Return value for this function */ 04975 04976 /* If the left and right expression values are not unknown, calculate exponent */ 04977 if( !vector_is_unknown( expr->left->value ) && !vector_is_unknown( expr->right->value ) ) { 04978 04979 int intval1; 04980 int intval2; 04981 ulong vall = 1; 04982 ulong valh = 0; 04983 int i; 04984 04985 intval1 = vector_to_int( expr->left->value ); 04986 intval2 = vector_to_int( expr->right->value ); 04987 04988 for( i=0; i<intval2; i++ ) { 04989 vall *= intval1; 04990 } 04991 04992 /* Assign value and calculate coverage */ 04993 retval = vector_set_coverage_and_assign_ulong( expr->value, &vall, &valh, 0, 31 ); 04994 04995 /* Otherwise, the entire value should be X */ 04996 } else { 04997 04998 retval = vector_set_to_x( expr->value ); 04999 05000 } 05001 05002 /* Gather coverage information */ 05003 expression_set_tf_preclear( expr, retval ); 05004 vector_set_unary_evals( expr->value ); 05005 05006 PROFILE_END; 05007 05008 return( retval ); 05009 05010 }
bool expression_op_func__finish | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $finish statement operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References FALSE, PROFILE, PROFILE_END, and sim_finish().
05510 { PROFILE(EXPRESSION_OP_FUNC__FINISH); 05511 05512 sim_finish(); 05513 05514 PROFILE_END; 05515 05516 return( FALSE ); 05517 05518 }
bool expression_op_func__fork | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a fork operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::elem, expression_set_tf_preclear(), func_unit_s::first_stmt, expression_s::funit, PROFILE, PROFILE_END, sim_add_thread(), and TRUE.
04877 { PROFILE(EXPRESSION_OP_FUNC__FORK); 04878 04879 (void)sim_add_thread( thr, expr->elem.funit->first_stmt, expr->elem.funit, time ); 04880 04881 /* Gather coverage information */ 04882 expression_set_tf_preclear( expr, TRUE ); 04883 04884 PROFILE_END; 04885 04886 return( TRUE ); 04887 04888 }
bool expression_op_func__func_call | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a function call operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, vsuppl_u::data_type, expression_s::elem, expression_set_tf_preclear(), func_unit_s::first_stmt, thread_s::funit, expression_s::funit, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, reentrant_dealloc(), thread_s::ren, expression_s::sig, sim_add_thread(), sim_thread(), vector_s::suppl, vector_s::ul, rv32_s::val, rv64_s::val, vector_s::value, vsignal_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_from_real64(), vector_set_unary_evals(), vector_set_value_ulong(), and vector_s::width.
04786 { PROFILE(EXPRESSION_OP_FUNC__FUNC_CALL); 04787 04788 bool retval; /* Return value for this function */ 04789 04790 /* First, simulate the function */ 04791 sim_thread( sim_add_thread( thr, expr->elem.funit->first_stmt, expr->elem.funit, time ), ((thr == NULL) ? time : &(thr->curr_time)) ); 04792 04793 /* Then copy the function variable to this expression */ 04794 switch( expr->value->suppl.part.data_type ) { 04795 case VDATA_UL : retval = vector_set_value_ulong( expr->value, expr->sig->value->value.ul, expr->value->width ); break; 04796 case VDATA_R64 : retval = vector_from_real64( expr->value, expr->sig->value->value.r64->val ); break; 04797 case VDATA_R32 : retval = vector_from_real64( expr->value, (double)expr->sig->value->value.r32->val ); break; 04798 default : assert( 0 ); break; 04799 } 04800 04801 /* Deallocate the reentrant structure of the current thread (if it exists) */ 04802 if( (thr != NULL) && (thr->ren != NULL) ) { 04803 reentrant_dealloc( thr->ren, thr->funit, expr ); 04804 thr->ren = NULL; 04805 } 04806 04807 /* Gather coverage information */ 04808 expression_set_tf_preclear( expr, retval ); 04809 vector_set_unary_evals( expr->value ); 04810 04811 PROFILE_END; 04812 04813 return( retval ); 04814 04815 }
bool expression_op_func__ge | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a greater-than-or-equal comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_ge(), and vector_set_unary_evals().
03678 { PROFILE(EXPRESSION_OP_FUNC__GE); 03679 03680 /* Perform greater-than-or-equal operation */ 03681 bool retval = vector_op_ge( expr->value, expr->left->value, expr->right->value ); 03682 03683 /* Gather coverage information */ 03684 expression_set_tf_preclear( expr, retval ); 03685 vector_set_unary_evals( expr->value ); 03686 expression_set_eval_NN( expr ); 03687 03688 PROFILE_END; 03689 03690 return( retval ); 03691 03692 }
bool expression_op_func__gt | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a greater-than comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_gt(), and vector_set_unary_evals().
02701 { PROFILE(EXPRESSION_OP_FUNC__GT); 02702 02703 /* Perform greater-than operation */ 02704 bool retval = vector_op_gt( expr->value, expr->left->value, expr->right->value ); 02705 02706 /* Gather coverage information */ 02707 expression_set_tf_preclear( expr, retval ); 02708 vector_set_unary_evals( expr->value ); 02709 expression_set_eval_NN( expr ); 02710 02711 PROFILE_END; 02712 02713 return( retval ); 02714 02715 }
bool expression_op_func__idec | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an immediate decrement operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References cli_debug_mode, thread_s::curr_time, vsuppl_u::data_type, debug_mode, expression_s::elem, flag_use_command_line_debug, vecblk_s::index, expression_s::left, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, vsuppl_u::set, expression_s::sig, vector_s::suppl, TRUE, expression_s::tvecs, vector_s::ul, rv32_s::val, rv64_s::val, vector_s::value, expression_s::value, vsignal_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_op_dec(), vector_set_value_ulong(), vsignal_display(), vsignal_propagate(), and vector_s::width.
05265 { PROFILE(EXPRESSION_OP_FUNC__IDEC); 05266 05267 /* Perform decrement */ 05268 expr->elem.tvecs->index = 0; 05269 if( expr->left->sig != NULL ) { 05270 (void)vector_op_dec( expr->left->sig->value, expr->elem.tvecs ); 05271 expr->left->sig->value->suppl.part.set = 1; 05272 } else { 05273 (void)vector_op_dec( expr->left->value, expr->elem.tvecs ); 05274 } 05275 05276 /* Copy the left-hand value to our expression */ 05277 switch( expr->left->value->suppl.part.data_type ) { 05278 case VDATA_UL : (void)vector_set_value_ulong( expr->value, expr->left->value->value.ul, expr->left->value->width ); break; 05279 case VDATA_R64 : expr->value->value.r64->val = expr->left->value->value.r64->val; break; 05280 case VDATA_R32 : expr->value->value.r32->val = expr->left->value->value.r32->val; break; 05281 default : assert( 0 ); break; 05282 } 05283 05284 #ifdef DEBUG_MODE 05285 if( debug_mode && (!flag_use_command_line_debug || cli_debug_mode) ) { 05286 printf( " " ); vsignal_display( expr->left->sig ); 05287 } 05288 #endif 05289 05290 /* Propagate value change */ 05291 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 05292 05293 PROFILE_END; 05294 05295 return( TRUE ); 05296 05297 }
bool expression_op_func__iinc | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an immediate increment operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References cli_debug_mode, thread_s::curr_time, vsuppl_u::data_type, debug_mode, expression_s::elem, flag_use_command_line_debug, vecblk_s::index, expression_s::left, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, vsuppl_u::set, expression_s::sig, vector_s::suppl, TRUE, expression_s::tvecs, vector_s::ul, rv32_s::val, rv64_s::val, vector_s::value, expression_s::value, vsignal_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_op_inc(), vector_set_value_ulong(), vsignal_display(), vsignal_propagate(), and vector_s::width.
05179 { PROFILE(EXPRESSION_OP_FUNC__IINC); 05180 05181 /* Perform increment */ 05182 expr->elem.tvecs->index = 0; 05183 if( expr->left->sig != NULL ) { 05184 (void)vector_op_inc( expr->left->sig->value, expr->elem.tvecs ); 05185 expr->left->sig->value->suppl.part.set = 1; 05186 } else { 05187 (void)vector_op_inc( expr->left->value, expr->elem.tvecs ); 05188 } 05189 05190 /* Assign the left value to our value */ 05191 switch( expr->left->value->suppl.part.data_type ) { 05192 case VDATA_UL : (void)vector_set_value_ulong( expr->value, expr->left->value->value.ul, expr->left->value->width ); break; 05193 case VDATA_R64 : expr->value->value.r64->val = expr->left->value->value.r64->val; break; 05194 case VDATA_R32 : expr->value->value.r32->val = expr->left->value->value.r32->val; break; 05195 default : assert( 0 ); break; 05196 } 05197 05198 #ifdef DEBUG_MODE 05199 if( debug_mode && (!flag_use_command_line_debug || cli_debug_mode) ) { 05200 printf( " " ); vsignal_display( expr->left->sig ); 05201 } 05202 #endif 05203 05204 /* Propagate value change */ 05205 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 05206 05207 PROFILE_END; 05208 05209 return( TRUE ); 05210 05211 }
bool expression_op_func__itor | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $itor system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References vsuppl_u::data_type, EXP_OP_SASSIGN, FATAL, func_unit_s::filename, thread_s::funit, expression_s::left, expression_s::line, expression_s::op, vsuppl_u::part, print_output(), PROFILE, PROFILE_END, vector_s::suppl, sys_task_itor(), Throw, user_msg, USER_MSG_LENGTH, expression_s::value, VDATA_UL, vector_from_real64(), and vector_to_int().
03333 { PROFILE(EXPRESSION_OP_FUNC__ITOR); 03334 03335 expression* left = expr->left; 03336 uint64 u64; 03337 bool retval; 03338 03339 /* Check to make sure that there is exactly one parameter */ 03340 if( (left == NULL) || (left->op != EXP_OP_SASSIGN) ) { 03341 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$itor called with incorrect number of parameters (file: %s, line: %d)", thr->funit->filename, expr->line ); 03342 assert( rv < USER_MSG_LENGTH ); 03343 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03344 Throw 0; 03345 } 03346 03347 /* Check to make sure that the parameter is a real */ 03348 if( left->value->suppl.part.data_type != VDATA_UL ) { 03349 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$itor called without non-real parameter (file: %s, line: %d)", thr->funit->filename, expr->line ); 03350 assert( rv < USER_MSG_LENGTH ); 03351 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03352 Throw 0; 03353 } 03354 03355 /* Convert and store the data */ 03356 retval = vector_from_real64( expr->value, sys_task_itor( vector_to_int( left->value ) ) ); 03357 03358 PROFILE_END; 03359 03360 return( retval ); 03361 03362 }
bool expression_op_func__join | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a join operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::active_children, expression_set_tf_preclear(), PROFILE, and PROFILE_END.
04899 { PROFILE(EXPRESSION_OP_FUNC__JOIN); 04900 04901 /* Gather coverage information */ 04902 expression_set_tf_preclear( expr, (thr->active_children == 0) ); 04903 04904 PROFILE_END; 04905 04906 return( thr->active_children == 0 ); 04907 04908 }
bool expression_op_func__land | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a logical AND operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_land(), and vector_set_and_comb_evals().
03778 { PROFILE(EXPRESSION_OP_FUNC__LAND); 03779 03780 /* Perform logical AND operation */ 03781 bool retval = vector_op_land( expr->value, expr->left->value, expr->right->value ); 03782 03783 /* Gather coverage information */ 03784 expression_set_tf_preclear( expr, retval ); 03785 vector_set_and_comb_evals( expr->value, expr->left->value, expr->right->value ); 03786 expression_set_eval_NN( expr ); 03787 03788 PROFILE_END; 03789 03790 return( retval ); 03791 03792 }
bool expression_op_func__le | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a less-than-or-equal comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_le(), and vector_set_unary_evals().
03653 { PROFILE(EXPRESSION_OP_FUNC__LE); 03654 03655 /* Perform less-than-or-equal operation */ 03656 bool retval = vector_op_le( expr->value, expr->left->value, expr->right->value ); 03657 03658 /* Gather coverage information */ 03659 expression_set_tf_preclear( expr, retval ); 03660 vector_set_unary_evals( expr->value ); 03661 expression_set_eval_NN( expr ); 03662 03663 PROFILE_END; 03664 03665 return( retval ); 03666 03667 }
bool expression_op_func__list | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a list (,) operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_list(), vector_set_unary_evals(), and vector_s::width.
04295 { PROFILE(EXPRESSION_OP_FUNC__LIST); 04296 04297 bool retval = FALSE; 04298 04299 if( expr->value->width > 0 ) { 04300 04301 /* Perform list operation */ 04302 retval = vector_op_list( expr->value, expr->left->value, expr->right->value ); 04303 04304 /* Gather coverage information */ 04305 expression_set_tf_preclear( expr, retval ); 04306 vector_set_unary_evals( expr->value ); 04307 expression_set_eval_NN( expr ); 04308 04309 } 04310 04311 PROFILE_END; 04312 04313 return( retval ); 04314 04315 }
bool expression_op_func__lor | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a logical OR operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_lor(), and vector_set_or_comb_evals().
03753 { PROFILE(EXPRESSION_OP_FUNC__LOR); 03754 03755 /* Perform logical OR operation */ 03756 bool retval = vector_op_lor( expr->value, expr->left->value, expr->right->value ); 03757 03758 /* Gather coverage information */ 03759 expression_set_tf_preclear( expr, retval ); 03760 vector_set_or_comb_evals( expr->value, expr->left->value, expr->right->value ); 03761 expression_set_eval_NN( expr ); 03762 03763 PROFILE_END; 03764 03765 return( retval ); 03766 03767 }
bool expression_op_func__lshift | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a left shift operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_lshift(), and vector_set_unary_evals().
02726 { PROFILE(EXPRESSION_OP_FUNC__LSHIFT); 02727 02728 /* Perform left-shift operation */ 02729 bool retval = vector_op_lshift( expr->value, expr->left->value, expr->right->value ); 02730 02731 /* Gather coverage information */ 02732 expression_set_tf_preclear( expr, retval ); 02733 vector_set_unary_evals( expr->value ); 02734 expression_set_eval_NN( expr ); 02735 02736 PROFILE_END; 02737 02738 return( retval ); 02739 02740 }
bool expression_op_func__lshift_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an left-shift-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, PROFILE, PROFILE_END, expression_s::right, sim_expression(), TRUE, expression_s::tvecs, expression_s::value, vecblk_s::vec, vector_copy(), vector_op_lshift(), and vector_set_unary_evals().
02751 { PROFILE(EXPRESSION_OP_FUNC__LSHIFT_A); 02752 02753 bool retval; /* Return value for this function */ 02754 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02755 int intval = 0; /* Integer value */ 02756 02757 /* First, evaluate the left-hand expression */ 02758 (void)sim_expression( expr->left, thr, time, TRUE ); 02759 02760 /* Second, copy the value of the left expression into a temporary vector */ 02761 vector_copy( expr->left->value, tmp ); 02762 02763 /* Third, perform left-shift operation */ 02764 retval = vector_op_lshift( expr->value, tmp, expr->right->value ); 02765 02766 /* Gather coverage information */ 02767 expression_set_tf_preclear( expr, retval ); 02768 vector_set_unary_evals( expr->value ); 02769 expression_set_eval_NN( expr ); 02770 02771 /* Finally, assign the new value to the left expression */ 02772 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02773 02774 PROFILE_END; 02775 02776 return( retval ); 02777 02778 }
bool expression_op_func__lt | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a less-than comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_lt(), and vector_set_unary_evals().
02676 { PROFILE(EXPRESSION_OP_FUNC__LT); 02677 02678 /* Perform less-than operation */ 02679 bool retval = vector_op_lt( expr->value, expr->left->value, expr->right->value ); 02680 02681 /* Gather coverage information */ 02682 expression_set_tf_preclear( expr, retval ); 02683 vector_set_unary_evals( expr->value ); 02684 expression_set_eval_NN( expr ); 02685 02686 PROFILE_END; 02687 02688 return( retval ); 02689 02690 }
bool expression_op_func__mbit | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a multi-bit select operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References exp_dim_s::curr_lsb, 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, ESUPPL_IS_ROOT, EXP_OP_DIM, expr_stmt_u::expr, expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, exp_dim_s::last, expression_s::left, esuppl_u::nba, expression_s::op, expression_s::parent, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::sig, expression_s::suppl, TRUE, vsignal_s::value, expression_s::value, vector_part_select_pull(), vector_to_int(), and vector_s::width.
04209 { PROFILE(EXPRESSION_OP_FUNC__MBIT); 04210 04211 bool retval = FALSE; /* Return value for this function */ 04212 int intval; /* LSB of range to copy */ 04213 int vwidth; /* Width of vector to use */ 04214 int prev_lsb; 04215 int curr_lsb; 04216 exp_dim* dim = (expr->suppl.part.nba == 0) ? expr->elem.dim : expr->elem.dim_nba->dim; 04217 04218 /* Calculate starting bit position */ 04219 if( (ESUPPL_IS_ROOT( expr->suppl ) == 0) && (expr->parent->expr->op == EXP_OP_DIM) && (expr->parent->expr->right == expr) ) { 04220 vwidth = expr->parent->expr->left->value->width; 04221 prev_lsb = expr->parent->expr->left->elem.dim->curr_lsb; 04222 } else { 04223 vwidth = expr->sig->value->width; 04224 prev_lsb = 0; 04225 } 04226 04227 /* Calculate the LSB and MSB and copy the bit range */ 04228 intval = ((dim->dim_be ? vector_to_int( expr->left->value ) : vector_to_int( expr->right->value )) - dim->dim_lsb) * dim->dim_width; 04229 if( dim->dim_be ) { 04230 curr_lsb = (prev_lsb + (vwidth - (intval + (int)expr->value->width))); 04231 } else { 04232 curr_lsb = (prev_lsb + intval); 04233 } 04234 04235 if( dim->last ) { 04236 retval = vector_part_select_pull( expr->value, expr->sig->value, curr_lsb, ((curr_lsb + expr->value->width) - 1), TRUE ); 04237 } else { 04238 retval = (curr_lsb != dim->curr_lsb); 04239 } 04240 04241 /* Set current LSB dimensional information */ 04242 dim->curr_lsb = curr_lsb; 04243 04244 /* Gather coverage information */ 04245 expression_set_tf_preclear( expr, retval ); 04246 expression_set_eval_NN( expr ); 04247 04248 PROFILE_END; 04249 04250 return( retval ); 04251 04252 }
bool expression_op_func__mbit_neg | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a negative variable multi-bit select operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References exp_dim_s::curr_lsb, dim_and_nba_s::dim, expression_s::dim, exp_dim_s::dim_lsb, expression_s::dim_nba, expression_s::elem, ESUPPL_IS_ROOT, EXP_OP_DIM, expr_stmt_u::expr, expression_set_tf_preclear(), FALSE, exp_dim_s::last, expression_s::left, esuppl_u::nba, expression_s::op, expression_s::parent, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::sig, expression_s::suppl, TRUE, vsignal_s::value, expression_s::value, vector_part_select_pull(), and vector_to_int().
05115 { PROFILE(EXPRESSION_OP_FUNC__MBIT_NEG); 05116 05117 bool retval = FALSE; /* Return value for this function */ 05118 exp_dim* dim = (expr->suppl.part.nba == 0) ? expr->elem.dim : expr->elem.dim_nba->dim; 05119 int intval1 = vector_to_int( expr->left->value ) - dim->dim_lsb; 05120 int intval2 = vector_to_int( expr->right->value ); 05121 int prev_lsb = ((ESUPPL_IS_ROOT( expr->suppl ) == 0) && (expr->parent->expr->op == EXP_OP_DIM) && (expr->parent->expr->right == expr)) ? expr->parent->expr->left->elem.dim->curr_lsb : 0; 05122 int curr_lsb = (prev_lsb + ((intval1 - intval2) + 1)); 05123 05124 /* If this is the last dimension, perform the assignment */ 05125 if( dim->last ) { 05126 retval = vector_part_select_pull( expr->value, expr->sig->value, curr_lsb, ((curr_lsb + vector_to_int( expr->right->value )) - 1), TRUE ); 05127 } else { 05128 retval = (dim->curr_lsb != curr_lsb); 05129 } 05130 05131 /* Set the dimensional current LSB with the calculated value */ 05132 dim->curr_lsb = curr_lsb; 05133 05134 /* Gather coverage information */ 05135 expression_set_tf_preclear( expr, retval ); 05136 05137 PROFILE_END; 05138 05139 return( retval ); 05140 05141 }
bool expression_op_func__mbit_pos | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a positive variable multi-bit select operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References exp_dim_s::curr_lsb, dim_and_nba_s::dim, expression_s::dim, exp_dim_s::dim_lsb, expression_s::dim_nba, exp_dim_s::dim_width, expression_s::elem, ESUPPL_IS_ROOT, EXP_OP_DIM, expr_stmt_u::expr, expression_set_tf_preclear(), FALSE, exp_dim_s::last, expression_s::left, esuppl_u::nba, expression_s::op, expression_s::parent, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::sig, expression_s::suppl, TRUE, vsignal_s::value, expression_s::value, vector_part_select_pull(), and vector_to_int().
05079 { PROFILE(EXPRESSION_OP_FUNC__MBIT_POS); 05080 05081 bool retval = FALSE; /* Return value for this function */ 05082 exp_dim* dim = (expr->suppl.part.nba == 0) ? expr->elem.dim : expr->elem.dim_nba->dim; 05083 int intval = (vector_to_int( expr->left->value ) - dim->dim_lsb) * dim->dim_width; 05084 int prev_lsb = ((ESUPPL_IS_ROOT( expr->suppl ) == 0) && (expr->parent->expr->op == EXP_OP_DIM) && (expr->parent->expr->right == expr)) ? expr->parent->expr->left->elem.dim->curr_lsb : 0; 05085 int curr_lsb = (prev_lsb + intval); 05086 05087 /* If this is the last dimension, perform the assignment */ 05088 if( dim->last ) { 05089 retval = vector_part_select_pull( expr->value, expr->sig->value, curr_lsb, ((curr_lsb + vector_to_int( expr->right->value )) - 1), TRUE ); 05090 } else { 05091 retval = (dim->curr_lsb != curr_lsb); 05092 } 05093 05094 /* Set current LSB dimensional information */ 05095 dim->curr_lsb = curr_lsb; 05096 05097 /* Gather coverage information */ 05098 expression_set_tf_preclear( expr, retval ); 05099 05100 PROFILE_END; 05101 05102 return( retval ); 05103 05104 }
bool expression_op_func__mod | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
anonymous | Throw |
Performs a 32-bit modulus operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_modulus(), and vector_set_unary_evals().
02252 { PROFILE(EXPRESSION_OP_FUNC__MOD); 02253 02254 /* Perform mod operation */ 02255 bool retval = vector_op_modulus( expr->value, expr->left->value, expr->right->value ); 02256 02257 /* Gather coverage information */ 02258 expression_set_tf_preclear( expr, retval ); 02259 vector_set_unary_evals( expr->value ); 02260 expression_set_eval_NN( expr ); 02261 02262 PROFILE_END; 02263 02264 return( retval ); 02265 02266 }
bool expression_op_func__mod_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an modulus-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, PROFILE, PROFILE_END, expression_s::right, sim_expression(), TRUE, expression_s::tvecs, expression_s::value, vecblk_s::vec, vector_copy(), vector_op_modulus(), and vector_set_unary_evals().
02277 { PROFILE(EXPRESSION_OP_FUNC__MOD_A); 02278 02279 bool retval; /* Return value for this function */ 02280 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02281 int intval = 0; /* Integer value */ 02282 02283 /* First, evaluate the left-hand expression */ 02284 (void)sim_expression( expr->left, thr, time, TRUE ); 02285 02286 /* Second, copy the value of the left expression into a temporary vector */ 02287 vector_copy( expr->left->value, tmp ); 02288 02289 /* Perform mod operation and ather coverage information */ 02290 retval = vector_op_modulus( expr->value, expr->left->value, expr->right->value ); 02291 02292 /* Gather coverage information */ 02293 expression_set_tf_preclear( expr, retval ); 02294 vector_set_unary_evals( expr->value ); 02295 expression_set_eval_NN( expr ); 02296 02297 /* Finally, assign the new value to the left expression */ 02298 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02299 02300 PROFILE_END; 02301 02302 return( retval ); 02303 02304 }
bool expression_op_func__multiply | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a multiply operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_multiply(), and vector_set_unary_evals().
02092 { PROFILE(EXPRESSION_OP_FUNC__MULTIPLY); 02093 02094 /* Perform multiply operation */ 02095 bool retval = vector_op_multiply( expr->value, expr->left->value, expr->right->value ); 02096 02097 /* Gather other coverage stats */ 02098 expression_set_tf_preclear( expr, retval ); 02099 vector_set_unary_evals( expr->value ); 02100 expression_set_eval_NN( expr ); 02101 02102 PROFILE_END; 02103 02104 return( retval ); 02105 02106 }
bool expression_op_func__multiply_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an multiply-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, vsuppl_u::data_type, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, expression_s::right, expression_s::sig, sim_expression(), vector_s::suppl, TRUE, expression_s::tvecs, rv32_s::val, rv64_s::val, vector_s::value, vsignal_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vecblk_s::vec, vector_copy(), vector_from_real64(), vector_op_multiply(), vector_set_unary_evals(), and vsignal_propagate().
02117 { PROFILE(EXPRESSION_OP_FUNC__MULTIPLY_A); 02118 02119 bool retval; /* Return value for this function */ 02120 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02121 int intval = 0; /* Integer value */ 02122 02123 /* First, evaluate the left-hand expression */ 02124 (void)sim_expression( expr->left, thr, time, TRUE ); 02125 02126 /* Second, copy the value of the left expression into a temporary vector */ 02127 vector_copy( expr->left->value, tmp ); 02128 02129 /* Third, perform multiply */ 02130 retval = vector_op_multiply( expr->value, tmp, expr->right->value ); 02131 02132 /* Gather coverage information */ 02133 expression_set_tf_preclear( expr, retval ); 02134 vector_set_unary_evals( expr->value ); 02135 expression_set_eval_NN( expr ); 02136 02137 /* Fourth, assign the new value to the left expression */ 02138 switch( expr->value->suppl.part.data_type ) { 02139 case VDATA_UL : 02140 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02141 break; 02142 case VDATA_R64 : 02143 if( vector_from_real64( expr->left->sig->value, expr->value->value.r64->val ) ) { 02144 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 02145 } 02146 break; 02147 case VDATA_R32 : 02148 if( vector_from_real64( expr->left->sig->value, (double)expr->value->value.r32->val ) ) { 02149 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 02150 } 02151 break; 02152 default : assert( 0 ); break; 02153 } 02154 02155 PROFILE_END; 02156 02157 return( retval ); 02158 02159 }
bool expression_op_func__nand | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a bitwise NAND operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_bitwise_nand_op(), and vector_set_and_comb_evals().
02601 { PROFILE(EXPRESSION_OP_FUNC__NAND); 02602 02603 /* Perform bitwise NAND operation */ 02604 bool retval = vector_bitwise_nand_op( expr->value, expr->left->value, expr->right->value ); 02605 02606 /* Gather coverage information */ 02607 expression_set_tf_preclear( expr, retval ); 02608 vector_set_and_comb_evals( expr->value, expr->left->value, expr->right->value ); 02609 expression_set_eval_NN( expr ); 02610 02611 PROFILE_END; 02612 02613 return( retval ); 02614 02615 }
bool expression_op_func__nb_call | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a named block call operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, expression_s::elem, ESUPPL_IS_IN_FUNC, FALSE, func_unit_s::first_stmt, expression_s::funit, PROFILE, PROFILE_END, sim_add_thread(), sim_thread(), expression_s::suppl, and TRUE.
04848 { PROFILE(EXPRESSION_OP_FUNC__NB_CALL); 04849 04850 bool retval = FALSE; /* Return value for this function */ 04851 04852 /* Add the thread to the active queue */ 04853 thread* tmp = sim_add_thread( thr, expr->elem.funit->first_stmt, expr->elem.funit, time ); 04854 04855 if( ESUPPL_IS_IN_FUNC( expr->suppl ) ) { 04856 04857 sim_thread( tmp, &(thr->curr_time) ); 04858 retval = TRUE; 04859 04860 } 04861 04862 PROFILE_END; 04863 04864 return( retval ); 04865 04866 }
bool expression_op_func__ne | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a not-equal (!=) comparison operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_ne(), and vector_set_unary_evals().
03703 { PROFILE(EXPRESSION_OP_FUNC__NE); 03704 03705 /* Perform not-equal operation */ 03706 bool retval = vector_op_ne( expr->value, expr->left->value, expr->right->value ); 03707 03708 /* Gather coverage information */ 03709 expression_set_tf_preclear( expr, retval ); 03710 vector_set_unary_evals( expr->value ); 03711 expression_set_eval_NN( expr ); 03712 03713 PROFILE_END; 03714 03715 return( retval ); 03716 03717 }
bool expression_op_func__nedge | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a negative-edge event operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::elem, esuppl_u::eval_t, FALSE, esuppl_u::part, thread_s::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, thread_s::suppl, TRUE, esuppl_u::true, expression_s::tvecs, vector_s::ul, vector_s::value, expression_s::value, vecblk_s::vec, VTYPE_INDEX_EXP_VALH, and VTYPE_INDEX_EXP_VALL.
04386 { PROFILE(EXPRESSION_OP_FUNC__NEDGE); 04387 04388 bool retval; /* Return value for this function */ 04389 ulong nvall = expr->right->value->value.ul[0][VTYPE_INDEX_EXP_VALL]; 04390 ulong nvalh = expr->right->value->value.ul[0][VTYPE_INDEX_EXP_VALH]; 04391 ulong* ovall = &(expr->elem.tvecs->vec[0].value.ul[0][VTYPE_INDEX_EXP_VALL]); 04392 ulong* ovalh = &(expr->elem.tvecs->vec[0].value.ul[0][VTYPE_INDEX_EXP_VALH]); 04393 04394 if( ((*ovalh | *ovall) & (~nvalh & ~nvall)) && thr->suppl.part.exec_first ) { 04395 expr->suppl.part.true = 1; 04396 expr->suppl.part.eval_t = 1; 04397 retval = TRUE; 04398 } else { 04399 expr->suppl.part.eval_t = 0; 04400 retval = FALSE; 04401 } 04402 04403 /* Set left LAST value to current value of right */ 04404 *ovalh = nvalh; 04405 *ovall = nvall; 04406 04407 PROFILE_END; 04408 04409 return( retval ); 04410 04411 }
bool expression_op_func__negate | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a negate of the specified expression.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::elem, expression_set_tf_preclear(), vecblk_s::index, PROFILE, PROFILE_END, expression_s::right, expression_s::tvecs, expression_s::value, vector_op_negate(), and vector_set_unary_evals().
05152 { PROFILE(EXPRESSION_OP_FUNC__NEGATE); 05153 05154 bool retval; /* Return value for this function */ 05155 05156 /* Perform negate operation and gather coverage information */ 05157 expr->elem.tvecs->index = 0; 05158 retval = vector_op_negate( expr->value, expr->right->value ); 05159 05160 /* Gather coverage information */ 05161 expression_set_tf_preclear( expr, retval ); 05162 vector_set_unary_evals( expr->value ); 05163 05164 PROFILE_END; 05165 05166 return( retval ); 05167 05168 }
bool expression_op_func__nor | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a bitwise NOR operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_bitwise_nor_op(), and vector_set_or_comb_evals().
02626 { PROFILE(EXPRESSION_OP_FUNC__NOR); 02627 02628 /* Perform bitwise NOR operation */ 02629 bool retval = vector_bitwise_nor_op( expr->value, expr->left->value, expr->right->value ); 02630 02631 /* Gather coverage information */ 02632 expression_set_tf_preclear( expr, retval ); 02633 vector_set_or_comb_evals( expr->value, expr->left->value, expr->right->value ); 02634 expression_set_eval_NN( expr ); 02635 02636 PROFILE_END; 02637 02638 return( retval ); 02639 02640 }
bool expression_op_func__null | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
No operation is performed -- expression value is assumed to be changed.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References EXP_OP_STATIC, expression_set_tf(), expression_set_tf_preclear(), expression_s::op, PROFILE, PROFILE_END, and TRUE.
04107 { PROFILE(EXPRESSION_OP_FUNC__NULL); 04108 04109 /* Set the true/false indicators as necessary */ 04110 if( expr->op != EXP_OP_STATIC ) { 04111 expression_set_tf_preclear( expr, TRUE ); 04112 } else { 04113 expression_set_tf( expr, TRUE ); 04114 } 04115 04116 PROFILE_END; 04117 04118 return( TRUE ); 04119 04120 }
bool expression_op_func__nxor | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a bitwise NXOR operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_bitwise_nxor_op(), and vector_set_other_comb_evals().
02651 { PROFILE(EXPRESSION_OP_FUNC__NXOR); 02652 02653 /* Perform bitwise NXOR operation */ 02654 bool retval = vector_bitwise_nxor_op( expr->value, expr->left->value, expr->right->value ); 02655 02656 /* Gather coverage information */ 02657 expression_set_tf_preclear( expr, retval ); 02658 vector_set_other_comb_evals( expr->value, expr->left->value, expr->right->value ); 02659 expression_set_eval_NN( expr ); 02660 02661 PROFILE_END; 02662 02663 return( retval ); 02664 02665 }
bool expression_op_func__or | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a bitwise OR operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_bitwise_or_op(), and vector_set_or_comb_evals().
02538 { PROFILE(EXPRESSION_OP_FUNC__OR); 02539 02540 /* Perform bitwise OR operation */ 02541 bool retval = vector_bitwise_or_op( expr->value, expr->left->value, expr->right->value ); 02542 02543 /* Gather coverage information */ 02544 expression_set_tf_preclear( expr, retval ); 02545 vector_set_or_comb_evals( expr->value, expr->left->value, expr->right->value ); 02546 expression_set_eval_NN( expr ); 02547 02548 PROFILE_END; 02549 02550 return( retval ); 02551 02552 }
bool expression_op_func__or_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an OR-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, PROFILE, PROFILE_END, expression_s::right, sim_expression(), TRUE, expression_s::tvecs, expression_s::value, vecblk_s::vec, vector_bitwise_or_op(), vector_copy(), and vector_set_or_comb_evals().
02563 { PROFILE(EXPRESSION_OP_FUNC__OR_A); 02564 02565 bool retval; /* Return value for this function */ 02566 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02567 int intval = 0; /* Integer value */ 02568 02569 /* First, evaluate the left-hand expression */ 02570 (void)sim_expression( expr->left, thr, time, TRUE ); 02571 02572 /* Second, copy the value of the left expression into a temporary vector */ 02573 vector_copy( expr->left->value, tmp ); 02574 02575 /* Third, perform OR operation */ 02576 retval = vector_bitwise_or_op( expr->value, tmp, expr->right->value ); 02577 02578 /* Gather coverage information */ 02579 expression_set_tf_preclear( expr, retval ); 02580 vector_set_or_comb_evals( expr->value, expr->left->value, expr->right->value ); 02581 expression_set_eval_NN( expr ); 02582 02583 /* Finally, assign the new value to the left expression */ 02584 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02585 02586 PROFILE_END; 02587 02588 return( retval ); 02589 02590 }
bool expression_op_func__passign | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a port assignment operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, expression_assign(), expression_set_tf_preclear(), FALSE, thread_s::funit, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, ssuppl_u::part, PROFILE, PROFILE_END, reentrant_create(), thread_s::ren, expression_s::right, expression_s::sig, SSUPPL_TYPE_INPUT_NET, SSUPPL_TYPE_INPUT_REG, SSUPPL_TYPE_OUTPUT_NET, SSUPPL_TYPE_OUTPUT_REG, vsignal_s::suppl, TRUE, ssuppl_u::type, func_unit_s::type, vector_s::ul, vector_s::value, expression_s::value, vector_set_value_ulong(), vsignal_propagate(), and vector_s::width.
05021 { PROFILE(EXPRESSION_OP_FUNC__PASSIGN); 05022 05023 bool retval = FALSE; /* Return value for this function */ 05024 int intval = 0; /* Integer value */ 05025 05026 /* If the current thread is running an automatic function, create a reentrant structure for it */ 05027 if( (thr != NULL) && (thr->ren == NULL) && 05028 ((thr->funit->type == FUNIT_AFUNCTION) || (thr->funit->type == FUNIT_ATASK) || (thr->funit->type == FUNIT_ANAMED_BLOCK)) ) { 05029 thr->ren = reentrant_create( thr->funit ); 05030 } 05031 05032 switch( expr->sig->suppl.part.type ) { 05033 05034 /* If the connected signal is an input type, copy the parameter expression value to this vector */ 05035 case SSUPPL_TYPE_INPUT_NET : 05036 case SSUPPL_TYPE_INPUT_REG : 05037 retval = vector_set_value_ulong( expr->value, expr->right->value->value.ul, expr->right->value->width ); 05038 vsignal_propagate( expr->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 05039 break; 05040 05041 /* 05042 If the connected signal is an output type, do an expression assign from our expression value 05043 to the right expression. 05044 */ 05045 case SSUPPL_TYPE_OUTPUT_NET : 05046 case SSUPPL_TYPE_OUTPUT_REG : 05047 expression_assign( expr->right, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), TRUE, FALSE ); 05048 retval = TRUE; 05049 break; 05050 05051 /* We don't currently support INOUT as these are not used in tasks or functions */ 05052 default : 05053 assert( (expr->sig->suppl.part.type == SSUPPL_TYPE_INPUT_NET) || 05054 (expr->sig->suppl.part.type == SSUPPL_TYPE_INPUT_REG) || 05055 (expr->sig->suppl.part.type == SSUPPL_TYPE_OUTPUT_NET) || 05056 (expr->sig->suppl.part.type == SSUPPL_TYPE_OUTPUT_REG) ); 05057 break; 05058 05059 } 05060 05061 /* Gather coverage information */ 05062 expression_set_tf_preclear( expr, retval ); 05063 05064 PROFILE_END; 05065 05066 return( retval ); 05067 05068 }
bool expression_op_func__pdec | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a postponed decrement operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References cli_debug_mode, thread_s::curr_time, vsuppl_u::data_type, debug_mode, expression_s::elem, expression_display(), flag_use_command_line_debug, vecblk_s::index, expression_s::left, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, vsuppl_u::set, expression_s::sig, vector_s::suppl, TRUE, expression_s::tvecs, vector_s::ul, rv32_s::val, rv64_s::val, vsignal_s::value, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_op_dec(), vector_set_value_ulong(), vsignal_display(), vsignal_propagate(), and vector_s::width.
05308 { PROFILE(EXPRESSION_OP_FUNC__PDEC); 05309 05310 /* Copy the left-hand value to our expression */ 05311 switch( expr->left->value->suppl.part.data_type ) { 05312 case VDATA_UL : (void)vector_set_value_ulong( expr->value, expr->left->value->value.ul, expr->left->value->width ); break; 05313 case VDATA_R64 : expr->value->value.r64->val = expr->left->value->value.r64->val; break; 05314 case VDATA_R32 : expr->value->value.r32->val = expr->left->value->value.r32->val; break; 05315 default : assert( 0 ); break; 05316 } 05317 05318 /* Perform decrement */ 05319 expr->elem.tvecs->index = 0; 05320 if( expr->left->sig != NULL ) { 05321 (void)vector_op_dec( expr->left->sig->value, expr->elem.tvecs ); 05322 expr->left->sig->value->suppl.part.set = 1; 05323 } else { 05324 (void)vector_op_dec( expr->left->value, expr->elem.tvecs ); 05325 } 05326 05327 #ifdef DEBUG_MODE 05328 if( debug_mode && (!flag_use_command_line_debug || cli_debug_mode) ) { 05329 printf( " " ); vsignal_display( expr->left->sig ); 05330 printf( " " ); expression_display( expr->left ); 05331 } 05332 #endif 05333 05334 /* Propagate value change */ 05335 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 05336 05337 PROFILE_END; 05338 05339 return( TRUE ); 05340 05341 }
bool expression_op_func__pedge | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a positive edge event operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::elem, esuppl_u::eval_t, FALSE, esuppl_u::part, thread_s::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, thread_s::suppl, TRUE, esuppl_u::true, expression_s::tvecs, vector_s::ul, vector_s::value, expression_s::value, vecblk_s::vec, VTYPE_INDEX_EXP_VALH, and VTYPE_INDEX_EXP_VALL.
04350 { PROFILE(EXPRESSION_OP_FUNC__PEDGE); 04351 04352 bool retval; /* Return value for this function */ 04353 ulong nvall = expr->right->value->value.ul[0][VTYPE_INDEX_EXP_VALL]; 04354 ulong nvalh = expr->right->value->value.ul[0][VTYPE_INDEX_EXP_VALH]; 04355 ulong* ovall = &(expr->elem.tvecs->vec[0].value.ul[0][VTYPE_INDEX_EXP_VALL]); 04356 ulong* ovalh = &(expr->elem.tvecs->vec[0].value.ul[0][VTYPE_INDEX_EXP_VALH]); 04357 04358 if( ((*ovalh | ~(*ovall)) & (~nvalh & nvall)) && thr->suppl.part.exec_first ) { 04359 expr->suppl.part.true = 1; 04360 expr->suppl.part.eval_t = 1; 04361 retval = TRUE; 04362 } else { 04363 expr->suppl.part.eval_t = 0; 04364 retval = FALSE; 04365 } 04366 04367 /* Set left LAST value to current value of right */ 04368 *ovalh = nvalh; 04369 *ovall = nvall; 04370 04371 PROFILE_END; 04372 04373 return( retval ); 04374 04375 }
bool expression_op_func__pinc | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a postponed increment operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References cli_debug_mode, thread_s::curr_time, vsuppl_u::data_type, debug_mode, expression_s::elem, flag_use_command_line_debug, vecblk_s::index, expression_s::left, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, vsuppl_u::set, expression_s::sig, vector_s::suppl, TRUE, expression_s::tvecs, vector_s::ul, rv32_s::val, rv64_s::val, vsignal_s::value, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_op_inc(), vector_set_value_ulong(), vsignal_display(), vsignal_propagate(), and vector_s::width.
05222 { PROFILE(EXPRESSION_OP_FUNC__PINC); 05223 05224 /* Copy the left-hand value to our expression */ 05225 switch( expr->left->value->suppl.part.data_type ) { 05226 case VDATA_UL : (void)vector_set_value_ulong( expr->value, expr->left->value->value.ul, expr->left->value->width ); break; 05227 case VDATA_R64 : expr->value->value.r64->val = expr->left->value->value.r64->val; break; 05228 case VDATA_R32 : expr->value->value.r32->val = expr->left->value->value.r32->val; break; 05229 default : assert( 0 ); break; 05230 } 05231 05232 /* Perform increment */ 05233 expr->elem.tvecs->index = 0; 05234 if( expr->left->sig != NULL ) { 05235 (void)vector_op_inc( expr->left->sig->value, expr->elem.tvecs ); 05236 expr->left->sig->value->suppl.part.set = 1; 05237 } else { 05238 (void)vector_op_inc( expr->left->value, expr->elem.tvecs ); 05239 } 05240 05241 #ifdef DEBUG_MODE 05242 if( debug_mode && (!flag_use_command_line_debug || cli_debug_mode) ) { 05243 printf( " " ); vsignal_display( expr->left->sig ); 05244 } 05245 #endif 05246 05247 /* Propagate value change */ 05248 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 05249 05250 PROFILE_END; 05251 05252 return( TRUE ); 05253 05254 }
bool expression_op_func__random | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs the $random system call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, EXP_OP_DIM, EXP_OP_MBIT_SEL, EXP_OP_SASSIGN, EXP_OP_SBIT_SEL, EXP_OP_SIG, expression_assign(), FALSE, expression_s::left, expression_s::op, PROFILE, PROFILE_END, expression_s::right, sys_task_random(), TRUE, expression_s::value, vector_from_int(), and vector_to_int().
02961 { PROFILE(EXPRESSION_OP_FUNC__RANDOM); 02962 02963 long rand; 02964 02965 /* If $random contains a seed parameter, get it */ 02966 if( (expr->left != NULL) && (expr->left->op == EXP_OP_SASSIGN) ) { 02967 02968 int intval = 0; 02969 exp_op_type op = expr->left->right->op; 02970 long seed = (long)vector_to_int( expr->left->value ); 02971 02972 /* Get random number from seed */ 02973 rand = sys_task_random( &seed ); 02974 02975 /* Store seed value */ 02976 if( (op == EXP_OP_SIG) || (op == EXP_OP_SBIT_SEL) || (op == EXP_OP_MBIT_SEL) || (op == EXP_OP_DIM) ) { 02977 (void)vector_from_int( expr->left->value, seed ); 02978 expression_assign( expr->left->right, expr->left, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), TRUE, FALSE ); 02979 } 02980 02981 } else { 02982 02983 /* Get random value using existing seed value */ 02984 rand = sys_task_random( NULL ); 02985 02986 } 02987 02988 /* Convert it to a vector and store it */ 02989 (void)vector_from_int( expr->value, (int)rand ); 02990 02991 PROFILE_END; 02992 02993 return( TRUE ); 02994 02995 }
bool expression_op_func__realtime | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs the $realtime system call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, sim_time_s::full, thread_s::funit, PROFILE, PROFILE_END, func_unit_s::timescale, expression_s::value, and vector_from_real64().
02938 { PROFILE(EXPRESSION_OP_FUNC__REALTIME); 02939 02940 bool retval; 02941 02942 assert( thr != NULL ); 02943 02944 retval = vector_from_real64( expr->value, ((real64)thr->curr_time.full / thr->funit->timescale) ); 02945 02946 PROFILE_END; 02947 02948 return( retval ); 02949 02950 }
bool expression_op_func__realtobits | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $realtobits system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References vsuppl_u::data_type, EXP_OP_SASSIGN, FATAL, func_unit_s::filename, thread_s::funit, expression_s::left, expression_s::line, expression_s::op, vsuppl_u::part, print_output(), PROFILE, PROFILE_END, vector_s::r64, vector_s::suppl, sys_task_realtobits(), Throw, user_msg, USER_MSG_LENGTH, rv64_s::val, vector_s::value, expression_s::value, VDATA_R64, VDATA_UL, and vector_from_uint64().
03167 { PROFILE(EXPRESSION_OP_FUNC__REALTOBITS); 03168 03169 expression* left = expr->left; 03170 uint64 u64; 03171 bool retval; 03172 03173 /* Check to make sure that there is exactly one parameter */ 03174 if( (left == NULL) || (left->op != EXP_OP_SASSIGN) ) { 03175 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$realtobits called with incorrect number of parameters (file: %s, line: %d)", thr->funit->filename, expr->line ); 03176 assert( rv < USER_MSG_LENGTH ); 03177 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03178 Throw 0; 03179 } 03180 03181 /* Check to make sure that the parameter is a real */ 03182 if( left->value->suppl.part.data_type != VDATA_R64 ) { 03183 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$realtobits called without real parameter (file: %s, line: %d)", thr->funit->filename, expr->line ); 03184 assert( rv < USER_MSG_LENGTH ); 03185 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03186 Throw 0; 03187 } 03188 03189 /* Make sure that the storage vector is a bits type */ 03190 assert( expr->value->suppl.part.data_type == VDATA_UL ); 03191 03192 /* Convert and store the data */ 03193 retval = vector_from_uint64( expr->value, sys_task_realtobits( left->value->value.r64->val ) ); 03194 03195 PROFILE_END; 03196 03197 return( retval ); 03198 03199 }
bool expression_op_func__repeat | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a repeat loop operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, vector_s::ul, vector_s::value, expression_s::value, vector_from_int(), vector_op_lt(), vector_set_unary_evals(), vector_to_int(), and VTYPE_INDEX_VAL_VALL.
Referenced by expression_op_func__repeat_dly().
04941 { PROFILE(EXPRESSION_OP_FUNC__REPEAT); 04942 04943 bool retval; /* Return value for this function */ 04944 04945 retval = vector_op_lt( expr->value, expr->left->value, expr->right->value ); 04946 04947 if( expr->value->value.ul[0][VTYPE_INDEX_VAL_VALL] == 0 ) { 04948 (void)vector_from_int( expr->left->value, 0 ); 04949 } else { 04950 (void)vector_from_int( expr->left->value, (vector_to_int( expr->left->value ) + 1) ); 04951 } 04952 04953 /* Gather coverage information */ 04954 expression_set_tf_preclear( expr, retval ); 04955 vector_set_unary_evals( expr->value ); 04956 04957 PROFILE_END; 04958 04959 return( retval ); 04960 04961 }
bool expression_op_func__repeat_dly | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a repeated delay for a given assignment.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References esuppl_u::eval_t, expression_op_func__repeat(), FALSE, exp_info_s::func, expression_s::left, expression_s::op, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, TRUE, vector_s::ul, vector_s::value, expression_s::value, and VTYPE_INDEX_VAL_VALL.
05416 { PROFILE(EXPRESSION_OP_FUNC__REPEAT_DLY); 05417 05418 bool retval = FALSE; /* Return value for this function */ 05419 05420 /* If the delay condition has been met, call the repeat operation */ 05421 if( exp_op_info[expr->right->op].func( expr->right, thr, time ) ) { 05422 05423 /* Execute repeat operation */ 05424 (void)expression_op_func__repeat( expr->left, thr, time ); 05425 05426 /* If the repeat operation evaluated to TRUE, perform delay operation */ 05427 if( expr->left->value->value.ul[0][VTYPE_INDEX_VAL_VALL] == 1 ) { 05428 (void)exp_op_info[expr->right->op].func( expr->right, thr, time ); 05429 expr->suppl.part.eval_t = 0; 05430 05431 /* Otherwise, we are done with the repeat/delay sequence */ 05432 } else { 05433 expr->suppl.part.eval_t = 1; 05434 retval = TRUE; 05435 } 05436 05437 } 05438 05439 PROFILE_END; 05440 05441 return( retval ); 05442 05443 }
bool expression_op_func__rshift | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a right shift operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_op_rshift(), and vector_set_unary_evals().
02789 { PROFILE(EXPRESSION_OP_FUNC__RSHIFT); 02790 02791 /* Perform right-shift operation */ 02792 bool retval = vector_op_rshift( expr->value, expr->left->value, expr->right->value ); 02793 02794 /* Gather coverage information */ 02795 expression_set_tf_preclear( expr, retval ); 02796 vector_set_unary_evals( expr->value ); 02797 expression_set_eval_NN( expr ); 02798 02799 PROFILE_END; 02800 02801 return( retval ); 02802 02803 }
bool expression_op_func__rshift_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an right-shift-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, PROFILE, PROFILE_END, expression_s::right, sim_expression(), TRUE, expression_s::tvecs, expression_s::value, vecblk_s::vec, vector_copy(), vector_op_rshift(), and vector_set_unary_evals().
02814 { PROFILE(EXPRESSION_OP_FUNC__RSHIFT_A); 02815 02816 bool retval; /* Return value for this function */ 02817 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02818 int intval = 0; /* Integer value */ 02819 02820 /* First, evaluate the left-hand expression */ 02821 (void)sim_expression( expr->left, thr, time, TRUE ); 02822 02823 /* Second, copy the value of the left expression into a temporary vector */ 02824 vector_copy( expr->left->value, tmp ); 02825 02826 /* Third, perform right-shift and collect coverage information */ 02827 retval = vector_op_rshift( expr->value, tmp, expr->right->value ); 02828 02829 /* Gather coverage information */ 02830 expression_set_tf_preclear( expr, retval ); 02831 vector_set_unary_evals( expr->value ); 02832 expression_set_eval_NN( expr ); 02833 02834 /* Finally, assign the new value to the left expression */ 02835 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02836 02837 PROFILE_END; 02838 02839 return( retval ); 02840 02841 }
bool expression_op_func__rtoi | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $rtoi system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References vsuppl_u::data_type, EXP_OP_SASSIGN, FATAL, func_unit_s::filename, thread_s::funit, expression_s::left, expression_s::line, expression_s::op, vsuppl_u::part, print_output(), PROFILE, PROFILE_END, vector_s::r64, vector_s::suppl, sys_task_rtoi(), Throw, user_msg, USER_MSG_LENGTH, rv64_s::val, vector_s::value, expression_s::value, VDATA_R64, VDATA_UL, and vector_from_int().
03373 { PROFILE(EXPRESSION_OP_FUNC__RTOI); 03374 03375 expression* left = expr->left; 03376 uint64 u64; 03377 bool retval; 03378 03379 /* Check to make sure that there is exactly one parameter */ 03380 if( (left == NULL) || (left->op != EXP_OP_SASSIGN) ) { 03381 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$rtoi called with incorrect number of parameters (file: %s, line: %d)", thr->funit->filename, expr->line ); 03382 assert( rv < USER_MSG_LENGTH ); 03383 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03384 Throw 0; 03385 } 03386 03387 /* Check to make sure that the parameter is a real */ 03388 if( left->value->suppl.part.data_type != VDATA_R64 ) { 03389 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$rtoi called without real parameter (file: %s, line: %d)", thr->funit->filename, expr->line ); 03390 assert( rv < USER_MSG_LENGTH ); 03391 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03392 Throw 0; 03393 } 03394 03395 /* Make sure that the storage vector is a bits type */ 03396 assert( expr->value->suppl.part.data_type == VDATA_UL ); 03397 03398 /* Convert and store the data */ 03399 retval = vector_from_int( expr->value, sys_task_rtoi( left->value->value.r64->val ) ); 03400 03401 PROFILE_END; 03402 03403 return( retval ); 03404 03405 }
bool expression_op_func__sassign | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a system task port assignment.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References vsuppl_u::data_type, DEQ, FEQ, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, expression_s::right, vector_s::suppl, vector_s::ul, rv32_s::val, rv64_s::val, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_set_value_ulong(), and vector_s::width.
03006 { PROFILE(EXPRESSION_OP_FUNC__SASSIGN); 03007 03008 bool retval; 03009 03010 switch( expr->value->suppl.part.data_type ) { 03011 case VDATA_UL : retval = vector_set_value_ulong( expr->value, expr->right->value->value.ul, expr->right->value->width ); break; 03012 case VDATA_R64 : 03013 { 03014 double real = expr->right->value->value.r64->val; 03015 retval = !DEQ( expr->value->value.r64->val, real ); 03016 expr->value->value.r64->val = real; 03017 } 03018 break; 03019 case VDATA_R32 : 03020 { 03021 float real = expr->right->value->value.r32->val; 03022 retval = !FEQ( expr->value->value.r32->val, real ); 03023 expr->value->value.r32->val = real; 03024 } 03025 break; 03026 default : assert( 0 ); break; 03027 } 03028 03029 PROFILE_END; 03030 03031 return( retval ); 03032 03033 }
bool expression_op_func__sbit | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a single bit select operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References exp_dim_s::curr_lsb, 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, ESUPPL_IS_ROOT, EXP_OP_DIM, expr_stmt_u::expr, expression_set_tf_preclear(), exp_dim_s::last, expression_s::left, esuppl_u::nba, expression_s::op, expression_s::parent, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::sig, expression_s::suppl, TRUE, vsignal_s::value, expression_s::value, vector_part_select_pull(), vector_to_int(), and vector_s::width.
04157 { PROFILE(EXPRESSION_OP_FUNC__SBIT); 04158 04159 bool retval; 04160 exp_dim* dim = (expr->suppl.part.nba == 0) ? expr->elem.dim : expr->elem.dim_nba->dim; 04161 int curr_lsb; 04162 int intval = (vector_to_int( expr->left->value ) - dim->dim_lsb) * dim->dim_width; 04163 int prev_lsb; 04164 int vwidth; 04165 04166 /* Calculate starting bit position and width */ 04167 if( (ESUPPL_IS_ROOT( expr->suppl ) == 0) && (expr->parent->expr->op == EXP_OP_DIM) && (expr->parent->expr->right == expr) ) { 04168 vwidth = expr->parent->expr->left->value->width; 04169 prev_lsb = expr->parent->expr->left->elem.dim->curr_lsb; 04170 } else { 04171 vwidth = expr->sig->value->width; 04172 prev_lsb = 0; 04173 } 04174 04175 if( dim->dim_be ) { 04176 curr_lsb = (prev_lsb + (vwidth - (intval + (int)expr->value->width))); 04177 } else { 04178 curr_lsb = (prev_lsb + intval); 04179 } 04180 04181 /* If we are the last dimension to be calculated, perform the bit pull */ 04182 if( dim->last ) { 04183 retval = vector_part_select_pull( expr->value, expr->sig->value, curr_lsb, ((curr_lsb + expr->value->width) - 1), TRUE ); 04184 } else { 04185 retval = (dim->curr_lsb != curr_lsb); 04186 } 04187 04188 /* Set current LSB dimensional information */ 04189 dim->curr_lsb = curr_lsb; 04190 04191 /* Gather coverage information */ 04192 expression_set_tf_preclear( expr, retval ); 04193 04194 PROFILE_END; 04195 04196 return( retval ); 04197 04198 }
bool expression_op_func__shortrealtobits | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $shortrealtobits system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References vsuppl_u::data_type, EXP_OP_SASSIGN, FATAL, func_unit_s::filename, thread_s::funit, expression_s::left, expression_s::line, expression_s::op, vsuppl_u::part, print_output(), PROFILE, PROFILE_END, vector_s::r64, vector_s::suppl, sys_task_shortrealtobits(), Throw, user_msg, USER_MSG_LENGTH, rv64_s::val, vector_s::value, expression_s::value, VDATA_R64, VDATA_UL, and vector_from_uint64().
03250 { PROFILE(EXPRESSION_OP_FUNC__SHORTREALTOBITS); 03251 03252 expression* left = expr->left; 03253 uint64 u64; 03254 bool retval; 03255 03256 /* Check to make sure that there is exactly one parameter */ 03257 if( (left == NULL) || (left->op != EXP_OP_SASSIGN) ) { 03258 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$shortrealtobits called with incorrect number of parameters (file: %s, line: %d)", thr->funit->filename, expr->line ); 03259 assert( rv < USER_MSG_LENGTH ); 03260 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03261 Throw 0; 03262 } 03263 03264 /* Check to make sure that the parameter is a real */ 03265 if( left->value->suppl.part.data_type != VDATA_R64 ) { 03266 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$shortrealtobits called without real parameter (file: %s, line: %d)", thr->funit->filename, expr->line ); 03267 assert( rv < USER_MSG_LENGTH ); 03268 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03269 Throw 0; 03270 } 03271 03272 /* Make sure that the storage vector is a bits type */ 03273 assert( expr->value->suppl.part.data_type == VDATA_UL ); 03274 03275 /* Convert and store the data */ 03276 retval = vector_from_uint64( expr->value, sys_task_shortrealtobits( left->value->value.r64->val ) ); 03277 03278 PROFILE_END; 03279 03280 return( retval ); 03281 03282 }
bool expression_op_func__sig | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a signal operation. This function should be called by any operation that would otherwise call the expression_op_func__null operation but have a valid signal pointer. We just need to copy the unknown and not_zero bits from the signal's vector supplemental field to our own.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References EXP_OP_PARAM, expression_set_tf(), expression_set_tf_preclear(), expression_s::op, PROFILE, PROFILE_END, and TRUE.
04133 { PROFILE(EXPRESSION_OP_FUNC__SIG); 04134 04135 /* Gather coverage information */ 04136 if( expr->op != EXP_OP_PARAM ) { 04137 expression_set_tf_preclear( expr, TRUE ); 04138 } else { 04139 expression_set_tf( expr, TRUE ); 04140 } 04141 04142 PROFILE_END; 04143 04144 return( TRUE ); 04145 04146 }
bool expression_op_func__signed | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $signed system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::left, PROFILE, PROFILE_END, TRUE, expression_s::value, and vector_copy().
03545 { PROFILE(EXPRESSION_OP_FUNC__SIGNED); 03546 03547 vector_copy( expr->left->value, expr->value ); 03548 03549 PROFILE_END; 03550 03551 return( TRUE ); 03552 03553 }
bool expression_op_func__slist | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a sensitivity list operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References ESUPPL_IS_TRUE, esuppl_u::eval_t, FALSE, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, TRUE, and esuppl_u::true.
04508 { PROFILE(EXPRESSION_OP_FUNC__SLIST); 04509 04510 bool retval; /* Return value for this function */ 04511 04512 if( ESUPPL_IS_TRUE( expr->right->suppl ) == 1 ) { 04513 04514 expr->suppl.part.eval_t = 1; 04515 expr->suppl.part.true = 1; 04516 retval = TRUE; 04517 04518 /* Clear eval_t bit in right expression */ 04519 expr->right->suppl.part.eval_t = 0; 04520 04521 } else { 04522 04523 expr->suppl.part.eval_t = 0; 04524 retval = FALSE; 04525 04526 } 04527 04528 PROFILE_END; 04529 04530 return( retval ); 04531 04532 }
bool expression_op_func__srandom | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $srandom system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References EXP_OP_SASSIGN, expression_s::left, expression_s::op, PROFILE, PROFILE_END, sys_task_srandom(), TRUE, expression_s::value, and vector_to_int().
03044 { PROFILE(EXPRESSION_OP_FUNC__SRANDOM); 03045 03046 assert( (expr->left != NULL) && (expr->left->op == EXP_OP_SASSIGN) ); 03047 03048 /* Get the seed value and set it */ 03049 sys_task_srandom( (long)vector_to_int( expr->left->value ) ); 03050 03051 PROFILE_END; 03052 03053 return( TRUE ); 03054 03055 }
bool expression_op_func__stop | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $stop statement operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References FALSE, PROFILE, PROFILE_END, and sim_stop().
05529 { PROFILE(EXPRESSION_OP_FUNC__STOP); 05530 05531 sim_stop(); 05532 05533 PROFILE_END; 05534 05535 return( FALSE ); 05536 05537 }
bool expression_op_func__sub_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a subtract-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, vsuppl_u::data_type, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, vecblk_s::index, expression_s::left, vsuppl_u::part, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, expression_s::right, expression_s::sig, sim_expression(), vector_s::suppl, TRUE, expression_s::tvecs, rv32_s::val, rv64_s::val, vector_s::value, vsignal_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vecblk_s::vec, vector_copy(), vector_from_real64(), vector_op_subtract(), vector_set_other_comb_evals(), and vsignal_propagate().
02421 { PROFILE(EXPRESSION_OP_FUNC__SUB_A); 02422 02423 bool retval; /* Return value for this function */ 02424 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02425 int intval = 0; /* Integer value */ 02426 02427 /* First, evaluate the left-hand expression */ 02428 (void)sim_expression( expr->left, thr, time, TRUE ); 02429 02430 /* Second, copy the value of the left expression into a temporary vector */ 02431 vector_copy( expr->left->value, tmp ); 02432 02433 /* Third, perform subtraction */ 02434 expr->elem.tvecs->index = 1; 02435 retval = vector_op_subtract( expr->value, tmp, expr->right->value ); 02436 02437 /* Gather coverage information */ 02438 expression_set_tf_preclear( expr, retval ); 02439 vector_set_other_comb_evals( expr->value, expr->left->value, expr->right->value ); 02440 expression_set_eval_NN( expr ); 02441 02442 /* Finally, assign the new value to the left expression */ 02443 switch( expr->value->suppl.part.data_type ) { 02444 case VDATA_UL : 02445 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02446 break; 02447 case VDATA_R64 : 02448 if( vector_from_real64( expr->left->sig->value, expr->value->value.r64->val ) ) { 02449 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 02450 } 02451 break; 02452 case VDATA_R32 : 02453 if( vector_from_real64( expr->left->sig->value, (double)expr->value->value.r32->val ) ) { 02454 vsignal_propagate( expr->left->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 02455 } 02456 break; 02457 default : assert( 0 ); break; 02458 } 02459 02460 PROFILE_END; 02461 02462 return( retval ); 02463 02464 }
bool expression_op_func__subtract | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a subtraction operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::elem, expression_set_eval_NN(), expression_set_tf_preclear(), vecblk_s::index, expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::tvecs, expression_s::value, vector_op_subtract(), and vector_set_other_comb_evals().
02393 { PROFILE(EXPRESSION_OP_FUNC__SUBTRACT); 02394 02395 bool retval; /* Return value for this function */ 02396 02397 /* Perform SUBTRACT operation */ 02398 expr->elem.tvecs->index = 0; 02399 retval = vector_op_subtract( expr->value, expr->left->value, expr->right->value ); 02400 02401 /* Gather coverage information */ 02402 expression_set_tf_preclear( expr, retval ); 02403 vector_set_other_comb_evals( expr->value, expr->left->value, expr->right->value ); 02404 expression_set_eval_NN( expr ); 02405 02406 PROFILE_END; 02407 02408 return( retval ); 02409 02410 }
bool expression_op_func__task_call | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a task call operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::elem, FALSE, func_unit_s::first_stmt, expression_s::funit, PROFILE, PROFILE_END, sim_add_thread(), expression_s::value, and vector_set_unary_evals().
04826 { PROFILE(EXPRESSION_OP_FUNC__TASK_CALL); 04827 04828 (void)sim_add_thread( thr, expr->elem.funit->first_stmt, expr->elem.funit, time ); 04829 04830 /* Gather coverage information */ 04831 vector_set_unary_evals( expr->value ); 04832 04833 PROFILE_END; 04834 04835 return( FALSE ); 04836 04837 }
bool expression_op_func__test_plusargs | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $test$plusargs system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::exec_num, EXP_OP_SASSIGN, expression_set_tf_preclear(), FALSE, FATAL, func_unit_s::filename, free_safe, thread_s::funit, expression_s::left, expression_s::line, expression_s::op, print_output(), PROFILE, PROFILE_END, QSTRING, sys_task_test_plusargs(), Throw, TRUE, user_msg, USER_MSG_LENGTH, expression_s::value, vector_set_coverage_and_assign_ulong(), vector_set_unary_evals(), and vector_to_string().
03416 { PROFILE(EXPRESSION_OP_FUNC__TEST_PLUSARGS); 03417 03418 bool retval = FALSE; 03419 03420 /* Only evaluate this expression if it has not been evaluated yet */ 03421 if( expr->exec_num == 0 ) { 03422 03423 expression* left = expr->left; 03424 uint64 u64; 03425 char* arg; 03426 ulong scratchl; 03427 ulong scratchh = 0; 03428 03429 /* Check to make sure that there is exactly one parameter */ 03430 if( (left == NULL) || (left->op != EXP_OP_SASSIGN) ) { 03431 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$test$plusargs called with incorrect number of parameters (file: %s, line: %d)", thr->funit->filename, expr->line ); 03432 assert( rv < USER_MSG_LENGTH ); 03433 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03434 Throw 0; 03435 } 03436 03437 /* Get argument to search for */ 03438 arg = vector_to_string( left->value, QSTRING, TRUE, 0 ); 03439 03440 /* Scan the simulation argument list for matching values */ 03441 scratchl = sys_task_test_plusargs( arg ); 03442 03443 /* Perform coverage and assignment */ 03444 retval = vector_set_coverage_and_assign_ulong( expr->value, &scratchl, &scratchh, 0, 0 ); 03445 03446 /* Deallocate memory */ 03447 free_safe( arg, (strlen( arg ) + 1) ); 03448 03449 } 03450 03451 /* Gather coverage information */ 03452 expression_set_tf_preclear( expr, retval ); 03453 vector_set_unary_evals( expr->value ); 03454 03455 PROFILE_END; 03456 03457 return( retval ); 03458 03459 }
bool expression_op_func__time | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs the $time system call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, sim_time_s::full, thread_s::funit, PROFILE, PROFILE_END, func_unit_s::timescale, expression_s::value, and vector_from_uint64().
02915 { PROFILE(EXPRESSION_OP_FUNC__TIME); 02916 02917 bool retval; 02918 02919 assert( thr != NULL ); 02920 02921 retval = vector_from_uint64( expr->value, (thr->curr_time.full / thr->funit->timescale) ); 02922 02923 PROFILE_END; 02924 02925 return( retval ); 02926 02927 }
bool expression_op_func__trigger | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an event trigger (->) operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, PROFILE, PROFILE_END, expression_s::sig, TRUE, vector_s::ul, vector_s::value, vsignal_s::value, vsignal_propagate(), VTYPE_INDEX_SIG_VALH, and VTYPE_INDEX_SIG_VALL.
04593 { PROFILE(EXPRESSION_OP_FUNC__TRIGGER); 04594 04595 /* Indicate that we have triggered */ 04596 expr->sig->value->value.ul[0][VTYPE_INDEX_SIG_VALL] = 1; 04597 expr->sig->value->value.ul[0][VTYPE_INDEX_SIG_VALH] = 0; 04598 04599 /* Propagate event */ 04600 vsignal_propagate( expr->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 04601 04602 PROFILE_END; 04603 04604 return( TRUE ); 04605 04606 }
bool expression_op_func__uand | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a unary AND operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_set_unary_evals(), and vector_unary_and().
03939 { PROFILE(EXPRESSION_OP_FUNC__UAND); 03940 03941 /* Perform unary AND operation */ 03942 bool retval = vector_unary_and( expr->value, expr->right->value ); 03943 03944 /* Gather coverage information */ 03945 expression_set_tf_preclear( expr, retval ); 03946 vector_set_unary_evals( expr->value ); 03947 03948 PROFILE_END; 03949 03950 return( retval ); 03951 03952 }
bool expression_op_func__uinv | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a unary invert operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_set_unary_evals(), and vector_unary_inv().
03915 { PROFILE(EXPRESSION_OP_FUNC__UINV); 03916 03917 /* Perform unary inversion operation */ 03918 bool retval = vector_unary_inv( expr->value, expr->right->value ); 03919 03920 /* Gather coverage information */ 03921 expression_set_tf_preclear( expr, retval ); 03922 vector_set_unary_evals( expr->value ); 03923 03924 PROFILE_END; 03925 03926 return( retval ); 03927 03928 }
bool expression_op_func__unand | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a unary NAND operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_set_unary_evals(), and vector_unary_nand().
04035 { PROFILE(EXPRESSION_OP_FUNC__UNAND); 04036 04037 /* Perform unary NAND operation */ 04038 bool retval = vector_unary_nand( expr->value, expr->right->value ); 04039 04040 /* Gather coverage information */ 04041 expression_set_tf_preclear( expr, retval ); 04042 vector_set_unary_evals( expr->value ); 04043 04044 PROFILE_END; 04045 04046 return( retval ); 04047 04048 }
bool expression_op_func__unor | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a unary NOR operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_set_unary_evals(), and vector_unary_nor().
04059 { PROFILE(EXPRESSION_OP_FUNC__UNOR); 04060 04061 /* Perform unary NOR operation */ 04062 bool retval = vector_unary_nor( expr->value, expr->right->value ); 04063 04064 /* Gather coverage information */ 04065 expression_set_tf_preclear( expr, retval ); 04066 vector_set_unary_evals( expr->value ); 04067 04068 PROFILE_END; 04069 04070 return( retval ); 04071 04072 }
bool expression_op_func__unot | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a unary NOT operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_set_unary_evals(), and vector_unary_not().
03963 { PROFILE(EXPRESSION_OP_FUNC__UNOT); 03964 03965 /* Perform unary NOT operation */ 03966 bool retval = vector_unary_not( expr->value, expr->right->value ); 03967 03968 /* Gather coverage information */ 03969 expression_set_tf_preclear( expr, retval ); 03970 vector_set_unary_evals( expr->value ); 03971 03972 PROFILE_END; 03973 03974 return( retval ); 03975 03976 }
bool expression_op_func__unsigned | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $unsigned system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_s::left, PROFILE, PROFILE_END, TRUE, expression_s::value, and vector_copy().
03564 { PROFILE(EXPRESSION_OP_FUNC__UNSIGNED); 03565 03566 vector_copy( expr->left->value, expr->value ); 03567 03568 PROFILE_END; 03569 03570 return( TRUE ); 03571 03572 }
bool expression_op_func__unxor | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a unary NXOR operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_set_unary_evals(), and vector_unary_nxor().
04083 { PROFILE(EXPRESSION_OP_FUNC__UNXOR); 04084 04085 /* Perform unary NXOR operation */ 04086 bool retval = vector_unary_nxor( expr->value, expr->right->value ); 04087 04088 /* Gather coverage information */ 04089 expression_set_tf_preclear( expr, retval ); 04090 vector_set_unary_evals( expr->value ); 04091 04092 PROFILE_END; 04093 04094 return( retval ); 04095 04096 }
bool expression_op_func__uor | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a unary OR operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_set_unary_evals(), and vector_unary_or().
03987 { PROFILE(EXPRESSION_OP_FUNC__UOR); 03988 03989 /* Perform unary OR operation */ 03990 bool retval = vector_unary_or( expr->value, expr->right->value ); 03991 03992 /* Gather coverage information */ 03993 expression_set_tf_preclear( expr, retval ); 03994 vector_set_unary_evals( expr->value ); 03995 03996 PROFILE_END; 03997 03998 return( retval ); 03999 04000 }
bool expression_op_func__urandom | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $urandom system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, EXP_OP_DIM, EXP_OP_MBIT_SEL, EXP_OP_SASSIGN, EXP_OP_SBIT_SEL, EXP_OP_SIG, expression_assign(), FALSE, expression_s::left, expression_s::op, PROFILE, PROFILE_END, expression_s::right, sys_task_urandom(), TRUE, expression_s::value, vector_from_int(), vector_from_uint64(), and vector_to_int().
03066 { PROFILE(EXPRESSION_OP_FUNC__URANDOM); 03067 03068 unsigned long rand; 03069 bool retval; 03070 03071 /* If $random contains a seed parameter, get it */ 03072 if( (expr->left != NULL) && (expr->left->op == EXP_OP_SASSIGN) ) { 03073 03074 int intval = 0; 03075 exp_op_type op = expr->left->right->op; 03076 long seed = (long)vector_to_int( expr->left->value ); 03077 03078 /* Get random number from seed */ 03079 rand = sys_task_urandom( &seed ); 03080 03081 /* Store seed value */ 03082 if( (op == EXP_OP_SIG) || (op == EXP_OP_SBIT_SEL) || (op == EXP_OP_MBIT_SEL) || (op == EXP_OP_DIM) ) { 03083 (void)vector_from_int( expr->left->value, seed ); 03084 expression_assign( expr->left->right, expr->left, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), TRUE, FALSE ); 03085 } 03086 03087 } else { 03088 03089 /* Get random value using existing seed value */ 03090 rand = sys_task_urandom( NULL ); 03091 03092 } 03093 03094 /* Convert it to a vector and store it */ 03095 retval = vector_from_uint64( expr->value, (uint64)rand ); 03096 03097 PROFILE_END; 03098 03099 return( retval ); 03100 03101 }
bool expression_op_func__urandom_range | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $urandom_range system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References EXP_OP_PLIST, EXP_OP_SASSIGN, FATAL, func_unit_s::filename, thread_s::funit, expression_s::left, expression_s::line, expression_s::op, print_output(), PROFILE, PROFILE_END, expression_s::right, sys_task_urandom_range(), Throw, user_msg, USER_MSG_LENGTH, expression_s::value, vector_from_uint64(), and vector_to_uint64().
03112 { PROFILE(EXPRESSION_OP_FUNC__URANDOM_RANGE); 03113 03114 expression* plist = expr->left; 03115 unsigned long max; 03116 unsigned long min = 0; 03117 unsigned long rand; 03118 bool retval; 03119 03120 if( (plist == NULL) || ((plist->op != EXP_OP_PLIST) && (plist->op != EXP_OP_SASSIGN)) ) { 03121 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$urandom_range called without any parameters specified (file: %s, line: %d)", thr->funit->filename, expr->line ); 03122 assert( rv < USER_MSG_LENGTH ); 03123 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03124 Throw 0; 03125 } 03126 03127 if( plist->op == EXP_OP_SASSIGN ) { 03128 03129 /* This value should be max value */ 03130 max = (long)vector_to_uint64( plist->value ); 03131 03132 } else { 03133 03134 assert( (plist->left != NULL) && (plist->left->op == EXP_OP_SASSIGN) ); 03135 03136 /* Get max value */ 03137 max = (long)vector_to_uint64( plist->left->value ); 03138 03139 /* Get min value if it has been specified */ 03140 if( (plist->right != NULL) && (plist->right->op == EXP_OP_SASSIGN) ) { 03141 min = (long)vector_to_uint64( plist->right->value ); 03142 } 03143 03144 } 03145 03146 /* Get random number from seed */ 03147 rand = sys_task_urandom_range( max, min ); 03148 03149 /* Convert it to a vector and store it */ 03150 retval = vector_from_uint64( expr->value, (uint64)rand ); 03151 03152 PROFILE_END; 03153 03154 return( retval ); 03155 03156 }
bool expression_op_func__uxor | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a unary XOR operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_tf_preclear(), PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_set_unary_evals(), and vector_unary_xor().
04011 { PROFILE(EXPRESSION_OP_FUNC__UXOR); 04012 04013 /* Perform unary XOR operation */ 04014 bool retval = vector_unary_xor( expr->value, expr->right->value ); 04015 04016 /* Gather coverage information */ 04017 expression_set_tf_preclear( expr, retval ); 04018 vector_set_unary_evals( expr->value ); 04019 04020 PROFILE_END; 04021 04022 return( retval ); 04023 04024 }
bool expression_op_func__value_plusargs | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a $value$plusargs system task call.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, vsuppl_u::data_type, expression_s::exec_num, EXP_OP_PLIST, EXP_OP_SASSIGN, expression_assign(), expression_set_tf_preclear(), FALSE, FATAL, func_unit_s::filename, free_safe, thread_s::funit, expression_s::left, expression_s::line, expression_s::op, vsuppl_u::part, print_output(), PROFILE, PROFILE_END, QSTRING, vector_s::r32, vector_s::r64, expression_s::right, expression_s::sig, vector_s::suppl, sys_task_value_plusargs(), Throw, TRUE, user_msg, USER_MSG_LENGTH, rv32_s::val, rv64_s::val, vector_s::value, vsignal_s::value, expression_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_from_real64(), vector_set_coverage_and_assign_ulong(), vector_set_unary_evals(), vector_to_string(), and vsignal_propagate().
03470 { PROFILE(EXPRESSION_OP_FUNC__VALUE_PLUSARGS); 03471 03472 bool retval = FALSE; 03473 03474 /* Only evaluate this expression if it has not been evaluated yet */ 03475 if( expr->exec_num == 0 ) { 03476 03477 expression* left = expr->left; 03478 uint64 u64; 03479 char* arg; 03480 ulong scratchl; 03481 ulong scratchh = 0; 03482 int intval = 0; 03483 03484 /* Check to make sure that there is exactly two parameters */ 03485 if( (left == NULL) || (left->op != EXP_OP_PLIST) || (left->left->op != EXP_OP_SASSIGN) || (left->right->op != EXP_OP_SASSIGN) ) { 03486 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "$value$plusargs called with incorrect number of parameters (file: %s, line: %d)", thr->funit->filename, expr->line ); 03487 assert( rv < USER_MSG_LENGTH ); 03488 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 03489 Throw 0; 03490 } 03491 03492 /* Get the first argument string value */ 03493 arg = vector_to_string( left->left->value, QSTRING, TRUE, 0 ); 03494 03495 /* Scan the simulation argument list for matching values */ 03496 if( (scratchl = sys_task_value_plusargs( arg, left->right->value )) == 1 ) { 03497 03498 /* Assign the value to the proper signal and propagate the signal change, if an option match occurred */ 03499 switch( left->right->value->suppl.part.data_type ) { 03500 case VDATA_UL : 03501 expression_assign( left->right->right, left->right, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), TRUE, FALSE ); 03502 break; 03503 case VDATA_R64 : 03504 if( vector_from_real64( left->right->right->sig->value, left->right->value->value.r64->val ) ) { 03505 vsignal_propagate( left->right->right->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 03506 } 03507 break; 03508 case VDATA_R32 : 03509 if( vector_from_real64( left->right->right->sig->value, (double)left->right->value->value.r32->val ) ) { 03510 vsignal_propagate( left->right->right->sig, ((thr == NULL) ? time : &(thr->curr_time)) ); 03511 } 03512 break; 03513 default : assert( 0 ); break; 03514 } 03515 03516 } 03517 03518 /* Perform coverage and assignment */ 03519 retval = vector_set_coverage_and_assign_ulong( expr->value, &scratchl, &scratchh, 0, 0 ); 03520 03521 /* Deallocate memory */ 03522 free_safe( arg, (strlen( arg ) + 1) ); 03523 03524 } 03525 03526 /* Gather coverage information */ 03527 expression_set_tf_preclear( expr, retval ); 03528 vector_set_unary_evals( expr->value ); 03529 03530 PROFILE_END; 03531 03532 return( retval ); 03533 03534 }
bool expression_op_func__wait | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs a wait statement operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References esuppl_u::eval_t, FALSE, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, TRUE, esuppl_u::true, expression_s::value, and vector_is_not_zero().
05481 { PROFILE(EXPRESSION_OP_FUNC__WAIT); 05482 05483 bool retval; /* Return value for this function */ 05484 05485 /* If the right expression evaluates to TRUE, continue; otherwise, do a context switch */ 05486 if( vector_is_not_zero( expr->right->value ) ) { 05487 expr->suppl.part.eval_t = 1; 05488 expr->suppl.part.true = 1; 05489 retval = TRUE; 05490 } else { 05491 expr->suppl.part.eval_t = 0; 05492 retval = FALSE; 05493 } 05494 05495 PROFILE_END; 05496 05497 return( retval ); 05498 05499 }
bool expression_op_func__xor | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs XOR operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References expression_set_eval_NN(), expression_set_tf_preclear(), expression_s::left, PROFILE, PROFILE_END, expression_s::right, expression_s::value, vector_bitwise_xor_op(), and vector_set_other_comb_evals().
02030 { PROFILE(EXPRESSION_OP_FUNC__XOR); 02031 02032 /* Perform XOR operation */ 02033 bool retval = vector_bitwise_xor_op( expr->value, expr->left->value, expr->right->value ); 02034 02035 /* Gather other coverage stats */ 02036 expression_set_tf_preclear( expr, retval ); 02037 vector_set_other_comb_evals( expr->value, expr->left->value, expr->right->value ); 02038 expression_set_eval_NN( expr ); 02039 02040 PROFILE_END; 02041 02042 return( retval ); 02043 02044 }
bool expression_op_func__xor_a | ( | expression * | expr, | |
thread * | thr, | |||
const sim_time * | time | |||
) | [static] |
Performs an XOR-and-assign operation.
expr | Pointer to expression to perform operation on | |
thr | Pointer to thread containing this expression | |
time | Pointer to current simulation time |
References thread_s::curr_time, expression_s::elem, expression_assign(), expression_set_eval_NN(), expression_set_tf_preclear(), FALSE, expression_s::left, PROFILE, PROFILE_END, expression_s::right, sim_expression(), TRUE, expression_s::tvecs, expression_s::value, vecblk_s::vec, vector_bitwise_xor_op(), vector_copy(), and vector_set_other_comb_evals().
02055 { PROFILE(EXPRESSION_OP_FUNC__XOR_A); 02056 02057 bool retval; /* Return value for this function */ 02058 vector* tmp = &(expr->elem.tvecs->vec[0]); /* Temporary pointer to temporary vector */ 02059 int intval = 0; /* Integer value */ 02060 02061 /* First, evaluate the left-hand expression */ 02062 (void)sim_expression( expr->left, thr, time, TRUE ); 02063 02064 /* Second, copy the value of the left expression into a temporary vector */ 02065 vector_copy( expr->left->value, tmp ); 02066 02067 /* Third, perform XOR and gather coverage information */ 02068 retval = vector_bitwise_xor_op( expr->value, tmp, expr->right->value ); 02069 02070 expression_set_tf_preclear( expr, retval ); 02071 vector_set_other_comb_evals( expr->value, expr->left->value, expr->right->value ); 02072 expression_set_eval_NN( expr ); 02073 02074 /* Fourth, assign the new value to the left expression */ 02075 expression_assign( expr->left, expr, &intval, thr, ((thr == NULL) ? time : &(thr->curr_time)), FALSE, FALSE ); 02076 02077 PROFILE_END; 02078 02079 return( retval ); 02080 02081 }
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 }
static void expression_set_eval_NN | ( | expression * | expr | ) | [inline, static] |
Sets the eval_00/01/10/11 supplemental bits as necessary. This function should be called by expression_op_func__* functions that are NOT events and have both the left and right expression children present.
expr | Pointer to expression to set 00/01/10/11 supplemental bits |
References ESUPPL_IS_FALSE, ESUPPL_IS_TRUE, esuppl_u::eval_00, esuppl_u::eval_01, esuppl_u::eval_10, esuppl_u::eval_11, expression_s::left, esuppl_u::part, expression_s::right, and expression_s::suppl.
Referenced by expression_op_func__add(), expression_op_func__add_a(), expression_op_func__and(), expression_op_func__and_a(), expression_op_func__arshift(), expression_op_func__arshift_a(), expression_op_func__case(), expression_op_func__casex(), expression_op_func__casez(), expression_op_func__ceq(), expression_op_func__cne(), expression_op_func__cond_sel(), expression_op_func__divide(), expression_op_func__divide_a(), expression_op_func__eq(), expression_op_func__expand(), expression_op_func__ge(), expression_op_func__gt(), expression_op_func__land(), expression_op_func__le(), expression_op_func__list(), expression_op_func__lor(), expression_op_func__lshift(), expression_op_func__lshift_a(), expression_op_func__lt(), expression_op_func__mbit(), expression_op_func__mod(), expression_op_func__mod_a(), expression_op_func__multiply(), expression_op_func__multiply_a(), expression_op_func__nand(), expression_op_func__ne(), expression_op_func__nor(), expression_op_func__nxor(), expression_op_func__or(), expression_op_func__or_a(), expression_op_func__rshift(), expression_op_func__rshift_a(), expression_op_func__sub_a(), expression_op_func__subtract(), expression_op_func__xor(), and expression_op_func__xor_a().
02007 { 02008 02009 uint32 lf = ESUPPL_IS_FALSE( expr->left->suppl ); 02010 uint32 lt = ESUPPL_IS_TRUE( expr->left->suppl ); 02011 uint32 rf = ESUPPL_IS_FALSE( expr->right->suppl ); 02012 uint32 rt = ESUPPL_IS_TRUE( expr->right->suppl ); 02013 02014 expr->suppl.part.eval_00 |= lf & rf; 02015 expr->suppl.part.eval_01 |= lf & rt; 02016 expr->suppl.part.eval_10 |= lt & rf; 02017 expr->suppl.part.eval_11 |= lt & rt; 02018 02019 }
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 }
static void expression_set_tf | ( | expression * | expr, | |
bool | changed | |||
) | [inline, static] |
This function sets the true/false indicators in the expression supplemental field as needed. This function should only be called by expression_op_func__* functions whose return value is TRUE AND whose op type is either STATIC or PARAM.
expr | Pointer to expression to set true/false indicators of | |
changed | Set to TRUE if the expression changed value |
References esuppl_u::eval_f, esuppl_u::eval_t, esuppl_u::false, esuppl_u::part, vsuppl_u::part, vsuppl_u::set, expression_s::suppl, vector_s::suppl, esuppl_u::true, expression_s::value, vector_is_not_zero(), and vector_is_unknown().
Referenced by expression_op_func__null(), and expression_op_func__sig().
01977 { 01978 01979 /* If the expression changed value or it has never been set, calculate coverage information */ 01980 if( changed || (expr->value->suppl.part.set == 0) ) { 01981 01982 /* Set TRUE/FALSE bits to indicate value */ 01983 if( !vector_is_unknown( expr->value ) ) { 01984 if( vector_is_not_zero( expr->value ) ) { 01985 expr->suppl.part.true = 1; 01986 expr->suppl.part.eval_t = 1; 01987 } else { 01988 expr->suppl.part.false = 1; 01989 expr->suppl.part.eval_f = 1; 01990 } 01991 } 01992 01993 /* Indicate that the vector has been evaluated */ 01994 expr->value->suppl.part.set = 1; 01995 01996 } 01997 01998 }
static void expression_set_tf_preclear | ( | expression * | expr, | |
bool | changed | |||
) | [inline, static] |
This function sets the true/false indicators in the expression supplemental field as needed. This function should only be called by expression_op_func__* functions that are NOT events AND whose return value is TRUE AND whose op type is not STATIC or PARAM.
expr | Pointer to expression to set true/false indicators of | |
changed | Set to TRUE if the expression changed value |
References esuppl_u::eval_f, esuppl_u::eval_t, esuppl_u::false, esuppl_u::part, vsuppl_u::part, vsuppl_u::set, expression_s::suppl, vector_s::suppl, esuppl_u::true, expression_s::value, vector_is_not_zero(), and vector_is_unknown().
Referenced by expression_op_func__add(), expression_op_func__add_a(), expression_op_func__and(), expression_op_func__and_a(), expression_op_func__arshift(), expression_op_func__arshift_a(), expression_op_func__assign(), expression_op_func__case(), expression_op_func__casex(), expression_op_func__casez(), expression_op_func__ceq(), expression_op_func__cne(), expression_op_func__concat(), expression_op_func__cond(), expression_op_func__cond_sel(), expression_op_func__default(), expression_op_func__dim(), expression_op_func__disable(), expression_op_func__divide(), expression_op_func__divide_a(), expression_op_func__eq(), expression_op_func__expand(), expression_op_func__exponent(), expression_op_func__fork(), expression_op_func__func_call(), expression_op_func__ge(), expression_op_func__gt(), expression_op_func__join(), expression_op_func__land(), expression_op_func__le(), expression_op_func__list(), expression_op_func__lor(), expression_op_func__lshift(), expression_op_func__lshift_a(), expression_op_func__lt(), expression_op_func__mbit(), expression_op_func__mbit_neg(), expression_op_func__mbit_pos(), expression_op_func__mod(), expression_op_func__mod_a(), expression_op_func__multiply(), expression_op_func__multiply_a(), expression_op_func__nand(), expression_op_func__ne(), expression_op_func__negate(), expression_op_func__nor(), expression_op_func__null(), expression_op_func__nxor(), expression_op_func__or(), expression_op_func__or_a(), expression_op_func__passign(), expression_op_func__repeat(), expression_op_func__rshift(), expression_op_func__rshift_a(), expression_op_func__sbit(), expression_op_func__sig(), expression_op_func__sub_a(), expression_op_func__subtract(), expression_op_func__test_plusargs(), expression_op_func__uand(), expression_op_func__uinv(), expression_op_func__unand(), expression_op_func__unor(), expression_op_func__unot(), expression_op_func__unxor(), expression_op_func__uor(), expression_op_func__uxor(), expression_op_func__value_plusargs(), expression_op_func__xor(), and expression_op_func__xor_a().
01942 { 01943 01944 /* If the expression changed value or it has never been set, calculate coverage information */ 01945 if( changed || (expr->value->suppl.part.set == 0) ) { 01946 01947 /* Clear current TRUE/FALSE indicators */ 01948 expr->suppl.part.eval_t = 0; 01949 expr->suppl.part.eval_f = 0; 01950 01951 /* Set TRUE/FALSE bits to indicate value */ 01952 if( !vector_is_unknown( expr->value ) ) { 01953 if( vector_is_not_zero( expr->value ) ) { 01954 expr->suppl.part.true = 1; 01955 expr->suppl.part.eval_t = 1; 01956 } else { 01957 expr->suppl.part.false = 1; 01958 expr->suppl.part.eval_f = 1; 01959 } 01960 } 01961 01962 /* Indicate that the vector has been evaluated */ 01963 expr->value->suppl.part.set = 1; 01964 01965 } 01966 01967 }
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 }
unsigned int curr_db |
Index of current database in db_list array that is being handled.
int curr_expr_id |
This static value contains the current expression ID number to use for the next expression found, it is incremented by one when an expression is found. This allows us to have a unique expression ID for each expression (since expressions have no intrinsic names).
If set to TRUE, causes debug information to be spewed to screen.
const exp_info exp_op_info[EXP_OP_NUM] |
Array containing static information about expression operation types. NOTE: This structure MUST be updated if a new expression is added! The third argument is an initialization to the exp_info_s structure.
Specifies whether the command-line debugger should be enabled
Referenced by expression_assign(), expression_op_func__idec(), expression_op_func__iinc(), expression_op_func__pdec(), expression_op_func__pinc(), print_output(), score_parse_args(), sim_add_thread(), sim_initialize(), sim_kill_thread(), sim_perform_nba(), sim_simulate(), sim_thread_insert_into_delay_queue(), sim_thread_pop_head(), and sim_thread_push().
int nba_queue_size |
The allocated size of the non-blocking assignment queue.
Referenced by expression_create_nba(), sim_dealloc(), and sim_initialize().
Pointer to head of expression list that contains all expressions that contain static (non-changing) values. These expressions will be forced to be simulated, making sure that correct coverage numbers for expressions containing static values is maintained.
Pointer to tail of expression list that contains all expressions that contain static (non-changing) values. These expressions will be forced to be simulated, making sure that correct coverage numbers for expressions containing static values is maintained.
char user_msg[USER_MSG_LENGTH] |
Holds some output that will be displayed via the print_output command. This is created globally so that memory does not need to be reallocated for each function that wishes to use it.