Jump to content

Philipp A Hartmann

Members
  • Posts

    547
  • Joined

  • Last visited

  • Days Won

    135

Everything posted by Philipp A Hartmann

  1. sc_link_mp, sc_inslave, sc_outmaster are elements of the old "SystemC Master-Slave library". This library has been an early approach to transaction-level modeling in SystemC. The original implementation will most likely not compile with IEEE 1666-20xx standard-compliant simulators. For high-level modeling, you should look into the TLM-1 and TLM-2 APIs, that are now part of the IEEE standard for SystemC. /Philipp
  2. If you find an answer to your question by yourself, please don't drop the original question and just add an answer to your own post. This lets other users benefit from the discussion. Thanks, Philipp
  3. I would use the clock generator coming with SystemC by instantiating an sc_clock (see Section 6.7 in IEEE 1666-2011): sc_clock clk( "clk" // name , sc_time(100, SC_NS) // period , 0.5 // duty cycle , sc_time(100, SC_NS) // start time , true ); // start with positive edge I've selected the parameters guessing from your code snippet. In "your" code, the first rising edge seems to occur at 100ns (start time). Play with the values as you need them. You can then bind this clock to any sc_in<bool> port in your system. /Philipp
  4. SC_ON, SC_OFF are related to "floating-point cast switches". You likely don't need to worry about these, if you don't know what problems these intend to address. Otherwise, please refer to Sections 7.10.7, 711.5 of IEEE 1666-2011. Syntaxwise, you currently try to invoke the function call operator on the sc_ufixed variable d (with an incompatible parameter). What do you intend to achieve? Do you want to assign a value? /Philipp
  5. It should. You should see a second "func2 start" line. Please post a complete example. Is there a difference between SystemC 2.3.0 and 2.3.1? Which platform/what compiler (flags)? /Philipp
  6. First of all, all "time units" related functions are deprecated and should not be used. These functions predate the IEEE standard for SystemC. That said, at the beginning of the simulation, sc_time_stamp() is SC_ZERO_TIME (i.e. 0). As a result, the conversion to "default time units" is zero as well. /Philipp
  7. As the original error message says, you are not supposed to disable() a process that is within a timed wait (i.e. wait(xx,SC_NS); in your case). See Section 5.6.6.2 of IEEE 1666-2011. Moreover, since your func2 process has no static sensitivity, the process will not run again after it is enabled, unless it is explicitly reset. See 5.6.6.2 again, quoting: If you want to enable/disable a process, the target process should be sensitive to events, instead of using timed waits itself. /Philipp
  8. Although Cygwin is not among the most widely tested platforms for the Accellera SystemC proof-of-concept simulator, the current version 2.3.1 has been tested successfully on Windows 7 SP1 (WoW64), (Cygwin 1.7.17)GNU C++ compiler versions gcc-3.4.4 through gcc-4.3.4 (x86)Please provide at least SystemC version platform (version), compiler (version), flags compile/runtime warnings and errors AFAIK, the _WIN32 macro tells that you're using the Windows API. Using the Windows API implies that you have support for __int64 and the like. Do you define _WIN32 explicitly on the command-line? Why? Cygwin does not provide this symbol by default. Greetings from Oldenburg, Philipp
  9. It's called "direct memory interface", because it's a direct access to a target's memory range. The target has no way to observe accesses from initiators to the currently allowed DMI ranges. If the target requires to observe such accesses, you should not grant DMI access for these address ranges during the relevant communication states/phases. Usually, DMI is preferred for the plain memory parts of the target's interface, while (control) registers often require explicit TLM transactions for that reason. hth, Philipp
  10. Your NOC module has indeed many signals. Hopefully, they are already organized as arrays, which you can replace by using appropriate sc_vectors, which can take an explicit name (prefix). As a general recommendation, you should consider to give your channels an explicit name to ease debugging of such errors. A simpler solution is probably to look at the two processes (txProcess, rxProcess) in your Router module. If the problem would be the duplicate binding of a single signal to multiple output ports, the error should have been reported during elaboration already. Instead, the error is raised during simulation, where both processes try to write to the same signal, most likely through the same (in)out port. This should be local enough to find manually. hth, Philipp
  11. If you bind the same interface object (a "single" b_transport) to both target sockets, there is no predefined way to determine the port through which the interface has been called. If you insist on using a plain tlm_target_socket instead of the tagged convenience sockets, you can build the tagging mechanism on your own by implementing a small helper that provides the forward interface (most notably b_transport), stores an ID internally and forwards the call including the ID to the module itself. Not sure, why you would need to reinvent that, though. /Philipp
  12. Sounds like you didn't look up the suggested parts in the standard. /Philipp
  13. The error is caused by the fact that the notify() function of sc_event returns nothing (i.e. 'void'). So you can't return the (non-existing) return value in the marked line above. Secondly, e_HCE is a local variable. You won't be able to trigger any other process by notifying this event. This looks wrong as well. /Philipp
  14. Make sure that you have the "process" function declaration in the body of host_cntrl: class host_cntrl : public sc_module { public: // SC_CTOR(), etc. private: void process(); }; /Philipp
  15. You don't have a member function called 'process' in your 'host_cntrl' class? Hard to tell without actual code. /Philipp
  16. Why don't you ask the process itself? std::cout << std::boolalpha << h1.dynamic() << std::endl; Short answer: Processes created from the process macros SC_THREAD,... are called "unspawned" processes, whereas processes created by sc_spawn are called (surprise!) spawned processes. Unspawned processes are by definition static processes, as the macros can't be used during simulation. On the other hand, spawned processes can be either static or dynamic processes: A dynamic process is created during simulation, whereas a static process is created during elaboration. hth, Philipp
  17. Your problem is not specific to sc_vector, but to C++ in general: You can't initialize a member of an SC_MODULE (or any other C++ class) in the body of the class itself. You need to do it in the constructor, using an initializer list: SC_MODULE(mod) { sc_vector<sc_signal<sc_uint<C_WIDTH> > > sDin; SC_CTOR(mod) : sDin("sDin", C_SIZE) // C++ initializer list { // ... } }; Greetings from Oldenburg, Philipp
  18. Ok, the next step could be to skip simulation and just run the elaboration/initialization via sc_start( SC_ZERO_TIME ); Secondly, you should break on the destructor of mod in the debugger to check whether you can see any indication why the destructor is called twice for the same object. If you have a memory corruption, this might be more difficult to track down. This looks unrelated and is probably caused by accessing unbound ports too early. For now, I think it's more likely that the problem is in your model rather than that there is a bug in SystemC 2.3.1. The sc_vector code didn't change much between 2.3.0 and 2.3.1. This also sounds like an unrelated problem. Good luck in the bug hunting. Feel free to share/post your simplified code if you have further questions. /Philipp
  19. For your convenience, I have created a simple example based on your code at EDA playground (which uses SystemC 2.3.0). Just add/correct the relevant parts and try to reproduce the problem. If the module has just the members you listed, I don't think the problem is related to mod itself. If you add the line after the call to sc_start, it should lead to an error as you can't instantiate additional modules after the end of the elaboration phase. If there is no such error, there may be something else going wrong here (memory corruption?). Do you keep seeing the segmentation fault, if you skip the sc_start call? /Philipp
  20. The creator struct and its use looks fine to me. What's suspicious is indeed the second call to ~mod() from within ~mod() itself. What types of members do you have in mod? How do you initialize them? Do you (ab)use smart-pointers? What happens, if you add the following line to sc_main? delete new mod("tmp", args1, args2); Can you assemble a minimal but compilable example demonstrating the problem? From your description above, it's more or less just the (relevant parts of the) definition of mod that's missing. @dakupoto: The sc_vector itself will cleanup its allocated elements. A creator function/class for sc_vector is one of the rare examples, where users must not write their own delete to the new. /Philipp
  21. Of course, sc_thread_process::prepare_for_simulation is called for dynamic processes as well, see sc_simcontext::create_[c]thread_process. But you should be able to observe the start of the simulation before the assertion fails, in case of a later resource exhaustion being the problem. You don't provide sufficient information about what kind of module you instantiate 6000-8000 times. Based on your comments, you seem to have at least 12000 threads in your simulation, which indeed seems to be quite many. You could try to add a simple (static) counter to the stack_protect call and print out a message for the first failing mprotect call to shed some more light on this issue. My guess would still be that some OS resources are running low. /Philipp
  22. It depends on your particular scenario, whether there is a significant benefit in maintaining a complex set of DMI allowances. If you think it is necessary, I would recommend to implement a dedicated data structure to store the DMI access information, which you can reuse and test separately keep the ranges non-overlapping and sorted by start-address (and probably have two sets for reads and writes in the initiator) use std::lower_bound to efficiently search the sorted vector internally merge adjacent/overlapping entries to keep the number of entries small forward the invalidate_direct_mem_ptr call to update the ranges in the (internal) vector /Philipp
  23. First of all, it is recommended to keep the stack protection activated (where available) to avoid arbitrary memory corruption upon stack overflow. Stack-related memory corruption is very hard to debug... Assuming, you're running on Linux, then secondly, there are indeed (kernel) resources allocated within the mprotect call. Quoting the mprotect(2) manpage: ERRORS ... ENOMEM Internal kernel structures could not be allocated. ENOMEM Addresses in the range [addr, addr+len-1] are invalid for the address space of the process, or specify one or more pages that are not mapped. (Before kernel 2.4.19, the error EFAULT was incorrectly produced for these cases.) Activating the memory protection on some page(s) requires to setup an appropriate memory mapping, of which a limited number can be created by the kernel. You can try to increase this limit by $ sudo bash -c 'echo 131060 > /proc/sys/vm/max_map_count' (which doubles the default number on my system). Last but not least, some additional questions: Do you encounter the problem during elaboration or during simulation? If it occurs during simulation, you may have "leaking" dynamic processes. If possible, try to reuse dynamic process instances you've created.Which version of SystemC are you using? There has been an internal "dynamic process/object leak" in some cases, which has been fixed in SystemC 2.3.0.Can you change some thread processes to method processes? SC_METHODs have a significantly lower simulation overhead. Especially, when you're using thousands of processes, this may be a worthy optimization.Hope that helps, Philipp
  24. The problem in those two lines is probably that you never clean up your p_dmi vector? Does it help to empty it when invalidating the DMI access in invalidate_direct_mem_ptr? p_dmi_enabled = false; p_dmi.clear(); Otherwise, you may need to implement a more efficient way to handle multiple active DMI accesses with a custom DMI table wrapped around p_dmi, allowing more efficient address range handling and lookup, e.g. by combining and sorting address ranges and avoiding duplicates. NB: Obviously, modelling a memory latency in the initiator does not improve the simulation speed of the model. I probably misunderstood your original question here.
  25. The code is still quite wrong: an array of pointers is not a two-dimensional array and won't work at all. You need to pass a contiguous memory block as data pointer in the generic payload. As said in my previous answer, you need to provide a buffer of the target type (i.e. the two dimensional array), not a raw pointer of unsigned char. Otherwise alignment, offsets and arithmetic will go completely wrong. I don't really understand, what you intend to do in print_memory, as there are still quite strange constants in use (128, 32, vs. MSIZE1, MSIZE2). Nevertheless, I tried to address your "casting issue" in the following (fully untested) snippet: template <typename DATA_TYPE, unsigned int BUS_WIDTH> void traffic_injector<DATA_TYPE,BUS_WIDTH>::print_memory(){ tlm::tlm_generic_payload trans; // no need to use a pointer, avoid memory leaks! trans.set_address(0); trans.set_read(); trans.set_data_length(32); // you only read 32 bytes?! // don't use a char pointer. use the "real" type instead // again, no need for dynamic allocation with leaking memory uint32_t data[MSIZE1][MSIZE2]; // sizes are just a guess // cast for generic payload data pointer trans.set_data_ptr(reinterpret_cast<unsigned char*>(data)); // don't you want to read the whole memory? trans.set_data_length( sizeof(data) ); uint32_t count = initiator_socket->transport_dbg( trans ); for(uint32_t j=0;j<MSIZE2;j++){ for(uint32_t i=0;i<MSIZE1;i++){ // no cast here, correct pointer arithmetic printf("MEM[%d][%d]=%d \n",j,i,data[i][j]))); } } } Side note: Please educate yourself about the C++ memory model and management. You leak memory in nearly every function. Never use new without a matching delete, C++ is not Java or C#. hth, Philipp
×
×
  • Create New...