Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

/Users/trevorw/projects/release/covered-0.7.4/src/binding.h File Reference


Detailed Description

Contains all functions for vsignal/expression binding.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
3/4/2002

#include "defines.h"

Go to the source code of this file.

Functions

void bind_add (int type, const char *name, expression *exp, func_unit *funit)
 Adds vsignal and expression to binding list.

void bind_append_fsm_expr (expression *fsm_exp, const expression *exp, const func_unit *curr_funit)
 Appends an FSM expression to a matching expression binding structure.

void bind_remove (int id, bool clear_assigned)
 Removes the expression with ID of id from binding list.

char * bind_find_sig_name (const expression *exp)
 Searches current binding list for the signal name associated with the given expression.

void bind_rm_stmt (int id)
 Removes the statement block associated with the expression with ID of id after binding has occurred.

bool bind_signal (char *name, expression *exp, func_unit *funit_exp, bool fsm_bind, bool cdd_reading, bool clear_assigned, int exp_line, bool bind_locally)
 Binds a signal to an expression.

void bind_perform (bool cdd_reading, int pass)
 Performs vsignal/expression bind (performed after parse completed).

void bind_dealloc ()
 Deallocates memory used for binding.


Function Documentation

void bind_add int  type,
const char *  name,
expression exp,
func_unit funit
 

Adds vsignal and expression to binding list.

Adds the specified signal/function/task and expression to the bindings linked list. This bindings list will be handled after all input Verilog has been parsed.

Parameters:
type  Type of thing being bound with the specified expression (0=signal, 1=functional unit)
name  Signal/Function/Task scope to bind
exp  Expression ID to bind
funit  Pointer to module containing specified expression

00125   { PROFILE(BIND_ADD);
00126   
00127   exp_bind* eb;   /* Temporary pointer to signal/expressing binding */
00128 
00129   assert( exp != NULL );
00130   
00131   /* Create new signal/expression binding */
00132   eb                 = (exp_bind *)malloc_safe( sizeof( exp_bind ) );
00133   eb->type           = type;
00134   eb->name           = strdup_safe( name );
00135   eb->clear_assigned = 0;
00136   eb->line           = exp->line;
00137   eb->funit          = funit;
00138   eb->exp            = exp;
00139   eb->fsm            = NULL;
00140   eb->next           = NULL;
00141   
00142   /* Add new signal/expression binding to linked list */
00143   if( eb_head == NULL ) {
00144     eb_head = eb_tail = eb;
00145   } else {
00146     eb_tail->next = eb;
00147     eb_tail       = eb;
00148   }
00149 
00150   PROFILE_END;
00151   
00152 }

void bind_append_fsm_expr expression fsm_exp,
const expression exp,
const func_unit curr_funit
 

Appends an FSM expression to a matching expression binding structure.

Searches the expression binding list for the entry that matches the given exp and curr_funit parameters. When the entry is found, the FSM expression is added to the exp_bind structure to be sized when the expression is bound.

Parameters:
fsm_exp  Expression pertaining to an FSM input state that needs to be sized when its associated expression is bound to its signal
exp  Expression to match
curr_funit  Functional unit that the FSM expression resides in (this will be the same functional unit as the expression functional unit)

00165   { PROFILE(BIND_APPEND_FSM_EXPR);
00166 
00167   exp_bind* curr;
00168 
00169   curr = eb_head;
00170   while( (curr != NULL) && ((exp != curr->exp) || (curr_funit != curr->funit)) ) {
00171     curr = curr->next;
00172   }
00173 
00174   assert( curr != NULL );
00175 
00176   curr->fsm = fsm_exp;
00177 
00178   PROFILE_END;
00179 
00180 }

void bind_dealloc  ) 
 

Deallocates memory used for binding.

Deallocates all memory used for the storage of the binding list.

