5. OpenCLでI/O叩く
Altera の I/O チャネルが用意されてる
HDL 側のレジスタに OpenCL で値を出力→ LED へ
データムーバができれば,後は何とかなりそう
OpenCL
Kernel
Register
FIFO
LED
CPU
Main Memory
ドキュメントを参考に,
OpenCL コードとボード定義を作ってみる
6. I/OチャネルでI/Oする
OpenCL のコード.読んだり書いたり.
channel uint inCtrlCh __attribute__ (( io (” aux_ctrl_in ” ) ) ) ;
channel uint outCtrlCh __attribute__ (( io (”aux_ctrl_out” ) ) ) ;
channel uint inDataCh __attribute__ (( io (”aux_data_in” ) ) ) ;
channel uint outDataCh __attribute__ (( io (”aux_data_out” ) ) ) ;
__kernel void ctrl_write_read ( int a ,
__global int * r e s t r i c t b ){
write_channel_altera ( outCtrlCh , a ) ;
*b = read_channel_altera ( inCtrlCh ) ;
}
__kernel void data_write_read ( __global int * r e s t r i c t a ,
__global int * r e s t r i c t b ){
for ( int i = 0; i < 256; i++){
write_channel_altera (outDataCh , a [ i ] ) ;
b [ i ] = read_channel_altera ( inDataCh ) ;
}
}
12. カメラ画像取得 - 取得するだけ
__kernel
void ov7670_capture ( __global unsigned int * r e s t r i c t buf ){
const int s i z e = 320 * 480;
for ( int i = 0; i < s i z e ; i++){
int d = read_channel_altera ( inDataCh ) ;
buf [ i ] = d ;
}
}
Y0UY1V の順でデータを書き出す
YUV->RGB はソフトウェアで変換
13. カメラ画像取得 - 取得しつつRGBに
#define RANGE(x) (x < 16 ? 16 : x > 235 ? 235 : x)
__kernel void ov7670_capture ( __global unsigned char * r e s t r i c t buf ){
const int s i z e = 320 * 480;
for ( int i = 0; i < s i z e ; i++){
int d = read_channel_altera ( inDataCh ) ;
int y0 = (d >> 24) & 0x000000FF ;
int cb = (d >> 16) & 0x000000FF ;
int y1 = (d >> 8) & 0x000000FF ;
int cr = (d >> 0) & 0x000000FF ;
int r0 , g0 , b0 ;
r0 = y0+140750*(cr −128)/100000;
g0 = y0− 34550*(cb−128)/100000−71690*(cr −128)/100000;
b0 = y0+177900*(cb −128)/100000;
int r1 , g1 , b1 ;
. . .
int ptr ;
ptr = 3*(640*480−1−(2* i ) ) ;
buf [ ptr +0] = ( unsigned char )(RANGE(b0 ) ) ;
buf [ ptr +1] = ( unsigned char )(RANGE(g0 ) ) ;
buf [ ptr +2] = ( unsigned char )(RANGE( r0 ) ) ;
ptr = 3*(640*480−1−(2* i +1));
. . .
}
}
19. コードの例
test/dot-product.kfc
; ; Dense dot product between two vectors .
(module
( define (main)
( l e t ((X ( vector 1 2 3 4))
(Y ( vector 4 3 2 1)))
( l e t (( dot ( reduce + ( kernel (( x X) (y Y))
(* x y ) ) ) ) )
( p r i n t l n dot )
( assert (= dot 20))
0))))
コンパイル
./ harlanc −g −v test /dot−product . kfc