www.pudn.com > noc.rar > netif_b.h


/*
 *  TU Eindhoven
 *  Eindhoven, The Netherlands
 *
 *  Name            :   netif.h
 *
 *  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
 *
 */

#ifndef NETIF_H_INCLUDED
#define NETIF_H_INCLUDED

#include 
#include "router.h"

SC_MODULE(NETWORK_INTERFACE)
{
  sc_in clk, rst;
  
  // processor interface
  
  // packet data or destination address
  sc_in< sc_bv<32> > reg_data_in;         
  // write reg_data_in to data buffer
  sc_in< bool > write_data;
  // write reg_data_in to address buffer
  sc_in< bool > write_addr;   
  // trigger sending
  sc_in< bool > send;
  // assert packet_end when 'send'ing last word of the packet
  sc_in< bool > packet_end;
  // free the receiving buffer
  sc_in< bool > read;
  
  // contents of the receive buffer
  sc_out< sc_bv<32> > reg_data_out;
  // receive buffer contains data not confirmed with 'read'
  sc_out< bool > data_rdy;
  sc_out< bool > rcv_packet_end;
  // previous send operation completed
  sc_out< bool > send_rdy;

  // network interface
  sc_in< sc_bv > data_in;
  sc_in< bool > req_in, ack_in;

  sc_out< sc_bv > data_out;
  sc_out< bool > req_out, ack_out;

  // buffers
  void buffer_addr_process();
  void buffer_out_process();
  sc_signal< sc_bv<2*ADDRESS_LEN> > buffer_addr;
  sc_signal< sc_bv<32> > buffer_in, buffer_out;

  sc_signal< sc_bv<32> > buffer_in_n;

  
  // control FSM for sending data
  
  // which flit (there are three flits necessary to send 32-bit data)
  enum flit_type { NONE, HEADER, DATA, TAIL };
#ifdef VERILOG
  sc_signal send_flit, next_send_flit;
#else
  sc_signal send_flit, next_send_flit;
#endif
  
  // state of the sending process
  enum send_state { SEND_IDLE, SEND, WAIT_ACK_OFF, WAIT_SEND_OFF, NEXT_WORD };
#ifdef VERILOG
  sc_signal send_current_state, send_next_state;
#else
  sc_signal send_current_state, send_next_state;
#endif
  
  void send_logic();
  void send_change_state();

  // 
  sc_signal< bool > wr_packet_end, packet_end_reg;
  void register_packet_end();
  
  // control FSM for receiving data
  enum rcv_state { RCV_IDLE, ACK, WAIT_READ };
#ifdef VERILOG
  sc_signal rcv_flit, next_rcv_flit;
  sc_signal rcv_current_state, rcv_next_state;
#else
  sc_signal rcv_flit, next_rcv_flit;
  sc_signal rcv_current_state, rcv_next_state;
#endif
  void rcv_logic();
  void rcv_change_state();

  void forward_buffer(){
	reg_data_out.write(buffer_in.read());
  }
  
  SC_CTOR(NETWORK_INTERFACE)
	{
	  SC_METHOD(buffer_out_process);
	  sensitive_pos << clk << rst;

	  SC_METHOD(buffer_addr_process);
	  sensitive_pos << clk << rst;
	  
	  SC_METHOD(send_logic);
	  sensitive << send_current_state << send_flit << send << buffer_out << buffer_addr << ack_in << packet_end_reg;
	  
	  SC_METHOD(send_change_state);
	  sensitive_pos << clk << rst;

	  SC_METHOD(rcv_logic);
	  sensitive << rcv_current_state << rcv_flit << req_in << data_in << buffer_in << read;
	  
	  SC_METHOD(rcv_change_state);
	  sensitive_pos << clk << rst;
	  
	  SC_METHOD(forward_buffer);
	  sensitive << buffer_in;
	  
	  SC_METHOD(register_packet_end);
	  sensitive_pos << clk << rst;
	}
};

#ifndef VERILOG

// non-synthesizable behavioral model of a network interface client (dummy data processor)
// receive packets from the NI, send random packets
SC_MODULE(NI_RAND_DRIVER){
  
  sc_in clk, rst;
  sc_in en;
  
  sc_out< sc_bv<32> > reg_data_in;
  sc_out< bool > write_data, write_addr;
  sc_out< bool > send, read;
  sc_out< bool > packet_end;
  
  sc_in< sc_bv<32> > reg_data_out;
  sc_in< bool > data_rdy, send_rdy;
  sc_in< bool > rcv_packet_end;

  unsigned x,y,maxx,maxy;
  
  // the sending process
  void sending(){
	unsigned ax, ay, words, w;
	unsigned data[8];
	sc_bv<32> d;
	
	while(true){
	  
	  while( !en.read() || (rand()%4 != 0) )
		wait();
	  
	  cout << name() << " : sending " << flush;
	  // generate address
	  while(1){
		ax = rand()%(maxx+1);
		ay = rand()%(maxy+1);
		if ( ax!=x || ay !=y ) break;
	  }
	  cout << " addr=(" << ax << ',' << ay << ") data=0x";
	  
	  // generate data
	  words = 1 + rand()%4;
	  for( unsigned i=0; i