XilinxのISEやVivadoを使った開発では,中間生成物であるngcやEDIFを生成して,ブラックボックス的に利用することができます.部分モジュールをライブラリ化して取り回すことができるため便利です.
ところが,AlteraのQuartusIIでは同じように利用できる中間生成物の作成機能が見当たりません.…というのをAlteraに詳しい方に訪ねてみたところ,「パーティション機能を使った分割したモジュールをエクスポートしてみては?」というアドバイスをもらったので試してみました.
今回試してみた範囲では,このパーティション機能は有償版(Subscription Edtion)でしか利用できないため,ファイルの作成には有償ライセンスが必要ですが,エクスポートされたファイルの利用だけならWeb Editionでも可能でした.
ちなみに,使用したバージョンはSubscription Edtion,Web Edition共に15.0.0.145です.
QuartusIIのパーティション機能とエクスポート
QuartusII Subscription Edtionでは大規模なハードウェアの設計時にコンパイル時間を短縮するためにインクリメンタルコンパイルをサポートしています.明示的に分割した,それぞれのモジュールを個別に合成することで,合成時間が短縮されます.
分割してコンパイルしたモジュールの中間生成物はqxpというファイルにエクスポートされます.このファイルは,他のプロジェクトに持っていってHDLソースコードの代わりに使用することができます.
作ってみる
この作業はQuartusII Subscription Edtionでしか実行できません(多分).ただし,30日間の体験版でも実行できます.
まずは,qxpファイルを作ってみます.実験用にとても簡単なVHDLコードを用意しました.testでインスタンス生成しているcounterがブラックボックス化するソースコードです.
私はVerilog HDL派だ,という人でも,まあなんとなく理解していただけるシンプルなコードですね.ちなみに普段はこんなに詰めてVHDLコードを記述することはありません ^^;)
-- test.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity test is
port ( clk, reset : in std_logic; q : out std_logic );
end test;
architecture RTL of test is
component counter
port(clk, reset : in std_logic; value : out std_logic_vector(31 downto 0));
end component counter;
signal value : std_logic_vector(31 downto 0);
begin
q <= value(22);
U: counter port map( clk => clk, reset => reset, value => value );
end RTL;
-- counter.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter is
port (clk, reset : in std_logic; value : out std_logic_vector(31 downto 0));
end counter;
architecture RTL of counter is
signal c : unsigned(31 downto 0) := (others => '0');
begin
value <= std_logic_vector(c);
process(clk) begin
if clk'event and clk = '1' then
if reset = '1' then
c <= (others => '0');
else
c <= c + 1;
end if;
end if;
end process;
end RTL;
ファイルが用意できたら,いつもの手順でプロジェクトを作ってtest.vhdとcounter.vhdをFileタブで登録します.

ここで,test.vhdをトップモジュールとしてセットするのを忘れずに(test.vhdを選択してコンテクストメニューから”Set as Top-Level Entity”ですね).Hierarchyタブに切り替えるとtestが表示さているはずです.

階層構造を構築させるために,メニューから”Porcessing”->”Start”->”Start Hierarchy Elaboration”を実行します.

testの下にcounterがぶら下がっていることが確認できました.counterを選択した状態でコンテクストメニュを開き”Design Partition”->”Set as Design Partition”を選択します.

これで分割コンパイルのトップモジュールに設定されます.Hierarcyタブにも,ルートっぽいアイコンが追加されます.

あらためて,ソース一式をコンパイルします.メニューから”Processing”->”Start Compilation”を選択します.
ここまで終わると,生成物をエクスポートできます.生成対象のcounterを選択した状態でコンテクストメニューをひらき,”Design Partition”->”Export Design Parition…”を選択します.

ダイアログが開くので適当に名前をつけて保存すれば,中間生成物を手に入れることができます.

ちなみに生成されたファイルを,ページャーで開いてみたのですが,ぱっと見は何が書いてあるかわからないバイナリ形式でした.

stringsでも,元のコードの文字列は残念ながら見当たらず…
使ってみる
ここからはWeb EdtionでもOKです.当然のことながらqxpを作るときにWeb Editionでサポートされているデバイスを選択する必要があります.
では,エクスポートしたファイルを使ってみることにします.登録していたcounter.vhdをプロジェクトから取り除いて,生成したcounter-U.qxpを登録します.

登録したら,いつも通り,メニューから”Processing”->”Start Compilation”を選んで,合成,配置配線ができます.Hierarchyタブを開くと,ソースコードを追加したときと同様にcounterモジュールがぶら下がっていることがわかります.

ちなみに,ここでパーティンション分割の記号がつくのはSubscription Editionの場合だけ.WebEdtionでは,特に何のマークもつきません.
Fitter終了時点でのTechnology Map Viewerをみても,ちゃんとインスタンスが生成されていることがわかります.ちなみに,counterモジュールの箱をダブルクリックすると中身が簡単に見えますので,あまりソースコード隠蔽という点では強くなさそう(まあ,カウンタ程度ならともかく,複雑なステートマシンが展開されると,ぱっと見はよくわからないかもですが).

たとえば,test.vhdを修正して,counterのインスタンスを2個生成すると,ちゃんと2個のモジュールがぶら下がります.

Technology Map Viewerはこんな感じ.

もちろん,qとq_1(追加した方のモジュールからの出力)は,別々のポートに割り当てられます.

まとめ
Subscription Editionのパーティンション分割→エクスポートを利用して,簡易なライブラリ生成が可能であることがわかりました.特にオチはないですが.
本来のパーティション分割機能の意義は,小さな範囲でタイミング制約をかけることや短TATで開発をまわすことにあるようです.今後,その当りの機能も試してみたいですね.


コメント