Jump to content

Eyck

Members
  • Posts

    356
  • Joined

  • Last visited

  • Days Won

    87

Reputation Activity

  1. 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 } }  
  2. 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.
  3. 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.
  4. 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
  5. 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...
  6. 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.
  7. 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.
  8. 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.
     
  9. 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.
  10. 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.
  11. 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
  12. 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.
  13. 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;'.
     
  14. 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/)
  15. 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
  16. 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.
  17. 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; } };  
  18. 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.
  19. Like
    Eyck got a reaction from David Black in get interface failed: port is not bound:   
    You are writing to ports in the constructor of server. At this point they are not bound. Since you initialize them in the beginning of your thread this is not needed anyways.
    Aside of that you also do not need the sensitivity list for the monitor thread as you never use the default sensitivity (by using wait() ). And if you use C++11 or newer you should use In-class member initializers which eases the naming of signals (and you should name them to make debugging easier):
    sc_in<bool> begin1{"begin1"}, begin2{"begin2"}, begin3{"begin3"}; sc_in<bool> end1{"end1"}, end2{"end2"}, end3{"end3"}; sc_in<bool> incoming1{"incoming1"}, incoming2{"incoming2"}, incoming3{"incoming3"}; sc_out<bool> free{"free"}, outgoing1{"outgoing1"}, outgoing2{"outgoing2"}, outgoing3{"outgoing3"};  
  20. Like
    Eyck got a reaction from David Black in Queue fifo   
    Actually you created an array of inputs of type int, not a pipe. Without more code it is hard to give any advise
  21. Like
    Eyck got a reaction from maehne in Time, initialization and async_request_update   
    You should seriously read the SystemC standard or related books.
    Neither SC_METHOD nor SC_THREAD pass time, time advances only in the SystemC kernel and the kernel returns control to them at certain time points.
    The difference is that SC_THREAD preserves state when returning control to the kernel by calling wait(). SC_METHOD cannot preserve the state (it is always called as a function) and is therefore not allowed to call wait(). next_trigger() tells the SC kernel when to invoke the SC_METHOD next time. Calling next_trigger() several times in the same method as you do it is meaningless as the last call to next_trigger() prevails. Again: next_trigger() does not stop execution rather tells the kernel when to start the method next time.
     
  22. Thanks
    Eyck got a reaction from Bes in syntax problems   
    You can access elements using array index operator like this:
    in2[0][1]=42.0; But you write you want to put values onto the array. You cannot write onto ports as these are only proxys and do not hold values. You need to create a similar sc_signal array and connect it to the ports. sc_signals hold values so you can put values on them using write().
     
    A side node: you should declare your vectors as:
    sc_vector<sc_vector<sc_in<float>>> in2{"in2", 4, [](char const* name, size_t idx) -> sc_vector<sc_in<float>>*{ return new sc_vector<sc_in<float>>(name, 4); }}; This names your ports (very helpful when tracing values) and you don't need to call init() separately.
  23. Like
    Eyck got a reaction from maehne in How to create two stage pipeline using SystemC?   
    Your problem is the use of POD (plain old datatype) for communication between the processes. Why? As soon as you write onto it all other processes see the update. So the behavior of your design depends on the scheduling of the processes. If Design::process is scheduled before Design::second_stage_process the second_stage_process sees the updates of process.
    Actually there are 2 ways out:
    you just have one thread and call the function from the output to the input: void Design::process() { txProcess(); intermediateProcess(); rxProcess(); } Although it will work in your case this approach will not scale. As soon as you cross sc_module boundaries you cannot control the order of calling.
    you use a primitive channel instead of POD. In your case you might use a sc_core::sc_fifo with a depth of one. And you should use sc_vector instead of the POD array type since they need the proper initialization. Why does it help? New values being written will be visible at the output of the fifo in the next delta cycle. So no matter in which order the threads and methods are invoked they will read the 'old' values despite 'new' values have been written. HTH
  24. Like
    Eyck got a reaction from katang in Handling SystemC engine from a Qt5 thread   
    Esp. as educational project you should implement it in 2 threads which communicate with each other. Since they run in the same process space you can access data safely once the simulation is in paused state.
    But you cannot restart the simulation without restarting the process it self. SystemC uses static global variables storing the simulation state and those get only initialized at program start.
  25. Thanks
    Eyck got a reaction from Amol Nikade in SC_METHOD/SC_THREAD Synchronization   
    There is no guarantee which method or thread is activated first There is no means to give priority. Why would you like to do this? In my experience you have a thought problem if you believe you need to do this. thread activation is more expensive (in terms of computing power) than method as the thread context needs to be restored and saved. But threads keep an internal state so they are good to describe state machines.
×
×
  • Create New...