svinco

Members
  • Content count

    7
  • Joined

  • Last visited

  1. Dear all, I implemented a memory manager (implementing the tlm_mm_interface interface). However, whenever I use the manager with TLM, I get loads of memory leaks, that seem to be caused by the new in the allocate method. Does anybody know an alternative implementation of this, or does anybody understand how I could avoid the leaks? What am I doing wrong? Best regards, S. #include <systemc.h> #include <tlm.h> class mem_manager : public tlm::tlm_mm_interface{ public: std::vector<tlm::tlm_generic_payload *> free_list; tlm::tlm_generic_payload * allocate(); void free(tlm::tlm_generic_payload *); tlm::tlm_generic_payload * ptr; private: ~mem_manager(); }; mem_manager::~mem_manager(){ } tlm::tlm_generic_payload * mem_manager::allocate(){ if (!free_list.empty()) { ptr = free_list.back(); free_list.pop_back(); cout<<"free list not empty"<<endl; } else { ptr = new tlm::tlm_generic_payload(this); cout<<"free list empty"<<endl; } return ptr; } void mem_manager::free(tlm::tlm_generic_payload * trans){ free_list.push_back((tlm::tlm_generic_payload *)trans); }
  2. Dear all, I am new to payload extensions and I would appreciate a feedback on whether I am doing things right.. I need to declare a simple payload extension, including two additional fields: a reset value a 16 bit bit vector representing the value of a register In the header, I simply declare the clone/copy from functions, plus my additional fields: class reg_extension : public tlm::tlm_extension<reg_extension>{ public: reg_extension(); tlm::tlm_extension_base* clone() const ; void copy_from(tlm::tlm_extension_base const &); bool reset; sc_bv<16> value; }; And then I implemented the functions, by taking care of the additional reset and value fields: reg_extension::reg_extension(){ reset = false; value = sc_bv<16>(0); } tlm::tlm_extension_base * reg_extension::clone() const{ cout<<"Executing clone!"<<endl; reg_extension * ext = new reg_extension(); ext->reset = this->reset; ext->value = this->value; return ext; } void reg_extension::copy_from(tlm::tlm_extension_base const & ext){ reset = static_cast<reg_extension const &>(ext).reset; value = static_cast<reg_extension const &>(ext).value; } Is this enough for the extension to work? Best regards, S.
  3. Dear all, I am new to payload extensions and I would appreciate a feedback on whether I am doing things right.. I need to declare a simple payload extension, including two additional fields: a reset value a 16 bit bit vector representing the value of a register In the header, I simply declare the clone/copy from functions, plus my additional fields: class reg_extension : public tlm::tlm_extension<reg_extension>{ public: reg_extension(); tlm::tlm_extension_base* clone() const ; void copy_from(tlm::tlm_extension_base const &); bool reset; sc_bv<16> value; }; And then I implemented the functions, by taking care of the additional reset and value fields: reg_extension::reg_extension(){ reset = false; value = sc_bv<16>(0); } tlm::tlm_extension_base * reg_extension::clone() const{ cout<<"Executing clone!"<<endl; reg_extension * ext = new reg_extension(); ext->reset = this->reset; ext->value = this->value; return ext; } void reg_extension::copy_from(tlm::tlm_extension_base const & ext){ reset = static_cast<reg_extension const &>(ext).reset; value = static_cast<reg_extension const &>(ext).value; } Is this enough for the extension to work? Best regards, S.
  4. Dear all, to define extensions of the generic payload, I defined also a memory manager class, implementing the tlm_mm_interface. I googled and tried almost all implementations available out there - they all generate memory leaks (as bad as 80 bytes in 2 blocks, according to Valgrind). Can anybody help me? The issue seems to be caused by the allocate method. Header file: class mem_manager : public tlm::tlm_mm_interface{ public: std::vector<tlm::tlm_generic_payload *> free_list; tlm::tlm_generic_payload * allocate(); void free(tlm::tlm_generic_payload *); tlm::tlm_generic_payload * ptr; private: ~mem_manager(); }; Implementation: mem_manager::~mem_manager(){ } tlm::tlm_generic_payload * mem_manager::allocate(){ if (!free_list.empty()) { ptr = free_list.back(); free_list.pop_back(); cout<<"free list not empty"<<endl; } else { ptr = new tlm::tlm_generic_payload(this); cout<<"free list empty"<<endl; } return ptr; } void mem_manager::free(tlm::tlm_generic_payload * trans){ free_list.push_back((tlm::tlm_generic_payload *)trans); } Example of code using the memory manager: tlm::tlm_generic_payload * trans; sc_time time; mem = new mem_manager(); trans = mem->allocate(); payload_data = new reg_extension; payload_data->value = sc_bv<16>("01"); payload_data->reset = 1; trans->set_data_length(sizeof(register_data_t)); trans->set_auto_extension(payload_data); trans->set_address(0); trans->set_write(); initiator_socket->b_transport(*trans, time); if(trans->is_response_ok()){ } else{ cout<<"Error!"<<endl; } Regards, S.
  5. Dear all, is it possible to apply standard SystemC tracing to tlm_extensions? I defined my own tlm extension to add a reset and a value fields to the standard payload: class reg_extension : public tlm::tlm_extension<reg_extension>{ public: reg_extension(); tlm::tlm_extension_base* clone() const ; void copy_from(tlm::tlm_extension_base const &); bool reset; sc_bv<16> value; }; Then, my testbench declares and uses it to carry data to/from the target: class testbench : public sc_module , public virtual tlm::tlm_bw_transport_if<> { public: tlm::tlm_initiator_socket<> initiator_socket; reg_extension * payload_data; ... } void testbench::run() { tlm::tlm_generic_payload * trans; sc_time time; mem = new mem_manager(); trans = mem->allocate(); payload_data = new reg_extension; payload_data->value = sc_bv<16>("00001111"); payload_data->reset = 1; trans->set_data_length(sizeof(register_data_t)); trans->set_auto_extension(payload_data); trans->set_address(0); trans->set_write(); initiator_socket->b_transport(*trans, time); ... } In my main, I try to apply standard tracing: int main(int argc, char* argv[]) { toplevel top("top"); sc_trace_file* fp = sc_create_vcd_trace_file("wave"); fp->set_time_unit(1, SC_NS); sc_trace(fp, top.tb.payload_data->reset, "reset" ); sc_trace(fp, top.tb.payload_data->value, "value" ); sc_start(); sc_close_vcd_trace_file(fp); return 0; } The code compiles correctly, but: with SystemC 2.2.0, the generated trace is weird (see attached - I truncated the value as it had far too many digits) things get worse when compiling with SystemC 2.3.0, as the execution returns this error: My impression is that memory is somehow not managed - this would explain the wrong size for the value field, the huge correponding value, and the bad_alloc. Please note that I forced some wait invocations to advance simulation time, so that write operations onto the extension fields occur at different simulation times. Thank you in advance, Regards, S. wave.vcd
  6. Ralph, thank you for your prompt answer. I hadn't realized that the sc_vector is a novel construct of the 2.3.0 version of SystemC - and for some reason my files were working with the 2.2 version. It now works :) I also avoided using the class pointer. The resulting declarations are: sc_vector<reg > register_file; sc_vector <tlm::tlm_initiator_socket<> > initiator_socket; Thank you for your support. Regards, S.
  7. 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.