enumerate.h File Reference

Contains functions for handling enumerations. More...

#include "defines.h"

Go to the source code of this file.

Functions

void enumerate_add_item (vsignal *enum_sig, static_expr *value, func_unit *funit)
 Allocates, initializes and adds a new enumerated item to the given functional unit.
void enumerate_end_list (func_unit *funit)
 Sets the last status of the last item in the enumerated list.
void enumerate_resolve (funit_inst *inst)
 Resolves all enumerations within the given functional unit instance.
void enumerate_dealloc (enum_item *ei)
 Deallocates all memory associated with the given enumeration.
void enumerate_dealloc_list (func_unit *funit)
 Deallocates enumeration list from given functional unit.

Detailed Description

Contains functions for handling enumerations.

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
8/29/2006

Function Documentation

void enumerate_add_item ( vsignal enum_sig,
static_expr value,
func_unit funit 
)

Allocates, initializes and adds a new enumerated item to the given functional unit.

Parameters:
enum_sig Pointer to signal in database that represents an enumeration value
value Pointer to static expression that contains the value to be assigned to the signal during elaboration
funit Pointer to functional unit that this enumeration value will be added to

References func_unit_s::ei_head, func_unit_s::ei_tail, FALSE, enum_item_s::last, malloc_safe, enum_item_s::next, PROFILE, PROFILE_END, enum_item_s::sig, and enum_item_s::value.

Referenced by db_add_enum().

00043   { PROFILE(ENUMERATE_ADD_ITEM);
00044 
00045   enum_item* ei;  /* Pointer to newly allocated enumeration item */
00046 
00047   /* Allocate and initialize the enumeration item */
00048   ei = (enum_item*)malloc_safe( sizeof( enum_item ) );
00049   ei->sig   = enum_sig;
00050   ei->value = value;
00051   ei->last  = FALSE;
00052   ei->next  = NULL;
00053 
00054   /* Add it to the current functional unit's enumeration list */
00055   if( funit->ei_head == NULL ) {
00056     funit->ei_head = funit->ei_tail = ei;
00057   } else {
00058     funit->ei_tail->next = ei;
00059     funit->ei_tail       = ei;
00060   }
00061 
00062   PROFILE_END;
00063 
00064 }

void enumerate_dealloc ( enum_item ei  ) 

Deallocates all memory associated with the given enumeration.

Parameters:
ei Pointer to enumeration to deallocate

References free_safe, PROFILE, PROFILE_END, static_expr_dealloc(), TRUE, and enum_item_s::value.

Referenced by enumerate_dealloc_list(), and struct_union_member_dealloc().

00163   { PROFILE(ENUMERATE_DEALLOC);
00164 
00165   if( ei != NULL ) {
00166 
00167     /* Deallocate static expression, if necessary */
00168     if( ei->value != NULL ) {
00169       static_expr_dealloc( ei->value, TRUE );
00170     }
00171 
00172     /* Deallocate ourself */
00173     free_safe( ei, sizeof( enum_item ) );
00174 
00175   }
00176 
00177   PROFILE_END;
00178 
00179 }

void enumerate_dealloc_list ( func_unit funit  ) 

Deallocates enumeration list from given functional unit.

Deallocates all memory associated with the enumeration list in the given functional unit

Parameters:
funit Pointer to functional unit to remove enumeration list for

References func_unit_s::ei_head, func_unit_s::ei_tail, enumerate_dealloc(), enum_item_s::next, PROFILE, and PROFILE_END.

Referenced by funit_clean().

00186   { PROFILE(ENUMERATE_DEALLOC_LIST);
00187 
00188   enum_item* tmp;  /* Temporary pointer to current link in list */
00189 
00190   while( funit->ei_head != NULL ) {
00191     tmp  = funit->ei_head;
00192     funit->ei_head = tmp->next;
00193     enumerate_dealloc( tmp );
00194   }
00195 
00196   /* Set the tail pointer to NULL as well */
00197   funit->ei_tail = NULL;
00198 
00199   PROFILE_END;
00200 
00201 }

void enumerate_end_list ( func_unit funit  ) 

Sets the last status of the last item in the enumerated list.

Called after all enumerations have been parsed for this list.

Parameters:
funit Pointer to functional unit to close out enumerated list

