0

I'm trying to simulate a SystemC module which adds two pixels but when I compile the code I get the following error message:

/tmp/ccb1wY9C.o: In function `sc_dt::sc_uint_base::length() const':
Test/pixels.h:24: multiple definition of `sc_trace(sc_core::sc_trace_file*, pixels const&, std::string const&)'

/tmp/ccpklMFz.o:/Test/pixels.h:24: first defined here
collect2: error: ld returned 1 exit status

This problem happens when I try to separate the module which adds the pixels in a separate header. If I write all the code within the same file the simulation runs without any problem.

This is the code which can be simulated:

File main.cpp:

#include <systemc.h>
#include "pixels.h"
//I use this header when I try to separate the module
//#include "addpixels.h"

// This is the module I'm trying to code within a separate header    
SC_MODULE(addpixels){
    sc_in<pixels> pixel1;
    sc_in<pixels> pixel2;
    sc_out<pixels> pixelout;

    SC_CTOR(addpixels){
        SC_METHOD(addition);
        sensitive << pixel1 << pixel2;
    }

    void addition(){
    sc_uint<5> ir;
    sc_uint<6> ig;
    sc_uint<5> ib;
    pixels temp1 = pixel1.read();
    pixels temp2 = pixel2.read();
    ir = temp1.r + temp2.r;
    ig = temp1.g + temp2.g;
    ib = temp1.b + temp2.b;

    pixelout = pixels(ir, ig, ib);
    }

};

//

//Main function
int sc_main (int argc, char * argv[])
{

    sc_signal<pixels> pix1("pix1");
    sc_signal<pixels> pix2("pix2");
  sc_signal<pixels> pixout("pixout");

    addpixels addpixels_m("addpixels_m");
    addpixels_m.pixel1(pix1);    
    addpixels_m.pixel2(pix2);
    addpixels_m.pixelout(pixout);

    sc_trace_file *trace_fpixels;
    trace_fpixels = sc_create_vcd_trace_file("pixels_trace");
    trace_fpixels->set_time_unit(100, SC_NS);

    sc_trace(trace_fpixels, pix1, "pixel1");
    sc_trace(trace_fpixels, pix2, "pixel2");
    sc_trace(trace_fpixels, pixout, "pixelOut");

    int r, g, b;
    int k = 1;

    while (k < 21){
        r = rand() % (256-1);
        g = rand() % (256-1);
        b = rand() % (256-1);

        pix1 = pixels(r,g,b);

        r = rand() % (256-1);
        g = rand() % (256-1);
        b = rand() % (256-1);

        pix2 = pixels(r,g,b);

        sc_start(300,SC_NS);

        cout << "Test number " << k << endl;
        cout << "--> @ " << sc_time_stamp() << " P1 = " << pix1 << endl;
        cout << "--> @ " << sc_time_stamp() << " P2 = " << pix2 << endl;
        cout << "--> @ " << sc_time_stamp() << " Pout = " << pixout << endl;
        k++;

    }

    sc_close_vcd_trace_file(trace_fpixels);

    return 0;
}

File pixels.h

#ifndef PIXELS_H
#define PIXELS_H

struct pixels {
    sc_uint<8> r;
    sc_uint<8> g;
    sc_uint<8> b;

    //Constructor with values by default
    pixels( sc_uint<8> _r = 0, sc_uint<8> _g = 0, sc_uint<8> _b = 0): r(_r), g(_g), b(_b) { }

    bool operator == (const pixels &other) {
        return (r == other.r) && (g == other.g) && (b == other.b);
    }

    //Displaying of this struct
    friend ostream& operator << ( ostream& o, const pixels& P ) {
        o << "{" << P.r << "," << P.g << "," << P.b << "}" ;
        return o;
    }
};

//Overloading of sc_trace function
void sc_trace( sc_trace_file* _f, const pixels& _foo, const std::string& _s ) {
   sc_trace( _f, _foo.r, _s + "_r" );
   sc_trace( _f, _foo.g, _s + "_g" );
   sc_trace( _f, _foo.b, _s + "_b" );
}

#endif

What I would like to understand is why I can't compile the code when I delete it from the main function and separate it in another header file which is called in the main function.

0

1 Answer 1

3

Free functions defined in a header file need to be prefixed with the inline keyword if they are used in multiple translation units:

   //Overloading of sc_trace function
   inline void sc_trace( sc_trace_file* _f, const pixels& _foo, const std::string& _s ) {
// ^^^^^^
       sc_trace( _f, _foo.r, _s + "_r" );
       sc_trace( _f, _foo.g, _s + "_g" );
       sc_trace( _f, _foo.b, _s + "_b" );
    }

The other option is to extern the definition of that function in a separate translation unit.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.