├── .github └── ISSUE_TEMPLATE │ ├── vnx-issue-template.md │ └── vnx-xrt-issue-template.md ├── .gitignore ├── .gitmodules ├── Basic_kernels ├── .gitignore ├── Makefile └── src │ ├── krnl_counters.cpp │ ├── krnl_mm2s.cpp │ └── krnl_s2mm.cpp ├── Benchmark_kernel ├── .gitignore ├── Makefile ├── README.md ├── kernel.xml ├── package_switch.tcl ├── package_trafficgen.tcl ├── platform.tcl ├── src │ ├── axi4lite.v │ ├── collector.cpp │ ├── collector_tb.cpp │ ├── segment_generator.v │ ├── segment_generator_tb_producer.v │ ├── switch_wrapper.v │ └── traffic_generator.v ├── switch.xml └── switch_bd.tcl ├── CONTRIBUTING.md ├── Ethernet ├── .gitignore ├── Makefile ├── README.md ├── bd_cmac.tcl ├── duplicate_patch.sh ├── package_cmac.tcl ├── platform.tcl ├── post_sys_link.tcl ├── src │ ├── cmac_0_axi4_lite_user_if.v │ ├── cmac_sync.v │ ├── cmac_synq_false_path.xdc │ ├── frame_padding.v │ ├── rx_sync.v │ └── template_top.v └── template.xml ├── LICENSE.md ├── Makefile ├── NetLayers ├── .gitignore ├── Makefile ├── README.md ├── bd_network_layer.tcl ├── package_netlayer.tcl ├── platform.tcl ├── src │ ├── 6to3_reducer.vhd │ ├── axi4stream_constant.v │ ├── axi4stream_sinker.v │ ├── bandwidth_reg.v │ ├── counter_64_7_v3.vhd │ ├── interface_settings.v │ ├── networklayer.v │ └── performance_debug_reg.v └── template.xml ├── Notebooks ├── README.md ├── dask_pynq.py ├── vnx-basic-image-transfer.ipynb ├── vnx-basic.ipynb ├── vnx-benchmark-rtt-switch.ipynb ├── vnx-benchmark-rtt.ipynb ├── vnx-benchmark-throughput-switch.ipynb ├── vnx-benchmark-throughput.ipynb └── vnx_utils.py ├── README.md ├── THIRD_PARTY_LIC.md ├── config_files ├── connectivity_basic_if0.ini ├── connectivity_basic_if1.ini ├── connectivity_basic_if3.ini ├── connectivity_benchmark_if0.ini ├── connectivity_benchmark_if1.ini └── connectivity_benchmark_if3.ini ├── img ├── cmac_kernel.png ├── jupyterlab.png ├── udp_network_basic.png ├── udp_network_benchmark.png ├── udp_network_benchmark_modes.png └── udp_network_infrastructure.png └── xrt_host_api ├── .gitignore ├── CMakeLists.txt ├── README.md ├── examples ├── ping_fpga │ ├── .gitignore │ ├── CMakeLists.txt │ ├── README.md │ └── ping_fpga.cpp └── test_link │ ├── .gitignore │ ├── CMakeLists.txt │ ├── README.md │ └── test_link.cpp ├── include └── vnx │ ├── cmac.hpp │ ├── mac.hpp │ └── networklayer.hpp └── src ├── cmac.cpp ├── mac.cpp └── networklayer.cpp /.github/ISSUE_TEMPLATE/vnx-issue-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: VNx issues 3 | about: Please only open issues that pertain to VNx 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **For Vivado questions, please use [Vivado forum]( 11 | https://forums.xilinx.com/t5/Vivado-RTL-Development/ct-p/DESIGN)** 12 | 13 | **For Vitis questions, please use [the Vitis forum]( 14 | https://forums.xilinx.com/t5/Vitis-Acceleration-SDAccel-SDSoC/bd-p/tools_v)** 15 | 16 | **For Vitis questions, please use [the Vitis forum]( 17 | https://forums.xilinx.com/t5/Alveo-Accelerator-Cards/bd-p/alveo)** 18 | 19 | **For pynq questions, please use [the PYNQ discussion forum]( 20 | https://discuss.pynq.io/).** 21 | 22 | **Usign Vitis 2021.2 or older? Make sure the [Y2K22 patch is applied]( 23 | https://support.xilinx.com/s/article/76960?language=en_US)** 24 | 25 | If you still want to raise an issue here, please give us as much detail as 26 | possible to the issue you are seeing. We have listed some helpful fields below. 27 | 28 | - Please, use [code snippets](https://docs.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks) to provide textual content instead of images. 29 | 30 | ### Build Issues 31 | 32 | 1. OS version, e.g. `lsb_release -a` 33 | 1. Vitis version `vitis -version` 34 | 1. If Vitis is 2021.2 or older. Is the [Y2K22 patch applied](https://support.xilinx.com/s/article/76960?language=en_US)? 35 | 1. XRT version `xbutil version` 36 | 37 | ### Run Time Issues 38 | 39 | 1. OS version `lsb_release -a` 40 | 1. XRT version `xbutil version` 41 | 1. pynq version `pynq version` 42 | 1. JupyterLab and Dask version if applicable -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/vnx-xrt-issue-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: XRT issues 3 | about: Please only open issues that pertain to the XRT host application 4 | title: '[XRT] ' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | 10 | 11 | **For Vivado questions, please use [Vivado forum]( 12 | https://forums.xilinx.com/t5/Vivado-RTL-Development/ct-p/DESIGN)** 13 | 14 | **For Vitis questions, please use [the Vitis forum]( 15 | https://forums.xilinx.com/t5/Vitis-Acceleration-SDAccel-SDSoC/bd-p/tools_v)** 16 | 17 | **For Vitis questions, please use [the Vitis forum]( 18 | https://forums.xilinx.com/t5/Alveo-Accelerator-Cards/bd-p/alveo)** 19 | 20 | **For pynq questions, please use [the PYNQ discussion forum]( 21 | https://discuss.pynq.io/).** 22 | 23 | **Usign Vitis 2021.2 or older? Make sure the [Y2K22 patch is applied]( 24 | https://support.xilinx.com/s/article/76960?language=en_US)** 25 | 26 | If you still want to raise an issue here, please give us as much detail as 27 | possible to the issue you are seeing. We have listed some helpful fields below. 28 | 29 | - Please, use [code snippets](https://docs.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks) to provide textual content instead of images. 30 | 31 | ### XRT Compile Issues 32 | 33 | 1. OS version, e.g. `lsb_release -a` 34 | 1. Vitis version `vitis -version` 35 | 1. XRT version `xbutil version` 36 | 1. CMake version `cmake --version` 37 | 38 | ### XRT Runtime Issues 39 | 40 | 1. OS version `lsb_release -a` 41 | 1. XRT version `xbutil version` 42 | 1. Alveo card you are targeting and shell 43 | 44 | If using U250 is the second partition programmed? [DFX two-stage](https://support.xilinx.com/s/article/75975?language=en_US) 45 | 46 | Using a design with the two interfaces and XRT 2.13.xyz? https://github.com/Xilinx/xup_vitis_network_example/issues/65 47 | 48 | 1. How did you excecuted the code? Please provide the command(s) 49 | 1. Provide `dmesg` log 50 | 51 | 52 | 53 | 54 | Can @fpgafais please have a look? -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _x/ 2 | *.log 3 | *.jou 4 | v++* 5 | build*/ 6 | .ipcache/ 7 | .ipynb_checkpoints/ 8 | *.tmp.ini 9 | *.xclbin 10 | basic.*/ 11 | benchmark.*/ 12 | __pycache__/ 13 | *.jstack -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "NetLayers/100G-fpga-network-stack-core"] 2 | path = NetLayers/100G-fpga-network-stack-core 3 | url = https://github.com/hpcn-uam/100G-fpga-network-stack-core.git 4 | shallow = true 5 | branch = vnx-vitis-hls 6 | -------------------------------------------------------------------------------- /Basic_kernels/.gitignore: -------------------------------------------------------------------------------- 1 | v++* 2 | _x.*/ 3 | *.log 4 | .Xil/ -------------------------------------------------------------------------------- /Basic_kernels/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help 2 | 3 | help: 4 | @echo "Makefile Usage:" 5 | @echo " make all DEVICE= kernel_list=\""\" 6 | @echo " Command to generate the xo for specified device and Interface." 7 | @echo " By default, DEVICE=xilinx_u280_xdma_201920_3 and kernel_list=\"krnl_s2mm krnl_mm2s\"" 8 | @echo "" 9 | @echo " make clean " 10 | @echo " Command to remove the generated non-hardware files." 11 | @echo "" 12 | @echo " make distclean" 13 | @echo " Command to remove all the generated files." 14 | @echo "" 15 | 16 | 17 | DEVICE ?= xilinx_u280_xdma_201920_3 18 | kernel_list ?= krnl_s2mm krnl_mm2s 19 | 20 | 21 | XSA := $(strip $(patsubst %.xpfm, % , $(shell basename $(DEVICE)))) 22 | TEMP_DIR := _x.$(XSA) 23 | VPP := $(XILINX_VITIS)/bin/v++ 24 | CLFLAGS += -t hw --platform $(DEVICE) --save-temps 25 | BINARY_OBJS = $(addprefix $(TEMP_DIR)/, $(addsuffix .xo, $(kernel_list))) 26 | 27 | 28 | .PHONY: all clean distclean 29 | all: check-devices check-vitis check-xrt $(BINARY_OBJS) 30 | 31 | 32 | # Cleaning stuff 33 | clean: 34 | rm -rf *v++* *.log *.jou 35 | 36 | distclean: clean 37 | rm -rf _x* .Xil 38 | 39 | $(TEMP_DIR)/krnl_mm2s.xo: src/krnl_mm2s.cpp 40 | $(VPP) $(CLFLAGS) -k $(subst $(TEMP_DIR)/,,$(subst .xo,,$@)) -c -o $@ $^ 41 | 42 | $(TEMP_DIR)/krnl_s2mm.xo: src/krnl_s2mm.cpp 43 | $(VPP) $(CLFLAGS) -k $(subst $(TEMP_DIR)/,,$(subst .xo,,$@)) -c -o $@ $^ 44 | 45 | $(TEMP_DIR)/krnl_counters.xo: src/krnl_counters.cpp 46 | $(VPP) $(CLFLAGS) -k $(subst $(TEMP_DIR)/,,$(subst .xo,,$@)) -c -o $@ $^ 47 | 48 | 49 | check-devices: 50 | ifndef DEVICE 51 | $(error DEVICE not set. Please set the DEVICE properly and rerun. Run "make help" for more details.) 52 | endif 53 | 54 | #Checks for XILINX_VITIS 55 | check-vitis: 56 | ifndef XILINX_VITIS 57 | $(error XILINX_VITIS variable is not set, please set correctly and rerun) 58 | endif 59 | 60 | #Checks for XILINX_XRT 61 | check-xrt: 62 | ifndef XILINX_XRT 63 | $(error XILINX_XRT variable is not set, please set correctly and rerun) 64 | endif -------------------------------------------------------------------------------- /Basic_kernels/src/krnl_counters.cpp: -------------------------------------------------------------------------------- 1 | /********** 2 | Copyright (c) 2021, Xilinx, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | ARE DISCLAIMED. 23 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 | INDIRECT, 25 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, 27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28 | BUSINESS INTERRUPTION) 29 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | LIABILITY, 31 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | THIS SOFTWARE, 33 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | **********/ 35 | 36 | /* 37 | * Streaming pass-through kernel that counts number of packets and beats 38 | * These counters can be reseted with a rising edge of reset 39 | */ 40 | 41 | 42 | #include "ap_axi_sdata.h" 43 | #include "ap_int.h" 44 | #include "hls_stream.h" 45 | 46 | #define DWIDTH 512 47 | #define TDWIDTH 16 48 | 49 | typedef ap_axiu pkt; 50 | 51 | ap_uint<7> keep2len(ap_uint<64> keepValue); 52 | 53 | extern "C" { 54 | void krnl_counters( 55 | hls::stream &in, 56 | hls::stream &out, 57 | unsigned int &packets, 58 | unsigned int &beats, 59 | unsigned int &bytes, 60 | bool &reset 61 | ) { 62 | #pragma HLS INTERFACE axis port = out 63 | #pragma HLS INTERFACE axis port = in 64 | #pragma HLS INTERFACE s_axilite port = packets bundle = control 65 | #pragma HLS INTERFACE s_axilite port = beats bundle = control 66 | #pragma HLS INTERFACE s_axilite port = bytes bundle = control 67 | #pragma HLS INTERFACE s_axilite port = reset bundle = control 68 | #pragma HLS INTERFACE ap_ctrl_none port=return 69 | #pragma HLS PIPELINE II=1 70 | 71 | pkt word; 72 | static unsigned int pkts_i = 0; 73 | static unsigned int beats_i = 0; 74 | static unsigned int bytes_i = 0; 75 | static bool reset_1d = 0; 76 | 77 | if (!in.empty()){ 78 | in.read(word); 79 | out.write(word); 80 | beats_i++; 81 | bytes_i += keep2len(word.keep); 82 | if (word.last) 83 | pkts_i++; 84 | } 85 | // Only reset counters when rising edge 86 | else if (reset && !reset_1d) { 87 | pkts_i = 0; 88 | beats_i = 0; 89 | bytes_i = 0; 90 | } 91 | 92 | packets = pkts_i; 93 | beats = beats_i; 94 | bytes = bytes_i; 95 | reset_1d = reset; 96 | 97 | } 98 | } 99 | 100 | ap_uint<7> keep2len(ap_uint<64> keepValue){ 101 | if (keepValue.bit(63)) 102 | return 64; 103 | else if (keepValue.bit(62)) 104 | return 63; 105 | else if (keepValue.bit(61)) 106 | return 62; 107 | else if (keepValue.bit(60)) 108 | return 61; 109 | else if (keepValue.bit(59)) 110 | return 60; 111 | else if (keepValue.bit(58)) 112 | return 59; 113 | else if (keepValue.bit(57)) 114 | return 58; 115 | else if (keepValue.bit(56)) 116 | return 57; 117 | else if (keepValue.bit(55)) 118 | return 56; 119 | else if (keepValue.bit(54)) 120 | return 55; 121 | else if (keepValue.bit(53)) 122 | return 54; 123 | else if (keepValue.bit(52)) 124 | return 53; 125 | else if (keepValue.bit(51)) 126 | return 52; 127 | else if (keepValue.bit(50)) 128 | return 51; 129 | else if (keepValue.bit(49)) 130 | return 50; 131 | else if (keepValue.bit(48)) 132 | return 49; 133 | else if (keepValue.bit(47)) 134 | return 48; 135 | else if (keepValue.bit(46)) 136 | return 47; 137 | else if (keepValue.bit(45)) 138 | return 46; 139 | else if (keepValue.bit(44)) 140 | return 45; 141 | else if (keepValue.bit(43)) 142 | return 44; 143 | else if (keepValue.bit(42)) 144 | return 43; 145 | else if (keepValue.bit(41)) 146 | return 42; 147 | else if (keepValue.bit(40)) 148 | return 41; 149 | else if (keepValue.bit(39)) 150 | return 40; 151 | else if (keepValue.bit(38)) 152 | return 39; 153 | else if (keepValue.bit(37)) 154 | return 38; 155 | else if (keepValue.bit(36)) 156 | return 37; 157 | else if (keepValue.bit(35)) 158 | return 36; 159 | else if (keepValue.bit(34)) 160 | return 35; 161 | else if (keepValue.bit(33)) 162 | return 34; 163 | else if (keepValue.bit(32)) 164 | return 33; 165 | else if (keepValue.bit(31)) 166 | return 32; 167 | else if (keepValue.bit(30)) 168 | return 31; 169 | else if (keepValue.bit(29)) 170 | return 30; 171 | else if (keepValue.bit(28)) 172 | return 29; 173 | else if (keepValue.bit(27)) 174 | return 28; 175 | else if (keepValue.bit(26)) 176 | return 27; 177 | else if (keepValue.bit(25)) 178 | return 26; 179 | else if (keepValue.bit(24)) 180 | return 25; 181 | else if (keepValue.bit(23)) 182 | return 24; 183 | else if (keepValue.bit(22)) 184 | return 23; 185 | else if (keepValue.bit(21)) 186 | return 22; 187 | else if (keepValue.bit(20)) 188 | return 21; 189 | else if (keepValue.bit(19)) 190 | return 20; 191 | else if (keepValue.bit(18)) 192 | return 19; 193 | else if (keepValue.bit(17)) 194 | return 18; 195 | else if (keepValue.bit(16)) 196 | return 17; 197 | else if (keepValue.bit(15)) 198 | return 16; 199 | else if (keepValue.bit(14)) 200 | return 15; 201 | else if (keepValue.bit(13)) 202 | return 14; 203 | else if (keepValue.bit(12)) 204 | return 13; 205 | else if (keepValue.bit(11)) 206 | return 12; 207 | else if (keepValue.bit(10)) 208 | return 11; 209 | else if (keepValue.bit(9)) 210 | return 10; 211 | else if (keepValue.bit(8)) 212 | return 9; 213 | else if (keepValue.bit(7)) 214 | return 8; 215 | else if (keepValue.bit(6)) 216 | return 7; 217 | else if (keepValue.bit(5)) 218 | return 6; 219 | else if (keepValue.bit(4)) 220 | return 5; 221 | else if (keepValue.bit(3)) 222 | return 4; 223 | else if (keepValue.bit(2)) 224 | return 3; 225 | else if (keepValue.bit(1)) 226 | return 2; 227 | else if (keepValue.bit(0)) 228 | return 1; 229 | else 230 | return 0; 231 | 232 | } 233 | -------------------------------------------------------------------------------- /Basic_kernels/src/krnl_mm2s.cpp: -------------------------------------------------------------------------------- 1 | /********** 2 | Copyright (c) 2019-2020, Xilinx, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | ARE DISCLAIMED. 23 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 | INDIRECT, 25 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, 27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28 | BUSINESS INTERRUPTION) 29 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | LIABILITY, 31 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | THIS SOFTWARE, 33 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | **********/ 35 | 36 | /* This is a data mover kernel which reads data from global memory(DDR) via 37 | memory mapped interface 38 | and writes to a stream interface to another kernel */ 39 | 40 | #include "ap_axi_sdata.h" 41 | #include "ap_int.h" 42 | #include "hls_stream.h" 43 | 44 | #define DWIDTH 512 45 | #define TDWIDTH 16 46 | 47 | typedef ap_axiu pkt; 48 | 49 | 50 | extern "C" { 51 | void krnl_mm2s(ap_uint *in, // Read-Only Vector 1 52 | hls::stream &k2n, // Internal Stream 53 | unsigned int size, // Size in bytes 54 | unsigned int dest // destination ID 55 | ) { 56 | #pragma HLS INTERFACE m_axi port = in offset = slave bundle = gmem 57 | #pragma HLS INTERFACE axis port = k2n 58 | #pragma HLS INTERFACE s_axilite port = in bundle = control 59 | #pragma HLS INTERFACE s_axilite port = size bundle = control 60 | #pragma HLS INTERFACE s_axilite port = dest bundle = control 61 | #pragma HLS INTERFACE s_axilite port = return bundle = control 62 | 63 | data_mover: 64 | 65 | unsigned int bytes_per_beat = (DWIDTH / 8); 66 | pkt v; 67 | 68 | // Auto-pipeline is going to apply pipeline to this loop 69 | for (unsigned int i = 0; i < (size / bytes_per_beat); i++) { 70 | #pragma HLS LATENCY min=1 max=1000 71 | #pragma HLS PIPELINE II=1 72 | ap_uint<512> res = in[i]; 73 | v.data = res; 74 | v.keep = -1; 75 | 76 | // set last signals when last piece of data or 77 | // multiple of 1408 bytes, packetize the payload 78 | if ( (((size / bytes_per_beat) - 1)==i) || ((((i + 1) * DWIDTH/8) % 1408) == 0)) 79 | v.last = 1; 80 | else 81 | v.last = 0; 82 | 83 | v.dest = dest; 84 | k2n.write(v); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Basic_kernels/src/krnl_s2mm.cpp: -------------------------------------------------------------------------------- 1 | /********** 2 | Copyright (c) 2019-2020, Xilinx, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | ARE DISCLAIMED. 23 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 | INDIRECT, 25 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, 27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28 | BUSINESS INTERRUPTION) 29 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | LIABILITY, 31 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 | THIS SOFTWARE, 33 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | **********/ 35 | /* This is a stream to memory mapped data mover kernel which takes input from a 36 | stream and writes data 37 | to global memory via memory mapped interface */ 38 | 39 | #include "ap_axi_sdata.h" 40 | #include "ap_int.h" 41 | #include "hls_stream.h" 42 | 43 | #define DWIDTH 512 44 | #define TDWIDTH 16 45 | 46 | typedef ap_axiu pkt; 47 | 48 | extern "C" { 49 | void krnl_s2mm(ap_uint *out, // Write only memory mapped 50 | hls::stream &n2k, // Internal Stream 51 | unsigned int size // Size in bytes 52 | ) { 53 | #pragma HLS INTERFACE m_axi port = out offset = slave bundle = gmem 54 | #pragma HLS INTERFACE axis port = n2k 55 | #pragma HLS INTERFACE s_axilite port = out bundle = control 56 | #pragma HLS INTERFACE s_axilite port = size bundle = control 57 | #pragma HLS INTERFACE s_axilite port = return bundle = control 58 | 59 | unsigned int bytes_per_beat = (DWIDTH / 8); 60 | //unsigned int count = 0: 61 | data_mover: 62 | 63 | int i = 0; 64 | pkt v; 65 | // Auto-pipeline is going to apply pipeline to this loop 66 | for (unsigned int i = 0; i < (size / bytes_per_beat); i++) { 67 | n2k.read(v); 68 | out[i] = v.data; 69 | } 70 | // do { 71 | // n2k.read(v); 72 | // out[i] = v.data; 73 | // count++; 74 | // } while (v.last != 1) 75 | // size = count; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Benchmark_kernel/.gitignore: -------------------------------------------------------------------------------- 1 | _x*/ 2 | packaged*/ 3 | tmp*/ -------------------------------------------------------------------------------- /Benchmark_kernel/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help 2 | 3 | help: 4 | @echo "Makefile Usage:" 5 | @echo " make all DEVICE=" 6 | @echo " Command to generate the xo for specified device." 7 | @echo " By default, DEVICE=xilinx_u280_xdma_201920_3" 8 | @echo "" 9 | @echo " make clean " 10 | @echo " Command to remove the generated non-hardware files." 11 | @echo "" 12 | @echo " make distclean" 13 | @echo " Command to remove all the generated files." 14 | @echo "" 15 | 16 | 17 | DEVICE ?= xilinx_u280_xdma_201920_3 18 | KRNL_NAME_HDL := traffic_generator 19 | KRNL_SWITCH := switch_wrapper 20 | KRNL_NAME_HLS := collector 21 | SUBMODULENAME = 100G-fpga-network-stack-core 22 | 23 | XSA := $(strip $(patsubst %.xpfm, % , $(shell basename $(DEVICE)))) 24 | TEMP_DIR := _x.$(XSA) 25 | VIVADO := $(XILINX_VIVADO)/bin/vivado 26 | VPP := $(XILINX_VITIS)/bin/v++ 27 | CLFLAGS += -t hw --platform $(DEVICE) --save-temps 28 | 29 | BINARY_HLD_OBJS = $(TEMP_DIR)/${KRNL_NAME_HDL}.xo 30 | BINARY_HLD_OBJS += $(TEMP_DIR)/${KRNL_SWITCH}.xo 31 | BINARY_HLS_OBJS = $(TEMP_DIR)/${KRNL_NAME_HLS}.xo 32 | 33 | .PHONY: all clean cleanall 34 | all: check-devices check-vivado check-vitis $(BINARY_HLD_OBJS) $(BINARY_HLS_OBJS) 35 | 36 | 37 | # Cleaning stuff 38 | clean: 39 | rm -rf *v++* *.log *.jou 40 | 41 | distclean: clean 42 | rm -rf build_dir* 43 | rm -rf ./tmp_$(KRNL_NAME_HDL)* ./packaged_kernel* ./tmp_$(KRNL_SWITCH)* 44 | rm -rf _x* *.str 45 | rm -rf .Xil 46 | 47 | 48 | $(TEMP_DIR)/${KRNL_NAME_HDL}.xo: 49 | mkdir -p $(TEMP_DIR) 50 | $(VIVADO) -mode batch -source package_trafficgen.tcl -notrace -tclargs $@ ${KRNL_NAME_HDL} $(XSA) 51 | 52 | $(TEMP_DIR)/${KRNL_SWITCH}.xo: 53 | mkdir -p $(TEMP_DIR) 54 | $(VIVADO) -mode batch -source package_switch.tcl -notrace -tclargs $@ ${KRNL_SWITCH} $(XSA) 55 | 56 | $(TEMP_DIR)/$(KRNL_NAME_HLS).xo: src/$(KRNL_NAME_HLS).cpp 57 | $(VPP) $(CLFLAGS) -k $(subst $(TEMP_DIR)/,,$(subst .xo,,$@)) -c -o $@ $^ 58 | 59 | 60 | check-devices: 61 | ifndef DEVICE 62 | $(error DEVICE not set. Please set the DEVICE properly and rerun. Run "make help" for more details.) 63 | endif 64 | 65 | #Checks for XILINX_VIVADO 66 | check-vivado: 67 | ifndef XILINX_VIVADO 68 | $(error XILINX_VIVADO variable is not set, please set correctly and rerun) 69 | endif 70 | 71 | #Checks for XILINX_VITIS 72 | check-vitis: 73 | ifndef XILINX_VITIS 74 | $(error XILINX_VITIS variable is not set, please set correctly and rerun) 75 | endif -------------------------------------------------------------------------------- /Benchmark_kernel/README.md: -------------------------------------------------------------------------------- 1 | # Benchmark kernel 2 | 3 | This folder contains the source code to generate the benchmark application, which is a mix of RTL and HLS kernels. 4 | 5 | This application is actually split into two independent kernels, [traffic generator](#traffic-generator) and [collector](#collector) 6 | 7 | ## Modes 8 | 9 | First let's see what the benchmark application is capable of. The following figure shows a representation of the four modes available on the benchmark kernel. 10 | 11 | ![](../img/udp_network_benchmark_modes.png) 12 | 13 | * Mode 0, `PRODUCER`. Generates payload with a specif *dest* and size, multiple of 64-Byte up to 1472-Byte, the minimum size is 64-Byte. Only transmitting AXI4-Stream is enabled. 14 | 15 | * Mode 1, `LATENCY`. Generates an 18-Byte payload, it also consume incoming payload (which are reflected from other endpoint) and generate a summary of it that is populated to the collector. All three AXI4-Stream are enabled. 16 | 17 | * Mode 2, `LOOPBACK`. The receiving payload is forwarded, the *dest* can be updated in the transmitter side. Both transmitting and receiving AXI4-Stream are enabled. 18 | 19 | * Mode 3, `CONSUMER`. Consume incoming packets and do nothing else. Only receiving AXI4-Stream is enabled. 20 | 21 | ## Traffic Generator 22 | 23 | The traffic generator kernel is an RTL kernel, and it not only in charge of generating payload, but also consuming payload and generating a summary of incoming payload. 24 | The functionality depends on the mode. 25 | 26 | 27 | ### Payload generator 28 | 29 | The main FSM is in charge of generating the data that will be use as payload in the UDP packets, each payload packet has the following header. 30 | 31 | ```C 32 | struct payload_header { 33 | bit[ 39: 0] packet_id; 34 | bit[ 79: 40] local_timestamp; 35 | bit[119: 80] total_number_packets; 36 | } 37 | ``` 38 | 39 | This header is useful when measuring latency. There is a secondary FSM, which depending on the mode will generate a summary that it is populated to the collector. The summary stream has the following structure. 40 | 41 | ```C 42 | struct summary_struct { 43 | bit[ 39: 0] packet_id; 44 | bit[ 79: 40] tx_local_timestamp; 45 | bit[119: 80] rx_local_timestamp; 46 | } 47 | ``` 48 | 49 | This secondary FSM will assert `tlast` in the summary stream either when the experiment ends, last payload packet was received or when a timeout is reached. 50 | 51 | ### Register map 52 | 53 | |Offset | Name | Mode | Description | 54 | |-------|-----------------------|------|-------------| 55 | | 0x00 | crtl\_signals | R/W | Kernel control signals, more info [here](https://www.xilinx.com/html_docs/xilinx2020_1/vitis_doc/devrtlkernel.html#xvi1504034323705) | 56 | | 0x10 | mode | R/W | Mode selector | 57 | | 0x14 | outbound\_dest | R/W | Set outbound `TDEST` | 58 | | 0x18 | num\_packets\_lsb | R/W | Number of packets LSB | 59 | | 0x1C | num\_packets\_msb | R/W | Number of packets MSB | 60 | | 0x20 | num\_beats | R/W | Number of transactions per piece of payload, the size the payload will be num\_beats * 64-Byte. Max is 23 | 61 | | 0x24 | tbwp | R/W | Clock ticks between two consecutive payload packets | 62 | | 0x28 | reset\_fsm | W | Reset internal FSMs, self clear | 63 | | 0x2C | fsm\_debug\_info | R | Internal FSM state | 64 | | 0x30 | reserved | - | Reserved for future use | 65 | | 0x34 | out\_traffic\_cycles | R | Outbound traffic, number of cycles (64-bit) | 66 | | 0x3C | out\_traffic\_bytes | R | Outbound traffic, number of bytes (64-bit) | 67 | | 0x44 | out\_traffic\_packets | R | Outbound traffic, number of payload packets (64-bit) | 68 | | 0x4C | in\_traffic\_cycles | R | Inbound traffic, number of cycles (64-bit) | 69 | | 0x54 | in\_traffic\_bytes | R | Inbound traffic, number of bytes (64-bit) | 70 | | 0x5C | in\_traffic\_packets | R | Inbound traffic, number of payload packets (64-bit) | 71 | | 0x64 | summary\_cycles | R | Summary traffic, number of cycles (64-bit) | 72 | | 0x6C | summary\_bytes | R | Summary traffic, number of bytes (64-bit) | 73 | | 0x74 | summary\_packets | R | Summary traffic, number of payload packets (64-bit) | 74 | | 0x7C | debug\_reset | W | Reset debug probes, self clear | 75 | 76 | 77 | ## Collector 78 | 79 | The [collector](src/collector.cpp) is an HLS kernel. It should only be enabled when measuring latency. This kernels reads the summary generated by the *payload generator* and performs the following operation for each incoming packet `rx_local_timestamp - tx_local_timestamp`, this result is the Round-Trip Time (RTT) for an individual packet (in clock cycles) and it is represented using 32-bit. The RTT result (32-bit value) for each packet is written to a local memory, in order to maximize throughput with global memory, 16 elements are arranged in a 512-bit vector. Once the local memory is full the results are copied to global memory, again this is done to maximize performance with global memory. The local memory is 512-bit width and 64 rows depth, so I can hold up to 1,024 RTT results. 80 | 81 | When `tlast` is asserted this kernel finishes and moves the local memory to global memory. The total number of received packets can be read from the `received_packets` argument. 82 | 83 | From Software, users should retrieve the results from global memory and multiply each individual result by the clock period in order to convert the RTT measurement to seconds. Statistics such as arithmetic mean, max, min standard deviation can also be computed. The companion notebooks shows how to do this. 84 | 85 | > Note: The clock frequency can vary between implementations and even at runtime. For this reason the conversion from clock cycles to seconds is perform in software. 86 | 87 | --------------------------------------- 88 |
Copyright© 2022 Xilinx
-------------------------------------------------------------------------------- /Benchmark_kernel/kernel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Benchmark_kernel/package_switch.tcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020, Xilinx, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without modification, 5 | # are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its contributors 15 | # may be used to endorse or promote products derived from this software 16 | # without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 | # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | # Copyright (c) 2020 Xilinx, Inc. 28 | 29 | ## Get variables 30 | if { $::argc != 3 } { 31 | puts "ERROR: Program \"$::argv0\" requires 3 arguments!, (${argc} given)\n" 32 | puts "Usage: $::argv0 \n" 33 | exit 34 | } 35 | 36 | set xoname [lindex $::argv 0] 37 | set krnl_name [lindex $::argv 1] 38 | set device [lindex $::argv 2] 39 | 40 | set suffix "${krnl_name}_${device}" 41 | 42 | puts "INFO: xoname-> ${xoname}\n krnl_name-> ${krnl_name}\n device-> ${device}\n suffix -> ${suffix}" 43 | 44 | set projName "kernel_pack" 45 | set bd_name "switch_bd" 46 | set root_dir "[file normalize "."]" 47 | set path_to_hdl "${root_dir}/src" 48 | set path_to_hdl_debug "${root_dir}/../NetLayers/src" 49 | set path_to_packaged "./packaged_kernel_${suffix}" 50 | set path_to_tmp_project "./tmp_${suffix}" 51 | 52 | ## Get projPart 53 | source platform.tcl 54 | 55 | ## Create Vivado project and add IP cores 56 | create_project -force $projName $path_to_tmp_project -part $projPart 57 | 58 | add_files -norecurse ${path_to_hdl}/switch_wrapper.v 59 | 60 | # Create block design 61 | source switch_bd.tcl -notrace 62 | # Set top function 63 | 64 | generate_target all [get_files ${path_to_tmp_project}/${projName}.srcs/sources_1/bd/${bd_name}/${bd_name}.bd] 65 | export_ip_user_files -of_objects [get_files ${path_to_tmp_project}/${projName}.srcs/sources_1/bd/${bd_name}/${bd_name}.bd] -no_script -sync -force -quiet 66 | create_ip_run [get_files -of_objects [get_fileset sources_1] ${path_to_tmp_project}/${projName}.srcs/sources_1/bd/${bd_name}/${bd_name}.bd] 67 | update_compile_order -fileset sources_1 68 | set_property top switch_wrapper [current_fileset] 69 | 70 | # Package IP 71 | ipx::package_project -root_dir ${path_to_packaged} -vendor xilinx.com -library RTLKernel -taxonomy /KernelIP -import_files -set_current false 72 | ipx::unload_core ${path_to_packaged}/component.xml 73 | ipx::edit_ip_in_project -upgrade true -name tmp_edit_project -directory ${path_to_packaged} ${path_to_packaged}/component.xml 74 | set_property core_revision 1 [ipx::current_core] 75 | foreach up [ipx::get_user_parameters] { 76 | ipx::remove_user_parameter [get_property NAME $up] [ipx::current_core] 77 | } 78 | set_property sdx_kernel true [ipx::current_core] 79 | set_property sdx_kernel_type rtl [ipx::current_core] 80 | ipx::create_xgui_files [ipx::current_core] 81 | ipx::add_bus_interface ap_clk [ipx::current_core] 82 | set_property abstraction_type_vlnv xilinx.com:signal:clock_rtl:1.0 [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 83 | set_property bus_type_vlnv xilinx.com:signal:clock:1.0 [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 84 | ipx::add_port_map CLK [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 85 | set_property physical_name ap_clk [ipx::get_port_maps CLK -of_objects [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]]] 86 | ipx::associate_bus_interfaces -busif s_rx_in -clock ap_clk [ipx::current_core] 87 | ipx::associate_bus_interfaces -busif m_rx_out0 -clock ap_clk [ipx::current_core] 88 | ipx::associate_bus_interfaces -busif m_rx_out1 -clock ap_clk [ipx::current_core] 89 | ipx::associate_bus_interfaces -busif m_rx_out2 -clock ap_clk [ipx::current_core] 90 | ipx::associate_bus_interfaces -busif m_rx_out3 -clock ap_clk [ipx::current_core] 91 | ipx::associate_bus_interfaces -busif s_tx_in0 -clock ap_clk [ipx::current_core] 92 | ipx::associate_bus_interfaces -busif s_tx_in1 -clock ap_clk [ipx::current_core] 93 | ipx::associate_bus_interfaces -busif s_tx_in2 -clock ap_clk [ipx::current_core] 94 | ipx::associate_bus_interfaces -busif s_tx_in3 -clock ap_clk [ipx::current_core] 95 | ipx::associate_bus_interfaces -busif m_tx_out -clock ap_clk [ipx::current_core] 96 | 97 | 98 | set_property xpm_libraries {XPM_CDC XPM_MEMORY XPM_FIFO} [ipx::current_core] 99 | set_property supported_families { } [ipx::current_core] 100 | set_property auto_family_support_level level_2 [ipx::current_core] 101 | ipx::update_checksums [ipx::current_core] 102 | ipx::save_core [ipx::current_core] 103 | close_project -delete 104 | 105 | ## Generate XO 106 | if {[file exists "${xoname}"]} { 107 | file delete -force "${xoname}" 108 | } 109 | 110 | package_xo -xo_path ${xoname} -kernel_name ${krnl_name} -ip_directory ./packaged_kernel_${suffix} -kernel_xml ./switch.xml -------------------------------------------------------------------------------- /Benchmark_kernel/package_trafficgen.tcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020, Xilinx, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without modification, 5 | # are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its contributors 15 | # may be used to endorse or promote products derived from this software 16 | # without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 | # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | # Copyright (c) 2020 Xilinx, Inc. 28 | 29 | ## Get variables 30 | if { $::argc != 3 } { 31 | puts "ERROR: Program \"$::argv0\" requires 3 arguments!, (${argc} given)\n" 32 | puts "Usage: $::argv0 \n" 33 | exit 34 | } 35 | 36 | set xoname [lindex $::argv 0] 37 | set krnl_name [lindex $::argv 1] 38 | set device [lindex $::argv 2] 39 | 40 | set suffix "${krnl_name}_${device}" 41 | 42 | puts "INFO: xoname-> ${xoname}\n krnl_name-> ${krnl_name}\n device-> ${device}\n" 43 | 44 | set projName kernel_pack 45 | set root_dir "[file normalize "."]" 46 | set path_to_hdl "${root_dir}/src" 47 | set path_to_hdl_debug "${root_dir}/../NetLayers/src" 48 | set path_to_packaged "./packaged_kernel_${suffix}" 49 | set path_to_tmp_project "./tmp_${suffix}" 50 | 51 | #get projPart 52 | source platform.tcl 53 | 54 | ## Create Vivado project and add IP cores 55 | create_project -force $projName $path_to_tmp_project -part $projPart 56 | 57 | add_files -norecurse ${path_to_hdl} 58 | add_files -norecurse ${path_to_hdl_debug}/bandwidth_reg.v 59 | add_files -norecurse ${path_to_hdl_debug}/6to3_reducer.vhd 60 | add_files -norecurse ${path_to_hdl_debug}/counter_64_7_v3.vhd 61 | 62 | set_property top traffic_generator [current_fileset] 63 | update_compile_order -fileset sources_1 64 | 65 | # Package IP 66 | 67 | ipx::package_project -root_dir ${path_to_packaged} -vendor xilinx.com -library RTLKernel -taxonomy /KernelIP -import_files -set_current false 68 | ipx::unload_core ${path_to_packaged}/component.xml 69 | ipx::edit_ip_in_project -upgrade true -name tmp_edit_project -directory ${path_to_packaged} ${path_to_packaged}/component.xml 70 | set_property core_revision 1 [ipx::current_core] 71 | foreach up [ipx::get_user_parameters] { 72 | ipx::remove_user_parameter [get_property NAME $up] [ipx::current_core] 73 | } 74 | set_property sdx_kernel true [ipx::current_core] 75 | set_property sdx_kernel_type rtl [ipx::current_core] 76 | ipx::create_xgui_files [ipx::current_core] 77 | ipx::add_bus_interface ap_clk [ipx::current_core] 78 | set_property abstraction_type_vlnv xilinx.com:signal:clock_rtl:1.0 [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 79 | set_property bus_type_vlnv xilinx.com:signal:clock:1.0 [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 80 | ipx::add_port_map CLK [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 81 | set_property physical_name ap_clk [ipx::get_port_maps CLK -of_objects [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]]] 82 | ipx::associate_bus_interfaces -busif S_AXIS_n2k -clock ap_clk [ipx::current_core] 83 | ipx::associate_bus_interfaces -busif M_AXIS_k2n -clock ap_clk [ipx::current_core] 84 | ipx::associate_bus_interfaces -busif M_AXIS_summary -clock ap_clk [ipx::current_core] 85 | ipx::associate_bus_interfaces -busif S_AXIL -clock ap_clk [ipx::current_core] 86 | 87 | 88 | set_property xpm_libraries {XPM_CDC XPM_MEMORY XPM_FIFO} [ipx::current_core] 89 | set_property supported_families { } [ipx::current_core] 90 | set_property auto_family_support_level level_2 [ipx::current_core] 91 | ipx::update_checksums [ipx::current_core] 92 | ipx::save_core [ipx::current_core] 93 | close_project -delete 94 | 95 | ## Generate XO 96 | if {[file exists "${xoname}"]} { 97 | file delete -force "${xoname}" 98 | } 99 | 100 | package_xo -xo_path ${xoname} -kernel_name ${krnl_name} -ip_directory ./packaged_kernel_${suffix} -kernel_xml ./kernel.xml 101 | -------------------------------------------------------------------------------- /Benchmark_kernel/platform.tcl: -------------------------------------------------------------------------------- 1 | ../NetLayers/platform.tcl -------------------------------------------------------------------------------- /Benchmark_kernel/src/collector.cpp: -------------------------------------------------------------------------------- 1 | /************************************************ 2 | Copyright (c) 2020, Xilinx, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// Copyright (c) 2020 Xilinx, Inc. 28 | ************************************************/ 29 | 30 | #include "ap_axi_sdata.h" 31 | #include "ap_int.h" 32 | #include "hls_stream.h" 33 | 34 | #define DWIDTH 128 35 | #define LOCAL_MEM_DEPTH 64 36 | #define VECTOR_WIDTH 512 37 | 38 | typedef ap_axiu pkt; 39 | 40 | void collector(ap_uint *out, 41 | hls::stream &summary, 42 | ap_uint<40> &received_packets) { 43 | 44 | ap_uint local_mem[LOCAL_MEM_DEPTH]; 45 | ap_uint vector_word; 46 | ap_uint< 32> global_memory_offset = 0; 47 | ap_uint< 40> total_pkts_reg = 0; 48 | ap_uint< 40> total_consecutive = 0; 49 | ap_uint< 40> nextId = 0; 50 | ap_uint< 32> latency = 0; 51 | bool move_data = false; 52 | bool end_loop = false; 53 | pkt currWord; 54 | unsigned int max_elements_local_memory = (VECTOR_WIDTH/32) * LOCAL_MEM_DEPTH; 55 | unsigned int local_occupancy; 56 | 57 | #pragma HLS BIND_STORAGE variable=local_mem type=ram_2p impl=bram 58 | while (!end_loop) { 59 | if (move_data) { 60 | move_data = false; 61 | // Move local memory to global memory to get ready for the next batch 62 | // This stall in data consumption should be buffered by the input FIFO 63 | data_mover: 64 | for(unsigned int m = 0; m < LOCAL_MEM_DEPTH; m++){ 65 | #pragma HLS PIPELINE 66 | out[global_memory_offset] = local_mem[m]; 67 | global_memory_offset++; 68 | } 69 | 70 | } 71 | else if (!summary.empty()){ 72 | summary.read(currWord); 73 | // tlast indicates the end of a test and the content is dummy 74 | if (currWord.last){ 75 | end_loop = true; 76 | } 77 | else { 78 | ap_uint< 40> currId = currWord.data(39,0); 79 | if (currId == nextId){ 80 | total_consecutive++; 81 | } 82 | nextId = currId + 1; 83 | latency = currWord.data(119,80) - currWord.data( 79, 40); 84 | unsigned int i = total_pkts_reg(3,0); // Get position in the vector 85 | unsigned int j = total_pkts_reg(9,4); // Get position in the local memory 86 | vector_word((i * 32) + 31 ,(i * 32)) = latency; 87 | // Store vector word in local memory even though it may not be full 88 | local_mem[j] = vector_word; 89 | total_pkts_reg++; 90 | // If the local memory is full prepare to move it next cycle 91 | if ((total_pkts_reg % (max_elements_local_memory)) == 0) { 92 | move_data = true; 93 | } 94 | } 95 | } 96 | } 97 | 98 | // Get the amount of rows to be moved, number of full occupied rows + a potential half-full row 99 | local_occupancy = total_pkts_reg(9,4) + ((total_pkts_reg(3,0) != 0) ? 1 : 0); 100 | // Move remaining rows if any 101 | data_mover_partial: 102 | for(unsigned int m = 0; m < local_occupancy; m++){ 103 | #pragma HLS LOOP_TRIPCOUNT max=64 min=1 104 | #pragma HLS PIPELINE 105 | out[global_memory_offset] = local_mem[m]; 106 | global_memory_offset++; 107 | } 108 | 109 | received_packets = total_pkts_reg; 110 | 111 | } 112 | -------------------------------------------------------------------------------- /Benchmark_kernel/src/collector_tb.cpp: -------------------------------------------------------------------------------- 1 | /************************************************ 2 | Copyright (c) 2020, Xilinx, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// Copyright (c) 2020 Xilinx, Inc. 28 | ************************************************/ 29 | 30 | #include "ap_axi_sdata.h" 31 | #include "ap_int.h" 32 | #include "hls_stream.h" 33 | 34 | #define DWIDTH 128 35 | #define LOCAL_MEM_DEPTH 64 36 | #define VECTOR_WIDTH 512 37 | 38 | typedef ap_axiu pkt; 39 | 40 | 41 | void collector(ap_uint *out, 42 | hls::stream &summary, 43 | ap_uint<40> &received_packets); 44 | 45 | hls::stream summary("summary"); 46 | 47 | void fillStream (void){ 48 | unsigned int num_pkts = 33; 49 | pkt currWord; 50 | for (unsigned int i = 0 ; i < num_pkts; i++){ 51 | currWord.data( 39, 0) = (ap_uint<40>) i; 52 | currWord.data( 79, 40) = 0x57438 + i * 8; // Fake tx timestamp 53 | currWord.data(119, 80) = 0x57738 + i * 15; // Fake rx timestamp 54 | currWord.last = 0; 55 | summary.write(currWord); 56 | } 57 | // Send dummy word to finish processing 58 | currWord.last = 1; 59 | summary.write(currWord); 60 | } 61 | 62 | int main (void){ 63 | 64 | ap_uint global_memory[2048]; 65 | ap_uint<40> received_packets; 66 | 67 | std::cout << "Stating simulation " << std::endl; 68 | fillStream(); 69 | 70 | collector(global_memory, 71 | summary, 72 | received_packets); 73 | 74 | std::cout << "Total received packets " << received_packets << std::endl; 75 | 76 | unsigned int addr = 0; 77 | unsigned int m; 78 | 79 | for (unsigned int i = 0; i < received_packets ; i++){ 80 | m = i % 16; 81 | std::cout << "Packet ["<< std::setw(4) << i << "] Address [" << std::setw(3) << addr << "] position ["; 82 | std::cout << std::setw(2) << m << "] value: " << global_memory[addr]((m*32) + 31,m*32) << std::endl; 83 | if (((i+1) % 16) == 0) 84 | addr++; 85 | } 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /Benchmark_kernel/src/switch_wrapper.v: -------------------------------------------------------------------------------- 1 | /************************************************ 2 | Copyright (c) 2020, Xilinx, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// Copyright (c) 2020 Xilinx, Inc. 28 | ************************************************/ 29 | 30 | `default_nettype wire 31 | `timescale 1 ps / 1 ps 32 | 33 | module switch_wrapper ( 34 | // System clock and reset 35 | (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 ap_clk CLK" *) 36 | (* X_INTERFACE_PARAMETER = "ASSOCIATED_BUSIF s_rx_in:m_rx_out0:m_rx_out1:m_rx_out2:m_rx_out3:s_tx_in0:s_tx_in1:s_tx_in2:s_tx_in3:m_tx_out, ASSOCIATED_RESET ap_rst_n" *) 37 | input wire ap_clk, 38 | (* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 ap_rst_n RST" *) 39 | (* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_LOW" *) 40 | input wire ap_rst_n, 41 | 42 | // Rx path 43 | input wire [511:0] s_rx_in_tdata, 44 | input wire [63:0] s_rx_in_tkeep, 45 | input wire s_rx_in_tvalid, 46 | input wire s_rx_in_tlast, 47 | input wire [15:0] s_rx_in_tdest, 48 | output wire s_rx_in_tready, 49 | 50 | output wire [511:0] m_rx_out0_tdata, 51 | output wire [63:0] m_rx_out0_tkeep, 52 | output wire m_rx_out0_tvalid, 53 | output wire m_rx_out0_tlast, 54 | output wire [15:0] m_rx_out0_tdest, 55 | input wire m_rx_out0_tready, 56 | 57 | output wire [511:0] m_rx_out1_tdata, 58 | output wire [63:0] m_rx_out1_tkeep, 59 | output wire m_rx_out1_tvalid, 60 | output wire m_rx_out1_tlast, 61 | output wire [15:0] m_rx_out1_tdest, 62 | input wire m_rx_out1_tready, 63 | 64 | output wire [511:0] m_rx_out2_tdata, 65 | output wire [63:0] m_rx_out2_tkeep, 66 | output wire m_rx_out2_tvalid, 67 | output wire m_rx_out2_tlast, 68 | output wire [15:0] m_rx_out2_tdest, 69 | input wire m_rx_out2_tready, 70 | 71 | output wire [511:0] m_rx_out3_tdata, 72 | output wire [63:0] m_rx_out3_tkeep, 73 | output wire m_rx_out3_tvalid, 74 | output wire m_rx_out3_tlast, 75 | output wire [15:0] m_rx_out3_tdest, 76 | input wire m_rx_out3_tready, 77 | 78 | // Tx path 79 | input wire [511:0] s_tx_in0_tdata, 80 | input wire [63:0] s_tx_in0_tkeep, 81 | input wire s_tx_in0_tvalid, 82 | input wire s_tx_in0_tlast, 83 | input wire [15:0] s_tx_in0_tdest, 84 | output wire s_tx_in0_tready, 85 | 86 | input wire [511:0] s_tx_in1_tdata, 87 | input wire [63:0] s_tx_in1_tkeep, 88 | input wire s_tx_in1_tvalid, 89 | input wire s_tx_in1_tlast, 90 | input wire [15:0] s_tx_in1_tdest, 91 | output wire s_tx_in1_tready, 92 | 93 | input wire [511:0] s_tx_in2_tdata, 94 | input wire [63:0] s_tx_in2_tkeep, 95 | input wire s_tx_in2_tvalid, 96 | input wire s_tx_in2_tlast, 97 | input wire [15:0] s_tx_in2_tdest, 98 | output wire s_tx_in2_tready, 99 | 100 | input wire [511:0] s_tx_in3_tdata, 101 | input wire [63:0] s_tx_in3_tkeep, 102 | input wire s_tx_in3_tvalid, 103 | input wire s_tx_in3_tlast, 104 | input wire [15:0] s_tx_in3_tdest, 105 | output wire s_tx_in3_tready, 106 | 107 | output wire [511:0] m_tx_out_tdata, 108 | output wire [63:0] m_tx_out_tkeep, 109 | output wire m_tx_out_tvalid, 110 | output wire m_tx_out_tlast, 111 | output wire [15:0] m_tx_out_tdest, 112 | input wire m_tx_out_tready 113 | ); 114 | 115 | 116 | switch_bd switch_bd_i ( 117 | .ap_clk ( ap_clk), 118 | .ap_rst_n ( ap_rst_n), 119 | 120 | .rx_in_tdata ( s_rx_in_tdata), 121 | .rx_in_tkeep ( s_rx_in_tkeep), 122 | .rx_in_tvalid ( s_rx_in_tvalid), 123 | .rx_in_tlast ( s_rx_in_tlast), 124 | .rx_in_tdest ( s_rx_in_tdest), 125 | .rx_in_tready ( s_rx_in_tready), 126 | 127 | .rx_out0_tdata ( m_rx_out0_tdata), 128 | .rx_out0_tkeep ( m_rx_out0_tkeep), 129 | .rx_out0_tvalid ( m_rx_out0_tvalid), 130 | .rx_out0_tlast ( m_rx_out0_tlast), 131 | .rx_out0_tdest ( m_rx_out0_tdest), 132 | .rx_out0_tready ( m_rx_out0_tready), 133 | 134 | .rx_out1_tdata ( m_rx_out1_tdata), 135 | .rx_out1_tkeep ( m_rx_out1_tkeep), 136 | .rx_out1_tvalid ( m_rx_out1_tvalid), 137 | .rx_out1_tlast ( m_rx_out1_tlast), 138 | .rx_out1_tdest ( m_rx_out1_tdest), 139 | .rx_out1_tready ( m_rx_out1_tready), 140 | 141 | .rx_out2_tdata ( m_rx_out2_tdata), 142 | .rx_out2_tkeep ( m_rx_out2_tkeep), 143 | .rx_out2_tvalid ( m_rx_out2_tvalid), 144 | .rx_out2_tlast ( m_rx_out2_tlast), 145 | .rx_out2_tdest ( m_rx_out2_tdest), 146 | .rx_out2_tready ( m_rx_out2_tready), 147 | 148 | .rx_out3_tdata ( m_rx_out3_tdata), 149 | .rx_out3_tkeep ( m_rx_out3_tkeep), 150 | .rx_out3_tvalid ( m_rx_out3_tvalid), 151 | .rx_out3_tlast ( m_rx_out3_tlast), 152 | .rx_out3_tdest ( m_rx_out3_tdest), 153 | .rx_out3_tready ( m_rx_out3_tready), 154 | 155 | .tx_in0_tdata ( s_tx_in0_tdata), 156 | .tx_in0_tkeep ( s_tx_in0_tkeep), 157 | .tx_in0_tvalid ( s_tx_in0_tvalid), 158 | .tx_in0_tlast ( s_tx_in0_tlast), 159 | .tx_in0_tdest ( s_tx_in0_tdest), 160 | .tx_in0_tready ( s_tx_in0_tready), 161 | 162 | .tx_in1_tdata ( s_tx_in1_tdata), 163 | .tx_in1_tkeep ( s_tx_in1_tkeep), 164 | .tx_in1_tvalid ( s_tx_in1_tvalid), 165 | .tx_in1_tlast ( s_tx_in1_tlast), 166 | .tx_in1_tdest ( s_tx_in1_tdest), 167 | .tx_in1_tready ( s_tx_in1_tready), 168 | 169 | .tx_in2_tdata ( s_tx_in2_tdata), 170 | .tx_in2_tkeep ( s_tx_in2_tkeep), 171 | .tx_in2_tvalid ( s_tx_in2_tvalid), 172 | .tx_in2_tlast ( s_tx_in2_tlast), 173 | .tx_in2_tdest ( s_tx_in2_tdest), 174 | .tx_in2_tready ( s_tx_in2_tready), 175 | 176 | .tx_in3_tdata ( s_tx_in3_tdata), 177 | .tx_in3_tkeep ( s_tx_in3_tkeep), 178 | .tx_in3_tvalid ( s_tx_in3_tvalid), 179 | .tx_in3_tlast ( s_tx_in3_tlast), 180 | .tx_in3_tdest ( s_tx_in3_tdest), 181 | .tx_in3_tready ( s_tx_in3_tready), 182 | 183 | .tx_out_tdata ( m_tx_out_tdata), 184 | .tx_out_tkeep ( m_tx_out_tkeep), 185 | .tx_out_tvalid ( m_tx_out_tvalid), 186 | .tx_out_tlast ( m_tx_out_tlast), 187 | .tx_out_tdest ( m_tx_out_tdest), 188 | .tx_out_tready ( m_tx_out_tready) 189 | ); 190 | 191 | endmodule 192 | -------------------------------------------------------------------------------- /Benchmark_kernel/switch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to VNx 2 | 3 | We welcome contributions to VNx! You can contribute to VNx in a variety of ways. You can report bugs and feature requests using [GitHub Issues](https://github.com/Xilinx/xup_vitis_network_example/issues). You can send patches which add new features to VNx or fix bugs in VNx. You can also send patches to update VNx documentation. 4 | 5 | ## Reporting Issues 6 | 7 | When reporting issues on GitHub, please include the following. 8 | 9 | Use [snippets](https://docs.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks) instead of images when reporting these, it is much easier to track the problem. 10 | 11 | ### Build Issues 12 | 13 | 1. OS version `lsb_release -a` 14 | 1. Vivado version `vivado -version` 15 | 1. XRT version `xbutil version` 16 | 17 | ### Run Time Issues 18 | 19 | 1. OS version `lsb_release -a` 20 | 1. XRT version `xbutil version` 21 | 1. pynq version `pynq version` 22 | 1. Jupyter Lab and Dask version if applies 23 | 24 | ## Contributing Code 25 | 26 | Please use [GitHub Pull Requests (PR)](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) for sending code contributions. When sending code sign your work as described below. Be sure to use the same license for your contributions as the current license of the VNx component you are contributing to. 27 | 28 | 29 | ## Sign Your Work 30 | 31 | Please use the *Signed-off-by* line at the end of your patch which indicates that you accept the Developer Certificate of Origin (DCO) defined by https://developercertificate.org/ reproduced below: 32 | 33 | ``` 34 | Developer Certificate of Origin 35 | Version 1.1 36 | 37 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 38 | 1 Letterman Drive 39 | Suite D4700 40 | San Francisco, CA, 94129 41 | 42 | Everyone is permitted to copy and distribute verbatim copies of this 43 | license document, but changing it is not allowed. 44 | 45 | 46 | Developer's Certificate of Origin 1.1 47 | 48 | By making a contribution to this project, I certify that: 49 | 50 | (a) The contribution was created in whole or in part by me and I 51 | have the right to submit it under the open source license 52 | indicated in the file; or 53 | 54 | (b) The contribution is based upon previous work that, to the best 55 | of my knowledge, is covered under an appropriate open source 56 | license and I have the right under that license to submit that 57 | work with modifications, whether created in whole or in part 58 | by me, under the same open source license (unless I am 59 | permitted to submit under a different license), as indicated 60 | in the file; or 61 | 62 | (c) The contribution was provided directly to me by some other 63 | person who certified (a), (b) or (c) and I have not modified 64 | it. 65 | 66 | (d) I understand and agree that this project and the contribution 67 | are public and that a record of the contribution (including all 68 | personal information I submit with it, including my sign-off) is 69 | maintained indefinitely and may be redistributed consistent with 70 | this project or the open source license(s) involved. 71 | ``` 72 | 73 | Here is an example Signed-off-by line which indicates that the contributor accepts DCO: 74 | 75 | ``` 76 | This is my commit message 77 | 78 | Signed-off-by: Jane Doe 79 | ``` 80 | 81 | 82 | ## Contribution Review 83 | 84 | If any additional fixes or modifications are necessary, we may provide feedback to guide 85 | you. When accepted, your pull request will be merged to the repository. 86 | 87 | ## Code License 88 | 89 | All VNx code is licensed under the terms [LICENSE.m](LICENSE.md). Your contribution will be accepted under the same license. 90 | 91 | Third party is licensed under the terms [THIRD_PARTY_LIC.md](THIRD_PARTY_LIC.md) 92 | 93 | ------------------------------------------------------ 94 |

Copyright© 2021 Xilinx

-------------------------------------------------------------------------------- /Ethernet/.gitignore: -------------------------------------------------------------------------------- 1 | kernel*.xml 2 | tmp_cmac*/ 3 | _x.* 4 | packaged_kernel*/ 5 | *.log 6 | *.jou 7 | src/cmac_top*.v -------------------------------------------------------------------------------- /Ethernet/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help 2 | 3 | help: 4 | @echo "Makefile Usage:" 5 | @echo " make all DEVICE= INTERFACE=" 6 | @echo " Command to generate the xo for specified device and Interface." 7 | @echo " By default, DEVICE=xilinx_u280_xdma_201920_3 and INTERFACE=0" 8 | @echo " INTERFACE can be 0, 1 or 3 (both interface 0 and 1 simultaneously)" 9 | @echo "" 10 | @echo " make clean " 11 | @echo " Command to remove the generated non-hardware files." 12 | @echo "" 13 | @echo " make distclean" 14 | @echo " Command to remove all the generated files." 15 | @echo "" 16 | 17 | 18 | DEVICE ?= xilinx_u280_xdma_201920_3 19 | INTERFACE ?= 0 20 | KRNL_NAME = cmac 21 | PADDING_MODE ?= 1 22 | 23 | XSA := $(strip $(patsubst %.xpfm, % , $(shell basename $(DEVICE)))) 24 | TEMP_DIR := _x.$(XSA) 25 | VIVADO := $(XILINX_VIVADO)/bin/vivado 26 | 27 | 28 | BINARY_NETLAYER_OBJS := $(TEMP_DIR)/${KRNL_NAME}_$(INTERFACE).xo 29 | 30 | #Overwrite targets when INTERFACE equals 3 31 | ifeq (3,$(INTERFACE)) 32 | BINARY_NETLAYER_OBJS := $(TEMP_DIR)/${KRNL_NAME}_0.xo 33 | BINARY_NETLAYER_OBJS += $(TEMP_DIR)/${KRNL_NAME}_1.xo 34 | endif 35 | 36 | .PHONY: all clean distclean 37 | all: check-devices check-vivado check-interface $(BINARY_NETLAYER_OBJS) 38 | 39 | 40 | # Cleaning stuff 41 | clean: 42 | rm -rf *v++* *.log *.jou 43 | 44 | distclean: clean 45 | rm -rf build_dir* 46 | rm -rf _x.* kernel_*.xml src/cmac_top*.v *.str 47 | rm -rf ./tmp_cmac* ./packaged_kernel* .Xil 48 | rm -rf component.xml xgui/ 49 | 50 | 51 | $(TEMP_DIR)/${KRNL_NAME}%.xo: current_interface=$(subst $(TEMP_DIR)/${KRNL_NAME}_,,$(subst .xo,,$@)) 52 | $(TEMP_DIR)/${KRNL_NAME}%.xo: template.xml package_cmac.tcl bd_cmac.tcl src/*.v 53 | mkdir -p $(TEMP_DIR) 54 | ./duplicate_patch.sh 55 | $(VIVADO) -mode batch -source package_cmac.tcl -notrace -tclargs $@ ${KRNL_NAME}_$(current_interface) $(XSA) $(current_interface) $(PADDING_MODE) 56 | 57 | 58 | check-devices: 59 | ifndef DEVICE 60 | $(error DEVICE not set. Please set the DEVICE properly and rerun. Run "make help" for more details.) 61 | endif 62 | 63 | #Checks for XILINX_VIVADO 64 | check-vivado: 65 | ifndef XILINX_VIVADO 66 | $(error XILINX_VIVADO variable is not set, please set correctly and rerun) 67 | endif 68 | 69 | check-interface: 70 | ifeq (2,$(INTERFACE)) 71 | $(error INTERFACE cannot value 2, to use generate both interfaces xo use INTERFACE=3) 72 | endif 73 | -------------------------------------------------------------------------------- /Ethernet/README.md: -------------------------------------------------------------------------------- 1 | # CMAC Kernel 2 | 3 | This documents provides an overview of the cmac kernel. 4 | 5 | ## The cmac kernel 6 | 7 | The `cmac` kernel is an RTL free running kernel which encapsulates the [UltraScale+ Integrated 100G Ethernet Subsystem](https://www.xilinx.com/products/intellectual-property/cmac_usplus.html). The kernel uses `ap_ctrl_none` as hardware control protocol. 8 | 9 | This kernel is configured according to the `INTERFACE`, `DEVICE`, and `PADDING_MODE` arguments passed to make. It exposes two 512-bit AXI4-Stream interfaces (S_AXIS and M_AXIS) to the user logic, which run at the same frequency as the kernel, internally it has CDC (clock domain crossing) logic to convert from kernel clock to the 100G Ethernet Subsystem clock. It also provides and AXI4-Lite interface to check the UltraScale+ Integrated 100G Ethernet Subsystem register map. 10 | 11 | ![](../img/cmac_kernel.png) 12 | 13 | ### UltraScale+ Integrated 100G Ethernet Subsystem 14 | 15 | The 100G Ethernet Subsystem offers an integrated 100 Gigabit per second (Gbps) Ethernet Media Access Controller (MAC), Physical Coding Sublayer (PCS), IEEE 802.3bj Reed-Solomon Forward Error Correction (RS-FEC), and 100GE Auto-Negotiation/Link Training (AN/LT) IP to enable solutions such as KR4, CR4, SR4, CWDM4, PSM4, or ER4f for high performance applications. 16 | 17 | > **Note:** Auto-Negotiation/Link Training is not enabled in this kernel. 18 | 19 | ### cmac_sync 20 | 21 | This IP implements the Core Bring Up Sequence described in the [PG203](https://docs.xilinx.com/v/u/en-US/pg203-cmac-usplus) 22 | 23 | ### frame_padding 24 | 25 | This IP implements optional frame padding to 60 or 64 bytes. The padding mode is set at compile-time by the `PADDING_MODE` parameter as follows: mode `0` indicates no padding, mode `1` (default) pads to 60 bytes, and mode `2` pads to 64 bytes. 26 | 27 | ### Clock Domain Crossing 28 | 29 | The Rx and Tx AXI4-Stream interfaces in the UltraScale+ Integrated 100G Ethernet Subsystem operate at 322.265625 MHz. To accommodate for a different frequency in the rest of the design cross domain crossing is included in the Tx path (acc_kernel_tx_cdc and fifo_cmac_tx) and Rx path (fifo_cmac_rx_cdc). 30 | 31 | ### Register map 32 | 33 | The UltraScale+ Integrated 100G Ethernet Subsystem register map (described in the [PG203](https://docs.xilinx.com/v/u/en-US/pg203-cmac-usplus)) is accessible via the AXI4-Lite interface. Many of these registers have been conveniently mapped into the kernel arguments using the [template.xml](template.xml) file. 34 | If you wish to access a register that is not mapped, you can use the [pynq MMIO](https://pynq.readthedocs.io/en/latest/pynq_package/pynq.mmio.html#module-pynq.mmio) read and write methods. 35 | 36 | For instance: 37 | 38 | ```python 39 | # Read CONFIGURATION_AN_ABILITY register 40 | cmac.read(0xA8) 41 | # Set ctl_an_ability_1000base_kx in the CONFIGURATION_AN_ABILITY register 42 | cmac.write(0xA8, 0x1) 43 | ``` 44 | 45 | You could also modify the [template.xml](template.xml) file to add more registers. Care must be taken when modifying this file, make sure id are properly changed. Once the [template.xml](template.xml) file is modified, you will have to rebuild the design for these changes to be included in the xclbin. Remove all \*.xo files in this folder after changing [template.xml](template.xml). 46 | 47 | ### Interfaces 48 | 49 | | Name | Description | 50 | |----------------|-----------------------------------------| 51 | | ap_clk | Primary clock | 52 | | ap_rst_n | Primary active-Low reset | 53 | | clk_gt_freerun | Free running kernel | 54 | | gt_ref_clk | GT reference clock | 55 | | gt_serial_port | GT serial lanes | 56 | | S_AXILITE | AXI4-Lite subordinate control interface | 57 | | S_AXIS | 512-bit AXI4-Stream Tx interface | 58 | | M_AXIS | 512-bit AXI4-Stream Rx interface | 59 | 60 | ### Multiple 100 GbE Interfaces and Alveo cards 61 | 62 | To target multiple 100 GbE interfaces and Alveo cards a slightly different kernels are generated, the internal structure and interfaces are the same. However, the UltraScale+ Integrated 100G Ethernet Subsystem configuration changes to accommodate each interface and Alveo card. These configurations are cover [here](bd_cmac.tcl#L41-L114). 63 | 64 | ## License 65 | 66 | To generate the an xclbin file that uses the [UltraScale+ Integrated 100G Ethernet Subsystem](https://www.xilinx.com/products/intellectual-property/cmac_usplus.html) you need a valid license. You can generate a free of charge license following [these steps](https://github.com/Xilinx/open-nic-shell#cmac-license) 67 | 68 | > **Note:** To enable Auto-Negotiation/Link Training you would need a separate license. Check the documentation for more information. 69 | 70 | ## Changing RS-FEC 71 | 72 | RS-FEC is enabled by default in the CMAC instance. At runtime RS-FEC is deactivated by default and can be activated by calling the corresponding functions in the Pynq and C++ drivers. When active, the RS-FEC is set to sub-mode 1 (both correction and indication active). Please refer to the [UltraScale+ Integrated 100G Ethernet Subsystem](https://www.xilinx.com/products/intellectual-property/cmac_usplus.html) documentation for more details. 73 | 74 | > **Note:** When active, RS-FEC increases latency. 75 | ------------------------------------------------------ 76 |

Copyright© 2022 Xilinx

77 | -------------------------------------------------------------------------------- /Ethernet/duplicate_patch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2020, Xilinx, Inc. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without modification, 7 | # are permitted provided that the following conditions are met: 8 | # 9 | # 1. Redistributions of source code must retain the above copyright notice, 10 | # this list of conditions and the following disclaimer. 11 | # 12 | # 2. Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # 3. Neither the name of the copyright holder nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 | # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// Copyright (c) 2020 Xilinx, Inc. 29 | 30 | if [[ -f "kernel_0.xml" && -f "kernel_1.xml" ]]; then 31 | # Files exist therefore do nothing 32 | exit 0 33 | fi 34 | 35 | cp template.xml kernel_0.xml 36 | cp template.xml kernel_1.xml 37 | 38 | sed -i 's/name=\"placeholder\"/name=\"cmac\_0\"/g' kernel_0.xml 39 | sed -i 's/xilinx\.com\:kernel\:placeholder/xilinx\.com\:kernel\:cmac_0/g' kernel_0.xml 40 | sed -i 's/name=\"placeholder\"/name=\"cmac\_1\"/g' kernel_1.xml 41 | sed -i 's/xilinx\.com\:kernel\:placeholder/xilinx\.com\:kernel\:cmac_1/g' kernel_1.xml 42 | 43 | # Duplicate verilog 44 | cp src/template_top.v src/cmac_top_0.v 45 | cp src/template_top.v src/cmac_top_1.v 46 | 47 | sed -i 's/module\ placeholder/module\ cmac_0/g' src/cmac_top_0.v 48 | sed -i 's/cmac_bd\ placeholder/cmac_bd\ cmac_bd_0_i/g' src/cmac_top_0.v 49 | sed -i 's/gt_placeholder_clk/gt_refclk0/g' src/cmac_top_0.v 50 | 51 | sed -i 's/module\ placeholder/module\ cmac_1/g' src/cmac_top_1.v 52 | sed -i 's/cmac_bd\ placeholder/cmac_bd\ cmac_bd_1_i/g' src/cmac_top_1.v 53 | sed -i 's/gt_placeholder_clk/gt_refclk1/g' src/cmac_top_1.v -------------------------------------------------------------------------------- /Ethernet/package_cmac.tcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021, Xilinx, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 | # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 22 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 | # OR BUSINESS INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 | # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | if { $::argc != 5 } { 31 | puts "ERROR: Program \"$::argv0\" requires 5 arguments!, (${argc} given)\n" 32 | puts "Usage: $::argv0 \n" 33 | exit 34 | } 35 | 36 | set xoname [lindex $::argv 0] 37 | set krnl_name [lindex $::argv 1] 38 | set device [lindex $::argv 2] 39 | set interface [lindex $::argv 3] 40 | set padding_mode [lindex $::argv 4] 41 | 42 | set suffix "${krnl_name}_${device}" 43 | 44 | puts "INFO: xoname-> ${xoname}\n krnl_name-> ${krnl_name}\n device-> ${device}\n interface-> ${interface}\n padding_mode-> ${padding_mode}" 45 | 46 | set projName kernel_pack 47 | set bd_name cmac_bd 48 | set root_dir "[file normalize "."]" 49 | set path_to_hdl "./src" 50 | set path_to_packaged "./packaged_kernel_${suffix}" 51 | set path_to_tmp_project "./tmp_${suffix}" 52 | 53 | #get projPart 54 | source platform.tcl 55 | 56 | if {${projPart} eq "xcu50-fsvh2104-2-e"} { 57 | if {$interface != 0} { 58 | catch {common::send_gid_msg -ssname BD::TCL -id 2041 -severity "ERROR" "Alveo U50 only has one interface (0)"} 59 | return 1 60 | } 61 | } 62 | 63 | ## Create Vivado project and add IP cores 64 | create_project -force $projName $path_to_tmp_project -part $projPart 65 | add_files -norecurse [glob ${root_dir}/src/cmac_top_${interface}.v] 66 | add_files -norecurse [glob ${root_dir}/src/cmac_0_axi4_lite_user_if.v] 67 | add_files -norecurse [glob ${root_dir}/src/cmac_sync.v] 68 | add_files -norecurse [glob ${root_dir}/src/rx_sync.v] 69 | add_files -norecurse [glob ${root_dir}/src/frame_padding.v] 70 | add_files -fileset constrs_1 -norecurse [glob ${root_dir}/src/cmac_synq_false_path.xdc] 71 | 72 | update_compile_order -fileset sources_1 73 | 74 | source ${root_dir}/bd_cmac.tcl 75 | update_compile_order -fileset sources_1 76 | 77 | 78 | generate_target all [get_files ${path_to_tmp_project}/${projName}.srcs/sources_1/bd/${bd_name}/${bd_name}.bd] 79 | export_ip_user_files -of_objects [get_files ${path_to_tmp_project}/${projName}.srcs/sources_1/bd/${bd_name}/${bd_name}.bd] -no_script -sync -force -quiet 80 | create_ip_run [get_files -of_objects [get_fileset sources_1] ${path_to_tmp_project}/${projName}.srcs/sources_1/bd/${bd_name}/${bd_name}.bd] 81 | update_compile_order -fileset sources_1 82 | set_property top cmac_${interface} [current_fileset] 83 | 84 | 85 | set gt_name "gt_serial_port${interface}" 86 | set refclkIntfName "gt_refclk${interface}" 87 | # Package IP 88 | 89 | ipx::package_project -root_dir ${path_to_packaged} -vendor xilinx.com -library RTLKernel -taxonomy /KernelIP -import_files -set_current false 90 | ipx::unload_core ${path_to_packaged}/component.xml 91 | ipx::edit_ip_in_project -upgrade true -name tmp_edit_project -directory ${path_to_packaged} ${path_to_packaged}/component.xml 92 | set_property core_revision 1 [ipx::current_core] 93 | foreach up [ipx::get_user_parameters] { 94 | ipx::remove_user_parameter [get_property NAME $up] [ipx::current_core] 95 | } 96 | set_property sdx_kernel true [ipx::current_core] 97 | set_property sdx_kernel_type rtl [ipx::current_core] 98 | ipx::create_xgui_files [ipx::current_core] 99 | ipx::add_bus_interface ap_clk [ipx::current_core] 100 | set_property abstraction_type_vlnv xilinx.com:signal:clock_rtl:1.0 [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 101 | set_property bus_type_vlnv xilinx.com:signal:clock:1.0 [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 102 | ipx::add_port_map CLK [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 103 | set_property physical_name ap_clk [ipx::get_port_maps CLK -of_objects [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]]] 104 | ipx::associate_bus_interfaces -busif S_AXIS -clock ap_clk [ipx::current_core] 105 | ipx::associate_bus_interfaces -busif M_AXIS -clock ap_clk [ipx::current_core] 106 | ipx::associate_bus_interfaces -busif S_AXILITE -clock ap_clk [ipx::current_core] 107 | 108 | ipx::add_bus_interface ${gt_name} [ipx::current_core] 109 | set_property interface_mode master [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]] 110 | set_property abstraction_type_vlnv xilinx.com:interface:gt_rtl:1.0 [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]] 111 | set_property bus_type_vlnv xilinx.com:interface:gt:1.0 [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]] 112 | ipx::add_port_map GRX_P [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]] 113 | set_property physical_name gt_rxp_in [ipx::get_port_maps GRX_P -of_objects [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]]] 114 | ipx::add_port_map GRX_N [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]] 115 | set_property physical_name gt_rxn_in [ipx::get_port_maps GRX_N -of_objects [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]]] 116 | ipx::add_port_map GTX_P [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]] 117 | set_property physical_name gt_txp_out [ipx::get_port_maps GTX_P -of_objects [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]]] 118 | ipx::add_port_map GTX_N [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]] 119 | set_property physical_name gt_txn_out [ipx::get_port_maps GTX_N -of_objects [ipx::get_bus_interfaces ${gt_name} -of_objects [ipx::current_core]]] 120 | 121 | # GT Differential Reference Clock 122 | ipx::add_bus_interface ${refclkIntfName} [ipx::current_core] 123 | set_property abstraction_type_vlnv xilinx.com:interface:diff_clock_rtl:1.0 [ipx::get_bus_interfaces ${refclkIntfName} -of_objects [ipx::current_core]] 124 | set_property bus_type_vlnv xilinx.com:interface:diff_clock:1.0 [ipx::get_bus_interfaces ${refclkIntfName} -of_objects [ipx::current_core]] 125 | ipx::add_port_map CLK_P [ipx::get_bus_interfaces ${refclkIntfName} -of_objects [ipx::current_core]] 126 | set_property physical_name ${refclkIntfName}_p [ipx::get_port_maps CLK_P -of_objects [ipx::get_bus_interfaces ${refclkIntfName} -of_objects [ipx::current_core]]] 127 | ipx::add_port_map CLK_N [ipx::get_bus_interfaces ${refclkIntfName} -of_objects [ipx::current_core]] 128 | set_property physical_name ${refclkIntfName}_n [ipx::get_port_maps CLK_N -of_objects [ipx::get_bus_interfaces ${refclkIntfName} -of_objects [ipx::current_core]]] 129 | 130 | 131 | set_property xpm_libraries {XPM_CDC XPM_MEMORY XPM_FIFO} [ipx::current_core] 132 | set_property supported_families { } [ipx::current_core] 133 | set_property auto_family_support_level level_2 [ipx::current_core] 134 | ipx::update_checksums [ipx::current_core] 135 | ipx::save_core [ipx::current_core] 136 | close_project -delete 137 | 138 | ## Generate XO 139 | if {[file exists "${xoname}"]} { 140 | file delete -force "${xoname}" 141 | } 142 | 143 | package_xo -xo_path ${xoname} -kernel_name ${krnl_name} -ip_directory ./packaged_kernel_${suffix} -kernel_xml ./kernel_${interface}.xml 144 | -------------------------------------------------------------------------------- /Ethernet/platform.tcl: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2021 Xilinx, Inc 2 | # 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | 5 | set words [split $device "_"] 6 | set board [lindex $words 1] 7 | 8 | if {[string first "u55n" ${board}] != -1} { 9 | set projPart "xcu55n-fsvh2892-2L-e" 10 | } elseif {[string first "u50" ${board}] != -1} { 11 | set projPart "xcu50-fsvh2104-2-e" 12 | } elseif {[string first "u55c" ${board}] != -1} { 13 | set projPart "xcu55c-fsvh2892-2L-e" 14 | } elseif {[string first "u200" ${board}] != -1} { 15 | set projPart "xcu200-fsgd2104-2-e" 16 | } elseif {[string first "u250" ${board}] != -1} { 17 | set projPart "xcu250-figd2104-2L-e" 18 | } elseif {[string first "u280" ${board}] != -1} { 19 | set projPart "xcu280-fsvh2892-2L-e" 20 | } else { 21 | catch {common::send_gid_msg -ssname BD::TCL -id 2041 -severity "ERROR" "unsupported device: ${device}"} 22 | return 1 23 | } 24 | -------------------------------------------------------------------------------- /Ethernet/src/cmac_sync.v: -------------------------------------------------------------------------------- 1 | /************************************************ 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2019, 5 | Naudit HPCN, Spain (naudit.es) 6 | HPCN Group, UAM Spain (hpcn-uam.es) 7 | All rights reserved. 8 | 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this 14 | list of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright notice, 17 | this list of conditions and the following disclaimer in the documentation 18 | and/or other materials provided with the distribution. 19 | 20 | * Neither the name of the copyright holder nor the names of its 21 | contributors may be used to endorse or promote products derived from 22 | this software without specific prior written permission. 23 | 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 28 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | ************************************************/ 36 | 37 | 38 | `timescale 1ns/1ps 39 | 40 | 41 | module cmac_sync ( 42 | (* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 usr_tx_reset RST" *) 43 | (* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_HIGH" *) 44 | input wire usr_tx_reset , 45 | (* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 usr_rx_reset RST" *) 46 | (* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_HIGH" *) 47 | input wire usr_rx_reset , 48 | // Control ports 49 | input wire stat_rx_aligned, 50 | 51 | (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 s_axi_aclk CLK" *) 52 | (* X_INTERFACE_PARAMETER = "ASSOCIATED_BUSIF s_axi, ASSOCIATED_RESET s_axi_sreset" *) 53 | input wire s_axi_aclk , 54 | (* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 s_axi_sreset RST" *) 55 | (* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_HIGH" *) 56 | input wire s_axi_sreset , 57 | output wire [11:0] s_axi_awaddr , 58 | output wire s_axi_awvalid , 59 | input wire s_axi_awready , 60 | output wire [31:0] s_axi_wdata , 61 | output wire [ 3:0] s_axi_wstrb , 62 | output wire s_axi_wvalid , 63 | input wire s_axi_wready , 64 | input wire [ 1:0] s_axi_bresp , 65 | input wire s_axi_bvalid , 66 | output wire s_axi_bready , 67 | output wire [11:0] s_axi_araddr , 68 | output wire s_axi_arvalid , 69 | input wire s_axi_arready , 70 | input wire [31:0] s_axi_rdata , 71 | input wire [ 1:0] s_axi_rresp , 72 | input wire s_axi_rvalid , 73 | output wire s_axi_rready , 74 | // Leds 75 | output wire rx_gt_locked_led , 76 | output wire rx_aligned_led , 77 | output wire rx_done_led , 78 | output wire rx_data_fail_led , 79 | output wire rx_busy_led , 80 | output wire cmac_aligned_sync 81 | ); 82 | 83 | wire usr_rx_reset_synq; 84 | 85 | // Sync mechanism 86 | rx_sync rx_sync_i ( 87 | .clk (s_axi_aclk ), 88 | .reset (usr_rx_reset_synq ), 89 | .sys_reset (s_axi_sreset ), 90 | 91 | .stat_rx_aligned (cmac_aligned_sync ), 92 | .rx_gt_locked_led (rx_gt_locked_led ), 93 | .rx_aligned_led (rx_aligned_led ), 94 | .rx_done_led (rx_done_led ), 95 | .rx_data_fail_led (rx_data_fail_led ) 96 | ); 97 | 98 | 99 | cmac_0_axi4_lite_user_if cmac_0_axi4_lite_user_if_i ( 100 | .gt_locked_sync (rx_gt_locked_led ), 101 | .stat_rx_aligned_sync (cmac_aligned_sync ), 102 | .rx_busy_led (rx_busy_led ), 103 | .s_axi_aclk (s_axi_aclk ), 104 | .s_axi_sreset (s_axi_sreset ), 105 | .s_axi_pm_tick (1'b0 ), 106 | .s_axi_awaddr (s_axi_awaddr ), 107 | .s_axi_awvalid (s_axi_awvalid ), 108 | .s_axi_awready (s_axi_awready ), 109 | .s_axi_wdata (s_axi_wdata ), 110 | .s_axi_wstrb (s_axi_wstrb ), 111 | .s_axi_wvalid (s_axi_wvalid ), 112 | .s_axi_wready (s_axi_wready ), 113 | .s_axi_bresp (s_axi_bresp ), 114 | .s_axi_bvalid (s_axi_bvalid ), 115 | .s_axi_bready (s_axi_bready ), 116 | .s_axi_araddr (s_axi_araddr ), 117 | .s_axi_arvalid (s_axi_arvalid ), 118 | .s_axi_arready (s_axi_arready ), 119 | .s_axi_rdata (s_axi_rdata ), 120 | .s_axi_rresp (s_axi_rresp ), 121 | .s_axi_rvalid (s_axi_rvalid ), 122 | .s_axi_rready (s_axi_rready ) 123 | ); 124 | 125 | /* Synchronizers */ 126 | 127 | cdc_sync i_cmac_0_sync_usr_rx_reset ( 128 | .clk (s_axi_aclk ), 129 | .signal_in (usr_rx_reset ), 130 | .signal_out (usr_rx_reset_synq ) 131 | ); 132 | 133 | cdc_sync i_cmac_0_mon_clk_stat_rx_aligned ( 134 | .clk (s_axi_aclk ), 135 | .signal_in (stat_rx_aligned ), 136 | .signal_out (cmac_aligned_sync ) 137 | ); 138 | 139 | endmodule 140 | 141 | module cdc_sync ( 142 | input wire clk, 143 | (* ASYNC_REG = "TRUE" *) 144 | input wire signal_in, 145 | output wire signal_out 146 | ); 147 | 148 | HARD_SYNC #( 149 | .INIT (1'b0), // Initial values, 1'b0, 1'b1 150 | .IS_CLK_INVERTED (1'b0), // Programmable inversion on CLK input 151 | .LATENCY (3) // 2-3 152 | ) 153 | HARD_SYNC_i ( 154 | .CLK ( clk), // 1-bit input: Clock 155 | .DIN ( signal_in), // 1-bit input: Data 156 | .DOUT ( signal_out) // 1-bit output: Data 157 | ); 158 | 159 | 160 | endmodule -------------------------------------------------------------------------------- /Ethernet/src/cmac_synq_false_path.xdc: -------------------------------------------------------------------------------- 1 | ################################################################################################ 2 | # cmac_synq false path 3 | ################################################################################################ 4 | 5 | set_false_path -through [get_nets cmac_bd_*/usr_rx_reset] 6 | set_false_path -through [get_nets cmac_bd_*/usr_tx_reset] 7 | set_false_path -through [get_nets cmac_bd_*/cmac_stat_rx_aligned] 8 | -------------------------------------------------------------------------------- /Ethernet/src/frame_padding.v: -------------------------------------------------------------------------------- 1 | /************************************************ 2 | Copyright (c) 2021, Xilinx, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | ************************************************/ 29 | 30 | /* 31 | * This module adds padding to frames shorter than 60-Byte. 32 | * This is to comply with Integrated 100G Ethernet Subsystem 33 | * minimum frame length, which is 60-Byte (without FCS) 34 | */ 35 | 36 | module frame_padding 37 | #( 38 | parameter PADDING_MODE = 0 //0 = no padding; 1 = 60B padding; 2 = 64B padding 39 | ) 40 | ( 41 | (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 S_AXI_ACLK CLK" *) 42 | (* X_INTERFACE_PARAMETER = "ASSOCIATED_BUSIF S_AXIS:M_AXIS, ASSOCIATED_RESET S_AXI_ARESETN" *) 43 | input wire S_AXI_ACLK, 44 | (* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 S_AXI_ARESETN RST" *) 45 | (* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_LOW" *) 46 | input wire S_AXI_ARESETN, 47 | 48 | // Users to add ports here 49 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 S_AXIS TDATA" *) 50 | input wire [511:0] S_AXIS_TDATA, 51 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 S_AXIS TKEEP" *) 52 | input wire [ 63:0] S_AXIS_TKEEP, 53 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 S_AXIS TVALID" *) 54 | input wire S_AXIS_TVALID, 55 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 S_AXIS TREADY" *) 56 | output wire S_AXIS_TREADY, 57 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 S_AXIS TLAST" *) 58 | input wire S_AXIS_TLAST, 59 | 60 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 M_AXIS TDATA" *) 61 | output wire [511:0] M_AXIS_TDATA, 62 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 M_AXIS TKEEP" *) 63 | output wire [ 63:0] M_AXIS_TKEEP, 64 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 M_AXIS TVALID" *) 65 | output wire M_AXIS_TVALID, 66 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 M_AXIS TREADY" *) 67 | input wire M_AXIS_TREADY, 68 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 M_AXIS TLAST" *) 69 | output wire M_AXIS_TLAST 70 | ); 71 | 72 | reg [511:0] data; 73 | reg [ 63:0] keep; 74 | reg new_frame = 1'b1; 75 | integer i; 76 | 77 | // Flag when a new frame starts 78 | always @(posedge S_AXI_ACLK) begin 79 | if (~S_AXI_ARESETN) begin 80 | new_frame = 1'b1; 81 | end 82 | else begin 83 | if (S_AXIS_TVALID && S_AXIS_TREADY) begin 84 | new_frame = S_AXIS_TLAST; 85 | end 86 | end 87 | end 88 | 89 | always @(*) begin 90 | // If keep[59] is 0, the frame is shorter than 60-Byte 91 | if ((PADDING_MODE > 0) && new_frame && (S_AXIS_TKEEP[59] == 0)) begin 92 | // Force frame to be 60-Byte or 64-Byte 93 | if(PADDING_MODE == 2) begin 94 | keep = {64{1'b1}}; 95 | end else begin 96 | keep = {4'h0,{60{1'b1}}}; 97 | end 98 | data[511:480] = 32'h0; 99 | // Pad remaining bytes with zeros 100 | for (i = 0; i < 60; i = i+1) begin 101 | if (S_AXIS_TKEEP[i]) 102 | data[i*8 +: 8] = S_AXIS_TDATA[i*8 +: 8]; 103 | else 104 | data[i*8 +: 8] = 8'h0; 105 | end 106 | end 107 | else begin 108 | data = S_AXIS_TDATA; 109 | keep = S_AXIS_TKEEP; 110 | end 111 | end 112 | 113 | 114 | // Valid, ready and last are bypassed unmodified 115 | assign S_AXIS_TREADY = M_AXIS_TREADY; 116 | assign M_AXIS_TVALID = S_AXIS_TVALID; 117 | assign M_AXIS_TLAST = S_AXIS_TLAST; 118 | // Assign padded frame 119 | assign M_AXIS_TDATA = data; 120 | assign M_AXIS_TKEEP = keep; 121 | 122 | 123 | endmodule 124 | -------------------------------------------------------------------------------- /Ethernet/src/template_top.v: -------------------------------------------------------------------------------- 1 | /************************************************ 2 | Copyright (c) 2021, Xilinx, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 | OR BUSINESS INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | ************************************************/ 31 | 32 | `default_nettype wire 33 | `timescale 1 ns / 1 ps 34 | // Top level of the kernel. Do not modify module name, parameters or ports. 35 | module placeholder #( 36 | parameter integer AXIL_CTRL_ADDR_WIDTH = 13, 37 | parameter integer AXIL_CTRL_DATA_WIDTH = 32, 38 | parameter integer AXIS_TDATA_WIDTH = 512 39 | ) 40 | ( 41 | // System clocks and resets 42 | (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 ap_clk CLK" *) 43 | (* X_INTERFACE_PARAMETER = "ASSOCIATED_BUSIF S_AXIS:M_AXIS:S_AXILITE, ASSOCIATED_RESET ap_rst_n" *) 44 | input wire ap_clk, 45 | (* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 ap_rst_n RST" *) 46 | (* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_LOW" *) 47 | input wire ap_rst_n, 48 | 49 | (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 clk_gt_freerun CLK" *) 50 | input wire clk_gt_freerun, 51 | 52 | input wire S_AXIS_tvalid, 53 | output wire S_AXIS_tready, 54 | input wire [AXIS_TDATA_WIDTH-1:0] S_AXIS_tdata, 55 | input wire [AXIS_TDATA_WIDTH/8-1:0] S_AXIS_tkeep, 56 | input wire S_AXIS_tlast, 57 | 58 | output wire M_AXIS_tvalid, 59 | input wire M_AXIS_tready, 60 | output wire [AXIS_TDATA_WIDTH-1:0] M_AXIS_tdata, 61 | output wire [AXIS_TDATA_WIDTH/8-1:0] M_AXIS_tkeep, 62 | output wire M_AXIS_tlast, 63 | 64 | input wire S_AXILITE_awvalid, 65 | output wire S_AXILITE_awready, 66 | input wire [AXIL_CTRL_ADDR_WIDTH-1:0] S_AXILITE_awaddr, 67 | input wire S_AXILITE_wvalid, 68 | output wire S_AXILITE_wready, 69 | input wire [AXIL_CTRL_DATA_WIDTH-1:0] S_AXILITE_wdata, 70 | input wire [AXIL_CTRL_DATA_WIDTH/8-1:0] S_AXILITE_wstrb, 71 | input wire S_AXILITE_arvalid, 72 | output wire S_AXILITE_arready, 73 | input wire [AXIL_CTRL_ADDR_WIDTH-1:0] S_AXILITE_araddr, 74 | output wire S_AXILITE_rvalid, 75 | input wire S_AXILITE_rready, 76 | output wire [AXIL_CTRL_DATA_WIDTH-1:0] S_AXILITE_rdata, 77 | output wire [1:0] S_AXILITE_rresp, 78 | output wire S_AXILITE_bvalid, 79 | input wire S_AXILITE_bready, 80 | output wire [1:0] S_AXILITE_bresp, 81 | 82 | // GT interfaces 83 | input wire [3:0] gt_rxp_in, 84 | input wire [3:0] gt_rxn_in, 85 | output wire [3:0] gt_txp_out, 86 | output wire [3:0] gt_txn_out, 87 | input wire gt_placeholder_clk_p, 88 | input wire gt_placeholder_clk_n 89 | ); 90 | 91 | 92 | cmac_bd placeholder ( 93 | .ap_clk ( ap_clk), 94 | .ap_rst_n ( ap_rst_n), 95 | 96 | .clk_gt_freerun ( clk_gt_freerun), 97 | 98 | .gt_ref_clk_clk_n ( gt_placeholder_clk_n), 99 | .gt_ref_clk_clk_p ( gt_placeholder_clk_p), 100 | .gt_serial_port_grx_n ( gt_rxn_in), 101 | .gt_serial_port_grx_p ( gt_rxp_in), 102 | .gt_serial_port_gtx_n ( gt_txn_out), 103 | .gt_serial_port_gtx_p ( gt_txp_out), 104 | 105 | .S_AXIS_tdata ( S_AXIS_tdata), 106 | .S_AXIS_tkeep ( S_AXIS_tkeep), 107 | .S_AXIS_tlast ( S_AXIS_tlast), 108 | .S_AXIS_tready ( S_AXIS_tready), 109 | .S_AXIS_tvalid ( S_AXIS_tvalid), 110 | 111 | .M_AXIS_tdata ( M_AXIS_tdata), 112 | .M_AXIS_tkeep ( M_AXIS_tkeep), 113 | .M_AXIS_tlast ( M_AXIS_tlast), 114 | .M_AXIS_tready ( M_AXIS_tready), 115 | .M_AXIS_tvalid ( M_AXIS_tvalid), 116 | 117 | .S_AXILITE_awvalid ( S_AXILITE_awvalid), 118 | .S_AXILITE_awready ( S_AXILITE_awready), 119 | .S_AXILITE_awaddr ( S_AXILITE_awaddr), 120 | .S_AXILITE_wvalid ( S_AXILITE_wvalid), 121 | .S_AXILITE_wready ( S_AXILITE_wready), 122 | .S_AXILITE_wdata ( S_AXILITE_wdata), 123 | .S_AXILITE_wstrb ( S_AXILITE_wstrb), 124 | .S_AXILITE_arvalid ( S_AXILITE_arvalid), 125 | .S_AXILITE_arready ( S_AXILITE_arready), 126 | .S_AXILITE_araddr ( S_AXILITE_araddr), 127 | .S_AXILITE_rvalid ( S_AXILITE_rvalid), 128 | .S_AXILITE_rready ( S_AXILITE_rready), 129 | .S_AXILITE_rdata ( S_AXILITE_rdata), 130 | .S_AXILITE_rresp ( S_AXILITE_rresp), 131 | .S_AXILITE_bvalid ( S_AXILITE_bvalid), 132 | .S_AXILITE_bready ( S_AXILITE_bready), 133 | .S_AXILITE_bresp ( S_AXILITE_bresp), 134 | .S_AXILITE_arprot ( 3'b0), 135 | .S_AXILITE_awprot ( 3'b0) 136 | ); 137 | 138 | 139 | endmodule -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, Xilinx, Inc. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, 7 | are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, 10 | this list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its contributors 17 | may be used to endorse or promote products derived from this software 18 | without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// Copyright (c) 2020 Xilinx, Inc. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL=/bin/bash 2 | 3 | .PHONY: help 4 | 5 | help: 6 | @echo "Makefile Usage:" 7 | @echo " make all DEVICE= INTERFACE= DESIGN=" 8 | @echo " Command to generate the xo for specified device and Interface." 9 | @echo " By default, DEVICE=xilinx_u280_xdma_201920_3, INTERFACE=0 DESIGN=benchmark" 10 | @echo " DESIGN also supports the string basic" 11 | @echo "" 12 | @echo " make clean " 13 | @echo " Command to remove the generated non-hardware files." 14 | @echo "" 15 | @echo " make distclean" 16 | @echo " Command to remove all the generated files in the current directory" 17 | @echo "" 18 | @echo " make distcleanall" 19 | @echo " Command to remove all the generated in the current directory and one level down" 20 | @echo "" 21 | 22 | 23 | DEVICE ?= xilinx_u280_xdma_201920_3 24 | INTERFACE ?= 0 25 | DESIGN ?= benchmark 26 | XCLBIN_NAME ?= vnx_$(DESIGN)_if$(INTERFACE) 27 | MAX_SOCKETS ?= 16 28 | 29 | 30 | ifeq ($(shell test $(MAX_SOCKETS) -gt 63; echo $$?),0) 31 | $(error Error: maximum number of sockets is 63) 32 | endif 33 | UDP_THEIR_IP_OFFSET = 0x820 34 | UDP_THEIR_PORT_OFFSET = $(shell printf "0x%04X\n" $$(($(UDP_THEIR_IP_OFFSET) + 8*$(MAX_SOCKETS)))) 35 | UDP_MY_PORT_OFFSET = $(shell printf "0x%04X\n" $$(($(UDP_THEIR_PORT_OFFSET) + 8*$(MAX_SOCKETS)))) 36 | UDP_VALID_OFFSET = $(shell printf "0x%04X\n" $$(($(UDP_MY_PORT_OFFSET) + 8*$(MAX_SOCKETS)))) 37 | 38 | XSA := $(strip $(patsubst %.xpfm, % , $(shell basename $(DEVICE)))) 39 | TEMP_DIR := _x.$(XSA) 40 | VPP := $(XILINX_VITIS)/bin/v++ 41 | CLFLAGS += -t hw --platform $(DEVICE) --save-temps 42 | 43 | BUILD_DIR := ./$(DESIGN).intf$(INTERFACE).$(XSA) 44 | BINARY_CONTAINERS = $(BUILD_DIR)/${XCLBIN_NAME}.xclbin 45 | 46 | NETLAYERDIR = NetLayers/ 47 | CMACDIR = Ethernet/ 48 | BASICDIR = Basic_kernels/ 49 | BENCHMARDIR = Benchmark_kernel/ 50 | 51 | NETLAYERHLS = 100G-fpga-network-stack-core 52 | 53 | POSTSYSLINKTCL ?= $(shell readlink -f ./Ethernet/post_sys_link.tcl) 54 | SWITCH_IP_FOLDER ?= $(shell readlink -f ./$(BENCHMARDIR)/packaged_kernel_switch_wrapper_$(XSA)) 55 | 56 | 57 | LIST_XO = $(NETLAYERDIR)$(TEMP_DIR)/networklayer.xo 58 | 59 | CONFIGFLAGS = --config configuration_$(DESIGN)_if$(INTERFACE).tmp.ini 60 | #CONFIGFLAGS += --kernel_frequency 280 61 | 62 | # Include cmac kernel depending on the interface 63 | ifeq (3,$(INTERFACE)) 64 | LIST_XO += $(CMACDIR)$(TEMP_DIR)/cmac_0.xo 65 | LIST_XO += $(CMACDIR)$(TEMP_DIR)/cmac_1.xo 66 | else 67 | LIST_XO += $(CMACDIR)$(TEMP_DIR)/cmac_$(INTERFACE).xo 68 | endif 69 | 70 | LIST_REPOS = 71 | 72 | # Include application kernels depending on the design 73 | ifeq (benchmark,$(DESIGN)) 74 | LIST_XO += $(BENCHMARDIR)$(TEMP_DIR)/traffic_generator.xo 75 | LIST_XO += $(BENCHMARDIR)$(TEMP_DIR)/collector.xo 76 | LIST_XO += $(BENCHMARDIR)$(TEMP_DIR)/switch_wrapper.xo 77 | LIST_REPOS += --user_ip_repo_paths $(SWITCH_IP_FOLDER) 78 | else 79 | LIST_XO += $(BASICDIR)$(TEMP_DIR)/krnl_mm2s.xo 80 | LIST_XO += $(BASICDIR)$(TEMP_DIR)/krnl_s2mm.xo 81 | endif 82 | 83 | # Linker parameters 84 | # Linker userPostSysLinkTcl param 85 | ifeq (u5,$(findstring u5, $(DEVICE))) 86 | HLS_IP_FOLDER = $(shell readlink -f ./$(NETLAYERDIR)$(NETLAYERHLS)/synthesis_results_HBM) 87 | else ifeq (u280,$(findstring u280, $(DEVICE))) 88 | HLS_IP_FOLDER = $(shell readlink -f ./$(NETLAYERDIR)$(NETLAYERHLS)/synthesis_results_HBM) 89 | else ifeq (u2,$(findstring u2, $(DEVICE))) 90 | HLS_IP_FOLDER = $(shell readlink -f ./$(NETLAYERDIR)$(NETLAYERHLS)/synthesis_results_noHBM) 91 | endif 92 | 93 | LIST_REPOS += --user_ip_repo_paths $(HLS_IP_FOLDER) 94 | 95 | .PHONY: all clean distclean distcleanall 96 | all: check-devices check-vitis check-xrt check-design check-interface create-conf-file $(BINARY_CONTAINERS) 97 | 98 | # Cleaning stuff 99 | clean: 100 | rm -rf *v++* *.log *.jou *.str 101 | 102 | distclean: clean 103 | rm -rf _x* *.tmp.ini .Xil benchmark*/ basic*/ .ipcache/ 104 | 105 | distcleanall: distclean 106 | make -C $(NETLAYERDIR) distcleanall 107 | make -C $(CMACDIR) distclean 108 | make -C $(BASICDIR) distclean 109 | make -C $(BENCHMARDIR) distclean 110 | 111 | 112 | # Building xclbin 113 | $(BUILD_DIR)/${XCLBIN_NAME}.xclbin: $(LIST_XO) 114 | mkdir -p $(BUILD_DIR) 115 | $(VPP) $(CLFLAGS) $(CONFIGFLAGS) --temp_dir $(BUILD_DIR) -l -o'$@' $^ $(LIST_REPOS) -j 8 116 | 117 | $(BASICDIR)$(TEMP_DIR)/%.xo: $(BASICDIR)src/*.cpp 118 | make -C $(BASICDIR) all DEVICE=$(DEVICE) -j3 119 | 120 | $(BENCHMARDIR)$(TEMP_DIR)/%.xo: $(BENCHMARDIR)src/* 121 | make -C $(BENCHMARDIR) all DEVICE=$(DEVICE) -j3 122 | 123 | $(CMACDIR)$(TEMP_DIR)/%.xo: 124 | make -C $(CMACDIR) all DEVICE=$(DEVICE) INTERFACE=$(INTERFACE) 125 | 126 | $(NETLAYERDIR)$(TEMP_DIR)/%.xo: 127 | cd ./$(NETLAYERDIR)$(NETLAYERHLS) && git checkout -- . 128 | sed -i 's/define NUMBER_SOCKETS 16/define NUMBER_SOCKETS $(MAX_SOCKETS)/' ./$(NETLAYERDIR)$(NETLAYERHLS)/hls/UDP/udp.hpp 129 | sed -i 's/port=numberSockets/port=numberSockets offset=0x10/' ./$(NETLAYERDIR)$(NETLAYERHLS)/hls/UDP/udp.cpp 130 | cat ./$(NETLAYERDIR)/template.xml | sed 's/UDP_TP_PLACEHOLDER/$(UDP_THEIR_PORT_OFFSET)/' \ 131 | | sed 's/UDP_MP_PLACEHOLDER/$(UDP_MY_PORT_OFFSET)/' \ 132 | | sed 's/UDP_VL_PLACEHOLDER/$(UDP_VALID_OFFSET)/' > ./$(NETLAYERDIR)/kernel.xml 133 | make -C $(NETLAYERDIR) all DEVICE=$(DEVICE) 134 | 135 | check-devices: 136 | ifndef DEVICE 137 | $(error DEVICE not set. Please set the DEVICE properly and rerun. Run "make help" for more details.) 138 | endif 139 | 140 | #Checks for XILINX_VITIS 141 | check-vitis: 142 | ifndef XILINX_VITIS 143 | $(error XILINX_VITIS variable is not set, please set correctly and rerun) 144 | endif 145 | 146 | #Checks for XILINX_XRT 147 | check-xrt: 148 | ifndef XILINX_XRT 149 | $(error XILINX_XRT variable is not set, please set correctly and rerun) 150 | endif 151 | 152 | #Check if the design name is supported 153 | check-design: 154 | @if [[ ($(DESIGN) != "benchmark") && ($(DESIGN) != "basic") ]]; then\ 155 | echo "DESIGN=$(DESIGN) is not supported!";\ 156 | exit 1;\ 157 | fi 158 | 159 | check-interface: 160 | @if [[ ($(XSA) =~ "u50") && ($(INTERFACE) != 0) ]]; then\ 161 | echo "Platform $(XSA) only has INTERFACE=0!";\ 162 | exit 1;\ 163 | fi 164 | @if [[ ($(INTERFACE) != 0) && ($(INTERFACE) != 1) && ($(INTERFACE) != 3) ]]; then\ 165 | echo "Interface $(INTERFACE) is not supported in platform $(XSA)!";\ 166 | exit 1;\ 167 | fi 168 | 169 | #Create configuration file for current design and settings 170 | create-conf-file: 171 | cp config_files/connectivity_$(DESIGN)_if$(INTERFACE).ini configuration_$(DESIGN)_if$(INTERFACE).tmp.ini 172 | echo "" >> configuration_$(DESIGN)_if$(INTERFACE).tmp.ini 173 | echo "" >> configuration_$(DESIGN)_if$(INTERFACE).tmp.ini 174 | echo "[advanced]" >> configuration_$(DESIGN)_if$(INTERFACE).tmp.ini 175 | echo "param=compiler.userPostSysLinkOverlayTcl=$(POSTSYSLINKTCL)" >> configuration_$(DESIGN)_if$(INTERFACE).tmp.ini 176 | echo "#param=compiler.worstNegativeSlack=-2" >> configuration_$(DESIGN)_if$(INTERFACE).tmp.ini 177 | echo "#param=compiler.errorOnHoldViolation=false" >> configuration_$(DESIGN)_if$(INTERFACE).tmp.ini 178 | echo "[vivado]" >> configuration_$(DESIGN)_if$(INTERFACE).tmp.ini 179 | echo "prop=run.impl_1.strategy=Performance_NetDelay_low" >> configuration_$(DESIGN)_if$(INTERFACE).tmp.ini 180 | @if [[ $(DEVICE) = *"u5"* ]]; then\ 181 | sed -i 's/SLR2/SLR1/g' configuration_$(DESIGN)_if$(INTERFACE).tmp.ini;\ 182 | sed -i 's/DDR\[1\]/HBM\[0\]/g' configuration_$(DESIGN)_if$(INTERFACE).tmp.ini;\ 183 | fi 184 | -------------------------------------------------------------------------------- /NetLayers/.gitignore: -------------------------------------------------------------------------------- 1 | _x.* 2 | packaged_kernel*/ 3 | tmp_*/ 4 | *.jou 5 | *.log 6 | .Xil/ 7 | 8 | -------------------------------------------------------------------------------- /NetLayers/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help 2 | 3 | help: 4 | @echo "Makefile Usage:" 5 | @echo " make all DEVICE=" 6 | @echo " Command to generate the xo for specified device." 7 | @echo " By default, DEVICE=xilinx_u280_xdma_201920_3" 8 | @echo "" 9 | @echo " make clean " 10 | @echo " Command to remove the generated non-hardware files." 11 | @echo "" 12 | @echo " make distclean" 13 | @echo " Command to remove all the generated files." 14 | @echo " make distcleanall" 15 | @echo " Command to remove all the generated in the current directory and one level down" 16 | @echo "" 17 | 18 | 19 | DEVICE ?= xilinx_u280_xdma_201920_3 20 | KRNL_NAME := networklayer 21 | SUBMODULENAME = 100G-fpga-network-stack-core 22 | 23 | XSA := $(strip $(patsubst %.xpfm, % , $(shell basename $(DEVICE)))) 24 | TEMP_DIR := ./_x.$(XSA) 25 | VIVADO := $(XILINX_VIVADO)/bin/vivado 26 | 27 | NETLAYER_OBJS = $(TEMP_DIR)/${KRNL_NAME}.xo 28 | 29 | ifeq (u5,$(findstring u5, $(DEVICE))) 30 | SUBMODULETARGET = hbm 31 | else ifeq (u280,$(findstring u280, $(DEVICE))) 32 | SUBMODULETARGET = hbm 33 | else ifeq (u2,$(findstring u2, $(DEVICE))) 34 | SUBMODULETARGET = nohbm 35 | else ifeq (vck5000,$(findstring vck5000, $(DEVICE))) 36 | SUBMODULETARGET = versalaicore 37 | endif 38 | 39 | .PHONY: all clean cleanall 40 | all: check-devices check-vivado $(NETLAYER_OBJS) 41 | 42 | 43 | # Cleaning stuff 44 | clean: 45 | rm -rf *v++* *.log *.jou 46 | 47 | distclean: clean 48 | rm -rf build_dir* 49 | rm -rf ./tmp_$(KRNL_NAME)* ./packaged_kernel* 50 | rm -rf _x.* *.str 51 | rm -rf .Xil 52 | 53 | distcleanall: distclean 54 | make -C $(SUBMODULENAME) distclean 55 | 56 | 57 | $(TEMP_DIR)/${KRNL_NAME}.xo: kernel.xml package_netlayer.tcl src/*.v src/*.vhd 58 | mkdir -p $(TEMP_DIR) 59 | make -C $(SUBMODULENAME) $(SUBMODULETARGET) 60 | $(VIVADO) -mode batch -source package_netlayer.tcl -notrace -tclargs $@ ${KRNL_NAME} $(XSA) 61 | 62 | check-devices: 63 | ifndef DEVICE 64 | $(error DEVICE not set. Please set the DEVICE properly and rerun. Run "make help" for more details.) 65 | endif 66 | 67 | #Checks for XILINX_VIVADO 68 | check-vivado: 69 | ifndef XILINX_VIVADO 70 | $(error XILINX_VIVADO variable is not set, please set correctly and rerun) 71 | endif -------------------------------------------------------------------------------- /NetLayers/README.md: -------------------------------------------------------------------------------- 1 | # Network layer kernel 2 | 3 | The network layer kernel is a collection of HLS modules to provide basic network functionality. It exposes two 512-bit (with 16-bit TDEST) AXI4-Stream to the application, S_AXIS_sk2nl and M_AXIS_nl2sk. 4 | 5 | ### ARP 6 | It provides a translation between IP addresses and MAC addresses. This table has 256 elements and it is accessible using AXI4-Lite. It also has ARP discovery capability to map IP addresses on its subnetwork. 7 | 8 | ```C 9 | struct arpTableEntry { 10 | ap_uint<48> macAddress; 11 | ap_uint<32> ipAddress; 12 | ap_uint<1> valid; 13 | } 14 | ``` 15 | 16 | ### ICMP 17 | It provides ping capability. It is useful to check if the design is *up* when using standard network equipment such as, routers or NICs. 18 | 19 | ### UDP 20 | 21 | It provides UDP transport layer functionality. It has a 16-element socket table, which must be filled from the host side in order to receive and send data. 22 | 23 | ```C 24 | struct socket_table { 25 | ap_uint<32> theirIP; 26 | ap_uint<16> theirPort; 27 | ap_uint<16> myPort; 28 | ap_uint< 1> valid; 29 | } 30 | ``` 31 | 32 | The user application communicates with this module using the *S_AXIS_sk2nl* and *M_AXIS_nl2sk* AXI4-Stream interface. 33 | 34 | In the transmitting side, the application sends the payload identifying the socket using `dest`. If the socket is valid, an UDP packet containing the payload is populated to the network. If the socket is not valid, the payload is dropped. 35 | 36 | In the receiving side UDP packets are parsed and the socket information is compared against the socket table. If the socket information is valid, the UDP will populate the payload to the application setting `dest` accordingly, the `user` signal will also contains metadata pertaining to source and destination IP address as well as source and destination port. 37 | 38 | Currently, to simplify the receiver side logic, valid incoming connections must be fully specified in the socket table. 39 | 40 | 41 | The structure for these two interfaces are specified below. 42 | 43 | #### User kernel to network layer (S_AXIS_sk2nl) 44 | 45 | ```C 46 | struct udp_app2nl { 47 | ap_uint<512> data; 48 | ap_uint< 64> keep; 49 | ap_uint< 16> dest; 50 | ap_uint< 1> last; 51 | } 52 | ``` 53 | 54 | #### Network layer to user kernel (M_AXIS_nl2sk) 55 | 56 | ```C 57 | 58 | struct userMetadata { 59 | ap_uint<32> myIP; 60 | ap_uint<32> theirIP; 61 | ap_uint<16> myPort; 62 | ap_uint<16> theirPort; 63 | }; 64 | 65 | struct udp_nl2app { 66 | ap_uint<512> data; 67 | ap_uint< 64> keep; 68 | ap_uint< 16> dest; 69 | ap_uint< 1> last; 70 | userMetadata user; 71 | } 72 | ``` 73 | 74 | ## Embedded Probes 75 | 76 | The network layer contains embedded probes at different points in order to facilitate debug and monitorization. These probes provide the following metrics: a) number of packets, b) number of bytes and c) active time (number of cycles), suffices `_packets`, `_bytes` and `_cycles` respectively. 77 | 78 | These metrics can can be clear by writing `0x1` to the register `debug_reset_counters`, be aware that this is global event and all probes are clear. 79 | 80 | The `NetworkLayer` class in the [vnx_util.py](../Notebooks/vnx_utils.py) file provides the `getDebugProbes` property that returns a dictionary with the current value of the probes. 81 | 82 | Below you can find the probes and their description. For more information about the offset address of each of them refer to the [kernel.xml](kernel.xml) file. 83 | 84 | ### Receiving Path 85 | 86 | | Name | Description | 87 | |--------|---------------------------------------------| 88 | | eth_in | Incoming packets from the Network interface | 89 | | pkth_in | Incoming packets after filtering | 90 | | arp_in | Incoming ARP packets | 91 | | icmp_in | Incoming ICMP packets | 92 | | udp_in | Incoming UDP packets | 93 | | app_in | Incoming UDP Segments to the application | 94 | 95 | 96 | ### Transmitting Path 97 | 98 | | Name | Description | 99 | |--------|---------------------------------------------| 100 | | eth_out | Outgoing packets to the Network interface | 101 | | ethhi_out | Outgoing packets after Ethernet header insertion | 102 | | arp_out | Outgoing ARP packets | 103 | | icmp_out | Outgoing ICMP packets | 104 | | udp_out | Outgoing UDP packets | 105 | | app_out | Outgoing UDP Segments from the application | 106 | 107 | ------------------------------------------------------ 108 |

Copyright© 2022 Xilinx

-------------------------------------------------------------------------------- /NetLayers/package_netlayer.tcl: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020, Xilinx, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without modification, 5 | # are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright notice, 11 | # this list of conditions and the following disclaimer in the documentation 12 | # and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its contributors 15 | # may be used to endorse or promote products derived from this software 16 | # without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 | # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// Copyright (c) 2020 Xilinx, Inc. 27 | 28 | if { $::argc != 3 } { 29 | puts "ERROR: Program \"$::argv0\" requires 3 arguments!, (${argc} given)\n" 30 | puts "Usage: $::argv0 \n" 31 | exit 32 | } 33 | 34 | set xoname [lindex $::argv 0] 35 | set krnl_name [lindex $::argv 1] 36 | set device [lindex $::argv 2] 37 | 38 | set suffix "${krnl_name}_${device}" 39 | 40 | puts "INFO: xoname-> ${xoname}\n krnl_name-> ${krnl_name}\n device-> ${device}\n" 41 | 42 | set projName kernel_pack 43 | set bd_name network_layer_bd 44 | set root_dir "[file normalize "."]" 45 | set path_to_hdl "${root_dir}/src" 46 | set path_to_ip "${root_dir}/100G-fpga-network-stack-core" 47 | set path_to_packaged "./packaged_kernel_${suffix}" 48 | set path_to_tmp_project "./tmp_${suffix}" 49 | 50 | #get projPart 51 | source platform.tcl 52 | 53 | if {[string first "fsvh" ${projPart}] != -1} { 54 | set path_to_ip ${path_to_ip}/synthesis_results_HBM 55 | } elseif {[string first "vsva" ${projPart}] != -1} { 56 | set path_to_ip ${path_to_ip}/synthesis_results_versalaicore 57 | } else { 58 | set path_to_ip ${path_to_ip}/synthesis_results_noHBM 59 | } 60 | 61 | ## Create Vivado project and add IP cores 62 | create_project -force $projName $path_to_tmp_project -part $projPart 63 | 64 | add_files -norecurse ${path_to_hdl} 65 | 66 | set_property ip_repo_paths ${path_to_ip} [current_project] 67 | 68 | update_compile_order -fileset sources_1 69 | 70 | source ${root_dir}/bd_network_layer.tcl -notrace 71 | update_compile_order -fileset sources_1 72 | 73 | 74 | generate_target all [get_files ${path_to_tmp_project}/${projName}.srcs/sources_1/bd/${bd_name}/${bd_name}.bd] 75 | export_ip_user_files -of_objects [get_files ${path_to_tmp_project}/${projName}.srcs/sources_1/bd/${bd_name}/${bd_name}.bd] -no_script -sync -force -quiet 76 | create_ip_run [get_files -of_objects [get_fileset sources_1] ${path_to_tmp_project}/${projName}.srcs/sources_1/bd/${bd_name}/${bd_name}.bd] 77 | update_compile_order -fileset sources_1 78 | set_property top networklayer [current_fileset] 79 | 80 | # Package IP 81 | 82 | ipx::package_project -root_dir ${path_to_packaged} -vendor xilinx.com -library RTLKernel -taxonomy /KernelIP -import_files -set_current false 83 | ipx::unload_core ${path_to_packaged}/component.xml 84 | ipx::edit_ip_in_project -upgrade true -name tmp_edit_project -directory ${path_to_packaged} ${path_to_packaged}/component.xml 85 | set_property core_revision 1 [ipx::current_core] 86 | foreach up [ipx::get_user_parameters] { 87 | ipx::remove_user_parameter [get_property NAME $up] [ipx::current_core] 88 | } 89 | set_property sdx_kernel true [ipx::current_core] 90 | set_property sdx_kernel_type rtl [ipx::current_core] 91 | ipx::create_xgui_files [ipx::current_core] 92 | ipx::add_bus_interface ap_clk [ipx::current_core] 93 | set_property abstraction_type_vlnv xilinx.com:signal:clock_rtl:1.0 [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 94 | set_property bus_type_vlnv xilinx.com:signal:clock:1.0 [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 95 | ipx::add_port_map CLK [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]] 96 | set_property physical_name ap_clk [ipx::get_port_maps CLK -of_objects [ipx::get_bus_interfaces ap_clk -of_objects [ipx::current_core]]] 97 | ipx::associate_bus_interfaces -busif S_AXIS_eth2nl -clock ap_clk [ipx::current_core] 98 | ipx::associate_bus_interfaces -busif M_AXIS_nl2eth -clock ap_clk [ipx::current_core] 99 | ipx::associate_bus_interfaces -busif S_AXIS_sk2nl -clock ap_clk [ipx::current_core] 100 | ipx::associate_bus_interfaces -busif M_AXIS_nl2sk -clock ap_clk [ipx::current_core] 101 | ipx::associate_bus_interfaces -busif S_AXIL_nl -clock ap_clk [ipx::current_core] 102 | 103 | 104 | 105 | set_property xpm_libraries {XPM_CDC XPM_MEMORY XPM_FIFO} [ipx::current_core] 106 | set_property supported_families { } [ipx::current_core] 107 | set_property auto_family_support_level level_2 [ipx::current_core] 108 | ipx::update_checksums [ipx::current_core] 109 | ipx::save_core [ipx::current_core] 110 | close_project -delete 111 | 112 | ## Generate XO 113 | if {[file exists "${xoname}"]} { 114 | file delete -force "${xoname}" 115 | } 116 | 117 | package_xo -xo_path ${xoname} -kernel_name ${krnl_name} -ip_directory ./packaged_kernel_${suffix} -kernel_xml ./kernel.xml 118 | -------------------------------------------------------------------------------- /NetLayers/platform.tcl: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2021 Xilinx, Inc 2 | # 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | 5 | set words [split $device "_"] 6 | set board [lindex $words 1] 7 | 8 | if {[string first "u55n" ${board}] != -1} { 9 | set projPart "xcu55n-fsvh2892-2L-e" 10 | } elseif {[string first "u50" ${board}] != -1} { 11 | set projPart "xcu50-fsvh2104-2-e" 12 | } elseif {[string first "u55c" ${board}] != -1} { 13 | set projPart "xcu55c-fsvh2892-2L-e" 14 | } elseif {[string first "u200" ${board}] != -1} { 15 | set projPart "xcu200-fsgd2104-2-e" 16 | } elseif {[string first "u250" ${board}] != -1} { 17 | set projPart "xcu250-figd2104-2L-e" 18 | } elseif {[string first "u280" ${board}] != -1} { 19 | set projPart "xcu280-fsvh2892-2L-e" 20 | } elseif {[string first "vck5000" ${board}] != -1} { 21 | set projPart "xcvc1902-vsva2197-2MP-e-S" 22 | } else { 23 | catch {common::send_gid_msg -ssname BD::TCL -id 2041 -severity "ERROR" "unsupported device: ${device}"} 24 | return 1 25 | } 26 | -------------------------------------------------------------------------------- /NetLayers/src/6to3_reducer.vhd: -------------------------------------------------------------------------------- 1 | -- /************************************************ 2 | -- BSD 3-Clause License 3 | -- 4 | -- Copyright (c) 2019, HPCN Group, UAM Spain (hpcn-uam.es) 5 | -- and Systems Group, ETH Zurich (systems.ethz.ch) 6 | -- All rights reserved. 7 | -- 8 | -- 9 | -- Redistribution and use in source and binary forms, with or without 10 | -- modification, are permitted provided that the following conditions are met: 11 | -- 12 | -- * Redistributions of source code must retain the above copyright notice, this 13 | -- list of conditions and the following disclaimer. 14 | -- 15 | -- * Redistributions in binary form must reproduce the above copyright notice, 16 | -- this list of conditions and the following disclaimer in the documentation 17 | -- and/or other materials provided with the distribution. 18 | -- 19 | -- * Neither the name of the copyright holder nor the names of its 20 | -- contributors may be used to endorse or promote products derived from 21 | -- this software without specific prior written permission. 22 | -- 23 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | -- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | -- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | -- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | -- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | -- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | -- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | -- 34 | -- ************************************************/ 35 | 36 | -------------------------------------------------------------- 37 | -- Reduce 6 input, outputs the addition in 3 bits 38 | -- It's a carry-save like adder. 39 | -------------------------------------------------------------- 40 | library IEEE; 41 | use IEEE.std_logic_1164.all; 42 | use IEEE.std_logic_arith.all; 43 | use IEEE.std_logic_unsigned.all; 44 | 45 | entity reducer_6to3 is port ( 46 | x: in std_logic_vector (5 downto 0); 47 | s: out std_logic_vector (2 downto 0) 48 | ); 49 | end reducer_6to3 ; 50 | 51 | architecture rtl of reducer_6to3 is 52 | type memrom is array (0 to 63) of STD_LOGIC; 53 | signal sum_0: memrom := x"6996_9669_9669_6996"; 54 | signal sum_1: memrom := x"177E_7EE8_7EE8_E881"; 55 | signal sum_2: memrom := x"0001_0117_0117_177F"; 56 | 57 | begin 58 | 59 | s(2) <= sum_2(conv_integer(x)); 60 | s(1) <= sum_1(conv_integer(x)); 61 | s(0) <= sum_0(conv_integer(x)); 62 | 63 | end rtl; 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /NetLayers/src/axi4stream_constant.v: -------------------------------------------------------------------------------- 1 | /************************************************ 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2019, HPCN Group, UAM Spain (hpcn-uam.es) 5 | All rights reserved. 6 | 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | ************************************************/ 34 | 35 | module axi4stream_constant #( 36 | parameter C_AXI_TDATA_WIDTH = 512 37 | ) ( 38 | input wire CLK , // Clock 39 | input wire RST_N , // Rst (active low level) 40 | output wire [C_AXI_TDATA_WIDTH-1:0] M_AXIS_TDATA , 41 | output wire M_AXIS_TLAST , 42 | output wire [(C_AXI_TDATA_WIDTH/8)-1:0] M_AXIS_TKEEP , 43 | output wire M_AXIS_TVALID, 44 | input wire M_AXIS_TREADY 45 | ); 46 | 47 | assign M_AXIS_TDATA = {C_AXI_TDATA_WIDTH{1'b0}}; 48 | assign M_AXIS_TKEEP = {(C_AXI_TDATA_WIDTH/8){1'b0}}; 49 | assign M_AXIS_TLAST = 1'b0; 50 | assign M_AXIS_TVALID = 1'b0; 51 | 52 | endmodule -------------------------------------------------------------------------------- /NetLayers/src/axi4stream_sinker.v: -------------------------------------------------------------------------------- 1 | /************************************************ 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2019, HPCN Group, UAM Spain (hpcn-uam.es) 5 | All rights reserved. 6 | 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | ************************************************/ 34 | 35 | module axi4stream_sinker #( 36 | parameter C_AXI_TDATA_WIDTH = 512 37 | ) ( 38 | input wire CLK , // Clock 39 | input wire RST_N , // Rst (active low level) 40 | input wire [C_AXI_TDATA_WIDTH-1:0] S_AXIS_TDATA , 41 | input wire S_AXIS_TLAST , 42 | input wire [(C_AXI_TDATA_WIDTH/8)-1:0] S_AXIS_TKEEP , 43 | input wire S_AXIS_TVALID, 44 | output wire S_AXIS_TREADY 45 | ); 46 | assign S_AXIS_TREADY = 1'b1; 47 | 48 | endmodule -------------------------------------------------------------------------------- /NetLayers/src/bandwidth_reg.v: -------------------------------------------------------------------------------- 1 | /************************************************ 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2019, HPCN Group, UAM Spain (hpcn-uam.es) 5 | All rights reserved. 6 | 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the copyright holder nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | ************************************************/ 34 | 35 | /* 36 | * The debug_slot is arranged as follow 37 | * 38 | * ------------------------------------------------------------- 39 | * | Time | Time | Bytes | Bytes | Packets | Packets | 40 | * | LSB | MSB | LSB | MSB | LSB | MSB | 41 | * ------------------------------------------------------------- 42 | * 191 159 127 95 63 31 0 43 | * 44 | * 45 | */ 46 | 47 | module bandwidth_reg # 48 | ( 49 | // Users to add parameters here 50 | 51 | // User parameters ends 52 | // Do not modify the parameters beyond this line 53 | 54 | // Width of S_AXI data bus 55 | parameter C_AXIS_DATA_WIDTH = 512, 56 | parameter TUSER_WIDTH = 0, 57 | parameter TDEST_WIDTH = 0 58 | 59 | // Width of S_AXI address bus 60 | 61 | ) 62 | ( 63 | // Users to add ports here 64 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 IN_DBG TDATA" *) 65 | input wire [C_AXIS_DATA_WIDTH-1:0] S_AXIS_TDATA, 66 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 IN_DBG TKEEP" *) 67 | input wire [(C_AXIS_DATA_WIDTH/8)-1:0] S_AXIS_TKEEP, 68 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 IN_DBG TVALID" *) 69 | input wire S_AXIS_TVALID, 70 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 IN_DBG TREADY" *) 71 | output wire S_AXIS_TREADY, 72 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 IN_DBG TLAST" *) 73 | input wire S_AXIS_TLAST, 74 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 IN_DBG TUSER" *) 75 | input wire [TUSER_WIDTH-1:0] S_AXIS_TUSER, 76 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 IN_DBG TDEST" *) 77 | input wire [TDEST_WIDTH-1:0] S_AXIS_TDEST, 78 | 79 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 OUT_DBG TDATA" *) 80 | output wire [C_AXIS_DATA_WIDTH-1:0] M_AXIS_TDATA, 81 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 OUT_DBG TKEEP" *) 82 | output wire [(C_AXIS_DATA_WIDTH/8)-1:0] M_AXIS_TKEEP, 83 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 OUT_DBG TVALID" *) 84 | output wire M_AXIS_TVALID, 85 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 OUT_DBG TREADY" *) 86 | input wire M_AXIS_TREADY, 87 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 OUT_DBG TLAST" *) 88 | output wire M_AXIS_TLAST, 89 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 OUT_DBG TUSER" *) 90 | output wire [TUSER_WIDTH-1:0] M_AXIS_TUSER, 91 | (* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 OUT_DBG TDEST" *) 92 | output wire [TDEST_WIDTH-1:0] M_AXIS_TDEST, 93 | 94 | (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 S_AXI_ACLK CLK" *) 95 | (* X_INTERFACE_PARAMETER = "ASSOCIATED_BUSIF IN_DBG:OUT_DBG, ASSOCIATED_RESET S_AXI_ARESETN" *) 96 | input wire S_AXI_ACLK, 97 | // Global Reset Signal. This Signal is Active LOW 98 | input wire S_AXI_ARESETN, 99 | 100 | output reg [191:0] debug_slot, 101 | input wire user_rst_n 102 | 103 | 104 | ); 105 | 106 | reg [63:0] time_counter; 107 | reg [63:0] byte_counter; 108 | reg [63:0] pkt_counter; 109 | reg active_counter; 110 | wire [6:0] number_of_ones; 111 | reg [6:0] number_of_ones_1d; 112 | reg tvalid_1d; 113 | reg tready_1d; 114 | reg tlast_1d; 115 | 116 | reg [31:0] time_counter_lsb; 117 | reg [31:0] time_counter_msb; 118 | 119 | 120 | always @( posedge S_AXI_ACLK ) begin 121 | if ( S_AXI_ARESETN == 1'b0 || user_rst_n== 1'b0) begin 122 | byte_counter <= {64{1'b0}}; 123 | time_counter <= {64{1'b0}}; 124 | active_counter <= 1'b0; 125 | pkt_counter <= {64{1'b0}}; 126 | tvalid_1d <= 1'b0; 127 | tready_1d <= 1'b0; 128 | tlast_1d <= 1'b0; 129 | number_of_ones_1d <= {7{1'b0}}; 130 | time_counter_lsb <= {32{1'b0}}; 131 | time_counter_msb <= {32{1'b0}}; 132 | end 133 | else begin 134 | 135 | time_counter <= (active_counter) ? time_counter + 1 : time_counter; 136 | 137 | if (S_AXIS_TVALID && S_AXIS_TREADY) begin 138 | active_counter <= 1'b1; 139 | end 140 | 141 | if (tvalid_1d && tready_1d) begin 142 | byte_counter <= byte_counter + number_of_ones_1d; 143 | {time_counter_msb,time_counter_lsb} <= time_counter + 1; // this +1 is because active_counter is behind one cycle 144 | end 145 | 146 | if (tvalid_1d && tready_1d && tlast_1d) begin 147 | pkt_counter <= pkt_counter + 1; 148 | end 149 | 150 | number_of_ones_1d <= number_of_ones; 151 | tvalid_1d <= S_AXIS_TVALID; 152 | tready_1d <= S_AXIS_TREADY; 153 | tlast_1d <= S_AXIS_TLAST; 154 | 155 | end 156 | end 157 | 158 | always @( posedge S_AXI_ACLK ) begin 159 | debug_slot <={time_counter_lsb,time_counter_msb, byte_counter[31:0],byte_counter[63:32],pkt_counter[31:0],pkt_counter[63:32]}; 160 | end 161 | 162 | counter64_7_v3 counter64_7_v3_i ( 163 | .x(S_AXIS_TKEEP ), 164 | .s(number_of_ones) 165 | ); 166 | 167 | // make bridge connections 168 | 169 | assign M_AXIS_TDATA = S_AXIS_TDATA; 170 | assign M_AXIS_TKEEP = S_AXIS_TKEEP; 171 | assign M_AXIS_TVALID = S_AXIS_TVALID; 172 | assign S_AXIS_TREADY = M_AXIS_TREADY; 173 | assign M_AXIS_TLAST = S_AXIS_TLAST; 174 | assign M_AXIS_TUSER = S_AXIS_TUSER; 175 | assign M_AXIS_TDEST = S_AXIS_TDEST; 176 | 177 | 178 | endmodule 179 | -------------------------------------------------------------------------------- /NetLayers/src/counter_64_7_v3.vhd: -------------------------------------------------------------------------------- 1 | -- /************************************************ 2 | -- BSD 3-Clause License 3 | -- 4 | -- Copyright (c) 2019, HPCN Group, UAM Spain (hpcn-uam.es) 5 | -- and Systems Group, ETH Zurich (systems.ethz.ch) 6 | -- All rights reserved. 7 | -- 8 | -- 9 | -- Redistribution and use in source and binary forms, with or without 10 | -- modification, are permitted provided that the following conditions are met: 11 | -- 12 | -- * Redistributions of source code must retain the above copyright notice, this 13 | -- list of conditions and the following disclaimer. 14 | -- 15 | -- * Redistributions in binary form must reproduce the above copyright notice, 16 | -- this list of conditions and the following disclaimer in the documentation 17 | -- and/or other materials provided with the distribution. 18 | -- 19 | -- * Neither the name of the copyright holder nor the names of its 20 | -- contributors may be used to endorse or promote products derived from 21 | -- this software without specific prior written permission. 22 | -- 23 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | -- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | -- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | -- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | -- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | -- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | -- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | -- 34 | -- ************************************************/ 35 | 36 | 37 | -------------------------------------------------------------- 38 | -- 64 bit counter 39 | -- 40 | -------------------------------------------------------------- 41 | library IEEE; 42 | use IEEE.std_logic_1164.all; 43 | use IEEE.std_logic_arith.all; 44 | use IEEE.std_logic_unsigned.all; 45 | 46 | entity counter64_7_v3 is port ( 47 | x: in std_logic_vector (63 downto 0); 48 | s: out std_logic_vector (6 downto 0) 49 | ); 50 | end counter64_7_v3 ; 51 | 52 | architecture rtl_3 of counter64_7_v3 is 53 | 54 | COMPONENT reducer_6to3 is port ( 55 | x: in std_logic_vector (5 downto 0); 56 | s: out std_logic_vector (2 downto 0) 57 | ); 58 | END COMPONENT; 59 | 60 | 61 | type sums_L1 is array (0 to 10) of STD_LOGIC_VECTOR(2 downto 0); 62 | signal sum_L1: sums_L1; 63 | 64 | signal L1_vert0: STD_LOGIC_VECTOR(10 downto 0); 65 | signal L1_vert1: STD_LOGIC_VECTOR(10 downto 0); 66 | signal L1_vert2: STD_LOGIC_VECTOR(10 downto 0); 67 | signal sum_L2_0, sum_L2_1, sum_L2_2: STD_LOGIC_VECTOR(2 downto 0); 68 | signal sum_L2_3, sum_L2_4, sum_L2_5: STD_LOGIC_VECTOR(2 downto 0); 69 | 70 | signal sum_L3_0: STD_LOGIC_VECTOR(3 downto 0); 71 | signal sum_L3_1: STD_LOGIC_VECTOR(3 downto 0); 72 | signal sum_L3_2: STD_LOGIC_VECTOR(3 downto 0); 73 | signal sum_L4: STD_LOGIC_VECTOR(6 downto 0); 74 | 75 | signal xx, xx1, xx2, xx3: STD_LOGIC_VECTOR(5 downto 0); 76 | 77 | begin 78 | 79 | -- First level of reduction 80 | L_1: for i in 0 to 9 generate 81 | reduc: reducer_6to3 port map( x => x(i*6+5 downto i*6), s => sum_L1(i) ); 82 | end generate; 83 | xx <= x(63 downto 60)&"00"; 84 | reduc10: reducer_6to3 port map( x => xx, s => sum_L1(10) ); 85 | 86 | 87 | -- grouped vertically result of first level of reduction 88 | L_1a: for i in 0 to 10 generate 89 | L1_vert0(i) <= sum_L1(i)(0); 90 | L1_vert1(i) <= sum_L1(i)(1); 91 | L1_vert2(i) <= sum_L1(i)(2); 92 | end generate; 93 | 94 | -- Second level of reduction 95 | -- reduce complete 6 to 3 96 | L_2b: reducer_6to3 port map( x => L1_vert0(5 downto 0), s => sum_L2_0 ); 97 | L_2c: reducer_6to3 port map( x => L1_vert1(5 downto 0), s => sum_L2_1 ); 98 | L_2d: reducer_6to3 port map( x => L1_vert2(5 downto 0), s => sum_L2_2 ); 99 | 100 | -- reduce partial 5 to 3 101 | xx1 <= L1_vert0(10 downto 6)&'0'; 102 | xx2 <= L1_vert1(10 downto 6)&'0'; 103 | xx3 <= L1_vert2(10 downto 6)&'0'; 104 | 105 | L_2e: reducer_6to3 port map( x => xx1, s => sum_L2_3 ); 106 | L_2f: reducer_6to3 port map( x => xx2, s => sum_L2_4 ); 107 | L_2g: reducer_6to3 port map( x => xx3, s => sum_L2_5 ); 108 | 109 | 110 | 111 | -- sum result of second level reduction 112 | sum_L3_0 <= sum_L2_0 + ('0' & sum_L2_3); 113 | sum_L3_1 <= sum_L2_1 + ('0' & sum_L2_4); 114 | sum_L3_2 <= sum_L2_2 + ('0' & sum_L2_5); 115 | 116 | --L4 117 | sum_L4 <= ('0' & sum_L3_2 & "00") + (sum_L3_1 & '0') + (sum_L3_0); 118 | 119 | s <= sum_L4; 120 | end rtl_3; 121 | 122 | -------------------------------------------------------------------------------- /NetLayers/src/networklayer.v: -------------------------------------------------------------------------------- 1 | /************************************************ 2 | Copyright (c) 2020, Xilinx, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | Copyright (c) 2020 Xilinx, Inc. 29 | ************************************************/ 30 | 31 | `default_nettype wire 32 | `timescale 1 ns / 1 ps 33 | // Top level of the kernel. Do not modify module name, parameters or ports. 34 | module networklayer #( 35 | parameter integer AXIL_CTRL_ADDR_WIDTH = 16, 36 | parameter integer AXIL_CTRL_DATA_WIDTH = 32, 37 | parameter integer AXIS_TDATA_WIDTH = 512, 38 | parameter integer STREAMING_TDEST_WIDTH = 16, 39 | parameter integer STREAMING_TUSER_WIDTH = 96 40 | ) 41 | ( 42 | // System clocks and resets 43 | (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 ap_clk CLK" *) 44 | (* X_INTERFACE_PARAMETER = "ASSOCIATED_BUSIF S_AXIS_eth2nl:M_AXIS_nl2eth:S_AXIS_sk2nl:M_AXIS_nl2sk:S_AXIL_nl, ASSOCIATED_RESET ap_rst_n" *) 45 | input wire ap_clk, 46 | (* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 ap_rst_n RST" *) 47 | (* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_LOW" *) 48 | input wire ap_rst_n, 49 | 50 | // AXI4-Stream streaming ethenet 2 network layer 51 | input wire S_AXIS_eth2nl_tvalid, 52 | output wire S_AXIS_eth2nl_tready, 53 | input wire [AXIS_TDATA_WIDTH-1:0] S_AXIS_eth2nl_tdata, 54 | input wire [AXIS_TDATA_WIDTH/8-1:0] S_AXIS_eth2nl_tkeep, 55 | input wire S_AXIS_eth2nl_tlast, 56 | // AXI4-Stream network layer to ethernet 57 | output wire M_AXIS_nl2eth_tvalid, 58 | input wire M_AXIS_nl2eth_tready, 59 | output wire [AXIS_TDATA_WIDTH-1:0] M_AXIS_nl2eth_tdata, 60 | output wire [AXIS_TDATA_WIDTH/8-1:0] M_AXIS_nl2eth_tkeep, 61 | output wire M_AXIS_nl2eth_tlast, 62 | // AXI4-Stream streaming kernel 2 network layer 63 | input wire S_AXIS_sk2nl_tvalid, 64 | output wire S_AXIS_sk2nl_tready, 65 | input wire [AXIS_TDATA_WIDTH-1:0] S_AXIS_sk2nl_tdata, 66 | input wire [AXIS_TDATA_WIDTH/8-1:0] S_AXIS_sk2nl_tkeep, 67 | input wire S_AXIS_sk2nl_tlast, 68 | input wire [STREAMING_TDEST_WIDTH-1:0] S_AXIS_sk2nl_tdest, 69 | // AXI4-Stream network layer to streaming kernel 70 | output wire M_AXIS_nl2sk_tvalid, 71 | input wire M_AXIS_nl2sk_tready, 72 | output wire [AXIS_TDATA_WIDTH-1:0] M_AXIS_nl2sk_tdata, 73 | output wire [AXIS_TDATA_WIDTH/8-1:0] M_AXIS_nl2sk_tkeep, 74 | output wire M_AXIS_nl2sk_tlast, 75 | output wire [STREAMING_TDEST_WIDTH-1:0] M_AXIS_nl2sk_tdest, 76 | output wire [STREAMING_TUSER_WIDTH-1:0] M_AXIS_nl2sk_tuser, 77 | // AXI4-Lite 78 | input wire S_AXIL_nl_awvalid, 79 | output wire S_AXIL_nl_awready, 80 | input wire [AXIL_CTRL_ADDR_WIDTH-1:0] S_AXIL_nl_awaddr, 81 | input wire S_AXIL_nl_wvalid, 82 | output wire S_AXIL_nl_wready, 83 | input wire [AXIL_CTRL_DATA_WIDTH-1:0] S_AXIL_nl_wdata, 84 | input wire [AXIL_CTRL_DATA_WIDTH/8-1:0] S_AXIL_nl_wstrb, 85 | input wire S_AXIL_nl_arvalid, 86 | output wire S_AXIL_nl_arready, 87 | input wire [AXIL_CTRL_ADDR_WIDTH-1:0] S_AXIL_nl_araddr, 88 | output wire S_AXIL_nl_rvalid, 89 | input wire S_AXIL_nl_rready, 90 | output wire [AXIL_CTRL_DATA_WIDTH-1:0] S_AXIL_nl_rdata, 91 | output wire [1:0] S_AXIL_nl_rresp, 92 | output wire S_AXIL_nl_bvalid, 93 | input wire S_AXIL_nl_bready, 94 | output wire [1:0] S_AXIL_nl_bresp 95 | ); 96 | 97 | 98 | network_layer_bd network_layer_bd_i ( 99 | .ap_clk ( ap_clk), 100 | .ap_rst_n ( ap_rst_n), 101 | // AXI4-Stream streaming ethenet 2 network layer 102 | .S_AXIS_eth2nl_tvalid ( S_AXIS_eth2nl_tvalid), 103 | .S_AXIS_eth2nl_tready ( S_AXIS_eth2nl_tready), 104 | .S_AXIS_eth2nl_tdata ( S_AXIS_eth2nl_tdata), 105 | .S_AXIS_eth2nl_tkeep ( S_AXIS_eth2nl_tkeep), 106 | .S_AXIS_eth2nl_tlast ( S_AXIS_eth2nl_tlast), 107 | // AXI4-Stream network layer to ethernet 108 | .M_AXIS_nl2eth_tvalid ( M_AXIS_nl2eth_tvalid), 109 | .M_AXIS_nl2eth_tready ( M_AXIS_nl2eth_tready), 110 | .M_AXIS_nl2eth_tdata ( M_AXIS_nl2eth_tdata), 111 | .M_AXIS_nl2eth_tkeep ( M_AXIS_nl2eth_tkeep), 112 | .M_AXIS_nl2eth_tlast ( M_AXIS_nl2eth_tlast), 113 | // AXI4-Stream streaming kernel 2 network layer 114 | .S_AXIS_sk2nl_tdata ( S_AXIS_sk2nl_tdata), 115 | .S_AXIS_sk2nl_tkeep ( S_AXIS_sk2nl_tkeep), 116 | .S_AXIS_sk2nl_tlast ( S_AXIS_sk2nl_tlast), 117 | .S_AXIS_sk2nl_tready ( S_AXIS_sk2nl_tready), 118 | .S_AXIS_sk2nl_tdest ( S_AXIS_sk2nl_tdest), 119 | .S_AXIS_sk2nl_tvalid ( S_AXIS_sk2nl_tvalid), 120 | // AXI4-Stream network layer to streaming kernel 121 | .M_AXIS_nl2sk_tdata ( M_AXIS_nl2sk_tdata), 122 | .M_AXIS_nl2sk_tkeep ( M_AXIS_nl2sk_tkeep), 123 | .M_AXIS_nl2sk_tlast ( M_AXIS_nl2sk_tlast), 124 | .M_AXIS_nl2sk_tready ( M_AXIS_nl2sk_tready), 125 | .M_AXIS_nl2sk_tdest ( M_AXIS_nl2sk_tdest), 126 | .M_AXIS_nl2sk_tuser ( M_AXIS_nl2sk_tuser), 127 | .M_AXIS_nl2sk_tvalid ( M_AXIS_nl2sk_tvalid), 128 | // AXI4-Lite 129 | .S_AXIL_nl_awvalid ( S_AXIL_nl_awvalid), 130 | .S_AXIL_nl_awready ( S_AXIL_nl_awready), 131 | .S_AXIL_nl_awaddr ( S_AXIL_nl_awaddr), 132 | .S_AXIL_nl_wvalid ( S_AXIL_nl_wvalid), 133 | .S_AXIL_nl_wready ( S_AXIL_nl_wready), 134 | .S_AXIL_nl_wdata ( S_AXIL_nl_wdata), 135 | .S_AXIL_nl_wstrb ( S_AXIL_nl_wstrb), 136 | .S_AXIL_nl_arvalid ( S_AXIL_nl_arvalid), 137 | .S_AXIL_nl_arready ( S_AXIL_nl_arready), 138 | .S_AXIL_nl_araddr ( S_AXIL_nl_araddr), 139 | .S_AXIL_nl_rvalid ( S_AXIL_nl_rvalid), 140 | .S_AXIL_nl_rready ( S_AXIL_nl_rready), 141 | .S_AXIL_nl_rdata ( S_AXIL_nl_rdata), 142 | .S_AXIL_nl_rresp ( S_AXIL_nl_rresp), 143 | .S_AXIL_nl_bvalid ( S_AXIL_nl_bvalid), 144 | .S_AXIL_nl_bready ( S_AXIL_nl_bready), 145 | .S_AXIL_nl_bresp ( S_AXIL_nl_bresp), 146 | .S_AXIL_nl_arprot ( 3'b0), 147 | .S_AXIL_nl_awprot ( 3'b0) 148 | ); 149 | 150 | 151 | endmodule -------------------------------------------------------------------------------- /Notebooks/README.md: -------------------------------------------------------------------------------- 1 | # Companion Notebooks 2 | 3 | ## Environment 4 | 5 | To run these Jupyter notebooks, you will need an environment with JupyterLab and `pynq` installed, the best way to accomplish this is to create a [Python virtual environment](https://docs.python.org/3/library/venv.html#module-venv) or to create a [Conda environment](https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/environments.html#conda-environments). 6 | 7 | The steps to Install Conda and get the environment setup are [here](https://pynq.readthedocs.io/en/latest/getting_started/alveo_getting_started.html#install-conda). 8 | 9 | ## Distributed Alveo cards 10 | 11 | The Dask class and Notebooks that use such class are only intended for systems where the Alveo cards are located in different systems, either different servers or different VMs. 12 | 13 | For these type of scenarios you can use the Notebooks as it. 14 | 15 | ## Multiple Alveo cards in the same system 16 | 17 | If you have multiple Alveo cards in the same system you can still reuse the Notebooks, but, some modifications are needed. 18 | 19 | To begin with, we will use `pynq` to [identify how many Alveo cards are present in the system and their id](https://pynq.readthedocs.io/en/latest/pynq_alveo.html#multiple-cards). 20 | 21 | ```python 22 | import pynq 23 | for i in range(len(pynq.Device.devices)): 24 | print("{} {}".format(i, pynq.Device.devices[i].name)) 25 | ``` 26 | 27 | An example output should look like this, where the first column is the id and the second one is the Alveo shell 28 | 29 | ```console 30 | 0 xilinx_u280_xdma_201920_3 31 | 1 xilinx_u250_xdma_201830_2 32 | 2 xilinx_u280_xdma_201920_3 33 | ``` 34 | 35 | In this case, three cards are available. We are only interested in the Alveo U280. To use them the `Overlay` class in `pynq` allows us to specify the device where the `xclbin` file is downloaded. 36 | 37 | In the companion Notebooks discard everything before **Download xclbin to workers*** and use this code to configure the Alveo cards. *Replace Alveo id accordingly.* 38 | 39 | ```python 40 | from vnx_utils import * 41 | import pynq 42 | import numpy as np 43 | 44 | xclbin = 45 | ol_w0 = pynq.Overlay(xclbin, device=pynq.Device.devices[0]) 46 | ol_w1 = pynq.Overlay(xclbin, device=pynq.Device.devices[2]) 47 | ``` 48 | 49 | You can reuse the rest of the Notebook after this point. 50 | 51 | ## Getting Started with these Notebooks 52 | 53 | To use these notebooks you need `pynq` installed in your system. `pynq` is available in [PYPI](https://pypi.org/project/pynq/), hence you can install it using `pip install pynq`. However, for a smoother and more iterative experience, we recommend to use [JupyterLab](https://jupyterlab.readthedocs.io/en/stable/). As described in the [Environment](#environment) section, the easiest way to accomplish this is to use a [Conda environment](https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/environments.html#conda-environments). 54 | 55 | Once `pynq` and `JupyterLab` are installed you can start using these notebooks. 56 | 57 | ### Launch JupyterLab 58 | 59 | It is recommended to launch `JupyterLab` directly from the `Notebooks` directory. 60 | 61 | ```sh 62 | jupyter lab 63 | ``` 64 | 65 | This will launch a JupyterLab on a web browser. 66 | 67 | ![](../img/jupyterlab.png) 68 | 69 | Double click in any of the notebooks you want to use --- files with extension `*.ipynb`. Learn more about JupyterLab [here](https://jupyterlab.readthedocs.io/en/stable/user/interface.html). 70 | 71 | ------------------------------------------------------ 72 |

Copyright© 2022 Xilinx

-------------------------------------------------------------------------------- /Notebooks/dask_pynq.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022, Xilinx, Inc. 2 | # All rights reserved. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # 1. Redistributions of source code must retain the above copyright notice, 8 | # this list of conditions and the following disclaimer. 9 | # 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # 3. Neither the name of the copyright holder nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 | # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 22 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 | # OR BUSINESS INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 | # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | __author__ = "Peter Ogden, Mario Ruiz" 31 | __copyright__ = "Copyright 2022, Xilinx Inc." 32 | __email__ = "pynq_support@xilinx.com" 33 | 34 | import pynq 35 | import ctypes 36 | import tempfile 37 | import re 38 | from pynq.pl_server.xrt_device import XrtStream 39 | 40 | """ Simple logic to use Dask on top of pynq """ 41 | 42 | # Hold references to buffers to avoid them being collected 43 | # Won't be visible in the process but is an easy way to 44 | # let workers hold on to local references 45 | buffers = [] 46 | 47 | 48 | # Functions that will be called in the context of dask 49 | def _invalidate(bo, offset, size): 50 | buf = bytearray(size) 51 | pynq.Device.active_device.invalidate(bo, offset, 0, size) 52 | pynq.Device.active_device.buffer_read(bo, offset, buf) 53 | return bytes(buf) 54 | 55 | 56 | def _flush(bo, offset, size, data): 57 | pynq.Device.active_device.buffer_write(bo, offset, bytearray(data)) 58 | pynq.Device.active_device.flush(bo, offset, 0, size) 59 | 60 | 61 | def _read_registers(address, length): 62 | return pynq.Device.active_device.read_registers(address, length) 63 | 64 | 65 | def _write_registers(address, data): 66 | pynq.Device.active_device.write_registers(address, data) 67 | 68 | 69 | def _download(bitstream_data): 70 | with tempfile.NamedTemporaryFile() as f: 71 | f.write(bitstream_data) 72 | f.flush() 73 | ol = pynq.Overlay(f.name) 74 | 75 | 76 | def _alloc(size, memdesc): 77 | mem = pynq.Device.active_device.get_memory(memdesc) 78 | buf = mem.allocate((size,), 'u1') 79 | buffers.append(buf) 80 | return buf.bo, buf.device_address 81 | 82 | 83 | class DaskMemory: 84 | """Memory object proxied over dask 85 | 86 | """ 87 | def __init__(self, device, desc): 88 | self._desc = desc 89 | self._device = device 90 | 91 | def allocate(self, shape, dtype): 92 | from pynq.buffer import PynqBuffer 93 | buf = PynqBuffer(shape, dtype, device_address=0, 94 | bo=0, device=self._device, coherent=False) 95 | bo, addr = self._device._call_dask(_alloc, buf.nbytes, self._desc) 96 | buf.bo = bo 97 | buf.device_address = addr 98 | return buf 99 | 100 | 101 | class DaskDevice(pynq.Device): 102 | """PYNQ Proxy device for using PYNQ via dask 103 | 104 | """ 105 | def __init__(self, client, worker): 106 | """The worker ID should be unique 107 | 108 | """ 109 | super().__init__("dask-" + re.sub(r'[^\w]', '_', worker)) 110 | self._dask_client = client 111 | self._worker = worker 112 | self.capabilities = { 113 | 'REGISTER_RW': True, 114 | 'CALLABLE': True 115 | } 116 | self._streams = {} 117 | self.sync_to_device = self.flush 118 | self.sync_from_device = self.invalidate 119 | 120 | def _call_dask(self, func, *args): 121 | future = self._dask_client.submit(func, *args, workers=self._worker, 122 | pure=False) 123 | return future.result() 124 | 125 | def invalidate(self, bo, offset, ptr, size): 126 | """Copy buffer from the device to the host 127 | """ 128 | 129 | ctype = ctypes.c_uint8 * size 130 | target = ctype.from_address(ptr) 131 | target[:] = self._call_dask(_invalidate, bo, offset, size) 132 | 133 | def flush(self, bo, offset, ptr, size): 134 | """Copy buffer from the host to the device 135 | """ 136 | 137 | ctype = ctypes.c_uint8 * size 138 | target = ctype.from_address(ptr) 139 | self._call_dask(_flush, bo, offset, size, bytes(target)) 140 | 141 | def read_registers(self, address, length): 142 | return self._call_dask(_read_registers, address, length) 143 | 144 | def write_registers(self, address, data): 145 | self._call_dask(_write_registers, address, bytes(data)) 146 | 147 | def get_bitfile_metadata(self, bitfile_name): 148 | return pynq.pl_server.xclbin_parser.XclBin(bitfile_name) 149 | 150 | def open_context(self, description, shared=True): 151 | return pynq.Device.active_device.open_context(description, shared) 152 | 153 | def close_context(self, cu_name): 154 | pynq.Device.active_device.close_context(cu_name) 155 | 156 | def download(self, bitstream, parser=None): 157 | with open(bitstream.bitfile_name, 'rb') as f: 158 | bitstream_data = f.read() 159 | self._call_dask(_download, bitstream_data) 160 | super().post_download(bitstream, parser) 161 | 162 | def get_memory(self, desc): 163 | if desc['streaming']: 164 | if desc['idx'] not in self._streams: 165 | self._streams[desc['idx']] = XrtStream(self, desc) 166 | return self._streams[desc['idx']] 167 | else: 168 | return DaskMemory(self, desc) 169 | 170 | def get_memory_by_idx(self, idx): 171 | for m in self.mem_dict.values(): 172 | if m['idx'] == idx: 173 | return self.get_memory(m) 174 | raise RuntimeError("Could not find memory") 175 | 176 | def get_memory_by_name(self, name): 177 | for m in self.mem_dict.values(): 178 | if m["tag"] == name: 179 | return self.get_memory(m) 180 | raise RuntimeError("Could not find memory") 181 | -------------------------------------------------------------------------------- /THIRD_PARTY_LIC.md: -------------------------------------------------------------------------------- 1 | Components: xup_vitis_network_example 2 | 3 | 4 | /************************************************ 5 | Copyright (c) 2020, Xilinx, Inc. 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without modification, 9 | are permitted provided that the following conditions are met: 10 | 11 | 1. Redistributions of source code must retain the above copyright notice, 12 | this list of conditions and the following disclaimer. 13 | 14 | 2. Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | 3. Neither the name of the copyright holder nor the names of its contributors 19 | may be used to endorse or promote products derived from this software 20 | without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// Copyright (c) 2020 Xilinx, Inc. 31 | ************************************************/ 32 | 33 | 34 | Copyright 2015-2016, 2018-2020 Xilinx Inc 35 | Copyright (c) 2020 Xilinx All rights reserved. 36 | 37 | 38 | Components: jupyter-notebook 39 | 40 | 41 | Copyright (c) 2020, Xilinx, Inc. 42 | All rights reserved. 43 | 44 | Redistribution and use in source and binary forms, with or without modification, 45 | are permitted provided that the following conditions are met: 46 | 47 | 1. Redistributions of source code must retain the above copyright notice, 48 | this list of conditions and the following disclaimer. 49 | 50 | 2. Redistributions in binary form must reproduce the above copyright notice, 51 | this list of conditions and the following disclaimer in the documentation 52 | and/or other materials provided with the distribution. 53 | 54 | 3. Neither the name of the copyright holder nor the names of its contributors 55 | may be used to endorse or promote products derived from this software 56 | without specific prior written permission. 57 | 58 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 59 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 60 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 61 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 62 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 63 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 65 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 66 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.// Copyright (c) 2020 Xilinx, Inc. 67 | 68 | 69 | Components: hpcn-uam 70 | 71 | 72 | /************************************************ 73 | BSD 3-Clause License 74 | 75 | Copyright (c) 2019, HPCN Group, UAM Spain (hpcn-uam.es) 76 | and Systems Group, ETH Zurich (systems.ethz.ch) 77 | All rights reserved. 78 | 79 | 80 | Redistribution and use in source and binary forms, with or without 81 | modification, are permitted provided that the following conditions are met: 82 | 83 | * Redistributions of source code must retain the above copyright notice, this 84 | list of conditions and the following disclaimer. 85 | 86 | * Redistributions in binary form must reproduce the above copyright notice, 87 | this list of conditions and the following disclaimer in the documentation 88 | and/or other materials provided with the distribution. 89 | 90 | * Neither the name of the copyright holder nor the names of its 91 | contributors may be used to endorse or promote products derived from 92 | this software without specific prior written permission. 93 | 94 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 95 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 96 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 97 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 98 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 99 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 100 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 101 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 102 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 103 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 104 | 105 | 106 | Copyright 2019 HPCN Group UAM Spain 107 | Copyright 2020 Xilinx Inc 108 | Copyright (c) 2019 Systems Group ETH Zurich All rights reserved. 109 | Copyright 2019 Naudit HPCN Spain 110 | 111 | 112 | -------------------------------------------------------------------------------- /config_files/connectivity_basic_if0.ini: -------------------------------------------------------------------------------- 1 | [connectivity] 2 | nk=cmac_0:1:cmac_0 3 | nk=networklayer:1:networklayer_0 4 | nk=krnl_mm2s:1:krnl_mm2s_0 5 | nk=krnl_s2mm:1:krnl_s2mm_0 6 | 7 | slr=cmac_0:SLR2 8 | slr=networklayer_0:SLR2 9 | slr=krnl_mm2s_0:SLR2 10 | slr=krnl_s2mm_0:SLR2 11 | 12 | # Connect Network Layer to CMAC DO NOT CHANGE 13 | stream_connect=cmac_0.M_AXIS:networklayer_0.S_AXIS_eth2nl 14 | stream_connect=networklayer_0.M_AXIS_nl2eth:cmac_0.S_AXIS 15 | 16 | # Connect memory mapped with network layers 17 | stream_connect=krnl_mm2s_0.k2n:networklayer_0.S_AXIS_sk2nl 18 | stream_connect=networklayer_0.M_AXIS_nl2sk:krnl_s2mm_0.n2k -------------------------------------------------------------------------------- /config_files/connectivity_basic_if1.ini: -------------------------------------------------------------------------------- 1 | [connectivity] 2 | nk=cmac_1:1:cmac_1 3 | nk=networklayer:1:networklayer_1 4 | nk=krnl_mm2s:1:krnl_mm2s_1 5 | nk=krnl_s2mm:1:krnl_s2mm_1 6 | 7 | slr=cmac_1:SLR2 8 | slr=networklayer_1:SLR2 9 | slr=krnl_mm2s_1:SLR2 10 | slr=krnl_s2mm_1:SLR2 11 | 12 | # Connect Network Layer to CMAC DO NOT CHANGE 13 | stream_connect=cmac_1.M_AXIS:networklayer_1.S_AXIS_eth2nl 14 | stream_connect=networklayer_1.M_AXIS_nl2eth:cmac_1.S_AXIS 15 | 16 | # Connect memory mapped with network layers 17 | stream_connect=krnl_mm2s_1.k2n:networklayer_1.S_AXIS_sk2nl 18 | stream_connect=networklayer_1.M_AXIS_nl2sk:krnl_s2mm_1.n2k -------------------------------------------------------------------------------- /config_files/connectivity_basic_if3.ini: -------------------------------------------------------------------------------- 1 | [connectivity] 2 | nk=cmac_0:1:cmac_0 3 | nk=cmac_1:1:cmac_1 4 | nk=networklayer:2:networklayer_0.networklayer_1 5 | nk=krnl_mm2s:2:krnl_mm2s_0.krnl_mm2s_1 6 | nk=krnl_s2mm:2:krnl_s2mm_0.krnl_s2mm_1 7 | 8 | slr=cmac_0:SLR2 9 | slr=cmac_1:SLR2 10 | slr=networklayer_0:SLR2 11 | slr=networklayer_1:SLR2 12 | slr=krnl_mm2s_0:SLR2 13 | slr=krnl_mm2s_1:SLR2 14 | slr=krnl_s2mm_0:SLR2 15 | slr=krnl_s2mm_1:SLR2 16 | 17 | # Connect Network Layer to CMAC DO NOT CHANGE 18 | stream_connect=cmac_0.M_AXIS:networklayer_0.S_AXIS_eth2nl 19 | stream_connect=networklayer_0.M_AXIS_nl2eth:cmac_0.S_AXIS 20 | stream_connect=cmac_1.M_AXIS:networklayer_1.S_AXIS_eth2nl 21 | stream_connect=networklayer_1.M_AXIS_nl2eth:cmac_1.S_AXIS 22 | 23 | # Connect memory mapped kernels with network layers 24 | stream_connect=krnl_mm2s_0.k2n:networklayer_0.S_AXIS_sk2nl 25 | stream_connect=networklayer_0.M_AXIS_nl2sk:krnl_s2mm_0.n2k 26 | stream_connect=krnl_mm2s_1.k2n:networklayer_1.S_AXIS_sk2nl 27 | stream_connect=networklayer_1.M_AXIS_nl2sk:krnl_s2mm_1.n2k -------------------------------------------------------------------------------- /config_files/connectivity_benchmark_if0.ini: -------------------------------------------------------------------------------- 1 | [connectivity] 2 | # Define number of kernels and their name 3 | nk=cmac_0:1:cmac_0 4 | nk=networklayer:1:networklayer_0 5 | nk=traffic_generator:4:traffic_generator_0_0.traffic_generator_0_1.traffic_generator_0_2.traffic_generator_0_3 6 | nk=collector:4:collector_0_0.collector_0_1.collector_0_2.collector_0_3 7 | nk=switch_wrapper:1:switch_0 8 | 9 | # Kernels Foorplaning 10 | slr=cmac_0:SLR2 11 | slr=networklayer_0:SLR2 12 | slr=traffic_generator_0_0:SLR2 13 | slr=traffic_generator_0_1:SLR2 14 | slr=traffic_generator_0_2:SLR2 15 | slr=traffic_generator_0_3:SLR2 16 | slr=collector_0_0:SLR2 17 | slr=collector_0_1:SLR2 18 | slr=collector_0_2:SLR2 19 | slr=collector_0_3:SLR2 20 | slr=switch_0:SLR2 21 | 22 | #Connect Network Layer to CMAC DO NOT CHANGE 23 | stream_connect=cmac_0.M_AXIS:networklayer_0.S_AXIS_eth2nl 24 | stream_connect=networklayer_0.M_AXIS_nl2eth:cmac_0.S_AXIS 25 | 26 | # Connect Switch to Network layer 27 | stream_connect=switch_0.m_tx_out:networklayer_0.S_AXIS_sk2nl 28 | stream_connect=networklayer_0.M_AXIS_nl2sk:switch_0.s_rx_in 29 | 30 | # Connect Benchmark kernels to Switch 31 | stream_connect=traffic_generator_0_0.M_AXIS_k2n:switch_0.s_tx_in0 32 | stream_connect=traffic_generator_0_1.M_AXIS_k2n:switch_0.s_tx_in1 33 | stream_connect=traffic_generator_0_2.M_AXIS_k2n:switch_0.s_tx_in2 34 | stream_connect=traffic_generator_0_3.M_AXIS_k2n:switch_0.s_tx_in3 35 | stream_connect=switch_0.m_rx_out0:traffic_generator_0_0.S_AXIS_n2k 36 | stream_connect=switch_0.m_rx_out1:traffic_generator_0_1.S_AXIS_n2k 37 | stream_connect=switch_0.m_rx_out2:traffic_generator_0_2.S_AXIS_n2k 38 | stream_connect=switch_0.m_rx_out3:traffic_generator_0_3.S_AXIS_n2k 39 | 40 | # Connect traffic generators to collectors 41 | stream_connect=traffic_generator_0_0.M_AXIS_summary:collector_0_0.summary 42 | stream_connect=traffic_generator_0_1.M_AXIS_summary:collector_0_1.summary 43 | stream_connect=traffic_generator_0_2.M_AXIS_summary:collector_0_2.summary 44 | stream_connect=traffic_generator_0_3.M_AXIS_summary:collector_0_3.summary -------------------------------------------------------------------------------- /config_files/connectivity_benchmark_if1.ini: -------------------------------------------------------------------------------- 1 | [connectivity] 2 | # Rename kernels 3 | nk=cmac_1:1:cmac_1 4 | nk=networklayer:1:networklayer_1 5 | nk=traffic_generator:4:traffic_generator_1_0.traffic_generator_1_1.traffic_generator_1_2.traffic_generator_1_3 6 | nk=collector:4:collector_1_0.collector_1_1.collector_1_2.collector_1_3 7 | nk=switch_wrapper:1:switch_1 8 | 9 | # Kernels Foorplaning 10 | slr=cmac_1:SLR2 11 | slr=networklayer_1:SLR2 12 | slr=traffic_generator_1_0:SLR2 13 | slr=traffic_generator_1_1:SLR2 14 | slr=traffic_generator_1_2:SLR2 15 | slr=traffic_generator_1_3:SLR2 16 | slr=collector_1_0:SLR2 17 | slr=collector_1_1:SLR2 18 | slr=collector_1_2:SLR2 19 | slr=collector_1_3:SLR2 20 | slr=switch_1:SLR2 21 | 22 | #Connect Network Layer to CMAC DO NOT CHANGE 23 | stream_connect=cmac_1.M_AXIS:networklayer_1.S_AXIS_eth2nl 24 | stream_connect=networklayer_1.M_AXIS_nl2eth:cmac_1.S_AXIS 25 | 26 | # Connect Switch to Network layer 27 | stream_connect=switch_1.m_tx_out:networklayer_1.S_AXIS_sk2nl 28 | stream_connect=networklayer_1.M_AXIS_nl2sk:switch_1.s_rx_in 29 | 30 | # Connect Benchmark kernels to Switch 31 | stream_connect=traffic_generator_1_0.M_AXIS_k2n:switch_1.s_tx_in0 32 | stream_connect=traffic_generator_1_1.M_AXIS_k2n:switch_1.s_tx_in1 33 | stream_connect=traffic_generator_1_2.M_AXIS_k2n:switch_1.s_tx_in2 34 | stream_connect=traffic_generator_1_3.M_AXIS_k2n:switch_1.s_tx_in3 35 | stream_connect=switch_1.m_rx_out0:traffic_generator_1_0.S_AXIS_n2k 36 | stream_connect=switch_1.m_rx_out1:traffic_generator_1_1.S_AXIS_n2k 37 | stream_connect=switch_1.m_rx_out2:traffic_generator_1_2.S_AXIS_n2k 38 | stream_connect=switch_1.m_rx_out3:traffic_generator_1_3.S_AXIS_n2k 39 | 40 | # Connect traffic generators to collectors 41 | stream_connect=traffic_generator_1_0.M_AXIS_summary:collector_1_0.summary 42 | stream_connect=traffic_generator_1_1.M_AXIS_summary:collector_1_1.summary 43 | stream_connect=traffic_generator_1_2.M_AXIS_summary:collector_1_2.summary 44 | stream_connect=traffic_generator_1_3.M_AXIS_summary:collector_1_3.summary -------------------------------------------------------------------------------- /config_files/connectivity_benchmark_if3.ini: -------------------------------------------------------------------------------- 1 | [connectivity] 2 | # Rename kernels 3 | nk=cmac_0:1:cmac_0 4 | nk=cmac_1:1:cmac_1 5 | nk=networklayer:2:networklayer_0.networklayer_1 6 | nk=traffic_generator:8:traffic_generator_0_0.traffic_generator_0_1.traffic_generator_0_2.traffic_generator_0_3.traffic_generator_1_0.traffic_generator_1_1.traffic_generator_1_2.traffic_generator_1_3 7 | nk=collector:8:collector_0_0.collector_0_1.collector_0_2.collector_0_3.collector_1_0.collector_1_1.collector_1_2.collector_1_3 8 | nk=switch_wrapper:2:switch_0.switch_1 9 | 10 | # Kernels Foorplaning 11 | slr=cmac_0:SLR2 12 | slr=cmac_1:SLR2 13 | slr=networklayer_0:SLR2 14 | slr=networklayer_1:SLR2 15 | slr=traffic_generator_0_0:SLR2 16 | slr=traffic_generator_0_1:SLR2 17 | slr=traffic_generator_0_2:SLR2 18 | slr=traffic_generator_0_3:SLR2 19 | slr=traffic_generator_1_0:SLR2 20 | slr=traffic_generator_1_1:SLR2 21 | slr=traffic_generator_1_2:SLR2 22 | slr=traffic_generator_1_3:SLR2 23 | slr=collector_0_0:SLR2 24 | slr=collector_0_1:SLR2 25 | slr=collector_0_2:SLR2 26 | slr=collector_0_3:SLR2 27 | slr=collector_1_0:SLR2 28 | slr=collector_1_1:SLR2 29 | slr=collector_1_2:SLR2 30 | slr=collector_1_3:SLR2 31 | slr=switch_0:SLR2 32 | slr=switch_1:SLR2 33 | 34 | #Connect Network Layer to CMAC DO NOT CHANGE 35 | stream_connect=cmac_0.M_AXIS:networklayer_0.S_AXIS_eth2nl 36 | stream_connect=networklayer_0.M_AXIS_nl2eth:cmac_0.S_AXIS 37 | stream_connect=cmac_1.M_AXIS:networklayer_1.S_AXIS_eth2nl 38 | stream_connect=networklayer_1.M_AXIS_nl2eth:cmac_1.S_AXIS 39 | 40 | # Connect Switch to Network layer 41 | stream_connect=switch_0.m_tx_out:networklayer_0.S_AXIS_sk2nl 42 | stream_connect=networklayer_0.M_AXIS_nl2sk:switch_0.s_rx_in 43 | 44 | stream_connect=switch_1.m_tx_out:networklayer_1.S_AXIS_sk2nl 45 | stream_connect=networklayer_1.M_AXIS_nl2sk:switch_1.s_rx_in 46 | 47 | # Connect Benchmark kernels to Switches 48 | stream_connect=traffic_generator_0_0.M_AXIS_k2n:switch_0.s_tx_in0 49 | stream_connect=traffic_generator_0_1.M_AXIS_k2n:switch_0.s_tx_in1 50 | stream_connect=traffic_generator_0_2.M_AXIS_k2n:switch_0.s_tx_in2 51 | stream_connect=traffic_generator_0_3.M_AXIS_k2n:switch_0.s_tx_in3 52 | stream_connect=switch_0.m_rx_out0:traffic_generator_0_0.S_AXIS_n2k 53 | stream_connect=switch_0.m_rx_out1:traffic_generator_0_1.S_AXIS_n2k 54 | stream_connect=switch_0.m_rx_out2:traffic_generator_0_2.S_AXIS_n2k 55 | stream_connect=switch_0.m_rx_out3:traffic_generator_0_3.S_AXIS_n2k 56 | 57 | stream_connect=traffic_generator_1_0.M_AXIS_k2n:switch_1.s_tx_in0 58 | stream_connect=traffic_generator_1_1.M_AXIS_k2n:switch_1.s_tx_in1 59 | stream_connect=traffic_generator_1_2.M_AXIS_k2n:switch_1.s_tx_in2 60 | stream_connect=traffic_generator_1_3.M_AXIS_k2n:switch_1.s_tx_in3 61 | stream_connect=switch_1.m_rx_out0:traffic_generator_1_0.S_AXIS_n2k 62 | stream_connect=switch_1.m_rx_out1:traffic_generator_1_1.S_AXIS_n2k 63 | stream_connect=switch_1.m_rx_out2:traffic_generator_1_2.S_AXIS_n2k 64 | stream_connect=switch_1.m_rx_out3:traffic_generator_1_3.S_AXIS_n2k 65 | 66 | # Connect traffic generators to collectors 67 | stream_connect=traffic_generator_0_0.M_AXIS_summary:collector_0_0.summary 68 | stream_connect=traffic_generator_0_1.M_AXIS_summary:collector_0_1.summary 69 | stream_connect=traffic_generator_0_2.M_AXIS_summary:collector_0_2.summary 70 | stream_connect=traffic_generator_0_3.M_AXIS_summary:collector_0_3.summary 71 | 72 | stream_connect=traffic_generator_1_0.M_AXIS_summary:collector_1_0.summary 73 | stream_connect=traffic_generator_1_1.M_AXIS_summary:collector_1_1.summary 74 | stream_connect=traffic_generator_1_2.M_AXIS_summary:collector_1_2.summary 75 | stream_connect=traffic_generator_1_3.M_AXIS_summary:collector_1_3.summary -------------------------------------------------------------------------------- /img/cmac_kernel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xilinx/xup_vitis_network_example/d5147d827de9cf6a16d743c1c376feccbb4075db/img/cmac_kernel.png -------------------------------------------------------------------------------- /img/jupyterlab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xilinx/xup_vitis_network_example/d5147d827de9cf6a16d743c1c376feccbb4075db/img/jupyterlab.png -------------------------------------------------------------------------------- /img/udp_network_basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xilinx/xup_vitis_network_example/d5147d827de9cf6a16d743c1c376feccbb4075db/img/udp_network_basic.png -------------------------------------------------------------------------------- /img/udp_network_benchmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xilinx/xup_vitis_network_example/d5147d827de9cf6a16d743c1c376feccbb4075db/img/udp_network_benchmark.png -------------------------------------------------------------------------------- /img/udp_network_benchmark_modes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xilinx/xup_vitis_network_example/d5147d827de9cf6a16d743c1c376feccbb4075db/img/udp_network_benchmark_modes.png -------------------------------------------------------------------------------- /img/udp_network_infrastructure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xilinx/xup_vitis_network_example/d5147d827de9cf6a16d743c1c376feccbb4075db/img/udp_network_infrastructure.png -------------------------------------------------------------------------------- /xrt_host_api/.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | CMakeLists.txt.user 55 | CMakeCache.txt 56 | CMakeFiles 57 | CMakeScripts 58 | Testing 59 | Makefile 60 | cmake_install.cmake 61 | install_manifest.txt 62 | compile_commands.json 63 | CTestTestfile.cmake 64 | _deps 65 | -------------------------------------------------------------------------------- /xrt_host_api/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 Xilinx, Inc 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.12) 5 | 6 | # Consider switching to PROJECT_IS_TOP_LEVEL from CMake 3.21 (2021) 7 | # (https://cmake.org/cmake/help/latest/variable/PROJECT_IS_TOP_LEVEL.html) 8 | get_directory_property(HAS_PARENT PARENT_DIRECTORY) 9 | 10 | set(VNX_INCLUDE_PATH ${CMAKE_CURRENT_LIST_DIR}/include) 11 | if (HAS_PARENT) 12 | set(VNX_INCLUDE_PATH ${CMAKE_CURRENT_LIST_DIR}/include PARENT_SCOPE) 13 | endif (HAS_PARENT) 14 | 15 | # Json 16 | find_package(jsoncpp) 17 | 18 | if (jsoncpp_FOUND) 19 | add_library(vnx OBJECT src/cmac.cpp src/networklayer.cpp src/mac.cpp) 20 | 21 | target_link_libraries(vnx PRIVATE jsoncpp_lib) 22 | get_target_property(JSON_INC_PATH jsoncpp_lib INTERFACE_INCLUDE_DIRECTORIES) 23 | target_include_directories(vnx PRIVATE ${JSON_INC_PATH}) 24 | else (jsoncpp_FOUND) 25 | message(WARNING "jsoncpp not found on the system, compiling vnx without mac address utilities.") 26 | add_library(vnx OBJECT src/cmac.cpp src/networklayer.cpp) 27 | endif (jsoncpp_FOUND) 28 | 29 | target_include_directories(vnx PUBLIC ${VNX_INCLUDE_PATH}) 30 | 31 | # XRT 32 | if (NOT EXISTS $ENV{XILINX_XRT}) 33 | message(FATAL_ERROR "Xilinx XRT not found, make sure to source setup.sh") 34 | endif () 35 | 36 | target_link_directories(vnx PUBLIC $ENV{XILINX_XRT}/lib) 37 | target_link_libraries(vnx PUBLIC xilinxopencl xrt_coreutil xrt_core) 38 | target_include_directories(vnx PUBLIC $ENV{XILINX_XRT}/include) 39 | -------------------------------------------------------------------------------- /xrt_host_api/README.md: -------------------------------------------------------------------------------- 1 | # Low level C++ host API 2 | This folder contains a low level API build on top of XRT to control the network 3 | stack from C++. 4 | 5 | The [cmake project](CMakeLists.txt) contains a library (`vnx`) that you can link 6 | to your project, and the bindings are described in the header files located in 7 | [`include/vnx`](include/vnx). An example program using this API is located in 8 | [`examples/ping_fpga`](examples/ping_fpga). 9 | -------------------------------------------------------------------------------- /xrt_host_api/examples/ping_fpga/.gitignore: -------------------------------------------------------------------------------- 1 | ping_fpga -------------------------------------------------------------------------------- /xrt_host_api/examples/ping_fpga/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2022 Xilinx, Inc 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.12) 5 | project(setup_link CXX) 6 | 7 | # Set useful compile warnings 8 | add_compile_options(-Wall -Wextra -Wno-unused-variable 9 | -Wno-unused-but-set-variable -Wno-unused-parameter) 10 | 11 | add_subdirectory(../../ "CMakeFiles/xrt_host_api") 12 | find_package(jsoncpp REQUIRED) 13 | get_target_property(JSON_INC_PATH jsoncpp_lib INTERFACE_INCLUDE_DIRECTORIES) 14 | 15 | add_executable(ping_fpga ping_fpga.cpp) 16 | target_compile_features(ping_fpga PRIVATE cxx_std_17) 17 | target_include_directories(ping_fpga PUBLIC ${VNX_INCLUDE_PATH} ${JSON_INC_PATH}) 18 | target_link_libraries(ping_fpga PUBLIC jsoncpp_lib vnx) 19 | -------------------------------------------------------------------------------- /xrt_host_api/examples/ping_fpga/README.md: -------------------------------------------------------------------------------- 1 | # Example ping program 2 | This example program loads the VNx xclbin onto the FPGA, tests the link on the 3 | network interface, sets the IP address to the FPGA, and pings the FPGA from the 4 | host. 5 | 6 | To compile and run this program first make sure that the config at the start of 7 | `ping_fpga.cpp` contains the the correct hostnames. Then run the following 8 | commands (make sure that XRT is sourced): 9 | ```bash 10 | # Compiling the program 11 | mkdir build 12 | cd build 13 | cmake .. 14 | cmake --build . 15 | # Running the program 16 | ./ping_fpga 17 | ``` 18 | 19 | Note that this program depends on 20 | [jsoncpp](https://github.com/open-source-parsers/jsoncpp), which can be 21 | installed using `sudo apt install libjsoncpp-dev` on Ubuntu. 22 | -------------------------------------------------------------------------------- /xrt_host_api/examples/test_link/.gitignore: -------------------------------------------------------------------------------- 1 | test_link -------------------------------------------------------------------------------- /xrt_host_api/examples/test_link/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | cmake_minimum_required(VERSION 3.12) 5 | project(setup_link CXX) 6 | 7 | # Set useful compile warnings 8 | add_compile_options(-Wall -Wextra -Wno-unused-variable 9 | -Wno-unused-but-set-variable -Wno-unused-parameter) 10 | 11 | add_subdirectory(../../ "CMakeFiles/xrt_host_api") 12 | 13 | add_executable(test_link test_link.cpp) 14 | target_compile_features(test_link PRIVATE cxx_std_17) 15 | target_include_directories(test_link PUBLIC ${VNX_INCLUDE_PATH}) 16 | target_link_libraries(test_link PUBLIC vnx) 17 | -------------------------------------------------------------------------------- /xrt_host_api/examples/test_link/README.md: -------------------------------------------------------------------------------- 1 | # Example Test Link 2 | 3 | This example program loads the VNx xclbin onto the FPGA and allows testing 4 | CMAC link with and without RS-FEC enabled. 5 | 6 | To compile and run this program run the following commands 7 | (make sure that XRT is sourced): 8 | 9 | ```bash 10 | # Compiling the program 11 | mkdir build && cd build 12 | /usr/bin/cmake .. 13 | /usr/bin/cmake --build . 14 | # Running the program 15 | ./test_link 16 | ``` 17 | 18 | The arguments are as follows: 19 | 20 | - `XCLBIN`: path to the *.xclbin file 21 | - `RS-FEC` (bool): `0` RS-FEC disabled (default); `1` RS-FEC enabled 22 | - `DEVICE ID`: device ID, can be found with `xbutil examine` 23 | 24 | ------------------------------------------------------ 25 |

Copyright© 2024 Advanced Micro Devices, Inc.

-------------------------------------------------------------------------------- /xrt_host_api/examples/test_link/test_link.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. 2 | // SPDX-License-Identifier: BSD-3-Clause 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | namespace fs = std::filesystem; 17 | 18 | 19 | enum xclbin_types { if0, if1, if3 }; 20 | 21 | struct xclbin_path { 22 | std::string path; 23 | xclbin_types type; 24 | }; 25 | // Map type of xclbin to contained kernels 26 | const std::map>> 28 | kernels = { 29 | {if0, { 30 | {"cmac_0", "networklayer_0"} 31 | } 32 | }, 33 | {if1, { 34 | {"cmac_1", "networklayer_1"} 35 | } 36 | }, 37 | {if3, { 38 | {"cmac_0", "networklayer_0"}, 39 | {"cmac_1", "networklayer_1"} 40 | } 41 | } 42 | }; 43 | 44 | 45 | xclbin_path parse_xclbin(const char *arg) { 46 | // Determine content of xclbin based on filename. 47 | xclbin_path xclbin; 48 | xclbin.path = arg; 49 | std::string filename = fs::path(arg).filename(); 50 | 51 | bool found = true; 52 | 53 | if (filename.find("if0.xclbin") != std::string::npos) 54 | xclbin.type = if0; 55 | else if (filename.find("if1.xclbin") != std::string::npos) 56 | xclbin.type = if1; 57 | else if (filename.find("if3.xclbin") != std::string::npos) 58 | xclbin.type = if3; 59 | else 60 | found = false; 61 | 62 | if (!found) 63 | throw std::runtime_error("Unexpected xclbin file " + filename + ". It does not provide information about the interfaces."); 64 | 65 | return xclbin; 66 | } 67 | 68 | int main(int argc, char *argv[]) { 69 | // Set default device and RS-FEC status 70 | int device_id = 0; 71 | bool rs_fec = false; 72 | 73 | // Read xclbin files from commandline 74 | std::vector args(argv + 1, argv + argc); 75 | 76 | if (args.size() < 1) { 77 | std::cerr << "No xclbin provided" << std::endl; 78 | std::cerr << argv[0] << " = 2) { 83 | rs_fec = std::stoi(args[1]); 84 | std::cout << "Configure RS-FEC to: "; 85 | std::cout << (rs_fec ? "enabled" : "disabled" ) << std::endl; 86 | } 87 | 88 | if (args.size() >= 3) { 89 | device_id = std::stoi(args[2]); 90 | std::cout << "Loading XRT device " << device_id << std::endl; 91 | } 92 | 93 | xrt::device device = xrt::device(device_id); 94 | // Collect platform info from xclbin 95 | const std::string platform_json = device.get_info(); 96 | 97 | const xclbin_path xclbin = parse_xclbin(args[0]); 98 | auto xclbin_uuid = device.load_xclbin(xclbin.path); 99 | std::cout << "Loaded " << xclbin.path << " onto FPGA" << std::endl; 100 | // Give time for xclbin to be loaded completely before attempting to read the link status. 101 | std::this_thread::sleep_for(std::chrono::seconds(1)); 102 | 103 | // Loop over compute units in xclbin 104 | for (const auto &cus : kernels.at(xclbin.type)) { 105 | auto cmac = vnx::CMAC(xrt::ip(device, xclbin_uuid, std::string(cus.first) + ":{" + std::string(cus.first) + "}")); 106 | // Enable rsfec depending on user input 107 | cmac.set_rs_fec(rs_fec); 108 | 109 | bool link_status; 110 | 111 | // Can take a few tries before link is ready. 112 | for (std::size_t i = 0; i < 6; ++i) { 113 | auto status = cmac.link_status(); 114 | link_status = status["rx_status"]; 115 | if (link_status) 116 | break; 117 | std::this_thread::sleep_for(std::chrono::seconds(1)); 118 | } 119 | std::cout << "Link interface " << cus.first << " link up: " << (link_status ? "true" : "false") << std::endl; 120 | std::cout << "RS-FEC: " << (cmac.get_rs_fec() ? "enabled" : "disabled") << std::endl; 121 | } 122 | return 0; 123 | } 124 | -------------------------------------------------------------------------------- /xrt_host_api/include/vnx/cmac.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Xilinx, Inc 2 | // SPDX-License-Identifier: BSD-3-Clause 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace vnx { 11 | struct stats_t { 12 | std::map tx; 13 | std::map rx; 14 | std::uint32_t cycle_count; 15 | }; 16 | 17 | class CMAC { 18 | public: 19 | CMAC(xrt::ip &cmac); 20 | CMAC(xrt::ip &&cmac); 21 | 22 | /** 23 | * Retrieves the link status from the CMAC kernel. 24 | * 25 | * Contains boolean status for the following keys: 26 | * rx_status 27 | * rx_aligned 28 | * rx_misaligned 29 | * rx_aligned_err 30 | * rx_hi_ber 31 | * rx_remote_fault 32 | * rx_local_fault 33 | * rx_got_signal_os 34 | * tx_local_fault 35 | */ 36 | std::map link_status(); 37 | 38 | /* Retrieves stats from the CMAC kernel. Will also copy internal registers 39 | * over if update_registers is true. */ 40 | stats_t statistics(bool update_registers = false); 41 | 42 | /* Set GT loopback */ 43 | void set_loopback(bool loopback); 44 | 45 | /* Get GT loopback */ 46 | bool get_loopback(); 47 | 48 | /* Set RS FEC */ 49 | void set_rs_fec(bool rs_fec); 50 | 51 | /* Get RS FEC */ 52 | bool get_rs_fec(); 53 | 54 | private: 55 | xrt::ip cmac; 56 | 57 | void update_statistics_registers(); 58 | }; 59 | 60 | // Register Map 61 | // Extracted from Ethernet/template.xml 62 | // CMAC 63 | constexpr std::size_t gt_reset_reg = 0x0000; 64 | constexpr std::size_t reset_reg = 0x0004; 65 | constexpr std::size_t mode = 0x0008; 66 | constexpr std::size_t conf_tx = 0x000C; 67 | constexpr std::size_t conf_rx = 0x0014; 68 | constexpr std::size_t core_mode = 0x0020; 69 | constexpr std::size_t version = 0x0024; 70 | constexpr std::size_t gt_loopback = 0x0090; 71 | constexpr std::size_t user_reg0 = 0x00CC; 72 | constexpr std::size_t stat_tx_status = 0x0200; 73 | constexpr std::size_t stat_rx_status = 0x0204; 74 | constexpr std::size_t stat_status = 0x0208; 75 | constexpr std::size_t stat_rx_block_lock = 0x020C; 76 | constexpr std::size_t stat_rx_lane_sync = 0x0210; 77 | constexpr std::size_t stat_rx_lane_sync_err = 0x0214; 78 | constexpr std::size_t stat_an_link_ctl = 0x0260; 79 | constexpr std::size_t stat_lt_status = 0x0264; 80 | constexpr std::size_t stat_pm_tick = 0x02B0; 81 | constexpr std::size_t stat_cycle_count = 0x02B8; 82 | // Tx Stats 83 | constexpr std::size_t stat_tx_total_packets = 0x0500; 84 | constexpr std::size_t stat_tx_total_good_packets = 0x0508; 85 | constexpr std::size_t stat_tx_total_bytes = 0x0510; 86 | constexpr std::size_t stat_tx_total_good_bytes = 0x0518; 87 | constexpr std::size_t stat_tx_total_packets_64B = 0x0520; 88 | constexpr std::size_t stat_tx_total_packets_65_127B = 0x0528; 89 | constexpr std::size_t stat_tx_total_packets_128_255B = 0x0530; 90 | constexpr std::size_t stat_tx_total_packets_256_511B = 0x0538; 91 | constexpr std::size_t stat_tx_total_packets_512_1023B = 0x0540; 92 | constexpr std::size_t stat_tx_total_packets_1024_1518B = 0x0548; 93 | constexpr std::size_t stat_tx_total_packets_1519_1522B = 0x0550; 94 | constexpr std::size_t stat_tx_total_packets_1523_1548B = 0x0558; 95 | constexpr std::size_t stat_tx_total_packets_1549_2047B = 0x0560; 96 | constexpr std::size_t stat_tx_total_packets_2048_4095B = 0x0568; 97 | constexpr std::size_t stat_tx_total_packets_4096_8191B = 0x0570; 98 | constexpr std::size_t stat_tx_total_packets_8192_9215B = 0x0578; 99 | constexpr std::size_t stat_tx_total_packets_large = 0x0580; 100 | constexpr std::size_t stat_tx_total_packets_small = 0x0588; 101 | constexpr std::size_t stat_tx_total_bad_fcs = 0x05B8; 102 | constexpr std::size_t stat_tx_pause = 0x05F0; 103 | constexpr std::size_t stat_tx_user_pause = 0x05F8; 104 | // Rx Stats 105 | constexpr std::size_t stat_rx_total_packets = 0x0608; 106 | constexpr std::size_t stat_rx_total_good_packets = 0x0610; 107 | constexpr std::size_t stat_rx_total_bytes = 0x0618; 108 | constexpr std::size_t stat_rx_total_good_bytes = 0x0620; 109 | constexpr std::size_t stat_rx_total_packets_64B = 0x0628; 110 | constexpr std::size_t stat_rx_total_packets_65_127B = 0x0630; 111 | constexpr std::size_t stat_rx_total_packets_128_255B = 0x0638; 112 | constexpr std::size_t stat_rx_total_packets_256_511B = 0x0640; 113 | constexpr std::size_t stat_rx_total_packets_512_1023B = 0x0648; 114 | constexpr std::size_t stat_rx_total_packets_1024_1518B = 0x0650; 115 | constexpr std::size_t stat_rx_total_packets_1519_1522B = 0x0658; 116 | constexpr std::size_t stat_rx_total_packets_1523_1548B = 0x0660; 117 | constexpr std::size_t stat_rx_total_packets_1549_2047B = 0x0668; 118 | constexpr std::size_t stat_rx_total_packets_2048_4095B = 0x0670; 119 | constexpr std::size_t stat_rx_total_packets_4096_8191B = 0x0678; 120 | constexpr std::size_t stat_rx_total_packets_8192_9215B = 0x0680; 121 | constexpr std::size_t stat_rx_total_packets_large = 0x0688; 122 | constexpr std::size_t stat_rx_total_packets_small = 0x0690; 123 | constexpr std::size_t stat_rx_total_packets_undersize = 0x0698; 124 | constexpr std::size_t stat_rx_total_packets_fragmented = 0x06A0; 125 | constexpr std::size_t stat_rx_total_packets_oversize = 0x06A8; 126 | constexpr std::size_t stat_rx_total_packets_toolong = 0x06B0; 127 | constexpr std::size_t stat_rx_total_packets_jabber = 0x06B8; 128 | constexpr std::size_t stat_rx_total_bad_fcs = 0x06C0; 129 | constexpr std::size_t stat_rx_packets_bad_fcs = 0x06C8; 130 | constexpr std::size_t stat_rx_stomped_fcs = 0x06D0; 131 | constexpr std::size_t stat_rx_pause = 0x06F8; 132 | constexpr std::size_t stat_rx_user_pause = 0x0700; 133 | // FEC 134 | constexpr std::size_t rsfec_config_ind_corr = 0x1000; 135 | constexpr std::size_t rsfec_config_enable = 0x107C; 136 | } // namespace vnx 137 | -------------------------------------------------------------------------------- /xrt_host_api/include/vnx/mac.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Xilinx, Inc 2 | // SPDX-License-Identifier: BSD-3-Clause 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | namespace vnx { 10 | /** 11 | * Get the mac address of the FPGA. Retrieves the first mac address by default. 12 | */ 13 | std::string get_mac_address(xrt::device &device, std::size_t index = 0); 14 | } // namespace vnx 15 | -------------------------------------------------------------------------------- /xrt_host_api/include/vnx/networklayer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Xilinx, Inc 2 | // SPDX-License-Identifier: BSD-3-Clause 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace vnx { 14 | 15 | // Register offsets 16 | constexpr std::size_t mac_address_offset = 0x0010; 17 | constexpr std::size_t ip_address_offset = 0x0018; 18 | constexpr std::size_t gateway_offset = 0x001C; 19 | constexpr std::size_t arp_discovery_offset = 0x1010; 20 | 21 | // network stack register map (from NetLayers/kernel.xml) 22 | constexpr std::size_t eth_in_cycles = 0x0400; 23 | constexpr std::size_t eth_in_bytes = 0x0408; 24 | constexpr std::size_t eth_in_packets = 0x0410; 25 | constexpr std::size_t pkth_in_cycles = 0x0418; 26 | constexpr std::size_t pkth_in_bytes = 0x0420; 27 | constexpr std::size_t pkth_in_packets = 0x0428; 28 | constexpr std::size_t arp_in_cycles = 0x0430; 29 | constexpr std::size_t arp_in_bytes = 0x0438; 30 | constexpr std::size_t arp_in_packets = 0x0440; 31 | constexpr std::size_t arp_out_cycles = 0x0448; 32 | constexpr std::size_t arp_out_bytes = 0x0450; 33 | constexpr std::size_t arp_out_packets = 0x0458; 34 | constexpr std::size_t icmp_in_cycles = 0x0460; 35 | constexpr std::size_t icmp_in_bytes = 0x0468; 36 | constexpr std::size_t icmp_in_packets = 0x0470; 37 | constexpr std::size_t icmp_out_cycles = 0x0478; 38 | constexpr std::size_t icmp_out_bytes = 0x0480; 39 | constexpr std::size_t icmp_out_packets = 0x0488; 40 | constexpr std::size_t ethhi_out_cycles = 0x0490; 41 | constexpr std::size_t ethhi_out_bytes = 0x0498; 42 | constexpr std::size_t ethhi_out_packets = 0x04A0; 43 | constexpr std::size_t eth_out_cycles = 0x04A8; 44 | constexpr std::size_t eth_out_bytes = 0x04B0; 45 | constexpr std::size_t eth_out_packets = 0x04B8; 46 | constexpr std::size_t udp_in_cycles = 0x04C0; 47 | constexpr std::size_t udp_in_bytes = 0x04C8; 48 | constexpr std::size_t udp_in_packets = 0x04D0; 49 | constexpr std::size_t app_out_cycles = 0x04D8; 50 | constexpr std::size_t app_out_bytes = 0x04E0; 51 | constexpr std::size_t udp_app_out_bytes = 0x04E0; 52 | constexpr std::size_t app_out_packets = 0x04E8; 53 | constexpr std::size_t udp_app_out_packets = 0x04E8; 54 | constexpr std::size_t udp_out_cycles = 0x04F0; 55 | constexpr std::size_t udp_out_bytes = 0x04F8; 56 | constexpr std::size_t udp_out_packets = 0x0500; 57 | constexpr std::size_t app_in_cycles = 0x0508; 58 | constexpr std::size_t app_in_bytes = 0x0510; 59 | constexpr std::size_t udp_app_in_bytes = 0x0510; 60 | constexpr std::size_t app_in_packets = 0x0518; 61 | constexpr std::size_t udp_app_in_packets = 0x0518; 62 | constexpr std::size_t debug_reset_counters = 0x05F0; 63 | constexpr std::size_t udp_number_sockets = 0x0810; 64 | constexpr std::size_t udp_theirIP_offset = 0x0820; 65 | constexpr std::size_t arp_discovery = 0x1010; 66 | constexpr std::size_t arp_valid_offset = 0x1100; 67 | constexpr std::size_t arp_ip_addr_offset = 0x1400; 68 | constexpr std::size_t arp_mac_addr_offset = 0x1800; 69 | 70 | struct socket_t { 71 | std::string theirIP; 72 | uint32_t theirIPint; 73 | uint16_t theirPort = 62781; 74 | uint16_t myPort = 62781; 75 | bool valid = false; 76 | }; 77 | 78 | uint32_t encode_ip_address(const std::string decoded_ip); 79 | std::string decode_ip_address(const uint32_t encoded_ip); 80 | 81 | class Networklayer { 82 | public: 83 | Networklayer(xrt::ip &networklayer); 84 | Networklayer(xrt::ip &&networklayer); 85 | 86 | /* Updates the IP address of the networklayer based on the encoded ip address. 87 | */ 88 | void update_ip_address(const uint32_t ip_address); 89 | /* Updates the IP address of the networklayer based on the decoded ip address. 90 | */ 91 | uint32_t update_ip_address(const std::string ip_address); 92 | 93 | /* Runs the arp discovery */ 94 | void arp_discovery(); 95 | 96 | /* Read out the arp table on the FPGA */ 97 | std::map> 98 | read_arp_table(int num_entries); 99 | 100 | /* Configure the socket at the given index. Run populate_socket_table to write 101 | * the information to the FPGA. */ 102 | void configure_socket(int index, std::string theirIP, uint16_t theirPort, 103 | uint16_t myPort, bool valid); 104 | 105 | /* Get socket configuration at given index. */ 106 | socket_t get_host_socket(int index); 107 | 108 | /* Populate the socket table on the FPGA based on local configuration. */ 109 | std::map populate_socket_table(); 110 | /* Populate the socket table on the FPGA based on provided configuration. */ 111 | void populate_socket_table(std::vector &socket_table); 112 | 113 | /* Print the first num_sockets entries of the socket_table. */ 114 | void print_socket_table(const unsigned int num_sockets); 115 | 116 | /* Statistic functions. */ 117 | uint32_t get_udp_in_pkts(); 118 | uint32_t get_udp_out_pkts(); 119 | uint32_t get_udp_app_in_pkts(); 120 | uint32_t get_udp_app_out_pkts(); 121 | uint32_t get_icmp_in_pkts(); 122 | uint32_t get_icmp_out_pkts(); 123 | 124 | private: 125 | std::vector sockets; 126 | xrt::ip networklayer; 127 | }; 128 | } // namespace vnx 129 | -------------------------------------------------------------------------------- /xrt_host_api/src/cmac.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Xilinx, Inc 2 | // SPDX-License-Identifier: BSD-3-Clause 3 | 4 | #include "vnx/cmac.hpp" 5 | #include 6 | #include 7 | #include 8 | 9 | namespace vnx { 10 | CMAC::CMAC(xrt::ip &cmac) : cmac(cmac) {} 11 | CMAC::CMAC(xrt::ip &&cmac) : cmac(cmac) {} 12 | 13 | std::map CMAC::link_status() { 14 | std::map status_dict; 15 | 16 | uint32_t l_rxStatus = cmac.read_register(stat_rx_status); 17 | std::bitset<32> l_rxBits(l_rxStatus); 18 | uint32_t l_txStatus = cmac.read_register(stat_tx_status); 19 | std::bitset<32> l_txBits(l_txStatus); 20 | status_dict.insert({"rx_status", l_rxBits.test(0)}); 21 | status_dict.insert({"rx_aligned", l_rxBits.test(1)}); 22 | status_dict.insert({"rx_misaligned", l_rxBits.test(2)}); 23 | status_dict.insert({"rx_aligned_err", l_rxBits.test(3)}); 24 | status_dict.insert({"rx_hi_ber", l_rxBits.test(4)}); 25 | status_dict.insert({"rx_remote_fault", l_rxBits.test(5)}); 26 | status_dict.insert({"rx_local_fault", l_rxBits.test(6)}); 27 | status_dict.insert({"rx_got_signal_os", l_rxBits.test(14)}); 28 | status_dict.insert({"tx_local_fault", l_txBits.test(0)}); 29 | return status_dict; 30 | } 31 | 32 | stats_t CMAC::statistics(bool update_reg) { 33 | stats_t stats{}; 34 | 35 | if (update_reg) { 36 | update_statistics_registers(); 37 | } 38 | 39 | stats.cycle_count = cmac.read_register(stat_cycle_count); 40 | 41 | stats.tx.insert({"packets", cmac.read_register(stat_tx_total_packets)}); 42 | stats.tx.insert({"good_packets", cmac.read_register(stat_tx_total_good_packets)}); 43 | stats.tx.insert({"bytes", cmac.read_register(stat_tx_total_bytes)}); 44 | stats.tx.insert({"good_bytes", cmac.read_register(stat_tx_total_good_bytes)}); 45 | stats.tx.insert({"packets_64B", cmac.read_register(stat_tx_total_packets_64B)}); 46 | stats.tx.insert({"packets_65_127B", cmac.read_register(stat_tx_total_packets_65_127B)}); 47 | stats.tx.insert({"packets_128_255B", cmac.read_register(stat_tx_total_packets_128_255B)}); 48 | stats.tx.insert({"packets_256_511B", cmac.read_register(stat_tx_total_packets_256_511B)}); 49 | stats.tx.insert({"packets_512_1023B", cmac.read_register(stat_tx_total_packets_512_1023B)}); 50 | stats.tx.insert({"packets_1024_1518B", cmac.read_register(stat_tx_total_packets_1024_1518B)}); 51 | stats.tx.insert({"packets_1519_1522B", cmac.read_register(stat_tx_total_packets_1519_1522B)}); 52 | stats.tx.insert({"packets_1523_1548B", cmac.read_register(stat_tx_total_packets_1523_1548B)}); 53 | stats.tx.insert({"packets_1549_2047B", cmac.read_register(stat_tx_total_packets_1549_2047B)}); 54 | stats.tx.insert({"packets_2048_4095B", cmac.read_register(stat_tx_total_packets_2048_4095B)}); 55 | stats.tx.insert({"packets_4096_8191B", cmac.read_register(stat_tx_total_packets_4096_8191B)}); 56 | stats.tx.insert({"packets_8192_9215B", cmac.read_register(stat_tx_total_packets_8192_9215B)}); 57 | stats.tx.insert({"packets_large", cmac.read_register(stat_tx_total_packets_large)}); 58 | stats.tx.insert({"packets_small", cmac.read_register(stat_tx_total_packets_small)}); 59 | stats.tx.insert({"bad_fcs", cmac.read_register(stat_tx_total_bad_fcs)}); 60 | stats.tx.insert({"pause", cmac.read_register(stat_tx_pause)}); 61 | stats.tx.insert({"user_pause", cmac.read_register(stat_tx_user_pause)}); 62 | 63 | stats.rx.insert({"packets", cmac.read_register(stat_rx_total_packets)}); 64 | stats.rx.insert({"good_packets", cmac.read_register(stat_rx_total_good_packets)}); 65 | stats.rx.insert({"bytes", cmac.read_register(stat_rx_total_bytes)}); 66 | stats.rx.insert({"good_bytes", cmac.read_register(stat_rx_total_good_bytes)}); 67 | stats.rx.insert({"packets_64B", cmac.read_register(stat_rx_total_packets_64B)}); 68 | stats.rx.insert({"packets_65_127B", cmac.read_register(stat_rx_total_packets_65_127B)}); 69 | stats.rx.insert({"packets_128_255B", cmac.read_register(stat_rx_total_packets_128_255B)}); 70 | stats.rx.insert({"packets_256_511B", cmac.read_register(stat_rx_total_packets_256_511B)}); 71 | stats.rx.insert({"packets_512_1023B", cmac.read_register(stat_rx_total_packets_512_1023B)}); 72 | stats.rx.insert({"packets_1024_1518B", cmac.read_register(stat_rx_total_packets_1024_1518B)}); 73 | stats.rx.insert({"packets_1519_1522B", cmac.read_register(stat_rx_total_packets_1519_1522B)}); 74 | stats.rx.insert({"packets_1523_1548B", cmac.read_register(stat_rx_total_packets_1523_1548B)}); 75 | stats.rx.insert({"packets_1549_2047B", cmac.read_register(stat_rx_total_packets_1549_2047B)}); 76 | stats.rx.insert({"packets_2048_4095B", cmac.read_register(stat_rx_total_packets_2048_4095B)}); 77 | stats.rx.insert({"packets_4096_8191B", cmac.read_register(stat_rx_total_packets_4096_8191B)}); 78 | stats.rx.insert({"packets_8192_9215B", cmac.read_register(stat_rx_total_packets_8192_9215B)}); 79 | stats.rx.insert({"packets_large", cmac.read_register(stat_rx_total_packets_large)}); 80 | stats.rx.insert({"packets_small", cmac.read_register(stat_rx_total_packets_small)}); 81 | stats.rx.insert({"packets_undersize", cmac.read_register(stat_rx_total_packets_undersize)}); 82 | stats.rx.insert({"packets_fragmented", cmac.read_register(stat_rx_total_packets_fragmented)}); 83 | stats.rx.insert({"packets_oversize", cmac.read_register(stat_rx_total_packets_oversize)}); 84 | stats.rx.insert({"packets_toolong", cmac.read_register(stat_rx_total_packets_toolong)}); 85 | stats.rx.insert({"packets_jabber", cmac.read_register(stat_rx_total_packets_jabber)}); 86 | stats.rx.insert({"bad_fcs", cmac.read_register(stat_rx_total_bad_fcs)}); 87 | stats.rx.insert({"packets_bad_fcs", cmac.read_register(stat_rx_total_bad_fcs)}); 88 | stats.rx.insert({"stomped_fcs", cmac.read_register(stat_rx_stomped_fcs)}); 89 | stats.rx.insert({"pause", cmac.read_register(stat_rx_pause)}); 90 | stats.rx.insert({"user_pause", cmac.read_register(stat_rx_user_pause)}); 91 | 92 | return stats; 93 | } 94 | 95 | void CMAC::set_loopback(bool loopback) { 96 | cmac.write_register(gt_loopback, loopback ? 0x1 : 0x0); 97 | } 98 | 99 | bool CMAC::get_loopback() { 100 | return cmac.read_register(gt_loopback) == 0x1; 101 | } 102 | 103 | void CMAC::set_rs_fec(bool rs_fec) { 104 | cmac.write_register(rsfec_config_enable, rs_fec ? 0x3 : 0x0); 105 | cmac.write_register(rsfec_config_ind_corr, rs_fec ? 0x7 : 0x0); 106 | cmac.write_register(reset_reg, 0xC0000000); 107 | cmac.write_register(reset_reg, 0); 108 | } 109 | 110 | bool CMAC::get_rs_fec() { 111 | return cmac.read_register(rsfec_config_enable) == 0x3; 112 | } 113 | 114 | void CMAC::update_statistics_registers() { 115 | cmac.write_register(stat_pm_tick, 0x1); 116 | } 117 | } // namespace vnx 118 | -------------------------------------------------------------------------------- /xrt_host_api/src/mac.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022 Xilinx, Inc 2 | // SPDX-License-Identifier: BSD-3-Clause 3 | 4 | #include "vnx/mac.hpp" 5 | #include 6 | 7 | namespace { 8 | const std::string default_mac = std::string("FF:FF:FF:FF:FF:FF"); 9 | 10 | std::string get_mac_address_from_json(Json::Value &json, std::size_t index) { 11 | // Read mac addresses from first platform 12 | Json::Value &macs = json["platforms"][0u]["macs"]; 13 | Json::ArrayIndex array_index = index; 14 | if (!macs.isValidIndex(array_index)) { 15 | std::cerr << "Error finding mac address: index out of range" << std::endl; 16 | return default_mac; 17 | } 18 | 19 | // Return mac address at correct index. 20 | return macs[array_index]["address"].asString(); 21 | } 22 | } // namespace 23 | 24 | namespace vnx { 25 | std::string get_mac_address(xrt::device &device, std::size_t index) { 26 | Json::Reader reader; 27 | Json::Value json; 28 | std::string platform = device.get_info(); 29 | 30 | // Parse platform string as JSON. 31 | bool status = reader.parse(platform, json); 32 | if (!status) { 33 | std::cerr << "Error finding mac address: failed to parse json" << std::endl; 34 | return default_mac; 35 | } 36 | 37 | std::string mac; 38 | 39 | try { 40 | mac = get_mac_address_from_json(json, index); 41 | } catch (const Json::Exception &e) { 42 | std::cerr << "Error finding mac address: " << e.what() << std::endl; 43 | return default_mac; 44 | } 45 | 46 | return mac; 47 | } 48 | } // namespace vnx 49 | --------------------------------------------------------------------------------