gen_item.h File Reference

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_itemgen_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_itemgen_item_create_expr (expression *expr)
 Creates a generate item for an expression.
gen_itemgen_item_create_sig (vsignal *sig)
 Creates a generate item for a signal.
gen_itemgen_item_create_stmt (statement *stmt)
 Creates a generate item for a statement.
gen_itemgen_item_create_inst (funit_inst *inst)
 Creates a generate item for an instance.
gen_itemgen_item_create_tfn (funit_inst *inst)
 Creates a generate item for a namespace.
gen_itemgen_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.

Detailed Description

Contains functions for handling generate items.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
7/10/2006

Function Documentation

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.

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

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

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

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.

Parameters:
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.
Returns:
Returns allocated string containing the signal name with embedded generate variables evaluated
Exceptions:
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 }

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.

Returns:
Returns TRUE if the connection was successful; otherwise, returns FALSE.
Parameters:
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.

Parameters:
name Name of signal to bind to
expr Pointer to expression to bind signal to
Returns:
Returns a pointer to create generate item.

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.

Parameters:
expr Pointer to root expression to create (this is an expression from a FOR, IF or CASE statement)
Returns:
Returns a pointer to created generate item.

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.

Parameters:
inst Pointer to instance to create a generate item for (instantiations)
Returns:
Returns a pointer to create generate item.

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 }

gen_item* gen_item_create_sig ( vsignal sig  ) 

Creates a generate item for a signal.

Parameters:
sig Pointer to signal to create a generate item for (wire/reg instantions)
Returns:
Returns a pointer to created generate item.

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 }

gen_item* gen_item_create_stmt ( statement stmt  ) 

Creates a generate item for a statement.

Parameters:
stmt Pointer to statement to create a generate item for (assign, always, initial blocks)
Returns:
Returns a pointer to create generate item.

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.

Parameters:
inst Pointer to namespace to create a generate item for (named blocks, functions or tasks)
Returns:
Returns a pointer to create generate item.

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.

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

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

void gen_item_dealloc ( gen_item gi,
bool  rm_elem 
)

Deallocates all associated memory for the given generate item.

Recursively deallocates the gen_item structure tree.

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

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

Returns:
Returns a value of 1 so that this function can be called within an expression.

Displays an entire generate block to standard output (used for debugging purposes).

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

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.

Returns:
Returns a pointer to the generate item that matches the given generate item in the given generate item block. Returns NULL if it was not able to find a matching item.

Recursively traverses the specified generate item block searching for a generate item that matches the specified generate item.

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

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.

Removes the given generate item if it contains an expressions that calls a statement.

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

void gen_item_resize_stmts_and_sigs ( gen_item gi,
func_unit funit 
)

Resizes all statements and signals in the given generate item block.

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

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

Parameters:
name Variable name to check
Returns:
Returns TRUE if the specified variable name contains a generate variable within it; otherwise, returns FALSE.

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 }

bool generate_remove_stmt ( statement stmt  ) 

Removes the given generate statement from the correct instance.

Returns:
Returns TRUE if we found at least one match; otherwise, returns FALSE.

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.

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

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

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

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