causma Posted September 26, 2014 Report Posted September 26, 2014 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; } }; Quote
dakupoto Posted September 27, 2014 Report Posted September 27, 2014 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 Quote
causma Posted September 27, 2014 Author Report Posted September 27, 2014 Dear Dakupoto,Thank you for answering. I understand your point.But I am not just looking to bypass the problem, otherwise I wouldhave used the standard types provided with SystemC. I would like tounderstand why my piece of code is not working. In fact, if I run thesame 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. Quote
dakupoto Posted September 28, 2014 Report Posted September 28, 2014 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. Quote
causma Posted September 29, 2014 Author Report Posted September 29, 2014 Dear Dakupoto,Thank you really so much. It helps a lot! I'll try this way! Best, Quote
Philipp A Hartmann Posted September 29, 2014 Report Posted September 29, 2014 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 Quote
causma Posted September 29, 2014 Author Report Posted September 29, 2014 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 Quote
Recommended Posts
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.