我想编写一个 VPI/PLI 接口(interface)来打开音频文件(即 wav、aiff 等)
并将数据呈现给 Verilog 模拟器。我目前正在使用 Icarus 并希望
使用 libsndfile 处理输入文件格式和数据类型转换。
我不太确定在 C 代码中使用什么......看过 IEEE 1364-2001 并且仍然
困惑我应该使用哪些功能。
理想情况下,我想要一个带有数据端口(串行或并行)、时钟输入的 verilog 模块
和启动/停止引脚。我想实现两个模块,一个用于从文件中回放,另一个用于记录被测过滤器的输出。
我可以在 C 中完成所有操作,然后在我的测试平台中实例化模块,否则我将不得不编写
一个函数(比如 $read_audio_data
)和包装模块在每个时钟脉冲上调用它??
嗯,或者我可能需要创建模块,然后获取它的句柄并传递 value/vect
以某种方式处理?
我不太关心如何设置文件名,因为我可能
无论如何都不会从verilog代码中做到这一点。
我可能会暂时坚持使用 24 位整数样本libsndfile
应该很好地处理转换。
也许,我现在会坚持串行(甚至可能以类似 I2S 的方式进行)和
如果需要,在 Verilog 中对其进行反序列化。
我也看过伊卡洛斯 plug-in它实现了一个读取 PNG 文件的摄像机,
尽管图像处理还有很多方面,但音频方面还有很多。
因此,该代码目前对我来说看起来有点过于复杂 - 我都没有设法得到
它运行。
最佳答案
我建议像这样接近它:
界面可能非常简单。一个函数打开音频文件并指定任何必要的参数(样本大小、大/小字节序等),另一个函数返回下一个样本。如果您需要支持在同一个模拟中读取多个文件,则需要将某种句柄传递给 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
,并解码/编码一个 s_vpi_vector 结构。
关于audio - 用于打开音频文件的简单 Verilog VPI 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6372455/