Jump to content


Popular Content

Showing content with the highest reputation on 05/04/2018 in all areas

  1. 1 point
    David Black

    serial transmission

    [I assume that when you say "TLM", you mean SystemC TLM 2.0.] You need to understand the difference between modeling styles. TLM is precisely about not modeling at the level of RTL. The SystemC TLM 2.0 also has two different modeling styles: Loosely Timed (LT) and Approximately Timed (AT). Let's look at each using a specific case. Suppose you are modeling two UARTs operating at 9600 baud (bits per second) with 8-bits, no parity, and 1 stop bit to transfer the message "Hello World\n". This configuration results in 960 characters per second (1.042 ms/char), which is quite slow, so probably you would be transmitting/receiving characters slowly enough that most systems would either process them one at a time or provide a FIFO (e.g. 16 bytes) and only process empty/full events. There is one more question to answer though. Consider the diagram below. The connections between sender to UART and UART to receiver are clearly memory mapped for most systems. So there is no question of modeling. The connection UART to UART is not memory mapped, which means you need to create a custom protocol. Furthermore, for TLM, it actually requires to connections since communication can be invoked bi-directionally (for a full UART). You need to decide what is important to model. For a high level model and efficiency, I would either transfer as much data as I could. It might even make sense to use TLM 1.0 rather than TLM 2.0. Do you have the requirement to inject errors? For my example, you would configure the transmitter, and then transfer a burst of 12 characters into the transmit FIFO on one end of the transfer and generate an empty FIFO interrupt at 12.5 ms later. The receiver side would be similar. What about the UART/UART transaction? An efficient approach might be as follows: Create a required extension that carries the transmit configuration information (baud rate, bits, parity, etc.) Use TLM_WRITE_COMMAND because all transactions over this socket pair are initiated from the sender. The second pair in the opposite direction would do the same thing. Check and insist that the address always be 0 and the streaming width is 1. Byte enables would be illegal. Check that the configuration matches before accepting data. Place all received data into an unbounded queue and then indicate the size allowed by the hardware model. Send interrupts using the sc_signal when the received queue goes non-empty. Consider the error situation when the timing indicates characters would be lost due to FIFO full and timing of characters. You will have to decide how to deal with interrupts received in your thread process. Notice that I do not model at the bit level. If you wish to add bit-level error injection, then inject errors at the point of transmission.
  2. 1 point
    David Black

    Changing the width in sc_bv<W>

    These questions have little to do with SystemC per se, and are really about C++. Templates are all about compile-time elaboration and template arguments must be compile-time computable. If you use C++11 or later, then various forms of constexpr functions may be available, but they are still compile-time issues. You could of course use sc_bv_base and its constructors, but keep in mind that modules, ports, and other "hardware" constructs are not allowed to be modified after end_of_elaboration. KEY POINT: To be an effective SystemC designer, you MUST be proficient at C++. Minimal C++ is NOT enough. Knowledge of C (even expert knowledge) is totally inadequate and in some cases downright harmful. Furthermore, really good SystemC often requires excellent C++ skills. Therefore, before you even consider learning much in SystemC, you really should invest in a solid C++ course. Expert SystemC practitioners take time to continually update their C++ skills. If this does not sound like fun to you, then I would advise choosing a different discipline.
  3. 1 point

    Changing the width in sc_bv<W>

    In many cases , I cant use "const" I often use : #define or enum{}; you can try : #define WDW_SIZE 2 or enum {WDW_SIZE=2}; Best regards
  4. 1 point

    Changing the width in sc_bv<W>

    Hi Karthik, you need to provide a constant expression as template argument so that it can be evaluated at compilation time. See http://en.cppreference.com/w/cpp/language/constant_expression. and http://en.cppreference.com/w/cpp/language/template_parameters#Template_non-type_arguments. So it would need to be written as: const int WDW_SIZE = 2; Best regards -Eyck
  5. 1 point

    TLM payload extension declaration

    Dear all, I am new to payload extensions and I would appreciate a feedback on whether I am doing things right.. I need to declare a simple payload extension, including two additional fields: a reset value a 16 bit bit vector representing the value of a register In the header, I simply declare the clone/copy from functions, plus my additional fields: class reg_extension : public tlm::tlm_extension<reg_extension>{ public: reg_extension(); tlm::tlm_extension_base* clone() const ; void copy_from(tlm::tlm_extension_base const &); bool reset; sc_bv<16> value; }; And then I implemented the functions, by taking care of the additional reset and value fields: reg_extension::reg_extension(){ reset = false; value = sc_bv<16>(0); } tlm::tlm_extension_base * reg_extension::clone() const{ cout<<"Executing clone!"<<endl; reg_extension * ext = new reg_extension(); ext->reset = this->reset; ext->value = this->value; return ext; } void reg_extension::copy_from(tlm::tlm_extension_base const & ext){ reset = static_cast<reg_extension const &>(ext).reset; value = static_cast<reg_extension const &>(ext).value; } Is this enough for the extension to work? Best regards, S.
  6. 1 point
    In general: Yes, this implementation is sufficient to implement a TLM2 extension. Still, there is a more reliable pattern to implement the copy_from and clone methods by using the copy constructor and assignment operator of your extension type (which you may need to implement in some cases anyway and will be provided for free in your particular example): class reg_extension : public tlm::tlm_extension<reg_extension> { public: tlm::tlm_extension_base* clone() const { return new reg_extension(*this); } // use copy constructor void copy_from(tlm::tlm_extension_base const & that ) { *this = static_cast<const reg_extension&>(that); } // use assignment operator // ... }; This pattern works very well for all Copyable and CopyAssignable classes without having to enumerate the members in clone and copy_from. Hope that helps, Philipp