2

Hi I am getting below error while compiling a c code using gcc

/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status

I am trying to import the fftw() function into SystemVerilog. Here is my code

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

void fftw(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;
}

Here is a system Verilog code from where I am trying to call fftw

module top;
import "DPI-C" function void fftw(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(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

Here is an irun command to compile both systemverilg and C files

# 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/fftw/local/include -L/home/ss69/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

while running this command give below error: building library run.so ld: /home/fftw/local/lib/libfftw3.a(mapflags.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC /homefftw/local/lib/libfftw3.a: could not read symbols: Bad value collect2: ld returned 1 exit status make: * [/home/ss69/DPI/./INCA_libs/irun.lnx8664.12.20.nc/librun.so] Error 1 ncsc_run: *E,TBBLDF: Failed to build test library /home/DPI/./INCA_libs/irun.lnx8664.12.20.nc/librun.so

irun: *E,CCERR: Error during cc compilation (status 1), exiting.

When I simply try to compile C using gcc with below command:
gcc -g -Wall -Werror -I/home/fftw/local/include -L/home/ss69/fftw/local/lib \ fftw_test_DPI.c -lfftw3 -lm -o fftw_test_DPI

I get this error:

/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../lib64/crt1.o: In function _start': (.text+0x20): undefined reference tomain' collect2: ld returned 1 exit status

Greg
  • 18,111
  • 5
  • 46
  • 68
sanforyou
  • 455
  • 2
  • 8
  • 22
  • 2
    Do you have a main function? – Nafis Zaman Aug 06 '13 at 17:48
  • 11
    "I don't have a main function, yet the linker tells me I don't have a main function..." - [welcome to the Tautology Club.](http://xkcd.com/703/) –  Aug 06 '13 at 17:54
  • Perhaps you wanted to just compile, not link (-c) – sehe Aug 06 '13 at 20:04
  • 1
    @H2CO3 why don't you take a few moments to understand the user? Most people are honest in their approach and have, from their point of view, a valid question. – JackCColeman Aug 06 '13 at 22:20
  • @Sandeep - based on your question and a comment made in an answer, I think you need to read a basic C book to understand how a C program is put together. You're missing some very basic concepts. – Jim Buck Aug 06 '13 at 22:30
  • @Jim Buck, I hope you take some time to read all of the answers. Do NOT go over to the dark side. – JackCColeman Aug 07 '13 at 06:59
  • @JackCColeman - wait, what? I'm not sure what you mean. Oh, and this question and set of answers has changed *dramatically* since my comment, but based on the OP, it was clear the guy didn't understand how one puts together a C program, in which case, the best advice is "get a C book" (perhaps the classic K&R). However, since the OP, it's been edited to flesh out a much bigger picture that didn't exist at the time. – Jim Buck Aug 07 '13 at 22:46
  • @JimBuck then submit an answer that clarifies the topic rather than make an accusation. – JackCColeman Aug 08 '13 at 01:09
  • @JackCColeman Huh? Now I'm confused. What was I accusing anyone of? Based on what was posted at the time of my comment, any reasonable person would have concluded that the OP did not understand the basics of putting together a C-based .exe. An answer, with that in mind, wouldn't have been very helpful except to "do his homework" for him, which is frowned upon on this site. I'm often seeing comments along similar lines in questions where the OP is not understanding some very basic fundamentals. If you want to split hairs, "submit an answer that clarifies the topic" is quite exactly what I did. – Jim Buck Aug 08 '13 at 06:08

5 Answers5

4

Exactly how are you using the function void fftw(double FFT_in[],int size) from your comments it sounds like you are coding routine that is called as DLL or as part of a static library.

If this is the case then adding main() isn't going to help, at all.

What you have written is ABSOLUTELY 100% OK, if it is to be used as a callable routine.

What you might need to do is compile this routine into a library, even a static lib. is probably ok. If this is the case then consult your GCC documentation on how to create a static or dynamic lib.

Finally, I have written Verilog code myself, so you can also provide any lines or references to Verilog documentation that you have read and whose instructions you are following. I assume that at some point you are invoking Verilog and supplying it with a list of libraries it can/should use. Your lib should be included in that list.

Am including comments from jxh per his request: To import the function into SystemVerilog, you need to compile your function into a shared object. Then, you would point SystemVerilog at the shared object. (I don't use SystemVerilog, but that is what I gather from its web page.)

gcc -shared -fPIC -g -Wall -Werror \
-I/home/ss69/fftw/local/include -L/home/ss69/fftw/local/lib \
fftw_test_DPI.c -lfftw3 -lm -o libfftw_test_DPI.so
JackCColeman
  • 3,777
  • 1
  • 15
  • 21
  • Please take some of the relevant info in my post and incorporate it into your own. I'll delete my post. – jxh Aug 06 '13 at 22:46
  • Thanks @JackCColeman,Michael and jxh I have updated my system verilog code as well in my first post.. Also I have a run file to run system verilog and C using irun command. I am neither able to compile just C code using gcc or both codes using irun.. – sanforyou Aug 07 '13 at 01:23
3
  • Your are missing #include "svdpi.h" in the fftwc.c file (or maybe you are not showing it because it is in fftwc.h). This include is needed for DPI.
  • You are compiling a DPI library to be used with a SystemVerilog simulator. Therefore, you do not need a main() method.
  • I prefer to always compile all DPI methods outside of the SystemVerilog compiler. The include the DPI library to the simulation phase. My flow looks something like the following:
${SVTOOL} -compile -f svfiles.f -dpi_header gen_dpi_header.h
gcc -fPIC -pipe -O2 -c -g \
    -I${SVTOOL_PATH}/include -Imy_dpi_dir -I. \
    -o fftw_test_DPI.o \
    fftw_test_DPI.c
gcc -shared -o libdpi.so \
    fftw_test_DPI.o [other object files]
# then call ${SVTOOL} again for simulation with libdpi.so

If you cannot get past the first gcc stage then your issue is clearly on the C side.

I do not have access to the fftw3 library at the moment. I'm wondering your void fftw(double FFT_in[],int size) might be clobbering a library function. Try renaming it void dpi_fftw(double FFT_in[],int size)

Greg
  • 18,111
  • 5
  • 46
  • 68
  • I could successfully execute your three steps.. but I have few questions, What does gcc -O2 and -pipe options do? also could elaborate on last step a bit? # then call ${SVTOOL} again for simulation with libdpi.so – sanforyou Aug 07 '13 at 17:18
  • '-O2' is a level 2 optimizer. '-pipe' use pipes rather than temporary files for communication between the various stages of compilation. The options gave me the best results(may not be required). The last step is different between simulators. At this stage, the simulator needs to know what binary to run with or require an intermediate linker stage. You'll need to look up how your specific simulator works. '-sv_lib' and '-sv_root' seem to be common simulator options to include DPI libraries between simulators. (http://www.doulos.com/knowhow/sysverilog/tutorial/dpi/) – Greg Aug 07 '13 at 19:12
  • @Sandeep , I just noticed your error is referring to a lib64. If your running a 64-bit simulator then add '-m64' to the gcc at the compile stage. If your simulator is 32-bit running a a 64-bit machine, then you might want to use '-m32' instead. – Greg Aug 07 '13 at 19:20
  • I added -m64 option while compiling. I am using irun for simulating systemverilog. irun uses ncsim to simulate systemverilog. so after creating shared library, I tried to simulate it with "irun -snshlib libdpi.so" but I am getting an error, it doent recognized fftw functions.. below is the complete error message: irun: *E,SNLDLIB: Unable able to load the dynamic library /home/ss69/DPI/libdpi.so. rundynlib - failed to load the provided library /home/ss69/DPI/libdpi.so OS MSG: /home/ss69/DPI/libdpi.so: undefined symbol: fftw_plan_dft_r2c_1d – sanforyou Aug 07 '13 at 20:26
  • Tried, " irun -sv_lib libdpi.so fftw_test.sv" Still results in error: Loading snapshot worklib.top:sv .................... Done ncsim> source /home/netcad/cadence/INCISIV12.20.010/tools/inca/files/ncsimrc ncsim> run Entering in SystemVerilog Initial Block – sanforyou Aug 07 '13 at 21:17
  • @Sandeep What is the error message? Is it triminating because it cannot find the function? I suggest adding print statements in the C code before the malloc and another calling methods. Try: `irun -64bit -sv_lib ./libdpi.so fftw_test.sv` This makes sure everything is in 64-bit mode and specifies the path of the shared library. If you still have problems, try breaking down the issue: 1) a pure C to make sure fftw is working as you expect, 2) make a simple DPI work (checkout online tutorials). Once you master the two, then go back and make fftw work as a DPI. – Greg Aug 08 '13 at 00:55
  • @Sandeep I agree with Greg's direction. Even simpler is the question does your SystemVerilog get emulated by irun without a DPI? Also, does /home/ss69/DPI/libdpi.so really have fftw_plan_dft_r2c_1d the library name looks like a SystemVerilog name as opposed to a lib that you have created for the fftw_plan etc. module? – JackCColeman Aug 08 '13 at 01:15
  • Actually I got fftw C functions running with Pure C code, I also have sample system verilog code which works fine with c function calls, I am only having issue while integrating fftw C functions with system verilog. Maybe I will start a new thread with better explanation of all that I have.. – sanforyou Aug 08 '13 at 22:31
  • @Greg,Jack: I have started a new thread with clear posting. It would be great if you guys could have a look and put forward any suggestions. Here is the link=> [link]http://stackoverflow.com/questions/18137576/integrating-fftw-c-function-calls-inside-system-verilog-code – sanforyou Aug 08 '13 at 22:59
1

You have no main function. Every binary must define main. If it doesn't, you don't have a null region of memory that _start defines in the binary, which means your program can't start!

Add a function:

int main(){

   fftw(doubleArgumentsArray, intArgument); //Or whatever function calls this function
   return 1; //Needed for C89, C99 will automatically return 1
}
KrisSodroski
  • 2,796
  • 3
  • 24
  • 39
  • 1
    "If it doesn't, you don't have an _start label in the binary" - you still have (on implementations that use `_start` as the entry point), it's just that it has an unresolved reference to `main()`. –  Aug 06 '13 at 17:55
  • I added int main(){} but still I am getting below error cc1: warnings being treated as errors fftw_test_DPI.c: In function ‘main’: fftw_test_DPI.c:7: error: control reaches end of non-void function. Actually I am calling fftw from a system verilog so I don't want to call it again from main. – sanforyou Aug 06 '13 at 19:51
  • 1
    @Sandeep: I'm not sure exactly what's involved in 'calling fftw from a system verilog', but it sounds like it's possible that you might really want to build a library (a shared library, I'd guess) instead of a stand-alone program. – Michael Burr Aug 06 '13 at 23:21
1

Have found the following tutorial on Dynamic Programming Interface (DPI) :

    http://www.doulos.com/knowhow/sysverilog/tutorial/dpi/

Specifically, scroll down to the "Including Foreign Language Code".

It should help with background information about how to construct a C modules for SystemVerilog.

Also, the tutorial has the following import statement:

  import "DPI" function void slave_write(input int address, input int data);

This SystemVerilog statement obviously has input defs on the parameters, is this required? Your import does NOT identify input vs. output??

JackCColeman
  • 3,777
  • 1
  • 15
  • 21
  • @Greg, I have included #include "svdpi.h", but when I try to compile C file outside system verilog using gcc, It gives me an error, fftw_test_DPI.c:6:20: error: svdpi.h: No such file or directory.. this is not a problem when I compile inside irun(sv tool) – sanforyou Aug 07 '13 at 17:06
  • I have some sample DPI codes which doesn't use input keyword and it still works. I don't think its required, but good to have it in your code.. – sanforyou Aug 07 '13 at 17:07
  • @Greg,Actually I found where svdpi.h inside svtool install path.. using -I option to point to svdpi.h resolved that issue.. – sanforyou Aug 07 '13 at 17:14
0

I believe this is an issue with some gcc linkers. I added the following linker flag:

irun ... -Wld,-B/usr/lib/x86_64-linux-gnu

And it fixed the issue.

Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
user3716072
  • 187
  • 1
  • 2
  • 14