reentrant.c File Reference

#include <assert.h>
#include "defines.h"
#include "reentrant.h"
#include "sys_tasks.h"
#include "util.h"

Functions

static int reentrant_count_afu_bits (func_unit *funit)
static void reentrant_store_data_bits (func_unit *funit, reentrant *ren, unsigned int curr_bit)
static void reentrant_restore_data_bits (func_unit *funit, reentrant *ren, unsigned int curr_bit, expression *expr)
reentrantreentrant_create (func_unit *funit)
 Allocates and initializes the reentrant structure for the given functional unit.
void reentrant_dealloc (reentrant *ren, func_unit *funit, expression *expr)
 Deallocates all memory associated with the given reentrant structure.

Variables

const exp_info exp_op_info [EXP_OP_NUM]

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
12/11/2006

Function Documentation

static int reentrant_count_afu_bits ( func_unit funit  )  [static]
Returns:
Returns the total number of bits in all signals in this functional unit and all parents within the same reentrant task/function.

Recursively iterates up the functional unit tree keeping track of the total number of bits needed to store all information in the current reentrant task/function.

Parameters:
funit Pointer to current function to count the bits of

References vsuppl_u::data_type, ESUPPL_BITS_TO_STORE, exp_link_s::exp, func_unit_s::exp_head, EXPR_IS_STATIC, EXPR_OWNS_VEC, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, exp_link_s::next, sig_link_s::next, expression_s::op, func_unit_s::parent, vsuppl_u::part, PROFILE, PROFILE_END, sig_link_s::sig, func_unit_s::sig_head, vector_s::suppl, func_unit_s::type, expression_s::value, vsignal_s::value, VDATA_R32, VDATA_R64, VDATA_UL, and vector_s::width.

Referenced by reentrant_create().

00042   { PROFILE(REENTRANT_COUNT_AFU_BITS);
00043 
00044   sig_link* sigl;      /* Pointer to current signal link */
00045   exp_link* expl;      /* Pointer to current expression link */
00046   int       bits = 0;  /* Number of bits in this functional unit and all parent functional units in the reentrant task/function */
00047 
00048   if( (funit->type == FUNIT_ATASK) || (funit->type == FUNIT_AFUNCTION) || (funit->type == FUNIT_ANAMED_BLOCK) ) {
00049 
00050     /* Count the number of signal bits in this functional unit */
00051     sigl = funit->sig_head;
00052     while( sigl != NULL ) {
00053       switch( sigl->sig->value->suppl.part.data_type ) {
00054         case VDATA_UL  :  bits += (sigl->sig->value->width * 2) + 1;  break;
00055         case VDATA_R64 :  bits += 64;  break;
00056         case VDATA_R32 :  bits += 32;  break;
00057         default        :  assert( 0 );  break;
00058       }
00059       sigl = sigl->next;
00060     }
00061 
00062     /* Count the number of expression bits in this functional unit */
00063     expl = funit->exp_head;
00064     while( expl != NULL ) {
00065       if( (EXPR_OWNS_VEC( expl->exp->op ) == 1) && (EXPR_IS_STATIC( expl->exp ) == 0) ) {
00066         bits += (expl->exp->value->width * 2);
00067       }
00068       bits += ((ESUPPL_BITS_TO_STORE % 2) == 0) ? ESUPPL_BITS_TO_STORE : (ESUPPL_BITS_TO_STORE + 1);
00069       expl = expl->next;
00070     }
00071 
00072     /* If the current functional unit is a named block, gather the bits in the parent functional unit */
00073     if( funit->type == FUNIT_ANAMED_BLOCK ) {
00074       bits += reentrant_count_afu_bits( funit->parent );
00075     }
00076 
00077   }
00078 
00079   PROFILE_END;
00080 
00081   return( bits );
00082 
00083 }

reentrant* reentrant_create ( func_unit funit  ) 

Allocates and initializes the reentrant structure for the given functional unit.

