5

我想编写一个 VPI/PLI 接口,它将打开音频文件(即 wav、aiff 等)并将数据呈现给 Verilog 模拟器。我目前正在使用 Icarus,并希望使用 libsndfile 来处理输入文件格式和数据类型转换。

我不太确定在 C 代码中使用什么……查看了 IEEE 1364-2001,但仍然对我应该使用哪些函数感到困惑。

理想情况下,我想要一个带有数据端口(串行或并行)、时钟输入和启动/停止引脚的 verilog 模块。我想实现两个模块,一个用于从文件中回放,另一个用于记录被测过滤器的输出。

我可以在 C 中完成这一切并在我的测试平台中实例化模块,还是我必须编写一个函数(比如$read_audio_data)和包装模块来在每个时钟脉冲上调用它?

嗯,或者我可能需要创建模块然后获取它的句柄并以某种方式将值/向量传递给句柄?

我不太关心如何设置文件名,因为无论如何我可能不会从 verilog 代码中这样做。我可能会暂时坚持使用 24 位整数样本,并且 libsndfile应该很好地处理转换。也许,我现在会坚持串行(甚至可能以类似 I2S 的方式进行)并在需要时在 Verilog 中对其进行反序列化。

我还查看了 Icarus插件,它实现了一个读取 PNG 文件的摄像机,尽管图像处理还有更多方面,然后是音频。因此,该代码目前对我来说看起来有点过于复杂——我都没有设法让它运行。

4

3 回答 3

3

我建议像这样接近它:

  1. 找出你的 C/Verilog 接口
  2. 考虑到该接口实现音频文件访问,但不必担心 VPI
  3. 使用 VPI 实现 C/Verilog 胶水

界面可能非常简单。一个函数打开音频文件并指定任何必要的参数(样本大小、大/小字节序等),另一个函数返回下一个样本。如果您需要支持在同一个模拟中读取多个文件,则需要将某种句柄传递给 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 结构。

于 2011-06-17T16:41:44.790 回答
2

我已经花了几天时间来实现 PLI 测试平台,如果有人读到这个,他们可能会发现它很有用 - 这是我的源代码。有一个自述文件,下面是一些基本结果的截图;)

用于git clone git://github.com/errordeveloper/sftb获取代码仓库或从 github.com 下载。

gtkwave 中 Velvet Underground 的 Sunday Morning 的小片段的屏幕截图

我也在我的新博客中写过这个,所以希望如果有人搜索这种东西,他们会找到它。我找不到类似的东西,因此开始了这个项目!

于 2011-06-23T13:20:17.057 回答
1

这听起来很适合Cocotb一个开源项目,它抽象了 VPI 来为您的 DUT 提供 Pythonic 接口。您不必编写任何额外的 Verilog 测试平台或包装 RTL 或从 Verilog 调用 VPI 任务或函数,因为测试平台是纯 Python。

您所描述的测试台将如下所示:

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开发人员之一,因此可能存在偏见,但是我也挑战任何人以尽可能快地生成与上述测试平台类似的功能,并且使用更少的(可维护的)代码行。

于 2014-01-04T00:10:05.113 回答