Jump to content

Kelly Stevens

Members
  • Content Count

    2
  • Joined

  • Last visited

About Kelly Stevens

  • Rank
    Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Kelly Stevens

    sc_fifo with multiple readers (or writers)

    Roman, David, thank you for your responses and guidance. I'll add "coroutine" to my terminology stash. In answer to the question Roman asked at the end of his post, my use case involves a supervisor farming out job IDs to workers. It doesn't matter which worker does which job, so I was stuffing all the jobs into a fifo and letting chance decide who ends up with what. I agree with you all that switching to a deterministic approach is wise. I've rewritten my "write by one, read by many" example to respect ports and provide a manager that arbitrates requests (following along with David's suggestion #1). Here is that code. #include <systemc.h> #include <iostream> // define number of consumers #define N 5 class Consumer : public sc_module { public: sc_in<int> val_in; int id; SC_HAS_PROCESS(Consumer); Consumer(sc_module_name name) : sc_module(name) { // process registration SC_METHOD(readStuff); sensitive << val_in; dont_initialize(); } void readStuff() { int val = val_in; cout << "Consumer " << id << " reading val " << val_in << endl; } }; class Manager : public sc_module { public: sc_in<int> value_in; // one port for a writer to use sc_vector<sc_signal<int> > values_out_sig; // many signals for readers to use sc_fifo<int> fifo; SC_HAS_PROCESS(Manager); Manager(sc_module_name name) : sc_module(name), values_out_sig("values_out_sig", N) { SC_METHOD(manage); sensitive << value_in; curIdx = 0; } void manage() { int val = value_in; cout << "Manager received " << val << " and assigned to " << curIdx << endl; values_out_sig[curIdx%N] = val; curIdx++; // for now, just iterate through the consumers in order } private: int curIdx; }; class Producer : public sc_module { public: sc_vector<Consumer> consumers; Manager manager; sc_signal<int> signal; // for sending the int to the manager SC_HAS_PROCESS(Producer); Producer(sc_module_name name) : sc_module(name), consumers("consumers", N), manager("manager") { // process registration SC_THREAD(write); // submodules for (int i = 0; i < N; i++) { consumers[i].val_in(manager.values_out_sig[i]); consumers[i].id = i; } manager.value_in(signal); } void write() { for (int i = 0; i < 7; i++) { cout << "writing " << (i * 10) << endl; signal.write(i * 10); wait(SC_ZERO_TIME); } } }; int sc_main(int argc, char* argv[]) { Producer producer("producer"); srand(time(NULL)); sc_start(); return 0; } In the end I didn't need the fifo but that's okay. Thanks again everyone for your help.
  2. Hello! My question is whether it is thread-safe to use multiple readers on a fifo. The "quick reference card" I found here indicates this is not allowed. However, I have a working code example with multiple readers that throws no errors and I haven't found any official documentation forbidding this. Here is my sample code that works. In a nutshell, all the consumers get a pointer directly to the fifo and no fifo port is used. #include <systemc.h> #include <iostream> class Consumer : public sc_module { public: sc_in<bool> clock_in; sc_fifo<int> *my_fifo; int id; SC_HAS_PROCESS(Consumer); Consumer(sc_module_name name) : sc_module(name) { // process registration SC_METHOD(readStuff); sensitive << clock_in; } void readStuff() { if (my_fifo->num_available() > 0) { int val = my_fifo->read(); cout << id << " reading val " << val << endl; } } }; class Producer : public sc_module { public: sc_clock clock; // submodules sc_vector<Consumer> consumers; // communications sc_fifo<int> my_fifo; // annotations SC_HAS_PROCESS(Producer); // constructor Producer(sc_module_name name) : sc_module(name), consumers("consumer", 5), clock("clock") { // process registration SC_THREAD(writeStuff); // submodules for (int i = 0; i < 5; i++) { consumers[i].my_fifo = &my_fifo; consumers[i].clock_in(clock); consumers[i].id = i; } } void writeStuff() { // write a bunch of numbers right away and then quit my_fifo.write(0); my_fifo.write(10); my_fifo.write(20); my_fifo.write(30); my_fifo.write(40); my_fifo.write(50); my_fifo.write(60); } }; int sc_main(int argc, char* argv[]) { Producer producer("producer"); srand(time(NULL)); sc_start(10, SC_NS); return 0; } I would like to know - is there a recommended design for a channel with multiple readers? Also, is there a recommended design for a channel with one reader and multiple writers?
×