Jump to content
TRANG

Initial value port

Recommended Posts

Hi all,

sc_in<type> input;
sc_out<type> output;
sc_signal<type> signal;

Do you need set Initial value ( use write(0); ) for output and signal port  or it auto set 0 when declare?

Thank all. 

Share this post


Link to post
Share on other sites

Ports do not hold values. Ports are simply references to channels. Ports provide a means to access a channel.

sc_signal is simply a type of channel. This particular channel supports several methods including read() and write(), which are used to obtain (get) and alter (set) the state (attribute) of the channel.

You can use these methods signal directly:

type value; //< local storage
...
  signal.write( value );
...
  value = signal.read();

Or if the channel is located outside your module, you should access the methods via port connections thus:

output->write( value );
...
value = input->read();

Because the connectivity is not fully established until after elaboration is completed, you generally cannot provide an initial value during construction of an external channel from inside a module. Also, the signal method takes advantage of the update phase of the simulator and should only be accessed at start of simulation.

Therefore, the proper way to initialize a "port" is to write to the corresponding signal a the start of simulation by overriding the so-called callback method start_of_simulation():

SC_MODULE( MyModule )
{
  ...
  void start_of_simulation( void ) override;
};

Implementation:

void MyModule::start_of_simulation( void )
{
  output->write( initial_value );
}

 

Share this post


Link to post
Share on other sites

In addition to what David said.

 

Quote

Do you need set Initial value ( use write(0); ) for output and signal port  or it auto set 0 when declare?

Here is what SystemC standard says:

Quote

6.4.5 Constructors
sc_signal();    
explicit sc_signal( const char* name_ );   

Both constructors shall initialize the value of the signal by calling the default constructor for type T from their initializer lists.

So SystemC standard guarantees that signal value is initialized by default constructor. So for example sc_signal<int> is guaranteed to be initialized with 0.

Accellera SystemC also supports passing initial value as a second constructor parameter:

sc_signal<int>  int_signal{"int_signal", 42}; // Initialized to 42

Looks like this feature is not part of IEEE standard yet.

As David noted, ports in SystemC have no value, they behave more like a pointers to channels. So "value" of port always equals to value of binded channel.

 

Share this post


Link to post
Share on other sites

Thank @David Black and @Roman Popov

Thank you so much!!!

But I think that, initialize the value depend on specification model require.

Ex:  Model A can reset Model B  with reset port active with LOW level

Then sc_out<bool> resetPort; in the Model A must be set initialize the value for resetPort is 1 on constructor

So I think that , Should set initialize the value of port on constructor

 -->  Clearly

-->  Easy maintain source code

/
//A.h
class A: public sc_module
{

public:
    sc_in<bool>     clkAPM;
    sc_out<bool>    resetPort;
    sc_signal<bool> sig;
...
///A.cpp
A::A(sc_module_name name)
        :sc_module(name)
	    // Initializing
        ,clkAPM("clkAPM")
        ,resetPort("resetPort")
        ,sig("sig")
{//{{{ 
    /// Initializing

    resetPort.initialize(true);
    sig.write(true);

    SC_METHOD(AMethod);
    dont_initialize();
    sensitive << sig ;
...

 

Share this post


Link to post
Share on other sites

The 'initialize(T)' method is a leftover from SystemC 1.0 circa 1999, when SystemC had not yet properly abstracted the port/channel concept. At that point in time, there was a stronger emphasis on making SystemC look like Verilog or VHDL. The 'initialize(T)' method is only present on the 'sc_out<T>' and 'sc_inout<T>' port classes, as part of their partial template specialization. The 'initialize(T)' method is not generally available to 'sc_port<>'.

I usually don't mention it because then the reader gets the wrong impression that 'initialize(T)' should be present everywhere. In fact, it is only useful for RTL aspects. Certainly, this is not part of TLM.

Since SystemC is more about abstraction and modeling, I avoid it. It is straightforward to override start_of_simulation.

@TRANGIt is important for you to understand this distinction. I realize that the specification may say that "port is initialized to zero" or some such, but the concept of port in the specification is quite different than the concept of port in SystemC. If you don't understand this, you will hobble your understanding of SystemC. So there are three ways in SystemC of modeling what the specification says regarding an output pin on a hardware design.

  1. Depend on the underlying datatype's initial value to initialize the signal (not very flexible)
  2. If using the specialized ports (sc_out and sc_inout only), call the initialize(T) method.
  3. Write to the port during start_of_simulation, which is the most general and powerful approach.

Challenge: How would you initialize an sc_fifo< float > connected to an sc_fifo< float > channel with four values?

#include <systemc>
#include <list>
#include <iostream>
using namespace sc_core;
using namespace std;
SC_MODULE( Source ) {
  sc_fifo_out< float > send_port;
  SC_CTOR( Source ) {
    SC_THREAD( source_thread );
  }
  void source_thread( void ) {
    wait( 10, SC_NS );
    send_port->write( 99.7 );
    wait( 10, SC_NS );
    std::cout << "Finished" << std::endl;
    sc_stop();
  }
  // How to initialize output to contain following initial values?
  // { 4.2, -8.3e9, 0.0, 3.14 }
  // Do not add this to the thread. Instead, ensure that it happens before any thread executes.
  }
};

SC_MODULE( Sink ) {
  sc_fifo_in< float > receive_port;
  SC_CTOR( Sink ) {
    SC_THREAD( sink_thread );
  };
  void sink_thread( void ) {
    for(;;) {
      std::cout 
        << "Received " << setw(12) << receive_port->read() 
        << " at " << sc_time_stamp() 
        << std::endl;
    }
  }
};

SC_MODULE( Top ) {
  // Constructor
  SC_CTOR( Top ) {
    m_source.send_port .bind( m_fifo );
    m_sink.receive_port.bind( m_fifo );
  }
  // Local modules
  Source           m_source { "source" };
  Sink             m_sink   { "sink"   };
  // Local channels
  sc_fifo< float > m_fifo;
};

int sc_main( int argc, char* argv[] ) {
  Top top { "top" };
  sc_start();
  return 0;
}

Key concepts:

