2007年09月11日
VHDL TIPS 「shared variableの使用法」
VHDL93から「共有変数」が使用可能になりVHDL2002で使用方法が変更になった。
XSTはVHDL93をサポートしており限定的ではあるが、共有変数を使用できるみたいなのでVHDL93とVHDL2002両方の使い方を紹介する。
(ただし今回、紹介する例はXSTで合成出来ない。合成するためには同じアーキテクチャ内から共有変数にアクセスする必要がある。)
まず、VHDL93の例
shared variable SH_INT : integer;
end shared_pkg;
library IEEE;
use IEEE.std_logic_1164.all;
library work;
use work.shared_pkg.all;
entity a is
port
(
CLK : in std_logic;
DATA : out integer
);
end a;
architecture a of a is
component b
port
(
CLK : in std_logic
);
end component;
begin
u_b : b port map( CLK );
process ( CLK ) begin
if ( CLK'event and CLK = '1' ) then
DATA <= SH_INT;
end if;
end process;
end a;
library IEEE;
use IEEE.std_logic_1164.all;
library work;
use work.shared_pkg.all;
entity b is
port
(
CLK : in std_logic
);
end b;
architecture b of b is
begin
process ( CLK ) begin
if ( CLK'event and CLK = '1' ) then
SH_INT := SH_INT + 1;
end if;
end process;
end b;
この例では、2つのアーキテクチャからパッケージで宣言した共有変数にアクセスしている。
次に、VHDL2002の例
type SH_TEST is protected
-- 書き込み関数
procedure write ( data : in integer );
-- 読み出し関数
impure function read return integer;
end protected SH_TEST;
-- 共有変数をプロテクトタイプで宣言
shared variable SH_INT : SH_TEST;
end shared_pkg;
package body shared_pkg is
type SH_TEST is protected body
-- 実データ
variable buf : integer := 0;
-- 書き込み関数
procedure write ( data : in integer ) is
begin
buf := data;
end;
-- 読み出し関数
impure function read return integer is
begin
return buf;
end;
end protected body SH_TEST;
end shared_pkg;
library IEEE;
use IEEE.std_logic_1164.all;
library work;
use work.shared_pkg.all;
entity a is
port
(
CLK : in std_logic;
DATA : out integer
);
end a;
architecture a of a is
component b
port
(
CLK : in std_logic
);
end component;
begin
process ( CLK ) begin
if ( CLK'event and CLK = '1' ) then
DATA <= SH_INT.read;
end if;
end process;
u_b : b port map( CLK );
end a;
library IEEE;
use IEEE.std_logic_1164.all;
library work;
use work.shared_pkg.all;
entity b is
port
(
CLK : in std_logic
);
end b;
architecture b of b is
begin
process ( CLK ) begin
if ( CLK'event and CLK = '1' ) then
SH_INT.write( SH_INT.read + 1 );
end if;
end process;
end b;
VHDL2002では単純にアクセスするのでは無く、プロテクトタイプを宣言しデータにアクセスするための関数を定義してその関数を通してデータにアクセスする。
丁度、C++のクラスでプライベートのデータにパブリックのメソッドからアクセスするようなイメージだ。
今回、共有変数の使用例を紹介したがXSTでは同じアーキテクチャ内からでしかアクセス出来ない等の制限があり余り利用価値がない。
もし別のアーキテクチャからアクセス出来ればデバッグ時に信号を引き出す手段として有効利用できたと思う。私はコレがやりたかったのでとても残念に思う。
尚、今回の例は変数の使い方としては良くない例で、同じ時間に違うプロセスからリードライトしているのでシミュレータによってはタイミングが変わるかもしれない。あくまでも共有変数の動作を確認する目的で作成している。
2010/2/19:今更ながら少し修正、VHDL93版の"DATA <= SH_INT;"でイベントが発生しないのでCLKイベントにしました。
この記事へのコメント
共有変数はよさそうですね。
シミュレーションで使ってみたいと思います。論理合成できなければ、論理合成OFFして使えば、シミュレーションには使えそうですね。
ところで、ブログに関係ないことで、恐縮なのですが、よろしければ、VHDLのLRMをどこで手に入れられるのかを、教えていただけますでしょうか?
FPGAの部屋さんのコメントにも書かせてもらいましたが、Modelsimを使っていればUtilパッケージで同様の事が出来ると思います。
LRMは古い物の印刷物があったと記憶していましたが、探しても見つかりませんでした。たぶんIEEEの規格書入手サービスを提供している会社から購入したと思います。
Draftで良ければaccelleraのHomeからTechnical Activities->VHDL->View all publicly available documentsを開きSizeで一番大きいファイルでソートするとLRM-SC-to-be-uploaded.zipが出てきます。
accelleraからLRMドラフト手に入れました。
ModelSimのUtilパッケージの情報もありがとうございました。うちのブログのコメントにも書きましたが、まずは共有変数でやってみたいと思います。
私はいつもModelSimのUtilパッケージを使っているので、余り共有変数は使った事がありません。
ですのでFPGAの部屋さんの「VHDLの共有変数を使用したシミュレーション」は逆に参考になりました。