Jump to content

Roman Popov

  • Content count

  • Joined

  • Last visited

  • Days Won


Roman Popov last won the day on June 22

Roman Popov had the most liked content!


About Roman Popov

  • Rank
    Advanced Member

Recent Profile Visitors

930 profile views
  1. Roman Popov

    Error during installation

    Did you configured it with pthreads as described in release notes? In general, if possible you should use Visual Studio or MinGW on Windows. Cygwin is not widely used with SystemC so some bugs are possible. Also SystemC with cygwin/pthreads is much slower then with fibers.
  2. Roman Popov

    The conceptual behavior of sc_in<>

    Simulation semantics is described in SystemC standard, paragraph 4.2 Simulation. sc_signal is particular kind of primitive channel, it's value is updated in Update phase. You don't need to wait for delta cycle in your SC_THREAD. Most likely your signal value changes multiple times, but you catch only first change (the one you don't expect). Try to rewrite your thread with with inifinite loop to catch all signal change events: void XXX::InputChanged() { while (1) { cerr << '@' << sc_time_stamp() << ' ' << Address<< endl; } }
  3. Roman Popov

    SystemC generator

    Most of the tools do the opposite: convert SystemC into schematic... But in case you have a schematic in some machine-readable format it should be pretty straightforward to generate SystemC netlist.
  4. Roman Popov

    Passing event to SC_CTHREAD macro

    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). 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.
  5. Roman Popov

    How SystemC kernel is implemented !!

    SC_THREADS are coroutines https://en.wikipedia.org/wiki/Coroutine. SystemC uses different coroutines implementations depending on platform (Fibers, QuickThreads..). Function of sc_simcontext is not standartized. But in open-source SystemC it contains main simulator loop.
  6. Roman Popov

    How SystemC kernel is implemented !!

    You should probably read a book about multi-threaded programming to understand what thread means. A good book about standard C++ threads is C++ Concurrency in Action by Anthony Williams. SystemC is indeed a single thread. Most of other cycle-accurate (RTL) and TLM simulators are also single-threaded. In theory, you can write a parallel scheduler that can utilize multiple HW threads to evaluate a single delta-cycle (because SystemC standard does not restrict the order of process evaluation inside delta cycle) . However, amount of work performed in a single delta cycle is usually small, so instead of speedup you will get a slow down. To utilize power of multicore CPUs you should parallelize your test environment. Instead of running multiple tests sequentially in a single simulator, you can run different tests in parallel on different simulators. Personally, I integrate my tests with CTest : https://cmake.org/cmake/help/latest/manual/ctest.1.html and then run in parallel simply by specifying number processes I want to utilize, for example "ctest -j 8"
  7. 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.
  8. Roman Popov

    sc_spawn and anthoer process

    If you want to pass a parameter to process, then you can use sc_spawn and std::bind to bind parameters.
  9. Roman Popov

    Graph Generation

    In some cases yes, you can do it by playing with dynamic casts. For example: #include <systemc.h> SC_MODULE(test) { sc_signal <int> xsig{"xsig"}; sc_signal <unsigned> xsig2{"xsig2"}; sc_in <int> xin{"xin"}; sc_out <unsigned> xout{"xout"}; SC_CTOR(test) { xin(xsig); xout(xsig2); } }; int sc_main(int argc, char **argv) { test t0{"t0"}; sc_start(SC_ZERO_TIME); cout << hex; for (auto * obj : t0.get_child_objects()) { cout << obj->kind() << " " << obj->name() << " @ " << obj; if(sc_port_base* port = dynamic_cast<sc_port_base*>(obj)) if (sc_prim_channel * chan = dynamic_cast<sc_prim_channel*>(port->get_interface())) std::cout << " ( binded to " << chan->name() << " @ " << chan << ")"; cout << endl; } return 0; } Possible output: sc_signal t0.xsig @ 0x111f878 sc_signal t0.xsig2 @ 0x111f938 sc_in t0.xin @ 0x111f9e8 ( binded to t0.xsig @ 0x111f878) sc_out t0.xout @ 0x111fa90 ( binded to t0.xsig2 @ 0x111f938) SystemC however does not store information about hierarchical bindings.
  10. Roman Popov

    sc_spawn and anthoer process

    sc_spawn allows to create process during simulation runtime. SC_* macro can be used only at elaboration time. Please read more details in IEEE SystemC standard. Here is small usage example: #define SC_INCLUDE_DYNAMIC_PROCESSES #include <systemc.h> SC_MODULE(spawn_demo) { SC_CTOR(spawn_demo) { SC_THREAD(static_thread); } void static_thread() { sc_spawn_options opts; sc_spawn([&]() { wait(1, SC_NS); cout << "spawned @ " << sc_time_stamp() << "\n"; }, "spawned_thread", &opts); wait(1, SC_NS); cout << "static @ " << sc_time_stamp() << "\n"; } }; int sc_main(int argc, char **argv) { spawn_demo demo0{"demo0"}; sc_start(); return 0; }
  11. Roman Popov

    Implement sc_trace for std::string

    Unfortunately current implementation was not designed to be extensible by user. So you will have to hack SystemC kernel itself. Tracing part is relatively small so it's should not be very hard. Just follow the implementation for existing types. In general however it should be better to redesign tracing API so it will be extensible for user-supplied types. In addition to accepting fixed set of datatypes, it should also accept abstract interfaces that can be implemented by end user. For example: // currently does not exist struct BitVecConvertible { virtual sc_dt::sc_bv_base to_bv() = 0; } sc_trace(sc_trace_file* tf, BitVecConvertible &obj, onst std::string& name); In that case user can trace any type as a bit vector, by implementing an interface or providing a proxy-class.
  12. Roman Popov

    Possible Bug in VCD tracing

    Thanks for reporting! Here is a small reproducer for this bug: #include <systemc> int sc_main(int argc, char ** argv ) { sc_core::sc_trace_file *tf = sc_core::sc_create_vcd_trace_file("vcdtrace"); sc_core::sc_close_vcd_trace_file(tf); return 0; } Probably the easiest way to fix is to do zero check before printing last time stamp.
  13. The problem is that both sockets are binded to same target interface implementation. So: In[0].get_interface() == In[1].get_interface(); When you bind same interface twice to a single port, SystemC considers this a design error. Solution depends on your modeling needs. Usually TLM sockets are connected point-to-point and to model interconnect a separate module that forwards transactions from initiator to targets is created.
  14. You can use sc_vector: sc_vector<tlm_utils::multi_passthrough_initiator_socket<Router, 32, tlm::tlm_base_protocol_types,1,sc_core::SC_ZERO_OR_MORE_BOUND >> Out{"Out", 10};
  15. No, this is not allowed by SystemC LRM "5.3.3 Constraints on usage":