Coder Social home page Coder Social logo

verilog-ethernet's People

Contributors

alexforencich avatar lomotos10 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

verilog-ethernet's Issues

porting to a ZCU102 and ZCU111?

Hello,

I am curious how to make the 10 GbE core work on the ZCU102 and ZCU111.

The ZCU111 have these extra signals:

SFP_TX_FAULT
SFP_TX_DISABLE J
SFP_MOD_DETECT
SFP_RS0
SFP_RS1
SFP_LOS

While the ZCU102 only has:

SFP0_TX_P
SFP0_TX_N
SFP0_RX_P
SFP0_RX_N
SFP0_TX_DISABLE(1)

While you have these signals on the VCU118 example:
qsfp2_modsell
qsfp2_resetl
qsfp2_modprsl
qsfp2_intl
qsfp2_lpmode

Question is do I need the extra VCU118 and ZCU111 signals? Also, it looks like you are using 2 10 GbE on the VCU118 is that correct? Sorry I am trying to port this into those two boards and I don't have a VCU118 in hand. Also, can I use a 1000Base-T with this? Thanks.

respond to ARP through direct connection but doesn't respond through the LAN Switch

Hi.
I added your GMII & UDP stack like the KC705 example.

when I connecting the Ethernet cable from the FPGA to the PC, there is not a lot of traffic, {~1packet / 1sec on average},
I make ARP broadcast from my computer and the FPGA responding correctly and I can see the FPGA on the LAN (arp -a).

On the other hand, when I connect the FPGA to my LAN switch, {~20packets / 1sec on average}, and the PC also connected to this switch, once again I broadcast ARP requests through the LAN, I can see this request on the LAN using Wireshark, but the FPGA not responding to it.

Any idea why that might happen? Does the FPGA miss this request because of a heavy load of traffic on the cable? seems unreasonable, any idea what going on?
Edit:
I tried in the direct connection where is not a lot of traffic to send a fast stream of UDP packets.. and seems like the FPGA catch them all so the explanation of too much traffic on the cable seems more unreasonable now.

Edit2:
------------------------------

Edit3:
In both cases, I can see the transmit path logic ticking. When it is connected to the LAN and not responding to ARP request as I described my problem, in the FPGA logic I can see the MAC trying to respond:

sent_not_good

and it even seems like a good response because I compared it to the working case (connected directly from FPGA to PC with USB adapter {Ethernet->USB-C} in between):
sent_good

seems like the only difference is the different MAC Address between the cases (when connected through Switch the MAC it's trying to respond to is my PC MAC Address and in the working case it's responding to the adapter MAC Address.

Thanks!
(btw my solution to this issue: #47 was to pass the input clock in Lattice PLL and output 125MHz clock... I think it's a good enough solution for now no?)

Typo in eth_gth_phy_quad.v line 233

Discrepancy (likely typo) between Coregen IP instantiate in eth_gth_phy_quad.v line 233 in example/HXT100G/fpga/rtl/.

Component name as per .xco is ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper, while the substantiation refers to ten_gig_eth_pcs_pma_v2_6_v6gth_wrapper_QUAD.

Change instantiation to match .xco as a solution?

Problems trying to combine GMII MAC Module with Xilinx PCS/PMA IP

Hello Alex, thanks for this amazing repository.

I'm having some troubles trying to connect your modules with the PCS/PMA IP. I started from the VCU108 example (which is also using the IP but with a LVDS transceiver) and made some changes. I'm using a device specific transceiver for 1G 1000BASE-X, so I changed the IP accordingly. I also changed to the eth_mac_1g_gmii_fifo module in the fpga_core file. I'm pretty sure that the PCS/PMA IP is well configured by checking at the last bit in the pcs_pma_status_vector. However, I cannot receive any packets from the FPGA.

fpga_core
pcs_pma
eth_mac_gmii

I am not sure what I'm doing wrong.

UDP invalid payload length

It seems that the UDP payload length is miss handeled.

If I have short frame, the udp_payload contains the padding.

To fix that, i change the following line into the file udp_ip_rx.v, from:

word_count_next = m_udp_length_reg - 16'd8;

to

word_count_next = m_udp_length_reg;

make error at Cygwin64

Hello,

I am trying to build an example project, but I found it to make an error.
My setup is Vivado 2018.2 and any comment to make a bitstream file?

kha@kha-PC /cygdrive/c/home/test/verilog-ethernet/example/Arty/fpga
$ make
cd fpga && make
make[1]: Entering directory '/cygdrive/c/home/test/verilog-ethernet/example/Arty/fpga/fpga'
rm -rf defines.v
touch defines.v
for x in ; do echo '`define' $x >> defines.v; done
echo "create_project -force -part xc7a35t-csg324-1 fpga" > create_project.tcl
echo "add_files -fileset sources_1 defines.v" >> create_project.tcl
for x in  ../rtl/fpga.v  ../rtl/fpga_core.v  ../rtl/debounce_switch.v  ../rtl/sync_signal.v  ../lib/eth/rtl/ssio_sdr_in.v  ../lib/eth/rtl/mii_phy_if.v  ../lib/eth/rtl/eth_mac_mii_fifo.v  ../lib/eth/rtl/eth_mac_mii.v  ../lib/eth/rtl/eth_mac_1g.v  ../lib/eth/rtl/axis_gmii_rx.v  ../lib/eth/rtl/axis_gmii_tx.v  ../lib/eth/rtl/lfsr.v  ../lib/eth/rtl/eth_axis_rx.v  ../lib/eth/rtl/eth_axis_tx.v  ../lib/eth/rtl/udp_complete.v  ../lib/eth/rtl/udp_checksum_gen.v  ../lib/eth/rtl/udp.v  ../lib/eth/rtl/udp_ip_rx.v  ../lib/eth/rtl/udp_ip_tx.v  ../lib/eth/rtl/ip_complete.v  ../lib/eth/rtl/ip.v  ../lib/eth/rtl/ip_eth_rx.v  ../lib/eth/rtl/ip_eth_tx.v  ../lib/eth/rtl/ip_arb_mux.v  ../lib/eth/rtl/arp.v  ../lib/eth/rtl/arp_cache.v  ../lib/eth/rtl/arp_eth_rx.v  ../lib/eth/rtl/arp_eth_tx.v  ../lib/eth/rtl/eth_arb_mux.v  ../lib/eth/lib/axis/rtl/arbiter.v  ../lib/eth/lib/axis/rtl/priority_encoder.v  ../lib/eth/lib/axis/rtl/axis_fifo.v  ../lib/eth/lib/axis/rtl/axis_async_fifo.v  ../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v  ../lib/eth/lib/axis/rtl/sync_reset.v; do echo "add_files -fileset sources_1 $x" >> create_project.tcl; done
for x in  ../fpga.xdc  ../lib/eth/syn/mii_phy_if.tcl  ../lib/eth/syn/eth_mac_fifo.tcl  ../lib/eth/lib/axis/syn/axis_async_fifo.tcl  ../lib/eth/lib/axis/syn/sync_reset.tcl; do echo "add_files -fileset constrs_1 $x" >> create_project.tcl; done
for x in ; do echo "import_ip $x" >> create_project.tcl; done
for x in ; do echo "source $x" >> create_project.tcl; done
echo "exit" >> create_project.tcl
vivado -nojournal -nolog -mode batch -source create_project.tcl

****** Vivado v2018.2.2 (64-bit)
  **** SW Build 2348494 on Mon Oct  1 18:25:44 MDT 2018
  **** IP Build 2318053 on Mon Oct  1 21:44:26 MDT 2018
    ** Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.

source create_project.tcl
# create_project -force -part xc7a35t-csg324-1 fpga
# add_files -fileset sources_1 defines.v
# add_files -fileset sources_1 ../rtl/fpga.v
# add_files -fileset sources_1 ../rtl/fpga_core.v
# add_files -fileset sources_1 ../rtl/debounce_switch.v
# add_files -fileset sources_1 ../rtl/sync_signal.v
# add_files -fileset sources_1 ../lib/eth/rtl/ssio_sdr_in.v
ERROR: [Vivado 12-172] File or Directory '../lib/eth/rtl/ssio_sdr_in.v' does not exist
INFO: [Common 17-206] Exiting Vivado at Sat Aug 15 01:00:50 2020...
make[1]: *** [../common/vivado.mk:91: fpga.xpr] Error 1
make[1]: Leaving directory '/cygdrive/c/

eth_mac_mii_fifo module not fully working for me

Hello. First of all, thanks for this great ethernet IP.

I'm trying to use this ethernet mac & UDP/IP stack for my project, my board is Lattice ECP3 Versa, Marvel 88E1111 PHY.
I took the Arty example as a reference for implementing the ethernet MII & UDP/IP interface to my FPGA.

I did as in the example and instantiated fpga_core module like this:

ethernet_core ethernet_inst (
    .clk		 (phy_clk125),
    .rst		 (rst),
	.led		 (led),
 
    .phy_rx_clk	 (phy_rx_clk),
    .phy_rxd	 (phy_rxd[3:0]),
    .phy_rx_dv	 (phy_rx_dv),
    .phy_rx_er	 (phy_rx_er),
    .phy_tx_clk	 (phy_tx_clk),
    .phy_txd	 (phy_txd[3:0]),
    .phy_tx_en	 (phy_tx_en),
    .phy_col	 (phy_col),
    .phy_crs	 (phy_crs),
    .phy_rst_n   (phy_rst_n)
);

I just made a few changes that don't make any difference like delete the UART signals & Switches I don't use.
In the example, you created the 125MHz clock from Xilinx PLL, in my case I used the Marvel PHY 125MHz clock,
from Marvel 88E1111 PHY datasheet:
image

Next, inside the fpga_core, where the eth_mac_mii_fifo module instantiated I make sure that the TARGET parameters is "GENERIC":

eth_mac_mii_fifo #(
    .TARGET("GENERIC"),
    .CLOCK_INPUT_STYLE("BUFR"),
    .ENABLE_PADDING(1),
    .MIN_FRAME_LENGTH(64),
    .TX_FIFO_DEPTH(4096),
    .TX_FRAME_FIFO(1),
    .RX_FIFO_DEPTH(4096),
    .RX_FRAME_FIFO(1)
)
eth_mac_inst (
    .rst(rst),
    .logic_clk(clk),
    .logic_rst(rst),

    .tx_axis_tdata(tx_axis_tdata),
    .tx_axis_tvalid(tx_axis_tvalid),
    .tx_axis_tready(tx_axis_tready),
    .tx_axis_tlast(tx_axis_tlast),
    .tx_axis_tuser(tx_axis_tuser),

    .rx_axis_tdata(rx_axis_tdata),
    .rx_axis_tvalid(rx_axis_tvalid),
    .rx_axis_tready(rx_axis_tready),
    .rx_axis_tlast(rx_axis_tlast),
    .rx_axis_tuser(rx_axis_tuser),

    .mii_rx_clk(phy_rx_clk),
    .mii_rxd(phy_rxd),
    .mii_rx_dv(phy_rx_dv),
    .mii_rx_er(phy_rx_er),
    .mii_tx_clk(phy_tx_clk),
    .mii_txd(phy_txd),
    .mii_tx_en(phy_tx_en),
    .mii_tx_er(),

    .tx_fifo_overflow(),
    .tx_fifo_bad_frame(),
    .tx_fifo_good_frame(),
    .rx_error_bad_frame(),
    .rx_error_bad_fcs(),
    .rx_fifo_overflow(),
    .rx_fifo_bad_frame(),
    .rx_fifo_good_frame(),

    .ifg_delay(12)
);
configured the following mac / IP address:
// Configuration
wire [47:0] local_mac   = 48'h00_01_02_03_04_05;
wire [31:0] local_ip    = {8'd192, 8'd168, 8'd33,  8'd69};
wire [31:0] gateway_ip  = {8'd192, 8'd168, 8'd33,  8'd1};
wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0};
...
..
.
wire match_cond = rx_udp_dest_port == 1234;

