Jump to content

Eyck

Members
  • Content Count

    199
  • Joined

  • Last visited

  • Days Won

    61

Everything posted by Eyck

  1. In case 1 you should use sc_core::sc_vector<..> instead of a plain array as you cannot call constructors for plain arrays (what sc_vector does). Given that objA and objB are pointers case 1 is ok and works also with the sc_vector. Case 2 is fine as far as I see... Best regards
  2. Actually you don't assign anything to adata->sdata in sc_main In your if branch testing the pointer for NULL and create the design but then you throw away the pointer. So it is called a second time after calling sc_start() and it is not allowed to instantiate primitive channels after the elaboration phase. But in genereral your approach is quite a mess and prone to errors (as you encountered already). Why don't you put your outer for-loop in sc_main and just load the model from the shared librar? This way you have proper initialization, do not abuse any parameters and have a similar fl
  3. 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 an
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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 synconizin
  9. 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.
  10. 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
  11. 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 wa
  12. 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 t
  13. 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 pr
  14. 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
  15. 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. T
  16. 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
  17. 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
  18. The time resolution is the minimal time step the simulater can advance, not how it is formatted or printed. Internally time is represented as in integer value which you multiply with the time resolution to get the actual time. And BTW, a delta cylce has by definition not time associated. If you want to format the time appropriately you would want to get this internal time value (sc_time_stamp().value()) and format it accordingly based on the time resolution. Another way would be to use to_seconds() (which returns a double) multiply it with 1000 and fomat it accordingly using the io manipu
  19. 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
  20. Well, there are several problems in your code: naming and sc_out input is counterintuitive - but this is minor you use a limited range integer and assign values outside this range. sc_in<2> is a 2.bit integer and can hold values from -2 to 1. it seems you did not understand and obey event scheduling, more see below So what you see in line 16-22 of the output is the initial invocation of tb::source(), tb::sink(), and statem::controller(). There tb::source() writes 11 to input_sig and statem::controller() write enable=false. Due to the write to input_sig tb::source(),
  21. Well, actually the error message from the point of the compiler is quite right: using the '*'-operator you intent to dereference the return value of write() which is 'void'. BR
  22. I agree here with David, best would be to share the basic parts of your code as well as the complete commands and outputs From your description you have your DUT and your testbench in a separate file. You should compile them (inlcuding your main.cpp) into .o files e.g. by running something like g++ -I. -I$SYSTEMC_HOME/include -L. -L$SYSTEMC_HOME/lib-linux64 -c <cpp file here> and then link all .o file into your executable like: g++ -L$SYSTEMC_HOME/lib-linux64 -Wl,-rpath=§SYSTEMC_HOME/lib-linux64 -o main *.o -lsystemc -lm This is a basic C++ compile flow, see also here
  23. 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 yo
  24. 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 n
  25. Hi Sumit, Quoting http://en.cppreference.com: Some member functions are special: under certain circumstances they are defined by the compiler even if not defined by the user. They are: Default constructor Copy constructor Move constructor (since C++11) Copy assignment operator Move assignment operator (since C++11) Destructor So in the code you show you just delete the default constructor and the destructor. Obviously this does not make sense as you cannot construct any object since you do not have a parameterized constructor. But if
×
×
  • Create New...