磯野ー! SoC FPGAやろうぜ！


#はじめに
* [SoC FPGA](http://www.elsena.co.jp/elspear/altera/device/soc/)の魅力を書きます.
* この記事は,私の経験からなる勘違いで構成されております.
* Xilinxはやったことないので,Alteraについてだけ書きます.

注)この記事を読んでもFPGAが出来るようになりません.

#FPGAについて

#[SoC FPGA](https://www.altera.co.jp/products/soc/overview.html)が素晴らしい理由
**SoC FPGA**は,1チップ内に**FPGA**と**ARM Cortex-A9**を搭載しています.

![image_43_thumb.jpg](https://qiita-image-store.s3.amazonaws.com/0/97833/adb6883e-6829-f134-cb4d-fabb5ea5f116.jpeg)

[DE1-SoC FPGA](http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&No=836)
Terasic社のDE1-SoC FPGA Board $249(12月1日)

[DE0-nano-SoC](http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&No=941)
Terasic社のDE0-nano-SoC Board $99(12月1日)

素晴らしい理由

* SD Cardから**Linux OS**をブート出来る!(ラズパイ感覚で)
* [HPS](https://www.altera.co.jp/products/fpga/features/cyv-soc-hps.html) IPコアで**FPGA**と**ARM**で**DRR3メモリを共有**出来る!!(最近できた)
* FPGAは**並列処理**や**パイプライン処理**が得意(CPUには不得意)
* FPGA側は**ソフトウェアCPU(NIOS)**が積める(マイコン的逐次処理が可能)
* **1ボード**内でOSのある高速処理システムが完成する
* 省エネ小スペースでロボットに乗せ易い

**...つまり最強!!!**(雑な説明)

1チップ(ボード)で**OSのある組込みシステム**を構築することが出来ます.
従来のFPGA+CPU(OSあり)のシステムは,FPGAボードを[PCI Express](https://ja.wikipedia.org/wiki/PCI_Express)経由で通信していました.SoC FPGAは,チップ内でそれが完結している感じです.さらに**ソフトとハードの分担**が切り分けやりやすい(卒研体験談).FPGAとARM(Linux)で切り分けできて,お互い何してるか分からなくてもシステム構築が出来る.ソフトとハードの開発者が共有する情報は,**メモリマップ**と**レジスタの作用**だけで出来ます.

#SoC FPGAの設計フロー

　　　[Qsys](https://www.altera.co.jp/products/design-software/fpga-design/quartus-prime/quartus-ii-subscription-edition/qts-qsys.html)でシステム設計
　　　　　　　↓
　[Quartus](https://www.altera.co.jp/products/design-software/fpga-design/quartus-prime/overview.html)で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コア](https://ja.wikipedia.org/wiki/IP%E3%82%B3%E3%82%A2)を配置してシステム設計を行います.
画像で一例を示します.(クリックして拡大して見てください)



![hps3.png](https://qiita-image-store.s3.amazonaws.com/0/97833/3ecb6e24-4a0c-7377-8c41-618c3e566999.png)
Qsys画像1
![hps4.png](https://qiita-image-store.s3.amazonaws.com/0/97833/cf5b918c-9cf5-c490-d9d5-3b011508d295.png)
Qsys画像2

このツールで配置してコネックションをクリックして作って行きます.
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にアクセスするプログラム例を貼ります.

```c
#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ってことになります.

```c
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のサポート**がないボードもお勧めしません.