Everything else Is the same as in the example and rtl files.

In my computer I connected an ethernet cable from my PC straight to the FPGA, the ethernet cable configured as following:
image

  • I created a bit file and programmed my device.

  • run analyzer to debug the code
    image
    ...
    image

the data the FPGA catch from RJ-45 is exactly the same data that can be seen in Wireshark traffic:
image
image

  • great my FPGA catching all the ethernet packets and make some process in the mac interface to present them as bytes.

  • keep moving on with the ethernet packet, that data goes to the module: axis_async_fifo_adapter and stuck there:
    image

it tries to write the data into the FIFO, and even the address counter is counting as it should, but all the other counters in this block (axis_async_fifo) don't move, and the empty flag stays high.
I can't get anything in the output of the FIFO and therefore the data just stuck there and never come out of the mii block and doesnt come in the udp_complete block (because there is no output from eth_mac_mii_fifo module).
I tries also make ARP request and on the FPGA i catch this data coming, but same as always got stuck in the FIFO.

why does it happening? any Idea?
Thanks! Michael.

top level logic:

module top (
    // board clock&reset / leds&switches
    input               clk_board,      // 100MHz versa board clock    	
    input               reset_n,        // rst neg - push button       
    output	[7:0]  		led,            // led array                                           
    output  		    dp,             // 7-seg screen led                               
    input 	[7:0]    	sw,             // switches                                

    // Ethernet: 100BASE-T MII   
    input               phy_tx_clk,                                                                                    
    output [7:0]        phy_txd,                                                                                   
    output              phy_tx_en,                                 
                                                                              
    input               phy_rx_clk,                                                       
    input  [7:0]        phy_rxd,       
    input               phy_rx_dv,                
    input               phy_rx_er,  
	
    input               phy_col,                                                                                 
    input               phy_crs,  
    output              phy_mdc,                                                                       
    inout               phy_mdio,                                      
	
	input               phy_clk125,
    output              phy_rst_n
	);

