diff --git a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile index 0fcb11d0..8ba83357 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_10g/fpga/Makefile @@ -24,8 +24,8 @@ SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v -SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v -SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete_64.v SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v diff --git a/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v index 8cfd5602..afda622b 100644 --- a/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v +++ b/example/ADM_PCIE_9V3/fpga_10g/rtl/fpga_core.v @@ -422,7 +422,9 @@ eth_mac_10g_fifo_inst ( .ifg_delay(8'd12) ); -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(64) +) eth_axis_rx_inst ( .clk(clk), .rst(rst), @@ -450,7 +452,9 @@ eth_axis_rx_inst ( .error_header_early_termination() ); -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(64) +) eth_axis_tx_inst ( .clk(clk), .rst(rst), diff --git a/example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py b/example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py index d11bc14c..7f0698a0 100755 --- a/example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py +++ b/example/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py @@ -42,8 +42,8 @@ srcs.append("../lib/eth/rtl/eth_mac_10g.v") srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") -srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") diff --git a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile index 0fcb11d0..8ba83357 100644 --- a/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile +++ b/example/ADM_PCIE_9V3/fpga_25g/fpga/Makefile @@ -24,8 +24,8 @@ SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v -SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v -SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete_64.v SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v diff --git a/example/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v b/example/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v index 8cfd5602..afda622b 100644 --- a/example/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v +++ b/example/ADM_PCIE_9V3/fpga_25g/rtl/fpga_core.v @@ -422,7 +422,9 @@ eth_mac_10g_fifo_inst ( .ifg_delay(8'd12) ); -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(64) +) eth_axis_rx_inst ( .clk(clk), .rst(rst), @@ -450,7 +452,9 @@ eth_axis_rx_inst ( .error_header_early_termination() ); -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(64) +) eth_axis_tx_inst ( .clk(clk), .rst(rst), diff --git a/example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py b/example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py index d11bc14c..7f0698a0 100755 --- a/example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py +++ b/example/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py @@ -42,8 +42,8 @@ srcs.append("../lib/eth/rtl/eth_mac_10g.v") srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") -srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") diff --git a/example/DE5-Net/fpga/fpga/Makefile b/example/DE5-Net/fpga/fpga/Makefile index f70df77b..2b9b6e85 100644 --- a/example/DE5-Net/fpga/fpga/Makefile +++ b/example/DE5-Net/fpga/fpga/Makefile @@ -17,8 +17,8 @@ SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/lfsr.v -SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v -SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete_64.v SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v diff --git a/example/DE5-Net/fpga/rtl/fpga_core.v b/example/DE5-Net/fpga/rtl/fpga_core.v index bf4f8a15..1352793b 100644 --- a/example/DE5-Net/fpga/rtl/fpga_core.v +++ b/example/DE5-Net/fpga/rtl/fpga_core.v @@ -373,7 +373,9 @@ eth_mac_10g_fifo_inst ( .ifg_delay(8'd12) ); -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(64) +) eth_axis_rx_inst ( .clk(clk), .rst(rst), @@ -401,7 +403,9 @@ eth_axis_rx_inst ( .error_header_early_termination() ); -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(64) +) eth_axis_tx_inst ( .clk(clk), .rst(rst), diff --git a/example/DE5-Net/fpga/tb/test_fpga_core.py b/example/DE5-Net/fpga/tb/test_fpga_core.py index 6b92d8df..dda16b28 100755 --- a/example/DE5-Net/fpga/tb/test_fpga_core.py +++ b/example/DE5-Net/fpga/tb/test_fpga_core.py @@ -42,8 +42,8 @@ srcs.append("../lib/eth/rtl/eth_mac_10g.v") srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") -srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") diff --git a/example/ExaNIC_X10/fpga/fpga/Makefile b/example/ExaNIC_X10/fpga/fpga/Makefile index e1ba8294..74f15e51 100644 --- a/example/ExaNIC_X10/fpga/fpga/Makefile +++ b/example/ExaNIC_X10/fpga/fpga/Makefile @@ -23,8 +23,8 @@ SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v -SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v -SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete_64.v SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v diff --git a/example/ExaNIC_X10/fpga/rtl/fpga_core.v b/example/ExaNIC_X10/fpga/rtl/fpga_core.v index 6430a982..5aed5b22 100644 --- a/example/ExaNIC_X10/fpga/rtl/fpga_core.v +++ b/example/ExaNIC_X10/fpga/rtl/fpga_core.v @@ -353,7 +353,9 @@ eth_mac_10g_fifo_inst ( .ifg_delay(8'd12) ); -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(64) +) eth_axis_rx_inst ( .clk(clk), .rst(rst), @@ -381,7 +383,9 @@ eth_axis_rx_inst ( .error_header_early_termination() ); -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(64) +) eth_axis_tx_inst ( .clk(clk), .rst(rst), diff --git a/example/ExaNIC_X10/fpga/tb/test_fpga_core.py b/example/ExaNIC_X10/fpga/tb/test_fpga_core.py index f8a6f5c6..e2214336 100755 --- a/example/ExaNIC_X10/fpga/tb/test_fpga_core.py +++ b/example/ExaNIC_X10/fpga/tb/test_fpga_core.py @@ -44,8 +44,6 @@ srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") -srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") -srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") diff --git a/example/ExaNIC_X25/fpga_10g/fpga/Makefile b/example/ExaNIC_X25/fpga_10g/fpga/Makefile index d875d679..8aa8ee67 100644 --- a/example/ExaNIC_X25/fpga_10g/fpga/Makefile +++ b/example/ExaNIC_X25/fpga_10g/fpga/Makefile @@ -23,8 +23,8 @@ SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v -SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v -SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete_64.v SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v diff --git a/example/ExaNIC_X25/fpga_10g/rtl/fpga_core.v b/example/ExaNIC_X25/fpga_10g/rtl/fpga_core.v index 6430a982..5aed5b22 100644 --- a/example/ExaNIC_X25/fpga_10g/rtl/fpga_core.v +++ b/example/ExaNIC_X25/fpga_10g/rtl/fpga_core.v @@ -353,7 +353,9 @@ eth_mac_10g_fifo_inst ( .ifg_delay(8'd12) ); -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(64) +) eth_axis_rx_inst ( .clk(clk), .rst(rst), @@ -381,7 +383,9 @@ eth_axis_rx_inst ( .error_header_early_termination() ); -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(64) +) eth_axis_tx_inst ( .clk(clk), .rst(rst), diff --git a/example/ExaNIC_X25/fpga_10g/tb/test_fpga_core.py b/example/ExaNIC_X25/fpga_10g/tb/test_fpga_core.py index f8a6f5c6..e2214336 100755 --- a/example/ExaNIC_X25/fpga_10g/tb/test_fpga_core.py +++ b/example/ExaNIC_X25/fpga_10g/tb/test_fpga_core.py @@ -44,8 +44,6 @@ srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") -srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") -srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") diff --git a/example/HXT100G/fpga/fpga/Makefile b/example/HXT100G/fpga/fpga/Makefile index 83bb94ae..26e707d2 100644 --- a/example/HXT100G/fpga/fpga/Makefile +++ b/example/HXT100G/fpga/fpga/Makefile @@ -22,8 +22,8 @@ SYN_FILES += lib/eth/rtl/eth_mac_10g.v SYN_FILES += lib/eth/rtl/axis_xgmii_rx_64.v SYN_FILES += lib/eth/rtl/axis_xgmii_tx_64.v SYN_FILES += lib/eth/rtl/lfsr.v -SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v -SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete_64.v SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v diff --git a/example/HXT100G/fpga/rtl/fpga_core.v b/example/HXT100G/fpga/rtl/fpga_core.v index 4de50e0a..09d2c171 100644 --- a/example/HXT100G/fpga/rtl/fpga_core.v +++ b/example/HXT100G/fpga/rtl/fpga_core.v @@ -517,7 +517,9 @@ eth_mac_10g_fifo_inst ( .ifg_delay(8'd12) ); -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(64) +) eth_axis_rx_inst ( .clk(clk), .rst(rst), @@ -545,7 +547,9 @@ eth_axis_rx_inst ( .error_header_early_termination() ); -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(64) +) eth_axis_tx_inst ( .clk(clk), .rst(rst), diff --git a/example/HXT100G/fpga/tb/test_fpga_core.py b/example/HXT100G/fpga/tb/test_fpga_core.py index 64b403d5..3ca870e0 100755 --- a/example/HXT100G/fpga/tb/test_fpga_core.py +++ b/example/HXT100G/fpga/tb/test_fpga_core.py @@ -42,8 +42,8 @@ srcs.append("../lib/eth/rtl/eth_mac_10g.v") srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") -srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") diff --git a/example/VCU108/fpga_10g/fpga/Makefile b/example/VCU108/fpga_10g/fpga/Makefile index 2d3b5378..c74d63e3 100644 --- a/example/VCU108/fpga_10g/fpga/Makefile +++ b/example/VCU108/fpga_10g/fpga/Makefile @@ -28,8 +28,8 @@ SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v -SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v -SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete_64.v SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v diff --git a/example/VCU108/fpga_10g/rtl/fpga_core.v b/example/VCU108/fpga_10g/rtl/fpga_core.v index f01760ae..fdf63d8f 100644 --- a/example/VCU108/fpga_10g/rtl/fpga_core.v +++ b/example/VCU108/fpga_10g/rtl/fpga_core.v @@ -630,7 +630,9 @@ axis_switch_inst ( .m_axis_tuser({ gig_tx_axis_tuser_64, rx_axis_tuser, mac_tx_axis_tuser}) ); -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(64) +) eth_axis_rx_inst ( .clk(clk), .rst(rst), @@ -658,7 +660,9 @@ eth_axis_rx_inst ( .error_header_early_termination() ); -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(64) +) eth_axis_tx_inst ( .clk(clk), .rst(rst), diff --git a/example/VCU108/fpga_10g/tb/test_fpga_core.py b/example/VCU108/fpga_10g/tb/test_fpga_core.py index b2e3c8a7..1224a08f 100755 --- a/example/VCU108/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU108/fpga_10g/tb/test_fpga_core.py @@ -49,8 +49,6 @@ srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") -srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") -srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") diff --git a/example/VCU118/fpga_10g/fpga/Makefile b/example/VCU118/fpga_10g/fpga/Makefile index ce1738f6..e10ba2d0 100644 --- a/example/VCU118/fpga_10g/fpga/Makefile +++ b/example/VCU118/fpga_10g/fpga/Makefile @@ -29,8 +29,8 @@ SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v -SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v -SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete_64.v SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v diff --git a/example/VCU118/fpga_10g/rtl/fpga_core.v b/example/VCU118/fpga_10g/rtl/fpga_core.v index 417ac81d..efd80d68 100644 --- a/example/VCU118/fpga_10g/rtl/fpga_core.v +++ b/example/VCU118/fpga_10g/rtl/fpga_core.v @@ -671,7 +671,9 @@ axis_switch_inst ( .m_axis_tuser({ gig_tx_axis_tuser_64, rx_axis_tuser, mac_tx_axis_tuser}) ); -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(64) +) eth_axis_rx_inst ( .clk(clk), .rst(rst), @@ -699,7 +701,9 @@ eth_axis_rx_inst ( .error_header_early_termination() ); -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(64) +) eth_axis_tx_inst ( .clk(clk), .rst(rst), diff --git a/example/VCU118/fpga_10g/tb/test_fpga_core.py b/example/VCU118/fpga_10g/tb/test_fpga_core.py index e20f4f86..725c2d6d 100755 --- a/example/VCU118/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU118/fpga_10g/tb/test_fpga_core.py @@ -49,8 +49,6 @@ srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") -srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") -srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") diff --git a/example/VCU118/fpga_25g/fpga/Makefile b/example/VCU118/fpga_25g/fpga/Makefile index ce1738f6..e10ba2d0 100644 --- a/example/VCU118/fpga_25g/fpga/Makefile +++ b/example/VCU118/fpga_25g/fpga/Makefile @@ -29,8 +29,8 @@ SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v -SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v -SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete_64.v SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v diff --git a/example/VCU118/fpga_25g/rtl/fpga_core.v b/example/VCU118/fpga_25g/rtl/fpga_core.v index 417ac81d..efd80d68 100644 --- a/example/VCU118/fpga_25g/rtl/fpga_core.v +++ b/example/VCU118/fpga_25g/rtl/fpga_core.v @@ -671,7 +671,9 @@ axis_switch_inst ( .m_axis_tuser({ gig_tx_axis_tuser_64, rx_axis_tuser, mac_tx_axis_tuser}) ); -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(64) +) eth_axis_rx_inst ( .clk(clk), .rst(rst), @@ -699,7 +701,9 @@ eth_axis_rx_inst ( .error_header_early_termination() ); -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(64) +) eth_axis_tx_inst ( .clk(clk), .rst(rst), diff --git a/example/VCU118/fpga_25g/tb/test_fpga_core.py b/example/VCU118/fpga_25g/tb/test_fpga_core.py index e20f4f86..725c2d6d 100755 --- a/example/VCU118/fpga_25g/tb/test_fpga_core.py +++ b/example/VCU118/fpga_25g/tb/test_fpga_core.py @@ -49,8 +49,6 @@ srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") srcs.append("../lib/eth/rtl/eth_axis_rx.v") srcs.append("../lib/eth/rtl/eth_axis_tx.v") -srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") -srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") diff --git a/example/VCU1525/fpga_10g/fpga/Makefile b/example/VCU1525/fpga_10g/fpga/Makefile index dd4b7141..138815a9 100644 --- a/example/VCU1525/fpga_10g/fpga/Makefile +++ b/example/VCU1525/fpga_10g/fpga/Makefile @@ -24,8 +24,8 @@ SYN_FILES += lib/eth/rtl/eth_phy_10g_tx_if.v SYN_FILES += lib/eth/rtl/xgmii_baser_dec_64.v SYN_FILES += lib/eth/rtl/xgmii_baser_enc_64.v SYN_FILES += lib/eth/rtl/lfsr.v -SYN_FILES += lib/eth/rtl/eth_axis_rx_64.v -SYN_FILES += lib/eth/rtl/eth_axis_tx_64.v +SYN_FILES += lib/eth/rtl/eth_axis_rx.v +SYN_FILES += lib/eth/rtl/eth_axis_tx.v SYN_FILES += lib/eth/rtl/udp_complete_64.v SYN_FILES += lib/eth/rtl/udp_checksum_gen_64.v SYN_FILES += lib/eth/rtl/udp_64.v diff --git a/example/VCU1525/fpga_10g/rtl/fpga_core.v b/example/VCU1525/fpga_10g/rtl/fpga_core.v index 9c2cb633..70039a58 100644 --- a/example/VCU1525/fpga_10g/rtl/fpga_core.v +++ b/example/VCU1525/fpga_10g/rtl/fpga_core.v @@ -423,7 +423,9 @@ eth_mac_10g_fifo_inst ( .ifg_delay(8'd12) ); -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(64) +) eth_axis_rx_inst ( .clk(clk), .rst(rst), @@ -451,7 +453,9 @@ eth_axis_rx_inst ( .error_header_early_termination() ); -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(64) +) eth_axis_tx_inst ( .clk(clk), .rst(rst), diff --git a/example/VCU1525/fpga_10g/tb/test_fpga_core.py b/example/VCU1525/fpga_10g/tb/test_fpga_core.py index 1be0eca3..b2a0e316 100755 --- a/example/VCU1525/fpga_10g/tb/test_fpga_core.py +++ b/example/VCU1525/fpga_10g/tb/test_fpga_core.py @@ -42,8 +42,8 @@ srcs.append("../lib/eth/rtl/eth_mac_10g.v") srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/eth_axis_rx_64.v") -srcs.append("../lib/eth/rtl/eth_axis_tx_64.v") +srcs.append("../lib/eth/rtl/eth_axis_rx.v") +srcs.append("../lib/eth/rtl/eth_axis_tx.v") srcs.append("../lib/eth/rtl/udp_complete_64.v") srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v") srcs.append("../lib/eth/rtl/udp_64.v") diff --git a/rtl/eth_axis_rx.v b/rtl/eth_axis_rx.v index f2e399aa..a5ccc376 100644 --- a/rtl/eth_axis_rx.v +++ b/rtl/eth_axis_rx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2018 Alex Forencich +Copyright (c) 2014-2020 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 @@ -29,41 +29,66 @@ THE SOFTWARE. /* * AXI4-Stream ethernet frame receiver (AXI in, Ethernet frame out) */ -module eth_axis_rx +module eth_axis_rx # ( - input wire clk, - input wire rst, + // Width of AXI stream interfaces in bits + parameter DATA_WIDTH = 8, + // Propagate tkeep signal + // If disabled, tkeep assumed to be 1'b1 + parameter KEEP_ENABLE = (DATA_WIDTH>8), + // tkeep signal width (words per cycle) + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, /* * AXI input */ - input wire [7:0] s_axis_tdata, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire s_axis_tuser, /* * Ethernet frame output */ - output wire m_eth_hdr_valid, - input wire m_eth_hdr_ready, - output wire [47:0] m_eth_dest_mac, - output wire [47:0] m_eth_src_mac, - output wire [15:0] m_eth_type, - output wire [7:0] m_eth_payload_axis_tdata, - output wire m_eth_payload_axis_tvalid, - input wire m_eth_payload_axis_tready, - output wire m_eth_payload_axis_tlast, - output wire m_eth_payload_axis_tuser, + output wire m_eth_hdr_valid, + input wire m_eth_hdr_ready, + output wire [47:0] m_eth_dest_mac, + output wire [47:0] m_eth_src_mac, + output wire [15:0] m_eth_type, + output wire [DATA_WIDTH-1:0] m_eth_payload_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep, + output wire m_eth_payload_axis_tvalid, + input wire m_eth_payload_axis_tready, + output wire m_eth_payload_axis_tlast, + output wire m_eth_payload_axis_tuser, /* * Status signals */ - output wire busy, - output wire error_header_early_termination + output wire busy, + output wire error_header_early_termination ); +parameter CYCLE_COUNT = (14+KEEP_WIDTH-1)/KEEP_WIDTH; + +parameter PTR_WIDTH = $clog2(CYCLE_COUNT); + +parameter OFFSET = 14 % KEEP_WIDTH; + +// bus width assertions +initial begin + if (KEEP_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: AXI stream interface requires byte (8-bit) granularity (instance %m)"); + $finish; + end +end + /* Ethernet frame @@ -79,48 +104,44 @@ with the payload in a separate AXI stream. */ -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_READ_HEADER = 2'd1, - STATE_READ_PAYLOAD = 2'd2; +reg read_eth_header_reg = 1'b1, read_eth_header_next; +reg read_eth_payload_reg = 1'b0, read_eth_payload_next; +reg [PTR_WIDTH-1:0] ptr_reg = 0, ptr_next; -reg [1:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg store_eth_dest_mac_0; -reg store_eth_dest_mac_1; -reg store_eth_dest_mac_2; -reg store_eth_dest_mac_3; -reg store_eth_dest_mac_4; -reg store_eth_dest_mac_5; -reg store_eth_src_mac_0; -reg store_eth_src_mac_1; -reg store_eth_src_mac_2; -reg store_eth_src_mac_3; -reg store_eth_src_mac_4; -reg store_eth_src_mac_5; -reg store_eth_type_0; -reg store_eth_type_1; - -reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; +reg flush_save; +reg transfer_in_save; reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg m_eth_hdr_valid_reg = 1'b0, m_eth_hdr_valid_next; -reg [47:0] m_eth_dest_mac_reg = 48'd0; -reg [47:0] m_eth_src_mac_reg = 48'd0; -reg [15:0] m_eth_type_reg = 16'd0; +reg [47:0] m_eth_dest_mac_reg = 48'd0, m_eth_dest_mac_next; +reg [47:0] m_eth_src_mac_reg = 48'd0, m_eth_src_mac_next; +reg [15:0] m_eth_type_reg = 16'd0, m_eth_type_next; reg busy_reg = 1'b0; reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; +reg [DATA_WIDTH-1:0] save_axis_tdata_reg = 64'd0; +reg [KEEP_WIDTH-1:0] save_axis_tkeep_reg = 8'd0; +reg save_axis_tlast_reg = 1'b0; +reg save_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] shift_axis_tdata; +reg [KEEP_WIDTH-1:0] shift_axis_tkeep; +reg shift_axis_tvalid; +reg shift_axis_tlast; +reg shift_axis_tuser; +reg shift_axis_input_tready; +reg shift_axis_extra_cycle_reg = 1'b0; + // internal datapath -reg [7:0] m_eth_payload_axis_tdata_int; -reg m_eth_payload_axis_tvalid_int; -reg m_eth_payload_axis_tready_int_reg = 1'b0; -reg m_eth_payload_axis_tlast_int; -reg m_eth_payload_axis_tuser_int; -wire m_eth_payload_axis_tready_int_early; +reg [DATA_WIDTH-1:0] m_eth_payload_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep_int; +reg m_eth_payload_axis_tvalid_int; +reg m_eth_payload_axis_tready_int_reg = 1'b0; +reg m_eth_payload_axis_tlast_int; +reg m_eth_payload_axis_tuser_int; +wire m_eth_payload_axis_tready_int_early; assign s_axis_tready = s_axis_tready_reg; @@ -133,169 +154,170 @@ assign busy = busy_reg; assign error_header_early_termination = error_header_early_termination_reg; always @* begin - state_next = STATE_IDLE; + if (OFFSET == 0) begin + // passthrough if no overlap + shift_axis_tdata = s_axis_tdata; + shift_axis_tkeep = s_axis_tkeep; + shift_axis_tvalid = s_axis_tvalid; + shift_axis_tlast = s_axis_tlast; + shift_axis_tuser = s_axis_tuser; + shift_axis_input_tready = 1'b1; + end else if (shift_axis_extra_cycle_reg) begin + shift_axis_tdata = {s_axis_tdata, save_axis_tdata_reg} >> (OFFSET*8); + shift_axis_tkeep = {{KEEP_WIDTH{1'b0}}, save_axis_tkeep_reg} >> OFFSET; + shift_axis_tvalid = 1'b1; + shift_axis_tlast = save_axis_tlast_reg; + shift_axis_tuser = save_axis_tuser_reg; + shift_axis_input_tready = flush_save; + end else begin + shift_axis_tdata = {s_axis_tdata, save_axis_tdata_reg} >> (OFFSET*8); + shift_axis_tkeep = {s_axis_tkeep, save_axis_tkeep_reg} >> OFFSET; + shift_axis_tvalid = s_axis_tvalid; + shift_axis_tlast = (s_axis_tlast && ((s_axis_tkeep & ({KEEP_WIDTH{1'b1}} << OFFSET)) == 0)); + shift_axis_tuser = (s_axis_tuser && ((s_axis_tkeep & ({KEEP_WIDTH{1'b1}} << OFFSET)) == 0)); + shift_axis_input_tready = !(s_axis_tlast && s_axis_tready && s_axis_tvalid); + end +end - s_axis_tready_next = 1'b0; +always @* begin + read_eth_header_next = read_eth_header_reg; + read_eth_payload_next = read_eth_payload_reg; + ptr_next = ptr_reg; - store_eth_dest_mac_0 = 1'b0; - store_eth_dest_mac_1 = 1'b0; - store_eth_dest_mac_2 = 1'b0; - store_eth_dest_mac_3 = 1'b0; - store_eth_dest_mac_4 = 1'b0; - store_eth_dest_mac_5 = 1'b0; - store_eth_src_mac_0 = 1'b0; - store_eth_src_mac_1 = 1'b0; - store_eth_src_mac_2 = 1'b0; - store_eth_src_mac_3 = 1'b0; - store_eth_src_mac_4 = 1'b0; - store_eth_src_mac_5 = 1'b0; - store_eth_type_0 = 1'b0; - store_eth_type_1 = 1'b0; + s_axis_tready_next = m_eth_payload_axis_tready_int_early && shift_axis_input_tready && (!m_eth_hdr_valid || m_eth_hdr_ready); - frame_ptr_next = frame_ptr_reg; + flush_save = 1'b0; + transfer_in_save = 1'b0; m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; + m_eth_dest_mac_next = m_eth_dest_mac_reg; + m_eth_src_mac_next = m_eth_src_mac_reg; + m_eth_type_next = m_eth_type_reg; + error_header_early_termination_next = 1'b0; - m_eth_payload_axis_tdata_int = 8'd0; + m_eth_payload_axis_tdata_int = shift_axis_tdata; + m_eth_payload_axis_tkeep_int = shift_axis_tkeep; m_eth_payload_axis_tvalid_int = 1'b0; - m_eth_payload_axis_tlast_int = 1'b0; - m_eth_payload_axis_tuser_int = 1'b0; + m_eth_payload_axis_tlast_int = shift_axis_tlast; + m_eth_payload_axis_tuser_int = shift_axis_tuser; - case (state_reg) - STATE_IDLE: begin - // idle state - wait for data - frame_ptr_next = 8'd0; - s_axis_tready_next = !m_eth_hdr_valid_reg; + if ((s_axis_tready && s_axis_tvalid) || (m_eth_payload_axis_tready_int_reg && shift_axis_extra_cycle_reg)) begin + transfer_in_save = 1'b1; - if (s_axis_tready && s_axis_tvalid) begin - // got first word of packet - if (s_axis_tlast) begin - // tlast asserted on first word - error_header_early_termination_next = 1'b1; - state_next = STATE_IDLE; - end else begin - // move to read header state - frame_ptr_next = 1'b1; - store_eth_dest_mac_5 = 1'b1; - state_next = STATE_READ_HEADER; + if (read_eth_header_reg) begin + // word transfer in - store it + ptr_next = ptr_reg + 1; + + `define _HEADER_FIELD_(offset, field) \ + if (ptr_reg == offset/KEEP_WIDTH && (!KEEP_ENABLE || s_axis_tkeep[offset%KEEP_WIDTH])) begin \ + field = s_axis_tdata[(offset%KEEP_WIDTH)*8 +: 8]; \ end - end else begin - state_next = STATE_IDLE; - end - end - STATE_READ_HEADER: begin - // read header - s_axis_tready_next = 1'b1; - if (s_axis_tready && s_axis_tvalid) begin - // word transfer in - store it - frame_ptr_next = frame_ptr_reg + 8'd1; - state_next = STATE_READ_HEADER; - case (frame_ptr_reg) - 8'h00: store_eth_dest_mac_5 = 1'b1; - 8'h01: store_eth_dest_mac_4 = 1'b1; - 8'h02: store_eth_dest_mac_3 = 1'b1; - 8'h03: store_eth_dest_mac_2 = 1'b1; - 8'h04: store_eth_dest_mac_1 = 1'b1; - 8'h05: store_eth_dest_mac_0 = 1'b1; - 8'h06: store_eth_src_mac_5 = 1'b1; - 8'h07: store_eth_src_mac_4 = 1'b1; - 8'h08: store_eth_src_mac_3 = 1'b1; - 8'h09: store_eth_src_mac_2 = 1'b1; - 8'h0A: store_eth_src_mac_1 = 1'b1; - 8'h0B: store_eth_src_mac_0 = 1'b1; - 8'h0C: store_eth_type_1 = 1'b1; - 8'h0D: begin - store_eth_type_0 = 1'b1; - m_eth_hdr_valid_next = 1'b1; - s_axis_tready_next = m_eth_payload_axis_tready_int_early; - state_next = STATE_READ_PAYLOAD; - end - endcase - if (s_axis_tlast) begin - error_header_early_termination_next = 1'b1; - s_axis_tready_next = !m_eth_hdr_valid_reg; - state_next = STATE_IDLE; + `_HEADER_FIELD_(0, m_eth_dest_mac_next[5*8 +: 8]) + `_HEADER_FIELD_(1, m_eth_dest_mac_next[4*8 +: 8]) + `_HEADER_FIELD_(2, m_eth_dest_mac_next[3*8 +: 8]) + `_HEADER_FIELD_(3, m_eth_dest_mac_next[2*8 +: 8]) + `_HEADER_FIELD_(4, m_eth_dest_mac_next[1*8 +: 8]) + `_HEADER_FIELD_(5, m_eth_dest_mac_next[0*8 +: 8]) + `_HEADER_FIELD_(6, m_eth_src_mac_next[5*8 +: 8]) + `_HEADER_FIELD_(7, m_eth_src_mac_next[4*8 +: 8]) + `_HEADER_FIELD_(8, m_eth_src_mac_next[3*8 +: 8]) + `_HEADER_FIELD_(9, m_eth_src_mac_next[2*8 +: 8]) + `_HEADER_FIELD_(10, m_eth_src_mac_next[1*8 +: 8]) + `_HEADER_FIELD_(11, m_eth_src_mac_next[0*8 +: 8]) + `_HEADER_FIELD_(12, m_eth_type_next[1*8 +: 8]) + `_HEADER_FIELD_(13, m_eth_type_next[0*8 +: 8]) + + if (ptr_reg == 13/KEEP_WIDTH && (!KEEP_ENABLE || s_axis_tkeep[13%KEEP_WIDTH])) begin + if (!shift_axis_tlast) begin + m_eth_hdr_valid_next = 1'b1; + read_eth_header_next = 1'b0; + read_eth_payload_next = 1'b1; end - end else begin - state_next = STATE_READ_HEADER; end + + `undef _HEADER_FIELD_ end - STATE_READ_PAYLOAD: begin - // read payload - s_axis_tready_next = m_eth_payload_axis_tready_int_early; - m_eth_payload_axis_tdata_int = s_axis_tdata; - m_eth_payload_axis_tvalid_int = s_axis_tvalid; - m_eth_payload_axis_tlast_int = s_axis_tlast; - m_eth_payload_axis_tuser_int = s_axis_tuser; + if (read_eth_payload_reg) begin + // transfer payload + m_eth_payload_axis_tdata_int = shift_axis_tdata; + m_eth_payload_axis_tkeep_int = shift_axis_tkeep; + m_eth_payload_axis_tvalid_int = 1'b1; + m_eth_payload_axis_tlast_int = shift_axis_tlast; + m_eth_payload_axis_tuser_int = shift_axis_tuser; + end - if (s_axis_tready && s_axis_tvalid) begin - // word transfer through - if (s_axis_tlast) begin - s_axis_tready_next = !m_eth_hdr_valid_reg; - state_next = STATE_IDLE; - end else begin - state_next = STATE_READ_PAYLOAD; - end - end else begin - state_next = STATE_READ_PAYLOAD; + if (shift_axis_tlast) begin + if (read_eth_header_next) begin + // don't have the whole header + error_header_early_termination_next = 1'b1; end + + flush_save = 1'b1; + ptr_next = 1'b0; + read_eth_header_next = 1'b1; + read_eth_payload_next = 1'b0; end - endcase + end end always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - frame_ptr_reg <= 8'd0; - s_axis_tready_reg <= 1'b0; - m_eth_hdr_valid_reg <= 1'b0; - busy_reg <= 1'b0; - error_header_early_termination_reg <= 1'b0; - end else begin - state_reg <= state_next; + read_eth_header_reg <= read_eth_header_next; + read_eth_payload_reg <= read_eth_payload_next; + ptr_reg <= ptr_next; - frame_ptr_reg <= frame_ptr_next; + s_axis_tready_reg <= s_axis_tready_next; - s_axis_tready_reg <= s_axis_tready_next; + m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; + m_eth_dest_mac_reg <= m_eth_dest_mac_next; + m_eth_src_mac_reg <= m_eth_src_mac_next; + m_eth_type_reg <= m_eth_type_next; - m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; + error_header_early_termination_reg <= error_header_early_termination_next; - error_header_early_termination_reg <= error_header_early_termination_next; + busy_reg <= (read_eth_payload_next || ptr_next != 0); - busy_reg <= state_next != STATE_IDLE; + if (transfer_in_save) begin + save_axis_tdata_reg <= s_axis_tdata; + save_axis_tkeep_reg <= s_axis_tkeep; + save_axis_tuser_reg <= s_axis_tuser; end - // datapath - if (store_eth_dest_mac_0) m_eth_dest_mac_reg[ 7: 0] <= s_axis_tdata; - if (store_eth_dest_mac_1) m_eth_dest_mac_reg[15: 8] <= s_axis_tdata; - if (store_eth_dest_mac_2) m_eth_dest_mac_reg[23:16] <= s_axis_tdata; - if (store_eth_dest_mac_3) m_eth_dest_mac_reg[31:24] <= s_axis_tdata; - if (store_eth_dest_mac_4) m_eth_dest_mac_reg[39:32] <= s_axis_tdata; - if (store_eth_dest_mac_5) m_eth_dest_mac_reg[47:40] <= s_axis_tdata; - if (store_eth_src_mac_0) m_eth_src_mac_reg[ 7: 0] <= s_axis_tdata; - if (store_eth_src_mac_1) m_eth_src_mac_reg[15: 8] <= s_axis_tdata; - if (store_eth_src_mac_2) m_eth_src_mac_reg[23:16] <= s_axis_tdata; - if (store_eth_src_mac_3) m_eth_src_mac_reg[31:24] <= s_axis_tdata; - if (store_eth_src_mac_4) m_eth_src_mac_reg[39:32] <= s_axis_tdata; - if (store_eth_src_mac_5) m_eth_src_mac_reg[47:40] <= s_axis_tdata; - if (store_eth_type_0) m_eth_type_reg[ 7: 0] <= s_axis_tdata; - if (store_eth_type_1) m_eth_type_reg[15: 8] <= s_axis_tdata; + if (flush_save) begin + save_axis_tlast_reg <= 1'b0; + shift_axis_extra_cycle_reg <= 1'b0; + end else if (transfer_in_save) begin + save_axis_tlast_reg <= s_axis_tlast; + shift_axis_extra_cycle_reg <= OFFSET ? s_axis_tlast && ((s_axis_tkeep & ({KEEP_WIDTH{1'b1}} << OFFSET)) != 0) : 1'b0; + end + + if (rst) begin + read_eth_header_reg <= 1'b1; + read_eth_payload_reg <= 1'b0; + ptr_reg <= 0; + m_eth_hdr_valid_reg <= 1'b0; + save_axis_tlast_reg <= 1'b0; + shift_axis_extra_cycle_reg <= 1'b0; + busy_reg <= 1'b0; + error_header_early_termination_reg <= 1'b0; + end end // output datapath logic -reg [7:0] m_eth_payload_axis_tdata_reg = 8'd0; -reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; -reg m_eth_payload_axis_tlast_reg = 1'b0; -reg m_eth_payload_axis_tuser_reg = 1'b0; +reg [DATA_WIDTH-1:0] m_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; +reg m_eth_payload_axis_tlast_reg = 1'b0; +reg m_eth_payload_axis_tuser_reg = 1'b0; -reg [7:0] temp_m_eth_payload_axis_tdata_reg = 8'd0; -reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; -reg temp_m_eth_payload_axis_tlast_reg = 1'b0; -reg temp_m_eth_payload_axis_tuser_reg = 1'b0; +reg [DATA_WIDTH-1:0] temp_m_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; +reg temp_m_eth_payload_axis_tlast_reg = 1'b0; +reg temp_m_eth_payload_axis_tuser_reg = 1'b0; // datapath control reg store_eth_payload_int_to_output; @@ -303,6 +325,7 @@ reg store_eth_payload_int_to_temp; reg store_eth_payload_axis_temp_to_output; assign m_eth_payload_axis_tdata = m_eth_payload_axis_tdata_reg; +assign m_eth_payload_axis_tkeep = KEEP_ENABLE ? m_eth_payload_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; assign m_eth_payload_axis_tlast = m_eth_payload_axis_tlast_reg; assign m_eth_payload_axis_tuser = m_eth_payload_axis_tuser_reg; @@ -352,16 +375,19 @@ always @(posedge clk) begin // datapath if (store_eth_payload_int_to_output) begin m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; end else if (store_eth_payload_axis_temp_to_output) begin m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; + m_eth_payload_axis_tkeep_reg <= temp_m_eth_payload_axis_tkeep_reg; m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; end if (store_eth_payload_int_to_temp) begin temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; + temp_m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; end diff --git a/rtl/eth_axis_rx_64.v b/rtl/eth_axis_rx_64.v deleted file mode 100644 index 2f815ccc..00000000 --- a/rtl/eth_axis_rx_64.v +++ /dev/null @@ -1,417 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * AXI4-Stream ethernet frame receiver (AXI in, Ethernet frame out, 64 bit datapath) - */ -module eth_axis_rx_64 -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [63:0] s_axis_tdata, - input wire [7:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire s_axis_tuser, - - /* - * Ethernet frame output - */ - output wire m_eth_hdr_valid, - input wire m_eth_hdr_ready, - output wire [47:0] m_eth_dest_mac, - output wire [47:0] m_eth_src_mac, - output wire [15:0] m_eth_type, - output wire [63:0] m_eth_payload_axis_tdata, - output wire [7:0] m_eth_payload_axis_tkeep, - output wire m_eth_payload_axis_tvalid, - input wire m_eth_payload_axis_tready, - output wire m_eth_payload_axis_tlast, - output wire m_eth_payload_axis_tuser, - - /* - * Status signals - */ - output wire busy, - output wire error_header_early_termination -); - -/* - -Ethernet frame - - Field Length - Destination MAC address 6 octets - Source MAC address 6 octets - Ethertype 2 octets - -This module receives an Ethernet frame on an AXI stream interface, decodes -and strips the headers, then produces the header fields in parallel along -with the payload in a separate AXI stream. - -*/ - -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_READ_HEADER = 3'd1, - STATE_READ_PAYLOAD = 3'd2; - -reg [2:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg store_hdr_word_0; -reg store_hdr_word_1; - -reg flush_save; -reg transfer_in_save; - -reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; - -reg s_axis_tready_reg = 1'b0, s_axis_tready_next; - -reg m_eth_hdr_valid_reg = 1'b0, m_eth_hdr_valid_next; -reg [47:0] m_eth_dest_mac_reg = 48'd0; -reg [47:0] m_eth_src_mac_reg = 48'd0; -reg [15:0] m_eth_type_reg = 16'd0; - -reg busy_reg = 1'b0; -reg error_header_early_termination_reg = 1'b0, error_header_early_termination_next; - -reg [63:0] save_axis_tdata_reg = 64'd0; -reg [7:0] save_axis_tkeep_reg = 8'd0; -reg save_axis_tlast_reg = 1'b0; -reg save_axis_tuser_reg = 1'b0; - -reg [63:0] shift_axis_tdata; -reg [7:0] shift_axis_tkeep; -reg shift_axis_tvalid; -reg shift_axis_tlast; -reg shift_axis_tuser; -reg shift_axis_s_tready; -reg shift_axis_extra_cycle_reg = 1'b0; - -// internal datapath -reg [63:0] m_eth_payload_axis_tdata_int; -reg [7:0] m_eth_payload_axis_tkeep_int; -reg m_eth_payload_axis_tvalid_int; -reg m_eth_payload_axis_tready_int_reg = 1'b0; -reg m_eth_payload_axis_tlast_int; -reg m_eth_payload_axis_tuser_int; -wire m_eth_payload_axis_tready_int_early; - -assign s_axis_tready = s_axis_tready_reg; - -assign m_eth_hdr_valid = m_eth_hdr_valid_reg; -assign m_eth_dest_mac = m_eth_dest_mac_reg; -assign m_eth_src_mac = m_eth_src_mac_reg; -assign m_eth_type = m_eth_type_reg; - -assign busy = busy_reg; -assign error_header_early_termination = error_header_early_termination_reg; - -always @* begin - shift_axis_tdata[15:0] = save_axis_tdata_reg[63:48]; - shift_axis_tkeep[1:0] = save_axis_tkeep_reg[7:6]; - - if (shift_axis_extra_cycle_reg) begin - shift_axis_tdata[63:16] = 48'd0; - shift_axis_tkeep[7:2] = 6'd0; - shift_axis_tvalid = 1'b1; - shift_axis_tlast = save_axis_tlast_reg; - shift_axis_tuser = save_axis_tuser_reg; - shift_axis_s_tready = flush_save; - end else begin - shift_axis_tdata[63:16] = s_axis_tdata[47:0]; - shift_axis_tkeep[7:2] = s_axis_tkeep[5:0]; - shift_axis_tvalid = s_axis_tvalid; - shift_axis_tlast = (s_axis_tlast && (s_axis_tkeep[7:6] == 0)); - shift_axis_tuser = (s_axis_tuser && (s_axis_tkeep[7:6] == 0)); - shift_axis_s_tready = !(s_axis_tlast && s_axis_tvalid && transfer_in_save); - end -end - -always @* begin - state_next = STATE_IDLE; - - s_axis_tready_next = 1'b0; - - flush_save = 1'b0; - transfer_in_save = 1'b0; - - store_hdr_word_0 = 1'b0; - store_hdr_word_1 = 1'b0; - - frame_ptr_next = frame_ptr_reg; - - m_eth_hdr_valid_next = m_eth_hdr_valid_reg && !m_eth_hdr_ready; - - error_header_early_termination_next = 1'b0; - - m_eth_payload_axis_tdata_int = 64'd0; - m_eth_payload_axis_tkeep_int = 8'd0; - m_eth_payload_axis_tvalid_int = 1'b0; - m_eth_payload_axis_tlast_int = 1'b0; - m_eth_payload_axis_tuser_int = 1'b0; - - case (state_reg) - STATE_IDLE: begin - // idle state - wait for data - frame_ptr_next = 8'd0; - flush_save = 1'b1; - s_axis_tready_next = !m_eth_hdr_valid_reg; - - if (s_axis_tready && s_axis_tvalid) begin - // got first word of packet - if (s_axis_tlast) begin - // tlast asserted on first word - error_header_early_termination_next = 1'b1; - state_next = STATE_IDLE; - end else begin - // move to read header state - frame_ptr_next = 8'd8; - store_hdr_word_0 = 1'b1; - transfer_in_save = 1'b1; - state_next = STATE_READ_HEADER; - end - end else begin - state_next = STATE_IDLE; - end - end - STATE_READ_HEADER: begin - // read header state - s_axis_tready_next = 1'b1; - - if (s_axis_tready && s_axis_tvalid) begin - // word transfer in - store it - frame_ptr_next = frame_ptr_reg + 8'd8; - transfer_in_save = 1'b1; - state_next = STATE_READ_HEADER; - case (frame_ptr_reg) - 8'h00: store_hdr_word_0 = 1'b1; - 8'h08: begin - store_hdr_word_1 = 1'b1; - m_eth_hdr_valid_next = 1'b1; - s_axis_tready_next = m_eth_payload_axis_tready_int_early; - state_next = STATE_READ_PAYLOAD; - end - endcase - if (s_axis_tlast) begin - if (s_axis_tkeep[7:6] != 2'd0) begin - s_axis_tready_next = 1'b0; - state_next = STATE_READ_PAYLOAD; - end else begin - flush_save = 1'b1; - m_eth_hdr_valid_next = 1'b0; - error_header_early_termination_next = 1'b1; - s_axis_tready_next = !m_eth_hdr_valid_reg; - state_next = STATE_IDLE; - end - end - end else begin - state_next = STATE_READ_HEADER; - end - end - STATE_READ_PAYLOAD: begin - // read payload - s_axis_tready_next = m_eth_payload_axis_tready_int_early && shift_axis_s_tready; - - m_eth_payload_axis_tdata_int = shift_axis_tdata; - m_eth_payload_axis_tkeep_int = shift_axis_tkeep; - m_eth_payload_axis_tvalid_int = shift_axis_tvalid; - m_eth_payload_axis_tlast_int = shift_axis_tlast; - m_eth_payload_axis_tuser_int = shift_axis_tuser; - - if (m_eth_payload_axis_tready_int_reg && shift_axis_tvalid) begin - // word transfer through - transfer_in_save = 1'b1; - if (shift_axis_tlast) begin - flush_save = 1'b1; - s_axis_tready_next = !m_eth_hdr_valid_reg; - state_next = STATE_IDLE; - end else begin - state_next = STATE_READ_PAYLOAD; - end - end else begin - state_next = STATE_READ_PAYLOAD; - end - end - endcase -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - frame_ptr_reg <= 8'd0; - s_axis_tready_reg <= 1'b0; - m_eth_hdr_valid_reg <= 1'b0; - save_axis_tlast_reg <= 1'b0; - shift_axis_extra_cycle_reg <= 1'b0; - busy_reg <= 1'b0; - error_header_early_termination_reg <= 1'b0; - end else begin - state_reg <= state_next; - - frame_ptr_reg <= frame_ptr_next; - - s_axis_tready_reg <= s_axis_tready_next; - - m_eth_hdr_valid_reg <= m_eth_hdr_valid_next; - - error_header_early_termination_reg <= error_header_early_termination_next; - - busy_reg <= state_next != STATE_IDLE; - - if (flush_save) begin - save_axis_tlast_reg <= 1'b0; - shift_axis_extra_cycle_reg <= 1'b0; - end else if (transfer_in_save) begin - save_axis_tlast_reg <= s_axis_tlast; - shift_axis_extra_cycle_reg <= s_axis_tlast && (s_axis_tkeep[7:6] != 0); - end - end - - // datapath - if (store_hdr_word_0) begin - m_eth_dest_mac_reg[47:40] <= s_axis_tdata[ 7: 0]; - m_eth_dest_mac_reg[39:32] <= s_axis_tdata[15: 8]; - m_eth_dest_mac_reg[31:24] <= s_axis_tdata[23:16]; - m_eth_dest_mac_reg[23:16] <= s_axis_tdata[31:24]; - m_eth_dest_mac_reg[15: 8] <= s_axis_tdata[39:32]; - m_eth_dest_mac_reg[ 7: 0] <= s_axis_tdata[47:40]; - m_eth_src_mac_reg[47:40] <= s_axis_tdata[55:48]; - m_eth_src_mac_reg[39:32] <= s_axis_tdata[63:56]; - end - if (store_hdr_word_1) begin - m_eth_src_mac_reg[31:24] <= s_axis_tdata[ 7: 0]; - m_eth_src_mac_reg[23:16] <= s_axis_tdata[15: 8]; - m_eth_src_mac_reg[15: 8] <= s_axis_tdata[23:16]; - m_eth_src_mac_reg[ 7: 0] <= s_axis_tdata[31:24]; - m_eth_type_reg[15:8] <= s_axis_tdata[39:32]; - m_eth_type_reg[ 7:0] <= s_axis_tdata[47:40]; - end - - if (transfer_in_save) begin - save_axis_tdata_reg <= s_axis_tdata; - save_axis_tkeep_reg <= s_axis_tkeep; - save_axis_tuser_reg <= s_axis_tuser; - end -end - -// output datapath logic -reg [63:0] m_eth_payload_axis_tdata_reg = 64'd0; -reg [7:0] m_eth_payload_axis_tkeep_reg = 8'd0; -reg m_eth_payload_axis_tvalid_reg = 1'b0, m_eth_payload_axis_tvalid_next; -reg m_eth_payload_axis_tlast_reg = 1'b0; -reg m_eth_payload_axis_tuser_reg = 1'b0; - -reg [63:0] temp_m_eth_payload_axis_tdata_reg = 64'd0; -reg [7:0] temp_m_eth_payload_axis_tkeep_reg = 8'd0; -reg temp_m_eth_payload_axis_tvalid_reg = 1'b0, temp_m_eth_payload_axis_tvalid_next; -reg temp_m_eth_payload_axis_tlast_reg = 1'b0; -reg temp_m_eth_payload_axis_tuser_reg = 1'b0; - -// datapath control -reg store_eth_payload_int_to_output; -reg store_eth_payload_int_to_temp; -reg store_eth_payload_axis_temp_to_output; - -assign m_eth_payload_axis_tdata = m_eth_payload_axis_tdata_reg; -assign m_eth_payload_axis_tkeep = m_eth_payload_axis_tkeep_reg; -assign m_eth_payload_axis_tvalid = m_eth_payload_axis_tvalid_reg; -assign m_eth_payload_axis_tlast = m_eth_payload_axis_tlast_reg; -assign m_eth_payload_axis_tuser = m_eth_payload_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign m_eth_payload_axis_tready_int_early = m_eth_payload_axis_tready || (!temp_m_eth_payload_axis_tvalid_reg && (!m_eth_payload_axis_tvalid_reg || !m_eth_payload_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_reg; - temp_m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; - - store_eth_payload_int_to_output = 1'b0; - store_eth_payload_int_to_temp = 1'b0; - store_eth_payload_axis_temp_to_output = 1'b0; - - if (m_eth_payload_axis_tready_int_reg) begin - // input is ready - if (m_eth_payload_axis_tready || !m_eth_payload_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; - store_eth_payload_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_m_eth_payload_axis_tvalid_next = m_eth_payload_axis_tvalid_int; - store_eth_payload_int_to_temp = 1'b1; - end - end else if (m_eth_payload_axis_tready) begin - // input is not ready, but output is ready - m_eth_payload_axis_tvalid_next = temp_m_eth_payload_axis_tvalid_reg; - temp_m_eth_payload_axis_tvalid_next = 1'b0; - store_eth_payload_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - m_eth_payload_axis_tvalid_reg <= 1'b0; - m_eth_payload_axis_tready_int_reg <= 1'b0; - temp_m_eth_payload_axis_tvalid_reg <= 1'b0; - end else begin - m_eth_payload_axis_tvalid_reg <= m_eth_payload_axis_tvalid_next; - m_eth_payload_axis_tready_int_reg <= m_eth_payload_axis_tready_int_early; - temp_m_eth_payload_axis_tvalid_reg <= temp_m_eth_payload_axis_tvalid_next; - end - - // datapath - if (store_eth_payload_int_to_output) begin - m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; - m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; - m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; - m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; - end else if (store_eth_payload_axis_temp_to_output) begin - m_eth_payload_axis_tdata_reg <= temp_m_eth_payload_axis_tdata_reg; - m_eth_payload_axis_tkeep_reg <= temp_m_eth_payload_axis_tkeep_reg; - m_eth_payload_axis_tlast_reg <= temp_m_eth_payload_axis_tlast_reg; - m_eth_payload_axis_tuser_reg <= temp_m_eth_payload_axis_tuser_reg; - end - - if (store_eth_payload_int_to_temp) begin - temp_m_eth_payload_axis_tdata_reg <= m_eth_payload_axis_tdata_int; - temp_m_eth_payload_axis_tkeep_reg <= m_eth_payload_axis_tkeep_int; - temp_m_eth_payload_axis_tlast_reg <= m_eth_payload_axis_tlast_int; - temp_m_eth_payload_axis_tuser_reg <= m_eth_payload_axis_tuser_int; - end -end - -endmodule diff --git a/rtl/eth_axis_tx.v b/rtl/eth_axis_tx.v index 55388f27..5d582c42 100644 --- a/rtl/eth_axis_tx.v +++ b/rtl/eth_axis_tx.v @@ -1,6 +1,6 @@ /* -Copyright (c) 2014-2018 Alex Forencich +Copyright (c) 2014-2020 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 @@ -29,40 +29,65 @@ THE SOFTWARE. /* * AXI4-Stream ethernet frame transmitter (Ethernet frame in, AXI out) */ -module eth_axis_tx +module eth_axis_tx # ( - input wire clk, - input wire rst, + // Width of AXI stream interfaces in bits + parameter DATA_WIDTH = 8, + // Propagate tkeep signal + // If disabled, tkeep assumed to be 1'b1 + parameter KEEP_ENABLE = (DATA_WIDTH>8), + // tkeep signal width (words per cycle) + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, /* * Ethernet frame input */ - input wire s_eth_hdr_valid, - output wire s_eth_hdr_ready, - input wire [47:0] s_eth_dest_mac, - input wire [47:0] s_eth_src_mac, - input wire [15:0] s_eth_type, - input wire [7:0] s_eth_payload_axis_tdata, - input wire s_eth_payload_axis_tvalid, - output wire s_eth_payload_axis_tready, - input wire s_eth_payload_axis_tlast, - input wire s_eth_payload_axis_tuser, + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [DATA_WIDTH-1:0] s_eth_payload_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, /* * AXI output */ - output wire [7:0] m_axis_tdata, - output wire m_axis_tvalid, - input wire m_axis_tready, - output wire m_axis_tlast, - output wire m_axis_tuser, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, /* * Status signals */ - output wire busy + output wire busy ); +parameter CYCLE_COUNT = (14+KEEP_WIDTH-1)/KEEP_WIDTH; + +parameter PTR_WIDTH = $clog2(CYCLE_COUNT); + +parameter OFFSET = 14 % KEEP_WIDTH; + +// bus width assertions +initial begin + if (KEEP_WIDTH * 8 != DATA_WIDTH) begin + $error("Error: AXI stream interface requires byte (8-bit) granularity (instance %m)"); + $finish; + end +end + /* Ethernet frame @@ -78,17 +103,15 @@ transmits the complete Ethernet frame on the output AXI stream interface. */ -localparam [1:0] - STATE_IDLE = 2'd0, - STATE_WRITE_HEADER = 2'd1, - STATE_WRITE_PAYLOAD = 2'd2; - -reg [1:0] state_reg = STATE_IDLE, state_next; - // datapath control signals reg store_eth_hdr; -reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; +reg send_eth_header_reg = 1'b0, send_eth_header_next; +reg send_eth_payload_reg = 1'b0, send_eth_payload_next; +reg [PTR_WIDTH-1:0] ptr_reg = 0, ptr_next; + +reg flush_save; +reg transfer_in_save; reg [47:0] eth_dest_mac_reg = 48'd0; reg [47:0] eth_src_mac_reg = 48'd0; @@ -99,13 +122,27 @@ reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; reg busy_reg = 1'b0; +reg [DATA_WIDTH-1:0] save_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] save_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg save_eth_payload_axis_tlast_reg = 1'b0; +reg save_eth_payload_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] shift_eth_payload_axis_tdata; +reg [KEEP_WIDTH-1:0] shift_eth_payload_axis_tkeep; +reg shift_eth_payload_axis_tvalid; +reg shift_eth_payload_axis_tlast; +reg shift_eth_payload_axis_tuser; +reg shift_eth_payload_axis_input_tready; +reg shift_eth_payload_axis_extra_cycle_reg = 1'b0; + // internal datapath -reg [7:0] m_axis_tdata_int; -reg m_axis_tvalid_int; -reg m_axis_tready_int_reg = 1'b0; -reg m_axis_tlast_int; -reg m_axis_tuser_int; -wire m_axis_tready_int_early; +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; assign s_eth_hdr_ready = s_eth_hdr_ready_reg; assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; @@ -113,131 +150,178 @@ assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; assign busy = busy_reg; always @* begin - state_next = STATE_IDLE; + if (OFFSET == 0) begin + // passthrough if no overlap + shift_eth_payload_axis_tdata = s_eth_payload_axis_tdata; + shift_eth_payload_axis_tkeep = s_eth_payload_axis_tkeep; + shift_eth_payload_axis_tvalid = s_eth_payload_axis_tvalid; + shift_eth_payload_axis_tlast = s_eth_payload_axis_tlast; + shift_eth_payload_axis_tuser = s_eth_payload_axis_tuser; + shift_eth_payload_axis_input_tready = 1'b1; + end else if (shift_eth_payload_axis_extra_cycle_reg) begin + shift_eth_payload_axis_tdata = {s_eth_payload_axis_tdata, save_eth_payload_axis_tdata_reg} >> ((KEEP_WIDTH-OFFSET)*8); + shift_eth_payload_axis_tkeep = {{KEEP_WIDTH{1'b0}}, save_eth_payload_axis_tkeep_reg} >> (KEEP_WIDTH-OFFSET); + shift_eth_payload_axis_tvalid = 1'b1; + shift_eth_payload_axis_tlast = save_eth_payload_axis_tlast_reg; + shift_eth_payload_axis_tuser = save_eth_payload_axis_tuser_reg; + shift_eth_payload_axis_input_tready = flush_save; + end else begin + shift_eth_payload_axis_tdata = {s_eth_payload_axis_tdata, save_eth_payload_axis_tdata_reg} >> ((KEEP_WIDTH-OFFSET)*8); + shift_eth_payload_axis_tkeep = {s_eth_payload_axis_tkeep, save_eth_payload_axis_tkeep_reg} >> (KEEP_WIDTH-OFFSET); + shift_eth_payload_axis_tvalid = s_eth_payload_axis_tvalid; + shift_eth_payload_axis_tlast = (s_eth_payload_axis_tlast && ((s_eth_payload_axis_tkeep & ({KEEP_WIDTH{1'b1}} << (KEEP_WIDTH-OFFSET))) == 0)); + shift_eth_payload_axis_tuser = (s_eth_payload_axis_tuser && ((s_eth_payload_axis_tkeep & ({KEEP_WIDTH{1'b1}} << (KEEP_WIDTH-OFFSET))) == 0)); + shift_eth_payload_axis_input_tready = !(s_eth_payload_axis_tlast && s_eth_payload_axis_tready && s_eth_payload_axis_tvalid); + end +end + +always @* begin + send_eth_header_next = send_eth_header_reg; + send_eth_payload_next = send_eth_payload_reg; + ptr_next = ptr_reg; s_eth_hdr_ready_next = 1'b0; s_eth_payload_axis_tready_next = 1'b0; store_eth_hdr = 1'b0; - frame_ptr_next = frame_ptr_reg; + flush_save = 1'b0; + transfer_in_save = 1'b0; - m_axis_tdata_int = 8'd0; + m_axis_tdata_int = {DATA_WIDTH{1'b0}}; + m_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; m_axis_tvalid_int = 1'b0; m_axis_tlast_int = 1'b0; m_axis_tuser_int = 1'b0; - case (state_reg) - STATE_IDLE: begin - // idle state - wait for data - frame_ptr_next = 8'd0; - s_eth_hdr_ready_next = 1'b1; + if (s_eth_hdr_ready && s_eth_hdr_valid) begin + store_eth_hdr = 1'b1; + ptr_next = 0; + send_eth_header_next = 1'b1; + send_eth_payload_next = (OFFSET != 0) && (CYCLE_COUNT == 1); + s_eth_payload_axis_tready_next = send_eth_payload_next && m_axis_tready_int_early; + end - if (s_eth_hdr_ready && s_eth_hdr_valid) begin - store_eth_hdr = 1'b1; - s_eth_hdr_ready_next = 1'b0; - if (m_axis_tready_int_reg) begin - m_axis_tvalid_int = 1'b1; - m_axis_tdata_int = s_eth_dest_mac[47:40]; - frame_ptr_next = 1'b1; + if (send_eth_payload_reg) begin + s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_axis_input_tready; + + if ((s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) || (m_axis_tready_int_reg && shift_eth_payload_axis_extra_cycle_reg)) begin + transfer_in_save = 1'b1; + + m_axis_tdata_int = shift_eth_payload_axis_tdata; + m_axis_tkeep_int = shift_eth_payload_axis_tkeep; + m_axis_tvalid_int = 1'b1; + m_axis_tlast_int = shift_eth_payload_axis_tlast; + m_axis_tuser_int = shift_eth_payload_axis_tuser; + + if (shift_eth_payload_axis_tlast) begin + flush_save = 1'b1; + s_eth_payload_axis_tready_next = 1'b0; + ptr_next = 0; + send_eth_payload_next = 1'b0; + end + end + end + + if (m_axis_tready_int_reg && (!OFFSET || !send_eth_payload_reg || m_axis_tvalid_int)) begin + if (send_eth_header_reg) begin + ptr_next = ptr_reg + 1; + + if ((OFFSET != 0) && (CYCLE_COUNT == 1 || ptr_next == CYCLE_COUNT-1) && !send_eth_payload_reg) begin + send_eth_payload_next = 1'b1; + s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_axis_input_tready; + end + + m_axis_tvalid_int = 1'b1; + + `define _HEADER_FIELD_(offset, field) \ + if (ptr_reg == offset/KEEP_WIDTH) begin \ + m_axis_tdata_int[(offset%KEEP_WIDTH)*8 +: 8] = field; \ + m_axis_tkeep_int[offset%KEEP_WIDTH] = 1'b1; \ end - state_next = STATE_WRITE_HEADER; - end else begin - state_next = STATE_IDLE; - end - end - STATE_WRITE_HEADER: begin - // write header - if (m_axis_tready_int_reg) begin - frame_ptr_next = frame_ptr_reg+1; - m_axis_tvalid_int = 1'b1; - state_next = STATE_WRITE_HEADER; - case (frame_ptr_reg) - 8'h00: m_axis_tdata_int = eth_dest_mac_reg[47:40]; - 8'h01: m_axis_tdata_int = eth_dest_mac_reg[39:32]; - 8'h02: m_axis_tdata_int = eth_dest_mac_reg[31:24]; - 8'h03: m_axis_tdata_int = eth_dest_mac_reg[23:16]; - 8'h04: m_axis_tdata_int = eth_dest_mac_reg[15: 8]; - 8'h05: m_axis_tdata_int = eth_dest_mac_reg[ 7: 0]; - 8'h06: m_axis_tdata_int = eth_src_mac_reg[47:40]; - 8'h07: m_axis_tdata_int = eth_src_mac_reg[39:32]; - 8'h08: m_axis_tdata_int = eth_src_mac_reg[31:24]; - 8'h09: m_axis_tdata_int = eth_src_mac_reg[23:16]; - 8'h0A: m_axis_tdata_int = eth_src_mac_reg[15: 8]; - 8'h0B: m_axis_tdata_int = eth_src_mac_reg[ 7: 0]; - 8'h0C: m_axis_tdata_int = eth_type_reg[15: 8]; - 8'h0D: begin - m_axis_tdata_int = eth_type_reg[ 7: 0]; - s_eth_payload_axis_tready_next = m_axis_tready_int_early; - state_next = STATE_WRITE_PAYLOAD; - end - endcase - end else begin - state_next = STATE_WRITE_HEADER; - end - end - STATE_WRITE_PAYLOAD: begin - // write payload - s_eth_payload_axis_tready_next = m_axis_tready_int_early; - m_axis_tdata_int = s_eth_payload_axis_tdata; - m_axis_tvalid_int = s_eth_payload_axis_tvalid; - m_axis_tlast_int = s_eth_payload_axis_tlast; - m_axis_tuser_int = s_eth_payload_axis_tuser; + `_HEADER_FIELD_(0, eth_dest_mac_reg[5*8 +: 8]) + `_HEADER_FIELD_(1, eth_dest_mac_reg[4*8 +: 8]) + `_HEADER_FIELD_(2, eth_dest_mac_reg[3*8 +: 8]) + `_HEADER_FIELD_(3, eth_dest_mac_reg[2*8 +: 8]) + `_HEADER_FIELD_(4, eth_dest_mac_reg[1*8 +: 8]) + `_HEADER_FIELD_(5, eth_dest_mac_reg[0*8 +: 8]) + `_HEADER_FIELD_(6, eth_src_mac_reg[5*8 +: 8]) + `_HEADER_FIELD_(7, eth_src_mac_reg[4*8 +: 8]) + `_HEADER_FIELD_(8, eth_src_mac_reg[3*8 +: 8]) + `_HEADER_FIELD_(9, eth_src_mac_reg[2*8 +: 8]) + `_HEADER_FIELD_(10, eth_src_mac_reg[1*8 +: 8]) + `_HEADER_FIELD_(11, eth_src_mac_reg[0*8 +: 8]) + `_HEADER_FIELD_(12, eth_type_reg[1*8 +: 8]) + `_HEADER_FIELD_(13, eth_type_reg[0*8 +: 8]) - if (s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) begin - // word transfer through - if (s_eth_payload_axis_tlast) begin - s_eth_payload_axis_tready_next = 1'b0; - s_eth_hdr_ready_next = 1'b1; - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_PAYLOAD; + if (ptr_reg == 13/KEEP_WIDTH) begin + if (!send_eth_payload_reg) begin + s_eth_payload_axis_tready_next = m_axis_tready_int_early; + send_eth_payload_next = 1'b1; end - end else begin - state_next = STATE_WRITE_PAYLOAD; + send_eth_header_next = 1'b0; end + + `undef _HEADER_FIELD_ end - endcase + end + + s_eth_hdr_ready_next = !(send_eth_header_next || send_eth_payload_next); end always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - frame_ptr_reg <= 8'd0; - s_eth_hdr_ready_reg <= 1'b0; - s_eth_payload_axis_tready_reg <= 1'b0; - busy_reg <= 1'b0; - end else begin - state_reg <= state_next; + send_eth_header_reg <= send_eth_header_next; + send_eth_payload_reg <= send_eth_payload_next; + ptr_reg <= ptr_next; - frame_ptr_reg <= frame_ptr_next; + s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; + s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; - s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; + busy_reg <= send_eth_header_next || send_eth_payload_next; - s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; - - busy_reg <= state_next != STATE_IDLE; - end - - // datapath if (store_eth_hdr) begin eth_dest_mac_reg <= s_eth_dest_mac; eth_src_mac_reg <= s_eth_src_mac; eth_type_reg <= s_eth_type; end + + if (transfer_in_save) begin + save_eth_payload_axis_tdata_reg <= s_eth_payload_axis_tdata; + save_eth_payload_axis_tkeep_reg <= s_eth_payload_axis_tkeep; + save_eth_payload_axis_tuser_reg <= s_eth_payload_axis_tuser; + end + + if (flush_save) begin + save_eth_payload_axis_tlast_reg <= 1'b0; + shift_eth_payload_axis_extra_cycle_reg <= 1'b0; + end else if (transfer_in_save) begin + save_eth_payload_axis_tlast_reg <= s_eth_payload_axis_tlast; + shift_eth_payload_axis_extra_cycle_reg <= OFFSET ? s_eth_payload_axis_tlast && ((s_eth_payload_axis_tkeep & ({KEEP_WIDTH{1'b1}} << (KEEP_WIDTH-OFFSET))) != 0) : 1'b0; + end + + if (rst) begin + send_eth_header_reg <= 1'b0; + send_eth_payload_reg <= 1'b0; + ptr_reg <= 0; + s_eth_hdr_ready_reg <= 1'b0; + s_eth_payload_axis_tready_reg <= 1'b0; + busy_reg <= 1'b0; + end end // output datapath logic -reg [7:0] m_axis_tdata_reg = 8'd0; -reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; -reg m_axis_tlast_reg = 1'b0; -reg m_axis_tuser_reg = 1'b0; +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; -reg [7:0] temp_m_axis_tdata_reg = 8'd0; -reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; -reg temp_m_axis_tlast_reg = 1'b0; -reg temp_m_axis_tuser_reg = 1'b0; +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; // datapath control reg store_axis_int_to_output; @@ -245,6 +329,7 @@ reg store_axis_int_to_temp; reg store_axis_temp_to_output; assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tlast = m_axis_tlast_reg; assign m_axis_tuser = m_axis_tuser_reg; @@ -294,16 +379,19 @@ always @(posedge clk) begin // datapath if (store_axis_int_to_output) begin m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; m_axis_tlast_reg <= m_axis_tlast_int; m_axis_tuser_reg <= m_axis_tuser_int; end else if (store_axis_temp_to_output) begin m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; m_axis_tlast_reg <= temp_m_axis_tlast_reg; m_axis_tuser_reg <= temp_m_axis_tuser_reg; end if (store_axis_int_to_temp) begin temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; temp_m_axis_tlast_reg <= m_axis_tlast_int; temp_m_axis_tuser_reg <= m_axis_tuser_int; end diff --git a/rtl/eth_axis_tx_64.v b/rtl/eth_axis_tx_64.v deleted file mode 100644 index e414d2cd..00000000 --- a/rtl/eth_axis_tx_64.v +++ /dev/null @@ -1,428 +0,0 @@ -/* - -Copyright (c) 2014-2018 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 - -/* - * AXI4-Stream ethernet frame transmitter (Ethernet frame in, AXI out, 64 bit datapath) - */ -module eth_axis_tx_64 -( - input wire clk, - input wire rst, - - /* - * Ethernet frame input - */ - input wire s_eth_hdr_valid, - output wire s_eth_hdr_ready, - input wire [47:0] s_eth_dest_mac, - input wire [47:0] s_eth_src_mac, - input wire [15:0] s_eth_type, - input wire [63:0] s_eth_payload_axis_tdata, - input wire [7:0] s_eth_payload_axis_tkeep, - input wire s_eth_payload_axis_tvalid, - output wire s_eth_payload_axis_tready, - input wire s_eth_payload_axis_tlast, - input wire s_eth_payload_axis_tuser, - - /* - * AXI output - */ - output wire [63:0] m_axis_tdata, - output wire [7:0] m_axis_tkeep, - output wire m_axis_tvalid, - input wire m_axis_tready, - output wire m_axis_tlast, - output wire m_axis_tuser, - - /* - * Status signals - */ - output wire busy -); - -/* - -Ethernet frame - - Field Length - Destination MAC address 6 octets - Source MAC address 6 octets - Ethertype 2 octets - -This module receives an Ethernet frame with header fields in parallel along -with the payload in an AXI stream, combines the header with the payload, and -transmits the complete Ethernet frame on the output AXI stream interface. - -*/ - -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_WRITE_HEADER = 3'd1, - STATE_WRITE_HEADER_LAST = 3'd2, - STATE_WRITE_PAYLOAD = 3'd3; - -reg [2:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg store_eth_hdr; - -reg flush_save; -reg transfer_in_save; - -reg [7:0] frame_ptr_reg = 8'd0, frame_ptr_next; - -reg [47:0] eth_dest_mac_reg = 48'd0; -reg [47:0] eth_src_mac_reg = 48'd0; -reg [15:0] eth_type_reg = 16'd0; - -reg s_eth_hdr_ready_reg = 1'b0, s_eth_hdr_ready_next; -reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; - -reg busy_reg = 1'b0; - -reg [63:0] save_eth_payload_axis_tdata_reg = 64'd0; -reg [7:0] save_eth_payload_axis_tkeep_reg = 8'd0; -reg save_eth_payload_axis_tlast_reg = 1'b0; -reg save_eth_payload_axis_tuser_reg = 1'b0; - -reg [63:0] shift_eth_payload_axis_tdata; -reg [7:0] shift_eth_payload_axis_tkeep; -reg shift_eth_payload_axis_tvalid; -reg shift_eth_payload_axis_tlast; -reg shift_eth_payload_axis_tuser; -reg shift_eth_payload_s_tready; -reg shift_eth_payload_extra_cycle_reg = 1'b0; - -// internal datapath -reg [63:0] m_axis_tdata_int; -reg [7:0] m_axis_tkeep_int; -reg m_axis_tvalid_int; -reg m_axis_tready_int_reg = 1'b0; -reg m_axis_tlast_int; -reg m_axis_tuser_int; -wire m_axis_tready_int_early; - -assign s_eth_hdr_ready = s_eth_hdr_ready_reg; -assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; - -assign busy = busy_reg; - -always @* begin - shift_eth_payload_axis_tdata[47:0] = save_eth_payload_axis_tdata_reg[63:16]; - shift_eth_payload_axis_tkeep[5:0] = save_eth_payload_axis_tkeep_reg[7:2]; - - if (shift_eth_payload_extra_cycle_reg) begin - shift_eth_payload_axis_tdata[63:48] = 16'd0; - shift_eth_payload_axis_tkeep[7:6] = 2'd0; - shift_eth_payload_axis_tvalid = 1'b1; - shift_eth_payload_axis_tlast = save_eth_payload_axis_tlast_reg; - shift_eth_payload_axis_tuser = save_eth_payload_axis_tuser_reg; - shift_eth_payload_s_tready = flush_save; - end else begin - shift_eth_payload_axis_tdata[63:48] = s_eth_payload_axis_tdata[15:0]; - shift_eth_payload_axis_tkeep[7:6] = s_eth_payload_axis_tkeep[1:0]; - shift_eth_payload_axis_tvalid = s_eth_payload_axis_tvalid; - shift_eth_payload_axis_tlast = (s_eth_payload_axis_tlast && (s_eth_payload_axis_tkeep[7:2] == 0)); - shift_eth_payload_axis_tuser = (s_eth_payload_axis_tuser && (s_eth_payload_axis_tkeep[7:2] == 0)); - shift_eth_payload_s_tready = !(s_eth_payload_axis_tlast && s_eth_payload_axis_tvalid && transfer_in_save); - end -end - -always @* begin - state_next = STATE_IDLE; - - s_eth_hdr_ready_next = 1'b0; - s_eth_payload_axis_tready_next = 1'b0; - - store_eth_hdr = 1'b0; - - flush_save = 1'b0; - transfer_in_save = 1'b0; - - frame_ptr_next = frame_ptr_reg; - - m_axis_tdata_int = 64'd0; - m_axis_tkeep_int = 8'd0; - m_axis_tvalid_int = 1'b0; - m_axis_tlast_int = 1'b0; - m_axis_tuser_int = 1'b0; - - case (state_reg) - STATE_IDLE: begin - // idle state - wait for data - frame_ptr_next = 8'd0; - flush_save = 1'b1; - s_eth_hdr_ready_next = 1'b1; - - if (s_eth_hdr_ready && s_eth_hdr_valid) begin - store_eth_hdr = 1'b1; - s_eth_hdr_ready_next = 1'b0; - state_next = STATE_WRITE_HEADER; - if (m_axis_tready_int_reg) begin - m_axis_tvalid_int = 1'b1; - m_axis_tdata_int[ 7: 0] = s_eth_dest_mac[47:40]; - m_axis_tdata_int[15: 8] = s_eth_dest_mac[39:32]; - m_axis_tdata_int[23:16] = s_eth_dest_mac[31:24]; - m_axis_tdata_int[31:24] = s_eth_dest_mac[23:16]; - m_axis_tdata_int[39:32] = s_eth_dest_mac[15: 8]; - m_axis_tdata_int[47:40] = s_eth_dest_mac[ 7: 0]; - m_axis_tdata_int[55:48] = s_eth_src_mac[47:40]; - m_axis_tdata_int[63:56] = s_eth_src_mac[39:32]; - m_axis_tkeep_int = 8'hff; - frame_ptr_next = 8'd8; - s_eth_payload_axis_tready_next = m_axis_tready_int_early; - state_next = STATE_WRITE_HEADER_LAST; - end - end else begin - state_next = STATE_IDLE; - end - end - STATE_WRITE_HEADER: begin - // write header - if (m_axis_tready_int_reg) begin - frame_ptr_next = frame_ptr_reg + 8'd8; - m_axis_tvalid_int = 1'b1; - state_next = STATE_WRITE_HEADER; - case (frame_ptr_reg) - 5'd00: begin - m_axis_tdata_int[ 7: 0] = eth_dest_mac_reg[47:40]; - m_axis_tdata_int[15: 8] = eth_dest_mac_reg[39:32]; - m_axis_tdata_int[23:16] = eth_dest_mac_reg[31:24]; - m_axis_tdata_int[31:24] = eth_dest_mac_reg[23:16]; - m_axis_tdata_int[39:32] = eth_dest_mac_reg[15: 8]; - m_axis_tdata_int[47:40] = eth_dest_mac_reg[ 7: 0]; - m_axis_tdata_int[55:48] = eth_src_mac_reg[47:40]; - m_axis_tdata_int[63:56] = eth_src_mac_reg[39:32]; - m_axis_tkeep_int = 8'hff; - s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_s_tready; - state_next = STATE_WRITE_HEADER_LAST; - end - endcase - end else begin - state_next = STATE_WRITE_HEADER; - end - end - STATE_WRITE_HEADER_LAST: begin - // last header word requires first payload word; process accordingly - s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_s_tready; - - if (s_eth_payload_axis_tready && shift_eth_payload_axis_tvalid) begin - frame_ptr_next = frame_ptr_reg + 8'd8; - m_axis_tvalid_int = 1'b1; - transfer_in_save = 1'b1; - - m_axis_tdata_int[ 7: 0] = eth_src_mac_reg[31:24]; - m_axis_tdata_int[15: 8] = eth_src_mac_reg[23:16]; - m_axis_tdata_int[23:16] = eth_src_mac_reg[15: 8]; - m_axis_tdata_int[31:24] = eth_src_mac_reg[ 7: 0]; - m_axis_tdata_int[39:32] = eth_type_reg[15: 8]; - m_axis_tdata_int[47:40] = eth_type_reg[ 7: 0]; - m_axis_tdata_int[55:48] = shift_eth_payload_axis_tdata[55:48]; - m_axis_tdata_int[63:56] = shift_eth_payload_axis_tdata[63:56]; - m_axis_tkeep_int = {shift_eth_payload_axis_tkeep[7:6], 6'h3F}; - m_axis_tlast_int = shift_eth_payload_axis_tlast; - m_axis_tuser_int = shift_eth_payload_axis_tuser; - - if (shift_eth_payload_axis_tlast) begin - s_eth_payload_axis_tready_next = 1'b0; - flush_save = 1'b1; - s_eth_hdr_ready_next = 1'b1; - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_PAYLOAD; - end - end else begin - state_next = STATE_WRITE_HEADER_LAST; - end - end - STATE_WRITE_PAYLOAD: begin - // write payload - s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_s_tready; - - m_axis_tdata_int = shift_eth_payload_axis_tdata; - m_axis_tkeep_int = shift_eth_payload_axis_tkeep; - m_axis_tvalid_int = shift_eth_payload_axis_tvalid; - m_axis_tlast_int = shift_eth_payload_axis_tlast; - m_axis_tuser_int = shift_eth_payload_axis_tuser; - - if (m_axis_tready_int_reg && shift_eth_payload_axis_tvalid) begin - // word transfer through - transfer_in_save = 1'b1; - if (shift_eth_payload_axis_tlast) begin - s_eth_payload_axis_tready_next = 1'b0; - flush_save = 1'b1; - s_eth_hdr_ready_next = 1'b1; - state_next = STATE_IDLE; - end else begin - state_next = STATE_WRITE_PAYLOAD; - end - end else begin - state_next = STATE_WRITE_PAYLOAD; - end - end - endcase -end - -always @(posedge clk) begin - if (rst) begin - state_reg <= STATE_IDLE; - frame_ptr_reg <= 8'd0; - s_eth_hdr_ready_reg <= 1'b0; - s_eth_payload_axis_tready_reg <= 1'b0; - save_eth_payload_axis_tlast_reg <= 1'b0; - shift_eth_payload_extra_cycle_reg <= 1'b0; - busy_reg <= 1'b0; - end else begin - state_reg <= state_next; - - frame_ptr_reg <= frame_ptr_next; - - s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; - - s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; - - busy_reg <= state_next != STATE_IDLE; - - // datapath - if (store_eth_hdr) begin - eth_dest_mac_reg <= s_eth_dest_mac; - eth_src_mac_reg <= s_eth_src_mac; - eth_type_reg <= s_eth_type; - end - - if (flush_save) begin - save_eth_payload_axis_tlast_reg <= 1'b0; - shift_eth_payload_extra_cycle_reg <= 1'b0; - end else if (transfer_in_save) begin - save_eth_payload_axis_tlast_reg <= s_eth_payload_axis_tlast; - shift_eth_payload_extra_cycle_reg <= s_eth_payload_axis_tlast && (s_eth_payload_axis_tkeep[7:2] != 0); - end - end - - // datapath - if (store_eth_hdr) begin - eth_dest_mac_reg <= s_eth_dest_mac; - eth_src_mac_reg <= s_eth_src_mac; - eth_type_reg <= s_eth_type; - end - - if (transfer_in_save) begin - save_eth_payload_axis_tdata_reg <= s_eth_payload_axis_tdata; - save_eth_payload_axis_tkeep_reg <= s_eth_payload_axis_tkeep; - save_eth_payload_axis_tuser_reg <= s_eth_payload_axis_tuser; - end -end - -// output datapath logic -reg [63:0] m_axis_tdata_reg = 64'd0; -reg [7:0] m_axis_tkeep_reg = 8'd0; -reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; -reg m_axis_tlast_reg = 1'b0; -reg m_axis_tuser_reg = 1'b0; - -reg [63:0] temp_m_axis_tdata_reg = 64'd0; -reg [7:0] temp_m_axis_tkeep_reg = 8'd0; -reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; -reg temp_m_axis_tlast_reg = 1'b0; -reg temp_m_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign m_axis_tdata = m_axis_tdata_reg; -assign m_axis_tkeep = m_axis_tkeep_reg; -assign m_axis_tvalid = m_axis_tvalid_reg; -assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = m_axis_tuser_reg; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - m_axis_tvalid_next = m_axis_tvalid_reg; - temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (m_axis_tready_int_reg) begin - // input is ready - if (m_axis_tready || !m_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - m_axis_tvalid_next = m_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_m_axis_tvalid_next = m_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (m_axis_tready) begin - // input is not ready, but output is ready - m_axis_tvalid_next = temp_m_axis_tvalid_reg; - temp_m_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - if (rst) begin - m_axis_tvalid_reg <= 1'b0; - m_axis_tready_int_reg <= 1'b0; - temp_m_axis_tvalid_reg <= 1'b0; - end else begin - m_axis_tvalid_reg <= m_axis_tvalid_next; - m_axis_tready_int_reg <= m_axis_tready_int_early; - temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; - end - - // datapath - if (store_axis_int_to_output) begin - m_axis_tdata_reg <= m_axis_tdata_int; - m_axis_tkeep_reg <= m_axis_tkeep_int; - m_axis_tlast_reg <= m_axis_tlast_int; - m_axis_tuser_reg <= m_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - m_axis_tdata_reg <= temp_m_axis_tdata_reg; - m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; - m_axis_tlast_reg <= temp_m_axis_tlast_reg; - m_axis_tuser_reg <= temp_m_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_m_axis_tdata_reg <= m_axis_tdata_int; - temp_m_axis_tkeep_reg <= m_axis_tkeep_int; - temp_m_axis_tlast_reg <= m_axis_tlast_int; - temp_m_axis_tuser_reg <= m_axis_tuser_int; - end -end - -endmodule diff --git a/tb/test_eth_axis_rx.py b/tb/test_eth_axis_rx.py index bb6ad1e3..e4da51d9 100755 --- a/tb/test_eth_axis_rx.py +++ b/tb/test_eth_axis_rx.py @@ -43,12 +43,18 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = int(DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - s_axis_tdata = Signal(intbv(0)[8:]) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) s_axis_tvalid = Signal(bool(0)) s_axis_tlast = Signal(bool(0)) s_axis_tuser = Signal(bool(0)) @@ -61,7 +67,8 @@ def bench(): m_eth_dest_mac = Signal(intbv(0)[48:]) m_eth_src_mac = Signal(intbv(0)[48:]) m_eth_type = Signal(intbv(0)[16:]) - m_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_eth_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) m_eth_payload_axis_tvalid = Signal(bool(0)) m_eth_payload_axis_tlast = Signal(bool(0)) m_eth_payload_axis_tuser = Signal(bool(0)) @@ -78,6 +85,7 @@ def bench(): clk, rst, tdata=s_axis_tdata, + tkeep=s_axis_tkeep, tvalid=s_axis_tvalid, tready=s_axis_tready, tlast=s_axis_tlast, @@ -97,6 +105,7 @@ def bench(): eth_src_mac=m_eth_src_mac, eth_type=m_eth_type, eth_payload_tdata=m_eth_payload_axis_tdata, + eth_payload_tkeep=m_eth_payload_axis_tkeep, eth_payload_tvalid=m_eth_payload_axis_tvalid, eth_payload_tready=m_eth_payload_axis_tready, eth_payload_tlast=m_eth_payload_axis_tlast, @@ -116,6 +125,7 @@ def bench(): current_test=current_test, s_axis_tdata=s_axis_tdata, + s_axis_tkeep=s_axis_tkeep, s_axis_tvalid=s_axis_tvalid, s_axis_tready=s_axis_tready, s_axis_tlast=s_axis_tlast, @@ -127,6 +137,7 @@ def bench(): m_eth_src_mac=m_eth_src_mac, m_eth_type=m_eth_type, m_eth_payload_axis_tdata=m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep=m_eth_payload_axis_tkeep, m_eth_payload_axis_tvalid=m_eth_payload_axis_tvalid, m_eth_payload_axis_tready=m_eth_payload_axis_tready, m_eth_payload_axis_tlast=m_eth_payload_axis_tlast, @@ -182,7 +193,7 @@ def bench(): yield delay(100) yield clk.posedge - for payload_len in range(1,18): + for payload_len in range(1,KEEP_WIDTH*2+2): yield clk.posedge print("test 1: test packet, length %d" % payload_len) current_test.next = 1 diff --git a/tb/test_eth_axis_rx.v b/tb/test_eth_axis_rx.v index bacd0ddf..4070caee 100644 --- a/tb/test_eth_axis_rx.v +++ b/tb/test_eth_axis_rx.v @@ -31,12 +31,18 @@ THE SOFTWARE. */ module test_eth_axis_rx; +// Parameters +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [7:0] s_axis_tdata = 0; +reg [DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; reg s_axis_tvalid = 0; reg s_axis_tlast = 0; reg s_axis_tuser = 0; @@ -49,7 +55,8 @@ wire m_eth_hdr_valid; wire [47:0] m_eth_dest_mac; wire [47:0] m_eth_src_mac; wire [15:0] m_eth_type; -wire [7:0] m_eth_payload_axis_tdata; +wire [DATA_WIDTH-1:0] m_eth_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep; wire m_eth_payload_axis_tvalid; wire m_eth_payload_axis_tlast; wire m_eth_payload_axis_tuser; @@ -63,6 +70,7 @@ initial begin rst, current_test, s_axis_tdata, + s_axis_tkeep, s_axis_tvalid, s_axis_tlast, s_axis_tuser, @@ -76,6 +84,7 @@ initial begin m_eth_src_mac, m_eth_type, m_eth_payload_axis_tdata, + m_eth_payload_axis_tkeep, m_eth_payload_axis_tvalid, m_eth_payload_axis_tlast, m_eth_payload_axis_tuser, @@ -88,12 +97,17 @@ initial begin $dumpvars(0, test_eth_axis_rx); end -eth_axis_rx +eth_axis_rx #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH) +) UUT ( .clk(clk), .rst(rst), // AXI input .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), .s_axis_tvalid(s_axis_tvalid), .s_axis_tready(s_axis_tready), .s_axis_tlast(s_axis_tlast), @@ -105,6 +119,7 @@ UUT ( .m_eth_src_mac(m_eth_src_mac), .m_eth_type(m_eth_type), .m_eth_payload_axis_tdata(m_eth_payload_axis_tdata), + .m_eth_payload_axis_tkeep(m_eth_payload_axis_tkeep), .m_eth_payload_axis_tvalid(m_eth_payload_axis_tvalid), .m_eth_payload_axis_tready(m_eth_payload_axis_tready), .m_eth_payload_axis_tlast(m_eth_payload_axis_tlast), diff --git a/tb/test_eth_axis_rx_64.py b/tb/test_eth_axis_rx_64.py index c7733a36..ade468f6 100755 --- a/tb/test_eth_axis_rx_64.py +++ b/tb/test_eth_axis_rx_64.py @@ -29,8 +29,8 @@ import os import axis_ep import eth_ep -module = 'eth_axis_rx_64' -testbench = 'test_%s' % module +module = 'eth_axis_rx' +testbench = 'test_%s_64' % module srcs = [] @@ -43,13 +43,18 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = int(DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) current_test = Signal(intbv(0)[8:]) - s_axis_tdata = Signal(intbv(0)[64:]) - s_axis_tkeep = Signal(intbv(0)[8:]) + s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) s_axis_tvalid = Signal(bool(0)) s_axis_tlast = Signal(bool(0)) s_axis_tuser = Signal(bool(0)) @@ -62,8 +67,8 @@ def bench(): m_eth_dest_mac = Signal(intbv(0)[48:]) m_eth_src_mac = Signal(intbv(0)[48:]) m_eth_type = Signal(intbv(0)[16:]) - m_eth_payload_axis_tdata = Signal(intbv(0)[64:]) - m_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + m_eth_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_eth_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) m_eth_payload_axis_tvalid = Signal(bool(0)) m_eth_payload_axis_tlast = Signal(bool(0)) m_eth_payload_axis_tuser = Signal(bool(0)) @@ -188,7 +193,7 @@ def bench(): yield delay(100) yield clk.posedge - for payload_len in range(1,18): + for payload_len in range(1,KEEP_WIDTH*2+2): yield clk.posedge print("test 1: test packet, length %d" % payload_len) current_test.next = 1 @@ -208,7 +213,6 @@ def bench(): yield wait() - yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -244,13 +248,11 @@ def bench(): yield wait() - yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 - yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -288,14 +290,12 @@ def bench(): yield wait() - yield clk.posedge yield sink.wait() rx_frame = sink.recv() assert rx_frame == test_frame1 assert rx_frame.payload.user[-1] - yield clk.posedge yield sink.wait() rx_frame = sink.recv() @@ -336,7 +336,6 @@ def bench(): yield wait() - yield clk.posedge yield sink.wait() rx_frame = sink.recv() diff --git a/tb/test_eth_axis_rx_64.v b/tb/test_eth_axis_rx_64.v index 985e2e56..01bafce7 100644 --- a/tb/test_eth_axis_rx_64.v +++ b/tb/test_eth_axis_rx_64.v @@ -27,17 +27,22 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for eth_axis_rx_64 + * Testbench for eth_axis_rx */ module test_eth_axis_rx_64; +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; reg [7:0] current_test = 0; -reg [63:0] s_axis_tdata = 0; -reg [7:0] s_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] s_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; reg s_axis_tvalid = 0; reg s_axis_tlast = 0; reg s_axis_tuser = 0; @@ -50,8 +55,8 @@ wire m_eth_hdr_valid; wire [47:0] m_eth_dest_mac; wire [47:0] m_eth_src_mac; wire [15:0] m_eth_type; -wire [63:0] m_eth_payload_axis_tdata; -wire [7:0] m_eth_payload_axis_tkeep; +wire [DATA_WIDTH-1:0] m_eth_payload_axis_tdata; +wire [KEEP_WIDTH-1:0] m_eth_payload_axis_tkeep; wire m_eth_payload_axis_tvalid; wire m_eth_payload_axis_tlast; wire m_eth_payload_axis_tuser; @@ -92,7 +97,11 @@ initial begin $dumpvars(0, test_eth_axis_rx_64); end -eth_axis_rx_64 +eth_axis_rx #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH) +) UUT ( .clk(clk), .rst(rst), diff --git a/tb/test_eth_axis_tx.py b/tb/test_eth_axis_tx.py index 229712fe..5f305fbc 100755 --- a/tb/test_eth_axis_tx.py +++ b/tb/test_eth_axis_tx.py @@ -43,6 +43,11 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 8 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = int(DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) @@ -52,14 +57,16 @@ def bench(): s_eth_dest_mac = Signal(intbv(0)[48:]) s_eth_src_mac = Signal(intbv(0)[48:]) s_eth_type = Signal(intbv(0)[16:]) - s_eth_payload_axis_tdata = Signal(intbv(0)[8:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_eth_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) s_eth_payload_axis_tvalid = Signal(bool(0)) s_eth_payload_axis_tlast = Signal(bool(0)) s_eth_payload_axis_tuser = Signal(bool(0)) m_axis_tready = Signal(bool(0)) # Outputs - m_axis_tdata = Signal(intbv(0)[8:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) m_axis_tuser = Signal(bool(0)) @@ -82,6 +89,7 @@ def bench(): eth_src_mac=s_eth_src_mac, eth_type=s_eth_type, eth_payload_tdata=s_eth_payload_axis_tdata, + eth_payload_tkeep=s_eth_payload_axis_tkeep, eth_payload_tvalid=s_eth_payload_axis_tvalid, eth_payload_tready=s_eth_payload_axis_tready, eth_payload_tlast=s_eth_payload_axis_tlast, @@ -96,6 +104,7 @@ def bench(): clk, rst, tdata=m_axis_tdata, + tkeep=m_axis_tkeep, tvalid=m_axis_tvalid, tready=m_axis_tready, tlast=m_axis_tlast, @@ -120,12 +129,14 @@ def bench(): s_eth_src_mac=s_eth_src_mac, s_eth_type=s_eth_type, s_eth_payload_axis_tdata=s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep=s_eth_payload_axis_tkeep, s_eth_payload_axis_tvalid=s_eth_payload_axis_tvalid, s_eth_payload_axis_tready=s_eth_payload_axis_tready, s_eth_payload_axis_tlast=s_eth_payload_axis_tlast, s_eth_payload_axis_tuser=s_eth_payload_axis_tuser, m_axis_tdata=m_axis_tdata, + m_axis_tkeep=m_axis_tkeep, m_axis_tvalid=m_axis_tvalid, m_axis_tready=m_axis_tready, m_axis_tlast=m_axis_tlast, @@ -173,7 +184,7 @@ def bench(): yield delay(100) yield clk.posedge - for payload_len in range(1,18): + for payload_len in range(1,KEEP_WIDTH*2+2): yield clk.posedge print("test 1: test packet, length %d" % payload_len) current_test.next = 1 diff --git a/tb/test_eth_axis_tx.v b/tb/test_eth_axis_tx.v index f72a5723..e1380f93 100644 --- a/tb/test_eth_axis_tx.v +++ b/tb/test_eth_axis_tx.v @@ -31,6 +31,11 @@ THE SOFTWARE. */ module test_eth_axis_tx; +// Parameters +parameter DATA_WIDTH = 8; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; @@ -40,7 +45,8 @@ reg s_eth_hdr_valid = 0; reg [47:0] s_eth_dest_mac = 0; reg [47:0] s_eth_src_mac = 0; reg [15:0] s_eth_type = 0; -reg [7:0] s_eth_payload_axis_tdata = 0; +reg [DATA_WIDTH-1:0] s_eth_payload_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep = 0; reg s_eth_payload_axis_tvalid = 0; reg s_eth_payload_axis_tlast = 0; reg s_eth_payload_axis_tuser = 0; @@ -49,7 +55,8 @@ reg m_axis_tready = 0; // Outputs wire s_eth_payload_axis_tready; wire s_eth_hdr_ready; -wire [7:0] m_axis_tdata; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; wire m_axis_tuser; @@ -66,6 +73,7 @@ initial begin s_eth_src_mac, s_eth_type, s_eth_payload_axis_tdata, + s_eth_payload_axis_tkeep, s_eth_payload_axis_tvalid, s_eth_payload_axis_tlast, s_eth_payload_axis_tuser, @@ -75,6 +83,7 @@ initial begin s_eth_hdr_ready, s_eth_payload_axis_tready, m_axis_tdata, + m_axis_tkeep, m_axis_tvalid, m_axis_tlast, m_axis_tuser, @@ -86,7 +95,11 @@ initial begin $dumpvars(0, test_eth_axis_tx); end -eth_axis_tx +eth_axis_tx #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH) +) UUT ( .clk(clk), .rst(rst), @@ -97,12 +110,14 @@ UUT ( .s_eth_src_mac(s_eth_src_mac), .s_eth_type(s_eth_type), .s_eth_payload_axis_tdata(s_eth_payload_axis_tdata), + .s_eth_payload_axis_tkeep(s_eth_payload_axis_tkeep), .s_eth_payload_axis_tvalid(s_eth_payload_axis_tvalid), .s_eth_payload_axis_tready(s_eth_payload_axis_tready), .s_eth_payload_axis_tlast(s_eth_payload_axis_tlast), .s_eth_payload_axis_tuser(s_eth_payload_axis_tuser), // AXI output .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), .m_axis_tvalid(m_axis_tvalid), .m_axis_tready(m_axis_tready), .m_axis_tlast(m_axis_tlast), diff --git a/tb/test_eth_axis_tx_64.py b/tb/test_eth_axis_tx_64.py index f529c49f..b9e2617b 100755 --- a/tb/test_eth_axis_tx_64.py +++ b/tb/test_eth_axis_tx_64.py @@ -29,8 +29,8 @@ import os import axis_ep import eth_ep -module = 'eth_axis_tx_64' -testbench = 'test_%s' % module +module = 'eth_axis_tx' +testbench = 'test_%s_64' % module srcs = [] @@ -43,6 +43,11 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) def bench(): + # Parameters + DATA_WIDTH = 64 + KEEP_ENABLE = (DATA_WIDTH>8) + KEEP_WIDTH = int(DATA_WIDTH/8) + # Inputs clk = Signal(bool(0)) rst = Signal(bool(0)) @@ -52,20 +57,20 @@ def bench(): s_eth_dest_mac = Signal(intbv(0)[48:]) s_eth_src_mac = Signal(intbv(0)[48:]) s_eth_type = Signal(intbv(0)[16:]) - s_eth_payload_axis_tdata = Signal(intbv(0)[64:]) - s_eth_payload_axis_tkeep = Signal(intbv(0)[8:]) + s_eth_payload_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + s_eth_payload_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) s_eth_payload_axis_tvalid = Signal(bool(0)) s_eth_payload_axis_tlast = Signal(bool(0)) s_eth_payload_axis_tuser = Signal(bool(0)) m_axis_tready = Signal(bool(0)) # Outputs - m_axis_tdata = Signal(intbv(0)[64:]) - m_axis_tkeep = Signal(intbv(0)[8:]) + m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) + m_axis_tkeep = Signal(intbv(1)[KEEP_WIDTH:]) m_axis_tvalid = Signal(bool(0)) m_axis_tlast = Signal(bool(0)) m_axis_tuser = Signal(bool(0)) - s_eth_hdr_ready = Signal(bool(1)) + s_eth_hdr_ready = Signal(bool(0)) s_eth_payload_axis_tready = Signal(bool(0)) busy = Signal(bool(0)) @@ -179,7 +184,7 @@ def bench(): yield delay(100) yield clk.posedge - for payload_len in range(1,18): + for payload_len in range(1,KEEP_WIDTH*2+2): yield clk.posedge print("test 1: test packet, length %d" % payload_len) current_test.next = 1 diff --git a/tb/test_eth_axis_tx_64.v b/tb/test_eth_axis_tx_64.v index 3f16b14e..d8b4737d 100644 --- a/tb/test_eth_axis_tx_64.v +++ b/tb/test_eth_axis_tx_64.v @@ -27,10 +27,15 @@ THE SOFTWARE. `timescale 1ns / 1ps /* - * Testbench for eth_axis_tx_64 + * Testbench for eth_axis_tx */ module test_eth_axis_tx_64; +// Parameters +parameter DATA_WIDTH = 64; +parameter KEEP_ENABLE = (DATA_WIDTH>8); +parameter KEEP_WIDTH = (DATA_WIDTH/8); + // Inputs reg clk = 0; reg rst = 0; @@ -40,8 +45,8 @@ reg s_eth_hdr_valid = 0; reg [47:0] s_eth_dest_mac = 0; reg [47:0] s_eth_src_mac = 0; reg [15:0] s_eth_type = 0; -reg [63:0] s_eth_payload_axis_tdata = 0; -reg [7:0] s_eth_payload_axis_tkeep = 0; +reg [DATA_WIDTH-1:0] s_eth_payload_axis_tdata = 0; +reg [KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep = 0; reg s_eth_payload_axis_tvalid = 0; reg s_eth_payload_axis_tlast = 0; reg s_eth_payload_axis_tuser = 0; @@ -50,8 +55,8 @@ reg m_axis_tready = 0; // Outputs wire s_eth_payload_axis_tready; wire s_eth_hdr_ready; -wire [63:0] m_axis_tdata; -wire [7:0] m_axis_tkeep; +wire [DATA_WIDTH-1:0] m_axis_tdata; +wire [KEEP_WIDTH-1:0] m_axis_tkeep; wire m_axis_tvalid; wire m_axis_tlast; wire m_axis_tuser; @@ -90,7 +95,11 @@ initial begin $dumpvars(0, test_eth_axis_tx_64); end -eth_axis_tx_64 +eth_axis_tx #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH) +) UUT ( .clk(clk), .rst(rst),