netif.cpp
来自「基于4个mips核的noc设计」· C++ 代码 · 共 275 行
CPP
275 行
/* * TU Eindhoven * Eindhoven, The Netherlands * * Name : netif.cpp * * Author : A.S.Slusarczyk@tue.nl * * Date : 15-09-2003 * * Function : Generic network interface module for the network of Ecube routers * * */#include "netif.h"// buffering packet data to sendvoid NETWORK_INTERFACE::buffer_out_process(){ if( rst.read() ) buffer_out.write(0); else if( write_data.read() ) buffer_out.write(reg_data_in);}// buffering destination address for the packetvoid NETWORK_INTERFACE::buffer_addr_process(){ sc_bv<2*ADDRESS_LEN> addr = reg_data_in.read().range(2*ADDRESS_LEN-1,0); if( rst.read() ) buffer_addr.write(0); else if( write_addr.read() ) buffer_addr.write(addr);}// FSM sending a packetvoid NETWORK_INTERFACE::send_logic(){ bool req_out_v, send_rdy_v; sc_bv<FLIT_LEN> data_out_v; sc_bv<FLIT_TYPE_LEN> flit_type_v = 0; sc_bv<ADDRESS_LEN> addrx = buffer_addr.read().range(2*ADDRESS_LEN-1,ADDRESS_LEN), addry = buffer_addr.read().range(ADDRESS_LEN-1,0); sc_bv<16> flit_data_v = 0; next_send_flit = send_flit.read(); send_next_state = SEND_IDLE; req_out_v = false; send_rdy_v = false; switch( send_current_state.read() ){ case SEND_IDLE: // idle - wait for send signal from processor if( send.read() ){ // send arrived - build header flit send_next_state = BUILD_FLIT; next_send_flit = HEADER; flit_type_v = 0x1; flit_data_v = (addrx,addry); } else { send_next_state = SEND_IDLE; next_send_flit = NONE; send_rdy_v = true; } break; case BUILD_FLIT: // building next flit - depending on which flit - output // the flit marker (header,data,trailer) and the appropriate data // (address,data high,data low) switch( send_flit.read() ){ case HEADER: flit_type_v = 0x1; flit_data_v = (addrx,addry); break; case DATA_HIGH: flit_type_v = 0x0; flit_data_v = buffer_out.read().range(31,16); break; case DATA_LOW_TAIL: flit_type_v = 0x2; flit_data_v = buffer_out.read().range(15,0); break; } send_next_state = SEND; break; case SEND: // sending - assert network request, output flit req_out_v = true; switch( send_flit.read() ){ case HEADER: flit_type_v = 0x1; flit_data_v = (addrx,addry); break; case DATA_HIGH: flit_type_v = 0x0; flit_data_v = buffer_out.read().range(31,16); break; case DATA_LOW_TAIL: flit_type_v = 0x2; flit_data_v = buffer_out.read().range(15,0); break; } if( ack_in.read() ){ // flit acknowledged - can send next one // withdraw request, wait for ack to disappear#ifdef NETPRINT cout << name() << " sent flit t=" << flit_type_v << " data=" << hex << flit_data_v.to_uint() << dec << " @ " << sc_time_stamp() << endl;#endif send_next_state = WAIT_ACK_OFF; } else send_next_state = SEND; break; case WAIT_ACK_OFF: // wait for ack to disappear if( ! ack_in.read() ) { // send next flit, or exit switch( send_flit.read() ){ case HEADER: send_next_state = BUILD_FLIT; next_send_flit = DATA_HIGH; break; case DATA_HIGH: send_next_state = BUILD_FLIT; next_send_flit = DATA_LOW_TAIL; break; case DATA_LOW_TAIL: send_next_state = WAIT_SEND_OFF; next_send_flit = NONE; send_rdy_v = true; break; } } else send_next_state = WAIT_ACK_OFF; break; case WAIT_SEND_OFF: // assert send ready, wait for send to be withdrawn send_rdy_v = true; if( !send.read() ) send_next_state = SEND_IDLE; else send_next_state = WAIT_SEND_OFF; break; } req_out.write(req_out_v); send_rdy.write(send_rdy_v); data_out.write( (flit_type_v, flit_data_v) );}// state update of the sending FSMvoid NETWORK_INTERFACE::send_change_state(){ if( rst.read() ){ send_current_state = SEND_IDLE; send_flit = NONE; } else{ send_current_state = send_next_state; send_flit = next_send_flit; }}// FSM receiving packetsvoid NETWORK_INTERFACE::rcv_logic(){ bool ack_out_v, data_rdy_v; // sc_bv<32> buffer_in_v; rcv_next_state = RCV_IDLE; next_rcv_flit = rcv_flit.read(); buffer_in_n = buffer_in.read(); ack_out_v = false; data_rdy_v = false; switch( rcv_current_state.read() ) { case RCV_IDLE: // idle - wait for request from network if( req_in.read() ){#ifdef NETPRINT cout << name() << " rcv flit " << hex << data_in.read().to_uint() << dec << " @ " << sc_time_stamp() << endl;#endif // discard flit if it's header, store in buffer if it's data rcv_next_state = ACK; switch(rcv_flit.read()){ case NONE: next_rcv_flit = HEADER; break; case HEADER: next_rcv_flit = DATA_HIGH; buffer_in_n = (data_in.read().range(15,0), buffer_in_n.read().range(15,0)); break; case DATA_HIGH: next_rcv_flit = DATA_LOW_TAIL; buffer_in_n = (buffer_in_n.read().range(31,16), data_in.read().range(15,0)); break; } } else rcv_next_state = RCV_IDLE; break; case ACK: // acknowledge flit and wait until request is withdrawn ack_out_v = true; if( ! req_in.read() ){ // flit transmission finished if( rcv_flit.read() == DATA_LOW_TAIL ) { // if it was tail flit - wait for processor to read the packet#ifdef NETPRINT cout << name() << " received packet " << hex << buffer_in_n.to_uint() << dec << " @ " << sc_time_stamp() << endl;#endif rcv_next_state = WAIT_READ; } else // otherwise - wait for next flit rcv_next_state = RCV_IDLE; } else rcv_next_state = ACK; break; case WAIT_READ: // assert data ready and wait for processor to read the data data_rdy_v = true; if( read.read() ){#ifdef NETPRINT cout << name() << " packet read " << hex << buffer_in.read().to_uint() << dec << " @ " << sc_time_stamp() << endl;#endif next_rcv_flit = NONE; rcv_next_state = RCV_IDLE; } else rcv_next_state = WAIT_READ; break; } // buffer_in.write(buffer_in_v); // reg_data_out.write(buffer_in_v); ack_out.write(ack_out_v); data_rdy.write(data_rdy_v);}// state update of the receiving FSMvoid NETWORK_INTERFACE::rcv_change_state(){ if( rst.read() ){ rcv_current_state = RCV_IDLE; rcv_flit = NONE; buffer_in.write(0); } else{ rcv_current_state = rcv_next_state; rcv_flit = next_rcv_flit; buffer_in.write(buffer_in_n); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?