// ------- rst_n & rst -------- //	
wire rst, rst_n;
reg [7:0] count; 
assign rst_n = (count > 8'b1111_1010) ? 1'b1 : 1'b0;
assign rst = !rst_n;
		
always @(posedge clk_100 or negedge reset_n) begin
	if (~reset_n)
		count = 8'b0000_0000;
	else if (count < 8'b1111_1101)
		count = count + 1;
end	

// --- logic clock heart beat --- //
reg [23:0] heartbeat_cntr;
assign dp = heartbeat_cntr[23];

always @ (posedge phy_clk125 or negedge rst_n) begin
	if (~rst_n)
		heartbeat_cntr <= 24'h00_0000;
	else
		heartbeat_cntr <= heartbeat_cntr + 1;
end


ethernet_core ethernet_inst (
    .clk		 (phy_clk125),
    .rst		 (rst),
	.led		 (led),
 
    .phy_rx_clk	 (phy_rx_clk),
    .phy_rxd	 (phy_rxd[3:0]),
    .phy_rx_dv	 (phy_rx_dv),
    .phy_rx_er	 (phy_rx_er),
    .phy_tx_clk	 (phy_tx_clk),
    .phy_txd	 (phy_txd[3:0]),
    .phy_tx_en	 (phy_tx_en),
    .phy_col	 (phy_col),
    .phy_crs	 (phy_crs),
    .phy_rst_n   (phy_rst_n)
);

assign phy_txd[7:4] = 4'b0;
assign phy_mdc		= 1'b0;
assign phy_mdio		= 1'b0;

endmodule

ethernet core top after little changes:

module ethernet_core (
    input  wire       clk,
    input  wire       rst,
    output wire [7:0] led,

    input  wire       phy_rx_clk,
    input  wire [3:0] phy_rxd,
    input  wire       phy_rx_dv,
    input  wire       phy_rx_er,
    input  wire       phy_tx_clk,
    output wire [3:0] phy_txd,
    output wire       phy_tx_en,
    input  wire       phy_col,
    input  wire       phy_crs,
    output wire       phy_rst_n
);

// AXI between MAC and Ethernet modules
wire [7:0] rx_axis_tdata;
wire rx_axis_tvalid;
wire rx_axis_tready;
wire rx_axis_tlast;
wire rx_axis_tuser;

wire [7:0] tx_axis_tdata;
wire tx_axis_tvalid;
wire tx_axis_tready;
wire tx_axis_tlast;
wire tx_axis_tuser;

// Ethernet frame between Ethernet modules and UDP stack
wire rx_eth_hdr_ready;
wire rx_eth_hdr_valid;
wire [47:0] rx_eth_dest_mac;
wire [47:0] rx_eth_src_mac;
wire [15:0] rx_eth_type;
wire [7:0] rx_eth_payload_axis_tdata;
wire rx_eth_payload_axis_tvalid;
wire rx_eth_payload_axis_tready;
wire rx_eth_payload_axis_tlast;
wire rx_eth_payload_axis_tuser;

wire tx_eth_hdr_ready;
wire tx_eth_hdr_valid;
wire [47:0] tx_eth_dest_mac;
wire [47:0] tx_eth_src_mac;
wire [15:0] tx_eth_type;
wire [7:0] tx_eth_payload_axis_tdata;
wire tx_eth_payload_axis_tvalid;
wire tx_eth_payload_axis_tready;
wire tx_eth_payload_axis_tlast;
wire tx_eth_payload_axis_tuser;

// IP frame connections
wire rx_ip_hdr_valid;
wire rx_ip_hdr_ready;
wire [47:0] rx_ip_eth_dest_mac;
wire [47:0] rx_ip_eth_src_mac;
wire [15:0] rx_ip_eth_type;
wire [3:0] rx_ip_version;
wire [3:0] rx_ip_ihl;
wire [5:0] rx_ip_dscp;
wire [1:0] rx_ip_ecn;
wire [15:0] rx_ip_length;
wire [15:0] rx_ip_identification;
wire [2:0] rx_ip_flags;
wire [12:0] rx_ip_fragment_offset;
wire [7:0] rx_ip_ttl;
wire [7:0] rx_ip_protocol;
wire [15:0] rx_ip_header_checksum;
wire [31:0] rx_ip_source_ip;
wire [31:0] rx_ip_dest_ip;
wire [7:0] rx_ip_payload_axis_tdata;
wire rx_ip_payload_axis_tvalid;
wire rx_ip_payload_axis_tready;
wire rx_ip_payload_axis_tlast;
wire rx_ip_payload_axis_tuser;

wire tx_ip_hdr_valid;
wire tx_ip_hdr_ready;
wire [5:0] tx_ip_dscp;
wire [1:0] tx_ip_ecn;
wire [15:0] tx_ip_length;
wire [7:0] tx_ip_ttl;
wire [7:0] tx_ip_protocol;
wire [31:0] tx_ip_source_ip;
wire [31:0] tx_ip_dest_ip;
wire [7:0] tx_ip_payload_axis_tdata;
wire tx_ip_payload_axis_tvalid;
wire tx_ip_payload_axis_tready;
wire tx_ip_payload_axis_tlast;
wire tx_ip_payload_axis_tuser;

// UDP frame connections
wire rx_udp_hdr_valid;
wire rx_udp_hdr_ready;
wire [47:0] rx_udp_eth_dest_mac;
wire [47:0] rx_udp_eth_src_mac;
wire [15:0] rx_udp_eth_type;
wire [3:0] rx_udp_ip_version;
wire [3:0] rx_udp_ip_ihl;
wire [5:0] rx_udp_ip_dscp;
wire [1:0] rx_udp_ip_ecn;
wire [15:0] rx_udp_ip_length;
wire [15:0] rx_udp_ip_identification;
wire [2:0] rx_udp_ip_flags;
wire [12:0] rx_udp_ip_fragment_offset;
wire [7:0] rx_udp_ip_ttl;
wire [7:0] rx_udp_ip_protocol;
wire [15:0] rx_udp_ip_header_checksum;
wire [31:0] rx_udp_ip_source_ip;
wire [31:0] rx_udp_ip_dest_ip;
wire [15:0] rx_udp_source_port;
wire [15:0] rx_udp_dest_port;
wire [15:0] rx_udp_length;
wire [15:0] rx_udp_checksum;
wire [7:0] rx_udp_payload_axis_tdata;
wire rx_udp_payload_axis_tvalid;
wire rx_udp_payload_axis_tready;
wire rx_udp_payload_axis_tlast;
wire rx_udp_payload_axis_tuser;

wire tx_udp_hdr_valid;
wire tx_udp_hdr_ready;
wire [5:0] tx_udp_ip_dscp;
wire [1:0] tx_udp_ip_ecn;
wire [7:0] tx_udp_ip_ttl;
wire [31:0] tx_udp_ip_source_ip;
wire [31:0] tx_udp_ip_dest_ip;
wire [15:0] tx_udp_source_port;
wire [15:0] tx_udp_dest_port;
wire [15:0] tx_udp_length;
wire [15:0] tx_udp_checksum;
wire [7:0] tx_udp_payload_axis_tdata;
wire tx_udp_payload_axis_tvalid;
wire tx_udp_payload_axis_tready;
wire tx_udp_payload_axis_tlast;
wire tx_udp_payload_axis_tuser;

wire [7:0] rx_fifo_udp_payload_axis_tdata;
wire rx_fifo_udp_payload_axis_tvalid;
wire rx_fifo_udp_payload_axis_tready;
wire rx_fifo_udp_payload_axis_tlast;
wire rx_fifo_udp_payload_axis_tuser;

wire [7:0] tx_fifo_udp_payload_axis_tdata;
wire tx_fifo_udp_payload_axis_tvalid;
wire tx_fifo_udp_payload_axis_tready;
wire tx_fifo_udp_payload_axis_tlast;
wire tx_fifo_udp_payload_axis_tuser;

// Configuration
wire [47:0] local_mac   = 48'h00_01_02_03_04_05;
wire [31:0] local_ip    = {8'd192, 8'd168, 8'd33,  8'd69};
wire [31:0] gateway_ip  = {8'd192, 8'd168, 8'd33,  8'd1};
wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0};

// IP ports not used
assign rx_ip_hdr_ready = 1;
assign rx_ip_payload_axis_tready = 1;

assign tx_ip_hdr_valid = 0;
assign tx_ip_dscp = 0;
assign tx_ip_ecn = 0;
assign tx_ip_length = 0;
assign tx_ip_ttl = 0;
assign tx_ip_protocol = 0;
assign tx_ip_source_ip = 0;
assign tx_ip_dest_ip = 0;
assign tx_ip_payload_axis_tdata = 0;
assign tx_ip_payload_axis_tvalid = 0;
assign tx_ip_payload_axis_tlast = 0;
assign tx_ip_payload_axis_tuser = 0;

// Loop back UDP
wire match_cond = rx_udp_dest_port == 1234;
wire no_match = !match_cond;

reg match_cond_reg = 0;
reg no_match_reg = 0;

always @(posedge clk) begin
    if (rst) begin
        match_cond_reg <= 0;
        no_match_reg <= 0;
    end else begin
        if (rx_udp_payload_axis_tvalid) begin
            if ((!match_cond_reg && !no_match_reg) ||
                (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin
                match_cond_reg <= match_cond;
                no_match_reg <= no_match;
            end
        end else begin
            match_cond_reg <= 0;
            no_match_reg <= 0;
        end
    end
end

assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond;
assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match;
assign tx_udp_ip_dscp = 0;
assign tx_udp_ip_ecn = 0;
assign tx_udp_ip_ttl = 64;
assign tx_udp_ip_source_ip = local_ip;
assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip;
assign tx_udp_source_port = rx_udp_dest_port;
assign tx_udp_dest_port = rx_udp_source_port;
assign tx_udp_length = rx_udp_length;
assign tx_udp_checksum = 0;

assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata;
assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid;
assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready;
assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast;
assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser;

assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata;
assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg;
assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg;
assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast;
assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser;

// Place first payload byte onto LEDs
reg valid_last = 0;
reg [7:0] led_reg = 0;

always @(posedge clk) begin
    if (rst) begin
        led_reg <= 0;
    end else begin
        if (tx_udp_payload_axis_tvalid) begin
            if (!valid_last) begin
                led_reg <= tx_udp_payload_axis_tdata;
                valid_last <= 1'b1;
            end
            if (tx_udp_payload_axis_tlast) begin
                valid_last <= 1'b0;
            end
        end
    end
end


assign led = led_reg;
assign phy_rst_n = !rst;


eth_mac_mii_fifo #(
    .TARGET("GENERIC"),
    .CLOCK_INPUT_STYLE("BUFR"),
    .ENABLE_PADDING(1),
    .MIN_FRAME_LENGTH(64),
    .TX_FIFO_DEPTH(4096),
    .TX_FRAME_FIFO(1),
    .RX_FIFO_DEPTH(4096),
    .RX_FRAME_FIFO(1)
)
eth_mac_inst (
    .rst(rst),
    .logic_clk(clk),
    .logic_rst(rst),

    .tx_axis_tdata(tx_axis_tdata),
    .tx_axis_tvalid(tx_axis_tvalid),
    .tx_axis_tready(tx_axis_tready),
    .tx_axis_tlast(tx_axis_tlast),
    .tx_axis_tuser(tx_axis_tuser),

    .rx_axis_tdata(rx_axis_tdata),
    .rx_axis_tvalid(rx_axis_tvalid),
    .rx_axis_tready(rx_axis_tready),
    .rx_axis_tlast(rx_axis_tlast),
    .rx_axis_tuser(rx_axis_tuser),

    .mii_rx_clk(phy_rx_clk),
    .mii_rxd(phy_rxd),
    .mii_rx_dv(phy_rx_dv),
    .mii_rx_er(phy_rx_er),
    .mii_tx_clk(phy_tx_clk),
    .mii_txd(phy_txd),
    .mii_tx_en(phy_tx_en),
    .mii_tx_er(),

    .tx_fifo_overflow(),
    .tx_fifo_bad_frame(),
    .tx_fifo_good_frame(),
    .rx_error_bad_frame(),
    .rx_error_bad_fcs(),
    .rx_fifo_overflow(),
    .rx_fifo_bad_frame(),
    .rx_fifo_good_frame(),

    .ifg_delay(12)
);

eth_axis_rx
eth_axis_rx_inst (
    .clk(clk),
    .rst(rst),
    // AXI input
    .s_axis_tdata(rx_axis_tdata),
    .s_axis_tvalid(rx_axis_tvalid),
    .s_axis_tready(rx_axis_tready),
    .s_axis_tlast(rx_axis_tlast),
    .s_axis_tuser(rx_axis_tuser),
    // Ethernet frame output
    .m_eth_hdr_valid(rx_eth_hdr_valid),
    .m_eth_hdr_ready(rx_eth_hdr_ready),
    .m_eth_dest_mac(rx_eth_dest_mac),
    .m_eth_src_mac(rx_eth_src_mac),
    .m_eth_type(rx_eth_type),
    .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
    .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
    .m_eth_payload_axis_tready(rx_eth_payload_axis_tready),
    .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
    .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
    // Status signals
    .busy(),
    .error_header_early_termination()
);

eth_axis_tx
eth_axis_tx_inst (
    .clk(clk),
    .rst(rst),
    // Ethernet frame input
    .s_eth_hdr_valid(tx_eth_hdr_valid),
    .s_eth_hdr_ready(tx_eth_hdr_ready),
    .s_eth_dest_mac(tx_eth_dest_mac),
    .s_eth_src_mac(tx_eth_src_mac),
    .s_eth_type(tx_eth_type),
    .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
    .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
    .s_eth_payload_axis_tready(tx_eth_payload_axis_tready),
    .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
    .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
    // AXI output
    .m_axis_tdata(tx_axis_tdata),
    .m_axis_tvalid(tx_axis_tvalid),
    .m_axis_tready(tx_axis_tready),
    .m_axis_tlast(tx_axis_tlast),
    .m_axis_tuser(tx_axis_tuser),
    // Status signals
    .busy()
);

udp_complete
udp_complete_inst (
    .clk(clk),
    .rst(rst),
    // Ethernet frame input
    .s_eth_hdr_valid(rx_eth_hdr_valid),
    .s_eth_hdr_ready(rx_eth_hdr_ready),
    .s_eth_dest_mac(rx_eth_dest_mac),
    .s_eth_src_mac(rx_eth_src_mac),
    .s_eth_type(rx_eth_type),
    .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
    .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
    .s_eth_payload_axis_tready(rx_eth_payload_axis_tready),
    .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
    .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
    // Ethernet frame output
    .m_eth_hdr_valid(tx_eth_hdr_valid),
    .m_eth_hdr_ready(tx_eth_hdr_ready),
    .m_eth_dest_mac(tx_eth_dest_mac),
    .m_eth_src_mac(tx_eth_src_mac),
    .m_eth_type(tx_eth_type),
    .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
    .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
    .m_eth_payload_axis_tready(tx_eth_payload_axis_tready),
    .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
    .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
    // IP frame input
    .s_ip_hdr_valid(tx_ip_hdr_valid),
    .s_ip_hdr_ready(tx_ip_hdr_ready),
    .s_ip_dscp(tx_ip_dscp),
    .s_ip_ecn(tx_ip_ecn),
    .s_ip_length(tx_ip_length),
    .s_ip_ttl(tx_ip_ttl),
    .s_ip_protocol(tx_ip_protocol),
    .s_ip_source_ip(tx_ip_source_ip),
    .s_ip_dest_ip(tx_ip_dest_ip),
    .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata),
    .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid),
    .s_ip_payload_axis_tready(tx_ip_payload_axis_tready),
    .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast),
    .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser),
    // IP frame output
    .m_ip_hdr_valid(rx_ip_hdr_valid),
    .m_ip_hdr_ready(rx_ip_hdr_ready),
    .m_ip_eth_dest_mac(rx_ip_eth_dest_mac),
    .m_ip_eth_src_mac(rx_ip_eth_src_mac),
    .m_ip_eth_type(rx_ip_eth_type),
    .m_ip_version(rx_ip_version),
    .m_ip_ihl(rx_ip_ihl),
    .m_ip_dscp(rx_ip_dscp),
    .m_ip_ecn(rx_ip_ecn),
    .m_ip_length(rx_ip_length),
    .m_ip_identification(rx_ip_identification),
    .m_ip_flags(rx_ip_flags),
    .m_ip_fragment_offset(rx_ip_fragment_offset),
    .m_ip_ttl(rx_ip_ttl),
    .m_ip_protocol(rx_ip_protocol),
    .m_ip_header_checksum(rx_ip_header_checksum),
    .m_ip_source_ip(rx_ip_source_ip),
    .m_ip_dest_ip(rx_ip_dest_ip),
    .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata),
    .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid),
    .m_ip_payload_axis_tready(rx_ip_payload_axis_tready),
    .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast),
    .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser),
    // UDP frame input
    .s_udp_hdr_valid(tx_udp_hdr_valid),
    .s_udp_hdr_ready(tx_udp_hdr_ready),
    .s_udp_ip_dscp(tx_udp_ip_dscp),
    .s_udp_ip_ecn(tx_udp_ip_ecn),
    .s_udp_ip_ttl(tx_udp_ip_ttl),
    .s_udp_ip_source_ip(tx_udp_ip_source_ip),
    .s_udp_ip_dest_ip(tx_udp_ip_dest_ip),
    .s_udp_source_port(tx_udp_source_port),
    .s_udp_dest_port(tx_udp_dest_port),
    .s_udp_length(tx_udp_length),
    .s_udp_checksum(tx_udp_checksum),
    .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata),
    .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid),
    .s_udp_payload_axis_tready(tx_udp_payload_axis_tready),
    .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast),
    .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser),
    // UDP frame output
    .m_udp_hdr_valid(rx_udp_hdr_valid),
    .m_udp_hdr_ready(rx_udp_hdr_ready),
    .m_udp_eth_dest_mac(rx_udp_eth_dest_mac),
    .m_udp_eth_src_mac(rx_udp_eth_src_mac),
    .m_udp_eth_type(rx_udp_eth_type),
    .m_udp_ip_version(rx_udp_ip_version),
    .m_udp_ip_ihl(rx_udp_ip_ihl),
    .m_udp_ip_dscp(rx_udp_ip_dscp),
    .m_udp_ip_ecn(rx_udp_ip_ecn),
    .m_udp_ip_length(rx_udp_ip_length),
    .m_udp_ip_identification(rx_udp_ip_identification),
    .m_udp_ip_flags(rx_udp_ip_flags),
    .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset),
    .m_udp_ip_ttl(rx_udp_ip_ttl),
    .m_udp_ip_protocol(rx_udp_ip_protocol),
    .m_udp_ip_header_checksum(rx_udp_ip_header_checksum),
    .m_udp_ip_source_ip(rx_udp_ip_source_ip),
    .m_udp_ip_dest_ip(rx_udp_ip_dest_ip),
    .m_udp_source_port(rx_udp_source_port),
    .m_udp_dest_port(rx_udp_dest_port),
    .m_udp_length(rx_udp_length),
    .m_udp_checksum(rx_udp_checksum),
    .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata),
    .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid),
    .m_udp_payload_axis_tready(rx_udp_payload_axis_tready),
    .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast),
    .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser),
    // Status signals
    .ip_rx_busy(),
    .ip_tx_busy(),
    .udp_rx_busy(),
    .udp_tx_busy(),
    .ip_rx_error_header_early_termination(),
    .ip_rx_error_payload_early_termination(),
    .ip_rx_error_invalid_header(),
    .ip_rx_error_invalid_checksum(),
    .ip_tx_error_payload_early_termination(),
    .ip_tx_error_arp_failed(),
    .udp_rx_error_header_early_termination(),
    .udp_rx_error_payload_early_termination(),
    .udp_tx_error_payload_early_termination(),
    // Configuration
    .local_mac(local_mac),
    .local_ip(local_ip),
    .gateway_ip(gateway_ip),
    .subnet_mask(subnet_mask),
    .clear_arp_cache(0)
);

