text: #include "merge_sort.h"
  #include "assert.h"
  
  // subarray1 is in[ii..i2-1]; subarray2 is in[i2..i3-1]
  // sorted merge is stored in out[i1..i3-1]
  void merge(DTYPE in[SIZE], int i1, int i2, int i3, DTYPE out[SIZE]) {
      int f1 = i1, f2 = i2;
      // Foreach element that needs to be sorted...
      for(int index = i1; index < i3; index++) {
  #pragma HLS pipeline II=1
          DTYPE t1 = in[f1];
          DTYPE t2 = (f2 == i3) ? 0 : in[f2];
          // Select the smallest available element.
          if(f2 == i3 || (f1 < i2 && t1 <= t2)) {
              out[index] = t1;
              f1++;
          } else {
              assert(f2 < i3);
              out[index] = t2;
              f2++;
          }
      }
  }
  
  void merge_sort(DTYPE A[SIZE]) {
      DTYPE temp[SIZE];
      // Each time through the loop, we try to merge sorted subarrays of width elements
      // into a sorted subarray of 2*width elements.
   stage:
      for (int width = 1; width < SIZE; width = 2 * width) {
      merge_arrays:
          for (int i1 = 0; i1 < SIZE; i1 = i1 + 2 * width) {
              // Try to merge two sorted subarrays:
              // A[i1..i1+width-1] and A[i1+width..i1+2*width-1] to temp[i1..2*width-1]
              int i2 = i1 + width;
              int i3 = i1 + 2*width;
              // Don't go beyond the length of the array.
              if(i2 >= SIZE) i2 = SIZE;
              if(i3 >= SIZE) i3 = SIZE;
              merge(A, i1, i2, i3, temp);
          }
  
          // Copy temp[] back to A[] for next iteration
      copy:
          for(int i = 0; i < SIZE; i++) {
              A[i] = temp[i];
          }
      }
  }
  
  