netif_b.cpp
来自「国外开源的一个片上网络系统的源代码」· C++ 代码 · 共 303 行
CPP
303 行
/* * 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 * with arbitrary length packets * */#include "netif_b.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);}void NETWORK_INTERFACE::register_packet_end(){ if( rst.read() ) packet_end_reg.write(0); else if( wr_packet_end.read() ) packet_end_reg.write(packet_end.read()); }// FSM sending a packetvoid NETWORK_INTERFACE::send_logic(){ bool req_out_v, send_rdy_v, wr_packet_end_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; wr_packet_end_v = false; switch( send_current_state.read() ){ case SEND_IDLE: // idle - wait for send signal from processor if( send.read() ){ // send header flit send_next_state = SEND; next_send_flit = HEADER; wr_packet_end_v = true; // check if the last-packet-word marker is set } else { send_next_state = SEND_IDLE; next_send_flit = NONE; send_rdy_v = true; } 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: flit_type_v = 0x0; flit_data_v = buffer_out.read().range(31,16); break; case TAIL: // if its the last packet word, mark flit as trailer flit_type_v = (packet_end_reg.read() ? 0x2 : 0x0); 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 of the word, or check if next word is there switch( send_flit.read() ){ case HEADER: send_next_state = SEND; next_send_flit = DATA; break; case DATA: send_next_state = SEND; next_send_flit = TAIL; break; case 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() ) if( packet_end_reg.read() ) // if it was last word of the packet - goto idle send_next_state = SEND_IDLE; else // otherwise - wait for processor to supply next packet word send_next_state = NEXT_WORD; else send_next_state = WAIT_SEND_OFF; break; case NEXT_WORD: // wait for processor to supply next word of the packet next_send_flit = DATA; if( send.read() ){ // send next word send_next_state = SEND; wr_packet_end_v = true; } else { send_next_state = NEXT_WORD; send_rdy_v = true; } break; } wr_packet_end.write(wr_packet_end_v); 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, rcv_packet_end_v; sc_uint<2> flit_type = sc_bv<2>(data_in.read().range(17,16)); 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; rcv_packet_end_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: buffer_in_n = 0; next_rcv_flit = HEADER; break; case HEADER: buffer_in_n = 0; break; case DATA: buffer_in_n = (data_in.read().range(15,0), buffer_in.read().range(15,0)); break; case TAIL: buffer_in_n = (buffer_in.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 switch(rcv_flit.read()){ case HEADER: // got header, wait for data rcv_next_state = RCV_IDLE; next_rcv_flit = DATA; break; case DATA: // got data high, get data low rcv_next_state = RCV_IDLE; next_rcv_flit = TAIL; break; case TAIL: // got data low - check if it's tail flit or another data follows // and wait for the processor to read the received data rcv_next_state = WAIT_READ; if( flit_type == 2 ) next_rcv_flit = NONE; else next_rcv_flit = DATA;#ifdef NETPRINT cout << name() << " received data " << hex << buffer_in.read().to_uint() << dec << " @ " << sc_time_stamp() << endl;#endif break; } } 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 the next expected flit is header - it's the last word of packet rcv_packet_end_v = (rcv_flit.read() == NONE); if( read.read() ){#ifdef NETPRINT cout << name() << " data read " << hex << buffer_in.read().to_uint() << dec << " @ " << sc_time_stamp() << endl;#endif rcv_next_state = RCV_IDLE; } else rcv_next_state = WAIT_READ; break; } ack_out.write(ack_out_v); data_rdy.write(data_rdy_v); rcv_packet_end.write(rcv_packet_end_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 + -
显示快捷键?