c - 在系统 verilog 代码中集成 fftw C 函数调用

标签 c gcc system-verilog fftw system-verilog-dpi

我已经在我的 Linux 系统上成功安装了 fftw C 库。以下是有关 fftw c => http://www.fftw.org/ 的更多信息我有一个示例 C 代码,可以成功调用 fftw C 函数。下面是 C 代码和运行 C 代码的命令: 代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <fftw3.h> 

int main(void)
{
    double FFT_in[] = {0.1, 0.6, 0.1, 0.4, 0.5, 0, 0.8, 0.7, 0.8, 0.6, 0.1,0};
    double *IFFT_out;
    int i,size = 12;

    fftw_complex *middle;

    fftw_plan fft;
    fftw_plan ifft;
    middle = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*size);
    IFFT_out = (double *) malloc(size*sizeof(double));

    fft = fftw_plan_dft_r2c_1d(size, FFT_in, middle, FFTW_ESTIMATE);  //Setup fftw plan for fft (real 1D data)
    ifft = fftw_plan_dft_c2r_1d(size, middle, IFFT_out, FFTW_ESTIMATE);   //Setup fftw plan for ifft

    fftw_execute(fft);
    fftw_execute(ifft);

    printf("Input:    \tFFT_coefficient[i][0]      \tFFT_coefficient[i][1]   \tRecovered Output:\n");

    for(i=0;i<size;i++)
        printf("%f\t%f\t\t\t%f\t\t\t%f\n",(FFT_in[i]),middle[i][0],middle[i][1],IFFT_out[i]/size);

    fftw_destroy_plan(fft);
    fftw_destroy_plan(ifft);
    fftw_free(middle);
    free(IFFT_out);

    return 0;
}

我可以使用以下 gcc 命令成功运行此代码: gcc -g -Wall -I/home/usr/fftw/local/include -L/home/usr/fftw/local/lib fftw_test.c -lfftw3 -lm -o fftw_test

现在我想使用 DPI 方法在系统 verilog 中调用此函数。在展示我的问题之前,下面是一个可以成功运行的示例 DPI-C/systemverilog 测试用例: C:代码

#include <stdio.h>
#include <stdlib.h>
#include "svdpi.h"

int add(x,y)
{
    int z;
    z=x+y;
    printf("This is from C:%d+%d=%d\n",x,y,z);
    return z;
}

使用 DPI 从系统 verilog 调用上述 C 函数:

module top;
import "DPI-C" function int add(int a, int b);
int a,b,j;

initial begin
    $display("Entering in SystemVerilog Initial Block\n");
    #20
     a=20;b=10;
    j = add(a,b);
    $display("This is from System Verilog:Value of J=%d",j);
    $display("Exiting from SystemVerilog Initial Block");
    #5 $finish;

end

endmodule

最后我可以使用 irun 命令成功运行它 irun -f run.f 其中 run.f 包含以下命令:

# Compile the SystemVerilog files
basicadd.sv 
-access +rwc
# Generate a header file called _sv_export.h
-dpiheader _sv_export.h
# Delay compilation of testexport.c until after elaboration
-cpost add.c -end
# Redirect output of ncsc_run to a log file called ncsc_run.log
-log_ncsc_run ncsc_run.log

现在我真正的问题是 当我尝试将 fftw C 与系统 verilog 链接时,我无法运行它。下面是我的 C 代码,它与我发布的第一个 C 代码非常相似: C代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <fftw3.h>
#include "svdpi.h" 

void fftw_test_DPI(double FFT_in[],int size)
{

    double *IFFT_out;
    int i;

    fftw_complex *middle;

    fftw_plan fft;
    fftw_plan ifft;
    middle = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*size);
    IFFT_out = (double *) malloc(size*sizeof(double));

    fft = fftw_plan_dft_r2c_1d(size, FFT_in, middle, FFTW_ESTIMATE);  //Setup fftw plan for fft (real 1D data)
    ifft = fftw_plan_dft_c2r_1d(size, middle, IFFT_out, FFTW_ESTIMATE);   //Setup fftw plan for ifft

    fftw_execute(fft);
    fftw_execute(ifft);

    printf("Input:    \tFFT_coefficient[i][0]      \tFFT_coefficient[i][1]   \tRecovered Output:\n");

    for(i=0;i<size;i++)
        printf("%f\t%f\t\t\t%f\t\t\t%f\n",FFT_in[i],middle[i][0],middle[i][1],IFFT_out[i]/size);

    fftw_destroy_plan(fft);
    fftw_destroy_plan(ifft);
    fftw_free(middle);
    free(IFFT_out);

    //return IFFT_out;
}

