Hi Mark,
Thanks for your questions. I agree that we need documentation for your questions - they are asked quite often and aren't immediately clear or at all obvious in some cases. We'll get on it.
As for the configuration file: the format is pretty simple. The types of partitioning are explained
here. We directly used the terminology from Vivado HLS in this case.
The format of the partition lines are:
partition,cyclic,array_name,array_size_in_bytes,element_size_in_bytes,partition_factor
partition,block,array_name,array_size_in_bytes,element_size_in_bytes,partition_factor
partition,complete,array_name,array_size_in_bytes,element_size_in_bytes
so, as an example, an array declared like int myarray[32] would have array_size_in_bytes = 32*4 = 128, element_size_in_bytes=4, and partition_factor whatever you wanted it to be (generally pick a power of 2).
The loop unrolling/pipelining lines are also pretty simple - the first term describes what you want to do. Again, see
here for details.
unrolling,function_name,loop_label,unrolling_factor
flatten,function_name,loop_label
pipeline,function_name,loop_label
Keep in mind that even if you don't want to unroll a loop (i.e. loop unrolling factor = 1), it MUST be specified as so in the cfg file, or Aladdin will actually flatten the loop by default due to the way it constructs the initial DDG.
Your array address ranges: that means that two arrays detected by Aladdin overlap in their base address + size. You'll want to be careful if you are accessing one of those two arrays. The base address is the actual virtual address of that pointer when you were building the trace.
As for your mysterious variable names: if you see strange names like ".01", "someword.somenumber", etc, which don't appear in your code, those are LLVM's autogenerated register names. This is because of an Aladdin coding style restriction: you cannot assign a pointer to another variable and dereference it via that variable, or Aladdin won't be able to associate the original array name (which has an SRAM structure backing it) to that memory access. As an example:
void foo(int* array) {
int value = array[1]; // this is OK.
int offset = /* some value */;
value = array[offset + 4]; // this is OK.
int* newptr = array;
value = newptr[1]; // NOT OK. this may cause LLVM to generate a temporary variable with an arbitrary name that you're seeing.
int* newptr2 = array + 4;
value = newptr2[4]; // NOT OK. same reason here.
}
void bar(int* myarray) {
foo(myarray); // this is OK: aladdin knows that myarray in function bar == array in function foo.
foo(&myarray[4]); // NOT OK; Aladdin will not be able to resolve memory accesses in foo() correctly. you would need to pass 4 as an separate function argument.
}
So in short: all memory operations within a function that is being turned into HW must be based from the original pointer that was passed to the top level function.
Sam