Jump to content

Roman Popov

Members
  • Posts

    353
  • Joined

  • Last visited

  • Days Won

    46

Reputation Activity

  1. Thanks
    Roman Popov got a reaction from Shashank V M in how to implement delay in systemC?   
    If you use SC_THREAD that means that you are using sc_event under the hood. Because every SC_THREAD in SystemC has event that activates the process.
    You can for example spawn a SC_THREAD process to do delayed assignment like this:
    #include <systemc.h> struct spawned_assignment_demo : sc_module { SC_CTOR(spawned_assignment_demo) { SC_THREAD(test_thread); } sc_signal<int, SC_MANY_WRITERS> out{"out", 0}; void print_out_value() { cout << " out value = " << out.read() << " at " << sc_time_stamp() << "\n"; } void test_thread() { print_out_value(); sc_spawn([&]() { wait(10, SC_NS); out = 42; }); wait(5, SC_NS); print_out_value(); sc_spawn([&]() { wait(10, SC_NS); out = 124; }); wait(6, SC_NS); print_out_value(); wait(6, SC_NS); print_out_value(); } }; int sc_main (int argc, char**argv) { spawned_assignment_demo demo{"demo"}; sc_start(); sc_stop(); }  
    Output will be as expected:
    out value = 0 at 0 s out value = 0 at 5 ns out value = 42 at 11 ns out value = 124 at 17 ns  
    But when you call  wait(10,SC_NS) you create timed event notification. You can use debugger to step into wait() to see what happens there.
  2. Like
    Roman Popov got a reaction from amal in 2d array data passing through generic payload   
    TLM payload is used for untyped raw data transfers. Data format is usually a property of device. 
    Let's consider an example:  Initiator is CPU model, and target is Convolution filter accelerator. Accelerator accepts a 2d matrix (2d array) of coefficients as an input.  Documentation of accelerator must specify a binary format of data, for example:  coefficients are stored in row-major order, each coefficient is 8-byte signed integer.
    Using this documentation initiator converts 2d array into a raw data of tlm payload. And device model converts raw data back into 2d array. This is how it is usually done.
  3. Like
    Roman Popov got a reaction from OMark in sc_port sc_export binding issue   
    Than you have a typo in another place:
     
    class target : public sc_module {
        public:
        sc_export<sc_signal_in_if<bool> > in;          ---- > Change to   sc_export<sc_signal_inout_if<bool> > in;  
        sc_signal<bool> sig;
        target(sc_module_name name){in(sig);}
    };
     
    The problem is that you try to bind port and export with different interfaces
  4. Sad
    Roman Popov got a reaction from tymonx in New UVM Reference Implementation Now Available   
    This is not official Accellera repository.  But in case your company is Accellera member you can request access to Accellera UVM git repositories.
  5. Like
    Roman Popov reacted to SiGa in How to trace std::list<int> with sc_trace? [solved]   
    I have to correct my statements. 
    It works they way I described it, I unintentionally looked at the wrong trace signals...
  6. Thanks
    Roman Popov got a reaction from SiGa in How to trace std::list<int> with sc_trace? [solved]   
    I see at least 1 bug in code sample:
    for (auto val : var.read()) here you create copies of vector elements on a stack of your function. And then pass references to them into SystemC kernel. So those will be dangling references one you return from your sc_trace overload.
    Change to:
    for (auto & val : var.read())  
  7. Thanks
    Roman Popov got a reaction from rainer in How to trace std::list<int> with sc_trace? [solved]   
    This is correct, you cannot trace dynamic data structure. This is not even a SystemC limitation, but limitation of VCD waveform dump in general. VCD does not allow to add/remove signals to waveform dynamically.
    So usually you have two options : 
    1) If maximum capacity is known in advance and is small, you can create your own "list" that utilizes statically sized array as a storage:
    template<typename T> struct my_list_item { bool has_value = false; T value; } template<typename T, size_t MAX_SIZE> class my_list { std::array<my_list_item, MAX_SIZE> storage; // ... } 2) If maximum size is large or unknown, but it is sufficient for you to trace only head and tail of the list, you can have a copy of tail and head that is updated on every push and pop:
    class my_list { std::list<T> storage; my_list_item head_copy; my_list_item tail_copy; //... custom push pop }  
  8. Thanks
    Roman Popov got a reaction from SiGa in How to pass a sc_event as parameter without pointers?   
    Looks like XY problem to me. If you need pointer to event, use pointer.
  9. Thanks
    Roman Popov got a reaction from plafratt in sc_fifo data_read_event   
    Did you probably forget to add wait() into consumer thread to suspend it after first read?
  10. Thanks
    Roman Popov got a reaction from SiGa in Multiple inheritance in SystemC, is it possible?   
    No, if you want to keep all ports in same scope you will need to follow Philipp's suggestion. 
  11. Thanks
    Roman Popov got a reaction from SiGa in Multiple inheritance in SystemC, is it possible?   
    In general avoid using multiple inheritance for aggregation. It is possible, but has many drawbacks and no major benefits.  Now I regret that I've written original post, but at that time I had no enough experience myself.
    Now, if we read any object oriented design book, we will learn that inheritance usually means "is-a" relation ship, and "has-a" relation ship is expressed by composition. Translating into HW modeling : what we want to express is that "some_module has port bundles", and not "some_module is port bundles". 
    We can still use single inheritance in limited cases, for example if all modules in design have clock and reset, we can have a common base class like
    class clocked_module : public sc_module Back to your example. I recommend to convert your port bundles into modules:
    struct if_inputs : sc_module { sc_inout<sc_uint<4>> SC_NAMED(R_OP_MODE); sc_inout<sc_uint<8>> SC_NAMED(R_PRESET_MANUAL); if_inputs(sc_module_name){} }; struct if_outputs : sc_module { sc_inout<sc_uint<2>> SC_NAMED(T_BIT); sc_inout<sc_uint<4>> SC_NAMED(T_OP_MODE); sc_inout<sc_uint<8>> SC_NAMED(T_PRESET_MANUAL); if_outputs(sc_module_name){} }; And now you can aggregate any number of them inside monitor. Even have a vector of port bundles:
    class monitor : public sc_module { public: if_inputs SC_NAMED(sim_inputs); if_outputs SC_NAMED(sim_outputs); if_inputs SC_NAMED(stub_inputs); if_outputs SC_NAMED(stub_outputs); sc_vector<if_inputs> SC_NAMED(inputs_vector, 3); monitor(sc_module_name name_); private : // implementation details };  
  12. Like
    Roman Popov got a reaction from SiGa in Multiple inheritance in SystemC, is it possible?   
    No, multiple inheritance is not supported in this case 
    Here is quote from IEEE 1666-2011
     
    So you have two options:
    Use composition instead of inheritance : in SystemC case this means you need to instantiate modules and bind their ports In some cases you can put some sc_objects in pure C++ classes (not sc_modules). This technique is commonly used for "port bundles". For example: struct clock_reset_if { sc_in_clk clk{"clk"}; sc_in<bool> rstn{"rstn"}; } struct some_module: sc_module, clock_reset_if { // ... }   
    Unfortunately this approach does not work with SC_METHOD/SC_THREAD macros.  But I think it should work with sc_spawn.
     
  13. Like
    Roman Popov got a reaction from DS1701 in sequence processing   
    SystemC standard does not guarantee any order of process evaluation within a single delta cycle. So in first example  both 2,4 and 4,2 will be correct.
  14. Like
    Roman Popov got a reaction from Marwan in Compiling a Simple C code on Mac   
    They are in namespace sc_core. If you don't want to use namespaces you can change #include <systemc> to #include<systemc.h> and it will pull everything into global namespace.
  15. Thanks
    Roman Popov got a reaction from ArjunMadhudi in Consecutive notify of same event   
    e.notify(); // immediate notification is executed "immediately" - Thread2 added to set of runnable processes e.notify(3,SC_NS); // e added to kernel event queue, it will be triggered in 3 ns  
    e.notify(3,SC_NS); // e added to kernel event queue to be triggered in 3 ns e.notify(); // previous notification canceled, and instead event is notified immediately, Thread2 added to set of runnable processes  
     
  16. Like
    Roman Popov got a reaction from Retvisan in How to configure the compiler in CodeLite IDE   
    Setting library path != Linking library.  Also add -l systemc to g++ options.
  17. Like
    Roman Popov got a reaction from Retvisan in How to configure the compiler in CodeLite IDE   
    Because dynamic linker does not know where to find library. You have two options: use -Wl,rpath,<path/to/lib>  command line option at compile time, or set LD_LIBRARY_PATH environment variable. Google for more details.
  18. Like
    Roman Popov got a reaction from Retvisan in How to configure the compiler in CodeLite IDE   
    According to log, you are using C compiler driver (/usr/bin/gcc).  SystemC is C++, you should write your application in C++ and use C++ compiler driver (g++).
    Maybe your IDE automatically uses C compiler because you named your source file main.c
  19. Like
    Roman Popov got a reaction from saad in One clock cycle delay in communication between two SC_CTHREAD   
    You have controversial requirements:
    a) put stored value when enable == 1 , which sounds like a dff with output_enable 
    b) put input to output when enable == 1, which sounds more like a latch
    Anyway, in both cases you will need to make process sensitive to enable signal. And usually such  low-level logic is modeled with SC_METHODs.
    In SystemC context "register" usually means some memory-mapped CSR on TLM bus 🙂   
  20. Like
    Roman Popov got a reaction from saad in One clock cycle delay in communication between two SC_CTHREAD   
    What do you mean exactly by "modeling a register"?
    If you are working on synthesizable code (i.e. using Mentor/Cadence HLS tools), then it is not possible to have 0-delay communication between threads in synthesizable code, as you wanted in original post. At least it was not possible last time I've used these tools. 
    If you are working on some non-synthesizable high-level model, then you can model "register" any way you like, you don't even have to use sc_signal<> for that purpose. 
     
  21. Like
    Roman Popov got a reaction from saad in One clock cycle delay in communication between two SC_CTHREAD   
    If you want immediate communications  between threads, then you should use regular SC_THREADs and wait on event, like  wait(some_signal.value_changed_event());
  22. Like
    Roman Popov got a reaction from saad in One clock cycle delay in communication between two SC_CTHREAD   
    You have 2 clocked processes. Any communication between them will take at least 1 clock cycle. If you need request and response, then you have at least 2 cycle latency.
  23. Like
    Roman Popov got a reaction from David Black in Systemc performance   
    Real-life simulation performance usually depends a lot on modeling style. For high-level TLM-2.0 models share of simulation time consumed by SystemC primitives is usually much lower, comparing to time consumed by "business logic" of models.  Efficiency of simulation kernel (like context switches and channels) is much more important for low-level RTL simulations.
  24. Like
    Roman Popov reacted to karthickg in SC_METHOD performance improvement discussion   
    Are you only looking at disabling  process_output from getting triggered when reset is on? In that case, it is as simple as:
    void fir::process_output() { if (reset.read() == 0) { //reset sequence next_trigger(reset.pos()); } else if (clk.read() == 0) { //Ignore the trigger just after reset is de-asserted and //sync to next clock edge next_trigger(clk.pos()); // Note: will work even if we comment out line above, due to static sensitivity } else { if(enable.read()) { //normal operation } } } But this may not really get you a significant improvement in itself. You may want to check what is going on in "normal operation" - and see if you can optimize that.
  25. Like
    Roman Popov got a reaction from mladia in Support for C++11/14 in SystemC 2.3.2   
    Most likely you have C++98 in CMake cache. 
    You don't need to modify SystemC CMakeLists, just set c++ standard from command line. Check here for detailed instructions https://stackoverflow.com/questions/46875731/setting-up-a-systemc-project-with-cmake-undefined-reference-to-sc-core
×
×
  • Create New...