axis_fifo #(
    .DEPTH(8192),
    .DATA_WIDTH(8),
    .KEEP_ENABLE(0),
    .ID_ENABLE(0),
    .DEST_ENABLE(0),
    .USER_ENABLE(1),
    .USER_WIDTH(1),
    .FRAME_FIFO(0)
)
udp_payload_fifo (
    .clk(clk),
    .rst(rst),

    // AXI input
    .s_axis_tdata(rx_fifo_udp_payload_axis_tdata),
    .s_axis_tkeep(0),
    .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid),
    .s_axis_tready(rx_fifo_udp_payload_axis_tready),
    .s_axis_tlast(rx_fifo_udp_payload_axis_tlast),
    .s_axis_tid(0),
    .s_axis_tdest(0),
    .s_axis_tuser(rx_fifo_udp_payload_axis_tuser),

    // AXI output
    .m_axis_tdata(tx_fifo_udp_payload_axis_tdata),
    .m_axis_tkeep(),
    .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid),
    .m_axis_tready(tx_fifo_udp_payload_axis_tready),
    .m_axis_tlast(tx_fifo_udp_payload_axis_tlast),
    .m_axis_tid(),
    .m_axis_tdest(),
    .m_axis_tuser(tx_fifo_udp_payload_axis_tuser),

    // Status
    .status_overflow(),
    .status_bad_frame(),
    .status_good_frame()
);

endmodule
	

Using 10GbE UDP for ZC706 board

Hi Alex,

Thank you for putting together this project. I'm interested in porting it over to the Xilinx ZC706 board. Are there issues you see with doing this? Anything I should watch out for?

Sorry if this is not the best way to reach you, I wasn't sure how else to message a user now that private messaging is gone from GitHub.

Bypass Xilinx PCS?

for your 10G ethernet solution, do you implement your own PCS layer in the fabric, and bypass the PCS that is built-in to the Xilinx transceiver macro?

Block Diagram

Thank you so much for a great library.

I'm wondering if there already exists a block diagram for udp_complete or ip_complete. With all the muxing going on it can be hard to follow all the connections to understand what's going on.

Thanks in advance.

Is there any example for UDP stack + DHCP?

udp_complete.v works ok. Big thanks for nice udp stack implementation.

Also, it would be great to have DHCP support in order to obtain IP address automatically from the router. Is there any example? Thanks

support 40G

Hello, may I ask you a question? 40g is composed of four 10g channels. Referring to 802.3, we know that each channel adopts 64b / 66b coding standard. The axis stream output from Xilinx's MAC / PHY IP core is 256 bit wide. Where is the data merging of the four channels completed? Is it at the interface between the physical layer and the MAC layer

udp_complete for tx only

Thanks for this IP!

However, I have a small issue. I'm trying to figure out exactly what signals are needed to produce just a single UDP TX packet, but I can't seem to produce anything else than ARP packets. I'm trying to use the test_udp_complete.py as a guide. I noticed that if I commented out all other test cases but testcase5(UDP TX), the test failed. It only works if I uncomment testcase2(IP TX). When testcase2 is commented out, it seems that I'm only creating an ARP packet (type= 0x0806) and not IPv4 (type = 0x0800). Another hint for what I'm doing wrong might be that udp_tx_busy goes high, and stays high forever.

What exactly is it that happens in testcase 2 that is required to create a UDP TX packet in testcase5?

Any help is greatly appreciated!

AU50 and AU280 build error

Hello,

I am trying to build AU50& AU280 and found build error.

INFO: [IP_Flow 19-2313] Loaded Vivado IP repository '/opt/Xilinx/Vivado/2019.1/data/ip'.
WARNING: [IP_Flow 19-3664] IP 'gtwizard_ultrascale_0' generated file not found '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga/fpga.srcs/sources_1/ip/gtwizard_ultrascale_0/gtwizard_ultrascale_0.dcp'. Please regenerate to continue.
WARNING: [IP_Flow 19-3664] IP 'gtwizard_ultrascale_0' generated file not found '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga/fpga.srcs/sources_1/ip/gtwizard_ultrascale_0/gtwizard_ultrascale_0_stub.v'. Please regenerate to continue.
WARNING: [IP_Flow 19-3664] IP 'gtwizard_ultrascale_0' generated file not found '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga/fpga.srcs/sources_1/ip/gtwizard_ultrascale_0/gtwizard_ultrascale_0_stub.vhdl'. Please regenerate to continue.
WARNING: [IP_Flow 19-3664] IP 'gtwizard_ultrascale_0' generated file not found '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga/fpga.srcs/sources_1/ip/gtwizard_ultrascale_0/gtwizard_ultrascale_0_sim_netlist.v'. Please regenerate to continue.
WARNING: [IP_Flow 19-3664] IP 'gtwizard_ultrascale_0' generated file not found '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga/fpga.srcs/sources_1/ip/gtwizard_ultrascale_0/gtwizard_ultrascale_0_sim_netlist.vhdl'. Please regenerate to continue.
# reset_run synth_1
# launch_runs synth_1
ERROR: [Common 17-70] Application Exception: Failed to launch run 'synth_1' due to failures in the following run(s):
gtwizard_ultrascale_0_synth_1
These failed run(s) need to be reset prior to launching 'synth_1' again.

INFO: [Common 17-206] Exiting Vivado at Fri Sep  4 19:46:42 2020...
../common/vivado.mk:95: recipe for target 'fpga.runs/synth_1/%.dcp' failed
make[1]: *** [fpga.runs/synth_1/%.dcp] Error 1
make[1]: Leaving directory '/home/kha/fpga/verilog-ethernet/example/AU50/fpga_10g/fpga'
Makefile:14: recipe for target 'fpga' failed
make: *** [fpga] Error 2

PC Ethernet connection settings

I used KC705 Ethernet code to implement Ethernet on my custom Artix board. I remove button and uart interface of code, because i haven't them on my board.
I used ila to see output of phy_rxd when running on the board.

After programming and running, I set Ethernet cable with below code: (eth0 is board connection)
ifconfig enp7s0 192.168.1.128 netmask 255.255.255.0
and set configuration of ethernet connection to Automatic(DHCP)

but when i echo something through below terminal command:
netcat -u 192.168.1.128 1234
nothing coming on phy_rxd .

Is something wrong with my setting?

gig_ethernet_pcs_pma_0 IP on board VCU108 (1g example)

Hi Alex,
First of all, want to thank you for such an amazing project. I am new to FPGA development and currently using Vivado 2019.2 version with VCU108 board. I am trying the 1g example.

1st Attempt : Linux env. -->
I followed your instruction to the word and found the following issue
"WARNING: [Vivado 12-4802] The synthesis checkpoint for IP '../gig_ethernet_pcs_pma_0.xci' is not generated and IP is locked. An out-of-context (OOC) run will be created and/or launched, but synthesis may not be able to complete or could result in incorrect behavior."
I believe the IP is upgraded (found in the IP catalog) and not synthesizing correctly. This caused implementation to fail.

Question--> How can I upgrade the IP in makefile. Is there a way I can do it? I tried other forums, couldn't find it.

