« Kintex-7でHDMI入出力 | トップページ | 「AWS EC2 F1について、みんなでワイワイ調べる会」に参加した »

2017.07.04

Vivadoでソースファイルを秘密にしたIPを作る方法

Vivadoで配布するプロジェクトでソースコードを秘密にしたいと思ったことはありませんか?

例えば、

  • 商用のコアを作りたい人
  • 商用じゃなくても、秘密にしたコアを持っている人
  • 学生に実習用に渡すライブラリの中身を見せたくないTAさん
  • 学生実験のソースが汚すぎてTAに見られたくない学生さん
  • ・・

ソースを秘密にするには、いろいろな理由があると思います。

こういう場合、本来のVivadoの使い方は公開鍵を使って暗号化したものを配布するらしいのですが、NDAとかあって、すぐにできるものではありません。

そこで、誰もが簡単に、秘密IPを配布できる方法として、ネットリストを使った配布方法を紹介します。ネットリストというのは、HDLのソースを論理合成して、XILINXのプリミティブを当てはめたもので、要するにC言語に対するOBJファイルみたいなものです。

1.プロジェクトのディレクトリを作る

まずはプロジェクトのディレクトリを作ります。プロジェクトの本体とレポジトリを分けますが、そのほかにコアを生成するためのmycoreというディレクトリも作ります。全体の構造は下の図のようになります。

Vivsec1

そして、Vivadoでプロジェクトの本体を作ります。Vivadoでのプロジェクトの作り方については詳しい説明は割愛します。

Vivsec2 Vivsec3 Vivsec4

2.ISEでコアを作る

次に、XILINXのISE14.7を使って、コアのプロジェクトを作ります。コア名はledchikaとしました。Working Directoryがrepoのledchikaになっているところがポイントです。こうすると後で少し楽になります。

Vivsec5

そしてプロジェクトを作ったら、VHDLのソースを書きます。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity ledchika_core is
    Port ( clk_ip : in  STD_LOGIC;
           pushsw_ip : in  STD_LOGIC;
           led_op : out  STD_LOGIC_VECTOR (7 downto 0));
end ledchika_core;
architecture Behavioral of ledchika_core is
	signal clk     : std_logic;
	signal pushsw  : std_logic;
	signal timer   : std_logic_vector(21 downto 0);
	signal counter : std_logic_vector(7 downto 0);
	signal led     : std_logic_vector(7 downto 0);
