OpenCores
URL https://opencores.org/ocsvn/cheap_ethernet/cheap_ethernet/trunk

Subversion Repositories cheap_ethernet

[/] [cheap_ethernet/] [trunk/] [Ethernet_test/] [ethernet_test.v] - Rev 3

Compare with Previous | Blame | View Log

`timescale 1ns / 1ps
`include "const.vh"
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Ivan Krutov (grvfrv@gmail.com)
// 
// Create Date:    10:36:10 08/28/2012 
// Design Name:    Cheap Ethernet test project
// Module Name:    ethernet_test
// Project Name:   Cheap Ethernet
// Target Devices: Spartan 3E
// Tool versions:  ISE 14.1
// Description:    Base functional of ARP, ICMP, UDP server, UDP client.
//
// Dependencies:   EthernetRX.v, EthernetTX.v, TENBASET_RxD.v, TENBASET_TxD.v,
//	                const.vh
// Revision: 
// Revision 0.9 beta
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
 
module ethernet_test(clk_in, 
	Ethernet_RDp, Ethernet_RDm, Ethernet_TDp, Ethernet_TDm, Ethernet_LED_Link, Ethernet_LED_Act,
	PushButton, LED_Test);
 
input clk_in;								// 50 MHz
input Ethernet_RDp, Ethernet_RDm;	// Ethernel input
output Ethernet_TDp, Ethernet_TDm;	// Ethernel output
output Ethernet_LED_Link;				// Ethernet link - Not realized! (VCC)
output Ethernet_LED_Act;				// Etheret activity (low - active)
input PushButton;							// Pushbutton for send data test
output LED_Test;
 
// Server config
wire [31:0] HostIP     	= 32'hC0A8012C;	// 192.168.1.44
wire [47:0] HostMAC    	= 48'h001234567890;
wire [15:0] HostPort   	= 16'd1024;
 
// Client config
wire [31:0] RemoteIP		= 32'hC0A80102;	// 192.168.1.2
reg [47:0] RemoteMAC		= 48'h0;
wire [15:0] RemotePort	= 16'd1024;
 
wire clk20, clk50;
wire Ethernet_RD;
 
reg SendStart = 0;
wire SendDataReq;
reg [7:0] SendData = 0;
reg [9:0] SendDataLen = 0;
wire [9:0] SendDataPos;
wire SendingPacket;
reg [2:0] SendPacketType = 0;
 
reg [31:0] SendToIP   = 32'h0;
reg [47:0] SendToMAC  = 48'h0;
reg [15:0] SendToPort = 16'h0;
 
wire RcvStart, RcvStop;
wire [7:0] RcvData;
wire [9:0] RcvDataLen;
wire [9:0] RcvDataPos;
wire RcvDataAvailable;
wire RcvCRCValid;
wire ReceivingPacket;
wire [2:0] RcvPacketType;
wire [31:0] RcvFromIP;
wire [47:0] RcvFromMAC;
wire [15:0] RcvFromPort;
wire [15:0] RcvICMPId;
wire [15:0] RcvICMPSeq;
wire [15:0] RcvICMPCRC;
 
wire Ethernet_LED_Link = 1;
reg Ethernet_LED_Act = 0;
reg LED_Test = 0;
reg last_btn_st = 0;
 
reg PacketReceived = 0;
reg PacketProcessed = 0;
reg [7:0] Cmd = 0;
reg [7:0] Arg = 0;
reg SendReq = 0;
 
reg [2:0] SavedPacketType = 0;
reg [9:0] SavedDataLen = 0;
reg [15:0] SavedPort = 0;
reg SavedEcho = 0;
reg Echo = 0;
 
