Jump to content
Luis.Cargnini

Problems with custom Packet Class in sc_in/sc_out

Recommended Posts

Hello,

 

I have a Packet class, that for the last week I had to overload some operators ot make it compile using SystemC. Currently I'm trying to instantiate this class in the main file to start testing and I am having compilation issues.

 

The custom class:

 

from my_defines.h

typedef sc_bv< _DATA_SIZE > particle_t;
 

 

#include <systemc.h>
#include "my_defines.h"


class Packet {
public:
    sc_bv< _BITADDR > _field1;
    sc_bv< _BITADDR > _field2;
    sc_bv< _INDEX >     _index;
    particle_t                  _data;

    virtual ~Packet();
    Packet();
    Packet(sc_bv<_BITADDR> _field1, sc_bv< _BITADDR > _field2 sc_bv< _INDEX >     _index, particle_t _data);
   ....
    }
    inline Packet& operator =(const Packet& rhs){
    ...
    }
    inline friend void sc_trace(sc_trace_file *tf, const Packet & v, const std::string & NAME ){
   ....
    }

    inline friend ostream& operator<<(ostream& os,   Packet const & v)
    {
      ....
    }
};

 

 

Queue:

 

SC_MODULE(Queue) {

    sc_in< bool >            rstn;
    sc_in< bool >            clk; // ??? keep it or remove it ?

    //P1
    sc_in< bool >             clkin;
    sc_in< bool >            write;
    sc_in< Packet >            dataIn;
    sc_out< bool >            busyIn;

    //P2
    sc_in< bool >             clkout;
    sc_in< bool >            read;
    sc_out< Packet >        dataOut;
    sc_out< bool >            busyOut; // wait is a reserved word so I used busy for now

//public:


    sc_fifo< Packet > *_buffer;//(_BUFFER_SIZE); //they key component

 

Main file:

...

int sc_main(int argc, char *argv[])
{
    int _channel = 0;


    sc_clock clk("clk",10,SC_NS, 0.5);
    //sc_reset rstn("rstn", 0 , SC_NS, 2.0);

    sc_signal< bool > rstn;// = rstn;

     sc_signal<bool>   enable;
     Packet pkt1,     pkt2;
    pkt1._field1= 0x0000;
    pkt1._field1     = 0x0001;   

    pkt1._index     = 0x0000;
    pkt1._data = 0Xffff;

    Queue tqueue("UUT");

    tqueue.clk(clk);
    tqueue.clkin(clk);
    tqueue.clkout(clk);
    tqueue.rstn(rstn);
    tqueue.dataIn(pkt1);
    tqueue.dataOut(pkt2);
    tqueue.write(true);
    tqueue.read(true);


    sc_start();


    return EXIT_SUCCESS;
}

 

 

Whe I coimpile Queue and Packet it compiles without problems, but when I try to compile the main file I'm receiving the error messages below. I'm using clang++ and the systemc was compiled with clang++ too, so if anyone could give me a help I would appreciate it since SystemC is not exactly 'my cup of tea' and I'm begiinig with it.

 

 

ERROR LOG:

 

clang++     -I. -I.. -I/opt/vlsi/systemc/include  -c src/systemc/packet.cpp -o src/systemc/packet.o
clang++     -I. -I.. -I/opt/vlsi/systemc/include  -c src/systemc/queue.cpp -o src/systemc/queue.o
clang++     -I. -I.. -I/opt/vlsi/systemc/include  -c src/systemc/main.cpp -o src/systemc/main.o
src/systemc/main.cpp:43:2: error: no matching function for call to object of type 'sc_in<Packet>'
        tqueue.dataIn(pkt1);
        ^~~~~~~~~~~~~
/opt/vlsi/systemc/include/sysc/communication/sc_signal_ports.h:166:10: note: candidate function not viable: no known conversion from 'Packet' to 'const in_if_type' (aka 'const sc_signal_in_if<data_type>') for 1st argument
    void operator () ( const in_if_type& interface_ )
         ^
/opt/vlsi/systemc/include/sysc/communication/sc_signal_ports.h:175:10: note: candidate function not viable: no known conversion from 'Packet' to 'in_port_type &' (aka 'sc_port<if_type, 1, SC_ONE_OR_MORE_BOUND> &') for 1st argument
    void operator () ( in_port_type& parent_ )
         ^
/opt/vlsi/systemc/include/sysc/communication/sc_signal_ports.h:184:10: note: candidate function not viable: no known conversion from 'Packet' to 'inout_port_type &' (aka 'sc_port<inout_if_type, 1, SC_ONE_OR_MORE_BOUND> &') for 1st argument
    void operator () ( inout_port_type& parent_ )
         ^
src/systemc/main.cpp:44:2: error: no matching function for call to object of type 'sc_out<Packet>'
        tqueue.dataOut(pkt2);
        ^~~~~~~~~~~~~~
/opt/vlsi/systemc/include/sysc/communication/sc_port.h:270:10: note: candidate function not viable: no known conversion from 'Packet' to 'sc_core::sc_signal_inout_if<Packet> &' for 1st argument
    void operator () ( IF& interface_ )
         ^
/opt/vlsi/systemc/include/sysc/communication/sc_port.h:279:10: note: candidate function not viable: no known conversion from 'Packet' to 'port_type &' (aka 'sc_port_b<sc_core::sc_signal_inout_if<Packet> > &') for 1st argument
    void operator () ( port_type& parent_ )
         ^
src/systemc/main.cpp:45:2: error: no matching function for call to object of type 'sc_in<bool>'
        tqueue.write(true);
        ^~~~~~~~~~~~
/opt/vlsi/systemc/include/sysc/communication/sc_signal_ports.h:489:10: note: candidate function not viable: no known conversion from 'bool' to 'const in_if_type' (aka 'const sc_signal_in_if<data_type>') for 1st argument
    void operator () ( const in_if_type& interface_ )
         ^
/opt/vlsi/systemc/include/sysc/communication/sc_signal_ports.h:498:10: note: candidate function not viable: no known conversion from 'bool' to 'in_port_type &' (aka 'sc_port<if_type, 1, SC_ONE_OR_MORE_BOUND> &') for 1st argument
    void operator () ( in_port_type& parent_ )
         ^
/opt/vlsi/systemc/include/sysc/communication/sc_signal_ports.h:507:10: note: candidate function not viable: no known conversion from 'bool' to 'inout_port_type &' (aka 'sc_port<inout_if_type, 1, SC_ONE_OR_MORE_BOUND> &') for 1st argument
    void operator () ( inout_port_type& parent_ )
         ^
src/systemc/main.cpp:46:2: error: no matching function for call to object of type 'sc_in<bool>'
        tqueue.read(true);
        ^~~~~~~~~~~
/opt/vlsi/systemc/include/sysc/communication/sc_signal_ports.h:489:10: note: candidate function not viable: no known conversion from 'bool' to 'const in_if_type' (aka 'const sc_signal_in_if<data_type>') for 1st argument
    void operator () ( const in_if_type& interface_ )
         ^
/opt/vlsi/systemc/include/sysc/communication/sc_signal_ports.h:498:10: note: candidate function not viable: no known conversion from 'bool' to 'in_port_type &' (aka 'sc_port<if_type, 1, SC_ONE_OR_MORE_BOUND> &') for 1st argument
    void operator () ( in_port_type& parent_ )
         ^
/opt/vlsi/systemc/include/sysc/communication/sc_signal_ports.h:507:10: note: candidate function not viable: no known conversion from 'bool' to 'inout_port_type &' (aka 'sc_port<inout_if_type, 1, SC_ONE_OR_MORE_BOUND> &') for 1st argument
    void operator () ( inout_port_type& parent_ )
         ^
4 errors generated.

 

Share this post


Link to post
Share on other sites

pkt1 and pkt2 need to be signals, e.g.

sc_signal<Packet> pkt1, pkt2;

 

regards

Alan

Totally in agreement with you, the OP has to create his/her own

custom channel. The built-in SystemC sc_signal class would not

support any custom user-defined data type.

Share this post


Link to post
Share on other sites

So Should I 'extend' sc_signal in my class so I can use it in a sc_in or sc_out port  of a major device ?

O I should reduce my expectaion and use a sc_bv<n> of the size I want and remap everytime in each class I exchange the packet ?

 

Vitorio.

Share this post


Link to post
Share on other sites

I'm not sure what you mean by "extend". You can use your Packet class as the template argument of sc_signal, sc_in, and sc_out as long as you implement the correct operators (as shown in section 6.4.3 of the 1666-2011 Language Reference Manual).

 

However you can't bind a packet to an sc_in, you must bind sc_signal<Packet> instead,

 

regards

Alan

Share this post


Link to post
Share on other sites

So thank everyone for the  help, now I saw what you all meant, the Packet in the main.cpp, I changed and it compiled.

 

But answering: by extend I meant : Inherit the class signal into class Packet, would that be possible ? or just overload the necessary operators ? How to exaclty find them, the ones I need to overload ?

 

However, when I tried to execute, after fixing with the sc_signal,  I got the error message below:

 

Error: (E109) complete binding failed: port not bound: port 'UUT.port_9' (sc_out)
In file: ../../../../src/sysc/communication/sc_port.cpp:231
 

my new main.cpp is the following:

 

    int _channel = 0;


    sc_clock clk("clk",10,SC_NS, 0.5);
    //sc_reset rstn("rstn", 0 , SC_NS, 2.0);

    sc_signal< bool > rstn;// = rstn;

     sc_signal<bool>   _run;
     sc_sgnal< Packet > pkt1,     pkt2;

     Packet tpkt1,     tpkt2;
    tpkt1._field1= 0x0000;
    tpkt1._field1     = 0x0001;   

     tpkt1._index     = 0x0000;
    tpkt1._data = 0Xffff;

    _run.write(true);

    pkt1.write(tpkt1);
 

    Queue tqueue("UUT");

    tqueue.clk(clk);
    tqueue.clkin(clk);
    tqueue.clkout(clk);
    tqueue.rstn(rstn);
    tqueue.dataIn(pkt1);
    tqueue.dataOut(pkt2);
    tqueue.write(_run);
    tqueue.read(_run);

    tpkt2 = pkt2.read();

    sc_start();


    return EXIT_SUCCESS;

 

Off-Topic: Besides there is a better debugger for C++ then DDD ? specially using Clang++ ?

I tried to debug but was quite complicated to 'see' anything.

Regards,

Vitorio.

Share this post


Link to post
Share on other sites

So thank everyone for the  help, now I saw what you all meant, the Packet in the main.cpp, I changed and it compiled.

 

But answering: by extend I meant : Inherit the class signal into class Packet, would that be possible ? or just overload the necessary operators ? How to exaclty find them, the ones I need to overload ?

 

However, when I tried to execute, after fixing with the sc_signal,  I got the error message below:

 

Error: (E109) complete binding failed: port not bound: port 'UUT.port_9' (sc_out)

In file: ../../../../src/sysc/communication/sc_port.cpp:231

 

my new main.cpp is the following:

 

    int _channel = 0;

    sc_clock clk("clk",10,SC_NS, 0.5);

    //sc_reset rstn("rstn", 0 , SC_NS, 2.0);

    sc_signal< bool > rstn;// = rstn;

     sc_signal<bool>   _run;

     sc_sgnal< Packet > pkt1,     pkt2;

     Packet tpkt1,     tpkt2;

    tpkt1._field1= 0x0000;

    tpkt1._field1     = 0x0001;   

     tpkt1._index     = 0x0000;

    tpkt1._data = 0Xffff;

    _run.write(true);

    pkt1.write(tpkt1);

 

    Queue tqueue("UUT");

    tqueue.clk(clk);

    tqueue.clkin(clk);

    tqueue.clkout(clk);

    tqueue.rstn(rstn);

    tqueue.dataIn(pkt1);

    tqueue.dataOut(pkt2);

    tqueue.write(_run);

    tqueue.read(_run);

    tpkt2 = pkt2.read();

    sc_start();

    return EXIT_SUCCESS;

 

Off-Topic: Besides there is a better debugger for C++ then DDD ? specially using Clang++ ?

I tried to debug but was quite complicated to 'see' anything.

Regards,

Vitorio.

Hello Sir,

Messing around with the SystemC built-in sc_signal class and trying to extend it

will lead to more confusion for you. Because any SystemC channel is essentially

a buffer to which you write(IF empty) or read from(IF full) creating a custom

signal channel is really not difficult. Then you would have absolute control over

your custom channel's behaviour. Alternatively, as a real-world packet contains

bytes (C/C++ unsigned char), why not send a vector of unsigned chars over a

built-in sc_signal object ? Hope that helps.

Share this post


Link to post
Share on other sites

Thanks again

 

@dakupoto: Why not unsigned: in fact sc_bv seems more RTL oriented, this way, is my understanding, that I can keep the coherence between my SystemC model and my later RTL implementation, using the SystemC as golden model, for the implementation. Also the 'Packet' resembles a user defined type in VHDL as well in SystemVerilog (struct), also in verilog I would only have to break the class into separated in/out signals or a single bit vector and remap internally into the module for organization purposes.

 

In addition to that, using elementary types like sc_bv this mandates me to use binary operations only, since according with the description you cannot operate with this values, without relying in a 'a=b/c' in C++ for example, avoiding anyone in the future doing that, once they use this model to try and experiment with it.

 

That makes sense to you ?

 

 

About the inheritance of the sc_sginal: OK I'll avoid it completely to not mask any mistake underneath my implementation in C++

Share this post


Link to post
Share on other sites

You can derive from sc_signal (that's how sc_buffer is defined in the LRM), but that's not how you're supposed to do it.

 

The intention of sc_signal is that you supply your data type as a template argument.

 

The intention of using a template argument is that the SystemC elaboration code can statically detect if you attempt to connect an sc_in<foo> to an sc_signal<Packet> for instance, and give you an error.

 

The error message is telling you that port "busyOut" is not bound. With default template parameters, you must bind all ports (you cannot leave them unbound). 

 

With default constructor arguments, the ports are given names "port_0", "port_1" and so on - so the 10th port (busyOut) is the problem.

 

regards

Alan

Share this post


Link to post
Share on other sites

Your 'port not bound' error is because you don't have all the ports connected. In SystemC, you generally cannot have unconnected ports. port_9 indicates it's the tenth port (since ports are numbered 0...N-1). You can get more sensible port names if you specify names in the constructor of your Queue via the initializer list.

 

If you really want an unconnected port (e.g. a dangling output port), you will need to specify a non-default policy for each port that has this feature AND you will need to be certain to not access that port during simulation (i.e. no writes) by testing the ports size() method for validity.

 

The easiest solution is to bind a dangling signal.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×