netif_b.h
来自「国外开源的一个片上网络系统的源代码」· C头文件 代码 · 共 275 行
H
275 行
/* * 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 <systemc.h>#include "router.h"SC_MODULE(NETWORK_INTERFACE){ sc_in<bool> 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<FLIT_LEN> > data_in; sc_in< bool > req_in, ack_in; sc_out< sc_bv<FLIT_LEN> > 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<flit_type> send_flit, next_send_flit;#else sc_signal<unsigned> 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_state> send_current_state, send_next_state;#else sc_signal<unsigned> 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<flit_type> rcv_flit, next_rcv_flit; sc_signal<rcv_state> rcv_current_state, rcv_next_state;#else sc_signal<unsigned> rcv_flit, next_rcv_flit; sc_signal<unsigned> 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 packetsSC_MODULE(NI_RAND_DRIVER){ sc_in<bool> clk, rst; sc_in<bool> 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<words; i++ ) { w = rand(); if( i==0 ){ // top byte of data contains sender address (for debugging) w &= 0x00ffffff; w |= (x << 28); w |= (y << 24); } data[i] = w; cout << hex << w ; } cout << " " << sc_time_stamp() << endl; // make address relative if( ax < x ) ax = ax - x + maxx + 1; else ax -= x; if( ay < y ) ay = ay - y + maxy + 1; else ay -= y; // write address to NI d.range(15,8) = ax; d.range(7,0) = ay; reg_data_in = d; write_addr = 1; packet_end.write(false); wait(); // write data to NI write_addr = 0; for( unsigned i = 0 ; i < words; i++ ) { d = data[i]; reg_data_in = d; write_data = 1; wait(); // send data write_data = 0; send = 1; packet_end.write( i==(words-1) ); // wait for send to complete wait_until(send_rdy.delayed()==true); send = 0; wait(); } cout << '\t' << name() << " : sent (" << ax << ',' << ay << ") 0x"; for( unsigned i = 0 ; i < words; i++ ) cout << hex << data[i]; cout << " " << sc_time_stamp() << endl; wait(); } } // the receiving process void receiving(){ while(true){ unsigned data[8]; unsigned words; bool eop; words = 0; do{ while( !data_rdy.read() ) wait(); eop = rcv_packet_end.read(); data[words] = reg_data_out.read().to_uint(); read = 1; wait(); words++; read = 0; while( data_rdy.read() ) wait(); } while( !eop ); cout << name() << " received 0x" ; for( unsigned i = 0; i < words; i++ ) cout << hex << data[i]; cout << " " << sc_time_stamp() << endl; } } SC_CTOR(NI_RAND_DRIVER){ SC_CTHREAD(sending, clk.pos()); watching(rst.delayed()==true); SC_CTHREAD(receiving, clk.pos()); watching(rst.delayed()==true); }};#endif#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?