2nd Attempt : Windows env. -->
I manually pulled every code for the experiment, IP, .xdc constraints, .tcl constraints. Upgraded the IP to the newer version present in IP catalog (GUI has option to upgrade IP). This completed synthesis, implementation, generated bit-stream and programmed the device. But didn't see the result as expected in netcat. No returned characters after pressing enter.

Question --> Is there some files or process that I might be missing in windows env.?

eth_crc_8.v missing

There are many references to module eth_crc_8 (..64), but I can't find the corresponding source files in the repository? Did you remove them?

VCU118 25G ...payload_axis_tdata[] width

In example/VCU118/fpga_25g the rates (156.25 MHz) and widths (64 bits) of rx_udp_payload_axis_tdata and tx_udp_payload_axis_tdata appear to be sized for 10G and not 25G. I do see the GTY line rate is higher in the *.xci file.

AXI config example

Hi,
do you have an example where the AXIS module "axis_registers.v" or AXI modules "axi_register_wd/rd.v" are used for configuring the ETH MAC?

thanks in advance
BR

axis_xgmii_tx_32 state_reg not big enough

https://github.com/alexforencich/verilog-ethernet/blob/e9949f57a934071bf7da30445b88808e7fdd7124/rtl/axis_xgmii_tx_32.v

The state variables (such as STATE_WAIT_END) use 4 bits but the state variable state_reg uses 3.

localparam [3:0]
    STATE_IDLE = 4'd0,
    STATE_PREAMBLE = 4'd1,
    STATE_PAYLOAD = 4'd2,
    STATE_PAD = 4'd3,
    STATE_FCS_1 = 4'd4,
    STATE_FCS_2 = 4'd5,
    STATE_FCS_3 = 4'd6,
    STATE_IFG = 4'd7,
    STATE_WAIT_END = 4'd8;

reg [2:0] state_reg = STATE_IDLE, state_next;

so when in the code we have

state_next = STATE_WAIT_END

It's probably going to go to overflow and go to STATE_IDLE.

Problem with sythesizing - VCU108 - fpga_1g

Hi,

I am trying to implement the 1g version on the VCU108 evaluation board. I manually added all the files to the project as I am using Windows machine.

I added the files as per the make file which has links to all the files needed for fpga-1g version. ( Folder ..../fpga-1g/fpga)

When i try to synthesize i get the error saying that the get_property should have atleast one object and is referring to both the tcl scripts eth_mac_fifo and axis_async_fifo.

It looks the hardware is not being generated only. I am not sure about the problem. I am I missing anything. I am using Vivado version 2019.2

When I disable both the tcl scripts I am sucessfully able to generate the bit file but it doesn't work. The IP 192.168.1.128 is reachable but nothing is being echoed back.

Can you please help me understand what can be the issue.

Thanks,

Ramu

DE2115 TXD

Hi,

I'm running the ethernet code provided for DE2-115. I'm able to see data from AXI input, AXI output signals and rgmii_rxd till eth_mac_1g_rgmii_fifo.v but not rgmii_txd. Also ENET0_RX_DATA, ENET0_RX_DV but not ENET0_TX_DATA, ENET0_TX_EN. I cannot add signals from "oddr" to Signal Tap Logic Analyzer in Quartus. Can you help me out in finding the issue. TIA

axis_eth_fcs modules example

is there any example where your "axis_eth_fcs.v" / "axis_eth_fcs_check.v" modules are used?
or a description where and how to use them?

currently if I use the "axis_eth_fcs_check.v" module within the "eth_mac_1g_rgmii", the loopback isn't working simultaneously

thanks in advance,
BR

missing parts for PTP and 1g example design with PTP source

First of all thank you for your excellent work regarding the verilog ethernet and axi repos.
I am currently trying to understand and activate your PTP components and i am uncertain because i read in a different issue that PTP is not necessarily 100% complete. What's here exactly missing? And is there an example where PTP is activated and PTP source clock is connected?

I already found the three parameters in the eth_mac_phy_10g_fifo file to activate PTP for 10G design, it synthesize and generate+connect all PTP related components.
Is it possible to copy it simple to the 1G design with the 10G design as "template"? Or is it necessary to pay attention at some stages?
Thanks

Minor nits. Default state in mdio state case

Running the VCU118 10G example design with Vivado and linter. One nits highlighted is the case statement implementing the mdio command FSM engine starting at 1043 in fpga.v. That case statement end with:

            4'd12: begin
                // done
                state_reg <= 4'd12;
            end
        endcase

Which of course ensure that it stops when done. But since the state space is incomplete the toots gets annoyed. How abot simply adding a

default:
state_reg <= 4d0;

eth_mac_1g_fifo rx bad bcs interrupt is not assigned correctly

Line 169 of eth_mac_1g_fifo shows that the rx_error_bad_frame_int is assigned to both bits of the rx_sync_reg_1 register. I believe that bit 1 of the register should be assigned to rx_error_bad_fcs_int instead. This is also the case in the eth_mac_1g_rgmii_fifo module.

First byte of Ethernet preamble being replaced by XGMII start byte

Looking at test_axis_xgmii_rx_64.py, and testing axis_xgmii_rx_64.v it seems that current behavior ignores the first 8 XGMII bytes (including the start byte 0xFB). However, I'd expect it to ignore the first 9 XGMII bytes (including the start byte 0xFB) since the ethernet preamble + start of frame delimiter is 8 bytes.
Additionally, in xgmii_ep.py (which is used to test the XGMII Rx) the first byte is replaced by the XGMII start byte. That is, one of the preamble 0x55 bytes isn't sent through the XGMII.

dl[0] = XGMII_START
cl[0] = 1

I added a print out for d and c in xgmii_ep.py when running test_axis_xgmii_rx_64.py and got what's below. You can see 0x55 is only repeated 6 times instead of 7.

d is d5555555555555fb
c is 1

Vivado block diagram, recursive priority encoder

I successfully built the example project for my board with Vivado, but now I need to integrate it with the rest of my system (Microblaze). Just like this issue here Vivado is complaining about the recursive definition of the priority encoder when trying to import the modules into the block diagram. From what I understand about this question I only need the eth_mac_1g_rgmii_fifo and the udp_complete (and the TCL files, I just copied all the ones used in the example project). So potentially I could just rewrite the module myself? I know back in Feb there was talk of doing so. Doesn't seem like it would be too terribly difficult, but I doubt my abilities when it comes to high speed stuff.

ENABLE_PADDING(0) leads to failure

I tested example based on ATLYS/fpga code. It works, but it add zero padding to the end of udp packet. I don't need it.

In order to disable unwanted padding, I set ENABLE_PADDING(0) for eth_mac_1g_gmii_fifo. Unfortunately it leads to complete fail. Loopback example don't works with ENABLE_PADDING(0) and stops to receive payload from incoming udp packets (first byte of the udp payload is not passed to the led display).

Please fix it.

RX_DROP_BAD_FRAME in eth_mac_1g_fifo.v

RX_DROP_BAD_FRAME in eth_mac_1g_fifo.v is not used.

rx_fifo parameters in eth_mac_1g_fifo.v are assigned TX_FRAME_FIFO, TX_DROP_BAD_FRAME and TX_DROP_WHEN_FULL. I think they should be replaced with RX_... parameters. It looks like copy-paste error.

Unable to connect MII Ethernet interface with 1G/100M/10M switch