00923                     { PROFILE(BIND_DEALLOC);
00924 
00925   exp_bind* tmp;  /* Temporary binding pointer */
00926 
00927   while( eb_head != NULL ) {
00928 
00929     tmp     = eb_head;
00930     eb_head = tmp->next;
00931 
00932     /* Deallocate the name, if specified */
00933     if( tmp->name != NULL ) {
00934       free_safe( tmp->name, (strlen( tmp->name ) + 1) );
00935     }
00936 
00937     /* Deallocate this structure */
00938     free_safe( tmp, sizeof( exp_bind ) );
00939 
00940   }
00941 
00942   /* Reset the head and tail pointers */
00943   eb_head = eb_tail = NULL;
00944 
00945   PROFILE_END;
00946 
00947 }

char* bind_find_sig_name const expression exp  ) 
 

Searches current binding list for the signal name associated with the given expression.

Returns:
Returns the name of the signal to be bound with the given expression (if one exists); otherwise, returns NULL if no match was found.
Parameters:
exp  Pointer to expression to search for

00297   { PROFILE(BIND_FIND_SIG_NAME);
00298 
00299   exp_bind*  curr;         /* Pointer to current exp_bind link */
00300   vsignal*   found_sig;    /* Placeholder */
00301   func_unit* found_funit;  /* Specifies the functional unit containing this signal */
00302   char*      name = NULL;  /* Specifies the signal name relative to its parent module */
00303   char*      front;        /* Front part of functional unit hierarchy */
00304   char*      rest;         /* Rest of functional unit hierarchy (minus front) */
00305  
00306   /* Find matching binding element that matches the given expression */
00307   curr = eb_head;
00308   while( (curr != NULL) && (curr->exp != exp) ) {
00309     curr = curr->next;
00310   }
00311 
00312   /*
00313    If we found the matching expression, find the signal and construct its hierarchical pathname
00314    relative to its parent module.
00315   */
00316   if( curr != NULL ) {
00317     if( scope_find_signal( curr->name, curr->funit, &found_sig, &found_funit, -1 ) ) {
00318       if( funit_get_curr_module_safe( curr->funit ) == funit_get_curr_module_safe( found_funit ) ) {
00319         front = strdup_safe( found_funit->name );
00320         rest  = strdup_safe( found_funit->name );
00321         scope_extract_front( found_funit->name, front, rest );
00322         if( rest[0] != '\0' ) {
00323           unsigned int sig_size = strlen( curr->name ) + strlen( rest ) + 2;
00324           unsigned int rv;
00325           name = (char*)malloc_safe( sig_size );
00326           rv = snprintf( name, sig_size, "%s.%s", rest, curr->name );
00327           assert( rv < sig_size );
00328         }
00329         free_safe( front, (strlen( found_funit->name ) + 1) );
00330         free_safe( rest, (strlen( found_funit->name ) + 1) );
00331       }
00332     }
00333     if( name == NULL ) {
00334       name = strdup_safe( curr->name );
00335     }
00336   }
00337 
00338   PROFILE_END;
00339 
00340   return( name );
00341 
00342 }

void bind_perform bool  cdd_reading,
int  pass
 

Performs vsignal/expression bind (performed after parse completed).

Exceptions:
anonymous Throw param_resolve bind_signal generate_resolve bind_task_function_namedblock bind_task_function_namedblock
In the process of binding, we go through each element of the binding list, finding the signal to be bound in the specified tree, adding the expression to the signal's expression pointer list, and setting the expression vector pointer to point to the signal vector.
Parameters:
cdd_reading  Set to TRUE if we are binding after reading the CDD file; otherwise, set to FALSE
pass  Specifies the starting pass to perform (setting this to 1 will bypass resolutions)

