www.pudn.com > noc.rar > oarbiter.h


/*
 *  TU Eindhoven
 *  Eindhoven, The Netherlands
 *
 *  Name            :   oarbiter.h
 *
 *  Author          :   A.S.Slusarczyk@tue.nl
 *
 *  Date            :   13-09-2003
 *
 *  Function        :   Link access arbiter for e-cube router
 *
 *
 */


#ifndef OARBITER_H_INCLUDED
#define OARBITER_H_INCLUDED

#include 
#include "net_dim.h"

// channel controller for a single virtual channel
SC_MODULE(ARBITER_CHANNEL_CTRL)
{
  sc_in< bool > clk, rst;
  // two sets of req/ack - from the associated output queue and the network
  sc_in< bool > reqin, ackin;
  sc_out< bool > reqout, ackout;
  
  sc_out< bool > arb_req;  // arbiter link request
  sc_in< bool > arb_grant; // arbiter link grant
  
  enum state { IDLE, REQUEST_CHANNEL, WAIT_REQ_OFF };
#ifdef VERILOG
  sc_signal current_state, next_state;
#else
  sc_signal current_state, next_state;
#endif
  
  // FSM
  void logic();
  void change_state();
  
  // ack received from the network is permanently forwarded to the queue
  void forward_ack();
  
  SC_CTOR(ARBITER_CHANNEL_CTRL){
	SC_METHOD(logic);
	sensitive << current_state << reqin << arb_grant;

	SC_METHOD(change_state);
	sensitive_pos << clk << rst;

	SC_METHOD(forward_ack);
	sensitive << ackin;
  }
};


// link request arbitration
SC_MODULE(ARBITER_SELECT_CHANNEL)
{
  sc_in clk;
  sc_in req0, req1;
  sc_out grant0, grant1;
  
  sc_in< sc_bv > data0, data1;
  sc_out< sc_bv > dataout;
  
  // is link busy?
  sc_signal channel_busy;
  // if busy, which channel is using it?
  sc_signal selected_channel;
  
  void select();
  void output();
  
  SC_CTOR(ARBITER_SELECT_CHANNEL){
	SC_METHOD(select);
	sensitive_pos << clk;

	SC_METHOD(output);
	sensitive << req0 << req1 << data0 << data1 << channel_busy << selected_channel;
  }
};


// RTL arbiter module - connects two channel controllers with the link arbiter
SC_MODULE(OUTPUT_ARBITER)
{
  sc_in< bool > clk, rst;
  
  sc_in< sc_bv > data0, data1;
  sc_in< bool > req0in, req1in;
  sc_out< bool > ack0out, ack1out;
  
  sc_out< sc_bv > data;
  sc_out< bool > req0out, req1out;
  sc_in< bool > ack0in, ack1in;
  
  ARBITER_CHANNEL_CTRL *ch0ctrl, *ch1ctrl;
  ARBITER_SELECT_CHANNEL *arbiter;
  
  sc_signal arb_req0, arb_req1, arb_grant0, arb_grant1;
  
  SC_CTOR(OUTPUT_ARBITER)
	{
	  ch0ctrl = new ARBITER_CHANNEL_CTRL("ch0ctrl");
	  ch1ctrl = new ARBITER_CHANNEL_CTRL("ch1ctrl");
	  arbiter = new ARBITER_SELECT_CHANNEL("arbiter");
	  
	  ch0ctrl->clk(clk); ch0ctrl->rst(rst);
	  ch0ctrl->reqin( req0in ); ch0ctrl->reqout( req0out );
	  ch0ctrl->ackin( ack0in ); ch0ctrl->ackout( ack0out );
	  ch0ctrl->arb_req( arb_req0 ); ch0ctrl->arb_grant( arb_grant0 );
	  
	  ch1ctrl->clk(clk); ch1ctrl->rst(rst);
	  ch1ctrl->reqin( req1in ); ch1ctrl->reqout( req1out );
	  ch1ctrl->ackin( ack1in ); ch1ctrl->ackout( ack1out );
	  ch1ctrl->arb_req( arb_req1 ); ch1ctrl->arb_grant( arb_grant1 );
	  
	  arbiter->clk(clk);
	  arbiter->data0( data0 ); arbiter->data1( data1 );
	  arbiter->dataout( data );
	  arbiter->req0( arb_req0 ); arbiter->req1( arb_req1 );
	  arbiter->grant0( arb_grant0 ); arbiter->grant1( arb_grant1 );
	}
};

#endif