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 + -
显示快捷键?