diff options
Diffstat (limited to 'src/udp_rx_c.v')
| -rw-r--r-- | src/udp_rx_c.v | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/udp_rx_c.v b/src/udp_rx_c.v new file mode 100644 index 0000000..546990f --- /dev/null +++ b/src/udp_rx_c.v @@ -0,0 +1,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 |



