Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 05/17/2019 in all areas

  1. 2 points
    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
  2. 1 point
    Philipp A Hartmann

    timer with systemC

    I don't fully understand the question? My snippet above runs all remaining delta cycles at the current time without advancing the time any further. You can wrap your original sc_start call with the loop in a small helper function (e.g. sc_start_including_deltas(...) , if you find yourself copying the snippet too often.
  3. 1 point
    Philipp A Hartmann

    timer with systemC

    You can run the delta cycles at the current time until everything settles: while( sc_pending_activity_at_current_time() ) sc_start( SC_ZERO_TIME );
  4. 1 point
    Eyck

    timer with systemC

    If you run a simulation until a certain point it time the kernel stops before evaluating the processes at this time point. So if you schedule an event for lets say 100ns and simulate for 100ns then the process being sensitive to this event will not be executed (yet). So this is intended behavior. BR
  5. 1 point
    Eyck

    tlm model with clocks & code sample

    My fault, SC_THREAD has a sensitivity list and you can call wait() for the default event. In my experience -and this guided my answer- it is better to have no sensitivity list and wait explicitly for events. When specifying a port in the sensitivity list you need to use an event finder (with .pos()) as the port is not bound yet and hence does not have an event associated. In the thread itself you can use the pos_edge event. So your code shown above is correct. BR
  6. 1 point
    Eyck

    tlm model with clocks & code sample

    You should consult the LRM again.:SC_THREAD does not have a sensitivity list. Moreover you create a memory leak creating the transaction object using new and not deleting it. And your thread ends after 10 accesses. Basically you need to wait for the clock explicitly while (1) { // wait for the rising edge wait(clk.posedge_event()); tlm::tlm_generic_payload trans; // setup the transaction ... // execute the access i_socket->b_transport(*trans, delay); } In your solution the loop in your threads are based on timed delays hence it is not reactiong on your clocks at all. Best regards
  7. 1 point
    Are you only looking at disabling process_output from getting triggered when reset is on? In that case, it is as simple as: void fir::process_output() { if (reset.read() == 0) { //reset sequence next_trigger(reset.pos()); } else if (clk.read() == 0) { //Ignore the trigger just after reset is de-asserted and //sync to next clock edge next_trigger(clk.pos()); // Note: will work even if we comment out line above, due to static sensitivity } else { if(enable.read()) { //normal operation } } } But this may not really get you a significant improvement in itself. You may want to check what is going on in "normal operation" - and see if you can optimize that.
  8. 1 point
    Eyck

    using clocks in tlm

    Adding to Davids answer: you can supply clocks to the modules having initiator and/or target sockets. This is can be done using the usual signal/sc_in/sc_out means as David mentioned. There is also the option to have 'tick-less' clock as David presented many years ago (http://www.nascug.org/events/12th/nascug12_david_black.pdf). This can also be achieved by distributing a signal just carrying the clock period as sc_time and caculating the time points in the modules. This way it is even possible to model timers or PWM (e.g. https://git.minres.com/DBT-RISE/DBT-RISE-RISCV/src/branch/develop/platform/incl/sysc/SiFive/pwm.h). This modelling style avoids the many context switches implied by toggling clocks. All this holds true for LT and PV modelling, if you think about AT modelling the story becomes different. But this is as usual: you trade speed for accuracy. BR
  9. 1 point
    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. 1 point
    David Black

    block_interface

    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. 1 point
    Unfortunately, there is currently no way to obtain the name of the affected signals/variables in this message. You can suppress the warning via: sc_core::sc_report_handler::set_actions(sc_core::SC_ID_TRACING_VCD_DUPLICATE_TIME_, sc_core::SC_DO_NOTHING);
  12. 1 point
    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. 1 point
    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. 1 point
    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.
  15. 1 point
    @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.
  16. 1 point
    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 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.
  17. 1 point
    Philipp A Hartmann

    sensitivity list

    In SystemC 2.3.2 and later, you can use the sc_event::triggered() member function to query, if an event was triggered (and thus might have caused your method to run): if( event1.triggered() ) { std::cout << "event1 got triggered"; } if( event2.triggered() ) { std::cout << "event2 got triggered"; } Please note that if both events were triggered in/for the same evaluation phase, your method might well be run only once.
  18. 1 point
    Eyck

    Timing in TLM

    All of these relate to the concept of loosly-timed simulation. The basic principle behind this is that parts of the design can simulate larger time slices without returning control to the simulation kernel; the run ahead of the rest of the simulation. This is used e.g. for processors and alike as for quite some parts the do not interact with the rest of the design and create (a memory read does not really trigger any action other than returning some data). This way the simulation speed and hence the simulation performance can be drasticalliy improved but you trade performance for accuracy. This domain (or part of the simulation) running ahead of the simulation kernel is temporally decoupled. As such it needs some mechanism to control its local time (the amount it is ahead of the simulation kernel). This is done by the quantum keeper, the quantum is the amount of time the decoupled domain is allowd to be ahead at max. To allow interaction with the rest of the design all interaction need to carry some information what the local time in the dcoupled domain is, this is called timing annotation. This information is needed to either schedule events in the simulation kernel to happen at the correct time or to decide to break the quantum which means the decoupled domain is stopped and control is returned to the simulation kern until it reaches the local time of the decoupled domain, they are in sync then. HTH
  19. 1 point
    Well, to me it is always helpful to think about sockets as a proxy or sophisticated function forwarder (in some sense similar lto sc_port). So you call b_transport on the initiator side and the socket forwards the call to the target and invokes b_transport there. HTH
  20. 1 point
    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.
  21. 1 point
    Eyck

    why is,what is, and how is tlm used ?

    Well, in TLM1.0 there is even a tlm::tlm_fifo channel which provides something similar what you use. The sockets defined in TLM2.0 are more geared towards memory-mapped busses and provide facilities to model for speed (DMI, loosly-timed blocking interfaces) or accurracy (approximately-timed non-blocking interfaces). To achive this with pure SystemC provided classes takes some effort and it ends to be proprietary... BR -Eyck
  22. 1 point
    From SystemC standard: SystemC requires that you add sc_module_name as a parameter to module constructors, like this: MULT(sc_module_name, int var_a, int var_b); MULT(sc_module_name); This is a hack that allows SystemC kernel to track lifetime of constructor.
  23. 1 point
    Eyck

    why is,what is, and how is tlm used ?

    Hi, TLM2.0 is used to model bus-like transactions as you have in APB, AHB, AXI or alike. It abstracts those transactions in to e.g. read and write with some attribites (liek protection and alike). This saves some from dealing with bit wiggling and, as you have less events, improves simulation performance. If you use in your scenarion fifo between your producer and consumer you are already using TLM as you abstract the transmission of more or less complex data as a write into the fifo. If you keep this style in your design you do transaction level modeling (TLM). If you are asking if it makes sense to use the TLM2.0 standard is a different question and depends on what aspects of your design do you need to represent in your model. If you have some kind bus structure (e.g. some micro processor or controller) then it is highly advisable to use TLM2.0. In that case your producer calls the transfer functions of the initiator socket and your consumer needs to react on the callbacks of the target socket. Actually this does not relate to your file structure but as a starting poitn I would suggest to study the lt example comign with the SysetmC distribution. You will find it under examples/tlm/lt, it contains 2 initiator_top mdouels, a bus and 2 lt_target modules. if you reduce the thing to just one initiator_top and one lt_target being directly connected you have your producer/consumer scenario. HTH
  24. 1 point
    Most likely you have C++98 in CMake cache. You don't need to modify SystemC CMakeLists, just set c++ standard from command line. Check here for detailed instructions https://stackoverflow.com/questions/46875731/setting-up-a-systemc-project-with-cmake-undefined-reference-to-sc-core
  25. 1 point
    apfitch

    loosely timed vs accurate timed ??

    In a loosely timed model you only have two timing points - start of transaction, end of transaction. In an approximately timed model using the base protocol, you have four timing points - start request, end request, start response, end response - hence you can model overlapped (pipelined) transactions, because you can start a new request before you have the response to the previous request. In my example above, you would only be able to send a new transaction every 75 ns using loosely timed, so the model of the timing of the transaction is less accurate - in the loosely timed model I can send a new transaction every 75 ns, in approximately timed every 50 ns using that example. If you do not use overlapped transactions, then you could just use begin request and end response, so as you say the non-blocking (approximately timed) and blocking (loosely timed) models would give the same results, regards Alan
×