112855Sgabeblack@google.com#include "systemc.h"
212855Sgabeblack@google.com
312855Sgabeblack@google.comtypedef sc_biguint<121> atom;  // Value to be pipe delayed.
412855Sgabeblack@google.com
512855Sgabeblack@google.com//==============================================================================
612855Sgabeblack@google.com// esc_dpipe<T,N> - DELAY PIPELINE FOR AN ARBITRARY CLASS:
712855Sgabeblack@google.com//==============================================================================
812855Sgabeblack@google.comtemplate<class T, int N>
912855Sgabeblack@google.comSC_MODULE(esc_dpipe) {
1012855Sgabeblack@google.com  public:
1112855Sgabeblack@google.com    typedef sc_export<sc_signal_inout_if<T> > in;   // To pipe port type.
1212855Sgabeblack@google.com    typedef sc_export<sc_signal_in_if<T> >    out;  // From pipe port type.
1312855Sgabeblack@google.com
1412855Sgabeblack@google.com  public:
1512855Sgabeblack@google.com    SC_CTOR(esc_dpipe)
1612855Sgabeblack@google.com    {
1712855Sgabeblack@google.com        m_in(m_pipe[0]);
1812855Sgabeblack@google.com        m_out(m_pipe[N-1]);
1912855Sgabeblack@google.com        SC_METHOD(rachet);
2012855Sgabeblack@google.com        sensitive << m_clk.pos();
2112855Sgabeblack@google.com    }
2212855Sgabeblack@google.com
2312855Sgabeblack@google.com  protected:
2412855Sgabeblack@google.com    void rachet()
2512855Sgabeblack@google.com    {
2612855Sgabeblack@google.com        for ( int i = N-1; i > 0; i-- )
2712855Sgabeblack@google.com        {
2812855Sgabeblack@google.com            m_pipe[i].write(m_pipe[i-1].read());
2912855Sgabeblack@google.com        }
3012855Sgabeblack@google.com    }
3112855Sgabeblack@google.com
3212855Sgabeblack@google.com  public:
3312855Sgabeblack@google.com    sc_in_clk m_clk;  // Pipe synchronization.
3412855Sgabeblack@google.com    in        m_in;   // Input to delay pipe.
3512855Sgabeblack@google.com    out       m_out;  // Output from delay pipe.
3612855Sgabeblack@google.com
3712855Sgabeblack@google.com  protected:
3812855Sgabeblack@google.com    sc_signal<T> m_pipe[N]; // Pipeline stages.
3912855Sgabeblack@google.com};
4012855Sgabeblack@google.com
4112855Sgabeblack@google.com
4212855Sgabeblack@google.com// Testbench reader of values from the pipe:
4312855Sgabeblack@google.com
4412855Sgabeblack@google.comSC_MODULE(Reader)
4512855Sgabeblack@google.com{
4612855Sgabeblack@google.com    SC_CTOR(Reader)
4712855Sgabeblack@google.com    {
4812855Sgabeblack@google.com        SC_METHOD(extract)
4912855Sgabeblack@google.com        sensitive << m_clk.pos();
5012855Sgabeblack@google.com        dont_initialize();
5112855Sgabeblack@google.com    }
5212855Sgabeblack@google.com
5312855Sgabeblack@google.com    void extract()
5412855Sgabeblack@google.com    {
5512855Sgabeblack@google.com        cout << sc_time_stamp() << ": " << m_from_pipe.read() << endl;
5612855Sgabeblack@google.com    }
5712855Sgabeblack@google.com
5812855Sgabeblack@google.com    sc_in_clk    m_clk;         // Module synchronization.
5912855Sgabeblack@google.com    sc_in<atom > m_from_pipe;   // Output from delay pipe.
6012855Sgabeblack@google.com};
6112855Sgabeblack@google.com
6212855Sgabeblack@google.com
6312855Sgabeblack@google.com
6412855Sgabeblack@google.com// Testbench writer of values to the pipe:
6512855Sgabeblack@google.com
6612855Sgabeblack@google.comSC_MODULE(Writer)
6712855Sgabeblack@google.com{
6812855Sgabeblack@google.com    SC_CTOR(Writer)
6912855Sgabeblack@google.com    {
7012855Sgabeblack@google.com        SC_METHOD(insert)
7112855Sgabeblack@google.com        sensitive << m_clk.pos();
7212855Sgabeblack@google.com        m_counter = 0;
7312855Sgabeblack@google.com    }
7412855Sgabeblack@google.com
7512855Sgabeblack@google.com    void insert()
7612855Sgabeblack@google.com    {
7712855Sgabeblack@google.com        m_to_pipe.write(m_counter);
7812855Sgabeblack@google.com        m_counter++;
7912855Sgabeblack@google.com    }
8012855Sgabeblack@google.com
8112855Sgabeblack@google.com    sc_in_clk       m_clk;       // Module synchronization.
8212855Sgabeblack@google.com    atom            m_counter;   // Write value.
8312855Sgabeblack@google.com    sc_inout<atom > m_to_pipe;   // Input for delay pipe.
8412855Sgabeblack@google.com};
8512855Sgabeblack@google.com
8612855Sgabeblack@google.com// Main program
8712855Sgabeblack@google.com
8812855Sgabeblack@google.comint sc_main(int argc, char* argv[])
8912855Sgabeblack@google.com{
9012855Sgabeblack@google.com    sc_clock          clock;
9112855Sgabeblack@google.com    esc_dpipe<atom,4> delay("pipe");
9212855Sgabeblack@google.com    Reader            reader("reader");
9312855Sgabeblack@google.com    Writer            writer("writer");
9412855Sgabeblack@google.com
9512855Sgabeblack@google.com    delay.m_clk(clock);
9612855Sgabeblack@google.com
9712855Sgabeblack@google.com    reader.m_clk(clock);
9812855Sgabeblack@google.com    reader.m_from_pipe(delay.m_out);
9912855Sgabeblack@google.com
10012855Sgabeblack@google.com    writer.m_clk(clock);
10112855Sgabeblack@google.com    writer.m_to_pipe(delay.m_in);
10212855Sgabeblack@google.com
10312855Sgabeblack@google.com    sc_start(50, SC_NS);
10412855Sgabeblack@google.com
10512855Sgabeblack@google.com    return 0;
10612855Sgabeblack@google.com}
107