Jump to content

David Black

  • Content Count

  • Joined

  • Last visited

  • Days Won


Reputation Activity

  1. Like
    David Black reacted to Eyck in Issue while calling sc_main multiple times from main   
    Just to add 2 cents to @David Black proposal: If the instantiation is exepensive you could fork() (https://en.wikipedia.org/wiki/Fork_(system_call)) your programm after instantiating the design. Basically you create a new OS process as copy of the current one and here you can continue the simulation. But in essence it is the same approach as David described.
  2. Like
    David Black reacted to maehne in Issue while calling sc_main multiple times from main   
    The primary reason is that the SystemC Proof-of-Concept (PoC) implementation uses some global data structures, which get constructed during elaboration, which are not fully cleaned up when sc_stop() is called. These data structures are only freed by the OS when the application quits. There have been some efforts improve the PoC implementation in this area, but these are currently stalled. Unfortunately, partially due to bad code examples, bad habits, and laziness, many SystemC models also not cleanly deallocate their dynamically allocated resources, as they still use manual resource allocation using the new operator, but never release that memory using delete as they don't implement a destructor out of laziness. Since the general availability of smart pointers in C++'11, especially std::unique_ptr<T>,  managing cleanly dynamic memory management has become much more convenient and there is no justification anymore to write such dirty code. However, there is a lot of legacy code out there making a bad example and hardware engineers often lack a formal education in C++ instead learning the language basically on the job. This will only resolve slowly over time. 
    @David Black's suggestion to launch your multiple simulations from a separate process implemented using your favourite scripting language or even in C++, is the easiest workaround for the above problems.
  3. Like
    David Black got a reaction from KiranK in Does anyone knows what different between systemC and systemC TLM?   
    SystemC TLM is a part of the SystemC standard (both parts TLM1 and TLM2). True, it is an newer addition, but it is never-the-less part of the standard.
    TLM1 was the first attempt to standardize an API, which worked, but it didn't address the needs of the SystemC community as well as had been hoped. TLM2 standardizes a methodology to model address mapped bus communications and the associated API. It allows for easier exchange of IP blocks for simulation.
    TLM emphasizes that "ports" are not just wiring connection points, but rather a nexus for higher levels of communication. TLM2 has "sockets", which are really just glorified SystemC port combinations (sc_port & sc_export). TLM2 also standardizes some concepts (even if not stringently) of different styles of transaction level modeling (sometimes called coding styles). For instance, "loosely-timed" (LT) represents "execute as fast as possible while maintaining register functional accuracy"; whereas, "approximately-timed" (AT) means "provide sufficient timing detail to allow bus-level timing analysis[1]". AT does not simulate as quickly as LT because it has to provide extra details and timing behavior.
    Note 1: Not necessarily the same as clock cycle accuracy.
    On the other hand, the SystemC core provides the fundamental mechanisms that allow for design encapsulation (sc_module), event-driven simulation (sc_event and wait()), processes (SC_THREAD, SC_METHOD), a notion of simulated time (sc_time) and channels (sc_interface, sc_prim_channel, sc_channel). Channels are one of the most important features and enable abstraction of safe interprocess communications. SystemC also provides the minor addition of hardware datatypes (sc_logic<>, sc_int<>, sc_fixed<>, etc). It also provides primitive communications channels such as sc_signal<> and sc_fifo<>. Thus, the SystemC core provides the foundation needed to implement TLM.
    Sadly in some sense, SystemC provides a number of simplifications for writing RTL even though it is fundamentally not the strong point of the simulator. To some degree these simplifications are an holdover from SystemC 1.0 for backwards compatibility. I said sad because the simplifications have encouraged many to think of SystemC as an appropriate vehicle for writing RTL code, but then get frustrated at the lack of performance (for RTL). SystemVerilog and VHDL are much better suited for that task. The RTL aspect of SystemC is good in making it easier to interface SystemC to the other languages for co-simulation.
  4. Like
    David Black got a reaction from Nitin_S in Issue while calling sc_main multiple times from main   
    @Eyck is correct. It would be a major rewrite of SystemC to allow this. If you are trying to launch multiple simulations (sequentially) perhaps with different parameters, you need to do that from a script. If you are super insistent you have to do it under C++, you could try the following:
    // Compile your main SystemC as run.exe and place it in the same directory as this program int main(void) { int errors = 0; errors |= system("./run.exe -option 1"); errors |= system("./run.exe -option 2"); return errors; } Or just use your favorite script language (bash, perl, zsh, csh, python) to do the equivalent. You can store results in files and read configuration data from files. It's just C++.
    If you want to rewrite the main.cpp from the library, feel free to do so, but you still won't be able to reset SystemC's internal data structures without invoke a completely new process.
  5. Like
    David Black reacted to Eyck in Binding sc_out type of ports to sc_port<sc_signal_inout_if<T>,N> type of multiports failed   
    You cannot bind an output port to an input port. Ultimately each port must bind to a signal either hierarchically (this is where port to port binding can is used) or directly.
    So you need to define signal for each of the test_module output ports and bind the sc_out and sc_inout ports to it.
    2 remarks:
    you should use sc_in instead of sc_inout to indicate the purpose clearly sc_out is just a child of sc_inout to reduce the number of output ports (and hence signal) you might want to group signals logically belonging together into structs. Those can be used as data typs of signals and ports. This reduces the number of signals and events and increases simulation speed.
  6. Like
    David Black got a reaction from maehne in How can I identify which port has changed value when using a multiport   
    First, you have an error in your example corrected below:
    for(int i=0;i<prt_input.size();i++) sensitive << prt_input[i]->value_changed_event(); } Second, you can use a recent addition to SystemC (if using version 2.3.3 or later) using the new sc_event::triggered() method, which returns true if the event happened in the immediately preceding delta-cycle. You would simply apply this to the default_event() method present in most channels. A less general approach could also be used with sc_signal channel, which has always provided the event() method for the same effect, but won't work on other channels. Of course you can apply this to any method returning events of other types (e.g. sc_fifo_in_if::data_written_event()). This can also be used with SC_THREADs with the sc_event_or_list.
    I illustrate the more general approach on EDAplayground here: https://edaplayground.com/x/4kgB
  7. Like
    David Black got a reaction from maehne in About AT   
    Approximately-Timed (AT) models provide decent timing accuracy for modeling purposes. Common use cases include architectural analysis (cost vs performance). AT models are used to understand the effects of interconnect and bus protocols on overall performance.
    Loosely-Timed (LT) models provide for simulation performance (i.e. fast), but often use techniques that sacrifice modeled timing accuracy. The intent is for use in software development on virtual platforms. Techniques used include Temporal De-coupling coupled a notion of a Quantum, and Direct Memory Interface. LT models usually try to minimize calls to wait() due to overhead of context switching. Fast models almost never use sc_clock (slows simulation).
    Both modeling styles (AT & LT) should be register accurate and functionally correct. Both include timing, but obviously the degree of accuracy differs greatly.
    Standards compliant models will provide both modeling styles in a single design; although; it is often the case that early modeling starts with one or the other and later adds the missing style. Generally, b_transport functions provide the LT coding style, and nb_transport_* methods provide the AT coding style.
    Neither should be as accurate as RTL because that would require adding so much code overhead that you might as well write RTL and skip SystemC. Clock cycle accurate models are generally inappropriate. Cycle-Approximate or Cycle-Count Accurate modeling is a better description of AT models.
    [As an employee of Doulos Ltd, I teach courses on SystemC modeling with TLM-2.0. You might find that taking an on-line class from us is beneficial. https://www.doulos.com]
  8. Like
    David Black got a reaction from maehne in About AT   
    TLM (Transaction Level Modeling) is focused on communication (interconnection) of SystemC models. So your question is slightly irrelevant. From what you indicate, I would say that AT modeling style would accomplish what you are interested in. Sockets are an almost essential aspect of  TLM as they simplify modeling and can provide information about the transaction.
    As to what metrics you can get, that is up to you. SystemC is not a prepacked set of subroutines, nor is it a narrowly focused on one type of analysis. SystemC is a methodology using C++ to model any variety of ideas using an event driven simulation core (provided). You provide the code to stimulate and assess the information. It is common to obtain things such as bus bandwidth and utilization, but there are no primitives provided to do this on its own.
    Important: You need to be well versed in C++ to effectively use SystemC. Far too many folks approach SystemC thinking it will be a panacea and only requires C.
    There are companies that provide commercial tools on top of SystemC to help with modeling. I will not comment on their utility, but obviously they have some value or they would not be around for long. There are also consulting companies that specialize in SystemC. Learn more on the main Accellera website (https://www.accellera.com). My employer (and thus myself) focuses on the training/educational aspect.
  9. Like
    David Black got a reaction from maehne in SC_METHOD Dynamic sensitivity modification outside the process   
    Silly me, I was quite mistaken in my simple solution (and it only took me a few minutes after posting to realize it); however, this exercise reminded me of a 2011 feature: reset. This works for SC_METHOD processes, but is inconvenient for SC_THREADs. I enjoyed working the puzzle.
    You can see a full working example here: https://www.edaplayground.com/x/39QM
    When registering your SC_METHOD process capture the process handle and specify dont_initialize(). At the start of your method implementation, check for the trigger state of reset_event and return immediately if triggered. To reset static sensitivity, simply issue reset on the process. Include a comment that you are simply interrupting. Note 1: This assumes you are using a version of SystemC 2.3.3 or later. If using 2.3, you will need to add a bool flag that is set at the time of invoking reset and cleared inside the process upon detection.
    Note 2: You could also use reset_signal_is(); however, that would require adding deassertion and would be messier in my opinion.
    An alternate and less intrusive method would be to simply add an interrupt event into the sc_event_or_list every time you change sensitivity:
    next_trigger(some_event | interrupt_event); next_trigger(time_delay, interrupt_event); Unfortunately, this doesn't work for sc_event_and_list; however, you can synthesize that situation with another process. I will leave that for you to figure out.
  10. Like
    David Black reacted to Eyck in How to open and read TEXT file in systemC   
    AFAICS you don't increment the index i in the while loop.
    But your code is way to complex.:
    std::ifstream ifs("TEXT.txt"); if(ifs.is_open()){ int buf = 0; for (int i = 0; i < MEM_DEPTH; i++) { ifs >> buf; buff_1[i]=buf } } ifs.close(); should replace everything from fopen() until fclose(). And you should avoid using macros, they will bite you. '#define MEM_DEPTH 20' should become 'const size_t MEM_DEPTH=20;'.
  11. Like
    David Black got a reaction from tahirsengine in A weird question about UVM   
    UVM is all about reuse. Reuse has several different aspects:
    Reuse of an engineers knowledge -- those experienced with UVM can usually jump onto an existing or new UVM project with very little ramp time. I have seen some verification environments using their own methodology that literally took months for new engineers to come up to speed on. Mind you misuse of UVM can lead to the same conclusion if you don't stay within the standard itself. Reuse of verification components -- means you can reuse a UVM environment without editing a single line of code provided by that environment. This is huge. It is possible to purchase UVM components that test standard interfaces (e.g., 1G Ethernet) and not have to create the code yourself. It still requires the expertise to plug the component into your environment, but it is relatively easy to do. UVM also means application of a tried and tested methodology rather than role your own.
    Downsides to UVM include:
    UVM is fairly complex and to get the most out of it generally requires training UVM is fairly large as a body of code and has a lot of boilerplate code Bottom-line: You don't have to use UVM to verify your code, but if your designs are large enough, it seem crazy not to adopt it. You can hire employees and contractors that know how to do leverage UVM and purchase components to shorten your design task. For small/tiny designs, it may not make sense.
  12. Like
    David Black got a reaction from Nimesh in Determining change in signals   
    module who_changed_first(input a, b, start); always @(posedge start) begin byte changed; WATCHERS: fork @a changed = "a"; @b changed = "b"; join_any disable WATCHERS; //< prevent others from overwriting case (changed) "a": work_1; "b": work_2; endcase end Assumes SystemVerilog. If Verilog you will need to add .
    See https://edaplayground.com/x/2NXz for example code.
  13. Like
    David Black reacted to Eyck in Module that convert an sc_vector input into sc_signal   
    Sure. Just add a method reading all bool sc_in and write to the output. You need to make it sensitive to all inputs Something like:
    SC_MODULE(conv){ sc_vector<sc_in<bool> > input{"input"}; sc_out<bool> ouput{"ouput"}; SC_CTOR(conv){ SC_HAS_PROCESS(conv); SC_METHOD(method); for(auto& in: input){ sensitive<<in; } } void method(){ unsigned res = input[1]?2:0+input[0]?1:0; output=res; } };  
  14. Like
    David Black reacted to Philipp A Hartmann in Support for C++11/14 in SystemC 2.3.2   
    Hi Ameya,
    you're right: The SystemC 2.3.2 release selects a particular C++ standard to build upon and enforces consistency of this selection between the model and the library at link-time.
    Users can override the detection by setting the SC_CPLUSPLUS macro at build time to a (usually earlier) C++ version, as documented in the RELEASENOTES and INSTALL files of the SystemC 2.3.2 public review release.
    5) Initial support for C++11/14 =============================== This package includes an initial implementation of the C++11/14 proposal, presented at DVCon Europe 2016 ("Moving SystemC to a new C++ Standard"). This includes the addition of two new preprocessor symbols: - IEEE_1666_CPLUSPLUS (read-only) This symbol indicates the availability of certain SystemC features which depend on a particular version of the ISO C++ standard (see below). - SC_CPLUSPLUS (overridable) By default, the most recent supported version of the C++ standard for the current platform/compiler is automatically detected and reflected by the SC_CPLUSPLUS macro. Users can override (i.e. usually downgrade) the assumed C++ standard to an earlier version for compatiblity. The value of this macro has to be set consistently across the SystemC library build and all linked models (see INSTALL). The values of these macros follow the values defined by the C++ standards. Currently supported versions are: - 199711L (C++03, ISO/IEC 14882:1998, 14882:2003) - 201103L (C++11, ISO/IEC 14882:2011) - 201402L (C++14, ISO/IEC 14882:2014) The following features currently require a dedicated C++ standard version beyond ISO/IEC 14882:2003 (aka C++03): - C++11 (IEEE_1666_CPLUSPLUS==201103L) o explicit sc_bitref_r<>::operator bool() const Restricts direct boolean conversion of bitvector element references to explicit boolean contexts (e.g. `if` expressions). Use the `to_bool()` function on earlier setups. In the future, further language features depending on modern C++ language constructs may be added. INSTALL:
    * SC_CPLUSPLUS - Override automatically detected C++ standard support This setting allows downgrading the assumed version of the underlying C++ standard on the current platform. By default, the latest supported version is chosen. Supported values are * SC_CPLUSPLUS=199701L (C++03, ISO/IEC 14882:1998, 14882:2003) * SC_CPLUSPLUS=201103L (C++11, ISO/IEC 14882:2011) * SC_CPLUSPLUS=201402L (C++14, ISO/IEC 14882:2014) Note: This symbol needs to be consistently defined in the library and any application linking against the built library.  
    Especially the last note in the RELEASENOTES is relevant to your question:
    In order to reduce the complexity of all the different C++ language support differences across compiler versions, the LWG decided to at least enforce a consistent selection of the C++ baseline in the proof-of-concept implementation.  Of course, other vendors may chose to allow more flexibility here, although sometimes even a consistent compiler version selection is mandated.
    With this decision, the implementation does not have to worry about binary compatibility across different (C++ standard dependent) feature sets in the future.  As of today, the (currently internal) classes sc_type_index, sc_string_view differ depending on the platform's C++ standard support. Future extensions might change other classes as well.  Not worrying about the ABI compatibility is a helpful simplification here.
    As described above, you can set -DSC_CPLUSPLUS=... consistently on the compiler command-line to build a single library build across several GCC versions.  If supported by your platform/compiler, you can still use the different -std=c++XY flags (or their defaults) from the compilers, provided that they generate compatible code across the selected C++ standard version.
    Hope that clarifies the rationale behind the current implementation.
    Greetings from Duisburg,
  15. Like
    David Black reacted to chr_sue in Covergroup instance issue - system verilog coverage   
    You dot need a reference to the covergroup class. You can omit this line of code:
    cg_fsm_state cg_fsm_state_inst;
    In the constructor you are calling new directly on the coverage class name:
    cg_fsm_state = new();
  16. Like
    David Black reacted to Eyck in get interface failed: port is not bound:   
    You are writing to ports in the constructor of server. At this point they are not bound. Since you initialize them in the beginning of your thread this is not needed anyways.
    Aside of that you also do not need the sensitivity list for the monitor thread as you never use the default sensitivity (by using wait() ). And if you use C++11 or newer you should use In-class member initializers which eases the naming of signals (and you should name them to make debugging easier):
    sc_in<bool> begin1{"begin1"}, begin2{"begin2"}, begin3{"begin3"}; sc_in<bool> end1{"end1"}, end2{"end2"}, end3{"end3"}; sc_in<bool> incoming1{"incoming1"}, incoming2{"incoming2"}, incoming3{"incoming3"}; sc_out<bool> free{"free"}, outgoing1{"outgoing1"}, outgoing2{"outgoing2"}, outgoing3{"outgoing3"};  
  17. Like
    David Black got a reaction from maehne in async_request_update example   
    usleep() does not interact with the systemc kernel at all. SystemC time is different from real time.
  18. Like
    David Black got a reaction from maehne in How to read or write a 256 bit binary?   
    This is easy.
    First, sc_int<N> and sc_uint<N> are limited to 64 bits. So you cannot use 256 there; however, you can use sc_bigint<N> and sc_biguint<N> for any value of N>64.
    Second, you will need to specify constants as strings since C++ itself does not support >64 native numbers; although, you can use C++ user-defined literals to get around this limitation if using C++ 2011 or better.
  19. Like
    David Black reacted to Eyck in Queue fifo   
    Actually you created an array of inputs of type int, not a pipe. Without more code it is hard to give any advise
  20. Sad
    David Black got a reaction from Bes in System c help   
    SystemC is simply a C++ library. The syntax of SystemC is C++. To meet the requirement of using SystemC you would probably just place the C++ inside a SystemC SC_THREAD method. SystemC is easy to wrap around C or C++.
    This is sounding more and more like you are doing homework for a class, which means you need to get educated. This forum is not a place to have us do your work for you.
    First, go and learn C++. I don't mean minimal C++ either. SystemC uses plenty of advanced constructs of C++ including OO concepts, generic programming concepts and coding patterns. You have very little hope of being a successful SystemC coder if you don't know C++ well.
    Second, take a class on SystemC or read a good book. Take time to do the examples and understand how it hangs together.
    Shy of the above, find another field of endeavour.
    In any case, please do not ask people to do your homework. We have enough on our plates as it is, and you will do your future employer no favor if you slide by with minimal SystemC skills.
    Where to take a course? Try https://www.doulos.com/content/training/SysC_training.php (my employer)
    Where to find a book? Try Amazon. I wrote a book (slightly dated: SystemC: From the Ground Up) that will get you started. Or search for others.
    But a SystemC course or book will not help much until you become proficient at C++.
  21. Confused
    David Black got a reaction from Bes in Fsm   
    This looks like homework and a trivial FSM. Most of the coding would be simple C++. Good luck!
  22. Thanks
    David Black got a reaction from Bes in System c help   
    For your specific problem just Google "C++ read CSV":
    https://thispointer.com/how-to-read-data-from-a-csv-file-in-c/ https://www.gormanalysis.com/blog/reading-and-writing-csv-files-with-cpp/ For C++ try:
    https://www.geeksforgeeks.org/c-plus-plus/ http://www.cplusplus.com/doc/tutorial/
  23. Thanks
    David Black got a reaction from Amol Nikade in sc_clock Doubt   
    There is no default_time_unit in SystemC; however, the sc_clock default constructor does supply a default value of 1 ns. Be careful you don't set the time resolution larger than 1 ns, if you are going to use the default time. You could of course be more explict:
    sc_time clock{ "clock", 1, SC_NS }; //< assumes C++11 or better and using namespace sc_core  
  24. Sad
    David Black got a reaction from tymonx in UVM Library Test Suite and Git Repository   
    If your question on UVM is whether the repository is open to modifications, the answer is no. The UVM proof of concept library is carefully managed by Accellera as part of the standard's development. I cannot answer the question about test suites.
  25. Thanks
    David Black got a reaction from SiGa in How to generate sc_signal at runtime?   
    Sc_signals are not data types. Sc_signals are channels, which represent hardware being modeled and are used as mechanisms to transport data between processes. As such, channels are only allowed to be created during the “elaboration phase” that occurs prior to simulation starting up.
    Also, strictly speaking, sc_port’s are not normal pointers; although, an underlying mechanism uses pointers for efficiencies sake. The operator->() is overloaded on sc_port<IF_TYPE>.
    You could of course create an sc_vector< sc_signal<T> >, N >, where N was a maximum of the number of signals required and then allocate specific index to each spawned process. 
  • Create New...