Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by apfitch

  1. Regarding your questions about blocking transport... wait(delay) means that the initiator has chosen to synchronise to sc_time_stamp() by calling wait. In the target, the delay parameter represents the time at which the target should consider the request to have been received. In the initiator, the delay parameter contains the time at which the initiator should consider the response to have been received. If you have wait(delay) in the target, it means the target has chosen not to use temporal decoupling and has instead decided to wait to the actual sc_time_stamp() when the request should be received. The delay returned by the target does represent the time at which the response should be considered to have arrived (relative to sc_time_stamp()), which is the time at which the transaction ends. You can think of b_transport as representing a protocol with only two timing points, the time at which the request is sent, and the time at which the response is received. regards Alan
  2. Who knows? You need a stack backtrace to narrow down the location of the error. regards Alan P.S. One thing looks odd - why is packet->address assigned using to_ulong(), and tam assigned using to_uint()?
  3. Hi, the first problem is that sc_bv doesn't have arithmetic operators defined, so you have to convert to an integer type (e.g. sc_bigint). The second problem is that the range() method returns a hidden proxy class, and there are two ambiguous type conversions from that class. It's counter-intuitive, but you have to cast to a known type on the right-hand side (not the type on the left-hand side), then let operator= do its work. result = sc_biguint<128>( sc_bv<128>(rdata.range(127, 0))) + sc_biguint<64>(sc_bv<64>(wdata.range(63, 0))); The section sc_bv<128>(rdata.range(127,0)) converts the hidden proxy class to a bit vector, which can then be cast to an sc_biguint. The two sc_biguints produce an sc_biguint, which is converted to the result by the overloaded.operator=. Obviously using temporary variables would make it a bit more readable :-) regards Alan P.S. The advantage of the code I've shown is it would work with any widths as you never use conversion to native C++ types.
  4. On our website there's a tutorial and a number of videos and examples of TLM2 and SystemC (see www.doulos.com/knowhow/systemc and www.doulos.com/knowhow/systemc/tlm2), though I must admit the tutorial is quite hardware orientated. There used to be a tutorial on the Forte Design Systems website, but I can't find it any more. I would recommend downloading the latest standard (IEEE 1666-2011) via http://www.accellera.org/downloads/ieee/ I certainly would *not* recommend either the 2.0 user guide or the 2.0.1 reference manual, they are very out-of-date. To paraphrase someone, every time I see sc_bit I reach for my revolver :-) Probably the best general book is "SystemC from the Ground Up" by David C Black, Jack Donovan, Bill Bunton and Anna Keist. regards Alan
  5. Try writing out sc_delta_count() as well as sc_time_stamp(). If sc_delta_count() is increasing, but sc_time_stamp() stays at 0, you are stuck in a combinational feedback loop, regards Alan
  6. As all your clocks are not multiples of 2 ns, I would increase the time resolution to at least 500ps, Alan
  7. Don't use to_seconds(), the stream operators are overloaded for the sc_time type Alan
  8. Hi Reza, The idea of the quantum is that a process does *not* give up to the scheduler until it decides enough local time has passed. For instance, imagine the current time (as returned by sc_time_stamp()) is 1000ns. My initiator has a local sc_time variable t. I initialise t to e.g. 10 ns. An initiator thread executes b_transport(tx, t); That means my local time is now 1010ns (but sc_time_stamp() has not changed, and no other process has run). The target which implements b_transport, now updates t by 100ns i.e. t now contains 110ns. In other words, the target is "pretending" it took 100ns to process my request, and my local "pretend" time is 1110ns. I can then call b_transport again with t = 110 + 10 = 120 ns; The target returns with 220 ns; and so on. So in answer to one of your questions, yes there can be many calls to b_transport within a quantum. Let's now suppose the global quantum is set to 500 ns. Eventually, my local time offset is greater than 500 ns. At that point my initiator calls wait(), and another initiator can run. SystemC time is still at 1000 ns, sc_time_stamp() hasn't changed. The second initiator runs sending calls back and forth until its local time offset exceeds the global quantum. It then calls wait(). Eventually all initiators have run and suspended. sc_time_stamp() increases, and off we go again. Now to keep track of that yourself would be possible, but boring to write the code - so in tlm_utils there is a utility called the tlm_quantum_keeper. The idea is that each initiator has its own tlm_quantum_keeper instance, and that's what keeps track of the local time offset. So the answer to "who manages the time" is either "you do - good luck!". Or use tlm_utils::tlm_quantum_keeper (much easier). In your third example, the idea of the delay parameter is that this represents the offset from systemc time (sc_time_stamp()). In my description above, I assumed the target did *not* call wait. However if the target *does* call wait, then the offset must be reset to 0 ns, because sc_time_stamp() has increased. I hope this helps, regards Alan P.S. I suppose I should really try and sell you a training course http://www.doulos.com/content/training/systemc_tlm2.php
  9. It's definitely on the Questa download page. I suspect it breaks the license agreement for me to post a link, so I'm not going to. When you get to the download page, you may need to scroll down to see it, regards Alan
  10. It's available from supportnet. Click on Questa at the left. Click on the downloads tab. Click through to download, and it's on the download page. Alan
  11. If you're lucky someone will know the answer. But you probably first need to read the Questa manuals; and then if that doesn't solve the problem, contact Mentor support, regards Alan
  12. Hi Guiseppe, you can register with the Accellera website (it has a separate registration from these forums). Once you're registered, I think you can join the group as an observer (a non-voting member), as long as the group chair approves you. I hope what I've said is true! kind regards Alan
  13. For the signal class, there is an overloaded operator= which calls write(), so you can do either. Some people find it clearer to use write() so that you can tell that you are assigning to a special class, rather than a plain C variable. In other words it is a matter of style, regards Alan
  14. It can make sense to read an output. The classic example is to implement a counter, where you want to increment the count using count = count + 1; This will work in SystemC for an output signal port of an integer type. Of course a counter has a clock. I would guess your example is a case of combinational feedback, though I can't tell without knowing the sensitivity of your process, regards Alan
  15. For a long time the Verification Working Group was moribund, but it is now alive again - you can join it here: http://www.accellera.org/activities/committees/systemc-verification Cadence's version did have significant enhancements, including coverage classes, event operators, and more constraint operators. regards Alan
  16. Hi, a couple of points - firstly if you use SC_THREAD to emulate a VHDL process, the wait() function call should be at the bottom of the thread. Regarding SC_METHOD vs SC_THREAD, in this case there is no different behaviour. SC_METHODs may simulate faster due to few context switches to the kernel, so I would prefer an SC_METHOD. regards Alan
  17. Hi Elliott, one other thing - it's not clear from your original post what you mean by a new value - if you mean a change in value, then the event() method will tell you a value has changed *assuming* the ports are connected to sc_signal. If you want to detect an event even if the value hasn't changed (for instance if the same value is assigned twice) you can use the sc_buffer channel instead, regards Alan
  18. There's a paper about sc_vector written by Philipp Hartmann who was the original author. You can download it here: http://complex.offis.de/documents/doc_download/29-scvector-container-and-the-ieee-p1666-2011-systemc-standard Also of course have a look at the 1666-2011 standard, in particular pages 404 and 405. You should just be able to do something like struct Mod: sc_module { sc_vector< tlm_utils::simple_target_socket_tagged<interconnect1> > vec; Mod(sc_module_name n) : vec("vec", 4) // 4 is the size { You can also defer the creation by calling the init() of sc_vector in the constructor, regards Alan
  19. Hi Tanja, yes the std::vector is trying to assign and copy sockets, which then is causing it to attempt and assign an an sc_event. To avoid that, you could create an array of pointers to sockets e.g. std::vector<tlm_utils::simple_target_socket_tagged<interconnect1>* > sockets_array; and then dynamically allocate the sockets and bind them, e.g. interconnect1::interconnect1( sc_module_name name, const unsigned int number ) : nr(number) { socket_array.resize(nr); for (int i=0; i<nr; i++) { socket_array[i] = new tlm_utils::simple_target_socket_tagged<interconnect1>; *(socket_array[i]).register_b_transport ( this, &interconnect1::b_transport , i); // etc } } and then preferably implement a destructor. Does that make sense? If you're using SystemC 2.3.0, the sc_vector should provide a better solution, regards Alan
  20. The errors are saying that you are attempting to copy or assign an sc_module. Copying and assignment of sc_modules is disabled by making the copy constructor and operator= private. This can happen if you declare std::vector<sc_module> for instance, as std::vector using copying and assignment internally. In SystemC you can use the sc_vector class instead to manage arrays of modules, ports, and so on, regards Alan
  21. Hi Tanja, we need more information. Going from what you've posted above, I'd say the problem is a missing semicolon in file.h regards Alan
  22. Hi, there's no explicit support for synchronizing clocks in SystemC. Your solution of choosing "nice numbers" makes sense. Regarding your comment "This has got to be a common problem." may not be true :-) Most industry use of SystemC is for virtual prototyping, which generally doesn't use clocks. People do use SystemC for synthesis of course, but then your problem is similar in any hardware description language (and in real hardware as well, hence the use of frequency synthesis techniques for clock division and multiplication on modern FPGAs). regards Alan
  23. You should add the include and library directories to the paths. Here are my rather short notes: Visual C++ 2010 Tools > Settings > Expert Settings View > Property Manager Expand project properties until you see Microsoft.Cpp.Win32.User Right-click on the above under e.g. Debug, and set directories. Close and re-open Visual C++. When it says "set directories", include should be set to the src directory, library should be set to the Debug directory, Alan
  24. You could provide stimulus in sc_main, but you need to call sc_start for a limited amount of time, e.g. sc_start(1, SC_NS); // assign some signals sc_start(1, SC_NS); and so on. At least I think that will work - I always write a separate stimulus module :-) Alan
  • Create New...