Jump to content

maehne

Members
  • Posts

    367
  • Joined

  • Last visited

  • Days Won

    43

Everything posted by maehne

  1. Alan's code snippet already shows you how to write constructors with additional arguments. The only thing, which is omitted in the snippet, but mentioned in his post is the necessary call to the SC_HAS_PROCESS macro with the name of the module class as argument so that you can use SC_THREADs and SC_METHODs in your module. I tend to write it just in front of the declaration of the first constructor. Thus, Alan's example would look like: #include "systemc.h" SC_MODULE(mod) { int i; SC_HAS_PROCESS(mod) mod(sc_module_name nm) : sc_module(nm) { // ... } mod(sc_module_name nm, int i_) : sc_module(nm), i(i_) { // ... } }; You can find more information in clause 5.2.6 to 5.2.8 of IEEE Std 1666-2011. I suggest that you read an introductory book on SystemC, e.g., "SystemC from the Ground Up" by David Black and Jack Donovan. Also, get familiar with C++: https://isocpp.org/get-started
  2. I totally agree with David, a good read for an introduction on SystemC is, e.g., "SystemC from the Ground Up" by David Black and Jack Donovan.
  3. The error message indicates that you use a custom data type "com" with the sc_fifo, which does not support the output stream operator. For a custom data type to be compatible with sc_fifo (and other SystemC channels), it has to fulfil a certain number of conditions, which are documented in the SystemC LRM (IEEE Std 1666-2011). In the case of sc_fifo, the constraints are listed in clause 6.23.3 of IEEE Std 1666-2011. In summary, your type "com" needs to implement: The output stream operator: std::ostream& operator<< ( std::ostream&, const com& ); The copy operator (default version automatically generated by the compiler may suffice): const com& operator= ( const com& ); If any constructor has been defined for data type com, there must be a default constructor taking no arguments
  4. David's proposal is semantically very clear. The phasing of the before_end_of_elaboration(), end_of_elaboration(), and end_of_simulation() callbacks ensure that the actions to set up the tracing of implementation details are executed in the right order. IMHO, setting up tracing belongs semantically into the elaboration phase and not into the start of simulation. Then, you have to be aware that there is no guarantee in which order one type of callback is executed for all modules in your design. Therefore, you need to use two separate callbacks to open the trace file (before_end_of_elaboration()) and to register the signals for tracing (end_of_elaboration()).
  5. To learn more about the different elaboration and simulation callbacks, I suggest you have a closer look to Clause 4.4 in IEEE Std 1666-2011. I states for each callback which kind of actions are allowed at the different moments and which are not.
  6. The different elaboration and simulation phase callbacks in SystemC are provided to allow external libraries to hook additional functionality into the elaboration and simulation phases of the SystemC kernel. E.g., the SystemC AMS extensions make heavy use of it to implement the elaboration of the AMS sub-models, which need to be clustered to sub-models that require their own dedicated solver, which handles then the execution of the sub-model and synchronisation with the SystemC kernel. Setting up specialised monitoring and tracing for your SystemC model, which goes beyond the sc_trace mechanism is also a common use case.
  7. 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
  8. You are right. It is usually best practice to bind the ports of a module to the corresponding channels in the constructor of the parent module. However, there are cases, where modules have ports, which do not correspond to physical ports of the component, but which rather expose internal state of the module for debug/monitoring purposes. Designers don't want to bind these ports under all circumstances in their parent/top-level module, but rather want to make that optional. However, all ports need to get bound for simulation. Therefore, SystemC provides you with the before_end_of_elaboration() callback as a mechanism to bind yet unbound ports to some dummy or global channels to make the elaborated model structure well-formed for simulation.
  9. In the above example, you forgot to close the trace file after the last call to sc_start(). You have to explicitly call sc_close_vcd_trace_file(dummy) before you return from sc_main(). Otherwise, the trace file is not guaranteed to be complete and flushed to the disk. The same holds true for the equivalent tracing functions in SystemC AMS. This is essentially equivalent to the file handling with fopen() and fclose() in C, which the original designers of SystemC seem to have tried to mimic as much as possible to not "scare" away hardware designers with "too complex/strange" C++ syntax. ;-)
  10. Your problem description is a bit vague. Did the errors really occur when you tried to compile the unmodified QPSK example? The warnings you are showing point to a file header.h, which does neither exist in the SystemC-AMS PoC simulator sources nor the TUV library sources. You should check the lines referenced by the compiler warnings to understand the cause of the warnings. Probably, std::time_t is on your platform 64 bit long whereas unsigned int is 32 bit long. Try to use unsigned long instead. Nevertheless, the warnings are most probably unrelated to why no VCD trace files get generated. Tracing is usually set up in the sc_main() function (located in main.cpp in the QPSK example). First a handle for the trace file needs to be created with sca_util::sca_create_vcd_trace_file(). Then, the signals to be traced have to be selected by calling sca_util::sca_trace() on them. After simulation (sc_start() call), the trace file needs to be closed using sca_util::sca_close_vcd_trace_file(). In the QPSK example, tracing is set up to be written to a file named "tr.vcd". You will find it in your current working directory, from where you called the executable.
  11. Once you are familiar with the C++ fundamentals, you might also have a look at "Effective Modern C++" by Scott Meyers.
  12. 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.
  13. Philipp in his post from 2017-09-22 already provided you with the answer: To create your two-dimensional array of modules, you actually need two element creators: One for the outer vector, which will create entire rows of modules: This is the one you have implemented with you module_model::element_vector_creator(size_t size, const char* name, size_t) member function. Another one for the inner vector, where you will allocate the individual modules. This is what Philipp demonstrated with his element_creator Lambda function. He just allocated the module and passed the module's base name as an argument. However, you can also pass any additional arguments to the constructor of the module, e.g., your argument r_value. The arguments, you pass to the constructor can be either hard-coded or calculated based on the current index for the element to initialise (i.e., the second argument passed to the element_creator, which is of type std::size_t). If you also need the current index of the outer vector, you can capture the variable representing that outer index for use within the lambda (check a book on Modern C++ discussing Lambdas for details). You can find more information on sc_vector in clause 8.5 of IEEE Std 1666-2011. However, more accessible might be the paper "Automated SystemC Model Instantiation with modern C++ Features and sc_vector" by Ralph Goergen, Philipp Hartmann, and Wolfgang Nebel from DVCon-Europe 2015: and the "An Introduction to IEEE 1666-2011, the New SystemC Standard" video tutorial by John Ainsley, David C. Black, and Tor Jeremiassen: http://videos.accellera.org/ieee16662011/index.html
  14. Your stimuli_pressure_mech_process() member function has to be registered as a SC_THREAD and not a SC_METHOD to be able to use the wait() functions for timing the application of your stimuli. It is not good practice to use the <systemc.h> header. Instead, you should get used right from the start to use the <systemc> header and prefix SystemC functions and types with the appropriate namespace prefixes. In context of functions, you can abbreviate typing by using "using" statements (e.g., "using namespace sc_core;") (cf. to a good book on C++). Also, instead of deactivating the deprecation warnings, you should fix the source of the problem in your code. "sc_start(200)" with only the integer argument is non-standard and, if I remember correctly, has been removed from recent versions of the SystemC PoC simulator. Instead, you should also specify the time unit, e.g., "sc_start(200.0, sc_core::SC_NS);". I suggest you read a good introductory book on SystemC, e.g., "SystemC from the Ground Up".
  15. Regarding your port binding error: It is not sufficient to bind the isink.n terminal to another terminal. Instead, you have to make sure that through these terminal-to-terminal bindings at some point a node of type sca_eln::sca_node or sca_eln::sca_node_ref is bound. (This is basically the same as SystemC allows port-to-port bindings, but requires any port to be bound at some point to a channel.) Regarding setting the sample time of the ELN/TDF cluster: You can use the sca_core::sca_module::set_timestep() member function for this purpose, which can be used across all MoCs (TDF, ELN, LSF) as their specialised primitive module classes derive from the sca_core::sca_module base class.
  16. Hello Roman, instead of developing your own class, have you considered to use std::unique_ptr<T[]> (C++'11) and std::make_unique<T[]> to allocate your array of a fixed size during elaboration? For examples see, e.g.: http://en.cppreference.com/w/cpp/memory/unique_ptr http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique Regards, Torsten
  17. The SystemC AMS proof-of-concept library is available for download from the COSEDA Technologies GmbH: http://www.coseda-tech.com/systemc-ams-proof-of-concept The archive contains an INSTALL file with detailed instructions for building SystemC AMS with MS Visual Studio.
  18. This error message suggests that SystemC itself was not built with the C++'11 standard enabled. Please follow the INSTALL instructions in the SystemC 2.3.2 PoC distribution archive (Section "Preprocessor switches" SC_CPLUSPLUS). The C++ language standard needs to be consistently defined for the SystemC library and your application. This is enforced by the sc_api_version_* linker symbol that you see in the error message.
  19. You don't have to create a new ELN primitive to achieve what you described. However, the sketched-out approach is good: Indeed, you have to connect a sca_eln::sca_vsink and sca_eln::sca_isink to your ELN circuit for which you want to trace the power to measure the voltage drop across and the current flowing through the circuit. Describing such an ELN netlist is done in an sc_core::sc_module instead of an sca_eln::sca_module as a netlist constitutes a structural description of the circuit and not a new ELN primitive (which would add new equations describing the circuit element behaviour to the equation system). Defining such user-defined ELN primitives is not standardised in IEEE Std 1666.1-2016 so you have to live with the pre-defined set of ELN primitives. The isink and vsink modules have a TDF output port, which you have to connect via two signals to a user-defined TDF module, which will define in its processing() member function the calculation of the power and the updating of the corresponding trace variable. Depending on your needs, you may also consider to add a second trace variable for tracing the energy (i.e., the integral over time of the power). You might consider to wrap the isink and vsink as well as the power-calculation TDF module into an sc_core::sc_module, which only exposes the electrical terminals needed for power measurement and the trace variables. This may simplify instantiation of several power measurements. Another approach you may consider is to simply trace the relevant voltages and currents and calculate the power/energy offline in your waveform viewer or math tool, which can process the SystemC AMS trace file format (e.g., Octave).
  20. The memory leaks reported by valgrind, which are related to quickthreads are likely false positives, as is explained by Philipp A. Hartmann in this older thread "SystemC 2.3: valgrind error". Regards, Torsten
  21. Sorry for the late reply! I just saw that this post now. The lines containing scv_report_handler::set_actions(...) in the _scv_message::setup() member function implemented in scv_report.cpp were removed by @StS as suggested in my post from 2017-08-08. So you just stumbled again over the same issue.
  22. Because this detects early common errors when describing the behavior of digital circuits, which would be fatal if they get implemented through logic synthesis. If two gates (represented by different processes, i.e., SC_THREAD or SC_METHOD) drive the same signal line, the resulting behavior in hardware is hard to predict and depends heavily from the used technology. Correct logic levels on the signal line are not anymore guaranteed and high currents flowing constantly through the same wires from VDD to GND can damage the IC. If different gates shall drive the same line (common to model signal busses), they need to have tristate outputs and the logic has to guarantee that driving the line is mutually exclusive. If we come to writing test benches, activating SC_MANY_WRITERS in certain selected cases may be necessary to, e.g., easily inject faults inside the DUT. So, IMHO, the default of SystemC is sane and protects the user.
  23. I agree with Roman that UVM-SystemC is the way to go in the long run. In the meantime, you should be able to avoid the observed warnings by passing globally unique module names to the modules and sc_objects you are creating across all tests. This should satisfy the hierarchical name registry of SystemC. To my knowledge, the latter does not keep track of deallocation of sc_objects and thus that its corresponding hierarchical name is not anymore used. Be aware though that you may run into other surprises as the SystemC kernel is currently not able to fully restart from scratch elaboration and simulation.
  24. The root for your problem is not in the implementation of SystemC, but in your code. You forgot that in C, you cannot simply concatenate C string (i.e., arrays of type char) by adding them. Instead of concatenating strings the addition of char(ID+'A') to the string "My_Name_" modified the pointer to the string to point ID+65 positions beyond the start of the original string. At that point in memory is probably only garbage, which was interpreted by the sc_object constructor as an object name thus causing the illegal characters warning. To properly concatenate strings in C, you need to reserve a big enough buffer to hold the concatenated result and then use strcpy(), strcat(), strncpy(), strncat() functions copying / concatenating strings. However, in C++, you can use std::string to simplify your task. The following code should work. Though, it may not be optimal in terms of performance (a std:: string gets temporarily constructed): scMod((std::string("My_Name_") + char(ID+'A')).c_str())
×
×
  • Create New...