这是我的系统 verilog,我在其中调用上面的 C 函数:

module top;
import "DPI-C" function void fftw_test_DPI(real FFT_in[0:11], int size);
real j [0:11];
integer i,size;
real FFT_in [0:11]; 

initial begin
    size = 12;
    FFT_in[0] = 0.1;
     FFT_in[1] = 0.6;
     FFT_in[2] = 0.1;
     FFT_in[3] = 0.4;
     FFT_in[4] = 0.5;
     FFT_in[5] = 0.0;
     FFT_in[6] = 0.8;
     FFT_in[7] = 0.7;
     FFT_in[8] = 0.8;
     FFT_in[9] = 0.6;
     FFT_in[10] = 0.1;
     FFT_in[11] = 0.0;

    $display("Entering in SystemVerilog Initial Block\n");
    #20
     fftw_test_DPI(FFT_in,size);

    $display("Printing recovered output from system verilog\n"); 
    //for(i=0;i<size;i++)
        //$display("%f\t\n",(j[i])/size);

    $display("Exiting from SystemVerilog Initial Block");
    #5 $finish;

end

endmodule

最后我尝试了几种运行方式,我将提到我尝试过的几种方法: 第一种方法:

irun -f run_fftw.f where run_fftw.f contains:
# Compile the SystemVerilog files
fftw_test.sv 
-access +rwc
# Generate a header file called _sv_export.h
-dpiheader _sv_export.h
# Delay compilation of fftw_test.c until after elaboration
-cpost fftw_test_DPI.c -end
-I/home/usr/fftw/local/include -L/home/usr/fftw/local/lib fftw_test_DPI.c -lfftw3 -lm 
# Redirect output of ncsc_run to a log file called ncsc_run.log
-log_ncsc_run ncsc_run.log

但这会导致以下错误: 构建库 run.so ld:/home/usr/fftw/local/lib/libfftw3.a(mapflags.o): 创建共享对象时不能使用针对“.rodata”的重定位 R_X86_64_32;使用 -fPIC 重新编译 /home/usr/fftw/local/lib/libfftw3.a:无法读取符号:错误值 Collect2: ld 返回 1 退出状态 make: * [/home/usr/DPI/./INCA_libs/irun.lnx8664.12.20.nc/librun.so] 错误 1 ncsc_run: *E,TBBLDF: 无法构建测试库 /home/usr/DPI/./INCA_libs/irun.lnx8664.12.20.nc/librun.so

第二种方法: 1.gcc -fPIC -O2 -c -g -I/home/ss69/fftw/local/include -I。 -L/home/usr/fftw/local/lib -L. -o fftw_test_DPI.o fftw_test_DPI.c -lfftw3 -lm

2.gcc -shared -o libdpi.so fftw_test_DPI.o

3.irun -64bit -sv_lib libdpi.so fftw_test.sv

这会导致以下错误: 正在加载快照 worklib.top:sv ........................ 完成 NCSIM > 运行 进入SystemVerilog初始 block

ncsim:符号查找错误:./libdpi.so: undefined symbol :fftw_malloc

我知道我的帖子有点难以理解,但我非常感谢任何帮助。

最佳答案

这是对我们之前讨论的问题的很好的描述和总结。我通常不在 *nix 系统上工作,因此我无法提出任何具体细节。我要指出的是,分步解决这样的问题通常是一个好方法。

直接从 main() 调用 fft 代码的第一步很好。但是,我没有看到将 fft 代码编译到库中(不使用 SystemVerilog 或 ncsim)然后从 main() 调用该代码的步骤。

看来将代码存储在单独的库中并从 main() 调用是必要的步骤。完成该工作后,您应该能够将 fft 库包含在 SystemVerilog 内容中,而不必同时编译 fft 例程?

关于c - 在系统 verilog 代码中集成 fftw C 函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18137576/

相关文章:

syntax-error - Verilog中的语法错误

verilog - 是否可以访问加密模块内未加密模块实例中的信号?

c - 你如何清除 C 中的字符串 vector ?

清除换行符后的输入行

c++ - 在 OpenCV C/C++ 中只过滤掉一个轮廓

c++ - 将 header 添加到 CMake 中的库

c - 字符串在 Visual Studio 和 gcc 中的打印方式不同

c - 是否有预处理器选项来检查 hdf5 的可用性?

c - 在 C 中,如何添加第 3 方库并使用 Makefile 从我现有的代码库调用

verilog - 用 %f 打印的实际值为 0.0000,但条件 '>0' 不适用(在任务中使用 $floor 后)