Jump to content

Passing event to SC_CTHREAD macro


Roman Popov

Recommended Posts

Why SystemC does not allow to pass event directly to SC_CTHREAD macro?

For example:

#include <systemc.h>

SC_MODULE(test) {
    sc_clock clkgen{"clkgen", 10, SC_NS};
    sc_in_clk clk{"clk"};

    SC_CTOR(test) {
        clk(clkgen);

        SC_CTHREAD(test_cthread, clk.pos()); // OK
        SC_CTHREAD(test_cthread, clkgen.posedge_event());  // Compile error!
    }
  
  void test_cthread();
};

If I inline macro I can do what I want:

{ ::sc_core::sc_process_handle test_cthread_handle =
  sc_core::sc_get_curr_simcontext()->create_cthread_process(
    "test_cthread",
    false,
    static_cast<sc_core::SC_ENTRY_FUNC>(&SC_CURRENT_USER_MODULE::test_cthread),
    this,
    0);
  /// this->sensitive.operator()(test_cthread_handle, clkgen.posedge_event());   /// Error 
  sc_sensitive::make_static_sensitivity(test_cthread_handle,clkgen.posedge_event());  /// OK
};

This looks to me as inconvenience without a good reason. 

Link to comment
Share on other sites

For your particular use case, you can just pass in the clock signal directly:

  SC_CTHREAD(test_cthread, clkgen); // posedge by default for CTHREADs

If you need a negedge triggered process, you can also write the equivalent SC_THREAD instead:

  SC_THREAD(test_cthread);
    sensitive << clkgen.negedge_event();
    dont_initialize();

Allowing plain events for CTHREAD sensitivity was probably just never needed. 

Link to comment
Share on other sites

The only use I see for SC_CTHREAD is synthesis tools, and this is really just a legacy issue and a vendor tools issue. The same SC_THREAD could have been used for posedge_event. This would change the coding of wait in your code though:

wait(5); // 5 clock delay

becomes

for(int i=5; i--;) wait();// prior to C++17

which could easily be addressed with:

void nWait(size_t n) { while(n--) wait(); }

and allows

nWait(5);

 

Link to comment
Share on other sites

4 hours ago, David Black said:

The only use I see for SC_CTHREAD is synthesis tools, and this is really just a legacy issue and a vendor tools issue.

There is a difference: in SC_CTHREADs you can't wait on event. Since this would not be synthesizable.

sc_clock    clk{"clk", 1, SC_NS};

SC_CTOR(test) {
  SC_THREAD(test_thread);
  sensitive << clk.posedge_event();

  SC_CTHREAD(test_cthread, clk);
}

void test_thread() {
  wait(clk.negedge_event()); // OK
}

void test_cthread() {
  wait(clk.negedge_event()); // RUNTIME ERROR
}

So I always use SC_CTHREADs in synthesizable code, to specify my intent and prevent accidental calls to non-synthesizable methods with wait(event).

23 hours ago, Philipp A Hartmann said:

  SC_CTHREAD(test_cthread, clkgen); // posedge by default for CTHREADs

Indeed, did not know about it. This works for me. In my practice I did not yet encountered a case where I need to create a CTHREAD sensitive to negedge.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...