Jump to content

David Black

Members
  • Posts

    690
  • Joined

  • Last visited

  • Days Won

    154

Everything posted by David Black

  1. 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
  2. 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.
  3. 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]
  4. Create a class auto-extension with an id that automatically increments. Be sure to include <cstdint> and define it as uintmax_t to ensure portability. You could even automatically add it in your memory manager so that it is always there for your models.
  5. This question is NOT a question for Accellera since Questa is a product of Mentor Graphics. Due to legal requirements it would NOT be appropriate for anybody to respond to your question here except to tell you to go elsewhere. You may read the preceding thread for a few clues, but if that does not suffice then please redirect your questions to Mentor.
  6. 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 Outline: 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.
  7. You can restore a process' sensitivity only while executing the process prior to yielding. If that is the case, simply invoke next_trigger(void). Once you have yielded (returned), you will have to wait until you are triggered. If you don't call next_trigger() at all inside your method, then static sensitivity is implied for the next invocation. Static sensitivity is really just a precompiled list of of or conditions and is not really different from dynamic sensitivity anyhow. It is called static because it is established prior to the start of simulation (normally during construction). For dynamic processes, it concept is similar, but the "static" list is established prior to sc_spawn. So a simple solution is to add an event designed to get your waiting SC_METHOD back to reset the sensitivity. This can be done with 1 sc_event and a bool. I will illustrate in a followup post.
  8. For ordinary memory transfers, you want the data length equal to the streaming width. For FIFO-like transfers, you would set the streaming width to the width of the FIFO, which will be less than the data length. Having a streaming length greater than the data length is somewhat pointless; however, it you don't want to think about it, using a value of UNINT_MAX (#include <climits>) is a great way of ensuring that streaming won't mess up the transaction. The default constructed value of streaming width is zero and illegal.
  9. You might want to add an else clause and issue an error message in case the file does not open successfully (e.g. due to the filename or location being wrong or permissions). I/O errors always bite when you least expect them and they often waste time figuring out what happened. Clear error messages are very helpful. For more information: <https://www.cplusplus.com/reference/fstream/ifstream/is_open/> look at the example.
  10. I strongly agree with @maehne that you should consider using sc_signal_resolved unless you guarantee that all the writers will be perfectly synchronized and never disagree with one another. If you don't, you risk race conditions. You might even want to consider using a pullup signal, which you can easily derive from sc_signal_resolved.
  11. 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. Use either the multi_passthrough_target_socket<T> or any of the tagged sockets Not necessary You probably would need to use std::vector to manage various protocol related state variables per port. Obviously use the payload command field to distinguish Read/Write. Simple arrays are definitely faster and allow for DMI Sockets have built-in width already. Since width is generally a multiple of 8 bits, I would probably factor that into an aspect of my arrays. Take a look at Boost library for multi-dimensional arrays that would have decent performance for the memory since it will likely be multi-dimensional.
  13. 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.
  14. This is not really a UVM topic and should be posted under a SystemVerilog or Verilog forum. Sounds like you could use basic SystemVerilog training. You might be served by a simple: initial begin $monitor( $time,,wdata,,rdata ); ///< Display wdata or rdata anytime they change end There can only be one $monitor active at any time. So if you have more than one need, you have to combine all into a single monitor. At any rate, perhaps you could put a code sample illustrating the problem on www.EDAplayground.com then share the link back here.
  15. Of course you could not start the program, because a library is not an application. You have to write the simulation application yourself using the library to accomplish your goal. SystemC is not an application. It is a library. You need to be suitably proficient in C++ programming to accomplish the tasks.
  16. How proficient are you with C++? Have you read IEEE-1666-2011 (download for free via accellera.org)? Have you downloaded an read all the documentation that comes with the Proof-of-Concept library for SystemC (version 2.3.3)? There are examples and documentation there. Have you visited edaplayground.com? There are limited examples there. Do you hold a degree in Electrical Engineering or Computer Science? Have your read the book, SystemC: From the Ground Up? It contains exercises. You can find associated files at https://github.com/dcblack/SCFTGU_BOOK/blob/master/README.md You will also find some examples on GitHub at various locations. Here is one (I have several others including some currently under development): https://github.com/dcblack/ModernSystemC
  17. You have several errors due to: Failure to specify the compile-time option '-std=c++11' when using C++11 syntax. Compiler defaults to C++03. 'using namespace std' in conjunction with a global named 'array'. std::array<T> is a new templated class in C++11 and conflicts. Changing references from 'array' to '::array' solves the problem. It would be better to rename it to something that does not collide (e.g. data_array) or remove the 'using' clause and properly provide the correct 'std::' prefix where appropriate. Failure to use uniform initialization of a variable used as a global. As of C++11. When creating a global use the syntax 'TYPE VARNAME { CONSTRUCTOR_ARGUMENTS };' This also works for class members. Specifying global variables that should really be private class members (e.g. count). Solved by moving the declarations to the header file and using uniform initialization. Note that use of globals is generally (including this case) a very poor design decision. Note also the use of '#include "systemc.h"' is frowned upon in many circles. Use '#include <systemc>' (without the '.h') instead. You need to take a proper course in modern C++ to avoid C++ syntax errors. These are novice C++ errors. This forum is for real SystemC issues, not C++ syntax.
  18. Dynamic threads have sc_process_handle's that can be used to distinguish them from one another. Dynamic processes can also have arguments passed when they launch by value, reference and const reference. So processes are not a problem. Vectors of sc_event's should be fine (because they are not considered as elaboration time only objects), data structure can be done the same. Ports and modules on the other hand are somewhat problematic; however, you could allocate sc_vector's of these with a fixed upper limit; however, connectivity must be fixed at elaboration. You will of course need to manage the configuration information as to how you use these. I suspect that once you properly define the parameters of your design, it will all be possible. I suggest you first draw a diagram illustrating what you are attempting to do and describe the application. You certainly cannot have an open-ended "I want it to do everything". So please indicate the bounds and time relevant information. Perhaps provide a UML sequence diagram to give a better idea of the dynamic nature required.
  19. @junjiegI apologize for not understanding that your comment was referring to the header of the PSS standard. I will step aside.
  20. Your question is inappropriate for this forum and organization. C++ is used by several of the standards here; however, the definition of C++ and its appropriate use should be redirected to the C++ standards organization elsewhere. This is also not a forum to debate the merits of syntax decisions made elsewhere unless you are proposing and contrasting the syntax with a fundamental language defined here.
  21. 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.
  22. Try issuing a fatal message: `uvm_fatal(get_type_name(),"Self-destruct")
  23. usleep() does not interact with the systemc kernel at all. SystemC time is different from real time.
  24. You cannot compile C++ under a C compiler and SystemC is C++. You will need to create an extern "C" wrapper and you will need to deal with maintaining objects. This is really a C++ issue and you should probably read <https://isocpp.org/wiki/faq/mixing-c-and-cpp>.
  25. Nothing in SC_THREAD main has any dependence on anything other than time in your example. The external event will have not effect. If you want to see an event, you must be waiting on it. usleep only consumes time. wait(SC_ZERO_TIME) means that the simulation for that portion will wait zero simulated seconds and resume. You should add wait(event) to see it.
×
×
  • Create New...