Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Eyck last won the day on November 6

Eyck had the most liked content!

About Eyck

  • Rank
    Advanced Member

Contact Methods

  • Website URL

Profile Information

  • Gender
  • Location
    Munich, Germany

Recent Profile Visitors

456 profile views
  1. Hi, there is no way to do this easily. Actually you have 32 output ports and 1 input port. So you need to connect the output ports to 32 bool signals and the input port to a uint32_t signal as well and make a SC_METHOD sensitive to all of the 32 bool signals. Within that method you iterate over the 32 bool signals and collect them into a 32bit value. BTW, having a POD array of ports is not preferable, I would use 'sc_core::sc_vector<sc_core::sc_out<bool>> out;'. This way you gain several things: the ports are initialized with a name based on the sc_vector instance name and you can bind a vector of ports to a vector of signals with a single line statement. Best regards
  2. Actually in the demo part of the tutorial 'Efficient use of Virtual Prototypes in Hardware/Software Development and Verification' (slides are here) there is exactly such a case show-cased. If you go to https://git.minres.com/DVCon2018/RISCV-VP/src/branch/develop/platform/src/rtl/spi_rtl.cpp you will find a class called rtl which instantiates a verialted RTL, a bus-functional model (BFM) of the TileLink protocol, and a few more converters adapting the RTL signals. The respcetive header can be found at https://git.minres.com/DVCon2018/RISCV-VP/src/branch/develop/platform/incl/sysc/rtl The BFM implements non-blocking transport where the target socket mixin (which is similar to simple_target_socket) does the translation from blocking to non-blocking if needed. This is just since the TIleLink protocol has an explicit request and response channel (similar to AXI). In case of loosely timed model the blocking access with wait() will break your quantum thus syncronizing the time. Having several initiators with different annotated time will then change the order of accesses. You treat speed for accuracy... I hope this gives you some idea. If you have further questions feel free to ask. Best
  3. Eyck

    Read in customized structs

    Well, if this is in the same method then you won't see the update as there is not delta cylce in between. You would see it if you put it in a SC_THREAD and put a wait(SC_ZERO_TIME); between the write() and the read() of p1 and p2
  4. Eyck

    sc_port zero copy?

    There will only be one copy initialized: slave_port, simple_bus_slave_if will not be instantiated (which usually is even not possible as those are in the common case pure virtual classes). N just defines how many interface can be bound at most, 0 means unlimited. Internally there is a vector holding pointers to the simple_bus_slave_if , no copies. The vector will be resized as soon as you bind an interface. Best regards
  5. Eyck

    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
  6. Eyck

    Temporal Decoupling

    Well, the principle is fairly straightforward but the implications are not. The basic idea is: you have part(s) of the design (a domain) running with its own time . A domain not just uses the simulation time rather also holds an (positive) offset to this and manages it; basically the domain might be ahead of the simulation time. If you now have a communication from the domain to the rest of the simulation (e.g. a tlm transaction to a target) the initiator (within the domain) sends the offest along with all of its interactions with the system. As long as the target can answer without synconizing to the simulation (a typical example would be a memory without side effects) it just adds the delays to the annotated time and returns it to the initiator. This allows to execute quite some time within the domain without returning to the simulation kernel. This way context swithes are avoided and the simulation can run fiaster. Actually I'm not aware of a simple example of this. A fairly complete one can be found at a DVCon Europe tutorial (slides at https://www.minres.com/#pub, source at https://git.minres.com/DVCon2018/RISCV-VP) Best regards
  7. Actually, I forgot to answer your quesions, so here we go. Can struct contain signals that flow in different directions? Yes, of course. struct is just a a wrapper which handles datatype as one Can sc_inout<struct T> also map directly to another module with the same sc_inout<struct T>? Well, ports need to connect to signals, there is no way to connect 2 ports directly except you do a hierarchical binding Am I also setting the struct contents correctly? This I answer in the last post.
  8. The problem is that you do not write to the signal carrying the struct (and therefore you do not trigger any event). The SetValid() call implicitly triggers a read (thru the overloaded cast) but you never write back to the signal. Either you change the use of SetValid (and SetReady): { hs data = handshake.read(); SetValid(hs, false); handshake.write(data); } Here the call to wriite() trigges the respective events. The other option is to change SetValid() to take a signal reference and move the code into the function. Best regards
  9. 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
  10. Eyck

    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
  11. 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
  12. Actually you could use some kind of a router or broadcaster between the master and the target(s). Examples of this can be found here: or here: https://git.minres.com/SystemC/SystemC-Components/src/branch/master/incl/scc/router.h where the first one may be better suited as a stand-alone example HTH
  13. Eyck

    event vs software call

    SystemC is an event based simulator as VHDL or (System)Verilog simulators are. So you would write to signals, the update their values and notify an event for that so that processes can react on them. This is described in the SystemC standard, I guess paragraph 4.2 Simulation. The downside of this that each event and the evaluation of processes being triggered by this takes time. As the processes are often fairly short this incures a significant overhead and speed impact. In TL modeling you forward the function calls via a port/export directly to the affected/addressed module/function. This way a lot of context switches can be avoided and the simulation speed is higher. But since the effect (e.g. writing a register) happens immediately care needs to be taken to not introduce feedback loops and a like which won't happen if you use signales and events. To model timing you also carry some delay time with the transaction so that the functions along the call chain and the target function can tell the initiator of the transaction how long the entire transaction took. Best is to have a look into the examples coming with TLM2.0 (now being part of the SystemC distribution), also Doulos has some explanation and examples: https://www.doulos.com/knowhow/systemc/tlm2/ Best regards
  14. Eyck

    The conceptual behavior of sc_in<>

    In the case Roman described you need to declare InputChanged as SC_METHOD. Otherwise your simulation time won't progress. If you want/need to stick with SC_THREAD you would want to write something: void XXX::InputChanged() { while (1) { wait(); // wait for the events in the sensitivity list. For explicit wait use wait(Address.default_event()) cerr << '@' << sc_time_stamp() << ' ' << Address<< endl; } } Best regards
  15. Eyck

    Build error with 2.3.2

    It seems you did not rebuild entirely your design. The symbol sc_core::sc_api_version_2_3_2* ist there to make sure your object files are build against the right systemc library and its headers. In general they are not binary (ABI) compatible between versions. Just switching the link libraries is not enough, you need to do a 'make clean' or whatever you need to tun to remove all build artifacts of your model and rebuild the entire stuff. HTH