DS1701 Posted December 13, 2018 Report Share Posted December 13, 2018 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. Quote Link to comment Share on other sites More sharing options...
David Black Posted December 13, 2018 Report Share Posted December 13, 2018 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 ); } Quote Link to comment Share on other sites More sharing options...
Roman Popov Posted December 14, 2018 Report Share Posted December 14, 2018 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. Quote Link to comment Share on other sites More sharing options...
DS1701 Posted December 14, 2018 Author Report Share Posted December 14, 2018 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 ; ... Roman Popov 1 Quote Link to comment Share on other sites More sharing options...
Roman Popov Posted December 14, 2018 Report Share Posted December 14, 2018 12 hours ago, TRANG said: resetPort.initialize(true); Nice, I didn't know such a method exists! Looks like it does what you want. DS1701 1 Quote Link to comment Share on other sites More sharing options...
David Black Posted December 15, 2018 Report Share Posted December 15, 2018 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. Depend on the underlying datatype's initial value to initialize the signal (not very flexible) If using the specialized ports (sc_out and sc_inout only), call the initialize(T) method. 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. DS1701 1 Quote Link to comment Share on other sites More sharing options...
DS1701 Posted December 17, 2018 Author Report Share Posted December 17, 2018 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. Depend on the underlying datatype's initial value to initialize the signal (not very flexible) If using the specialized ports (sc_out and sc_inout only), call the initialize(T) method. 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 Quote Link to comment Share on other sites More sharing options...
David Black Posted January 17, 2019 Report Share Posted January 17, 2019 [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. Quote Link to comment Share on other sites More sharing options...
Frank Poppen Posted July 24, 2019 Report Share Posted July 24, 2019 I'm reading this thread and successfully tried 'start_of_simulation' and 'initialize', but as I expected, this did not solve my issue. I want to build a SystemC transactor translating READ/WRITE-TLM to a RAM into RTL "bit wiggles". This part was no problem for me. I implemented a b_transport that is being called by the requesting module and this b_transport is assigning the intended values to my transactor's sc_out (ram_en, ram_rw, ram_addr, ...) But until the first TLM arrives, the sc_out are not initialized. If I use 'start_of_simulation' or 'initialize' than I create a second driver! One as part of my transactor and one more by the module that is making use of the b_transport. In other words: I cannot override the initial values and receive 'X' where the driven '1' and '0' collide. My plan is to have b_transport work on dedicated extra signals. My transactor initializes the sc_out (ram_en, ram_rw, ram_addr, ...). I will also implement another method, that shall be sensitive to the extra signals which will be toggled by b_transport. In this method I then assign the values of the signals to the sc_out. This way the driver to sc_out should be the transactor, only. QUESTIONS: Does it really have to be such a pain to implement a transactor by making use of such a mentioned method in between? And I did not try it yet, but I guess this should work? Quote Link to comment Share on other sites More sharing options...
Philipp A Hartmann Posted July 24, 2019 Report Share Posted July 24, 2019 4 hours ago, Frank Poppen said: But until the first TLM arrives, the sc_out are not initialized. If I use 'start_of_simulation' or 'initialize' than I create a second driver! One as part of my transactor and one more by the module that is making use of the b_transport. In other words: I cannot override the initial values and receive 'X' where the driven '1' and '0' collide. Won't you have multiple drivers anyway as soon as you have a second initiator accessing your transactor? I would recommend to switch your pin interface to use sc_export<sc_signal_*_if<T> > instead of plain signal ports and bind signals with an SC_MANY_WRITERS policy internally. These signals also have constructors that allow initialization to a non-zero value without triggering an event at the start of simulation. Quote Link to comment Share on other sites More sharing options...
Roman Popov Posted July 24, 2019 Report Share Posted July 24, 2019 I always change default policy to SC_MANY_WRITERS. In commercial simulators usually there is also a way to change default policy. In verification environments default SC_ONE_WRITER policy is violated way too often. It also does not work well with FORK/JOIN, when you spawn different threads in each test to generate stimulus on same set of ports. Quote Link to comment Share on other sites More sharing options...
Philipp A Hartmann Posted July 25, 2019 Report Share Posted July 25, 2019 Changing the default writer policy requires to be set consistently throughout the whole application, which might be difficult with third-party infeeds. Since SystemC 2.3.2, you can also set the environment variable SC_SIGNAL_WRITE_CHECK=CONFLICT, which effectively enables SC_MANY_WRITERS at runtime (for all signals, though). Quoting the release notes: - [2.3.2] Add support for SC_SIGNAL_WRITE_CHECK=CONFLICT Instead of disabling all runtime signal write checks via the environment setting SC_SIGNAL_WRITE_CHECK=DISABLE, setting the variable to SC_SIGNAL_WRITE_CHECK=CONFLICT allows detecting conflicting writes to a signal within a single evaluation phase (see INSTALL). Quote Link to comment Share on other sites More sharing options...
Frank Poppen Posted August 2, 2019 Report Share Posted August 2, 2019 On 7/24/2019 at 3:17 PM, Philipp A Hartmann said: Won't you have multiple drivers anyway as soon as you have a second initiator accessing your transactor? Oh, ... right I guess that would be true. Luckily, in my scenario I have just one initiator. Under this circumstances I was able to help myself with the second set of signals and the method inbetween as mentioned above. For the time being I will leave it the way it is. Once multiple initiators start to be relevant in our case I will definitely come back to your recommandation. Thanks for the help! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.