Jump to content

David Black

Members
  • Posts

    690
  • Joined

  • Last visited

  • Days Won

    154

Everything posted by David Black

  1. Caution: SystemC Kernel is not thread-safe without taking special precautions. If you call into SystemC from outside the SystemC OS-thread, you may need to create a primitive channel utilizing async_request_update(). If on the other hand you are simply stalling SystemC from within, which is what I think is being stated, then you should be fine with simple std::mutex (not sc_core::sc_mutex which is only for use inside SystemC between SystemC internal "processes").
  2. The error looks like a 64-bit library issue with stdc++.
  3. If you are trying to inject events from received TCP/IP running in parallel OS threads or external OS processes, then you will need to create a primitive channel utilizing sc_core::async_request_update() in order to safely (see note 1) inject events into SystemC. Your only other option is to poll, which is rather inefficient. Also be mindful that the SystemC side performance does not guarantee you will only get one event per delta cycle; therefor, you need to use a queue to receive data. You will also likely need to use an OS mutex (C++11 std::mutex should work fine for this application). Note 1: SystemC is not inherently thread-safe and random injection from outside can corrupt the simulation.
  4. Sorry, but tracing TLM is not directly supported. Recording transactions is supported.
  5. 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.
  6. 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
  7. I would say it is definitely interesting.
  8. 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?
  9. 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; });
  10. 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.
  11. 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
  12. 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.
  13. 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.
  14. 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.
  15. 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; } };
  16. 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>.
  17. 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.
  18. @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.
  19. @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.
  20. @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 11.1.3.1 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.
  21. 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.
  22. 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.
  23. 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
×
×
  • Create New...