  • SystemC is a modeling language mapped on top of C++.
  • SystemC ports are not signals or pins.
  • sc_in<T>, sc_out<T> and sc_inout<T> are partial template specializations of sc_port<T> on the respective sc_signal<T> interface classes.
  • For historic reasons (SystemC 1.0), there are extra methods added to these specializations including initialize(T), read(), and write(T) that can later confuse novice SystemC programmers.

Share this post


Link to post
Share on other sites
On 12/15/2018 at 7:24 PM, David Black said:

The 'initialize(T)' method is a leftover from SystemC 1.0 circa 1999, when SystemC had not yet properly abstracted the port/channel concept. At that point in time, there was a stronger emphasis on making SystemC look like Verilog or VHDL. The 'initialize(T)' method is only present on the 'sc_out<T>' and 'sc_inout<T>' port classes, as part of their partial template specialization. The 'initialize(T)' method is not generally available to 'sc_port<>'.

I usually don't mention it because then the reader gets the wrong impression that 'initialize(T)' should be present everywhere. In fact, it is only useful for RTL aspects. Certainly, this is not part of TLM.

Since SystemC is more about abstraction and modeling, I avoid it. It is straightforward to override start_of_simulation.

@TRANGIt is important for you to understand this distinction. I realize that the specification may say that "port is initialized to zero" or some such, but the concept of port in the specification is quite different than the concept of port in SystemC. If you don't understand this, you will hobble your understanding of SystemC. So there are three ways in SystemC of modeling what the specification says regarding an output pin on a hardware design.

  1. Depend on the underlying datatype's initial value to initialize the signal (not very flexible)
  2. If using the specialized ports (sc_out and sc_inout only), call the initialize(T) method.
  3. Write to the port during start_of_simulation, which is the most general and powerful approach.

Challenge: How would you initialize an sc_fifo< float > connected to an sc_fifo< float > channel with four values?

Key concepts:

  • SystemCis a modeling language mapped on top of C++.
  • SystemC ports are not signals or pins.
  • sc_in<T>, sc_out<T> and sc_inout<T> are partial template specializations of sc_port<T> on the respective sc_signal<T> interface classes.
  • For historic reasons (SystemC 1.0), there are extra methods added to these specializations including initialize(T), read(), and write(T) that can later confuse novice SystemC programmers.

I usually don't use sc_fifo ( only use sc_signal, sc_in, sc_out ). But I don't see any function  initialize the value for sc_fifo . Both "write()" and "nb_write()" (sc_fifo) will call to sc_prim_channel::request_update() . So I think , sc_fifo can set value for buffer ( this isn't called initialize the value forbuffer )

Thank you so much!!! @David Black

Share this post


Link to post
Share on other sites

[Sorry for delay. For some reason I was not notified of your reply.]

The point of my challenge was that you would not initialize the FIFO beyond allowing to come up empty. At least I have never see a FIFO that would be pre-filled.

At start_of_simulation, you can initialize all you want as long as you can do everything within a single delta cycle. Hence you can write signals and fffos. Effectively, start_of_simulation is when activity is allowed to start happening.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×