begin
	clk    <= clk_ip;
	pushsw <= pushsw_ip;
	process(clk) begin
		if(clk'event and clk='1') then
			timer <= timer + 1;
			if(timer = 0) then
				counter <= counter + 1;
				if(pushsw = '0') then -- pushed!
					if(counter(4) = '0') then
						led <= x"ff";
					else
						led <= x"00";
					end if;
				else
					led <= not counter;
				end if;
			end if;
		end if;
	end process;
	led_op <= led;
end Behavioral;

Vivsec6

このとき、entityの名前は〇〇_coreのようにしておくと良いでしょう。

そうしたら、Synthesisのところで右クリックし、オプションを出します。そして、Xilinx Specific Optionsのタブを開き、Add I/O Buffersのチェックを外します。

Vivsec7

そして、Synthesisを実行します。

Working Directoryで指定したrepo/ledchikaの中にledchika_core.ngcというファイルができています。

Vivsec8_2

これがネットリストです。

3.ラッパ用のVHDLファイルを作る

そうしたら、コア用のラッパを作ります。ラッパは何もせずに下位のモジュールを呼び出すだけのものを作ります。component文では、ISEで作ったコアのエンティティ名を指定します。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity ledchika is
    Port ( clk_ip : in  STD_LOGIC;
           pushsw_ip : in  STD_LOGIC;
           led_op : out  STD_LOGIC_VECTOR (7 downto 0));
end ledchika;

architecture Behavioral of ledchika is

	component ledchika_core is
	    Port ( clk_ip : in  STD_LOGIC;
	           pushsw_ip : in  STD_LOGIC;
	           led_op : out  STD_LOGIC_VECTOR (7 downto 0));
	end component;

begin

	inst_ledchika : ledchika_core port map (
		clk_ip     => clk_ip,
		pushsw_ip  => pushsw_ip,
		led_op     => led_op
	);

end Behavioral;

4.VivadoでIPのプロジェクトを作る

そして、Vivadoへ戻ってメインのプロジェクトからTools->Create and Package New IPを行います。

Vivsec9

Package a specified directoryを行い、

Vivsec10

先ほど作ったngcとラッパVHDのあるディレクトリを指定します。

Vivsec11

出来上がったプロジェクトには、ラッパのledchika.vhdとNGCがデフォルトで登録されてますが、ツリーの中に入っていないので気持ちがわるいので、いったんngcを削除します。

Vivsec12

そして、Add Sourceで改めてngcを登録します。

Vivsec13

Copy sourcesのチェックは外しておきます。

Vivsec14

これで、ラッパの下にngcが入っている構造が認識されました。

Vivsec15

最後にPackagingして完成です。

Vivsec16

5.メインのプロジェクトから呼び出す

そうしたら、作ったIPコアをブロックデザインで呼び出せるようにします。プロジェクトのsettingsのIPの中からRepositoryを選び、今つくったrepoフォルダを指定します。

Vivsec17

サブディレクトリにあるIPコアが認識され、IPカタログから呼び出せるようになります。

Vivsec18_2

こうして、足をつけて、

Vivsec19

論理合成実行!

何事も問題なくBitstreamが作れました。

Vivsec20

ちゃんと動きます。

6.IPコアのソースを書き換える

IPコアのソースを書き換えたときは、再びISEでSynthesisを行います。ngcが生成されるので、Vivadoはngcの更新を検知してIP Statusが起動します。

Vivsec21

あとはいつも通りにRefresh IP Catalogを行って、Upgrade Selectedを行えばコアがアップデートされます。

Vivsec22

IPコアをRefreshするためにサブVivadoを開く必要はない(メインのプロジェクトでボタンを押すだけな)ので、普通にIPコアを作るよりも楽かもしれません。

なお、ISEのプロジェクトとソースファイルはなくても、NGCとラッパVHDLがあれば論理合成はできるので、ソースを秘密にしたまま配布できるというわけです。

7.まとめと注意点

要点をまとめると、

  • ISEに含まれるXSTを使ってVHDLからNGCを作る(そのとき、Add I/Oバッファは外しておく)
  • component宣言と、つなぐだけのラッパVHDLを作る。componentの名前はXSTで作ったコアの名前に合わせておく。
  • ラッパVHDLをIPコア化する。
  • 全体の論理合成には、ラッパVHDLとNGCがあればよく、ソースのVHDLは不要。

ということです。

注意点/問題点としては、

  • Kintexでやる場合は、UltrascaleがどうのというCritical Warningが出るのでNGCではなくEDIFでやったほうが良いかもしれない(Warningが少し減る)
  • ISEを使うため、Coregenの新しいコアが使えない
  • Genericでパラメータ化ができない

NGCではなくて、DCPを使えば上の問題は解決できると思うのですが、Vivadoの非プロジェクトモードでDCPを作る方法がわからないので、それは後日また試してみることにします。

NGCでのIPコアは配布はISEではよくやられていたのですが、最近ではあまり見なくなりました。この方法は古い方法なのですがVivadoでも使えることがわかりました。

ソースが秘密のIPを配布できると思うので、みなさんぜひ試してみてください。

|

« Kintex-7でHDMI入出力 | トップページ | 「AWS EC2 F1について、みんなでワイワイ調べる会」に参加した »

コメント

コメントを書く



(ウェブ上には掲載しません)




« Kintex-7でHDMI入出力 | トップページ | 「AWS EC2 F1について、みんなでワイワイ調べる会」に参加した »