Search code examples
c++systemcgtkwave

How can I check the difference between sc_buffer and sc_signal?


I would like to check the difference between using sc_buffer and sc_signal. I have coded a module which adds two random numbers and then I run two tests in parallel: one using sc_buffer and the other using sc_signal. Nevertheless, when I check with gtkwave I see the same traces for both examples, so I think for this case there should not be any difference. How can I check the difference? or is it that these two different types of channel are intended for different applications?


Solution

  • sc_buffer is probably most useful when modeling at an abstract level.

    For example, consider modeling a serial communication channel. The transmitter could send the same character twice in a row. If an sc_signal was used as the channel, the receiver wouldn't detect the second character, but with an sc_buffer, it would.

    #include <systemc>
    #include <iostream>
    
    using namespace sc_core;
    using namespace std;
    
    struct Transmitter : public sc_module {
    
        sc_out<char> out;
    
        Transmitter(sc_module_name name) : sc_module(name) {
            SC_THREAD(transmit);
        }
    
        void transmit() {
            wait(1, SC_NS);
            out.write('x');
    
            wait(1, SC_NS);
            out.write('x');
    
            wait(1, SC_NS);
            out.write('y');
        };
    
        SC_HAS_PROCESS(Transmitter);
    };
    
    struct Receiver : public sc_module {
    
        sc_in<char> in;
    
        Receiver(sc_module_name name) : sc_module(name) {
            SC_METHOD(receive);
            sensitive << in;
            dont_initialize();
        }
    
        void receive() {
            cout << sc_time_stamp() << ": " << name() << " received "
                 << in.read() << endl;
        }
    
        SC_HAS_PROCESS(Receiver);
    };
    
    int sc_main(int argc, char* argv[])
    {
        sc_signal<char> signal;
        sc_buffer<char> buffer;
    
        Transmitter signal_transmitter("signal_transmitter");
        Receiver signal_receiver("signal_receiver");
        Transmitter buffer_transmitter("buffer_transmitter");
        Receiver buffer_receiver("buffer_receiver");
    
        signal_transmitter.out(signal);
        signal_receiver.in(signal);
    
        buffer_transmitter.out(buffer);
        buffer_receiver.in(buffer);
    
        sc_start();
    
        return 0;
    }
    

    The above example produces this output:

    1 ns: signal_receiver received x
    1 ns: buffer_receiver received x
    2 ns: buffer_receiver received x
    3 ns: signal_receiver received y
    3 ns: buffer_receiver received y
    

    Notice that signal_receiver didn't detect the character sent at 2 ns.

    You won't see any difference in a VCD trace, because the values stored in the sc_buffer and sc_signal channels are identical. The difference is when the receiver is triggered.