Jump to content


  • Posts

  • Joined

  • Last visited

About kaiserhaz

  • Birthday 06/19/1991

Profile Information

  • Gender
  • Location
    Kuala Lumpur
  • Interests
    Formal verification, functional verification, SystemC in general

Recent Profile Visitors

571 profile views

kaiserhaz's Achievements


Member (1/2)



  1. My bad, seems to me like I should have used a proper variable rather than calling it directly like I did. I declared an sc_time var called delay and initialised it to SC_ZERO_TIME and used that in the b_transport call. That did the job. Btw to answer your question, it didn't solve the problem.
  2. Hello, I'm trying to compile a design with a TLM2 socket (simple_initiator_socket) in ModelSim (sccom). So far, the compiler returns an error saying that there is no function called b_transport. Yet I have this same design working in the PoC SC simulator, so I'm guessing that ModelSim is doing things differently than the PoC. However ModelSim does point out an alternative, which was to use blocking_transport_if's version. I believe this was the one used all along in the PoC, and it should be the same in ModelSim. Any ideas? Here are the designs: Initiator /** * RTL-to-TLM2 Adaptor */ ... /** Includes **/ ... #include <tlm.h> #include <tlm_utils/simple_initiator_socket.h> ... struct rtl_to_tlm2_adaptor: public sc_channel { /** TLM-2 simple initiator socket **/ tlm_utils::simple_initiator_socket<rtl_to_tlm2_adaptor> rtt2a_socket; ... /** Adaptor constructor **/ SC_HAS_PROCESS( rtl_to_tlm2_adaptor ); rtl_to_tlm2_adaptor(sc_module_name _name) : sc_module(_name), addr(0), data(0), cmd(tlm::TLM_IGNORE_COMMAND) { // Construct and name socket SC_THREAD(write_thread); // Register adaptor channel thread SC_THREAD(read_thread); // Register read/write method trans = new tlm::tlm_generic_payload; // Create new payload instance } private: ... // Variables defined here /** Methods **/ // Sets up TLM2 payload void payload_setup(tlm::tlm_generic_payload* trans, tlm::tlm_command cmd, signed short& data, uint64 addr) { // Initialize 8 out of the 10 TLM-2 attributes, byte_enable_length and extensions being unused trans->set_command(cmd); trans->set_address(addr); trans->set_data_ptr(reinterpret_cast<unsigned char*>(&data)); trans->set_data_length(MEM_DATA_WORD_LEN); trans->set_streaming_width(MEM_DATA_WORD_LEN); trans->set_byte_enable_ptr(0); trans->set_dmi_allowed(false); trans->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); } // Local b_transport used to execute the standard TLM2 procedures void local_b_transport() { payload_setup(trans, cmd, data, addr); // Payload setup rtt2a_socket->b_transport(*trans, sc_time(SC_ZERO_TIME)); // Blocking transport call // Initiator obliged to check response status and delay if (trans->is_response_error()) SC_REPORT_ERROR("TLM-2", "Response error from b_transport"); } // Memory write procedure void mem_write() { cmd = tlm::TLM_WRITE_COMMAND; // Set command ... local_b_transport(); // Call local b_transport ... } // Memory read procedure void mem_read() { cmd = tlm::TLM_READ_COMMAND; // Set command ... local_b_transport(); // Call local b_transport ... } }; #endif Target /** * Generic memory instance, mostly inspired by Doulos' example */ ... /** Includes **/ #include <tlm.h> #include <tlm_utils/simple_target_socket.h> ... struct gen_mem: sc_module { /** TLM-2 simple target socket **/ tlm_utils::simple_target_socket<gen_mem> mem_socket; /** Generic memory constructor **/ SC_CTOR(gen_mem) : mem_socket("mem_socket") { // Register callback for incoming b_transport interface method call mem_socket.register_b_transport(this, &gen_mem::b_transport); dont_initialize(); // Mark to not initialize thread // Initialize memory with random data mem_reset(); } // TLM-2 blocking transport method virtual void b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) { tlm::tlm_command cmd = trans.get_command(); // Get command sc_dt::uint64 adr = trans.get_address(); // Get address unsigned char* ptr = trans.get_data_ptr(); // Get data pointer unsigned int len = trans.get_data_length(); // Get data length unsigned char* byt = trans.get_byte_enable_ptr(); // Get byte enable pointer unsigned int wid = trans.get_streaming_width(); // Get streaming width // Obliged to check address range and check for unsupported features if (adr >= sc_dt::uint64(MEM_SIZE) || byt != 0 || len > 16 || wid < len) SC_REPORT_ERROR("TLM-2", "Target does not support given generic payload transaction"); // Obliged to implement read and write commands if (cmd == tlm::TLM_READ_COMMAND) { // Read command memcpy(ptr, &mem[adr], len); // Use memcopy function to copy memory address pointer // cout << sc_time_stamp() << " MEMORY: Reading value " << *(mem+adr) << " @" << adr << endl; } else if (cmd == tlm::TLM_WRITE_COMMAND) { // Write command memcpy(&mem[adr], ptr, len); // Use memcopy function to copy to memory // cout << sc_time_stamp() << " MEMORY: Writing value " << *ptr << " @" << adr << endl; } else if (cmd == tlm::TLM_IGNORE_COMMAND) { // Reset command mem_reset(); // Reset memory // cout << sc_time_stamp() << " MEMORY: Reset requested" << endl; } else SC_REPORT_ERROR("TLM-2", "Command not supported"); // Obliged to set response status to indicate successful completion trans.set_response_status(tlm::TLM_OK_RESPONSE); // Realize wait delay to advance simulation time wait(delay); } private: unsigned short mem[MEM_SIZE]; // Memory array instance void mem_reset() { for (int i = 0; i < MEM_SIZE; i++) mem[i] = 0x21; // 33 in decimals } }; #endif Error printout # Model Technology ModelSim PE sccom 10.4a compiler 2015.03 Mar 25 2015 # # In file included from source/testbench/../module/c/memory.h:11, # from source/testbench/cpu_testbench.h:11, # from source/testbench/cpu_testbench.cpp:5: # source/testbench/../module/c/rtl_to_tlm2_adaptor.h: In member function 'void rtl_to_tlm2_adaptor::local_b_transport()': # source/testbench/../module/c/rtl_to_tlm2_adaptor.h:148: error: no matching function for call to 'tlm::tlm_fw_transport_if<tlm::tlm_base_protocol_types>::b_transport(tlm::tlm_generic_payload&, sc_core::sc_time)' # C:/modeltech_pe_10.4a\include\systemc/tlm_core/tlm_2/tlm_2_interfaces/tlm_fw_bw_ifs.h:54: note: candidates are: void tlm::tlm_blocking_transport_if<TRANS>::b_transport(TRANS&, sc_core::sc_time&) [with TRANS = tlm::tlm_generic_payload]
  3. Kartik, you are right in fact. I had used a wait() in an SC_METHOD, but it wasn't in that module that I showed. It was due to the use of a mutex lock() statement in an SC_METHOD. Thanks.
  4. Hello, No, I am sure that it was from an SC_THREAD. SC_THREAD( mem_constr_module_thread ); ... void mem_constr_module_thread() { ... if(mem_c0->m_t0->r_nw.read() == SC_LOGIC_1) { write(); wait(_mem_write_access_time, MEM_TIME_UNIT); // This one is ok } else { wait(_mem_read_access_time, MEM_TIME_UNIT); // This one triggers the error } ... } _mem_[read|write]_access_time and MEM_TIME_UNIT are constants defined elsewhere. I keep thinking that might be a bad pointer from elsewhere. But I can't think of anything.
  5. Hello, I was doing a simulation and I keep getting a runtime error exception (MSVC). I traced the error to a wait() statement. What could be the cause? Thank you,
  6. I did set it previously. I found out the problem by the way. I set simulation duration to be exactly the same as that of the b_transport, therefore somehow the simulation ends after the call to wait. Maybe I need more training in writing adaptor-type transactors? Kinda getting tedious trying to interface RTL and TLM
  7. Hello, I used b_transport in of my TL models to exchange data from a transactor to a memory. It was a read/write/reset operation kinda thing. Data from memory is transferred to another module attached to the transactor. What I noticed was at the end of my b_transport call, the simulation ends directly, without returning to the transactor thread in order to affect the obtained data from memory (in case of a read operation, for example) to the port connecting the transactor and the other module. Why is this? Code for reference: memory // TLM-2 blocking transport method virtual void b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) { /** Code here to transfer data **/ // Realize wait delay to advance simulation time wait(delay); // After wait, the simulator goes directly back to sc_main } transactor void thread_process() { /** Code here **/ while(true) { wait(CLK->posedge_event()); // Wait on CLK posedge event /** More code here **/ payload_setup(trans, cmd, data_ref, addr); rtt2a_socket->b_transport(*trans, delay); // Blocking transport call. Trans is a generic payload // I expected the program to return here, but it didn't // Initiator obliged to check response status and delay if (trans->is_response_error()) SC_REPORT_ERROR("TLM-2", "Response error from b_transport"); if(cmd == tlm::TLM_READ_COMMAND) DATA->write(d_word_t(data)); // Write data back to port. So far, this does not work properly } Thank you,
  8. Wouldn't you need to use the bind() method for binding? Not sure about binding ports during construction.
  9. Shoot, I knew something felt wrong It's supposed to be sc_bv<32> instead of sc_bit<32>. My bad.
  10. Hello, As far as I know, in SystemC one would model a register (or memory) as a an array, be it unidimensional or multidimensional. It's not worth the effort of actually using 'real hardware' registers and memory-mapped addresses (correct me if I'm wrong). The whole point of using SystemC to model systems is to be able to describe functionality and not worry about implementation too much. In your case, the control register could be represented as an sc_bit<32> or sc_lv<32>, as do other registers: /** registers.h **/ sc_bit<32> control_register // ADC control reg sc_bit<32> status_register // ADC status reg // Other registers below /*EOF*/ In this case, writing to reg would be as such: control_register = 2 // Not sure if you need to cast the 2, I think you do need to Alternatively, you could use an array of sc_bit, and define the address for specific registers as follows: /** registers.h **/ #define ADC_CTRL_REG 0 #define ADC_STAT_REG 1 // Other reg addresses sc_bit<32> adc_reg_file[/*size of regfile, or number of regs you want to have in ADC*/] /*EOF*/ In this case writing to a register would be as such: adc_reg_file[ADC_CTRL_REG] = 2 // Again I'm sure you'd have to cast it Instead of arrays, you can also use sc_vector. Technically, you could also still use the memory-mapped addresses. In this case, you could employ any of the methods above, but you'll need a translation method to convert that address to a simpler index (i.e. 0x40038000 -> /*Some int index, like 0 for example*/). Hope that helps.
  11. @Matteo Thanks. I'll have a look at that. @Ruchir In your opinion, would the many 'if's affect the performance? I was specifically concerned with that because at almost each loop, there are a minimum of 4 conditions to test. In hardware terms, I'd have to use comparator blocks, and I'd rather save cost than using 4 of them.
  12. I did a bit of reading on the subject of profiling in MSVC. Turns out for VS2010 Professional, there are no tools available Though they did mention a standalone tool. I'm checking that out at the moment. Are there other alternatives?
  13. I don't really know how to in MSVC. Is there a tool that I can use?
  14. Hello, I've recently completed a design but I'm not convinced that it is an optimal one. How would you modify this to give optimal speed? EDIT: I've attached it in a file. vga_controller_edit.txt
  • Create New...