summaryrefslogtreecommitdiffhomepage
path: root/src/udp_rx.v
blob: 8b548aad7c060b4ec860cb7f4b76009d0710669e (plain)
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 *   udp_rx.v
 *
 *   Copyright (C) 2023-2025 Private Island Networks Inc.
 *   Copyright (C) 2021 Mind Chasers Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 *	function: Receive State Machine and Logic for UDP
 *	
 *	
 *		0-15					16:32
 *	0	Source port			Destination port
 *	4	Length				Checksum
 *
 */

module udp_rx (
	input	rstn,
	input	clk,
	
	// control
	input phy_resetn,
	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 trigger_src_port,
	output reg trigger_dst_port,
	output reg keep
);
	
	/* 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;
	wire rx_error;

	/*		
	 * 		rx_state machine
	 * 		capture a UDP Packet
	 *  
	 */
	always @(posedge clk, negedge rstn)
		if (!rstn)
			rx_state <= RX_ST_IDLE;	
		else if ( rx_eop || !phy_resetn )						// EOP will reset state machine
			rx_state <= RX_ST_IDLE;	
		else if ( phy_up )
			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;
			endcase
		else 
			rx_state <= RX_ST_IDLE;

	/* 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;

	/*
	 *  Packet Filter Trigger(s)
	 *  
	 */
	always @(posedge clk, negedge rstn)
		if (!rstn) 
			trigger_src_port <= 1'b0;
		else if ( rx_sample && rx_byte_cnt == UDP_SRC_PORT )
			trigger_src_port <= 1'b1;
		else
			trigger_src_port <= 1'b0;

	always @(posedge clk, negedge rstn)
		if (!rstn) 
			trigger_dst_port <= 1'b0;
		else if ( rx_sample && rx_byte_cnt == UDP_DST_PORT )
			trigger_dst_port <= 1'b1;
		else
			trigger_dst_port <= 1'b0;
		
	assign pkt_complete = (  rx_byte_cnt == 3'h7 );
	assign rx_error = 0;
	
endmodule

Highly Recommended Verilog Books