Jump to content
causma

sc_signal not updating to its new_value

Recommended Posts

Dear All,

 

I created a class BusAssembly, which basically contains a matrix of sc_uint<>, and I provided it with operator= , ==, >> and sc_trace.

 

In a simple sc_main I defined some variables with type sc_signal<BusAssembly<W,Dim0,Dim1> > . Then I assinged them with a static matrix. (Both by = or .write())

 

Now, the new_value of the sc_signal variables is correctly assigned, but after a while of simulaiton, their current value is not updated to it. Surprisingly it is only working for the fisrt assignment occurrence.

        SystemC 2.3.1-Accellera --- Sep 20 2014 12:00:32
        Copyright (c) 1996-2014 by all Contributors,
        ALL RIGHTS RESERVED
data1 (5,1,1,1,1,1)
     name = signal_0
    value = (5,1,1,1,1,1)
new value = (5,5,3,1,2,3)

data2 (1,1,1)
     name = signal_1
    value = (1,1,1)
new value = (1,64,130)

data1 (5,5,3,1,2,3)  <-- After simulation data1 is OK
     name = signal_0
    value = (5,5,3,1,2,3)
new value = (5,0,0,0,0,0)

data2 (1,1,1)       <-- data2 is not
     name = signal_1
    value = (1,1,1)
new value = (1,0,0)

data1 (5,5,3,1,2,3)     <-- data1 is not
     name = signal_0
    value = (5,5,3,1,2,3)
new value = (5,0,0,0,0,0)

data2 (1,1,1)         <-- neither data2 
     name = signal_1
    value = (1,1,1)
new value = (1,0,0)


What am I mistaken with ?

 

Thank you in advance.

 

Please find here the sc_main code:

#include <iostream>
#include "frames.h"

using namespace std;

int sc_main(int argc, char *argv[])
{
	// Testbench internal variables
	static const sc_uint<4> a[5][1] = {{5},{3},{1},{2},{3}};
	static const sc_uint<4> b[5][1] = {{0},{0},{0},{0},{0}};
	static const sc_uint<8> c[1][2] = {{64,130}};
	static const sc_uint<8> d[1][2] = {{0,0}};
	
	sc_signal<BusAssembly<4,5> >		data1;
	sc_signal<BusAssembly<8,1,2> >		data2;
	
	sc_clock clk("clk",10,SC_NS,true);
	
	data1.write(a);
	cout << "data1 " << data1 << "\n";
	data1.dump();
	
	data2.write(c);
	cout << "data2 " << data2 << "\n";
	data2.dump();
	
	sc_start(20,SC_NS);
	
	data1 = b;
	cout << "data1 " << data1 << "\n";
	data1.dump();
	
	data2 = d;
	cout << "data2 " << data2 << "\n";
	data2.dump();
	
	sc_start(20,SC_NS);
	
	data1.dump();
	data2.dump();

	return EXIT_SUCCESS;
}

And the Class definition one "frames.h" :

#include <exception>
#include "systemc.h"
#include <stdio.h>

template <int W=8, unsigned short Dim0=1, unsigned short Dim1=1>
class BusAssembly
{
	private:
		static const unsigned short dim = Dim0;

	public:
		sc_uint<W> value[Dim0][Dim1];


    BusAssembly()
    {
	    for (unsigned short i=0; i<Dim0; i++)
                   for (unsigned short j=0; j<Dim1; j++)
				value[i][j] = 1; 
    }

    BusAssembly(const sc_uint<W> t[][Dim1])
    {
	    for (unsigned short i=0; i<Dim0; i++)
                   for (unsigned short j=0; j<Dim1; j++)
				value[i][j] = t[i][j];
    }

	// Assignment operator
	BusAssembly& operator = (const BusAssembly& v)
	{
		if (this == &v)
			return *this;

		if (dim == v.dim)
		{
			for (unsigned short i=0; i<Dim0; i++)
            	              for (unsigned short j=0; j<Dim1; j++)
					value[i][j] = v.value[i][j];
//			cout << *this << "\n";
			return *this;
		}
		else
			throw "Assignment Error: Dimensions must match!";
	}

    bool operator == (const BusAssembly& v) const
	{
		bool end = true;
 		if (dim == v.dim)
		{
			for (unsigned short i=0; i<Dim0 && end; i++)
            	               for (unsigned short j=0; j<Dim1 && end; j++)
					end = (value[i][j] != v.value[i][j]);
			return end;
		}
		else
			throw "Assignment Error: Dimensions must match!";
    }