00765   { PROFILE(BIND_PERFORM);
00766   
00767   exp_bind*  curr_eb;   /* Pointer to current expression bind structure */
00768   int        id;        /* Current expression id -- used for removal */
00769   bool       bound;     /* Specifies if the current expression was successfully bound or not */
00770   statement* tmp_stmt;  /* Pointer to temporary statement */
00771 
00772   Try {
00773 
00774     /* Make three passes through binding list, 0=local signal/param bindings, 1=remote signal/param bindings */
00775     for( ; pass<2; pass++ ) {
00776 
00777       curr_eb = eb_head;
00778       while( curr_eb != NULL ) {
00779 
00780         /* Figure out ID to clear from the binding list after the bind occurs */
00781         if( curr_eb->clear_assigned == 0 ) {
00782           id = curr_eb->exp->id;
00783         } else {
00784           id = curr_eb->clear_assigned;
00785         }
00786 
00787         /* If the expression has already been bound, do not attempt to do it again */
00788         if( (curr_eb->exp != NULL) && (curr_eb->exp->name != NULL) ) {
00789 
00790           bound = TRUE;
00791 
00792         } else {
00793 
00794           /* Handle signal/parameter binding */
00795           if( curr_eb->type == 0 ) {
00796 
00797             /* Attempt to bind the expression to a parameter; otherwise, bind to a signal */
00798             if( !(bound = bind_param( curr_eb->name, curr_eb->exp, curr_eb->funit, curr_eb->line, (pass == 0) )) ) {
00799               bound = bind_signal( curr_eb->name, curr_eb->exp, curr_eb->funit, FALSE, cdd_reading,
00800                                    (curr_eb->clear_assigned > 0), curr_eb->line, (pass == 0) );
00801             }
00802 
00803             /* If an FSM expression is attached, size it now */
00804             if( curr_eb->fsm != NULL ) {
00805               curr_eb->fsm->value = vector_create( curr_eb->exp->value->width, VTYPE_EXP, VDATA_UL, TRUE );
00806             }
00807 
00808           /* Otherwise, handle disable binding */
00809           } else if( curr_eb->type == 1 ) {
00810 
00811             /* Attempt to bind a named block -- if unsuccessful, attempt to bind with a task */
00812             if( !(bound = bind_task_function_namedblock( FUNIT_NAMED_BLOCK, curr_eb->name, curr_eb->exp, curr_eb->funit,
00813                                                          cdd_reading, curr_eb->line, (pass == 0) )) ) {
00814               bound = bind_task_function_namedblock( FUNIT_TASK, curr_eb->name, curr_eb->exp, curr_eb->funit,
00815                                                      cdd_reading, curr_eb->line, (pass == 0) );
00816             }
00817 
00818           /* Otherwise, handle function/task binding */
00819           } else {
00820 
00821             /*
00822              Bind the expression to the task/function.  If it is unsuccessful, we need to remove the statement
00823              that this expression is a part of.
00824             */
00825             bound = bind_task_function_namedblock( curr_eb->type, curr_eb->name, curr_eb->exp, curr_eb->funit,
00826                                                    cdd_reading, curr_eb->line, (pass == 0) );
00827 
00828           }
00829 
00830           /* If we have bound successfully, copy the name of this exp_bind to the expression */
00831           if( bound && (curr_eb->exp != NULL) ) {
00832             curr_eb->exp->name = strdup_safe( curr_eb->name );
00833           }
00834 
00835         }
00836 
00837         /*
00838          If the expression was unable to be bound, put its statement block in a list to be removed after
00839          binding has been completed.
00840         */
00841         if( !bound && (curr_eb->clear_assigned == 0) && (pass == 1) ) {
00842           if( (tmp_stmt = expression_get_root_statement( curr_eb->exp )) != NULL ) {
00843 #ifdef DEBUG_MODE
00844             if( debug_mode ) {
00845               unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Removing statement block containing line %d in file \"%s\", because it was unbindable",
00846                                           curr_eb->exp->line, obf_file( curr_eb->funit->filename ) );
00847               assert( rv < USER_MSG_LENGTH );
00848               print_output( user_msg, DEBUG, __FILE__, __LINE__ );
00849             }
00850 #endif        
00851             stmt_blk_add_to_remove_list( tmp_stmt );
00852           }
00853         }
00854 
00855         curr_eb = curr_eb->next;
00856 
00857         /* Remove this from the binding list */
00858         if( bound ) {
00859           bind_remove( id, FALSE );
00860         }
00861 
00862       }
00863 
00864 #ifndef VPI_ONLY
00865       /* If we are in parse mode, resolve all parameters and arrays of instances now */
00866       if( !cdd_reading && (pass == 0) ) {
00867         inst_link* instl;
00868 #ifdef DEBUG_MODE
00869         if( debug_mode ) {
00870           print_output( "Resolving parameters...", DEBUG, __FILE__, __LINE__ );
00871         }
00872 #endif
00873         instl = db_list[curr_db]->inst_head;
00874         while( instl != NULL ) {
00875           param_resolve( instl->inst );
00876           instl = instl->next;
00877         }
00878 #ifdef DEBUG_MODE
00879         if( debug_mode ) {
00880           print_output( "Resolving generate statements...", DEBUG, __FILE__, __LINE__ );
00881         }
00882 #endif
00883         instl = db_list[curr_db]->inst_head;
00884         while( instl != NULL ) {
00885           generate_resolve( instl->inst );
00886           instl = instl->next;
00887         }
00888 #ifdef DEBUG_MODE
00889         if( debug_mode ) {
00890           print_output( "Resolving arrays of instances...", DEBUG, __FILE__, __LINE__ );
00891         }
00892 #endif
00893         instl = db_list[curr_db]->inst_head;
00894         while( instl != NULL ) {
00895           instance_resolve( instl->inst );
00896           instl = instl->next;
00897         }
00898       }
00899 #endif
00900 
00901     }
00902 
00903   } Catch_anonymous {
00904     exp_bind* tmp_eb;
00905     curr_eb = eb_head;
00906     while( curr_eb != NULL ) {
00907       tmp_eb  = curr_eb;
00908       curr_eb = curr_eb->next;
00909       free_safe( tmp_eb->name, (strlen( tmp_eb->name ) + 1) );
00910       free_safe( tmp_eb, sizeof( exp_bind ) );
00911     }
00912     eb_head = eb_tail = NULL;
00913     Throw 0;
00914   }
00915 
00916   PROFILE_END;
00917 
00918 }

