Contains functions for handling generate items. More...
#include <stdio.h>
#include "defines.h"
Go to the source code of this file.
Functions | |
void | gen_item_display (gen_item *gi) |
Displays the specified generate item to standard output. | |
int | gen_item_display_block (gen_item *root) |
Displays an entire generate block. | |
gen_item * | gen_item_find (gen_item *root, gen_item *gi) |
Searches for a generate item in the generate block of root that matches gi. | |
void | gen_item_remove_if_contains_expr_calling_stmt (gen_item *gi, statement *stmt) |
Searches for an expression in the generate list that calls the given statement. | |
bool | gen_item_varname_contains_genvar (char *name) |
Returns TRUE if the specified variable name contains a generate variable within it. | |
char * | gen_item_calc_signal_name (const char *name, func_unit *funit, int line, bool no_genvars) |
Returns the actual signal name specified by the given signal name which references a generated hierarchy. | |
gen_item * | gen_item_create_expr (expression *expr) |
Creates a generate item for an expression. | |
gen_item * | gen_item_create_sig (vsignal *sig) |
Creates a generate item for a signal. | |
gen_item * | gen_item_create_stmt (statement *stmt) |
Creates a generate item for a statement. | |
gen_item * | gen_item_create_inst (funit_inst *inst) |
Creates a generate item for an instance. | |
gen_item * | gen_item_create_tfn (funit_inst *inst) |
Creates a generate item for a namespace. | |
gen_item * | gen_item_create_bind (const char *name, expression *expr) |
Creates a generate item for a binding. | |
void | gen_item_resize_stmts_and_sigs (gen_item *gi, func_unit *funit) |
Resizes all statements and signals in the given generate item block. | |
void | gen_item_assign_ids (gen_item *gi, func_unit *funit) |
Assigns unique signal ID or expression IDs to all expressions for specified statement block. | |
void | gen_item_db_write (gen_item *gi, uint32 type, FILE *file) |
Outputs the current generate item to the given output file if it matches the type specified. | |
void | gen_item_db_write_expr_tree (gen_item *gi, FILE *file) |
Outputs the entire expression tree from the given generate statement. | |
bool | gen_item_connect (gen_item *gi1, gen_item *gi2, int conn_id, bool stop_on_null) |
Connects a generate item block to a new generate item. | |
void | gen_item_bind (gen_item *gi) |
Checks generate item and if it is a bind, adds it to binding pool and returns TRUE. | |
void | generate_resolve_inst (funit_inst *inst) |
Resolves all generate items in the design. | |
bool | generate_remove_stmt (statement *stmt) |
Removes the given generate statement from the correct instance. | |
void | gen_item_dealloc (gen_item *gi, bool rm_elem) |
Deallocates all associated memory for the given generate item. |
Contains functions for handling generate items.
Assigns unique signal ID or expression IDs to all expressions for specified statement block.
anonymous | statement_assign_expr_ids |
Assigns unique expression and signal IDs to each expression in the tree given for a generated statement or for the given signal.
gi | Pointer to generate item to check and assign expression IDs for | |
funit | Pointer to functional unit containing this generate item |
References curr_sig_id, gen_item_s::elem, GI_TYPE_SIG, GI_TYPE_STMT, vsignal_s::id, gen_item_s::part, PROFILE, PROFILE_END, gen_item_s::sig, statement_assign_expr_ids(), gen_item_s::stmt, and gen_item_s::suppl.
Referenced by instance_db_write().
00772 { PROFILE(GEN_ITEM_ASSIGN_IDS); 00773 00774 if( gi->suppl.part.removed == 0 ) { 00775 00776 /* Assign expression IDs if this is a statement */ 00777 if( gi->suppl.part.type == GI_TYPE_STMT ) { 00778 statement_assign_expr_ids( gi->elem.stmt, funit ); 00779 } else if( gi->suppl.part.type == GI_TYPE_SIG ) { 00780 gi->elem.sig->id = curr_sig_id; 00781 curr_sig_id++; 00782 } 00783 00784 } 00785 00786 PROFILE_END; 00787 00788 }
void gen_item_bind | ( | gen_item * | gi | ) |
Checks generate item and if it is a bind, adds it to binding pool and returns TRUE.
Updates the specified expression name to be that of the generate item name if the current generate item is a BIND type.
gi | Pointer to generate item to examine |
References gen_item_s::elem, gen_item_s::expr, free_safe, GI_TYPE_BIND, expression_s::name, gen_item_s::part, PROFILE, PROFILE_END, strdup_safe, gen_item_s::suppl, and gen_item_s::varname.
Referenced by funit_size_elements().
01068 { PROFILE(GEN_ITEM_BIND); 01069 01070 if( gi->suppl.part.type == GI_TYPE_BIND ) { 01071 01072 /* Remove the current name */ 01073 free_safe( gi->elem.expr->name, (strlen( gi->elem.expr->name ) + 1) ); 01074 01075 /* Assign the new name */ 01076 gi->elem.expr->name = strdup_safe( gi->varname ); 01077 01078 } 01079 01080 PROFILE_END; 01081 01082 }
Returns the actual signal name specified by the given signal name which references a generated hierarchy.
name | Name of signal that we possibly need to convert if it contains generate variable(s) | |
funit | Pointer to current functional unit | |
line | Line number in which the signal's expression exists | |
no_genvars | If set to TRUE, we need to make sure that we do not see a generate variable in the generate hierarchical expression. |
anonymous | parse_static_expr Throw |
Iterates through the given name, substituting any found generate variables with their current value.
References Catch_anonymous, free_safe, gen_item_get_genvar(), parse_static_expr(), PROFILE, realloc_safe, strdup_safe, Throw, and Try.
Referenced by gen_item_resolve().
00449 { PROFILE(GEN_ITEM_CALC_SIGNAL_NAME); 00450 00451 char* new_name = NULL; /* Return value of this function */ 00452 char* tmpname; /* Temporary name of current part of variable */ 00453 char* pre; /* String prior to the generate variable */ 00454 char* genvar; /* Generate variable */ 00455 char* post; /* String after the generate variable */ 00456 char intstr[20]; /* String containing an integer value */ 00457 char* ptr; /* Pointer to allocated memory for name */ 00458 00459 /* Allocate memory */ 00460 tmpname = strdup_safe( name ); 00461 ptr = tmpname; 00462 new_name = strdup_safe( "" ); 00463 00464 Try { 00465 00466 do { 00467 gen_item_get_genvar( tmpname, &pre, &genvar, &post ); 00468 if( genvar != NULL ) { 00469 unsigned int rv = snprintf( intstr, 20, "%d", parse_static_expr( genvar, funit, line, no_genvars ) ); 00470 assert( rv < 20 ); 00471 new_name = (char*)realloc_safe( new_name, (strlen( new_name ) + 1), (strlen( new_name ) + strlen( pre ) + strlen( intstr ) + 3) ); 00472 strncat( new_name, pre, strlen( pre ) ); 00473 strncat( new_name, "[", 1 ); 00474 strncat( new_name, intstr, strlen( intstr ) ); 00475 strncat( new_name, "]", 1 ); 00476 tmpname = post; 00477 } else { 00478 new_name = (char*)realloc_safe( new_name, (strlen( new_name ) + 1), (strlen( new_name ) + strlen( pre ) + 1) ); 00479 strncat( new_name, pre, strlen( pre ) ); 00480 } 00481 } while( genvar != NULL ); 00482 00483 } Catch_anonymous { 00484 free_safe( new_name, (strlen( new_name ) + 1) ); 00485 free_safe( ptr, (strlen( name ) + 1) ); 00486 Throw 0; 00487 } 00488 00489 /* Deallocate memory */ 00490 free_safe( ptr, (strlen( name ) + 1) ); 00491 00492 /* Make sure that the new_name is set to something */ 00493 assert( new_name != NULL ); 00494 00495 return( new_name ); 00496 00497 }
Connects a generate item block to a new generate item.
gi1 | Pointer to generate item block to connect to gi2 | |
gi2 | Pointer to generate item to connect to gi1 | |
conn_id | Connection ID | |
stop_on_null | Sets stop bit(s) if a NULL next_true/next_false pointer is found |
References FALSE, gen_item_connect(), GI_TYPE_TFN, gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, PROFILE, PROFILE_END, gen_item_s::suppl, TRUE, and gen_item_s::varname.
Referenced by db_gen_item_connect(), and gen_item_connect().
00849 { PROFILE(GEN_ITEM_CONNECT); 00850 00851 bool retval = FALSE; /* Return value for this function */ 00852 00853 /* Set the connection ID */ 00854 gi1->suppl.part.conn_id = conn_id; 00855 00856 /* If both paths go to the same destination, only parse one path */ 00857 if( gi1->next_true == gi1->next_false ) { 00858 00859 /* If the TRUE path is NULL, connect it to the new statement */ 00860 if( gi1->next_true == NULL ) { 00861 gi1->next_true = gi2; 00862 gi1->next_false = gi2; 00863 if( (gi1->next_true->suppl.part.conn_id == conn_id) || stop_on_null ) { 00864 gi1->suppl.part.stop_true = 1; 00865 gi1->suppl.part.stop_false = 1; 00866 } 00867 retval = TRUE; 00868 } else if( gi1->next_true->suppl.part.conn_id == conn_id ) { 00869 gi1->suppl.part.stop_true = 1; 00870 gi1->suppl.part.stop_false = 1; 00871 00872 /* If the TRUE path leads to a loop/merge, stop traversing */ 00873 } else if( gi1->next_true != gi2 ) { 00874 retval |= gen_item_connect( gi1->next_true, gi2, conn_id, stop_on_null ); 00875 } 00876 00877 } else { 00878 00879 /* Traverse FALSE path */ 00880 if( gi1->next_false == NULL ) { 00881 gi1->next_false = gi2; 00882 if( (gi1->next_false->suppl.part.conn_id == conn_id) || stop_on_null ) { 00883 gi1->suppl.part.stop_false = 1; 00884 } else { 00885 gi1->next_false->suppl.part.conn_id = conn_id; 00886 } 00887 retval = TRUE; 00888 } else if( gi1->next_false->suppl.part.conn_id == conn_id ) { 00889 gi1->suppl.part.stop_false = 1; 00890 } else if( gi1->next_false != gi2 ) { 00891 retval |= gen_item_connect( gi1->next_false, gi2, conn_id, stop_on_null ); 00892 } 00893 00894 /* Traverse TRUE path */ 00895 if( gi1->next_true == NULL ) { 00896 gi1->next_true = gi2; 00897 if( (gi1->next_true->suppl.part.conn_id == conn_id) || stop_on_null ) { 00898 gi1->suppl.part.stop_true = 1; 00899 } 00900 retval = TRUE; 00901 } else if( gi1->next_true->suppl.part.conn_id == conn_id ) { 00902 gi1->suppl.part.stop_true = 1; 00903 } else if( (gi1->next_true != gi2) && (gi1->suppl.part.type != GI_TYPE_TFN) && (gi1->varname == NULL) ) { 00904 retval |= gen_item_connect( gi1->next_true, gi2, conn_id, TRUE ); 00905 } 00906 00907 } 00908 00909 PROFILE_END; 00910 00911 return( retval ); 00912 00913 }
gen_item* gen_item_create_bind | ( | const char * | name, | |
expression * | expr | |||
) |
Creates a generate item for a binding.
name | Name of signal to bind to | |
expr | Pointer to expression to bind signal to |
Create a new generate item for a namespace.
References gen_item_s::all, DEBUG, debug_mode, gen_item_s::elem, gen_item_s::expr, gen_item_stringify(), GI_TYPE_BIND, malloc_safe, gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, print_output(), PROFILE, strdup_safe, gen_item_s::suppl, user_msg, USER_MSG_LENGTH, and gen_item_s::varname.
Referenced by db_create_expression(), and gen_item_resolve().
00695 { PROFILE(GEN_ITEM_CREATE_BIND); 00696 00697 gen_item* gi; 00698 00699 /* Create the generate item for a namespace */ 00700 gi = (gen_item*)malloc_safe( sizeof( gen_item ) ); 00701 gi->elem.expr = expr; 00702 gi->suppl.all = 0; 00703 gi->suppl.part.type = GI_TYPE_BIND; 00704 gi->varname = strdup_safe( name ); 00705 gi->next_true = NULL; 00706 gi->next_false = NULL; 00707 00708 #ifdef DEBUG_MODE 00709 if( debug_mode ) { 00710 char str[USER_MSG_LENGTH]; 00711 unsigned int rv; 00712 gen_item_stringify( gi, str, USER_MSG_LENGTH ); 00713 rv = snprintf( user_msg, USER_MSG_LENGTH, "In gen_item_create_bind, %s", str ); 00714 assert( rv < USER_MSG_LENGTH ); 00715 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00716 } 00717 #endif 00718 00719 return( gi ); 00720 00721 }
gen_item* gen_item_create_expr | ( | expression * | expr | ) |
Creates a generate item for an expression.
expr | Pointer to root expression to create (this is an expression from a FOR, IF or CASE statement) |
Creates a new generate item for an expression.
References gen_item_s::all, DEBUG, debug_mode, gen_item_s::elem, gen_item_s::expr, gen_item_stringify(), GI_TYPE_EXPR, malloc_safe, gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, print_output(), PROFILE, gen_item_s::suppl, user_msg, USER_MSG_LENGTH, and gen_item_s::varname.
Referenced by db_add_expression().
00508 { PROFILE(GEN_ITEM_CREATE_EXPR); 00509 00510 gen_item* gi; 00511 00512 /* Create the generate item for an expression */ 00513 gi = (gen_item*)malloc_safe( sizeof( gen_item ) ); 00514 gi->elem.expr = expr; 00515 gi->suppl.all = 0; 00516 gi->suppl.part.type = GI_TYPE_EXPR; 00517 gi->varname = NULL; 00518 gi->next_true = NULL; 00519 gi->next_false = NULL; 00520 00521 #ifdef DEBUG_MODE 00522 if( debug_mode ) { 00523 char str[USER_MSG_LENGTH]; 00524 unsigned int rv; 00525 gen_item_stringify( gi, str, USER_MSG_LENGTH ); 00526 rv = snprintf( user_msg, USER_MSG_LENGTH, "In gen_item_create_expr, %s", str ); 00527 assert( rv < USER_MSG_LENGTH ); 00528 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00529 } 00530 #endif 00531 00532 return( gi ); 00533 00534 }
gen_item* gen_item_create_inst | ( | funit_inst * | inst | ) |
Creates a generate item for an instance.
inst | Pointer to instance to create a generate item for (instantiations) |
Create a new generate item for an instance.
References gen_item_s::all, DEBUG, debug_mode, gen_item_s::elem, gen_item_stringify(), GI_TYPE_INST, gen_item_s::inst, malloc_safe, gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, print_output(), PROFILE, gen_item_s::suppl, user_msg, USER_MSG_LENGTH, and gen_item_s::varname.
Referenced by db_add_instance().
00619 { PROFILE(GEN_ITEM_CREATE_INST); 00620 00621 gen_item* gi; 00622 00623 /* Create the generate item for an instance */ 00624 gi = (gen_item*)malloc_safe( sizeof( gen_item ) ); 00625 gi->elem.inst = inst; 00626 gi->suppl.all = 0; 00627 gi->suppl.part.type = GI_TYPE_INST; 00628 gi->varname = NULL; 00629 gi->next_true = NULL; 00630 gi->next_false = NULL; 00631 00632 #ifdef DEBUG_MODE 00633 if( debug_mode ) { 00634 char str[USER_MSG_LENGTH]; 00635 unsigned int rv; 00636 gen_item_stringify( gi, str, USER_MSG_LENGTH ); 00637 rv = snprintf( user_msg, USER_MSG_LENGTH, "In gen_item_create_inst, %s", str ); 00638 assert( rv < USER_MSG_LENGTH ); 00639 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00640 } 00641 #endif 00642 00643 return( gi ); 00644 00645 }
Creates a generate item for a signal.
sig | Pointer to signal to create a generate item for (wire/reg instantions) |
Creates a new generate item for a signal.
References gen_item_s::all, DEBUG, debug_mode, gen_item_s::elem, gen_item_stringify(), GI_TYPE_SIG, malloc_safe, gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, print_output(), PROFILE, gen_item_s::sig, gen_item_s::suppl, user_msg, USER_MSG_LENGTH, and gen_item_s::varname.
Referenced by db_add_signal(), funit_find_signal(), and gen_item_resolve().
00545 { PROFILE(GEN_ITEM_CREATE_SIG); 00546 00547 gen_item* gi; 00548 00549 /* Create the generate item for a signal */ 00550 gi = (gen_item*)malloc_safe( sizeof( gen_item ) ); 00551 gi->elem.sig = sig; 00552 gi->suppl.all = 0; 00553 gi->suppl.part.type = GI_TYPE_SIG; 00554 gi->varname = NULL; 00555 gi->next_true = NULL; 00556 gi->next_false = NULL; 00557 00558 #ifdef DEBUG_MODE 00559 if( debug_mode ) { 00560 char str[USER_MSG_LENGTH]; 00561 unsigned int rv; 00562 gen_item_stringify( gi, str, USER_MSG_LENGTH ); 00563 rv = snprintf( user_msg, USER_MSG_LENGTH, "In gen_item_create_sig, %s", str ); 00564 assert( rv < USER_MSG_LENGTH ); 00565 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00566 } 00567 #endif 00568 00569 return( gi ); 00570 00571 }
Creates a generate item for a statement.
stmt | Pointer to statement to create a generate item for (assign, always, initial blocks) |
Create a new generate item for a statement.
References gen_item_s::all, DEBUG, debug_mode, gen_item_s::elem, gen_item_stringify(), GI_TYPE_STMT, malloc_safe, gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, print_output(), PROFILE, gen_item_s::stmt, gen_item_s::suppl, user_msg, USER_MSG_LENGTH, and gen_item_s::varname.
Referenced by db_add_statement(), and gen_item_resolve().
00582 { PROFILE(GEN_ITEM_CREATE_STMT); 00583 00584 gen_item* gi; 00585 00586 /* Create the generate item for a statement */ 00587 gi = (gen_item*)malloc_safe( sizeof( gen_item ) ); 00588 gi->elem.stmt = stmt; 00589 gi->suppl.all = 0; 00590 gi->suppl.part.type = GI_TYPE_STMT; 00591 gi->varname = NULL; 00592 gi->next_true = NULL; 00593 gi->next_false = NULL; 00594 00595 #ifdef DEBUG_MODE 00596 if( debug_mode ) { 00597 char str[USER_MSG_LENGTH]; 00598 unsigned int rv; 00599 gen_item_stringify( gi, str, USER_MSG_LENGTH ); 00600 rv = snprintf( user_msg, USER_MSG_LENGTH, "In gen_item_create_stmt, %s", str ); 00601 assert( rv < USER_MSG_LENGTH ); 00602 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00603 } 00604 #endif 00605 00606 return( gi ); 00607 00608 }
gen_item* gen_item_create_tfn | ( | funit_inst * | inst | ) |
Creates a generate item for a namespace.
inst | Pointer to namespace to create a generate item for (named blocks, functions or tasks) |
Create a new generate item for a namespace.
References gen_item_s::all, DEBUG, debug_mode, gen_item_s::elem, gen_item_stringify(), GI_TYPE_TFN, gen_item_s::inst, malloc_safe, gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, print_output(), PROFILE, gen_item_s::suppl, user_msg, USER_MSG_LENGTH, and gen_item_s::varname.
00656 { PROFILE(GEN_ITEM_CREATE_TFN); 00657 00658 gen_item* gi; 00659 00660 /* Create the generate item for a namespace */ 00661 gi = (gen_item*)malloc_safe( sizeof( gen_item ) ); 00662 gi->elem.inst = inst; 00663 gi->suppl.all = 0; 00664 gi->suppl.part.type = GI_TYPE_TFN; 00665 gi->varname = NULL; 00666 gi->next_true = NULL; 00667 gi->next_false = NULL; 00668 00669 #ifdef DEBUG_MODE 00670 if( debug_mode ) { 00671 char str[USER_MSG_LENGTH]; 00672 unsigned int rv; 00673 gen_item_stringify( gi, str, USER_MSG_LENGTH ); 00674 rv = snprintf( user_msg, USER_MSG_LENGTH, "In gen_item_create_tfn, %s", str ); 00675 assert( rv < USER_MSG_LENGTH ); 00676 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00677 } 00678 #endif 00679 00680 return( gi ); 00681 00682 }
void gen_item_db_write | ( | gen_item * | gi, | |
uint32 | type, | |||
FILE * | ofile | |||
) |
Outputs the current generate item to the given output file if it matches the type specified.
Checks the given generate item against the supplied type. If they match, outputs the given generate item to the specified output file. If they do not match, nothing is done.
gi | Pointer to current generate item to test and output | |
type | Specifies the type of the generate item to output | |
ofile | Output file to display generate item to |
References gen_item_s::elem, GI_TYPE_SIG, GI_TYPE_STMT, gen_item_s::part, PROFILE, PROFILE_END, gen_item_s::sig, statement_db_write_tree(), gen_item_s::stmt, gen_item_s::suppl, and vsignal_db_write().
Referenced by funit_db_write().
00799 { PROFILE(GEN_ITEM_DB_WRITE); 00800 00801 /* If the types match, output based on type */ 00802 if( (gi->suppl.part.type == type) && (gi->suppl.part.removed == 0) ) { 00803 00804 switch( type ) { 00805 case GI_TYPE_SIG : 00806 vsignal_db_write( gi->elem.sig, ofile ); 00807 break; 00808 case GI_TYPE_STMT : 00809 statement_db_write_tree( gi->elem.stmt, ofile ); 00810 break; 00811 default : /* Should never be called */ 00812 assert( (type == GI_TYPE_SIG) || (type == GI_TYPE_STMT) ); 00813 break; 00814 } 00815 00816 } 00817 00818 PROFILE_END; 00819 00820 }
void gen_item_db_write_expr_tree | ( | gen_item * | gi, | |
FILE * | ofile | |||
) |
Outputs the entire expression tree from the given generate statement.
Outputs all expressions for the statement contained in the specified generate item.
gi | Pointer to current generate item to test and output | |
ofile | Output file to display generate item to |
References gen_item_s::elem, GI_TYPE_STMT, gen_item_s::part, PROFILE, PROFILE_END, statement_db_write_expr_tree(), gen_item_s::stmt, and gen_item_s::suppl.
Referenced by funit_db_write().
00828 { PROFILE(GEN_ITEM_DB_WRITE_EXPR_TREE); 00829 00830 /* Only do this for statements */ 00831 if( (gi->suppl.part.type == GI_TYPE_STMT) && (gi->suppl.part.removed == 0) ) { 00832 00833 statement_db_write_expr_tree( gi->elem.stmt, ofile ); 00834 00835 } 00836 00837 PROFILE_END; 00838 00839 }
Deallocates all associated memory for the given generate item.
Recursively deallocates the gen_item structure tree.
gi | Pointer to gen_item structure to deallocate | |
rm_elem | If set to TRUE, removes the associated element |
References gen_item_s::elem, gen_item_s::expr, expression_dealloc(), FALSE, free_safe, gen_item_dealloc(), GI_TYPE_BIND, GI_TYPE_EXPR, GI_TYPE_INST, GI_TYPE_SIG, GI_TYPE_STMT, GI_TYPE_TFN, gen_item_s::inst, instance_dealloc_tree(), gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, PROFILE, PROFILE_END, gen_item_s::sig, statement_dealloc_recursive(), gen_item_s::stmt, gen_item_s::suppl, gen_item_s::varname, and vsignal_dealloc().
Referenced by db_find_gen_item(), funit_find_signal(), gen_item_dealloc(), and gitem_link_delete_list().
01179 { PROFILE(GEN_ITEM_DEALLOC); 01180 01181 if( gi != NULL ) { 01182 01183 /* Deallocate children first */ 01184 if( gi->next_true == gi->next_false ) { 01185 if( gi->suppl.part.stop_true == 0 ) { 01186 gen_item_dealloc( gi->next_true, rm_elem ); 01187 } 01188 } else { 01189 if( gi->suppl.part.stop_false == 0 ) { 01190 gen_item_dealloc( gi->next_false, rm_elem ); 01191 } 01192 if( gi->suppl.part.stop_true == 0 ) { 01193 gen_item_dealloc( gi->next_true, rm_elem ); 01194 } 01195 } 01196 01197 /* If we need to remove the current element, do so now */ 01198 if( rm_elem ) { 01199 switch( gi->suppl.part.type ) { 01200 case GI_TYPE_EXPR : 01201 expression_dealloc( gi->elem.expr, FALSE ); 01202 break; 01203 case GI_TYPE_SIG : 01204 vsignal_dealloc( gi->elem.sig ); 01205 break; 01206 case GI_TYPE_STMT : 01207 statement_dealloc_recursive( gi->elem.stmt, FALSE ); 01208 break; 01209 case GI_TYPE_INST : 01210 case GI_TYPE_TFN : 01211 instance_dealloc_tree( gi->elem.inst ); 01212 break; 01213 case GI_TYPE_BIND : 01214 break; 01215 default : break; 01216 } 01217 } 01218 01219 /* Remove the varname if necessary */ 01220 free_safe( gi->varname, (strlen( gi->varname ) + 1) ); 01221 01222 /* Now deallocate ourselves */ 01223 free_safe( gi, sizeof( gen_item ) ); 01224 01225 } 01226 01227 PROFILE_END; 01228 01229 }
void gen_item_display | ( | gen_item * | gi | ) |
Displays the specified generate item to standard output.
Displays the contents of the specified generate item to standard output (used for debugging purposes).
gi | Pointer to generate item to display |
References gen_item_stringify(), PROFILE, and PROFILE_END.
Referenced by gen_item_display_block_helper().
00134 { PROFILE(GEN_ITEM_DISPLAY); 00135 00136 char str[4096]; /* String to store data into */ 00137 00138 gen_item_stringify( gi, str, 4096 ); 00139 00140 printf( " %s\n", str ); 00141 00142 PROFILE_END; 00143 00144 }
int gen_item_display_block | ( | gen_item * | root | ) |
Displays an entire generate block.
Displays an entire generate block to standard output (used for debugging purposes).
root | Pointer to starting generate item to display |
References gen_item_display_block_helper(), PROFILE, and PROFILE_END.
Referenced by gitem_link_display().
00189 { PROFILE(GEN_ITEM_DISPLAY_BLOCK); 00190 00191 printf( "Generate block:\n" ); 00192 00193 gen_item_display_block_helper( root ); 00194 00195 PROFILE_END; 00196 00197 return( 1 ); 00198 00199 }
Searches for a generate item in the generate block of root that matches gi.
Recursively traverses the specified generate item block searching for a generate item that matches the specified generate item.
root | Pointer to root of generate item block to search in | |
gi | Pointer to generate item to search for |
References gen_item_compare(), gen_item_find(), gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, PROFILE, PROFILE_END, and gen_item_s::suppl.
Referenced by db_find_gen_item(), funit_find_signal(), gen_item_find(), and gitem_link_find().
00244 { PROFILE(GEN_ITEM_FIND); 00245 00246 gen_item* found = NULL; /* Return value for this function */ 00247 00248 assert( gi != NULL ); 00249 00250 if( root != NULL ) { 00251 00252 if( gen_item_compare( root, gi ) ) { 00253 00254 found = root; 00255 00256 } else { 00257 00258 /* If both true and false paths lead to same item, just traverse the true path */ 00259 if( root->next_true == root->next_false ) { 00260 00261 if( root->suppl.part.stop_true == 0 ) { 00262 found = gen_item_find( root->next_true, gi ); 00263 } 00264 00265 /* Otherwise, traverse both true and false paths */ 00266 } else if( (root->suppl.part.stop_true == 0) && ((found = gen_item_find( root->next_true, gi )) == NULL) ) { 00267 00268 if( root->suppl.part.stop_false == 0 ) { 00269 found = gen_item_find( root->next_false, gi ); 00270 } 00271 00272 } 00273 00274 } 00275 00276 } 00277 00278 PROFILE_END; 00279 00280 return( found ); 00281 00282 }
Searches for an expression in the generate list that calls the given statement.
Removes the given generate item if it contains an expressions that calls a statement.
gi | Pointer to generate item list to search | |
stmt | Pointer to statement to search for |
References gen_item_s::elem, gen_item_remove_if_contains_expr_calling_stmt(), GI_TYPE_STMT, gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, PROFILE, PROFILE_END, statement_contains_expr_calling_stmt(), gen_item_s::stmt, and gen_item_s::suppl.
Referenced by gen_item_remove_if_contains_expr_calling_stmt(), and instance_remove_stmt_blks_calling_stmt().
00290 { PROFILE(GEN_ITEM_REMOVE_IF_CONTAINS_EXPR_CALLING_STMT); 00291 00292 if( gi != NULL ) { 00293 00294 if( gi->suppl.part.type == GI_TYPE_STMT ) { 00295 00296 if( statement_contains_expr_calling_stmt( gi->elem.stmt, stmt ) ) { 00297 gi->suppl.part.removed = 1; 00298 } 00299 00300 } else { 00301 00302 /* If both true and false paths lead to same item, just traverse the true path */ 00303 if( gi->next_true == gi->next_false ) { 00304 00305 if( gi->suppl.part.stop_true == 0 ) { 00306 gen_item_remove_if_contains_expr_calling_stmt( gi->next_true, stmt ); 00307 } 00308 00309 /* Otherwise, traverse both true and false paths */ 00310 } else { 00311 00312 if( gi->suppl.part.stop_true == 0 ) { 00313 gen_item_remove_if_contains_expr_calling_stmt( gi->next_true, stmt ); 00314 } 00315 00316 if( gi->suppl.part.stop_false == 0 ) { 00317 gen_item_remove_if_contains_expr_calling_stmt( gi->next_false, stmt ); 00318 } 00319 00320 } 00321 00322 } 00323 00324 } 00325 00326 PROFILE_END; 00327 00328 }
Resizes all statements and signals in the given generate item block.
anonymous | vsignal_create_vec statement_size_elements gen_item_resize_stmts_and_sigs gen_item_resize_stmts_and_sigs gen_item_resize_stmts_and_sigs |
Recursively iterates the the specified generate item block, resizing all statements within that block.
gi | Pointer to generate item block to check | |
funit | Pointer to functional unit that contains this generate item |
References gen_item_s::elem, gen_item_resize_stmts_and_sigs(), GI_TYPE_SIG, GI_TYPE_STMT, gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, PROFILE, PROFILE_END, gen_item_s::sig, statement_size_elements(), gen_item_s::stmt, gen_item_s::suppl, and vsignal_create_vec().
Referenced by funit_size_elements(), and gen_item_resize_stmts_and_sigs().
00732 { PROFILE(GEN_ITEM_RESIZE_STMTS_AND_SIGS); 00733 00734 if( gi != NULL ) { 00735 00736 /* Resize our statement, if we are one */ 00737 if( gi->suppl.part.type == GI_TYPE_STMT ) { 00738 statement_size_elements( gi->elem.stmt, funit ); 00739 } else if( gi->suppl.part.type == GI_TYPE_SIG ) { 00740 vsignal_create_vec( gi->elem.sig ); 00741 } 00742 00743 /* Go to the next generate item */ 00744 if( gi->next_true == gi->next_false ) { 00745 if( gi->suppl.part.stop_true == 0 ) { 00746 gen_item_resize_stmts_and_sigs( gi->next_true, funit ); 00747 } 00748 } else { 00749 if( gi->suppl.part.stop_false == 0 ) { 00750 gen_item_resize_stmts_and_sigs( gi->next_false, funit ); 00751 } 00752 if( gi->suppl.part.stop_true == 0 ) { 00753 gen_item_resize_stmts_and_sigs( gi->next_true, funit ); 00754 } 00755 } 00756 00757 } 00758 00759 PROFILE_END; 00760 00761 }
bool gen_item_varname_contains_genvar | ( | char * | name | ) |
Returns TRUE if the specified variable name contains a generate variable within it.
name | Variable name to check |
This function is called by db_create_expression() just before it places its signal name in the binding list. If the specified signal name contains a generate variable, we need to create a generate item binding element so that we can properly substitute the generate variable name with its current value.
References FALSE, free_safe, gen_item_get_genvar(), PROFILE, strdup_safe, and TRUE.
Referenced by db_create_expression().
00406 { PROFILE(GEN_ITEM_VARNAME_CONTAINS_GENVAR); 00407 00408 bool retval = FALSE; /* Return value for this function */ 00409 char* pre; /* String prior to the generate variable */ 00410 char* genvar; /* Generate variable */ 00411 char* post; /* String after the generate variable */ 00412 char* tmpname; /* Copy of the given name */ 00413 00414 /* Allocate memory */ 00415 tmpname = strdup_safe( name ); 00416 00417 /* Find the first generate variable */ 00418 gen_item_get_genvar( tmpname, &pre, &genvar, &post ); 00419 00420 if( genvar != NULL ) { 00421 retval = TRUE; 00422 } 00423 00424 /* Deallocate memory */ 00425 free_safe( tmpname, (strlen( name ) + 1) ); 00426 00427 return( retval ); 00428 00429 }
Removes the given generate statement from the correct instance.
Iterates through the entire instance tree finding and "removing" all statement generate items that match the given statement ID. This will get called by the stmt_blk_remove() function when a statement has been found that does not exist in a functional unit.
stmt | Statement to set "remove" bit on |
References curr_db, FALSE, generate_remove_stmt_helper(), inst_link_s::inst, db_s::inst_head, inst_link_s::next, PROFILE, and PROFILE_END.
Referenced by stmt_blk_add_to_remove_list().
01155 { PROFILE(GENERATE_REMOVE_STMT); 01156 01157 bool retval = FALSE; /* Return value for this function */ 01158 inst_link* instl; /* Pointer to current instance list to parse */ 01159 01160 /* Search for the generate item in the instance lists */ 01161 instl = db_list[curr_db]->inst_head; 01162 while( instl != NULL ) { 01163 retval |= generate_remove_stmt_helper( instl->inst, stmt ); 01164 instl = instl->next; 01165 } 01166 01167 PROFILE_END; 01168 01169 return( retval ); 01170 01171 }
void generate_resolve_inst | ( | funit_inst * | inst | ) |
Resolves all generate items in the design.
anonymous | generate_resolve gen_item_resolve |
Resolves all generate items in the given instance. This is called at a specific point in the binding process.
inst | Pointer to current instance in instance tree to resolve for |
References funit_inst_s::funit, gen_item_resolve(), gitem_link_s::gi, func_unit_s::gitem_head, gitem_link_s::next, PROFILE, and PROFILE_END.
Referenced by instance_resolve_helper().
01092 { PROFILE(GENERATE_RESOLVE_INST); 01093 01094 if( inst != NULL ) { 01095 01096 /* Resolve ourself */ 01097 if( inst->funit != NULL ) { 01098 gitem_link* curr_gi = inst->funit->gitem_head; 01099 while( curr_gi != NULL ) { 01100 gen_item_resolve( curr_gi->gi, inst ); 01101 curr_gi = curr_gi->next; 01102 } 01103 } 01104 01105 } 01106 01107 PROFILE_END; 01108 01109 }