References func_unit_s::ei_tail, enum_item_s::last, PROFILE, PROFILE_END, and TRUE.

Referenced by db_end_enum_list().

00071   { PROFILE(ENUMERATE_END_LIST);
00072 
00073   /* Make sure that we aren't calling this function when there is no existing enumerated list */
00074   assert( funit->ei_tail != NULL );
00075 
00076   /* Set the last bit of the tail enumerated item */
00077   funit->ei_tail->last = TRUE;
00078 
00079   PROFILE_END;
00080 
00081 }

void enumerate_resolve ( funit_inst inst  ) 

Resolves all enumerations within the given functional unit instance.

Exceptions:
anonymous Throw param_expr_eval

Resolves all enumerated values for their value for the given instance. This needs to be called during elaboration after all signals have been sized and parameters have been resolved.

Parameters:
inst Pointer to functional unit instance to resolve all enumerated values

References func_unit_s::ei_head, static_expr_s::exp, FATAL, FATAL_WRAP, func_unit_s::filename, funit_inst_s::funit, vsuppl_u::is_signed, enum_item_s::last, vsignal_s::line, enum_item_s::next, static_expr_s::num, obf_file, param_expr_eval(), vsuppl_u::part, print_output(), PROFILE, PROFILE_END, enum_item_s::sig, vector_s::suppl, Throw, TRUE, vector_s::ul, user_msg, USER_MSG_LENGTH, vector_s::value, expression_s::value, enum_item_s::value, vsignal_s::value, vector_from_int(), vector_is_unknown(), vector_set_value_ulong(), vector_to_int(), and vector_s::width.

Referenced by funit_size_elements().

00092   { PROFILE(ENUMERATE_RESOLVE);
00093 
00094   enum_item* ei;                 /* Pointer to current enumeration item in the given functional unit */
00095   int        last_value = 0;     /* Value of last value for this enumeration */
00096   bool       first      = TRUE;  /* Specifies if the current enumeration is the first */
00097   bool       is_signed;          /* Contains original value of signedness of signal */
00098 
00099   assert( inst != NULL );
00100 
00101   ei = inst->funit->ei_head;
00102   while( ei != NULL ) {
00103 
00104     assert( ei->sig->value != NULL );
00105 
00106     /* Store signedness */
00107     is_signed = ei->sig->value->suppl.part.is_signed;
00108 
00109     /* If no value was assigned, we need to assign one now */
00110     if( ei->value == NULL ) {
00111 
00112       if( first ) {
00113         (void)vector_from_int( ei->sig->value, 0 );
00114       } else if( last_value == -1 ) {
00115         unsigned int rv;
00116         print_output( "Implicit enumerate assignment cannot follow an X or Z value", FATAL, __FILE__, __LINE__ );
00117         rv = snprintf( user_msg, USER_MSG_LENGTH, "File: %s, Line: %d", obf_file( inst->funit->filename ), ei->sig->line );
00118         assert( rv < USER_MSG_LENGTH );
00119         print_output( user_msg, FATAL_WRAP, __FILE__, __LINE__ );
00120         Throw 0;
00121       } else {
00122         (void)vector_from_int( ei->sig->value, (last_value + 1) );
00123       }
00124 
00125     /* Otherwise, reduce the static_expr value to a number and assign it */
00126     } else {
00127 
00128       if( ei->value->exp == NULL ) {
00129         (void)vector_from_int( ei->sig->value, ei->value->num );
00130       } else {
00131         param_expr_eval( ei->value->exp, inst );
00132         (void)vector_set_value_ulong( ei->sig->value, ei->value->exp->value->value.ul, ei->sig->value->width );
00133       }
00134 
00135     }
00136 
00137     /* Put back the original signedness */
00138     ei->sig->value->suppl.part.is_signed = is_signed;
00139         
00140     /* Set the first value to indicate if the next value is the first in the list */
00141     first = ei->last;
00142 
00143     /* Set last_value to that of this this signal value */
00144     if( !vector_is_unknown( ei->sig->value ) ) {
00145       last_value = vector_to_int( ei->sig->value );
00146     } else {
00147       last_value = -1;
00148     }
00149 
00150     ei = ei->next;
00151 
00152   }
00153 
00154   PROFILE_END;
00155 
00156 }

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