まずは、SDSoCのpragmaでメモリ(主に配列)がどのように展開されるかを実験してみた。
実験は次のソースコードを対象とする。
#include <stdio.h>
#include <stdlib.h>
#define SIZE (256)
int MemTest(
char MemInA[SIZE],
char MemInB[SIZE],
char MemOut[SIZE]
)
{
int i;
for(i = 0; i < SIZE; i++){
MemOut[i] = MemInA[i] * MemInB[i];
}
return 0;
}
int main(){
int i;
char MemInA[SIZE], MemInB[SIZE], MemOut[SIZE];
FILE *fp = fopen("test.dat", "r");
fread(MemInA, sizeof(char) * SIZE, 1, fp);
fread(MemInB, sizeof(char) * SIZE, 1, fp);
fclose(fp);
MemTest(
MemInA,
MemInB,
MemOut
);
for(i = 0; i< SIZE; ++i){
printf("%d: %d\n", i, MemOut[i]);
}
return 0;
}
実験対象のソースコードにPHYSICAL_CONTIGUOUSを適用した。
#pragma SDS data mem_attribute(MemInA:PHYSICAL_CONTIGUOUS)
#pragma SDS data mem_attribute(MemInB:PHYSICAL_CONTIGUOUS)
#pragma SDS data mem_attribute(MemOut:PHYSICAL_CONTIGUOUS)
まず、これを基準に比較してみよう。
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|DSP | -| -| -| -|
|Expression | -| 0| 0| 70|
|FIFO | -| -| -| -|
|Instance | -| -| -| -|
|Memory | -| -| -| -|
|Multiplexer | -| -| -| 36|
|Register | -| -| 39| -|
+-----------------+---------+-------+-------+-------+
|Total | 0| 0| 39| 106|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 0| 0| ~0 | ~0 |
+-----------------+---------+-------+-------+-------+
sizeof(char) * 256wordなので256Byte = 2,048bit
どこに2,048bitが隠れた?
#define SIZE (512)
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|DSP | -| -| -| -|
|Expression | -| 0| 0| 71|
|FIFO | -| -| -| -|
|Instance | -| -| -| -|
|Memory | -| -| -| -|
|Multiplexer | -| -| -| 36|
|Register | -| -| 42| -|
+-----------------+---------+-------+-------+-------+
|Total | 0| 0| 42| 107|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 0| 0| ~0 | ~0 |
+-----------------+---------+-------+-------+-------+
256Byteと比較するとFFとLUTが若干増えたけど、256Byte同じく、4,096bitはどこに隠れた?
#define SIZE (1024)
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|DSP | -| -| -| -|
|Expression | -| 0| 0| 72|
|FIFO | -| -| -| -|
|Instance | -| -| -| -|
|Memory | -| -| -| -|
|Multiplexer | -| -| -| 36|
|Register | -| -| 45| -|
+-----------------+---------+-------+-------+-------+
|Total | 0| 0| 45| 108|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 0| 0| ~0 | ~0 |
+-----------------+---------+-------+-------+-------+
4kbit増えてるんだけど、本当にこれでいいの?
#define SIZE (2048)
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|DSP | -| -| -| -|
|Expression | -| 0| 0| 73|
|FIFO | -| -| -| -|
|Instance | -| -| -| -|
|Memory | -| -| -| -|
|Multiplexer | -| -| -| 36|
|Register | -| -| 48| -|
+-----------------+---------+-------+-------+-------+
|Total | 0| 0| 48| 109|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 0| 0| ~0 | ~0 |
+-----------------+---------+-------+-------+-------+
ホント、bitはどこに消えたの?
#define SIZE (4096)
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|DSP | -| -| -| -|
|Expression | -| 0| 0| 74|
|FIFO | -| -| -| -|
|Instance | -| -| -| -|
|Memory | -| -| -| -|
|Multiplexer | -| -| -| 36|
|Register | -| -| 51| -|
+-----------------+---------+-------+-------+-------+
|Total | 0| 0| 51| 110|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 0| 0| ~0 | ~0 |
+-----------------+---------+-------+-------+-------+
やべ、なんかもう信用できないサイズになってきた。
#define SIZE (16384)
+-----------------+---------+-------+-------+-------+
| Name | BRAM_18K| DSP48E| FF | LUT |
+-----------------+---------+-------+-------+-------+
|DSP | -| -| -| -|
|Expression | -| 0| 0| 76|
|FIFO | -| -| -| -|
|Instance | -| -| -| -|
|Memory | -| -| -| -|
|Multiplexer | -| -| -| 36|
|Register | -| -| 57| -|
+-----------------+---------+-------+-------+-------+
|Total | 0| 0| 57| 112|
+-----------------+---------+-------+-------+-------+
|Available | 120| 80| 35200| 17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%) | 0| 0| ~0 | ~0 |
+-----------------+---------+-------+-------+-------+
マジでどこに消えたの?
#define SIZE (16385)
これはエラーになった。
ERROR: [CF2XD 83-2235] Invalid array size (16385) for bram port 'MemInA_PORTA' on component 'MemTest_1'
ERROR: [CF2XD 83-2239] failed to create xd_adapter for accelerator comp MemTest_1
ERROR: [CF2XD 83-2110] An error has occurred reading the system description file apsys_0.xml. If targeting a custom platform or hardware library, ensure that hardware function mappings accurately map software function prototypes to IP port interfaces and register offsets. Please consult the log files in _sds/reports for additional ERROR messages. You may find it helpful to run sdscc with the '-verbose' option.
ERROR: [SystemLinker 83-4806] Exiting system_linker: Error when calling '/opt/Xilinx/SDx/2017.1/bin/cf2xd -i apsys_0.xml -o top.xml -r /home/hidemi/workspace/sdsocCNN/MemTest0_6/Debug/_sds/.cdb/xd_ip_db.xml -trace-buffer 1024 -mc '
ERROR: [SdsCompiler 83-5019] Exiting sds++ : Error when calling '/opt/Xilinx/SDx/2017.1/bin/system_linker -cf-input /home/hidemi/workspace/sdsocCNN/MemTest0_6/Debug/_sds/.llvm/apsys_0.xml -cf-output-dir _sds/p0 -ip-db /home/hidemi/workspace/sdsocCNN/MemTest0_6/Debug/_sds/.cdb/xd_ip_db.xml -ip-repo /home/hidemi/workspace/sdsocCNN/MemTest0_6/Debug/_sds/iprepo/repo -sds-pf /opt/Xilinx/SDx/2017.1/platforms/zybo:linux -sds-sys-config linux -sds-proc a9_0 -software-only -target-os linux -trace-buffer 1024 -sdsoc '
sds++ log file saved as /home/hidemi/workspace/sdsocCNN/MemTest0_6/Debug/_sds/reports/sds.log
ERROR: [SdsCompiler 83-5004] Build failed
make: *** [MemTest0_6.elf] Error 1
makefile:45: recipe for target 'MemTest0_6.elf' failed
ちょっと待て!
16,384wordまでBRAMを使用しなかったくせに、16,385wordになったらBRAMを使うの?
急に?
BRAM使ってないんだからエラーにすんなよ。
マニュアルにもBRAMの深さは16,384が最大で・・・と、書いてのと、16,384までBRAMに割り振られなかったのでFFで対応しているのかと思ってたんだけど・・・
もしかして、配列の深さが16,384を超えるとエラーなだけ?