Protocol Layer Architecture
Ethernet communication employs a layered protocol structure where data is encapsulated sequentially. The UDP payload is embedded within IP packets, which are subsequent framed by MAC layer protocols. Each layer adds specific header information for network delivery.
MAC Frame Structure
Preamble: 7 bytes of alternating 1s and 0s (0x55) for physical layer synchronization.
Start Frame Delimiter: 1 byte (0xD5) indicating frame commencement.
Destination MAC Address: 6-byte hardware address of the receiving device.
Source MAC Address: 6-byte hardware address of the transmitting device.
EtherType/Length: 2-byte field indicating either payload length (values < 0x0600) or protocol type (e.g., 0x0800 for IP).
Payload Data: Variable-length field with minimum 46 bytes and maximum 1500 bytes (MTU).
Frame Check Sequence: 4-byte CRC-32 checksum for error detection, calculated from MAC header through payload.
Inter-Frame Gap: Minimum 96-bit time intervals between frames (96ns for Gigabit Ethernet).
IP Datagram Format
Version: 4-bit IP version identifier (4 for IPv4).
Header Length: 4-bit value representing number of 32-bit words in header (typically 5 for 20-byte header).
Type of Service: 8-bit field generally set to zero.
Total Length: 16-bit value indicating complete datagram size (IP header + UDP header + data).
Identification: 16-bit value unique to each datagram.
Flags: 3-bit field controlling packet fragmentation.
Fragment Offset: 13-bit value for reassembling fragmented packets.
Time to Live: 8-bit counter preventing infinite packet propagation.
Protocol: 8-bit identifier for upper-layer protocol (17 for UDP).
Header Checksum: 16-bit value verifying IP header integrity.
Source/Destination IP Addresses: 32-bit IPv4 addresses.
UDP Protocol Header
Source Port: 16-bit originating application port.
Destination Port: 16-bit target application port.
Length: 16-bit value specifying UDP header and data length.
Checksum: 16-bit validation field (often disabled with 0x0000).
GMII Interface Signals
Transmit Signals:
- GTX_CLK: 125MHz clock generated by FPGA PLL
- TX_EN: Data transmission enable
- TX_ER: Error indication signal
- TXD[7:0]: 8-bit data bus
Receive Signals:
- RX_CLK: 125MHz clock from PHY
- RX_EN: Data reception enable
- RX_ER: Receive error indicator
- RXD[7:0]: 8-bit receive data bus
Transmission Sequence
- Preamble and SFD: 8 bytes (7×0x55 + 0xD5)
- MAC header: Destination MAC, Source MAC, EtherType
- IP header: 20 bytes with calculated checksum
- UDP header: 8 bytes with port specifications
- Application data payload
- CRC-32 frame check sequence
FPGA Implementation Example
Top-Level Module
module ethernet_controller(
input system_clock,
output phy_reset_n,
output [7:0] tx_data,
output tx_enable,
output tx_error,
output gtx_clock
);
clock_generator clock_gen(
.input_clock(system_clock),
.output_clock(gtx_clock)
);
udp_transmitter tx_module(
.tx_clock(gtx_clock),
.tx_en(tx_enable),
.tx_err(tx_error),
.tx_data(tx_data),
.phy_rst(phy_reset_n)
);
endmodule
UDP Transmission Module
module udp_transmitter(
input tx_clock,
output reg tx_en,
output reg tx_err,
output reg [7:0] tx_data,
output phy_rst
);
parameter IDLE = 0, PREAMBLE = 1, MAC_HEADER = 2;
parameter IP_HEADER = 3, UDP_HEADER = 4, DATA = 5, CRC = 6;
reg [3:0] current_state;
reg [4:0] byte_counter;
reg [15:0] data_length = 16'd33;
reg [15:0] ip_total_length = 16'd61;
wire [31:0] crc_value;
wire [31:0] next_crc;
crc32 crc_calculator(
.clock(tx_clock),
.reset(crc_reset),
.data_in(tx_data),
.enable(crc_enable),
.crc_out(crc_value),
.crc_next(next_crc)
);
assign phy_rst = 1'b1;
always @(posedge tx_clock) begin
case(current_state)
IDLE: begin
tx_en <= 1'b0;
tx_err <= 1'b0;
if(delay_counter == 32'h1000) begin
current_state <= PREAMBLE;
delay_counter <= 0;
end
end
PREAMBLE: begin
tx_en <= 1'b1;
if(byte_counter == 7) begin
tx_data <= 8'hd5;
byte_counter <= 0;
current_state <= MAC_HEADER;
end else begin
tx_data <= 8'h55;
byte_counter <= byte_counter + 1;
end
end
MAC_HEADER: begin
crc_enable <= 1'b1;
// MAC address transmission logic
if(byte_counter == 13) begin
current_state <= IP_HEADER;
byte_counter <= 0;
end
end
// Additional state implementations...
CRC: begin
crc_enable <= 1'b0;
// CRC transmission logic
if(byte_counter == 3) begin
current_state <= IDLE;
byte_counter <= 0;
end
end
endcase
end
endmodule
CRC-32 Calculation Module
module crc32(
input clock,
input reset,
input [7:0] data_in,
input enable,
output reg [31:0] crc_out,
output [31:0] crc_next
);
wire [7:0] reversed_data = {data_in[0], data_in[1], data_in[2], data_in[3],
data_in[4], data_in[5], data_in[6], data_in[7]};
assign crc_next[0] = crc_out[24] ^ crc_out[30] ^ reversed_data[0] ^ reversed_data[6];
// Additional CRC calculation equations...
assign crc_next[31] = crc_out[23] ^ crc_out[29] ^ reversed_data[5];
always @(posedge clock or posedge reset) begin
if(reset) begin
crc_out <= 32'hffffffff;
end else if(enable) begin
crc_out <= crc_next;
end
end
endmodule
Hardware Configuration
- FPGA Platform: MP801 development board
- PHY Chip: RTL8211EG Gigabit Ethernet transceiver
- Development Enviroment: Quartus II 13.0
- Clock Configuration: 125MHz GMII clock generated via FPGA PLL
Protocol Implemantation Notes
Data transmission follows big-endian format with most significant bits transmitted first. The CRC calculation encompasses all data from MAC header through payload. IP header checksum verification ensures packet integrity during routing.