Active-HDLとRiviera-PROにビルト・インされたインターフェースにより、MathWorksの直観的な言語とテクニカル・コンピューティング環境とアルデックのHDLベースのシミュレーション環境の統合が可能になります。Active-HDL/Riviera-PROが提供するインターフェースでは、MATLAB®コマンドの実行、Mファンクションの呼び出し、MATLABワークスペースとのデータ転送が可能です。全ての操作はHDLコードから制御されます。MATLABとのやり取りは、Verilog/VHDL向けに用意された専用のサブプログラム一式により実行されます。デザインのどの階層からも、MATLABへコマンド(数式の実行やMファンクションの呼び出し)を発行し、MATLABワークスペースへHDL変数を転送して必要な演算を実行し、HDLシミュレータへ結果を返すことができます。
インターフェースの構成:
libaldec_matlab_cosim.soシェアード・オブジェクト・ライブラリ(Linux)またはaldec_matlab_cosim.dllダイナミックリンク・ライブラリ(Windows)。MATLAB環境でコマンドを実行し、HDLシミュレータとMATLABワークスペース間でデータを転送するVHDL foreignサブプログラムとVerilogシステムタスク一式を含むライブラリ。ライブラリはbin/サブディレクトリに存在する。
aldecライブラリにコンパイルされたVHDL matlabパッケージ(パッケージはforeignサブプログラム宣言を含む)。
LinuxでMATLABへのインターフェースを使用する前に、$LD_LIBRARY_PATHシステム変数の設定とMATLABリソースへのパスを通す必要があります。
$matlabroot/bin/<platform>
$matlabroot/extern/lib/<platform>
$matlabrootの位置が/usr/local/matlab、<platform>の文字列がglnx86とすると、以下のコマンドを環境構築にしようすることができます。
bashシェル用:
LD_LIBRARY_PATH=/usr/local/matlab/bin/glnx86:/usr/local/matlab/extern/lib/glnx86:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
cshシェル用:
setenv LD_LIBRARY_PATH
/usr/local/matlab/bin/glnx86:/usr/local/matlab/extern/lib/glnx86:$LD_LIBRARY_PATH
使用するコンピュータにMATLABをインストールすると、オペレーティング・システムにCOMサーバーが登録されます。しかし、場合によっては、MATLABインターフェースを使用する前に、マニュアルでCOMサーバーを登録する必要があります。オペレーティング・システムのコマンドプロンプトで、以下のコマンドを使用して行うことができます。
matlab /regserver
コマンドを一回は入力する必要がありますが、システムの再起動後に再入力する必要はありません。
MATLAB関連タスクとファンクションは、libaldec_matlab_cosim.so (Linux)またはaldec_matlab_cosim.dll (Windows)ライブラリに含まれます。PLIアプリケーションのリストにこのライブラリを追加し、シミュレータから認識できるようにします。PLI設定がないとシミュレータはこれらのタスクやファンクションを認識(実行)することができません。
PLIアプリケーションにライブラリを追加する手順は次の通りです:
メニューからTools->Preferencesダイアログ・ボックスを開き、Category:のCompilation | Verilog | Entries または Simulation | Verilog | Entries を選択します。PLI Applicationsのリストは、コンパイラとシミュレータで共有します。Compilation | Verilog | Entries の設定は、Simulation | Verilog | Entries の設定とは異なり必須ではありません。Show entries for: PLI Applications を選び、libaldec_matlab_cosim.so (Linux)またはaldec_matlab_cosim.dll (Windows) を指定します。
PLI Applications と同様の設定が$user_pli変数を使って行えます。この変数はPLI Applicationsのリストを含み、シミュレーションのイニシャライズ時に読み込まれます。
必要なPLI Applicationは、asimコマンドの-pliオプションを使っても指定できます。詳しくはVerilog PLIおよびVPIの詳細をご参照ください。
VHDLでは、MATLABインターフェース用のルーチンはaldecライブラリにコンパイルされているmatlabパッケージに含まれています。VHDLソースコードにおいて本パッケージの宣言を追加する必要があります。パッケージの宣言は、以下を行います。
VHDLソースコードで以下のライブラリ宣言節を使用。
library aldec;
use aldec.matlab.all;
シミュレータがaldecライブラリを認識しており、matlab パッケージがコンパイルされていることを確認するには、次のコマンドを実行します。
alist
adir -lib aldec
これらのファンクション・グループは、MATLAB®へのコマンドの送信や、Active-HDL/Riviera-PROとMATLAB間のデータ転送に関するファンクションの引数に対して、デフォルト値を設定するのに使用できます。また、起動時にMATLABデスクトップを起動するかどうかを指定することができます。
eval_string プロシージャ呼び出しは、以下のVHDLコードで示されるように、MATLABの".m"ファイルを実行するために使用されます。MATLABの".m"ファイルはMATLABコマンドの集合体であり、MATLABのコマンド・プロンプトで入力できることに注意してください。よって、MATLABのディレクトリを変更する簡単なコマンドでもeval_stringを使用します。すなわち、コマンド・プロンプトで実行される全てのMATLABコマンドは、VrilogまたはVHDLのHDLテストベンチの一部として、eval_stringコマンドで実行可能です。
MATLAB_INIT : process variable dim_constr : TDims(1 to 2) := (1, 1024); begin eval_string("cd src"); eval_string("prepare_workspace");
注意:"prepare_workspace.m"はソース・ディレクトリに存在します。
次のルーチンは、MATLAB®インターフェースによりサポートされ、スカラー値の送受信や操作に使用されます。
put_variable プロシージャ呼び出しは、以下のVHDLコードで示されるように、VHDLコンスタント、変数または信号をMATLABに送信するのに使用されます。
constant window_type : integer := 4; signal in_wave : std_logic_vector (15 downto 0); MATLAB_WINDOW : process (clk) variable i : integer; begin put_variable("w", window_type); put_variable("input", in_wave); put_variable("index", i); eval_string("windowed_input = input * windows1024(w).coeff(index);");
FROM MATLAB:
> w>
w =
4
注意:"input", "index", "windowed_input"がMATLABコマンド・プロンプトで入力されると、"W"のように値が表示されます。
get_variable プロシージャ呼び出しは、以下のVHDLコードで示されるように、MATLABの値をVHDL変数へ引き渡すのに使用されます。
MATLAB_WINDOW : process (clk) variable Qin_var : std_logic_vector(15 downto 0); begin eval_string("windowed_input = input * windows1024(w).coeff(index);"); get_variable("windowed_input", Qin_var);
注意:MATLAB_WINDOWのVHDLプロセスで、VHDL変数Qin_var"にMATLABの値"windowed_input"が引き渡されます。
put_simtime プロシージャ呼び出しは、以下のVHDLコードで示されるようにVHDLのプロセスで実行され、VHDLのシミュレーション時間をMATLABの値へ転送します。
ANALYZE_FFT : process (clk) variable dim_constr : TDims(1 to 2) := (1, 1); begin if rising_edge(clk) then if start = '1' then dim_constr(2) := 1; end if; if OE = '1' then put_simtime("UPDATED_TIME");--VHDL simulation time is transferred to the “UPDATED_TIME” MATLAB value. dim_constr(2) := dim_constr(2) + 1; end if; if (dim_constr(2) = 1025) then dim_constr(2) := 1; end if; end if; end process;
FROM MATLAB:
> UPDATED_TIME>
UPDATED_TIME =
0.1409
MATLABインターフェースでは、HDLルーチンを使って、多次元配列の送受信と操作が可能です。効率を考慮して、配列はインターフェース空間に作成され、HDLシミュレータにはコピーされません。初めに配列の作成にルーチンが使われ、それからデータが転送されます。
以下のルーチンが提供されています:
create_array ファンクション呼び出しは、以下のVHDLコードで示されるように、VHDLプロセスから一時的なストレージ・アレイを作成するために使用されます。一時的なストレージ・アレイは識別子(Id)が与えられ、hdl2mlプロシージャ呼び出しを介して転送/更新されます。
---- Architecture declarations ----- shared variable Qin_Id : INTEGER := 0; shared variable Iout_Id : INTEGER := 0; shared variable Qout_Id : INTEGER := 0; MATLAB_INIT : process variable dim_constr : TDims(1 to 2) := (1, 1024); begin Qin_Id := create_array("fft_Qin", 2, dim_constr); --fft_Qin is set to be a 2 dimensional array [1 X 1024] in temporary storage Iout_Id := create_array("fft_Iout", 2, dim_constr); --fft_Iout is set to be a 2 dimensional array [1 X 1024] in temporary storage Qout_Id := create_array("fft_Qout", 2, dim_constr); --fft_Qout is set to be a 2 dimensional array [1 X 1024] in temporary storage hdl2ml(Iout_Id); --fft_Iout is sent to MATLAB hdl2ml(Qout_Id); --fft_Qout is sent to MATLAB hdl2ml(Qin_Id); --fft_Qin is sent to MATLAB
FROM MATLAB:
> fft_Qin>
fft_Qin =
Columns 1 through 12
183 183 184 184 184 184 184 184 185 185 185 -186
Columns 13 through 24
...........
Columns 1021 through 1024
184 184 183 -184
destroy_array プロシージャ呼び出しは、以下のVHDLコードで示されるように、VHDLのプロセスから一時的なストレージ・アレイを削除するために使用されます。既知の一時的なストレージ・アレイの識別子(Id)を与えなければなりません。
---- Architecture declarations ----- shared variable Qin_Id : INTEGER := 0; MATLAB_INIT : process variable dim_constr : TDims(1 to 2) := (1, 1024); begin Qin_Id := create_array("fft_Qin", 2, dim_constr); --fft_Qin is set to be a 2 dimensional array [1 X 1024] in temporary storage hdl2ml(Qin_Id); --fft_Qin is sent to MATLAB destory_array(Qin_Id); -- fft_Qin has been deleted/removed from temporary storage and therefore no updates possible to MATLAB, --i.e. “fft_Qin” still remains in MATLAB but can’t be updated
put_item プロシージャ呼び出しは、以下のVHDLコードで示されるように、VHDLのプロセスからVHDLコンスタント、変数または信号を一時的なストレージ・アレイへ格納するために使用されます。既知の一時的なストレージ・アレイの識別子(Id)を与えなければなりません。適切に行列を移動するため、ポインタやエレメントの参照を与えなければなりません。
---- Signal declarations --- signal Qin : std_logic_vector (15 downto 0); DISPLAY_INPUT : process (clk,reset) variable dim_constr : TDims(1 to 2) := (1, 1); -- (row,column) of an (M X N) matrix, in this example M = 1 and N = 1024 -- and begin populating matrix at [1,1], i.e. [row,col] begin if reset = ‘1’ then dim_constr(2) := 1; end if; put_item(Qin, 0, Qin_Id, dim_constr);--the VHDL signal “Qin” pointed to as “Qin[0]” as the starting point has --each element assigned to the “fft_Qin” matrix --as shown in the previous example. The temporary storage “fft_Qin” 2 dimensional --array reference element is given in the “dim_constr” value and starts at [1,1] --and goes to [1,1024] in populating the matrix, so it is a row vector of 1024 elements. dim_constr(2) := dim_constr(2) + 1; if (dim_constr(2) = 1025) then hdl2ml(Qin_Id); --fft_Qin is sent to MATLAB, i.e. “fft_Qin” is updated so all previous values in MATLAB are replaced with new ones. eval_string("display_input"); --file “display_input.m” exists in the source directory dim_constr(2) := 1; end if; end process;
ml2hdl ファンクション呼び出しは、以下のVHDLコードで示されるように、VHDLプロセスでMATLABの配列を一時的なストレージ・アレイに転送します。get_item プロシージャ呼び出しは、配列の特定の要素を所得し、VHDL変数に格納するために使用されます。一時的なストレージ・アレイは識別子(Id)は、VHDLプロセスのml2hdlプロシージャ呼び出しから所得されます。MATLAB行列や配列から正しい値を得るために、ポインタやエレメントの参照を与えなければなりません。
---- Architecture declarations -----; shared variable Iin_Id : INTEGER := 0; ANALYZE_FFT : process (clk) variable dim_constr : TDims(1 to 2) := (1, 1);-- (row,column) of an (M X N) matrix, in this example M = 1 and N = 1024 variable Iin_test : STD_LOGIC_VECTOR(15 downto 0); -- variable required to store element of array obtained from MATLAB begin if rising_edge(clk) then if start = '1' then dim_constr(2) := 1; end if; if OE = '1' then Iin_Id := ml2hdl("fft_Iin");--fft_Iin is an array in MATLAB and that array is transferred to a temporary -- storage space and is accessed using the Identifier Iin_Id get_item(Iin_test,0,Iin_Id,dim_constr); -- the VHDL variable “Iin_test” pointed to as “Iin[0]” as the -- starting point has its single value assigned to the “fft_Iin” matrix -- element pointed to by “dim_constr”. The temporary storage “fft_Iin” -- 2 dimensional array reference element is given in -- the “dim_constr” value and starts at [1,1] and goes to [1,1024] which -- is the MATLAB matrix, i.e. a row vector of 1024 elements. dim_constr(2) := dim_constr(2) + 1; end if; end if; end process;
get_num_dims ファンクション呼び出しは、一時的なストレージ空間のMATLAB行列(配列)の次元を所得します。すなわち、(M X N X K)で与えられた場合は、VHDLプロセスで3の値が返されます。get_dim ファンクション呼び出しは、3次元の場合はKを、1次元の場合はMを、2次元の場合はNの値を返します。両方のファンクション呼び出しは、以下のVHDLコードで示されるように、VHDLプロセスで実行されます。
---- Architecture declarations -----; shared variable Iin_Id : INTEGER := 0; ANALYZE_FFT : process (clk) variable dim_constr : TDims(1 to 2) := (1, 1);-- (row,column) of an (M X N) matrix, in this example M = 1 and N = 1024 variable Iin_test : STD_LOGIC_VECTOR(15 downto 0); -- variable required to store element of array obtained from MATLAB variable Iin_total_dimensions : INTEGER; variable Iin_size_last_dimension : INTEGER; begin if rising_edge(clk) then if start = '1' then dim_constr(2) := 1; end if; if OE = '1' then Iin_Id := ml2hdl("EKF");--EKF is an array in MATLAB and that array is transferred to a temporary storage --space and is accessed using the Identifier Iin_Id Iin_total_dimensions := get_num_dims(Iin_Id);--EKF is a [1 X 1024] matrix, so this procedure call will return the value of 2. Iin_size_last_dimension := get_dim(Iin_Id,Iin_total_dimensions);--the procedure call will return the value of 1024. dim_constr(2) := dim_constr(2) + 1; get_item(Iin_test,0,Iin_Id,dim_constr); end if; if (dim_constr(2) = Iin_size_last_dimension + 1) then dim_constr(2) := 1; end if; end if; end process;
get_time プロシージャ呼び出しは、以下のVHDLコードで示されるように、VHDLのプロセスで実行されMATLABのシミュレーション時間を所得します。
ANALYZE_FFT : process (clk) variable dim_constr : TDims(1 to 2) := (1, 1); begin if rising_edge(clk) then if start = '1' then dim_constr(2) := 1; end if; if OE = '1' then get_time;--Benchmark procedure dim_constr(2) := dim_constr(2) + 1; end if; if (dim_constr(2) = 1025) then dim_constr(2) := 1; end if; end if; end process;
VHDLの型およびキャストのニーモニックは、aldecライブラリにコンパイルされているmatlab パッケージで定義されています。型のニーモニックはmxClassIDの列挙型で、キャストのニーモニックはmxCastIDの列挙型でリストされます。Verilogソースコードで使用する場合には、ニーモニックはアクセント記号(`)を前に置く必要があります。
Active-HDLおよびRiviera-PROの両方に、MATLABインターフェースの使用方法を示した、"fft_analysis"サンプルデザインが付属しています。
Active-HDL: デフォルトのサンプルデザインの場所は C:\My_Designs\Samples\matlab_fft_analysis\
Riviera-PRO: デザインの位置は <Riviera-PRO_Install_Dir>/examples/tools/matlab、全てのユーザにRiviera-PROデザインをキープするため、他のディレクトリにコピーすることをお勧めします。
Active-HDL/Riviera-PROでユーザディレクトリからfft_analysisワークスペース・ファイルをロードします。fft_analysisワークスペースをコンパイルし、runme.doファイルを実行すると(Riviera-PROではrunme.doファイルの初めにあるcdコマンドをコメントアウトします)、MATLABで生成された結果の波形を観測できます。
VHDLテストベンチファイル"top_fft_tb.vhd"を開き、eval_string, put_variable, create_array, get_variable, put_itemおよびhdl2mlコマンドが使用されていることを確認ください。