Returns:
Returns a pointer to the newly created reentrant structure.

Allocates and initializes the reentrant structure for the given functional unit, compressing and packing the bits into the given data structure.

Parameters:
funit Pointer to functional unit to create a new reentrant structure for

References reentrant_s::data, reentrant_s::data_size, malloc_safe, PROFILE, PROFILE_END, reentrant_count_afu_bits(), and reentrant_store_data_bits().

Referenced by expression_op_func__passign().

00366   { PROFILE(REENTRANT_CREATE);
00367 
00368   reentrant*   ren  = NULL;  /* Pointer to newly created reentrant structure */
00369   int          data_size;    /* Number of uint8s needed to store the given functional unit */
00370   unsigned int bits = 0;     /* Number of bits needed to store signal values */
00371   int          i;            /* Loop iterator */
00372 
00373   /* Get size needed to store data */
00374   bits = reentrant_count_afu_bits( funit );
00375 
00376   /* Calculate data size */
00377   data_size = ((bits & 0x7) == 0) ? (bits >> 3) : ((bits >> 3) + 1);
00378 
00379   /* If there is data to store, allocate the needed memory and populate it */
00380   if( data_size > 0 ) {
00381 
00382     /* Allocate the structure */
00383     ren = (reentrant*)malloc_safe( sizeof( reentrant ) );
00384 
00385     /* Set the data size */
00386     ren->data_size = data_size;
00387 
00388     /* Allocate and initialize memory for data */
00389     ren->data = (uint8*)malloc_safe( sizeof( uint8 ) * ren->data_size );
00390     for( i=0; i<data_size; i++ ) {
00391       ren->data[i] = 0;
00392     }
00393 
00394     /* Walk through the signal list in the reentrant functional unit, compressing and saving vector values */
00395     reentrant_store_data_bits( funit, ren, 0 );
00396 
00397   }
00398 
00399   PROFILE_END;
00400 
00401   return( ren );
00402 
00403 }

void reentrant_dealloc ( reentrant ren,
func_unit funit,
expression expr 
)

Deallocates all memory associated with the given reentrant structure.

Pops data back into the given functional unit and deallocates all memory associated with the given reentrant structure.

Parameters:
ren Pointer to the reentrant structure to deallocate from memory
funit Pointer to functional unit associated with this reentrant structure
expr Pointer of expression to exclude from updating (optional)

References reentrant_s::data, reentrant_s::data_size, free_safe, PROFILE, PROFILE_END, and reentrant_restore_data_bits().

Referenced by expression_op_func__func_call(), and sim_thread().

00413   { PROFILE(REENTRANT_DEALLOC);
00414 
00415   if( ren != NULL ) {
00416 
00417     /* If we have data being stored, pop it */
00418     if( ren->data_size > 0 ) {
00419 
00420       /* Walk through each bit in the compressed data array and assign it back to its signal */
00421       reentrant_restore_data_bits( funit, ren, 0, expr );
00422 
00423       /* Deallocate the data uint8 array */
00424       free_safe( ren->data, (sizeof( uint8 ) * ren->data_size) );
00425 
00426     }
00427 
00428     /* Deallocate memory allocated for this reentrant structure */
00429     free_safe( ren, sizeof( reentrant ) );
00430 
00431   }
00432 
00433   PROFILE_END;
00434 
00435 }

static void reentrant_restore_data_bits ( func_unit funit,
reentrant ren,
unsigned int  curr_bit,
expression expr 
) [static]

Recursively restores the signal and expression values of the functional units in a reentrant task/function.

Parameters:
funit Pointer to current functional unit to restore
ren Pointer to reentrant structure containing bits to restore
curr_bit Current bit in reentrant structure to restore
expr Pointer to expression to exclude from updating

