/*
 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * OutputUnit_d.hh
 *
 * Niket Agarwal, Princeton University
 *
 * */

#ifndef OUTPUT_UNIT_D_H
#define OUTPUT_UNIT_D_H

#include "mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/flitBuffer_d.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh"

class Router_d;

class OutputUnit_d : public Consumer {
public:
        OutputUnit_d(int id, Router_d *router);
        ~OutputUnit_d();
        void set_out_link(NetworkLink_d *link);
        void set_credit_link(CreditLink_d *credit_link);
        void wakeup();
        flitBuffer_d* getOutQueue();
        void printConfig(ostream& out);
        void update_vc(int vc, int in_port, int in_vc);
        void print(ostream& out) const {};
        int get_credit_cnt(int vc) { return m_outvc_state[vc]->get_credit_count(); }
        void decrement_credit(int out_vc);

        inline int get_outlink_id()
        {
                return m_out_link->get_id();
        }

        inline void set_vc_state(VC_state_type state, int vc)
        {
                m_outvc_state[vc]->setState(state, g_eventQueue_ptr->getTime() + 1);
        }
        inline bool is_vc_idle(int vc)
        {
                return (m_outvc_state[vc]->isInState(IDLE_, g_eventQueue_ptr->getTime())        );
        }
        inline void insert_flit(flit_d *t_flit)
        {
                m_out_buffer->insert(t_flit);
                g_eventQueue_ptr->scheduleEvent(m_out_link, 1);
        }



private:
        int m_id;
        int m_num_vcs;
        Router_d *m_router;
        NetworkLink_d *m_out_link;
        CreditLink_d *m_credit_link;

        flitBuffer_d *m_out_buffer; // This is for the network link to consume
        Vector<OutVcState_d *> m_outvc_state; // vc state of downstream router

};

#endif
