#include <stdio.h>
#include <assert.h>
#include "defines.h"
#include "statement.h"
#include "expr.h"
#include "util.h"
#include "link.h"
#include "sim.h"
#include "db.h"
#include "stmt_blk.h"
Functions | |
statement * | statement_create (expression *exp, func_unit *funit, unsigned int ppline) |
Creates new statement structure. | |
void | statement_queue_display () |
static void | statement_queue_add (statement *stmt, int id, int type) |
static void | statement_queue_compare (statement *stmt) |
void | statement_size_elements (statement *stmt, func_unit *funit) |
Sizes all expressions for the given statement block. | |
void | statement_db_write (statement *stmt, FILE *ofile, bool ids_issued) |
Writes specified statement to the specified output file. | |
void | statement_db_write_tree (statement *stmt, FILE *ofile) |
Writes specified statement tree to the specified output file. | |
void | statement_db_write_expr_tree (statement *stmt, FILE *ofile) |
Writes specified expression trees for given statement block to specified output file. | |
void | statement_db_read (char **line, func_unit *curr_funit, int read_mode) |
Reads in statement line from specified string and stores statement in specified functional unit. | |
void | statement_assign_expr_ids (statement *stmt, func_unit *funit) |
Assigns unique expression IDs to each expression in the given statement block. | |
bool | statement_connect (statement *curr_stmt, statement *next_stmt, int conn_id) |
Connects statement sequence to next statement and sets stop bit. | |
static int | statement_get_last_line_helper (statement *stmt, statement *base) |
int | statement_get_last_line (statement *stmt) |
Calculates the last line of the specified statement tree. | |
void | statement_find_rhs_sigs (statement *stmt, str_link **head, str_link **tail) |
Creates a list of all signals on the RHS of expressions in the given statement block. | |
statement * | statement_find_statement (statement *curr, int id) |
Searches for statement with ID in the given statement block. | |
bool | statement_contains_expr_calling_stmt (statement *curr, statement *stmt) |
Searches the specified statement block for expression that calls the given stmt. | |
void | statement_dealloc_recursive (statement *stmt, bool rm_stmt_blk) |
void | statement_dealloc (statement *stmt) |
Deallocates statement memory and associated expression tree from the heap. | |
Variables | |
char | user_msg [USER_MSG_LENGTH] |
exp_info | exp_op_info [EXP_OP_NUM] |
static stmt_loop_link * | stmt_loop_head = NULL |
static stmt_loop_link * | stmt_loop_tail = NULL |
intial begin a = 0; if( a ) b = 1; else b = 0; c = a | b; end
a = 0;
if( a )
b = 1;
b = 0;
c = a | b;
always
, forever
, for
, repeat
, and while
.wait
, @
, etc.), the next_true pointer will point to the next statement in the tree; however, the next_false pointer will point to NULL. This NULL assignment indicates to the statement simulation engine that this statement will receive the head bit and the current statement tree is finished for this timestep. Assigns unique expression IDs to each expression in the given statement block.
stmt | Pointer to statement block to traverse | |
funit | Pointer to functional unit containing this statement block |
anonymous | statement_assign_expr_ids statement_assign_expr_ids statement_assign_expr_ids expression_assign_expr_ids |
Recursively traverses the entire statement block and assigns unique expression IDs for each expression tree that it finds.
References statement_s::exp, expression_assign_expr_ids(), statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_assign_expr_ids(), and statement_s::suppl.
Referenced by gen_item_assign_ids(), and statement_assign_expr_ids().
00561 { PROFILE(STATEMENT_ASSIGN_EXPR_IDS); 00562 00563 if( stmt != NULL ) { 00564 00565 /* Assign unique expression IDs */ 00566 expression_assign_expr_ids( stmt->exp, funit ); 00567 00568 /* Traverse down the rest of the statement block */ 00569 if( (stmt->next_true == stmt->next_false) && (stmt->suppl.part.stop_true == 0) ) { 00570 statement_assign_expr_ids( stmt->next_true, funit ); 00571 } else { 00572 if( stmt->suppl.part.stop_false == 0 ) { 00573 statement_assign_expr_ids( stmt->next_false, funit ); 00574 } 00575 if( stmt->suppl.part.stop_true == 0 ) { 00576 statement_assign_expr_ids( stmt->next_true, funit ); 00577 } 00578 } 00579 00580 } 00581 00582 PROFILE_END; 00583 00584 }
Connects statement sequence to next statement and sets stop bit.
curr_stmt | Pointer to statement sequence to traverse. | |
next_stmt | Pointer to statement to connect ends to. | |
conn_id | Current connection identifier (used to eliminate infinite looping and connection overwrite) |
Recursively traverses the specified stmt sequence. When it reaches a statement that has either next_true or next_false set to NULL, sets next_true and/or next_false of that statement to point to the next_stmt statement.
References statement_s::conn_id, statement_s::exp, EXPR_IS_CONTEXT_SWITCH, FALSE, statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_connect(), statement_s::suppl, and TRUE.
Referenced by db_statement_connect(), and statement_connect().
00612 { PROFILE(STATEMENT_CONNECT); 00613 00614 bool retval = FALSE; /* Return value for this function */ 00615 00616 assert( curr_stmt != NULL ); 00617 assert( next_stmt != NULL ); 00618 00619 /* Specify that this statement has been traversed */ 00620 curr_stmt->conn_id = conn_id; 00621 00622 //display( "In statement_connect", curr_stmt, next_stmt, conn_id ); 00623 00624 /* If both paths go to the same destination, only parse one path */ 00625 if( curr_stmt->next_true == curr_stmt->next_false ) { 00626 00627 /* If the TRUE path is NULL, connect it to the new statement */ 00628 if( curr_stmt->next_true == NULL ) { 00629 //display( "Setting next_true to next_stmt", curr_stmt, next_stmt, conn_id ); 00630 curr_stmt->next_true = next_stmt; 00631 /* If the current statement is a wait statement, don't connect next_false path */ 00632 if( !EXPR_IS_CONTEXT_SWITCH( curr_stmt->exp ) ) { 00633 //display( "Setting next_false to next_stmt", curr_stmt, next_stmt, conn_id ); 00634 curr_stmt->next_false = next_stmt; 00635 } 00636 if( curr_stmt->next_true->conn_id == conn_id ) { 00637 //display( "Setting stop_true and stop_false", curr_stmt, next_stmt, conn_id ); 00638 curr_stmt->suppl.part.stop_true = 1; 00639 curr_stmt->suppl.part.stop_false = 1; 00640 } else { 00641 curr_stmt->next_true->conn_id = conn_id; 00642 } 00643 retval = TRUE; 00644 /* If the TRUE path leads to a loop/merge, set the stop bit and stop traversing */ 00645 } else if( curr_stmt->next_true->conn_id == conn_id ) { 00646 //display( "Setting stop_true and stop_false", curr_stmt, next_stmt, conn_id ); 00647 curr_stmt->suppl.part.stop_true = 1; 00648 curr_stmt->suppl.part.stop_false = 1; 00649 /* Continue to traverse the TRUE path if the next_stmt does not match this statement */ 00650 } else if( curr_stmt->next_true != next_stmt ) { 00651 //display( "Traversing next_true path", curr_stmt, next_stmt, conn_id ); 00652 retval |= statement_connect( curr_stmt->next_true, next_stmt, conn_id ); 00653 } 00654 00655 } else { 00656 00657 /* Traverse FALSE path */ 00658 if( curr_stmt->next_false == NULL ) { 00659 if( !EXPR_IS_CONTEXT_SWITCH( curr_stmt->exp ) ) { 00660 //display( "Setting next_false to next_stmt", curr_stmt, next_stmt, conn_id ); 00661 curr_stmt->next_false = next_stmt; 00662 if( curr_stmt->next_false->conn_id == conn_id ) { 00663 //display( "Setting stop_false", curr_stmt, next_stmt, conn_id ); 00664 curr_stmt->suppl.part.stop_false = 1; 00665 } else { 00666 curr_stmt->next_false->conn_id = conn_id; 00667 } 00668 retval = TRUE; 00669 } 00670 /* If the FALSE path leads to a loop/merge, set the stop bit and stop traversing */ 00671 } else if( curr_stmt->next_false->conn_id == conn_id ) { 00672 //display( "Setting stop_false", curr_stmt, next_stmt, conn_id ); 00673 curr_stmt->suppl.part.stop_false = 1; 00674 /* Continue to traverse the FALSE path if the next statement does not match this statement */ 00675 } else if( (curr_stmt->next_false != next_stmt) ) { 00676 //display( "Traversing next_false path", curr_stmt, next_stmt, conn_id ); 00677 retval |= statement_connect( curr_stmt->next_false, next_stmt, conn_id ); 00678 } 00679 00680 /* Traverse TRUE path */ 00681 if( curr_stmt->next_true == NULL ) { 00682 //display( "Setting next_true to next_stmt", curr_stmt, next_stmt, conn_id ); 00683 curr_stmt->next_true = next_stmt; 00684 if( curr_stmt->next_true->conn_id == conn_id ) { 00685 //display( "Setting stop_true", curr_stmt, next_stmt, conn_id ); 00686 curr_stmt->suppl.part.stop_true = 1; 00687 } else { 00688 curr_stmt->next_true->conn_id = conn_id; 00689 } 00690 retval = TRUE; 00691 /* If the TRUE path leads to a loop/merge, set the stop bit and stop traversing */ 00692 } else if( curr_stmt->next_true->conn_id == conn_id ) { 00693 //display( "Setting stop_true", curr_stmt, next_stmt, conn_id ); 00694 curr_stmt->suppl.part.stop_true = 1; 00695 /* Continue to traverse the TRUE path if the next statement does not match this statement */ 00696 } else if( curr_stmt->next_true != next_stmt ) { 00697 //display( "Traversing next_true path", curr_stmt, next_stmt, conn_id ); 00698 retval |= statement_connect( curr_stmt->next_true, next_stmt, conn_id ); 00699 } 00700 00701 } 00702 00703 PROFILE_END; 00704 00705 return( retval ); 00706 00707 }
Searches the specified statement block for expression that calls the given stmt.
curr | Pointer to current statement to traverse | |
stmt | Pointer to statement to find in the associated expression tree |
References statement_s::exp, expression_contains_expr_calling_stmt(), statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_contains_expr_calling_stmt(), and statement_s::suppl.
Referenced by funit_remove_stmt_blks_calling_stmt(), gen_item_remove_if_contains_expr_calling_stmt(), and statement_contains_expr_calling_stmt().
00876 { PROFILE(STATEMENT_CONTAINS_EXPR_CALLING_STMT); 00877 00878 bool contains = (curr != NULL) && 00879 (expression_contains_expr_calling_stmt( curr->exp, stmt ) || 00880 ((curr->suppl.part.stop_true == 0) && 00881 statement_contains_expr_calling_stmt( curr->next_true, stmt )) || 00882 ((curr->next_false != curr->next_false) && 00883 (curr->suppl.part.stop_false == 0) && 00884 statement_contains_expr_calling_stmt( curr->next_false, stmt ))); 00885 00886 PROFILE_END; 00887 00888 return( contains ); 00889 00890 }
statement* statement_create | ( | expression * | exp, | |
func_unit * | funit, | |||
unsigned int | ppline | |||
) |
Creates new statement structure.
Creates a new statement structure from heap memory and initializes it with the specified parameter information.
exp | Pointer to root expression of expression tree for this statement | |
funit | Pointer to functional unit that this statement exists in | |
ppline | File line from the preprocessed file |
References statement_s::all, statement_s::conn_id, statement_s::exp, statement_s::funit, statement_s::head, malloc_safe, statement_s::next_false, statement_s::next_true, expression_s::parent, statement_s::ppline, PROFILE, PROFILE_END, expr_stmt_u::stmt, and statement_s::suppl.
Referenced by db_create_statement(), fsm_arg_parse_state(), and statement_db_read().
00138 { PROFILE(STATEMENT_CREATE); 00139 00140 statement* stmt; /* Pointer to newly created statement */ 00141 00142 stmt = (statement*)malloc_safe( sizeof( statement ) ); 00143 stmt->exp = exp; 00144 stmt->exp->parent->stmt = stmt; 00145 stmt->next_true = NULL; 00146 stmt->next_false = NULL; 00147 stmt->head = NULL; 00148 stmt->conn_id = 0; 00149 stmt->suppl.all = 0; 00150 stmt->funit = funit; 00151 stmt->ppline = ppline; 00152 00153 PROFILE_END; 00154 00155 return( stmt ); 00156 00157 }
void statement_db_read | ( | char ** | line, | |
func_unit * | curr_funit, | |||
int | read_mode | |||
) |
Reads in statement line from specified string and stores statement in specified functional unit.
line | Pointer to current line of file being read. | |
curr_funit | Pointer to current module. | |
read_mode | If set to REPORT, adds statement to head of list; otherwise, adds statement to tail. |
anonymous | Throw Throw |
Reads in the contents of the statement from the specified line, creates a statement structure to hold the contents.
References statement_s::all, exp_link_s::exp, func_unit_s::exp_head, exp_link_find(), FALSE, FATAL, func_unit_s::first_stmt, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, FUNIT_FUNCTION, FUNIT_NAMED_BLOCK, FUNIT_TASK, statement_s::head, statement_s::next_false, statement_s::next_true, statement_s::part, print_output(), PROFILE, PROFILE_END, READ_MODE_NO_MERGE, sim_add_thread(), statement_create(), statement_queue_add(), statement_queue_compare(), stmt_link_s::stmt, func_unit_s::stmt_head, stmt_link_add(), stmt_link_find(), func_unit_s::stmt_tail, statement_s::suppl, Throw, TRUE, and func_unit_s::type.
Referenced by db_read(), and funit_db_mod_merge().
00436 { PROFILE(STATEMENT_DB_READ); 00437 00438 int id; /* ID of root expression that is associated with this statement */ 00439 int true_id; /* ID of root expression that is associated with the next_true statement */ 00440 int false_id; /* ID of root expression that is associated with the next_false statement */ 00441 int head_id; 00442 statement* stmt; /* Pointer to newly created statement */ 00443 exp_link* expl; /* Pointer to found expression link */ 00444 stmt_link* stmtl; /* Pointer to found statement link */ 00445 int chars_read; /* Number of characters read from line */ 00446 uint32 suppl; /* Supplemental field value */ 00447 unsigned int ppline; /* Preprocessor file line */ 00448 uint32 first_col; /* First column */ 00449 00450 if( sscanf( *line, "%d %u %u %x %d %d %d%n", &id, &ppline, &first_col, &suppl, &true_id, &false_id, &head_id, &chars_read ) == 7 ) { 00451 00452 *line = *line + chars_read; 00453 00454 if( curr_funit == NULL ) { 00455 00456 print_output( "Internal error: statement in database written before its functional unit", FATAL, __FILE__, __LINE__ ); 00457 Throw 0; 00458 00459 } else { 00460 00461 /* Find associated root expression */ 00462 expl = exp_link_find( id, curr_funit->exp_head ); 00463 assert( expl != NULL ); 00464 00465 stmt = statement_create( expl->exp, curr_funit, ppline ); 00466 stmt->suppl.all = suppl; 00467 00468 /* 00469 If this statement is a head statement and the current functional unit is a task, function or named block, 00470 set the curr_funit->first_stmt pointer to this statement. 00471 */ 00472 if( (stmt->suppl.part.head == 1) && 00473 ((curr_funit->type == FUNIT_TASK) || 00474 (curr_funit->type == FUNIT_ATASK) || 00475 (curr_funit->type == FUNIT_FUNCTION) || 00476 (curr_funit->type == FUNIT_AFUNCTION) || 00477 (curr_funit->type == FUNIT_NAMED_BLOCK) || 00478 (curr_funit->type == FUNIT_ANAMED_BLOCK)) ) { 00479 curr_funit->first_stmt = stmt; 00480 } 00481 00482 /* Find and link next_true */ 00483 if( true_id == id ) { 00484 stmt->next_true = stmt; 00485 } else if( true_id != 0 ) { 00486 stmtl = stmt_link_find( true_id, curr_funit->stmt_head ); 00487 if( stmtl == NULL ) { 00488 /* Add to statement loop queue */ 00489 statement_queue_add( stmt, true_id, 0 ); 00490 } else { 00491 stmt->next_true = stmtl->stmt; 00492 } 00493 /* Check against statement queue */ 00494 statement_queue_compare( stmt ); 00495 } 00496 00497 /* Find and link next_false */ 00498 if( false_id == id ) { 00499 stmt->next_false = stmt; 00500 } else if( false_id != 0 ) { 00501 stmtl = stmt_link_find( false_id, curr_funit->stmt_head ); 00502 if( stmtl == NULL ) { 00503 statement_queue_add( stmt, false_id, 1 ); 00504 } else { 00505 stmt->next_false = stmtl->stmt; 00506 } 00507 statement_queue_compare( stmt ); 00508 } 00509 00510 /* Find and link head */ 00511 if( head_id == id ) { 00512 stmt->head = stmt; 00513 } else if( head_id != 0 ) { 00514 stmtl = stmt_link_find( head_id, curr_funit->stmt_head ); 00515 if( stmtl == NULL ) { 00516 statement_queue_add( stmt, head_id, 2 ); 00517 } else { 00518 stmt->head = stmtl->stmt; 00519 } 00520 statement_queue_compare( stmt ); 00521 } 00522 00523 /* Add the statement to the functional unit list */ 00524 (void)stmt_link_add( stmt, TRUE, &(curr_funit->stmt_head), &(curr_funit->stmt_tail) ); 00525 00526 /* 00527 Possibly add statement to presimulation queue (if the current functional unit is a task 00528 or function, do not add this to the presimulation queue (this will be added when the expression 00529 is called. 00530 */ 00531 if( (read_mode == READ_MODE_NO_MERGE) && (stmt->suppl.part.is_called == 0) ) { 00532 sim_time tmp_time = {0,0,0,FALSE}; 00533 (void)sim_add_thread( NULL, stmt, curr_funit, &tmp_time ); 00534 } 00535 00536 } 00537 00538 } else { 00539 00540 print_output( "Unable to read statement value", FATAL, __FILE__, __LINE__ ); 00541 Throw 0; 00542 00543 } 00544 00545 PROFILE_END; 00546 00547 }
Writes specified statement to the specified output file.
Recursively writes the contents of the specified statement tree (and its associated expression trees to the specified output stream.
stmt | Pointer to statement to write out value | |
ofile | Pointer to output file to write statement line to | |
ids_issued | Specifies that IDs were issued just prior to calling this function |
References statement_s::all, expression_s::col, DB_TYPE_STATEMENT, statement_s::exp, expression_get_id(), statement_s::head, statement_s::next_false, statement_s::next_true, expression_s::part, statement_s::ppline, PROFILE, PROFILE_END, and statement_s::suppl.
Referenced by funit_db_write(), and statement_db_write_tree().
00332 { PROFILE(STATEMENT_DB_WRITE); 00333 00334 assert( stmt != NULL ); 00335 00336 /* Write out contents of this statement last */ 00337 fprintf( ofile, "%d %d %u %u %x %d %d %d", 00338 DB_TYPE_STATEMENT, 00339 expression_get_id( stmt->exp, ids_issued ), 00340 stmt->ppline, 00341 stmt->exp->col.part.first, 00342 (stmt->suppl.all & 0xff), 00343 ((stmt->next_true == NULL) ? 0 : expression_get_id( stmt->next_true->exp, ids_issued )), 00344 ((stmt->next_false == NULL) ? 0 : expression_get_id( stmt->next_false->exp, ids_issued )), 00345 ((stmt->head == NULL) ? 0 : expression_get_id( stmt->head->exp, ids_issued )) 00346 ); 00347 00348 fprintf( ofile, "\n" ); 00349 00350 PROFILE_END; 00351 00352 }
void statement_db_write_expr_tree | ( | statement * | stmt, | |
FILE * | ofile | |||
) |
Writes specified expression trees for given statement block to specified output file.
stmt | Pointer to specified statement tree to display | |
ofile | Pointer to output file to write |
Traverses the specified statement block, writing all expression trees to specified output file.
References statement_s::exp, expression_db_write_tree(), statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_db_write_expr_tree(), and statement_s::suppl.
Referenced by gen_item_db_write_expr_tree(), and statement_db_write_expr_tree().
00397 { PROFILE(STATEMENT_DB_WRITE_EXPR_TREE); 00398 00399 if( stmt != NULL ) { 00400 00401 /* Output ourselves first */ 00402 expression_db_write_tree( stmt->exp, ofile ); 00403 00404 /* Traverse down the rest of the statement block */ 00405 if( (stmt->next_true == stmt->next_false) && (stmt->suppl.part.stop_true == 0) ) { 00406 statement_db_write_expr_tree( stmt->next_true, ofile ); 00407 } else { 00408 if( stmt->suppl.part.stop_false == 0 ) { 00409 statement_db_write_expr_tree( stmt->next_false, ofile ); 00410 } 00411 if( stmt->suppl.part.stop_true == 0 ) { 00412 statement_db_write_expr_tree( stmt->next_true, ofile ); 00413 } 00414 } 00415 00416 } 00417 00418 PROFILE_END; 00419 00420 }
void statement_db_write_tree | ( | statement * | stmt, | |
FILE * | ofile | |||
) |
Writes specified statement tree to the specified output file.
stmt | Pointer to root of statement tree to output | |
ofile | Pointer to output file to write statements to |
Traverses specified statement tree, outputting all statements within that tree.
References statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_db_write(), statement_db_write_tree(), statement_s::suppl, and TRUE.
Referenced by gen_item_db_write(), and statement_db_write_tree().
00363 { PROFILE(STATEMENT_DB_WRITE_TREE); 00364 00365 if( stmt != NULL ) { 00366 00367 /* Traverse down the rest of the statement block */ 00368 if( (stmt->next_true == stmt->next_false) && (stmt->suppl.part.stop_true == 0) ) { 00369 statement_db_write_tree( stmt->next_true, ofile ); 00370 } else { 00371 if( stmt->suppl.part.stop_false == 0 ) { 00372 statement_db_write_tree( stmt->next_false, ofile ); 00373 } 00374 if( stmt->suppl.part.stop_true == 0 ) { 00375 statement_db_write_tree( stmt->next_true, ofile ); 00376 } 00377 } 00378 00379 /* Output ourselves first */ 00380 statement_db_write( stmt, ofile, TRUE ); 00381 00382 } 00383 00384 PROFILE_END; 00385 00386 }
void statement_dealloc | ( | statement * | stmt | ) |
Deallocates statement memory and associated expression tree from the heap.
Deallocates specified statement from heap memory. Does not remove attached expression (this is assumed to be cleaned up by the expression list removal function).
stmt | Pointer to statement to deallocate |
References free_safe, PROFILE, and PROFILE_END.
Referenced by db_create_statement(), fsm_var_cleanup(), and stmt_link_delete_list().
00951 { PROFILE(STATEMENT_DEALLOC); 00952 00953 if( stmt != NULL ) { 00954 00955 /* Finally, deallocate this statement */ 00956 free_safe( stmt, sizeof( statement ) ); 00957 00958 } 00959 00960 PROFILE_END; 00961 00962 }
Recursively deallocates specified statement tree.
stmt | Pointer to head of statement tree to deallocate | |
rm_stmt_blk | If set to TRUE, removes the statement block this statement points to (if any) |
References db_remove_statement_from_current_funit(), expression_s::elem, ESUPPL_TYPE, ETYPE_FUNIT, statement_s::exp, EXP_OP_FORK, EXP_OP_NB_CALL, func_unit_s::first_stmt, free_safe, expression_s::funit, FUNIT_NO_SCORE, statement_s::next_false, statement_s::next_true, expression_s::op, statement_s::part, PROFILE, PROFILE_END, statement_dealloc_recursive(), stmt_blk_add_to_remove_list(), statement_s::suppl, expression_s::suppl, and func_unit_s::type.
Referenced by db_remove_statement(), gen_item_dealloc(), statement_dealloc_recursive(), and stmt_blk_remove().
00898 { PROFILE(STATEMENT_DEALLOC_RECURSIVE); 00899 00900 if( stmt != NULL ) { 00901 00902 assert( stmt->exp != NULL ); 00903 00904 /* If we are a named block or fork call statement, remove that statement block */ 00905 if( (stmt->exp->op == EXP_OP_NB_CALL) || (stmt->exp->op == EXP_OP_FORK) ) { 00906 00907 if( rm_stmt_blk && (ESUPPL_TYPE( stmt->exp->suppl ) == ETYPE_FUNIT) && (stmt->exp->elem.funit->type != FUNIT_NO_SCORE) ) { 00908 stmt_blk_add_to_remove_list( stmt->exp->elem.funit->first_stmt ); 00909 } 00910 00911 } 00912 00913 /* Remove TRUE path */ 00914 if( stmt->next_true == stmt->next_false ) { 00915 00916 if( stmt->suppl.part.stop_true == 0 ) { 00917 statement_dealloc_recursive( stmt->next_true, rm_stmt_blk ); 00918 } 00919 00920 } else { 00921 00922 if( stmt->suppl.part.stop_true == 0 ) { 00923 statement_dealloc_recursive( stmt->next_true, rm_stmt_blk ); 00924 } 00925 00926 /* Remove FALSE path */ 00927 if( stmt->suppl.part.stop_false == 0 ) { 00928 statement_dealloc_recursive( stmt->next_false, rm_stmt_blk ); 00929 } 00930 00931 } 00932 00933 /* Disconnect statement from current functional unit */ 00934 db_remove_statement_from_current_funit( stmt ); 00935 00936 free_safe( stmt, sizeof( statement ) ); 00937 00938 } 00939 00940 PROFILE_END; 00941 00942 }
Creates a list of all signals on the RHS of expressions in the given statement block.
Searches the specified statement block and returns a list of all signals on the right-hand-side of expressions.
stmt | Pointer to current statement block to traverse | |
head | Pointer to head of signal name list that will contain a list of all RHS signals | |
tail | Pointer to tail of signal name list that will contain a list of all RHS signals |
References expression_s::elem, statement_s::exp, EXP_OP_FORK, EXP_OP_NB_CALL, expression_find_rhs_sigs(), func_unit_s::first_stmt, expression_s::funit, statement_s::next_false, statement_s::next_true, expression_s::op, statement_s::part, PROFILE, PROFILE_END, statement_find_rhs_sigs(), and statement_s::suppl.
Referenced by db_create_sensitivity_list(), and statement_find_rhs_sigs().
00780 { PROFILE(STATEMENT_FIND_RHS_SIGS); 00781 00782 if( stmt != NULL ) { 00783 00784 if( (stmt->exp->op == EXP_OP_NB_CALL) || (stmt->exp->op == EXP_OP_FORK) ) { 00785 00786 statement_find_rhs_sigs( stmt->exp->elem.funit->first_stmt, head, tail ); 00787 00788 } else { 00789 00790 /* Find all RHS signals in this statement's expression tree */ 00791 expression_find_rhs_sigs( stmt->exp, head, tail ); 00792 00793 } 00794 00795 /* If both true and false paths lead to same statement, just traverse the true path */ 00796 if( stmt->next_true == stmt->next_false ) { 00797 00798 if( stmt->suppl.part.stop_true == 0 ) { 00799 statement_find_rhs_sigs( stmt->next_true, head, tail ); 00800 } 00801 00802 /* Otherwise, traverse both true and false paths */ 00803 } else { 00804 00805 if( stmt->suppl.part.stop_true == 0 ) { 00806 statement_find_rhs_sigs( stmt->next_true, head, tail ); 00807 } 00808 00809 if( stmt->suppl.part.stop_false == 0 ) { 00810 statement_find_rhs_sigs( stmt->next_false, head, tail ); 00811 } 00812 00813 } 00814 00815 } 00816 00817 PROFILE_END; 00818 00819 }
Searches for statement with ID in the given statement block.
Recursively searches the given statement block for the expression that matches the given ID.
curr | Pointer to current statement in statement block being evaluated | |
id | Statement ID to find |
References statement_s::exp, expression_s::id, statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_find_statement(), and statement_s::suppl.
Referenced by generate_remove_stmt_helper(), and statement_find_statement().
00831 { PROFILE(STATEMENT_FIND_STATEMENT); 00832 00833 statement* found = NULL; /* Pointer to found statement */ 00834 00835 if( curr != NULL ) { 00836 00837 if( curr->exp->id == id ) { 00838 00839 found = curr; 00840 00841 } else { 00842 00843 /* If both true and false paths lead to same item, just traverse the true path */ 00844 if( curr->next_true == curr->next_false ) { 00845 00846 if( curr->suppl.part.stop_true == 0 ) { 00847 found = statement_find_statement( curr->next_true, id ); 00848 } 00849 00850 /* Otherwise, traverse both true and false paths */ 00851 } else if( (curr->suppl.part.stop_true == 0) && 00852 ((found = statement_find_statement( curr->next_true, id )) == NULL) ) { 00853 00854 if( curr->suppl.part.stop_false == 0 ) { 00855 found = statement_find_statement( curr->next_false, id ); 00856 } 00857 00858 } 00859 00860 } 00861 00862 } 00863 00864 PROFILE_END; 00865 00866 return( found ); 00867 00868 }
int statement_get_last_line | ( | statement * | stmt | ) |
Calculates the last line of the specified statement tree.
stmt | Pointer to statement to get last line number for |
References PROFILE, PROFILE_END, and statement_get_last_line_helper().
Referenced by race_handle_race_condition().
00762 { PROFILE(STATEMENT_GET_LAST_LINE); 00763 00764 int retval = statement_get_last_line_helper( stmt, stmt ); 00765 00766 PROFILE_END; 00767 00768 return( retval ); 00769 00770 }
stmt | Pointer to current statement to look at. | |
base | Pointer to root statement in statement tree. |
Recursively iterates through the specified statement tree searching for the last statement in each false/true path (the one whose next pointer points to the head statement). Once it is found, its expression is parsed for its last line and this value is returned. If both the false and tru paths have been parsed, the highest numbered line is returned.
References statement_s::exp, expression_get_last_line_expr(), expression_s::line, statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, and statement_s::suppl.
Referenced by statement_get_last_line().
00724 { PROFILE(STATEMENT_GET_LAST_LINE_HELPER); 00725 00726 expression* last_exp; /* Pointer to last expression in the statement tree */ 00727 int last_false = -1; /* Last false path line number */ 00728 int last_true = -1; /* Last true path line number */ 00729 00730 if( stmt != NULL ) { 00731 00732 /* Check out/traverse false path */ 00733 if( (stmt->next_false == NULL) || (stmt->next_false == base) ) { 00734 last_exp = expression_get_last_line_expr( stmt->exp ); 00735 last_false = last_exp->line; 00736 } else if( stmt->suppl.part.stop_false == 0 ) { 00737 last_false = statement_get_last_line_helper( stmt->next_false, base ); 00738 } 00739 00740 /* Check out/traverse true path */ 00741 if( (stmt->next_true == NULL) || (stmt->next_true == base) ) { 00742 last_exp = expression_get_last_line_expr( stmt->exp ); 00743 last_true = last_exp->line; 00744 } else if( stmt->suppl.part.stop_true == 0 ) { 00745 last_true = statement_get_last_line_helper( stmt->next_true, base ); 00746 } 00747 00748 } 00749 00750 PROFILE_END; 00751 00752 /* Return the greater of the two path last lines */ 00753 return( (last_false > last_true) ? last_false : last_true ); 00754 00755 }
static void statement_queue_add | ( | statement * | stmt, | |
int | id, | |||
int | type | |||
) | [static] |
stmt | Pointer of statement waiting to be linked. | |
id | ID of statement to be read out later. | |
next_true | Set to TRUE if the specified ID is for the next_true statement. |
Creates a new statement loop link for the specified parameters and adds this element to the top of the statement loop queue.
References stmt_loop_link_s::id, malloc_safe, stmt_loop_link_s::next, PROFILE, PROFILE_END, stmt_loop_link_s::stmt, and stmt_loop_link_s::type.
Referenced by statement_db_read().
00195 { PROFILE(STATEMENT_QUEUE_ADD); 00196 00197 stmt_loop_link* sll; /* Pointer to newly created statement loop link */ 00198 00199 /* Create statement loop link element */ 00200 sll = (stmt_loop_link*)malloc_safe( sizeof( stmt_loop_link ) ); 00201 00202 /* Populate statement loop link with specified parameters */ 00203 sll->stmt = stmt; 00204 sll->id = id; 00205 sll->type = type; 00206 sll->next = NULL; 00207 00208 /* Add to top of statement loop queue */ 00209 if( stmt_loop_head == NULL ) { 00210 stmt_loop_head = stmt_loop_tail = sll; 00211 } else { 00212 stmt_loop_tail->next = sll; 00213 stmt_loop_tail = sll; 00214 } 00215 00216 PROFILE_END; 00217 00218 }
static void statement_queue_compare | ( | statement * | stmt | ) | [static] |
stmt | Pointer to statement being read out of the CDD. |
Compares the specified statement against the top of the statement loop queue. If an ID in the queue matches this statement's ID, the element is removed and the next_true and next_false pointers of the stored statement are pointed to the specified statement. The next head is also compared against this statement and the process is repeated until a match is not found.
References statement_s::exp, free_safe, statement_s::head, stmt_loop_link_s::id, expression_s::id, stmt_loop_link_s::next, statement_s::next_false, statement_s::next_true, PROFILE, PROFILE_END, stmt_loop_link_s::stmt, and stmt_loop_link_s::type.
Referenced by statement_db_read().
00231 { PROFILE(STATEMENT_QUEUE_COMPARE); 00232 00233 stmt_loop_link* sll; /* Pointer to current element in statement loop list */ 00234 stmt_loop_link* tsll; /* Temporary pointer to current element in statement loop list */ 00235 stmt_loop_link* last_sll; /* Pointer to last parsed element in statement loop list */ 00236 00237 sll = stmt_loop_head; 00238 last_sll = NULL; 00239 00240 while( sll != NULL ) { 00241 00242 /* If we have a match */ 00243 if( stmt->exp->id == sll->id ) { 00244 00245 /* Set next_true and next_false pointers */ 00246 if( (sll->stmt->next_true == NULL) && (sll->type == 0) ) { 00247 sll->stmt->next_true = stmt; 00248 } 00249 if( (sll->stmt->next_false == NULL) && (sll->type == 1) ) { 00250 sll->stmt->next_false = stmt; 00251 } 00252 if( (sll->stmt->head == NULL) && (sll->type == 2) ) { 00253 sll->stmt->head = stmt; 00254 } 00255 00256 /* Remove this element from the list */ 00257 if( (stmt_loop_head == sll) && (stmt_loop_tail == sll) ) { 00258 stmt_loop_head = stmt_loop_tail = NULL; 00259 } else if( stmt_loop_head == sll ) { 00260 stmt_loop_head = sll->next; 00261 } else if( stmt_loop_tail == sll ) { 00262 stmt_loop_tail = last_sll; 00263 stmt_loop_tail->next = NULL; 00264 } else { 00265 last_sll->next = sll->next; 00266 } 00267 00268 /* Deallocate the current element */ 00269 tsll = sll; 00270 sll = sll->next; 00271 free_safe( tsll, sizeof( stmt_loop_link ) ); 00272 00273 } else { 00274 00275 last_sll = sll; 00276 sll = sll->next; 00277 00278 } 00279 00280 } 00281 00282 PROFILE_END; 00283 00284 }
void statement_queue_display | ( | ) |
Displays the current contents of the statement loop list for debug purposes only.
References statement_s::exp, expression_string(), stmt_loop_link_s::id, stmt_loop_link_s::next, stmt_loop_link_s::stmt, and stmt_loop_link_s::type.
00162 { 00163 00164 stmt_loop_link* sll; /* Pointer to current statement loop link */ 00165 00166 printf( "Statement loop list:\n" ); 00167 00168 sll = stmt_loop_head; 00169 while( sll != NULL ) { 00170 printf( " id: %d, type: %d, stmt: %s ", sll->id, sll->type, expression_string( sll->stmt->exp ) ); 00171 if( sll == stmt_loop_head ) { 00172 printf( "H" ); 00173 } 00174 if( sll == stmt_loop_tail ) { 00175 printf( "T" ); 00176 } 00177 printf( "\n" ); 00178 sll = sll->next; 00179 } 00180 00181 }
Sizes all expressions for the given statement block.
stmt | Pointer to statement block to size elements for | |
funit | Pointer to functional unit containing this statement block |
anonymous | expression_resize statement_size_elements statement_size_elements statement_size_elements |
Recursively sizes all elements for the given statement block.
References statement_s::exp, expression_resize(), FALSE, statement_s::next_false, statement_s::next_true, statement_s::part, PROFILE, PROFILE_END, statement_size_elements(), statement_s::suppl, and TRUE.
Referenced by gen_item_resize_stmts_and_sigs(), and statement_size_elements().
00297 { PROFILE(STATEMENT_SIZE_ELEMENTS); 00298 00299 if( stmt != NULL ) { 00300 00301 /* Size the current statement */ 00302 expression_resize( stmt->exp, funit, TRUE, FALSE ); 00303 00304 /* Iterate to the next statement */ 00305 if( stmt->next_true == stmt->next_false ) { 00306 if( stmt->suppl.part.stop_true == 0 ) { 00307 statement_size_elements( stmt->next_true, funit ); 00308 } 00309 } else { 00310 if( stmt->suppl.part.stop_false == 0 ) { 00311 statement_size_elements( stmt->next_false, funit ); 00312 } 00313 if( stmt->suppl.part.stop_true == 0 ) { 00314 statement_size_elements( stmt->next_true, funit ); 00315 } 00316 } 00317 00318 } 00319 00320 PROFILE_END; 00321 00322 }
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.
stmt_loop_link* stmt_loop_head = NULL [static] |
Pointer to head of statement loop list.
stmt_loop_link* stmt_loop_tail = NULL [static] |
Pointer to tail of statement loop list.
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.