Atlas-SoCで遊んでみる準備をした

なんか，まわりでFPGA+SoCな環境はZynq一色なのですが，Atlas-SoCで遊んでみる準備をしてみました．
Atlas-SoCが何かについては，[Atlas-SoC素晴らしいんじゃないの](http://qiita.com/yukitaketake/items/96f9fd8607cc1f3c8e7c)が分かりやすいです．
Xilinxにおける(最近はAlteraにも対応しているけど)Xillinux的な便利な環境という感じ．

で，開封して動かしはじめるまでは，すぐなのだけど，
自分のハードウェアを動かすにはどうするの？というところが分からないと遊びはじめられません．

公式サイト[RocketBoards.org](http://rocketboards.org/)をみながら進めてみたものの，いくつかのポイントでハマったりつまづいたりしたのでメモです．

# まずは合成
Linuxはgccも入ったすばらしい環境だったので，そのまま使うことにしてハードウェア部分だけ変更できればいいかな，という方針．まずはサンプルと同じものを合成する，というところからはじめたいのですが...

## 準備
公式サイトの[Compiling Hardware Design and Preloader](http://rocketboards.org/foswiki/view/Documentation/AtlasSoCCompileHardwareDesign)に手順がありますので，これに従います．環境はQuartusII 15.0.2 WebEdtion + SoC EDS 15.0.1，OSはCentOS 7.1です．

### CentOS7でSoC EDSを使う
そういえば，私，SoC EDSが，"はじめまして"でした．Linuxの場合

```
 export SOCEDS_DEST_ROOT=/opt/Altera/15.0/embedded
 source /opt/Altera/15.0/embedded/env.sh
```

で各種ツールへの環境変数をセットできます．

### Procedureに従ってソース一式をダウンロード
これは，公式の手順[Compiling Hardware Design and Preloader - 3. Procedure](http://rocketboards.org/foswiki/view/Documentation/AtlasSoCCompileHardwareDesign#3)のまま．wgetして展開すればOKです．

## ビルド

```
make all
```

でビルド...できませんでした．

### ビルドできない理由(1) - StratixVなデバイス情報が必要
makeスクリプト内部では，Qsysプロジェクトを作成→必要なIPのインスタンス生成→IPの接続，SoCのビルド→QuartusIIで合成→...という処理が自動的に進行するはずなのですが，altera_hps(ARMのHW IP)をQsysでインスタンシエーションする時に固まってしまいます．で調べてみると，AlteraのForumでも同じ苦しみを味わっている方が[Generating a Qsys System with qsys-script](http://www.alteraforum.com/forum/archive/index.php/t-46837.html)．一番最後の回答に示されているURLを辿ってみると，答えが[Why can't I create and HPS instance with qsys-script?](https://www.altera.com/support/support-resources/knowledge-base/solutions/rd05082015_486.html)にありました．

Stratixのデバイスパッケージをインストールしてね

ってことらしいのですが，WebEditionにはStratixのデバイスパッケージはインストールできません．仕方がないので，デバイスパッケージ(qdz)を手動で追加．qdzは単なるzipファイルなので，

```
 cd /opt/Altera/15.0/
 unzip stratixv-15.0.0.145.qdz
```

と展開しました．

### ビルドできない理由(2) - 時限付きのIPコアにより想定外のsofファイルが生成される
サンプルのハードウェアはFFTをFPGAにオフロードできるようになっている(と思われる)のですが，その処理を司どるIPコアが，"OpenCore Plus feature"のために，WebEditionでは時限付きでしか利用できません．通常，QuartusIIでは合成，配置配線の結果としてFPGA用のビットストリーム"ほげほげ.sof"を生成するのですが，時限付きのコアを含むビットストリームでは"ほげほげ\_time_limited.sof"が生成されるようです．(具体的には，ATLAS_SOC_GHRD/output_files/ATLAS_SOC_GHRD_time_limited.sof)

Altera-SoCではHPSからFPGAをコンフィギュレーションする際に，sofから変換して作るrbfというファイルを使用するのですが，想定した"ほげほげ.sof"ができていないので，rbfが生成できなかった，といわけです．rbfは，qaurtus_cpfというツールで作るのですが，単純に"ほげほげ_time_limited.sof"を"ほげほげ.sof"に変換して胡麻化そうとしても，時限付きコアが入っていると言って受け付けてくれません...よくできてる

というわけで，fftなIPコアを使わないことにします．fftなIPコアのインスタンスを生成しているscripts/qsys_add_fft128_components.tclというスクリプトファイルを無効にすることにしました．

```
 mv scripts/qsys_add_fft128_components.tcl scripts/qsys_add_fft128_components.tcl.old

```

### make allが完了したら
以上のハックをした結果，無事make allで回路情報一式とPreloaderイメージができあがりました．

## オリジナル回路の追加
王道としては，Qsysにぶらさげることができるモジュールを作る→インスタンス生成するtclスクリプトを用意，というのがよいのでしょうが，まずは単純にLチカとかしてみたいですよね．

QsysなSoCシステムはhdl_src/ghrd_top.vというVerilogでインスタンシエーションされているにすぎませんので，ghrd_top.vをいじれば，好きなことができます．
GPIOポートの出力をLEDに接続している

```
 assign fpga_led_pio = fpga_led_internal;
```

をコメントアウトして，代わりに，

```
reg[31:0] debug_counter = 32'h0;
assign fpga_led_pio = debug_counter[22:15];
always @(posedge fpga_clk1_50)
begin
        debug_counter <= debug_counter + 1;
end
```

としてみました．make allして起動すると，無事LEDが点滅．これでハードウェアをいじるための第一ステップは完了です．

*以下，後で詳しく書く*

# HPSとFPGAのやりとり
ここまでで，好きなモジュールを組み込むためのツールの使い方は分かりました．で，好きなモジュールを実装すればいいのですが，折角なのでLinuxから制御したり，データの共有をしたりしたいですよね．

## Liteweight H2F

### /sys/class経由
気分はRaspberryPiのGPIOアクセスと同じ

### mmapする
0xff20_000

### 割込み
/sys/classを使うのが簡単です．

## H2F
64KBのRAMに接続されています．0xc0000000をmmapして読み書きできます．

RAMをデュアルポートに変更，追加したポートのアドレスにLinuxからのGPIOを，データ出力にLEDを接続．Linuxからメモリに書き込んだ値がLEDに出力されることで，Linuxからのメモリアクセスができていること，FPGAでもちゃんと使えることが実験的に確認できました．