mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
Add IP complete module and testbench
This commit is contained in:
parent
9bf6f01649
commit
4a228f06c5
403
rtl/ip_complete.v
Normal file
403
rtl/ip_complete.v
Normal file
@ -0,0 +1,403 @@
|
||||
/*
|
||||
|
||||
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, ethernet frame interface
|
||||
*/
|
||||
module ip_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
|
||||
)
|
||||
(
|
||||
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,
|
||||
|
||||
/*
|
||||
* Status
|
||||
*/
|
||||
output wire rx_busy,
|
||||
output wire tx_busy,
|
||||
output wire rx_error_header_early_termination,
|
||||
output wire rx_error_payload_early_termination,
|
||||
output wire rx_error_invalid_header,
|
||||
output wire rx_error_invalid_checksum,
|
||||
output wire tx_error_payload_early_termination,
|
||||
output wire tx_error_arp_failed,
|
||||
|
||||
/*
|
||||
* 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
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
This module integrates the IP and ARP modules for a complete IP stack
|
||||
|
||||
*/
|
||||
|
||||
wire arp_request_valid;
|
||||
wire [31:0] arp_request_ip;
|
||||
wire arp_response_valid;
|
||||
wire arp_response_error;
|
||||
wire [47:0] arp_response_mac;
|
||||
|
||||
wire ip_rx_eth_hdr_valid;
|
||||
wire ip_rx_eth_hdr_ready;
|
||||
wire [47:0] ip_rx_eth_dest_mac;
|
||||
wire [47:0] ip_rx_eth_src_mac;
|
||||
wire [15:0] ip_rx_eth_type;
|
||||
wire [7:0] ip_rx_eth_payload_tdata;
|
||||
wire ip_rx_eth_payload_tvalid;
|
||||
wire ip_rx_eth_payload_tready;
|
||||
wire ip_rx_eth_payload_tlast;
|
||||
wire ip_rx_eth_payload_tuser;
|
||||
|
||||
wire ip_tx_eth_hdr_valid;
|
||||
wire ip_tx_eth_hdr_ready;
|
||||
wire [47:0] ip_tx_eth_dest_mac;
|
||||
wire [47:0] ip_tx_eth_src_mac;
|
||||
wire [15:0] ip_tx_eth_type;
|
||||
wire [7:0] ip_tx_eth_payload_tdata;
|
||||
wire ip_tx_eth_payload_tvalid;
|
||||
wire ip_tx_eth_payload_tready;
|
||||
wire ip_tx_eth_payload_tlast;
|
||||
wire ip_tx_eth_payload_tuser;
|
||||
|
||||
wire arp_rx_eth_hdr_valid;
|
||||
wire arp_rx_eth_hdr_ready;
|
||||
wire [47:0] arp_rx_eth_dest_mac;
|
||||
wire [47:0] arp_rx_eth_src_mac;
|
||||
wire [15:0] arp_rx_eth_type;
|
||||
wire [7:0] arp_rx_eth_payload_tdata;
|
||||
wire arp_rx_eth_payload_tvalid;
|
||||
wire arp_rx_eth_payload_tready;
|
||||
wire arp_rx_eth_payload_tlast;
|
||||
wire arp_rx_eth_payload_tuser;
|
||||
|
||||
wire arp_tx_eth_hdr_valid;
|
||||
wire arp_tx_eth_hdr_ready;
|
||||
wire [47:0] arp_tx_eth_dest_mac;
|
||||
wire [47:0] arp_tx_eth_src_mac;
|
||||
wire [15:0] arp_tx_eth_type;
|
||||
wire [7:0] arp_tx_eth_payload_tdata;
|
||||
wire arp_tx_eth_payload_tvalid;
|
||||
wire arp_tx_eth_payload_tready;
|
||||
wire arp_tx_eth_payload_tlast;
|
||||
wire arp_tx_eth_payload_tuser;
|
||||
|
||||
/*
|
||||
* Input classifier (eth_type)
|
||||
*/
|
||||
wire input_select_ip = (input_eth_type == 16'h0800);
|
||||
wire input_select_arp = (input_eth_type == 16'h0806);
|
||||
wire input_select_none = ~(input_select_ip | input_select_arp);
|
||||
|
||||
assign ip_rx_eth_hdr_valid = input_select_ip & input_eth_hdr_valid;
|
||||
assign ip_rx_eth_dest_mac = input_eth_dest_mac;
|
||||
assign ip_rx_eth_src_mac = input_eth_src_mac;
|
||||
assign ip_rx_eth_type = 16'h0800;
|
||||
assign ip_rx_eth_payload_tdata = input_eth_payload_tdata;
|
||||
assign ip_rx_eth_payload_tvalid = input_select_ip & input_eth_payload_tvalid;
|
||||
assign ip_rx_eth_payload_tlast = input_eth_payload_tlast;
|
||||
assign ip_rx_eth_payload_tuser = input_eth_payload_tuser;
|
||||
|
||||
assign arp_rx_eth_hdr_valid = input_select_arp & input_eth_hdr_valid;
|
||||
assign arp_rx_eth_dest_mac = input_eth_dest_mac;
|
||||
assign arp_rx_eth_src_mac = input_eth_src_mac;
|
||||
assign arp_rx_eth_type = 16'h0806;
|
||||
assign arp_rx_eth_payload_tdata = input_eth_payload_tdata;
|
||||
assign arp_rx_eth_payload_tvalid = input_select_arp & input_eth_payload_tvalid;
|
||||
assign arp_rx_eth_payload_tlast = input_eth_payload_tlast;
|
||||
assign arp_rx_eth_payload_tuser = input_eth_payload_tuser;
|
||||
|
||||
assign input_eth_hdr_ready = arp_rx_eth_hdr_ready & ip_rx_eth_hdr_ready;
|
||||
|
||||
assign input_eth_payload_tready = (input_select_ip & ip_rx_eth_payload_tready) |
|
||||
(input_select_arp & arp_rx_eth_payload_tready) |
|
||||
input_select_none;
|
||||
|
||||
/*
|
||||
* Output arbiter
|
||||
*/
|
||||
eth_arb_mux_2
|
||||
eth_arb_mux_2_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
// Ethernet frame inputs
|
||||
// ARP input (highest priority)
|
||||
.input_0_eth_hdr_valid(arp_tx_eth_hdr_valid),
|
||||
.input_0_eth_hdr_ready(arp_tx_eth_hdr_ready),
|
||||
.input_0_eth_dest_mac(arp_tx_eth_dest_mac),
|
||||
.input_0_eth_src_mac(arp_tx_eth_src_mac),
|
||||
.input_0_eth_type(arp_tx_eth_type),
|
||||
.input_0_eth_payload_tdata(arp_tx_eth_payload_tdata),
|
||||
.input_0_eth_payload_tvalid(arp_tx_eth_payload_tvalid),
|
||||
.input_0_eth_payload_tready(arp_tx_eth_payload_tready),
|
||||
.input_0_eth_payload_tlast(arp_tx_eth_payload_tlast),
|
||||
.input_0_eth_payload_tuser(arp_tx_eth_payload_tuser),
|
||||
// IP input (lowest priority)
|
||||
.input_1_eth_hdr_valid(ip_tx_eth_hdr_valid),
|
||||
.input_1_eth_hdr_ready(ip_tx_eth_hdr_ready),
|
||||
.input_1_eth_dest_mac(ip_tx_eth_dest_mac),
|
||||
.input_1_eth_src_mac(ip_tx_eth_src_mac),
|
||||
.input_1_eth_type(ip_tx_eth_type),
|
||||
.input_1_eth_payload_tdata(ip_tx_eth_payload_tdata),
|
||||
.input_1_eth_payload_tvalid(ip_tx_eth_payload_tvalid),
|
||||
.input_1_eth_payload_tready(ip_tx_eth_payload_tready),
|
||||
.input_1_eth_payload_tlast(ip_tx_eth_payload_tlast),
|
||||
.input_1_eth_payload_tuser(ip_tx_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 module
|
||||
*/
|
||||
ip
|
||||
ip_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
// Ethernet frame input
|
||||
.input_eth_hdr_valid(ip_rx_eth_hdr_valid),
|
||||
.input_eth_hdr_ready(ip_rx_eth_hdr_ready),
|
||||
.input_eth_dest_mac(ip_rx_eth_dest_mac),
|
||||
.input_eth_src_mac(ip_rx_eth_src_mac),
|
||||
.input_eth_type(ip_rx_eth_type),
|
||||
.input_eth_payload_tdata(ip_rx_eth_payload_tdata),
|
||||
.input_eth_payload_tvalid(ip_rx_eth_payload_tvalid),
|
||||
.input_eth_payload_tready(ip_rx_eth_payload_tready),
|
||||
.input_eth_payload_tlast(ip_rx_eth_payload_tlast),
|
||||
.input_eth_payload_tuser(ip_rx_eth_payload_tuser),
|
||||
// Ethernet frame output
|
||||
.output_eth_hdr_valid(ip_tx_eth_hdr_valid),
|
||||
.output_eth_hdr_ready(ip_tx_eth_hdr_ready),
|
||||
.output_eth_dest_mac(ip_tx_eth_dest_mac),
|
||||
.output_eth_src_mac(ip_tx_eth_src_mac),
|
||||
.output_eth_type(ip_tx_eth_type),
|
||||
.output_eth_payload_tdata(ip_tx_eth_payload_tdata),
|
||||
.output_eth_payload_tvalid(ip_tx_eth_payload_tvalid),
|
||||
.output_eth_payload_tready(ip_tx_eth_payload_tready),
|
||||
.output_eth_payload_tlast(ip_tx_eth_payload_tlast),
|
||||
.output_eth_payload_tuser(ip_tx_eth_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),
|
||||
// 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),
|
||||
// ARP requests
|
||||
.arp_request_valid(arp_request_valid),
|
||||
.arp_request_ip(arp_request_ip),
|
||||
.arp_response_valid(arp_response_valid),
|
||||
.arp_response_error(arp_response_error),
|
||||
.arp_response_mac(arp_response_mac),
|
||||
// Status
|
||||
.rx_busy(rx_busy),
|
||||
.tx_busy(tx_busy),
|
||||
.rx_error_header_early_termination(rx_error_header_early_termination),
|
||||
.rx_error_payload_early_termination(rx_error_payload_early_termination),
|
||||
.rx_error_invalid_header(rx_error_invalid_header),
|
||||
.rx_error_invalid_checksum(rx_error_invalid_checksum),
|
||||
.tx_error_payload_early_termination(tx_error_payload_early_termination),
|
||||
.tx_error_arp_failed(tx_error_arp_failed),
|
||||
// Configuration
|
||||
.local_mac(local_mac),
|
||||
.local_ip(local_ip)
|
||||
);
|
||||
|
||||
/*
|
||||
* ARP module
|
||||
*/
|
||||
arp #(
|
||||
.CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH),
|
||||
.REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT),
|
||||
.REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL),
|
||||
.REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT)
|
||||
)
|
||||
arp_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
// Ethernet frame input
|
||||
.input_eth_hdr_valid(arp_rx_eth_hdr_valid),
|
||||
.input_eth_hdr_ready(arp_rx_eth_hdr_ready),
|
||||
.input_eth_dest_mac(arp_rx_eth_dest_mac),
|
||||
.input_eth_src_mac(arp_rx_eth_src_mac),
|
||||
.input_eth_type(arp_rx_eth_type),
|
||||
.input_eth_payload_tdata(arp_rx_eth_payload_tdata),
|
||||
.input_eth_payload_tvalid(arp_rx_eth_payload_tvalid),
|
||||
.input_eth_payload_tready(arp_rx_eth_payload_tready),
|
||||
.input_eth_payload_tlast(arp_rx_eth_payload_tlast),
|
||||
.input_eth_payload_tuser(arp_rx_eth_payload_tuser),
|
||||
// Ethernet frame output
|
||||
.output_eth_hdr_valid(arp_tx_eth_hdr_valid),
|
||||
.output_eth_hdr_ready(arp_tx_eth_hdr_ready),
|
||||
.output_eth_dest_mac(arp_tx_eth_dest_mac),
|
||||
.output_eth_src_mac(arp_tx_eth_src_mac),
|
||||
.output_eth_type(arp_tx_eth_type),
|
||||
.output_eth_payload_tdata(arp_tx_eth_payload_tdata),
|
||||
.output_eth_payload_tvalid(arp_tx_eth_payload_tvalid),
|
||||
.output_eth_payload_tready(arp_tx_eth_payload_tready),
|
||||
.output_eth_payload_tlast(arp_tx_eth_payload_tlast),
|
||||
.output_eth_payload_tuser(arp_tx_eth_payload_tuser),
|
||||
// ARP requests
|
||||
.arp_request_valid(arp_request_valid),
|
||||
.arp_request_ip(arp_request_ip),
|
||||
.arp_response_valid(arp_response_valid),
|
||||
.arp_response_error(arp_response_error),
|
||||
.arp_response_mac(arp_response_mac),
|
||||
// Configuration
|
||||
.local_mac(local_mac),
|
||||
.local_ip(local_ip),
|
||||
.gateway_ip(gateway_ip),
|
||||
.subnet_mask(subnet_mask),
|
||||
.clear_cache(clear_arp_cache)
|
||||
);
|
||||
|
||||
endmodule
|
422
rtl/ip_complete_64.v
Normal file
422
rtl/ip_complete_64.v
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
|
||||
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, ethernet frame interface (64 bit datapath)
|
||||
*/
|
||||
module ip_complete_64 #(
|
||||
parameter ARP_CACHE_ADDR_WIDTH = 2,
|
||||
parameter ARP_REQUEST_RETRY_COUNT = 4,
|
||||
parameter ARP_REQUEST_RETRY_INTERVAL = 156250000*2,
|
||||
parameter ARP_REQUEST_TIMEOUT = 156250000*30
|
||||
)
|
||||
(
|
||||
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,
|
||||
|
||||
/*
|
||||
* Status
|
||||
*/
|
||||
output wire rx_busy,
|
||||
output wire tx_busy,
|
||||
output wire rx_error_header_early_termination,
|
||||
output wire rx_error_payload_early_termination,
|
||||
output wire rx_error_invalid_header,
|
||||
output wire rx_error_invalid_checksum,
|
||||
output wire tx_error_payload_early_termination,
|
||||
output wire tx_error_arp_failed,
|
||||
|
||||
/*
|
||||
* 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
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
This module integrates the IP and ARP modules for a complete IP stack
|
||||
|
||||
*/
|
||||
|
||||
wire arp_request_valid;
|
||||
wire [31:0] arp_request_ip;
|
||||
wire arp_response_valid;
|
||||
wire arp_response_error;
|
||||
wire [47:0] arp_response_mac;
|
||||
|
||||
wire ip_rx_eth_hdr_valid;
|
||||
wire ip_rx_eth_hdr_ready;
|
||||
wire [47:0] ip_rx_eth_dest_mac;
|
||||
wire [47:0] ip_rx_eth_src_mac;
|
||||
wire [15:0] ip_rx_eth_type;
|
||||
wire [63:0] ip_rx_eth_payload_tdata;
|
||||
wire [7:0] ip_rx_eth_payload_tkeep;
|
||||
wire ip_rx_eth_payload_tvalid;
|
||||
wire ip_rx_eth_payload_tready;
|
||||
wire ip_rx_eth_payload_tlast;
|
||||
wire ip_rx_eth_payload_tuser;
|
||||
|
||||
wire ip_tx_eth_hdr_valid;
|
||||
wire ip_tx_eth_hdr_ready;
|
||||
wire [47:0] ip_tx_eth_dest_mac;
|
||||
wire [47:0] ip_tx_eth_src_mac;
|
||||
wire [15:0] ip_tx_eth_type;
|
||||
wire [63:0] ip_tx_eth_payload_tdata;
|
||||
wire [7:0] ip_tx_eth_payload_tkeep;
|
||||
wire ip_tx_eth_payload_tvalid;
|
||||
wire ip_tx_eth_payload_tready;
|
||||
wire ip_tx_eth_payload_tlast;
|
||||
wire ip_tx_eth_payload_tuser;
|
||||
|
||||
wire arp_rx_eth_hdr_valid;
|
||||
wire arp_rx_eth_hdr_ready;
|
||||
wire [47:0] arp_rx_eth_dest_mac;
|
||||
wire [47:0] arp_rx_eth_src_mac;
|
||||
wire [15:0] arp_rx_eth_type;
|
||||
wire [63:0] arp_rx_eth_payload_tdata;
|
||||
wire [7:0] arp_rx_eth_payload_tkeep;
|
||||
wire arp_rx_eth_payload_tvalid;
|
||||
wire arp_rx_eth_payload_tready;
|
||||
wire arp_rx_eth_payload_tlast;
|
||||
wire arp_rx_eth_payload_tuser;
|
||||
|
||||
wire arp_tx_eth_hdr_valid;
|
||||
wire arp_tx_eth_hdr_ready;
|
||||
wire [47:0] arp_tx_eth_dest_mac;
|
||||
wire [47:0] arp_tx_eth_src_mac;
|
||||
wire [15:0] arp_tx_eth_type;
|
||||
wire [63:0] arp_tx_eth_payload_tdata;
|
||||
wire [7:0] arp_tx_eth_payload_tkeep;
|
||||
wire arp_tx_eth_payload_tvalid;
|
||||
wire arp_tx_eth_payload_tready;
|
||||
wire arp_tx_eth_payload_tlast;
|
||||
wire arp_tx_eth_payload_tuser;
|
||||
|
||||
/*
|
||||
* Input classifier (eth_type)
|
||||
*/
|
||||
wire input_select_ip = (input_eth_type == 16'h0800);
|
||||
wire input_select_arp = (input_eth_type == 16'h0806);
|
||||
wire input_select_none = ~(input_select_ip | input_select_arp);
|
||||
|
||||
assign ip_rx_eth_hdr_valid = input_select_ip & input_eth_hdr_valid;
|
||||
assign ip_rx_eth_dest_mac = input_eth_dest_mac;
|
||||
assign ip_rx_eth_src_mac = input_eth_src_mac;
|
||||
assign ip_rx_eth_type = 16'h0800;
|
||||
assign ip_rx_eth_payload_tdata = input_eth_payload_tdata;
|
||||
assign ip_rx_eth_payload_tkeep = input_eth_payload_tkeep;
|
||||
assign ip_rx_eth_payload_tvalid = input_select_ip & input_eth_payload_tvalid;
|
||||
assign ip_rx_eth_payload_tlast = input_eth_payload_tlast;
|
||||
assign ip_rx_eth_payload_tuser = input_eth_payload_tuser;
|
||||
|
||||
assign arp_rx_eth_hdr_valid = input_select_arp & input_eth_hdr_valid;
|
||||
assign arp_rx_eth_dest_mac = input_eth_dest_mac;
|
||||
assign arp_rx_eth_src_mac = input_eth_src_mac;
|
||||
assign arp_rx_eth_type = 16'h0806;
|
||||
assign arp_rx_eth_payload_tdata = input_eth_payload_tdata;
|
||||
assign arp_rx_eth_payload_tkeep = input_eth_payload_tkeep;
|
||||
assign arp_rx_eth_payload_tvalid = input_select_arp & input_eth_payload_tvalid;
|
||||
assign arp_rx_eth_payload_tlast = input_eth_payload_tlast;
|
||||
assign arp_rx_eth_payload_tuser = input_eth_payload_tuser;
|
||||
|
||||
assign input_eth_hdr_ready = arp_rx_eth_hdr_ready & ip_rx_eth_hdr_ready;
|
||||
|
||||
assign input_eth_payload_tready = (input_select_ip & ip_rx_eth_payload_tready) |
|
||||
(input_select_arp & arp_rx_eth_payload_tready) |
|
||||
input_select_none;
|
||||
|
||||
/*
|
||||
* Output arbiter
|
||||
*/
|
||||
eth_arb_mux_64_2
|
||||
eth_arb_mux_2_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
// Ethernet frame inputs
|
||||
// ARP input (highest priority)
|
||||
.input_0_eth_hdr_valid(arp_tx_eth_hdr_valid),
|
||||
.input_0_eth_hdr_ready(arp_tx_eth_hdr_ready),
|
||||
.input_0_eth_dest_mac(arp_tx_eth_dest_mac),
|
||||
.input_0_eth_src_mac(arp_tx_eth_src_mac),
|
||||
.input_0_eth_type(arp_tx_eth_type),
|
||||
.input_0_eth_payload_tdata(arp_tx_eth_payload_tdata),
|
||||
.input_0_eth_payload_tkeep(arp_tx_eth_payload_tkeep),
|
||||
.input_0_eth_payload_tvalid(arp_tx_eth_payload_tvalid),
|
||||
.input_0_eth_payload_tready(arp_tx_eth_payload_tready),
|
||||
.input_0_eth_payload_tlast(arp_tx_eth_payload_tlast),
|
||||
.input_0_eth_payload_tuser(arp_tx_eth_payload_tuser),
|
||||
// IP input (lowest priority)
|
||||
.input_1_eth_hdr_valid(ip_tx_eth_hdr_valid),
|
||||
.input_1_eth_hdr_ready(ip_tx_eth_hdr_ready),
|
||||
.input_1_eth_dest_mac(ip_tx_eth_dest_mac),
|
||||
.input_1_eth_src_mac(ip_tx_eth_src_mac),
|
||||
.input_1_eth_type(ip_tx_eth_type),
|
||||
.input_1_eth_payload_tdata(ip_tx_eth_payload_tdata),
|
||||
.input_1_eth_payload_tkeep(ip_tx_eth_payload_tkeep),
|
||||
.input_1_eth_payload_tvalid(ip_tx_eth_payload_tvalid),
|
||||
.input_1_eth_payload_tready(ip_tx_eth_payload_tready),
|
||||
.input_1_eth_payload_tlast(ip_tx_eth_payload_tlast),
|
||||
.input_1_eth_payload_tuser(ip_tx_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 module
|
||||
*/
|
||||
ip_64
|
||||
ip_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
// Ethernet frame input
|
||||
.input_eth_hdr_valid(ip_rx_eth_hdr_valid),
|
||||
.input_eth_hdr_ready(ip_rx_eth_hdr_ready),
|
||||
.input_eth_dest_mac(ip_rx_eth_dest_mac),
|
||||
.input_eth_src_mac(ip_rx_eth_src_mac),
|
||||
.input_eth_type(ip_rx_eth_type),
|
||||
.input_eth_payload_tdata(ip_rx_eth_payload_tdata),
|
||||
.input_eth_payload_tkeep(ip_rx_eth_payload_tkeep),
|
||||
.input_eth_payload_tvalid(ip_rx_eth_payload_tvalid),
|
||||
.input_eth_payload_tready(ip_rx_eth_payload_tready),
|
||||
.input_eth_payload_tlast(ip_rx_eth_payload_tlast),
|
||||
.input_eth_payload_tuser(ip_rx_eth_payload_tuser),
|
||||
// Ethernet frame output
|
||||
.output_eth_hdr_valid(ip_tx_eth_hdr_valid),
|
||||
.output_eth_hdr_ready(ip_tx_eth_hdr_ready),
|
||||
.output_eth_dest_mac(ip_tx_eth_dest_mac),
|
||||
.output_eth_src_mac(ip_tx_eth_src_mac),
|
||||
.output_eth_type(ip_tx_eth_type),
|
||||
.output_eth_payload_tdata(ip_tx_eth_payload_tdata),
|
||||
.output_eth_payload_tkeep(ip_tx_eth_payload_tkeep),
|
||||
.output_eth_payload_tvalid(ip_tx_eth_payload_tvalid),
|
||||
.output_eth_payload_tready(ip_tx_eth_payload_tready),
|
||||
.output_eth_payload_tlast(ip_tx_eth_payload_tlast),
|
||||
.output_eth_payload_tuser(ip_tx_eth_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),
|
||||
// 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),
|
||||
// ARP requests
|
||||
.arp_request_valid(arp_request_valid),
|
||||
.arp_request_ip(arp_request_ip),
|
||||
.arp_response_valid(arp_response_valid),
|
||||
.arp_response_error(arp_response_error),
|
||||
.arp_response_mac(arp_response_mac),
|
||||
// Status
|
||||
.rx_busy(rx_busy),
|
||||
.tx_busy(tx_busy),
|
||||
.rx_error_header_early_termination(rx_error_header_early_termination),
|
||||
.rx_error_payload_early_termination(rx_error_payload_early_termination),
|
||||
.rx_error_invalid_header(rx_error_invalid_header),
|
||||
.rx_error_invalid_checksum(rx_error_invalid_checksum),
|
||||
.tx_error_payload_early_termination(tx_error_payload_early_termination),
|
||||
.tx_error_arp_failed(tx_error_arp_failed),
|
||||
// Configuration
|
||||
.local_mac(local_mac),
|
||||
.local_ip(local_ip)
|
||||
);
|
||||
|
||||
/*
|
||||
* ARP module
|
||||
*/
|
||||
arp_64 #(
|
||||
.CACHE_ADDR_WIDTH(ARP_CACHE_ADDR_WIDTH),
|
||||
.REQUEST_RETRY_COUNT(ARP_REQUEST_RETRY_COUNT),
|
||||
.REQUEST_RETRY_INTERVAL(ARP_REQUEST_RETRY_INTERVAL),
|
||||
.REQUEST_TIMEOUT(ARP_REQUEST_TIMEOUT)
|
||||
)
|
||||
arp_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
// Ethernet frame input
|
||||
.input_eth_hdr_valid(arp_rx_eth_hdr_valid),
|
||||
.input_eth_hdr_ready(arp_rx_eth_hdr_ready),
|
||||
.input_eth_dest_mac(arp_rx_eth_dest_mac),
|
||||
.input_eth_src_mac(arp_rx_eth_src_mac),
|
||||
.input_eth_type(arp_rx_eth_type),
|
||||
.input_eth_payload_tdata(arp_rx_eth_payload_tdata),
|
||||
.input_eth_payload_tkeep(arp_rx_eth_payload_tkeep),
|
||||
.input_eth_payload_tvalid(arp_rx_eth_payload_tvalid),
|
||||
.input_eth_payload_tready(arp_rx_eth_payload_tready),
|
||||
.input_eth_payload_tlast(arp_rx_eth_payload_tlast),
|
||||
.input_eth_payload_tuser(arp_rx_eth_payload_tuser),
|
||||
// Ethernet frame output
|
||||
.output_eth_hdr_valid(arp_tx_eth_hdr_valid),
|
||||
.output_eth_hdr_ready(arp_tx_eth_hdr_ready),
|
||||
.output_eth_dest_mac(arp_tx_eth_dest_mac),
|
||||
.output_eth_src_mac(arp_tx_eth_src_mac),
|
||||
.output_eth_type(arp_tx_eth_type),
|
||||
.output_eth_payload_tdata(arp_tx_eth_payload_tdata),
|
||||
.output_eth_payload_tkeep(arp_tx_eth_payload_tkeep),
|
||||
.output_eth_payload_tvalid(arp_tx_eth_payload_tvalid),
|
||||
.output_eth_payload_tready(arp_tx_eth_payload_tready),
|
||||
.output_eth_payload_tlast(arp_tx_eth_payload_tlast),
|
||||
.output_eth_payload_tuser(arp_tx_eth_payload_tuser),
|
||||
// ARP requests
|
||||
.arp_request_valid(arp_request_valid),
|
||||
.arp_request_ip(arp_request_ip),
|
||||
.arp_response_valid(arp_response_valid),
|
||||
.arp_response_error(arp_response_error),
|
||||
.arp_response_mac(arp_response_mac),
|
||||
// Configuration
|
||||
.local_mac(local_mac),
|
||||
.local_ip(local_ip),
|
||||
.gateway_ip(gateway_ip),
|
||||
.subnet_mask(subnet_mask),
|
||||
.clear_cache(clear_arp_cache)
|
||||
);
|
||||
|
||||
endmodule
|
733
tb/test_ip_complete.py
Executable file
733
tb/test_ip_complete.py
Executable file
@ -0,0 +1,733 @@
|
||||
#!/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
|
||||
|
||||
module = 'ip_complete'
|
||||
|
||||
srcs = []
|
||||
|
||||
srcs.append("../rtl/%s.v" % module)
|
||||
srcs.append("../rtl/ip.v")
|
||||
srcs.append("../rtl/ip_eth_rx.v")
|
||||
srcs.append("../rtl/ip_eth_tx.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_ip_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,
|
||||
|
||||
rx_busy,
|
||||
tx_busy,
|
||||
rx_error_header_early_termination,
|
||||
rx_error_payload_early_termination,
|
||||
rx_error_invalid_header,
|
||||
rx_error_invalid_checksum,
|
||||
tx_error_payload_early_termination,
|
||||
tx_error_arp_failed,
|
||||
|
||||
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,
|
||||
|
||||
rx_busy=rx_busy,
|
||||
tx_busy=tx_busy,
|
||||
rx_error_header_early_termination=rx_error_header_early_termination,
|
||||
rx_error_payload_early_termination=rx_error_payload_early_termination,
|
||||
rx_error_invalid_header=rx_error_invalid_header,
|
||||
rx_error_invalid_checksum=rx_error_invalid_checksum,
|
||||
tx_error_payload_early_termination=tx_error_payload_early_termination,
|
||||
tx_error_arp_failed=tx_error_arp_failed,
|
||||
|
||||
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))
|
||||
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))
|
||||
|
||||
# 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))
|
||||
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))
|
||||
rx_busy = Signal(bool(0))
|
||||
tx_busy = Signal(bool(0))
|
||||
rx_error_header_early_termination = Signal(bool(0))
|
||||
rx_error_payload_early_termination = Signal(bool(0))
|
||||
rx_error_invalid_header = Signal(bool(0))
|
||||
rx_error_invalid_checksum = Signal(bool(0))
|
||||
tx_error_payload_early_termination = Signal(bool(0))
|
||||
tx_error_arp_failed = 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))
|
||||
|
||||
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')
|
||||
|
||||
# DUT
|
||||
dut = dut_ip_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,
|
||||
|
||||
rx_busy,
|
||||
tx_busy,
|
||||
rx_error_header_early_termination,
|
||||
rx_error_payload_early_termination,
|
||||
rx_error_invalid_header,
|
||||
rx_error_invalid_checksum,
|
||||
tx_error_payload_early_termination,
|
||||
tx_error_arp_failed,
|
||||
|
||||
local_mac,
|
||||
local_ip,
|
||||
gateway_ip,
|
||||
subnet_mask,
|
||||
clear_arp_cache)
|
||||
|
||||
@always(delay(4))
|
||||
def clkgen():
|
||||
clk.next = not clk
|
||||
|
||||
rx_error_header_early_termination_asserted = Signal(bool(0))
|
||||
rx_error_payload_early_termination_asserted = Signal(bool(0))
|
||||
rx_error_invalid_header_asserted = Signal(bool(0))
|
||||
rx_error_invalid_checksum_asserted = Signal(bool(0))
|
||||
tx_error_payload_early_termination_asserted = Signal(bool(0))
|
||||
tx_error_arp_failed_asserted = Signal(bool(0))
|
||||
|
||||
@always(clk.posedge)
|
||||
def monitor():
|
||||
if (rx_error_header_early_termination):
|
||||
rx_error_header_early_termination_asserted.next = 1
|
||||
if (rx_error_payload_early_termination):
|
||||
rx_error_payload_early_termination_asserted.next = 1
|
||||
if (rx_error_invalid_header):
|
||||
rx_error_invalid_header_asserted.next = 1
|
||||
if (rx_error_invalid_checksum):
|
||||
rx_error_invalid_checksum_asserted.next = 1
|
||||
if (tx_error_payload_early_termination):
|
||||
tx_error_payload_early_termination_asserted.next = 1
|
||||
if (tx_error_arp_failed):
|
||||
tx_error_arp_failed_asserted.next = 1
|
||||
|
||||
def wait_normal():
|
||||
while (input_eth_payload_tvalid or input_ip_payload_tvalid or
|
||||
output_eth_payload_tvalid or output_ip_payload_tvalid or
|
||||
input_eth_hdr_valid or input_ip_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 = 0x11
|
||||
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 = 0x11
|
||||
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
|
||||
|
||||
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 = 0x11
|
||||
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 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)
|
||||
|
||||
raise StopSimulation
|
||||
|
||||
return dut, eth_source, eth_sink, ip_source, ip_sink, clkgen, monitor, check
|
||||
|
||||
def test_bench():
|
||||
sim = Simulation(bench())
|
||||
sim.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("Running test...")
|
||||
test_bench()
|
||||
|
282
tb/test_ip_complete.v
Normal file
282
tb/test_ip_complete.v
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
|
||||
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_ip_complete;
|
||||
|
||||
// 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 output_eth_hdr_ready = 0;
|
||||
reg output_eth_payload_tready = 0;
|
||||
reg output_ip_hdr_ready = 0;
|
||||
reg output_ip_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 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 rx_busy;
|
||||
wire tx_busy;
|
||||
wire rx_error_header_early_termination;
|
||||
wire rx_error_payload_early_termination;
|
||||
wire rx_error_invalid_header;
|
||||
wire rx_error_invalid_checksum;
|
||||
wire tx_error_payload_early_termination;
|
||||
wire tx_error_arp_failed;
|
||||
|
||||
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,
|
||||
output_eth_hdr_ready,
|
||||
output_eth_payload_tready,
|
||||
output_ip_hdr_ready,
|
||||
output_ip_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,
|
||||
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,
|
||||
rx_busy,
|
||||
tx_busy,
|
||||
rx_error_header_early_termination,
|
||||
rx_error_payload_early_termination,
|
||||
rx_error_invalid_header,
|
||||
rx_error_invalid_checksum,
|
||||
tx_error_payload_early_termination,
|
||||
tx_error_arp_failed);
|
||||
|
||||
// dump file
|
||||
$dumpfile("test_ip_complete.lxt");
|
||||
$dumpvars(0, test_ip_complete);
|
||||
end
|
||||
|
||||
ip_complete #(
|
||||
.ARP_CACHE_ADDR_WIDTH(2),
|
||||
.ARP_REQUEST_RETRY_COUNT(4),
|
||||
.ARP_REQUEST_RETRY_INTERVAL(150),
|
||||
.ARP_REQUEST_TIMEOUT(400)
|
||||
)
|
||||
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),
|
||||
// Status signals
|
||||
.rx_busy(rx_busy),
|
||||
.tx_busy(tx_busy),
|
||||
.rx_error_header_early_termination(rx_error_header_early_termination),
|
||||
.rx_error_payload_early_termination(rx_error_payload_early_termination),
|
||||
.rx_error_invalid_header(rx_error_invalid_header),
|
||||
.rx_error_invalid_checksum(rx_error_invalid_checksum),
|
||||
.tx_error_payload_early_termination(tx_error_payload_early_termination),
|
||||
.tx_error_arp_failed(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)
|
||||
);
|
||||
|
||||
endmodule
|
753
tb/test_ip_complete_64.py
Executable file
753
tb/test_ip_complete_64.py
Executable file
@ -0,0 +1,753 @@
|
||||
#!/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
|
||||
|
||||
module = 'ip_complete_64'
|
||||
|
||||
srcs = []
|
||||
|
||||
srcs.append("../rtl/%s.v" % module)
|
||||
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/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_ip_complete_64(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,
|
||||
|
||||
rx_busy,
|
||||
tx_busy,
|
||||
rx_error_header_early_termination,
|
||||
rx_error_payload_early_termination,
|
||||
rx_error_invalid_header,
|
||||
rx_error_invalid_checksum,
|
||||
tx_error_payload_early_termination,
|
||||
tx_error_arp_failed,
|
||||
|
||||
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,
|
||||
|
||||
rx_busy=rx_busy,
|
||||
tx_busy=tx_busy,
|
||||
rx_error_header_early_termination=rx_error_header_early_termination,
|
||||
rx_error_payload_early_termination=rx_error_payload_early_termination,
|
||||
rx_error_invalid_header=rx_error_invalid_header,
|
||||
rx_error_invalid_checksum=rx_error_invalid_checksum,
|
||||
tx_error_payload_early_termination=tx_error_payload_early_termination,
|
||||
tx_error_arp_failed=tx_error_arp_failed,
|
||||
|
||||
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))
|
||||
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))
|
||||
|
||||
# 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))
|
||||
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))
|
||||
rx_busy = Signal(bool(0))
|
||||
tx_busy = Signal(bool(0))
|
||||
rx_error_header_early_termination = Signal(bool(0))
|
||||
rx_error_payload_early_termination = Signal(bool(0))
|
||||
rx_error_invalid_header = Signal(bool(0))
|
||||
rx_error_invalid_checksum = Signal(bool(0))
|
||||
tx_error_payload_early_termination = Signal(bool(0))
|
||||
tx_error_arp_failed = 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))
|
||||
|
||||
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')
|
||||
|
||||
# DUT
|
||||
dut = dut_ip_complete_64(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,
|
||||
|
||||
rx_busy,
|
||||
tx_busy,
|
||||
rx_error_header_early_termination,
|
||||
rx_error_payload_early_termination,
|
||||
rx_error_invalid_header,
|
||||
rx_error_invalid_checksum,
|
||||
tx_error_payload_early_termination,
|
||||
tx_error_arp_failed,
|
||||
|
||||
local_mac,
|
||||
local_ip,
|
||||
gateway_ip,
|
||||
subnet_mask,
|
||||
clear_arp_cache)
|
||||
|
||||
@always(delay(4))
|
||||
def clkgen():
|
||||
clk.next = not clk
|
||||
|
||||
rx_error_header_early_termination_asserted = Signal(bool(0))
|
||||
rx_error_payload_early_termination_asserted = Signal(bool(0))
|
||||
rx_error_invalid_header_asserted = Signal(bool(0))
|
||||
rx_error_invalid_checksum_asserted = Signal(bool(0))
|
||||
tx_error_payload_early_termination_asserted = Signal(bool(0))
|
||||
tx_error_arp_failed_asserted = Signal(bool(0))
|
||||
|
||||
@always(clk.posedge)
|
||||
def monitor():
|
||||
if (rx_error_header_early_termination):
|
||||
rx_error_header_early_termination_asserted.next = 1
|
||||
if (rx_error_payload_early_termination):
|
||||
rx_error_payload_early_termination_asserted.next = 1
|
||||
if (rx_error_invalid_header):
|
||||
rx_error_invalid_header_asserted.next = 1
|
||||
if (rx_error_invalid_checksum):
|
||||
rx_error_invalid_checksum_asserted.next = 1
|
||||
if (tx_error_payload_early_termination):
|
||||
tx_error_payload_early_termination_asserted.next = 1
|
||||
if (tx_error_arp_failed):
|
||||
tx_error_arp_failed_asserted.next = 1
|
||||
|
||||
def wait_normal():
|
||||
while (input_eth_payload_tvalid or input_ip_payload_tvalid or
|
||||
output_eth_payload_tvalid or output_ip_payload_tvalid or
|
||||
input_eth_hdr_valid or input_ip_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 = 0x11
|
||||
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 = 0x11
|
||||
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
|
||||
|
||||
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 = 0x11
|
||||
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 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)
|
||||
|
||||
raise StopSimulation
|
||||
|
||||
return dut, eth_source, eth_sink, ip_source, ip_sink, clkgen, monitor, check
|
||||
|
||||
def test_bench():
|
||||
sim = Simulation(bench())
|
||||
sim.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("Running test...")
|
||||
test_bench()
|
||||
|
294
tb/test_ip_complete_64.v
Normal file
294
tb/test_ip_complete_64.v
Normal file
@ -0,0 +1,294 @@
|
||||
/*
|
||||
|
||||
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_ip_complete_64;
|
||||
|
||||
// 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 output_eth_hdr_ready = 0;
|
||||
reg output_eth_payload_tready = 0;
|
||||
reg output_ip_hdr_ready = 0;
|
||||
reg output_ip_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 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 rx_busy;
|
||||
wire tx_busy;
|
||||
wire rx_error_header_early_termination;
|
||||
wire rx_error_payload_early_termination;
|
||||
wire rx_error_invalid_header;
|
||||
wire rx_error_invalid_checksum;
|
||||
wire tx_error_payload_early_termination;
|
||||
wire tx_error_arp_failed;
|
||||
|
||||
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,
|
||||
output_eth_hdr_ready,
|
||||
output_eth_payload_tready,
|
||||
output_ip_hdr_ready,
|
||||
output_ip_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,
|
||||
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,
|
||||
rx_busy,
|
||||
tx_busy,
|
||||
rx_error_header_early_termination,
|
||||
rx_error_payload_early_termination,
|
||||
rx_error_invalid_header,
|
||||
rx_error_invalid_checksum,
|
||||
tx_error_payload_early_termination,
|
||||
tx_error_arp_failed);
|
||||
|
||||
// dump file
|
||||
$dumpfile("test_ip_complete_64.lxt");
|
||||
$dumpvars(0, test_ip_complete_64);
|
||||
end
|
||||
|
||||
ip_complete_64 #(
|
||||
.ARP_CACHE_ADDR_WIDTH(2),
|
||||
.ARP_REQUEST_RETRY_COUNT(4),
|
||||
.ARP_REQUEST_RETRY_INTERVAL(150),
|
||||
.ARP_REQUEST_TIMEOUT(400)
|
||||
)
|
||||
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),
|
||||
// Status signals
|
||||
.rx_busy(rx_busy),
|
||||
.tx_busy(tx_busy),
|
||||
.rx_error_header_early_termination(rx_error_header_early_termination),
|
||||
.rx_error_payload_early_termination(rx_error_payload_early_termination),
|
||||
.rx_error_invalid_header(rx_error_invalid_header),
|
||||
.rx_error_invalid_checksum(rx_error_invalid_checksum),
|
||||
.tx_error_payload_early_termination(tx_error_payload_early_termination),
|
||||
.tx_error_arp_failed(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)
|
||||
);
|
||||
|
||||
endmodule
|
Loading…
x
Reference in New Issue
Block a user