« Prev | Next » Matlab®インターフェースを使用したVHDLテストベンチの強化 はじめに MATLABインターフェースは、Active-HDL 7.1のフルバージョンで導入されました。それ以前のバージョンを使用している場合は、Simulinkインターフェースのみ利用可能です。これらの2つのインターフェースの主な違いは、MATLABインターフェースではActive-HDLがコ・シミュレーションプロセスを制御し、必要に応じてMATLABを起動するのに対し、SimulinkインターフェースではMathWorksが起動する点です。Simulinkはコ・シミュレーションプロセスを制御し、必要に応じてActive-HDLを起動します。 VHDLコードレベルで利用可能なMATLABインターフェースには以下の機能が備わっています: MATLABコマンドの実行(ネイティブとユーザー作成のmファイルの両方) Active-HDLとMATLAB間で変数の受け渡し Active-HDLとMATLAB間の配列転送に必要なデータ構造の作成と破棄 Active-HDLとMATLAB間の配列データの高速な受け渡し MATLABインターフェースによって達成可能な典型的なタスクは以下の通りです: HDLでは記述が困難な関数の計算 複雑な波形の迅速な生成 シミュレーション結果のポスト処理 シミュレーション結果の高度な可視化 このインターフェースを最大限に活用するには、お使いのコンピュータにMATLABバージョン7(R14)以降をインストールし、COMサーバーとして登録する必要があります(コマンドプロンプトにMATLAB/regserverと入力して登録を実行してください)。 インターフェースへのアクセスの取得 MATLABインターフェースを使用するには、VHDLコードから特別な関数、タスク、およびプロシージャを呼び出す必要があります(最初のコマンドまたはデータ転送要求が実行されると、MATLABのウィンドウが表示されます)。これらのVHDLルーチンをコード内で利用するには環境を設定する必要があります。 MATLABインターフェースにアクセスするVHDLコード内のすべてのユニットで、以下のライブラリ、およびuse項を記述する必要があります: library aldec; use aldec.MATLAB.all; MATLABからのデータインポート テストベンチで頻繁に役立つ最も簡単なタスクは、MATLABで波形を生成し、その波形データをテストベンチにインポートすることです。以下の例では、適切なライブラリがすでにテストベンチコードに関連付けられ、テストベンチコードから利用可能になっていることを前提としています。 ここでは、以下のパラメータを持つ変調正弦波スティミュラスを生成します: 搬送波周波数 CFRQ:40 搬送波振幅 AMPL:16383 信号周波数 SFRQ:4 変調深度 DPTH:0.8 このスティミュラスを説明する数式は次のとおりです: AMPL*sin(2*pi*CFRQ*t) * (1-DPTH*cos(2*pi*SFRQ*t)) サンプリング周期を1nsと仮定して、MATLABで少なくとも1000個のサンプルを作成し、それらを配列に格納した後、その配列をActive-HDLに転送して、テスト回路(例:デジタルフィルター)の16ビット入力DIに供給する波形を生成したいと考えています。 Matlabでサンプルを生成するには、Active-HDLプロジェクトのSRCフォルダ内にdo_wave.mファイルを作成し、そのファイル内に次の2行を記述する必要があります: t = 0:.001:1.024 ; sw = fix(AMPL*sin(2*pi*CFRQ*t).*(1-DPTH*cos(2*pi*SFRQ*t))) ; 注記: 最初の行は時間領域ベクトルtを作成し、0から1.024までのすべての値を0.001ステップで格納します 2行目が波形を作成します MATLAB関数 fixは、引数をゼロに近い方の整数に丸めます MATLAB演算子.*は、2つの正弦波の要素同士を乗算します(この文脈では、通常の*演算子は行列の乗算を試みようとする) MATLAB関数の詳細については、MATLABのドキュメントを参照してください。 行と列の構造を区別するため、MATLABの1次元配列は内部的に2次元配列として格納されます(行ベクトルは1×n、列ベクトルはn×1)。この区別は、tおよびsw配列の内部構造にも反映されています。つまり、これらは2次元配列であり第1次元のサイズは1、第2次元のサイズは1025となります。この構造は、Active-HDL環境へのインポート後も維持されます。 VHDLテストベンチには、以下の変数およびタイプの宣言を追加する必要があります: shared variable inp_arr_id : integer; type arr2dim is array (1 to 1025) of std_logic_vector(15 downto 0); shared variable stim_arr : arr2dim; 注記: inp_arr_idは、MATLABからインポートされたサンプル配列のIDを保持します arr2dimは、16ビットサンプルのグループを保存するためのデータタイプです stim_arrは、VHDLにおける波形生成用のサンプルを保存する配列です スティミュラス生成パラメータの値をMATLABに渡すには、aldec.MATLABパッケージのput_variableプロシージャを呼び出す必要があります: put_variable("AMPL", amplitude); put_variable("CFRQ", carrier_frq); put_variable("SFRQ", signal_frq); put_variable("DPTH", mod_depth); タスクの最初の引数は、MATLAB変数名を表す文字列です。2つ目の引数は、その変数に割り当てられるべき値です(ここでは、2番目の引数としてVHDL定数を使用しています)。 ヒント:シミュレーション中にMATLAB関連のプロシージャを初めて使用すると、MATLABのアプリケーションを起動します。Microsoft Windowsの一部のkン協では、MATLABの初回起動にかなりの時間がかかります。シミュレーション中にこの一見無反応に見える期間を避けるため、Active-HDLによるシミュレーションを実行する前に、MATLABを起動してすぐに終了することを検討してください。それ以降の ATLABの起動は速くなるはずです。 前述のmファイルを実行し、MATLABで作成されたsw配列をインポートするには、aldec.MATLABパッケージから2つのサブプログラムを呼び出す必要があります: eval_string("do_wave"); inp_arr_id := ml2hdl("sw"); 注記:: eval_stringプロシージャは、文字列引数として渡されたMATLABコマンドまたはmファイルを実行します ml2hdl関数は、文字列引数として渡されたMATLAB配列をインポートし、インポートされた配列の整数識別子を返します 以前にも述べたように、sw配列はインポート後も元の1行102列というサイズを維持します。そのため、インポートされた配列から通常のVHDL配列変数stim_arrへ要素を転送するには、get_itemプロシージャの以下の構文を使用する必要があります: for i in stim_arr'range loop get_item( stim_arr(i), 0, inp_arr_id, (1,i) ); end loop 注記: stim_arr(i)は、インポートされた配列の1要素が格納されるベクタです 0は、転送される値の分数部分の桁数です inp_arr_idはインポートされた配列の識別子です(ml2hdlによって返されます) (1,i)は、インポートされた配列内における転送要素の位置を表す集合体です 作業を完了するには、stim_arr配列に格納されているサンプルをテスト対象回路の入力へ転送する必要があります: for i in stim_arr'range loop DI <= stim_arr(i); wait for 1 ns; end loop; destroy_array(inp_arr_id); 注記: destroy_arrayプロシージャは、インポートされた配列に割り当てられたメモリを解放します MATLABへのデータエクスポート HDLシミュレーターの波形ビューアは強力ですが、時間領域グラフ(波形)に制限されています。その他のグラフを表示したい場合(例えば、テスト対象の回路が生成したデータの高速フーリエ変換など)を表示したい場合は、MATLABが最適なソリューションとなります。 このノートのセクションでは、以下のタスクを行います: テスト対象回路の出力DOから512サンプルを収集する エクスポート手順に必要な一時的な1×512配列を作成する サンプルを一時配列に転送します 一時配列をMatlabにエクスポートします エクスポートされたデータを処理してグラフ化する 一部の計算結果をHDLシミュレータにインポートする エクスポートされたデータの処理方法をMATLABに指示するには、デザイン内にdo_fft.mという名前のmファイルを作成し、FFTの計算やグラフ作成を行うMATLABコマンドを記述する必要があります。MATLABコマンドの一覧は以下の通りです: Y=fft(smpl,512) ; My = sqrt(Y.* conj(Y)) ; f = 1000*(0:256)/512 ; [MM, MI] = max( My(1:50) ); MF = f(MI); plot(f,My(1:257)) title('Frequency content of filter output') xlabel('frequency (Hz)') grid on 注記: 1行目は、512ポイントのFFT(高速フーリエ変換)の計算を行い、その結果を複素数行列Yに格納する 2行目は、Yに格納されたFFT係数の絶対値(振幅)を計算し、行列Myに送信します 3行目は、最終的なグラフに必要な周波数軸の値を計算します。FFTの結果は対称性を持つため、データ点数の半分のみ使用します 4行目および5行目は、先ほど計算した出力信号のスペクトルにおいて、最大パワーを示す周波数を特定します 残りの行では、グラフを作成し、グラフおよび周波数軸へのラベル付け、グリッドの表示を行います VHDLテストベンチでは、テスト対象回路の出力サンプルを保存するための配列が必要になります。以下にタイプおよび変数の宣言例を示します: type s_arr is array(1 to 512) of STD_LOGIC_VECTOR(15 downto 0); variable samples : s_arr; テスト対象の回路の特性や検証手順に合わせて、適切なサンプリングコードを記述してください。ここでの唯一の前提条件は、サンプリング周期が1 nsであることです。サンプル配列にデータが格納されたら、MATLABへのエクスポートに進むことができます: out_arr_id := create_array( "smpl", 2, (1,samples'right) ); for i in samples'range loop put_item( samples(i), 0, out_arr_id, (1,i) ); end loop; hdl2ml( out_arr_id ); // send temp. array to Matlab 注記: out_arr_idは、作成する一時配列の整数識別子です create_array関数は、MATLAB上での名前をsmplとし、2次元で各次元のサイズを、(1,samples'right)という集約で指定した一時配列を作成します put_itemは、samples(i)の値(小数部を持たない数値として扱われます)をout_arr_id指定された一時配列の要素へ転送するプロシージャです。この際、要素のインデックスは集約(1, i)で指定されます hdl2mlプロシージャは、out_arr_idで表される一時配列をMATLAB環境にエクスポートします データがMATLABにエクスポートされた時点でmファイルを実行し、MATLABから変数 MFを読み込み、一時配列の削除を行う準備が整います: $eval_string( "do_fft" ); // request processing $get_variable( "MF", fmax ); // read variable from Matlab $destroy_array( out_arr_id ); // clean up! 注記: get_variableは、第1引数で指定されたMATLABのスカラ変数を、第2引数で指定されたVHDL変数にインポートするプロシージャです まとめ このドキュメントで説明したMATLABインターフェースは、MATLABの豊富な数学的機能やグラフ描画機能を活用して、VerilogやVHDLコードの機能を簡単に拡張する方法です。 Previous article Next article