なんか,まわりでFPGA+SoCな環境はZynq一色なのですが,Atlas-SoCで遊んでみる準備をしてみました.
Atlas-SoCが何かについては,Atlas-SoC素晴らしいんじゃないのが分かりやすいです.
Xilinxにおける(最近はAlteraにも対応しているけど)Xillinux的な便利な環境という感じ.
で,開封して動かしはじめるまでは,すぐなのだけど,
自分のハードウェアを動かすにはどうするの?というところが分からないと遊びはじめられません.
公式サイトRocketBoards.orgをみながら進めてみたものの,いくつかのポイントでハマったりつまづいたりしたのでメモです.
まずは合成
Linuxはgccも入ったすばらしい環境だったので,そのまま使うことにしてハードウェア部分だけ変更できればいいかな,という方針.まずはサンプルと同じものを合成する,というところからはじめたいのですが...
準備
公式サイトのCompiling Hardware Design and Preloaderに手順がありますので,これに従います.環境は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のまま.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.一番最後の回答に示されているURLを辿ってみると,答えがWhy can't I create and HPS instance with qsys-script?にありました.
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でもちゃんと使えることが実験的に確認できました.