Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 08/23/2018 in all areas

  1. 2 points
    Thanks! I can reproduce the behavior and verified that removing the dynamic sensitivity in sc_thread_process::kill_process fixes the issue: void sc_thread_process::kill_process(sc_descendant_inclusion_info descendants ) { // ... if ( sc_is_running() && m_has_stack ) { m_throw_status = THROW_KILL; m_wait_cycle_n = 0; remove_dynamic_events(); // <-- add this line to avoid the exception simcontext()->preempt_with(this); } // ... } I'm not sure, if it is necessary to do the same for the static sensitivity. At least I haven't come up with a similar scenario, where the error is actually "incorrect".
  2. 2 points
    The problem is, when you integrate RTL IP into Loosely-Timed VP that way, the whole simulator will have a performance of cycle-accurate model. Because clock generator will be always on, and Verilated model will be triggered even if it is idle. So don't try to boot Linux with such a simulator. If your RTL IP supports power gating or clock gating, it is a good idea to disable clock generation when RTL IP is turned off. In that case you don't pay for what you don't use: you can boot your OS quickly and then enable clock generator when you start to debug IP-specific driver code.
  3. 2 points
    Hello @kallooran, What version of SystemC library are you using? This issue has been fixed in the release of SystemC-2.3.2. You can find the latest release of SystemC-2.3.3 here: http://accellera.org/downloads/standards/systemc Hope it helps. Regards, Ameya Vikram Singh
  4. 2 points
    David Black

    Seeking Feedback on Datatypes

    Actually, it adds a lot of value. std::array can be passed by reference in a function call and the function can then determine the proper size of the array. This is much better than passing pointers, the C standard. You can also copy an array, which should be synthesizable, which reduces coding and greatly improves readability. It should be possible to implement some #include <algorithm>s on std::array too. Also, you can have bounds checking for additional safety; although, that aspect is probably not synthesizable. Additionally, constexpr should be quite helpful for the synthesis aspect.
  5. 2 points
    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 pretty handy in such cases. Best regards
  6. 1 point
    Simple answer: there really is no straightforward way to do this. Of course if you wanted to get into the internals of the SystemC implementation, it is possible; however, that completely violates the standard. As to why this is not allowed: performance. The desire to have efficiency overrides the desire for corner cases such as yours. How can you work around this? Several possible approaches, but here one I would use: Create a new event class that adds tracking and an API to access it. This is easy to do if you know your C++ and SystemC well enough. Trivial outline of concept:: static const sc_core::sc_process_handle NONEXISTANT; struct Tracked_Event { void notify( void ); // sets m_process_handle and notifies m_event void notify( sc_core::sc_time delay ); // same except waits for delay sc_process_handle get_trigger( void ) { return m_process_handle; } void clear( void ) { m_process_handle = NONEXISTANT; }; private: sc_core::sc_event m_event; sc_core::sc_processhandle m_process_handle; }; struct Event_array { Event_array( int depth ); void wait( void ); // clears all m_process on entry, then waits for an m_event Tracked_event operator[]( int ); sc_vector<sc_core::sc_process_handle> get_trigger_list( void ); private: sc_vector<Tracked_Event> m_event_array; sc_core::uint64 m_delta_count; };
  7. 1 point
    I think there are a few more options, but first, you need to acutely aware of the issue of OS thread safety. The SystemC kernel is not generally thread-safe unless you use async_request_update(), and a queue. I've done this several times. That said you have several options: Place software inside a SystemC SC_THREAD and provide convenience methods to initiate TLM transport calls. This is the simplest SystemC approach, but does not allow for modeling the actual CPU planned to be used and hence timing is not very accurate. This has the fastest performance from the SystemC point of view. Place the software on a development board that has the target CPU and some type of communications to the machine where you will run SystemC. I generally use TCP/IP sockets. Replace the driver with a special socket call passing packets to to a remote machine and receiving back the response. On the SystemC side, create an OS thread to receive the socket and inject the message into SystemC via the async_request_update call and an unbounded STL queue or FIFO of some type. A TLM 1.0 FIFO might do. A receiving thread can then pass the data into the SystemC simulation and return the result. This is somewhat more overhead, but allows for a more accurate target CPU. Obtain an ISS (Instruction Set Simulator) for the target processor and interface it to SystemC. This varies in complexity. You might look at existing models or talk with vendors such as Cadence or Mentor. Or perhaps your CPU vendor (e.g. Arm has some very nice models). As @Eyck suggested QEMU, DBT-RISE-RISCV. Also Gem5 (Google it).
  8. 1 point
    Hi Bhargav, In the 1685-2014 version, component wire ports can be multidimensional, i.e., it can have muliple arrays and multiple vectors. For this reason, a portReference must support multiple dimensions as well. This is done using the partSelect element. The partSelect element can contain a single range with left and right to support a single vector as before. Or it can contain can indices plus a range. The indices indicate which dimension the range applies to. If the indices contain more than one index then the first indices apply to the arrays and the last indices apply to the vectors. Best regards, Erwin
  9. 1 point
    BEGIN_REQ/END_REQ and BEGIN_RESP/END_RESP mark time points in the protocol. So in the stanndard implementation you have 2 phases: request and response. Depending on the type of access various data is been transferred: for a read REQ usually carries the addr while RESP carries the data and status while during a write REQ carries addess and data while RESP just carries the status. It is up to the initiator and target to care for consistency of the data in the payload, in most implementations I''ve seen the data is sampled/set at the BEGIN_* time point. Best regards
  10. 1 point
    To answer the question of a fifo multiple writers and one reader, I would suggest either of two approaches: Create a module with a vector of inputs (1 per writer) and the sc_fifo output. A simple method process can then arbitrate and facilitate placing incoming data onto the output. This has the advantage of allowing a custom arbitration scheme Create an internal std::queue and limit access with a mutex (sc_mutex might work). Since the queue doesn't have a limitation, it will be up to you to manage maximum depth issues. Downside is that arbitration is managed by the mutex and may not be ideal. For a fifo with multiple readers, you probably need a manager to decide arbitrate requests, which is similar to 1 above.
  11. 1 point
    In general, your design would not work because reading a real hardware FIFO takes time and readers would get entangled. How would you manage that? Second, you are not using the correct methodology to connect up your FIFO, which is why you don't see the error. SystemC expects you to connect modules to channels using ports. Skipping the hierarchy and connecting consumers using pointers is incorrect. Instead, you consumer should replace your my_fifo pointer with a fifo port. You have two choices: sc_port< sc_fifo_in_if<int> my_fifo_port; or sc_fifo_in<int> my_fifo_port; The syntax to access the fifo will be my_fifo_port->read(). Next you will need to attempt to connect the port to the fifo during construction in your producer with: for( int i=0...4 ) consumer.port.bind( my_fifo ); When you run you will encounter an error during elaboration (construction) that you already have a connection and fifo ports don't allow more than one binding.
  12. 1 point
    Roman Popov

    Array when declare port for model

    This is a very old style. With a modern SystemC you can have the same with sc_vector: //exxe.h class EXXE : public sc_module { public: sc_vector<sc_in<sc_dt::uint64>> SC_NAMED(clock,3); sc_vector<sc_in<bool>> SC_NAMED(input,5); EXXE(sc_module_name); ~EXXE(); } But as David mentioned, before starting learning SystemC you should learn C++ first. Trying to understand SystemC without being proficient with C++ is a waste of time.
  13. 1 point
    You would need to write a wrapper class with debug aids builtin. A sketch might be: struct debug_mutex : sc_core::sc_mutex { void lock( void ) override { auto requester = sc_core::sc_get_current_process_handle(); INFO( DEBUG, "Attempting lock of mutex " << uint_ptr_t(this) << " from " << requester.name() " at " << sc_time_stamp() ); this->sc_mutex::lock(); locked = true; locker = requester.name(); time = sc_time_stamp(); changed.notify(); } void unlock( void ) override { auto requester = sc_core::sc_get_current_process_handle(); this->sc_mutex::unlock(); time = sc_time_stamp(); locked = false; locker = ""; changed.notify(); } // Attributes bool locked{ false }; sc_event changed; sc_time time; string locker; }; I have not tested above. NOTE: I have a macro INFO that issues an appropriate SC_REPORT_INFO_VERB with the above indicated syntax. Replace with your own. Never use std::cout or std::cerr if coding SystemC.
  14. 1 point
    Roman Popov

    How to connect array of ports?

    Usually you should use sc_vector instead of array. The problem with array is that names of signals and ports in array will be initialized to meaningless values (port_0 ... port_1 ). If you still want to use arrays, then bind with a loop. Here is example, both for array and sc_vector. #include <systemc.h> static const int N_PORTS = 4; struct dut : sc_module { sc_in<int> in_array[N_PORTS]; sc_vector<sc_in<int>> in_vector{"in_vector", N_PORTS}; SC_CTOR(dut) {} }; struct test : sc_module { dut d0{"d0"}; sc_signal<int> sig_array[N_PORTS]; sc_vector<sc_signal<int>> sig_vector{"sig_vector", N_PORTS}; SC_CTOR(test) { for (size_t i = 0; i < N_PORTS; ++i) { d0.in_array[i](sig_array[i]); } d0.in_vector(sig_vector); } };
  15. 1 point
    Philipp A Hartmann

    tlm_socket_base_if

    Hi Guillaume, I agree, that the new pure-virtual functions in tlm_base_(initiator/target)_socket are not compliant to IEEE 1666-2011. However, I'm curious what use case you have to use these classes directly instead of inheriting from tlm_(initiator/target)_socket, where the functions are implemented? Regarding the implementation on the base socket level, I suggest to add a typedef to the fw/bw interface classes, and use these typedefs in the socket base class then. Something like: template <typename TYPES = tlm_base_protocol_types> class tlm_fw_transport_if // ... { public: typedef TYPES protocol_types; }; // tlm_base_target_socket virtual sc_core::sc_type_index get_protocol_types() const { return typeid(typename FW_IF::protocol_types); } Theoretically, these types could mismatch between FW_IF and BW_IF in manual socket implementations. Therefore, I'd suggest to refer to the FW_IF in the target and BW_IF in the initiator socket. Greetings from Duisburg, Philipp
  16. 1 point
    maehne

    Direct Digital Synthesis

    As you can see from the DDS block diagram, which you posted, the structure of DDS block is quite simple. I therefore would model it as a single TDF module containing the accumulator register as a state variable. As input, you will have your frequency control and phase offset control signals. The frequency control signal basically is the value, which you continuously add to the value in your accumulator register to generate a periodic sawtooth signal (due to the overflow of the accumulator). The phase offset control signal gets added to the accumulator register to enable shifting the phase of the sawtooth signal. This sawtooth signal is interpreted as the angle operand of a sine function. The period of the sawtooth signal represents a full revolution on the phase circle, i.e., the 2^L possible sawtooth signal values are evenly mapped to phase angles in the range of 0 rad to 2 pi rad (0° to 360°). To avoid repeated calculations of the sine function, the sine amplitudes for all possible angles are pre-calculated and stored in a look-up table (LUT). The current value of the sawtooth signal is then used as the index into that look-up table to find the corresponding output amplitude. To implement this in a generic DDS TDF module, I would choose M, L, and K (bit widths) as generic parameters, which can be passed upon DDS module instantiation to the DDS module's constructor. From M and L, you can calculate the value for the modulo operation, which models in software your overflowing of a M-bits-wide and L-bits-wide addition operation. The difference of M and L gives you the shift distance needed to implement your accumulator output quantisation. The sine LUT needs to have 2^L entries. The sine function should be scaled by 2^(k-1)-1 to use the full range of a k bit wide signed output. All these preparatory calculations, you can do in your DDS module's constructor. The processing function then only needs to only implement the two additions and the amplitude look-up based on the current values of the frequency and phase control inputs and the current value stored in the accumulator register. If you plan to use this kind of module in a model of communication system, you might consider having a look to the Vienna SystemC AMS Building Block Library, which is available for download from systems-ams.org. The latter web site contains also other useful SystemC AMS resources.
  17. 1 point
    SystemC is single threaded, you don't need std::mutex. However SystemC does not guarantee any order for processes executed in the same delta cycle. SystemC is a discrete-event simulator, and I suggest you to learn the concepts of simulation semantics from Paragraph 4 "Elaboration and simulation semantics" of IEEE-1666 SystemC standard. The purpose of primitive channels, like sc_signal, is to remove non-determinism by separating channel update request from actual update of value into two different simulation phases. But it only works if there is a single writing process during a delta cycle. In your case if initiator and responder threads are executed on same cycle, they both will read the same "current value" of signal. Initiator will request to set signal value to (valid = 1, ready = 0) and responder will request to set it to (valid = 0, ready = 1). Since there is no guarantee on order between processes, you will either get (1,0) or (0,1) on the next cycle.
  18. 1 point
    maehne

    ELN Low pass filter

    Well, you will have to write a test bench, which provides your RC filter with some stimuli for transient simulation or sets up an AC analysis. However, I recommend you to have first a closer look to the fundamental concepts and ideas of SystemC AMS. A good introduction to SystemC AMS is provided by the SystemC AMS extensions User's Guide, which is part of the SystemC AMS extensions 1.0 release. Even though, this discusses only the features available sind SystemC AMS 1.0, it is a good start as SystemC AMS 2.0 and IEEE Std 1666.1 added mainly advanced features related to Dynamic TDF and bug fixes. Also, the SystemC AMS community pages provide some good links to introductory resources to get started with SystemC AMS.
  19. 1 point
    Those questions are covered in detail in paragraphs 14.1 and 14.2 of SystemC standard. Can't answer in a better way. TLM2.0 simulations are not cycle-accurate, so you don't have clock edge events. In AT modeling style you should call wait(delay) after each transport call. In LT modeling style all initiators are temporaly decoupled and can run ahead of simulation time, usually for a globally specified time quantum. For debugging you can use the same techinques as in cycle-accurate modeling: Source-level debugging with breakpoints and stepping Transaction and signal tracing Logging Comparing with RTL, debugging using waveform won't be that effective, because in AT/LT modeling state of model can change significantly in a single simulator/waveform step. Usually preffered way is combination of logging and source-level debug. Debugging TLM models is harder comparing to RTL. Also C++ is much more complex and error-prone comparing to VHDL/Verilog.
  20. 1 point
    Roman Popov

    using gtkwave

    I've removed next_trigger and simulated your code. Check attached waveform. Check how to model delay line here:
  21. 1 point
    Roman Popov

    SystemC 2.3 Pretty-Printer

    Hard to say without debugging. In source code I see they are registered using "RegexpCollectionPrettyPrinter", probably sc_dt::sc_int<(.*)> matches sc_signal<sc_int<2>> ? By curiosity, may I know how you manage signals/ports? Signal has m_cur_val and m_new_val fields, storing current and next signal value. So they are pretty-printed as "m_cur_val -> m_new_val". Ports are just decorated pointers, signal port has m_interface field holding a pointer to signal, so pretty-printer dereferences it, casts to dynamic type and prints it the same way as signal. Actually you can do much more with GDB Python API. I have even written SystemC to Verilog converter using GDB (Generates complete netlist, but without process bodies). Commercial SystemC interactive simulators/debuggers are also based on GDB AFAIK.
  22. 1 point
    Martin Barnasconi

    Error: System not scheduable

    It looks like you have a multi-rate system, i.e. somewhere you defined a <port>.set_rate(..) in a set_attributes callback. Now you try to access the n-th sample at this port, like <port>.read(<sample>), but the nth sample is higher than the rate specified. This means you have either the wrong rate, or reading a sample outside the range defined by the rate.
  23. 1 point
    Uwghiello

    Install SystemC on Visual Studio 2017

    I am trying to install systemC on visual studio 2017 but it seems that I cannot find the guide for it. So I had to follow the guide of installing systemC on VS2010 :( In fact, I have got systemC.lib but when I configured the project for systemC, i.e, the project->property->C/C++->Code Generation->Runtime Library->balabalabala... finished all of them and build solutions, there are some errors. So...what should I do? Totally confused because I know nothing about VS =_= PS: the guide is here
  24. 1 point
    David Black

    approximately timed

    IEEE 1666-2011 section 10.2 states: IEEE 1666-2011 section 10.3.4 states:
  25. 1 point
    There have been some improvements to the performance of the field automation macros, but I still do not believe their benefit is worth the cost. You should be able to prove it to yourself by creating a simple testbench with and without the macros.
×