オーディオファイルを開くための単純なVerilog VPIモジュール
-
28-10-2019 - |
質問
オーディオファイル(IE WAV、AIFFなど)を開き、Verilogシミュレーターにデータを提示するVPI/PLIインターフェイスを書き込みたいと思います。私は現時点でIcarusを使用しており、Libsndfileを使用して入力ファイル形式とデータ型変換を処理したいと考えています。
Cコードで何を使用するかはよくわかりません... IEEE 1364-2001を見て、どの機能を使用するか混乱しています。
理想的には、データポート(シリアルまたはパラレル)、クロック入力、開始/停止ピンを備えたVerilogモジュールが欲しいです。ファイルからの再生用の2つのモジュールを実装したいと思います。もう1つはテスト中のフィルターから出力を記録します。
すべてをCで行い、テストベンチにモジュールをインスタンス化するだけで、関数を書く必要があります(たとえば $read_audio_data
)そして、各クロックパルスでそれを呼び出すラッパーモジュール??
HM、またはモジュールを作成してから、ハンドルを取得し、値/ベクトを何らかの形でハンドルに渡す必要がある場合がありますか?
とにかくVerilogコードからそれをしないでしょうので、私はファイル名がどのように設定されるかについてはあまり心配していません。そして、私はおそらく、当分の間、24ビットの整数サンプルに固執するでしょう。libsndfile
コンバージョンを非常にうまく処理することになっています。おそらく、私は今のところ(I2Sのような方法でさえするかもしれません)シリアルに固執し、必要に応じてVerilogでそれを除去します。
また、私はイカロスを見ました プラグイン PNGファイルを読み取るビデオカメラを実装しますが、画像処理にはオーディオにはさらに多くの側面があります。したがって、そのコードは現時点で私に少し複雑になっているように見えます - どちらもそれを実行することができませんでした。
解決
このように近づくことをお勧めします:
- c/verilogインターフェイスを把握します
- そのインターフェイスを念頭に置いてオーディオファイルアクセスを実装しますが、VPIについて心配していません
- VPIを使用してC/Verilog接着剤を実装します
インターフェイスはおそらく非常に簡単な場合があります。 1つはオーディオファイルを開き、必要なパラメーター(サンプルサイズ、ビッグ/リトルエンディアンなど)を指定し、もう1つの関数が次のサンプルを返します。同じシミュレーション内の複数のファイルからの読み取りをサポートする必要がある場合は、読んでいるファイルを識別するために、PLI関数にハンドルを渡す必要があります。
Verilogの使用は、次のように簡単になる可能性があります。
initial $OpenAudioFile ("filename");
always @(posedge clk)
audio_data <= $ReadSample;
Image-VPIサンプルは、から始まる合理的な例のように見えます。 Cコードで使用する基本的なイディオムは次のとおりです。
引数アクセス
// Get a handle to the system task/function call that invoked your PLI routine
vpiHandle tf_obj = vpi_handle (vpiSysTfCall, NULL)
// Get an iterator for the arguments to your PLI routine
vpiHandle arg_iter = vpi_iterate (vpiArgument, tf_obj)
// Iterate through the arguments
vpiHandle arg_obj;
arg_obj = vpi_scan (arg_iter);
// do something with the first argument
arg_obj = vpi_scan (arg_iter);
// do something with the second argument
Verilogから値の取得
s_vpi_value v;
v.format = vpiIntVal;
vpi_get_value (handle, &v);
// value is in v.value.integer
Verilogに値を書く
s_vpi_value v;
v.format = vpiIntVal;
v.value.integer = 0x1234;
vpi_put_value (handle, &v, NULL, vpiNoDelay);
32ビットを超える値の読み取りまたは書き込みには、使用する必要があります vpiVectorVal
それ以外の vpiIntVal
, 、およびde/s_vpi_vector構造をエンコードします。
他のヒント
誰かがこれを読んで、彼らがそれを役立つと思うかもしれないなら、私は今、PLIテストベンチを実装するのに数日を費やしました - ここに私のものです ソースコード. 。 readmeファイルがあり、以下はいくつかの基本的な結果のスクリーンショットです;)
使用する git clone git://github.com/errordeveloper/sftb
コードリポジトリを取得するか、github.comからダウンロードします。
私もこれについて書きました 私の新しいブログ, 、だから、誰かがこの種のことを検索すると、彼らがそれを見つけることを願っています。私は似たようなものを見つけることができなかったので、このプロジェクトを開始しました!
これはぴったりのように聞こえます cocotb VPIを抽象化して、DUTにPythonicインターフェイスを提供するオープンソースプロジェクト。テストベンチが純粋なPythonであるため、追加のVerilog TestBenchまたはWrapper RTLを作成したり、VPIタスクまたはVerilogから機能を呼び出す必要はありません。
説明されているようにあなたのテストベンチは次のようになります:
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
# Whatever audio-file IO library you happen to like best...
from scikits.audiolab import wavread
@cocotb.test()
def stream_file(dut, fname="testfile.wav")
# Start a clock generator
cocotb.fork(Clock(dut.clk, 5000))
data, sample_frequency, encoding = wavread(fname)
result = []
while data:
yield RisingEdge(dut.clk)
dut.data_in <= data.pop(0)
result.append(dut.data_out.value.integer)
# Write result to output file
免責事項: :私はその一人です cocotb 開発者、したがって潜在的に偏っていますが、上記のテストベンチと同様の機能を迅速かつより少ない(保守可能な)コードで作成するように誰でも挑戦します。