void bind_remove int  id,
bool  clear_assigned
 

Removes the expression with ID of id from binding list.

Removes the binding containing the expression ID of id. This needs to be called before an expression is removed.

Parameters:
id  Expression ID of binding to remove
clear_assigned  If set to TRUE, clears the assigned bit in the specified expression

00239   { PROFILE(BIND_REMOVE);
00240 
00241   exp_bind* curr;  /* Pointer to current exp_bind link */
00242   exp_bind* last;  /* Pointer to last exp_bind link examined */
00243 
00244   curr = eb_head;
00245   last = eb_head;
00246 
00247   while( curr != NULL ) {
00248 
00249     if( ((curr->exp != NULL) && (curr->exp->id == id)) || (curr->clear_assigned == id) ) {
00250       
00251       if( clear_assigned ) {
00252 
00253         curr->clear_assigned = id;
00254         curr->exp            = NULL;
00255 
00256       } else {
00257 
00258         /* Remove this binding element */
00259         if( (curr == eb_head) && (curr == eb_tail) ) {
00260           eb_head = eb_tail = NULL;
00261         } else if( curr == eb_head ) {
00262           eb_head = eb_head->next;
00263         } else if( curr == eb_tail ) {
00264           eb_tail       = last;
00265           eb_tail->next = NULL;
00266         } else {
00267           last->next = curr->next;
00268         }
00269 
00270         /* Now free the binding element memory */
00271         free_safe( curr->name, (strlen( curr->name ) + 1) );
00272         free_safe( curr, sizeof( exp_bind ) );
00273 
00274       }
00275 
00276       curr = NULL;
00277       
00278     } else {
00279 
00280       last = curr;
00281       curr = curr->next;
00282 
00283     }
00284 
00285   }
00286 
00287   PROFILE_END;
00288 
00289 }

void bind_rm_stmt int  id  ) 
 

Removes the statement block associated with the expression with ID of id after binding has occurred.

bool bind_signal char *  name,
expression exp,
func_unit funit_exp,
bool  fsm_bind,
bool  cdd_reading,
bool  clear_assigned,
int  exp_line,
bool  bind_locally
 

Binds a signal to an expression.