    inline friend void sc_trace (sc_trace_file *tf, const BusAssembly& v, const std::string& NAME)
	{
//		sc_trace(tf,v.dim, NAME + ".dim");
                for (unsigned short i=0; i<Dim0; i++)
                     for (unsigned short j=0; j<Dim1; j++)
                     {
                        std::stringstream str;
                        str << NAME << ".value(" << i << ")(" << j << ")";
		        sc_trace(tf,v.value[i][j],str.str());
                    }
    }

    inline friend ostream& operator << (ostream& os, const BusAssembly& v)
	{
		os << "(" << v.dim ;
		for (unsigned short i=0; i<Dim0; i++)
                      for (unsigned short j=0; j<Dim1; j++)
			    os  << "," << v.value[i][j];
		os << ")";
      return os;
    }
};

Share this post


Link to post
Share on other sites

 

Dear All,

 

I created a class BusAssembly, which basically contains a matrix of sc_uint<>, and I provided it with operator= , ==, >> and sc_trace.

 

In a simple sc_main I defined some variables with type sc_signal<BusAssembly<W,Dim0,Dim1> > . Then I assinged them with a static matrix. (Both by = or .write())

 

Now, the new_value of the sc_signal variables is correctly assigned, but after a while of simulaiton, their current value is not updated to it. Surprisingly it is only working for the fisrt assignment occurrence.

        SystemC 2.3.1-Accellera --- Sep 20 2014 12:00:32
        Copyright (c) 1996-2014 by all Contributors,
        ALL RIGHTS RESERVED
data1 (5,1,1,1,1,1)
     name = signal_0
    value = (5,1,1,1,1,1)
new value = (5,5,3,1,2,3)

data2 (1,1,1)
     name = signal_1
    value = (1,1,1)
new value = (1,64,130)

data1 (5,5,3,1,2,3)  <-- After simulation data1 is OK
     name = signal_0
    value = (5,5,3,1,2,3)
new value = (5,0,0,0,0,0)

data2 (1,1,1)       <-- data2 is not
     name = signal_1
    value = (1,1,1)
new value = (1,0,0)

data1 (5,5,3,1,2,3)     <-- data1 is not
     name = signal_0
    value = (5,5,3,1,2,3)
new value = (5,0,0,0,0,0)

data2 (1,1,1)         <-- neither data2 
     name = signal_1
    value = (1,1,1)
new value = (1,0,0)


What am I mistaken with ?

 

Thank you in advance.

 

Please find here the sc_main code:

#include <iostream>
#include "frames.h"

using namespace std;

int sc_main(int argc, char *argv[])
{
	// Testbench internal variables
	static const sc_uint<4> a[5][1] = {{5},{3},{1},{2},{3}};
	static const sc_uint<4> b[5][1] = {{0},{0},{0},{0},{0}};
	static const sc_uint<8> c[1][2] = {{64,130}};
	static const sc_uint<8> d[1][2] = {{0,0}};
	
	sc_signal<BusAssembly<4,5> >		data1;
	sc_signal<BusAssembly<8,1,2> >		data2;
	
	sc_clock clk("clk",10,SC_NS,true);
	
	data1.write(a);
	cout << "data1 " << data1 << "\n";
	data1.dump();
	
	data2.write(c);
	cout << "data2 " << data2 << "\n";
	data2.dump();
	
	sc_start(20,SC_NS);
	
	data1 = b;
	cout << "data1 " << data1 << "\n";
	data1.dump();
	
	data2 = d;
	cout << "data2 " << data2 << "\n";
	data2.dump();
	
	sc_start(20,SC_NS);
	
	data1.dump();
	data2.dump();

	return EXIT_SUCCESS;
}

And the Class definition one "frames.h" :

#include <exception>
#include "systemc.h"
#include <stdio.h>

template <int W=8, unsigned short Dim0=1, unsigned short Dim1=1>
class BusAssembly
{
	private:
		static const unsigned short dim = Dim0;

	public:
		sc_uint<W> value[Dim0][Dim1];


    BusAssembly()
    {
	    for (unsigned short i=0; i<Dim0; i++)
                   for (unsigned short j=0; j<Dim1; j++)
				value[i][j] = 1; 
    }

