expr.c File Reference

#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"

Functions

static bool expression_op_func__xor (expression *, thread *, const sim_time *)
static bool expression_op_func__multiply (expression *, thread *, const sim_time *)
static bool expression_op_func__divide (expression *, thread *, const sim_time *)
static bool expression_op_func__mod (expression *, thread *, const sim_time *)
static bool expression_op_func__add (expression *, thread *, const sim_time *)
static bool expression_op_func__subtract (expression *, thread *, const sim_time *)
static bool expression_op_func__and (expression *, thread *, const sim_time *)
static bool expression_op_func__or (expression *, thread *, const sim_time *)
static bool expression_op_func__nand (expression *, thread *, const sim_time *)
static bool expression_op_func__nor (expression *, thread *, const sim_time *)
static bool expression_op_func__nxor (expression *, thread *, const sim_time *)
static bool expression_op_func__lt (expression *, thread *, const sim_time *)
static bool expression_op_func__gt (expression *, thread *, const sim_time *)
static bool expression_op_func__lshift (expression *, thread *, const sim_time *)
static bool expression_op_func__rshift (expression *, thread *, const sim_time *)
static bool expression_op_func__arshift (expression *, thread *, const sim_time *)
static bool expression_op_func__eq (expression *, thread *, const sim_time *)
static bool expression_op_func__ceq (expression *, thread *, const sim_time *)
static bool expression_op_func__le (expression *, thread *, const sim_time *)
static bool expression_op_func__ge (expression *, thread *, const sim_time *)
static bool expression_op_func__ne (expression *, thread *, const sim_time *)
static bool expression_op_func__cne (expression *, thread *, const sim_time *)
static bool expression_op_func__lor (expression *, thread *, const sim_time *)
static bool expression_op_func__land (expression *, thread *, const sim_time *)
static bool expression_op_func__cond (expression *, thread *, const sim_time *)
static bool expression_op_func__cond_sel (expression *, thread *, const sim_time *)
static bool expression_op_func__uinv (expression *, thread *, const sim_time *)
static bool expression_op_func__uand (expression *, thread *, const sim_time *)
static bool expression_op_func__unot (expression *, thread *, const sim_time *)
static bool expression_op_func__uor (expression *, thread *, const sim_time *)
static bool expression_op_func__uxor (expression *, thread *, const sim_time *)
static bool expression_op_func__unand (expression *, thread *, const sim_time *)
static bool expression_op_func__unor (expression *, thread *, const sim_time *)
static bool expression_op_func__unxor (expression *, thread *, const sim_time *)
static bool expression_op_func__sbit (expression *, thread *, const sim_time *)
static bool expression_op_func__mbit (expression *, thread *, const sim_time *)
static bool expression_op_func__expand (expression *, thread *, const sim_time *)
static bool expression_op_func__concat (expression *, thread *, const sim_time *)
static bool expression_op_func__pedge (expression *, thread *, const sim_time *)
static bool expression_op_func__nedge (expression *, thread *, const sim_time *)
static bool expression_op_func__aedge (expression *, thread *, const sim_time *)
static bool expression_op_func__eor (expression *, thread *, const sim_time *)
static bool expression_op_func__slist (expression *, thread *, const sim_time *)
static bool expression_op_func__delay (expression *, thread *, const sim_time *)
static bool expression_op_func__case (expression *, thread *, const sim_time *)
static bool expression_op_func__casex (expression *, thread *, const sim_time *)
static bool expression_op_func__casez (expression *, thread *, const sim_time *)
static bool expression_op_func__default (expression *, thread *, const sim_time *)
static bool expression_op_func__list (expression *, thread *, const sim_time *)
static bool expression_op_func__assign (expression *, thread *, const sim_time *)
static bool expression_op_func__func_call (expression *, thread *, const sim_time *)
static bool expression_op_func__task_call (expression *, thread *, const sim_time *)
static bool expression_op_func__trigger (expression *, thread *, const sim_time *)
static bool expression_op_func__nb_call (expression *, thread *, const sim_time *)
static bool expression_op_func__fork (expression *, thread *, const sim_time *)
static bool expression_op_func__join (expression *, thread *, const sim_time *)
static bool expression_op_func__disable (expression *, thread *, const sim_time *)
static bool expression_op_func__repeat (expression *, thread *, const sim_time *)
static bool expression_op_func__null (expression *, thread *, const sim_time *)
static bool expression_op_func__sig (expression *, thread *, const sim_time *)
static bool expression_op_func__exponent (expression *, thread *, const sim_time *)
static bool expression_op_func__passign (expression *, thread *, const sim_time *)
static bool expression_op_func__mbit_pos (expression *, thread *, const sim_time *)
static bool expression_op_func__mbit_neg (expression *, thread *, const sim_time *)
static bool expression_op_func__negate (expression *, thread *, const sim_time *)
static bool expression_op_func__iinc (expression *, thread *, const sim_time *)
static bool expression_op_func__pinc (expression *, thread *, const sim_time *)
static bool expression_op_func__idec (expression *, thread *, const sim_time *)
static bool expression_op_func__pdec (expression *, thread *, const sim_time *)
static bool expression_op_func__dly_assign (expression *, thread *, const sim_time *)
static bool expression_op_func__dly_op (expression *, thread *, const sim_time *)
static bool expression_op_func__repeat_dly (expression *, thread *, const sim_time *)
static bool expression_op_func__dim (expression *, thread *, const sim_time *)
static bool expression_op_func__wait (expression *, thread *, const sim_time *)
static bool expression_op_func__finish (expression *, thread *, const sim_time *)
static bool expression_op_func__stop (expression *, thread *, const sim_time *)
static bool expression_op_func__add_a (expression *, thread *, const sim_time *)
static bool expression_op_func__sub_a (expression *, thread *, const sim_time *)
static bool expression_op_func__multiply_a (expression *, thread *, const sim_time *)
static bool expression_op_func__divide_a (expression *, thread *, const sim_time *)
static bool expression_op_func__mod_a (expression *, thread *, const sim_time *)
static bool expression_op_func__and_a (expression *, thread *, const sim_time *)
static bool expression_op_func__or_a (expression *, thread *, const sim_time *)
static bool expression_op_func__xor_a (expression *, thread *, const sim_time *)
static bool expression_op_func__lshift_a (expression *, thread *, const sim_time *)
static bool expression_op_func__rshift_a (expression *, thread *, const sim_time *)
static bool expression_op_func__arshift_a (expression *, thread *, const sim_time *)
static bool expression_op_func__time (expression *, thread *, const sim_time *)
static bool expression_op_func__realtime (expression *, thread *, const sim_time *)
static bool expression_op_func__random (expression *, thread *, const sim_time *)
static bool expression_op_func__sassign (expression *, thread *, const sim_time *)
static bool expression_op_func__srandom (expression *, thread *, const sim_time *)
static bool expression_op_func__urandom (expression *, thread *, const sim_time *)
static bool expression_op_func__urandom_range (expression *, thread *, const sim_time *)
static bool expression_op_func__realtobits (expression *, thread *, const sim_time *)
static bool expression_op_func__bitstoreal (expression *, thread *, const sim_time *)
static bool expression_op_func__shortrealtobits (expression *, thread *, const sim_time *)
static bool expression_op_func__bitstoshortreal (expression *, thread *, const sim_time *)
static bool expression_op_func__itor (expression *, thread *, const sim_time *)
static bool expression_op_func__rtoi (expression *, thread *, const sim_time *)
static bool expression_op_func__test_plusargs (expression *, thread *, const sim_time *)
static bool expression_op_func__value_plusargs (expression *, thread *, const sim_time *)
static bool expression_op_func__signed (expression *, thread *, const sim_time *)
static bool expression_op_func__unsigned (expression *, thread *, const sim_time *)
static bool expression_op_func__clog2 (expression *, thread *, const sim_time *)
static void expression_assign (expression *, expression *, int *, thread *, const sim_time *, bool eval_lhs, bool nb)
static void expression_create_tmp_vecs (expression *exp, int width)
void expression_create_nba (expression *expr, vsignal *lhs_sig, vector *rhs_vec)
 Creates, initializes and adds a non-blocking assignment structure to the given expression's element pointer.
