Previous Up Next

Appendix C  Modifying Input Code to be Synthesizable by Spark

C.1  Input Code with Structs

Consider the input source code shown in Figure C.128Input Code with Structsfigure.C.1(a) and consider that we want to synthesize the function ``structEx''. Since Spark does not currently support structures, we can split this function into two and rewrite the code as shown in Figure C.128Input Code with Structsfigure.C.1(b). Now we can put the function ``structEx'' in a separate file and execute Spark on that file.

struct myStruct {
int fir;
int sec;
};

void structEx(myStruct a, int *b)
{
  *b = a->fir + a->sec;
}
 
struct myStruct {
int fir;
int sec;
};
void callStructCode(myStruct a, int *b)
{
  structEx(a->fir, a->sec, b);
}

void structEx(int A_fir, int A_sec, int *b)
{
  *b = A_fir + A_sec;
}

Figure C.1: (a) Input code that uses a structure (myStruct). (b) The function can be split into a calling function and a called function. The calling function calls the called function after enumerating the elements of the structure that are processed by the called function. The called function (structEx) is now synthesizable.


C.2  Input Code with Pointers


/* arr is an array that has been
declared outside this function */
void pointerCode(int *arr, int *b)
{
  int *ptr;
  int i;

  ptr = arr;
  for (i = 0; i < 10; i++)
   {
     *b += *ptr;
     ptr++;
   }
}
   
/* arr is an array that has been 
declared outside this function */
void pointerCode(int *arr, int *b)
{
  int i;
  int arr_index;
  
  arr_index = 0;
  for (i = 0; i < 10; i++)
   {
     *b += arr[arr_index];
     arr_index++;
   }
}

Figure C.2: (a) Input code that uses a pointer to address an array. (b) The pointer can be replaced by a array index variable (arr_index) that determines which array element to access.


Consider the input source code shown in Figure C.229Input Code with Pointersfigure.C.2(a) and consider that we want to synthesize the function ``pointerCode''. In this case, it is straight forward to replace the pointer ptr with the array variable arr. The code can, hence, be rewritten as shown in Figure C.229Input Code with Pointersfigure.C.2(b). We have replaced the pointer with an array index variable instead. The code is now synthesizable by Spark.

C.3  Input Code with Breaks


void breakCode(int a, int *b)
{
  int i;

  for (i = 0; i < N; i++)
   {
     *b += a;
     if (*b > 100)
       break;
   }
}
   
void breakCode(int a, int *b)
{
  int i;
  int breakFlag;

  breakFlag = 0;
  for (i = 0; i < N; i++)
   {
     if (breakFlag == 0)
     {
       *b += a;
       if (*b > 100)
         breakFlag = 1;
     }
   }
}

Figure C.3: (a) Input code with a break inside a for-loop. (b) The break can be replaced by a flag (breakFlag) that determines if future iterations of the loop body are executed or not.


Consider the input source code shown in Figure C.330Input Code with Breaksfigure.C.3(a). Consider that we want to synthesize the function ``breakCode''. We can remove the break in this code by creating a flag that is checked for each iteration of the loop as shown in Figure C.330Input Code with Breaksfigure.C.3(b). If the breakFlag is set, then the statements in the loop body are not executed.

C.4  Input Code with Continues


void continueCode(int a, int *b)
{
  int i;

  for (i = 0; i < N; i++)
   {
     *b += a;
     if (*b < 100)
       continue;
     b = b/2; 
   }
}
   
void continueCode(int a, int *b)
{
  int i;
  int continueFlag;

  for (i = 0; i < N; i++)
   {
     continueFlag = 0;
     *b += a;
     if (*b < 100)
       continueFlag = 1;
     if (continueFlag == 0)
      {
        b = b/2; 
      }
   }
}

Figure C.4: (a) Input code with a continue inside a for-loop. (b) The continue can be replaced by a flag (continueFlag) that determines if the rest of the code in the loop is executed or not.


Consider the input source code shown in Figure C.431Input Code with Continuesfigure.C.4(a). Consider that we want to synthesize the function ``continueCode''. We can remove the continue in this code by creating a flag that is checked for each iteration of the loop as shown in Figure C.431Input Code with Continuesfigure.C.4(b).

In the modified code, when b is less than 100, then the continueFlag is set and hence, the b=b/2 code does not execute. The continueFlag has to be reset to zero at the beginning of each loop iteration to retain the semantics of the original code.

C.5  Input Code in which an Argument is Modified


void argumentCode(int a, int *b)
{
  int i;

  for (i = 0; i < N; i++)
   {
     *b += a;
     a = a/2;
   }
}
   
void argumentCode(int a, int *b)
{
  int i;
  int temp;
  
  temp = a;
  for (i = 0; i < N; i++)
   {
     *b += a;
     temp = temp/2;
   }
}

Figure C.5: (a) ``C'' code with input variable a being modified in the function body. (b) Variable a is stored in a local variable temp and all instances of a are replaced by temp. This is done because VHDL semantics do not allow an input variable to be modified in the body of the code.


The ``C'' language allows a function to modify a variable that has been passed as an argument to the function. For example, consider the code in Figure C.532Input Code in which an Argument is Modifiedfigure.C.5(a). The modifications to the variable a are local to the function argumentCode since variable a has not been passed by reference.

When Spark generates VHDL code from this input C code, variable a will be declared as input in the VHDL code and there will be a statement updating a in the process body. However, VHDL semantics do not allow an input variable to be updated in the architecture body. Hence, to make this input code synthesizable, we have to modify the C code to store variable a in a temporary variable and update the temporary variable. The modified code is shown in Figure C.532Input Code in which an Argument is Modifiedfigure.C.5(b).

C.6  Input Code with ``?'' if-then-else

Consider this code with an if-then-else written in a question format:
  d = (a > 10) ? (a + b) : (a + c);



This code has to be converted explicitly into if-then-else as shown below:
 
  if (a > 10)
    d = a + b;
  else
    d = a + c;

C.7  Input Code with Multi-Dimensional Arrays

Input code that contains multi-dimensional arrays can be modified by making the arrays single-dimensional. Consider the following example:
  int myArray[N][M];

  ...

  temp = myArray[i][j]



The two-dimensional array ``myArray'' can be converted into a single-dimensional array as follows
  int myArray[N * M];

  ...

  temp = myArray[i*M + j]


Previous Up Next