#はじめに
- SoC FPGAの魅力を書きます.
- この記事は,私の経験からなる勘違いで構成されております.
- Xilinxはやったことないので,Alteraについてだけ書きます.
注)この記事を読んでもFPGAが出来るようになりません.
#FPGAについて
#SoC FPGAが素晴らしい理由
SoC FPGAは,1チップ内にFPGAとARM Cortex-A9を搭載しています.
DE1-SoC FPGA
Terasic社のDE1-SoC FPGA Board $249(12月1日)
DE0-nano-SoC
Terasic社のDE0-nano-SoC Board $99(12月1日)
素晴らしい理由
- SD CardからLinux OSをブート出来る!(ラズパイ感覚で)
- HPS IPコアでFPGAとARMでDRR3メモリを共有出来る!!(最近できた)
- FPGAは並列処理やパイプライン処理が得意(CPUには不得意)
- FPGA側は**ソフトウェアCPU(NIOS)**が積める(マイコン的逐次処理が可能)
- 1ボード内でOSのある高速処理システムが完成する
- 省エネ小スペースでロボットに乗せ易い
...つまり最強!!!(雑な説明)
1チップ(ボード)でOSのある組込みシステムを構築することが出来ます.
従来のFPGA+CPU(OSあり)のシステムは,FPGAボードをPCI Express経由で通信していました.SoC FPGAは,チップ内でそれが完結している感じです.さらにソフトとハードの分担が切り分けやりやすい(卒研体験談).FPGAとARM(Linux)で切り分けできて,お互い何してるか分からなくてもシステム構築が出来る.ソフトとハードの開発者が共有する情報は,メモリマップとレジスタの作用だけで出来ます.
#SoC FPGAの設計フロー
Qsysでシステム設計
↓
QuartusでHDLを用いて接続を記述
↓
EclipseでNIOS CPUのプログラム記述
↓
コンパイルしてSD Cardに入れるファイルを生成
↓
SD CardにOSのImageファイルやFPGAの回路情報のファイルを入れる
↓
起動!!!
↓
Linuxは,mmapでFPGAのレジスタにアクセス
SoCFPGAは,ブートする時にFPGAの回路が書き込まれます.
起動したら,プログラムを書くだけって感じです.
OSがあれば,USBでもEthernetでもライブラリでも好き放題出来ると思います.
以下でもう少し説明します.
雰囲気だけ伝えるように説明するので,適当に見てください.
Linux側は,みんな知ってるってことで今回は説明しません.
べっ別に全く分からない訳じゃないないんだからねΣ(´∀`||;)ドキッ!!(1mmもまだ触ってないなんて言えない
#Qsysでシステム設計
Qsysでは,Alteraが予め用意されているIPコアを配置してシステム設計を行います.
画像で一例を示します.(クリックして拡大して見てください)
このツールで配置してコネックションをクリックして作って行きます.
Exportの欄が黒い所はQuartusの方で接続先をHDL記述出来て実際のピンに割り当てることが出来ます.Qsysは,Avalon bus規格にしたがってHDLで自作モジュールを設計して登録することで,IPコアとして使えるようになります.
(メモリマップのアドレスの見方)
メモリマップのアドレスは16進数のバイト数で表示されています.
例)ram_mainは24576 bytesでパラメータ指定しています.
24576は16進数で5fff
よって1_0000~1_5fffのアドレス範囲になります.
#Quartusで接続を記述
ここでは,HDL言語を用いて設計します.馴染みがない人が多いと思うので簡単に説明するとPWMとかUARTとかのハードウェアをプログラムで設計することができます.QsysにあるIPコアもHDL言語で出来ています.QuartusでHDL記述してCPUに接続する場合とQsysでコンポーネントとして登録してCPUに接続する2パターンで設計出来ます.使い回したいコンポーネントは,Qsysで登録すると設計速度が向上します.Pin Planner Editorで,HDL記述のinputとoutputピンを実際のピンに割り当てします.
#EclipseでNIOSのプログラムを記述
この工程は,皆さんが知ってるマイコンでプログラムを書く工程と同じです.
NIOSとDMAでDDR3 SDRAMにアクセスするプログラム例を貼ります.
#include <stdio.h>
#include <stdlib.h>
#include "system.h"
#include <io.h>
int main()
{
void* tx_address = RAM1_BASE;
void* rx_address = 0x20000000; //DDR3 SDRAM top address
IOWR(DMA_BASE,6,0); // stop dma component
IOWR(DMA_BASE,0,0x0); // clear Stauts registe
int i;
for(i=0;i<16;i++){
IOWR_32DIRECT(RAM1_BASE,i*4,i); //4byte 16words
}
while(1){
if(IORD_32DIRECT(DIPSW_PIO_BASE,0) == 0x1){
IOWR(DMA_BASE,1,tx_address); // set source address
IOWR(DMA_BASE,2,rx_address); // set destination address
IOWR(DMA_BASE,3,4*16); // set bytes to transfer 4byte 16words
IOWR(DMA_BASE,6,0x8C); // start dma transfer (word mode)
while(!(IORD(DMA_BASE,0) & (1 << 0) == 1)); //transfer length 0 end
IOWR(DMA_BASE,6,0); // stop dma component
IOWR(DMA_BASE,0,0x0); // clear Stauts registe
}
}
return 0;
}
このプログラムはDIPSWが1になった時に,ram1からddr3へ32bit 16wordsのデータを転送しています.
DMA_BASEなどは,system.hで定義されています.
定義されている値は,Qsysに表示されているアドレスと同じです.上の画像で言うと,DMA_BASEは0x2000ってことになります.
IOWR_32DIRECT(addresss,offset,data); //write関数
IORD_32DIRECT(address,offset); //read関数 戻り値あり
この関数は32bitアクセスでNIOSのデータバスに接続されているIPコアのレジスタ(レジスタのアドレスはaddress+offset)にread/write出来ます(io.hに定義されていて16,8 bitの関数もあります).ちなみにポインタでもアクセス出来ます.
#おわりや補足
最後まで読んでもあまり分からなかったと思います.
世の中にはSoC FPGAって物があるんだなぁ~って程度でいいです.
SoC FPGAは,低レイヤから高レイヤまで自分でカスタム出来るのですごく楽しいと思います.CPU自作からGUIアプリケーションまで設計出来ます.まだまだ魅力や説明がちゃんと伝わってないと思うので興味がわいた人は直接聞いてください.
###使いどころ
ラズパイ+マイコンの組み合わせも手軽でいいですが,画像処理みたいなデータの転送や処理をする場合はSoC FPGAがお勧めです(Gbpsの通信が可能).
###購入注意点
注)HPS IPコアの設定は,ボードによってパラメータが異なります.DDRメモリなどのチップの仕様で設定するパラメータ異なるためです.DDRメモリを使いたい場合は,ボードメーカーが公開しているサンプルプロジェクトを使うことをお勧めします.サンプルや情報が少ないボードはお勧めしません.OSのサポートがないボードもお勧めしません.