    BusAssembly(const sc_uint<W> t[][Dim1])
    {
	    for (unsigned short i=0; i<Dim0; i++)
                   for (unsigned short j=0; j<Dim1; j++)
				value[i][j] = t[i][j];
    }

	// Assignment operator
	BusAssembly& operator = (const BusAssembly& v)
	{
		if (this == &v)
			return *this;

		if (dim == v.dim)
		{
			for (unsigned short i=0; i<Dim0; i++)
            	              for (unsigned short j=0; j<Dim1; j++)
					value[i][j] = v.value[i][j];
//			cout << *this << "\n";
			return *this;
		}
		else
			throw "Assignment Error: Dimensions must match!";
	}

    bool operator == (const BusAssembly& v) const
	{
		bool end = true;
 		if (dim == v.dim)
		{
			for (unsigned short i=0; i<Dim0 && end; i++)
            	               for (unsigned short j=0; j<Dim1 && end; j++)
					end = (value[i][j] != v.value[i][j]);
			return end;
		}
		else
			throw "Assignment Error: Dimensions must match!";
    }

    inline friend void sc_trace (sc_trace_file *tf, const BusAssembly& v, const std::string& NAME)
	{
//		sc_trace(tf,v.dim, NAME + ".dim");
                for (unsigned short i=0; i<Dim0; i++)
                     for (unsigned short j=0; j<Dim1; j++)
                     {
                        std::stringstream str;
                        str << NAME << ".value(" << i << ")(" << j << ")";
		        sc_trace(tf,v.value[i][j],str.str());
                    }
    }

    inline friend ostream& operator << (ostream& os, const BusAssembly& v)
	{
		os << "(" << v.dim ;
		for (unsigned short i=0; i<Dim0; i++)
                      for (unsigned short j=0; j<Dim1; j++)
			    os  << "," << v.value[i][j];
		os << ")";
      return os;
    }
};

 

Hello Sir,

The best option would be to sensitize a process(running

in a loop) to changes in data being read in via a port.

Check below as to how  a simple D flip-flop is implemented.

Please note that it is an old piece of code as it uses

'SC_CTHREAD'. It can be modified to use 'SC_THREAD'

easily. Hope that helps.

 

#ifndef DFF1_H

#define DFF1_H

#include <systemc>

SC_MODULE(dff1)

{

 sc_core::sc_in<bool> din;

 sc_core::sc_in<bool> clock;

 sc_core::sc_out<bool> dout;

 void ffoperation()

 {

   while(true)

   {

     wait();

     dout.write(din.read());

   }

 };

 

 SC_CTOR(dff1)

 {

   SC_CTHREAD(ffoperation, clock.pos());

 }

 ~dff1(){}

};

#endif

 

Share this post


Link to post
Share on other sites
Dear Dakupoto,

Thank you for answering. I understand your point.

But I am not just looking to bypass the problem, otherwise I would
have used the standard types provided with SystemC. I would like to
understand why my piece of code is not working. In fact, if I run the
same code with:
    sc_signal<bool>           data;
    sc_signal<sc_uint<5> >    data0;
I get :
        SystemC 2.3.1-Accellera --- Sep 20 2014 12:00:32
        Copyright (c) 1996-2014 by all Contributors,
        ALL RIGHTS RESERVED
data 0
     name = signal_0
    value = 0
new value = 1
data0 0
     name = signal_1
    value = 0
new value = 6
data1 (5,1,1,1,1,1)
     name = signal_2
    value = (5,1,1,1,1,1)
new value = (5,5,3,1,2,3)
data2 (1,1,1)
     name = signal_3
    value = (1,1,1)
new value = (1,64,130)
Simulation...
data 1                   <-- Update to the right value
     name = signal_0
    value = 1
new value = 0
data0 6                  <-- OK
     name = signal_1
    value = 6
new value = 0
data1 (5,5,3,1,2,3)      <-- OK
     name = signal_2
    value = (5,5,3,1,2,3)
new value = (5,0,0,0,0,0)
data2 (1,1,1)            <-- Not OK
     name = signal_3
    value = (1,1,1)
new value = (1,0,0)
Simulation...
data 0                   <-- OK
     name = signal_0
    value = 0
new value = 0
data0 0                  <-- OK
     name = signal_1
    value = 0
