Jump to content

Eyck

Members
  • Content Count

    209
  • Joined

  • Last visited

  • Days Won

    61

Reputation Activity

  1. Thanks
    Eyck got a reaction from zafir in SystemC communication with Linux kernel Module   
    No, you cannot run the SystemC simulator kernel as a Linux kernel module for sevberal reasons:
    SystemC requires quite some libraries (libc, libqt, ...) that are not available in kernel space You would taint the kernel and open up a security hole large as a gate. You would alos risk the system integrity. SystemC is simply not meant for such things. A proper design would make a distinction between (as little as possibel) code to run in kernel space providing interfaces (devices or shared memory) to interact with and a userspace application which could be the SystemC simulation e.g. running as a daemon. Even linux kernel hackers move everything into this direction...
    Yes, the simulation is a simple userspace process being constraint by the OS permissions. So it can use all resources a process is allowed. It can open socket connections and ports and whatever it needs. In the past I wrote some interface which allowed the SystemC simulation running on a Linux system to talk to another simulator running on a Windows host using network sockets (it also worked with UNIX domain sockets). And actually we are implementing a SystemC simulation talking to an FPGA on an accelerator card via device files.
    Unfortunately I'm not aware of freely available examples to do so. But if you have some C/C++ code to deal with the netlink sockets you can just embed this code into the simulator e.g. as part of a sc_module and tie it to the simulation phases (open the socket during start_of_simulation(), closing them during end_of_simulation()).
  2. Thanks
    Eyck got a reaction from zafir in SystemC communication with Linux kernel Module   
    Yes, it is possible. Since SystemC is basically a C++ class library you can you whatever C/C++ allows for.
  3. Like
    Eyck got a reaction from winniezhou in tlm to pin converter   
    Well, sc_fifo is not TLM.
    For your example the basic question is: what is the protocol on fifo_out? Should it be clock-based? Valid-Ready signaling? So your queastion and example is too generic and broad.
    If you are looking for an example to translate from TLM2.0 to pin level of an Amba AHB protocol you may have a look here: https://git.minres.com/SystemC/SystemC-Components/src/branch/master/incl/tlm/ahb/bfm and  https://git.minres.com/SystemC/SystemC-Components/src/branch/master/src/tlm_ahb_bfm_initiator.cpp as well as https://git.minres.com/SystemC/SystemC-Components/src/branch/master/src/tlm_ahb_bfm_target.cpp. They implement TLM2.0 to pin and pin to TLM2.0
  4. Thanks
    Eyck got a reaction from plafratt in TLM2.0 preempt last request   
    Actually the usual bus protocols allow to send larger number of requests and the interconnect is allowed to answer them 'out of order' (e.g. AMBA AXI or CHI). But you are free to define you onw protocol and its own rules. The LRM states exactly how to do this. One example can be found at  https://github.com/Arteris-IP/tlm2-interfaces which defines the extensions and phases for the AXI/ACE and the CHI protocol.
  5. Like
    Eyck got a reaction from David Black in TLM2.0 preempt last request   
    Actually the usual bus protocols allow to send larger number of requests and the interconnect is allowed to answer them 'out of order' (e.g. AMBA AXI or CHI). But you are free to define you onw protocol and its own rules. The LRM states exactly how to do this. One example can be found at  https://github.com/Arteris-IP/tlm2-interfaces which defines the extensions and phases for the AXI/ACE and the CHI protocol.
  6. Like
    Eyck got a reaction from maehne in Error:<E109> complete binding failed: port not bound:   
    This part is wrong:
    for ( int i=0; i<N ; i++){ for ( int j=0; j<NB_elements_trans ; j++){ i_adder = new adder("i_adder"); i_adder->in[j](sig_data[i][j]); } i_adder->out(sig_add); } You create N x NB_elements_trans i_adder elements and on each of them you only connect 1 of 4 in ports. I guess you mean:
    for ( int i=0; i<N ; i++){ i_adder = new adder("i_adder"); for ( int j=0; j<NB_elements_trans ; j++){ i_adder->in[j](sig_data[i][j]); } i_adder->out(sig_add); } A few remarks:
    you create a memory leak by assigning objects created with new to the same variable you should not use raw pointer. Use C++11 unique_ptr instead Name you SystemC objects, this helps debugging. C++11 makes it easy witn in-class constructors, e.g.: sc_signal<double> sig_add{"sig_add"}; don't use plain C-style arrays, uses either std::array or std::vector. These provide range checking capabilities and help finding out-of-bounds problems don't use C  or C++arrays for SystemC objects. Use sc_core::sc_vector instead use proper formatting, this eases reading (an IDe or clang-format is your friend). Keep in mind: code is a hundret times more often read than written!
  7. Like
    Eyck got a reaction from Beginner_KOR in can I use sc_fifo with socket?   
    Actually you cannot use sc_core::sc_fifo for this as it takes ownership of the data which doesn't play well with the concepts of the generic payload. But there are event queues in tlm_utils for this (tlm_utils::peq_with_get and tlm_utils::peq_with_cb_and_phase).
  8. Thanks
    Eyck got a reaction from gabriel123 in How to create a vector of fifos and add new fifos values depending on an input?   
    In the constructor list you would provide a creator function. This is a functor(a function pointer, a std::function object, a Functor classinstance, a lambda function, ...) which accepts a char const* and a size_type and returns a constructed object. In your case it would look like (C++11):
    class example: public sc_core::sc_module { public: sc_core::sc_vector<sc_core::sc_fifo<unsigned>> fifos; example(sc_core::sc_module_name nm, unsigned outputs) : sc_core::sc_module(nm) , fifos("fifos", outputs, [](char const* name, unsigned i)->sc_core::sc_fifo<unsigned> { return new sc_core::sc_fifo<unsigned>(5000); } { // some construction code } }  
  9. Thanks
    Eyck got a reaction from Abdelrahman in error LNK2019: unresolved external symbol   
    Actually this is a Virtualizer specific question so you are better up contacting SNPS directly or try their SolvNet.
    But if you have missing symbols during link you miss to specify a library. How to solve this is a question to SNPS.
  10. Like
    Eyck got a reaction from maehne in Pipeline with Stalling Example   
    I'm not aware of any example so I will no be able to answer your question.
    But I do not see your problem. You would do it as it is done in hardware. Each stage is providing a ready signal indicating to the stage before that it can take inputs. And now the preceeding stage updates its outputs only if the ready signal of the next stage is active.
  11. Like
    Eyck got a reaction from maehne in E100 - port specified outside of module   
    I guess your problem stem from a particular implementation detail in SystemC: if you have an inheritance hierarchy you should declare all constructor parameters as ' my_module( sc_core::sc_module_name const& nm). For the leaf module can leave it as 'MyModule(sc_core::sc_module_name nm)'. In the second case a copy of the module name is created which manipulates the hierarchy stack of the kernel. I assume this way you srew up your design.
    It is save to always pass the sc_module_name by const reference in the constructors. This would makeup for a good rule in a modleing guideline
  12. Like
    Eyck got a reaction from swami-cst in Adding sc_attribute of type user-defined Class to an sc_object   
    Basically yes but just add_attribute is not enough. From the top of my head: you need to declare in your sc_module:
    sc_core::sc_attribute<A*> attr{"attr", nullptr}; sc_core::sc_in<bool> pin{"pin"}; in the constructor of your sc_module you need to add the attribute to the sc_object/sc_port:
    pin.add_attribute(attr); via
    attr.value = new A(); you can assign a value. This way the attribute can be found e.g. via the SystemC object tree (sc_core::sc_get_top_level_objects() ).
    Alternatives depend of your goal. One option would be to use CCI, esp. cci_param. But again, it depends what you want to achieve...
  13. Like
    Eyck got a reaction from Nitin_S in Issue while calling sc_main multiple times from main   
    Just to add 2 cents to @David Black proposal: If the instantiation is exepensive you could fork() (https://en.wikipedia.org/wiki/Fork_(system_call)) your programm after instantiating the design. Basically you create a new OS process as copy of the current one and here you can continue the simulation. But in essence it is the same approach as David described.
  14. Like
    Eyck got a reaction from David Black in Issue while calling sc_main multiple times from main   
    Just to add 2 cents to @David Black proposal: If the instantiation is exepensive you could fork() (https://en.wikipedia.org/wiki/Fork_(system_call)) your programm after instantiating the design. Basically you create a new OS process as copy of the current one and here you can continue the simulation. But in essence it is the same approach as David described.
  15. Thanks
    Eyck got a reaction from azarmadr in randomize a vector of values using scv   
    SCV does not contain an the respective overloads for scv_introspection and _scv_distribution. Therefore there is afaik no way to simply randomize a vector. As a workaround you might use the randomization for  plain C-style arrays.
     
  16. Like
    Eyck got a reaction from maehne in Binding sc_out type of ports to sc_port<sc_signal_inout_if<T>,N> type of multiports failed   
    My point was more of a generic nature and more related to modeling guidelines. If your initiator/test_producer has many signals some of them might belong 'logically' together as they are written at the same time. E.g in AHB you have HADDR, HTRANS, HBURST, HWRITE, etc.
    Instead of declaring them as sc_out<sc_dt::sc_logic> xxx or alike:
    sc_out<sc_dt::sc_lv<32>> HADDR; sc_out<sc_dt::sc_lv<4>> HTRANS; sc_out<sc_dt::sc_logic> HWRITE; . . . it would make sense to do it this way:
    struct ahb_req { sc_dt::sc_lv<32> HADDR; sc_dt::sc_lv<4> HTRANS; sc_dt::sc_logic HWRITE; . . . }; sc_out<ahb_req> ahb_out; In the first case you have basically 3 signals/events to observe and deal with. In the latter one you only have 1 event.
    If you cannot refactor the the producer than doing so just for the receiver is point less. But if you have the option to refactor the initiator then I would recommend to do it in this or a similar way.
  17. Like
    Eyck got a reaction from maehne in Binding sc_out type of ports to sc_port<sc_signal_inout_if<T>,N> type of multiports failed   
    You cannot bind an output port to an input port. Ultimately each port must bind to a signal either hierarchically (this is where port to port binding can is used) or directly.
    So you need to define signal for each of the test_module output ports and bind the sc_out and sc_inout ports to it.
    2 remarks:
    you should use sc_in instead of sc_inout to indicate the purpose clearly sc_out is just a child of sc_inout to reduce the number of output ports (and hence signal) you might want to group signals logically belonging together into structs. Those can be used as data typs of signals and ports. This reduces the number of signals and events and increases simulation speed.
  18. Like
    Eyck got a reaction from Nitin_S in Issue while calling sc_main multiple times from main   
    You cannot call sc_main directly from main(). main() comes with the SystemC reference implementation (SystemC simulator) and initailizes the simulation kernel. You miss that in your main function, you migh tlook it up at https://github.com/accellera-official/systemc/blob/master/src/sysc/kernel/sc_main.cpp and https://github.com/accellera-official/systemc/blob/master/src/sysc/kernel/sc_main_main.cpp
    Despite that, you cannot call your sc_main twice. The simulation kernel in the reference implementation is not re-entrant. Thus the LRM states in section 4.3.4.2 Function sc_start:
    in the sequence you described you would call sc_start() after sc_stop() has been called
  19. Like
    Eyck got a reaction from David Black in Binding sc_out type of ports to sc_port<sc_signal_inout_if<T>,N> type of multiports failed   
    You cannot bind an output port to an input port. Ultimately each port must bind to a signal either hierarchically (this is where port to port binding can is used) or directly.
    So you need to define signal for each of the test_module output ports and bind the sc_out and sc_inout ports to it.
    2 remarks:
    you should use sc_in instead of sc_inout to indicate the purpose clearly sc_out is just a child of sc_inout to reduce the number of output ports (and hence signal) you might want to group signals logically belonging together into structs. Those can be used as data typs of signals and ports. This reduces the number of signals and events and increases simulation speed.
  20. Like
    Eyck got a reaction from David Black in How to open and read TEXT file in systemC   
    AFAICS you don't increment the index i in the while loop.
    But your code is way to complex.:
    std::ifstream ifs("TEXT.txt"); if(ifs.is_open()){ int buf = 0; for (int i = 0; i < MEM_DEPTH; i++) { ifs >> buf; buff_1[i]=buf } } ifs.close(); should replace everything from fopen() until fclose(). And you should avoid using macros, they will bite you. '#define MEM_DEPTH 20' should become 'const size_t MEM_DEPTH=20;'.
     
  21. Like
    Eyck got a reaction from maehne in Error E0304 and C2665   
    The example you are refering to is for SystemC 2.0 and more over has errors. Actually this is a bad example to start with.
    the sc_start() in line 17 needs to be commented out for 2 reasons: a) it doesn't make any sense and b) it runs elaboration and tracing (VCD) needs to be initialized before that. After elaboration you cannot add signals for tracing anymore sc_start() (lines 32, 34, 40, 42, 47, 49, 56 58) has to be called either without any arguments (so it runs to the end) or with a duration in terms of sc_time like this: sc_start(1, SC_NS);  
    My recommendation would be to either use  the Doulus tutorials: https://www.doulos.com/knowhow/systemc/tutorial/ or the stuff from SCLive (https://sclive.wordpress.com/)
  22. Like
    Eyck got a reaction from Mik in TLM CPU modeling   
    There is no such thing as CPU TLM modeling. Usually you write a C/C++ processor model with the needed accuracy (instruction accurate, cycle approximate, cycle accurate) and wrap it in a way that you translate memory accesses into TLM socket accesses. Along with that you need to manage to syncronization of the time of your model and the SystemC time (to run e.g. in loosly timed mode). Another task is to take the returned execution time of the bus accesses into account for the execution of the CPU model. This involves also the selection and implementation of the accesses (DMI & blocking or non-blocking).
    You can find a complete example of an instruction accurate VP at https://git.minres.com/DVCon2018/RISCV-VP (or https://git.minres.com/VP/RISCV-VP which is a newer version).  The wrapper for the C++ model in SystemC can be found at https://git.minres.com/DVCon2018/RISCV-VP/src/branch/develop/riscv.sc/incl/sysc/core_complex.h
    To put it straight: doing this correctly is a non-trivial task as it is the implementation of a micro-architecture model of a CPU. One option is to build an instruction accurate ISS and add a microarchitecture model like it is done in the ESECS project (https://github.com/MIPS/esesc)
    BR
  23. Like
    Eyck got a reaction from maehne in How to declare dynamic memory by new in systemC   
    Actually using new is not recommended at all. You should do something like:
    std::array<sc_dt::sc_uint<32>, MEMORY_DEPTH> mem; or (C++11):
    std::vector<sc_dt::sc_uint<32>> mem{MEMORY_DEPTH}; As far as I can see you try to initialize mem in-class (during declaration) and this is not allowed in C++. You can do this only in the constructor. And if you need to use new, don't forget to delete.
  24. Like
    Eyck got a reaction from David Black in Module that convert an sc_vector input into sc_signal   
    Sure. Just add a method reading all bool sc_in and write to the output. You need to make it sensitive to all inputs Something like:
    SC_MODULE(conv){ sc_vector<sc_in<bool> > input{"input"}; sc_out<bool> ouput{"ouput"}; SC_CTOR(conv){ SC_HAS_PROCESS(conv); SC_METHOD(method); for(auto& in: input){ sensitive<<in; } } void method(){ unsigned res = input[1]?2:0+input[0]?1:0; output=res; } };  
  25. Like
    Eyck got a reaction from aditya in no match for ‘operator|’   
    Just as explanation: pos() returns an event_finder (a proxy object which allows to use an event which is not yet available) while posedge_event() returns the event itself. And the operator|() is ony defined for sc_event.
×
×
  • Create New...