Returns:
Returns TRUE if bind occurred successfully; otherwise, returns FALSE.
Exceptions:
anonymous expression_set_value
Performs a binding of an expression and signal based on the name of the signal. Looks up signal name in the specified functional unit and sets the expression and signal to point to each other. If the signal is unused, the bind does not occur and the function returns a value of FALSE. If the signal does not exist, it is considered to be an implicit signal and a 1-bit signal is created.
Parameters:
name  String name of signal to bind to specified expression
exp  Pointer to expression to bind
funit_exp  Pointer to functional unit containing expression
fsm_bind  If set to TRUE, handling binding for FSM binding
cdd_reading  If set to TRUE, specifies that we are binding after reading a design from a CDD file (instead of the design files)
clear_assigned  If set to TRUE, clears signal assigned bit
exp_line  Line of specified expression (when expression is NULL)
bind_locally  If TRUE, only search for specified signal within the same functional unit as this expression

00421   { PROFILE(BIND_SIGNAL);
00422 
00423   bool         retval = TRUE;  /* Return value for this function */
00424   vsignal*     found_sig;      /* Pointer to found signal in design for the given name */
00425   func_unit*   found_funit;    /* Pointer to found functional unit containing given signal */
00426   statement*   stmt;           /* Pointer to root statement for the given expression */
00427   exp_link*    expl;           /* Pointer to current expression link */
00428   unsigned int rv;             /* Return value from snprintf calls */
00429 
00430   /* Skip signal binding if the name is not local and we are binding locally */
00431   if( scope_local( name ) || !bind_locally || (!clear_assigned && (exp->op == EXP_OP_PASSIGN)) ) {
00432 
00433     /* Search for specified signal in current functional unit */
00434     if( !scope_find_signal( name, funit_exp, &found_sig, &found_funit, exp_line ) ) {
00435 
00436       /* If we are binding an FSM, output an error message */
00437       if( fsm_bind ) {
00438         rv = snprintf( user_msg, USER_MSG_LENGTH, "Unable to find specified FSM signal \"%s\" in module \"%s\" in file %s",
00439                        obf_sig( name ), obf_funit( funit_exp->name ), obf_file( funit_exp->filename ) );
00440         assert( rv < USER_MSG_LENGTH );
00441         print_output( user_msg, FATAL, __FILE__, __LINE__ );
00442         retval = FALSE;
00443 
00444       /* Otherwise, implicitly create the signal and bind to it if the signal exists on the LHS of the equation */
00445       } else if( ESUPPL_IS_LHS( exp->suppl ) == 1 ) {
00446         assert( exp != NULL );
00447         rv = snprintf( user_msg, USER_MSG_LENGTH, "Implicit declaration of signal \"%s\", creating 1-bit version of signal", obf_sig( name ) );
00448         assert( rv < USER_MSG_LENGTH );
00449         print_output( user_msg, WARNING, __FILE__, __LINE__ );
00450         rv = snprintf( user_msg, USER_MSG_LENGTH, "module \"%s\", file \"%s\", line %d",
00451                        obf_funit( funit_exp->name ), obf_file( funit_exp->filename ), exp_line );
00452         assert( rv < USER_MSG_LENGTH );
00453         print_output( user_msg, WARNING_WRAP, __FILE__, __LINE__ );
00454         found_sig = vsignal_create( name, SSUPPL_TYPE_IMPLICIT, 1, exp->line, ((exp->col >> 16) & 0xffff) );
00455         found_sig->pdim_num   = 1;
00456         found_sig->dim        = (dim_range*)malloc_safe( sizeof( dim_range ) * 1 );
00457         found_sig->dim[0].msb = 0;
00458         found_sig->dim[0].lsb = 0;
00459         sig_link_add( found_sig, &(funit_exp->sig_head), &(funit_exp->sig_tail) );
00460 
00461       /* Otherwise, don't attempt to bind the signal */
00462       } else {
00463         retval = FALSE;
00464       }
00465 
00466     } else {
00467 
00468       /* If the found signal is not handled, do not attempt to bind to it */
00469       if( found_sig->suppl.part.not_handled == 1 ) {
00470         retval = FALSE;
00471       }
00472 
00473     }
00474 
00475     if( retval ) {
00476 
00477       /* Bind signal and expression if we are not clearing or this is an MBA */
00478       if( !clear_assigned ) {
00479 
00480         /* Add expression to signal expression list */
00481         exp_link_add( exp, &(found_sig->exp_head), &(found_sig->exp_tail) );
00482 
00483         /* Set expression to point at signal */
00484         exp->sig = found_sig;
00485 
00486         /* If this is a port assignment, we need to link the expression and signal together immediately */
00487         if( exp->op == EXP_OP_PASSIGN ) {
00488           vector_dealloc( exp->value );
00489           exp->suppl.part.owns_vec = 0;
00490           exp->value = found_sig->value;
00491         }
00492 
00493         if( ((exp->op == EXP_OP_SIG)            ||
00494              (exp->op == EXP_OP_SBIT_SEL)       ||
00495              (exp->op == EXP_OP_MBIT_SEL)       ||
00496              (exp->op == EXP_OP_MBIT_POS)       ||
00497              (exp->op == EXP_OP_MBIT_NEG)       ||
00498              (exp->op == EXP_OP_PARAM)          ||
00499              (exp->op == EXP_OP_PARAM_SBIT)     ||
00500              (exp->op == EXP_OP_PARAM_MBIT)     ||
00501              (exp->op == EXP_OP_PARAM_MBIT_POS) ||
00502              (exp->op == EXP_OP_PARAM_MBIT_NEG) ||
00503              (exp->op == EXP_OP_TRIGGER)) &&
00504             (cdd_reading || (found_sig->suppl.part.type == SSUPPL_TYPE_GENVAR)) ) {
00505           expression_set_value( exp, found_sig, funit_exp );
00506         }
00507 
00508         /*
00509          Create a non-blocking assignment handler for the given expression if the attached signal is a memory
00510          and the expression is assignable on the LHS of a non-blocking assignment operator.  Only perform this
00511          if we are reading from the CDD file and binding.
00512         */
00513         if( cdd_reading && (found_sig->suppl.part.type == SSUPPL_TYPE_MEM) ) {
00514           expression* nba_exp;
00515           if( (nba_exp = expression_is_nba_lhs( exp )) != NULL ) {
00516             expression_create_nba( exp, found_sig, nba_exp->right->value );
00517           }
00518         }
00519 
00520       }
00521 
00522       if( !cdd_reading ) {
00523 
00524         /* Check to see if this signal should be assigned by Covered or the dumpfile */
00525         if( clear_assigned ) {
00526           found_sig->suppl.part.assigned = 0;
00527         }
00528 
00529         if( !clear_assigned &&
00530             ((exp->op == EXP_OP_SIG)      ||
00531              (exp->op == EXP_OP_SBIT_SEL) ||
00532              (exp->op == EXP_OP_MBIT_SEL) ||
00533              (exp->op == EXP_OP_MBIT_POS) ||
00534              (exp->op == EXP_OP_MBIT_NEG)) &&
00535             !ovl_is_assertion_module( funit_exp ) ) {
00536           expression_set_assigned( exp );
00537         }
00538 
00539         /* Set signed bits */
00540         if( !clear_assigned ) {
00541           expression_set_signed( exp );
00542         }
00543 
00544         /*
00545          If the signal is found for the given expression but the signal is marked as "must be assigned" but is also marked as
00546          "won't be assigned", we need to remove all statement blocks that contain this signal from coverage consideration.
00547         */
00548         if( (found_sig->suppl.part.assigned == 0) && (found_sig->suppl.part.mba == 1) ) {
00549           expl = found_sig->exp_head;
00550           while( expl != NULL ) {
00551             if( (stmt = expression_get_root_statement( expl->exp )) != NULL ) {
00552 #ifdef DEBUG_MODE
00553               if( debug_mode ) {
00554                 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Removing statement block %d, line %d because it needed to be assigned but would not be",
00555                                             stmt->exp->id, stmt->exp->line );
00556                 assert( rv < USER_MSG_LENGTH );
00557                 print_output( user_msg, DEBUG, __FILE__, __LINE__ );
00558               }
00559 #endif
00560               stmt_blk_add_to_remove_list( stmt );
00561             }
00562             expl = expl->next;
00563           }
00564         }
00565 
00566       }
00567 
00568     }
00569 
00570   } else {
00571 
00572     retval = FALSE;
00573 
00574   }
00575 
00576   PROFILE_END;
00577 
00578   return( retval );
00579 
00580 }


Generated on Wed Jun 17 22:19:20 2009 for Covered by doxygen 1.3.4