new value = 0
data1 (5,5,3,1,2,3)      <-- Not OK
     name = signal_2
    value = (5,5,3,1,2,3)
new value = (5,0,0,0,0,0)
data2 (1,1,1)            <-- Not OK
     name = signal_3
    value = (1,1,1)
new value = (1,0,0)

Finally, my question is: where is the problem ?

 -  in the definition of my custom type / usage of static matrices;

​ -  there are some constraints related to sc_signal / systemC / C++, I am ignoring;

 -  a specialization of the sc_signal::write () method that is required for my own custom type.

 

Thank you in advance.

Share this post


Link to post
Share on other sites

 

Dear Dakupoto,

Thank you for answering. I understand your point.

But I am not just looking to bypass the problem, otherwise I would

have used the standard types provided with SystemC. I would like to

understand why my piece of code is not working. In fact, if I run the

same code with:

    sc_signal<bool>           data;
    sc_signal<sc_uint<5> >    data0;
I get :

        SystemC 2.3.1-Accellera --- Sep 20 2014 12:00:32
        Copyright (c) 1996-2014 by all Contributors,
        ALL RIGHTS RESERVED
data 0
     name = signal_0
    value = 0
new value = 1
data0 0
     name = signal_1
    value = 0
new value = 6
data1 (5,1,1,1,1,1)
     name = signal_2
    value = (5,1,1,1,1,1)
new value = (5,5,3,1,2,3)
data2 (1,1,1)
     name = signal_3
    value = (1,1,1)
new value = (1,64,130)
Simulation...
data 1                   <-- Update to the right value
     name = signal_0
    value = 1
new value = 0
data0 6                  <-- OK
     name = signal_1
    value = 6
new value = 0
data1 (5,5,3,1,2,3)      <-- OK
     name = signal_2
    value = (5,5,3,1,2,3)
new value = (5,0,0,0,0,0)
data2 (1,1,1)            <-- Not OK
     name = signal_3
    value = (1,1,1)
new value = (1,0,0)
Simulation...
data 0                   <-- OK
     name = signal_0
    value = 0
new value = 0
data0 0                  <-- OK
     name = signal_1
    value = 0
new value = 0
data1 (5,5,3,1,2,3)      <-- Not OK
     name = signal_2
    value = (5,5,3,1,2,3)
new value = (5,0,0,0,0,0)
data2 (1,1,1)            <-- Not OK
     name = signal_3
    value = (1,1,1)
new value = (1,0,0)

Finally, my question is: where is the problem ?

 -  in the definition of my custom type / usage of static matrices;

​ -  there are some constraints related to sc_signal / systemC / C++, I am ignoring;

 -  a specialization of the sc_signal::write () method that is required for my own custom type.

 

Thank you in advance.

 

Hello Sir,

In regards to the three points that you have raised at the end of your

response above,please note that

1. If you are using custom data types, you would have to implement

your own corresponding data channel - the built-in 'sc_signal' WOULD

NOT work. The 'sc_signal' is applicable ONLY to C++/SystemC standard

data types(unsigned int, int float ... etc.,) Implementing a custom channel

is not hard. First declare/define an interface, and then a class that 

implements it -- some synchronization method added in would remove

irritating glitches later. Think of what one would have to do to model a

TCP/IP channel. A TCP/IP packet is basically a large array of bytes

)unsigned char in C/C++)

2. Please see 1 above

3. Please see 1 above.. 

Hope that helps.

Share this post


Link to post
Share on other sites

In general, it's perfectly fine to use sc_signal with a custom data type, provided that you have a properly defined comparison operator (and an sc_trace overload).
In your case, I think your comparison operator is broken:

 

        bool operator == (const BusAssembly& v) const
	{
		bool end = true;
  		if (dim == v.dim)
		{
			for (unsigned short i=0; i<Dim0 && end; i++)
            	               for (unsigned short j=0; j<Dim1 && end; j++)
					end = (value[i][j] != v.value[i][j]);
			return end;
		}

 

In the code above, you update "end" with a != expression. This seems to be strange. Shouldn't this be ==?

 

hth,
  Philipp

Share this post


Link to post
Share on other sites

Dear Philipp,

 

that's great!!! Thank you very much. This helped much more!!!

 

In effect, an sc_singal is updated only if the newer value is different wrt the current one, consequently a broken operator== doesn't help!

 

Thank you again!

 

Best,

Matteo

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...