FuseSoC 入門 ~オープンソースの System on Chip を作る！~

ども、ねっぽです。

FPGA開発をしてると、CPUが欲しくなる場合があると思います。
最近であれば Zynq 等のARM入り SoC (System on Chip) が主流になってきていますが、
CPUなしの素のFPGAしか手元にない場合は、ソフトコアCPUが選択肢になると思います。

ソフトコアCPUといえば、Altera の NiosII や Xillinx の Microbraze が有名ですが、
それ以外の選択肢としてオープンソースのソフトコアCPU IPを使って、完全フリーな環境を
構築したいとします。

御存知の通り、CPU はそれ単体では役に立たず、周辺にメモリコントローラや入出力など
様々なペリフェラルを結合して、システムとして成立させなければ意味がありません。
オープンソースのコアを使うので、FPGAメーカーの出来合いシステムは使えないということで
自分でシステムを構築する必要があります。

そんな時に役に立つのが、 [FuseSoC](https://github.com/olofk/fusesoc) です。
これは、SoC界の apt/pacman/yum/etc., つまりパッケージ管理システムという位置づけです。

## FuseSoc のインストール
FuseSoC は Python で書かれたツールであり、pip でインストールできます。

```shell-session
$ pip install fusesoc
Collecting fusesoc
Requirement already satisfied: simplesat>=0.8.0 in /home/yasu/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages (from fusesoc)
Requirement already satisfied: ipyxact>=0.2.3 in /home/yasu/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages (from fusesoc)
Requirement already satisfied: okonomiyaki>=0.16.6 in /home/yasu/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages (from simplesat>=0.8.0->fusesoc)
Requirement already satisfied: six>=1.10.0 in /home/yasu/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages (from simplesat>=0.8.0->fusesoc)
Requirement already satisfied: attrs>=16.1.0 in /home/yasu/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages (from simplesat>=0.8.0->fusesoc)
Requirement already satisfied: pyyaml in /home/yasu/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages (from ipyxact>=0.2.3->fusesoc)
Requirement already satisfied: zipfile2>=0.0.12 in /home/yasu/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages (from okonomiyaki>=0.16.6->simplesat>=0.8.0->fusesoc)
Requirement already satisfied: jsonschema>=2.5.1 in /home/yasu/.pyenv/versions/anaconda3-4.1.1/lib/python3.5/site-packages (from okonomiyaki>=0.16.6->simplesat>=0.8.0->fusesoc)
Installing collected packages: fusesoc
Successfully installed fusesoc-1.7
```

pip でインストールしたら、チップの定義などのインストールをします。

```shell-session
$ fusesoc init
Directory to use for orpsoc-cores (old base library) [/home/yasu/.local/share/fusesoc/orpsoc-cores] :
INFO: Initializing orpsoc-cores
Cloning into '/home/yasu/.local/share/fusesoc/orpsoc-cores'...
remote: Counting objects: 2910, done.
remote: Total 2910 (delta 0), reused 0 (delta 0), pack-reused 2909
Receiving objects: 100% (2910/2910), 3.04 MiB | 1.14 MiB/s, done.
Resolving deltas: 100% (1348/1348), done.
Checking connectivity... done.
Directory to use for fusesoc-cores (new base library) [/home/yasu/.local/share/fusesoc/fusesoc-cores] :
INFO: Initializing fusesoc-cores
Cloning into '/home/yasu/.local/share/fusesoc/fusesoc-cores'...
remote: Counting objects: 187, done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 187 (delta 13), reused 30 (delta 10), pack-reused 150
Receiving objects: 100% (187/187), 29.77 KiB | 0 bytes/s, done.
Resolving deltas: 100% (60/60), done.
Checking connectivity... done.
INFO: Writing configuration file to '/home/yasu/.config/fusesoc/fusesoc.conf'
INFO: FuseSoC is ready to use!
```

## 適当に SoC システムをビルドしてみる
FuseSoC では、すでに幾つかのシステム、定義済みの SoC が用意されています。
用意されている SoC のリストは、 `$ fusesoc list-systems` コマンドで調べられます。

```shell-session
$ fusesoc list-systems
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::elf-loader:0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::fifo:1.0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::ram_wb:0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::stream_utils:1.0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::vlog_tb_utils:0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::wb_altera_ddr_wrapper:0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::wb_intercon:1.0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::wb_intercon:0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::wb_sdram_ctrl:0
Available systems:
::nyuzi_de2_115:0
::de0_nano:0
::neek:0
::de2:0
::de1:0
::atlys:0
::sockit:0
```

とりあえず、 [DE0-nano](http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&No=593) 向けにシステムをビルドしてみます。
`$ fusesoc build` でビルドできるようです。

```shell-session
$ fusesoc build de0_nano
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::elf-loader:0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::fifo:1.0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::ram_wb:0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::stream_utils:1.0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::vlog_tb_utils:0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::wb_altera_ddr_wrapper:0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::wb_intercon:1.0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::wb_intercon:0
WARNING: plusargs section is deprecated and will not be parsed by FuseSoC. Please migrate to parameters in ::wb_sdram_ctrl:0
INFO: Preparing ::adv_debug_sys:3.1.0
INFO: Downloading olofk/adv_debug_sys from github
INFO: Preparing ::altera_virtual_jtag:1.0
INFO: Checking out https://raw.githubusercontent.com/fusesoc/tiny-cores/2353a67ee0e51e3d458eb7bc71a8e1d06438a31c/altera_virtual_jtag/altera_virtual_jtag.v to /home/yasu/.cache/fusesoc/altera_virtual_jtag_1.0
INFO: Preparing ::gpio:1.0
INFO: Checking out https://raw.githubusercontent.com/fusesoc/tiny-cores/2353a67ee0e51e3d458eb7bc71a8e1d06438a31c/gpio/gpio.v to /home/yasu/.cache/fusesoc/gpio_1.0
INFO: Preparing ::i2c:1.13
INFO: Downloading olofk/i2c from github
INFO: Preparing ::jtag_tap:1.13
INFO: Downloading olofk/jtag from github
INFO: Preparing ::mor1kx:3.1
INFO: Downloading openrisc/mor1kx from github
INFO: Preparing ::or1k_bootloaders:0.9
INFO: Downloading olofk/or1k_bootloaders from github
INFO: Preparing ::simple_spi:1.6
INFO: Downloading olofk/simple_spi from github
INFO: Preparing ::uart16550:1.5.4
INFO: Downloading olofk/uart16550 from github
INFO: Preparing ::verilog-arbiter:0-r1
INFO: Downloading bmartini/verilog-arbiter from github
INFO: Preparing ::verilog_utils:0
INFO: Preparing ::wb_common:1.0.1
INFO: Downloading fusesoc/wb_common from github
INFO: Preparing ::wb_sdram_ctrl:0-r2
INFO: Downloading stffrdhrn/wb_sdram_ctrl from github
INFO: Preparing ::wb_intercon:1.0
INFO: Downloading olofk/wb_intercon from github
INFO: Preparing ::wb_ram:1.0
INFO: Preparing ::de0_nano:0

INFO: Running /home/yasu/build/de0_nano_0/src/de0_nano_0/legacy_symlink.sh
/home/yasu/build/src/de0_nano
/home/yasu/build/src/de0_nano_0
quartus_sh  -t de0_nano_0.tcl
make: quartus_sh: Command not found
Makefile:7: recipe for target 'project' failed
make: *** [project] Error 127
ERROR: Failed to build FPGA : "make" exited with an error code.
ERROR: See stderr for details.
```

ああ、Quartus を入れていなかった！
というわけで、今回はここで終了となります。
便利そうな雰囲気が伝わったかと思うので、続きは別途書いていきたいと思います。
やりたいことは、次のようなところです。

* 自分のシステム(手持ちのボードだと、Altera DE0 向け)を定義する
* 自分のシステムをビルドする
* 自分のシステムを動かしてみる

残念ながら FuseSoC には英語含めてドキュメントがあまりないので、雰囲気で試行錯誤せざるを得ません。
そこで、今回私が試行錯誤した結果を残すことで、少しでも FuseSoC が盛り上がると幸いです。