Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 06/15/2017 in all areas

  1. 3 points
    Philipp A Hartmann

    reset during wait(int)

    I agree with your conclusion that the observed behavior of the proof-of-concept implementation does not match the requirements of IEEE 1666-2011. I checked the code and it can be fixed by adding the check for resets to sc_thread_process.h (in the trigger_static() function): diff --git a/src/sysc/kernel/sc_thread_process.h b/src/sysc/kernel/sc_thread_process.h --- a/src/sysc/kernel/sc_thread_process.h +++ b/src/sysc/kernel/sc_thread_process.h @@ -485,5 +486,5 @@ sc_thread_process::trigger_static() #endif // SC_ENABLE_IMMEDIATE_SELF_NOTIFICATIONS - if ( m_wait_cycle_n > 0 ) + if ( m_wait_cycle_n > 0 && THROW_NONE == m_throw_status ) { --m_wait_cycle_n; I'll take this change to the language working group to get it fixed in a future version of the SystemC PoC kernel. Thanks for reporting! Greetings from Duisburg, Philipp
  2. 3 points
    Because your "analyzer" instance is a local variable in the before_end_of_elaboration function, which gets destructed immediately, when the function returns. So there is no analyzer left to call the callback on later (same holds for the local signal sig2, btw.). You would need to allocate the module dynamically instead. You cannot alter/modify/redefine any existing port binding at any time. You can only add new bindings, including during before_end_of_elaboration. Hope that helps, Philipp
  3. 3 points
    An other way to understand this is to look at SystemC/TLM as pure C++ code and see what is going on.. Let us assume that you have two classes, "Initiator" and "Target", that need to communicate with each other. Target implements a function called "transport" to be called by Initiator, and Initiator implements a function called "response" - that is called by target. For the sake of the explanation here, the payload itself is not important, which we will assume is plain "int" in both directions. You would normally do this as following: // Interface classes: class initiator_if { public: void response(int i) = 0; }; class target_if { public: void transport(int i) = 0; }; class Initiator : public initiator_if { public: // Implement the interface void response(int i) { cout << "Got: " << i << " from target" << endl; } void bind(target_if &_if) { // Store the pointer locally m_target = &_if; } }; class Target : public target_if { public: // Implement the interface void transport(int i) { cout << "Got: " << i << " from initiator " << endl; } void bind(initiator_if &_if) { // Store the pointer locally m_initiator = &_if; } }; Next we instantiate the objects and "bind" them: Initiator initiator; Target target; initiator.bind(target); target.bind(initiator); I hope you are seeing where we are going with this. What has been done above is a crude equivalent of sc_port binding. There is one problem however with the approach above. What if the class "Target" doesn't implement the target_if directly? Like so: class TargetGrandChild : public target_if { public: void transport(int i) { // Implement the interface.. cout << "Got " << i << " from initiator (in grand child)" << std::endl; } }; class TargetChild { public: TargetGrandChild gch; /* Other stuff.. */ }; class Target { public: TargetChild ch; /* Other stuff.. */ }; One way to deal with this is to change the way bind function is called: initiator.bind(target.ch.gch); This is ugly. Firstly, it makes the client of bind function dependent on an internal design aspect of the "Target" class. For example, if the Target class changes tomorrow (to let the TargetChild implement the "target_if" directly), the bind function call needs to change. Also, to allow the client to call the bind function as above, the elements "ch" and "gch" must be made public, which may not be necessarily a good thing. A way out is to have an additional indirection. Let us call this as simple_export (a very simplified version of sc_export): class simple_export : public target_if { public: void transport(int i) { // One level of indirection p_real_target->transport(i); } void bind(target_if &_if) { p_real_target = &_if; } private: target_if *p_real_target; }; The new version of the Target class now looks like the following: class TargetGrandChild : public target_if { public: void transport(int i) { // Implement the interface.. cout << "Got " << i << " from initiator (in grand child)" << std::endl; } }; class TargetChild { public: TargetGrandChild gch; /* Other stuff.. */ }; class Target { public: simple_export port; private: // private is ok TargetChild ch; /* Other stuff.. */ Target() { // Tell "export" where the real implementation is port.bind(ch.gch); } }; The initiator will be "bound" to the target like so: initiator.bind(target.port); So for the simple_export to work, you need two binds: First is where the initiator is bound to the simple_export instance Second is when the "real" implementation is bound to the simple_export instance The simple_export class acts like a bridge. It forward the calls from the initiator to the "real" implementation. In case the "Target" itself implements the interface, the bind would look like: class Target : public target_if { public: simple_export port; private: // private is ok TargetChild ch; /* Other stuff.. */ Target() { // Tell "export" where the real implementation is port.bind(*this); } }; I hope this explains the line you pointed out in the code. The TLM socket has both a port and an export. Please note that the code snips above does not correspond to how OSCI simulator actually implements sc_port/sc_export!
  4. 2 points
    Hello @ANKUR SAINI, If you are on Linux/UNIX with the Accellera release of SystemC library with the GNU toolchain, you can use the following tutorials for reference: https://sourceware.org/gdb/onlinedocs/gdb/Threads.html https://stackoverflow.com/questions/1695268/multi-threaded-debugging-tutorial-for-gdb-and-c Due to the co-operative multi-tasking implementation of the SystemC library available from Accellera as @Roman Popov has mentioned, much of the debugging tasks are easier since all threads synchronize with the main library thread. Let me know if it helps. Regards, Ameya Vikram Singh
  5. 2 points
    hle

    reset during wait(int)

    IEEE 1666-2011 describes wait(int ) as follows: If my interpretation is correct, wait(3); should always be equivalent to wait(); wait(); wait(); However, after applying such an equivalent transformation to tests/systemc/kernel/reset_signal_is/test02/test02.cpp from the regression suite, I got a different simulation output (with systemc-2.3.2): Is this possibly a bug in the reference implementation?
  6. 2 points
    David Black

    sc_thread vs pthread

    SystemC follows event driven simulation semantics to simplify hardware modeling. In part, this means using a cooperative multi-tasking model rather than a modern pre-emptive model. In this respect, SystemC is like SystemVerilog and VHDL. This makes it easier to focus on the modeling aspects rather than worrying about mutexes, volatility and other interactions due to multicore and parallel processes. Advanced SystemC users can use OS threads for some tasks, but the synchronization aspects are up to the programmer. So SC_THREAD's are not pre-emptive (nor are SC_METHOD processes) and hence a straightforward SystemC model is single core single threaded from an OS/software point of view. Additionally, you should be aware that the SystemC scheduler is not thread-safe for the most part. If you make use of async_request_update(), you can use multicore and parallel processes to interact with SystemC events. This assumes you are an expert programmer and proficient with C++ (not for beginners). There have been and are some efforts underway to standardize parallelization in SystemC, but it is a volunteer effort and you need to be on the SystemC LWG group to participate. Some commercial entities have developments underway, but keeping those closed for the time being. Always keep in mind that SystemC is not freeware, but was created as part of a commercial coalition to standardize modeling across/between companies. Don't think of SystemC as a free simulator. Also, SystemC is often mistaken as a competitor/alternative to SystemVerilog/VHDL, which it is NOT. SystemC was intended for high-level modeling and abstractions above RTL. The ability to co-simulate with RTL is a requirement for some of the use-cases. SystemC is used quietly by many large corporations to augment specification and verification. It differs from the other languages in that it uses an off-the-shelf C++ compiler and has no requirement of a specialized compiler. This benefits companies with huge software development teams using SystemC Virtual Platform models for early software development. The downside of this approach is the C++ compiler has no understanding of the SystemC domain and has no way to make optimizations that SystemVerilog/VHDL do (e.g. clocks). That is one reason that SystemC coders are advised to avoid explicit clock models to gain performance. Keep the design at as high a level of abstraction as you can.
  7. 2 points
    maehne

    sc_bitref usage

    The compiler has difficulties to decide which overload of the assignment operator it should use. You can help him by doing a static_cast<bool>(myint[7]).
  8. 2 points
    AmeyaVS

    Mingw Compile Issue

    Hello @Matthias Jung, It seems you are missing some of the compiler definition flags for the build: -DSC_BUILD ... etc. You can get the set of compiler flags for the SystemC library from the CMake generator(Only works with Makefile generator). # Using CMake to create compile_commands.json # SYSTEMC_SRC: SystemC source directory. cd $<SYSTEMC_SRC> # Create a build directory mkdir build cd build # Run CMake configuration for Make file generator. cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. Note: Also the quick thread library for user space thread support will not work on Windows since it is compatible only on Linux systems. Regards, Ameya Vikram Singh
  9. 2 points
    In general, SystemC models should avoid using clocks altogether. This is good for many reasons assuming your goal is high speed behavioral models. SystemC is often used for implementing functionally accurate virtual platforms that allow software to be designed well ahead of hardware delivery. Thus appropriate use of next_trigger() is actually a great idea. There is no way to distinguish between static and dynamic triggering at the point of invocation. Clock is synthesizable and if that particular mode of design is your goal, then sc_clock is appropriate. There are no features of SystemC itself that will tell you if the code itself is synthesizable. The answer to that is highly tool dependent. I know synthesis tools that require no clock at all, and others that insist a clock be specified. Always keep in mind: SystemC is simply C++ syntax used with a library and a methodology to model hardware and software. C++ has no concept of synthesizability. You have to go beyond GCC/LLVM to find out if your code is synthesizable with a given synthesis tool.
  10. 2 points
    This question cannot be answered with respect to the SystemC standard as the issue is heavily implementation dependent. I am aware of implementations where SC_THREAD is faster than SC_METHOD and visa versa. It is also not a good basis for evaluating SystemC itself since the issue of simulation performance almost always comes down to how SystemC was used and how the modeler wrote their SystemC model. I do know an awful lot of folks use SystemC inappropriately (e.g. using it for modeling RTL, where VHDL or SystemVerilog are much better suited). IEEE 1666-2011 calls out the desired behavior, and not the implementation. Note: I did a presentation on SystemC myths many years ago at NASCUG that included the myth about whether or not one should favor SC_METHOD over SC_THREAD for performance reasons. It is quite simply a poor way of making a decision when attempting to obtain performance.
  11. 2 points
    maehne

    Reading a binary File

    Yes, you can use C's fread() function for this purpose. However, you should not use malloc()/free() to handle allocation/deallocation of your buffers. Instead, use C++'s new/delete operators or even better a suitable standard container such as std::array<T, N> or std::vector<T>. C++'s <iostream> library also offers you the possibility to read/write binary data from/to files. SystemC is a C++ library. Therefore, I suggest that you get familiar with C++ first. Confer, e.g., to: https://isocpp.org/get-started http://www.cplusplus.com/reference/iolibrary/ https://stackoverflow.com/questions/8798127/binary-input-output-in-c
  12. 2 points
    This question in mostly about how the linker works on your platform, and not really specific to SystemC. Let me try to give a short summary: Yes, the "main" symbol is needed by the final application For every needed symbol, the linker looks in your object files first If the symbol is present there, the linker picks it up If not, the linker looks in the libraries given by the user (order/lookup is platform-specific) Repeat this for all required symbols (including "sc_main") So, if you define your own "main" in your application, SystemC's "main" will not be picked. This is actually a feature, as you can call "sc_elab_and_sim" manually from your "main" as well, if you want. Hope that helps, Philipp
  13. 2 points
    Hi Jarodw, Thanks for your report. I can confirm and reproduce the issue in SystemC 2.3.2. It looks indeed like a regression compared to SystemC 2.3.0/1 that has been introduced by the fix for optionally unbound sockets, see: It seems, the SystemC regression tests didn't cover the hierarchical binding for the multi sockets, so it wasn't caught before the release. Your example can be fixed by changing line 228 in src/tlm_utils/multi_passthrough_target_socket.h: if (unbound && !m_hierarch_bind) return; // ^-- add check for hierarchical binding here Hope that helps, Philipp
  14. 2 points
    Philipp A Hartmann

    makefile SystemC

    You can check out the example Makefiles in the installation (examples/build-unix/Makefile.{config,rules} and e.g. examples/sysc/simple_bus/Makefile) as a starting point. The files in examples/build-unix are reasonably generic, and you may "just" need to adjust the settings in Makefile.config. In the project's Makefile itself, you then set the PROJECT variable and your SRCS (to point to your source files). Admittedly, documentation could be better (as usual), but you can ask here, if you have further questions. The CMake support included in SystemC 2.3.2 is still experimental and is mostly targeted for early adopters with CMake knowledge. Greetings from Duisburg, Philipp
  15. 2 points
    AmeyaVS

    Clock to Q Propagation Delay

    Hello, In SystemC you can use SC_THREAD's to model delays by using wait statements but you will incur performance penalty. Instead you can use event's and event queues to model delays using in SystemC as mentioned here: http://workspace.accellera.org/Discussion_Forums/helpforum/archive/msg/msg?list_name=help_forum&monthdir=200803&msg=msg00061.html You can replace the SC_THREAD example given in the above mentioned link with SC_METHOD removing the infinite while loop. Here's the modified example listed from the above mentioned link: template<typename T> class delay_transport : public sc_module { public: sc_in<T> in; sc_out<T> out; SC_HAS_PROCESS(delay_transport); delay_transport(sc_module_name name_, sc_time tdelay_) : sc_module(name_), tdelay(tdelay_), in("in"), out("out") { SC_METHOD(mi); sensitive << in.default_event(); SC_METHOD(mo); sensitive << eq; } sc_time tdelay; void mi() { val = in.read(); vq.push(val); eq.notify(tdelay); } void mo() { val = vq.front(); out.write(val); vq.pop(); } sc_event_queue eq; std::queue<T> vq; T val; }; Regards, Ameya Vikram Singh
  16. 2 points
    Yes, but you need to write the constructors yourself (don't use the SC_CTOR macro). Something like #include "systemc.h" SC_MODULE(mod) { int i; mod(sc_module_name nm) : sc_module(nm) { // ... } mod(sc_module_name nm, int i_) : sc_module(nm), i(i_) { // ... } }; If you use SC_THREAD or SC_METHOD you must also include the SC_HAS_PROCESS macro. Try looking up SC_HAS_PROCESS in 1666-2011 and you should find an example near there, regards Alan
  17. 2 points
    Manikanta's solution assumes temp is public. If not public, you can take the opposite approach and simply call sc_trace from within the module itself. You could even do it conditionally based on run-time command-line arguments: sc_core::sc_trace_file trace_file = 0; //< initialize to indicate not open top::before_end_of_elaboration() { for (int i=1; i<sc_argc(); ++i) { if ( trace_file == 0 && std::string(sc_core::sc_argv()[i]) == "-trace" ) trace_file = sc_core::sc_create_vcd_trace_file("your.vcd"); }//endfor } top::end_of_simulation() { if ( trace_file != 0 ) sc_core::sc_close_trace_file(trace_file); } ... extern sc_core::sc_trace_file trace_file; void dut::end_of_elaboration() { if (trace_file != 0) { sc_core::sc_trace(trace_file, temp,"temp"); } } Of course I am assuming fp is made public as shown, and that you have opened it before end of elaboration:
  18. 1 point
    TRANG

    Changing the width in sc_bv<W>

    In many cases , I cant use "const" I often use : #define or enum{}; you can try : #define WDW_SIZE 2 or enum {WDW_SIZE=2}; Best regards
  19. 1 point
    maehne

    Using Debug mode.

    If you use the Makefile provided along the simple_fifo example, it should get compiled with debug symbols. On the console, you should see that the .cpp files get compiled with the "-g" switch. To actually make use of the debugging symbols, you have to execute the example in a debugger such as gdb (as Roman already pointed out). By the way, "make -d" does not influence which flags are passed to the C++ compiler. It just makes the output of make itself more verbose.
  20. 1 point
    Roman Popov

    Backtrace with sc_report_error()

    If you want to see stacktrace in LLDB, then just set a breakpoint in sc_report_error(). If you want to see a stacktrace when you run simulation without debugger, then use Boost::Stacktrace http://www.boost.org/doc/libs/1_65_1/doc/html/stacktrace.html
  21. 1 point
    David Black

    Getting a bit from bus

    First thing you need to realize is that sc_signal<> is not a wire and it is not a data type. sc_signal<> is a channel with a non-blocking write and a blocking read. You cannot "connect" a variable to a signal. You have to explicitly make the transfer each time the value changes. There is no equivalent to a Verilog continuous assignment. How do you know if a signal has changed? You have to explicitly watch/wait for the change using additional methods value_changed_event() or possibly posedge_event() if using sc_signal<bool> or sc_signal<sc_logic>. Due to overloading of operator=(), the innocuous looking busCON10 = var_bus_CON[10] turns into: busCON10.write(var_bus_CON[10].read()); which will not return a value until the end of the next delta cycle. Using a cout << busCON directly after this will yield the current delta's value.
  22. 1 point
    maehne

    SystemC-2.3.2 drops cstring

    Instead of #include <string.h>, you should better #include <cstring> and then add std:: prefixes to the string function calls, which are not found. This avoids polluting your public namespace with identifiers from string.h.
  23. 1 point
    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.
  24. 1 point
    dave_59

    Randomization in an initial block

    This is the correct functionality. There is a random number generator (RNG) for every module instance in your design, and it is seeded with a RNG from the module instance it starts from. All all modules instances start out with identical seeds. Every thread that starts inside a module instance grabs a new RNG. Threads in parallel blocks get seeded in declaration order, not in the indeterminate order they might actually start. Objects that get constructed get seeded with an RNG from the thread calling the constructor. This random stability model has a few problems that the UNM attempts to correct by using a path name as an initial seed. You just need to make sure your path names are unique enough to generate distinctive seeds. A good paper to read on this topic is: Random Stability, Don't leave it to chance.
  25. 1 point
    Admin

    Welcome!

    Welcome to the Accellera Systems Initiative forums. Please register to start new topics or reply to existing topics. We have resently migrated our UVM forums from UVMWorld to this site. If you were registered on the previous UVM forum site, you should be able to log into the forums using your username and password from the UVMWorld forums. If you had an account on both the UVMWorld forums and the Accellera forums and these accounts used the same email address, then log in with the username and password of the forums.accellera.org account, not your UVMWorld account. If you do not remember your password, you may reset it. If you have any questions about using the forums, click the Help button at the bottom of any forum page. If you need any help with your account and you are logged into the site, click the Messenger icon (a letter) in the upper right of your screen, click Compose New, enter “admin” in the Recipient’s Name field, compose your message, and then click Send. You may also send an email to admin@lists.accellera.org. Thank you, Accellera Systems Initiative
×