www.pudn.com > noc.rar > oarbiter.cpp
/*
* TU Eindhoven
* Eindhoven, The Netherlands
*
* Name : oarbiter.cpp
*
* Author : A.S.Slusarczyk@tue.nl
*
* Date : 13-09-2003
*
* Function : Link access arbiter for e-cube router
*
*
*/
#include "oarbiter.h"
void ARBITER_CHANNEL_CTRL::logic()
{
bool reqout_v, arb_req_v;
reqout_v = false;
arb_req_v = false;
next_state = IDLE;
switch(current_state.read())
{
case IDLE:
// wait for queue to request channel
if( reqin.read() ){
next_state = REQUEST_CHANNEL;
arb_req_v = true; // request link from arbiter
}
else
next_state = IDLE;
break;
case REQUEST_CHANNEL:
// wait for arbiter to grant the link
arb_req_v = true;
if( arb_grant.read() ){
// link was granted - the data will be output on the link
// output request to the network
reqout_v = true;
next_state = WAIT_REQ_OFF;
}
else{
arb_req_v = true;
next_state = REQUEST_CHANNEL;
}
break;
case WAIT_REQ_OFF:
// wait for queue to withdraw req
if( reqin.read() ) {
reqout_v = true;
next_state = WAIT_REQ_OFF;
}
else
next_state = IDLE;
break;
}
reqout.write(reqout_v);
arb_req.write(arb_req_v);
}
void ARBITER_CHANNEL_CTRL::change_state()
{
if( rst.read() )
current_state = IDLE;
else
current_state = next_state;
}
// ack received from the network is permanently forwarded to the queue
void ARBITER_CHANNEL_CTRL::forward_ack()
{
ackout.write( ackin.read() );
}
void ARBITER_SELECT_CHANNEL::select()
{
bool r0 = req0.read(), r1 = req1.read();
bool ch_bsy = channel_busy.read();
if( ch_bsy ){
// if link is busy and the requesting channel has withdrawn request
// - free the link
if( selected_channel.read() && !r1
||
!selected_channel.read() && !r0
)
ch_bsy = false;
}
if( !ch_bsy )
{
// link is free - assign it to a requesting channel
if( r0 ) { // ch0 has priority
selected_channel.write(false);
ch_bsy = true;
}
else if( r1 ){
selected_channel.write(true);
ch_bsy = true;
}
}
channel_busy.write( ch_bsy );
}
void ARBITER_SELECT_CHANNEL::output()
{
// multiplex virtual channel data on the link
dataout.write( selected_channel.read() ? data1.read() : data0.read() );
// grant link
grant0.write( channel_busy.read() && ! selected_channel.read() );
grant1.write( channel_busy.read() && selected_channel.read() );
}