Jump to content

Philipp A Hartmann

Members
  • Content Count

    525
  • Joined

  • Last visited

  • Days Won

    126

Everything posted by Philipp A Hartmann

  1. The OS scheduler has nothing to do with the SystemC process scheduler. SystemC uses a custom, cooperative scheduler following the simulation semantics as defined in IEEE 1666-2011: Only one SystemC process is guaranteed to run at all times. Even if SystemC processes might be implemented as OS threads, their scheduling is enforced to follow the SystemC rules. You can't tell. All of them are "equal". Whether or not this is sufficient for the original poster's use case depends on his/her requirements. /Philipp
  2. The same would be the case for a plain C assert: #include <cassert> #define NDEBUG int main() { assert( false ); } I'll leave the solution as an exercise for the reader. ;-) (Hint: look for the word "before" in the link above.) /Philipp
  3. Yes, defining NDEBUG also disables the sc_assert statements in the SystemC proof-of-concept implementation. Having said that, I don't think it is a good idea to do so globally. You usually want your simulation to reliably abort in case of an error/bug, instead of running into arbitrary undefined behaviour. I would recommend to leave assertions active by default until profiling proves that (specific) assertions have a significant performance impact. In such cases, selectively disable only these assertions in optimized configurations. /Philipp
  4. First of all, it somewhat depends on the preemption scheme you need to support. Are the serial threads preemptible while running one of their phases? If not (and it looks like this in your description), you can refactor the model to only use M "real" SystemC threads, one for each parallel thread. The serial threads would then have an explicit "state" (i.e. the functional state and the phase they're) and the phases could be implemented as individual functions. When a serial thread is resumed, you can simply call the corresponding phase function from its assigned "parallel thread". Details left to the reader. ;-) hth, Philipp
  5. You can query the event() function of the signal, to check whether it has been triggered in the previous update phase (see IEEE 1666-2011, 6.4.9). Of course, multiple signals might have been updated even though your process is only invoked once. Greetings from Oldenburg, Philipp
  6. No. The evaluation order of runnable processes is implementation-defined in SystemC, see IEEE 1666-2011, 4.2.1.2. There is no (standardized) backdoor API to influence the process scheduling of the kernel. Of course, you can add additional layers of scheduling on top of the SystemC scheduler, e.g. by defining your process dependencies and notifying properly crafted sc_events to trigger the successor process(es). Another option might be to model the system with the SystemC AMS extensions, which provides the timed dataflow (TDF) model of computation. But this somewhat depends on the real requirements. Additionally, the resulting TDF schedule can only be implicitly defined by constraining the scheduler in terms of process dependencies (AFAIK). Greetings from Oldenburg, Philipp
  7. You could try to print the return value of the pthread_create call via strerror (untested): int notok = pthread_create( &cor_p->m_thread, &attr, &sc_cor_pthread::invoke_module_method, (void*)cor_p ); if ( notok ) { std::fprintf(stderr, "ERROR - could not create thread: %s\n", strerror(notok) ); } You either set a too small stack size (EINVAL), or are running out of resources (number of allowed threads, memory limits) (EAGAIN). You may need to rethink your modeling approach, given the huge number of processes you have. Before reinstalling your OS, you can try to use a MinGW compiler, as mentioned in my previous answer. If you run configure from within your Cygwin environment, specify the MinGW target and the MinGW compiler on the command-line: ../configure --target=i686-pc-mingw32 CXX=/path/to/mingw32/g++.exe Because performance-wise, Cygwin with Pthreads is probably the worst combination on Windows platforms. hth, Philipp
  8. There is indeed an issue in the Makefile.rules file, used when compiling the examples manually. Due to some incomplete try to stay backwards-compatible with the old TLM Makefiles (which used CC instead of CXX), the Makefiles prefer CC over CXX (even for the linking) if explicitly set by the user. You should be able to fix the problem by changing all occurrences of $(CC) to $(CXX) in both examples/sysc/Makefile.rules and examples/tlm/build-unix/Makefile.rules. I'll queue up this change for a future release of the proof-of-concept simulator. Thanks for reporting, Philipp
  9. I think it would be fairly straight-forward to add an sc_event_or_list overload to set_sensitivity, as it would just be expanded and appended to the set of events the process is statically sensitive to. For symmetry reasons, users would certainly want to have an sc_event_and_list overload as well, but this "mixed expression" sensitivity is currently not easy to add (e.g. to the proof-of-concept implementation) and nobody cared enough to propose an implementation. I agree that in your case there is some additional burden to work around this limitation. /Philipp
  10. Sure, set_sensitivity can be called after the start of the simulation. And yes, there are no overloads to use sc_event_and/or_lists for static sensitivity, mostly for historical reasons (and limitations in some implementations). But why not simply use them with dynamic sensitivity? Simply store (a copy of) the event list in your module and use wait( event_list ) instead of a plain wait() inside your spawned process. hth, Philipp
  11. Oh, I should have mentioned that you can try to build your SystemC kernel with a Pthread threading implementation: ../configure [...] --enable-pthreads The stack size requirements might be different there. Alternatively, you can use a MinGW32 compiler (http://mingw-w64.sourceforge.net/), which then uses the native Windows threading facilities (WinFiber) under the hood. hth, Philipp
  12. Short answer: You can't. The current proof-of-concept simulator employs a stack protection mechanism to detect stack overflows by using the OSs memory protection mechanisms. This requires an additional memory page (as a red zone) after the "real" stack. As you have seen, this requires the minimum stack size to exceed a certain value. 0x1000 is certainly too small here. I would have expected that 0x10000 could work, but this seems not to be the case. If your threads are so small and simple, maybe you can port them to SC_METHODs. Alternatively, you can try to switch to a 64-bit OS. /Philipp
  13. No. In SystemC 2.3.1, the platform-specific defaults are defined in sc_thread_process.h. To obtain the default value used on your platform, you can query the SC_DEFAULT_STACK_SIZE constant in your application. Use sc_spawn_options, see Section 5.5 in IEEE 1666-2011: sc_spawn_options opt; opt.set_stack_size(0x10000); sc_spawn( func, "func", &opt ); Yes, on 32-bit OSs, the overall memory space for user applications is usually limited to 2GB (on Windows) and 3GB (on Linux). On 64-bit OSs, this limitation is lifted. hth, Philipp
  14. In general, it is not different from a classical C++ shared library. The details can't be answered without a more detailed question and/or problem description. If your "SystemC program" contains an sc_main, you can afterwards call "sc_elab_and_sim" from your scripting language to setup the kernel and the simulation model. See Section 4.3.2 in the IEEE 1666-2011 standard. hth, Philipp
  15. The file visualc.hpp is part of the external Boost library, where a rather old version is partially packaged with SystemC. The documentation in the README file is correct. You can safely ignore the warning during the build. The version check inconsistency has been fixed in SystemC 2.3.1 (among many other things). I would encourage you to update to the latest version. Greetings from Oldenburg, Philipp
  16. With the plain socket (interfaces), there is no way to determine the socket through which an interface function has been called. There are so called "tagged" convenience sockets provided as part of the TLM utilities (see IEEE 1666-2011, Section 16.1.3, including an example at the end of the section). This topic has been discussed here recently in this thread. hth, Philipp
  17. You can't use the "implement interface and export" idiom in this case, as you obviously can implement each function only once (for each transaction type). You can use a small wrapper instead: SC_MODULE(abc) { typedef int T; sc_core::sc_export<tlm::tlm_analysis_if<T> > exp_1, exp_2; SC_CTOR(abc) : exp_1("exp_1") , exp_2("exp_2") , aw_1(*this,&abc::write_1) // create wrapper for each implementation , aw_2(*this,&abc::write_2) { exp_1(aw_1); // bind wrappers exp_2(aw_2); } private: void write_1( const T& ); // implementation for each export void write_2( const T& ); struct analysis_wrapper : sc_core::sc_object, tlm::tlm_analysis_if<T> { typedef void (abc::*write_func)( const T& ); // pointer to member function with implementation analysis_wrapper( abc& owner, write_func f ) : sc_core::sc_object(sc_core::sc_gen_unique_name("analysis_if")) , this_(owner), f_(f){} void write( const T& v ) { (this_.*f_)(v); } // forward call to registered implementation private: abc& this_; write_func f_; }; analysis_wrapper aw_1, aw_2; }; Hope that helps, Philipp
  18. Yes. See http://forums.accellera.org/topic/1555-using-tlm2-but-not-generic-payload/ for a previous discussion. Greetings from Oldenburg, Philipp
  19. Yes, sc_interface itself is not derived from sc_object. But the channel that is bound to the port/socket is frequently derived from sc_object. I didn't look up the details in the standard, but to me it may be a reasonable assumption that the bound object is indeed a proper part of the SystemC object hierarchy. Indeed, the current implementation of the simple sockets use internal classes not derived from sc_object to provide the interface implementations. To me, this is at least an inconvenience for use cases like yours. I'll take this to the LWG/TLMWG for discussion. You may still be able to "lookup" the correct socket by traversing the object hierarchy (5.16.7) looking for candidate sockets and comparing the original result of 'get_interface()' with the interfaces of the candidates. Or derive your own socket and override the bind() function to store the name. Make sure to call the base-class bind() to actually perform the binding. /Philipp
  20. Sure, it's not possible to avoid such issues for arbitrary future languages. On the other hand, we should still address the languages that have a UVM implementation being worked on or are likely to see such an implementation in the future. Hopefully, people with interest in a particular language can do the check for potential conflicts and report back during the IEEE standardization process. Yes. The process can't be fully automated. The "grep -w" suggestion from above can serve as a simple starting point to identify possible conflicts, mainly regarding the convenient "word matching" functionality to avoid false negatives where the keywords are only a part of identifiers. You can easily exclude implementation files. Comments are not filtered either. Still, the resulting list is hopefully short enough to be processed manually processed for "real" conflicts in the public/official API. /Philipp
  21. You can use a dynamic cast to access the channel object bound to the port/socket: sc_object * obj = dynamic_cast<sc_object*>(socket.get_interface()); std::cout << obj->name() << std::endl; Greetings from Oldenburg, Philipp
  22. It should be possible to use "grep -w" (word match) for this purpose: grep -rwE '(catch|delete|register|...)' /path/to/uvm/src with "..." being all C++ keywords that are not already keywords in SV. The same could be done for e, VHDL, Python, Java, ... /Philipp
  23. No, this is not possible as C++ keywords (like catch, delete, register) are not part of scoping rules. They are part of the grammar instead. Therefore, I would second to rename these functions in UVM during the IEEE standardization. /Philipp
  24. I'm not sure, if I understand the question right. How do you use 'b_transport' without sockets? Of course, technically, you can just use sc_core::sc_port<tlm::tlm_blocking_transport_if<my_payload> > > my_transport_port; but the you are quite far away from TLM-2.0. ;-) Sockets (or ports and exports) in general are a good idea to separate communication and computation. This improves the modularity of your design. Using tlm_analysis_ports for data communication (in the modelled system) is probably not what you want either. But on the other hand, I don't know the details of your use case. /Philipp
  25. You can use b_transport and the convenience sockets with your custom payload class. First, you'll need the "my_protocol_types" traits class earlier in this thread. Secondly, due to the blocking/non-blocking conversions, the simple sockets depend on some features of the generic payloads internally (e.g. the memory management and extensions). If you don't want to use this functionality, you can provide dummy implementations for these GP parts. If you want the B/NB conversion to work, you should implement them properly, e.g. by reuising the relevant parts of the tlm_generic_payload class. Instead, I would suggest to use the passthrough sockets, that don't perform any protocol conversions, see Section 16.1 in IEEE 1666-2011: SC_MODULE(my_module) { tlm_utils::passthrough_target_socket<my_module,32,my_protocol_types> socket; // ... SC_CTOR(my_module) { socket.register_b_transport(this,&my_module::my_b_transport); } void my_b_transport(my_item& trans, sc_time& delay) { // ... } }; In general, TLM-2.0 is about interoperability. It is meant to cover a wide range of modeling requirements across tool and model providers. If you don't care about interoperability with third-party models, you're free to ignore many of the rules (and simply return an error for unsupported features, like byte enables, DMI, etc.). But I agree, the API and all details of the TLM-2.0 rules are quite complex and not made for beginners. Model writers often rely on in-house or vendor-specific convenience layers on top. hth, Philipp
×
×
  • Create New...