Popular Content

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

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

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!

The Accellera SystemC Language Working Group has released the proposed SystemC 2.3.2 for testing and feedback from the community. This is a maintenance release with some new features including a foundation for C++11/14 enablement, a centralized global name registration enabling CCI naming requirements, new TLM socket and sc_signal base classes, and updated compiler and platform support including Windows DLL support and an experimental CMake build system. There are also many bug-fixes and general clean-up. Licensed under Apache 2.0, the release package contains the SystemC class library and the regression test suite. It can be downloaded here.
The review period is open until May 31, 2017. Feedback is welcome and can be submitted either by email to review-systemc@lists.accellera.org or via this forum.

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

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?

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.

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

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.

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.

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

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

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

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

Have you looked at the functions defined in clause 4.5.7 Functions to detect pending activity of IEEE Std. 1666-2011? Using the simcontext directly is not advisable as its interface is not part of the SystemC standard. It is thus an implementation detail of the Accellera proof-of-concept implementation of SystemC on which you should not depend on if you want a portable solution.

Hi.
Ameya is right.
See SystemC LRM (ieee1666) Section 5.2.15:
[...] it is associated with the most recently created process instance [...]
I.e.: ONE process created most recently before calling dont_initialize is not execute.
BTW: No process is executed in the constructor. But all processes, that are not marked as dont_initialize, are evaluated once at simulation start.
Greetings
Ralph

Hi.
There seems to be a problem with the '#if defined' expressions.
MSYS gcc and clang define _WIN32, and in combination with using pthreads, SC_USE_PTHREADS is defined as well.
Could you please evaluate possible fixes? E.g. adding '!defined(SC_USE_PTHREADS)' in line 33 of sc_cor_fiber.h?
And could you please try with the public review version of SystemC 2.3.2 as well (http://www.accellera.org/downloads/drafts-review)?
If this works, I can try to forward the issue to the SystemC developer working group.
Greetings
Ralph

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

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:

Maybe a little bit late but there are socket implementations available which do trace tlm transactions int a SCV database. They can be found at https://github.com/Minres/SystemC-Components/tree/master/incl/scv4tlm and are used e.g. at https://github.com/Minres/SystemC-Components/blob/5f7387ab7e3dfc2ff6a7cac6fbe834ed7ec8ae36/incl/sysc/tlmtarget.h which in turn serve as building blocks in https://github.com/Minres/SystemC-Components-Test/tree/master/examples/simple_system
The setup given by Kai is put into sysc::tracer where all the tracing setup (VCD & SCV) is impelemted.
Best regards
-Eyck

Hi Ahmed,
apologies for the late reply.
This is indeed an surprising behavior on your system. It seems the default "--libdir" setting from Autoconf is different on your platform - which is not expected.
Can you please post the output of running
../configure --help
In order to create the canonical "classic installation layout" of SystemC, you can override the --libdir default via (please note the single quotes):
../configure --libdir='${prefix}/lib'
I'll look into the TESTNAME incompatibility for the final 2.3.2 release as well.
Thanks and Greetings from Duisburg,
Philipp

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.