mola Posted May 22, 2013 Report Share Posted May 22, 2013 I have the following code: class Top : public sc_core::sc_module{public:... sc_port<tlm::tlm_fifo_get_if<tlm::tlm_generic_payload*> > read_pTx; sc_port<tlm::tlm_fifo_put_if<tlm::tlm_generic_payload*> > write_pTx;... private: mysubmodule *pmysubmodule;} class mysubmodule: public sc_core::sc_module{public: ... sc_port<tlm::tlm_fifo_get_if<tlm::tlm_generic_payload*> > read_pTx; sc_port<tlm::tlm_fifo_put_if<tlm::tlm_generic_payload*> > write_pTx; ... } In Top constructor: SC_HAS_PROCESS(Top);Top::Top(...){pmysubmodule = new mysubmodule(...);pmysubmodule->read_pTx(read_pTx);pmysubmodule->write_pTx(write_pTx);} It compliles well. But when I run the test, I got Segmentation fault error at line: pmysubmodule->write_pTx(write_pTx); In debug tool, it shows that it stops at void sc_port_base::bind( this_type& parent_ ) { if( m_bind_info == 0 ) { // cannot bind a parent port after elaboration report_error( SC_ID_BIND_PORT_TO_PORT_, "simulation running" ); } ... } Does anyone know why and how to fix it? Thanks a lot! Annossyenudge 1 Quote Link to comment Share on other sites More sharing options...
ralph.goergen Posted May 23, 2013 Report Share Posted May 23, 2013 Hi. For me, it is hard to say what the problem is without some more information. First, yes it is not allowed to bind ports after the elaboration phase. How and when do you instantiate the Top module? If you do this after calling sc_start, the mentioned error occurs. But this does no expllain a segmentation fault. Second, is there any channel bound to your ports? In SystemC, you are allowed to bind ports to ports to cross hierarchy in the model. But finally, you have to bind a channel at any end of your hierarchy. The port solely forwards the interface of a channel. A channel provides the actual interface. Third, why do you use a pointer to a generic_payload object in your interface? Actually this is two questions. Why do you use a pointer? And why do you use tlm_generic_payload? tlm_fifo_get_if belongs to TLM 1 modelling, tlm_generic_payload is part of the TLM 2 modelling concept. It is not forbidden to mix them. But you should have any reason to do so. Greetings Ralph Quote Link to comment Share on other sites More sharing options...
mola Posted May 23, 2013 Author Report Share Posted May 23, 2013 Hi. For me, it is hard to say what the problem is without some more information. First, yes it is not allowed to bind ports after the elaboration phase. How and when do you instantiate the Top module? If you do this after calling sc_start, the mentioned error occurs. But this does no expllain a segmentation fault. Second, is there any channel bound to your ports? In SystemC, you are allowed to bind ports to ports to cross hierarchy in the model. But finally, you have to bind a channel at any end of your hierarchy. The port solely forwards the interface of a channel. A channel provides the actual interface. Third, why do you use a pointer to a generic_payload object in your interface? Actually this is two questions. Why do you use a pointer? And why do you use tlm_generic_payload? tlm_fifo_get_if belongs to TLM 1 modelling, tlm_generic_payload is part of the TLM 2 modelling concept. It is not forbidden to mix them. But you should have any reason to do so. Greetings Ralph 1. I instantiate the Top module before sc_start. 2. Yes. Channel will be bound to the Top port after Top is instantiated. But segmentation fault happens while Top is being instantiated. 3. I use a pointer because I think it more efficient than using the whole structure. Because I am using sockets and needs tlm_generic_payload. I tried to use sc_fifo. However, sc_fifo doesn't include the peek function. So I did some search and find the tlm_fifo is the way to go. Thanks. Quote Link to comment Share on other sites More sharing options...
ralph.goergen Posted May 24, 2013 Report Share Posted May 24, 2013 Hi. I tried to reproduce the problem but i couldn't. I used the following example and it did as expected. #include <systemc.h> #include <tlm.h> class mysubmodule: public sc_core::sc_module { public: sc_port<tlm::tlm_fifo_get_if<tlm::tlm_generic_payload*> > read_pTx; sc_port<tlm::tlm_fifo_put_if<tlm::tlm_generic_payload*> > write_pTx; SC_CTOR(mysubmodule) { } }; class Top : public sc_core::sc_module { public: sc_port<tlm::tlm_fifo_get_if<tlm::tlm_generic_payload*> > read_pTx; sc_port<tlm::tlm_fifo_put_if<tlm::tlm_generic_payload*> > write_pTx; private: mysubmodule *pmysubmodule; public: SC_CTOR(Top) { pmysubmodule = new mysubmodule("sub"); pmysubmodule->read_pTx(read_pTx); pmysubmodule->write_pTx(write_pTx); } }; int sc_main(int,char*[]) { tlm::tlm_fifo<tlm::tlm_generic_payload*> fifo("fifo"); Top top("top"); top.read_pTx(fifo); top.write_pTx(fifo); sc_start(20,SC_NS); return 0; } Quote Link to comment Share on other sites More sharing options...
ralph.goergen Posted May 24, 2013 Report Share Posted May 24, 2013 Could you maybe provide a small example that shows the erroneous behavior? Quote Link to comment Share on other sites More sharing options...
mola Posted May 29, 2013 Author Report Share Posted May 29, 2013 Thank you Ralph. I tried to debug it more and was able to fix it by adding read_pTx("read"), write_pTx("write") to mysubmodule constructor explicitly. I don't understand why I have to do this. Quote Link to comment Share on other sites More sharing options...
bluephilosopher Posted June 7, 2013 Report Share Posted June 7, 2013 hey Second, is there any channel bound to your ports?In SystemC, you are allowed to bind ports to ports to cross hierarchy in the model. But finally, you have to bind a channel at any end of your hierarchy. The port solely forwards the interface of a channel. A channel provides the actual interface. Hey Ralph, I have similar question: I have class father, it has different classes inside, son1, son2.but these classes have the same generic class definition, say class sonthen there is an another class, say, class mother now I want to use sc_method to run a function in class mother, which is sensitive to a variable called flag in class son...(i.e. there are actually two variables, in son1 and son2, but the definition of this variable is generic, which is in class son) What I did is to define like following:top: sc_signal<>flagson: sc_out<>flagmother: sc_in<>flag And for binding the signal, i did like thisfather1.son1.flag(flag)mother1.flag(flag) father1.son1.flag(flag)mother1.flag(flag) There is no compile error. But it doesn´t wrong.. The error is like below: Error: (E112) get interface failed: port is not bound: port 'Top_1.intController1.int0.port_0' (sc_out) In file: c:\data\systemc-2.3.0\src\sysc\communication\sc_port.cpp:230 You said it´s possible to bind cross hierachy, but how it´s realised Thanks Quote Link to comment Share on other sites More sharing options...
ralph.goergen Posted June 10, 2013 Report Share Posted June 10, 2013 Generally, you should go through the hierarchy step by step. And you should name your ports and signals by passing an name argument to its constructor. That helps understanding the error messages. In sc_main: Father father("father"); Mother mother("mother"); sc_signal< > s_flag("s_flag") // bind s_flag to father.flag and mother.flag mother.flag(s_flag); father.flag(s_flag); In father: sc_in < > flag; Son son; SC_CTOR(Father) : flag("flag") , son("son") { // bind father flag to son flag son.flag(flag); } Quote Link to comment Share on other sites More sharing options...
bluephilosopher Posted June 17, 2013 Report Share Posted June 17, 2013 Hey Ralph, thanks a lot. It works now. At the same time, I also found a similar example on cross hierarchy. Now I came to question of sc_event on cross hierarchy. I set the sc_event as the sc_signal like above. but it does not work. any suggestion? Quote Link to comment Share on other sites More sharing options...
ralph.goergen Posted June 18, 2013 Report Share Posted June 18, 2013 Hi. Plain events (sc_event, not signal/channel events) are not bound to anything. If you want to use an event declared in module A inside of module B, you need a handle to that event. You can use named events (name them by passing a const char * argument to its constructor). Named events can be found either by searching the sc_object hierarchy manually (get_child_objects ...) or by calling sc_find_event. sc_find_event expects the *hierarchical* name of the event as an argument. For more information see section 5.10 in the SystemC LRM (IEEE 1666 - 2011). Greetings Ralph Quote Link to comment Share on other sites More sharing options...
bluephilosopher Posted June 18, 2013 Report Share Posted June 18, 2013 Hey Ralph, thanks. But as you said sc_event is not bound to anything. So it´s could only be applied in the same module/ sub module, right? The thing is, I have multiple modules instantiated in top. and between these modules I need to write to a shared memory. and there is one module which will read from this shared memory, i.e. module A/B/C/D, write to it, and module E read it. But for sc_signal, it´s not allowed. I´m considering to use sc_semaphore, but after reading some reference books, i could not find this cross module application examples. thanks Quote Link to comment Share on other sites More sharing options...
ralph.goergen Posted June 18, 2013 Report Share Posted June 18, 2013 Hello again. To your first question: No. You can declare an sc_event wherever you want. And you can use them wherever you want. All you need to use them is a handle to the event and that is what you get from sc_find_event. A short example showing sc_find_event: #include <systemc.h> SC_MODULE(A) { sc_event ev; void proc() { std::cout << "notify ev: " << ev.name() << std::endl; ev.notify(5,SC_NS); } SC_CTOR(A) : ev("ev") { SC_METHOD(proc); } }; SC_MODULE( { sc_event ev; void proc() { wait(2, SC_NS); sc_event* evp = sc_find_event("modA.ev"); if (evp != NULL) { wait(*evp); std::cout << "mod B activated" << std::endl; } else { std::cout << "ev not found" << std::endl; } } void meth() { std::cout << "mod B method activated" << std::endl; } SC_CTOR( : ev("ev") { SC_THREAD(proc); SC_METHOD(meth); dont_initialize(); sensitive << *sc_find_event("modA.ev"); } }; int sc_main(int, char*[]) { A a("modA"); B b("modB"); sc_start(); return 0; } If you use sc_find_event in a static sensitivity list in the way shown here, be careful because the function might return NULL if the event is not found. In this case you get a memory access violation. Better check for NULL return before usage. In fact I am not sure if that solves your problem. at which level of abstraction do you want to model? Semaphores are high level constructs, signals RT level. In the sense of digital hardware at RTL, you should model explicit access infrastructure for the memory if you have multiple processes using it. You need some kind of arbiter an access protocol to handle concurrent access. At a higher level, with less timing accuracy, you can use a semaphore to arbitrate concurrent accesses and synchronize with sc_events. Greetings Ralph maehne 1 Quote Link to comment Share on other sites More sharing options...
bluephilosopher Posted June 26, 2013 Report Share Posted June 26, 2013 Hey Ralph, thanks. This really helps. The example is neat and easy to understand...I have not found the sc_find_event in my golden reference guide. ################################################## After rechecking my codes, I ran into another problem. I have a signal which is set to true in modules A and to false in module B. A process in module C is sensitive to the signal. For triggering the process in module C, I tried to use two buffers: set_sig and clear_sig, with either the sensitive list or event notification. Both work fine. Yet. I need to know the value of the signal for if-else calculation. The values of the two signals are actually the same. I tried to use the sc_signal_resolved, with which I only need a signal. Yet the value of the signal remains the same, i.e. "X" (A="0", B="1") Any suggestion? Quote Link to comment Share on other sites More sharing options...
ralph.goergen Posted June 26, 2013 Report Share Posted June 26, 2013 Think as an engineer. A signal is the model of an electrical wire. If driver A sets a voltage of 5 V, and driver B sets a voltage 0 V to the same wire, what do you think what happens? Thats why multiple drivers are not allowed for sc_signal. And thats why sc_signal_resolved becomes 'X' when you write '1' and '0' at the same time. You have to solve this problem in your architecture. Whenever multiple components may access the same resource, you should arbitrate them. Use whatever design pattern or bus-model you want, but you have to think about what should happen when two components access the memory at the same time. Greetings Ralph PS: For new problems without connection to the topic of this thread, it might be better to open a new one. Quote Link to comment Share on other sites More sharing options...
bluephilosopher Posted July 3, 2013 Report Share Posted July 3, 2013 Hey Rahlph, thanks for the explanation. Yes, you are right. That´s actually a hardware understanding.. I figured it with event and global variable, though it´s not a good solution, since the shared memory issue of global variables. but it works... thanks Quote Link to comment Share on other sites More sharing options...
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.