References reentrant_s::data, vsuppl_u::data_type, ESUPPL_BITS_TO_STORE, esuppl_u::eval_f, esuppl_u::eval_t, exp_link_s::exp, func_unit_s::exp_head, EXPR_IS_STATIC, EXPR_OWNS_VEC, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, esuppl_u::left_changed, exp_link_s::next, sig_link_s::next, expression_s::op, func_unit_s::parent, esuppl_u::part, vsuppl_u::part, esuppl_u::prev_called, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, esuppl_u::right_changed, vsuppl_u::set, sig_link_s::sig, func_unit_s::sig_head, expression_s::suppl, vector_s::suppl, sys_task_bitstoreal(), func_unit_s::type, vector_s::ul, UL_DIV, UL_MOD, rv32_s::val, rv64_s::val, expression_s::value, vector_s::value, vsignal_s::value, VDATA_R32, VDATA_R64, VDATA_UL, VTYPE_INDEX_VAL_VALH, VTYPE_INDEX_VAL_VALL, and vector_s::width.

Referenced by reentrant_dealloc().

00223   { PROFILE(REENTRANT_RESTORE_DATA_BITS);
00224 
00225   int i;  /* Loop iterator */
00226 
00227   if( (funit->type == FUNIT_ATASK) || (funit->type == FUNIT_AFUNCTION) || (funit->type == FUNIT_ANAMED_BLOCK) ) {
00228 
00229     sig_link* sigl;
00230     exp_link* expl;
00231 
00232     /* Walk through each bit in the compressed data array and assign it back to its signal */
00233     sigl = funit->sig_head;
00234     while( sigl != NULL ) {
00235       switch( sigl->sig->value->suppl.part.data_type ) {
00236         case VDATA_UL :
00237           {
00238             unsigned int i;
00239             for( i=0; i<sigl->sig->value->width; i++ ) {
00240               ulong* entry = sigl->sig->value->value.ul[UL_DIV(i)];
00241               if( UL_MOD(i) == 0 ) {
00242                 entry[VTYPE_INDEX_VAL_VALL] = 0;
00243                 entry[VTYPE_INDEX_VAL_VALH] = 0;
00244               }
00245               entry[VTYPE_INDEX_VAL_VALL] |= (ulong)((ren->data[curr_bit>>3] >> (curr_bit & 0x7)) & 0x1) << UL_MOD(i);
00246               curr_bit++;
00247               entry[VTYPE_INDEX_VAL_VALH] |= (ulong)((ren->data[curr_bit>>3] >> (curr_bit & 0x7)) & 0x1) << UL_MOD(i);
00248               curr_bit++;
00249             }
00250             sigl->sig->value->suppl.part.set = (ren->data[curr_bit>>3] >> (curr_bit & 0x7)) & 0x1;
00251             curr_bit++;
00252           }
00253           break;
00254         case VDATA_R64 :
00255           {
00256             uint64       real_bits = 0;
00257             unsigned int i;
00258             for( i=0; i<64; i++ ) {
00259               real_bits |= (uint64)ren->data[curr_bit>>3] << (i - curr_bit);
00260               curr_bit++;
00261             }
00262             sigl->sig->value->value.r64->val = sys_task_bitstoreal( real_bits );
00263           }
00264           break;
00265         case VDATA_R32 :
00266           {
00267             uint64       real_bits = 0;
00268             unsigned int i;
00269             for( i=0; i<32; i++ ) {
00270               real_bits |= (uint64)ren->data[curr_bit>>3] << (i - curr_bit);
00271               curr_bit++;
00272             }
00273             sigl->sig->value->value.r32->val = (float)sys_task_bitstoreal( real_bits );
00274           }
00275           break;
00276         default :  assert( 0 );  break;
00277       }
00278       sigl = sigl->next;
00279     }
00280 
00281     /* Walk through each bit in the compressed data array and assign it back to its expression */
00282     expl = funit->exp_head;
00283     while( expl != NULL ) {
00284       if( expl->exp == expr ) {
00285         curr_bit += (expr->value->width * 2);
00286       } else {
00287         if( (EXPR_OWNS_VEC( expl->exp->op ) == 1) && (EXPR_IS_STATIC( expl->exp ) == 0) ) {
00288           switch( expl->exp->value->suppl.part.data_type ) {
00289             case VDATA_UL :
00290               {
00291                 unsigned int i;
00292                 for( i=0; i<expl->exp->value->width; i++ ) {
00293                   ulong* entry = expl->exp->value->value.ul[UL_DIV(i)];
00294                   if( UL_MOD(i) == 0 ) {
00295                     entry[VTYPE_INDEX_VAL_VALL] = 0;
00296                     entry[VTYPE_INDEX_VAL_VALH] = 0;
00297                   }
00298                   entry[VTYPE_INDEX_VAL_VALL] |= (ulong)((ren->data[curr_bit>>3] >> (curr_bit & 0x7)) & 0x1) << UL_MOD(i);
00299                   curr_bit++;
00300                   entry[VTYPE_INDEX_VAL_VALH] |= (ulong)((ren->data[curr_bit>>3] >> (curr_bit & 0x7)) & 0x1) << UL_MOD(i);
00301                   curr_bit++;
00302                 }
00303               }
00304               break;
00305             case VDATA_R64 :
00306               {
00307                 uint64       real_bits = 0;
00308                 unsigned int i;
00309                 for( i=0; i<64; i++ ) {
00310                   real_bits |= (uint64)ren->data[curr_bit>>3] << (i - curr_bit);
00311                   curr_bit++;
00312                 }
00313                 expl->exp->value->value.r64->val = sys_task_bitstoreal( real_bits );
00314               }
00315               break;
00316             case VDATA_R32 :
00317               {
00318                 uint64       real_bits = 0;
00319                 unsigned int i;
00320                 for( i=0; i<32; i++ ) {
00321                   real_bits |= (uint64)ren->data[curr_bit>>3] << (i - curr_bit);
00322                   curr_bit++;
00323                 }
00324                 expl->exp->value->value.r32->val = (float)sys_task_bitstoreal( real_bits );
00325               }
00326               break;
00327             default :  assert( 0 );
00328           }
00329         }
00330       }
00331       for( i=0; i<(((ESUPPL_BITS_TO_STORE % 2) == 0) ? ESUPPL_BITS_TO_STORE : (ESUPPL_BITS_TO_STORE + 1)); i++ ) {
00332         switch( i ) {
00333           case 0 :  expl->exp->suppl.part.left_changed  = (ren->data[curr_bit>>3] >> (curr_bit & 0x7));  break;
00334           case 1 :  expl->exp->suppl.part.right_changed = (ren->data[curr_bit>>3] >> (curr_bit & 0x7));  break;
00335           case 2 :  expl->exp->suppl.part.eval_t        = (ren->data[curr_bit>>3] >> (curr_bit & 0x7));  break;
00336           case 3 :  expl->exp->suppl.part.eval_f        = (ren->data[curr_bit>>3] >> (curr_bit & 0x7));  break;
00337           case 4 :  expl->exp->suppl.part.prev_called   = (ren->data[curr_bit>>3] >> (curr_bit & 0x7));  break;
00338         }
00339         curr_bit++;
00340       }
00341       expl = expl->next;
00342     }
00343 
00344     /*
00345      If the current functional unit is a named block, restore the rest of the bits for the parent functional units
00346      in this reentrant task/function.
00347     */
00348     if( funit->type == FUNIT_ANAMED_BLOCK ) {
00349       reentrant_restore_data_bits( funit->parent, ren, curr_bit, expr );
00350     }
00351 
00352   }
00353  
00354   PROFILE_END;
00355 
00356 }

