inctrl.cpp
来自「基于4个mips核的noc设计」· C++ 代码 · 共 229 行
CPP
229 行
/* * TU Eindhoven * Eindhoven, The Netherlands * * Name : inctrl.cpp * * Author : A.S.Slusarczyk@tue.nl * * Date : 13-09-2003 * * Function : Input controller of the e-cube router * * */#include "inctrl.h"void INPUT_CTRL::dlatch(){ if( latch.read() )
data_latch.write(data.read());}void INPUT_CTRL::control_logic(){ bool ack_v, out_req_v, header_select_v, request_switch_v, latch_v; ack_v = false; out_req_v = false; header_select_v = false; request_switch_v = false; latch_v = false; next_state = IDLE; switch( current_state.read() ) { case IDLE: // waiting for a next packet to start if( req.read() ) { latch_v = true; next_state = OPEN; header_select_v = true; } else next_state = IDLE; break; case OPEN: // opening connection and forwarding header flit#ifdef ROUTEPRINT cout << name() << " got start of packet " << hex << data_latch.read().to_uint() << dec << " (addr=" << data_latch.read().range(15,8).to_uint() << ',' << data_latch.read().range(7,0).to_uint() << ") @" << sc_time_stamp() << endl;#endif request_switch_v = true; header_select_v = true; ack_v = out_ack.read(); out_req_v = req.read(); if( out_ack.read() ){ next_state = WAIT_ACK; } else{ next_state = OPEN; } break; case WAIT_ACK: request_switch_v = true; if( out_ack.read() ) next_state = WAIT_ACK; else next_state = NEXT; break; case NEXT: request_switch_v = true; // waiting for next flit of the packet if( req.read() ) { next_state = SEND; header_select_v = false; latch_v = true; //ack_v = out_ack.read(); //out_req_v = req.read(); } else { next_state = NEXT; } break; case SEND: // sending a flit#ifdef ROUTEPRINT cout << name() << " got flit 0x" << hex << data_latch.read().to_uint() << dec << " @" << sc_time_stamp() << endl;#endif request_switch_v = true; header_select_v = false; ack_v = out_ack.read(); out_req_v = req.read(); if( out_ack.read() ){ // flit was acknowledged if( end_of_packet.read() ) // it's EOP, go idle next_state = WAIT_END; else // not a last flit - wait for the next next_state = WAIT_ACK; } else{ // waiting for ACK next_state = SEND; } break; case WAIT_END: request_switch_v = true; if( out_ack.read() ) next_state = WAIT_END; else next_state = IDLE; break; } ack.write(ack_v); out_req.write(out_req_v); header_select.write(header_select_v); request_switch.write(request_switch_v); latch.write(latch_v);}void INPUT_CTRL::control_change_state(){ if( rst.read() ) current_state = IDLE; else current_state = next_state;}void INPUT_CTRL::route_select(){ sc_uint<ADDRESS_LEN> my_addr = my_address.read(); sc_bv<FLIT_LEN> d = (latch.read() ? data.read() : data_latch.read() ); sc_bv<ADDRESS_LEN> bvaddr = d.range(X_ADDR_START,X_ADDR_START-ADDRESS_LEN+1); sc_uint<ADDRESS_LEN> still_to_go = bvaddr; out_select_n = 0; if( still_to_go == 0 ){ // end-of-route - direct packet to data processor (or next dim. router) out_select_n = 3; } else if( (my_addr == 0 && ch0.read()) || ch1.read() ){ // this is zero-channel of 0-router - switch to channel #1 // also if packet is on 1-channel, it will stay on it out_select_n = 2; } else { // otherwise - route to output channel 0 out_select_n = 1; } }void INPUT_CTRL::switch_out_select(){ if( header_select.read() ) out_select.write(out_select_n.read());}void INPUT_CTRL::header_adjust(){ // all of this is irrelevant if it's not the header flit, but this decision // is made by data_select // extract flit type and x-address and y-address sc_bv<FLIT_TYPE_LEN> bFT = data_latch.read().range(FT_START,FT_START-FLIT_TYPE_LEN+1); sc_bv<8> bXA = data_latch.read().range(X_ADDR_START,X_ADDR_START-ADDRESS_LEN+1), bYA = data_latch.read().range(Y_ADDR_START,Y_ADDR_START-ADDRESS_LEN+1); sc_uint<FLIT_TYPE_LEN> flit_type = bFT; sc_uint<ADDRESS_LEN> xaddr = bXA, yaddr = bYA; sc_bv<ADDRESS_LEN> bXAout, bYAout; sc_uint<ADDRESS_LEN> xaddr_out, yaddr_out; if( xaddr == 0 ){ // if it's end of route, strip x address and replace it with y address end_of_route.write(true); xaddr_out = yaddr; yaddr_out = 0; } else{ // otherwise, decrement the address end_of_route.write(false); xaddr_out = xaddr-1; yaddr_out = yaddr; } // recognize flit type switch( flit_type ){ case 1 : start_of_packet.write(true); end_of_packet.write(false); break; case 2 : start_of_packet.write(false); end_of_packet.write(true); break; default : start_of_packet.write(false); end_of_packet.write(false); break; }; // construct the output flit bXAout = xaddr_out; bYAout = yaddr_out; sc_bv<FLIT_LEN> hout; hout.range(FT_START,FT_START-FLIT_TYPE_LEN+1) = bFT; hout.range(X_ADDR_START,X_ADDR_START-ADDRESS_LEN+1) = bXAout; hout.range(Y_ADDR_START,Y_ADDR_START-ADDRESS_LEN+1) = bYAout; header.write( hout );}void INPUT_CTRL::data_select(){ if( header_select.read() ) data_out.write( header.read() ); else data_out.write( data_latch.read() );}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?