expressionexpression_is_nba_lhs (expression *exp)
 Returns a pointer to the non-blocking assignment expression if the given expression is an assignable expression on the LHS of a non-blocking assignment.
static void expression_create_value (expression *exp, int width, bool data)
expressionexpression_create (expression *right, expression *left, exp_op_type op, bool lhs, int id, int line, unsigned int first, unsigned int last, bool data)
 Creates new expression.
void expression_set_value (expression *exp, vsignal *sig, func_unit *funit)
 Sets the specified expression value to the specified vector value.
void expression_set_signed (expression *exp)
 Sets the signed bit for all appropriate parent expressions.
void expression_resize (expression *expr, func_unit *funit, bool recursive, bool alloc)
 Recursively resizes specified expression tree leaf node.
int expression_get_id (expression *expr, bool parse_mode)
 Returns expression ID of this expression.
expressionexpression_get_first_line_expr (expression *expr)
 Returns first line in this expression tree.
expressionexpression_get_last_line_expr (expression *expr)
 Returns last line in this expression tree.
unsigned int expression_get_curr_dimension (expression *expr)
 Returns the current dimension of the given expression.
void expression_find_rhs_sigs (expression *expr, str_link **head, str_link **tail)
 Finds all RHS signals in given expression tree.
static void expression_find_params (expression *expr, exp_link **head, exp_link **tail)
expressionexpression_find_uline_id (expression *expr, int ulid)
 Finds the expression in this expression tree with the specified underline id.
