Jump to content

Roman Popov

  • Content count

  • Joined

  • Last visited

  • Days Won


Everything posted by Roman Popov

  1. Notify() Using Event Between Two modules

    Use pointers, references, or write your sc_interface and then use ports/exports. Example with references: #include <systemc.h> struct recv_mod : sc_module { sc_event &write_event; sc_event &recv_event; int &value ; recv_mod(::sc_core::sc_module_name, sc_event &write_event, sc_event &recv_event, int &value ) : write_event(write_event), recv_event(recv_event), value(value) { SC_HAS_PROCESS(recv_mod); SC_THREAD(receiver_thread); } void receiver_thread() { while (1) { wait(write_event); cout << "Read " << value << " at delta: " << sc_delta_count() << endl; recv_event.notify(); } } }; struct trans_mod : sc_module { SC_CTOR(trans_mod) { SC_THREAD(transmitter_thread); } sc_event write_event{"write_event"}; sc_event recv_event{"recv_event"}; int value = 0; recv_mod recv{"recv", write_event, recv_event, value}; void transmitter_thread() { wait(SC_ZERO_TIME); // need to wait to guarantee that reciever is waiting for event for (int i = 0; i < 4; i++) { cout << "Write " << i << " at delta: " << sc_delta_count() << endl; value = i; write_event.notify(); wait(recv_event); } sc_stop(); } }; int sc_main (int argc, char** argv) { trans_mod t{"t"}; sc_start(); } Simulation result: Write 0 at delta: 1 Read 0 at delta: 1 Write 1 at delta: 1 Read 1 at delta: 1 Write 2 at delta: 1 Read 2 at delta: 1 Write 3 at delta: 1 Read 3 at delta: 1
  2. Notify() Using Event Between Two modules

    Do you want to write something like this ?: Producer process: out1.write(42); sig_written.notify(); Consumer process: wait(sig_written); out1.read(); In that case you will read current value of signal, not new one (42). If you want to transfer data immediately between processes, use plain C++ variables.
  3. Stack Size Overflow due to recursion

    Do not put large arrays on process stack. Put them into Module instead, and allocate module in heap. Example: Large array on stack: SC_MODULE(top) { SC_CTOR(top){ SC_THREAD(thread); } void thread() { int large_array[1000000000]; // will be allocated on sc_thread stack } }; int sc_main(int , char**) { top top_inst{"top_inst"}; sc_start(); } After refactoring: SC_MODULE(top) { SC_CTOR(top){ SC_THREAD(thread); int large_array[1000000000]; // inside module body } void thread() { } }; int sc_main(int , char**) { auto top_inst = std::make_unique<top>{"top_inst"}; // allocated on heap sc_start(); }
  4. Mingw Compile Issue

    C:\<...>\main.cpp:-1: error: undefined reference to `sc_core::sc_api_version_2_3_2_cxx201103L<&sc_core::SC_DISABLE_VIRTUAL_BIND_UNDEFINED_>::sc_api_version_2_3_2_cxx201103L(sc_core::sc_writer_policy)' This error suggests that you are building your application with cxx201103L = C++11. But SystemC library was build with C++98. So you either have to rebuild SystemC library with C++11, or use C++98 for your application. Here is an example how to build SystemC and Applications using CMake (with option to enable C++11): https://stackoverflow.com/a/46880679/1503413 If you are using CMake, you can configure your application to use same C++ standard you were using for library build automatically: find_package(SystemCLanguage CONFIG REQUIRED) set (CMAKE_CXX_STANDARD ${SystemC_CXX_STANDARD}) Btw, g++ 5.3 you are using supports C++14, so you can use it instead of C++11. Just pass -DCMAKE_CXX_STANDARD=14 when generating Makefile using CMake.
  5. Mingw Compile Issue

    If you want to build SystemC inside QtCreator you can use CMake project bundled with systemc 2.3.2 ( Open Project, select CMakeLists.txt) . There is no need to create a qmake project.
  6. Why there is no standard interface class in SystemC

    Perhaps a savvy EDA vendor will pickup on This if there is sufficient commercial interest, which I doubt. Well, actually all HLS tools I've used have notion of modular interfaces. I.e. special kind of modules that aggregate ports together with protocol-handling threads and methods. For example in C-to-Silicon compiler you have to derive from both sc_module and sc_interface to create an interface module: struct slave : sc_module , sc_interface { sc_in<bool> data_rdy{"data_rdy"}; sc_in<int> data{"data"}; sc_out<bool> ack{"ack"}; sc_port<slave_if> slave_port{"slave_port"} ... }; The problem is that every tool has it's own way to define this concept. This seem to me like a language design issue: Why not standardize a common keyword for this concept?
  7. In SystemVerilog there is a standard interface keyword for module-like interface structures. Main purpose of interfaces is grouping of ports, protocol handling logic and assertions together. In SytemC there is no standard one in a language. Because of this each vendor has it's own way to create interfaces: some use pragmas, others special MACRO. In some tools interface is a class derived both from sc_module and sc_interface. There are two typedefs in a SystemC library: typedef sc_module sc_channel; typedef sc_module sc_behavior; Was it supposed that one of these should be used for interface classes?
  8. Why there is no standard interface class in SystemC

    No, this is not how interface in SystemVerilog works. Your example is more like Java or C# interface.
  9. Just for the record: None of them works, nor actively maintained.
  10. Verilog is currently supported by all major FPGA and ASIC synthesis vendors. This is why all other HDLs build on top of general purpose programming language offer Verilog converters. Verilog conversion is supported by Chisel (Scala), MyHDL (Python), C╬╗aSH (Haskell). But there is no one for SystemC. This I think is a serious issue for SystemC adaption as hardware design language. Especially in academia, where students are generally using free tools for learning, like free versions of FPGA design suites.
  11. Yes, I've noticed that in my company. People who contribute to SystemC are doing that in a spare time. Which is strange: software companies have full-time employees working on language standards and opensource compilers (C++ itself is an example). What I was talking about is a translator for cycle-accurate RTL models, not an HLS tool. So it would not hurt any business, but rather to promote SystemC as a design language. I did not know that Vivado HLS is included into free WebPack version. This explains why we are seeing students running SystemC in Vivado on this forum. Will try it to compare how good it is vs SystemC synthesis from EDA companies. I know, universities can buy licenses EDA licenses for very low cost. When I was a student we got commercial tools installed in university. But still you can't install them on your own laptop for learning at home. So free FPGA tools were always the best for practice.
  12. Simple Bus

    Do you mean simple_initiator_socket/simple_target_socket? They are described in TLM tutorial here : https://www.doulos.com/knowhow/systemc/tlm2/
  13. Using sc_uint_base directly?

    I think this is true for Chisel, but not for MyHDL. Chisel is indeed uses Scala syntax overload magic to construct netlist out of library predefined primitives. But this makes Chisel somewhat inferior to Verilog/SystemC/MyHDL, because it does not support synthesizable behavioral blocks (AFAIK). MyHDL is essentially the same idea as SystemC, but implemented in dynamic interpreted language. To generate Verilog it uses both Python reflection capabilities, but also has a "compiler" for behavioral blocks. SystemC synthesis tools are not just a compilers. They also have built-in rudimentary C++ interpreters, to comprehend module constructor code, where binding and process creation happens. Well, I think they read this forum periodically. But there is no button "Include HLS vendors". The problem is that synthesizable SystemC subset is essentially a common denominator of what HLS tools already support. So any real HLS tool is more powerful than syn subset. To support "hardware construction" in synthesizable subset SystemC synthesis should draw inspiration from MyHDL. I can reformulate syn subset like this: During elaboration-time everything is allowed. I.e. constructor code and phase callbacks code can be arbitrary C++. All SystemC integer datatypes are supported. This gives elaboration-time defined bit-width. sc_vector is supported. This gives elaboration-time sized container. But only for sc_objects. What if I want elaboration-time defined ROM? Support elaboration time constants and constant vectors. Currently missing in SystemC library SC_METHOD/SC_THREADs are restricted the same way as they are today. To support this subset real C++ interpreter like Cling should be integrated into HLS tool. Another option would be using introspection information like MyHDL does. C++ does not have a standardized one, but Clang and G++ can dump DWARF debug information that is sufficient to extract netlist of SystemC design together with values of all data fields (including constants, sizes of containers, bit-widths ...) as demonstrated by simulator tools based on GDB. I don't see how if constexpr helps in this particular case. Can you please elaborate on a small example? I agree that compile-time programming is powerful and solves most of hardware parameterization cases. We use it everywhere indeed. Originally I also thought that compile-time meta-programming is a solution for this case too. It is indeed possible to construct modules recursively the way like std::tuple is implemented. But there are two issues: TMP code is hard to comprehend. It's not possible to iterate compile-time data structures at runtime ( inside THREADS/METHODS). Behavioral code that uses sc_vector of elaboration-time defined buses is much easier to write and comprehend.
  14. Using sc_uint_base directly?

    Is it ok to use sc_uint_base directly, instead of template sc_uint<W> ? In particular I need to model a vector of buses of variable length. I'm thinking of modeling it like this: static const int VEC_SIZE = 3; static const int WIDTHS[VEC_SIZE] = {10, 20, 40}; SC_MODULE(top) { sc_vector<sc_signal<sc_uint_base>> sig_vec{"sig_vec", VEC_SIZE, [&](const char *name, size_t i) { return new sc_signal<sc_uint_base>(name, {0, WIDTHS[i]}); }}; sc_vector<sc_out<sc_uint_base>> out_port_vec{"out_port_vec", VEC_SIZE}; SC_CTOR(top) { out_port_vec.bind(sig_vec); SC_THREAD(test_thread); } void test_thread() { for (auto & p : out_port_vec) cout <<"width: " << p.read().length() << " value: " << p << endl; unsigned i = 10; for (auto & p : out_port_vec) p.write({i++, p.read().length()}); wait(1, SC_NS); for (auto & p : out_port_vec) cout <<"width: " << p.read().length() << " value: " << p << endl; } }; Was it supposed to be used like this by SystemC authors?
  15. Using sc_uint_base directly?

    I'm not an expert, but my understanding is that other HDLs built on top of general-purpose programming languages like MyHDL (Python) and Chisel (Scala) support this idea of runtime-defined bitwidths. It is very powerful when you need to create a configurable modules like fabrics,routers, caches etc. Chisel authors even advertise it as "Hardware construction language" instead of "Hardware description language", to emphasize that structure of hardware is created at runtime, instead of being hardcoded manually. SystemC also has hidden hardware construction capabilities like sc_uint_base (bitwidth defined at elaboration time), sc_vector (size can be defined during elaboration time, instead of compile-time). But this approach is not marketed widely yet (and not supported by most synthesis tools).
  16. Using sc_uint_base directly?

    Well, I want to use it for RTL bus fabric model. Number of bus slaves is parameterizable, and each slave have different address space size. So the other option I have here is to pick some "one size fits all" value for address bus width, like typedef sc_uint<64> bus_addr_t In that case I rely on synthesis tool to optimize bus width based on address decoding logic in slaves. I can help synthesis tool to by explicitly reducing bus address width in slave like this: <template unsigned WIDTH> struct bus_slave : sc_module { sc_in<sc_uint<64>> bus_addr{"bus_addr"}; sc_signal<sc_uint<WIDTH>> effective_bus_addr{"effective_bus_addr"}; SC_METHOD_INST(shrink_addr, sensitive << bus_addr;) { effective_bus_addr = bus_addr; } } But when cross-boundary optimizations are disabled, it will still have to emit 64 wires for address to gate-level netlist. If fabric slave port has a register buffer for address, it will also be 64-bits, instead of some slave-specific width. So sc_uint_base seem to me as the only solution now (if supported by tools). Unfortunately I don't know how to support user-defined channel classes for synthesis. Most tools support only sc_signal<T>. And it is not possible to bind sc_out<sc_uint_base> to sc_signal<sc_uint<W>>, despite sc_uint is derived from sc_uint_base.
  17. How to synchronize Qt5 and SystemC?

    You want to write a GUI for C++ debugger? You can check QtCreator source code, it's written in C++ with Qt and it has integration with GDB/LLDB/CDB. You can run your SystemC model in debugger from QtCreator.
  18. DEFINING GLOBAL IN SYSTEMC and Member Function

    Some synthesis tools support shared arrays between modules. So this is vendor-specific. But in general you will need to create a multiport memory module to share memory between multiple consumers.
  19. DEFINING GLOBAL IN SYSTEMC and Member Function

    Hard to say without processes source code. But if you use global variables like inp_image in your processes, this would not be synthesizable.
  20. DEFINING GLOBAL IN SYSTEMC and Member Function

    Depends on what you want. Global state is not synthesizable.
  21. help to understand

    There are no process-local signals in SystemC.
  22. help to understand

    If you are new to SystemC you should start with some tutorial, for example https://www.doulos.com/knowhow/systemc/tutorial/. Then learn by exploring examples bundled with SystemC kernel. SystemC standard PDF also has lots of useful information for beginners.
  23. help to understand

    This is not true. We use SystemC for RTL when we need to create highly-configurable RTL IPs. Also SystemC RTL has advantage in code sharing with VPs. So for example if I write UART in SystemC I can reuse CSR code between RTL and VP. And SystemC is better for FSMs, because CTHREADs are synthesizable. Unlike Verilog/VHDL where you need to code FSM state explicitly. (This is of course Verilog/VHDL synthesis tools limitation, not languages limitation ) The only major drawback of SystemC is specifying combinatorial circuits, because SystemC has no wildcard sensitivity lists, like always @* in Verilog.
  24. cannot understand error

    Looks like the error is inside Xilinx libraries internals. I suggest you should ask on Xilinx forums.
  25. port binding