Jump to content

David Black

Members
  • Content Count

    418
  • Joined

  • Last visited

  • Days Won

    90

Reputation Activity

  1. 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.
    RELEASENOTES:
    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,
      Philipp
     
  2. 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();
     
     
  3. 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"};  
  4. 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.
  5. 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.
     
  6. 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
  7. 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++.
  8. 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!
  9. 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/
  10. 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  
  11. 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.
  12. 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. 
  13. Thanks
    David Black got a reaction from isael.diaz in what is the intended use of sc_attribute   
    I believe the original intent was to be able attach "attributes" in the general sense to modules, channels, ports, processes and other "objects", which could be used for unforeseen or unaddressed needs in the future. For instance, if you wanted to add power information to certain modules (e.g. static leakage), and then add some type of processing to analyze power consumption either dynamically or later. This has been used internally at a few companies and I hope the feature will stick around.
    Although, the CCI (Control, Configuration & Inspection) WG (Working Group) of Accellera may argue their "configuration" solution may better address these ideas. [Personally, I have not seen the current CCI solution to work on all platforms yet (implementation needs more work) and the documentation needs more work. I think there are some issues with the version of SystemC and C++ compiler features.] You download/install/test CCI from https://accellera.org/downloads/standards/systemc .
  14. Like
    David Black got a reaction from maehne in SC_CTHREAD slows down simulation   
    You are missing at minimum a single wait() in the infinite loop. SystemC is an event driven simulator and as such concurrency is modeled using co-operative multi-tasking. An infinite loop is an infinite loop. No pre-emption.
  15. Thanks
    David Black got a reaction from juan in SYNTHESIZABLE SystemC   
    sc_core::sc_signal<sc_dt::sc_bv<32> > register[32]; ... SC_METHOD(prc_assign_rf_reg); for(int i=0;i<32;++i) { sensitive << register[i]; } Above should work from a simulation point of view, but probably fails the synthesizable test. Tools might support it.
    Unfortunately, despite the existence of a Synthesizable subset standard, you are really at the mercy of each implementation vendor since they usually vary from the standard in various ways. The standard simply provides a starting point they attempt to match, but then add their own extensions and/or exceptions. RTFM.
    If they ever get around to doing modern C++, they could easily enough implement C++11's std::array container, which is conceptually very synthesizable. Then you could possibly even do:
    #if __cplusplus < 201103L #error Requires C++11 or better #endif #include<array> std::array<sc_core::sc_signal<sc_dt::sc_bv<32>>,32> register; ... SC_METHOD(prc_assign_rf_reg); for(const auto& reg: register) sensitive << reg; // or possibly with changes to synthesizability rules sensitive << register;  
  16. Like
    David Black got a reaction from Ali in Is SystemC-Verification (SCV) useful for analog circuits(SystemC-AMS) ?   
    No. For analog, SCV has not solid application.
  17. Like
    David Black got a reaction from Nitin_S in TLM 2.0 Temporal Decoupling / b_transport delay parameter   
    In LT with Temporal Delay, the initiators maintain a local variable (sometimes with the aid of the Quantum Keeper) that represents time. Although time is not as important, we don't want to throw it completely away. So each initiator keeps a variable that represents how far ahead of the simulator's notion of time it has progressed. You can represent execution of instructions by simply adding a time value to that variable. Targets want to know the current simulated (not simulator) time so they can respond appropriately. For example, a timer definitely needs a notion of time in order to timeout. So initiators pass their local notion of the "current time" to the target. If a target wants to represent the notion of a time change, it can add to that delay, which will be reflected in the initiator since the b_transport call passes it by reference.
    LT models don't completely avoid sc_core::wait(), but they do try to minimize it because context switches affect performance. Adding to a local variable doesn't have as much of a hit.
  18. Like
    David Black got a reaction from swami-cst in sc::bigunit loading from string adds leading 'F's   
    You specified a signed number which was converted to unsigned under rules of twos complement. Change “0x to “0xus and you will obtain desired results. See section 7.3 String literals on page 199 of IEEE-1666-2011 for more information. 
  19. Like
    David Black got a reaction from Padma vathi 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.
  20. Like
    David Black reacted to Eyck in How to trace std::list<int> with sc_trace? [solved]   
    Your sc_trace function is a member function of the TraceList class and cannot be called like the sc_trace functions coming with the SystemC reference implementation. Those are free functions in the sc_core namespace.
    Moreover your sc_trace implementation is non-static so it cannot be used without a TraceList object. You need to move the function out of the class scope.
    Basically this is a valid approach to setup complex types. But under performance considerations I would suggest to use a different container. Best choices are std::vector or std::dqueue. And if you are using C++ 11 I would replace the while loop with a range based loop, something like:
    for(auto& val: var.lst) { // use namespace, compiler otherwise chooses wrong function sc_core::sc_trace(tf, val, nm + std::to_string(pos++)); }  
  21. Like
    David Black got a reaction from ArjunMadhudi in serial transmission   
    [I assume that when you say "TLM", you mean SystemC TLM 2.0.]
    You need to understand the difference between modeling styles. TLM is precisely about not modeling at the level of RTL. The SystemC TLM 2.0 also has two different modeling styles: Loosely Timed (LT) and Approximately Timed (AT). Let's look at each using a specific case. Suppose you are modeling two UARTs operating at 9600 baud (bits per second) with 8-bits, no parity, and 1 stop bit  to transfer the message "Hello World\n". This configuration results in 960 characters per second (1.042 ms/char), which is quite slow, so probably you would be transmitting/receiving characters slowly enough that most systems would either process them one at a time or provide a FIFO (e.g. 16 bytes) and only process empty/full events. There is one more question to answer though. Consider the diagram below. The connections between sender to UART and UART to receiver are clearly memory mapped for most systems. So there is no question of modeling. The connection UART to UART is not memory mapped, which means you need to create a custom protocol. Furthermore, for TLM, it actually requires to connections since communication can be invoked bi-directionally (for a full UART). You need to decide what is important to model. For a high level model and efficiency, I would either transfer as much data as I could. It might even make sense to use TLM 1.0 rather than TLM 2.0. Do you have the requirement to inject errors?

    For my example, you would configure the transmitter, and then transfer a burst of  12 characters into the transmit FIFO on one end of the transfer and generate an empty FIFO interrupt at 12.5 ms later. The receiver side would be similar. What about the UART/UART transaction? An efficient approach might be as follows:
    Create a required extension that carries the transmit configuration information (baud rate, bits, parity, etc.) Use TLM_WRITE_COMMAND because all transactions over this socket pair are initiated from the sender. The second pair in the opposite direction would do the same thing. Check and insist that the address always be 0 and the streaming width is 1. Byte enables would be illegal. Check that the configuration matches before accepting data. Place all received data into an unbounded queue and then indicate the size allowed by the hardware model. Send interrupts using the sc_signal when the received queue goes non-empty. Consider the error situation when the timing indicates characters would be lost due to FIFO full and timing of characters. You will have to decide how to deal with interrupts received in your thread process. Notice that I do not model at the bit level. If you wish to add bit-level error injection, then inject errors at the point of transmission.
     
  22. Like
    David Black got a reaction from chandan in The difference between run_phase and main_phase in uvm_component   
    Actually, you can start a sequence in any phase. It is more important to understand the domain/scheduling relationships between the task based (i.e. runtime) phases. UVM undergoes a number of pre-simulation phases (build, connect, end_of_elaboration, start_of_simulation) that are all implemented with functions. Once those are completed, the task based phases begin. The standard includes two schedules. One is simply the run_phase, which starts executing at time zero and continues until all components have dropped their objections within the run_phase. The other schedule contains twelve phases that execute parallel to the run phase. They are: pre_reset, reset, post_reset, pre_config, config, post_config, pre_main, main, post_main, pre_shutdown, shutdown, and post_shutdown. They execute in sequence. Every component has the opportunity to define or not define tasks to execute these phases. A phase starts only when all components in the previous phase have dropped their objections. A phase continues to execute until all components have dropped their objections in the current phase.
     
    Many companies use the run_phase for everything because there are some interesting issues to consider when crossing phase boundaries. In some respects it may be easier to use uvm_barriers for synchronization. Drivers and monitors (things that touch the hardware) are usally run exclusively in the run_phase, but there is nothing to prevent them also having reset_phase, main_phase, etc...
  23. Like
    David Black got a reaction from asicengineer in The difference between run_phase and main_phase in uvm_component   
    Actually, you can start a sequence in any phase. It is more important to understand the domain/scheduling relationships between the task based (i.e. runtime) phases. UVM undergoes a number of pre-simulation phases (build, connect, end_of_elaboration, start_of_simulation) that are all implemented with functions. Once those are completed, the task based phases begin. The standard includes two schedules. One is simply the run_phase, which starts executing at time zero and continues until all components have dropped their objections within the run_phase. The other schedule contains twelve phases that execute parallel to the run phase. They are: pre_reset, reset, post_reset, pre_config, config, post_config, pre_main, main, post_main, pre_shutdown, shutdown, and post_shutdown. They execute in sequence. Every component has the opportunity to define or not define tasks to execute these phases. A phase starts only when all components in the previous phase have dropped their objections. A phase continues to execute until all components have dropped their objections in the current phase.
     
    Many companies use the run_phase for everything because there are some interesting issues to consider when crossing phase boundaries. In some respects it may be easier to use uvm_barriers for synchronization. Drivers and monitors (things that touch the hardware) are usally run exclusively in the run_phase, but there is nothing to prevent them also having reset_phase, main_phase, etc...
  24. Like
    David Black reacted to Eyck in bind multi ports to other port.   
    Another option would be to use a resolved signal and connect all output ports to it.
    But this is already about techincal implementation options. The question to me is: what would you like to model? Is this the right way to model the intend?
    Best regards
  25. Like
    David Black reacted to Philipp A Hartmann in Static Sensitivity to "AND" of two events   
    Please be aware, that an sc_and_event_list does not imply that the events in the list are triggered at the same time. I would suggest to keep the only the clock sensitivity and act on the triggers in the body of the method instead:
     
    SC_METHOD(func2); sensitive << clk.pos(); dont_initialize(); // ... void func2() { if( nreset.posedge() ) { // nreset went high in this clock cycle // ... } } Alternatively, you can be sensitive to nreset.pos()  and check for clk.posedge() (as a consistency check), if you don't have anything else to do in the body of the method.  With this approach, you might be able to avoid unnecessary triggers of the method.
    Side note to Eyck: There's a small typo in the example above, which should should use "&=" to append to an sc_event_and_list.
    ev_list &= nreset;  
×
×
  • Create New...