bool expression_find_expr (expression *root, expression *expr)
 Returns TRUE if the specified expression exists within the given root expression tree.
bool expression_contains_expr_calling_stmt (expression *expr, statement *stmt)
 Searches for an expression that calls the given statement.
statementexpression_get_root_statement (expression *exp)
 Finds the root statement for the given expression.
void expression_assign_expr_ids (expression *root, func_unit *funit)
 Assigns each expression in the given tree a unique identifier.
void expression_db_write (expression *expr, FILE *file, bool parse_mode, bool ids_issued)
 Writes this expression to the specified database file.
void expression_db_write_tree (expression *root, FILE *ofile)
 Writes the entire expression tree to the specified data file.
void expression_db_read (char **line, func_unit *curr_funit, bool eval)
 Reads current line of specified file and parses for expression information.
void expression_db_merge (expression *base, char **line, bool same)
 Reads and merges two expressions and stores result in base expression.
void expression_merge (expression *base, expression *other)
 Merges two expressions into the base expression.
const char * expression_string_op (int op)
 Returns user-readable name of specified expression operation.
char * expression_string (expression *exp)
 Returns user-readable version of the supplied expression.
void expression_display (expression *expr)
 Displays the specified expression information.
static void expression_set_tf_preclear (expression *expr, bool changed)
static void expression_set_tf (expression *expr, bool changed)
static void expression_set_eval_NN (expression *expr)
bool expression_operate (expression *expr, thread *thr, const sim_time *time)
 Performs operation specified by parameter expression.
void expression_operate_recursively (expression *expr, func_unit *funit, bool sizing)
 Performs recursive expression operation (parse mode only).
static bool expression_is_static_only_helper (expression *expr, bool *one)
bool expression_is_static_only (expression *expr)
 Returns TRUE if specified expression is found to contain all static leaf expressions.
static bool expression_is_assigned (expression *expr)
bool expression_is_bit_select (expression *expr)
 Returns TRUE if specified expression is a part of an bit select expression tree.
bool expression_is_last_select (expression *expr)
 Returns TRUE if specified expression is the last select of a signal.
bool expression_is_in_rassign (expression *expr)
 Returns TRUE if specified expression is in an RASSIGN expression tree.
void expression_set_assigned (expression *expr)
 Sets the expression signal supplemental field assigned bit if the given expression is an RHS of an assignment.
void expression_set_changed (expression *expr)
 Sets the left/right changed expression bits for each expression in the tree.
void expression_dealloc (expression *expr, bool exp_only)
 Deallocates memory used for expression.

Variables

