Jump to content

Philipp A Hartmann

  • Posts

  • Joined

  • Last visited

  • Days Won


Posts posted by Philipp A Hartmann

  1. Thanks for the report.  I don't fully understand the summary, though.  Some questions:

    Are the changes to the API check and/or the exception handling in sc_simcontext.cpp really needed? I would hope that removing/skipping the assert in sc_cor_qt.cpp is sufficient to work around the mprotect restrictions on CentOS 7+?

    Your instructions do not include --enable-shared=no, but your description says that you only(?) see it on a static SystemC library. Can you please clarify?

    To better understand the failing mprotect call in your environment, can you please provide the value of errno after the call?  This can be obtained by adding something like:

    #include <errno.h>
    // ...
    ret = mprotect( ... );
    if( ret != 0 ) {
      int mprotect_errno = errno;
      printf( "mprotect errno: %d, %s\n", mprotect_errno, strerror(mprotect_errno) );


    IIRC, Linux generally allows calling mprotect on allocated memory.  The memory needs to be properly aligned at a page boundary, of course.  One option might be to allocate the stack memory via posix_memalign (if available) instead of new.  We can also change the implementation to gracefully ignore a failing protection and only restore the permissions if the mprotect(...,PROT_NONE) call was successful earlier.

    This brings me to my remaining question: Which one of the mprotect calls actually fails: Is it the one removing the protection (PROT_NONE) or the one trying to restore them?


  2. Hi Rainer,

    thanks for your detailed report.  The issue seems indeed an incomplete implementation of the CCI 1.0 LRM.  I'll forward your finding to the Accellera CCI working group.

    To achieve the expected behavior, you can locally change the from_json implementation to something like:

    inline cci_value
    cci_value::from_json( std::string const & json )
      cci_value v;
      bool ok = v.json_deserialize( json );
      if( !ok ) {
        // report CCI_VALUE_ERROR instead of using sc_assert
        v.report_error( "JSON conversion failed", __FILE__, __LINE__ );
      return v;

    Local error handling on the calling side then looks like:

    cci::cci_value v;
    try {
      v = cci::cci_value::from_json(string);
    } catch (... ) {
      // catch CCI value errors only, others are re-thrown
      cci::cci_handle_exception( cci::CCI_VALUE_FAILURE );
      // customize error behavior, e.g. via SC_REPORT_WARNING( ... );   

    Thanks and Greetings from Duisburg,

  3. Please be aware, that an sc_and_event_list does not imply that the events in the list are triggered at the same time. I would suggest to keep the only the clock sensitivity and act on the triggers in the body of the method instead:

      sensitive << clk.pos();
    // ...
    void func2() {
      if( nreset.posedge() ) { // nreset went high in this clock cycle
        // ... 

    Alternatively, you can be sensitive to nreset.pos()  and check for clk.posedge() (as a consistency check), if you don't have anything else to do in the body of the method.  With this approach, you might be able to avoid unnecessary triggers of the method.

    Side note to Eyck: There's a small typo in the example above, which should should use "&=" to append to an sc_event_and_list.

    ev_list &= nreset;


  4. Port-to-port binding is not tracked by SystemC after elaboration is completed.  You can try to restore (or at least approximate) the mapping yourself by checking "overlap" in the get_interface() results across ports and the hierarchical relationship between the ports' parent objects.

  5. Changing the default writer policy requires to be set consistently throughout the whole application, which might be difficult with third-party infeeds.

    Since SystemC 2.3.2, you can also set the environment variable SC_SIGNAL_WRITE_CHECK=CONFLICT, which effectively enables SC_MANY_WRITERS at runtime (for all signals, though). Quoting the release notes:

      - [2.3.2] Add support for SC_SIGNAL_WRITE_CHECK=CONFLICT
        Instead of disabling all runtime signal write checks via the
        environment setting SC_SIGNAL_WRITE_CHECK=DISABLE, setting the
        variable to SC_SIGNAL_WRITE_CHECK=CONFLICT allows detecting
        conflicting writes to a signal within a single evaluation phase
        (see INSTALL).


  6. 4 hours ago, Frank Poppen said:

    But until the first TLM arrives, the sc_out are not initialized. If I use 'start_of_simulation' or 'initialize' than I create a second driver! One as part of my transactor and one more by the module that is making use of the b_transport. In other words: I cannot override the initial values and receive 'X' where the driven '1' and '0' collide.

    Won't you have multiple drivers anyway as soon as you have a second initiator accessing your transactor?

    I would recommend to switch your pin interface to use sc_export<sc_signal_*_if<T> > instead of plain signal ports and bind signals with an SC_MANY_WRITERS policy internally.  These signals also have constructors that allow initialization to a non-zero value without triggering an event at the start of simulation.

  7. The match will occur (almost) at the "correct" point in time during the simulation.  However, if you sample the value from an unrelated process, there might be some process evaluation ordering dependency (i.e. whether the update_method had already been run).  It depends on your requirements, whether this might be an issue. 

    If you do the checks outside of the simulation, i.e. between sc_start calls, you would need to complete the deltas (as per the loop sketched above) before every check. You cannot call sc_start during end_of_simulation.

  8. 27 minutes ago, TRANG said:

    But I want to pending in my code. Is it possible?

    I don't fully understand the question?  My snippet above runs all remaining delta cycles at the current time without advancing the time any further. You can wrap your original sc_start call with the loop in a small helper function (e.g. sc_start_including_deltas(...) , if you find yourself copying the snippet too often.

  9. sc_get_curr_process_kind() is non-standard.  You can use something like this:

    void stop_now()
       // Assuming: sc_set_stop_mode( SC_STOP_IMMEDIATE ); to avoid running other processes?
       auto p = sc_get_current_process_handle();
       bool is_thread_or_cthread = p.valid() && p.proc_kind() != SC_METHOD_PROC_;
       if( is_thread_or_cthread )


  10. Generally speaking, it would be a bug if the whole SystemC simulation is hanging inside a timed wait.  I suspect that you have in face a separate (set of) process(es) that are running indefinitely without advancing SystemC time (beyond these 4 ns).

    You can try to find the culprit by setting a breakpoint in a debugger on the affected line above, continue the simulation for a bit and then break, checking in which SystemC process you end up.  Maybe you are missing a similar "wait" on the consumer side?

    Hope that helps,

  11. 53 minutes ago, TRANG said:

    How to detect My_method sensitive by event1 or event2?

    In SystemC 2.3.2 and later, you can use the sc_event::triggered() member function to query, if an event was triggered (and thus might have caused your method to run):

    if( event1.triggered() ) {
      std::cout << "event1 got triggered";
    if( event2.triggered() ) {
      std::cout << "event2 got triggered";

    Please note that if both events were triggered in/for the same evaluation phase, your method might well be run only once.

  12. I gave it a shot locally and noticed that there are indeed quite some compiler warnings due to differences between __declspec(...) and __attribute__((visibility(...))). Most of these warnings can be ignored for now, but are certainly annoying.

    Additionally, you need to explicitly mark the following with SC_API as well:

    // src/sysc/communication/sc_port.h
    template <class IF>
    class SC_API sc_port_b
    template <class IF>
    class SC_API sc_port
    // src/sysc/communication/sc_prim_channel.h
    class SC_API sc_prim_channel_registry
    // src/sysc/communication/sc_signal.h
    template< class T, sc_writer_policy POL >
    class SC_API sc_signal_t
    template< class T, sc_writer_policy POL >
    class SC_API sc_signal
    // src/sysc/datatypes/sc_proxy.h
    template <class X>
    class SC_API sc_proxy
    // src/sysc/datatypes/sc_proxy.h
    extern "C" SC_API int sc_main(int argc, char* argv[])
    // src/sysc/utils/sc_temporary.h
    template<class T>
    class SC_API sc_vpool

    For compiling SystemC itself with -fvisibility=hidden, some further changes to the .cpp files are needed.  And some of the above changes might break the Windows DLL support.   But for me, the above changes work with the examples in the SystemC distribution (i.e. "gmake check CXXFLAGS='-fvisibility=hidden").

    Long story short: The feature to SystemC build models with limited symbol visibility will require more changes and testing.  I will forward this topic to the Language Working Group for further discussion.

  • Create New...