1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/*
* udp_rx_c.v
*
* Copyright (C) 2023-2025 Private Island Networks Inc.
* Copyright (C) 2021 Mind Chasers Inc.
*
* function: Receive State Machine and Logic for UDP for the internall Controller
*
*
* 0-15 16:32
* 0 Source port Destination port
* 4 Length Checksum
*
* UDP Parser for Controller Port
*/
module udp_rx_c #(parameter UDP_PORT_MATCH_H=8'h90, parameter UDP_PORT_MATCH_L=8'h20) (
input rstn,
input clk,
// control
input phy_up,
// packet data
input pkt_start, // assert for each new frame to start state machines
input rx_sample, // enable in case we have connected at 100 Mbit
input rx_eop, // use as a synch reset
input[7:0] rx_data_m1,
input[7:0] rx_data_m2,
input[7:0] rx_data_m3, // first byte of packet appears here simultaneous with pkt_start
input[7:0] rx_data_m4,
// flags
output pkt_complete,
output reg udp_port_match
);
/* Byte Address (when last byte of field is present on rx_data_m1 ) */
localparam UDP_SRC_PORT=0, UDP_DST_PORT=2, UDP_LEN=4, UDP_CKSUM =6;
localparam RX_ST_IDLE=4'h0, RX_ST_DATA=4'h1, RX_ST_DONE=4'h2, RX_ST_3=4'h3,
RX_ST_4=4'h4, RX_ST_5=4'h5, RX_ST_6=4'h6, RX_ST_7=4'h7,
RX_ST_8=4'h8, RX_ST_9=4'h9, RX_ST_A=4'ha, RX_ST_B=4'hb,
RX_ST_C=4'hc, RX_ST_D=4'hd, RX_ST_E=4'he, RX_ST_F=4'hf;
reg [3:0] rx_state;
reg [3:0] rx_byte_cnt;
/*
* rx_state machine
* capture a UDP Packet
*
*/
always @(posedge clk, negedge rstn)
if (!rstn)
rx_state <= RX_ST_IDLE;
else if ( rx_eop || !phy_up ) // EOP will reset state machine
rx_state <= RX_ST_IDLE;
else
case ( rx_state )
RX_ST_IDLE: if ( pkt_start ) // Found /S/
rx_state <= RX_ST_DATA;
RX_ST_DATA: if (pkt_complete)
rx_state <= RX_ST_DONE;
RX_ST_DONE: rx_state <= RX_ST_IDLE;
default: rx_state <= RX_ST_IDLE;
endcase
/* rx_byte_cnt */
always @(posedge clk, negedge rstn)
if (!rstn)
rx_byte_cnt <= 0;
else if ( rx_sample && pkt_start ) // synch reset
rx_byte_cnt <= 0;
else if ( rx_sample && rx_byte_cnt <= 4'h7 )
rx_byte_cnt <= rx_byte_cnt + 1'b1;
// UDP Dest Port match logic
always @(posedge clk, negedge rstn)
if (!rstn)
udp_port_match <= 1'b0;
else if ( rx_byte_cnt == 4'h3 && rx_data_m1 == (UDP_PORT_MATCH_L) && rx_data_m2 == UDP_PORT_MATCH_H)
udp_port_match <= 1'b1;
else
udp_port_match <= 1'b0;
assign pkt_complete = ( rx_byte_cnt == 3'h7 );
endmodule
|