char user_msg [USER_MSG_LENGTH]
exp_linkstatic_expr_head
exp_linkstatic_expr_tail
db ** db_list
unsigned int curr_db
bool debug_mode
int generate_expr_mode
int curr_expr_id
bool flag_use_command_line_debug
bool cli_debug_mode
int nba_queue_size
const exp_info exp_op_info [EXP_OP_NUM]

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
12/1/2001
Expressions
The following are special expressions that are handled differently than standard unary (i.e., ~a) and dual operators (i.e., a & b). These expressions are documented to help remove confusion (my own) about how they are implemented by Covered and handled during the parsing and scoring phases of the tool.
EXP_OP_SIG
A signal expression has no left or right child (they are both NULL). Its vector value is a pointer to the signal vector value to which is belongs. This allows the signal expression value to change automatically when the signal value is updated. No further expression operation is necessary to calculate its value.
EXP_OP_SBIT_SEL
A single-bit signal expression has its left child pointed to the expression tree that is required to select the bit from the specified signal value. The left child is allowed to change values during simulation. To verify that the current bit select has not exceeded the ranges of the signal, the signal pointer value in the expression structure is used to reference the signal. The LSB and width values from the actual signal can then be used to verify that we are still within range. If we are found to be out of range, a value of X must be assigned to the SBIT_SEL expression. The width of an SBIT_SEL is always constant (1). The LSB of the SBIT_SEL is manipulated by the left expression value.
EXP_OP_MBIT_SEL
A multi-bit signal expression has its left child set to the expression tree on the left side of the ':' in the vector and the right child set to the expression tree on the right side of the ':' in the vector. The width of the MBIT_SEL must be constant but is related to the difference between the left and right child values; therefore, it is required that the left and right child values be constant expressions (consisting of only expressions, parameters, and static values). The width of the MBIT_SEL expression is calculated after reading in the MBIT_SEL expression from the CDD file. If the left or right child expressions are found to not be constant, an error is signaled to the user immediately. The LSB is also calculated to be the lesser of the two child values. The width and lsb are assigned to the MBIT_SEL expression vector immediately. In the case of MBIT_SEL, the LSB is also constant. Vector direction is currently not considered at this point.
EXP_OP_MBIT_POS
A variable multi-bit positive select expression operates in much the same way as the EXP_OP_MBIT_SEL expression; however, the right expression must be a constant expression. The left expression represents the LSB while the MSB is calculated by adding the value of the right expression to the value of the left expression and subtracting one.
EXP_OP_MBIT_NEG
A variable multi-bit negative select expression operates in much the same way as the EXP_OP_MBIT_POS expression. In this case, the left expression represents the MSB while the the LSB is calculated by subtracting the value of the right expression and adding one.
EXP_OP_ASSIGN, EXP_OP_DASSIGN, EXP_OP_NASSIGN, EXP_OP_IF
All of these expressions are assignment operators that are in assign statements, behavioral non-blocking assignments, and if expressions, respectively. These expressions do not have an operation to perform because their vector value pointers point to the vector value on the right-hand side of the assignment operator.
EXP_OP_BASSIGN
The blocking assignment operator differs from the assignment operators mentioned above in that Covered will perform the assignment for a blocking assignment expression. This allows us to expand the amount of code that can be covered by allowing several "zero-time" assignments to occur while maintaining accurate coverage information.
EXP_OP_RASSIGN
The register assignment operator is executed in the same manner as the BASSIGN expression operator with the exception that the RASSIGN must be executed prior to any simulation.
EXP_OP_PASSIGN
The port assignment operator is like the blocking assignment operator, in that Covered will perform the assignment. The signal pointer points to the port signal of the function/task, the vector pointer is set to point to this signal's vector.
EXP_OP_FUNC_CALL
A function call expression runs the head statement block of the prescribed function whenever an expression changes value in its parameter list. After the function is simulated the function variable value is copied to the expression vector.
EXP_OP_TASK_CALL
A task call expression simply runs the head statement block of the prescribed task immediately (the statement block is immediately run using the sim_statement function call).
EXP_OP_NB_CALL
A named block call expression is not really a legitimate Verilog expression type but is used for the purposes of binding an expression to a functional unit (like EXP_OP_FUNC_CALL). It is not measurable and has no report output structure. It acts much like an EXP_OP_FUNC_CALL expression if it is nested in a a function block; otherwise, acts like an EXP_OP_TASK_CALL in simulation but does not pass any parameters.
EXP_OP_REPEAT
The EXP_OP_REPEAT expression takes on the width of its right expression and, starting at a value of 0, increments by one until it reaches the value of the right expression (at that time it returns false and returns its incrementing value back to 0.
EXP_OP_SLIST, EXP_OP_ALWAYS_COMB, EXP_OP_ALWAYS_LATCH
The EXP_OP_SLIST expression is a 1-bit expression whose value is meaningless. It indicates the Verilog-2001 sensitivity list @* for a statement block and its right expression is attaches to an EOR attached list of AEDGE operations. The SLIST expression works like an EOR but only checks the right child. When outputting an expression tree whose root expression is an SLIST, the rest of the expression should be ignored for outputting purposes.
EXP_OP_NOOP
This expression does nothing. It is not measurable but is simply a placeholder for a statement that Covered will not handle (i.e., standard system calls that only contain inputs) but will not dismiss the statement block that the statement exists in.
EXP_OP_DIM
This expression handles a dimensional selection lookup, allowing us to properly handle multi-dimensional array accesses.
EXP_OP_SFINISH, EXP_OP_SSTOP
These expression types cause the simulator to stop execution immediately.

Function Documentation

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.

Parameters:
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.

Exceptions:
anonymous expression_resize expression_assign_expr_ids expression_assign_expr_ids

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

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

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

Referenced by expression_assign_expr_ids(), and statement_assign_expr_ids().

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

bool expression_contains_expr_calling_stmt ( expression expr,
statement stmt 
)

Searches for an expression that calls the given statement.

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

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

Referenced by expression_contains_expr_calling_stmt(), and statement_contains_expr_calling_stmt().

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

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

Creates new expression.

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

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

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

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

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

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

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

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

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

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

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

Referenced by bind_signal().

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

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.

Parameters:
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]
Exceptions:
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.

