#include <string.h>
#include <stdio.h>
#include "binding.h"
#include "defines.h"
#include "expr.h"
#include "func_unit.h"
#include "gen_item.h"
#include "instance.h"
#include "link.h"
#include "obfuscate.h"
#include "param.h"
#include "scope.h"
#include "statement.h"
#include "util.h"
#include "vector.h"
#include "vsignal.h"
Functions | |
int | parse_static_expr (char *str, func_unit *funit, int lineno, bool no_genvars) |
static void | gen_item_stringify (gen_item *gi, char *str, unsigned int str_len) |
void | gen_item_display (gen_item *gi) |
Displays the specified generate item to standard output. | |
static void | gen_item_display_block_helper (gen_item *root) |
int | gen_item_display_block (gen_item *root) |
Displays an entire generate block. | |
static bool | gen_item_compare (gen_item *gi1, gen_item *gi2) |
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. | |
static void | gen_item_get_genvar (char *varname, char **pre, char **genvar, char **post) |
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 *ofile) |
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 *ofile) |
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. | |
static void | gen_item_resolve (gen_item *gi, funit_inst *inst) |
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. | |
static bool | generate_remove_stmt_helper (funit_inst *root, statement *stmt) |
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. | |
Variables | |
db ** | db_list |
unsigned int | curr_db |
char | user_msg [USER_MSG_LENGTH] |
bool | debug_mode |
func_unit * | curr_funit |
int | curr_sig_id |
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 }
gi1 | Pointer to first generate item to compare | |
gi2 | Pointer to second generate item to compare |
References gen_item_s::elem, statement_s::exp, gen_item_s::expr, FALSE, GI_TYPE_BIND, GI_TYPE_EXPR, GI_TYPE_INST, GI_TYPE_SIG, GI_TYPE_STMT, GI_TYPE_TFN, expression_s::id, gen_item_s::inst, funit_inst_s::name, vsignal_s::name, gen_item_s::part, PROFILE, PROFILE_END, scope_compare(), gen_item_s::sig, gen_item_s::stmt, gen_item_s::suppl, TRUE, and gen_item_s::varname.
Referenced by gen_item_find().
00208 { PROFILE(GEN_ITEM_COMPARE); 00209 00210 bool retval = FALSE; /* Return value for this function */ 00211 00212 if( (gi1 != NULL) && (gi2 != NULL) && (gi1->suppl.part.type == gi2->suppl.part.type) ) { 00213 00214 switch( gi1->suppl.part.type ) { 00215 case GI_TYPE_EXPR : retval = (gi1->elem.expr->id == gi2->elem.expr->id) ? TRUE : FALSE; break; 00216 case GI_TYPE_SIG : retval = scope_compare( gi1->elem.sig->name, gi2->elem.sig->name ); break; 00217 case GI_TYPE_STMT : retval = (gi1->elem.stmt->exp->id == gi2->elem.stmt->exp->id) ? TRUE : FALSE; break; 00218 case GI_TYPE_INST : 00219 case GI_TYPE_TFN : retval = (strcmp( gi1->elem.inst->name, gi2->elem.inst->name ) == 0) ? TRUE : FALSE; break; 00220 case GI_TYPE_BIND : retval = ((gi1->elem.expr->id == gi2->elem.expr->id) && 00221 (strcmp( gi1->varname, gi2->varname ) == 0)) ? TRUE : FALSE; break; 00222 default : break; 00223 } 00224 00225 } 00226 00227 PROFILE_END; 00228 00229 return( retval ); 00230 00231 }
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 }
static void gen_item_display_block_helper | ( | gen_item * | root | ) | [static] |
Displays an entire generate block to standard output (used for debugging purposes).
root | Pointer to starting generate item to display |
References gen_item_display(), gen_item_s::next_false, gen_item_s::next_true, gen_item_s::part, PROFILE, PROFILE_END, and gen_item_s::suppl.
Referenced by gen_item_display_block().
00151 { PROFILE(GEN_ITEM_DISPLAY_BLOCK_HELPER); 00152 00153 if( root != NULL ) { 00154 00155 /* Display ourselves */ 00156 gen_item_display( root ); 00157 00158 if( root->next_true == root->next_false ) { 00159 00160 if( root->suppl.part.stop_true == 0 ) { 00161 gen_item_display_block_helper( root->next_true ); 00162 } 00163 00164 } else { 00165 00166 if( root->suppl.part.stop_true == 0 ) { 00167 gen_item_display_block_helper( root->next_true ); 00168 } 00169 00170 if( root->suppl.part.stop_false == 0 ) { 00171 gen_item_display_block_helper( root->next_false ); 00172 } 00173 00174 } 00175 00176 } 00177 00178 PROFILE_END; 00179 00180 }
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 }
static void gen_item_get_genvar | ( | char * | varname, | |
char ** | pre, | |||
char ** | genvar, | |||
char ** | post | |||
) | [static] |
Searches the given variable name for a generate variable. If one is found, pre is set to point to the string preceding the generate variable, genvar is set to point to the beginning of the generate variable, and post is set to point to the string succeeding the ']'.
varname | Variable name to search | |
pre | Reference pointer to string preceding the generate variable | |
genvar | Reference pointer to found generate variable name | |
post | Reference pointer to string succeeding the generate variable |
References PROFILE, and PROFILE_END.
Referenced by gen_item_calc_signal_name(), and gen_item_varname_contains_genvar().
00341 { PROFILE(GEN_ITEM_GET_GENVAR); 00342 00343 int i = 0; /* Loop iterator */ 00344 00345 /* Initialize pointers */ 00346 *pre = varname; 00347 *genvar = NULL; 00348 *post = NULL; 00349 00350 /* Iterate through the variable name until we either reach the end of the string or until we have found a genvar */ 00351 while( (varname[i] != '\0') && (*genvar == NULL) ) { 00352 00353 /* Iterate through the varname until we see either a \, [ or terminating character */ 00354 while( (varname[i] != '\\') && (varname[i] != '[') && (varname[i] != '\0') ) { 00355 i++; 00356 } 00357 00358 /* If we saw a \ character, keep going until we see whitespace */ 00359 if( varname[i] == '\\' ) { 00360 while( (varname[i] != ' ') && (varname[i] != '\n') && (varname[i] != '\t') && (varname[i] != '\r') ) { 00361 i++; 00362 } 00363 00364 /* If we saw a [, get the genvar name, stripping all whitespace from the name */ 00365 } else if( varname[i] == '[' ) { 00366 00367 varname[i] = '\0'; 00368 i++; 00369 while( (varname[i] == ' ') || (varname[i] == '\n') || (varname[i] == '\t') || (varname[i] == '\r') ) { 00370 i++; 00371 } 00372 *genvar = (varname + i); 00373 while( (varname[i] != ' ') && (varname[i] != '\n') && (varname[i] != '\t') && (varname[i] != '\r') && (varname[i] != ']') ) { 00374 i++; 00375 } 00376 if( varname[i] != ']' ) { 00377 varname[i] = '\0'; 00378 i++; 00379 while( varname[i] != ']' ) { 00380 i++; 00381 } 00382 } else { 00383 varname[i] = '\0'; 00384 } 00385 i++; 00386 *post = (varname + i); 00387 00388 } 00389 00390 } 00391 00392 PROFILE_END; 00393 00394 }
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 }
static void gen_item_resolve | ( | gen_item * | gi, | |
funit_inst * | inst | |||
) | [static] |
anonymous | gen_item_calc_signal_name Throw expression_resize expression_operate_recursively gen_item_resolve gen_item_resolve gen_item_resolve gen_item_resolve gen_item_resolve gen_item_resolve gen_item_resolve gen_item_resolve |
Recursively iterates through the entire generate block specified by gi, resolving all generate items within it. This is called by the generate_resolve function (in the middle of the binding process) and by the funit_size_elements function (just prior to outputting this instance to the CDD file).
gi | Pointer to current generate item to resolve | |
inst | Pointer to instance to store results to |
References bind_add(), curr_db, DEBUG, debug_mode, gen_item_s::elem, ESUPPL_IS_TRUE, expression_s::exec_num, EXP_OP_DISABLE, EXP_OP_FUNC_CALL, EXP_OP_NB_CALL, EXP_OP_TASK_CALL, gen_item_s::expr, expression_operate_recursively(), expression_resize(), FALSE, FATAL, free_safe, funit_link_s::funit, funit_inst_s::funit, funit_dealloc(), FUNIT_FUNCTION, db_s::funit_head, funit_link_find(), FUNIT_MODULE, FUNIT_NAMED_BLOCK, FUNIT_TASK, gen_item_calc_signal_name(), gen_item_create_bind(), gen_item_create_sig(), gen_item_create_stmt(), gen_item_stringify(), GI_TYPE_BIND, GI_TYPE_EXPR, GI_TYPE_INST, GI_TYPE_SIG, GI_TYPE_STMT, GI_TYPE_TFN, funit_inst_s::gitem_head, gitem_link_add(), funit_inst_s::gitem_tail, gen_item_s::inst, db_s::inst_head, inst_link_find_by_funit(), inst_parm_add_genvar(), instance_copy(), instance_find_scope(), instance_parse_add(), expression_s::line, malloc_safe, func_unit_s::name, funit_inst_s::name, gen_item_s::next_false, gen_item_s::next_true, obf_funit, obf_inst, obf_sig, expression_s::op, param_resolve_inst(), gen_item_s::part, print_output(), PROFILE, PROFILE_END, funit_inst_s::range, scope_find_signal(), gen_item_s::sig, gen_item_s::stmt, expression_s::suppl, gen_item_s::suppl, Throw, TRUE, func_unit_s::type, user_msg, USER_MSG_LENGTH, vsignal_s::value, gen_item_s::varname, and vector_to_int().
Referenced by generate_resolve_inst().
00926 { PROFILE(GEN_ITEM_RESOLVE); 00927 00928 funit_inst* child; /* Pointer to child instance of this instance to resolve */ 00929 char* varname; /* Pointer to new, substituted name (used for BIND types) */ 00930 00931 if( (gi != NULL) && (inst != NULL) ) { 00932 00933 #ifdef DEBUG_MODE 00934 if( debug_mode ) { 00935 char* str = (char*)malloc_safe( USER_MSG_LENGTH ); 00936 unsigned int rv; 00937 gen_item_stringify( gi, str, USER_MSG_LENGTH ); 00938 rv = snprintf( user_msg, USER_MSG_LENGTH, "Resolving generate item, %s for inst: %s", str, obf_inst( inst->name ) ); 00939 assert( rv < USER_MSG_LENGTH ); 00940 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00941 free_safe( str, USER_MSG_LENGTH ); 00942 } 00943 #endif 00944 00945 /* Specify that this generate item has been resolved */ 00946 gi->suppl.part.resolved = 1; 00947 00948 switch( gi->suppl.part.type ) { 00949 00950 case GI_TYPE_EXPR : 00951 /* Recursively resize the expression tree if we have not already done this */ 00952 if( gi->elem.expr->exec_num == 0 ) { 00953 expression_resize( gi->elem.expr, inst->funit, TRUE, FALSE ); 00954 } 00955 expression_operate_recursively( gi->elem.expr, inst->funit, FALSE ); 00956 if( ESUPPL_IS_TRUE( gi->elem.expr->suppl ) ) { 00957 gen_item_resolve( gi->next_true, inst ); 00958 } else { 00959 gen_item_resolve( gi->next_false, inst ); 00960 } 00961 break; 00962 00963 case GI_TYPE_SIG : 00964 gitem_link_add( gen_item_create_sig( gi->elem.sig ), &(inst->gitem_head), &(inst->gitem_tail) ); 00965 gen_item_resolve( gi->next_true, inst ); 00966 break; 00967 00968 case GI_TYPE_STMT : 00969 gitem_link_add( gen_item_create_stmt( gi->elem.stmt ), &(inst->gitem_head), &(inst->gitem_tail) ); 00970 gen_item_resolve( gi->next_true, inst ); 00971 break; 00972 00973 case GI_TYPE_INST : 00974 { 00975 funit_inst* tinst; 00976 if( gi->elem.inst->funit->type == FUNIT_MODULE ) { 00977 funit_link* found_funit_link; 00978 if( ((found_funit_link = funit_link_find( gi->elem.inst->funit->name, gi->elem.inst->funit->type, db_list[curr_db]->funit_head )) != NULL) && 00979 (gi->elem.inst->funit != found_funit_link->funit) ) { 00980 /* Make sure that any instances in the tree that point to the functional unit being replaced are pointing to the new functional unit */ 00981 int ignore = 0; 00982 while( (tinst = inst_link_find_by_funit( gi->elem.inst->funit, db_list[curr_db]->inst_head, &ignore )) != NULL ) { 00983 tinst->funit = found_funit_link->funit; 00984 } 00985 funit_dealloc( gi->elem.inst->funit ); 00986 gi->elem.inst->funit = found_funit_link->funit; 00987 } 00988 } 00989 if( (tinst = instance_copy( gi->elem.inst, inst, gi->elem.inst->name, gi->elem.inst->range, FALSE )) != NULL ) { 00990 param_resolve_inst( tinst ); 00991 } 00992 gen_item_resolve( gi->next_true, inst ); 00993 } 00994 break; 00995 00996 case GI_TYPE_TFN : 00997 if( gi->varname != NULL ) { 00998 char* inst_name = (char*)malloc_safe( 4096 ); 00999 vsignal* genvar; 01000 func_unit* found_funit; 01001 unsigned int rv; 01002 if( !scope_find_signal( gi->varname, inst->funit, &genvar, &found_funit, 0 ) ) { 01003 rv = snprintf( user_msg, USER_MSG_LENGTH, "Unable to find variable %s in module %s", 01004 obf_sig( gi->varname ), obf_funit( inst->funit->name ) ); 01005 assert( rv < USER_MSG_LENGTH ); 01006 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 01007 Throw 0; 01008 } 01009 rv = snprintf( inst_name, 4096, "%s[%d]", gi->elem.inst->name, vector_to_int( genvar->value ) ); 01010 assert( rv < 4096 ); 01011 (void)instance_parse_add( &inst, inst->funit, gi->elem.inst->funit, inst_name, NULL, FALSE, TRUE, FALSE, TRUE ); 01012 rv = snprintf( inst_name, 4096, "%s.%s[%d]", inst->name, gi->elem.inst->name, vector_to_int( genvar->value ) ); 01013 assert( rv < 4096 ); 01014 if( (child = instance_find_scope( inst, inst_name, TRUE )) != NULL ) { 01015 inst_parm_add_genvar( genvar, child ); 01016 } 01017 free_safe( inst_name, 4096 ); 01018 } else { 01019 char* inst_name = (char*)malloc_safe( 4096 ); 01020 unsigned int rv; 01021 (void)instance_parse_add( &inst, inst->funit, gi->elem.inst->funit, gi->elem.inst->name, NULL, FALSE, TRUE, FALSE, TRUE ); 01022 rv = snprintf( inst_name, 4096, "%s.%s", inst->name, gi->elem.inst->name ); 01023 assert( rv < 4096 ); 01024 child = instance_find_scope( inst, inst_name, TRUE ); 01025 free_safe( inst_name, 4096 ); 01026 } 01027 if( child != NULL ) { 01028 param_resolve_inst( child ); 01029 } 01030 gen_item_resolve( gi->next_true, child ); 01031 gen_item_resolve( gi->next_false, inst ); 01032 break; 01033 01034 case GI_TYPE_BIND : 01035 varname = gen_item_calc_signal_name( gi->varname, inst->funit, gi->elem.expr->line, FALSE ); 01036 switch( gi->elem.expr->op ) { 01037 case EXP_OP_FUNC_CALL : bind_add( FUNIT_FUNCTION, varname, gi->elem.expr, inst->funit ); break; 01038 case EXP_OP_TASK_CALL : bind_add( FUNIT_TASK, varname, gi->elem.expr, inst->funit ); break; 01039 case EXP_OP_NB_CALL : bind_add( FUNIT_NAMED_BLOCK, varname, gi->elem.expr, inst->funit ); break; 01040 case EXP_OP_DISABLE : bind_add( 1, varname, gi->elem.expr, inst->funit ); break; 01041 default : bind_add( 0, varname, gi->elem.expr, inst->funit ); break; 01042 } 01043 gitem_link_add( gen_item_create_bind( varname, gi->elem.expr ), &(inst->gitem_head), &(inst->gitem_tail) ); 01044 free_safe( varname, (strlen( varname ) + 1) ); 01045 gen_item_resolve( gi->next_true, inst ); 01046 break; 01047 01048 default : 01049 assert( (gi->suppl.part.type == GI_TYPE_EXPR) || (gi->suppl.part.type == GI_TYPE_SIG) || 01050 (gi->suppl.part.type == GI_TYPE_STMT) || (gi->suppl.part.type == GI_TYPE_INST) || 01051 (gi->suppl.part.type == GI_TYPE_TFN) || (gi->suppl.part.type == GI_TYPE_BIND) ); 01052 break; 01053 01054 } 01055 01056 } 01057 01058 PROFILE_END; 01059 01060 }
static void gen_item_stringify | ( | gen_item * | gi, | |
char * | str, | |||
unsigned int | str_len | |||
) | [static] |
Creates a user-readable version of the specified generate item and stores it in the specified string.
gi | Pointer to generate item to stringify | |
str | Pointer to string to store data into | |
str_len | Number of available characters in the str string |
References gen_item_s::all, gen_item_s::elem, statement_s::exp, gen_item_s::expr, expression_string(), free_safe, funit_inst_s::funit, get_funit_type(), GI_TYPE_BIND, GI_TYPE_EXPR, GI_TYPE_INST, GI_TYPE_SIG, GI_TYPE_STMT, GI_TYPE_TFN, expression_s::id, gen_item_s::inst, expression_s::line, malloc_safe_nolimit, funit_inst_s::name, vsignal_s::name, gen_item_s::next_false, gen_item_s::next_true, obf_inst, obf_sig, gen_item_s::part, PROFILE, PROFILE_END, gen_item_s::sig, gen_item_s::stmt, gen_item_s::suppl, func_unit_s::type, and gen_item_s::varname.
Referenced by gen_item_create_bind(), gen_item_create_expr(), gen_item_create_inst(), gen_item_create_sig(), gen_item_create_stmt(), gen_item_create_tfn(), gen_item_display(), and gen_item_resolve().
00059 { PROFILE(GEN_ITEM_STRINGIFY); 00060 00061 char* tmp; /* Temporary string */ 00062 00063 assert( str_len > 0 ); 00064 00065 if( gi != NULL ) { 00066 00067 unsigned int rv; 00068 00069 /* Allocate some memory in the tmp string */ 00070 tmp = (char*)malloc_safe_nolimit( str_len ); 00071 00072 rv = snprintf( str, str_len, "%p, suppl: %x", gi, gi->suppl.all ); 00073 assert( rv < str_len ); 00074 00075 switch( gi->suppl.part.type ) { 00076 case GI_TYPE_EXPR : 00077 rv = snprintf( tmp, str_len, ", EXPR, %s", expression_string( gi->elem.expr ) ); 00078 assert( rv < str_len ); 00079 break; 00080 case GI_TYPE_SIG : 00081 rv = snprintf( tmp, str_len, ", SIG, name: %s", obf_sig( gi->elem.sig->name ) ); 00082 assert( rv < str_len ); 00083 break; 00084 case GI_TYPE_STMT : 00085 rv = snprintf( tmp, str_len, ", STMT, id: %d, line: %d", gi->elem.stmt->exp->id, gi->elem.stmt->exp->line ); 00086 assert( rv < str_len ); 00087 break; 00088 case GI_TYPE_INST : 00089 rv = snprintf( tmp, str_len, ", INST, name: %s", obf_inst( gi->elem.inst->name ) ); 00090 assert( rv < str_len ); 00091 break; 00092 case GI_TYPE_TFN : 00093 rv = snprintf( tmp, str_len, ", TFN, name: %s, type: %s", obf_inst( gi->elem.inst->name ), get_funit_type( gi->elem.inst->funit->type ) ); 00094 assert( rv < str_len ); 00095 break; 00096 case GI_TYPE_BIND : 00097 rv = snprintf( tmp, str_len, ", BIND, %s", expression_string( gi->elem.expr ) ); 00098 assert( rv < str_len ); 00099 break; 00100 default : 00101 strcpy( tmp, "UNKNOWN!\n" ); 00102 break; 00103 } 00104 strcat( str, tmp ); 00105 00106 rv = snprintf( tmp, str_len, ", next_true: %p, next_false: %p", gi->next_true, gi->next_false ); 00107 assert( rv < str_len ); 00108 strcat( str, tmp ); 00109 00110 if( gi->varname != NULL ) { 00111 rv = snprintf( tmp, str_len, ", varname: %s", obf_sig( gi->varname ) ); 00112 assert( rv < str_len ); 00113 strcat( str, tmp ); 00114 } 00115 00116 /* Deallocate the temporary string memory */ 00117 free_safe( tmp, str_len ); 00118 00119 } else { 00120 00121 str[0] = '\0'; 00122 00123 } 00124 00125 PROFILE_END; 00126 00127 }
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 }
static bool generate_remove_stmt_helper | ( | funit_inst * | root, | |
statement * | stmt | |||
) | [static] |
root | Pointer to root instance to traverse | |
stmt | Pointer to statement to find and remove |
References funit_inst_s::child_head, gen_item_s::elem, statement_s::exp, FALSE, gitem_link_s::gi, GI_TYPE_STMT, funit_inst_s::gitem_head, expression_s::id, funit_inst_s::next, gitem_link_s::next, gen_item_s::part, PROFILE, PROFILE_END, statement_find_statement(), gen_item_s::stmt, gen_item_s::suppl, and TRUE.
Referenced by generate_remove_stmt().
01117 { PROFILE(GENERATE_REMOVE_STMT_HELPER); 01118 01119 bool retval = FALSE; /* Return value for this function */ 01120 funit_inst* curr_child; /* Pointer to current child to search */ 01121 gitem_link* gil; /* Pointer to generate item link */ 01122 01123 /* Remove the generate item from the current instance if it exists there */ 01124 gil = root->gitem_head; 01125 while( gil != NULL ) { 01126 if( (gil->gi->suppl.part.type == GI_TYPE_STMT) && (statement_find_statement( gil->gi->elem.stmt, stmt->exp->id ) != NULL) ) { 01127 gil->gi->suppl.part.removed = 1; 01128 retval = TRUE; 01129 } 01130 gil = gil->next; 01131 } 01132 01133 /* Search child instances */ 01134 curr_child = root->child_head; 01135 while( curr_child != NULL ) { 01136 retval |= generate_remove_stmt_helper( curr_child, stmt ); 01137 curr_child = curr_child->next; 01138 } 01139 01140 PROFILE_END; 01141 01142 return( retval ); 01143 01144 }
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 }
Referenced by gen_item_calc_signal_name().
unsigned int curr_db |
Index of current database in db_list array that is being handled.
Pointer to the functional unit structure for the functional unit that is currently being parsed.
int curr_sig_id |
Signal ID that is used for identification purposes (each signal will receive a unique ID).
If set to TRUE, causes debug information to be spewed to screen.
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.