« Prev | Next » Active-HDLとRiviera-PROによるMATLAB-HDLインターフェース はじめに 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の場合 - $LD_LIBRARY_PATH変数の設定 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 Windowsの場合 - COMサーバーの登録 使用するコンピュータにMATLABをインストールすると、オペレーティング・システムにCOMサーバーが登録されます。しかし、場合によっては、MATLABインターフェースを使用する前に、マニュアルでCOMサーバーを登録する必要があります。オペレーティング・システムのコマンドプロンプトで、以下のコマンドを使用して行うことができます。 matlab /regserver コマンドを一回は入力する必要がありますが、システムの再起動後に再入力する必要はありません。 Verilog/VHDLのインターフェース操作の実行 Verilog - PLI ライブラリの宣言 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パッケージの宣言 VHDLでは、MATLABインターフェース用のルーチンはaldecライブラリにコンパイルされているmatlabパッケージに含まれています。VHDLソースコードにおいて本パッケージの宣言を追加する必要があります。パッケージの宣言は、以下を行います。 VHDLソースコードで以下のライブラリ宣言節を使用。 library aldec; use aldec.matlab.all; シミュレータがaldecライブラリを認識しており、matlab パッケージがコンパイルされていることを確認するには、次のコマンドを実行します。 alist adir -lib aldec ファンクションインターフェース MATLABの制御とインターフェースの設定 これらのファンクション・グループは、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"はソース・ディレクトリに存在します。 Active-HDL/Riviera-PROとMATLAB間でのスカラー値の送受信 次のルーチンは、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ソースコードで使用する場合には、ニーモニックはアクセント記号(`)を前に置く必要があります。 FFTプログラムの例 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コマンドが使用されていることを確認ください。 Previous article Next article