Parameters:
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.

Exceptions:
anonymous Throw vector_db_merge

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

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

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

Referenced by funit_db_inst_merge(), and funit_db_mod_merge().

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

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

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

Exceptions:
anonymous expression_create Throw Throw Throw Throw Throw vector_db_read

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

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

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

Referenced by db_read(), and funit_db_mod_merge().

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

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

Writes this expression to the specified database file.

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

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

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

Referenced by expression_db_write_tree(), and funit_db_write().

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

void expression_db_write_tree ( expression root,
FILE *  ofile 
)

Writes the entire expression tree to the specified data file.

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

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

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

Referenced by expression_db_write_tree(), and statement_db_write_expr_tree().

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

void expression_dealloc ( expression expr,
bool  exp_only 
)

Deallocates memory used for expression.

Deallocates all heap memory allocated with the malloc routine.

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

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

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

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

void expression_display ( expression expr  ) 

Displays the specified expression information.

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

Parameters:
expr Pointer to expression to display

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

Referenced by expression_op_func__pdec(), and funit_display_expressions().

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

bool expression_find_expr ( expression root,
expression expr 
)

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

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

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

Referenced by expression_find_expr(), and instance_remove_parms_with_expr().

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

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.

Parameters:
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.

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

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

Referenced by expression_find_rhs_sigs(), and statement_find_rhs_sigs().

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

expression* expression_find_uline_id ( expression expr,
int  ulid 
)

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

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

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

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

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

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

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

unsigned int expression_get_curr_dimension ( expression expr  ) 

Returns the current dimension of the given expression.

Returns:
Returns the dimension index for the given expression

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

Parameters:
expr Pointer to expression to get dimension for

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

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

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

expression* expression_get_first_line_expr ( expression expr  ) 

Returns first line in this expression tree.

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

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

Referenced by codegen_create_expr(), and expression_get_first_line_expr().

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

int expression_get_id ( expression expr,
bool  parse_mode 
)

Returns expression ID of this expression.

Returns:
Returns expression ID for this expression.

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

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

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

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

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

expression* expression_get_last_line_expr ( expression expr  ) 

Returns last line in this expression tree.

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

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

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

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

statement* expression_get_root_statement ( expression exp  ) 

Finds the root statement for the given expression.

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

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

Parameters:
exp Pointer to expression to get root statement for

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

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

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

static bool expression_is_assigned ( expression expr  )  [static]
Returns:
Returns TRUE if specified expression is on the LHS of a blocking assignment operator.
Parameters:
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.

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

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

Referenced by expression_is_bit_select(), and race_check_one_block_assignment().

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

bool expression_is_in_rassign ( expression expr  ) 

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

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

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

Referenced by expression_is_in_rassign(), and race_check_one_block_assignment().

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

bool expression_is_last_select ( expression expr  ) 

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

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

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

Referenced by expression_set_value(), and race_check_one_block_assignment().

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

expression* expression_is_nba_lhs ( expression exp  ) 

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

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

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

Referenced by bind_signal().

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

bool expression_is_static_only ( expression expr  ) 

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

Parameters:
expr Pointer to expression to evaluate

References expression_is_static_only_helper().

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

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

static bool expression_is_static_only_helper ( expression expr,
bool one 
) [static]
Returns:
Returns TRUE if expression contains only static expressions; otherwise, returns FALSE.

Recursively iterates through specified expression tree and returns TRUE if all of the leaf expressions are static expressions (STATIC or parameters).

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.

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

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

Referenced by funit_merge().

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

