Jump to content
HenkNep

Method to write to struct elements

Recommended Posts

Hi All,

A basic C++ question, how can I add a method to the class below so that I can write to individual elements?

sc_signal<class des_struct> xyz,abc;

abc.write(xyz.read());  // works fine

xyz.attrib=4;                // Error
 

class des_struct {
  public:
    uint16_t reg;                                                       
    uint16_t attrib;                                                   
  
    des_struct() {
        reg=0;
        attrib=0;
    }

    des_struct& operator= (const des_struct& rhs)    {
            reg=rhs.reg;
            attrib=rhs.attrib;
            return *this;
   }
 ....
};

Thanks.

Share this post


Link to post
Share on other sites

In SystemC, you can't partially change the (new) value of a signal. Instead, you can simply use a local temporary variable:

sc_signal<des_struct> xyz,abc; 

des_struct tmp = xyz.read();
tmp.attrib = 4;
abc.write(tmp);

If you want to keep things in a single line, add a setter with a "fluent API" (i.e. returning the object itself) to the des_struct:

class des_struct {
public:
  // ... 
  des_struct& set_attrib(uint16_t a) { attrib = a; return *this; }
};

// allows:
abc.write( des_struct(xyz.read()).set_attrib(4) );

hth,
Philipp

Edited by Philipp A. Hartmann

Share this post


Link to post
Share on other sites

Hi All,

A basic C++ question, how can I add a method to the class below so that I can write to individual elements?

sc_signal<class des_struct> xyz,abc;

abc.write(xyz.read());  // works fine

xyz.attrib=4;                // Error

 

class des_struct {

  public:

    uint16_t reg;                                                       

    uint16_t attrib;                                                   

  

    des_struct() {

        reg=0;

        attrib=0;

    }

    des_struct& operator= (const des_struct& rhs)    {

            reg=rhs.reg;

            attrib=rhs.attrib;

            return *this;

   }

 ....

};

Thanks.

Hello Sir,

There are some peculiar issues with your code. 

1. How could you make a built-in SystemC signal channel carry a custom object ?

Built-in SystemC signal channels always carry built-in C/C++ data types.

2. SystemC does not allow reading/writing data from/to signal channels directly, 

ONLY to input/output ports.

So, from (e.g.,) module A, you send your custom object to module B. Inside module

B, you would have to read in your custom object, and then manipulate data items

in that object.' 

Hope that helps.

Share this post


Link to post
Share on other sites

Hi Philipp/Dakupoto,

Many thanks for the answers, the Fluent API solution works great.

Can I clarify that one can create user defined data types for sc_signal but you cannot add any methods. The reason being that it requires modification of the OSCI library?

If a user wants to create a custom sc_signal with additional methods one has to:

1) Create a new abstract interface

class write_if : virtual public sc_interface
{
    public:
        virtual void write_reg(int) = 0;          
};

2) Create a channel which implements the new interface
 

//class my_signal : public sc_prim_channel,public write_if {
class my_signal : public sc_channel,public write_if {
   
public:   

    virtual void write_reg(int value) {
        reg=value;
        request_update();
    }
   
private:
    int reg;                                             
}

3) Instantiate the new signal as if it were a module

my_signal xyz;
xyz.write_reg(4);

Am I on the right track?

I tried some simple code which resulted in a tsunami of error messages...

Thanks.

Share this post


Link to post
Share on other sites

"It's just C++" so you can derive from existing classes. If you look in the code for sc_buffer, it is a derived class of sc_signal, which modifies the semantics of write.

 

If you want to create your own primitive channel, then you need to derive from sc_prim_channel (not sc_channel as you've shown in your code). Otherwise you won't have access to request_update().

 

There's a very simple primitive channel example here:

 

http://www.doulos.com/knowhow/systemc/tutorial/primitive_channels/

 

regards

Alan

Share this post


Link to post
Share on other sites

Hi Alan,

Many thanks, I hacked my code as per the Doulos examples and it seems to work fine. Time to start studying abstract/pure/vtable/virtual/Fluent/... general C++ OO stuff...

Here is the code:

#include <systemc.h>

class write_if : virtual public sc_interface
{
    public:
        virtual void write_reg(int) = 0;
        virtual void write_attrib(bool) = 0;
    
    protected:
        write_if(){};
    
    private:
        write_if (const write_if&);             // disable copy
        write_if& operator= (const write_if&);  // disable      
};

class read_if : virtual public sc_interface
{
    public:
        virtual const int& read_reg() = 0;
        virtual const bool& read_attrib() = 0;
    
    protected:
        read_if(){};
        
    private:
    read_if (const read_if&);                   // disable copy
    read_if& operator= (const read_if&);        // disable
};


class des_struct : public sc_prim_channel,public write_if,public read_if
{
    
public:
    explicit des_struct(int reg_=1, bool attrib_=false) : sc_prim_channel(sc_gen_unique_name("des_struct"))  {
        reg=reg_;
        attrib=attrib_;
    }
    
    void write_reg(int c) {                     // blocking write
        reg=c;
        request_update();
    }
    void write_attrib(bool a) {                 // blocking write
        attrib=a;
        request_update();
    }
    
    const int& read_reg() {
        return(reg);
    }
    const bool& read_attrib() {
        return(attrib);
    }

protected:
    int  reg;                                                       
    bool attrib;    
};
des_struct dinx(0,true);
    
dinx.write_reg(1);
cout << "Result dinx : " << dinx.read_reg() << endl;

Thanks.

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

×