Jump to content

Philipp A Hartmann

  • Content Count

  • Joined

  • Last visited

  • Days Won


Posts posted by Philipp A Hartmann

  1. 18 hours ago, Stephan Gerth said:


    Thanks! I can reproduce the behavior and verified that removing the dynamic sensitivity in sc_thread_process::kill_process fixes the issue:

    void sc_thread_process::kill_process(sc_descendant_inclusion_info descendants )
        // ...
        if ( sc_is_running() && m_has_stack )
            m_throw_status = THROW_KILL;
            m_wait_cycle_n = 0;
            remove_dynamic_events(); // <-- add this line to avoid the exception
        // ...

    I'm not sure, if it is necessary to do the same for the static sensitivity.  At least I haven't come up with a similar scenario, where the error is actually "incorrect".

  2. 14 hours ago, Roman Popov said:

    I don't know what "TDB" means here, but it seems like the case when sc_event_list resides on SC_THREAD stack was not considered here.

    I did write the above comment and the case where a (e.g. temporary) list lives inside a thread is certainly one of the reasons why we need a check for premature destruction.  Due to the nature how event lists are internally handled, we will run into a memory corruption if list is destroyed while a process is still waiting for it.

    What was not considered is the explicit kill() of a process that is current waiting on such a list.

    The easiest fix would be to cancel (dynamic) sensitivity before doing the stack unwinding when killing the process.

    @Stephan Gerth: Can you submit a pull-request with your example above as testcase against the SystemC regressions repository?

  3. 22 hours ago, KEVIN CHACKO said:

    If the threads in top_uvm2 are in a SC_JOIN or SC_JOIN_None implementation(both commented in code) the whole system works fine without any errors but the issue is with the SC_JOIN_ANY implementation. 

    If you use SC_JOIN or your SC_JOIN_ANY, you want to keep the run_phase active until all (or at least one) of the threads terminate(s).  Why can't you raise an objection here?  You will drop the objection after the join, so the phase can successfully complete. (Without joining, it's fine not to raise an objection).

  4. The error looks strange to me, as terminated_events is not destroyed before exiting run_phase, i.e. after the wait() has returned.  However, I don't know how the objections are implemented in UVM SystemC and whether or how wait() is supported without raising an objection.  Can you check with a debugger, if an exception is thrown while your run_phase function is inside the wait()?

    Hope that helps,

  5. 52 minutes ago, TRANG said:

    I can't set base name for each initiator_socket as my expected.

    ex:   initiator_socket[0]   : " initiator_0_socket"

             initiator_socket [ 1]    : " initiator_1_socket"

             initiator_socket [ 2]    : " initiator_2_socket"

             initiator_socket [ 3]    : " initiator_3_socket"

    For this, you can use a custom creator, e.g. a lambda function in C++11.  For a tagged socket, you anyway need to specify the tag in the for the callbacks, so doing the registration in the creator saves you another loop in your code:

    sc_core::sc_vector< tlm_utils::simple_initiator_socket_tagged<Router > > initiator_socket;
      [this](const char* /*unused*/, size_t idx) {
        std::stringstream ss;
          ss << "initiator_" << idx << "_socket";
        auto * socket = new tlm_utils::simple_initiator_socket_tagged<Router >( ss.str().c_str() );
        //socket->register_invalidate_direct_mem_ptr( ..., idx );
        return socket;


    Hope that helps,

  6. Hi Roman,

    This would be something to discuss in the Accellera SystemC LWG (or the IEEE P1666 WG).  In practice, most/all commercial simulators provide much more advanced tracing mechanisms already, beyond what the current sc_trace() API allows to support. My guess would be, that this part of the standard is something where it is difficult to reach consensus, as it touches the core distinguishing features of commercial SystemC offerings.

    Moreover, the sc_trace()-based API is a costly "pull" interface, which effectively loops over all variables at each time step and does a value comparison.  This is also pretty inefficient for e.g. signals, which already "know" if they changed.  So I think, a plain sc_interface::trace() addition is not sufficient to bring real additional value here.

    Last, but not least, this function would have to have a default (empty) implementation to not break existing models and would require some extension mechanism to add support for custom types.

    Greetings from Duisburg,

  7. 12 hours ago, Elvis Shera said:

    What if the SystemC installation has not been done via Cmake?  There must be a way to locate the libraries (given that systemc has been installed in a local directory) for the linking process. In that case what are the instruction to achieve this ?

    SystemC supports pkg-config as well and generates a corresponding systemc.pc file.  Of course, you still need to have the systemc.pc file somewhere in your PKG_CONFIG_PATH

    For manual Makefiles, you can check the templates in examples/build-unix as a starting point.

    Greetings from Duisburg,

  8. Hi Guillaume,

    17 hours ago, Guillaume Audeon said:

    My use case is about extending the TLM interfaces, especially the BW_IF with a blocking backward transport call. For all that I need to derive my thus extended sockets from the tlm_base_*_socket classes so as to be able to specify my extended transport interfaces (which is not possible with tlm_*_socket).

    thanks for the background!

    For the time being, I guess you need to work around this issue in your custom sockets then by providing your own implementation of this function in SystemC >= 2.3.2.

    Greetings from Duisburg,

  9. Hi Tibor,

    the stack_protect function is called upon creation and destruction of the thread.  Upon creation, a special guard page after the end of the stack is allocated and protected against accesses to catch (some) stack overflows.  Upon deletion of the thread, this protection is removed.

    Quoting https://danwalsh.livejournal.com/6117.html (highlighting mine):


    The POSIX specification does not permit it, but the Linux implementation of mprotect allows changing the access protection of memory on the heap (e.g., allocated using malloc). This error indicates that heap memory was supposed to be made executable. Doing this is really a bad idea. If anonymous, executable memory is needed it should be allocated using mmap which is the only portable mechanism.

    Therefore, I agree that we probably don't need to try adding PROT_EXEC to the page's permissions and can only keep the read/write settings:

        // Revert the red zone to normal memory usage.
        else {
            ret = mprotect( redzone, pagesize - 1, PROT_READ|PROT_WRITE);

    Can you try with this change again?

    Thanks and Greetings from Duisburg,

  10. Hi Guillaume,

    I agree, that the new pure-virtual functions in tlm_base_(initiator/target)_socket are not compliant to IEEE 1666-2011.  However, I'm curious what use case you have to use these classes directly instead of inheriting from tlm_(initiator/target)_socket, where the functions are implemented?

    Regarding the implementation on the base socket level, I suggest to add a typedef to the fw/bw interface classes, and use these typedefs in the socket base class then.  Something like:

    template <typename TYPES = tlm_base_protocol_types>
    class tlm_fw_transport_if
    // ...
      typedef TYPES protocol_types;
    // tlm_base_target_socket
      virtual sc_core::sc_type_index get_protocol_types() const
        { return typeid(typename FW_IF::protocol_types); }

    Theoretically, these types could mismatch between FW_IF and BW_IF in manual socket implementations.  Therefore, I'd suggest to refer to the FW_IF in the target and BW_IF in the initiator socket.

    Greetings from Duisburg,

  11. I'm not aware of any executable heap usage in SystemC either.  However, there is a known issue around executable stacks in the QuickThreads implementation on some SELinux-enabled machines.  Quoting the RELEASENOTES file:

      - When building the SystemC library with QuickThreads support, the
        resulting shared library is marked as requiring an executable stack
        by certain compilers/assemblers (or rather not marked as not needing
        one).  As a result, some system security systems (like SELinux) might
        refuse to load the library.  As a workaround for GNU (compatible)
        assemblers, pass the assembler flags variable with the option
        to the `configure' script call before building the SystemC library.

    In case you can reproduce the effect again, can you try the suggested flag on the configure script?

    Hope that helps,

  12. On 9/27/2018 at 7:23 PM, Roman Popov said:

    This will break on each SystemC thread reset, since they are implemented using exceptions.  Some other more precise mechanism required.  'catch throw std::out_of_range' works for std::vector::at. But catching base classes, like 'catch throw std::logic_error' does not 

    You may be able to break on __cxa_throw explicitly and add a condition to the breakpoint to filter out unwanted exception types (e.g. sc_unwind_exception for  thread resets).

  13. Hi Roman,

    I can give some background here, as I'm guilty of the current implementation.

    The kernel also needs to handle exceptions that are escaping SystemC thread processes.  These are originally thrown in a different stack and still need to be propagated to sc_main, i.e. the main thread in order to be able to still catch the exceptions there in user code.  The propagation across stacks has to be done by catching in one stack and rethrowing in another.

    That said, exception handling not only covers sc_report, but also arbitrary exception types escaping sc_main or a SystemC thread.  We don't want to cause std::terminate to be called in case of uncaught exceptions, but want to properly propagate, catch and wind down the simulation.  Therefore, all exceptions are translated to standard sc_report objects before cross-stack propagation and are finally handled outside of sc_main.

    For consistency, the translation to sc_report is done for both, thread and method processes: It's an error, if an exception escapes a SystemC process and errors are reported as sc_report (and routed through the report handler) in SystemC.  Users can catch the original exceptions themselves by adding catch blocks to sc_main and their SystemC processes.

    Hope that helps,

  14. Hi Ameya,

    thanks for testing.  As said before, unfortunately I cannot reproduce this on my end.  I would need more details on the current behavior:

    • The backtrace looks like there is something broken during model teardown. Have you seen other cases?
    • Are all simulations with processes hanging in a similar way? (e.g. can you provide a full regression result?)

    Greetings from Duisburg,

  15. Hi Ameya,

    I currently don't have access to such new Linux platforms, but I may have a suspicion about a potential root cause.
    Can you please check, if it helps to change the sc_process_b::delete_process function in src/sysc/kernel/sc_process.cpp  as follows:

     // if ( this != sc_get_current_process_b() )
     if ( NULL == sc_get_current_process_b() )

    Thanks and Greetings from Duisburg,

  16. This example still uses the positional binding feature of SystemC, which is deprecated as per IEEE Std. 1666 (see Annex C (h), emphasis mine):


    This annex contains a list of deprecated features. A deprecated feature is a feature that was present in version 2.0.1 of the OSCI open source proof-of-concept SystemC implementation but is not part of this standard. Deprecated features may or may not remain in the Accellera Systems Initiative implementation in
    the future. The user is strongly discouraged from using deprecated features because an implementation is not obliged to support such features. An implementation may issue a warning on the first occurrence of each deprecated feature but is not obliged to do so.


    h) operator, and operator<< of class sc_module for positional port binding (use operator() instead)


  17. The full data length is independent of the word length. The rules for DATAWORD are defined by the standard as follows (see 14.20.3):


    e) The template argument to a hostendian function should be a type representing the internal initiator data word for the endianness conversion. The expression sizeof(DATAWORD) is used to determine the width of the data word in bytes, and the assignment operator of type DATAWORD is used during copying. sizeof(DATAWORD) shall be a power of 2.

    From your example below, you seem to be using four byte word, so "unsigned" (or uint32_t) could be a used as a DATAWORD parameter.

  18. Hi Khushi,

    the best is to look up the definition in the IEEE 1666-2011 standard, section 14.20(.3).

    The different conversion functions have different constraints associated with them, allowing for more performant implementations for the _word, _aligned, and _single specializations.  The _generic one covers arbitrary cases.  The DATAWORD template parameter allows for optimizations as well (and endianness is always specific to the notion of a word).

    Hope that helps,