bool expression_op_func__add ( expression expr,
thread thr,
const sim_time time 
) [static]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an addition operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an add-and-assign operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an any-edge event operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a bitwise AND operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an AND-and-assign operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an arithmetic right shift operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an arithmetic right-shift-and-assign operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a non-blocking or blocking assignment operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $bitstoreal system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $bitstoshortreal system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a case comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a casex comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a casez comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an equality (===) comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $clog2 system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a not-equal (!==) comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a concatenation ({}) operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a conditional (?:) operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a conditional select (?:) operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a case default comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a delay operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a multi-array dimension operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a block disable operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.
Exceptions:
anonymous Throw

Performs a 32-bit divide operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an divide-and-assign operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a delayed assignment.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an assignment and delay for a delayed assignment.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a event OR operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an equality (==) comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a expansion ({{}}) operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an exponential power operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $finish statement operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a fork operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a function call operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a greater-than-or-equal comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a greater-than comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an immediate decrement operation.

Parameters:
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]
Returns:
Returns TRUE.

Performs an immediate increment operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $itor system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a join operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a logical AND operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a less-than-or-equal comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a list (,) operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a logical OR operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a left shift operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an left-shift-and-assign operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a less-than comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a multi-bit select operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a negative variable multi-bit select operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a positive variable multi-bit select operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.
Exceptions:
anonymous Throw

Performs a 32-bit modulus operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an modulus-and-assign operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a multiply operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an multiply-and-assign operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a bitwise NAND operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a named block call operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a not-equal (!=) comparison operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a negative-edge event operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a negate of the specified expression.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a bitwise NOR operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

No operation is performed -- expression value is assumed to be changed.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a bitwise NXOR operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a bitwise OR operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an OR-and-assign operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a port assignment operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a postponed decrement operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a positive edge event operation.

Parameters:
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]
Returns:
Returns TRUE.

Performs a postponed increment operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs the $random system call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs the $realtime system call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $realtobits system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a repeat loop operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a repeated delay for a given assignment.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a right shift operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an right-shift-and-assign operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $rtoi system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a system task port assignment.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a single bit select operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $shortrealtobits system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

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.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $signed system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a sensitivity list operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $srandom system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $stop statement operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a subtract-and-assign operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a subtraction operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a task call operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $test$plusargs system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs the $time system call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an event trigger (->) operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a unary AND operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a unary invert operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a unary NAND operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a unary NOR operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a unary NOT operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $unsigned system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a unary NXOR operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a unary OR operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $urandom system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $urandom_range system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a unary XOR operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a $value$plusargs system task call.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs a wait statement operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs XOR operation.

Parameters:
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]
Returns:
Returns TRUE if the expression has changed value from its previous value; otherwise, returns FALSE.

Performs an XOR-and-assign operation.

Parameters:
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.

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

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

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

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

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

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

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

Performs recursive expression operation (parse mode only).

Exceptions:
anonymous expression_resize expression_operate_recursively expression_operate_recursively

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

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

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

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

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

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

Recursively resizes specified expression tree leaf node.

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

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

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

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

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

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

void expression_set_assigned ( expression expr  ) 

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

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

Parameters:
expr Pointer to current expression to evaluate

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

Referenced by bind_signal().

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

void expression_set_changed ( expression expr  ) 

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

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

Parameters:
expr Pointer to expression to set changed bits for

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

Referenced by expression_set_changed().

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

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.

Parameters:
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.

Parameters:
exp Pointer to current expression

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

Referenced by bind_signal(), and expression_set_signed().

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

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.

Parameters:
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.

Parameters:
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.

Exceptions:
anonymous expression_operate_recursively expression_operate_recursively expression_operate_recursively

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

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

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

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

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

char* expression_string ( expression exp  ) 

Returns user-readable version of the supplied expression.

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

Parameters:
exp Pointer to expression to display

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

Referenced by gen_item_stringify(), and statement_queue_display().

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

const char* expression_string_op ( int  op  ) 

Returns user-readable name of specified expression operation.

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

References EXP_OP_NUM, PROFILE, and PROFILE_END.

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

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


Variable Documentation

unsigned int curr_db

Index of current database in db_list array that is being handled.

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).

Array of database pointers storing all currently loaded databases.

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.

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.

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