mohitnegi Posted April 17, 2013 Report Share Posted April 17, 2013 could any one help me understand this TLM example for a simple counter ..... // TLM counter // compiler: Visual C++ 2008 Express Edition // #include <stdio.h> #include <systemc.h> #include "tlm.h" #include "tlm_utils/simple_initiator_socket.h" #include "tlm_utils/simple_target_socket.h" using namespace tlm; using namespace tlm_utils; // // C++ counter // unsigned int counter(unsigned int cnt) { return (cnt+1); } // // SystemC counter module // class counter_module : public sc_module { SC_HAS_PROCESS(counter_module); virtual void increment_request_transport(tlm_generic_payload& tx, sc_time& dt); public: simple_target_socket<counter_module> increment_socket; private: unsigned int cnt; public: counter_module(sc_module_name nm) : sc_module(nm), increment_socket("increment_socket") { increment_socket.register_b_transport(this, &counter_module::increment_request_transport); cnt=0; } const char* hdl_name() const { return "counter_module"; } }; // // Transport Handler // void counter_module::increment_request_transport(tlm_generic_payload& tx, sc_time& dt) { if(tx.get_command() == TLM_READ_COMMAND) { cnt = counter(cnt); tx.set_data_length(4); unsigned char rv[5]; rv[0] = cnt & 0xFF; rv[1] = (cnt>>8) & 0xFF; rv[2] = (cnt>>16) & 0xFF; rv[3] = (cnt>>24) & 0xFF; //cout << " cnt = " << (int)rv[0] << " " << (int)rv[1] << " " << (int)rv[2] << " " << (int)rv[3] << endl; tx.set_data_ptr(rv); tx.set_response_status(TLM_OK_RESPONSE); } else if(tx.get_command() == TLM_WRITE_COMMAND) // Reset actually { cnt = 0; unsigned char rv[5]; rv[0] = cnt & 0xFF; rv[1] = (cnt>>8) & 0xFF; rv[2] = (cnt>>16) & 0xFF; rv[3] = (cnt>>24) & 0xFF; tx.set_data_length(4); tx.set_data_ptr(rv);//conversion from int to char iccurs tx.set_response_status(TLM_OK_RESPONSE); } else tx.set_response_status(TLM_ADDRESS_ERROR_RESPONSE); } // // Stimulus generator // class stimulus: public sc_module { SC_HAS_PROCESS(stimulus); public: simple_initiator_socket<counter_module> read_increment; tlm_generic_payload tx; void run(); void reset_counter(); unsigned int read_counter(); stimulus(sc_module_name nm) : sc_module(nm), read_increment("read_increment") { SC_THREAD(run); } const char* hdl_name() const { return "stimulus"; } }; // // Stimulus main process // void stimulus::run() { reset_counter(); wait(1, SC_NS); for(int i=1; i<22; i++) { cout << "Counter = " << read_counter() << " at cycle " << i << endl; wait(1, SC_NS); } reset_counter(); wait(1, SC_NS); for(int i=23; i<100; i++) { cout << "Counter = " << read_counter() << " at cycle " << i << endl; wait(1, SC_NS); } sc_stop(); } // // Reset counter request // void stimulus::reset_counter() { tx.set_address(0); unsigned char value[5] = {0,0,0,0,0}; tx.set_data_ptr(value); tx.set_data_length(1); tx.set_command(TLM_WRITE_COMMAND); sc_time to(SC_ZERO_TIME); read_increment->b_transport(tx, to); wait(1, SC_NS); } // // Read counter (increment occurs before reading) // unsigned int stimulus::read_counter() { unsigned int data; tx.set_address(0); tx.set_data_length(1); sc_time to(SC_ZERO_TIME); tx.set_command(TLM_READ_COMMAND); read_increment->b_transport(tx, to); data = *reinterpret_cast<unsigned int*>(tx.get_data_ptr()); wait(20, SC_NS); return data; } // // Top-level module // int sc_main (int argc, char *argv[]) { counter_module counter_module_dut("counter_module_dut"); stimulus stimulus_dut ("stimulus_dut"); stimulus_dut.read_increment(counter_module_dut.increment_socket); sc_start(); return 0; } Quote Link to comment Share on other sites More sharing options...
apfitch Posted April 17, 2013 Report Share Posted April 17, 2013 Please ask a specific question - what specifically do you not understand? regards Alan Quote Link to comment Share on other sites More sharing options...
mohitnegi Posted April 17, 2013 Author Report Share Posted April 17, 2013 virtual void increment_request_transport(tlm_generic_payload& tx, sc_time& dt); this is something i dont understand why this has been used ... Quote Link to comment Share on other sites More sharing options...
Philipp A Hartmann Posted April 17, 2013 Report Share Posted April 17, 2013 The increment_request_transport just implements the b_transport interface for this component. It is registered on the forward path with the simple_target_socket, as you can see in the constructor. The name of this callback function can be chosen arbitrarily, as you can see (as long as the signature matches). That said, you should not adopt the coding style of this example. The target is not supposed to modify the data pointer (just its contents). Even worse, a pointer to a local variable is returned, which just happens to work by chance and may break at any moment (undefined behaviour). /Philipp sumit_tuwien and maehne 2 Quote Link to comment Share on other sites More sharing options...
mohitnegi Posted April 18, 2013 Author Report Share Posted April 18, 2013 thanks for your reply... could you help me understand what do you mean by signature matching ...... and // Reset counter request // void stimulus::reset_counter() { tx.set_address(0); unsigned char value[5] = {0,0,0,0,0}; tx.set_data_ptr(value); tx.set_data_length(1); tx.set_command(TLM_WRITE_COMMAND); sc_time to(SC_ZERO_TIME); read_increment->b_transport(tx, to); wait(1, SC_NS); } // // Read counter (increment occurs before reading) // unsigned int stimulus::read_counter() { unsigned int data; tx.set_address(0); tx.set_data_length(1); sc_time to(SC_ZERO_TIME); tx.set_command(TLM_READ_COMMAND); read_increment->b_transport(tx, to); data = *reinterpret_cast<unsigned int*>(tx.get_data_ptr()); wait(20, SC_NS); return data; } // why have they have two different definations for read_counter()..... Quote Link to comment Share on other sites More sharing options...
mohitnegi Posted April 18, 2013 Author Report Share Posted April 18, 2013 And another ques is there seems to be no socket binding ......done here.....or m i missing something ... Quote Link to comment Share on other sites More sharing options...
Philipp A Hartmann Posted April 18, 2013 Report Share Posted April 18, 2013 You should read up on C++ functions (and overloading) in general to learn about signatures. In the owning class of the simple_target_socket, a callback is registered instead of an explicit socket binding. One function is called reset_counter, the other one read_counter The stimulus class' socket (called read_increment) is bound in sc_main. But, as I said, the code is a rather bad example to learn about such basic things. /Philipp maehne 1 Quote Link to comment Share on other sites More sharing options...
mohitnegi Posted April 19, 2013 Author Report Share Posted April 19, 2013 any similar examples any body have .....pls share i m very interested ... Quote Link to comment Share on other sites More sharing options...
apfitch Posted April 19, 2013 Report Share Posted April 19, 2013 Have a look at the TLM examples on our website - http://www.doulos.com/knowhow/systemc/tlm2/ especially the "Getting Started with TLM2" tutorial, regards Alan Quote Link to comment Share on other sites More sharing options...
mohitnegi Posted April 23, 2013 Author Report Share Posted April 23, 2013 hello , i have a doubt when to use register transport and when to use only transport(could be blocking or non blocking).... With regards Mohit Negi Quote Link to comment Share on other sites More sharing options...
apfitch Posted April 23, 2013 Report Share Posted April 23, 2013 Hi Mohit, what do you mean by "register transport"? Alan -- http://www.doulos.com Quote Link to comment Share on other sites More sharing options...
mohitnegi Posted April 24, 2013 Author Report Share Posted April 24, 2013 hello Alan, actually i have seen in an example they have used register_b_transport for initiator and b_transport for target ..... With Regards Mohit Negi Quote Link to comment Share on other sites More sharing options...
apfitch Posted April 24, 2013 Report Share Posted April 24, 2013 Ok, that's when you use the Simple Sockets - have a look in the TLM2 documentation (in the SystemC 1666-2011 Language Reference Manual, which you can download from Accellera). There is a summary in there of the utilities that are provided with TLM2, including the "convenience sockets" - see section 16.1 regards Alan Quote Link to comment Share on other sites More sharing options...
mohitnegi Posted April 25, 2013 Author Report Share Posted April 25, 2013 Thanks Alan for that... I have another question that if we wish to use tlm_initiator_socket instead of simple_initiator_socket do we still require register callback....??? and when to use tlm_initiator_socket and simple_initiator_socket???.... With regards Mohit Negi Quote Link to comment Share on other sites More sharing options...
mohitnegi Posted April 25, 2013 Author Report Share Posted April 25, 2013 could you also help me when sc_module_name is used..... counter_module(sc_module_name nm) : sc_module(nm), increment_socket("increment_socket") and why is used in sc_has_process .... and could anyone explain me the above statement ...... Quote Link to comment Share on other sites More sharing options...
apfitch Posted April 25, 2013 Report Share Posted April 25, 2013 For your first question, please refer to Table 59 - Socket Types on page 521 of the standard. For your second question, please refer to section 5.2 sc_module - especially section 5.2.7, 5.2.8 regards Alan 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.