Search the Community
Showing results for tags 'sc_vector'.
-
Hello I 'm trying to create an nxn array (nested vectors) of an rc component, with each having different r,c values ex: rc[0][0] (r=10,c=5), rc[1][1] (r=3,c=4)..... I've created the rc sub module that take the values of R and C as arguments, As follows: SC_MODULE (rc){ sca_eln::sca_terminal n; sca_eln::sca_terminal p; sca_eln::sca_r r1; sca_eln::sca_c c1; sca_eln::sca_node n1; rc( sc_core::sc_module_name nm , double r0_,double c0_) :p("p"),n("n"), r1("r1"),c1("c1"), r0(r0_),c0(c0_) { r1.p(p); r1.n(n1); r1.value=r0; c1.p(n1); c1.n(n); c1.value=c0; } private: double r0; double c0; }; I have found the following post that shows how to initialize 1D vector so I customized my module accordingly ,which a follows #include <systemc> #include <systemc-ams> using namespace sc_core; SC_MODULE (rc){ sca_eln::sca_terminal n; sca_eln::sca_terminal p; sca_eln::sca_r r1; sca_eln::sca_c c1; sca_eln::sca_node n1; rc( sc_core::sc_module_name nm , double r0_,double c0_) :p("p"),n("n"), r1("r1"),c1("c1"), r0(r0_),c0(c0_) { r1.p(p); r1.n(n1); r1.value=r0; c1.p(n1); c1.n(n); c1.value=c0; } private: double r0; double c0; }; struct create_mod { double m_arg1; double m_arg2; create_mod(double arg1, double arg2) : m_arg1(arg1), m_arg2(arg2) {} rc* operator()(const char* name, size_t) { return new rc(name, m_arg1, m_arg2); } }; SC_MODULE (rc_tb){ rc rc0; rc_tb( sc_core::sc_module_name nm ):rc0("rc0",1.0,1.0) { unsigned int num_of_rcs = 4; unsigned int r_value = 5, c_value = 4; sc_vector<rc> vec_rc("mods"); vec_rc.init(num_of_rcs, create_mod( r_value, c_value)); //... connect nodes } }; Now the code works But it is only for 1D array This method also forces me to set same argument values for all the initialized submodules ( vec_rc.init(num_of_rcs, create_mod( r_value, c_value)); ). So my 2 questions are 1- How to make it a 2D vectors ? 2- How to initialize each component with specific RC values? I also have tried the code suggested in to make a 2D nested vectors but I failed I don't mind using either methods as long as it does the job. It will be nice if I use lambda function also Thanks in advance RF
-
Hello, I would like to create an arbitrary (random) number of processes, of the same module. So I tried with sc_vector. I can instantiate sc_module but not when there is a SC_THREAD in the module. I have the following code in my header "nodes.h" struct CNodes : sc_core::sc_module { CNodes(sc_core::sc_module_name instance); ~CNodes(void) = default; void CNodes::Init_node(int, float, float); SC_HAS_PROCESS(CNodes); private: int id = 0; // Processes and overrides void Thread_node(void); }; And the cpp files is : #include "Nodes.h" CNodes::CNodes(sc_core::sc_module_name instance) { id = 0; std::cout << "Constructing CNodes " << std::endl; SC_THREAD(Thread_node); // PROBLEMATIC LINE dont_initialize(); } void CNodes::Init_node(int pid, float bias, float rate) { } void CNodes::Thread_node(void) { while(true) { std::cout << "Hi there" << std::endl; wait(10,sc_core::SC_NS); } } When I put the "SC_THREAD" macro in my code, I got an error during elaboration Error: (E549) uncaught exception: Access violation - n In file: C:\SystemC\src\sysc\kernel\sc_except.cpp:98 The top module is this one. It instantiates 20 objects of class CNodes : #include <string> #include <time.h> #include "Network.h" #include "Nodes.h" using namespace std; CNetwork::CNetwork (sc_core::sc_module_name name, unsigned _size = 4): sc_core::sc_module(name), nodes("node") { float bias, rate; /* initialize random seed: */ srand((unsigned int)time(NULL)); nodes.init(20); for (unsigned int i = 0; i < nodes.size(); i++) { // generate random numbers for nodes bias = (float)rand() / RAND_MAX; rate = (float)rand() / RAND_MAX; nodes[i].Init_node(i, bias, rate); } } The modules "nodes" will have also ports, etc. But for the moment, I'm stuck with the instantiation. When I remove the problematic line, "SC_THREAD(Thread_node);", it works fine for the moment. But in that case I don't have the processes I need for my model. Is ther a way to instantiate a arbitrary number of processes, arbitrary meaning that the number is not known during coding phase because it will be random. Thanks ! Arnaud
-
I am debugging a problem with my custom datatype for sc_trace. I use my datatype for sc_signal, which is inside a sc_vector. Then I trace each signal inside the sc_vector. To narrow down my problem I removed all unnecessary parts for debugging. I still get the error, even though I'm not tracing a single signal. My MWE: main.cpp: // SystemC_FirstTest.cpp : Defines the entry point for the console application. // #pragma once //#define WIN32_LEAN_AND_MEAN //needed for tcp (winsock, ws2) #include <systemc.h> #include "globals.h" SC_MODULE(mA) { sc_inout<int> SC_NAMED(A); void stim() { wait(1, SC_SEC); A.write(0); wait(1, SC_SEC); A.write(1); }; SC_CTOR(mA) { SC_THREAD(stim); } }; SC_MODULE(mB) { sc_inout<int> SC_NAMED(A); void stim() { wait(0.8, SC_SEC); A.write(2); wait(1.1, SC_SEC); A.write(3); }; SC_CTOR(mB) { SC_THREAD(stim); } }; int sc_main(int argc, char** argv) { sc_vector< sc_signal<int, SC_MANY_WRITERS > > stub_vec("top_stub", 5); sc_vector< sc_signal<TraceVector, SC_MANY_WRITERS > > sim_vec("top_sim_", 5); mA SC_NAMED(modA); mB SC_NAMED(modB); modA.A(stub_vec[0]); modB.A(stub_vec[0]); sc_trace_file *tf = sc_create_vcd_trace_file("traces"); if (!tf) { cout << "Empty TraceFile could not be generated." << endl; } //sc_trace(tf, &(stub_vec[0]), "yolo"); //sc_signal<int, SC_MANY_WRITERS > testSig; //sc_trace(tf, &testSig, "yolo_more"); //for (int i = 0; i < 5; i++) { //sc_trace(tf, &(sim_vec[i]), sim_vec[i].name() ); //} // start simulation sc_start(); sc_close_vcd_trace_file(tf); return 0; } globals.h: #pragma once #include <systemc.h> #include <vector> // Vector that is traceable by sc_trace class TraceVector { private: std::vector<int> vec; public: // Methods for accessing list const std::vector<int>& read() const { return vec; } void write(std::vector<int> var) { if (var.size() != 4) { throw std::invalid_argument("Argument is not size 4!"); } this->vec.assign(var.begin(), var.end()); } // CTOR TraceVector() { vec.reserve(4); } // CTOR for init values TraceVector(std::vector<int> var) { if (var.size() != 4) { throw std::invalid_argument("Argument is not size 4!"); } vec = var; } // Required by sc_signal<> and sc_fifo<> TraceVector operator= (const TraceVector& var) { write(var.read()); return *this; } // Required by sc_signal<> bool operator== (const TraceVector& var) const { auto temp = var.read(); // size check if (temp.size() != vec.size()) { return false; } // element wise comparison bool equal = std::equal(vec.begin(), vec.end(), temp.begin()); return equal; } }; // Required functions by SystemC ostream& operator<< (ostream& os, const TraceVector& var); void sc_trace(sc_trace_file* tf, const TraceVector& var, const std::string& nm); globals.cpp: #include "globals.h" // Required functions by SystemC ostream& operator<< (ostream& os, const TraceVector& var) { os << "{"; for (auto& val : var.read()) { os << val << " "; } os << "}"; return os; } void sc_trace(sc_trace_file* tf, const TraceVector& var, const std::string& nm) { int pos = 0; //static int temp = 0; //sc_core::sc_trace(tf, temp, nm + "_test"); for (auto& val : var.read()) { // use namespace, compiler otherwise chooses wrong function sc_core::sc_trace(tf, val, nm + "." + std::to_string(pos++)); } } Where is the vector subscript error coming from? Why is it even appearing when I'm not tracing a signal with my custom type? When I completely remove tracing, no error appears.
-
Greetings everyone, I have a process that is sensitive to an sc_vector (specifically a vector of input ports) and was curious about how to handle the fact that values are maintained on each port in that vector on subsequent iterations of the process. This makes it very difficult to determine which values are actually new when the process is executed. I was hoping there would be a way to clear the value on a port once it had been read, but I could not find anything like this. The closest thing to a solution is to "latch" the value each time the process gets triggered and then compare the latch value with the port value to determine if anything new has arrived. Is there a better way to do this? Thanks a bunch in advance.
-
Hi, I am pretty new to systemc, and I am trying for days to instantiate an array of modules; but I am not being successfull using sc_vector. Here is the code: submodule.h #ifndef __SUBMODULE_h #define __SUBMODULE_h #include <systemc.h> //------------ DEFINITIONS --------------------------------- #define BYTE 8 typedef sc_uint<2*BYTE> uint_16b; typedef sc_uint<BYTE> uint_8b; //------------ PARAMETERS ---------------------------------- #define MAX_COUNT1 6 #define MAX_COUNT2 4 #define RESET_VALUE false //------------ MODULE -------------------------------------- template <int N> class SUBMODULE : public sc_module { public: //------------ Ports ----------------------------------- sc_in_clk i_clk; sc_in<bool> i_rst; sc_in<bool> i_en; sc_vector< sc_out<uint_16b> > o_data; sc_out<bool> o_finish; //------------ Variables ------------------------------- uint_8b v_state; uint_8b v_count1; uint_8b v_count2; //------------ Process --------------------------------- void p_main(void) { if (i_rst.read()){ v_state = 0; v_count1 = 0; v_count2 = 0; for(int i = 0; i < N; i++) o_data[i] = 0; } else{ if(i_en.read()){ switch(v_state){ case 0: for(int i = 0; i < N; i++) o_data[i] = 0; if (MAX_COUNT1 > 0) v_state = 1; else v_state = 2; break; case 1: v_count1++; if(!(v_count1 < MAX_COUNT1)) v_state = 2; break; case 2: if(v_count2 < MAX_COUNT2) for(int i = 0; i < N; i++) o_data[i] = (uint_16b)(100/MAX_COUNT2*(v_count2+1)); v_count2++; if(!(v_count2 < MAX_COUNT2)){ for(int i = 0; i < N; i++) o_data[i] = 100; v_state = 3; } break; case 3: if (!RESET_VALUE) for(int i = 0; i < N; i++) o_data[i] = 0; o_finish = 1; break; default: break; } } else{ v_state = 0; v_count1 = 0; v_count2 = 0; } } } //------------ Constructor ----------------------------- SC_HAS_PROCESS(SUBMODULE); SUBMODULE(sc_module_name name_) : sc_module(name_), o_data("o_data", N){ SC_METHOD(p_main); for (int j = 0; j < N; j++) sensitive << i_clk.pos() << i_rst; } }; #endif topmodule.h #ifndef __TOPMODULE_h #define __TOPMODULE_h #include <systemc.h> #include "SUBMODULE.h" #define MAX_N 8 template <int N> class TOPMODULE : public sc_module { public: //------------ General Data ---------------------------- //------------ Ports ----------------------------------- sc_in_clk i_clk; sc_in<bool> i_rst; sc_in<uint_8b> i_type; sc_vector< sc_out<uint_16b> > o_data; //------------ Signals --------------------------------- sc_signal<bool> s_en; sc_signal<bool> s_finish[N]; //------------ Variables ------------------------------- //------------ Components ------------------------------ sc_vector<SUBMODULE<N> > SM; //------------ Methods --------------------------------- //------------ Process --------------------------------- void p_main(void) { if (i_rst.read()){ } else{ } } //------------ Constructor ----------------------------- SC_HAS_PROCESS(TOPMODULE); TOPMODULE(sc_module_name name_) : sc_module(name_), SM("SM",N){ for (int i = 0; i < N; i++){ SM[i].i_clk(i_clk); SM[i].i_rst(i_rst); SM[i].i_en(s_en); SM[i].o_finish(s_finish[i]); SM[i].o_data(o_data[i]); } SC_METHOD(p_main); sensitive << i_clk.pos() << i_rst; } }; #endif TOPMODULE_tbm.cpp #include <systemc.h> #include "TOPMODULE.h" #define MIN_PERIOD 5 void debug(sc_trace_file* tf, TOPMODULE<MAX_N> *dut){ sc_trace(tf, dut->i_clk, "i_clk"); sc_trace(tf, dut->i_rst, "i_rst"); sc_trace(tf, dut->i_type, "i_en"); for (int i = 0; i < MAX_N; i++){ char str[16]; sprintf(str, "%d", i); sc_trace(tf, dut->o_data[i], "o_data_" + std::string(str)); } } int sc_main (int argc, char* argv[]) { sc_clock clk ("my_clock",MIN_PERIOD,0.5); sc_signal<bool> rst; sc_signal<uint_16b> data[MAX_N]; sc_signal<uint_8b> type; // Connect the DUT TOPMODULE<MAX_N> dut("dut"); dut.i_clk(clk); dut.i_rst(rst); dut.i_type(type); for (int i = 0; i < MAX_N; i++) dut.o_data[i](data[i]); // Open VCD file sc_trace_file *wf = sc_create_vcd_trace_file("SM_waveform"); debug(wf, &dut); //TODO // Test // End Test sc_close_vcd_trace_file(wf); return 0;// Terminate simulation } The error code I get is: Any help? I tried also with sc_assemble_vector( SM, &SUBMODULE::o_data).bind( o_data ) but this also does not work.
-
I created vector of fifos: sc_vector<sc_fifo> fifos; and in my constructor: template <unsigned S> class my_chnl : public my_chnl_if, public sc_channel { sc_vector<sc_fifo> fifos; //vectors of fifos //----------------------------------------------------------- public: //----------------------------------------------------------- //constructor //----------------------------------------------------------- explicit my_chnl(sc_module_name nm, unsigned _size = 4) : sc_channel(nm), fifos("FIFO") { fifos.init(S, _size); } ..... I am getting compile error saying that include/sysc/utils/sc_vector.h:634: error: \u2018c\u2019 cannot be used as a function If I do fifos.init(S), it works, but I get default size of 16. How do I set custom size? Any help? Thanks
-
I need to create a TLM module (that here we will call top_level) containing an array of TLM target modules (defined by class reg). As a consequence, the top_level module should implement the tlm_bw interface, and contain an array of initiator sockets, each bound to a target socket of the reg modules. Is it possible to implement this hierarchy by using the sc_vector construct? Here is a snapshot of the code that I am trying to implement, to give a clearer idea: Top level #include "reg.h" class top_level : public sc_module , public virtual tlm::tlm_bw_transport_if<> { private: sc_time time; sc_vector<reg*> register_file; tlm::tlm_generic_payload reg_trans; public: sc_vector <tlm::tlm_initiator_socket<>*> initiator_socket; ... }; Target module: class reg : public sc_module , public virtual tlm::tlm_fw_transport_if<> { public: tlm::tlm_target_socket<> target_socket; virtual void b_transport(tlm::tlm_generic_payload& trans, sc_time& t); reg(sc_module_name name_); ... }; When trying to compile, the compiler returns this error: error: ISO C++ forbids declaration of ‘sc_vector’ with no type error: expected ‘;’ before ‘<’ token referring to both the instances of sc_vector, as if neither my class nor the initiator_socket class were recognized as datatypes... Best regards, S.
-
I am trying to code a very generic module that takes the number of elements of a sc_vector of sc_in from an argument. This module looks like: transformation_arbiter.h using namespace sc_core; using namespace sc_dt; class transformation_arbiter : public sc_module { public: sc_in<bool> clk; sc_vector< sc_in<bool> > enable_in; . . . private: unsigned pre_rep; public: SC_HAS_PROCESS( transformation_arbiter ); transformation_arbiter( sc_module_name trans_arbiter, unsigned ext_pre_rep ): sc_module( trans_arbiter ), pre_rep( ext_pre_rep ), enable_in( "enable_in" ) { SC_THREAD( arbitrate ); sensitive << clk; } void arbitrate() { enable_in.init( pre_rep ); . . . } Then I am instantiating this module, along with a sc_vector of another module (request_generator.cpp) in a top module (top.cpp): request_generator.h . . . using namespace sc_core; using namespace sc_dt; class req_generator : public sc_module { public: //ports: sc_in_clk clk; sc_out<bool> enable_out; . . . top.h #include "trans_arbiter.h" #include "request_generator.h" . . . sc_signal<bool> signal[4]; sc_vector<req_generator> req_gen; transformation_arbiter trans_1_arb; . . . and top.cpp #include top.h top::top(sc_module_name sys_m): sc_module(top_m), trans_1_arb ( "trans_1_arb", 4 ), req_gen( "req_gen", 4) { . . . for ( auto i = 0; i < REQ_MODULES; ++i ) { trans_1_arb.enable_in[i].bind ( signal[i] ); } . . . } The problem is that this causes a segmentation fault in the bind instruction: Program received signal SIGSEGV, Segmentation fault. 0x0000000000412501 in sc_core::sc_vector<sc_core::sc_in<bool> >::operator[] (this=0x7fffffffcec0, i=0) at ./systemc-2.3.1/include/sysc/utils/sc_vector.h:384 384 { return *static_cast<element_type*>( base_type::at(i) ); } If I don't use de delayed initialization of the sc_vector like this: public: SC_HAS_PROCESS( transformation_arbiter ); transformation_arbiter( sc_module_name trans_arbiter ): sc_module( trans_arbiter ), enable_in( "enable_in", 4) { SC_THREAD( arbitrate ); sensitive << clk; } void arbitrate() { . . . } The code works, but then it is not generic anymore, since several instances of the module could have different number of ports, and not always 4. I'd really appreciate any help on this issue. Thanks, Fernando
-
I am trying to get an interface binded with a vector of port declared as sc_vector<sc_in<bool> > : std::vector<sc_object*> children = get_child_objects(); sc_signal<bool> *s = NULL; const char *tmp = "sc_vector"; for (unsigned i = 0; i < children.size(); i++) { if (strcmp(nm, children->basename()) == 0) { if (strcmp(children->kind(), tmp) == 0) { sc_vector<sc_in<bool> > *v = dynamic_cast<sc_vector<sc_in<bool> > * > (children); if (v != 0) { s = dynamic_cast<sc_signal<bool> *> (&v->at(0)); } } } } In the above code, I got the value of s as NULL. I have binded a port with signal, but still it's unexpected behavior. Am I doing something wrong here ??
-
Hello, I've been trying to instantiate (if I'm not mistaken) an array of submodules that were created using sc_vector. So far, I've followed the recommendations for using custom creator functions, but I'm kind of lost at how to actually make it work. Especially with sc_bind, which keeps returning me errors. The module master houses an array of ports that will be connected to a corresponding number of slaves. Order of connection does not matter. I'm using MSVC++ 10. The code is as follows: class top : public sc_module { //Submodule declarations master master_i; sc_vector<slave> slave_i; public: // Constructor top( sc_module_name module_name , int k ) : sc_module( module_name ) , master_i("master"), slave_i("slave") { slave_i.init(N_SLAVE, sc_bind(&top::create_slave, this, sc_unnamed::_1, sc_unnamed::_2)("slave",k)); sc_assemble_vector(slave_i, &slave::target_port).bind(master_i.initiator_port); } The creator function, which is a member of the class top, is as follows: static slave* top::create_slave(const char* name, size_t idx) { slave* s = new slave(name,1); // Hardcoding not intended; it's just to get it to // compile return s; } slave class constructor prototype: slave( sc_module_name module_name , int k ); Errors that I have so far: 1>c:\systemc\systemc-2.3.1\src\sysc\packages\boost\bind.hpp(63): error C2825: 'F': must be a class or namespace when followed by '::' 1> c:\systemc\systemc-2.3.1\src\sysc\packages\boost\bind\bind_template.hpp(15) : see reference to class template instantiation 'sc_boost::_bi::result_traits<R,F>' being compiled 1> with 1> [ 1> R=sc_boost::_bi::unspecified, 1> F=slave *(__cdecl *)(const char *,size_t) 1> ] 1> c:\users\khairul\dropbox\cours\systemc\examples\source\11\master_slave\top.h(32) : see reference to class template instantiation 'sc_boost::_bi::bind_t<R,F,L>' being compiled 1> with 1> [ 1> R=sc_boost::_bi::unspecified, 1> F=slave *(__cdecl *)(const char *,size_t), 1> L=sc_boost::_bi::list3<sc_boost::_bi::value<top *>,sc_boost::arg<1>,sc_boost::arg<2>> 1> ] Any ideas? Thanks,
-
I am trying to use an sc_vector of modules with a custom creator to pass constructor arguments. It seems to work and run through the entire program, but at exit causes a segfault. GDB shows that this is due to to sc_vector calling the destructor of the module. I have no dynamically-allocated memory or pointers in the module. Here's the overview: outside of sc_main (global -- but I also tried inside of sc_main): -------------------------- struct create_mod { unsigned int m_arg1; unsigned int m_arg2; create_mod(unsigned int arg1, unsigned int arg2) : m_arg1(arg1), m_arg2(arg2) {} mod* operator()(const char* name, size_t) { return new mod(name, m_arg1, m_arg2); } }; Inside sc_main: --------------------------- unsigned int num_of_mods = 8; unsigned int args1 = 5, args2 = 4; sc_vector<mod> vec_mod("mods"); vec_mod.init(num_of_mods, create_mod(args1, args2)); // ... use vec_mod, bind ports, etc ... return 0; So the program runs, then segfaults at the end with "core dumped". GDB results: Backtracing shows: Note the bit in red. Also note that line 334 is the closing brace of sc_main. Also: As I said, I have no dynamically-allocated memory in the class. I have tried an empty destructor (as well as = default since I'm using C++11) but got the same result. Any ideas? Thanks in advance.
-
Hi, So I have a submodule having an array of boolean input ports. Now in the top module, I define an sc_vector of the submodule type. Also, I define an array of sc_vector signals to be bound to. Questions: Can I use an array of sc_vectors? Any conventions on using them? eg: can I write sc_vector < sc_signal <bool> > operand_vec[max_operands]; If no, then is there any work around for this? Also, I now need to assemble and bind these ports: The code below doesn't seem to work. Both the stack_cnt_vec and operand_vec are initialized properly. for(int i=0;i<max_operands;i++){ operand_vec[i].init(10); } for(int i=0; i<10; i++) { sc_assemble_vector( stack_cnt_vec, &StackController::operands[i]).bind( operand_vec[i] ); } Thanks a lot for your time.