static void reentrant_store_data_bits ( func_unit funit,
reentrant ren,
unsigned int  curr_bit 
) [static]

Recursively gathers all signal data bits to store and stores them in the given reentrant structure.

Parameters:
funit Pointer to current functional unit to traverse
ren Pointer to reentrant structure to populate
curr_bit Current bit to store (should be started at a value of 0)

References reentrant_s::data, vsuppl_u::data_type, ESUPPL_BITS_TO_STORE, esuppl_u::eval_f, esuppl_u::eval_t, exp_link_s::exp, func_unit_s::exp_head, EXPR_IS_STATIC, EXPR_OWNS_VEC, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, esuppl_u::left_changed, exp_link_s::next, sig_link_s::next, expression_s::op, func_unit_s::parent, esuppl_u::part, vsuppl_u::part, esuppl_u::prev_called, PROFILE, PROFILE_END, vector_s::r32, vector_s::r64, esuppl_u::right_changed, vsuppl_u::set, sig_link_s::sig, func_unit_s::sig_head, expression_s::suppl, vector_s::suppl, sys_task_realtobits(), func_unit_s::type, vector_s::ul, UL_DIV, UL_MOD, rv32_s::val, rv64_s::val, expression_s::value, vector_s::value, vsignal_s::value, VDATA_R32, VDATA_R64, VDATA_UL, VTYPE_INDEX_VAL_VALH, VTYPE_INDEX_VAL_VALL, and vector_s::width.

