Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by Eyck

  1. Eyck

    bind multi ports to other port.

    Another option would be to use a resolved signal and connect all output ports to it. But this is already about techincal implementation options. The question to me is: what would you like to model? Is this the right way to model the intend? Best regards
  2. Well, your interrpt is set in a SC_THREAD or SC_METHOD and these are active when the ISS thread sleeps. In that sense the sensing is immediate when the ISS thread wakes up. But since the ISS thread is ahead of the SystemC simulation when the irq is activated in SystemC there is no way to have an immediate sensing. This is the accuracy you give up to gain simulation speed: the delay until the ISS acts on an external event is determined by the quantum. On solution could be to use a dynamic quantum which changes in the course of the simulation: you start with a large quantum until you reach a certain point in simulation (e.g. until you booted the system) and then you lower the quantum to get more accuracy.
  3. Each type of extension has an automatically assigned ordinal number which is available per extension as ID in the base class tlm_extension. So in your case you have 2 tlm_extensions defined somewhere. Under the hood this ID is used as an index into the m_extension array of the tlm::generic_payload. Best
  4. Eyck

    Static Sensitivity to "AND" of two events

    @Philipp A Hartmann you are right, '|=' would imply and or list.
  5. @Khushi This is not a good solution since this way you enforce a quantum from a component maybe deep in the hierarchy. This sacrifies compatibility and makes reuse pretty difficult. You should follow the guidlines outlined by David.
  6. Eyck

    Static Sensitivity to "AND" of two events

    You would want to use an sc_event_and_list. See IEEE1666 section 5.8. As its intended use is with next_trigger() and wait() you would need to move the sensitivity into your method. So the constructor part becomes SC_METHOD(func2); and func2 should something like (snippet of your module): sc_core::sc_event_and_list ev_list; void end_of_elaboration(){ ev_list |= clk.posedge_event(); ev_list |= nreset; } void func2(){ next_trigger(ev_list); // your code here ... }
  7. Well, the global quantum is as the name says global. So there is only one variable and it should be set at on central point. In many cases this is sc_main but it might also be some configuration unit. This depends on the requirement and implementation. I would refrain to set it in the initiators as then you dont know which one is the last one to set the quantum esp.if they want to set it to different values. Usually the leads to hard-to-debug problems. Best regards
  8. Actually in my experience mixing various C++ standard levels is not advisable as they imply changes in libstdc++ which may lead to all sort of issues. So my general recomendation is to have the same setting in all libraries. Hence this general apporach. And conan_set_std() conan_set_std() will set the standard level to C++14 in this example.
  9. Actually you need to add the library dirs to your cmake target liek this: link_directories(${CONAN_LIB_DIRS_GTEST}) add_executable(TransactionExample main.cpp) target_link_libraries(TransactionExample ${CONAN_LIBS}) Since the CMake setup in the example project is not 'conan only' things are a bit different (it can also be used with SYSTEMC_HOME env variable). If you rely entirely on conan you could simplify the CMakeLists.txt to cmake_minimum_required(VERSION 3.3) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include(Conan) project(TransactionExample CXX) setup_conan() conan_set_std() conan_global_flags() add_executable(TransactionExample main.cpp) conan_target_link_libraries(TransactionExample) I updated the README in the Quickstart Project accordingly
  10. You should use SystemCVerification/2.0.1@minres/stable instead of 2.0.0a. As these are binary packages (with source) there are version dependencies. TLM2.0 is part of SystemC so it comes automatically with the SystemC package. Actually I might want to start with: git clone https://github.com/Minres/SystemC-Quickstart cd SystemC-Quickstart/ mkdir build cd build/ cmake .. make This is all you need to start developing based on SystemC. More details to be found in the README.md
  11. Hmm, not sure if I understand you correctly. Your C++ code has an entry function, right? If you just call this entry function from a SC_THREAD it runs in a thread context and can call wait to let other parts of the simulation continue. The other option you have is to run your C++ code in a second (OS) thread, e.g. a std::thread. This allows to use the usual syncronization primitives of the OS like mutexes and alike. BR
  12. There are several ways to do this: you might use a different way to carry signals which are more TLM like. One option would be to use tlm_signal. The other common option is if your CPU writes into the register of your interrupt controller via TLM it carries the delay which is essentially the offset of the CPU local time to the SystemC kernel time. If you here just break the quantum and call a wait() so that the SystemC kernel can sync up and the signal change propagates you should be fine.
  13. Eyck

    Modeling large memories in System-C

    The sparse array of the memory I mentioned is implemented as paged memory with allocate on write semantics as @swami060. So you might have a look into this as example
  14. Did you build the scv library? Just referencing the headers is not enough. Actually this should do the trick, if not posting the log might help. Moreover you should change your toplevel. your initiator socket connects to the target socket of the recorder, the intiator socket of the recorder connects to the your target socket. scv_startup(); scv_tr_text_init(); scv_tr_db db("my_db.txlog"); scv_tr_db::set_default_db(&db); top t ("dut"); scv4tlm::tlm2_recorder_module<> inst_mod("rec_module"); init->i_socket(inst_mod.target); inst_mod.initiator(targ->t_socket); sc_start(200,SC_NS);
  15. Eyck

    Modeling large memories in System-C

    The is a memory using a sparse array as backing storage and having a tlm2.0 socket which you might want to use. You will find it at https://git.minres.com/SystemC/SystemC-Components/src/branch/master/incl/scc/memory.h.
  16. Hi Hai Dang, wait() takes a token from the semaphore (and waits for it if there is none) and post() puts a token back. In fact it decrements a counter until zero upon wait() and increments it upon post(), the initial value is given as constructor argument. Instantiating the semaphore with an initial value of one has the behavior of a mutex. So just posting the semaphore only increments it and obviously your program runs. If the code above fails then I would assume your initiators or targets have an issue since this is a proven pattern. Does the target call wait or does it just return an annotated time? How did you setup your initiators? BR
  17. If you can identify the condition of switching off clocks and the process being sensitive (and consuming the simulation time) you can enabel/disable the thread or method using the sc_process_handle as described here: BR
  18. You may use the tlm recorder of the SystemC components lib (SCC, esp. here: https://git.minres.com/SystemC/SystemC-Components/src/branch/master/incl/scv4tlm). This writes into a text database (the SCV default). You can view this e.g. with Impulse (https://toem.de/index.php/projects/impulse) or SCViewer (https://git.minres.com/VP-Tools/SCViewer, binaries here: https://github.com/Minres/SCViewer/releases). Basically you instantiate scc::tlm2_recorder_module and connect it's initiator and target sockets. to your target and initiator socket. Your sc_main should then look like: int sc_main(int argc, char *argv[]) { scv_startup(); scv_tr_text_init(); scv_tr_db db("my_db.txlog"); scv_tr_db::set_default_db(&db); dut_mod dut("dut"); sc_start(1.0, SC_MS); return 0; } The database is closed upon destruction of the db object. Best regards
  19. I would stick with the two methods where the one calls enable() and disable() for the second mehtod. Why enable()/disable()? The LRM says (section 5.6.6): So with suspend() you still have the sensitivity handling in place while with disable() you don't. Moreover if there is an event while being supended it becomes immediately runnable. So falling edge of reset implies a process activation although there is not rising edge on clock. An implementation could look like: // class declaration: sc_core::sc_process_handle process_output_hndl; // constructor body: SC_METHOD(process_output); sensitive<<clk.pos()<<reset; SC_METHOD(process_output_enable); sensitive<<enable; // function implementation: void fir::process_output() { if(!process_output_hndl.valid()) process_output_hndl = sc_process_handle(sc_get_current_process_handle()); if (reset.read() == 0) { //reset sequence } else { //normal operation } } void fir::process_output_enable() { if (enable.read()) { if(process_output_hndl.valid()) process_output_hndl.enable(); } else { if(process_output_hndl.valid()) process_output_hndl.disable(); } } BR
  20. Hi, from the snippets I see it does not get clear what you are doing. Basically you would Instantiate the ordered_semphore scc:ordered_semaphore sem{1} and in b_transport() you wait() and post(): void Bus::b_transport(int id, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) { sc_dt::uint64 global_addr = trans.get_address(); int slaveid = this->address_to_slaveid(global_addr); if(slaveid < 0) { trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE); std::cout << "\e[1;31m" << this->name() << ": " << "\e[1;31mInvalid address " << global_addr << std::endl; return; } sc_dt::uint64 slave_addr = global_addr - this->starts[slaveid]; trans.set_address(slave_addr); // make sure we are allowed to get access sem.wait(); this->initiator_socket[slaveid]->b_transport(trans, delay); // return back the token so that others can access sem.post(); trans.set_address(global_addr); } BR
  21. Eyck

    timer with systemC

    But what is the issue with running the simulation for 3*period? Best regards
  22. From the snippets you provide it looks ok. Assuming that bus_mutex is a sc_mutex this is you problem. sc_mutex does not do arbitration. It selects randomly which waiting thread to grant the lock (actually the next activated process base on an even notification) . But what you expect is arbitration. So either you write an arbiter or you may use and ordered semaphore with an initial counter value of 1. You may find an implementation here: https://git.minres.com/SystemC/SystemC-Components/src/branch/master/incl/scc/ordered_semaphore.h The semaphore grant access based on a queue. So eventually you get first-comes-first-serves (FCFS) behavior, but all requestors have equal priority. Best regards
  23. 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
  24. 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
  25. Well, actually a scenaron having a sc_main linking various shared objects which in turn reference the SystemC library as shared object works. So I suspect you build process is somehow wrong. To help you here you would need to post the your build log or at least the linker calls for your user and util liba and for your executable. Best regards