Jump to content

Philipp A Hartmann

Members
  • Content Count

    506
  • Joined

  • Last visited

  • Days Won

    122

Everything posted by Philipp A Hartmann

  1. I may completely miss the modeling intent, but if you want the process to be triggered upon each event notification or after ten nanoseconds at the latest, maybe you can use a wait with a timeout? wait(10,SC_NS); // startup? (trying to stay close to the original code) while(1) { cout << " Display ok"; wait( sc_time(10, SC_NS), event_1 ); // wakeup upon event_1, after 10ns at the latest } Would this help in your scenario? Greetings from Duisburg, Philipp
  2. Oh, there seems to be still an issue in 2.3.1, you should change the circular_buffer::clear function to template < typename T > void circular_buffer<T>::clear() { for( int i=0; i < used(); i++ ) { // buf_clear( m_buf, i ); // << BUG HERE buf_clear( m_buf, (m_ri + i) % m_size ); // This should(tm) be correct } m_free = m_size; m_used = m_ri = m_wi = 0; } Thanks for reporting. I'll take this to the Language Working Group to make sure a fix will be included in the next release of the proof-of-concept simulator. (I would still recommend to upgrade to 2.3.1... ) Greetings from Duisburg, Philipp
  3. AFAICS, this is another symptom of a known issue and fixed in 2.3.1. You should upgrade. Quoting the RELEASENOTES: Greetings from Duisburg, Philipp
  4. Tamilselvan, I had a quick glance and you're having signals with multiple drivers in your design (at least you're suppressing the related errors). There has been an issue in SystemC 2.3.0, fixed in 2.3.1, which could cause differences in this scenario. Quoting from the 2.3.1 RELEASENOTES: - Handle the case of a suppressed multiple-writer error in sc_signal (and related channels) consistently with SystemC 2.2.0 again. I would suggest to use the proper sc_writer_policy (i.e. SC_MANY_WRITERS) for these signals, if you really can't avoid having multiple SystemC processes driving them. Suppressing errors (or even warnings) is rarely the right thing to do. Greetings from Duisburg, Philipp
  5. The link order is incorrect. The dependencies are resolved from right to left. Your Makefile should say: # list SCV before SystemC LIBS = -lscv -lsystemc -lm # local objects first, then the required libraries $(TARGET): $(OBJS) $(CC) -o $@ $(LIBDIR) $(OBJS) $(LIBS) As a side note: For C++ applications, you should prefer the variables CXX (for the C++ compiler) and CXXFLAGS (for the compiler flags). CC and CFLAGS are intended for C projects. Secondly, I would recommend not to define DEBUG_SYSTEMC in user code. hth, Philipp
  6. You seem to misunderstand the relationship between templates and polymorphism here. Only the interfaces/classes that depend on a template type parameter are actually defined as a template. You're looking for something like dynamic typing (as known from languages like Python), where you could define a write method for different types without explicit overloads. This is not supported by C++ directly and you would need to build a mechanism for it on your own, if you really want this. Instead of just storing the sc_port_base pointer, you could store an adapter class, encapsulating the correct type conversion from some generic write parameter written by the testbench to the final C++ type used in the DUT. The adapter would then be constructed from the factory. Lookup "type erasure" in your favourite search engine. Still, this would only cover a specific channel interface (sc_port's template parameter), e.g. sc_signal_out_if for a set of compatible data types, e.g. sc_int_base for sc_int<N>. I'm not convinced that this simple architecture actually solves a real problem. Instead, you'd probably need to integrate something like the UVM driver concept on top of such a technique to orthogonalise concerns here. Theoretically, there is no need to recompile the testbench itself. Only the "missing" factory entries (i.e. adapter template instantiations) would need to be compiled and then linked to build the final simulation model. But yes, there's nothing you can do about this. But this is simply a consequence of C++ being natively compiled instead of dynamically interpreted. If you're just interested in signals of SystemC datatypes, you can also create a wrapper around your DUT and add adapters from the fixed-size types to their corresponding base classes (sc_int<N> -> sc_int_base, ...) and reduce the complexity of the problem. /Philipp
  7. While traversing, you should have realised already, that all ports (and the other SystemC objects) are derived from sc_object. But even more specifically, you can use a pointer to sc_port_base, the non-templated base class of all ports. That said, the port_wrapper you've shown won't work as is. You'd need to do proper type erasure. But even with that, you still need to instantiate the correctly templated ports/channels within your testbench. The step from a configuration file, i.e. some runtime data, to a (statically typed) C++ object then requires some kind of factory. hth, Philipp
  8. First of all: Yes, if you use MSVC 2010, you should rename/copy the msvc80 directory to msvc10 to allow enable the correct lookup of the SystemC.lib. But you currently don't come to this point. From the error message, it looks like you have the MSVC executable listed after the Cygwin command-line tools in your PATH environment variable. Obviously, the Cygwin link.exe doesn't understand the options of the MSVC LINK.exe. hth, Philipp PS: You should use SystemC 2.3.1 to avoid the warning about the unsupported compiler version. Secondly, a number of bugs have been fixed in this release.
  9. Well, but you tried to add these "members" from Python during the construction phase afterwards. /Philipp
  10. Quoting my earlier reply (emphasis added): "Otherwise, you can create a wrapper (or a derived class), with no own sc_object/sc_module members and construct the real SystemC module from within C++." The module/object hierarchy creation is closely related to the sc_module_name stack. Once the sc_module_name instance is destroyed (after the completion of your ExampleModule (base class) constructor), the "current module" is removed from this stack. Therefore, the ports you create afterwards can not be assigned to the correct module. Again, a workaround may be to create the ports via Python from within before_end_of_elaboration callback, where the module hierarchy is correctly restored without having a proper sc_module_name stack. The deprecated constructor comes from very old versions of SystemC (before the introduction of sc_module_name) and requires you to manually call the (similarly non-standard) function end_module after the creation of all sc_object members at the end of the constructor. Otherwise, your hierarchy will be messed up in case of multiple (nested) modules. I would not recommend this approach. Greetings from Oldenburg, Philipp
  11. As said before, you have to have an sc_module_name parameter in the (leaf) constructor of your module class hierarchy. Using the deprecated constructor will likely mess up your object hierarchy during elaboration. You can directly call such a constructor with a const char* argument, as you can implicitly construct an sc_module_name from a const char*. Maybe this is all you need. Otherwise, you can create a wrapper (or a derived class), with no own sc_object/sc_module members and construct the real SystemC module from within C++. hth, Philipp
  12. In your case, the Timer module (or a dedicated interrupt controller, wherever your "interrupt clear register" is located) would be responsible for actually writing to the interrupt signal. This can then be locally resolved to a single control process within the module. However, especially for interrupt signals, SC_MANY_WRITERS is a common use model. Note that SC_MANY_WRITERS is perfectly safe to use, because you are still not allowed to write to a signal from multiple processes in the same delta cycle (as that could lead to non-deterministic behaviour). /Philipp
  13. You can't let the second process write to the same signal (deassert) without using SC_MANY_WRITERS. (This wouldn't make much sense in real HW without additional logic either.) Solution: Restructure your design to have a single writer to each signal instead. Hard to be more specific with the available details. hth, Philipp
  14. Yes, the segmentation fault is caused by trying to access the terminated process instance (to format the error message), which has been deleted already. This problem will be fixed in the next public release of the Accellera proof-of-concept implementation. Thanks for your report, Philipp
  15. Why can't you just use a tlm_fifo instead, which already provides peek/poke? /Philipp
  16. Strictly speaking, it is your fault. Quoting 1666-2011, section 5.2.3 (sc_module, constraints on usage), emphasis mine: So the last variant posted by Ralph is the correct definition. /Philipp
  17. The events of an sc_signal are triggered during the update phase of the simulation. Therefore, you can't cancel the event from a SystemC process. What are you trying to achieve? Why are you sensitive to an sc_signal event, if you don't want to be triggered?
  18. You try to create a primitive channel (sc_signal, sc_fifo, ...) during the simulation. This is not allowed in SystemC. You have to create all of these channels during elaboration (i.e. before the simulation is started). hth, Philipp
  19. In SystemC, you can't partially change the (new) value of a signal. Instead, you can simply use a local temporary variable: sc_signal<des_struct> xyz,abc; des_struct tmp = xyz.read(); tmp.attrib = 4; abc.write(tmp); If you want to keep things in a single line, add a setter with a "fluent API" (i.e. returning the object itself) to the des_struct: class des_struct { public: // ... des_struct& set_attrib(uint16_t a) { attrib = a; return *this; } }; // allows: abc.write( des_struct(xyz.read()).set_attrib(4) ); hth, Philipp
  20. In general, it's perfectly fine to use sc_signal with a custom data type, provided that you have a properly defined comparison operator (and an sc_trace overload). In your case, I think your comparison operator is broken: In the code above, you update "end" with a != expression. This seems to be strange. Shouldn't this be ==? hth, Philipp
  21. It's documented in the IEEE Std. 1666-2011, downloadable at no cost at http://standards.ieee.org/getieee/1666/download/1666-2011.pdf (including SystemC and TLM-2.0). Greetings from Oldenburg, Philipp
  22. The templated SystemC datatypes all build upon a "dynamic bitwidth" implementation (e.g. sc_uint_base) that has its bitwidth set upon construction. The templates themselves only provide constructors (initializing the length of the base class), assignment operators, and related functions. It would of course be possible to add a static member to the sc_(big)(u)int templates to provide direct access to the template argument: template< int W > class sc_int : public sc_int_base { static const int static_length = W; // or some other name // ... }; For these classes, an external helper can be defined easily as well: template< typename T > struct number_traits; // undefined by default // specialization for SystemC integer datatypes template< int W > struct number_traits< sc_dt::sc_int<W> > { static const int length = W; }; // same for sc_uint, sc_bigint, ... But for true generic programming, the concatenation and range classes would require additional meta programming to make this fully usable. Secondly, as the base classes should provide access to the length() of the instances as well, this function would require to be declared virtual (as the base classes are non-templated). This would increase the size (and eventually the runtime cost) again. That said, if you're interested in bit true datatypes implemented with fully deduced widths etc., you might want to use the Mentor/Calypto "Algorithmic C datatypes", see http://calypto.com/en/products/catapult/overview/. Greetings from Oldenburg, Philipp
  23. Of course you can use members of your class without inheriting from their type. Otherwise, C++ would be an even stranger language than it is already, wouldnt it? Assuming that you do more than just forwarding the dut_input to the sc_output (by calling the write function) in your implementation, yes this can be seen as the right way. Indirectly, yes. You can bind the dut_input either to a port or to another export. As your class claimed to be "both", the compiler can't tell which bind function to call. /Philipp
  24. Why does your "eq_wrapper_top" inherit from an interface and a port? Maybe, you probably just want to drop the tlm_analysis_port<eq_transaction> base class. Or why do you need it? hth, Philipp
×
×
  • Create New...