Hi, first of all, thanks for this great ethernet interface.
I added the MII interface as shown in the Arty example to my FPGA (I'm using Lattice ECP3 Dev Board with Marvel PHY 88e1111).
Although my PHY/Cables and Switches support 1G (GMII) I prefer to work with MII because some of my equipment doesn't support 1G.

The ethernet interface is working when I connect the FPGA through a switch that supports 10/100 only.
If I connect the FPGA through a switch that supports 10/100/1G I getting 8bit of packets to my FPGA (I connected all the 8bits to the FPGA so I can see what happens although I need to use only the 4 LSB in the MII interface), and the MII interface doesn't do anything with this data (I anyway connecting 4LSB to the ethernet core).

Case 1: 10/100 Switch -> MII Interface
image
image
as can be seen in this case the FPGA receives only 4bits and the MAC successfully processing this data.

--

Case 2: 10/100/1G Switch -> MII Interface
image
image
as can be seen in this case the FPGA receives 8bits and the MAC doesn't do anything with the data.


My question is how I can adjust the MII ethernet interface to work with 10/100/1G switches and cables?
the interface doesn't need to notify the LAN about that he can receive only 10/100 data packets?
I have to implement a 3-state mac interface or there is a way using the mii interface with a 3-state switch?


top level code:

module top (
    // board clock&reset / leds&switches
    input               clk_board,      // 100MHz versa board clock    	
    input               reset_n,        // rst neg - push button       
    output	[7:0]  		led,            // led array                                           
    output  		    dp,             // 7-seg screen led                               
    input 	[7:0]    	sw,             // switches                                

    // Ethernet: 100BASE-T MII   
    input               phy_tx_clk,                                                                                    
    output [7:0]        phy_txd,                                                                                   
    output              phy_tx_en,                                 
                                                                              
    input               phy_rx_clk,                                                       
    input  [7:0]        phy_rxd,       
    input               phy_rx_dv,                
    input               phy_rx_er,  
	
    input               phy_col,                                                                                 
    input               phy_crs,  
    output              phy_mdc,                                                                       
    inout               phy_mdio,                                      
	
	input               phy_clk125,
    output              phy_rst_n
	);

// ------- rst_n & rst -------- //	
wire rst, rst_n;
reg [7:0] count; 
assign rst_n = (count > 8'b1111_1010) ? 1'b1 : 1'b0;
assign rst = !rst_n;
		
always @(posedge clk_100 or negedge reset_n) begin
	if (~reset_n)
		count = 8'b0000_0000;
	else if (count < 8'b1111_1101)
		count = count + 1;
end	


CLKDIVB clkdiv (
	.CLKI(clk_board), 
	.RST(1'b0), 
	.RELEASE(1'b1), 
	.CDIV1(clk_100), 
	.CDIV2(), 
	.CDIV4(clk_25), 
	.CDIV8()
);
	

// --- logic clock heart beat --- //
reg [23:0] heartbeat_cntr;
assign dp = heartbeat_cntr[23];

always @ (posedge phy_clk125 or negedge rst_n) begin
	if (~rst_n)
		heartbeat_cntr <= 24'h00_0000;
	else
		heartbeat_cntr <= heartbeat_cntr + 1;
end


ethernet_core ethernet_inst (
    .clk		 (phy_clk125),
    .rst		 (rst),
	.led		 (led),
 
    .phy_rx_clk	 (phy_rx_clk),
    .phy_rxd	 (phy_rxd[3:0]),
    .phy_rx_dv	 (phy_rx_dv),
    .phy_rx_er	 (phy_rx_er),
    .phy_tx_clk	 (phy_tx_clk),
    .phy_txd	 (phy_txd[3:0]),
    .phy_tx_en	 (phy_tx_en),
    .phy_col	 (phy_col),
    .phy_crs	 (phy_crs),
    .phy_rst_n   (phy_rst_n)
);

assign phy_txd[7:4] = 4'b0;
assign phy_mdc		= 1'b0;
assign phy_mdio		= 1'b0;


endmodule
	

ethernet core code:

module ethernet_core (
    input  wire       clk,
    input  wire       rst,
    output wire [7:0] led,

    input  wire       phy_rx_clk,
    input  wire [3:0] phy_rxd,
    input  wire       phy_rx_dv,
    input  wire       phy_rx_er,
    input  wire       phy_tx_clk,
    output wire [3:0] phy_txd,
    output wire       phy_tx_en,
    input  wire       phy_col,
    input  wire       phy_crs,
    output wire       phy_rst_n
);

// AXI between MAC and Ethernet modules
wire [7:0] rx_axis_tdata;
wire rx_axis_tvalid;
wire rx_axis_tready;
wire rx_axis_tlast;
wire rx_axis_tuser;

wire [7:0] tx_axis_tdata;
wire tx_axis_tvalid;
wire tx_axis_tready;
wire tx_axis_tlast;
wire tx_axis_tuser;

// Ethernet frame between Ethernet modules and UDP stack
wire rx_eth_hdr_ready;
wire rx_eth_hdr_valid;
wire [47:0] rx_eth_dest_mac;
wire [47:0] rx_eth_src_mac;
wire [15:0] rx_eth_type;
wire [7:0] rx_eth_payload_axis_tdata;
wire rx_eth_payload_axis_tvalid;
wire rx_eth_payload_axis_tready;
wire rx_eth_payload_axis_tlast;
wire rx_eth_payload_axis_tuser;

wire tx_eth_hdr_ready;
wire tx_eth_hdr_valid;
wire [47:0] tx_eth_dest_mac;
wire [47:0] tx_eth_src_mac;
wire [15:0] tx_eth_type;
wire [7:0] tx_eth_payload_axis_tdata;
wire tx_eth_payload_axis_tvalid;
wire tx_eth_payload_axis_tready;
wire tx_eth_payload_axis_tlast;
wire tx_eth_payload_axis_tuser;

// IP frame connections
wire rx_ip_hdr_valid;
wire rx_ip_hdr_ready;
wire [47:0] rx_ip_eth_dest_mac;
wire [47:0] rx_ip_eth_src_mac;
wire [15:0] rx_ip_eth_type;
wire [3:0] rx_ip_version;
wire [3:0] rx_ip_ihl;
wire [5:0] rx_ip_dscp;
wire [1:0] rx_ip_ecn;
wire [15:0] rx_ip_length;
wire [15:0] rx_ip_identification;
wire [2:0] rx_ip_flags;
wire [12:0] rx_ip_fragment_offset;
wire [7:0] rx_ip_ttl;
wire [7:0] rx_ip_protocol;
wire [15:0] rx_ip_header_checksum;
wire [31:0] rx_ip_source_ip;
wire [31:0] rx_ip_dest_ip;
wire [7:0] rx_ip_payload_axis_tdata;
wire rx_ip_payload_axis_tvalid;
wire rx_ip_payload_axis_tready;
wire rx_ip_payload_axis_tlast;
wire rx_ip_payload_axis_tuser;

wire tx_ip_hdr_valid;
wire tx_ip_hdr_ready;
wire [5:0] tx_ip_dscp;
wire [1:0] tx_ip_ecn;
wire [15:0] tx_ip_length;
wire [7:0] tx_ip_ttl;
wire [7:0] tx_ip_protocol;
wire [31:0] tx_ip_source_ip;
wire [31:0] tx_ip_dest_ip;
wire [7:0] tx_ip_payload_axis_tdata;
wire tx_ip_payload_axis_tvalid;
wire tx_ip_payload_axis_tready;
wire tx_ip_payload_axis_tlast;
wire tx_ip_payload_axis_tuser;

// UDP frame connections
wire rx_udp_hdr_valid;
wire rx_udp_hdr_ready;
wire [47:0] rx_udp_eth_dest_mac;
wire [47:0] rx_udp_eth_src_mac;
wire [15:0] rx_udp_eth_type;
wire [3:0] rx_udp_ip_version;
wire [3:0] rx_udp_ip_ihl;
wire [5:0] rx_udp_ip_dscp;
wire [1:0] rx_udp_ip_ecn;
wire [15:0] rx_udp_ip_length;
wire [15:0] rx_udp_ip_identification;
wire [2:0] rx_udp_ip_flags;
wire [12:0] rx_udp_ip_fragment_offset;
wire [7:0] rx_udp_ip_ttl;
wire [7:0] rx_udp_ip_protocol;
wire [15:0] rx_udp_ip_header_checksum;
wire [31:0] rx_udp_ip_source_ip;
wire [31:0] rx_udp_ip_dest_ip;
wire [15:0] rx_udp_source_port;
wire [15:0] rx_udp_dest_port;
wire [15:0] rx_udp_length;
wire [15:0] rx_udp_checksum;
wire [7:0] rx_udp_payload_axis_tdata;
wire rx_udp_payload_axis_tvalid;
wire rx_udp_payload_axis_tready;
wire rx_udp_payload_axis_tlast;
wire rx_udp_payload_axis_tuser;

wire tx_udp_hdr_valid;
wire tx_udp_hdr_ready;
wire [5:0] tx_udp_ip_dscp;
wire [1:0] tx_udp_ip_ecn;
wire [7:0] tx_udp_ip_ttl;
wire [31:0] tx_udp_ip_source_ip;
wire [31:0] tx_udp_ip_dest_ip;
wire [15:0] tx_udp_source_port;
wire [15:0] tx_udp_dest_port;
wire [15:0] tx_udp_length;
wire [15:0] tx_udp_checksum;
wire [7:0] tx_udp_payload_axis_tdata;
wire tx_udp_payload_axis_tvalid;
wire tx_udp_payload_axis_tready;
wire tx_udp_payload_axis_tlast;
wire tx_udp_payload_axis_tuser;

wire [7:0] rx_fifo_udp_payload_axis_tdata;
wire rx_fifo_udp_payload_axis_tvalid;
wire rx_fifo_udp_payload_axis_tready;
wire rx_fifo_udp_payload_axis_tlast;
wire rx_fifo_udp_payload_axis_tuser;

wire [7:0] tx_fifo_udp_payload_axis_tdata;
wire tx_fifo_udp_payload_axis_tvalid;
wire tx_fifo_udp_payload_axis_tready;
wire tx_fifo_udp_payload_axis_tlast;
wire tx_fifo_udp_payload_axis_tuser;

// Configuration
wire [47:0] local_mac   = 48'h00_01_02_03_04_05;
wire [31:0] local_ip    = {8'd192, 8'd168, 8'd33,  8'd69};
wire [31:0] gateway_ip  = {8'd192, 8'd168, 8'd33,  8'd1};
wire [31:0] subnet_mask = {8'd255, 8'd255, 8'd255, 8'd0};

// IP ports not used
assign rx_ip_hdr_ready = 1;
assign rx_ip_payload_axis_tready = 1;

assign tx_ip_hdr_valid = 0;
assign tx_ip_dscp = 0;
assign tx_ip_ecn = 0;
assign tx_ip_length = 0;
assign tx_ip_ttl = 0;
assign tx_ip_protocol = 0;
assign tx_ip_source_ip = 0;
assign tx_ip_dest_ip = 0;
assign tx_ip_payload_axis_tdata = 0;
assign tx_ip_payload_axis_tvalid = 0;
assign tx_ip_payload_axis_tlast = 0;
assign tx_ip_payload_axis_tuser = 0;

// Loop back UDP
wire match_cond = rx_udp_dest_port == 1234;
wire no_match = !match_cond;

reg match_cond_reg = 0;
reg no_match_reg = 0;

always @(posedge clk) begin
    if (rst) begin
        match_cond_reg <= 0;
        no_match_reg <= 0;
    end else begin
        if (rx_udp_payload_axis_tvalid) begin
            if ((!match_cond_reg && !no_match_reg) ||
                (rx_udp_payload_axis_tvalid && rx_udp_payload_axis_tready && rx_udp_payload_axis_tlast)) begin
                match_cond_reg <= match_cond;
                no_match_reg <= no_match;
            end
        end else begin
            match_cond_reg <= 0;
            no_match_reg <= 0;
        end
    end
end

assign tx_udp_hdr_valid = rx_udp_hdr_valid && match_cond;
assign rx_udp_hdr_ready = (tx_eth_hdr_ready && match_cond) || no_match;
assign tx_udp_ip_dscp = 0;
assign tx_udp_ip_ecn = 0;
assign tx_udp_ip_ttl = 64;
assign tx_udp_ip_source_ip = local_ip;
assign tx_udp_ip_dest_ip = rx_udp_ip_source_ip;
assign tx_udp_source_port = rx_udp_dest_port;
assign tx_udp_dest_port = rx_udp_source_port;
assign tx_udp_length = rx_udp_length;
assign tx_udp_checksum = 0;

assign tx_udp_payload_axis_tdata = tx_fifo_udp_payload_axis_tdata;
assign tx_udp_payload_axis_tvalid = tx_fifo_udp_payload_axis_tvalid;
assign tx_fifo_udp_payload_axis_tready = tx_udp_payload_axis_tready;
assign tx_udp_payload_axis_tlast = tx_fifo_udp_payload_axis_tlast;
assign tx_udp_payload_axis_tuser = tx_fifo_udp_payload_axis_tuser;

assign rx_fifo_udp_payload_axis_tdata = rx_udp_payload_axis_tdata;
assign rx_fifo_udp_payload_axis_tvalid = rx_udp_payload_axis_tvalid && match_cond_reg;
assign rx_udp_payload_axis_tready = (rx_fifo_udp_payload_axis_tready && match_cond_reg) || no_match_reg;
assign rx_fifo_udp_payload_axis_tlast = rx_udp_payload_axis_tlast;
assign rx_fifo_udp_payload_axis_tuser = rx_udp_payload_axis_tuser;

// Place first payload byte onto LEDs
reg valid_last = 0;
reg [7:0] led_reg = 0;

always @(posedge clk) begin
    if (rst) begin
        led_reg <= 0;
    end else begin
        if (tx_udp_payload_axis_tvalid) begin
            if (!valid_last) begin
                led_reg <= tx_udp_payload_axis_tdata;
                valid_last <= 1'b1;
            end
            if (tx_udp_payload_axis_tlast) begin
                valid_last <= 1'b0;
            end
        end
    end
end


assign led = led_reg;
assign phy_rst_n = !rst;


eth_mac_mii_fifo #(
    .TARGET("GENERIC"),
    .CLOCK_INPUT_STYLE("BUFR"),
    .ENABLE_PADDING(1),
    .MIN_FRAME_LENGTH(64),
    .TX_FIFO_DEPTH(4096),
    .TX_FRAME_FIFO(1),
    .RX_FIFO_DEPTH(4096),
    .RX_FRAME_FIFO(1)
)
eth_mac_inst (
    .rst(rst),
    .logic_clk(clk),
    .logic_rst(rst),

    .tx_axis_tdata(tx_axis_tdata),
    .tx_axis_tvalid(tx_axis_tvalid),
    .tx_axis_tready(tx_axis_tready),
    .tx_axis_tlast(tx_axis_tlast),
    .tx_axis_tuser(tx_axis_tuser),

    .rx_axis_tdata(rx_axis_tdata),
    .rx_axis_tvalid(rx_axis_tvalid),
    .rx_axis_tready(rx_axis_tready),
    .rx_axis_tlast(rx_axis_tlast),
    .rx_axis_tuser(rx_axis_tuser),

    .mii_rx_clk(phy_rx_clk),
    .mii_rxd(phy_rxd),
    .mii_rx_dv(phy_rx_dv),
    .mii_rx_er(phy_rx_er),
    .mii_tx_clk(phy_tx_clk),
    .mii_txd(phy_txd),
    .mii_tx_en(phy_tx_en),
    .mii_tx_er(),

    .tx_fifo_overflow(),
    .tx_fifo_bad_frame(),
    .tx_fifo_good_frame(),
    .rx_error_bad_frame(),
    .rx_error_bad_fcs(),
    .rx_fifo_overflow(),
    .rx_fifo_bad_frame(),
    .rx_fifo_good_frame(),

    .ifg_delay(12)
);

eth_axis_rx
eth_axis_rx_inst (
    .clk(clk),
    .rst(rst),
    // AXI input
    .s_axis_tdata(rx_axis_tdata),
    .s_axis_tvalid(rx_axis_tvalid),
    .s_axis_tready(rx_axis_tready),
    .s_axis_tlast(rx_axis_tlast),
    .s_axis_tuser(rx_axis_tuser),
    // Ethernet frame output
    .m_eth_hdr_valid(rx_eth_hdr_valid),
    .m_eth_hdr_ready(rx_eth_hdr_ready),
    .m_eth_dest_mac(rx_eth_dest_mac),
    .m_eth_src_mac(rx_eth_src_mac),
    .m_eth_type(rx_eth_type),
    .m_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
    .m_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
    .m_eth_payload_axis_tready(rx_eth_payload_axis_tready),
    .m_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
    .m_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
    // Status signals
    .busy(),
    .error_header_early_termination()
);

eth_axis_tx
eth_axis_tx_inst (
    .clk(clk),
    .rst(rst),
    // Ethernet frame input
    .s_eth_hdr_valid(tx_eth_hdr_valid),
    .s_eth_hdr_ready(tx_eth_hdr_ready),
    .s_eth_dest_mac(tx_eth_dest_mac),
    .s_eth_src_mac(tx_eth_src_mac),
    .s_eth_type(tx_eth_type),
    .s_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
    .s_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
    .s_eth_payload_axis_tready(tx_eth_payload_axis_tready),
    .s_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
    .s_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
    // AXI output
    .m_axis_tdata(tx_axis_tdata),
    .m_axis_tvalid(tx_axis_tvalid),
    .m_axis_tready(tx_axis_tready),
    .m_axis_tlast(tx_axis_tlast),
    .m_axis_tuser(tx_axis_tuser),
    // Status signals
    .busy()
);

udp_complete
udp_complete_inst (
    .clk(clk),
    .rst(rst),
    // Ethernet frame input
    .s_eth_hdr_valid(rx_eth_hdr_valid),
    .s_eth_hdr_ready(rx_eth_hdr_ready),
    .s_eth_dest_mac(rx_eth_dest_mac),
    .s_eth_src_mac(rx_eth_src_mac),
    .s_eth_type(rx_eth_type),
    .s_eth_payload_axis_tdata(rx_eth_payload_axis_tdata),
    .s_eth_payload_axis_tvalid(rx_eth_payload_axis_tvalid),
    .s_eth_payload_axis_tready(rx_eth_payload_axis_tready),
    .s_eth_payload_axis_tlast(rx_eth_payload_axis_tlast),
    .s_eth_payload_axis_tuser(rx_eth_payload_axis_tuser),
    // Ethernet frame output
    .m_eth_hdr_valid(tx_eth_hdr_valid),
    .m_eth_hdr_ready(tx_eth_hdr_ready),
    .m_eth_dest_mac(tx_eth_dest_mac),
    .m_eth_src_mac(tx_eth_src_mac),
    .m_eth_type(tx_eth_type),
    .m_eth_payload_axis_tdata(tx_eth_payload_axis_tdata),
    .m_eth_payload_axis_tvalid(tx_eth_payload_axis_tvalid),
    .m_eth_payload_axis_tready(tx_eth_payload_axis_tready),
    .m_eth_payload_axis_tlast(tx_eth_payload_axis_tlast),
    .m_eth_payload_axis_tuser(tx_eth_payload_axis_tuser),
    // IP frame input
    .s_ip_hdr_valid(tx_ip_hdr_valid),
    .s_ip_hdr_ready(tx_ip_hdr_ready),
    .s_ip_dscp(tx_ip_dscp),
    .s_ip_ecn(tx_ip_ecn),
    .s_ip_length(tx_ip_length),
    .s_ip_ttl(tx_ip_ttl),
    .s_ip_protocol(tx_ip_protocol),
    .s_ip_source_ip(tx_ip_source_ip),
    .s_ip_dest_ip(tx_ip_dest_ip),
    .s_ip_payload_axis_tdata(tx_ip_payload_axis_tdata),
    .s_ip_payload_axis_tvalid(tx_ip_payload_axis_tvalid),
    .s_ip_payload_axis_tready(tx_ip_payload_axis_tready),
    .s_ip_payload_axis_tlast(tx_ip_payload_axis_tlast),
    .s_ip_payload_axis_tuser(tx_ip_payload_axis_tuser),
    // IP frame output
    .m_ip_hdr_valid(rx_ip_hdr_valid),
    .m_ip_hdr_ready(rx_ip_hdr_ready),
    .m_ip_eth_dest_mac(rx_ip_eth_dest_mac),
    .m_ip_eth_src_mac(rx_ip_eth_src_mac),
    .m_ip_eth_type(rx_ip_eth_type),
    .m_ip_version(rx_ip_version),
    .m_ip_ihl(rx_ip_ihl),
    .m_ip_dscp(rx_ip_dscp),
    .m_ip_ecn(rx_ip_ecn),
    .m_ip_length(rx_ip_length),
    .m_ip_identification(rx_ip_identification),
    .m_ip_flags(rx_ip_flags),
    .m_ip_fragment_offset(rx_ip_fragment_offset),
    .m_ip_ttl(rx_ip_ttl),
    .m_ip_protocol(rx_ip_protocol),
    .m_ip_header_checksum(rx_ip_header_checksum),
    .m_ip_source_ip(rx_ip_source_ip),
    .m_ip_dest_ip(rx_ip_dest_ip),
    .m_ip_payload_axis_tdata(rx_ip_payload_axis_tdata),
    .m_ip_payload_axis_tvalid(rx_ip_payload_axis_tvalid),
    .m_ip_payload_axis_tready(rx_ip_payload_axis_tready),
    .m_ip_payload_axis_tlast(rx_ip_payload_axis_tlast),
    .m_ip_payload_axis_tuser(rx_ip_payload_axis_tuser),
    // UDP frame input
    .s_udp_hdr_valid(tx_udp_hdr_valid),
    .s_udp_hdr_ready(tx_udp_hdr_ready),
    .s_udp_ip_dscp(tx_udp_ip_dscp),
    .s_udp_ip_ecn(tx_udp_ip_ecn),
    .s_udp_ip_ttl(tx_udp_ip_ttl),
    .s_udp_ip_source_ip(tx_udp_ip_source_ip),
    .s_udp_ip_dest_ip(tx_udp_ip_dest_ip),
    .s_udp_source_port(tx_udp_source_port),
    .s_udp_dest_port(tx_udp_dest_port),
    .s_udp_length(tx_udp_length),
    .s_udp_checksum(tx_udp_checksum),
    .s_udp_payload_axis_tdata(tx_udp_payload_axis_tdata),
    .s_udp_payload_axis_tvalid(tx_udp_payload_axis_tvalid),
    .s_udp_payload_axis_tready(tx_udp_payload_axis_tready),
    .s_udp_payload_axis_tlast(tx_udp_payload_axis_tlast),
    .s_udp_payload_axis_tuser(tx_udp_payload_axis_tuser),
    // UDP frame output
    .m_udp_hdr_valid(rx_udp_hdr_valid),
    .m_udp_hdr_ready(rx_udp_hdr_ready),
    .m_udp_eth_dest_mac(rx_udp_eth_dest_mac),
    .m_udp_eth_src_mac(rx_udp_eth_src_mac),
    .m_udp_eth_type(rx_udp_eth_type),
    .m_udp_ip_version(rx_udp_ip_version),
    .m_udp_ip_ihl(rx_udp_ip_ihl),
    .m_udp_ip_dscp(rx_udp_ip_dscp),
    .m_udp_ip_ecn(rx_udp_ip_ecn),
    .m_udp_ip_length(rx_udp_ip_length),
    .m_udp_ip_identification(rx_udp_ip_identification),
    .m_udp_ip_flags(rx_udp_ip_flags),
    .m_udp_ip_fragment_offset(rx_udp_ip_fragment_offset),
    .m_udp_ip_ttl(rx_udp_ip_ttl),
    .m_udp_ip_protocol(rx_udp_ip_protocol),
    .m_udp_ip_header_checksum(rx_udp_ip_header_checksum),
    .m_udp_ip_source_ip(rx_udp_ip_source_ip),
    .m_udp_ip_dest_ip(rx_udp_ip_dest_ip),
    .m_udp_source_port(rx_udp_source_port),
    .m_udp_dest_port(rx_udp_dest_port),
    .m_udp_length(rx_udp_length),
    .m_udp_checksum(rx_udp_checksum),
    .m_udp_payload_axis_tdata(rx_udp_payload_axis_tdata),
    .m_udp_payload_axis_tvalid(rx_udp_payload_axis_tvalid),
    .m_udp_payload_axis_tready(rx_udp_payload_axis_tready),
    .m_udp_payload_axis_tlast(rx_udp_payload_axis_tlast),
    .m_udp_payload_axis_tuser(rx_udp_payload_axis_tuser),
    // Status signals
    .ip_rx_busy(),
    .ip_tx_busy(),
    .udp_rx_busy(),
    .udp_tx_busy(),
    .ip_rx_error_header_early_termination(),
    .ip_rx_error_payload_early_termination(),
    .ip_rx_error_invalid_header(),
    .ip_rx_error_invalid_checksum(),
    .ip_tx_error_payload_early_termination(),
    .ip_tx_error_arp_failed(),
    .udp_rx_error_header_early_termination(),
    .udp_rx_error_payload_early_termination(),
    .udp_tx_error_payload_early_termination(),
    // Configuration
    .local_mac(local_mac),
    .local_ip(local_ip),
    .gateway_ip(gateway_ip),
    .subnet_mask(subnet_mask),
    .clear_arp_cache(0)
);

axis_fifo #(
    .DEPTH(8192),
    .DATA_WIDTH(8),
    .KEEP_ENABLE(0),
    .ID_ENABLE(0),
    .DEST_ENABLE(0),
    .USER_ENABLE(1),
    .USER_WIDTH(1),
    .FRAME_FIFO(0)
)
udp_payload_fifo (
    .clk(clk),
    .rst(rst),

    // AXI input
    .s_axis_tdata(rx_fifo_udp_payload_axis_tdata),
    .s_axis_tkeep(0),
    .s_axis_tvalid(rx_fifo_udp_payload_axis_tvalid),
    .s_axis_tready(rx_fifo_udp_payload_axis_tready),
    .s_axis_tlast(rx_fifo_udp_payload_axis_tlast),
    .s_axis_tid(0),
    .s_axis_tdest(0),
    .s_axis_tuser(rx_fifo_udp_payload_axis_tuser),

    // AXI output
    .m_axis_tdata(tx_fifo_udp_payload_axis_tdata),
    .m_axis_tkeep(),
    .m_axis_tvalid(tx_fifo_udp_payload_axis_tvalid),
    .m_axis_tready(tx_fifo_udp_payload_axis_tready),
    .m_axis_tlast(tx_fifo_udp_payload_axis_tlast),
    .m_axis_tid(),
    .m_axis_tdest(),
    .m_axis_tuser(tx_fifo_udp_payload_axis_tuser),

    // Status
    .status_overflow(),
    .status_bad_frame(),
    .status_good_frame()
);

endmodule

Any documents on how to use UDP stack?

Thanks for sharing this amazing library, this pretty much has everything I need.
I consider myself a beginner in HDL programming, and I find it very hard to use this library.
I need to implement a 1G UDP on zedboard (which has a 1g Ethernet FMC card) and I was trying to mimic the project style you have in your examples folder but I wasn't sure how to compile the project or where to make modifications. Your make files don't seem to be a gcc make.
would you be able to give some advice on how to use this library,

tx parameters

Hi, I'm trying to modify the code. If not for loopback, how can determine values for below parametrs in fpga_core module:

tx_udp_hdr_valid
rx_udp_hdr_ready
tx_udp_length

Recursive call in priority encoder doesn't seem to work in Synplify

In priority_encoder.v, when WIDTH is greater than 2, I believe Synplify throws a warning and doesn't synthesize that section. In the ethernet stack, all of the WIDTHs (eth_arb_mux and ip_arb_mux) are equal to 2 so it didn't have any issues. However when using it standalone (axis_arb_mux), looks like that's causing some problems when WIDTH>2. Vivado seems to work fine. Anyone else seeing this issue?

loopback

How to connect between two ports in a DE2-115 Board. send message from port and receive from another

make build error for VCU118 projects

When I try to run make on any of the VCU118 projects, I get the following error:

make[1]: Entering directory '<path>/verilog-ethernet/example/VCU118/fpga_25g/fpga'
make[1]: *** No rule to make target 'fpga.bit', needed by 'fpga'.  Stop.

I've added the following to my path:
C:\Xilinx\Vivado\2019.2\bin
C:\Xilinx\Vivado\2019.2\bin\unwrapped\win64.o
C:\Xilinx\Vivado\2019.2\scripts

Am I missing something in my path? Thanks!

subnet decision issue

if (((arp_request_ip ^ gateway_ip) & subnet_mask) == 0) begin
                // within subnet, look up IP directly
                // (no bits differ between request IP and gateway IP where subnet mask is set)
      // some logic here
end

Is the expression to decide whether within subnet correct? I am confused.

VCU-118 10G and 25G Ethernet half expected data rate

I may be doing something dreadfully wrong but I'm getting about half the expected data rates for the 10G and 25G QSFP Ethernet examples. (its okay, even half rate is more than enough for my application!)

The example projects appear to use all the QSFP pins on both connectors; is it expecting to flow data through both connectors? (I only have one connected; could this explain me getting half the expected data rate?)

Which NIC did you use for the AU50 example?

AU50 example does not work in my setup.

I think that the reason is my NIC (Intel XL710 for 40GbE QSFP+) and its settings (auto-negotiation).
Which NIC did you use for the AU50 example?
Do you have any suggestions for trouble shooting?

The sample udp loopback respond to other IP

All of the UDP loopback sample have a bug and can respond to an incorrect destination IP.

For example, if I send data to the IP 192.168.1.250:1234 and the packet is received by the card, the card respond.

To fix that, I change the check into the fle fpga.v from

wire match_cond = rx_udp_dest_port == 1234;

to

wire match_cond = (rx_udp_dest_port == 1234 && rx_udp_ip_dest_ip == local_ip);

How to apply your project into ZC706?

Dear author:
First,thanks for your sharing the code,but now i am going apply it on ZC706.Of course i have found some data,then i find that ZC706 can only use the SFP.so i wonder if i can use your code or which part i can use.i am a beginning student,but i want to learn.so can you tell me how to put your code on the ZC706.Thank you very much.

Undriven PTP inputs when instancing 'eth_mac_1g'

First, thank you for sharing your valuable AXIS and Ethernet repositories.
I'm currently using your 'eth_mac_1g' MAC on a VCU118 platform, and noticed that you don't drive the 'tx_ptp_ts' and 'rx_ptp_ts' inputs when you instance this module in 'eth_max_1g_fifo' module.

I noticed this when simulating my design with your MAC and the 'gig_ethernet_pcs_pma'. I'm currently forming my own raw Ethernet frames and sending these directly via the AXIS interface into 'eth_mac_1g' (bypassing all of the UDP/IP/ARP stack modules and also using Xilinx AXIS data FIFO instead of your CDC FIFOs) . For some unknown reason, the PHY on the receive end of this link is reporting CRC errors. I do see that you do compute the CRC and transmit to the 'gig_ethernet_pcs_pma' block via the 'gmii_txd' and 'gmii_tx_en' signals, but for some reason, when the FCS field is examined on the the receive side of the link (via Wireshark), it shows the FCS bits all set to 1's. Not sure if this is related to the undriven PTP inputs (probably not), but I figured I'd let you know about this discrepancy.

Thank you

Use of tkeep in the middle of a packet for ignoring bytes

Hi Alex,

Sorry for all the questions today. I have a small issue with using tkeep with eth_mac_10g_fifo. It seems like tkeep is not really a byte qualifier if it is used somewhere in the stream before tlast. It will only remove the last bytes in the stream.

For instance, this is an input:
image

The bytes that are in the position of the unasserted tkeep will be kept in the resulting xgmii output. However, the last four bytes of the stream are dropped, even though tkeep is asserted for all of them. This issue seems to originate from axis_xgmii_tx_64.v, where non tkeep bytes are really only dropped if they are in the last window.

My question is this: is this intended behavior and do the IP in general require that a complete stream with no gaps are delivered?

Cheers,
Ola

Arty test, can't see loopback message

Hello,

I am trying to test the ARTY board loopback test.
Firstly, ping is not supported?

I use ‘netcat’ command you recommended at README.md.

After connection, I typed 1,2,3…8 number then I can see the LD2,3 ON and LD4,5,6,7 changing the same input number
But only 10 or 11 times working, then it has frozen and needs to hard reset.

Also, I typed string message, but I can’t see the echo string.

Please advise what I missing?

Thanks,

Unconnected clear_cache in arp_cache.v

Hi Alex,

Once again, thanks again for all your hard work. I've started to make out how to use most of your stuff now. However, the clear_cache wire on the arp_cache.v module seems to be unconnected. Any plans for adding some clear functionality in the near future?

Ola

Making of Example Vivado Project

Hi Alex,

Hope you are doing great!

When I trying to make the example Vivado Project under /example/VCU118/fpga_10g, I run into the following error message:

cd fpga && make
make[1] : Entering directory 'xxxx/example/VCU118/fpga_10g/fpga'
make[1] : *** NO rule to maek target 'fpga.bit', need by 'fpga'. Stop.
make[1]: Leaving directory 'xxxx/example/VCU118/fpga_10g/fpga'
Makefile: 14: recipe for target 'fpga' failed
make: *** [fpga] Error 2

I've already added the binary file path of Vivado 2019.1 to PATH.

I think this should be a simple fix. Could you give me a hint on what I might missing in my configuration?

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.