...

MAX® 10 FPGA で学ぶ FPGA 開発入門

by user

on
Category: Documents
195

views

Report

Comments

Transcript

MAX® 10 FPGA で学ぶ FPGA 開発入門
MAX® 10 FPGAで学ぶ
FPGA開発入門
1
著者
大原 雄介
(2015 年 8 月 10 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(1)
なぜ FPGA が注目されるのか、開発ボードに触れて確認する
3
http://monoist.atmarkit.co.jp/mn/articles/1508/10/news012.html
(2015 年 9 月 10 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(2)
「MAX 10 FPGA」のテスト環境を構築する
6
http://monoist.atmarkit.co.jp/mn/articles/1509/10/news002.html
(2015 年 10 月 13 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(3)
FPGA での L チカを Verilog HDL で理解する
13
http://monoist.atmarkit.co.jp/mn/articles/1510/13/news023.html
(2015 年 11 月 13 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(4)
FPGA の LED 制御プログラムを深く理解する
16
http://monoist.atmarkit.co.jp/mn/articles/1511/13/news007.html
(2015 年 12 月 11 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(5)
よろしいならばダイナミック点灯だ――FPGA で LED をダイナミックに L チカさせる
20
http://monoist.atmarkit.co.jp/mn/articles/1512/11/news015.html
(2016 年 1 月 26 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(6)
FPGA 上でソフトコア CPU を動かす手引き
24
http://monoist.atmarkit.co.jp/mn/articles/1601/26/news007.html
(2016 年 2 月 16 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(7)
FPGA のソフトコア CPU をベンチマークで測定する
31
http://monoist.atmarkit.co.jp/mn/articles/1602/16/news034.html
(2016 年 3 月 10 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(8)
周辺機器の充実した「MAX 10 NEEK」で本格的な開発を目指す
35
http://monoist.atmarkit.co.jp/mn/articles/1603/10/news058.html
(2016 年 4 月 12 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(9)
「MAX 10 NEEK」へソフトコア CPU を組み込む
40
http://monoist.atmarkit.co.jp/mn/articles/1604/12/news085.html
(2016 年 5 月 19 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(10)
「MAX 10 NEEK」に搭載された DDR3 メモリを使う
46
http://monoist.atmarkit.co.jp/mn/articles/1605/19/news021.html
(2016 年 6 月 14 日)
MAX 10 FPGA で学ぶ FPGA 開発入門(11)
「MAX 10 NEEK」でストップウォッチを開発し、内蔵メモリから起動する
http://monoist.atmarkit.co.jp/mn/articles/1606/14/news111.html
※ すべての商標および登録商標はそれぞれの所有者に帰属します。
※ 記事は執筆時の情報に基づいており、現在では異なる場合があります。
2
53
MAX 10 FPGA で学ぶ FPGA 開発入門(1)
なぜ FPGA が注目されるのか、
開発ボードに触れて確認する
最近では「FPGA の重要性」について語られる機会が増え、適用事例も増加している。ではなぜ今 FPGA なのか。実際
の開発ボードで FPGA を学びながら、FPGA への理解を深めよう。
なぜ今、FPGAが注目されているのか
CPU の搭載
以前から MPU あるいは MCU を内蔵した製品は存在していた
個人的な感想で恐縮だが、2012 ∼ 2013 年あたりから急速に
が、昨今は Cortex-A9 コアを内蔵したものが幅広く利用されてお
FPGA の適用事例が増えてきている気がする。
り、これまで SoC + FPGA の形で構成されていたシステムを
これは 2010 年前後から、いわゆる ASIC の開発コストが急速
FPGA1 個で済ませられる様になった。またこうした CPU 内蔵
に高騰化し始め、おいそれと ASIC を作れなくなったことに加え、
FPGA の場合、CPU コアと FPGA ファブリックの連携が高速に
汎用 MPU あるいはあまり特定用途に特化しすぎていない ASSP
行えるので、トータルとしての性能も上げやすい。
(モバイル機器向け SoC などこの好例であろう)の性能が急速に
改善したと、加えて FPGA そのものが 45nm ∼ 28nm 世代に移
低価格化
行することで高性能が進んだことも無縁ではないはずだ。
高集積化の逆説的な効果でもあるが、ハイエンド FPGA は相変
この結果、従来だと ASIC で済ませていたシステムを、ASSP +
わらず高価なままである。ところが一番広く使われるミドルレンジ
FPGA などの構成で済ませることが可能になってきた。部品原価の
や、さらにその下に位置する製品についてはどんどんコストが下
面で言えばまだ ASIC に分のあることもあるが、ASIC の開発コス
がっている。その結果、FPGA とは思えないような金額で入手する
トまで勘案するとペイしなくなりつつある。であれば、多少部品原
事も可能になってきた。
価が上がっても、FPGA をシステムの中核に組み入れた方が開発コ
ストの低減や開発期間の短縮化、機能の充実や構成の柔軟な変更
例えば Lattice Semiconductor の 提 供する「iCE40 ファミ
などメリットが上回る事になる。
リー」の場合、
ゲート数(同社の用語ではロジックセル数)が 384
こうした理由で FPGA を利用したシステムデザインの増え始め
∼ 7680 と小規模だが、その代わり一番安いものはデジキーあたり
それが最終製品として世の中に出始
たのが 2009 ∼ 2010 年ごろ、
で 1 個単位で買っても 300 ∼ 400 円、ある程度の数量(1 万個
めたのが 2012 年あたりからということになる。昨今では随分
程度)だと 1 個 100 円を切る金額で入手できる。
FPGA を組み込んだ最終製品が増えてきたように思う。
同規模製品だと Microsemi の「IGLOO シリーズ」がやはり同程
度の価格帯であるし、もう少し回路規模の大きい Altera の「MAX
FPGAのトレンド
、あるいは前世代製品の「Spartan」など
10」や Xilinx の「Artix」
こうした市場の活性化や拡大に伴い、各社がさまざまな製品を
は数千円のオーダーで購入できる(調べてみたら、3840 ゲートの
頻繁にリリースしている。MONOist の FPGA コーナーを見ていた
。
Spartan 6 LX がデジキーでは 1 個 1595 円で購入可能だった)
だければ、そうした状況の一端もお分かりかと思う。ここ数年のト
こうしたローエンド製品の低価格化に加え、FPGA のマーケット
レンドで言えば、
が広がった事で各社開発ボードや評価ボードを充実させてきた事
により、「FPGA を使ってみよう」という際の敷居が急激に下がっ
FPGA の高集積化
28nm に続き、20nm プロセスを利用した製品出荷や 16/14nm
てきた感がある。なにより開発キットの値段が急激に下がった。
*ちょっと古い話だが、MONOist でも 2007 年から「触って学
プロセス向けの開発ツールのリリースなど、先端製品はどんどん微
ぼう FPGA 開発入門」という連載があり、連載で利用されていた
いろいろ新技術や新機能は入っ
細化を進めている。FPGA の場合、
のはヒューマンデータの「EDX-002」だった。ただこの製品その
ているものの基本的には SRAM の塊であって、SRAM の容量は
ものがもう通常販売が終了しており、現在は処分特価という名前の
つまるところプロセスを微細化するほど増える結果、利用できる
在庫処分が行われている状況だし、搭載されている FPGA は
ゲート数がどんどん増える事になった。
Xilinx の Spartan-II で、これもまたちょっと古すぎる。
3
「MAX 10」でFPGA開発の基礎を学ぼう
さらに安価な製品としては、Arrow が提供する「BeMicro MAX
10 評価キット」が $30.00 だが、こちらは最近でこそ供給体制が
ということで、いよいよ本題。
整ったようだが当初はちょっと入手が難しかったのでパスした。
FPGA ベンダーは各社とも新製品が出るたびに、これを利用で
ボードの上
2 つ目が拡張性。Photo01 を見てもらえれば分かるが、
きる開発キットや開発ボードをリリースしているが、通常は汎用の
に Arduino と互換のピンヘッダが用意されており、実際に Arduino
開発ボードの上に、FPGA の乗ったドーターボードを積むという形
のシールドが流用可能となっている。これについては、そもそも 2014
態が多く、ちょっと試してみようといった用途にはコストの面から適
年 9 月に国内で MAX 10 に関する説明会が開催された折、同社の
切とは言いにくいものだった。
ま
Partic Dorsey 氏(Senior Director of Product Marketing)が、
ところが Altera が 2014 年 10 月に発表した「MAX 10」の場
さにこの評価キットの上に Arduino 用の LCD シールドを搭載して動
合、当初から自社でも低価格な評価キットが用意された上、早期か
、このあたりは Arduino
作させるというデモを行っており(Photo02)
らパートナーによるやはり低価格な開発キットが提供された。
の I/O に慣れている筆者としては有難いものと判断したからだ。
Altera はさらに「MAX 10 NEEK」と呼ばれる開発キットを発
表している。こちらは MAX 10 の上で「Nios II」というソフトウェ
ア CPU を駆動し、この上でさまざまな機器を開発するためのリ
ファレンスデザインとなっており、この結果、単にチップだけではな
く 7 インチ/ 5 点タッチ認識の液晶ディスプレイと 8M ピクセルの
カメラ、HDMI 出力、温度/湿度センサー、3 軸加速度センサー、
マイクなどを搭載した、充実したキットとなっている。その分、お値
段もそれなりで直販価格は 375 USD となっているから、ちょっと
触ってみたいという用途にはやや不適当ではある。
さて、その代わりといっては何だが、MAX 10 の発売当初から予
告されていた「MAX 10 FPGA 評価キット」を使って、FPGA で
遊んでみたいと思う。
このキットを選んだ理由は幾つかある。まずは価格。$49.95 と
いうのは、FPGA 評価キットとしては飛びぬけて安い。購入は
Altera の直販サイトからもできるし、代理店(筆者は Mouser
Photo02: このデモでは、評価ボードにマイクが接続され(ボードから下にぶら下って
る赤 / 黄 / 黒の線の先にマイクがつながっている)、ここで捕らえた音量を測定して
LCD に棒グラフで表示するという簡易騒音計の実装を行ったデモである。ちなみに
USB ケーブルは電源供給のためだけに使われている
Electronics から購入した)から入手も可能だ。
Arduino 互換のシールドは多用多種存在しており、これらを使う
ピン数が足りなければ、
ボー
事で容易にデバイスを使える事になる。
ド上に用意されているピン経由で、Arduino 用に割り当てられた以
(ただ当初はとりあえず使うとい
外の MAX 10 のピンを利用できる
うレベルだから、そこまでの拡張性は必要ないだろうという気もす
るが)。
3 つ目が、FPGA 自身の拡張性である。この評価キットに搭載さ
れているのは 10M08 という製品で、ゲート(Altera の用語ではロ
ジックエレメント LE:Logic Element)数が 8K、Block Memory
が 378Kbit、User Flash が 32 ∼ 172KB、18 18 の Multiplier
が 24 個と、ローエンドにしてはなかなかな充実振りとなっている。
何をやらせるかによって 8K LE で足りる場合もあれば全然足り
ない場合もあるが、取りあえず多すぎるほどの規模である。
加えて言うなら、これだけの規模があると、同社の Nios II プロ
セッサも動作する。Nios II は同社が提供する Embedded CPU の
IP であるが、最小構成ならば 600LE で Nios II が構築可能である。
絶対性能そのもので言えば Cortex-M4 あたりのプロセッサコアを
Photo01: ボード上のロゴから分かる通り、ボード設計そのものが aXelsys が行った
模様。パッケージはこの基板と USB ケーブル、それと ( 平置き用の ) ゴム足のみの
シンプルな構成
4
搭載した方がはるかに高速であるが、構成を変えて試すには最適で
あるし、FPGA とプログラムの協調動作なんてことをさせるには
Nios II は非常に便利である。
ということで、次回からこの MAX 10 評価キットを使って色々と
遊んでみた様をご紹介してゆきたいと思う。
MAX 10 FPGA 評価ボードとブロック図
5
MAX 10 FPGA で学ぶ FPGA 開発入門(2)
「MAX 10 FPGA」のテスト環境を構築する
今回から実際に「MAX 10 FPGA 評価キット」を利用しての開発に着手する。まずは環境構築だ。キット以外に必要なモ
ノもあるので注意して欲しい。
評価キット以外に入手すべき2アイテム
では FPGA へのプログラミングをどうやって行うかというと、基
板上に用意された JTAG ピンから行う事になる。この JTAG ピン
前回(MAX 10 FPGA で学ぶ FPGA 開発入門(1))でご説明
経由でプログラミングを行うためのツール(というかケーブル)が
したようこの連載では Altera「MAX 10 FPGA 評価キット」を利
「USB Blaster」と呼ばれる製品である。これは「MAX 10 FPGA
用するが、キット以外にも必要なものがある。入手すべきものは
評価キット」とは別に用意する必要がある。
「USB Blaster」「Quartus
「MAX 10 FPGA 評価キット」の他、
II Web Edition」である。
評価キットについては前回紹介したので詳細は省くが、入手方法
としては、Altera のショッピングサイト(Photo01)の他、Digi-
Key、Mouser Electronics、Terasic など販売代理店からの購入
も可能である。
Photo01: 米オフィシャルサイトの「MAX 10 FPGA 評価キット」購入ページ。日本
語の評価キットの購入ページはこのページに飛ばされる
Photo02: 米 Altera から購入すると USB Blaster が 56.67ドルで購入できるが、評
価キットとのまとめ買いは「自分で」との断り書きが
筆者は Mouser から購入したが特に深い意味がある訳ではない
6
(というか、列挙した販売代理店は全て使った事があり、どこから
ちなみにこの USB Blaster、Altera のサイトでは 1 個 300 ドル
も問題なく製品が届いている)。購入の際は在庫とか送料などで決
と正規品はあまり安くないが、Digi-Key では MAX 10 FPGA 評
めてしまって良いと思う。Mouser にオーダーした時も、確か数日
価キットとのセットで 1 万 4812 円付けている他、米 Altera では
で到着したと記憶している。
56.67 ドルで販売しているがまだちょっと高い(Photo02)。
さてその MAX 10 FPGA 評価キットだが、オンボードの Micro
幸い UBS Blaster に関しては互換品が大量に出回っているし、
USB コネクタは電源を取る事にしか利用できない。というのは
自作している方もいらっしゃる。筆者は Terasic の USB Blaster
USB コ ネ クタから の 配 線 は Enpirion という PMIC(Power
互換品「Terasic Blaster」を利用した。
Management IC)に直結しており、実はこのコネクタを経由して
「Quartus II Web Edition」は、FPGA のプログラミングを行うた
の USB としての動作はもちろん、FPGA のプログラミングも不可
めの開発環境である。Quartus II 自体は Subscription Edition と
能である。
、後者は無償で入手
Web Edition があり、前者は有償(契約ベース)
できる。両者の違いはこちら(リンク先 PDF)で確認できるが「MAX
なみにまだ USB Blaster 本体を USB ケーブルで PC と接続して
10 を使って遊ぼう」というレベルであれば無償版で十分である。
はいけない(ドライバのインストールが必要)。これは Quartus II
まず「MAX 10 FPGA 評価キット」から話をしよう。評価キッ
のインストールの際にあわせて行うことになる。
トのパッケージに入っているのはこれだけ(Photo03)で、これ単
体でたいしたことはできないが動作確認はできる。
Quartus II Web Editionのインストール
方法は簡単。USB ケーブルを評価キットにつなぎ、適当な USB
その次が Quartus II Web Edition である。最新のダウンロード
ポートから給電すると、基板上の LED 1 ∼ 5 が 1 秒間隔で点滅
ページはこちらである(Photo06)。ここから必要なファイルをダウ
。
(正確には 0.5 秒点灯、0.5 秒消灯)する(Movie01 )
※
ンロードできる。
これは評価ボード上の MAX 10 に初期状態で書き込まれている
プログラムによるもので、点滅していれば正常である。逆にここで
点滅しないようであれば初期不良の可能性がある。まずはこれを確
認しよう。
Photo03:パッケージ内容はボードとケーブル、平置き用のゴム足×4 のみ
次は USB Blaster である。前ページで説明した通り、今回は
Terasic の USB Blaster を利用した(Photo04)。内蔵されてい
るのは USB Blaster 本体と USB ケーブルのみである。このケー
ブルを評価キットの JTAG ポートに装着すれば準備 OK である。ち
Photo06:「個別ファイル」Tab で必要なものをきちんと選択しても良いが、面倒な
ら「一式ファイル」Tab でまとめて落とすほうが楽。ただし、ファイルサイズが 5G
超とデカイ
最低限必要なのは「Quartus II Software(includes Nios II
」ModelSim-Altera Edition(includes Starter Edition)
」
EDS)「
「MAX 10 FPGA device support」だが、他にも Quartus II の
Help やら Software update やら、別途落とした方が良いものも
あるので、「一式ファイル」での入手が楽だ。
問題はこのファイルサイズが約 5.5G バイトもあることで、光接
続環境でも 30 分ほど必要とした。ダウンロード時の回線には気を
付けて欲しい。
Quartus IIの環境構築
さて、実際にダウンロードしようとすると、その前に「myAltera」
への登録が要求されるので、ここで登録を行ってからダウンロード
を行う。ダウンロードが終わったら展開して(なぜか Windows 向
けも tar ファイルで提供されるので、ツールで適当なディレクトリに
Photo04:Terasic「USB Blaster」 のパッケージ。そういえばちょっと前から Atmel
がこうした のロボットのパッケージを利用していたが、それにならったのだろうか?
※このページのムービーはこちら →
展開、setup.bat を起動するとインストールが開始される。
インストールそのものはごく普通だが、インストールディレクトリ
https://www.youtube.com/watch?v=tLT-f7S_oC8
7
がちょっと変(Photo08)とか、インストール時のチェックに注意
といったあたりが要注意だ。またインストールが終わっ
(Photo09)
た際には、USB Blaster のドライバのインストールを行うかどうか
のチェックを入れておこう(Photo10)。問題なければ普通にドラ
イバがインストールされるはずだ(Photo11)。
以上が完了したら、USB Blaster を PC の USB ポートに接続
する。するとドライバの検索が始まるが、基本ここでは発見できな
「コンピューターを参照してドライバー
いと思った方がいい。そこで
ソフトウェアを検索します」を行う必要がある。
ここでドライバが入っているディレクトリ(今回の例だと C:\
altera\15.0\quartus を指定し、 サブディレクトリも検索する を
有 効 にする)と、ドライバが 発 見され、インストールが 終了
(Photo13)。USB Blaster 経由での FPGA へのプログラミング
が可能になった。
Photo10:一番上の "Launch USB Blaster II driver installation" にチェックが入っ
ている事を確認しておく
以上で一応の環境は整ったが、せっかくなのでプログラミングで
きる事を確認してみよう。
Photo11:なぜ Delaware Altera Corporation かといえば、同社が米 Delaware
州の会社だから
Photo08:説明の関係で一応このデフォルトのままインストールした
Photo09:一番下の ModelSim-Altera Edition は有償のソフトウェアなので、イ
ンストールしても意味が無い。またデバイスは使うもの(今回なら "MAX 10 FPGA")
のみにチェックをつけておく
8
Photo12:待っていても見つからないので、 Windows Update からのドライバー
ソフトウェアの取得をスキップする をクリックするのが吉
Photo13:インストール完了。ちなみに今回は Terasic USB Blaster での例だが、
Altera の純正 USB Blaster やその他の互換 USB Blaster も手順は同じだと思われる
Photo14:初回起動時の画面。ここでは真ん中の Run the Quartus II software"
をチェックして OK を押す
Photo17:
「Restore Factory Settings LED Flash」は要するに Movie01 の動作
の、0.5 秒毎に LED の点滅を繰り返すという奴である
Quartus II を起動すると最初にダイアログが出て、その次に
(Photo15)。ただここ
Quartus II の画面が出現する(Photo14)
Photo15:Quartus II の初期画面はこんな感じ。これは Project も何もない、まっ
さらな段階
でいきなりデザインを入力、というのもハードルが高いので、まず
はありモノをちょっとモディファイしてみることにしたい。
Quartus II をインストールしても、いわゆるサンプルプログラムの
たぐいは一切入っていないので Web から入手する。MAX 10 向け
の 場 合、Altera の「Design Store」にいろいろ置 か れている
。今回はこの中から「Restore Factory Settings LED
(Photo16)
。ここで「Download」を選ぶと、
Flash」を選んでみる(Photo17)
「LED_Flash.par」というファイルがダウンロードされるはずだ。
この .par ファイルの取り込みは、以下の流れで行う。
Photo16:さまざま開発キット向けの Sample が混在しているので、ちょっと分かり
にくい
(1) "File" → "New Project Wizard" を選択(Photo18)
9
(5) Template 指定で、先ほどダウンロードした .par ファイルを指定(Photo22)
(2) 適当な名前で Project を作成(Photo19)
(6)
一覧に追加された "Restore Factory Settings LED Flash" を選択(Photo23)
(3) Project Type で "Project template" を選択(Photo20)
(7) Template を利用して新規プロジェクトが生成(Photo24)
ここまで終了した段階で、左側の「Entity」の下にある「LED_
Flash_all」をクリックすると、ソースコードが表示されるはずだ。
ちなみに、
これで生成されたソースコードは以下「List1 ※」になる。
ソースコードの説明はまた次回以降に説明するとして、これをこ
のままコンパイルしてファイルを生成、ダウンロードしても LED に
(4) Template 一覧で、"Install the design templates." をクリック(Photo21)
変化はない。
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news001.html
10
そこで最後の 5 行を書き換えてみた。
assign LED1 = dec_cntr ;
assign LED2 = dec_cntr ;
assign LED3 = dec_cntr ;
assign LED4 = dec_cntr;
assign LED5 = dec_cntr ;
から
assign LED1 = dec_cntr ;
assign LED2 = !dec_cntr ;
assign LED3 = dec_cntr ;
assign LED4 = !dec_cntr;
Photo26:Mode は JTAG のままで構わない
assign LED5 = dec_cntr ;
に変更してみた。
dec_cntr は 0 か 1 の値を取り、0 なら LED が消灯、1 なら点
灯する。そこで LED 1 / 3 / 5 と LED 2 / 4 に与える値を反転
させることで、互い違いに点滅させようというものだ。この変更を
Quartus II の画面上で行ったら、やはり左側、Entity の下にある
Tasks 画面で Compile Design をクリックすると、問題がなけ
れば数分(環境による:2 回目以降は 1 分かからなかった)後にコ
ンパイルが完了するはずだ(Photo25)。
Photo27:もし一覧になければ、"Add Hareware..." ボタンを押して USB Blaster
を登録しておく。逆に一覧にあれば、それ以上追加する必要はない
Photo25:赤枠で囲った部分をクリックするとコンパイル開始。Warning が 16 個ほ
ど出ているが、今は無視してよい。利用している LE は 45 個、レジスタは 28 個で、
ほとんど使ってないと言ってい。
USB Blasterでの書き込み
Photo28:"output_files" というサブディレクトリは自動で生成されるが、指定は手
動で行う必要がある
Hardware Setup... を押して Hardware Setup 画面を出す。
これまで完了したら、その下にある Program Device をクリッ
ドライバが正しくインストールされていれば USB-Blaster が一
クすると Programmer が起動する(Photo26)。
覧にあるはずなので、 Currently selected hardware を USB-
初期状態では USB Blaster を認識していないので、左上の
Blaster に設定する(Photo27)。
11
次に programmer の Add File ボタンを押し、プロジェクト
ディレクトリの下の output_files ディレクトリに生成した「LED_
Flash.pof」を指定する(Photo28)。すると書き込み画面に戻る
ので、Program/Configure にチェックを入れて Start ボタンを
押すと、MAX 10 への書き込みが始まる(Photo29)。
書き込み時間は 1 分よりはかかるかな?という感じ。無事に書き
込みが終わると、すぐに起動し、狙い通り、互い通りに LED が点
滅することが確認できた(Movie02 ※)。
だいぶ長くなってしまったが、今回は入手から環境整備、書き込
みの検証までが行えた形だ。次回は FPGA の記述言語(という言
い方はちょっと妙なのだが)である「Verilog」の話なども交えて、
もう少し具体的なことをやってみたいと思う。
Photo29:"Veryfy" あるいは "Blank-Check" は別にチェックをつける必要はない(こ
の画面ではチェックを入れて実施したが、すると書き込みに加えて検証も行われるの
で 10 分近く必要になる)
※このページのムービーはこちら →
12
https://www.youtube.com/watch?v=hPOdpEnhTX8
「MAX 10 FPGA」のテスト環境を構築する
MAX 10 FPGA で学ぶ FPGA 開発入門(3)
FPGAでのLチカをVerilog HDLで理解する
今回は FPGA での L チカを例に、FPGA 開発に必要なハードウェア記述言語の解説をしたい。用いる「Verilog HDL」は
Arduino や C の経験がある方なら、理解そのものはそう難しくないと思う。
前回(「MAX 10 FPGA」のテスト環境を構築する)はでは MAX
module LED_Flash_all(
10 FPGA と Quartus II、それに USB Blaster を使って簡単に
input wire clk,
ソースコードを書き換えるところまでご紹介した。今回はもう少し
output wire LED1,
中身を説明したいと思う。
output wire LED2,
下のリスト が前回も説明した、L チカのソースコードとなる。記
output wire LED3,
述は Quartus II がサポートする Verilog HDL でのものだ。
output wire LED4,
まず冒頭の "`timescale 1ns / 1ps" は、実は L チカの動作とは
output wire LED5
全く無関係である。これは Quartus II から呼び出されるシミュレー
);
※
タで利用されるもので、意味としては ns 単位の割り込み(例えば
開始後 12.5142ns 後に入るとする)を ps 単位に丸める(開始後
とした方が良い。input/output は入出力だが、次の "wire" は配
12514ps に割り込みが入る)という意味である。ということで無
線を示す。つまり信号線の形でつながっている事を明示的に示すも
視してもらいその後に来るのがコメントだが、これも見れば分かる
ので、これに対比されるのが "reg"(レジスタ)である(Quartus
と思うので説明は割愛する。
II ではここで wire を省いても問題はないのだが)。ちなみに当然な
module宣言
がら clk や LED1 ∼ 5 は何れも 1bit の変数として扱われ、保持で
きる値としては 0 か 1 ということになる。
さて、ソースの最初に出てくるのが module 宣言である。この場
レジスタ定義
合は LED_Flash_all というモジュール名をつけている(ユニーク
であればなんでもいい)のだが、ここで入出力は clk という input、 さて、これに続いてレジスタ定義部が来る。
それと LED1 ∼ 5 という output があることを示している。
reg[15:0] div_cntr1;
reg[9:0] div_cntr2;
input clk,
reg dec_cntr;
output LED1,
reg half_sec_pulse;
module LED_Flash_all(
output LED2,
output LED3,
レジスタ定義
output LED4,
これは内部でカウンタを使う際に利用するもので、物理的な実体
output LED5
は内部のラッチである。レジスタも当然黙っていると 1bit 幅になる
);
ので、もっと幅が欲しい場合には、例えば div_cntrl1 の様に
Module 入出力宣言
つまり FPGA には(電源以外だと)Clock 信号のみが入力され、
reg[15:0] div_cntrl1;
LED 駆動出力 5 本が出てくるという仕組みだ。この module 宣言
といった指定を行うことになる。こうすると MSB が 15、LSB
と対をなすのが、リストの最後にある endmodule で、この間に挟
が 0 となる 16bit 幅のレジスタが確保される
(要するにラッチが 16
まれたブロックは全て、ここで宣言した input と output しか(外
個並ぶ)事になる。これもまた変数として扱える事になる。
部に出す信号としては)使えないことになる。
余談になるが、きちんと文法的に正しく書くのであれば
組み合わせ回路の記述
いよいよメインとなる組み合わせ回路の記述部である。組み合わ
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news002.html
13
せ回路は実際には幾つかあり、後述する assign 以外にもあるが、
でいきなり div_ctrl1 に 1 を追加してる( <= は代入の意味なので、
「電
ここではベーシックな initial と always である。ここで initial は
C 風に書けば div_cntrl++; ということになる)。そのあとで div_
源 投 入 時、もしくはリセット後に一 度だけ実 行される回 路 」、
cntl1 が 0 かどうかチェックしてるのは誤解を招きそうだが、要する
always は「常に動いている回路」となる。arduino 的に言えば前
に div_cntl1 は毎秒 50M 回加算をされることになる。ただし div_
者が void init()、後者が void loop() にあたると理解していただく
cntl1 は 16bit のレジスタなので、65535 の後で 0 に戻る事になる。
と早い。今回の回路では、initial は 3 種類のカウンタを 0 クリアす
要するに
るのだけに使っている。
begin
initial begin
div_cntr1 <= div_cntr1 + 1;
div_cntr1 = 0;
if (div_cntr1 == 0)
div_cntr2 = 0;
:
dec_cntr
:
end
= 0;
:
:
初期手続き部
else
always@(posedge clk)
half_sec_pulse <= 0;
begin
div_cntr1 <= div_cntr1 + 1;
とすることで、"…………" の部分が呼ばれる頻度は毎秒 50M
if (div_cntr1 == 0)
65536 = 762.939……で毎秒 763 回になるわけだ。で、呼ばれ
if (div_cntr2 == 762)
ていない間は常に half_sec_pulse というカウンタを 0 にしている
begin
だけである。
div_cntr2 <= 0;
さて、では "…………" の中身は?というと、こちらの中ではさら
half_sec_pulse <= 1;
に div_cntl2 というカウンタを回している。こちらは 10bit のカウン
end
タなので、
1024 まで達すると 0 に戻るが、1 秒にするためには 763
else
にしておかないと都合が悪いので、明示的に 762 になったかどうか
div_cntr2 <= div_cntr2 + 1;
を判断して、
762 に達したら half_sec_pulse を 1 にセットし、div_
else
cntl2 を 0 に戻す。そうでなければ div_cntl2 を 1 増やすというシ
half_sec_pulse <= 0;
ンプルなものだ。この結果、if(div_cntr1 == 0)... から始まる if ブ
ロックが終了するとき、約 1 秒に 1 回だけ half_sec_pulse が 1
if (half_sec_pulse == 1)
dec_cntr <= !dec_cntr;
になり、他の時には 0 になるというわけだ。
dec_cntr は純粋に LED の On/Off の状態を保持するもので、見
て分かる通り、half_sec_pulse が 1 の時だけ値をひっくり返すと
いう処理になる。
end
手続き部(メイン)
最後が assign で記述した部分である。便宜的に「出力割り当て
宣言」と書いたが、実は必ずしも出力でなくても良い。assing は
さて、メインとなる部分は always からだ。最初の
「配線の割り当て」を定義するもので、この例で言えば LED1/3/5
には dec_cntr の値をそのまま流し、LED2/4 には値を反転して流
always@(posedge clk)
す事を指定している。ここで注意されたいのは、assign の動作は
「同時」であることだ。
はクロック信号を取り込み、この信号の正の立ち上がりのタイミ
ングで begin 以下を実行するという意味である。コメントにもある
assign LED1 = dec_cntr ;
ようにクロック信号は 50MHz が供給されるので、always 以下の
assign LED2 = !dec_cntr ;
begin ∼ end のブロックは毎秒 50M 回実行されることになる。
assign LED3 = dec_cntr ;
ただ目的は 1 秒単位の LED の On/Off なので、これはあまりに
assign LED4 = !dec_cntr;
高速すぎる。そこでまず div_cntr1 を使ってこれを分周する。initial
assign LED5 = dec_cntr ;
のところで div_cntl1 は 0 に初期化し、で always の begin 直下
14
先の div_cntr2 の部分であるが、以下のブロックでもし div_
cntr2 が 762 だった場合、(1)div_cntr2 に 0 を代入する、(2)
half_sec_pulse に 1 を代入するという順番で処理は進む。 とこ
ろが assign は処理ではなく接続なので、動き出すタイミングで既
に配線が済んでおり、同時に行われる事になる。
if (div_cntr2 == 762)
begin
div_cntr2 <= 0;
half_sec_pulse <= 1;
end
これ はブロック図で 見 た 方 が 分かりやすいかもしれ ない。
Photo01 はこのプログラムのコンパイル後にブロックのマッピング
Photo01: 緑色がラッチ、紫のものが論理回路 ( 加算器やセレクタなど ) を示す。
を表示させたものだ。dec_cntr という緑のブロックは、要するに
dec_cntr の値を保持する 1bit のラッチであるが、その出力が
的にカバーするのが目的ではないので、この先も新しい概念なり何
LED1 ∼ output から LED5 ∼ output の 5 つのバッファに直接つ
なりが出てきたらその都度説明する形で進めてゆく予定だ。
ながっている。ただし LED2 と LED4 には、論理反転を示す○が
網羅的に知りたい、という方は検索エンジンで「Verilog HDL
ついているのがお分かりかと思う。なので LED1 ∼ 5 の出力は、
文法」などと検索すれば日本語での解説を探すことができるし、
dec_cntr のラッチの出力が変化した瞬間、同時に変化することが
Altera 自身もサンプルを公開している(英語なので読み解くのが手
お分かり頂けるかと思う。
間かもしれないが)。
ということで、文章で書くと案外に長くなるが、Arduino あるい
最後に今回紹介した回路全体のマッピングを示したのがこちら
は C/C++ のプログラミング経験がある方なら、所々作法に違いが
(Photo02)である。ラッチの数がかなりあるのは仕方ないが、そ
あるとはいえ、理解そのものはそう難しくないと思う。もちろん、こ
れよりも異様に長いのは二重ループの上に LED 制御をちょっと面
れは Verilog HDL の文法の一部の話であって、C/C++ 系とは異
倒な形でやっている部分もあるためである。次回はこのあたりに
なる概念なども少なくないのだが、この連載はそうした部分を網羅
ちょっと手をいれてみたい。
Photo02: これは「Technology Map Viewer」という Quartus II 標準のツールで、回路の割り当てが終わったあとの状況を示したものである。このままだとなんだかよく
分からないが、拡大すると Photo01 の様に細かく表示される。
FPGA での L チカを Verilog HDL で理解する
15
MAX 10 FPGA で学ぶ FPGA 開発入門(4)
FPGAのLED制御プログラムを深く理解する
FPGA 開発に必要な HDL への理解を深めるため、MAX 10 に用意されている Arduino I/O を利用しての L チカを行い、
多灯 LED の制御を含めたプログラミングも解説する。
Arduino I/OでのLチカ
前回(FPGA での L チカを Verilog HDL で理解する)では
「MAX 10 FPGA」を利用した L チカ動作を細かく紹介したので、
もうちょっとここから先に進めてみたい。前回はオンボードの LED
を使って行ったが、今回からは Arduino I/O を利用してみたい。
「MAX 10
といってもそう難しい話ではない。連載の第 2 回(
FPGA」のテスト環 境を構 築する) で「Design Template」に
今回は MAX
Restore Factory Settings LED Flash を使ったが、
(Photo01)
。こ
10 Evaluation Kit Baseline Desing を選べばよい
れで適当な名前を選んでプロジェクトを作成する。
Photo01: この Design Example は Quatus II に標準で用意されている
作成後のテンプレートファイルは List 1 ※の様になっている。プロ
Photo02: 赤枠で囲った部分が J3 Connector
グラムで利用できる I/O の一覧が全部 module 宣言の中に含まれ
と規定されている。今回は J3.3(ARDUINO_IO13)と GND
ている「だけ」である。まずはオンボードの LED の代わりに、
に LED をさして、これで L チカをやってみた。
Arduino 互換の I/O ピンに LED をさして、これを L チカさせてみ
ることにしたい。
出力をArduino I/Oとしたプログラム
ちょっとマニュアルが分かりにくいのだが、Arduino は本来 4 組
プログラムそのものは前回利用した L チカプログラムをそのまま
このうち MAX10 Evaluation Board
のコネクタピンを持っている。
流用して、List 2 ※の様にしてみた。修正点は「クロック信号の表
が互換なのは 3 組だけである。Photo02 で言えば、右上の J3 と
左下の J4(の一部)、それと右下の J5 が Arduino 互換の信号が
「一部」出ている。J3 コネクタの場合、上が J3.1、下が J3.8 と
なっており
「出力を Arduino_IO13 のみにする」
記を clk から Clock に変更」
の 2 点である。 間 違いがなければ、あっさり動 作するハズだ
(Movie01 ※)。
さて、この状態で点灯間隔はどの程度になるかをオシロスコープ
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news003.html
ムービーはこちら → https://www.youtube.com/watch?v=ZG7MSXOv26o
16
Photo03: 横軸は 200msec で、ほぼ 1 秒ごとに On/Off を繰り返している様に見える
Photo05: 一応 147.962sec ということになっているが、有効数字は小数以下 1 桁
程度と思われる
い理由は、1 つはオシロスコープの精度の問題だが、もう 1 つ別の
理由もある。これは後述することにしたい。
正確に1秒間隔とするために
若干長い理由はともかくとして、正確に 1 秒にならないのは、そ
もそも正確に 50M サイクルを数えるのではなく、65536 763 サイ
クルを数えているためである。では正確に 50M サイクル数えたらど
うなるか? というのが下の「List 3 ※」である。List 2 と見比べて
もらってもループの数が 1 個減って分かりやすくなったと思う。
Photo04: ここまで縮小すると、カーソルを 1 ピクセル移動するだけで数十ミリ秒の
変化になるので、精度はあまりよろしくない
カウンタは 26bit になったが、これは 50,000,000 まで数えるに
は 25.58bit が必要なためである。ただ List 2 では div_cntr1 が
16bit、div_cntr2 が 10bit で結局 26bit 分を使っているので、実
はここで差は無い。このやり方の場合、カウンターの周期をオシロ
でちょっと確認してみた。前回で説明した通り、On/Off の周期は
厳密には 65536 763 = 500173968 サイクルとなる。クロックは
50MHz なので、周期は 1.000348 秒という事になる。
1 周期の波形を見てみるとこんな感じ(Photo03)で、ほぼ 1
秒っぽく見えるが、これは解像度不足というか、1 周期分で判断す
るのは無理っぽい。そこで 150 周期分を一気に表示してみたのが
下の画像だ(Photo04)。150 周期で 150.125 秒ほどになり、1
サイクルあたり 1.0008333……秒となる。本来の周期より若干長
Photo06:
「無駄に長い構成」(筆者談)
スコ ープ で 見 て み ると 148 周 期 で 147.962sec ほ ど に なり
(Photo05)、1 周期の時間は 0.9997 秒と 1 秒を切ってしまった
のだが、これはオシロスコープ側の精度の限界(カーソル機能の精
度が足りない)であり、実際は 148sec に非常に近いと思われる。
ただし、当然ながらその代償もある。Photo06 はこのケースで
の回路全体のマップを Quartus II のツール「Technology Map
Viewer」で表示したものだ。前回に比較すると、相当長くなって
いるのが分かる。
要するにカウンタのデコードが、
前回のケースだと 65536 はシンプル
なデコーダ(16bit が全部 1 になっていればいい)で済み、763 のみ
こちらは前回の単純な L チカ回路
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news003.html
17
1011111011 のデコードが必要になるのでちょっと複雑、というもの
だったのが、
今回は 50000000 = 10111110101111000010000000
のデコードが必要になり、これによって回路が大規模化しているという
訳だ。
リソースの比較をして見るとこれは分かりやすい。Photo07 がも
との LED Flash における構成でのリソース利用率、Photo08 が
List 3 でのリソース利用率で、ロジックエレメントを 5 つほど余分
に消費している。これが大問題か?といわれると、全体で 8064 個
もロジックエレメントがあるうちの 45 個と 50 個だから、大きな違
いではないのだが。
Photo09: ブレッドボードを利用して実装。黒い配線が 3.3V ラインへのもの
Photo07: まだまだゆとりはある
図 1 回路図
干面倒である(Photo09)。
さて、まずは回路図であるが、図 1 の様な構造である。今回は
手 元 に 2 桁 の 7 セ グ メ ン ト LED(Avago Technologies の
「HDSP-K211」)しかなかったので、この下一桁のみを利用してい
る。この HDSP-K211 の内部は Photo10 の様になっているが、問
題は見てお分かりの通りアノードコモン(プラス極が共有)である。
なので、13 番ピンにまとめて電源を供給してやる必要がある。
ところが MAX10 Evaluation Board の Arduino ピンには、実
Photo08: ちょっとだけ無駄づかい
7セグメントLEDの制御
さて、次にここからもう一歩進めて 7 セグメント LED の L チカ
は電源が出ていない。先に互換の信号が「一部」出ていると書い
たのはこの事で、例えば Arduino なら J2.3 にあたるピンには 3.3V
が出ているのだが、MAX10 Evaluation Board にはこれが出てい
ない。
なので、どこかから 3.3V の出力を取らないといけない。幸いな
に話を進めてみたい。
事にマニュアルによれば EP5388QI(オンボードの PMIC)の出
7 セグメントの LED も、1 桁でやる分にはただの L チカの延長
力が TP6 に出ている。これは本来は消費電力測定用のパッドなの
7 セグメントだと 7 つ(実際には小数点まで含めると 8 つ)の LED
の 13 番ピンをここに接続。後は 5 ∼ 12 番のピンをそのまま J3.3
でしかない。面倒なのは 1 個の LED なら単に On/Off で済むのが、 だから、ここから 3.3V 出力が問題なく取れるので、HDSP-K211
の On/Off を 10 進数にあわせて切り替える必要があり、何かしら
のテーブルを持たないと大変ということだ。加えて言えば配線も若
∼ J3.8 と J5.1/5.2 に割り振った形だ。
ソースは List 4 ※だ。以前との違いは、まず 0 ∼ 9 まで 10 秒の
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news003.html
18
カウンタとなるので、dec_cntr を 4bit に増やした事。それと、新
が、この桁数を増やそうとするとやや面倒である。桁数を増やすた
しく 7bit の seg_cntr というレジスタを追加したが、これは 7 セグ
めにはダイナミック駆動をするのが一般的だが、アノードコモンでこ
メント LED のそれぞれに対応する形だ。具体的な処理はソースを
れをやるにはちょっと回路に細工が必要である。
見てもらえれば分かる程度で、dec_cntr の値の 0 ∼ 9 にあわせて
もう 1 つの問題が処理の遅延である。Photo11 はこの 7 セグメ
seg_cntr の値を bit 単位で操作し、その結果をそのまま Arduino_
ント LED の Technology Map だが、Photo06 と比べてもさらに
IO に出力するだけである。
回路が延びており、どうみても 1 サイクルで処理が終わるようには
注意点はアノードコモン方式であること。5 ∼ 12 番ピンを Hi に
思えない。実はこれ、全ての回路をシーケンシャルで動かしている
すると消灯、Lo にすると点灯という負論理になっているので、これ
のが問題で、この結果として、1 秒毎に表示処理を行っている時は、
ま
にあわせて seg_cntr に設定するあたりは本来の逆となっている。
何サイクルかクロックの割り込みを取り逃している。
た小数点(HDSP-K211 の 9 番ピン)は 1 秒おきに点滅というこ
冒頭で「本来の周期よりも若干長い」と書いたのはこれが理由で
とにしたので、dec_cntr の LSB の値をそのまま assign している。 ある。解決は簡単で、クロック信号を数えて 1 秒を割り出す部分と、
これを動かすと、Movie02 の様にちゃんと動作するはずだ。
そのあとの表示処理を分離すれば良い。次回はこのあたりを説明し
ということで 7 セグメント LED の 1 桁駆動は比較的簡単だった
たい。
Photo11:「Technology Map Viewer」での表示。右端が急に複雑化しているのが分かる
FPGA の LED 制御プログラムを深く理解する
19
MAX 10 FPGA で学ぶ FPGA 開発入門(5)
よろしいならばダイナミック点灯だ――
FPGAでLEDをダイナミックにLチカさせる
単純な L チカならば FPGA でもそう難しくない。ただ、ダイナミック点灯やそれに伴うソースの最適化については ならで
は のポイントが散見される。
アルテラ「MAX 10 FPGA」を利用して FPGA 開発の基礎を学
ぶこの連載、前回(FPGA の LED 制御プログラムを深く理解す
る)は Arduino I/O を利用し、7 セグメント LED1 桁でのカウント
アップを実装してみたが、今回はこれをもう少し展開してみたい。ま
ずはダイナミック点灯への変更を行う。
Photo00_1 ダイナミック点灯に対応すべく配線も変更した
である。
List 1 ※はこれを強引に実装してみたものだ。ちなみに配線も少
し変更している(Photo00_1)。ダイナミック点灯の場合、一度に
表示されている LED は 1 つだけなので、無理に PMIC から電源
Photo00 前回の 7 セグメント LED 配線図
を取らなくても、MAX 10 の I/O pin の出力(最大 25mA)でも
前回の配線図(Photo00)はアノードコモンをオンボードの
を、J5.3(Arduino の I/O 5 番に相当)に切り替えている。
PMIC 3.3V 出力につなぐ形で、後はそれ以外のピンを制御する形
で実装してみた。この方式の場合、LED は常時点灯する形になる。
それなりに明るく光る。このため、7 セグメント LED の 13 番 pin
プログラム解説
1 桁だけを表示するならこれでもいいのだが、桁数を増やそうとす
さてプログラムだが、1ms ごとに点灯させる LED を切り替える
ると途端にピン数が足りなくなる。
事にした(最初は 10ms で組んでみたら遅すぎてちらつきが酷かっ
利用した 7 セグメント LED「HDSP-K211」の場合、点灯時は
平均 37mW ほど消費するので、全桁+小数点を表示させると約
たので 1ms に減らした)。
まず div_cntr1 で 5 万回(= 1ms)のカウンタを作り、この中
300mW ほど消費する形になる。この状態で桁を増やすと、4 桁な
で 1000 回の div_cntr2 のカウンタを回す形で、毎秒 1000 回の
ら最大で 1.2W ほど消費することになり、PMIC の最大定格(連
ループを回している。その 1000 回のループで、最初の 1 回だけは
続出力最大 800mW)を超えてしまう(実際はその前にピンが足り
なくなるが)。これは賢明とは言いにくい。
ダイナミック点灯を実現する回路とプログラム
表示すべき数字(dec_cntr)の更新と、その数字にあわせた 7 セ
グメント LED の点滅パターンの更新(seg_cntr)を行っており、残
りの 999 回はダイナミック点灯の更新を行っている。
ダイナミック点灯といっても難しい処理をしているわけではなく、
ということでダイナミック点灯である。これは要するに同時に発
7 セグメント LED は小数点を含めて 8 つのセグメントを持つので、
光する LED は 1 本に留めるが、発光させる LED を高速に切り替
これにあわせて 8 回の小ループ(pos_cntr)を内部で回し、その
える事で、あたかも同時に LED が発光しているように見せかける
たびに表示する LED の場所(disp_cntr)を更新する形だ。表示
という手法。多桁の表示などではごく一般的に用いられている手法
しない場所は Hi(1)にしている。
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news004.html
20
実 際にこれを起 動すると、きちんと表 示されるのが分かる
(Movie01 )。良く見ると微妙に LED の表示がチラついているが、
※
これはダイナミック点灯の周期がちょっと長すぎるためで、もう少し
周期を短くすれば解決する。
2桁のダイナミック点灯に挑戦
1 桁がうまく行ったので、ではこれを 2 桁にしてみよう。
・L
ED の表示パターン(seg_cntr)も 2 つに(seg_cntr1, seg_
cntr2)に。
・d
isp_cntr そのものは変わらないが、小ループが 8 回から 16 回
に更新。これにあわせて、disp_cntr が seg_cntr1/seg_cntr2
のどちらを反映するかで場合分けが必要になった結果、case 文
が長大に。
といった弊害が出ている。
今度は 0.1 秒周期で 0.0 ∼ 9.9 秒まで順にカウントアップである。 他に変更点としてはリフレッシュ頻度が挙げられる。1 桁だとダイ
まず配線は図 2 の様に変更した。ダイナミック点灯を利用したので、 ナミック点灯は 1ms 間隔の更新で間に合ったが、2 桁になるとさ
今度はアノードコモンにあたる 13・14 番ピンは本体の J5.3 と J5.4
すがに間に合わない。そこで更新頻度は 0.5ms に高速化した。ま
の 2 つに接続され、これを切り替える事でどちらの 7 セグメントが
た、今度は 10 分の 1 秒単位での表示となるので、div_cntr2 は 1
点灯するかが切り替わる。一方、各セグメントにつなぐ配線は 2 つ
秒ごとに 1 回ではなく、0.1 秒ごとに 1 回カウントアップしている。
の 7 セグメントで共通という形だ(Photo02)。
長大なリストをスマートにする
で、動く動かないでいえばこれできちんと動いたのだが、もう少
しスマートに記述したいところ。そこで List 2 を Function 文と条
件演算子を使ってもう少し短くに書き換えたのが List 3 ※となる。
最初の Seg_Display という Function は、pos_cntr にあわせ
て seg_cntr1/seg_cntr2 のどのセグメントを点灯するかを割り当
てるもので、Function の戻り値でこれを反映することになる。ち
なみにここでは条件演算子を使うことで、長大な case 文からは逃
れられるようになった。
2 つ目の Map_Display という Function は、表示したい数字に
あわせて実際の LED の点灯パターンを返すものだ。1 桁だとわざ
わざ Function にする必要はないのだが、複数桁ある場合は桁の数
図 2 2 桁のダイナミック点灯を行う配線図
回分だけこれを繰り返す事になるので、ここを Function でまとめ
た形だ。
オシロでタイミング測定
さて、これでプログラム的には動いたのだが、タイミング的には
どうだろう(普通はまず設計段階でタイミングを見るわけだが、あ
えて逆にまず実際の動作の状況を見ることにする)。
下の Photo03 は LED の 4・9 番ピン(小数点)の信号をオシ
Photo02 配線はやや複雑化した。LED の裏にも 1 本配線を通している
配線はそれでいいのだが、問題はプログラムの方である。以下の
List 2 ※は List 1 をさらに力技で拡張したものである。基本は同じ
なのだが、
・表
示すべき数字(dec_cntr)が 2 桁(dec_cntr1, dec_cntr2)
になり、これにあわせて処理も 2 倍に
Photo03: ちなみにオシロスコープ本体の方で細かく情報を表示させると、信号が
Off になっている期間は平均 0.496ms ということで、きっちり 0.5ms にはならない
模様。とはいえ、ぎりぎりまで発光していることが分かる
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news004.html
ムービーはこちら → https://www.youtube.com/watch?v=pWcXy8u6eSc
21
ロスコープで見てみたところ。トリガーは信号の立下りである(ア
次の部分に、という作り方をするのが一般的である。また、今回は
ノードコモンなので、Level が 0 になると LED が電流に流れるた
最終的に外部に出てきている信号で成否を判断したが、内部ロジッ
め)。右下にあるように、Period は 4.000ms となっている。8 つ
クの検証などでは外部の信号が使えない場合も珍しくない。
のセグメントを 4.000ms ごとに更新するということは、1 つのセグ
こうした場合に利用できるのがシミュレーションである。幸いに
メントあたり 0.500ms ごとに更新しているということで、これはプ
ログラム通りの結果になっていることが分かる。
この工作程度だと「これで OK、万々歳」ということになるのだ
が、複雑なロジックを組んでいると、そもそも「全部作ってから動
かしてみる」のではなく、部分的に作りこんで動作を確認してから
Photo07 Objects から表示させたい信号を選んで右クリック→ "Add Wave" である
Photo04 利用している Version 15.0 の場合、Tools → Run Simulation Tool →
RTL Simulation で起動できる。
Photo08 Clock 信号を右クリック→ "Clock..." を選択
Photo05 一番左が用意されているさまざまモデリングツール。今作業している内容
は上から 2 つ目の "rtl_work" に含まれている。
Photo06 rtl_work の下の "top"(これはプロジェクトによって名前が違う。今回筆
者は起動する module 名を "top" のままにしたからこの名前になる)をダブルクリッ
クする
22
Photo09 この状態だと周期 100cycle(= 100ps = 10GHz)での動作になるので、
Period を 20000(= 50MHz)に指定する
も Quartus II には無償版ながらシミュレーションツールが利用可
能である。起動するとこんな画面になるので(Photo04、05)、作
業中のプロジェクトを選ぶと、実際にデザインの中身が見える
(Photo06)。今回は Clock 信号と Arduino_IO4 ∼ 13 を表示さ
せてみる
(Photo07)。ただこの状態だと /top/Clock が Hi-Z 状態
で進まないので、ここに Clock 信号を入力する(Photo08、09)。
ついでにメニューから「Simulate」→「Runtime Option」を
選んで、1 回に実行される時間を 100ps から 100ms まで増やし
ておく。これが終わったら、メニューの「Simulate」→「Run」→
「Run 100」を選ぶと、
Wave がこんな風になるはずだ(Photo10)。
このままだとちょっと見にくいので、上の縮小ボタンなどを使っ
て、先頭から 2ms ほどを表示させたのがこちら(Photo11)。カー
ソルの位置からも分かる通り、キチンと 0.5ms ごとに出力信号が
変化していることが分かる。今回は省くが内部レジスタや Wire の
値などを同様に表示することも可能であり、シミュレーション上も
Photo10 真ん中の "Default Run" が標準だと 100ps なのでここを書き換える
正しく動作することが検証された形だ。
次回はちょっと別のことをご紹介したい。
Photo11 最初の 0.5ms に信号が表示されないのは、disp_cntl に値を初めて設定
するのが最初の 0.5ms 目だからで、それまでは Hi-Z 扱いになる。本当はちゃんと
初期化していればいいのだが
よろしいならばダイナミック点灯だ
23
MAX 10 FPGA で学ぶ FPGA 開発入門(6)
FPGA上でソフトコアCPUを動かす手引き
これまで FPGA の開発基礎として L チカなどを紹介してきたが、今回はちょっと目先を変えて FPGA 上での CPU コア動
作に取り組む。
アル テラの 開 発 ボ ード
「MAX 10 FPGA」を利用し
て FPGA 開発の基礎を学ぶ
この連載、これまでには L チ
カやダイナミック点灯などを
紹介してきたが、今回はちょっ
と目先を変えて、FPGA の上
で CPU コアを動かしてみた
いと思う。
アルテラの FPGA には同社
より「NIOS II」と呼ばれるソ
フト IP コア(FPGA のゲート
アルテラの開発ボード「MAX 10 FPGA」
を利用して動作する 32bit CPU)が提供されており、これを利用
Photo01: ダウンロードするファイルは Quartus II のバージョン(15.0.0 か 15.1.0)
で異なるので、自分の利用している Quartus II のバージョンにあわせた方をダウン
ロードする必要がある
すると外部に MCU などを用意しなくても、C/C++ のプログラムを
実行させることができる。もちろん、これは MAX 10 でも利用可
一覧に出現して選択できる。選択して「Next」を押すとサマリーが
能である。
出てくる(Photo05)ので、「Finish」を押すとウィザードは完了
さて、
こちらについてもさまざまなサンプルプログラムが用意され
である。
「Nios II + Qsys "Hello World" Lab」
一番シンプルなのは
ている。
だが、あいにくこのサンプルは「MAX 10 Development Board」
向けなのでそのままでは使えない。MAX 10 Evaluation Board
で 動 作 す る Nios II の 一 番 簡 単 な も の は、「Nios II On-die
Temperature Sensor Design Example 2」なので、これを使っ
てみることにしたい。
インストールパッケージの入手と展開
最初のステップは、Installation Package のダウンロードであ
る。こちらページの中ほどにある「Download」をクリックして、
ファイルをダウンロードし
「evalkit_temp_sensor_console.par」
ておく(Photo01)。
「File」
→
「New Project
これが終わったら Quartus II を起動して、
Wizard」を選択し、まずは適当な名前で新規プロジェクトを作る
Photo02: 名前は自分が分かればなんでもいい
。次に Project Type は「Project Template」を選び
(Photo02)
、Template 一覧から「Nios II On-dir Temperature
(Photo03)
。
Sensor」を選択する(Photo04)
さて Quartus II に戻るとこんなメッセージが出ているはずだ
(Photo06)。左上のファイル一覧を見ると、
platform/nios_setup/
最初、この選択肢は出てこないハズである。ここで一覧の下にあ
simulation/nios_setup.sip と platform/nios_setup/synthesis/
る「Install the design template」をクリックし、先ほどダウン
nios_setup.qip の 2 つが確認できるはずだが、この時点でその
ロードした「evalkit_temp_sensor_console.par」を指定すると、 ファイルは存在していない。これは後で生成されるのだが、生成さ
24
Photo03:Empty Project を選ぶとちょっと後が大変
Photo04:"Nios II On-dir Temperature Sensor" が 2 つあるのは、最初間違って
Quartus II 15.1.0 をインストールしてしまったから(Software Version の欄を見る
と分かる)
Photo06: 画面下のステータス表示に注目。nios_setup.sip/nios_setup.qip が無
いと表示されている
Photo07: ファイル名を右クリックしてコンテクストメニューで "Remove File from
Project" を選ぶと削除できる
Nios IIの組み込み
さて、それでは実際に Nios II の組み込みである。これを行うの
は Qsys というユーティリティーなので「Tools」メニューから起動
する(Photo08)。
Qsys が 起 動 す ると、 ま ず は 設 定 ファイル の 指 定 に な る
Photo05: 実際はこの画面から、Quartus II に戻るまでの間、いろいろなファイルの
ビルドが行われるのでちょっと時間がかかる
(Photo09)。ここで 指 定 するものだ が、 先 に Template から
Project を生成した際に nios_setup.qsys というファイルが生成
されているのでこれを指定すると、しばらく処理を行った後、最終
れる場所は異なるので、取りあえずこのファイルは削除しておく
(Photo07)。
的 に こ ん な 情 報 を 示 して(Photo10)Qsys が 立 ち 上 が る
(Photo11)。
25
この画面を注意深く見てもらうと分かるが、一番上がクロックモ
ジュール、次が Nios II のコア、その下がオンチップの SRAM、と
いう具合にモジュールが並び、さらにモジュール間でどの信号がど
こに接続されるかがここで指定される。
他にもアドレスマップや割り込みなども全部ここで設定されので、
いろいろ設定を変えてみてもいいのだが、今のところは特に変更を
せずに、右下の「Generate HD」ボタンを押すと、こんな確認が
出る(Photo12)ので「Generate」を押す。しばらく処理が行わ
れた後に、最終的にこんなダイアログが出てくる(Photo13)はず
だ。これで、先に行方不明だった nios_setup.qip ファイルが生成
された事になる。
Photo08: スタートメニューからも呼び出せる
Photo09: ここで取り消しを押して真っ更な状態から構築もできるが、面倒なので既
存の設定を読み込む
Photo10: もともとの Qsys のファイルは全て Quartus 14.1 ベースで生成されたよ
うで、必要な IP が全て 15.0 に Update された事がここで示される
Photo11: この画面で、IP の形で提供される回路ブロックを追加 / 削除したり、構成
を変更したりといった事も可能
26
Photo12: 確認ダイアログ
Photo13: 今回はシミュレーションモデルは生成していないので、実際には .sip の方
は作成されていない
Photo14: 削除はファイル一覧からできるが、追加が出来ないあたりがちょっと使い
にくさを感じる
これで Qsys の設定は完了。再び Quartus II に戻る。
まずは生成された nios_setup.qip をプロジェクトに追加してや
る必 要がある。これは「Project」 →「Add/Remove Files in
ファ
Project..." で nios_setup.qip を指定してやると(Photo15)、
イル一覧に追加されたのが確認できる(Photo16)。
Photo17: 左下のウィンドウに Warning がいろいろ出ているが、取りあえず無視して
構わない
Photo15: ちなみに標準だと右下にあるファイル名のフィルターが "Design Files"(.
tdf/.vhd/.v/...) になっているので、ここを "IP Variation Files" に切り替えないと見
つからない
Photo18: 初回はこの後 "Auto Detect" を押して USB Blaster を認識させる必要が
ある
Photo16: 一番上に nios_setup.qip が追加されているのが分かる
以上で、Quartus II 側の作業は(おおむね)終了である。後は
「Processing」→「Start Compilation」を選んで、FPGA 側の
全コンパイルをかける。問題がなければ正常にコンパイルが完了し
た旨が表示されるので(Photo17)、「Tool」→「Programmer」
で Programmer を起動し(Photo18)、「Add File...」で作成し
た sof ファイルを指定して(Photo19)から「Start」ボタンを押
す。手順を間違えてなければ、無事に完了するはずだ(Photo20)。
Nios IIで動作するプログラムの記述
Photo19: 生成したイメージは output_files フォルダに生成されている。 ちなみ
に .sof は RAM に書き込むイメージ、.pof はフラッシュメモリに書き込むイメージだ
が、今回は RAM に直接書き込みということで .sof の方を選択する
さて、ここまでの作業で MAX 10 上にて動作するプロセッサが
構築され、さらにメモリと ADC(A/D Converter)、GPIO がこ
のプロセッサから利用可能な状態になっている。ただし、プログラ
ムを何も書き込んでいないので、この時点ではまだ何も動かない。
27
この画面で
・S
OPC Information File name: プロジェクトディレクトリの
トップに、nios_setup.sopcinfo というファイルが生成されてい
るので、これを指定する
・C
PU name: nios_gen_2_0( 自動的にこれが選択される )
・ Project name: 適当に自分でつける
・P
roject template:"Hello World Small" を選択
と作業する。
完了すると、こんな具合になるはずだ(Photo23)。
Photo20: 書き込みが終了すると右上の Progress Bar が緑で示される
Photo21: 初回はこんな具合にブランクだが、基本的には直前の作業状態を記憶して
いるので、次回からは直前の状況から再開できる。正直なトコロ、このバージョンは
ちょくちょく Eclipse そのものが落ちるのだが、再起動すると直前の状況から作業を
再開できるので大きなハンディにはならないだろう(ただし Save は小まめに)。
Photo23:Hello World を選ばない理由は、printf() を含む C のライブラリが結構メ
モリを専有する(40KB 以上)ので、SRAM を大容量に設定しないと、そもそも動
作しないため
設定が終わったら右下の「Finish」ボタンを押すとしばらくの後、
今回の例なら「TempSensor」と「TempSensor_bsp」の 2 つ
のプロジェクトが自動生成されている(Photo24)。ここでいきなり
ビルドをする前に、設定が 1 つ必要である。
Photo22: 簡単なプログラムのテンプレートも用意されている
そこでここからは Nios II 上で動作するプログラムを記述し、Nios
II にロードしてやる必要がある。
まず Quartus II の「Tool」→「Nios II Software Build Tools
for Eclipse」を選択し、Eclipse を立ち上げる(Photo21)。こ
の Eclipse で「New」→「Nios II Application and BSP from
Template」を選択して Template ファイルの選択画面を表示させ
る(Photo22)。
28
Photo24:TempSensor はプログラムそのもの、TempSensor_bsp は BSP(Board
Support Package) で、要するにランタイムである
左ペインのプロジェクト名(TempSensor)を右クリックし、プ
ロパティを表示させる(Photo25)。ここで「Nios II Application
Properties」を選ぶと、標準では Optimization level が「Size」
になっているので、これを「Off」にする(Photo26)。同様に、
TempSensor_bsp の方もやはり Optimization level を「Off」に
する。
Photo27: 何というか、説明の必要はまぁないだろう
Photo25: これは最適化の設定のためであるが、なぜか最適化オプションは "Nios II
Application Properties" に用意されている
Photo28:ondie_temp.c をファイルとして追加する方法も何度か試したのだが上手
くいかなかった
Photo29: 経過時間は利用するマシンによって当然変わる
Photo26:この目的はAlteraによれば "compiler optimization may cause some
problems while running the program." との事。
を右クリックして、コンテクストメニューから「Build Project」を選
次はソフトウェアの設定である。Project Template は「Hello
る(Photo29)はずで、これにてプログラムの開発は完了である。
world small」を選んだので自動的に "hello_world_small.c" が
最後に、プログラムを Nios II にロードする作業である。まず
生成される(Photo27)。このままだと「Hello from Nios II!」と
Eclipse の「Run」→「Run Configuration」を選び、Project 名
表示して終わってしまうのだが、これを置き換えるソースコード
。次に Target Connection
に「TempSensor」を選ぶ(Photo30)
(ondie_temp.c) が software フォルダの中に用意されている(List
タブを開く(Photo31)と、USB-Blaster が見えているはずだ。
1 )。これをエディタなどで開き、コピーして hello_world_small.
ここで「System ID checks」にある「Ignore mismatched
c にペーストする形でプログラムを入れ替える(Photo28)。
system ID」と「Ignore mismatched system timestamp」の
※
択するとプログラムのビルドが始まる。
問題なければ数十秒で終了す
両方にチェックを入れると、「Target Connection」タブの赤い
いよいよビルドへ
印が消える(Photo32)。これを確認して、まず右下の「Apply」
これが終わったら、
左ペインの Project Exploler の TempSensor
ボタンを押した後で、
さらに右下の「Run」ボタンを押すと、USB-
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news005.html
29
Blaster 経由で Nios II の SRAM にプログラムがロードされ、すぐ
み待ちのままずーっと無限ループに陥っている模様だ。
に Nios II が実行を開始する。ちなみに STDOUT に相当するもの
なんとなく、Photo10 にあるように IP の形で提供されるデバイ
は、USB-Blaster 経由の Nios II Console になり、ここにメッセー
スが 14.1 → 15 に Version up された際に何か仕様が変わってお
ジが表示される仕組みだ(Photo33)。
り、それを上手くフォローアップできていない感じがする。ただ逆に
さて、本当ならこのサンプルは 1 秒おきに温度を表示する他、基
ADC からの温度測定や DIP スイッチの設定取り込み /LED の表示
板上のディップスイッチにあわせて基板の LED の On/Off が操作可
などを省くとちゃんと動作しているので、Nios II そのものが正しく
能な「はず」なのだが、実は上手く動かない。調べてみたところ、
動作している事は間違いないようだ。次回はこのあたりを来月はも
デバイスから本来入るべき割り込みが上手く拾えておらず、割り込
う少し追及してみたいと思う。
Photo30:Project 名を選ぶと自動的に Elf file name も選択される
Photo32:「Target Connection」タブの赤い×印が消えている。Photo31 に比較
してもらうと分かりやすい
Photo33: これで動作した
Photo31: もし USB-Blaster が一覧にない場合、右の Refresh Connections を押
して再検索する
30
FPGA 上でソフトコア CPU を動かす手引き
MAX 10 FPGA で学ぶ FPGA 開発入門(7)
FPGA上でソフトコアCPUを動かす手引き
これまで FPGA の開発基礎として L チカなどを紹介してきたが、今回はちょっと目先を変えて FPGA 上での CPU コア動
作に取り組む。
この連載ではアルテラ
と同じ手順で行ったところ、あっさり動作してしまったからだ
の開発ボード「MAX 10
(Photo01)。温度表示だけではなく、スイッチを参照しての LED
FPGA」を用いた FPGA
の点灯もきちんと動作した(Movie01 ※)。ということで、
やっと前
開発を紹介しているが、
回の目的が実現された形だ。
今回は「FPGA 上でソフ
ちなみに似たような現象に陥っている人は他にも見かけたが
トコア CPU を動かす手
( Altera Forum : nios-ii-on-die-temperature-sensor
example)、決定的な解決策は特に見つかっていない模様。「俺は
引き」の続きである。
「NIOS II」
FPGA 上で
アルテラの開発ボード「MAX 10 FPGA」
15.0 で動作した」という人も居るので、原因は完全につかみきれ
と呼ばれるソフト IP コア
ないのだが。
を利用し、サンプルプログラム「Nios II On-die Temperature
スクラッチから作る場合はともかく、既存のデザインファイルをベー
Sensor Design Example 2」をビルドして動かすまでを紹介した
スにいろいろ遊んでみる場合、こと「Nios II On-die Temperature
のだが、実はうまく動かなかった。このサンプルプログラムは 1 秒
Sensor Design Example」に関しては古いバージョンの Quartus II
おきに温度を表示する他、基板上のディップスイッチにあわせて基
を利用するのが無難そうである。
板の LED の On/Off が操作可能な「はず」だったのだ。
余談であるが、Quartus II/Quatus Prime は複数バージョンを
前回の最後で「IP の形で提供されるデバイスが 14.1 → 15 に
混在してインストールできる。インストールディレクトリさえ分けて
Version up された際に何か仕様が変わっており、それを上手くフォ
いれば別に問題はない。ということで現在筆者の環境には 3 種類
ローアップできていない感じがする」と書いたが、その後にアレコレ
(Quartus II 14.1/15.0、Quartus Prime 15.1)が混在している
試行錯誤した結果、どうも当たりだったらしい。
しばらくの間「Quartus II 15.0」と格闘したものの状況は変わ
状況である。
らず。その後、「Quartus Prime 15.1 Lite Edition」にバージョ
NIOS IIの処理能力をベンチマークで測定する
ンアップしても状況が変わらなかった。
ということで無難に NIOS II が利用可能になったところで、もう
そこで試しに「Quartus II Web Edition 14.1」を入手してイン
少し遊んでみることにする。取りあえず知りたいのは「NIOS II が
ストール、アップデートをかけて(これもアップデータは同じ URL
どの程度の処理性能を持つか」である。こういう場合、何かしらの
から入手できる)Version 14.1.1.190 となった Quartus II で前回
ベンチマークを走らせてみるのが一番手っ取り早い。ということで、
Dhrystone を走らせてみた。
Dhrystone そのものはいまさら説明は要らないと思うが、非常
に古くから使われている整数演算用ベンチマークである。幸いな事
に、現在でもベンチマークは探せば入手できる(ここなど)ので、
まずは入手して適当に展開しよう。必要なファイルは dhry.h(ヘッ
ダファイル)、dhry_1.c(メインルーティン)、dhry_2.c(サブルー
ティン)の 3 つである。
さて、まずハードウェア(つまり Quartus II で直接記述する方)
はそのままにして、
まずはソフトウェアだけ入れ替えてみる。まずは
ここと同じ手順で、別の名前で新しいプロジェクトを立ち上げる
(Photo02)。
次に、Project Exploler のウィンドウに、先ほどダウンロードし
Photo01: 下の NIOS II Console を参照。ちゃんと温度が順次、表示されているの
が分かる
た dhry.h と drhy_2.c をドラッグアンドドロップで投入する。する
と「コピーかリンクか」を聞いてくる(Photo03)ので、どちらか
※このページのムービーはこちら → https://www.youtube.com/watch?v=fEwWo_a6hko
31
Photo04: よく見ると dhry21a.c( 上の説明で言うところの dhry_1.c) も入っている
が、これは後で外して hello_world_small.c に上書きの形にした
{
int n;
Photo02: 名前は自分が分かればなんでもいい
scanf ("%d", &n);
好きなほうを選択(筆者はコピーを選んだ)すると、Project
Number_Of_Runs = n;
Exploler にこれが追加される(Photo04)。ちなみに dhry_1.c で
}
あるが、こちらは中身をコピーして、自動生成される hello_world_
printf ("\n");
small.c にそのまま貼り付けた。
さて、これをコンパイル……してもさすがにそのままでは通らな
printf ("Execution starts, %d runs
い。そこで、最低限の変更をする。変更は dhry_1.c(の中身をコ
through Dhrystone\n",Number_Of_Runs);
ピーした hello_world_small.c)だけである。List 1 がオリジナ
*/
※
ルの dhry_1.c であるが
Number_Of_Runs = 100000;
という具合に 10 万回の決め打ちにしている。性能を比較するだ
けだからこれで十分であろうという判断だ。
もう 1 つの変更は時間測定である。もともとのコードでは、ベン
チマーク開始直前と終了直後に clock() という関数で現在のシステ
ム時間を msec 単位で取得してここから性能を測定しているが、
NIOS II の環境ではこれが利用できない。そこで代わりに NIOS II
Photo03:「コピーかリンクか」を選ぶ。「Link to file」を選ぶと、現在展開した場
所から読み込むことになりちょっと不便なので、プロジェクトディレクトリにコピーする
ほうを選んだ
の HAL API の Timestamp 機能を利用した。
・経
過時間の計算や Dhrystone スコア計算のために float 型を
ベンチマークの前後で alt_timestamp() を呼び出してタイムスタン
使っている
具体的にはまず alt_timestamp_start() を呼んで初期化した後、
プ値を取得、後でこれを引き算して経過時間を取得して表示する形
・ 何回ループを回すかを STDIN から入力する
にした。ちなみにこの alt_timestamp_start() や alt_timestamp()
・ 出力結果をファイルに出力する
を利用するためには、冒頭に
といったコードが入っており、このあたりはテストをするのに不要な
のでまるまる削除した。ちなみにループ回数は
#include "sys/alt_timestamp.h"
#include "alt_types.h"
/*
printf ("Please give the number of runs
through the benchmark: ");
を追加する必要があり、また alt_timestamp() の戻り値は alt_
u32 型なので、これにあわせて変数宣言を変更している。List 2 ※
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news006.html
32
がこれらの変更を行ったソースコードである。
ビルドしてDhrystoneを実行
さて、これをビルドして実行であるが、Run Configuration の
前に実行するプロジェクトをキチンと切り替えておくことを忘れずに
(Photo05)。切り替えて実行したところ、見事に Dhrystone が完
走した(Photo06)。
ただ、走った事はいいのだが、肝心の時間測定ができていない。
実 は alt_timestamp() はシステム・ クロック( の Timestamp
Timer)が利用できないと戻り値が 0 になる仕様なので、これの対
応を追加してやる必要がある。
Photo07:Interval Timer を追加。名前は後で右クリック→ "rename" で変更できる
ということで、再び QSYS に戻る。QSYS は現状この状態に
で、かなり細かく数字が取れるはずだ。
なっていて、よく見ると「one_sec_timer」なる Interval Timer
ちなみに配 線として clk/reset/s1/irq の各 配 線 は one_sec_
が既に存在しているのだが、こちらは 1 秒単位での測定しかしない
timer と同じようにつ ないで おく。以 上 が 完了したら右 下 の
ものなので、もう少し細かい精度がほしい。
「Generate HDL」ボタンを押して設定ファイルを生成、ついで
そこで左上から Processors and Peripherals → Peripherals →
Quartus II の画面に戻ってビルドをやり直し、最後に Programmer
Interval Timer と 選 び、も う 1 つ Interval Timer を 追 加 し た
を使って MAX 10 に書き込むところまでを繰り返す。
。こちらは右ペインにあるように、Period を 1 μ s としたの
(Photo06)
ソフトウェアを対応させる
次はソフトウェア側の対応である。ここでは追加した「sys_clk_
timer」をシステムタイマーとして利用する事を教えてやらなければ
いけない。
Eclipse の画面で「NIOS II」→「BSP Editor」を呼び出し
(Photo08)、「Dhrystone_bsp」の下にある settings.bsp を読
み込むと、「timestamp_timer」の値が「none」になっているは
ずなので(Photo09)、これを「sys_clk_timer」とする。これが
終わったら右下の Generate ボタンを押して BSP を生成し直す。
次にこれをプロジェクトに反映する。Eclipse で BSP 側を右ク
リックし、「NIOS II」→「Generate BSP」を選択した後にビル
Photo05: プロジェクト切り替えを忘れると、Dhrystone を走らせるハズが、延々と
温度を表示し続ける
ドしなおすと、今度はシステムクロックがちゃんと存在する状態でプ
ログラムが構築される。そこで実行すると Photo12 の様に、キチ
ンと所要時間が表示されるようになった。
さて、この所要時間は、実際には Tics(何 Clock 経過したか)な
Phoot06: この表示は「正しく Dhrystone が実際されたか」を確認するもので、結
果は全て正しいことが分かる。問題は Elapsed が 0 な事だけだ
Photo08: ディレクトリはプロジェクト名が Dhrystone の場合にはプロジェクトディレ
クトリの下の "software\Dhrystone_bsp" の下になる
33
性がある。興味のある方はぜひ、いろいろと設定を変えてみていた
だきたい。
ということでプロセッサが実用に耐えることが分かったので、次は
もう少しデバイスと組み合わせてみたい。
Photo09: ちなみに今回は timestamp 系の HAL API を使ったので timestamp_
timer を有効にしたが、逆に sys_clk_timer 系の API を使いたければこちらを有効
にする
Photo13:CPU コアを「Nios II/e」にするとリソース最適モードとなり余分なオプ
ションは一切使えず性能も低い。これを「Nios II/f」にするといろいろなオプション
が使えるようになる
Photo14:「Nios II/f」にすると、ここでキャッシュの有無やサイズなどを選べるよう
になる
Photo12: これが出てきたときには思わず安
(あんど)のため息が ( 笑 )
ので、実際には 50MHz 駆動で 8 億 5300 万 173clock ということ
で、17.06 秒ほどの時間となる。10 万回で 17.06 秒なので性能は
大 体 5861.7 Dhrystone/sec という数 値 になる。 基 準となる
(1757.0 Dhrystone/sec)
と比較すると 3.34
VAX11/780 のスコア
DMIPS という計算である。
これが速いか遅いかはどう使うか次第ではあるが、こちらのページ
に記載されている値に比べると、
MAXQ よりやや遅い程度で Texas
Instruments の MSP430F149 よりは高速、というのはそう悪くな
いのではと思う。
ちなみに QSYS でプロセッサの設定を見ていただく(Photo13
∼ 15)と分かるのだが、今回はリソース最適化でプロセッサを構
成しているので、このあたりを変更すればもっと性能は上がる可能
34
Photo15: 乗除算性能が必要な場合は Nios II/f ではこれらをハードウェアで実行さ
せることも可能。デフォルトはソフトウェアエミュレーションなので遅い
FPGA のソフトコア CPU をベンチマークで測定する
MAX 10 FPGA で学ぶ FPGA 開発入門(8)
周辺機器の充実した「MAX 10 NEEK」で
本格的な開発を目指す
これまで FPGA の開発基礎として L チカなどを紹介してきたが、今回はちょっと目先を変えて FPGA 上での CPU コア動
作に取り組む。
「MAX 10 NEEK」
アルテラの開 発ボード
「MAX 10 FPGA」でソフ
トコア CPU を構築し、ベ
さて MAX 10 NEEK はちょっと大きめの箱で届いた(Photo01)
。
ンチマークの Dhrystone
内部は MAX 10 NEEK 本体と付属品のみであり、ソフトウェア類は
も動いた。ではいよいよ
。
Terasic のサイトからダウンロードする形になっている(Photo02)
CPU と FPGA に周辺回路
LCD の裏には基板が実装されている(Photo03)が、細かなチップ
を組み合わせて、I/O のハ
ンドリングを試してみる事
にしよう……と思っていた
の説明は MAX 10 NEEK の紹介ページ写真に詳しいので割愛する。
Photo01:「MAX 10 NEEK」のパッケージ。
パッケ ー ジ サ イズ は 285mm × 186mm ×
88mm(実測値)とやや大きめ
矢先、アルテラから「よければ MAX 10 NEEK を使ってみません
か?」という申し出を頂いた。
この「MAX 10 NEEK」は台湾 Terasic が製造し、アルテラも
販売する MAX 10 評価ボードの 1 つだが、なにしろ周辺回路がて
んこ盛りなのが特徴。5 タッチセンサー付き LCD モニター(800
480Pixel)、カメラ、オーディオ入出力、温度/湿度/照度/加速
度センサー、パワーモニター、ADC 入力/ DAC 出力、スイッチ/
ポテンショメータ/ LED / 7 セグ LED など搭 載されており、
DDR3 メモリ(合計 256KB)、512Mbit Flash、MicroSD カー
おまけにギガビットイーサネットや UART
ドなども搭載されている。
to USB、PS/2 キーボード・マウスなどのインタフェース、更に
TMD(Terasic Mini Digital)拡張コネクタも用意され、USB
Blaster II まで実装されているから、本当に USB ケーブルをつな
ぐだけで開発が行えるという優れものである。
難点はお値段で、Terasic の直販では $359、販売代理店経由
Photo02: さすがに USB 給電では足りないようで、5V/3A 出力の AC アダプターが
付属する。他に USB Blaster II と接続用の USB ケーブル、Quick Stard Guide、
それとここには見えていない(NEEK 本体に既に装着されている)MicroSD カード
が付属する
だと、例えば MOUSER Electronics だと \47,185.9 と表示され
ている。昨今の円高を考えると USD で決済したほうが多分安いと
は思うのだが、
それにしても $359 はちょっとお高めということで当
初は見送った開発キットである。
ただし念のために言っておけば、これまで使ってきた「MAX 10
Evaluation Kit」は本当に MAX 10 に習熟するためのトレーニン
グキットであって、これを本格的な開発に使うのはちょっと無理が
ある。一方、MAX 10 NEEK はもう製品開発を指向したもので
あって、最終製品に近いレベルのプロトタイプまで作れる。これが
$359 というのは相場で考えてもかなりお安い部類に入る。まぁそ
うは言っても遊びで入手するのにはちょっと、二の足を踏んでいた
のだが、使わせて頂けるならこれ幸いと 1 台手配していただいた。
Photo03: 基板を写真と比べると、若干の仕様変更(MIPI I/F の端子がなくなり、LCD
コネクタ下の穴のサイズが小さくなり、Lineae Technology のロゴが入った)が見
られる。アクリルカバー付き
35
充実のビルドインプログラム
さて、まずはビルドインのソフトウェア(アプリケーション)を簡単
にご紹介したい。添付の MicroSD カードをスロットに装着した上で
AC アダプターをつなぎ、電源を ON にする(Photo03 で左上の赤
いボタンを押す)と、スタートアップ画面(Photo04)の後でメニュー
。
が出てくる(Photo05、06)
Photo06: メニュー(2)指で選んでから、左下の Load ボタンを押すとそれぞれス
タートする。ちなみにそれぞれを起動した後で再びメニューに戻る方法は無いので、
電源 Off →電源 On で戻る
Photo04: まず画面全体がホワイトアウトして、しばらくしてからこの画面になる。
MicroSD 経由ということもあり、処理はややゆっくり
ソフトは「painter」
「spider」
「camera」
「g_sensor」
「hdmi_rx」
「mic_adc」と用意されている。
「humidility_temperature」
・P
ainter(Photo07): マルチタッチスクリーンの動作サンプル。最
大 5 本までのタッチを検出して、それぞれ別の色でペイントする。
・S
pider(Photo08):Terasic がリリースしているクモ型の多脚ロ
ボット「Treasic Spider Robot」のコントローラーとなる機能。ち
なみにこれを利用するためには別売りとなる「Terasic BTS-TMD
Photo07:「Painter」の画面。ちょっとタッチ感度がよすぎて、タッチ前に検出され
ることもあった
Bluetooth Adapter」を併用する必要がある。
Photo08:Bluetooth Adapter はちゃんと技適を通っているので国内でも利用可能。
お値段は Terasic のサイトで 50$ だそうである。ちなみに Spider Robot は $1200
Photo05: メニュー(1)実は 2. の Spider はマニュアルには記載されていなかったり
する
・c
amera(Photo09): フロントカメラの映像を画面に出力するだけ
そこを中心にフォーカスを合
の機能。ちなみに画面をタッチすると、
わせる機能(Photo10)も用意されている
36
MAX 10 NEEK から操縦できる、クモ型の多脚ロボット「Treasic Spider Robot」
Photo09: あくまでカメラのデモなので、撮影して保存とかの機能は(もちろん)ない
Photo11: これ は 斜 め にした 状 態 な の で、 上 下 方 向 が 24 °
と 示 さ れ て い る。
Brigthness は表面と裏面のそれぞれの数値
Photo12: 手近に HDMI 出力できるプレーヤーがなかったので、取りあえず PC につ
ないで BIOS Setup 画面を出してみた
・m
ic_adc(Movie1 ※)
:ADC のデモ。マイクから入力した音声
を ADC 経由で取り込んで、そのまま表示する。ちなみに映像の
音源には Misuc-Notes.jp のファンタジー系 BGM 素材から
「ルービックキューブ」を利用させていただいた。
Photo10: 指で触ると、そこを中心にフォーカスを定める感じ
・ g_sensor(Photo11): 加速度センサーと照度センサーのデモ。
・h
dmi_rx(Photo12):HDMI 入力のデモ。ちなみに画面だけ
でなく、HDMI 経由の音声をデコードして出力する機能もある。
・h
umidility_temperature(Photo13): 温度 / 湿度センサーの
デモ
Photo13: 温度が異様に高いのは、NEEK ボードを連続稼働させた結果ボード全体の
温度が上がっているためで、室温ではない
※このページのムービーはこちら → https://www.youtube.com/watch?v=cXzQlqS-sUI
37
MAX 10 NEEKでの開発
デモで遊んでいても面白みは無いので、実際に簡単にいじるため
の方法を説明する。まず Terasic のサイトの MAX 10 NEEK の
Resource ページに移 動する。ここで MAX 10 NEEK CDROM をダウンロードする(Photo14)。今回入手したのは、執筆
時点で最新版となる v1.0.7 である。
このうち htm はこんな感じ(Photo17)でビジュアル的な要素
は少なく、必要な情報が一覧で示されるだけである。
これが生成されたら、この 5 つのファイルを適当なフォルダに移
動(今回は "C:\altera\15.1\Projects\NEEK_LED" というフォル
ダを作り、その下に移動した)してから Quartus II を起動するわ
けだが、その前に MAX 10 NEEK の接続である。
Photo03 で言えば左上、PS/2 ポートの左に Mini USB のコネ
ここに USB
クタがあるが、
これが USB Blaster との接続用である。
ケーブルを装着し、PC と接続してから MAX 10 NEEK の電源ス
イッチを On にする。ドライバは Quartus II のインストール時、シ
ステムに入っているので自動認識されるはずだ。
Photo14:ダウンロードには無料のユーザー登録が必要。筆者の場合、以前 Terasic
から USB Blaster を購入した際に登録済であるが、まだの人はダウンロードを選ぶと
飛ばされる Member ページで Join Now を選んで登録してからダウンロードを行
う形になる
これをダウンロード後、適当なディレクトリに解凍する。このディ
レクトリの中の Tool \ SystemBuilder というフォルダの中に、
MAX 10 NEEK 専用の System Builder が含まれている。これを
起動すると、MAX 10 NEEK のどの機能を利用したいかを選べる
(Photo15)。
取りあえずは L チカということで、Clock と 10 個の LED のみ
有効にして、これを NEEK_LED というプロジェクト名で生成する
。プロジェクト名と必要な項目を選んで
ことにする(Photo16)
"Generate" ボタンを押すと、指定のディレクトリに以下の 5 つの
ファイルが生成される。
Photo15: デフォルト状態ではこれだけ利用可能。「Ethernet」とか「DDR3」もお
いおい試してみたいと思う
38
Photo17: ピンの名前とピン番号、入出力、信号レベルが一覧で示される
「MAX 10 NEEK」のプログラミング
をインクリメントするとともに、どの LED を表示するかを定める
ではサンプルコードを書いてみる。
今回は
「Quartus Prime 15.1
LED は全部で 10 個なので、dec_cntr が 10 になったら 0 に戻
Lite」を使ってみた。まずは Open Project を選び、先ほど格納し
している。disp_cntr の方は、右から左に LED が流れるようにシ
た(今回なら NEEK_LED.qpf を指定する、Photo19)。すると
フト演算の形で 1 の値の位置を移動している。これを assign で
disp_cntr というレジスタを書き換えるというものだ。
NEEK_LED.v が開かれるが、この状態では下の List 1 に示すよ
LEDR(LED 出力)に割り当てて完了である。
うに、中身は空っぽである。今回は、0.1 秒間隔で LED を順に光
これをコンパイルすると特に問題なく生成されるはず(筆者のマ
※
らせる、
ということでこれを List 2 の様に書き換えてみた。書き換
シンだと 46 秒ほど要した)なので、Programmer を使って書き込
えたのは、REG/WIRE declarations と Structural coding の
こ
んでやると完了である(Photo20)。プログラミングが終わると、
みだ。
んな具合に LED が流れるように点滅するはずだ(Movie02 ※)。
※
ということで今回は MAX 10 NEEK を紹介した。来月はここに
NIOS II も組み込んで、もう少し本格的に取り組んでみたい。
Photo19: ここで Project Wizard を起動して新規にプロジェクトを生成すると、ピン
配置とかを全部手動で設定せねばならないので結構面倒である
おおむね昔の L チカに近いが、一応意図を説明しておけば、外
これを 50 万回(つ
部からは 50MHz でクロックが入ってくるので、
まり 5M 回)ごとにカウントし、内部の dec_cntr というレジスタ
Photo20:搭載される MAX 10 は 10M50DAF484ES で、MAX 10 Evaluation
Kit に搭載されていた 10M08SAR144ES と比較すると LE 数は 8K → 50K に、Flash
Memory は 144KB → 484KB に、 そ れ ぞ れ 強 化 さ れ て い る。 メ モ リ も
378Kbit → 1638Kbit と4倍になっており、NIOS II を使うにも支障はなさそう
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news007.html
ムービーはこちら → https://www.youtube.com/watch?v=38zzNVggEyM
周辺機器の充実した「MAX 10 NEEK」で本格的な開発を目指す
39
MAX 10 FPGA で学ぶ FPGA 開発入門(9)
「MAX 10 NEEK」へソフトコアCPUを組み込む
周辺機器の充実した MAX10 搭載開発ボード「MAX 10 NEEK」に、ソフトコア CPU「NIOS II」を組み込み、ソフトコ
ア CPU からボード搭載 LED の制御までを紹介する。
前回より、周辺回路の充実した台湾 Terasic 製 MAX 10 評価
ボード「MAX 10 NEEK」を用いての本格的な開発に着手したの
だが、NEEK の話を始める前にちょっと以前の補足を。
なぜか Quartus II 15.0 を使うと TempSensor
連載第 6 回にて、
をビルドしても上手く動かないという話をご紹介した。また続く第 7
回の冒頭で、Quartus Prime Lite でもうまく動かないが、Quartus
II 14.1 ならば普通に動作するという話も紹介した。
これが「マニュ
これに関しては「BSP の再構成も必要」であり、
アルに記載がない」旨をアルテラよりご連絡いただいた。具体的に
はこの画面で、左ペイン下側にある「TempSensor_bsp」につい
ても再構築が必要、との事である。
ただ実はこれに沿って TempSensor_bsp についても Clean
Build → Build を行ってみたものの、状況に変化は無かった。これ
は Quartus II 15.0 でも Quartus Prime Lite も同じであった。現
Photo02:Photo01 では指定していない PS2 の信号線が定義されているのは、恐ら
くは System Builder のバグであろう。HEX0/HEX1 は 7 セグ LED
在もう少し詳細をアルテラに問い合わせ中なので、結果が分かり次
たコードがおかれているので、これを適当なところ(筆者は C:\
第、お伝えしたいと思う。
altera\15.0\Projects\ の下に NEEK_NIOS2 というフォルダを生成
NEEKへNIOS IIを組み込む
してここにコピーした)におく。
次に Quartus II(でも Quartus Prime Lite でもどちらでもい
さて、気を取り直して(?)NEEK である。
い。今回は Quartus II 15.0 を選んだ)を起動し、既存の Project
前回は取りあえず FPGA のみを使っての L チカをやってみたので、
のオープンを選んで、今生成された NEEK_NIOS2.qpf(Project
今回は NIOS II を組み込んでみたいと思う。まずは NEEK に付属の
File)を選ぶとこんな具合(Photo02)になる。
System Builder を起動して、必要なコンポーネントを組み込む
さて、次は NIOS II の組み込みである。これは System Builder
。すると System Builder の 下 に "CodeGenerated\
(Photo01)
では行えないので、QSYS を起動してこれを行うことにする。起
MAX10\NEEK_NIOS2" というフォルダが生成されて、今生成され
、まず は
動 直 後 は Clock Source し か な い の で(Photo03)
"Processors and Peripherals" → "Embedded Processors" →
"NIOS II Processor" をダブルクリックして NIOS II コアを登録する
。
(Photo04)
ちなみに MAX 10 NEEK に搭載されている 10M50DAF484C6G
は LE(Logic Elements) が 50K、Block Memory も 1638Kbit
(204.75KB)と最大規模のものなので、つい Nios II/f を選択したくな
るのだが、
こちらは有償扱い(一応無償で利用できる OpenCore Plus
ベースのものが利用できるが、時間制限付き)なので、諦めて Nios II/
。
e を選択する(Photo05)
設定画面に戻るとエラーが出ているが(Photo06)、それは気に
せずに次は "Interface Protocols" → "Serial" → "JTAG UART"
を追加する(Photo07)。その次は、"Basic Functions" → "On
Photo01: プロジェクト名は「NEEK_NIOS2」とした。7 セグメント LED は今回利用
を考えていないが、後で使うかと思って組み込んでみた
40
Chip Memory" → "On-Chip Memory(RAM or ROM)" で
RAM を登録する(Photo08)。
Photo03:Clock Source は自動で登録される。これは特にいじる必要がない
Photo06: エラーは後でまとめて解消する
Photo07:JTAG UART は特に設定の必要はない
Photo04:NIOS II(Classic) を選ばない様に注意
Photo05:NIOS II/f
Photo08: エラーは更に増えているが気にしてはいけない
ここで容量は 64KB を選んだが、これはまぁこの位あれば取りあ
だ(Photo09)
。
デフォルトの 4KB のままでも今回
えずいいだろうという事であって、
最後に、
10 個の LED の点滅用の Parallel I/O ポートの指定であ
の用途には十分である。むしろ注意点は、"Memory Initialization"
。"Processors and Peripherals" → "Peripherals"
る
(Photo10)
の所にある "Initialize memory context" のチェックを外しておく事
→ PIO( Parallel I/O )" を指定する形だ。今回は LED が 10 個
41
Photo09: なぜか "Initialize memory context" はデフォルトでチェック「On」に
なっている
Photo11: これはまだ 10 と指定する前。デフォルトは 8
Photo10:IP の場所にいまいち一貫性がないのが困りモノ
Photo12:Warning は大幅に減った。エラーはこの次に対処
なので、Width には 10 を指定する(Photo11)
。あと、デバイスの
名前を "pio_0" に変更しておく。
次に、それぞれの IP の結合を行う。Photo12 で赤丸をつけて
ある箇所をクリックして、黒丸(結合状態)にする形だ。例えば一
番左側の線はクロックドライバから出力されるクロック信号なので、
これを NIOS II、JTAG_UART、On Chip Memory、PIO の各
デバイスに供給するための設定がこれである。同様に Reset 出力、
JTAG から NIOS II への IRQ、データの送受信など必要な配線を
つなぐ形だ。
メモリアドレスの重複解除
その次は、メモリアドレスの重複解除だ。それぞれのデバイスはメ
これの調整が必要である
(Photo13)
。対
モリアドレスを専有するが、
策は簡単で、"System" → "Assing Base Addresses" を選ぶと自
。これでエラーはほとんどなくなるハ
動調整してくれる(Photo14)
42
Photo13:Address Map のタブを見ると、全てのデバイスが似たようなアドレスを
マッピングしようとしている。そりゃエラーにもなる
Photo17: ここで QSYS の出力はプロジェクト名 ( 今回だと NEEK_NIOS2) と同じに
してはいけない。あとでえらい目に合う ( というか、合った )。
Photo14: 全部エラーがなくなるわけではない
Photo18: これはおなじみの手順
Photo15: これは reset の Export を行ったあとの状況。最後は pio_0
Photo19: ちなみにこのメッセージ、QSYS を終了すると出たり、QSYS を終了させ
なくても出たり、とイマイチ状況をつかみきれない
export するようにすれば良い。
すると pio_0 の Export の Warning が残っているだけになる
。
(Photo15)ので、
"led_pio" という名称で Export する(Photo16)
これで完了なので、ファイル名をつけて(Photo17)保存後に HDL
の生成を行う
(Photo18)
。問題なければこのメッセージ
(Photo19)
が出てくるはずだ。
Photo16:Error/Warning ともに 0 になった
Quartus IIに戻って
ズだ。
さて、ここからは Quartus II に戻る。左の Files 画面で、まず
残るエラーは、クロックドライバの「clk_in_reset」という信号
現在表示中の NEEK_NIOS2.v、それと QSYS で生成した qip
に関係する部分だ。これは "Double-click-to-export" とグレーア
ファイル(今回だと NEEK_NIOS2_QSYS/synthesis/NEEK_
ウトされている部分をダブルクリックし、"reset" という信号名で
NIOS2_QSYS.qip)をプロジェクトに追加する(Photo20)。
43
ここで NEEK_NIOS2_QSYS.v の中身を見ると、こんな宣言
になっているハズ(Photo21)なので、この記 述にあわせて、
NEEK_NIOS2.v をこんな風に書き換える(Photo22)。List 1 に
書き換えた後のソースを示すが、要するに NEEK_NIOS_QSYS
へ制御を移す宣言である。この際にクロックソースは、もともと供
給される 50MHz のもの(MAX10_CLK1_50)を指定し、PIO
ポートには LEDR を指定する。リセットは常時 Off ということで、1
(True)を与えておく形だ。
ここまで終わったら Verilog 側のプログラミングは完了である。
あとはビルドし(Photo23)、問題が無ければ Programmer を利
用して .sof ファイルを書き込んで置く。
さて、今度はソフトウェアの方だ。Quartus II から "Tools" →
"Nios II Software Build Tools for Eclipse" を選び、Eclipse を
Photo22: コメントとかは別にまねする必要はない(念のため)
立ち 上 げる。 立ち 上 げ たらまず "File" → "New" → "Nios II
Application and BSP from Template" を選んでテンプレートか
ら生成する(Photo24)。
今回はメモリもたっぷりあるので、Hello World Small ではな
く、Hello World を選んでみた。あとは自動で Hello World とその
BSP が生成されるので、以前と同じ手順でビルドして実行する。問
Photo23: 利用率を見るとまだほとんど余っている状況
Photo20: ファイルの追加は、左上の File タブの中で、"Files" フォルダを右クリック
して "Add/Remove Files in Project..." を呼び出して、そこで行う
Photo21:File タブで NEEK_NIOS2_QSYS.qip を展開するとこれが出てくる
44
Photo24:sopcinfo は QSYS が生成しているので、これを指定する ( 今回の場合だ
と NEEK_NIOS2_QSYS.sopcinfo)
Photo25: まぁこれに説明の必要はないだろう
Photo26: コンソールは右ペインにある。Photo25 と比較してもらえると分かりやすい
題がなければ、NIOS II の Console に "Hello from Nios II!" が
に指 定したアドレスが PIO_0_BASE となっているが、これは
表示されるはずだ(Photo26)。
QSYS で指定した名前を大文字にして、最後に "_BASE" が付加
LチカをソフトコアCPUから操作する
されたものになる。これを実行すると、Movie01 ※の様に右端の
LED が一定間隔で点滅する。
さて、ここまでできたので次は L チカを CPU から操作する方法
では LED10 個を全部点滅させるにはどうするか?であるが、PIO
(Photo27)。まず PIO
である。コードを List 2 の様に書き換える
の場合、与える値のビットフィールドがそのままそれぞれの LED の
の操作を行う API(というかマクロ)は、altera_avalon_pio_
On/Off となる。つまり 0bit 目(LSB)が LED0、
1bit 目が LED1……
regs.h(これは BSP の方の drivers/inc の下にある)に定義され
となって、9bit 目が LED9 に相当する。というわけで、プログラムを
ている。IOWR_ALTERA_AVALON_PIO_DATA() がそれで、指
List 3 ※の様に書き換えて実行した結果がこちら(Movie02 ※)である。
定したアドレスに値を書き込むというものである。
ちゃんと全 LED が正しく点滅するのがお分かりいただけるかと思う。
今回だと値は cnt++ の値にあわせて 0 か 1 なので、点滅が行わ
次回はもう少しいろいろな周辺回路を NIOS II からアクセスして
れるというわけだ。続く for ループは単なる delay である。ちなみ
みたい。
※
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news008.html
ムービーはこちら → https://www.youtube.com/watch?v=bSDt3ObjnAE
「MAX 10 NEEK」へソフトコア CPU を組み込む
45
MAX 10 FPGA で学ぶ FPGA 開発入門(10)
「MAX 10 NEEK」に搭載された
DDR3メモリを使う
周辺機器の充実した MAX10 搭載開発ボード「MAX 10 NEEK」に、ソフトコア CPU「NIOS II」を組み込み、ソフトコ
ア CPU からボード搭載 LED の制御までを紹介する。
Nios II On-die Temperature Sensor
Design Example
そもそも動かない原因は 2 つあり、1 つは BSP の再ビルドが必
要だった事、もう 1 つは ADC の初期化コードが含まれていなかっ
た事だ。1 つ目については前回紹介した通り、TempSensor_bsp
先月も触れた、MAX 10 Evaluation Board と TempSensor
の再構築を実施すればよい。問題は 2 つ目だ。
の話であるが、やっと問題が解決したので最初にこちらの話をして
アルテラによれば、ADC に対してまず初期化の際に割り込み禁
おきたい。
止を実施する必要があるとの事。ただしこれが Altera のドキュメン
経緯を説明すると、アルテラの Web サイトで提供される MAX
トから欠落しており、またサンプルコードにもこの割り込み禁止を
10 Evaluation Board 用 の サ ンプ ル で あ る「Nios II On-die
行う処理が抜けていた。この結果、NIOS II が起動して ADC を有
Temperature Sensor Design Example」(現在は存在しない:
効にした途端、ADC からの割り込みが発生する事になる。悪い事
理由は後述)をダウンロードし、マニュアルの手順に従って構築す
に今回のサンプルでは割り込みハンドラが無いので、割り込みが発
る際、Quartus II 14.1 を使う限りにおいては正常に動作するのだ
生してもユーザープログラムに制御が一切戻らないという事になっ
が、Quartus II 15.0、あるいは Quartus Prime を利用すると
ていた。
NIOS II コアが正常に動作しないという現象が出ていた。この件に
対策であるが、現在のサンプルでは初期化ルーティンが
関して、Altera より正式に原因と対処に関しての連絡を頂いた。
//Starting the ADC sequencer
IOWR(MODULAR_ADC_0_SEQUENCER_CSR_BASE, 0, 0);
usleep(10);
IOWR(MODULAR_ADC_0_SEQUENCER_CSR_BASE, 0, 1);
となっている。これを
//Starting the ADC sequencer
IOWR(MODULAR_ADC_0_SEQUENCER_CSR_BASE, 0, 0);
usleep(1000);
IOWR(MODULAR_ADC_0_SAMPLE_STORE_CSR_BASE, 64, 0);
IOWR(MODULAR_ADC_0_SEQUENCER_CSR_BASE, 0, 1);
と変更する事で解決できるとの話であった。この 3 行目に追加さ
ていた。だが、Quartus II 15.0 以降ではこれが変わってしまって
れた "IOWR(MODULAR_ADC_0_SAMPLE_STORE_CSR_
いた、という事が真相の様だ。
BASE, 64, 0);" が、ADC に割り込みの発生を禁止させる設定であ
既 に こ の Nios II On-die Temperature Sensor Design
。 Example は Nios II On-die Temperature Sensor Design
る。これを入れたところ、正常に動作するようになった(Photo01)
46
ち な み に な ぜ Quartus II 14.1 で 動 作 した の か で あるが、
Example 2 (15.0 用、15.1 用)としてアップデートされており、
Quartus II では明示的に初期化していない設定値をどう扱うか、に
こちらでは問題は解決している。また ADC のドキュメントへの反映
関してバージョン毎 に異 なっているのだそうで、「たまたま」
を現在本国に依頼中との事で、新しくサンプルをダウンロードすれ
Quartus II 14.1 では ADC の割り込みを無効化する初期値になっ
ば問題は解決する筈だ。ということで、やっと一件落着である。
Photo01: 一番右に NIOS II のコンソールが開いており、正しく温度も取得できて居
る事が分かる。ちなみにソースは最終版になる前の、暫定バージョンなので注意され
たい
MAX 10 NEEKに搭載されたDDR3メモリを使う
Photo04: このサンプルは Terasic 製
さて、今回は NEEK に搭載された DDR3 メモリを使ってみたい。
MAX 10 NEEK には、FPGA 内に内蔵された SRAM とは別に、
外部に DDR3 メモリが搭載されている。DDR3/LPDDR2 の I/F
は MAX 10 に標準搭載されており、なので基本 DDR3 ないし
LPDDR2 を搭載すれば MAX 10 からこれを利用する事ができる。
Photo05:先頭は Timer とか LED、スイッチ類が大量に入っている。ddr3_status、
というデバイスがあることに注意
Photo02:ここで言う "KEY0" は NEEK のボード側の KEY0( スライドスイッチの左 )
である
Photo06:NIOS II コアとかオンチップの SRAM、DDR3 I/F などは最後の方に
もちろん、NIOS II からの利用も可能だ。
MAX 10 NEEK の System CD を展開すると、
Demonstrations\
ddr3_nios の下に、
NIOS II から DDR3 をアクセスするためのサンプ
ルコードが用意されている。まずは手始めに、MAX 10 NEEK を起
Photo03:ちなみにテストを止める方法は無いので、放っておくと延々とテストが繰
り返される。
動して USB Blaster II を接続した状態で、Demonstrations\ddr3_
こんな
nios\demo_batch の下にある ddr3_nios.bat を起動すると、
47
Photo07:オンチップメモリは 0x0 ∼ 0x1f3ff までにマッピングされている
画面になるはずだ
(Photo02)
。KEY0 を押すと、
NIOS II から DDR3
メモリへの読み書きがテストが開始される
(Photo03)
。問題がなけれ
ば、test 結果は Pass になる。
この demo_batch の下はバイナリの形で提供されているので、
これを自分でビルドしなおしてみよう。
Demonstrations\ddr3_nios の下を丸ごと他のフォルダにコ
ピーして、Quartus II から "File" → "Open Project..." で ddr3_
nios.qpf を選択してプロジェクトを開く(Photo04)。そのままコ
Photo09:ここはメモリチップにあわせての設定となる。ちなみに Total Interface
Width が 24bit なのは、16bit 接続と 8bit 接続が混在しているから
Photo08:Speed Grade は 6(DDR3/LPDDR2) 固定。速度は今回 300MHz となっ
ている
48
Photo10:Memory Timing は、データシートの Typ 値に準じる形で入力
Photo11:こちらはメモリというよりはボードの設計にあわせる
Photo13:ここはデフォルトのままで
Photo14:コアは Nios II/f だが、オプションは最小限
ンパイルしてもいいのだが、構成を確認するために QSYS を開いて
みる(Photo05,06)。
メモリマップはこんな感じ(Photo07)で、0x08000000 ∼
0xfffffff に DDR3 メモリがマッピングされていることが分かる。マッ
ピングを見る限り、スタックとかダイナミックな変数に DDR3 の領
域を使うのは、そのままでは無理(Eclipse で C++ のソースのビ
ルドの際にリンクオプションで設定をしない限り自動では使ってく
Photo12:Memory Controller の設定。バースト長 4 というのは、DDR3 というよ
りはメモリコントローラ側の設定
れない)だが、プログラム内からアドレスを指定して利用するのは
問題なさそうだ。
49
Photo17:これが毎回出てくるのがちょっと面倒
Photo15:DDR3 回りの Timing で幾つか Warning が出ているが、無視して構わない
Photo18:この状態で "Start" を押せばよい
Photo16:このままだと _time_limited の有無のどちらが新しいのか分かりにくいの
で、ファイルの生成時刻も表示させるとよい
以下 Photo08 ∼ Photo13 が、その DDR3 I/F まわりのパラ
メータとなる。今回はこれをいじる必要はないが、自分で DDR3
を利用して何かやりたい、という場合にはこれに準じる形でパラ
Photo19:フラッシュメモリに書き込んで起動するような場合、OpenCore Plus で
は確か 1 時間の利用制限が付く(電源投入後、1 時間だけ Nios II/f が動作する)
メータの設定を行う事になる。また今回、デフォルトでは CPU コ
アは Nios II/f となっている(Photo14)。これは Terasic が Nios
開発用には OpenCore Plus ベースのものが利用できるが、
こち
II/f のライセンスを保有しており、これを利用して開発を行った為だ
らは時間制限付きとなっている。ファイル名に time_limited がつ
ろう。これについては後でちょっといじって遊ぶが、取りあえずはこ
いているのはこのためだ。この "_time_limited" 付を選ぶと、こん
のままで行くことにしたい。
な警告メッセージ(Photo17)が出てくるので OK を押して、その
Generate HDLで構成を生成
まま MAX 10 にロードする(Photo18)。
ロードが終わるとダイアログが表示される(Photo19)が、これ
もろもろ確認したら、Generate HDL を押して構成を生成する。 が Time Limited の制約である。今は USB Blaster 経由でロード
この際に Photo14 にもあるように Warning が出ているが、これは
しているから、このダイアログを表示させている間はずっと Nios II/
Quartus II というか QSYS の既知の問題(pll_sharing Warning
f を使い続けられるという意味で、ここで Cancel を押すと Nios II/
Message May Appear)なので、無視して差し支えない。
f が利用できなくなる。なので、Cancel を押さずに次に移る。
HDL の生成が終わったら Quartus II に戻ってコンパイルを行う
次はソフトウェア側である。まず Eclipse を立ち上げた後、"File"
(Photo15)。その後にはプログラミングであるが、Programmer
→ "Import..." で Import Menu を表示させ、ここから "Import
から "Add File..." を選ぶと見 慣 れないファイルがあるはずだ
50
Nios II Software Build Tools Project" を選ぶ(Photo20)。
(「MAX 10 NEEK」
へソフトコア CPU
(Photo16)。これは第 9 回
するとフォルダの参照になるので、先にコピーしたフォルダの下
を組み込む)でもちょっと触れたが、Nios II/f は有償であり、その
にある software\ddr3_nios を選ぶ(Photo21)び、Project
ままでは利用できないためだ。
名には ddr3_nios を選ぶ(Photo22)と、ちょっと時間を置い
Photo20:この Import、意外に分かりにくい
Photo22:指定を行うと、しばらくバックグラウンドでファイルの確認を行い、正常に
Import できると判断されると "Next" と "Finish" ボタンが有効になる
Photo21:フォルダ指定は "software" ではなく、その下の "software\ddr3_nios"
まで行う必要あり
て「Finish」ボタンが有効になるので「Finish」を押して、プロ
ジェクトを丸ごと Import する。同様に、ddr3_nios_bsp も Import
する(Photo23)。
2 つの Project の両方とも「Clean Project」を指定してクリア
にした後で、ddr3_nios_bsp のプロジェクトを右クリック、 Nios
II
→
Generate BSP を 指 定 して BSP の 再 構 築 を 行 う
(Photo24)。
Photo23:bsp は自動では入らないので、こちらも同じように指定する
る。問題なければこんな具合に実行が始まる(Photo26)。問題が
無ければ、Write と Read/Verify が 21 秒で完了するはずだ。
これが済んだらまず ddr3_nios_bsp をビルドし、次に ddr3_
さて、ここまではサンプルにある「ddr3_test」そのままである。
nios をビルドする。完成すると Warning が 1 つ出るが、これは無
これを NiosII/e に切り替えるとどの位遅くなるか、をちょっと試し
問題(Photo25)。Run Configuration で設定を行ったら実行す
てみた。
51
52
Photo24:これが必要ない場合もある。Import した場合、BSP をビルドしようとす
ると "BSP を作り直せ " と怒られるので、これをやっておくと無難
Photo26:一番右の NIOS II Console に、Photo03 と同じような表示が出てくるは
ずだ
Photo25:Warning の内容は、alt_dcacche_flash_all() の型指定が無いというもの
Photo27:Nios II/e に切り替えると目に見えて遅くなる
手順は簡単で、QSYS のプロパティ画面(先の Photo14 だ)で
成 → プロジェクト再構築 → 実行、という流れである。
Nios II/e に切り替え、QSYS で Generate HDL → Quartus II
結果はご覧の通り(Photo27)で、60 秒と Nios II/f に比べて
でコンパイル → Programmer で書き込み
(今度は _time_limited
3 倍近い時間がかかっている。次回はこのあたりをもう少し試して
の付かない ddr3_nios.sof を指定する)→ Eclipse で BSP の生
みたい。
MAX 10 FPGA で学ぶ FPGA 開発入門(11)
「MAX 10 NEEK」でストップウォッチを
開発し、内蔵メモリから起動する
アルテラの FPGA「MAX 10」を搭載した開発ボード「MAX 10 NEEK」には LED やフラッシュメモリなどの各周辺機器
が備えられている。今回は LED を使ったストップウォッチを開発し、内蔵メモリから起動する。
この連載ではアルテラの FPGA「MAX 10」を題材にしているお
り、ここ数回は各種周辺機器も備えた MAX10 搭載開発ボード
「MAX 10 NEEK」を使って周辺機器へのアクセス方法などを紹介
はうち 4 つ)も活用する。ということで、最初は System Builder
である(Photo01)。プロジェクト名はひねりがなくて恐縮だが
「NEEK_LED3」だ。
している。
ファイルが生成されたら、それを Quartus II(今回も 15.0 を
前回は DDR3 を利用する方法を説明したが、今回は内蔵 Flash
使った)のプロジェクトディレクトリにコピーしたのち、Quartus II
を使ってみたい。
でそのプロジェクトを開く。次いで QSYS を立ち上げて、プロセッ
もともと MAX 10 の場合、内部に Flash Memory を保持して
サコアと JTAG UART、オンチップメモリを組み込む手順までは第
おり、ブート時にはここから Configuration を読み出して即座に実
行できるので、これを利用できるようにしてみたい。もちろん、ソ
フトコア CPU の「NIOS II」を含めて、である。
9 回と同様だが、追加で作業を行う。
これらの 手 順 を 終 えると、 最 終 的 にはこん な 感じになる
(Photo04)。
下準備
ポートの名前
さてまずは前準備。今回は連載 第 9 回(「MAX 10 NEEK」へ
ちなみに追加した 4 つの PIO ポートの名前だが、これは MAX
で紹介した内容をもとに簡単なストッ
ソフトコア CPU を組み込む)
10 NEEK の System Builder の生成するソース(NEEK_LED3.
プウォッチを NIOS II ベースで構築してみる。
第 9 回では NIOS II の組み込みがメインであったので、LED と
7 セグメント LED はを組み込んだだけ(しかも実際には使わなかっ
た)だったが、今回はこれを活用する。ついでにボタン 5(実際
Photo01:DDR3 メモリは今回はちょっとおいておく
Photo02: 出力の場合、特にその他はいじる必要はない。初期値も特に設定しなくて
も今回は構わない
53
MAX 10 に書き込む(Photo06)。記述を間違えなければ、ここ
で問題が出ることは無いはずだ。
NIOS IIで動作するストップウォッチをプログラム
さて次は NIOS II 上で動作するプログラムの方だ。まずは第 9
回 の 手 順 と 同 じ よう、" Nios II Application and BSP from
Template " から Hello World のテンプレートでアプリケーション
を生成する(Photo07)。
このままでは文字通り、単なる「Hello World」なので、これを
Photo04: これは結線が全部完了し、さらに QSYS の "System" → "Assign Base
Address" を実施してアドレスの整合性を取った後の状況である
v)が List 1 ※の様になっている事を踏まえ、これと名前をあわせた
形だ。また、4 つの PIO については、いずれもそれぞれの名前で
Export を行っておく("Double-click to export" と書かれている
部分をダブルクリックすると名前 +"_pio" で Export される指定と
なる)。Photo04 で言えば、"ledr_pio"、"hex0_pio"、"hex1_
pio"、"key_pio" がこれにあたる。
ここまで完了したら名前(今回は "NEEK_LED3_QSYS" とし
た ) を付 けて保 存 後 に、Generate HDL で HDL を生 成する
(Photo05)。
ここまでできたら、次は Quartus II に戻るわけだが、まずは
NEEK_LED3.v を下の List 2 ※のように書き換える。
Photo07: アプリケーションプロジェクト名は "stopwatch" とした
ここで「NEEK_LED3_QSYS」という module を呼んでいる
List 3 ※のように書き換えた。
のだが、これは QSYS が生成した NEEK_LED3_QSYS.v とい
一応簡単に説明すると、LEDR_out は一列に並んだ LED の指
うファイル(synthesis フォルダの中にある)に定義が入っている
定桁(0 ∼ 9)のみを光らせる関数、HEX_out は 7 セグメント
ので、それを見ながら export されたものをつなげる形だ。これを
LED を指定した値(0 ∼ 9)に点滅させる関数である。
記述後にコンパイルし、問題がなければ普通に Programmer で
面白いのは、LEDR の方は指定した桁にあたる bit を立てると、
それに対応する LED が点滅する(例えば 0x3FF を指定すれば全
部点灯する)のに対し、7 セグメント LED は対応する bit を落とす
と、そのセグメントが点灯する方式になっていることだ。
ここに指定する bit field とセグメントの関係は
Photo05: 無事に生成
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news009.html
54
となっており、そこで最初に HEXtable[] でそれぞれの数字に対
World" の上にある選択肢)でないと利用できないので、今回は見
応した bit pattern を保持しておき、これをまとめて出力する形に
送った。
なっている。HEX_out(0,xxx) で 1 桁目を、HEX_out(1,xxx) で
さてそんなわけで、Alarm を使ってみることにする。まずは
2 桁目をそれぞれ表示する形だ。
Eclipse で stopwatch_bps のコンテクストメニュー → "Nios II"
一方、これを呼び出す main() は、見ての通りで cnt という変数
→ "BSP Editor..." を指 定して BSP Editor を起 動し、ここで
で 0 ∼ 9 を繰り返しながら表示させるだけの、純粋にテストプログ
"sys_clk_timer" に "One_ms_Timer" を選択する。これが終わっ
ラムである。実行すると Movie01 の様に、7 セグメントと 10 個
たら Generate を押して BSP を生成、stopwatch_bsp 自身を再
の LED が連動しながらきちんと表示されているはずだ。
ビルドする。プログラムは、以下 List 4 ※の様に書き換えた。
※
「光るLED」を「ストップウォッチ」に
List 4解説
さて、これだけでは何の意味も無いので、これをストップウォッ
List 3 からの変更点は、alt_alarm 関数への対応、それとキー
チに仕立ててみたい。0 秒から 99.9 秒まで測定できるものだ。
入力への対応である。
まずはタイマーを追加する必要がある。ということで QSYS に
まず KEY_START/KEY_HOLD/KEY_STOP/KEY_RESET
戻り、新たに "Processors and Peripherals" → "Peripherals"
という 4 つの定義が出てくるが、これは KEY 0 ∼ KEY3 の 4 つの
→ "Interval Timer" を選んで追加する(Photo08)。この際に、irq
キーそれぞれへの対応である。今回の場合、IORD_ALTERA_
の線を CPU とつなぐ事を忘れない様に。デバイスを追加するとア
AVALON_PIO_DATA(KEY_BASE) を 呼 ぶとキ ー の 状 態 が
ドレスが変わるので、再び "Assign Base Address" を呼んでアド
5bit の形で返ってくるが、0bit 目が KEY 0、1bit 目が KEY 1... と
レスを再配置してから Generate HDL で HDL を再生成。その後
なっており、それぞれに対応した形だ。
に Quartus II に戻り、コンパイルを行ってから Programmer で書
新しく Alarm_Int() という関数が追加されているが、これは
き込み直すところまでの手順は先ほどと同じである。
Alarm で呼び出される Callback 関数だ。今回の場合、Alarm は
さて、次は NIOS II のプログラムである。連載第 7 回で既に言
1ms にセットされている(つまり Alarm_Int() は 1ms 毎に呼び出
及したが、NIOS II では System Timer(Interval Timer)を追
される)事になるので、内部でカウンタを回して 100 回(つまり
加することで、Alarm 機能と TimeStamp 機能を排他的に利用で
100ms)経過したら Num(0.1 秒単位のカウンタ)を 1 つ増やし、
きる(FPGA のソフトコア CPU をベンチマークで測定する:タイ
それにあわせて LED と 7 セグメント LED の表示を行って戻るだけ
マーの組み込み)。
の処理を行う。
第 7 回で利用したのは TimeStamp だが、今回は Alarm を利
一方メインルーティンだが、while(1) の中でまずキーの値を読み
用してみたい。Alarm は名前の通り、指定した時間に Callback
取り、何かしらキーが押下されていた(7 セグメント LED と同じく、
Routine の起動が可能である。要するに Timer を利用した割り込
押されていないと 1、押されると 0 が bitfield に返ってくる)ら、そ
み機能だ。割り込みそのものは alt_irq 系の関数が用意されている
れにあわせて Alarm をストップしたりスタートしたり、あるいはカ
の だ が、 こちら は Micro C/OS-II 環 境(Photo07 で、"Hello
といった処理を行っている
ウンタ(Tick と Num)をクリアしたり、
だけである。
余談になるが、先に Photo03 のキャプションでこの KEY の入
力については Edge Capture を最終的に無効にしたと書いた。本
来この機能は、割り込みと組み合わせて使うものだ。Photo03 を
見ると「Interrupt」という項目があって、必要ならキーの押下を検
出して割り込みを発生させることができる。この際、押しっぱなし
にすると延々割り込みが発生するのはまずいので、押された瞬間を
検出しようというわけだ。
ところが今回の様にポーリングで検出する場合、押された瞬間が
あまりに一瞬すぎるためにほぼ取りこぼす。そんな訳で今回は「押
されている」という状態を検出するようにしたわけだ。
さらに余談になるが、こうした確認には printf デバッグが有効で
ある。ところがメモリが 64KB だと printf が動かない(厳密にいえ
ば、printf ("Hello, world\n"); は動作するが、printf( "Hello, %d",
Photo08: ちなみに Period は 1ms にしたが、10ms でも良かったかも。それ以外
はデフォルトのままである。名前は "ONE_ms_Timer" とした
100); はメモリが足りずにビルドに失敗する)ため、128KB にした
というわけだ。
※このページのソースコードはこちら → http://monoist.atmarkit.co.jp/mn/articles/1609/09/news009.html
ムービーはこちら → https://www.youtube.com/watch?v=JeLxu98yVis
55
さて、あとはビルドして実行させるだけである。実行結果はこん
ここで注意点は
な感じ(Movie02 )である。ボタンは右から START/HOLD/
・ Configure Mode を "Single Uncompressed Image" にする。
STOP/RESET に設定されており、7 セグメント LED で秒を、10
・ Initialize flash content のチェックを外す。
個の LED で 0.1 秒をそれぞれ示している。
の 2 点である。
※
「ストップウォッチ」をMAX 10
内蔵フラッシュから起動する
追加後は Photo11 の様に結線を行い、再度 "Assign Base
Address" でアドレスの再配置を行う。次に、NIOS II のパラメー
タを 表 示し、Reset Vector を "onchip_memory2_0.s1" から
恐ろしい事に今回はここまでが前段階であり、ここからが本題と
"onchip_flash_0.data" に変更する(Photo12)。
なる。多少なりとも意味のあるプログラムが完成したところで、そ
以上で QSYS の作業は終了で、後は保存して Generate HDL
れではこれを MAX 10 の内蔵 Flash Memory から起動させる手
で HDL を生成してから Quartus II に戻る。
順をご紹介したい。
Quartus II ではまずメニューの "Assignments" → "Device" で
まずは再び QSYS に戻る。"Basic Functions" → "On Chip
Device Menu を呼び出し、ここの "Device and Pin Options..."
Memory" → "Altera On-Chip Flash" を選択し、内蔵 Flash を
ボ タン を 押 して Device and Pin Options Menu を 表 示 す る
追加する(Photo09)。
Photo09: 連載 第 7 回の時は、timestamp_timer を指定して sys_clk_timer は
none だった
Photo11:NIOS II のプログラムとデータの両方がここに格納されるので、data の先
に両方が結線される
Photo10: たまたまなのか、筆者のケースでは追加したら 2 つともこの状態になって
いた
Photo12: 要するに CPU にリセットが掛かったときどこに飛ぶかの指定で、これで内
蔵 Flash Memory に飛ぶことになる
※このページのムービーはこちら → https://www.youtube.com/watch?v=TFGjrZEhJYM
56
Photo15: その他の箇所は変更不要
Photo13: ここは Photo10 と設定をあわせる形
(Photo13)
。ここの Configuration の中の "Configuration Mode"
を "Single Uncompressed Image(3584Kbit UFM)" に設定し、
OK ボタンを押す。
これが完了したら Quartus II に戻ってコンパイルを行うが、完了
しても Programmer はまだ呼び出さない。その前に Eclipse 側の
作業がある。
QSYS でハードウェアの構成変更を行ったので、stopwatch_
bsp のコンテクストメニューから "Nios II" → "Generate BSP" を
その後でもう一度 "Nios II" → "BSP
呼んで BSP の再構成を行う。
Editor" を起動する。
Photo16:stopwatch_bsp の方は、自動で再ビルドが掛かるはずであるが、まぁ一
応明示的に
ここで 左 の ツリ ー を 下 の 方 ま で ス クロ ー ル して ゆくと、
"Settings" → "Advanced" → "HAL" → "Linker" という項目が
ある。この HAL.Linker の 5 つのチェックボックスに全てチェック
を入れておく(Photo14)。
続いて上の Tab を "Main" から "Linker Script" に切り替えると、
セクション毎にどこに保存するかの指定があるが、ここで .text を
"onchip_memory2_0" から "onchip_flash_0_data" に切り替え
Photo17: ここで Build ボタンを押すと、まず elf ファイルの Build が行われた後に、
これを HEX ファイルに変換してくれる
る(Photo15)。以上で BSP の変更は完了したので、もう一度
Generate ボタンを押して BSP の再生成を行い、終了する。
まず stopwatch_bsp の再ビルドを行っ
続いて Eclipse に戻り、
Photo14: デフォルトでは "enable_alt_load_copy_rodata" と "enable_alt_load_
copy_exception" にはチェックが入っていない
た 後、stopwatch の 方 の コ ン テ ク ストメニュ ー か ら "Make
Targets" → "Build..." を選ぶ(Photo16)。すると Target メニュー
57
・ UFM source を "Page_0" から "load memory file" に変更。
・そ
の下のファイル選択ボタンを押し、mem_init フォルダの下に
生成された onchip_flash_0.hex を指定。
を行う(Photo20)。完了したら "OK" ボタンを押してこの画面は
終了である。
再び Converter 画面に戻るので、下にある "Add File..." ボタン
を押し、 先に Quartus II で生 成した .sof ファイル( 今 回だと
NEEK_LED3.sof)を指定してから(Photo21)Generate ボタ
ンを押す。問題なければ、これで .pof ファイルが生成される。最
後に Programmer を呼び出し、今生成した .pof ファイルを指定し
Photo18: 標準は外部の Flash に格納(というか内蔵 Flash を持っているのが MAX
10 しかない)なので、Mode の切り替えでいろいろ変わる
Photo20:File Path がグレーアウトされているのでちょっと分かりにくい
Photo19: この画面は、そんなわけで Photo18 で Mode を Internal Configuration
にしない限り出てこない
が出てくる(Photo17)ので、
ここで "mem_init_generate" を選
択した上で Build ボタンを押すと、通常の elf ファイルではなく、
Flash に組み込むための HEX ファイルが生成される。以上で
Eclipse での作業は終了し、再び Quartus II に戻る。
Quartus II は、"File" → "Convert Programming File..." から
Converter 画面(Photo18)を立ち上げる。ここでまず "Mode"
を "Internal Configuration" に切り替 えてから "Options/Boot
info..." ボタンを押すと "MAX 10 Device Options" 画面が出てく
る(Photo19)。
この画面で、
58
Photo21: 今回はデフォルトのままなので output_file.sof というファイル名になる
が、この画面で変更(例えば NEEK3_LED.pof)も可能
て書き込む(Photo22)。これが 100%になれば完了である。
以上で作業は終了である。
これで、電源を入れると直ちにストップウォッチが起動する。
Movie03 ※がその様子だが、AC アダプターだけつないだ(USB
ケーブルはつないでいない)状態で電源スイッチを入れるとすぐに
7 セグメント LED が 0 クリアされ、その後、スイッチの操作でストッ
プウォッチが動いているのがお分かりいただけるかと思う。
いろいろと設定があって面倒だが、取りあえず、このような手順
を踏む事で、FPGA の Configuration と NIOS II のプログラムの
両方を Flash に格納できる様になった。
Photo22: メモリに書き込む .sof ファイルの場合と異なり、Flash Memory の書き
込みには時間がかかるため、Progress バーの進み方はかなりゆっくりである。
※このページのムービーはこちら → https://www.youtube.com/watch?v=jLja8IGeLss
「MAX 10 NEEK」でストップウォッチを開発し、内蔵メモリから起動する
59
Fly UP