Jump to content

Using sc_buffer as trigger/ Checking if buffer was written to


Robin

Recommended Posts

Hello everyone

I want to use an sc_buffer write event as a "trigger" in an if statement. That is, iff any value was written to the buffer since last time it was checked, it should return true. A fifo of size one and accessing it using nb_read works for this, however I'd rather use a buffer as I don't have to store an intermediate value (which is required for nb_read).

However, I don't know which (if any) of the buffer member functions would work for that. I tried a lot of them, but as I couldn't find any useful doc for the buffer class, my attempts were not successful. The "event()" function looked promising, but it does not return true after repeated write access (see code)... I'm using C++14, gcc and SC 2.3.4.

#include "systemc.h"

class Callee: public sc_module{
    int i = 0;

    sc_clock clk{"Clock", 10, SC_NS};

    [[noreturn]] void thread(){
        while (true){
            if(reset.event()){ //if what?? 
                i = 0;
                printf("RESET! \n");
            }
            // do stuff
            iOdd.write(i % 2 == 1);
            i += 1;
            wait();
        }
    }

public:
    sc_buffer<bool> reset;
    sc_out<bool> iOdd;

    explicit Callee(const sc_module_name& name):
            sc_module(name) {
        SC_HAS_PROCESS(Callee);
        SC_CTHREAD(thread, clk)
    }
};

class Caller: public sc_module{
    Callee* callee;

    sc_signal<bool> iOddSig{};

    [[noreturn]] void caller(){
        while (true){
            callee->reset.write(true);  // actually resets!

            wait(iOddSig.default_event());

            callee->reset.write(true); // shouldn't this reset as well??

            wait(iOddSig.default_event());

            printf("Stopping simulation");
            sc_stop();
        }
    }

public:
    Caller(const sc_module_name& name, Callee* callee):
            sc_module(name),
            callee(callee) {

        SC_HAS_PROCESS(Caller);
        SC_THREAD(caller)

        callee->iOdd.bind(iOddSig);
    }
};

int sc_main(int argc, char *argv[]) {
    Callee ce("Callee");
    Caller cr("Caller", &ce);
    sc_start();

    return 0;
}

 

Link to comment
Share on other sites

There are no sticky methods as you suggest; however, it would not be too hard to construct. Here is an outline:

struct Some_module : sc_module
{
  sc_buffer<Data_t> my_buff;
  bool changed{false};
  SC_CTOR( Some_module ) {
    SC_METHOD( method_process );
    sensitive << my_buff;
    SC_THREAD( main_thread );
  }
  void method_process() {
    changed = true;
  }
  bool was_changed() {
    auto result = changed;
    changed = false;
    return changed;
  }
  void main_thread() {
    ... do stuff ...
    if( was_changed ) {
      ...stuff with changed info
    }
    ...
  }
};

Of course, you could replace my_buff with port (sc_in<Data_t>) that was tied to the (sc_buffer<Data_t>) externally.

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...