Jump to content

David Black

  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by David Black

  1. David Black

    tracing waveforms in tlm

    Sorry, but tracing TLM is not directly supported. Recording transactions is supported.
  2. David Black

    reading part of input port

    Sorry, but this is simply not possible in the convenient manner of Verilog. Reason: SystemC is not about RTL. If you need a few bits, then read all of them and mask off the ones you want.
  3. One way to disable the clock is to completely replace it with a model that does nothing. I presented a concept called no_clock at NASCUG a few years back demonstrating an approach. You can find the code on github: https://github.com/dcblack/no_clock with a link to the presentation. You could even replace the declaration of sc_clock directly with a conditional macro test: #ifdef USE_NO_CLOCK #include "no_clock.h" no_clock myclock{ "myclock", 10.0, SC_NS }; #else sc_core::sc_clock myclock{ "myclock", 10.0, SC_NS }; #endif
  4. David Black

    Systemc performance

    I would say it is definitely interesting.
  5. David Black

    Systemc performance

    Perhaps you would like to share your code for measurements via GitHub? Measuring performance can be tricky to say the least. How you compile (compiler, version, SystemC version) and what you measure can really change results. Probably helps to specify your computer's specifications (Processor, RAM, cache, OS version) too. Processor (vendor, version) L1 cache size L2 cache size L3 cache size RAM OS (name, version) Compiler (name, version) Compiler switches (--std, -O) SystemC version SystemC installation switches How time is measured and from what point (e.g. start_of_simulation to end_of_simulation) Memory consumption information if possible This will help to make meaningful statements about the measurements and allow others to reproduce/verify your results. It is also important to understand how these results should be interpreted (taken advantage of) and compared. As with respect to TLM, it will get a lot more challenging. For example, what style of coding: Loosely Timed, Approximately Timed. Are sc_clock's involved?
  6. David Black

    Simple program problem

    Your code is operating correctly; however, you are displaying the results at the wrong time. This is because the write() method of sc_signal is not the same as a simple store operation. In normal programming, you expect that if you do: variable = 5; Then immediately after storing the value into your variable, the variable will contain the value. You might then assume that the write() of sc_signal is the same. It is not. It takes a small amount of time for the value to be stored. The amount of time is tiny and is refered to as a "delta delay" time. You can cause your program to wait a delta cycle before displaying the result, but it is slightly more complicated because you are using an SC_METHOD style process instead of the SC_THREAD style process. If you are using C++11 you can replace your cout line with this to see correct answer: sc_spawn( [&]{ wait( SC_ZERO_TIME ); ///< wait one delta-cycle delay cout << "@" << sc_time_stamp() <<"(" << sc_delta_count() << ")" << " || in1:" << in1.read() << " + in2:" << in2.read() << "= val:" << out.read() << endl; });
  7. David Black

    is_inf() usage for sc_dt::scfx_ieee_float

    This is a C++ question. SystemC is simply a library under C++. Floating point (double & float) are part of C++. There are some implementation bits with IEEE floating point in the current proof of concept source; however, this is not documented nor supported in the official standard presently. Whether or not the is_inf works as defined you could ascertain by examining the source code if you like, but really should not count on it. If you have questions about fixed point types, those are addressed in the standard. Please redirect your question to a C++ forum on the topic of floating point. Here is a link <http://www.cplusplus.com/reference/limits/numeric_limits/> of related interest.
  8. Not directly, but you could create two knobs and use them in a constraint. +uvm_set_config.int=*,minsize,100 +uvm_set_config_int,*,max_size,500 then internally class MySeq extends uvm_sequence #(MyTrans); `uvm_object_utils(MySeq) rand int var_size; rand int min_size, max_size; constraint Size { min_size <= var_size; var_size <= max_size; } .... endclass: MySeq
  9. David Black

    using clocks in tlm

    Yes, you can supply clocks to TLM, but this is a very bad idea in general. Clocks will slow down your simulations There are many ways to insert clocks: ports, local instances, global references. The best b_transport implementations find ways to avoid calling wait. More precisely, we attempt to reduce context switching to a minimum and its associated overhead.
  10. David Black


    TLM does have a response status, but that is intended to catch modeling failures rather than modeled failures. So if you consider your case a modeling error, which seems unreasonable to me on the surface, then you should either set the error response to something like a generic error or issue SC_REPORT_ERROR. In any event, do not set both. If this is a modeled error, then you are left to your own devices. See section 14.17 of IEEE-1666-2011 for details.
  11. Let's move this to EDA playground... https://www.edaplayground.com/x/55Sj Doesn't compile. You can COPY into your own playground and fix the compile issues. Then I can look at it if you provide me with the URI.
  12. David Black

    system c,tlm & system verilog interfaces

    The term 'interface' (and for that matter 'virtual') is used in somewhat different ways in SystemVerilog than in SystemC. TLM is simply and library built on SystemC that has some well understood standard SystemC interfaces. Fundamentally, the concept of direction as used in hardware (and hence Verilog) does not translate to SystemC particularly well. In fact, it is somewhat annoying that we have the sc_in<T>, sc_out<T> ports in SystemC because it confuses most folks. It is best in SystemC to think like a C++ programmer. The way that SystemC views "input" and "output" is by observing data flow semantics of function calls. If I have a function with the signature put(int value), then I expect I am moving data from the caller to the callee. SystemC views the concept of interface in the same manner as other object oriented (OO) programming languages do. An OO interface class is simply an abstract class that exclusively contains pure virtual methods. SystemVerilog as of 2012 also has this concept in the manner of 'interace class', but this was added later. Thus SystemVerilog uses the keyword 'interface' in three completely different manners: interface blocks provide a wrapper around signals as a method of bundling signals hence the syntax: interface Bus( input clock ); logic[7:0] address, data; logic rw; modport cpu_mp( output address, rw, inout data ); modport mem_mp( input address, rw, inout data ); clocking cb @(posedge clock); input address, data, rw; endclocking modport verif_if; endinterface Note: semantically an interface is somewhat of a super module because it may contain initial, always, assign and hierarchy. SystemVerilog's virtual interface is simply references to instances of interface blocks to be used inside classes. SystemVerilog interface classes are more like C++ interface class Print_if; pure virtual function void print( string message ); endclass class A implements Print_if; function void print( string message ); $info("%s", message ); endfunction endclass By contrast C++ would use: class Print_if { virtual void print( std::string message ) = 0; }; class A : Print_if { void print( std::string message ) { std::cout << message << std::endl; } };
  13. David Black

    How to Method work with event?

    Notify (either case) is non-blocking, so your call to notify followed by initialize will happen. Then after you return, the notified element(s) may execute. Notify() implies execution will be in the same delta-cycle; whereas, notify(SC_ZERO_TIME) postpones to the next one and allows other processes in the current delta-cycle to complete. Take a look at <https://github.com/dcblack/SystemC-Engine/blob/master/Engine_v2.4.pdf>.
  14. We would need to see some code.
  15. David Black

    Connecting two Bi-directional ports

    sc_signal is not really a good channel for bi-directional signaling since by design it is intended for single driver (writer) multiple reader use. You should use sc_signal_rv<T> or sc_signal_resolved for multiple drivers so that contention can be properly modeled.
  16. David Black

    sensitivity list

    @TRANG you are correct re. 2.3.1 not having a built-in solution; however, you can manage it yourself prior to 2.3.2 by creating flags associated with the events and clearing them in the following delta cycle yourself. In other words, you can implement the same code as 2.3.2 with a bit of effort.
  17. @shubham_v as a course top-level description, you have the correct general idea, but there are many subtleties: b_transport() can block using a call to wait( args... ); although, models that do not block are desirable from a performance perspective. b_transport() executes in the simulation context of the caller. Anything requiring the SystemC kernel management (e.g. wait) imposes the requirement that b_transport() was invoked in the context of a SystemC SC_THREAD. Simulated time conceptually may be decoupled from the SystemC kernel's notion of time using a temporal offset (when 2nd argument of the b_transport call is non-zero). Sockets are not required; however, they solve a number of problems. TLM 2.0 Base Protocol compliant target models must support both blocking and non-blocking interfaces. This is one reason the convenience simple target sockets are so useful (automatic conversion provided may be suitable for some models). Extensions and custom protocols may have important consequences that need to be considered.
  18. David Black

    Timing in TLM

    @Eyck I would point out that Timing Annotation is not limited to Loosely-Timed (LT) modeling, but can also be applied to Approximately-Timed (AT) models (see section 11.1 of IEEE-1666-2011); however, there is an important difference. LT timing annotation describes temporal decoupling as you explained. AT timing annotation is a way of indicating where a phase applies. This has some odd implications that are not immediately obvious. For instance, I can start an nb_transport_fw transaction with a non-zero annotated delay: tlm_phase phase { BEGIN_REQ }; sc_time time { 50_ns }; auto status = nb_transport_fw( payload, phase, time ); ///< begin transaction 50 ns in the future // Note that ns_transport_fw may increase the time (same as b_transport); however, it may not decrease the time. Section describes this in detail. Why would this be done? Perhaps the initiator knows wants to dispatch a transaction and doesn't want to wait around to its initiation. I cannot immediately think of why the returned value might change, but it is legal. The main rule about time in SystemC requires that time never goes backward. No playing Dr. Who.
  19. At first glance, you can call b_transport from C++, but it must be C++ that is inside a SystemC process during simulation phase if the b_transport call invokes sc_core::wait(). You can read the details in the IEEE-1666-2011 specification. Or perhaps you should signup for the Doulos SystemC TLM-2.0 course and get expert hands-on training. Fundamentally, b_transport is a simple function call; however, it may use SystemC semantics to accomplish its work. Hence you should also be knowledgable on SystemC SC_THREADs (may not be used in SC_METHODs). Technically, you could write a b_transport method in the target that did not call sc_core::wait, which is desirable anyhow. If you did this, then you may call from pretty much anywhere; however, SystemC is not thread-safe without special precautions. In any event, there is a lot to learn about the subtleties of the generic payload and extensions too.
  20. Used by synthesis tools. Semantically almost identical to: SC_THREAD( my_thread ); sensitive << clock.pos(); Can be used for cycle modeling, but uses a costly sc_clock.
  21. David Black

    sensitivity list

    You can only specify sensitivity on objects that have events or event finders directly accessible at the time of construction. Normally this means using either a suitable channel, port or explicit event. If you wrap your int's with a channel such as sc_signal<T>, you can do it. Example - https://www.edaplayground.com/x/5vLP
  22. Insert timing delays with sc_core::wait(sc_time) method as called out by either the specification or your best understanding of the likely RTL result. Perhaps you have a function that compresses a JPEG image and experience shows that it take 550 to 568 clocks on an existing design. If you think you can improve the algorithm by 30% then using some statistical approach: #include <systemc> #include <random> sc_core::sc_time const period { 15.0, SC_NS }; //< clock period ... void compress_jpeg( args... ) { unsigned int seed = 1; std::default_random_engine generator { seed }; std::uniform_distribution<int> distribution { 550, 568 }; // Compress jpeg using software methods ... wait( 0.30 * distribution(generator) * period ); } No magic. Accuracy is dependent on your experience and best effort WAG. You may have a more sophisticated time calculation if you think you know more.
  23. Establish a clock period and insert appropriate wait( N*period ) as needed. Cycle accurate is seldom actually required, and cycle approximate is more likely. For instance, if you know that read transactions on a bus take 2 clocks and you make 5 accesses, you can lump that into a single 2 * 5 * period delay.
  24. By using convenience sockets, you can bind each socket to a different function (names will have to be different because the argument types are the same). Thus, twotarg.hpp: // Example code with two target sockets and separate implementations #ifndef TWOTARG_MODULE_HPP #define TWOTARG_MODULE_HPP #ifndef SC_INCLUDE_DYNAMIC_PROCESSES #define SC_INCLUDE_DYNAMIC_PROCESSES #endif #include <tlm> #include <tlm_utils/simple_target_socket.h> #include <cstdint> // Specific symbols for convenience using sc_core::sc_time; using sc_core::sc_event; struct Twotarg_module: sc_core::sc_module { // Type definitions to improve readability using tlm_payload_t = tlm::tlm_generic_payload; using tlm_phase_t = tlm::tlm_phase; using tlm_peq_t = tlm_utils::peq_with_cb_and_phase<Twotarg_module>; // Sockets, ports and exports tlm_utils::simple_target_socket<Twotarg_module> targ_socket_2{ "targ_socket_1" }; tlm_utils::simple_target_socket<Twotarg_module> targ_socket_2{ "targ_socket_2" }; Twotarg_module ///< Constructor ( sc_core::sc_module_name instance_name ); ~Twotarg_module( void ); ///< Destructor (allow PIMPL) virtual const char* kind( void ) const override { return "Twotarg_module"; } private: //---------------------------------------------------------------------------- // Forward interface void b_transport_1( tlm_payload_t& trans, sc_time& offset ); void b_transport_2( tlm_payload_t& trans, sc_time& offset ); private: Twotarg_module( const Twotarg_module& ) = delete; Twotarg_module& operator=( const Twotarg_module& ) = delete; }; #endif /*TWOTARG_MODULE_HPP*/ and twotarg.cpp: //File: twotarg.cpp #include "twotarg.hpp" namespace { const char* const MSGID{"/Doulos Inc./Example/Twotarg"}; } using namespace sc_core; using namespace tlm; using namespace std; //------------------------------------------------------------------------------ Twotarg_module::Twotarg_module // Constructor ( sc_module_name instance_name ) { targ_socket_1.register_b_transport ( this, &Twotarg_module::b_transport_1 ); targ_socket_2.register_b_transport ( this, &Twotarg_module::b_transport_2 ); } //------------------------------------------------------------------------------ // Destructor Twotarg_module::~Twotarg_module( void ) { } //////////////////////////////////////////////////////////////////////////////// // Forward interface //------------------------------------------------------------------------------ void Twotarg_module::b_transport_1 ( tlm_payload_t& trans , sc_time& delay ) { SC_REPORT_INFO_VERB( MSGID, "Not yet implemented", SC_NONE ); ///< replace this line // TO BE SUPPLIED // Check attributes // Perform transaction } //------------------------------------------------------------------------------ void Twotarg_module::b_transport_2 ( tlm_payload_t& trans , sc_time& delay ) { SC_REPORT_INFO_VERB( MSGID, "Not yet implemented", SC_NONE ); ///< replace this line // TO BE SUPPLIED // Check attributes // Perform transaction } /////////////////////////////////////////////////////////////////////////////// // Copyright 2019 by Doulos Inc.. All rights reserved. //END twotarg.cpp