Referenced by reentrant_create().

00093   { PROFILE(REENTRANT_STORE_DATA_BITS);
00094 
00095   if( (funit->type == FUNIT_ATASK) || (funit->type == FUNIT_AFUNCTION) || (funit->type == FUNIT_ANAMED_BLOCK) ) {
00096 
00097     sig_link* sigl = funit->sig_head;
00098     exp_link* expl = funit->exp_head;
00099 
00100     /* Walk through the signal list in the reentrant functional unit, compressing and saving vector values */
00101     while( sigl != NULL ) {
00102       switch( sigl->sig->value->suppl.part.data_type ) {
00103         case VDATA_UL :
00104           {
00105             unsigned int i;
00106             for( i=0; i<sigl->sig->value->width; i++ ) {
00107               ulong* entry = sigl->sig->value->value.ul[UL_DIV(i)];
00108               ren->data[curr_bit>>3] |= (((entry[VTYPE_INDEX_VAL_VALL] >> UL_MOD(i)) & 0x1) << (curr_bit & 0x7));
00109               curr_bit++;
00110               ren->data[curr_bit>>3] |= (((entry[VTYPE_INDEX_VAL_VALH] >> UL_MOD(i)) & 0x1) << (curr_bit & 0x7));
00111               curr_bit++;
00112             }
00113             ren->data[curr_bit>>3] |= sigl->sig->value->suppl.part.set << (curr_bit & 0x7);
00114             curr_bit++;
00115             /* Clear the set bit */
00116             sigl->sig->value->suppl.part.set = 0;
00117           }
00118           break;
00119         case VDATA_R64 :
00120           {
00121             uint64       real_bits = sys_task_realtobits( sigl->sig->value->value.r64->val );
00122             unsigned int i;
00123             for( i=0; i<64; i++ ) {
00124               ren->data[curr_bit>>3] |= (real_bits & 0x1) << (curr_bit & 0x7);
00125               real_bits >>= 1;
00126               curr_bit++;
00127             }
00128           }
00129           break;
00130         case VDATA_R32 :
00131           {
00132             uint64       real_bits = sys_task_realtobits( (double)sigl->sig->value->value.r32->val );
00133             unsigned int i;
00134             for( i=0; i<32; i++ ) {
00135               ren->data[curr_bit>>3] |= (real_bits & 0x1) << (curr_bit & 0x7);
00136               real_bits >>= 1;
00137               curr_bit++;
00138             }
00139           }
00140           break;
00141         default :  assert( 0 );
00142       }
00143       sigl = sigl->next;
00144     }
00145 
00146     /* Walk through expression list in the reentrant functional unit, compressing and saving vector and supplemental values */
00147     while( expl != NULL ) {
00148       unsigned int i;
00149       if( (EXPR_OWNS_VEC( expl->exp->op ) == 1) && (EXPR_IS_STATIC( expl->exp ) == 0) ) {
00150         switch( expl->exp->value->suppl.part.data_type ) {
00151           case VDATA_UL :
00152             {
00153               for( i=0; i<expl->exp->value->width; i++ ) {
00154                 ulong* entry = expl->exp->value->value.ul[UL_DIV(i)];
00155                 ren->data[curr_bit>>3] |= (((entry[VTYPE_INDEX_VAL_VALL] >> UL_MOD(i)) & 0x1) << (curr_bit & 0x7));
00156                 curr_bit++;
00157                 ren->data[curr_bit>>3] |= (((entry[VTYPE_INDEX_VAL_VALH] >> UL_MOD(i)) & 0x1) << (curr_bit & 0x7));
00158                 curr_bit++;
00159               }
00160             }
00161             break;
00162           case VDATA_R64 :
00163             {
00164               uint64 real_bits = sys_task_realtobits( expl->exp->value->value.r64->val );
00165               for( i=0; i<64; i++ ) {
00166                 ren->data[curr_bit>>3] |= (real_bits & 0x1) << (curr_bit & 0x7);
00167                 real_bits >>= 1;
00168                 curr_bit++;
00169               }
00170             }
00171             break;
00172           case VDATA_R32 :
00173             {
00174               uint64 real_bits = sys_task_realtobits( (double)expl->exp->value->value.r32->val );
00175               for( i=0; i<32; i++ ) {
00176                 ren->data[curr_bit>>3] |= (real_bits & 0x1) << (curr_bit & 0x7);
00177                 real_bits >>= 1;
00178                 curr_bit++;
00179               }
00180             }
00181             break;
00182           default :  assert( 0 );  break;
00183         }
00184       }
00185       for( i=0; i<(((ESUPPL_BITS_TO_STORE % 2) == 0) ? ESUPPL_BITS_TO_STORE : (ESUPPL_BITS_TO_STORE + 1)); i++ ) {
00186         switch( i ) {
00187           case 0 :  ren->data[curr_bit>>3] |= (expl->exp->suppl.part.left_changed  << (curr_bit & 0x7));  break;
00188           case 1 :  ren->data[curr_bit>>3] |= (expl->exp->suppl.part.right_changed << (curr_bit & 0x7));  break;
00189           case 2 :  ren->data[curr_bit>>3] |= (expl->exp->suppl.part.eval_t        << (curr_bit & 0x7));  break;
00190           case 3 :  ren->data[curr_bit>>3] |= (expl->exp->suppl.part.eval_f        << (curr_bit & 0x7));  break;
00191           case 4 :  ren->data[curr_bit>>3] |= (expl->exp->suppl.part.prev_called   << (curr_bit & 0x7));  break;
00192         }
00193         curr_bit++;
00194       }
00195       /* Clear supplemental bits that have been saved off */
00196       expl->exp->suppl.part.left_changed  = 0;
00197       expl->exp->suppl.part.right_changed = 0;
00198       expl->exp->suppl.part.eval_t        = 0;
00199       expl->exp->suppl.part.eval_f        = 0;
00200       expl->exp->suppl.part.prev_called   = 0;
00201       expl = expl->next;
00202     }
00203 
00204     /* If the current functional unit is a named block, store the bits in the parent functional unit */
00205     if( funit->type == FUNIT_ANAMED_BLOCK ) {
00206       reentrant_store_data_bits( funit->parent, ren, curr_bit );
00207     }
00208 
00209   }
00210 
00211   PROFILE_END;
00212 
00213 }


Variable Documentation

const exp_info exp_op_info[EXP_OP_NUM]

Array containing static information about expression operation types. NOTE: This structure MUST be updated if a new expression is added! The third argument is an initialization to the exp_info_s structure.

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