diff --git a/rtl/udp_complete.v b/rtl/udp_complete.v new file mode 100644 index 000000000..d32bba109 --- /dev/null +++ b/rtl/udp_complete.v @@ -0,0 +1,623 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * IPv4 and ARP block with UDP support, ethernet frame interface + */ +module udp_complete #( + parameter ARP_CACHE_ADDR_WIDTH = 2, + parameter ARP_REQUEST_RETRY_COUNT = 4, + parameter ARP_REQUEST_RETRY_INTERVAL = 125000000*2, + parameter ARP_REQUEST_TIMEOUT = 125000000*30, + parameter UDP_CHECKSUM_ENABLE = 1, + parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11, + parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3 +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [7:0] input_eth_payload_tdata, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [7:0] output_eth_payload_tdata, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * IP input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [7:0] input_ip_payload_tdata, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_ip_eth_dest_mac, + output wire [47:0] output_ip_eth_src_mac, + output wire [15:0] output_ip_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [7:0] output_ip_payload_tdata, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * UDP input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [5:0] input_udp_ip_dscp, + input wire [1:0] input_udp_ip_ecn, + input wire [7:0] input_udp_ip_ttl, + input wire [31:0] input_udp_ip_source_ip, + input wire [31:0] input_udp_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [7:0] input_udp_payload_tdata, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_udp_eth_dest_mac, + output wire [47:0] output_udp_eth_src_mac, + output wire [15:0] output_udp_eth_type, + output wire [3:0] output_udp_ip_version, + output wire [3:0] output_udp_ip_ihl, + output wire [5:0] output_udp_ip_dscp, + output wire [1:0] output_udp_ip_ecn, + output wire [15:0] output_udp_ip_length, + output wire [15:0] output_udp_ip_identification, + output wire [2:0] output_udp_ip_flags, + output wire [12:0] output_udp_ip_fragment_offset, + output wire [7:0] output_udp_ip_ttl, + output wire [7:0] output_udp_ip_protocol, + output wire [15:0] output_udp_ip_header_checksum, + output wire [31:0] output_udp_ip_source_ip, + output wire [31:0] output_udp_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [7:0] output_udp_payload_tdata, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Status + */ + output wire ip_rx_busy, + output wire ip_tx_busy, + output wire udp_rx_busy, + output wire udp_tx_busy, + output wire ip_rx_error_header_early_termination, + output wire ip_rx_error_payload_early_termination, + output wire ip_rx_error_invalid_header, + output wire ip_rx_error_invalid_checksum, + output wire ip_tx_error_payload_early_termination, + output wire ip_tx_error_arp_failed, + output wire udp_rx_error_header_early_termination, + output wire udp_rx_error_payload_early_termination, + output wire udp_tx_error_payload_early_termination, + + /* + * Configuration + */ + input wire [47:0] local_mac, + input wire [31:0] local_ip, + input wire [31:0] gateway_ip, + input wire [31:0] subnet_mask, + input wire clear_arp_cache +); + +wire ip_rx_ip_hdr_valid; +wire ip_rx_ip_hdr_ready; +wire [47:0] ip_rx_ip_eth_dest_mac; +wire [47:0] ip_rx_ip_eth_src_mac; +wire [15:0] ip_rx_ip_eth_type; +wire [3:0] ip_rx_ip_version; +wire [3:0] ip_rx_ip_ihl; +wire [5:0] ip_rx_ip_dscp; +wire [1:0] ip_rx_ip_ecn; +wire [15:0] ip_rx_ip_length; +wire [15:0] ip_rx_ip_identification; +wire [2:0] ip_rx_ip_flags; +wire [12:0] ip_rx_ip_fragment_offset; +wire [7:0] ip_rx_ip_ttl; +wire [7:0] ip_rx_ip_protocol; +wire [15:0] ip_rx_ip_header_checksum; +wire [31:0] ip_rx_ip_source_ip; +wire [31:0] ip_rx_ip_dest_ip; +wire [7:0] ip_rx_ip_payload_tdata; +wire ip_rx_ip_payload_tvalid; +wire ip_rx_ip_payload_tlast; +wire ip_rx_ip_payload_tuser; +wire ip_rx_ip_payload_tready; + +wire ip_tx_ip_hdr_valid; +wire ip_tx_ip_hdr_ready; +wire [5:0] ip_tx_ip_dscp; +wire [1:0] ip_tx_ip_ecn; +wire [15:0] ip_tx_ip_length; +wire [7:0] ip_tx_ip_ttl; +wire [7:0] ip_tx_ip_protocol; +wire [31:0] ip_tx_ip_source_ip; +wire [31:0] ip_tx_ip_dest_ip; +wire [7:0] ip_tx_ip_payload_tdata; +wire ip_tx_ip_payload_tvalid; +wire ip_tx_ip_payload_tlast; +wire ip_tx_ip_payload_tuser; +wire ip_tx_ip_payload_tready; + +wire udp_rx_ip_hdr_valid; +wire udp_rx_ip_hdr_ready; +wire [47:0] udp_rx_ip_eth_dest_mac; +wire [47:0] udp_rx_ip_eth_src_mac; +wire [15:0] udp_rx_ip_eth_type; +wire [3:0] udp_rx_ip_version; +wire [3:0] udp_rx_ip_ihl; +wire [5:0] udp_rx_ip_dscp; +wire [1:0] udp_rx_ip_ecn; +wire [15:0] udp_rx_ip_length; +wire [15:0] udp_rx_ip_identification; +wire [2:0] udp_rx_ip_flags; +wire [12:0] udp_rx_ip_fragment_offset; +wire [7:0] udp_rx_ip_ttl; +wire [7:0] udp_rx_ip_protocol; +wire [15:0] udp_rx_ip_header_checksum; +wire [31:0] udp_rx_ip_source_ip; +wire [31:0] udp_rx_ip_dest_ip; +wire [7:0] udp_rx_ip_payload_tdata; +wire udp_rx_ip_payload_tvalid; +wire udp_rx_ip_payload_tlast; +wire udp_rx_ip_payload_tuser; +wire udp_rx_ip_payload_tready; + +wire udp_tx_ip_hdr_valid; +wire udp_tx_ip_hdr_ready; +wire [5:0] udp_tx_ip_dscp; +wire [1:0] udp_tx_ip_ecn; +wire [15:0] udp_tx_ip_length; +wire [7:0] udp_tx_ip_ttl; +wire [7:0] udp_tx_ip_protocol; +wire [31:0] udp_tx_ip_source_ip; +wire [31:0] udp_tx_ip_dest_ip; +wire [7:0] udp_tx_ip_payload_tdata; +wire udp_tx_ip_payload_tvalid; +wire udp_tx_ip_payload_tlast; +wire udp_tx_ip_payload_tuser; +wire udp_tx_ip_payload_tready; + +/* + * Input classifier (ip_protocol) + */ +wire input_select_udp = (ip_rx_ip_protocol == 8'h11); +wire input_select_ip = ~input_select_udp; + +// IP frame to UDP module +assign udp_rx_ip_hdr_valid = input_select_udp & ip_rx_ip_hdr_valid; +assign udp_rx_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; +assign udp_rx_ip_eth_src_mac = ip_rx_ip_eth_src_mac; +assign udp_rx_ip_eth_type = ip_rx_ip_eth_type; +assign udp_rx_ip_version = ip_rx_ip_version; +assign udp_rx_ip_ihl = ip_rx_ip_ihl; +assign udp_rx_ip_dscp = ip_rx_ip_dscp; +assign udp_rx_ip_ecn = ip_rx_ip_ecn; +assign udp_rx_ip_length = ip_rx_ip_length; +assign udp_rx_ip_identification = ip_rx_ip_identification; +assign udp_rx_ip_flags = ip_rx_ip_flags; +assign udp_rx_ip_fragment_offset = ip_rx_ip_fragment_offset; +assign udp_rx_ip_ttl = ip_rx_ip_ttl; +assign udp_rx_ip_protocol = 8'h11; +assign udp_rx_ip_header_checksum = ip_rx_ip_header_checksum; +assign udp_rx_ip_source_ip = ip_rx_ip_source_ip; +assign udp_rx_ip_dest_ip = ip_rx_ip_dest_ip; +assign udp_rx_ip_payload_tdata = ip_rx_ip_payload_tdata; +assign udp_rx_ip_payload_tvalid = input_select_udp & ip_rx_ip_payload_tvalid; +assign udp_rx_ip_payload_tlast = ip_rx_ip_payload_tlast; +assign udp_rx_ip_payload_tuser = ip_rx_ip_payload_tuser; + +// External IP frame output +assign output_ip_hdr_valid = input_select_ip & ip_rx_ip_hdr_valid; +assign output_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; +assign output_ip_eth_src_mac = ip_rx_ip_eth_src_mac; +assign output_ip_eth_type = ip_rx_ip_eth_type; +assign output_ip_version = ip_rx_ip_version; +assign output_ip_ihl = ip_rx_ip_ihl; +assign output_ip_dscp = ip_rx_ip_dscp; +assign output_ip_ecn = ip_rx_ip_ecn; +assign output_ip_length = ip_rx_ip_length; +assign output_ip_identification = ip_rx_ip_identification; +assign output_ip_flags = ip_rx_ip_flags; +assign output_ip_fragment_offset = ip_rx_ip_fragment_offset; +assign output_ip_ttl = ip_rx_ip_ttl; +assign output_ip_protocol = ip_rx_ip_protocol; +assign output_ip_header_checksum = ip_rx_ip_header_checksum; +assign output_ip_source_ip = ip_rx_ip_source_ip; +assign output_ip_dest_ip = ip_rx_ip_dest_ip; +assign output_ip_payload_tdata = ip_rx_ip_payload_tdata; +assign output_ip_payload_tvalid = input_select_ip & ip_rx_ip_payload_tvalid; +assign output_ip_payload_tlast = ip_rx_ip_payload_tlast; +assign output_ip_payload_tuser = ip_rx_ip_payload_tuser; + +assign ip_rx_ip_hdr_ready = udp_rx_ip_hdr_ready & output_ip_hdr_ready; + +assign ip_rx_ip_payload_tready = (input_select_udp & udp_rx_ip_payload_tready) | + (input_select_ip & output_ip_payload_tready); + +/* + * Output arbiter + */ +ip_arb_mux_2 +ip_arb_mux_2_inst ( + .clk(clk), + .rst(rst), + // IP frame input from UDP module + .input_0_ip_hdr_valid(udp_tx_ip_hdr_valid), + .input_0_ip_hdr_ready(udp_tx_ip_hdr_ready), + .input_0_eth_dest_mac(0), + .input_0_eth_src_mac(0), + .input_0_eth_type(0), + .input_0_ip_version(0), + .input_0_ip_ihl(0), + .input_0_ip_dscp(udp_tx_ip_dscp), + .input_0_ip_ecn(udp_tx_ip_ecn), + .input_0_ip_length(udp_tx_ip_length), + .input_0_ip_identification(0), + .input_0_ip_flags(0), + .input_0_ip_fragment_offset(0), + .input_0_ip_ttl(udp_tx_ip_ttl), + .input_0_ip_protocol(udp_tx_ip_protocol), + .input_0_ip_header_checksum(0), + .input_0_ip_source_ip(udp_tx_ip_source_ip), + .input_0_ip_dest_ip(udp_tx_ip_dest_ip), + .input_0_ip_payload_tdata(udp_tx_ip_payload_tdata), + .input_0_ip_payload_tvalid(udp_tx_ip_payload_tvalid), + .input_0_ip_payload_tready(udp_tx_ip_payload_tready), + .input_0_ip_payload_tlast(udp_tx_ip_payload_tlast), + .input_0_ip_payload_tuser(udp_tx_ip_payload_tuser), + // External IP frame input + .input_1_ip_hdr_valid(input_ip_hdr_valid), + .input_1_ip_hdr_ready(input_ip_hdr_ready), + .input_1_eth_dest_mac(0), + .input_1_eth_src_mac(0), + .input_1_eth_type(0), + .input_1_ip_version(0), + .input_1_ip_ihl(0), + .input_1_ip_dscp(input_ip_dscp), + .input_1_ip_ecn(input_ip_ecn), + .input_1_ip_length(input_ip_length), + .input_1_ip_identification(0), + .input_1_ip_flags(0), + .input_1_ip_fragment_offset(0), + .input_1_ip_ttl(input_ip_ttl), + .input_1_ip_protocol(input_ip_protocol), + .input_1_ip_header_checksum(0), + .input_1_ip_source_ip(input_ip_source_ip), + .input_1_ip_dest_ip(input_ip_dest_ip), + .input_1_ip_payload_tdata(input_ip_payload_tdata), + .input_1_ip_payload_tvalid(input_ip_payload_tvalid), + .input_1_ip_payload_tready(input_ip_payload_tready), + .input_1_ip_payload_tlast(input_ip_payload_tlast), + .input_1_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output to IP stack + .output_ip_hdr_valid(ip_tx_ip_hdr_valid), + .output_ip_hdr_ready(ip_tx_ip_hdr_ready), + .output_eth_dest_mac(), + .output_eth_src_mac(), + .output_eth_type(), + .output_ip_version(), + .output_ip_ihl(), + .output_ip_dscp(ip_tx_ip_dscp), + .output_ip_ecn(ip_tx_ip_ecn), + .output_ip_length(ip_tx_ip_length), + .output_ip_identification(), + .output_ip_flags(), + .output_ip_fragment_offset(), + .output_ip_ttl(ip_tx_ip_ttl), + .output_ip_protocol(ip_tx_ip_protocol), + .output_ip_header_checksum(), + .output_ip_source_ip(ip_tx_ip_source_ip), + .output_ip_dest_ip(ip_tx_ip_dest_ip), + .output_ip_payload_tdata(ip_tx_ip_payload_tdata), + .output_ip_payload_tvalid(ip_tx_ip_payload_tvalid), + .output_ip_payload_tready(ip_tx_ip_payload_tready), + .output_ip_payload_tlast(ip_tx_ip_payload_tlast), + .output_ip_payload_tuser(ip_tx_ip_payload_tuser) +); + +/* + * IP stack + */ +ip_complete #( + .ARP_CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT) +) +ip_complete_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(ip_tx_ip_hdr_valid), + .input_ip_hdr_ready(ip_tx_ip_hdr_ready), + .input_ip_dscp(ip_tx_ip_dscp), + .input_ip_ecn(ip_tx_ip_ecn), + .input_ip_length(ip_tx_ip_length), + .input_ip_ttl(ip_tx_ip_ttl), + .input_ip_protocol(ip_tx_ip_protocol), + .input_ip_source_ip(ip_tx_ip_source_ip), + .input_ip_dest_ip(ip_tx_ip_dest_ip), + .input_ip_payload_tdata(ip_tx_ip_payload_tdata), + .input_ip_payload_tvalid(ip_tx_ip_payload_tvalid), + .input_ip_payload_tready(ip_tx_ip_payload_tready), + .input_ip_payload_tlast(ip_tx_ip_payload_tlast), + .input_ip_payload_tuser(ip_tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(ip_rx_ip_hdr_valid), + .output_ip_hdr_ready(ip_rx_ip_hdr_ready), + .output_ip_eth_dest_mac(ip_rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(ip_rx_ip_eth_src_mac), + .output_ip_eth_type(ip_rx_ip_eth_type), + .output_ip_version(ip_rx_ip_version), + .output_ip_ihl(ip_rx_ip_ihl), + .output_ip_dscp(ip_rx_ip_dscp), + .output_ip_ecn(ip_rx_ip_ecn), + .output_ip_length(ip_rx_ip_length), + .output_ip_identification(ip_rx_ip_identification), + .output_ip_flags(ip_rx_ip_flags), + .output_ip_fragment_offset(ip_rx_ip_fragment_offset), + .output_ip_ttl(ip_rx_ip_ttl), + .output_ip_protocol(ip_rx_ip_protocol), + .output_ip_header_checksum(ip_rx_ip_header_checksum), + .output_ip_source_ip(ip_rx_ip_source_ip), + .output_ip_dest_ip(ip_rx_ip_dest_ip), + .output_ip_payload_tdata(ip_rx_ip_payload_tdata), + .output_ip_payload_tvalid(ip_rx_ip_payload_tvalid), + .output_ip_payload_tready(ip_rx_ip_payload_tready), + .output_ip_payload_tlast(ip_rx_ip_payload_tlast), + .output_ip_payload_tuser(ip_rx_ip_payload_tuser), + // Status + .rx_busy(ip_rx_busy), + .tx_busy(ip_tx_busy), + .rx_error_header_early_termination(ip_rx_error_header_early_termination), + .rx_error_payload_early_termination(ip_rx_error_payload_early_termination), + .rx_error_invalid_header(ip_rx_error_invalid_header), + .rx_error_invalid_checksum(ip_rx_error_invalid_checksum), + .tx_error_payload_early_termination(ip_tx_error_payload_early_termination), + .tx_error_arp_failed(ip_tx_error_arp_failed), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(clear_arp_cache) +); + +/* + * UDP interface + */ +udp #( + .CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) +) +udp_inst ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(udp_rx_ip_hdr_valid), + .input_ip_hdr_ready(udp_rx_ip_hdr_ready), + .input_ip_eth_dest_mac(udp_rx_ip_eth_dest_mac), + .input_ip_eth_src_mac(udp_rx_ip_eth_src_mac), + .input_ip_eth_type(udp_rx_ip_eth_type), + .input_ip_version(udp_rx_ip_version), + .input_ip_ihl(udp_rx_ip_ihl), + .input_ip_dscp(udp_rx_ip_dscp), + .input_ip_ecn(udp_rx_ip_ecn), + .input_ip_length(udp_rx_ip_length), + .input_ip_identification(udp_rx_ip_identification), + .input_ip_flags(udp_rx_ip_flags), + .input_ip_fragment_offset(udp_rx_ip_fragment_offset), + .input_ip_ttl(udp_rx_ip_ttl), + .input_ip_protocol(udp_rx_ip_protocol), + .input_ip_header_checksum(udp_rx_ip_header_checksum), + .input_ip_source_ip(udp_rx_ip_source_ip), + .input_ip_dest_ip(udp_rx_ip_dest_ip), + .input_ip_payload_tdata(udp_rx_ip_payload_tdata), + .input_ip_payload_tvalid(udp_rx_ip_payload_tvalid), + .input_ip_payload_tready(udp_rx_ip_payload_tready), + .input_ip_payload_tlast(udp_rx_ip_payload_tlast), + .input_ip_payload_tuser(udp_rx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(udp_tx_ip_hdr_valid), + .output_ip_hdr_ready(udp_tx_ip_hdr_ready), + .output_ip_eth_dest_mac(), + .output_ip_eth_src_mac(), + .output_ip_eth_type(), + .output_ip_version(), + .output_ip_ihl(), + .output_ip_dscp(udp_tx_ip_dscp), + .output_ip_ecn(udp_tx_ip_ecn), + .output_ip_length(udp_tx_ip_length), + .output_ip_identification(), + .output_ip_flags(), + .output_ip_fragment_offset(), + .output_ip_ttl(udp_tx_ip_ttl), + .output_ip_protocol(udp_tx_ip_protocol), + .output_ip_header_checksum(), + .output_ip_source_ip(udp_tx_ip_source_ip), + .output_ip_dest_ip(udp_tx_ip_dest_ip), + .output_ip_payload_tdata(udp_tx_ip_payload_tdata), + .output_ip_payload_tvalid(udp_tx_ip_payload_tvalid), + .output_ip_payload_tready(udp_tx_ip_payload_tready), + .output_ip_payload_tlast(udp_tx_ip_payload_tlast), + .output_ip_payload_tuser(udp_tx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_udp_eth_dest_mac(0), + .input_udp_eth_src_mac(0), + .input_udp_eth_type(0), + .input_udp_ip_version(0), + .input_udp_ip_ihl(0), + .input_udp_ip_dscp(input_udp_ip_dscp), + .input_udp_ip_ecn(input_udp_ip_ecn), + .input_udp_ip_identification(0), + .input_udp_ip_flags(0), + .input_udp_ip_fragment_offset(0), + .input_udp_ip_ttl(input_udp_ip_ttl), + .input_udp_ip_header_checksum(0), + .input_udp_ip_source_ip(input_udp_ip_source_ip), + .input_udp_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_udp_eth_dest_mac(output_udp_eth_dest_mac), + .output_udp_eth_src_mac(output_udp_eth_src_mac), + .output_udp_eth_type(output_udp_eth_type), + .output_udp_ip_version(output_udp_ip_version), + .output_udp_ip_ihl(output_udp_ip_ihl), + .output_udp_ip_dscp(output_udp_ip_dscp), + .output_udp_ip_ecn(output_udp_ip_ecn), + .output_udp_ip_length(output_udp_ip_length), + .output_udp_ip_identification(output_udp_ip_identification), + .output_udp_ip_flags(output_udp_ip_flags), + .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_udp_ip_ttl(output_udp_ip_ttl), + .output_udp_ip_protocol(output_udp_ip_protocol), + .output_udp_ip_header_checksum(output_udp_ip_header_checksum), + .output_udp_ip_source_ip(output_udp_ip_source_ip), + .output_udp_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status + .rx_busy(udp_rx_busy), + .tx_busy(udp_tx_busy), + .rx_error_header_early_termination(udp_rx_error_header_early_termination), + .rx_error_payload_early_termination(udp_rx_error_payload_early_termination), + .tx_error_payload_early_termination(udp_tx_error_payload_early_termination) +); + +endmodule diff --git a/rtl/udp_complete_64.v b/rtl/udp_complete_64.v new file mode 100644 index 000000000..8eeb2525f --- /dev/null +++ b/rtl/udp_complete_64.v @@ -0,0 +1,646 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1ns / 1ps + +/* + * IPv4 and ARP block with UDP support, ethernet frame interface (64 bit datapath) + */ +module udp_complete_64 #( + parameter ARP_CACHE_ADDR_WIDTH = 2, + parameter ARP_REQUEST_RETRY_COUNT = 4, + parameter ARP_REQUEST_RETRY_INTERVAL = 125000000*2, + parameter ARP_REQUEST_TIMEOUT = 125000000*30, + parameter UDP_CHECKSUM_ENABLE = 1, + parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11, + parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3 +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire input_eth_hdr_valid, + output wire input_eth_hdr_ready, + input wire [47:0] input_eth_dest_mac, + input wire [47:0] input_eth_src_mac, + input wire [15:0] input_eth_type, + input wire [63:0] input_eth_payload_tdata, + input wire [7:0] input_eth_payload_tkeep, + input wire input_eth_payload_tvalid, + output wire input_eth_payload_tready, + input wire input_eth_payload_tlast, + input wire input_eth_payload_tuser, + + /* + * Ethernet frame output + */ + output wire output_eth_hdr_valid, + input wire output_eth_hdr_ready, + output wire [47:0] output_eth_dest_mac, + output wire [47:0] output_eth_src_mac, + output wire [15:0] output_eth_type, + output wire [63:0] output_eth_payload_tdata, + output wire [7:0] output_eth_payload_tkeep, + output wire output_eth_payload_tvalid, + input wire output_eth_payload_tready, + output wire output_eth_payload_tlast, + output wire output_eth_payload_tuser, + + /* + * IP input + */ + input wire input_ip_hdr_valid, + output wire input_ip_hdr_ready, + input wire [5:0] input_ip_dscp, + input wire [1:0] input_ip_ecn, + input wire [15:0] input_ip_length, + input wire [7:0] input_ip_ttl, + input wire [7:0] input_ip_protocol, + input wire [31:0] input_ip_source_ip, + input wire [31:0] input_ip_dest_ip, + input wire [63:0] input_ip_payload_tdata, + input wire [7:0] input_ip_payload_tkeep, + input wire input_ip_payload_tvalid, + output wire input_ip_payload_tready, + input wire input_ip_payload_tlast, + input wire input_ip_payload_tuser, + + /* + * IP output + */ + output wire output_ip_hdr_valid, + input wire output_ip_hdr_ready, + output wire [47:0] output_ip_eth_dest_mac, + output wire [47:0] output_ip_eth_src_mac, + output wire [15:0] output_ip_eth_type, + output wire [3:0] output_ip_version, + output wire [3:0] output_ip_ihl, + output wire [5:0] output_ip_dscp, + output wire [1:0] output_ip_ecn, + output wire [15:0] output_ip_length, + output wire [15:0] output_ip_identification, + output wire [2:0] output_ip_flags, + output wire [12:0] output_ip_fragment_offset, + output wire [7:0] output_ip_ttl, + output wire [7:0] output_ip_protocol, + output wire [15:0] output_ip_header_checksum, + output wire [31:0] output_ip_source_ip, + output wire [31:0] output_ip_dest_ip, + output wire [63:0] output_ip_payload_tdata, + output wire [7:0] output_ip_payload_tkeep, + output wire output_ip_payload_tvalid, + input wire output_ip_payload_tready, + output wire output_ip_payload_tlast, + output wire output_ip_payload_tuser, + + /* + * UDP input + */ + input wire input_udp_hdr_valid, + output wire input_udp_hdr_ready, + input wire [5:0] input_udp_ip_dscp, + input wire [1:0] input_udp_ip_ecn, + input wire [7:0] input_udp_ip_ttl, + input wire [31:0] input_udp_ip_source_ip, + input wire [31:0] input_udp_ip_dest_ip, + input wire [15:0] input_udp_source_port, + input wire [15:0] input_udp_dest_port, + input wire [15:0] input_udp_length, + input wire [15:0] input_udp_checksum, + input wire [63:0] input_udp_payload_tdata, + input wire [7:0] input_udp_payload_tkeep, + input wire input_udp_payload_tvalid, + output wire input_udp_payload_tready, + input wire input_udp_payload_tlast, + input wire input_udp_payload_tuser, + + /* + * UDP output + */ + output wire output_udp_hdr_valid, + input wire output_udp_hdr_ready, + output wire [47:0] output_udp_eth_dest_mac, + output wire [47:0] output_udp_eth_src_mac, + output wire [15:0] output_udp_eth_type, + output wire [3:0] output_udp_ip_version, + output wire [3:0] output_udp_ip_ihl, + output wire [5:0] output_udp_ip_dscp, + output wire [1:0] output_udp_ip_ecn, + output wire [15:0] output_udp_ip_length, + output wire [15:0] output_udp_ip_identification, + output wire [2:0] output_udp_ip_flags, + output wire [12:0] output_udp_ip_fragment_offset, + output wire [7:0] output_udp_ip_ttl, + output wire [7:0] output_udp_ip_protocol, + output wire [15:0] output_udp_ip_header_checksum, + output wire [31:0] output_udp_ip_source_ip, + output wire [31:0] output_udp_ip_dest_ip, + output wire [15:0] output_udp_source_port, + output wire [15:0] output_udp_dest_port, + output wire [15:0] output_udp_length, + output wire [15:0] output_udp_checksum, + output wire [63:0] output_udp_payload_tdata, + output wire [7:0] output_udp_payload_tkeep, + output wire output_udp_payload_tvalid, + input wire output_udp_payload_tready, + output wire output_udp_payload_tlast, + output wire output_udp_payload_tuser, + + /* + * Status + */ + output wire ip_rx_busy, + output wire ip_tx_busy, + output wire udp_rx_busy, + output wire udp_tx_busy, + output wire ip_rx_error_header_early_termination, + output wire ip_rx_error_payload_early_termination, + output wire ip_rx_error_invalid_header, + output wire ip_rx_error_invalid_checksum, + output wire ip_tx_error_payload_early_termination, + output wire ip_tx_error_arp_failed, + output wire udp_rx_error_header_early_termination, + output wire udp_rx_error_payload_early_termination, + output wire udp_tx_error_payload_early_termination, + + /* + * Configuration + */ + input wire [47:0] local_mac, + input wire [31:0] local_ip, + input wire [31:0] gateway_ip, + input wire [31:0] subnet_mask, + input wire clear_arp_cache +); + +wire ip_rx_ip_hdr_valid; +wire ip_rx_ip_hdr_ready; +wire [47:0] ip_rx_ip_eth_dest_mac; +wire [47:0] ip_rx_ip_eth_src_mac; +wire [15:0] ip_rx_ip_eth_type; +wire [3:0] ip_rx_ip_version; +wire [3:0] ip_rx_ip_ihl; +wire [5:0] ip_rx_ip_dscp; +wire [1:0] ip_rx_ip_ecn; +wire [15:0] ip_rx_ip_length; +wire [15:0] ip_rx_ip_identification; +wire [2:0] ip_rx_ip_flags; +wire [12:0] ip_rx_ip_fragment_offset; +wire [7:0] ip_rx_ip_ttl; +wire [7:0] ip_rx_ip_protocol; +wire [15:0] ip_rx_ip_header_checksum; +wire [31:0] ip_rx_ip_source_ip; +wire [31:0] ip_rx_ip_dest_ip; +wire [63:0] ip_rx_ip_payload_tdata; +wire [7:0] ip_rx_ip_payload_tkeep; +wire ip_rx_ip_payload_tvalid; +wire ip_rx_ip_payload_tlast; +wire ip_rx_ip_payload_tuser; +wire ip_rx_ip_payload_tready; + +wire ip_tx_ip_hdr_valid; +wire ip_tx_ip_hdr_ready; +wire [5:0] ip_tx_ip_dscp; +wire [1:0] ip_tx_ip_ecn; +wire [15:0] ip_tx_ip_length; +wire [7:0] ip_tx_ip_ttl; +wire [7:0] ip_tx_ip_protocol; +wire [31:0] ip_tx_ip_source_ip; +wire [31:0] ip_tx_ip_dest_ip; +wire [63:0] ip_tx_ip_payload_tdata; +wire [7:0] ip_tx_ip_payload_tkeep; +wire ip_tx_ip_payload_tvalid; +wire ip_tx_ip_payload_tlast; +wire ip_tx_ip_payload_tuser; +wire ip_tx_ip_payload_tready; + +wire udp_rx_ip_hdr_valid; +wire udp_rx_ip_hdr_ready; +wire [47:0] udp_rx_ip_eth_dest_mac; +wire [47:0] udp_rx_ip_eth_src_mac; +wire [15:0] udp_rx_ip_eth_type; +wire [3:0] udp_rx_ip_version; +wire [3:0] udp_rx_ip_ihl; +wire [5:0] udp_rx_ip_dscp; +wire [1:0] udp_rx_ip_ecn; +wire [15:0] udp_rx_ip_length; +wire [15:0] udp_rx_ip_identification; +wire [2:0] udp_rx_ip_flags; +wire [12:0] udp_rx_ip_fragment_offset; +wire [7:0] udp_rx_ip_ttl; +wire [7:0] udp_rx_ip_protocol; +wire [15:0] udp_rx_ip_header_checksum; +wire [31:0] udp_rx_ip_source_ip; +wire [31:0] udp_rx_ip_dest_ip; +wire [63:0] udp_rx_ip_payload_tdata; +wire [7:0] udp_rx_ip_payload_tkeep; +wire udp_rx_ip_payload_tvalid; +wire udp_rx_ip_payload_tlast; +wire udp_rx_ip_payload_tuser; +wire udp_rx_ip_payload_tready; + +wire udp_tx_ip_hdr_valid; +wire udp_tx_ip_hdr_ready; +wire [5:0] udp_tx_ip_dscp; +wire [1:0] udp_tx_ip_ecn; +wire [15:0] udp_tx_ip_length; +wire [7:0] udp_tx_ip_ttl; +wire [7:0] udp_tx_ip_protocol; +wire [31:0] udp_tx_ip_source_ip; +wire [31:0] udp_tx_ip_dest_ip; +wire [63:0] udp_tx_ip_payload_tdata; +wire [7:0] udp_tx_ip_payload_tkeep; +wire udp_tx_ip_payload_tvalid; +wire udp_tx_ip_payload_tlast; +wire udp_tx_ip_payload_tuser; +wire udp_tx_ip_payload_tready; + +/* + * Input classifier (ip_protocol) + */ +wire input_select_udp = (ip_rx_ip_protocol == 8'h11); +wire input_select_ip = ~input_select_udp; + +// IP frame to UDP module +assign udp_rx_ip_hdr_valid = input_select_udp & ip_rx_ip_hdr_valid; +assign udp_rx_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; +assign udp_rx_ip_eth_src_mac = ip_rx_ip_eth_src_mac; +assign udp_rx_ip_eth_type = ip_rx_ip_eth_type; +assign udp_rx_ip_version = ip_rx_ip_version; +assign udp_rx_ip_ihl = ip_rx_ip_ihl; +assign udp_rx_ip_dscp = ip_rx_ip_dscp; +assign udp_rx_ip_ecn = ip_rx_ip_ecn; +assign udp_rx_ip_length = ip_rx_ip_length; +assign udp_rx_ip_identification = ip_rx_ip_identification; +assign udp_rx_ip_flags = ip_rx_ip_flags; +assign udp_rx_ip_fragment_offset = ip_rx_ip_fragment_offset; +assign udp_rx_ip_ttl = ip_rx_ip_ttl; +assign udp_rx_ip_protocol = 8'h11; +assign udp_rx_ip_header_checksum = ip_rx_ip_header_checksum; +assign udp_rx_ip_source_ip = ip_rx_ip_source_ip; +assign udp_rx_ip_dest_ip = ip_rx_ip_dest_ip; +assign udp_rx_ip_payload_tdata = ip_rx_ip_payload_tdata; +assign udp_rx_ip_payload_tkeep = ip_rx_ip_payload_tkeep; +assign udp_rx_ip_payload_tvalid = input_select_udp & ip_rx_ip_payload_tvalid; +assign udp_rx_ip_payload_tlast = ip_rx_ip_payload_tlast; +assign udp_rx_ip_payload_tuser = ip_rx_ip_payload_tuser; + +// External IP frame output +assign output_ip_hdr_valid = input_select_ip & ip_rx_ip_hdr_valid; +assign output_ip_eth_dest_mac = ip_rx_ip_eth_dest_mac; +assign output_ip_eth_src_mac = ip_rx_ip_eth_src_mac; +assign output_ip_eth_type = ip_rx_ip_eth_type; +assign output_ip_version = ip_rx_ip_version; +assign output_ip_ihl = ip_rx_ip_ihl; +assign output_ip_dscp = ip_rx_ip_dscp; +assign output_ip_ecn = ip_rx_ip_ecn; +assign output_ip_length = ip_rx_ip_length; +assign output_ip_identification = ip_rx_ip_identification; +assign output_ip_flags = ip_rx_ip_flags; +assign output_ip_fragment_offset = ip_rx_ip_fragment_offset; +assign output_ip_ttl = ip_rx_ip_ttl; +assign output_ip_protocol = ip_rx_ip_protocol; +assign output_ip_header_checksum = ip_rx_ip_header_checksum; +assign output_ip_source_ip = ip_rx_ip_source_ip; +assign output_ip_dest_ip = ip_rx_ip_dest_ip; +assign output_ip_payload_tdata = ip_rx_ip_payload_tdata; +assign output_ip_payload_tkeep = ip_rx_ip_payload_tkeep; +assign output_ip_payload_tvalid = input_select_ip & ip_rx_ip_payload_tvalid; +assign output_ip_payload_tlast = ip_rx_ip_payload_tlast; +assign output_ip_payload_tuser = ip_rx_ip_payload_tuser; + +assign ip_rx_ip_hdr_ready = udp_rx_ip_hdr_ready & output_ip_hdr_ready; + +assign ip_rx_ip_payload_tready = (input_select_udp & udp_rx_ip_payload_tready) | + (input_select_ip & output_ip_payload_tready); + +/* + * Output arbiter + */ +ip_arb_mux_64_2 +ip_arb_mux_64_2_inst ( + .clk(clk), + .rst(rst), + // IP frame input from UDP module + .input_0_ip_hdr_valid(udp_tx_ip_hdr_valid), + .input_0_ip_hdr_ready(udp_tx_ip_hdr_ready), + .input_0_eth_dest_mac(0), + .input_0_eth_src_mac(0), + .input_0_eth_type(0), + .input_0_ip_version(0), + .input_0_ip_ihl(0), + .input_0_ip_dscp(udp_tx_ip_dscp), + .input_0_ip_ecn(udp_tx_ip_ecn), + .input_0_ip_length(udp_tx_ip_length), + .input_0_ip_identification(0), + .input_0_ip_flags(0), + .input_0_ip_fragment_offset(0), + .input_0_ip_ttl(udp_tx_ip_ttl), + .input_0_ip_protocol(udp_tx_ip_protocol), + .input_0_ip_header_checksum(0), + .input_0_ip_source_ip(udp_tx_ip_source_ip), + .input_0_ip_dest_ip(udp_tx_ip_dest_ip), + .input_0_ip_payload_tdata(udp_tx_ip_payload_tdata), + .input_0_ip_payload_tkeep(udp_tx_ip_payload_tkeep), + .input_0_ip_payload_tvalid(udp_tx_ip_payload_tvalid), + .input_0_ip_payload_tready(udp_tx_ip_payload_tready), + .input_0_ip_payload_tlast(udp_tx_ip_payload_tlast), + .input_0_ip_payload_tuser(udp_tx_ip_payload_tuser), + // External IP frame input + .input_1_ip_hdr_valid(input_ip_hdr_valid), + .input_1_ip_hdr_ready(input_ip_hdr_ready), + .input_1_eth_dest_mac(0), + .input_1_eth_src_mac(0), + .input_1_eth_type(0), + .input_1_ip_version(0), + .input_1_ip_ihl(0), + .input_1_ip_dscp(input_ip_dscp), + .input_1_ip_ecn(input_ip_ecn), + .input_1_ip_length(input_ip_length), + .input_1_ip_identification(0), + .input_1_ip_flags(0), + .input_1_ip_fragment_offset(0), + .input_1_ip_ttl(input_ip_ttl), + .input_1_ip_protocol(input_ip_protocol), + .input_1_ip_header_checksum(0), + .input_1_ip_source_ip(input_ip_source_ip), + .input_1_ip_dest_ip(input_ip_dest_ip), + .input_1_ip_payload_tdata(input_ip_payload_tdata), + .input_1_ip_payload_tkeep(input_ip_payload_tkeep), + .input_1_ip_payload_tvalid(input_ip_payload_tvalid), + .input_1_ip_payload_tready(input_ip_payload_tready), + .input_1_ip_payload_tlast(input_ip_payload_tlast), + .input_1_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output to IP stack + .output_ip_hdr_valid(ip_tx_ip_hdr_valid), + .output_ip_hdr_ready(ip_tx_ip_hdr_ready), + .output_eth_dest_mac(), + .output_eth_src_mac(), + .output_eth_type(), + .output_ip_version(), + .output_ip_ihl(), + .output_ip_dscp(ip_tx_ip_dscp), + .output_ip_ecn(ip_tx_ip_ecn), + .output_ip_length(ip_tx_ip_length), + .output_ip_identification(), + .output_ip_flags(), + .output_ip_fragment_offset(), + .output_ip_ttl(ip_tx_ip_ttl), + .output_ip_protocol(ip_tx_ip_protocol), + .output_ip_header_checksum(), + .output_ip_source_ip(ip_tx_ip_source_ip), + .output_ip_dest_ip(ip_tx_ip_dest_ip), + .output_ip_payload_tdata(ip_tx_ip_payload_tdata), + .output_ip_payload_tkeep(ip_tx_ip_payload_tkeep), + .output_ip_payload_tvalid(ip_tx_ip_payload_tvalid), + .output_ip_payload_tready(ip_tx_ip_payload_tready), + .output_ip_payload_tlast(ip_tx_ip_payload_tlast), + .output_ip_payload_tuser(ip_tx_ip_payload_tuser) +); + +/* + * IP stack + */ +ip_complete_64 #( + .ARP_CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT) +) +ip_complete_64_inst ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(ip_tx_ip_hdr_valid), + .input_ip_hdr_ready(ip_tx_ip_hdr_ready), + .input_ip_dscp(ip_tx_ip_dscp), + .input_ip_ecn(ip_tx_ip_ecn), + .input_ip_length(ip_tx_ip_length), + .input_ip_ttl(ip_tx_ip_ttl), + .input_ip_protocol(ip_tx_ip_protocol), + .input_ip_source_ip(ip_tx_ip_source_ip), + .input_ip_dest_ip(ip_tx_ip_dest_ip), + .input_ip_payload_tdata(ip_tx_ip_payload_tdata), + .input_ip_payload_tkeep(ip_tx_ip_payload_tkeep), + .input_ip_payload_tvalid(ip_tx_ip_payload_tvalid), + .input_ip_payload_tready(ip_tx_ip_payload_tready), + .input_ip_payload_tlast(ip_tx_ip_payload_tlast), + .input_ip_payload_tuser(ip_tx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(ip_rx_ip_hdr_valid), + .output_ip_hdr_ready(ip_rx_ip_hdr_ready), + .output_ip_eth_dest_mac(ip_rx_ip_eth_dest_mac), + .output_ip_eth_src_mac(ip_rx_ip_eth_src_mac), + .output_ip_eth_type(ip_rx_ip_eth_type), + .output_ip_version(ip_rx_ip_version), + .output_ip_ihl(ip_rx_ip_ihl), + .output_ip_dscp(ip_rx_ip_dscp), + .output_ip_ecn(ip_rx_ip_ecn), + .output_ip_length(ip_rx_ip_length), + .output_ip_identification(ip_rx_ip_identification), + .output_ip_flags(ip_rx_ip_flags), + .output_ip_fragment_offset(ip_rx_ip_fragment_offset), + .output_ip_ttl(ip_rx_ip_ttl), + .output_ip_protocol(ip_rx_ip_protocol), + .output_ip_header_checksum(ip_rx_ip_header_checksum), + .output_ip_source_ip(ip_rx_ip_source_ip), + .output_ip_dest_ip(ip_rx_ip_dest_ip), + .output_ip_payload_tdata(ip_rx_ip_payload_tdata), + .output_ip_payload_tkeep(ip_rx_ip_payload_tkeep), + .output_ip_payload_tvalid(ip_rx_ip_payload_tvalid), + .output_ip_payload_tready(ip_rx_ip_payload_tready), + .output_ip_payload_tlast(ip_rx_ip_payload_tlast), + .output_ip_payload_tuser(ip_rx_ip_payload_tuser), + // Status + .rx_busy(ip_rx_busy), + .tx_busy(ip_tx_busy), + .rx_error_header_early_termination(ip_rx_error_header_early_termination), + .rx_error_payload_early_termination(ip_rx_error_payload_early_termination), + .rx_error_invalid_header(ip_rx_error_invalid_header), + .rx_error_invalid_checksum(ip_rx_error_invalid_checksum), + .tx_error_payload_early_termination(ip_tx_error_payload_early_termination), + .tx_error_arp_failed(ip_tx_error_arp_failed), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(clear_arp_cache) +); + +/* + * UDP interface + */ +udp_64 #( + .CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) +) +udp_64_inst ( + .clk(clk), + .rst(rst), + // IP frame input + .input_ip_hdr_valid(udp_rx_ip_hdr_valid), + .input_ip_hdr_ready(udp_rx_ip_hdr_ready), + .input_ip_eth_dest_mac(udp_rx_ip_eth_dest_mac), + .input_ip_eth_src_mac(udp_rx_ip_eth_src_mac), + .input_ip_eth_type(udp_rx_ip_eth_type), + .input_ip_version(udp_rx_ip_version), + .input_ip_ihl(udp_rx_ip_ihl), + .input_ip_dscp(udp_rx_ip_dscp), + .input_ip_ecn(udp_rx_ip_ecn), + .input_ip_length(udp_rx_ip_length), + .input_ip_identification(udp_rx_ip_identification), + .input_ip_flags(udp_rx_ip_flags), + .input_ip_fragment_offset(udp_rx_ip_fragment_offset), + .input_ip_ttl(udp_rx_ip_ttl), + .input_ip_protocol(udp_rx_ip_protocol), + .input_ip_header_checksum(udp_rx_ip_header_checksum), + .input_ip_source_ip(udp_rx_ip_source_ip), + .input_ip_dest_ip(udp_rx_ip_dest_ip), + .input_ip_payload_tdata(udp_rx_ip_payload_tdata), + .input_ip_payload_tkeep(udp_rx_ip_payload_tkeep), + .input_ip_payload_tvalid(udp_rx_ip_payload_tvalid), + .input_ip_payload_tready(udp_rx_ip_payload_tready), + .input_ip_payload_tlast(udp_rx_ip_payload_tlast), + .input_ip_payload_tuser(udp_rx_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(udp_tx_ip_hdr_valid), + .output_ip_hdr_ready(udp_tx_ip_hdr_ready), + .output_ip_eth_dest_mac(), + .output_ip_eth_src_mac(), + .output_ip_eth_type(), + .output_ip_version(), + .output_ip_ihl(), + .output_ip_dscp(udp_tx_ip_dscp), + .output_ip_ecn(udp_tx_ip_ecn), + .output_ip_length(udp_tx_ip_length), + .output_ip_identification(), + .output_ip_flags(), + .output_ip_fragment_offset(), + .output_ip_ttl(udp_tx_ip_ttl), + .output_ip_protocol(udp_tx_ip_protocol), + .output_ip_header_checksum(), + .output_ip_source_ip(udp_tx_ip_source_ip), + .output_ip_dest_ip(udp_tx_ip_dest_ip), + .output_ip_payload_tdata(udp_tx_ip_payload_tdata), + .output_ip_payload_tkeep(udp_tx_ip_payload_tkeep), + .output_ip_payload_tvalid(udp_tx_ip_payload_tvalid), + .output_ip_payload_tready(udp_tx_ip_payload_tready), + .output_ip_payload_tlast(udp_tx_ip_payload_tlast), + .output_ip_payload_tuser(udp_tx_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_udp_eth_dest_mac(0), + .input_udp_eth_src_mac(0), + .input_udp_eth_type(0), + .input_udp_ip_version(0), + .input_udp_ip_ihl(0), + .input_udp_ip_dscp(input_udp_ip_dscp), + .input_udp_ip_ecn(input_udp_ip_ecn), + .input_udp_ip_identification(0), + .input_udp_ip_flags(0), + .input_udp_ip_fragment_offset(0), + .input_udp_ip_ttl(input_udp_ip_ttl), + .input_udp_ip_header_checksum(0), + .input_udp_ip_source_ip(input_udp_ip_source_ip), + .input_udp_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tkeep(input_udp_payload_tkeep), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_udp_eth_dest_mac(output_udp_eth_dest_mac), + .output_udp_eth_src_mac(output_udp_eth_src_mac), + .output_udp_eth_type(output_udp_eth_type), + .output_udp_ip_version(output_udp_ip_version), + .output_udp_ip_ihl(output_udp_ip_ihl), + .output_udp_ip_dscp(output_udp_ip_dscp), + .output_udp_ip_ecn(output_udp_ip_ecn), + .output_udp_ip_length(output_udp_ip_length), + .output_udp_ip_identification(output_udp_ip_identification), + .output_udp_ip_flags(output_udp_ip_flags), + .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_udp_ip_ttl(output_udp_ip_ttl), + .output_udp_ip_protocol(output_udp_ip_protocol), + .output_udp_ip_header_checksum(output_udp_ip_header_checksum), + .output_udp_ip_source_ip(output_udp_ip_source_ip), + .output_udp_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status + .rx_busy(udp_rx_busy), + .tx_busy(udp_tx_busy), + .rx_error_header_early_termination(udp_rx_error_header_early_termination), + .rx_error_payload_early_termination(udp_rx_error_payload_early_termination), + .tx_error_payload_early_termination(udp_tx_error_payload_early_termination) +); + +endmodule diff --git a/tb/test_udp_complete.py b/tb/test_udp_complete.py new file mode 100755 index 000000000..f50818cba --- /dev/null +++ b/tb/test_udp_complete.py @@ -0,0 +1,1108 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue + +import eth_ep +import arp_ep +import ip_ep +import udp_ep + +module = 'udp_complete' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/udp.v") +srcs.append("../rtl/udp_ip_rx.v") +srcs.append("../rtl/udp_ip_tx.v") +srcs.append("../rtl/ip_complete.v") +srcs.append("../rtl/ip.v") +srcs.append("../rtl/ip_eth_rx.v") +srcs.append("../rtl/ip_eth_tx.v") +srcs.append("../rtl/ip_arb_mux_2.v") +srcs.append("../rtl/ip_mux_2.v") +srcs.append("../rtl/arp.v") +srcs.append("../rtl/arp_cache.v") +srcs.append("../rtl/arp_eth_rx.v") +srcs.append("../rtl/arp_eth_tx.v") +srcs.append("../rtl/eth_arb_mux_2.v") +srcs.append("../rtl/eth_mux_2.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp_complete(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + input_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_ip_eth_dest_mac=output_ip_eth_dest_mac, + output_ip_eth_src_mac=output_ip_eth_src_mac, + output_ip_eth_type=output_ip_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + input_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_udp_ip_dscp=input_udp_ip_dscp, + input_udp_ip_ecn=input_udp_ip_ecn, + input_udp_ip_ttl=input_udp_ip_ttl, + input_udp_ip_source_ip=input_udp_ip_source_ip, + input_udp_ip_dest_ip=input_udp_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_length=input_udp_length, + input_udp_checksum=input_udp_checksum, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_udp_eth_dest_mac=output_udp_eth_dest_mac, + output_udp_eth_src_mac=output_udp_eth_src_mac, + output_udp_eth_type=output_udp_eth_type, + output_udp_ip_version=output_udp_ip_version, + output_udp_ip_ihl=output_udp_ip_ihl, + output_udp_ip_dscp=output_udp_ip_dscp, + output_udp_ip_ecn=output_udp_ip_ecn, + output_udp_ip_length=output_udp_ip_length, + output_udp_ip_identification=output_udp_ip_identification, + output_udp_ip_flags=output_udp_ip_flags, + output_udp_ip_fragment_offset=output_udp_ip_fragment_offset, + output_udp_ip_ttl=output_udp_ip_ttl, + output_udp_ip_protocol=output_udp_ip_protocol, + output_udp_ip_header_checksum=output_udp_ip_header_checksum, + output_udp_ip_source_ip=output_udp_ip_source_ip, + output_udp_ip_dest_ip=output_udp_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + ip_rx_busy=ip_rx_busy, + ip_tx_busy=ip_tx_busy, + udp_rx_busy=udp_rx_busy, + udp_tx_busy=udp_tx_busy, + ip_rx_error_header_early_termination=ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination=ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header=ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum=ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination=ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed=ip_tx_error_arp_failed, + udp_rx_error_header_early_termination=udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination=udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination=udp_tx_error_payload_early_termination, + + local_mac=local_mac, + local_ip=local_ip, + gateway_ip=gateway_ip, + subnet_mask=subnet_mask, + clear_arp_cache=clear_arp_cache) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + input_ip_hdr_valid = Signal(bool(0)) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + input_udp_hdr_valid = Signal(bool(0)) + input_udp_ip_dscp = Signal(intbv(0)[6:]) + input_udp_ip_ecn = Signal(intbv(0)[2:]) + input_udp_ip_ttl = Signal(intbv(0)[8:]) + input_udp_ip_source_ip = Signal(intbv(0)[32:]) + input_udp_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_length = Signal(intbv(0)[16:]) + input_udp_checksum = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + output_udp_payload_tready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_ip_eth_dest_mac = Signal(intbv(0)[48:]) + output_ip_eth_src_mac = Signal(intbv(0)[48:]) + output_ip_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + output_udp_hdr_valid = Signal(bool(0)) + output_udp_eth_dest_mac = Signal(intbv(0)[48:]) + output_udp_eth_src_mac = Signal(intbv(0)[48:]) + output_udp_eth_type = Signal(intbv(0)[16:]) + output_udp_ip_version = Signal(intbv(0)[4:]) + output_udp_ip_ihl = Signal(intbv(0)[4:]) + output_udp_ip_dscp = Signal(intbv(0)[6:]) + output_udp_ip_ecn = Signal(intbv(0)[2:]) + output_udp_ip_length = Signal(intbv(0)[16:]) + output_udp_ip_identification = Signal(intbv(0)[16:]) + output_udp_ip_flags = Signal(intbv(0)[3:]) + output_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + output_udp_ip_ttl = Signal(intbv(0)[8:]) + output_udp_ip_protocol = Signal(intbv(0)[8:]) + output_udp_ip_header_checksum = Signal(intbv(0)[16:]) + output_udp_ip_source_ip = Signal(intbv(0)[32:]) + output_udp_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + ip_rx_busy = Signal(bool(0)) + ip_tx_busy = Signal(bool(0)) + udp_rx_busy = Signal(bool(0)) + udp_tx_busy = Signal(bool(0)) + ip_rx_error_header_early_termination = Signal(bool(0)) + ip_rx_error_payload_early_termination = Signal(bool(0)) + ip_rx_error_invalid_header = Signal(bool(0)) + ip_rx_error_invalid_checksum = Signal(bool(0)) + ip_tx_error_payload_early_termination = Signal(bool(0)) + ip_tx_error_arp_failed = Signal(bool(0)) + udp_rx_error_header_early_termination = Signal(bool(0)) + udp_rx_error_payload_early_termination = Signal(bool(0)) + udp_tx_error_payload_early_termination = Signal(bool(0)) + local_mac = Signal(intbv(0)[48:]) + local_ip = Signal(intbv(0)[32:]) + gateway_ip = Signal(intbv(0)[32:]) + subnet_mask = Signal(intbv(0)[32:]) + clear_arp_cache = Signal(bool(0)) + + # sources and sinks + eth_source_queue = Queue() + eth_source_pause = Signal(bool(0)) + eth_sink_queue = Queue() + eth_sink_pause = Signal(bool(0)) + ip_source_queue = Queue() + ip_source_pause = Signal(bool(0)) + ip_sink_queue = Queue() + ip_sink_pause = Signal(bool(0)) + udp_source_queue = Queue() + udp_source_pause = Signal(bool(0)) + udp_sink_queue = Queue() + udp_sink_pause = Signal(bool(0)) + + eth_source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=eth_source_queue, + pause=eth_source_pause, + name='eth_source') + + eth_sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=eth_sink_queue, + pause=eth_sink_pause, + name='eth_sink') + + ip_source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=ip_source_queue, + pause=ip_source_pause, + name='ip_source') + + ip_sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_ip_eth_dest_mac, + eth_src_mac=output_ip_eth_src_mac, + eth_type=output_ip_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=ip_sink_queue, + pause=ip_sink_pause, + name='ip_sink') + + udp_source = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_valid=input_udp_hdr_valid, + udp_hdr_ready=input_udp_hdr_ready, + ip_dscp=input_udp_ip_dscp, + ip_ecn=input_udp_ip_ecn, + ip_ttl=input_udp_ip_ttl, + ip_source_ip=input_udp_ip_source_ip, + ip_dest_ip=input_udp_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_length=input_udp_length, + udp_checksum=input_udp_checksum, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + fifo=udp_source_queue, + pause=udp_source_pause, + name='udp_source') + + udp_sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_udp_eth_dest_mac, + eth_src_mac=output_udp_eth_src_mac, + eth_type=output_udp_eth_type, + ip_version=output_udp_ip_version, + ip_ihl=output_udp_ip_ihl, + ip_dscp=output_udp_ip_dscp, + ip_ecn=output_udp_ip_ecn, + ip_length=output_udp_ip_length, + ip_identification=output_udp_ip_identification, + ip_flags=output_udp_ip_flags, + ip_fragment_offset=output_udp_ip_fragment_offset, + ip_ttl=output_udp_ip_ttl, + ip_protocol=output_udp_ip_protocol, + ip_header_checksum=output_udp_ip_header_checksum, + ip_source_ip=output_udp_ip_source_ip, + ip_dest_ip=output_udp_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=udp_sink_queue, + pause=udp_sink_pause, + name='udp_sink') + + # DUT + dut = dut_udp_complete(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + ip_rx_error_header_early_termination_asserted = Signal(bool(0)) + ip_rx_error_payload_early_termination_asserted = Signal(bool(0)) + ip_rx_error_invalid_header_asserted = Signal(bool(0)) + ip_rx_error_invalid_checksum_asserted = Signal(bool(0)) + ip_tx_error_payload_early_termination_asserted = Signal(bool(0)) + ip_tx_error_arp_failed_asserted = Signal(bool(0)) + udp_rx_error_header_early_termination_asserted = Signal(bool(0)) + udp_rx_error_payload_early_termination_asserted = Signal(bool(0)) + udp_tx_error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (ip_rx_error_header_early_termination): + ip_rx_error_header_early_termination_asserted.next = 1 + if (ip_rx_error_payload_early_termination): + ip_rx_error_payload_early_termination_asserted.next = 1 + if (ip_rx_error_invalid_header): + ip_rx_error_invalid_header_asserted.next = 1 + if (ip_rx_error_invalid_checksum): + ip_rx_error_invalid_checksum_asserted.next = 1 + if (ip_tx_error_payload_early_termination): + ip_tx_error_payload_early_termination_asserted.next = 1 + if (ip_tx_error_arp_failed): + ip_tx_error_arp_failed_asserted.next = 1 + if (udp_rx_error_header_early_termination): + udp_rx_error_header_early_termination_asserted.next = 1 + if (udp_rx_error_payload_early_termination): + udp_rx_error_payload_early_termination_asserted.next = 1 + if (udp_tx_error_payload_early_termination): + udp_tx_error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or + output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or + input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # set MAC and IP address + local_mac.next = 0x5A5152535455 + local_ip.next = 0xc0a80164 + gateway_ip.next = 0xc0a80101 + subnet_mask.next = 0xffffff00 + + yield clk.posedge + print("test 1: test IP RX packet") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = ip_sink_queue.get(False) + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test IP TX packet") + current_test.next = 2 + + # send IP packet + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + # wait for ARP request packet + while eth_sink_queue.empty(): + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80166 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x5A5152535455 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80166 + arp_frame.arp_tha = 0x5A5152535455 + arp_frame.arp_tpa = 0xc0a80164 + eth_source_queue.put(arp_frame.build_eth()) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + print(test_frame) + print(check_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: test IP TX arp fail packet") + current_test.next = 2 + + ip_tx_error_arp_failed_asserted.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80167 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + assert ip_tx_error_arp_failed_asserted + + # check for 4 ARP requests + assert eth_sink_queue.qsize() == 4 + + while not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get(False) + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80167 + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: test UDP RX packet") + current_test.next = 4 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not udp_sink_queue.empty(): + rx_frame = udp_sink_queue.get() + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: test UDP TX packet") + current_test.next = 5 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + udp_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, eth_source, eth_sink, ip_source, ip_sink, udp_source, udp_sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_complete.v b/tb/test_udp_complete.v new file mode 100644 index 000000000..76e5b1e30 --- /dev/null +++ b/tb/test_udp_complete.v @@ -0,0 +1,440 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_udp_complete; + +// Parameters +parameter ARP_CACHE_ADDR_WIDTH = 2; +parameter ARP_REQUEST_RETRY_COUNT = 4; +parameter ARP_REQUEST_RETRY_INTERVAL = 150; +parameter ARP_REQUEST_TIMEOUT = 400; +parameter UDP_CHECKSUM_ENABLE = 0; +parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11; +parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [7:0] input_eth_payload_tdata = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg arp_response_valid = 0; +reg arp_response_error = 0; +reg [47:0] arp_response_mac = 0; +reg input_ip_hdr_valid = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [7:0] input_ip_payload_tdata = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg input_udp_hdr_valid = 0; +reg [5:0] input_udp_ip_dscp = 0; +reg [1:0] input_udp_ip_ecn = 0; +reg [7:0] input_udp_ip_ttl = 0; +reg [31:0] input_udp_ip_source_ip = 0; +reg [31:0] input_udp_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [15:0] input_udp_length = 0; +reg [15:0] input_udp_checksum = 0; +reg [7:0] input_udp_payload_tdata = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; +reg [47:0] local_mac = 0; +reg [31:0] local_ip = 0; +reg [31:0] gateway_ip = 0; +reg [31:0] subnet_mask = 0; +reg clear_arp_cache = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire input_udp_hdr_ready; +wire input_udp_payload_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [7:0] output_eth_payload_tdata; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire arp_request_valid; +wire [31:0] arp_request_ip; +wire output_ip_hdr_valid; +wire [47:0] output_ip_eth_dest_mac; +wire [47:0] output_ip_eth_src_mac; +wire [15:0] output_ip_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [7:0] output_ip_payload_tdata; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire output_udp_hdr_valid; +wire [47:0] output_udp_eth_dest_mac; +wire [47:0] output_udp_eth_src_mac; +wire [15:0] output_udp_eth_type; +wire [3:0] output_udp_ip_version; +wire [3:0] output_udp_ip_ihl; +wire [5:0] output_udp_ip_dscp; +wire [1:0] output_udp_ip_ecn; +wire [15:0] output_udp_ip_length; +wire [15:0] output_udp_ip_identification; +wire [2:0] output_udp_ip_flags; +wire [12:0] output_udp_ip_fragment_offset; +wire [7:0] output_udp_ip_ttl; +wire [7:0] output_udp_ip_protocol; +wire [15:0] output_udp_ip_header_checksum; +wire [31:0] output_udp_ip_source_ip; +wire [31:0] output_udp_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [7:0] output_udp_payload_tdata; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; +wire ip_rx_busy; +wire ip_tx_busy; +wire udp_rx_busy; +wire udp_tx_busy; +wire ip_rx_error_header_early_termination; +wire ip_rx_error_payload_early_termination; +wire ip_rx_error_invalid_header; +wire ip_rx_error_invalid_checksum; +wire ip_tx_error_payload_early_termination; +wire ip_tx_error_arp_failed; +wire udp_rx_error_header_early_termination; +wire udp_rx_error_payload_early_termination; +wire udp_tx_error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + input_ip_hdr_valid, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + input_udp_hdr_valid, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + output_ip_hdr_ready, + output_ip_payload_tready, + output_udp_hdr_ready, + output_udp_payload_tready, + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + input_ip_hdr_ready, + input_ip_payload_tready, + input_udp_hdr_ready, + input_udp_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + output_ip_hdr_valid, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + output_udp_hdr_valid, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser, + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination); + + // dump file + $dumpfile("test_udp_complete.lxt"); + $dumpvars(0, test_udp_complete); +end + +udp_complete #( + .ARP_CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT), + .UDP_CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_udp_ip_dscp(input_udp_ip_dscp), + .input_udp_ip_ecn(input_udp_ip_ecn), + .input_udp_ip_ttl(input_udp_ip_ttl), + .input_udp_ip_source_ip(input_udp_ip_source_ip), + .input_udp_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_udp_eth_dest_mac(output_udp_eth_dest_mac), + .output_udp_eth_src_mac(output_udp_eth_src_mac), + .output_udp_eth_type(output_udp_eth_type), + .output_udp_ip_version(output_udp_ip_version), + .output_udp_ip_ihl(output_udp_ip_ihl), + .output_udp_ip_dscp(output_udp_ip_dscp), + .output_udp_ip_ecn(output_udp_ip_ecn), + .output_udp_ip_length(output_udp_ip_length), + .output_udp_ip_identification(output_udp_ip_identification), + .output_udp_ip_flags(output_udp_ip_flags), + .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_udp_ip_ttl(output_udp_ip_ttl), + .output_udp_ip_protocol(output_udp_ip_protocol), + .output_udp_ip_header_checksum(output_udp_ip_header_checksum), + .output_udp_ip_source_ip(output_udp_ip_source_ip), + .output_udp_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status signals + .ip_rx_busy(ip_rx_busy), + .ip_tx_busy(ip_tx_busy), + .udp_rx_busy(udp_rx_busy), + .udp_tx_busy(udp_tx_busy), + .ip_rx_error_header_early_termination(ip_rx_error_header_early_termination), + .ip_rx_error_payload_early_termination(ip_rx_error_payload_early_termination), + .ip_rx_error_invalid_header(ip_rx_error_invalid_header), + .ip_rx_error_invalid_checksum(ip_rx_error_invalid_checksum), + .ip_tx_error_payload_early_termination(ip_tx_error_payload_early_termination), + .ip_tx_error_arp_failed(ip_tx_error_arp_failed), + .udp_rx_error_header_early_termination(udp_rx_error_header_early_termination), + .udp_rx_error_payload_early_termination(udp_rx_error_payload_early_termination), + .udp_tx_error_payload_early_termination(udp_tx_error_payload_early_termination), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(clear_arp_cache) +); + +endmodule diff --git a/tb/test_udp_complete_64.py b/tb/test_udp_complete_64.py new file mode 100755 index 000000000..98833866c --- /dev/null +++ b/tb/test_udp_complete_64.py @@ -0,0 +1,1138 @@ +#!/usr/bin/env python2 +""" + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +""" + +from myhdl import * +import os +from Queue import Queue + +import eth_ep +import arp_ep +import ip_ep +import udp_ep + +module = 'udp_complete_64' + +srcs = [] + +srcs.append("../rtl/%s.v" % module) +srcs.append("../rtl/udp_64.v") +srcs.append("../rtl/udp_ip_rx_64.v") +srcs.append("../rtl/udp_ip_tx_64.v") +srcs.append("../rtl/ip_complete_64.v") +srcs.append("../rtl/ip_64.v") +srcs.append("../rtl/ip_eth_rx_64.v") +srcs.append("../rtl/ip_eth_tx_64.v") +srcs.append("../rtl/ip_arb_mux_64_2.v") +srcs.append("../rtl/ip_mux_64_2.v") +srcs.append("../rtl/arp_64.v") +srcs.append("../rtl/arp_cache.v") +srcs.append("../rtl/arp_eth_rx_64.v") +srcs.append("../rtl/arp_eth_tx_64.v") +srcs.append("../rtl/eth_arb_mux_64_2.v") +srcs.append("../rtl/eth_mux_64_2.v") +srcs.append("../lib/axis/rtl/arbiter.v") +srcs.append("../lib/axis/rtl/priority_encoder.v") +srcs.append("test_%s.v" % module) + +src = ' '.join(srcs) + +build_cmd = "iverilog -o test_%s.vvp %s" % (module, src) + +def dut_udp_complete(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache): + + if os.system(build_cmd): + raise Exception("Error running build command") + return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module, + clk=clk, + rst=rst, + current_test=current_test, + + input_eth_hdr_valid=input_eth_hdr_valid, + input_eth_hdr_ready=input_eth_hdr_ready, + input_eth_dest_mac=input_eth_dest_mac, + input_eth_src_mac=input_eth_src_mac, + input_eth_type=input_eth_type, + input_eth_payload_tdata=input_eth_payload_tdata, + input_eth_payload_tkeep=input_eth_payload_tkeep, + input_eth_payload_tvalid=input_eth_payload_tvalid, + input_eth_payload_tready=input_eth_payload_tready, + input_eth_payload_tlast=input_eth_payload_tlast, + input_eth_payload_tuser=input_eth_payload_tuser, + + output_eth_hdr_valid=output_eth_hdr_valid, + output_eth_hdr_ready=output_eth_hdr_ready, + output_eth_dest_mac=output_eth_dest_mac, + output_eth_src_mac=output_eth_src_mac, + output_eth_type=output_eth_type, + output_eth_payload_tdata=output_eth_payload_tdata, + output_eth_payload_tkeep=output_eth_payload_tkeep, + output_eth_payload_tvalid=output_eth_payload_tvalid, + output_eth_payload_tready=output_eth_payload_tready, + output_eth_payload_tlast=output_eth_payload_tlast, + output_eth_payload_tuser=output_eth_payload_tuser, + + input_ip_hdr_valid=input_ip_hdr_valid, + input_ip_hdr_ready=input_ip_hdr_ready, + input_ip_dscp=input_ip_dscp, + input_ip_ecn=input_ip_ecn, + input_ip_length=input_ip_length, + input_ip_ttl=input_ip_ttl, + input_ip_protocol=input_ip_protocol, + input_ip_source_ip=input_ip_source_ip, + input_ip_dest_ip=input_ip_dest_ip, + input_ip_payload_tdata=input_ip_payload_tdata, + input_ip_payload_tkeep=input_ip_payload_tkeep, + input_ip_payload_tvalid=input_ip_payload_tvalid, + input_ip_payload_tready=input_ip_payload_tready, + input_ip_payload_tlast=input_ip_payload_tlast, + input_ip_payload_tuser=input_ip_payload_tuser, + + output_ip_hdr_valid=output_ip_hdr_valid, + output_ip_hdr_ready=output_ip_hdr_ready, + output_ip_eth_dest_mac=output_ip_eth_dest_mac, + output_ip_eth_src_mac=output_ip_eth_src_mac, + output_ip_eth_type=output_ip_eth_type, + output_ip_version=output_ip_version, + output_ip_ihl=output_ip_ihl, + output_ip_dscp=output_ip_dscp, + output_ip_ecn=output_ip_ecn, + output_ip_length=output_ip_length, + output_ip_identification=output_ip_identification, + output_ip_flags=output_ip_flags, + output_ip_fragment_offset=output_ip_fragment_offset, + output_ip_ttl=output_ip_ttl, + output_ip_protocol=output_ip_protocol, + output_ip_header_checksum=output_ip_header_checksum, + output_ip_source_ip=output_ip_source_ip, + output_ip_dest_ip=output_ip_dest_ip, + output_ip_payload_tdata=output_ip_payload_tdata, + output_ip_payload_tkeep=output_ip_payload_tkeep, + output_ip_payload_tvalid=output_ip_payload_tvalid, + output_ip_payload_tready=output_ip_payload_tready, + output_ip_payload_tlast=output_ip_payload_tlast, + output_ip_payload_tuser=output_ip_payload_tuser, + + input_udp_hdr_valid=input_udp_hdr_valid, + input_udp_hdr_ready=input_udp_hdr_ready, + input_udp_ip_dscp=input_udp_ip_dscp, + input_udp_ip_ecn=input_udp_ip_ecn, + input_udp_ip_ttl=input_udp_ip_ttl, + input_udp_ip_source_ip=input_udp_ip_source_ip, + input_udp_ip_dest_ip=input_udp_ip_dest_ip, + input_udp_source_port=input_udp_source_port, + input_udp_dest_port=input_udp_dest_port, + input_udp_length=input_udp_length, + input_udp_checksum=input_udp_checksum, + input_udp_payload_tdata=input_udp_payload_tdata, + input_udp_payload_tkeep=input_udp_payload_tkeep, + input_udp_payload_tvalid=input_udp_payload_tvalid, + input_udp_payload_tready=input_udp_payload_tready, + input_udp_payload_tlast=input_udp_payload_tlast, + input_udp_payload_tuser=input_udp_payload_tuser, + + output_udp_hdr_valid=output_udp_hdr_valid, + output_udp_hdr_ready=output_udp_hdr_ready, + output_udp_eth_dest_mac=output_udp_eth_dest_mac, + output_udp_eth_src_mac=output_udp_eth_src_mac, + output_udp_eth_type=output_udp_eth_type, + output_udp_ip_version=output_udp_ip_version, + output_udp_ip_ihl=output_udp_ip_ihl, + output_udp_ip_dscp=output_udp_ip_dscp, + output_udp_ip_ecn=output_udp_ip_ecn, + output_udp_ip_length=output_udp_ip_length, + output_udp_ip_identification=output_udp_ip_identification, + output_udp_ip_flags=output_udp_ip_flags, + output_udp_ip_fragment_offset=output_udp_ip_fragment_offset, + output_udp_ip_ttl=output_udp_ip_ttl, + output_udp_ip_protocol=output_udp_ip_protocol, + output_udp_ip_header_checksum=output_udp_ip_header_checksum, + output_udp_ip_source_ip=output_udp_ip_source_ip, + output_udp_ip_dest_ip=output_udp_ip_dest_ip, + output_udp_source_port=output_udp_source_port, + output_udp_dest_port=output_udp_dest_port, + output_udp_length=output_udp_length, + output_udp_checksum=output_udp_checksum, + output_udp_payload_tdata=output_udp_payload_tdata, + output_udp_payload_tkeep=output_udp_payload_tkeep, + output_udp_payload_tvalid=output_udp_payload_tvalid, + output_udp_payload_tready=output_udp_payload_tready, + output_udp_payload_tlast=output_udp_payload_tlast, + output_udp_payload_tuser=output_udp_payload_tuser, + + ip_rx_busy=ip_rx_busy, + ip_tx_busy=ip_tx_busy, + udp_rx_busy=udp_rx_busy, + udp_tx_busy=udp_tx_busy, + ip_rx_error_header_early_termination=ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination=ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header=ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum=ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination=ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed=ip_tx_error_arp_failed, + udp_rx_error_header_early_termination=udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination=udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination=udp_tx_error_payload_early_termination, + + local_mac=local_mac, + local_ip=local_ip, + gateway_ip=gateway_ip, + subnet_mask=subnet_mask, + clear_arp_cache=clear_arp_cache) + +def bench(): + + # Inputs + clk = Signal(bool(0)) + rst = Signal(bool(0)) + current_test = Signal(intbv(0)[8:]) + + input_eth_hdr_valid = Signal(bool(0)) + input_eth_dest_mac = Signal(intbv(0)[48:]) + input_eth_src_mac = Signal(intbv(0)[48:]) + input_eth_type = Signal(intbv(0)[16:]) + input_eth_payload_tdata = Signal(intbv(0)[64:]) + input_eth_payload_tkeep = Signal(intbv(0)[8:]) + input_eth_payload_tvalid = Signal(bool(0)) + input_eth_payload_tlast = Signal(bool(0)) + input_eth_payload_tuser = Signal(bool(0)) + input_ip_hdr_valid = Signal(bool(0)) + input_ip_dscp = Signal(intbv(0)[6:]) + input_ip_ecn = Signal(intbv(0)[2:]) + input_ip_length = Signal(intbv(0)[16:]) + input_ip_ttl = Signal(intbv(0)[8:]) + input_ip_protocol = Signal(intbv(0)[8:]) + input_ip_source_ip = Signal(intbv(0)[32:]) + input_ip_dest_ip = Signal(intbv(0)[32:]) + input_ip_payload_tdata = Signal(intbv(0)[64:]) + input_ip_payload_tkeep = Signal(intbv(0)[8:]) + input_ip_payload_tvalid = Signal(bool(0)) + input_ip_payload_tlast = Signal(bool(0)) + input_ip_payload_tuser = Signal(bool(0)) + input_udp_hdr_valid = Signal(bool(0)) + input_udp_ip_dscp = Signal(intbv(0)[6:]) + input_udp_ip_ecn = Signal(intbv(0)[2:]) + input_udp_ip_ttl = Signal(intbv(0)[8:]) + input_udp_ip_source_ip = Signal(intbv(0)[32:]) + input_udp_ip_dest_ip = Signal(intbv(0)[32:]) + input_udp_source_port = Signal(intbv(0)[16:]) + input_udp_dest_port = Signal(intbv(0)[16:]) + input_udp_length = Signal(intbv(0)[16:]) + input_udp_checksum = Signal(intbv(0)[16:]) + input_udp_payload_tdata = Signal(intbv(0)[64:]) + input_udp_payload_tkeep = Signal(intbv(0)[8:]) + input_udp_payload_tvalid = Signal(bool(0)) + input_udp_payload_tlast = Signal(bool(0)) + input_udp_payload_tuser = Signal(bool(0)) + output_eth_payload_tready = Signal(bool(0)) + output_eth_hdr_ready = Signal(bool(0)) + output_ip_hdr_ready = Signal(bool(0)) + output_ip_payload_tready = Signal(bool(0)) + output_udp_hdr_ready = Signal(bool(0)) + output_udp_payload_tready = Signal(bool(0)) + + # Outputs + input_eth_hdr_ready = Signal(bool(0)) + input_eth_payload_tready = Signal(bool(0)) + input_ip_hdr_ready = Signal(bool(0)) + input_ip_payload_tready = Signal(bool(0)) + input_udp_hdr_ready = Signal(bool(0)) + input_udp_payload_tready = Signal(bool(0)) + output_eth_hdr_valid = Signal(bool(0)) + output_eth_dest_mac = Signal(intbv(0)[48:]) + output_eth_src_mac = Signal(intbv(0)[48:]) + output_eth_type = Signal(intbv(0)[16:]) + output_eth_payload_tdata = Signal(intbv(0)[64:]) + output_eth_payload_tkeep = Signal(intbv(0)[8:]) + output_eth_payload_tvalid = Signal(bool(0)) + output_eth_payload_tlast = Signal(bool(0)) + output_eth_payload_tuser = Signal(bool(0)) + output_ip_hdr_valid = Signal(bool(0)) + output_ip_eth_dest_mac = Signal(intbv(0)[48:]) + output_ip_eth_src_mac = Signal(intbv(0)[48:]) + output_ip_eth_type = Signal(intbv(0)[16:]) + output_ip_version = Signal(intbv(0)[4:]) + output_ip_ihl = Signal(intbv(0)[4:]) + output_ip_dscp = Signal(intbv(0)[6:]) + output_ip_ecn = Signal(intbv(0)[2:]) + output_ip_length = Signal(intbv(0)[16:]) + output_ip_identification = Signal(intbv(0)[16:]) + output_ip_flags = Signal(intbv(0)[3:]) + output_ip_fragment_offset = Signal(intbv(0)[13:]) + output_ip_ttl = Signal(intbv(0)[8:]) + output_ip_protocol = Signal(intbv(0)[8:]) + output_ip_header_checksum = Signal(intbv(0)[16:]) + output_ip_source_ip = Signal(intbv(0)[32:]) + output_ip_dest_ip = Signal(intbv(0)[32:]) + output_ip_payload_tdata = Signal(intbv(0)[64:]) + output_ip_payload_tkeep = Signal(intbv(0)[8:]) + output_ip_payload_tvalid = Signal(bool(0)) + output_ip_payload_tlast = Signal(bool(0)) + output_ip_payload_tuser = Signal(bool(0)) + output_udp_hdr_valid = Signal(bool(0)) + output_udp_eth_dest_mac = Signal(intbv(0)[48:]) + output_udp_eth_src_mac = Signal(intbv(0)[48:]) + output_udp_eth_type = Signal(intbv(0)[16:]) + output_udp_ip_version = Signal(intbv(0)[4:]) + output_udp_ip_ihl = Signal(intbv(0)[4:]) + output_udp_ip_dscp = Signal(intbv(0)[6:]) + output_udp_ip_ecn = Signal(intbv(0)[2:]) + output_udp_ip_length = Signal(intbv(0)[16:]) + output_udp_ip_identification = Signal(intbv(0)[16:]) + output_udp_ip_flags = Signal(intbv(0)[3:]) + output_udp_ip_fragment_offset = Signal(intbv(0)[13:]) + output_udp_ip_ttl = Signal(intbv(0)[8:]) + output_udp_ip_protocol = Signal(intbv(0)[8:]) + output_udp_ip_header_checksum = Signal(intbv(0)[16:]) + output_udp_ip_source_ip = Signal(intbv(0)[32:]) + output_udp_ip_dest_ip = Signal(intbv(0)[32:]) + output_udp_source_port = Signal(intbv(0)[16:]) + output_udp_dest_port = Signal(intbv(0)[16:]) + output_udp_length = Signal(intbv(0)[16:]) + output_udp_checksum = Signal(intbv(0)[16:]) + output_udp_payload_tdata = Signal(intbv(0)[64:]) + output_udp_payload_tkeep = Signal(intbv(0)[8:]) + output_udp_payload_tvalid = Signal(bool(0)) + output_udp_payload_tlast = Signal(bool(0)) + output_udp_payload_tuser = Signal(bool(0)) + ip_rx_busy = Signal(bool(0)) + ip_tx_busy = Signal(bool(0)) + udp_rx_busy = Signal(bool(0)) + udp_tx_busy = Signal(bool(0)) + ip_rx_error_header_early_termination = Signal(bool(0)) + ip_rx_error_payload_early_termination = Signal(bool(0)) + ip_rx_error_invalid_header = Signal(bool(0)) + ip_rx_error_invalid_checksum = Signal(bool(0)) + ip_tx_error_payload_early_termination = Signal(bool(0)) + ip_tx_error_arp_failed = Signal(bool(0)) + udp_rx_error_header_early_termination = Signal(bool(0)) + udp_rx_error_payload_early_termination = Signal(bool(0)) + udp_tx_error_payload_early_termination = Signal(bool(0)) + local_mac = Signal(intbv(0)[48:]) + local_ip = Signal(intbv(0)[32:]) + gateway_ip = Signal(intbv(0)[32:]) + subnet_mask = Signal(intbv(0)[32:]) + clear_arp_cache = Signal(bool(0)) + + # sources and sinks + eth_source_queue = Queue() + eth_source_pause = Signal(bool(0)) + eth_sink_queue = Queue() + eth_sink_pause = Signal(bool(0)) + ip_source_queue = Queue() + ip_source_pause = Signal(bool(0)) + ip_sink_queue = Queue() + ip_sink_pause = Signal(bool(0)) + udp_source_queue = Queue() + udp_source_pause = Signal(bool(0)) + udp_sink_queue = Queue() + udp_sink_pause = Signal(bool(0)) + + eth_source = eth_ep.EthFrameSource(clk, + rst, + eth_hdr_ready=input_eth_hdr_ready, + eth_hdr_valid=input_eth_hdr_valid, + eth_dest_mac=input_eth_dest_mac, + eth_src_mac=input_eth_src_mac, + eth_type=input_eth_type, + eth_payload_tdata=input_eth_payload_tdata, + eth_payload_tkeep=input_eth_payload_tkeep, + eth_payload_tvalid=input_eth_payload_tvalid, + eth_payload_tready=input_eth_payload_tready, + eth_payload_tlast=input_eth_payload_tlast, + eth_payload_tuser=input_eth_payload_tuser, + fifo=eth_source_queue, + pause=eth_source_pause, + name='eth_source') + + eth_sink = eth_ep.EthFrameSink(clk, + rst, + eth_hdr_ready=output_eth_hdr_ready, + eth_hdr_valid=output_eth_hdr_valid, + eth_dest_mac=output_eth_dest_mac, + eth_src_mac=output_eth_src_mac, + eth_type=output_eth_type, + eth_payload_tdata=output_eth_payload_tdata, + eth_payload_tkeep=output_eth_payload_tkeep, + eth_payload_tvalid=output_eth_payload_tvalid, + eth_payload_tready=output_eth_payload_tready, + eth_payload_tlast=output_eth_payload_tlast, + eth_payload_tuser=output_eth_payload_tuser, + fifo=eth_sink_queue, + pause=eth_sink_pause, + name='eth_sink') + + ip_source = ip_ep.IPFrameSource(clk, + rst, + ip_hdr_valid=input_ip_hdr_valid, + ip_hdr_ready=input_ip_hdr_ready, + ip_dscp=input_ip_dscp, + ip_ecn=input_ip_ecn, + ip_length=input_ip_length, + ip_ttl=input_ip_ttl, + ip_protocol=input_ip_protocol, + ip_source_ip=input_ip_source_ip, + ip_dest_ip=input_ip_dest_ip, + ip_payload_tdata=input_ip_payload_tdata, + ip_payload_tkeep=input_ip_payload_tkeep, + ip_payload_tvalid=input_ip_payload_tvalid, + ip_payload_tready=input_ip_payload_tready, + ip_payload_tlast=input_ip_payload_tlast, + ip_payload_tuser=input_ip_payload_tuser, + fifo=ip_source_queue, + pause=ip_source_pause, + name='ip_source') + + ip_sink = ip_ep.IPFrameSink(clk, + rst, + ip_hdr_ready=output_ip_hdr_ready, + ip_hdr_valid=output_ip_hdr_valid, + eth_dest_mac=output_ip_eth_dest_mac, + eth_src_mac=output_ip_eth_src_mac, + eth_type=output_ip_eth_type, + ip_version=output_ip_version, + ip_ihl=output_ip_ihl, + ip_dscp=output_ip_dscp, + ip_ecn=output_ip_ecn, + ip_length=output_ip_length, + ip_identification=output_ip_identification, + ip_flags=output_ip_flags, + ip_fragment_offset=output_ip_fragment_offset, + ip_ttl=output_ip_ttl, + ip_protocol=output_ip_protocol, + ip_header_checksum=output_ip_header_checksum, + ip_source_ip=output_ip_source_ip, + ip_dest_ip=output_ip_dest_ip, + ip_payload_tdata=output_ip_payload_tdata, + ip_payload_tkeep=output_ip_payload_tkeep, + ip_payload_tvalid=output_ip_payload_tvalid, + ip_payload_tready=output_ip_payload_tready, + ip_payload_tlast=output_ip_payload_tlast, + ip_payload_tuser=output_ip_payload_tuser, + fifo=ip_sink_queue, + pause=ip_sink_pause, + name='ip_sink') + + udp_source = udp_ep.UDPFrameSource(clk, + rst, + udp_hdr_valid=input_udp_hdr_valid, + udp_hdr_ready=input_udp_hdr_ready, + ip_dscp=input_udp_ip_dscp, + ip_ecn=input_udp_ip_ecn, + ip_ttl=input_udp_ip_ttl, + ip_source_ip=input_udp_ip_source_ip, + ip_dest_ip=input_udp_ip_dest_ip, + udp_source_port=input_udp_source_port, + udp_dest_port=input_udp_dest_port, + udp_length=input_udp_length, + udp_checksum=input_udp_checksum, + udp_payload_tdata=input_udp_payload_tdata, + udp_payload_tkeep=input_udp_payload_tkeep, + udp_payload_tvalid=input_udp_payload_tvalid, + udp_payload_tready=input_udp_payload_tready, + udp_payload_tlast=input_udp_payload_tlast, + udp_payload_tuser=input_udp_payload_tuser, + fifo=udp_source_queue, + pause=udp_source_pause, + name='udp_source') + + udp_sink = udp_ep.UDPFrameSink(clk, + rst, + udp_hdr_ready=output_udp_hdr_ready, + udp_hdr_valid=output_udp_hdr_valid, + eth_dest_mac=output_udp_eth_dest_mac, + eth_src_mac=output_udp_eth_src_mac, + eth_type=output_udp_eth_type, + ip_version=output_udp_ip_version, + ip_ihl=output_udp_ip_ihl, + ip_dscp=output_udp_ip_dscp, + ip_ecn=output_udp_ip_ecn, + ip_length=output_udp_ip_length, + ip_identification=output_udp_ip_identification, + ip_flags=output_udp_ip_flags, + ip_fragment_offset=output_udp_ip_fragment_offset, + ip_ttl=output_udp_ip_ttl, + ip_protocol=output_udp_ip_protocol, + ip_header_checksum=output_udp_ip_header_checksum, + ip_source_ip=output_udp_ip_source_ip, + ip_dest_ip=output_udp_ip_dest_ip, + udp_source_port=output_udp_source_port, + udp_dest_port=output_udp_dest_port, + udp_length=output_udp_length, + udp_checksum=output_udp_checksum, + udp_payload_tdata=output_udp_payload_tdata, + udp_payload_tkeep=output_udp_payload_tkeep, + udp_payload_tvalid=output_udp_payload_tvalid, + udp_payload_tready=output_udp_payload_tready, + udp_payload_tlast=output_udp_payload_tlast, + udp_payload_tuser=output_udp_payload_tuser, + fifo=udp_sink_queue, + pause=udp_sink_pause, + name='udp_sink') + + # DUT + dut = dut_udp_complete(clk, + rst, + current_test, + + input_eth_hdr_valid, + input_eth_hdr_ready, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tready, + input_eth_payload_tlast, + input_eth_payload_tuser, + + output_eth_hdr_valid, + output_eth_hdr_ready, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tready, + output_eth_payload_tlast, + output_eth_payload_tuser, + + input_ip_hdr_valid, + input_ip_hdr_ready, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tready, + input_ip_payload_tlast, + input_ip_payload_tuser, + + output_ip_hdr_valid, + output_ip_hdr_ready, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tready, + output_ip_payload_tlast, + output_ip_payload_tuser, + + input_udp_hdr_valid, + input_udp_hdr_ready, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tready, + input_udp_payload_tlast, + input_udp_payload_tuser, + + output_udp_hdr_valid, + output_udp_hdr_ready, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tready, + output_udp_payload_tlast, + output_udp_payload_tuser, + + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination, + + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache) + + @always(delay(4)) + def clkgen(): + clk.next = not clk + + ip_rx_error_header_early_termination_asserted = Signal(bool(0)) + ip_rx_error_payload_early_termination_asserted = Signal(bool(0)) + ip_rx_error_invalid_header_asserted = Signal(bool(0)) + ip_rx_error_invalid_checksum_asserted = Signal(bool(0)) + ip_tx_error_payload_early_termination_asserted = Signal(bool(0)) + ip_tx_error_arp_failed_asserted = Signal(bool(0)) + udp_rx_error_header_early_termination_asserted = Signal(bool(0)) + udp_rx_error_payload_early_termination_asserted = Signal(bool(0)) + udp_tx_error_payload_early_termination_asserted = Signal(bool(0)) + + @always(clk.posedge) + def monitor(): + if (ip_rx_error_header_early_termination): + ip_rx_error_header_early_termination_asserted.next = 1 + if (ip_rx_error_payload_early_termination): + ip_rx_error_payload_early_termination_asserted.next = 1 + if (ip_rx_error_invalid_header): + ip_rx_error_invalid_header_asserted.next = 1 + if (ip_rx_error_invalid_checksum): + ip_rx_error_invalid_checksum_asserted.next = 1 + if (ip_tx_error_payload_early_termination): + ip_tx_error_payload_early_termination_asserted.next = 1 + if (ip_tx_error_arp_failed): + ip_tx_error_arp_failed_asserted.next = 1 + if (udp_rx_error_header_early_termination): + udp_rx_error_header_early_termination_asserted.next = 1 + if (udp_rx_error_payload_early_termination): + udp_rx_error_payload_early_termination_asserted.next = 1 + if (udp_tx_error_payload_early_termination): + udp_tx_error_payload_early_termination_asserted.next = 1 + + def wait_normal(): + while (input_eth_payload_tvalid or input_ip_payload_tvalid or input_udp_payload_tvalid or + output_eth_payload_tvalid or output_ip_payload_tvalid or output_udp_payload_tvalid or + input_eth_hdr_valid or input_ip_hdr_valid or input_udp_hdr_valid): + yield clk.posedge + + @instance + def check(): + yield delay(100) + yield clk.posedge + rst.next = 1 + yield clk.posedge + rst.next = 0 + yield clk.posedge + yield delay(100) + yield clk.posedge + + # set MAC and IP address + local_mac.next = 0x5A5152535455 + local_ip.next = 0xc0a80164 + gateway_ip.next = 0xc0a80101 + subnet_mask.next = 0xffffff00 + + yield clk.posedge + print("test 1: test IP RX packet") + current_test.next = 1 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = ip_sink_queue.get(False) + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 2: test IP TX packet") + current_test.next = 2 + + # send IP packet + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + # wait for ARP request packet + while eth_sink_queue.empty(): + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80166 + + # generate response + arp_frame = arp_ep.ARPFrame() + arp_frame.eth_dest_mac = 0x5A5152535455 + arp_frame.eth_src_mac = 0xDAD1D2D3D4D5 + arp_frame.eth_type = 0x0806 + arp_frame.arp_htype = 0x0001 + arp_frame.arp_ptype = 0x0800 + arp_frame.arp_hlen = 6 + arp_frame.arp_plen = 4 + arp_frame.arp_oper = 2 + arp_frame.arp_sha = 0xDAD1D2D3D4D5 + arp_frame.arp_spa = 0xc0a80166 + arp_frame.arp_tha = 0x5A5152535455 + arp_frame.arp_tpa = 0xc0a80164 + eth_source_queue.put(arp_frame.build_eth()) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = eth_sink_queue.get(False) + + check_frame = ip_ep.IPFrame() + check_frame.parse_eth(rx_frame) + + print(test_frame) + print(check_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 3: test IP TX arp fail packet") + current_test.next = 2 + + ip_tx_error_arp_failed_asserted.next = 0 + + test_frame = ip_ep.IPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x10 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80167 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + ip_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + assert ip_tx_error_arp_failed_asserted + + # check for 4 ARP requests + assert eth_sink_queue.qsize() == 4 + + while not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get(False) + + check_frame = arp_ep.ARPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF + assert check_frame.eth_src_mac == 0x5A5152535455 + assert check_frame.eth_type == 0x0806 + assert check_frame.arp_htype == 0x0001 + assert check_frame.arp_ptype == 0x0800 + assert check_frame.arp_hlen == 6 + assert check_frame.arp_plen == 4 + assert check_frame.arp_oper == 1 + assert check_frame.arp_sha == 0x5A5152535455 + assert check_frame.arp_spa == 0xc0a80164 + assert check_frame.arp_tha == 0x000000000000 + assert check_frame.arp_tpa == 0xc0a80167 + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert ip_source_queue.empty() + assert ip_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 4: test UDP RX packet") + current_test.next = 4 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0x5A5152535455 + test_frame.eth_src_mac = 0xDAD1D2D3D4D5 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80165 + test_frame.ip_dest_ip = 0xc0a80164 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + eth_frame = test_frame.build_eth() + + eth_source_queue.put(eth_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not udp_sink_queue.empty(): + rx_frame = udp_sink_queue.get() + + assert rx_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + yield clk.posedge + print("test 5: test UDP TX packet") + current_test.next = 5 + + test_frame = udp_ep.UDPFrame() + test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 + test_frame.eth_src_mac = 0x5A5152535455 + test_frame.eth_type = 0x0800 + test_frame.ip_version = 4 + test_frame.ip_ihl = 5 + test_frame.ip_dscp = 0 + test_frame.ip_ecn = 0 + test_frame.ip_length = None + test_frame.ip_identification = 0 + test_frame.ip_flags = 2 + test_frame.ip_fragment_offset = 0 + test_frame.ip_ttl = 64 + test_frame.ip_protocol = 0x11 + test_frame.ip_header_checksum = None + test_frame.ip_source_ip = 0xc0a80164 + test_frame.ip_dest_ip = 0xc0a80166 + test_frame.udp_source_port = 1234 + test_frame.udp_dest_port = 5678 + test_frame.payload = bytearray(range(32)) + test_frame.build() + + udp_source_queue.put(test_frame) + + yield clk.posedge + yield clk.posedge + + yield wait_normal() + + yield clk.posedge + yield clk.posedge + + rx_frame = None + if not eth_sink_queue.empty(): + rx_frame = eth_sink_queue.get() + + check_frame = udp_ep.UDPFrame() + check_frame.parse_eth(rx_frame) + + assert check_frame == test_frame + + assert eth_source_queue.empty() + assert eth_sink_queue.empty() + assert udp_source_queue.empty() + assert udp_sink_queue.empty() + + yield delay(100) + + raise StopSimulation + + return dut, eth_source, eth_sink, ip_source, ip_sink, udp_source, udp_sink, clkgen, monitor, check + +def test_bench(): + sim = Simulation(bench()) + sim.run() + +if __name__ == '__main__': + print("Running test...") + test_bench() + diff --git a/tb/test_udp_complete_64.v b/tb/test_udp_complete_64.v new file mode 100644 index 000000000..36e19c609 --- /dev/null +++ b/tb/test_udp_complete_64.v @@ -0,0 +1,458 @@ +/* + +Copyright (c) 2014 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`timescale 1 ns / 1 ps + +module test_udp_complete_64; + +// Parameters +parameter ARP_CACHE_ADDR_WIDTH = 2; +parameter ARP_REQUEST_RETRY_COUNT = 4; +parameter ARP_REQUEST_RETRY_INTERVAL = 150; +parameter ARP_REQUEST_TIMEOUT = 400; +parameter UDP_CHECKSUM_ENABLE = 0; +parameter UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH = 11; +parameter UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH = 3; + +// Inputs +reg clk = 0; +reg rst = 0; +reg [7:0] current_test = 0; + +reg input_eth_hdr_valid = 0; +reg [47:0] input_eth_dest_mac = 0; +reg [47:0] input_eth_src_mac = 0; +reg [15:0] input_eth_type = 0; +reg [63:0] input_eth_payload_tdata = 0; +reg [7:0] input_eth_payload_tkeep = 0; +reg input_eth_payload_tvalid = 0; +reg input_eth_payload_tlast = 0; +reg input_eth_payload_tuser = 0; +reg arp_response_valid = 0; +reg arp_response_error = 0; +reg [47:0] arp_response_mac = 0; +reg input_ip_hdr_valid = 0; +reg [5:0] input_ip_dscp = 0; +reg [1:0] input_ip_ecn = 0; +reg [15:0] input_ip_length = 0; +reg [7:0] input_ip_ttl = 0; +reg [7:0] input_ip_protocol = 0; +reg [31:0] input_ip_source_ip = 0; +reg [31:0] input_ip_dest_ip = 0; +reg [63:0] input_ip_payload_tdata = 0; +reg [7:0] input_ip_payload_tkeep = 0; +reg input_ip_payload_tvalid = 0; +reg input_ip_payload_tlast = 0; +reg input_ip_payload_tuser = 0; +reg input_udp_hdr_valid = 0; +reg [5:0] input_udp_ip_dscp = 0; +reg [1:0] input_udp_ip_ecn = 0; +reg [7:0] input_udp_ip_ttl = 0; +reg [31:0] input_udp_ip_source_ip = 0; +reg [31:0] input_udp_ip_dest_ip = 0; +reg [15:0] input_udp_source_port = 0; +reg [15:0] input_udp_dest_port = 0; +reg [15:0] input_udp_length = 0; +reg [15:0] input_udp_checksum = 0; +reg [63:0] input_udp_payload_tdata = 0; +reg [7:0] input_udp_payload_tkeep = 0; +reg input_udp_payload_tvalid = 0; +reg input_udp_payload_tlast = 0; +reg input_udp_payload_tuser = 0; +reg output_eth_hdr_ready = 0; +reg output_eth_payload_tready = 0; +reg output_ip_hdr_ready = 0; +reg output_ip_payload_tready = 0; +reg output_udp_hdr_ready = 0; +reg output_udp_payload_tready = 0; +reg [47:0] local_mac = 0; +reg [31:0] local_ip = 0; +reg [31:0] gateway_ip = 0; +reg [31:0] subnet_mask = 0; +reg clear_arp_cache = 0; + +// Outputs +wire input_eth_hdr_ready; +wire input_eth_payload_tready; +wire input_ip_hdr_ready; +wire input_ip_payload_tready; +wire input_udp_hdr_ready; +wire input_udp_payload_tready; +wire output_eth_hdr_valid; +wire [47:0] output_eth_dest_mac; +wire [47:0] output_eth_src_mac; +wire [15:0] output_eth_type; +wire [63:0] output_eth_payload_tdata; +wire [7:0] output_eth_payload_tkeep; +wire output_eth_payload_tvalid; +wire output_eth_payload_tlast; +wire output_eth_payload_tuser; +wire arp_request_valid; +wire [31:0] arp_request_ip; +wire output_ip_hdr_valid; +wire [47:0] output_ip_eth_dest_mac; +wire [47:0] output_ip_eth_src_mac; +wire [15:0] output_ip_eth_type; +wire [3:0] output_ip_version; +wire [3:0] output_ip_ihl; +wire [5:0] output_ip_dscp; +wire [1:0] output_ip_ecn; +wire [15:0] output_ip_length; +wire [15:0] output_ip_identification; +wire [2:0] output_ip_flags; +wire [12:0] output_ip_fragment_offset; +wire [7:0] output_ip_ttl; +wire [7:0] output_ip_protocol; +wire [15:0] output_ip_header_checksum; +wire [31:0] output_ip_source_ip; +wire [31:0] output_ip_dest_ip; +wire [63:0] output_ip_payload_tdata; +wire [7:0] output_ip_payload_tkeep; +wire output_ip_payload_tvalid; +wire output_ip_payload_tlast; +wire output_ip_payload_tuser; +wire output_udp_hdr_valid; +wire [47:0] output_udp_eth_dest_mac; +wire [47:0] output_udp_eth_src_mac; +wire [15:0] output_udp_eth_type; +wire [3:0] output_udp_ip_version; +wire [3:0] output_udp_ip_ihl; +wire [5:0] output_udp_ip_dscp; +wire [1:0] output_udp_ip_ecn; +wire [15:0] output_udp_ip_length; +wire [15:0] output_udp_ip_identification; +wire [2:0] output_udp_ip_flags; +wire [12:0] output_udp_ip_fragment_offset; +wire [7:0] output_udp_ip_ttl; +wire [7:0] output_udp_ip_protocol; +wire [15:0] output_udp_ip_header_checksum; +wire [31:0] output_udp_ip_source_ip; +wire [31:0] output_udp_ip_dest_ip; +wire [15:0] output_udp_source_port; +wire [15:0] output_udp_dest_port; +wire [15:0] output_udp_length; +wire [15:0] output_udp_checksum; +wire [63:0] output_udp_payload_tdata; +wire [7:0] output_udp_payload_tkeep; +wire output_udp_payload_tvalid; +wire output_udp_payload_tlast; +wire output_udp_payload_tuser; +wire ip_rx_busy; +wire ip_tx_busy; +wire udp_rx_busy; +wire udp_tx_busy; +wire ip_rx_error_header_early_termination; +wire ip_rx_error_payload_early_termination; +wire ip_rx_error_invalid_header; +wire ip_rx_error_invalid_checksum; +wire ip_tx_error_payload_early_termination; +wire ip_tx_error_arp_failed; +wire udp_rx_error_header_early_termination; +wire udp_rx_error_payload_early_termination; +wire udp_tx_error_payload_early_termination; + +initial begin + // myhdl integration + $from_myhdl(clk, + rst, + current_test, + input_eth_hdr_valid, + input_eth_dest_mac, + input_eth_src_mac, + input_eth_type, + input_eth_payload_tdata, + input_eth_payload_tkeep, + input_eth_payload_tvalid, + input_eth_payload_tlast, + input_eth_payload_tuser, + input_ip_hdr_valid, + input_ip_dscp, + input_ip_ecn, + input_ip_length, + input_ip_ttl, + input_ip_protocol, + input_ip_source_ip, + input_ip_dest_ip, + input_ip_payload_tdata, + input_ip_payload_tkeep, + input_ip_payload_tvalid, + input_ip_payload_tlast, + input_ip_payload_tuser, + input_udp_hdr_valid, + input_udp_ip_dscp, + input_udp_ip_ecn, + input_udp_ip_ttl, + input_udp_ip_source_ip, + input_udp_ip_dest_ip, + input_udp_source_port, + input_udp_dest_port, + input_udp_length, + input_udp_checksum, + input_udp_payload_tdata, + input_udp_payload_tkeep, + input_udp_payload_tvalid, + input_udp_payload_tlast, + input_udp_payload_tuser, + output_eth_hdr_ready, + output_eth_payload_tready, + output_ip_hdr_ready, + output_ip_payload_tready, + output_udp_hdr_ready, + output_udp_payload_tready, + local_mac, + local_ip, + gateway_ip, + subnet_mask, + clear_arp_cache); + $to_myhdl(input_eth_hdr_ready, + input_eth_payload_tready, + input_ip_hdr_ready, + input_ip_payload_tready, + input_udp_hdr_ready, + input_udp_payload_tready, + output_eth_hdr_valid, + output_eth_dest_mac, + output_eth_src_mac, + output_eth_type, + output_eth_payload_tdata, + output_eth_payload_tkeep, + output_eth_payload_tvalid, + output_eth_payload_tlast, + output_eth_payload_tuser, + output_ip_hdr_valid, + output_ip_eth_dest_mac, + output_ip_eth_src_mac, + output_ip_eth_type, + output_ip_version, + output_ip_ihl, + output_ip_dscp, + output_ip_ecn, + output_ip_length, + output_ip_identification, + output_ip_flags, + output_ip_fragment_offset, + output_ip_ttl, + output_ip_protocol, + output_ip_header_checksum, + output_ip_source_ip, + output_ip_dest_ip, + output_ip_payload_tdata, + output_ip_payload_tkeep, + output_ip_payload_tvalid, + output_ip_payload_tlast, + output_ip_payload_tuser, + output_udp_hdr_valid, + output_udp_eth_dest_mac, + output_udp_eth_src_mac, + output_udp_eth_type, + output_udp_ip_version, + output_udp_ip_ihl, + output_udp_ip_dscp, + output_udp_ip_ecn, + output_udp_ip_length, + output_udp_ip_identification, + output_udp_ip_flags, + output_udp_ip_fragment_offset, + output_udp_ip_ttl, + output_udp_ip_protocol, + output_udp_ip_header_checksum, + output_udp_ip_source_ip, + output_udp_ip_dest_ip, + output_udp_source_port, + output_udp_dest_port, + output_udp_length, + output_udp_checksum, + output_udp_payload_tdata, + output_udp_payload_tkeep, + output_udp_payload_tvalid, + output_udp_payload_tlast, + output_udp_payload_tuser, + ip_rx_busy, + ip_tx_busy, + udp_rx_busy, + udp_tx_busy, + ip_rx_error_header_early_termination, + ip_rx_error_payload_early_termination, + ip_rx_error_invalid_header, + ip_rx_error_invalid_checksum, + ip_tx_error_payload_early_termination, + ip_tx_error_arp_failed, + udp_rx_error_header_early_termination, + udp_rx_error_payload_early_termination, + udp_tx_error_payload_early_termination); + + // dump file + $dumpfile("test_udp_complete_64.lxt"); + $dumpvars(0, test_udp_complete_64); +end + +udp_complete_64 #( + .ARP_CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH), + .ARP_REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT), + .ARP_REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL), + .ARP_REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT), + .UDP_CHECKSUM_ENABLE(UDP_CHECKSUM_ENABLE), + .UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH(UDP_CHECKSUM_PAYLOAD_FIFO_ADDR_WIDTH), + .UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH(UDP_CHECKSUM_HEADER_FIFO_ADDR_WIDTH) +) +UUT ( + .clk(clk), + .rst(rst), + // Ethernet frame input + .input_eth_hdr_valid(input_eth_hdr_valid), + .input_eth_hdr_ready(input_eth_hdr_ready), + .input_eth_dest_mac(input_eth_dest_mac), + .input_eth_src_mac(input_eth_src_mac), + .input_eth_type(input_eth_type), + .input_eth_payload_tdata(input_eth_payload_tdata), + .input_eth_payload_tkeep(input_eth_payload_tkeep), + .input_eth_payload_tvalid(input_eth_payload_tvalid), + .input_eth_payload_tready(input_eth_payload_tready), + .input_eth_payload_tlast(input_eth_payload_tlast), + .input_eth_payload_tuser(input_eth_payload_tuser), + // Ethernet frame output + .output_eth_hdr_valid(output_eth_hdr_valid), + .output_eth_hdr_ready(output_eth_hdr_ready), + .output_eth_dest_mac(output_eth_dest_mac), + .output_eth_src_mac(output_eth_src_mac), + .output_eth_type(output_eth_type), + .output_eth_payload_tdata(output_eth_payload_tdata), + .output_eth_payload_tkeep(output_eth_payload_tkeep), + .output_eth_payload_tvalid(output_eth_payload_tvalid), + .output_eth_payload_tready(output_eth_payload_tready), + .output_eth_payload_tlast(output_eth_payload_tlast), + .output_eth_payload_tuser(output_eth_payload_tuser), + // IP frame input + .input_ip_hdr_valid(input_ip_hdr_valid), + .input_ip_hdr_ready(input_ip_hdr_ready), + .input_ip_dscp(input_ip_dscp), + .input_ip_ecn(input_ip_ecn), + .input_ip_length(input_ip_length), + .input_ip_ttl(input_ip_ttl), + .input_ip_protocol(input_ip_protocol), + .input_ip_source_ip(input_ip_source_ip), + .input_ip_dest_ip(input_ip_dest_ip), + .input_ip_payload_tdata(input_ip_payload_tdata), + .input_ip_payload_tkeep(input_ip_payload_tkeep), + .input_ip_payload_tvalid(input_ip_payload_tvalid), + .input_ip_payload_tready(input_ip_payload_tready), + .input_ip_payload_tlast(input_ip_payload_tlast), + .input_ip_payload_tuser(input_ip_payload_tuser), + // IP frame output + .output_ip_hdr_valid(output_ip_hdr_valid), + .output_ip_hdr_ready(output_ip_hdr_ready), + .output_ip_eth_dest_mac(output_ip_eth_dest_mac), + .output_ip_eth_src_mac(output_ip_eth_src_mac), + .output_ip_eth_type(output_ip_eth_type), + .output_ip_version(output_ip_version), + .output_ip_ihl(output_ip_ihl), + .output_ip_dscp(output_ip_dscp), + .output_ip_ecn(output_ip_ecn), + .output_ip_length(output_ip_length), + .output_ip_identification(output_ip_identification), + .output_ip_flags(output_ip_flags), + .output_ip_fragment_offset(output_ip_fragment_offset), + .output_ip_ttl(output_ip_ttl), + .output_ip_protocol(output_ip_protocol), + .output_ip_header_checksum(output_ip_header_checksum), + .output_ip_source_ip(output_ip_source_ip), + .output_ip_dest_ip(output_ip_dest_ip), + .output_ip_payload_tdata(output_ip_payload_tdata), + .output_ip_payload_tkeep(output_ip_payload_tkeep), + .output_ip_payload_tvalid(output_ip_payload_tvalid), + .output_ip_payload_tready(output_ip_payload_tready), + .output_ip_payload_tlast(output_ip_payload_tlast), + .output_ip_payload_tuser(output_ip_payload_tuser), + // UDP frame input + .input_udp_hdr_valid(input_udp_hdr_valid), + .input_udp_hdr_ready(input_udp_hdr_ready), + .input_udp_ip_dscp(input_udp_ip_dscp), + .input_udp_ip_ecn(input_udp_ip_ecn), + .input_udp_ip_ttl(input_udp_ip_ttl), + .input_udp_ip_source_ip(input_udp_ip_source_ip), + .input_udp_ip_dest_ip(input_udp_ip_dest_ip), + .input_udp_source_port(input_udp_source_port), + .input_udp_dest_port(input_udp_dest_port), + .input_udp_length(input_udp_length), + .input_udp_checksum(input_udp_checksum), + .input_udp_payload_tdata(input_udp_payload_tdata), + .input_udp_payload_tkeep(input_udp_payload_tkeep), + .input_udp_payload_tvalid(input_udp_payload_tvalid), + .input_udp_payload_tready(input_udp_payload_tready), + .input_udp_payload_tlast(input_udp_payload_tlast), + .input_udp_payload_tuser(input_udp_payload_tuser), + // UDP frame output + .output_udp_hdr_valid(output_udp_hdr_valid), + .output_udp_hdr_ready(output_udp_hdr_ready), + .output_udp_eth_dest_mac(output_udp_eth_dest_mac), + .output_udp_eth_src_mac(output_udp_eth_src_mac), + .output_udp_eth_type(output_udp_eth_type), + .output_udp_ip_version(output_udp_ip_version), + .output_udp_ip_ihl(output_udp_ip_ihl), + .output_udp_ip_dscp(output_udp_ip_dscp), + .output_udp_ip_ecn(output_udp_ip_ecn), + .output_udp_ip_length(output_udp_ip_length), + .output_udp_ip_identification(output_udp_ip_identification), + .output_udp_ip_flags(output_udp_ip_flags), + .output_udp_ip_fragment_offset(output_udp_ip_fragment_offset), + .output_udp_ip_ttl(output_udp_ip_ttl), + .output_udp_ip_protocol(output_udp_ip_protocol), + .output_udp_ip_header_checksum(output_udp_ip_header_checksum), + .output_udp_ip_source_ip(output_udp_ip_source_ip), + .output_udp_ip_dest_ip(output_udp_ip_dest_ip), + .output_udp_source_port(output_udp_source_port), + .output_udp_dest_port(output_udp_dest_port), + .output_udp_length(output_udp_length), + .output_udp_checksum(output_udp_checksum), + .output_udp_payload_tdata(output_udp_payload_tdata), + .output_udp_payload_tkeep(output_udp_payload_tkeep), + .output_udp_payload_tvalid(output_udp_payload_tvalid), + .output_udp_payload_tready(output_udp_payload_tready), + .output_udp_payload_tlast(output_udp_payload_tlast), + .output_udp_payload_tuser(output_udp_payload_tuser), + // Status signals + .ip_rx_busy(ip_rx_busy), + .ip_tx_busy(ip_tx_busy), + .udp_rx_busy(udp_rx_busy), + .udp_tx_busy(udp_tx_busy), + .ip_rx_error_header_early_termination(ip_rx_error_header_early_termination), + .ip_rx_error_payload_early_termination(ip_rx_error_payload_early_termination), + .ip_rx_error_invalid_header(ip_rx_error_invalid_header), + .ip_rx_error_invalid_checksum(ip_rx_error_invalid_checksum), + .ip_tx_error_payload_early_termination(ip_tx_error_payload_early_termination), + .ip_tx_error_arp_failed(ip_tx_error_arp_failed), + .udp_rx_error_header_early_termination(udp_rx_error_header_early_termination), + .udp_rx_error_payload_early_termination(udp_rx_error_payload_early_termination), + .udp_tx_error_payload_early_termination(udp_tx_error_payload_early_termination), + // Configuration + .local_mac(local_mac), + .local_ip(local_ip), + .gateway_ip(gateway_ip), + .subnet_mask(subnet_mask), + .clear_arp_cache(clear_arp_cache) +); + +endmodule