IO信号の合成
IO信号は引数から生成される。引数にハンドシェーク信号(vld,ack)を付けるにはpragmaで指定する。
複数回の入出力は固定回なら配列で書けるが任意回ならstreamクラスが用意されている。
引数 |
IO信号 |
値 x |
1回の入力 |
ポインタ *x |
1回の出力 |
配列 x[N] |
N回の入力または出力 インデックス0から順に参照・代入する必要がある |
hls::stream<型> &x |
任意回の入力または出力(ストリーム入出力) 1回あたりの入力はval = x.read() 1回あたりの出力はx.write(val)と書く (注)val << xやx<< valという書き方もあるが混在させない方がよい |
◇
配列は、1個ずつN回の入出力でなくN個1回の入出力(パラレルポート) にすることもできる。
例) パラレルポート32bit = 4個x 8bit
Cコード |
合成後のRTL記述 |
void dut (... ,ap_uint<8> din[4] // (i) ... ) { #pragma HLS array_reshape variable=din complete |
module dut(... ,input[31:0] din ... );
|
array_reshape variable=din completeと指定すると、配列dinは各要素を並べた1つのパラレルポートと見なされる。
din[31:0]={din[3],din[2],din[1],din[0]}
SystemVerilogのpacked型で書けばinput[3:0][7:0] dinの意味になる。
ちなみにarray_reshapeでなくarray_partitionと指定すると各要素が独立なポートと見なされてしまう。つまり各々にハンドシェーク信号がついてしまう。
input[7:0] din_0
input[7:0] din_1
input[7:0] din_2
input[7:0] din_3
◇◇
複数の引数を構造体にまとめて1つのパラレルポート にすることもできる。
例) パラレルポート12bit = 4bit + 8bit
Cコード |
合成後のRTL記述 |
typedef struct { ap_uint<8> x; ap_uint<4> y; } din_t; void dut (... ,din_t din // (i) ... ) { #pragma HLS aggregate variable=din compact=bit |
module dut(... ,input[11:0] din ... );
|
aggregate variable=din と指定すると、構造体dinは各要素を並べた1つのパラレルポートと見なされる。
din [11:0]={y[3:0],x[7:0]}
指定しないと独立なポートとみなされ、各々にハンドシェーク信号がついてしまう。