Jump to content

Eyck

Members
  • Posts

    356
  • Joined

  • Last visited

  • Days Won

    87

Reputation Activity

  1. Like
    Eyck got a reaction from shubham_v in 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
  2. Like
    Eyck got a reaction from DS1701 in 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
  3. Like
    Eyck got a reaction from shubham_v in block_interface between initiator and target   
    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
  4. Thanks
    Eyck got a reaction from shubham_v in 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
  5. Thanks
    Eyck got a reaction from shubham_v in 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
  6. Thanks
    Eyck got a reaction from JorgeAbarca in write different types of data in a custom port   
    You cannot not check typeid() against a string as this is compiler dependend. What you shoudl do is
    void write_out{ if(typeid(T) == typeid(sc_dt::sc_logic){ out.write(SC_LOGIC_Z); }else{ out.write(0); } } } But actually this is more a C++ related question, in my experience Stackoverflow is a good source of help.
    Cheers
  7. Like
    Eyck got a reaction from DS1701 in TLM extension   
    Actually this is done in the desrtuctor of the tlm_generic_payload. This part calls for all extensions the free() function. So if out is handled properly destroyed all extensions are destroyed as well. The other option is to call free_all_extensions() explicitly which also calls free() for all extensions as well as for auto extensions (those might be registered when a memory manager for the generic payload is used, usually in AT style modelling using the non-blocking interfaces).
    HTH
  8. Like
    Eyck got a reaction from DS1701 in sc_uint and unsigned int   
    unsigned int has always the length defined by the underlying platform while sc_uint<> lets you specify the exact bit with of the type. In your case case I would use 'unsigned int' as it is faster and has less overhead.
    Best regards
  9. Like
    Eyck got a reaction from Indunil in runtime error :- Fatal: (F4) assertion failed: iface != 0   
    This means that a port is not bound to an interface. A port is just a kind of a forwarder of an interface. So if none is bound nothing can be forwarded. E.g. if you have a sc_in<bool> it forwards the sc_signal_in_if which allows you to read and wait for events. But there needs to be 'something on the other side' which is usually a signal (implementing the sc_signal_in_if) being bound to the socker.
    But without further information it is hard to provide more help.
    Best regards
  10. Like
    Eyck got a reaction from deeku in runtime error :- Fatal: (F4) assertion failed: iface != 0   
    This means that a port is not bound to an interface. A port is just a kind of a forwarder of an interface. So if none is bound nothing can be forwarded. E.g. if you have a sc_in<bool> it forwards the sc_signal_in_if which allows you to read and wait for events. But there needs to be 'something on the other side' which is usually a signal (implementing the sc_signal_in_if) being bound to the socker.
    But without further information it is hard to provide more help.
    Best regards
  11. Like
    Eyck got a reaction from sHeshmat in Checking ports for power estimations   
    I'm not sure if I get your first question right. Essentially this is a C++ question. But what you could do is a type erase of your (POD) data, use it as a byte array and count the changed bits using XOR (be carefull to you plain data, no classes). Something like:
    struct my_data { int x; long y; }; my_data old_val, new_val; uint8_t* old_data = reinterpret_cast<uint8_t*>(&old_val); uint8_t* new_data = reinterpret_cast<uint8_t*>(&new_val); unsigned toggles=0; for(size_t i=0; i<sizeof(my_data); ++i){ uint8_t diff = *(old_data+i)^*(new_data+i); uint8_t mask=1; for(size_t j=0; j<8; ++j, mask<<=1) if(mask&diff) ++toggles; } Regarding your second question: you transport the data via a signal which implements the signal_in_if. This interface has a value_changed_event()  getter which returns an event firing when the value of the signal changes. Just wait for this event.
  12. Like
    Eyck got a reaction from maehne in Device driver development with the OSCI systemC library.   
    What you can do is build your driver software as a shared library with a main function. In a SC_THREAD you just load the library and execute the main function. Along with this you have to implement a few utility functions (read, write, wait) which interact with the SystemC kernel or your DUT and being used by the main function (and the called functions from there). This is called host based or host compiled simulation (you may check the search engine of your choice for it). With some infrastructure it is even possible to mimic interrupt.
    Another option is to use some instruction set simulator (e.g. QEMU, DBT-RISE-RISCV, or some commercial alternatives) and do you driver development using a virtual prototype...
    Best regards
  13. Like
    Eyck got a reaction from ZEESHAN KHATIB in Phases of AT type model in a system ?   
    BEGIN_REQ/END_REQ and BEGIN_RESP/END_RESP mark time points in the protocol. So in the stanndard implementation you have 2 phases: request and response. Depending on the type of access various data is been transferred: for a read REQ usually carries the addr while RESP carries the data and status while during a write REQ carries addess and data while RESP just carries the status. It is up to the initiator and target to care for consistency of the data in the payload, in most implementations I''ve seen the data is sampled/set at the BEGIN_* time point.
    Best regards
  14. Thanks
    Eyck got a reaction from Roman Popov in TLM transaction tracing   
    Maybe a little bit late but there are socket implementations available which do trace tlm transactions int a SCV database. They can be found at https://github.com/Minres/SystemC-Components/tree/master/incl/scv4tlm and are used e.g. at https://github.com/Minres/SystemC-Components/blob/5f7387ab7e3dfc2ff6a7cac6fbe834ed7ec8ae36/incl/sysc/tlmtarget.h which in turn serve as building blocks in https://github.com/Minres/SystemC-Components-Test/tree/master/examples/simple_system
    The setup given by Kai is put into sysc::tracer where all the tracing setup (VCD & SCV) is impelemted.
    Best regards
    -Eyck
  15. Like
    Eyck got a reaction from DS1701 in simple socket   
    Just looked further: there is a typo in case 1. It should read
    //bind for(int i=0;i<3;i++){ objA->initiator_socket[i]->bind(*(objB->target_socket[i])); } as you use an array of pointers. Again, sc_vector eases your life:
    //Model A sc_core::sc_vector<tlm_utils::simple_initiator_socket_tagged<ModelA>> initiator_socket; ... // Model B sc_core::sc_vector<tlm_utils::simple_target_socket_tagged<ModelB>> target_socket; ... //bind for(int i=0;i<3;i++){ objA->initiator_socket[i].bind(objB->target_socket[i]); } The same applies to case 2:
    //bind objA->initiator_socket1->bind(*(objB->target_socket2)); objA->initiator_socket2->bind(*(objB->target_socket3)); objA->initiator_socket3->bind(*(objB->target_socket1)); Best regards
  16. Like
    Eyck got a reaction from kartikkg in Read in customized structs   
    Where did you check the values of p1 and p2? write() only schedules the values to be written, you will see the actual value in the next delta cycle.
    Best regards
  17. Like
    Eyck got a reaction from David Black in difference between blocking and nonblocking interface   
    Well, the answer is i bit more complex. The main difference is that the standart requires that during the nb_transport call no sc_wait is allowed while in b_transport it si allowed. So any implementation adhereing to the standart guarantees this.
    Let's first look at the non-blockig implementation. tlm_phase do not denote a phase directly rather time -points o the protocol. Actually you have to phases: request and response which are denote by 2 time points each. So the initiator can indicate a start or end of a phase of a transaction and be sure that the call is not blocked by a call to wait(). So you can model the behavior and timing of a bus transaction in a fairly granular way and do something while the transaction is on-going. You can even have 2 transactions in parallel, one being in the request while the other one is in the response phase (or even more if you have more phases defined). The transaction are pipelined.
    Looking at the b_transport situation is different. The target can delay the transaction by calling wait() until it is ready to respond. During that time no other transaction can be ongoing, the initiator is blocked and cannot react to it.
    Blocking accesses can be used if timing of the communication is not of interest/not modeled (the other scenarion is loosly timed models, but that's a different story). They are easy to implement and easy to use.
    Non-blocking is used if the timing of the communication needs to be modeled in more detail. E.g. this allows to model, simulate and analyse bus contention situations as it allows to attach timing to all phases of a bus transaction lile grant, address phase, data phase.
    I hope this sheds some light
    -Eyck
  18. Like
    Eyck got a reaction from re1418ma in using gtkwave   
    Actually SystemC provided sc_trace(...) functions where you register your signals and variables for tracing. Running the simulation yields a .vcd file which you can open in gtkwave.
    You may have a look into https://github.com/Minres/SystemC-Components-Test/blob/master/examples/transaction_recording/scv_tr_recording_example.cpp
    In sc_main() you will find sc_trace_file *tf = sc_create_vcd_trace_file("my_db");
    sc_trace_file *tf = sc_create_vcd_trace_file("my_db"); This opens the waveform database. At the end you have to call
    sc_close_vcd_trace_file(tf); to properly close the database. 'tf' is a handle to the database, if you follow the code you will see how to trace signals (or variables),
    Best
     
  19. Like
    Eyck got a reaction from maehne in SystemC catching/rethrowing standard exceptions is harmful?   
    Hi,
    I'm not an implementer of the reference simulator but as far as I can judge the re-throw is used to find a more specific type of exception (since sc_elab_and_sim() just uses a catch-all) and uses sc_handle_exception() to convert it into an sc_report so it can be handled by the SystemC reproting system. Actually I agree it would be better to handle it directly in sc_elab_and_sim() but this would duplicate code.
    A side note rgd. debugging: if you use gdb there is a command 'catch throw' which stops execution right at the point where the (original) exception is thrown. This comes pretty handy in such cases.
    Best regards
  20. Like
    Eyck got a reaction from swami-cst in SystemC catching/rethrowing standard exceptions is harmful?   
    Hi,
    I'm not an implementer of the reference simulator but as far as I can judge the re-throw is used to find a more specific type of exception (since sc_elab_and_sim() just uses a catch-all) and uses sc_handle_exception() to convert it into an sc_report so it can be handled by the SystemC reproting system. Actually I agree it would be better to handle it directly in sc_elab_and_sim() but this would duplicate code.
    A side note rgd. debugging: if you use gdb there is a command 'catch throw' which stops execution right at the point where the (original) exception is thrown. This comes pretty handy in such cases.
    Best regards
  21. Like
    Eyck got a reaction from maehne in How to invoke a function/sc_method for two sensitive becomes true   
    Actually this is not going to work  as it is quite unlikely that both events fire at the same delta cycle. So you would write something like
    void do_dff(){ if(enable.read()) q=d; } sc_ctor(){ SC_METHOD(do_dff); sensitive << clk; } The only option to concatenate events is to use sc_core::sc_event_and_list and sc_core::sc_event_or_list but those can only use in dynamic sensitivity (wait() for SC_THREADs and next_trigger() for SC_METHODs).
    Best
  22. Like
    Eyck got a reaction from AmeyaVS in Need understanding of SystemC model use-cases   
    Well, this topic could fill an entire book...
    If you implement a model the first question you should as is: What is the purpose of the model? Which questions should the simulation of the model answer?
    Looking at architectural exploration which goes quite often hand in hand with performance analysis the question is: does my HW/SW split and my HW partitioning satisfy my perfomance requirements (wrt. latency, thru-put, compute.efficiency, power,...). In this case you usually do not need to implement a particular functionality in detail rather something that 'behaves like' in terms of your requirements. E.g. if you need to check that your communication scheme (buses, arbiters, bridges etc.) fulfills the needed band with you use traffic generators but have a fairly accurate bus model, sometimes even at AT. And you need to implement the mechanisms to observer and extract the needed performance indicators to allow the analysis
    For software development the requirements are different. Here the maximum simulation speed is required so whereever possible you take short cuts. Bus transaction are not modelled anymore rather DMI is used (of course if functionality allows to do so e.g. when reading from/writing to a memory) and the entire model may run in LT mode which allowes parts to independently advance in time. Peripheral units may be modelled register-accurate but with out real functionality, i.e. a system control unit does not follow the needed scheme if changing e PLL frequency and alike.
    This might give you some high-level clue. There are many more things to it but all of them depend on the answer to the initial questions.
    Maybe the DCVon Europe 2017 tutorial on virtiual protorypes might provide a few more answers. You may find a PDF version of it at the MINRES site in the Publications and Papers section or at https://minres.com/downloads/VP_Tutorial_DVCon-2017.pdf as well as at the DVCon Europe website https://dvcon-europe.org/conference/history
    Best regards
    -Eyck
  23. Like
    Eyck got a reaction from David Black in Need understanding of SystemC model use-cases   
    Well, this topic could fill an entire book...
    If you implement a model the first question you should as is: What is the purpose of the model? Which questions should the simulation of the model answer?
    Looking at architectural exploration which goes quite often hand in hand with performance analysis the question is: does my HW/SW split and my HW partitioning satisfy my perfomance requirements (wrt. latency, thru-put, compute.efficiency, power,...). In this case you usually do not need to implement a particular functionality in detail rather something that 'behaves like' in terms of your requirements. E.g. if you need to check that your communication scheme (buses, arbiters, bridges etc.) fulfills the needed band with you use traffic generators but have a fairly accurate bus model, sometimes even at AT. And you need to implement the mechanisms to observer and extract the needed performance indicators to allow the analysis
    For software development the requirements are different. Here the maximum simulation speed is required so whereever possible you take short cuts. Bus transaction are not modelled anymore rather DMI is used (of course if functionality allows to do so e.g. when reading from/writing to a memory) and the entire model may run in LT mode which allowes parts to independently advance in time. Peripheral units may be modelled register-accurate but with out real functionality, i.e. a system control unit does not follow the needed scheme if changing e PLL frequency and alike.
    This might give you some high-level clue. There are many more things to it but all of them depend on the answer to the initial questions.
    Maybe the DCVon Europe 2017 tutorial on virtiual protorypes might provide a few more answers. You may find a PDF version of it at the MINRES site in the Publications and Papers section or at https://minres.com/downloads/VP_Tutorial_DVCon-2017.pdf as well as at the DVCon Europe website https://dvcon-europe.org/conference/history
    Best regards
    -Eyck
  24. Like
    Eyck got a reaction from maehne in Need understanding of SystemC model use-cases   
    Well, this topic could fill an entire book...
    If you implement a model the first question you should as is: What is the purpose of the model? Which questions should the simulation of the model answer?
    Looking at architectural exploration which goes quite often hand in hand with performance analysis the question is: does my HW/SW split and my HW partitioning satisfy my perfomance requirements (wrt. latency, thru-put, compute.efficiency, power,...). In this case you usually do not need to implement a particular functionality in detail rather something that 'behaves like' in terms of your requirements. E.g. if you need to check that your communication scheme (buses, arbiters, bridges etc.) fulfills the needed band with you use traffic generators but have a fairly accurate bus model, sometimes even at AT. And you need to implement the mechanisms to observer and extract the needed performance indicators to allow the analysis
    For software development the requirements are different. Here the maximum simulation speed is required so whereever possible you take short cuts. Bus transaction are not modelled anymore rather DMI is used (of course if functionality allows to do so e.g. when reading from/writing to a memory) and the entire model may run in LT mode which allowes parts to independently advance in time. Peripheral units may be modelled register-accurate but with out real functionality, i.e. a system control unit does not follow the needed scheme if changing e PLL frequency and alike.
    This might give you some high-level clue. There are many more things to it but all of them depend on the answer to the initial questions.
    Maybe the DCVon Europe 2017 tutorial on virtiual protorypes might provide a few more answers. You may find a PDF version of it at the MINRES site in the Publications and Papers section or at https://minres.com/downloads/VP_Tutorial_DVCon-2017.pdf as well as at the DVCon Europe website https://dvcon-europe.org/conference/history
    Best regards
    -Eyck
  25. Like
    Eyck got a reaction from veeresh k in C++ class object bringing into systemC Hierarchy   
    Hi Aarthi,
    if you just need to get the currently active module when hitting a breakpoint in you C++ code you might use the following command (assuming you use gdb):
    x sc_core::sc_get_current_process_b()->get_parent()->name() (see also here: https://stackoverflow.com/questions/18078226/how-to-get-sc-module-name-of-the-current-running-module#18123785)
    What it does is it calles the SystemC kernel function sc_get_current_process_b() which returns a pointer to sc_process_b (the base class of of sc_method_process and sc_thread_process). Inheriting from sc_obejt it also has a name() method so you could also do
    x sc_core::sc_get_current_process_b()->name() which just returns the full hierarchical name of the process.
    HTH
    -Eyck
×
×
  • Create New...