wire [16:0] SendICMPCRC1 = {RcvICMPCRC[15:8] + 9'h08, RcvICMPCRC[7:0]};
wire [15:0] SendICMPCRC2 = SendICMPCRC1[15:0] + SendICMPCRC1[16];
 
wire [7:0] FIFOOut;
wire FIFOFull;
wire FIFOEmpty;
 
 
DCMMAIN DCMMAIN1 (
    .CLKIN_IN(clk_in),	// 50 MHz
    .RST_IN(1'b0),
    .CLKDV_OUT(), 
    .CLKFX_OUT(clk20), 
    .CLKIN_IBUFG_OUT(), 
    .CLK0_OUT(clk50),
	 .LOCKED_OUT());
 
   IBUFDS #(
      .IBUF_DELAY_VALUE("0"),    // Specify the amount of added input delay for
                                 //    the buffer: "0"-"12" (Spartan-3E)
      .IFD_DELAY_VALUE("0"),  // Specify the amount of added delay for input
                                 //    register: "AUTO", "0"-"6" (Spartan-3E)
      .IOSTANDARD("DIFF_HSTL_III_18")     // Specify the input I/O standard
   ) IBUFDS_EthRD (
      .O(Ethernet_RD),  // Buffer output
      .I(Ethernet_RDp),  // Diff_p buffer input (connect directly to top-level port)
      .IB(Ethernet_RDm) // Diff_n buffer input (connect directly to top-level port)
   );
 
FIFORX FIFO_RD (
  .rst(RcvStart), // input rst
  .wr_clk(clk50), // input wr_clk
  .rd_clk(clk20), // input rd_clk
  .din(RcvData), // input [7 : 0] din
  .wr_en(RcvDataAvailable), // input wr_en
  .rd_en(SendDataReq /*&& SendingPacket*/), // input rd_en
  .dout(FIFOOut), // output [7 : 0] dout
  .full(FIFOFull), // output full
  .empty(FIFOEmpty) // output empty
);
 
EthernetTX EthTX1 (clk20, 
	HostIP, SendToIP, HostMAC, SendToMAC, HostPort, SendToPort, 
   SendStart, SendDataReq, SendData, SendDataLen, SendDataPos, SendingPacket, 
	SendPacketType, RcvICMPId, RcvICMPSeq, SendICMPCRC2,
	Ethernet_TDp, Ethernet_TDm);
 
EthernetRX EthRX1 (clk50, 
	Ethernet_RD,
	HostIP, HostMAC, HostPort,
	RcvStart, RcvStop, RcvData, RcvDataLen, RcvDataPos, RcvDataAvailable, RcvCRCValid, ReceivingPacket,
	RcvPacketType, RcvICMPId, RcvICMPSeq, RcvICMPCRC,
	RcvFromIP, RcvFromMAC, RcvFromPort);
 
 
// Ethernet LEDs
reg [19:0] EthLEDCnt = 0;
always @(posedge clk20) begin
	EthLEDCnt <= EthLEDCnt + 1;
	Ethernet_LED_Act <= Ethernet_LED_Act && !(ReceivingPacket | SendingPacket);
	if (Ethernet_LED_Act)
		EthLEDCnt <= 0;
	if (&EthLEDCnt)
		Ethernet_LED_Act <= 1;
end
 
// Transmit packets
always @(posedge clk20) begin
	SendStart = 0;
	if (!SendingPacket && (PacketReceived || SendReq) && !PacketProcessed)
		begin
		Echo <= 0;
		PacketProcessed <= 1;
		SendToIP <= RcvFromIP;
		SendToMAC <= RcvFromMAC;
 
		if (RcvPacketType ==	`ARPReply)			// Remote MAC resolved
			begin
			RemoteMAC = RcvFromMAC;
			SendToPort = SavedPort;
			SendStart = 1;
			SendPacketType = SavedPacketType;
			SendDataLen = SavedDataLen;
			Echo <= SavedEcho;
			end
		else if ((RcvPacketType == `UDP) || SendReq)	// Send UDP packet
			begin
			if (SendReq)
				begin
				SendToIP <= RemoteIP;
				SendToMAC <= RemoteMAC;
				end
			else if (Cmd == `CmdDataEcho)
				Echo <= 1;
			SendToPort = RemotePort;
			SendStart = 1;
			SendPacketType = `UDP;
			SendDataLen = SendReq ? 18 : RcvDataLen;
			end
		else if (RcvPacketType == `ARPReq)				// Send ARP reply
			begin
			SendStart = 1;
			SendPacketType = `ARPReply;
			SendDataLen = 18;
			end
		else if (RcvPacketType == `ICMPReq)				// Send ICMP reply
			begin
			Echo <= 1;
			SendStart = 1;
			SendPacketType = `ICMPReply;
			SendDataLen = RcvDataLen;
			end
 
		if (~|RemoteMAC && SendStart && SendReq)		// If remote MAC unknown send ARP request
			begin													// TODO: clear RemoteMAC after 2 minutes inactivity
			SavedPacketType <= SendPacketType;
			SavedDataLen <= SendDataLen;
			SavedPort <= SendToPort;
			SavedEcho <= Echo;
			SendToIP <= RemoteIP;
			SendStart = 1;
			SendPacketType = `ARPReq;
			SendDataLen = 18;
			end
		end
 
	if (!PacketReceived && !SendReq)
		PacketProcessed <= 0;
 
	case (SendDataPos)
		0: SendData <= Cmd;
		1: SendData <= Arg;
		default: SendData <= 0;
	endcase
 
	if (Echo /*RcvPacketType == `ICMPReq*/)	// Cmd: Data echo
		SendData <= FIFOOut;
end
 
 
reg [25:0] cnt = 0;
reg AutoSend = 1;
 
// Receive packets
always @(posedge clk50) begin
	if (~&cnt)
		cnt <= cnt + 1;
 
	if (PacketProcessed)
		begin
		PacketReceived <= 0;
		SendReq <= 0;
		end
 
	if (RcvDataAvailable)
		if (RcvPacketType == `UDP)
			case (RcvDataPos)
				0: Cmd <= RcvData;
				1: Arg <= RcvData;
			endcase
 
	if (RcvStop && RcvCRCValid)
		begin
		PacketReceived <= 1;
		if (RcvPacketType == `UDP)
			begin
			if (Cmd == `CmdLEDCtrl)			// Received Cmd: Leds control
				begin
				LED_Test <= Arg[0];
				Cmd <= `CmdDone;				// Send reply: Cmd: Done
				end
			else if (Cmd == `CmdStatus)	// Received Cmd: Get Status
				begin
				Cmd <= `CmdStatus;			// Send reply: Cmd: Status
				Arg <= {5'd0, PushButton, AutoSend, LED_Test};	// Status
				end
			else if (Cmd == `CmdSetConfig)// Received Cmd: Set Config
				begin
				Cmd <= `CmdDone;				// Send reply: Cmd: Status
				AutoSend <= Arg[0];
				end
			end
		end
 
	if (!SendingPacket && !ReceivingPacket && !PacketProcessed)
		begin
		last_btn_st <= PushButton;
		if (last_btn_st != PushButton || (&cnt && AutoSend))
			begin
			cnt <= 0;
			Cmd <= `CmdSwChanged;	// Cmd: Pushbuttons state changed
			if (&cnt)
				Cmd <= `CmdStatus;
			Arg <= {8{PushButton}};
			SendReq <= 1;
			end
		end
end
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.