#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. | |
|
||||||||||||||||||||
|
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.
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 }
|
|
||||||||||||||||
|
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.
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 }
|
|
|
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 }
|
|
|
Searches current binding list for the signal name associated with the given expression.
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 }
|
|
||||||||||||
|
Performs vsignal/expression bind (performed after parse completed).
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 }
|
|
||||||||||||
|
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.
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 }
|
|
|
Removes the statement block associated with the expression with ID of id after binding has occurred.
|
|
||||||||||||||||||||||||||||||||||||
|
Binds a signal to an 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 }
|
1.3.4