├── .clang-format ├── .github └── workflows │ └── docs.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CITATION.cff ├── CPPLINT.cfg ├── LICENSE.txt ├── README.md ├── docs ├── .gitignore ├── .pages ├── CNAME ├── assets │ ├── enso-black.svg │ ├── enso-white.svg │ └── tx_pipe_partial_sent.svg ├── build_docs.sh ├── build_hw_docs.sh ├── compiling_hardware.md ├── compiling_software.md ├── config-doxybook2.json ├── diagrams_src │ └── tx_pipe_partial_sent.drawio ├── doxygen │ ├── Doxyfile.in │ ├── doxygen-awesome-sidebar-only.css │ ├── doxygen-awesome.css │ └── doxygen_header.html ├── enso_cli.md ├── ensogen.md ├── examples │ ├── .pages │ └── echo.md ├── generate_doc_markdown.sh ├── getting_started.md ├── hardware │ ├── .pages │ ├── counters.md │ ├── index.md │ └── modules │ │ ├── basic_data_mover.md │ │ ├── basic_data_mover.svg │ │ ├── configurator.md │ │ ├── configurator.svg │ │ ├── dc_back_pressure.md │ │ ├── dc_back_pressure.svg │ │ ├── dependency_graph.svg │ │ ├── esram_wrapper.md │ │ ├── esram_wrapper.svg │ │ ├── flow_director.md │ │ ├── flow_director.svg │ │ ├── flow_table_wrapper.md │ │ ├── flow_table_wrapper.svg │ │ ├── hash_func.md │ │ ├── hash_func.svg │ │ ├── hyper_pipe.md │ │ ├── hyper_pipe.svg │ │ ├── hyper_pipe_root.md │ │ ├── hyper_pipe_root.svg │ │ ├── hyper_pipe_rst.md │ │ ├── hyper_pipe_rst.svg │ │ ├── input_comp.md │ │ ├── input_comp.svg │ │ ├── my_stats.md │ │ ├── my_stats.svg │ │ ├── parser.md │ │ ├── parser.svg │ │ ├── pcie │ │ ├── bram_mux.md │ │ ├── bram_mux.svg │ │ ├── cpu_to_fpga.md │ │ ├── cpu_to_fpga.svg │ │ ├── dependency_graph.svg │ │ ├── fpga_to_cpu.md │ │ ├── fpga_to_cpu.svg │ │ ├── jtag_mmio_arbiter.md │ │ ├── jtag_mmio_arbiter.svg │ │ ├── pcie_core.md │ │ ├── pcie_core.svg │ │ ├── pcie_top.md │ │ ├── pcie_top.svg │ │ ├── queue_manager.md │ │ ├── queue_manager.svg │ │ ├── rx_dsc_queue_manager.md │ │ ├── rx_dsc_queue_manager.svg │ │ ├── stm_cpu_to_fpga_00.svg │ │ ├── stm_cpu_to_fpga_11.svg │ │ └── stm_fpga_to_cpu_00.svg │ │ ├── pdu_gen.md │ │ ├── pdu_gen.svg │ │ ├── rate_limiter.md │ │ ├── rate_limiter.svg │ │ ├── stm_basic_data_mover_00.svg │ │ ├── stm_flow_table_wrapper_00.svg │ │ ├── timestamp.md │ │ ├── timestamp.svg │ │ ├── top.md │ │ └── top.svg ├── index.md ├── javascripts │ └── tablesort.js ├── meson.build ├── out │ └── .gitignore ├── primitives │ ├── .pages │ ├── device.md │ ├── index.md │ ├── rx_enso_pipe.md │ ├── rx_tx_enso_pipe.md │ └── tx_enso_pipe.md ├── requirements.txt ├── running.md └── software_api.md ├── frontend ├── .gitignore ├── LICENSE ├── README.md ├── enso │ ├── __init__.py │ ├── __main__.py │ ├── consts.py │ ├── enso_nic.py │ └── ensogen.py ├── pcaps │ └── .gitignore ├── pytest.ini ├── scripts │ └── deploy.sh ├── setup.cfg └── setup.py ├── gcc.ini ├── hardware ├── .gitignore ├── alt_ehipc2_hw.sv ├── esram │ ├── altera_iopll_1930 │ │ └── synth │ │ │ ├── esram_altera_iopll_1930_rnqonzq.sdc │ │ │ ├── esram_altera_iopll_1930_rnqonzq.v │ │ │ ├── esram_altera_iopll_1930_rnqonzq_parameters.tcl │ │ │ ├── esram_altera_iopll_1930_rnqonzq_pin_map.tcl │ │ │ └── stratix10_altera_iopll.v │ ├── esram.bsf │ ├── esram.cmp │ ├── esram.html │ ├── esram.ppf │ ├── esram.qgsynthc │ ├── esram.qip │ ├── esram.sopcinfo │ ├── esram.xml │ ├── esram_1913 │ │ └── synth │ │ │ ├── esram_esram_1913_a3ainji.sv │ │ │ ├── iopll.v │ │ │ ├── stratix10_esram.sdc │ │ │ └── stratix10_esram_sdc_parameters.tcl │ ├── esram_bb.v │ ├── esram_generation.rpt │ ├── esram_inst.v │ ├── esram_inst.vhd │ └── synth │ │ └── esram.v ├── input_gen │ ├── generate_synthetic_trace.cpp │ ├── generate_synthetic_trace.py │ ├── meson.build │ ├── parse_output_100.py │ ├── raw_bytes.txt │ └── run.sh ├── ip │ ├── .gitignore │ ├── alt_ehipc2_jtag_avalon.tcl │ ├── alt_ehipc2_sys_pll.tcl │ ├── ex_100G.tcl │ ├── my_pll.tcl │ ├── pcie_ed.tcl │ ├── pcie_generic_component_0.v.template │ ├── probe8.tcl │ └── reset_ip.tcl ├── meson.build ├── quartus │ ├── .gitignore │ ├── enso.qpf │ ├── enso.qsf │ └── enso.sdc ├── run_tb.sh ├── run_tb_batch.sh ├── run_tb_pcap.sh ├── run_tests.sh ├── src │ ├── basic_data_mover.sv │ ├── common │ │ ├── alt_aeuex_avalon_mm_read_combine.v │ │ ├── alt_aeuex_user_mode_det.v │ │ ├── altera_avalon_st_pipeline_base.v │ │ ├── altera_dcfifo_synchronizer_bundle.v │ │ ├── altera_std_synchronizer_nocut.v │ │ ├── bram_1port.v │ │ ├── bram_core.v │ │ ├── bram_dc_diff_width.v │ │ ├── bram_dc_simple2port.v │ │ ├── bram_simple2port.v │ │ ├── bram_true2port.v │ │ ├── data_adapter.v │ │ ├── data_adapter_core.sv │ │ ├── dc_fifo_core.v │ │ ├── dc_fifo_core_mlab.v │ │ ├── dc_fifo_reg_core.v │ │ ├── dc_fifo_wrapper.sv │ │ ├── dc_fifo_wrapper_infill.sv │ │ ├── dc_fifo_wrapper_infill_mlab.sv │ │ ├── dc_fifo_wrapper_mlab.sv │ │ ├── dc_fifo_wrapper_outfill.sv │ │ ├── dsp.v │ │ ├── dsp_altera_s10_native_fixed_point_dsp_181_5337kly.sv │ │ ├── fifo_core.v │ │ ├── fifo_core_infill.v │ │ ├── fifo_core_infill_mlab.v │ │ ├── fifo_core_mlab.v │ │ ├── fifo_pkt_core.v │ │ ├── fifo_pkt_core_infill.v │ │ ├── fifo_pkt_wrapper.sv │ │ ├── fifo_pkt_wrapper_infill.sv │ │ ├── fifo_wrapper.sv │ │ ├── fifo_wrapper_infill.sv │ │ ├── fifo_wrapper_infill_mlab.sv │ │ ├── fifo_wrapper_mlab.sv │ │ ├── hyperpipe_vlat.v │ │ ├── mlab_dc_ram.v │ │ ├── mlab_ram.v │ │ ├── prefetch_rb.sv │ │ ├── prim_assert.sv │ │ ├── prim_assert_dummy_macros.sv │ │ ├── prim_assert_sec_cm.sv │ │ ├── prim_assert_standard_macros.sv │ │ ├── rom_2port.v │ │ ├── rom_2port_noreg.v │ │ ├── rom_2port_noreg_sim.v │ │ ├── rom_2port_sim.v │ │ ├── singledsp.v │ │ ├── singledsp_altera_s10_native_fixed_point_dsp_181_op75vsa.sv │ │ ├── st_multiplexer.sv │ │ ├── st_multiplexer_8.sv │ │ ├── st_multiplexer_pkt.sv │ │ └── st_multiplexer_pkt_3.sv │ ├── configurator.sv │ ├── constants.sv │ ├── dc_back_pressure.sv │ ├── esram_wrapper.sv │ ├── flow_director.sv │ ├── flow_table_wrapper.sv │ ├── hash_func.sv │ ├── hyper_pipe.sv │ ├── hyper_pipe_root.sv │ ├── hyper_pipe_rst.sv │ ├── input_comp.sv │ ├── my_stats.sv │ ├── parser.sv │ ├── pcie │ │ ├── bram_interface.sv │ │ ├── bram_mux.sv │ │ ├── cpu_to_fpga.sv │ │ ├── fpga_to_cpu.sv │ │ ├── jtag_mmio_arbiter.sv │ │ ├── pcie_consts.sv │ │ ├── pcie_core.sv │ │ ├── pcie_top.sv │ │ ├── pkt_queue_manager.sv │ │ ├── queue_manager.sv │ │ ├── rx_dsc_queue_manager.sv │ │ └── st_ordered_multiplexer.sv │ ├── pdu_gen.sv │ ├── rate_limiter.sv │ ├── timestamp.sv │ └── top.sv └── tests │ ├── .gitignore │ ├── helpers │ └── test_template.sv │ ├── tb.sv │ ├── test_cpu_to_fpga.sv │ ├── test_pcie_top.sv │ ├── test_prefetch_rb.sv │ ├── test_queue_manager.sv │ ├── test_rate_limiter.sv │ └── test_timestamp.sv ├── llvm.ini ├── meson.build ├── meson_options.txt ├── mkdocs.yml ├── requirements.txt ├── scripts ├── ensogen.sh ├── generate_ips.sh ├── get_pcap_pkt_size.cpp ├── hwtest │ ├── altera │ │ ├── alt_aeu_40 │ │ │ ├── eth_ultra_mac_inc.tcl │ │ │ ├── eth_ultra_phy_inc.tcl │ │ │ ├── eth_ultra_stats_inc.tcl │ │ │ └── main.tcl │ │ ├── kr4 │ │ │ └── kr4.tcl │ │ ├── optical_module │ │ │ ├── cfp_control_inc.tcl │ │ │ ├── main.tcl │ │ │ └── qsfp_control_inc.tcl │ │ ├── pkt_client │ │ │ └── pkt_client.tcl │ │ └── sval_top │ │ │ ├── main.tcl │ │ │ └── reg_map_inc.tcl │ ├── common │ │ ├── jtag_basic.tcl │ │ ├── main.tcl │ │ └── report.tcl │ ├── main.tcl │ └── my_stats.tcl ├── list_enso_nics.sh ├── load.cdf ├── load_bitstream.sh ├── meson.build ├── path.tcl ├── quartus_fit_save.sh ├── run_console.sh ├── sample_pcaps │ ├── 16_1518_1_16.pcap │ ├── 16_64_1_16.pcap │ ├── 2_1518_1_2.pcap │ ├── 2_64_1_2.pcap │ ├── 4_1518_1_4.pcap │ ├── 4_64_1_4.pcap │ ├── 8_1518_1_8.pcap │ └── 8_64_1_8.pcap ├── sw_setup.sh └── update_bitstream.sh ├── setup.sh ├── software ├── .gitignore ├── examples │ ├── capture.cpp │ ├── echo.cpp │ ├── echo_copy.cpp │ ├── echo_event.cpp │ ├── echo_prefetch.cpp │ ├── ensogen.cpp │ ├── example_helpers.h │ ├── l2_forward.cpp │ └── meson.build ├── include │ ├── enso │ │ ├── config.h │ │ ├── consts.h │ │ ├── helpers.h │ │ ├── internals.h │ │ ├── ixy_helpers.h │ │ ├── meson.build │ │ ├── pipe.h │ │ ├── queue.h │ │ └── socket.h │ └── meson.build ├── kernel │ ├── intel_fpga_pcie_ip_params.h │ └── linux │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── README │ │ ├── event_handler.c │ │ ├── event_handler.h │ │ ├── event_queue.c │ │ ├── event_queue.h │ │ ├── install │ │ ├── intel_fpga_pcie.h │ │ ├── intel_fpga_pcie_chr.c │ │ ├── intel_fpga_pcie_chr.h │ │ ├── intel_fpga_pcie_dma.c │ │ ├── intel_fpga_pcie_dma.h │ │ ├── intel_fpga_pcie_drv.mod.c │ │ ├── intel_fpga_pcie_ioctl.c │ │ ├── intel_fpga_pcie_ioctl.h │ │ ├── intel_fpga_pcie_setup.c │ │ ├── intel_fpga_pcie_setup.h │ │ ├── load │ │ └── unload ├── meson.build ├── src │ ├── backends │ │ ├── intel_fpga │ │ │ ├── dev_backend.h │ │ │ ├── doxygen_gen_cfg │ │ │ ├── intel_fpga_pcie_api.hpp │ │ │ ├── linux │ │ │ │ ├── intel_fpga_pcie_api_linux.cpp │ │ │ │ ├── intel_fpga_pcie_api_linux.hpp │ │ │ │ └── meson.build │ │ │ └── meson.build │ │ ├── meson.build │ │ └── software │ │ │ ├── dev_backend.h │ │ │ └── meson.build │ ├── enso │ │ ├── config.cpp │ │ ├── helpers.cpp │ │ ├── ixy_helpers.cpp │ │ ├── meson.build │ │ ├── pipe.cpp │ │ └── socket.cpp │ ├── meson.build │ ├── pcie.cpp │ └── pcie.h └── test │ ├── meson.build │ └── queue_test.cpp ├── subprojects └── gtest.wrap └── synthesize.sh /.clang-format: -------------------------------------------------------------------------------- 1 | # Use the Google style in this project. 2 | BasedOnStyle: Google 3 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: docs 2 | on: 3 | push: 4 | branches: 5 | - master 6 | - main 7 | permissions: 8 | contents: write 9 | jobs: 10 | deploy: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/setup-python@v4 15 | with: 16 | python-version: 3.x 17 | - uses: actions/cache@v4 18 | with: 19 | key: ${{ github.ref }} 20 | path: .cache 21 | - run: sudo apt-get update 22 | - run: sudo apt-get install -y python3-pip npm g++ libpcap-dev texlive-font-utils 23 | - run: wget https://www.doxygen.nl/files/doxygen-1.9.6.linux.bin.tar.gz 24 | - run: tar xzvf doxygen-1.9.6.linux.bin.tar.gz 25 | - run: cp doxygen-1.9.6/bin/* /usr/local/bin/ 26 | - run: python3 -m pip install meson ninja 27 | - run: python3 -m pip install -r docs/requirements.txt 28 | - run: sudo npm install -g git://github.com/TerosTechnology/colibri.git#master 29 | shell: bash 30 | - run: meson setup build 31 | - run: meson compile docs -v -C build 32 | - run: mkdocs gh-deploy --force 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | transcript 2 | *.wlf 3 | libraries/ 4 | work/ 5 | *.sof 6 | *.cspell 7 | site/ 8 | build* 9 | .setup_done 10 | 11 | # VSCode 12 | .vscode/ 13 | 14 | # macOS 15 | .DS_Store 16 | 17 | # DVT 18 | .dvt 19 | dvt_build.log 20 | 21 | # Autogenerated input 22 | input_gen/*.pcap 23 | input_gen/*.pkt 24 | 25 | # Meson subprojects 26 | /subprojects/* 27 | !/subprojects/*.wrap 28 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | 4 | fail_fast: false 5 | repos: 6 | - repo: https://github.com/pre-commit/pre-commit-hooks 7 | rev: v4.3.0 8 | hooks: 9 | - id: trailing-whitespace 10 | - id: end-of-file-fixer 11 | - id: check-yaml 12 | args: [--unsafe] 13 | - id: check-added-large-files 14 | - repo: https://gitlab.com/daverona/pre-commit-cpp 15 | rev: 0.8.0 # use the most recent version 16 | hooks: 17 | - id: clang-format # formatter of C/C++ code based on a style guide: LLVM, Google, Chromium, Mozilla, and WebKit available 18 | args: ["-style=Google"] 19 | - id: cpplint # linter (or style-error checker) for Google C++ Style Guide 20 | - id: cppcheck # static analyzer of C/C++ code 21 | - repo: https://github.com/charliermarsh/ruff-pre-commit 22 | rev: 'v0.0.255' # Ruff version. 23 | hooks: 24 | - id: ruff 25 | args: [--fix, --exit-non-zero-on-fix] 26 | - repo: https://github.com/psf/black 27 | rev: 22.10.0 28 | hooks: 29 | - id: black 30 | args: ["--line-length", "79"] 31 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: "If you use Ensō, consider citing it as below." 3 | authors: 4 | - family-names: "Sadok" 5 | given-names: "Hugo" 6 | orcid: "https://orcid.org/0000-0002-2464-1465" 7 | - family-names: "Atre" 8 | given-names: "Nirav" 9 | orcid: "https://orcid.org/0000-0003-0718-1839" 10 | - family-names: "Zhao" 11 | given-names: "Zhipeng" 12 | orcid: "https://orcid.org/0000-0002-3349-8939" 13 | - family-names: "Berger" 14 | given-names: "Daniel S." 15 | orcid: "https://orcid.org/0000-0002-3911-1512" 16 | - family-names: "Hoe" 17 | given-names: "James C." 18 | orcid: "https://orcid.org/0000-0002-9302-5287" 19 | - family-names: "Panda" 20 | given-names: "Aurojit" 21 | orcid: "https://orcid.org/0000-0001-9664-4377" 22 | - family-names: "Sherry" 23 | given-names: "Justine" 24 | orcid: "https://orcid.org/0000-0002-8270-4102" 25 | - family-names: "Wang" 26 | given-names: "Ren" 27 | title: "Ensō" 28 | version: 0.4.6 29 | license: BSD-3-Clause-Clear 30 | # doi: 10.5281/zenodo.1234 31 | date-released: 2023-04-23 32 | repository-code: "https://github.com/crossroadsfpga/enso" 33 | url: "https://github.com/crossroadsfpga/enso" 34 | # Update this: 35 | # repository-artifact: 'https://github.com/crossroadsfpga/enso' 36 | preferred-citation: 37 | type: conference-paper 38 | authors: 39 | - family-names: "Sadok" 40 | given-names: "Hugo" 41 | orcid: "https://orcid.org/0000-0002-2464-1465" 42 | - family-names: "Atre" 43 | given-names: "Nirav" 44 | orcid: "https://orcid.org/0000-0003-0718-1839" 45 | - family-names: "Zhao" 46 | given-names: "Zhipeng" 47 | orcid: "https://orcid.org/0000-0002-3349-8939" 48 | - family-names: "Berger" 49 | given-names: "Daniel S." 50 | orcid: "https://orcid.org/0000-0002-3911-1512" 51 | - family-names: "Hoe" 52 | given-names: "James C." 53 | orcid: "https://orcid.org/0000-0002-9302-5287" 54 | - family-names: "Panda" 55 | given-names: "Aurojit" 56 | orcid: "https://orcid.org/0000-0001-9664-4377" 57 | - family-names: "Sherry" 58 | given-names: "Justine" 59 | orcid: "https://orcid.org/0000-0002-8270-4102" 60 | - family-names: "Wang" 61 | given-names: "Ren" 62 | # doi: "10.0000/00000" 63 | title: "Ensō: A Streaming Interface for NIC-Application Communication" 64 | collection-title: "17th USENIX Symposium on Operating Systems Design and Implementation" 65 | conference: "OSDI '23" 66 | month: 7 67 | # start: 1 # First page number 68 | # end: 10 # Last page number 69 | publisher: "USENIX Association" 70 | # isbn: 71 | year: 2023 72 | -------------------------------------------------------------------------------- /CPPLINT.cfg: -------------------------------------------------------------------------------- 1 | filter=-build/include,-build/c++11 2 | filter=-readability/casting 3 | filter=-runtime/int,-runtime/references 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The Clear BSD License 2 | 3 | Copyright (c) 2023 Carnegie Mellon University 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted (subject to the limitations in the disclaimer 8 | below) provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from this 19 | software without specific prior written permission. 20 | 21 | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 22 | THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 23 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 25 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 30 | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *.pyc 3 | 4 | # Ignore autogenerated docs. 5 | # hardware/modules 6 | software 7 | 8 | !build_docs.sh 9 | !build_hw_docs.sh 10 | -------------------------------------------------------------------------------- /docs/.pages: -------------------------------------------------------------------------------- 1 | nav: 2 | - Home: index.md 3 | - Getting Started: 4 | - System Requirements: getting_started.md 5 | - Compiling Software: compiling_software.md 6 | - Compiling Hardware: compiling_hardware.md 7 | - Ensō CLI Tool: enso_cli.md 8 | - Running: running.md 9 | - EnsōGen: ensogen.md 10 | - Primitives: primitives 11 | # - Examples: examples 12 | # - Developer Guide: 13 | # - Development Environment 14 | # - Code Style 15 | - Hardware Reference: hardware 16 | - Software Reference: /software/" target="_blank 17 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | enso.cs.cmu.edu 2 | -------------------------------------------------------------------------------- /docs/build_docs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # print commands 4 | set -o xtrace 5 | 6 | # exit when error occurs 7 | # set -e 8 | 9 | ORIGINAL_PWD=$(pwd) 10 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 11 | REPO_DIR="$SCRIPT_DIR/.." 12 | 13 | cd $REPO_DIR 14 | # ./docs/build_hw_docs.sh 15 | mkdocs build -f mkdocs.yml 16 | -------------------------------------------------------------------------------- /docs/build_hw_docs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # print commands 4 | set -o xtrace 5 | 6 | # exit when error occurs 7 | # set -e 8 | 9 | ORIGINAL_PWD=$(pwd) 10 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 11 | REPO_DIR="$SCRIPT_DIR/.." 12 | 13 | HARDWARE_PATH="$REPO_DIR/hardware/src" 14 | HDL_DOC_PATH="$REPO_DIR/docs/hardware/modules" 15 | TEROS_HDL_OUTPUT_PATH="/tmp/teros_hdl_docs" 16 | 17 | TEROS_HDL_COMMON_OPTS="\ 18 | --dep \ 19 | --fsm \ 20 | --signals only_commented \ 21 | --constants only_commented \ 22 | --process only_commented \ 23 | --functions only_commented \ 24 | --symbol_verilog / \ 25 | --out markdown \ 26 | " 27 | 28 | rm -rf $HDL_DOC_PATH 29 | 30 | rm -rf /tmp/teros_hdl_docs 31 | mkdir /tmp/teros_hdl_docs 32 | 33 | # Build hardware docs. 34 | teroshdl-hdl-documenter $TEROS_HDL_COMMON_OPTS \ 35 | --input $HARDWARE_PATH \ 36 | --outpath $TEROS_HDL_OUTPUT_PATH &> /tmp/teros_hdl_docs/hardware.log 37 | # --recursive 38 | 39 | echo $? 40 | cat /tmp/teros_hdl_docs/hardware.log 41 | 42 | # Build hardware PCIe docs. 43 | teroshdl-hdl-documenter $TEROS_HDL_COMMON_OPTS \ 44 | --input "$HARDWARE_PATH/pcie" \ 45 | --outpath "$TEROS_HDL_OUTPUT_PATH/pcie" &> /tmp/teros_hdl_docs/pcie.log 46 | 47 | echo $? 48 | cat /tmp/teros_hdl_docs/pcie.log 49 | 50 | mv "$TEROS_HDL_OUTPUT_PATH/doc_internal" "$REPO_DIR/docs/hardware/modules" 51 | mv "$TEROS_HDL_OUTPUT_PATH/pcie/doc_internal" "$REPO_DIR/docs/hardware/modules/pcie" 52 | 53 | cd $REPO_DIR 54 | mkdocs build -f mkdocs.yml 55 | -------------------------------------------------------------------------------- /docs/compiling_hardware.md: -------------------------------------------------------------------------------- 1 | # Compiling Hardware 2 | 3 | Here we describe how to compile the hardware to produce a bitstream. This bitstream implements the Ensō NIC and can be loaded into the FPGA. 4 | 5 | The following steps assume that you have already [installed Quartus](getting_started.md#quartus). 6 | 7 | !!! warning 8 | 9 | Synthesizing the hardware can take hours. If you do not need to make hardware changes, you should skip this part and automatically download the appropriate bitstream by running: 10 | ```bash 11 | cd 12 | ./scripts/update_bitstream.sh --download 13 | ``` 14 | 15 | ## Generate IP cores 16 | 17 | Before synthesizing the bitstream for the first time, you need to generate the IP cores that are used by the hardware. To do so, run the following commands: 18 | 19 | ```bash 20 | cd 21 | ./scripts/generate_ips.sh 22 | ``` 23 | 24 | ## Synthesize the hardware 25 | 26 | After generating the IP cores, you can now synthesize the hardware by running: 27 | 28 | ```bash 29 | cd 30 | ./synthesize.sh 31 | ``` 32 | 33 | The resulting bitstream will be placed in the directory where you ran the command and it will be named `enso_0.sof`. If the design does not meet timing, the bitstream will be saved as `neg_slack_enso_0.sof`. 34 | 35 | !!! note 36 | 37 | The above command will use a single seed to synthesize the hardware. It is often advantageous to synthesize with multiple seeds to increase the probability of finding a design that meets timing. If you have enough memory, you can synthesize with multiple seeds in parallel. (Requires GNU Parallel to be installed.) 38 | 39 | To do so, you can specify multiple seeds when running the command. For example, to synthesize with seeds 1, 2, 3, and 4, run: 40 | 41 | ```bash 42 | cd 43 | ./synthesize.sh 1 2 3 4 44 | ``` 45 | 46 | This will run a separate synthesis for each seed and save the resulting bitstreams as `enso_{seed}.sof`, e.g., `enso_1.sof`, `enso_2.sof`. 47 | -------------------------------------------------------------------------------- /docs/compiling_software.md: -------------------------------------------------------------------------------- 1 | # Compiling Software 2 | 3 | Start by cloning the enso repository, if you haven't already: 4 | ```bash 5 | git clone https://github.com/crossroadsfpga/enso 6 | ``` 7 | 8 | Prepare the compilation using `meson` and compile it with `ninja`. 9 | 10 | Setup build directory: 11 | ```bash 12 | meson setup build 13 | ``` 14 | 15 | Now compile: 16 | ```bash 17 | cd build 18 | ninja 19 | ``` 20 | 21 | ## Compilation options 22 | 23 | There are a few compile-time options that you may set. You can see all the available options with: 24 | ```bash 25 | meson configure 26 | ``` 27 | 28 | If you run the above in the build directory, it also shows the current value for each option. 29 | 30 | To change one of the options run: 31 | ```bash 32 | meson configure -D= 33 | ``` 34 | 35 | For instance, to disable latency optimization: 36 | ```bash 37 | meson configure -Dlatency_opt=false 38 | ``` 39 | 40 | ## Build an application with Ensō 41 | 42 | If you want to build an application that uses Ensō, you should install the Ensō library in your system. You can use `ninja` for that: 43 | ```bash 44 | cd build 45 | ninja 46 | sudo ninja install 47 | ``` 48 | 49 | !!! tip 50 | 51 | If `sudo ninja install` fails, you may try using the following command instead: 52 | ```bash 53 | sudo $(which ninja) install 54 | ``` 55 | 56 | This will use the user `ninja` instead of the system `ninja`. 57 | 58 | Then, you should link the application with the Ensō library. The way you do it depends on how you are compiling your code. Here are some examples using `gcc`, `meson` and `cmake`. 59 | 60 | 61 | === "GCC with no build system" 62 | 63 | ```bash 64 | g++ -o my_app my_app.cpp -lenso 65 | ``` 66 | 67 | You may also use `pkg-config` to retrieve the flags: 68 | 69 | ```bash 70 | g++ -o my_app my_app.cpp $(pkg-config --cflags --libs enso) 71 | ``` 72 | 73 | === "Meson" 74 | 75 | Add the following to your `meson.build` file: 76 | ```meson 77 | enso_dep = dependency('enso') 78 | ``` 79 | 80 | Then, you can link your application with the Ensō library: 81 | ```meson 82 | executable('my_app', 'my_app.cpp', dependencies: [enso_dep]) 83 | ``` 84 | 85 | === "CMake" 86 | 87 | Add the following to your `CMakeLists.txt` file: 88 | ```cmake 89 | link_libraries(enso) 90 | ``` 91 | 92 | 93 | ## Build the documentation optional { #build-the-documentation data-toc-label="Build the documentation" } 94 | 95 | You can access Ensō's documentation at [https://enso.cs.cmu.edu/](https://enso.cs.cmu.edu/). But if you would like to contribute to the documentation, you may choose to also build it locally. 96 | 97 | Install the requirements: 98 | 99 | ```bash 100 | sudo apt update 101 | sudo apt install doxygen python3-pip npm 102 | python3 -m pip install -r docs/requirements.txt 103 | sudo npm install -g teroshdl 104 | ``` 105 | 106 | To build the documentation, run (from the build directory): 107 | 108 | ```bash 109 | meson compile docs 110 | ``` 111 | 112 | While writing documentation, you can use the following command to automatically rebuild the documentation when you make changes: 113 | 114 | ```bash 115 | cd 116 | mkdocs serve 117 | ``` 118 | 119 | Note that this does not automatically rebuild the hardware and software API reference. You need to rerun `meson compile docs` to do that. 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /docs/config-doxybook2.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseUrl": "/site/software/", 3 | "indexInFolders": true, 4 | "linkSuffix": "/", 5 | "indexClassesName": "index", 6 | "indexFilesName": "index", 7 | "indexGroupsName": "index", 8 | "indexNamespacesName": "index", 9 | "indexRelatedPagesName": "index", 10 | "indexExamplesName": "index", 11 | "mainPageInRoot": true, 12 | "mainPageName": "index" 13 | } 14 | -------------------------------------------------------------------------------- /docs/diagrams_src/tx_pipe_partial_sent.drawio: -------------------------------------------------------------------------------- 1 | 7VlNc9sgEP01mmkPzgiQFPtoO3ZySaeND+2VSFhmioWL8Efy6wsSkiwhjdOOP5LWyUwiFljgvcfuynbQeLm7F3i1eOQRYQ50o52D7hwIPS9Qf7XhJTcgiHJDLGiUm0BlmNFXYoyusa5pRNLaQMk5k3RVN4Y8SUgoazYsBN/Wh805q6+6wjGxDLMQM9v6nUZykVuh71b2B0LjhWx0LHEx1hjSBY74ds+EJg4aC85l/rTcjQnT0BWw5POmHb3lvgRJ5Fsm3PdmHvy2EdNg8NDfea/bL88/eoPcywaztTmv2ax8KQAQfJ1ERDtxHTTaLqgksxUOde9WMa5sC7lkqgXU45wyNuaMC9WOyByvmdrbKJWC/yzhUycfmWWJkGTXeR5QoqTERfiSSPGihpgJvpfPMLoCt3lzW5EEkIF+sUcQ8o02jC7i0nGFnXow8P0BlAC2YBlk559zdSR1BbDEPf3cS0WYjQh+rTX9CkGp5TzUO4BTPSS9iTmPGcErmt6EfKnMYaqGTOd4SZk+8xN/5pJXPrS4c1oqmz0miPX/0Xo+J0LNAMUWzbLFAEsFiidZpzontSA74Qlp8G9MmNE4Uc1Q8arWRCPNOlUXbGg6ljSK9DKt2qqr7wiy6Q/qsrFUE7SIBpxMNG+4gCSJhjqQVZDusVDHR1M4bQgkt874WmS45lKDvhabr+XmdwnOzyWnhhaiU4+VV/tS1xXhQISmwWQclLyRyAq1B1nbI8ZvIaawCcKwpJu6+za2zApfOc2uZEcsaQaJNEPPTNqPsQ0/wDvgSGIRE2k5yrRTnvrv5VTkmu4Y1Bki3EeetESKmVZfEk0FIZ8+f6xgkck+rycAMO1ucR41F6HACiuDc4aVIor8A3l9YEN53rxe1KvXvP6R8nrfvWxih/0T3kDDwEmun5XCbu0LWGB9nvvXViK99/sH/7v7B4KGboILl9YIHNJNWBYDFY/IzX7eRn9HzTRkjIdYEqWGa83UKZjbul58eNmSCR18fb/K5ZJyAV6/phcILi0Yuy78LqiUJFHGO5WSjpfvFZSTQP9aSR+0EZoqpzSJnwwIp6rLb3y7MgdeS2XgnYoB74Q11rvAvKUYa0EdnhX0oDNORnRTA78IdIwmpFdsbqjfTvqrnYmVWdWWRZCsIzAdzRjZCMX2GocdvaMy0ZlAZwCcodsZ7UtzhumHyQFHivXFjCLU2x/tw+Cckf72IpI3IgFXNdRjoGu/kJ5XDm2v9meTA7zKoS6H/snkoJrV17P5R/TVV9xo8hs= 2 | -------------------------------------------------------------------------------- /docs/doxygen/doxygen_header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | $projectname: $title 10 | $title 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | $treeview 21 | $search 22 | $mathjax 23 | 24 | $extrastylesheet 25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | 33 |
34 | 35 | 36 |
37 | 38 | 39 | 40 | 41 | 49 | 50 | 51 | 52 | 57 | 58 | 59 | 60 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
53 |
$projectname $projectnumber 54 |
55 |
$projectbrief
56 |
61 |
$projectbrief
62 |
$searchbox
$searchbox
80 |
81 | 82 | 83 | -------------------------------------------------------------------------------- /docs/ensogen.md: -------------------------------------------------------------------------------- 1 | # EnsōGen Packet Generator 2 | 3 | EnsōGen is a software packet generator built on top of the Ensō NIC interface. It can send packets from a pcap and receive them back at 100Gbps line rate using a single CPU core. EnsōGen is included with Ensō as one of its example applications. 4 | 5 | ## Running 6 | 7 | EnsōGen is built as part of Ensō. Make sure to follow the instructions in [Compiling Software](compiling_software.md) to build Ensō and that you have the [`enso` command](enso_cli.md) installed. 8 | 9 | You should use the `scripts/ensogen.sh` script to run EnsōGen: 10 | 11 | ```bash 12 | cd 13 | ./scripts/ensogen.sh --pcie-addr --count 14 | ``` 15 | 16 | Both `` and `` are optional but it's recommended to specify `` if you have more than one NIC in your system. If `` is not specified, EnsōGen will send packets indefinitely until you stop it with ++ctrl+c++. 17 | 18 | Recall that you may obtain the PCIe address of all Ensō NICs in your system by running `scripts/list_enso_nics.sh`. 19 | 20 | The `scripts/ensogen.sh` script makes it easier to run EnsōGen by automatically figuring out the hardware rate limiter parameters based on the input pcap file and the desired rate. 21 | 22 | You may also choose to run EnsōGen manually. Run the following command to see the available options: 23 | 24 | ```bash 25 | cd 26 | sudo ./build/software/examples/ensogen --help 27 | ``` 28 | 29 | All these options are also available through the `scripts/ensogen.sh` script. 30 | 31 | ## Other features 32 | 33 | - **Save:** You can save the statistics EnsōGen collects to a file by using the `--save SAVE_FILE` option. This will save the statistics in a csv file called `SAVE_FILE`. 34 | - **RTT:** You can also use EnsōGen to measure RTT. It uses hardware timestamping and can keep track of RTTs with 5ns precision. To enable RTT measurement, run EnsōGen with the `--rtt` flag. 35 | - **RTT Histogram**: The `--rtt` option will report the average RTT among all packets. You can also enable RTT histogram to record the RTT of *every* packet. This allows you to generate RTT CDFs as well as calculate relevant metrics such as 99th percentile latency. To enable RTT histogram, run EnsōGen with the `--rtt-hist HIST_FILE`. This will save the RTT histogram in a file called `HIST_FILE`. 36 | -------------------------------------------------------------------------------- /docs/examples/.pages: -------------------------------------------------------------------------------- 1 | nav: 2 | - Echo Server: echo.md 3 | -------------------------------------------------------------------------------- /docs/examples/echo.md: -------------------------------------------------------------------------------- 1 | # Raw packet echo server 2 | -------------------------------------------------------------------------------- /docs/generate_doc_markdown.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # print commands 4 | set -o xtrace 5 | 6 | # exit when error occurs 7 | set -e 8 | 9 | ORIGINAL_PWD=$(pwd) 10 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 11 | 12 | DOXYBOOK2_PATH="$PWD/doxybook2" 13 | DOXYBOOK2_BIN="$DOXYBOOK2_PATH/bin/doxybook2" 14 | 15 | # Check if doxybook2 is already downloaded 16 | if [ -d $DOXYBOOK2_PATH ]; then 17 | echo "doxybook2 is already downloaded skipping download" 18 | else 19 | # Download doxybook2. 20 | mkdir -p $DOXYBOOK2_PATH 21 | cd $DOXYBOOK2_PATH 22 | wget https://github.com/matusnovak/doxybook2/releases/download/v1.5.0/doxybook2-linux-amd64-v1.5.0.zip 23 | unzip doxybook2-linux-amd64-v1.5.0.zip 24 | rm doxybook2-linux-amd64-v1.5.0.zip 25 | fi 26 | 27 | cd $ORIGINAL_PWD 28 | ls -al 29 | 30 | rm -rf docs/software 31 | mkdir -p docs/software 32 | $DOXYBOOK2_BIN --input docs/xml --output docs/software \ 33 | --config $SCRIPT_DIR/config-doxybook2.json 34 | 35 | # Not ideal but mkdocs can only work with all the files in the same directory. 36 | rm -rf $SCRIPT_DIR/software 37 | cp -r docs/software $SCRIPT_DIR/software 38 | -------------------------------------------------------------------------------- /docs/getting_started.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | To use Ensō, you first need to make sure that your system meets the requirements in terms of hardware and software. 4 | 5 | ## System requirements 6 | 7 | Ensō currently requires an Intel Stratix 10 MX FPGA. Support for other boards might be added in the future. Ensō's codebase also assumes an x86-64 architecture and that the system is running Linux. Ensō was extensively tested on Ubuntu 22.04 and 16.04, but it should work on other Linux distributions as well. 8 | 9 | In what follows, we describe how to setup the software and install the required dependencies. 10 | 11 | ### Dependencies 12 | 13 | Ensō has the following dependencies: 14 | 15 | - GCC (>= 9.0) 16 | - Python (>= 3.9) 17 | - pip 18 | - Meson (>= 0.58) 19 | - Ninja 20 | - libpcap 21 | - wget 22 | 23 | There are also python dependencies listed in `requirements.txt` that can be installed with `pip`. 24 | 25 | If you are using Ubuntu 22.04 or other recent Debian-based distribution, you may be able to use the `setup.sh` script to install all the dependencies. The script is located at the root of the [Ensō repository](https://github.com/crossroadsfpga/enso). To run it, simply execute: 26 | 27 | ```bash 28 | ./setup.sh 29 | ``` 30 | 31 | In Ubuntu 22.04 or other recent Debian-based distributions these dependencies can also be manually installed with the following commands: 32 | ```bash 33 | sudo apt update 34 | sudo apt install \ 35 | python3.9 \ 36 | python3-pip \ 37 | python3-setuptools \ 38 | python3-wheel \ 39 | gcc \ 40 | g++ \ 41 | libpcap-dev \ 42 | tshark 43 | 44 | sudo python3 -m pip install meson ninja # Installing system-wide. 45 | python3 -m pip install -r requirements.txt 46 | ``` 47 | 48 | ### Huge pages 49 | 50 | Ensō requires 2MB huge pages to be allocated in the system. You may use the following snippet adapted from [ixy](https://github.com/emmericp/ixy/blob/master/setup-hugetlbfs.sh) to allocate them. In this example, we allocate 2,048 2MB huge pages per NUMA node. 51 | 52 | ```bash 53 | mkdir -p /mnt/huge 54 | (mount | grep /mnt/huge) > /dev/null || mount -t hugetlbfs hugetlbfs /mnt/huge 55 | for i in /sys/devices/system/node/node[0-9]* 56 | do 57 | echo 2048 > "$i"/hugepages/hugepages-2048kB/nr_hugepages 58 | done 59 | ``` 60 | 61 | ### Quartus 62 | 63 | To be able to load or synthesize the hardware, you also need to install [Intel Quartus 19.3](https://fpgasoftware.intel.com/19.3/?edition=pro) as well as the Stratix 10 device support (same link). 64 | 65 | You should also make sure that `quartus` and its tools are in your `PATH`. You may do so by adding the following lines to your `~/.bashrc` file: 66 | 67 | ```bash 68 | # Make sure this points to the Quartus installation directory. 69 | export quartus_dir= 70 | 71 | export INTELFPGAOCLSDKROOT="$quartus_dir/19.3/hld" 72 | export QUARTUS_ROOTDIR="$quartus_dir/19.3/quartus" 73 | export QSYS_ROOTDIR="$quartus_dir/19.3/qsys/bin" 74 | export IP_ROOTDIR="$quartus_dir/19.3/ip/" 75 | export PATH=$quartus_dir/19.3/quartus/bin:$PATH 76 | export PATH=$quartus_dir/19.3/modelsim_ase/linuxaloem:$PATH 77 | export PATH=$quartus_dir/19.3/quartus/sopc_builder/bin:$PATH 78 | ``` 79 | 80 | !!! note 81 | 82 | Some distributions (e.g., Ubuntu) include code in the `.bashrc` file to prevent it from running in non-interactive environments. This might prevent the above lines from running in some settings. You should remove or comment out the following lines in the `.bashrc` file: 83 | 84 | ```bash 85 | # If not running interactively, don't do anything 86 | case $- in 87 | *i*) ;; 88 | *) return;; 89 | esac 90 | ``` 91 | -------------------------------------------------------------------------------- /docs/hardware/.pages: -------------------------------------------------------------------------------- 1 | nav: 2 | # - Hardware Reference: index.md 3 | - Hardware Counters: counters.md 4 | # - FPGA Memory Mapped Registers 5 | - Hardware Modules: modules 6 | -------------------------------------------------------------------------------- /docs/hardware/index.md: -------------------------------------------------------------------------------- 1 | # Hardware Reference 2 | -------------------------------------------------------------------------------- /docs/hardware/modules/basic_data_mover.md: -------------------------------------------------------------------------------- 1 | # Entity: basic_data_mover 2 | 3 | - **File**: basic_data_mover.sv 4 | ## Diagram 5 | 6 | ![Diagram](basic_data_mover.svg "Diagram") 7 | ## Ports 8 | 9 | | Port name | Direction | Type | Description | 10 | | ------------------------ | --------- | ------------------- | ----------- | 11 | | clk | input | | | 12 | | rst | input | | | 13 | | meta_valid | input | | | 14 | | metadata_t | input | | | 15 | | meta_ready | output | | | 16 | | pkt_buffer_address | output | [PKTBUF_AWIDTH-1:0] | | 17 | | pkt_buffer_read | output | | | 18 | | pkt_buffer_readvalid | input | | | 19 | | pkt_buffer_readdata | input | | | 20 | | emptylist_in_data | output | [PKT_AWIDTH-1:0] | | 21 | | emptylist_in_valid | output | | | 22 | | emptylist_in_ready | input | | | 23 | | disable_pcie | input | | | 24 | | pcie_rx_pkt_sop | output | | | 25 | | pcie_rx_pkt_eop | output | | | 26 | | pcie_rx_pkt_valid | output | | | 27 | | pcie_rx_pkt_data | output | [511:0] | | 28 | | pcie_rx_pkt_empty | output | [5:0] | | 29 | | pcie_rx_pkt_ready | input | | | 30 | | pcie_rx_pkt_almost_full | input | | | 31 | | pcie_rx_meta_valid | output | | | 32 | | pcie_rx_meta_data | output | | | 33 | | pcie_rx_meta_ready | input | | | 34 | | pcie_rx_meta_almost_full | input | | | 35 | | pcie_tx_pkt_sop | input | | | 36 | | pcie_tx_pkt_eop | input | | | 37 | | pcie_tx_pkt_valid | input | | | 38 | | pcie_tx_pkt_data | input | [511:0] | | 39 | | pcie_tx_pkt_empty | input | [5:0] | | 40 | | pcie_tx_pkt_ready | output | | | 41 | | eth_pkt_sop | output | | | 42 | | eth_pkt_eop | output | | | 43 | | eth_pkt_valid | output | | | 44 | | eth_pkt_data | output | [511:0] | | 45 | | eth_pkt_empty | output | [5:0] | | 46 | | eth_pkt_ready | input | | | 47 | | eth_pkt_almost_full | input | | | 48 | ## Instantiations 49 | 50 | - hp_flags: hyper_pipe 51 | ## State machines 52 | 53 | ![Diagram_state_machine_0]( stm_basic_data_mover_00.svg "Diagram") 54 | -------------------------------------------------------------------------------- /docs/hardware/modules/configurator.md: -------------------------------------------------------------------------------- 1 | # Entity: configurator 2 | 3 | - **File**: configurator.sv 4 | ## Diagram 5 | 6 | ![Diagram](configurator.svg "Diagram") 7 | ## Ports 8 | 9 | | Port name | Direction | Type | Description | 10 | | ------------------------ | --------- | ---- | ----------- | 11 | | clk | input | | | 12 | | rst | input | | | 13 | | in_config_data | input | | | 14 | | in_config_valid | input | | | 15 | | in_config_ready | output | | | 16 | | flow_table_config_t | output | | | 17 | | out_conf_ft_valid | output | | | 18 | | out_conf_ft_ready | input | | | 19 | | timestamp_config_t | output | | | 20 | | out_conf_ts_valid | output | | | 21 | | out_conf_ts_ready | input | | | 22 | | rate_limit_config_t | output | | | 23 | | out_conf_rl_valid | output | | | 24 | | out_conf_rl_ready | input | | | 25 | | fallback_queues_config_t | output | | | 26 | | out_conf_fq_valid | output | | | 27 | | out_conf_fq_ready | input | | | 28 | -------------------------------------------------------------------------------- /docs/hardware/modules/dc_back_pressure.md: -------------------------------------------------------------------------------- 1 | # Entity: dc_back_pressure 2 | 3 | - **File**: dc_back_pressure.sv 4 | ## Diagram 5 | 6 | ![Diagram](dc_back_pressure.svg "Diagram") 7 | ## Generics 8 | 9 | | Generic name | Type | Value | Description | 10 | | ------------ | ---- | ----- | ----------- | 11 | | FULL_LEVEL | | 490 | | 12 | ## Ports 13 | 14 | | Port name | Direction | Type | Description | 15 | | ------------- | --------- | ------ | ----------- | 16 | | clk | input | | | 17 | | rst | input | | | 18 | | csr_address | output | | | 19 | | csr_read | output | | | 20 | | csr_write | output | | | 21 | | csr_readdata | input | [31:0] | | 22 | | csr_writedata | output | [31:0] | | 23 | | almost_full | output | | | 24 | -------------------------------------------------------------------------------- /docs/hardware/modules/dependency_graph.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crossroadsfpga/enso/632133a3fcd1d894dd4c3a873e4fde91d58b8894/docs/hardware/modules/dependency_graph.svg -------------------------------------------------------------------------------- /docs/hardware/modules/esram_wrapper.md: -------------------------------------------------------------------------------- 1 | # Entity: esram_wrapper 2 | 3 | - **File**: esram_wrapper.sv 4 | ## Diagram 5 | 6 | ![Diagram](esram_wrapper.svg "Diagram") 7 | ## Ports 8 | 9 | | Port name | Direction | Type | Description | 10 | | -------------- | --------- | ------------------- | ----------- | 11 | | clk_esram_ref | input | | | 12 | | esram_pll_lock | output | | | 13 | | clk_esram | output | | | 14 | | clk_esram | output | | | 15 | | wren | input | | | 16 | | wraddress | input | [PKTBUF_AWIDTH-1:0] | | 17 | | wrdata | input | [519:0] | | 18 | | rden | input | | | 19 | | rdaddress | input | [PKTBUF_AWIDTH-1:0] | | 20 | | rd_valid | output | | | 21 | | rddata | output | [519:0] | | 22 | ## Instantiations 23 | 24 | - esrm_sim: bram_simple2port 25 | - esram_0: esram 26 | -------------------------------------------------------------------------------- /docs/hardware/modules/flow_director.md: -------------------------------------------------------------------------------- 1 | # Entity: flow_director 2 | 3 | - **File**: flow_director.sv 4 | ## Diagram 5 | 6 | ![Diagram](flow_director.svg "Diagram") 7 | ## Ports 8 | 9 | | Port name | Direction | Type | Description | 10 | | ------------------------ | --------- | ---- | ----------- | 11 | | clk | input | | | 12 | | rst | input | | | 13 | | in_meta_data | input | | | 14 | | in_meta_valid | input | | | 15 | | in_meta_ready | output | | | 16 | | out_meta_data | output | | | 17 | | out_meta_valid | output | | | 18 | | out_meta_ready | input | | | 19 | | fallback_queues_config_t | input | | | 20 | | conf_fd_valid | input | | | 21 | | conf_fd_ready | output | | | 22 | -------------------------------------------------------------------------------- /docs/hardware/modules/flow_table_wrapper.md: -------------------------------------------------------------------------------- 1 | # Entity: flow_table_wrapper 2 | 3 | - **File**: flow_table_wrapper.sv 4 | ## Diagram 5 | 6 | ![Diagram](flow_table_wrapper.svg "Diagram") 7 | ## Ports 8 | 9 | | Port name | Direction | Type | Description | 10 | | ------------------- | --------- | ------ | ----------- | 11 | | clk | input | | | 12 | | rst | input | | | 13 | | in_meta_data | input | | | 14 | | in_meta_valid | input | | | 15 | | in_meta_ready | output | | | 16 | | out_meta_data | output | | | 17 | | out_meta_valid | output | | | 18 | | out_meta_ready | input | | | 19 | | flow_table_config_t | input | | | 20 | | in_control_valid | input | | | 21 | | in_control_ready | output | | | 22 | | out_control_done | output | | | 23 | | eviction_cnt | output | [31:0] | | 24 | ## Instantiations 25 | 26 | - s_hash0: hash_func 27 | - s_hash1: hash_func 28 | - s_hash2: hash_func 29 | - s_hash3: hash_func 30 | - p_hash0: hash_func 31 | - p_hash1: hash_func 32 | - p_hash2: hash_func 33 | - p_hash3: hash_func 34 | - FT_0: bram_true2port 35 | - FT_1: bram_true2port 36 | - FT_2: bram_true2port 37 | - FT_3: bram_true2port 38 | ## State machines 39 | 40 | ![Diagram_state_machine_0]( stm_flow_table_wrapper_00.svg "Diagram") 41 | -------------------------------------------------------------------------------- /docs/hardware/modules/hash_func.md: -------------------------------------------------------------------------------- 1 | # Entity: hash_func 2 | 3 | - **File**: hash_func.sv 4 | ## Diagram 5 | 6 | ![Diagram](hash_func.svg "Diagram") 7 | ## Ports 8 | 9 | | Port name | Direction | Type | Description | 10 | | -------------- | --------- | ------- | ----------- | 11 | | clk | input | | | 12 | | rst | input | | | 13 | | stall | input | | | 14 | | initval | input | [31:0] | | 15 | | tuple_in | input | tuple_t | | 16 | | tuple_in_valid | input | | | 17 | | hashed_valid | output | | | 18 | | hashed | output | [31:0] | | 19 | -------------------------------------------------------------------------------- /docs/hardware/modules/hyper_pipe.md: -------------------------------------------------------------------------------- 1 | # Entity: hyper_pipe 2 | 3 | - **File**: hyper_pipe.sv 4 | ## Diagram 5 | 6 | ![Diagram](hyper_pipe.svg "Diagram") 7 | ## Description 8 | 9 | 10 | 11 | ## Generics 12 | 13 | | Generic name | Type | Value | Description | 14 | | ------------ | ---- | ----- | ----------- | 15 | | WIDTH | | 1 | | 16 | | NUM_PIPES | | 1 | | 17 | ## Ports 18 | 19 | | Port name | Direction | Type | Description | 20 | | --------- | --------- | ----------- | ----------- | 21 | | clk | input | | | 22 | | din | input | [WIDTH-1:0] | | 23 | | dout | output | [WIDTH-1:0] | | 24 | -------------------------------------------------------------------------------- /docs/hardware/modules/hyper_pipe_rst.md: -------------------------------------------------------------------------------- 1 | # Entity: hyper_pipe_rst 2 | 3 | - **File**: hyper_pipe_rst.sv 4 | ## Diagram 5 | 6 | ![Diagram](hyper_pipe_rst.svg "Diagram") 7 | ## Description 8 | 9 | 10 | 11 | ## Generics 12 | 13 | | Generic name | Type | Value | Description | 14 | | ------------ | ---- | ----- | ----------- | 15 | | WIDTH | | 1 | | 16 | | NUM_PIPES | | 1 | | 17 | ## Ports 18 | 19 | | Port name | Direction | Type | Description | 20 | | --------- | --------- | ----------- | ----------- | 21 | | clk | input | | | 22 | | rst | input | | | 23 | | din | input | [WIDTH-1:0] | | 24 | | dout | output | [WIDTH-1:0] | | 25 | -------------------------------------------------------------------------------- /docs/hardware/modules/input_comp.md: -------------------------------------------------------------------------------- 1 | # Entity: input_comp 2 | 3 | - **File**: input_comp.sv 4 | ## Diagram 5 | 6 | ![Diagram](input_comp.svg "Diagram") 7 | ## Ports 8 | 9 | | Port name | Direction | Type | Description | 10 | | -------------------- | --------- | ------------------- | ----------- | 11 | | clk | input | | | 12 | | rst | input | | | 13 | | eth_sop | input | | | 14 | | eth_eop | input | | | 15 | | eth_data | input | [511:0] | | 16 | | eth_empty | input | [5:0] | | 17 | | eth_valid | input | | | 18 | | pkt_buffer_address | output | [PKTBUF_AWIDTH-1:0] | | 19 | | pkt_buffer_write | output | | | 20 | | pkt_buffer_writedata | output | flit_t | | 21 | | emptylist_out_data | input | [PKT_AWIDTH-1:0] | | 22 | | emptylist_out_valid | input | | | 23 | | emptylist_out_ready | output | | | 24 | | pkt_sop | output | | | 25 | | pkt_eop | output | | | 26 | | pkt_valid | output | | | 27 | | pkt_data | output | [511:0] | | 28 | | pkt_empty | output | [5:0] | | 29 | | pkt_ready | input | | | 30 | | meta_valid | output | | | 31 | | meta_data | output | metadata_t | | 32 | | meta_ready | input | | | 33 | -------------------------------------------------------------------------------- /docs/hardware/modules/my_stats.md: -------------------------------------------------------------------------------- 1 | # Entity: my_stats 2 | 3 | - **File**: my_stats.sv 4 | ## Diagram 5 | 6 | ![Diagram](my_stats.svg "Diagram") 7 | ## Ports 8 | 9 | | Port name | Direction | Type | Description | 10 | | --------------------- | --------- | ------- | ----------- | 11 | | arst | input | | | 12 | | clk_tx | input | | | 13 | | tx_ready | input | | | 14 | | tx_valid | input | | | 15 | | tx_data | input | [511:0] | | 16 | | tx_sop | input | | | 17 | | tx_eop | input | | | 18 | | tx_empty | input | [5:0] | | 19 | | clk_rx | input | | | 20 | | rx_sop | input | | | 21 | | rx_eop | input | | | 22 | | rx_empty | input | [5:0] | | 23 | | rx_data | input | [511:0] | | 24 | | rx_valid | input | | | 25 | | rx_ready | input | | | 26 | | o_rx_sop | output | | | 27 | | o_rx_eop | output | | | 28 | | o_rx_empty | output | [5:0] | | 29 | | o_rx_data | output | [511:0] | | 30 | | o_rx_valid | output | | | 31 | | clk_status | input | | | 32 | | status_addr | input | [29:0] | | 33 | | status_read | input | | | 34 | | status_write | input | | | 35 | | status_writedata | input | [31:0] | | 36 | | status_readdata | output | [31:0] | | 37 | | status_readdata_valid | output | | | 38 | ## Processes 39 | - unnamed: ( @(posedge clk_status) ) 40 | - **Type:** always 41 | - **Description** 42 | //////////////////////// /////////////////////// 43 | - unnamed: ( @(posedge clk_rx) ) 44 | - **Type:** always 45 | - **Description** 46 | //////////////////////// /////////////////////// 47 | - unnamed: ( @(posedge clk_tx) ) 48 | - **Type:** always 49 | - **Description** 50 | //////////////////////// /////////////////////// 51 | -------------------------------------------------------------------------------- /docs/hardware/modules/parser.md: -------------------------------------------------------------------------------- 1 | # Entity: parser 2 | 3 | - **File**: parser.sv 4 | ## Diagram 5 | 6 | ![Diagram](parser.svg "Diagram") 7 | ## Description 8 | 9 | 10 | 11 | ## Ports 12 | 13 | | Port name | Direction | Type | Description | 14 | | -------------- | --------- | ------- | ----------- | 15 | | clk | input | | | 16 | | rst | input | | | 17 | | disable_pcie | input | | | 18 | | in_pkt_data | input | [511:0] | | 19 | | in_pkt_valid | input | | | 20 | | in_pkt_ready | output | | | 21 | | in_pkt_sop | input | | | 22 | | in_pkt_eop | input | | | 23 | | in_pkt_empty | input | [5:0] | | 24 | | out_pkt_data | output | [511:0] | | 25 | | out_pkt_valid | output | | | 26 | | out_pkt_ready | input | | | 27 | | out_pkt_sop | output | | | 28 | | out_pkt_eop | output | | | 29 | | out_pkt_empty | output | [5:0] | | 30 | | in_meta_data | input | | | 31 | | in_meta_valid | input | | | 32 | | in_meta_ready | output | | | 33 | | out_meta_data | output | | | 34 | | out_meta_valid | output | | | 35 | | out_meta_ready | input | | | 36 | -------------------------------------------------------------------------------- /docs/hardware/modules/pcie/bram_mux.md: -------------------------------------------------------------------------------- 1 | # Entity: bram_mux 2 | 3 | - **File**: bram_mux.sv 4 | ## Diagram 5 | 6 | ![Diagram](bram_mux.svg "Diagram") 7 | ## Description 8 | 9 | Use to join multiple BRAM blocks into one (adds 1 cycle delay for write and 10 | 2 cycles for read) 11 | 12 | ## Generics 13 | 14 | | Generic name | Type | Value | Description | 15 | | ------------ | ---- | --------- | ----------- | 16 | | NB_BRAMS | | undefined | | 17 | ## Ports 18 | 19 | | Port name | Direction | Type | Description | 20 | | --------- | --------- | ---- | ----------- | 21 | | clk | input | | | 22 | | in | input | | | 23 | | out | input | | | 24 | -------------------------------------------------------------------------------- /docs/hardware/modules/pcie/bram_mux.svg: -------------------------------------------------------------------------------- 1 | NB_BRAMS clk in out 2 | -------------------------------------------------------------------------------- /docs/hardware/modules/pcie/dependency_graph.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crossroadsfpga/enso/632133a3fcd1d894dd4c3a873e4fde91d58b8894/docs/hardware/modules/pcie/dependency_graph.svg -------------------------------------------------------------------------------- /docs/hardware/modules/pcie/fpga_to_cpu.md: -------------------------------------------------------------------------------- 1 | # Entity: fpga_to_cpu 2 | 3 | - **File**: fpga_to_cpu.sv 4 | ## Diagram 5 | 6 | ![Diagram](fpga_to_cpu.svg "Diagram") 7 | ## Description 8 | 9 | 10 | 11 | ## Ports 12 | 13 | | Port name | Direction | Type | Description | 14 | | ---------------------- | --------- | ----------------- | ----------- | 15 | | clk | input | | | 16 | | rst | input | | | 17 | | pkt_buf_in_data | input | | | 18 | | pkt_buf_in_valid | input | | | 19 | | pkt_buf_in_ready | output | | | 20 | | pkt_buf_occup | output | [F2C_RB_AWIDTH:0] | | 21 | | pkt_meta_with_queues_t | input | | | 22 | | metadata_buf_in_valid | input | | | 23 | | metadata_buf_in_ready | output | | | 24 | | metadata_buf_occup | output | [F2C_RB_AWIDTH:0] | | 25 | | tx_compl_buf_in_data | input | | | 26 | | tx_compl_buf_in_valid | input | | | 27 | | tx_compl_buf_in_ready | output | | | 28 | | tx_compl_buf_occup | output | [31:0] | | 29 | | pkt_rb_size | input | [RB_AWIDTH:0] | | 30 | | dsc_rb_size | input | [RB_AWIDTH:0] | | 31 | | pcie_bas_waitrequest | input | | | 32 | | pcie_bas_address | output | [63:0] | | 33 | | pcie_bas_byteenable | output | [63:0] | | 34 | | pcie_bas_read | output | | | 35 | | pcie_bas_readdata | input | [511:0] | | 36 | | pcie_bas_readdatavalid | input | | | 37 | | pcie_bas_write | output | | | 38 | | pcie_bas_writedata | output | [511:0] | | 39 | | pcie_bas_burstcount | output | [3:0] | | 40 | | pcie_bas_response | input | [1:0] | | 41 | | pcie_core_full_cnt | output | [31:0] | | 42 | | dma_dsc_cnt | output | [31:0] | | 43 | | dma_dsc_drop_cnt | output | [31:0] | | 44 | | dma_pkt_flit_cnt | output | [31:0] | | 45 | | dma_pkt_flit_drop_cnt | output | [31:0] | | 46 | ## State machines 47 | 48 | ![Diagram_state_machine_0]( stm_fpga_to_cpu_00.svg "Diagram") 49 | -------------------------------------------------------------------------------- /docs/hardware/modules/pcie/jtag_mmio_arbiter.md: -------------------------------------------------------------------------------- 1 | # Entity: jtag_mmio_arbiter 2 | 3 | - **File**: jtag_mmio_arbiter.sv 4 | ## Diagram 5 | 6 | ![Diagram](jtag_mmio_arbiter.svg "Diagram") 7 | ## Description 8 | 9 | 10 | 11 | ## Generics 12 | 13 | | Generic name | Type | Value | Description | 14 | | ------------------ | ---- | ----- | ----------- | 15 | | PKT_QUEUE_RD_DELAY | | 2 | | 16 | ## Ports 17 | 18 | | Port name | Direction | Type | Description | 19 | | ---------------------- | --------- | --------------------- | ----------- | 20 | | pcie_clk | input | | | 21 | | jtag_clk | input | | | 22 | | pcie_reset_n | input | | | 23 | | pcie_address_0 | input | [PCIE_ADDR_WIDTH-1:0] | | 24 | | pcie_write_0 | input | | | 25 | | pcie_read_0 | input | | | 26 | | pcie_readdatavalid_0 | output | | | 27 | | pcie_readdata_0 | output | [511:0] | | 28 | | pcie_writedata_0 | input | [511:0] | | 29 | | pcie_byteenable_0 | input | [63:0] | | 30 | | status_addr | input | [29:0] | | 31 | | status_read | input | | | 32 | | status_write | input | | | 33 | | status_writedata | input | [31:0] | | 34 | | status_readdata | output | [31:0] | | 35 | | status_readdata_valid | output | | | 36 | | rx_dsc_q_table_tails | output | | | 37 | | rx_dsc_q_table_heads | output | | | 38 | | rx_dsc_q_table_l_addrs | output | | | 39 | | rx_dsc_q_table_h_addrs | output | | | 40 | | tx_dsc_q_table_tails | output | | | 41 | | tx_dsc_q_table_heads | output | | | 42 | | tx_dsc_q_table_l_addrs | output | | | 43 | | tx_dsc_q_table_h_addrs | output | | | 44 | | pkt_q_table_tails | output | | | 45 | | pkt_q_table_heads | output | | | 46 | | pkt_q_table_l_addrs | output | | | 47 | | pkt_q_table_h_addrs | output | | | 48 | | control_regs | output | [31:0] | | 49 | ## Instantiations 50 | 51 | - jtag_to_pcie_fifo: dc_fifo_reg_core 52 | - jtag_to_pcie_wr_data_fifo: dc_fifo_reg_core 53 | - pcie_to_jtag_fifo: dc_fifo_reg_core 54 | -------------------------------------------------------------------------------- /docs/hardware/modules/pcie/rx_dsc_queue_manager.md: -------------------------------------------------------------------------------- 1 | # Entity: rx_dsc_queue_manager 2 | 3 | - **File**: rx_dsc_queue_manager.sv 4 | ## Diagram 5 | 6 | ![Diagram](rx_dsc_queue_manager.svg "Diagram") 7 | ## Description 8 | 9 | 10 | 11 | ## Generics 12 | 13 | | Generic name | Type | Value | Description | 14 | | ------------ | ---- | --------- | ----------- | 15 | | NB_QUEUES | | undefined | | 16 | ## Ports 17 | 18 | | Port name | Direction | Type | Description | 19 | | ---------------------- | --------- | ------------- | ----------- | 20 | | clk | input | | | 21 | | rst | input | | | 22 | | pkt_meta_with_queues_t | input | | | 23 | | in_meta_valid | input | | | 24 | | in_meta_ready | output | | | 25 | | pkt_meta_with_queues_t | output | | | 26 | | out_meta_valid | output | | | 27 | | out_meta_ready | input | | | 28 | | q_table_tails | input | | | 29 | | q_table_heads | input | | | 30 | | q_table_l_addrs | input | | | 31 | | q_table_h_addrs | input | | | 32 | | rb_size | input | [RB_AWIDTH:0] | | 33 | | full_cnt | output | [31:0] | | 34 | | in_cnt | output | [31:0] | | 35 | | out_cnt | output | [31:0] | | 36 | -------------------------------------------------------------------------------- /docs/hardware/modules/pdu_gen.md: -------------------------------------------------------------------------------- 1 | # Entity: pdu_gen 2 | 3 | - **File**: pdu_gen.sv 4 | ## Diagram 5 | 6 | ![Diagram](pdu_gen.svg "Diagram") 7 | ## Generics 8 | 9 | | Generic name | Type | Value | Description | 10 | | ---------------------------- | ---- | ---------------------------------- | ----------- | 11 | | OUT_PKT_Q_DEPTH | | 64 | | 12 | | OUT_META_Q_DEPTH | | 128 | | 13 | | PKT_Q_ALMOST_FULL_THRESHOLD | | OUT_PKT_Q_DEPTH - MAX_PKT_SIZE * 2 | | 14 | | META_Q_ALMOST_FULL_THRESHOLD | | OUT_META_Q_DEPTH - 8 | | 15 | ## Ports 16 | 17 | | Port name | Direction | Type | Description | 18 | | -------------------- | --------- | ------- | ----------- | 19 | | clk | input | | | 20 | | rst | input | | | 21 | | in_sop | input | | | 22 | | in_eop | input | | | 23 | | in_data | input | [511:0] | | 24 | | in_empty | input | [5:0] | | 25 | | in_valid | input | | | 26 | | in_ready | output | | | 27 | | in_meta_valid | input | | | 28 | | in_meta_data | input | | | 29 | | in_meta_ready | output | | | 30 | | pcie_pkt_buf_data | output | | | 31 | | pcie_pkt_buf_valid | output | | | 32 | | pcie_pkt_buf_ready | input | | | 33 | | pcie_meta_buf_data | output | | | 34 | | pcie_meta_buf_valid | output | | | 35 | | pcie_meta_buf_ready | input | | | 36 | | out_pkt_queue_occup | output | [31:0] | | 37 | | out_meta_queue_occup | output | [31:0] | | 38 | -------------------------------------------------------------------------------- /docs/hardware/modules/rate_limiter.md: -------------------------------------------------------------------------------- 1 | # Entity: rate_limiter 2 | 3 | - **File**: rate_limiter.sv 4 | ## Diagram 5 | 6 | ![Diagram](rate_limiter.svg "Diagram") 7 | ## Description 8 | 9 | 10 | 11 | ## Ports 12 | 13 | | Port name | Direction | Type | Description | 14 | | ------------------- | --------- | ------- | ----------- | 15 | | clk | input | | | 16 | | rst | input | | | 17 | | in_pkt_data | input | [511:0] | | 18 | | in_pkt_valid | input | | | 19 | | in_pkt_ready | output | | | 20 | | in_pkt_sop | input | | | 21 | | in_pkt_eop | input | | | 22 | | in_pkt_empty | input | [5:0] | | 23 | | out_pkt_data | output | [511:0] | | 24 | | out_pkt_valid | output | | | 25 | | out_pkt_ready | input | | | 26 | | out_pkt_sop | output | | | 27 | | out_pkt_eop | output | | | 28 | | out_pkt_empty | output | [5:0] | | 29 | | rate_limit_config_t | input | | | 30 | | conf_rl_valid | input | | | 31 | | conf_rl_ready | output | | | 32 | -------------------------------------------------------------------------------- /docs/hardware/modules/timestamp.md: -------------------------------------------------------------------------------- 1 | # Entity: timestamp 2 | 3 | - **File**: timestamp.sv 4 | ## Diagram 5 | 6 | ![Diagram](timestamp.svg "Diagram") 7 | ## Description 8 | 9 | Timestamp outgoing packets and calculate RTT for incoming packets using this 10 | timestamp. For incoming packets we also replace the timestamp with the RTT 11 | (in number of cycles). Must be explicitly enabled using the configuration 12 | interface. Otherwise this module does nothing. 13 | 14 | ## Generics 15 | 16 | | Generic name | Type | Value | Description | 17 | | ---------------- | ---- | -------- | ----------- | 18 | | TIMESTAMP_WIDTH | | 32 | | 19 | | TIMESTAMP_OFFSET | | (112+32) | | 20 | ## Ports 21 | 22 | | Port name | Direction | Type | Description | 23 | | ------------------ | --------- | ------- | -------------- | 24 | | clk | input | | | 25 | | rst | input | | | 26 | | rx_in_pkt_data | input | [511:0] | RX input. | 27 | | rx_in_pkt_valid | input | | | 28 | | rx_in_pkt_ready | output | | | 29 | | rx_in_pkt_sop | input | | | 30 | | rx_in_pkt_eop | input | | | 31 | | rx_in_pkt_empty | input | [5:0] | | 32 | | rx_out_pkt_data | output | [511:0] | RX output. | 33 | | rx_out_pkt_valid | output | | | 34 | | rx_out_pkt_ready | input | | | 35 | | rx_out_pkt_sop | output | | | 36 | | rx_out_pkt_eop | output | | | 37 | | rx_out_pkt_empty | output | [5:0] | | 38 | | tx_in_pkt_data | input | [511:0] | TX input. | 39 | | tx_in_pkt_valid | input | | | 40 | | tx_in_pkt_ready | output | | | 41 | | tx_in_pkt_sop | input | | | 42 | | tx_in_pkt_eop | input | | | 43 | | tx_in_pkt_empty | input | [5:0] | | 44 | | tx_out_pkt_data | output | [511:0] | TX output. | 45 | | tx_out_pkt_valid | output | | | 46 | | tx_out_pkt_ready | input | | | 47 | | tx_out_pkt_sop | output | | | 48 | | tx_out_pkt_eop | output | | | 49 | | tx_out_pkt_empty | output | [5:0] | | 50 | | timestamp_config_t | input | | Configuration. | 51 | | conf_ts_valid | input | | | 52 | | conf_ts_ready | output | | | 53 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Ensō 2 | 3 | 4 | 5 | Ensō is a high-performance streaming interface for NIC-application communication. 6 | 7 | Ensō's design encompasses both *hardware* and *software*. The hardware component targets an FPGA NIC[^1] and implements the Ensō interface. The software component uses this interface and exposes simple communication primitives called [Ensō Pipes](primitives/rx_enso_pipe.md). Applications can use Ensō Pipes to send and receive data in different formats, such as raw packets, application-level messages, or TCP-like byte streams. 8 | 9 | Refer to the [OSDI '23 paper](https://www.usenix.org/conference/osdi23/presentation/sadok) for details about the design. 10 | 11 | [^1]: Network Interface Cards (NICs) are the hardware devices that connect a computer to the network. They are responsible for transmitting data from the CPU to the network and vice versa. FPGAs are reconfigurable hardware devices. They can be reconfigured to implement arbitrary hardware designs. Here we use an FPGA to implement a NIC with the Ensō interface but the same interface could also be implemented in a traditional fixed-function hardware. 12 | 13 | 14 | ## Why Ensō? 15 | 16 | Traditionally, NICs expose a *packetized* interface that software (applications or the kernel) must use to communicate with the NIC. Ensō provides two main advantages over this interface: 17 | 18 | - **Flexibility:** While NICs were traditionally in charge of delivering raw packets to software, an increasing amount of high-level functionality is now performed on the NIC. The packetized interface, however, forces data to be fragmented into packets that are then scattered across memory. This prevents the NIC and the application from communicating efficiently using higher-level abstractions such as application-level messages or TCP streams. Ensō instead allows the NIC and the application to communicate using a contiguous stream of bytes, which can be used to represent *arbitrary* data. 19 | - **Performance:** By forcing hardware and software to synchronize buffers for every packet, the packetized interface imposes significant per-packet overhead both in terms of CPU cycles as well as PCIe bandwidth. This results in significant performance degradation, in particular when using small requests. Ensō's use of a byte stream interface allows the NIC and the application to exchange multiple packets (or messages) at once, which reduces the number of CPU cycles and PCIe transactions required to communicate each request. Moreover, by placing packets (or messages) contiguously in memory, Ensō makes better use of the CPU prefetcher, vastly reducing the number of cache misses. 20 | 21 | 22 | ## Getting started 23 | 24 | - [Setup](getting_started.md) 25 | - Understanding the primitives: [RX Ensō Pipe](primitives/rx_enso_pipe.md), [TX Ensō Pipe](primitives/tx_enso_pipe.md), [RX/TX Ensō Pipe](primitives/rx_tx_enso_pipe.md) 26 | - Examples: [Echo Server](https://github.com/crossroadsfpga/enso/blob/master/software/examples/echo.cpp), [Packet Capture](https://github.com/crossroadsfpga/enso/blob/master/software/examples/capture.cpp), [EnsōGen Packet Generator](https://github.com/crossroadsfpga/enso/blob/master/software/examples/ensogen.cpp) 27 | - API References: [Software](software), [Hardware](hardware) 28 | -------------------------------------------------------------------------------- /docs/javascripts/tablesort.js: -------------------------------------------------------------------------------- 1 | document$.subscribe(function() { 2 | var tables = document.querySelectorAll("article table:not([class])") 3 | tables.forEach(function(table) { 4 | new Tablesort(table) 5 | }) 6 | }) 7 | -------------------------------------------------------------------------------- /docs/meson.build: -------------------------------------------------------------------------------- 1 | cdata = configuration_data() 2 | cdata.set('VERSION', meson.project_version()) 3 | cdata.set('TOP_SRCDIR', meson.project_source_root()) 4 | cdata.set('TOP_BUILDDIR', meson.project_build_root()) 5 | 6 | if find_program('dot', required: false).found() 7 | cdata.set('HAVE_DOT', 'YES') 8 | else 9 | cdata.set('HAVE_DOT', 'NO') 10 | endif 11 | 12 | doxygen = find_program('doxygen', required: false) 13 | 14 | sw_doc_path = join_paths(meson.project_source_root(), 'docs/software') 15 | 16 | if doxygen.found() 17 | doxyfile = configure_file(input: 'doxygen/Doxyfile.in', 18 | output: 'Doxyfile', 19 | configuration: cdata, 20 | install: false) 21 | 22 | doxygen_target = custom_target('doxygen', 23 | input: [doxyfile, files([ 24 | 'doxygen/doxygen-awesome.css', 25 | 'doxygen/doxygen-awesome-sidebar-only.css', 26 | 'doxygen/doxygen_header.html' 27 | ])], 28 | output: ['html', 'xml'], 29 | command: [doxygen, doxyfile], 30 | build_by_default: false) 31 | 32 | rm_software_doc_path = custom_target('rm_software_doc_path', 33 | input: doxygen_target, 34 | output: 'rm_software_doc_path', 35 | command: [ 36 | 'rm', '-r', '-f', sw_doc_path 37 | ], 38 | build_by_default: false, 39 | build_always_stale: true) 40 | 41 | cp_doxygen_target = custom_target('cp_html', 42 | input: doxygen_target, 43 | output: 'cp_doxygen_target', 44 | command: [ 45 | 'cp', 46 | '-r', 47 | '-T', 48 | 'html', 49 | sw_doc_path 50 | ], 51 | depends: [rm_software_doc_path, doxygen_target], 52 | build_by_default: false, 53 | build_always_stale: true) 54 | endif 55 | 56 | teroshdl_hdl_documenter = find_program('teroshdl-hdl-documenter', 57 | required: false) 58 | mkdocs = find_program('mkdocs', required: false) 59 | 60 | if teroshdl_hdl_documenter.found() and mkdocs.found() 61 | mkdocs_docs = custom_target('mkdocs_docs', 62 | input: [cp_doxygen_target], 63 | output: 'site', 64 | command: ['build_docs.sh'], 65 | build_by_default: false, 66 | build_always_stale: true) 67 | 68 | docs = alias_target('docs', mkdocs_docs) 69 | endif 70 | -------------------------------------------------------------------------------- /docs/out/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /docs/primitives/.pages: -------------------------------------------------------------------------------- 1 | nav: 2 | # - Primitives: index.md 3 | - RX Ensō Pipe: rx_enso_pipe.md 4 | - TX Ensō Pipe: tx_enso_pipe.md 5 | - RX/TX Ensō Pipe: rx_tx_enso_pipe.md 6 | - Device: device.md 7 | -------------------------------------------------------------------------------- /docs/primitives/index.md: -------------------------------------------------------------------------------- 1 | # Primitives 2 | -------------------------------------------------------------------------------- /docs/primitives/rx_tx_enso_pipe.md: -------------------------------------------------------------------------------- 1 | # RX/TX Ensō Pipe 2 | 3 | RX/TX Ensō Pipes are designed for applications that modify received data in place and then send it back to the NIC without the need to impose copy overhead. They can be seen as a combination of an [RX](rx_enso_pipe.md) and [TX](tx_enso_pipe.md) Ensō Pipes, containing a subset of their functionality. 4 | 5 | RX/TX Ensō Pipes can receive data from the NIC in the same way as RX Ensō Pipes. Therefore, applications can use analogous functions to receive data. Refer to the [RX Ensō Pipe](rx_enso_pipe.md) documentation for more information about each of those functions: 6 | 7 | - Receiving byte streams: [`RxTxPipe::Recv()`](/software/classenso_1_1RxTxPipe.html#ae5d2972f0bbe6aebb8e0521884a1557f){target=_blank}, [`RxTxPipe::Peek()`](/software/classenso_1_1RxTxPipe.html#a5026cb7e8ea1a5b335fbc77dcfe92c53){target=_blank} 8 | - Receiving raw packets: [`RxTxPipe::RecvPkts()`](/software/classenso_1_1RxTxPipe.html#a98b9f150a91474e0a529cfb7668f7e2a){target=_blank}, [`RxTxPipe::PeekPkts()`](/software/classenso_1_1RxTxPipe.html#a7ec0707e4a3adcc4f9a6c23d2d97d1c9){target=_blank} 9 | - Receiving generic messages: [`RxTxPipe::RecvMessages()`](/software/classenso_1_1RxTxPipe.html#a2619d7dd5d8efbf3d12095360d529cff){target=_blank} 10 | 11 | Different from RX Ensō Pipes, however, RX/TX Ensō Pipes do not support freeing the data received from the NIC. Instead, all received data is automatically freed after transmission. 12 | 13 | To send data back to the NIC, applications should call [`RxTxPipe::SendAndFree()`](/software/classenso_1_1RxTxPipe.html#a8d4c4987842afe0a5754ac36cb54e7f4){target=_blank}. Note that only data that was previously received can be sent back to the NIC, RX/TX Ensō Pipes do not support extending the buffer as in a TX Ensō Pipe. 14 | 15 | The following example shows how to use RX/TX Ensō Pipes to echo received packets back to the NIC after incrementing their payload: 16 | 17 | ```cpp 18 | RxTxPipe* pipe = dev->AllocateRxTxPipe(); // (1)! 19 | assert(pipe != nullptr); 20 | 21 | while (keep_running) { 22 | auto batch = pipe->RecvPkts(); 23 | if (unlikely(batch.available_bytes() == 0)) { 24 | continue; 25 | } 26 | for (auto pkt : batch) { 27 | ++pkt[59]; // Increment payload. 28 | } 29 | pipe->SendAndFree(batch.processed_bytes()); 30 | } 31 | ``` 32 | 33 | 1. :information_source: Note that you should use a [Device](device.md) instance to allocate an RX/TX Ensō Pipe. 34 | 35 | In this example we poll the RX/TX Ensō Pipe for new packets. If there are no packets available, we skip the current iteration of the loop. Otherwise, we increment the payload of each packet and send them back to the NIC. 36 | 37 | 38 | ## Examples 39 | 40 | The following examples use RX/TX Ensō Pipes: 41 | 42 | - [`echo.cpp`](https://github.com/crossroadsfpga/enso/blob/master/software/examples/echo.cpp){target=_blank} 43 | - [`echo_event.cpp`](https://github.com/crossroadsfpga/enso/blob/master/software/examples/echo_event.cpp){target=_blank} 44 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs-awesome-pages-plugin==2.8.0 2 | mkdocs-material==9.0.14 3 | vunit_hdl 4 | -------------------------------------------------------------------------------- /docs/software_api.md: -------------------------------------------------------------------------------- 1 | # Software API Reference 2 | 3 | This page contains the API reference for the software component of Ensō. 4 | 5 | Main components: 6 | 7 | - [Per-thread device class](@ref enso::Device) 8 | - Ensō Pipe classes: [RX Ensō Pipe](@ref enso::RxPipe), [TX Ensō Pipe](@ref enso::TxPipe), [RX/TX Ensō Pipe](@ref enso::RxTxPipe) 9 | - [Low-Level hardware configuration functions](@ref config.h) 10 | 11 | Or check [all the source files](files.html). 12 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /frontend/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022, Hugo Sadok 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | 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 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # Ensō Python Frontend 2 | 3 | ## Install 4 | 5 | To install the frontend run in the current directory (`frontend`): 6 | ```bash 7 | python3 -m pip install -e . 8 | ``` 9 | 10 | ## Running 11 | 12 | For usage information run: 13 | ```bash 14 | enso --help 15 | ``` 16 | 17 | ## Enable autocompletion (optional) 18 | 19 | #### For Bash 20 | Run this: 21 | ```bash 22 | _ENSO_COMPLETE=bash_source enso > ~/.enso-complete.bash 23 | ``` 24 | 25 | Then add the following to your `.bashrc`: 26 | ```bash 27 | . ~/.enso-complete.bash 28 | ``` 29 | 30 | #### For Zsh 31 | Run this: 32 | ```zsh 33 | _ENSO_COMPLETE=zsh_source enso > ~/.enso-complete.zsh 34 | ``` 35 | 36 | Then add the following to your `.zshrc`: 37 | ```zsh 38 | . ~/.enso-complete.zsh 39 | ``` 40 | 41 | #### For Fish 42 | Save the script to `~/.config/fish/completions/enso.fish`: 43 | ```fish 44 | _ENSO_COMPLETE=fish_source enso > ~/.config/fish/completions/enso.fish 45 | ``` 46 | -------------------------------------------------------------------------------- /frontend/enso/__init__.py: -------------------------------------------------------------------------------- 1 | # The following are also used in setup.py 2 | __author__ = "Hugo Sadok" 3 | __email__ = "sadok@cmu.edu" 4 | __version__ = "0.2.0" 5 | -------------------------------------------------------------------------------- /frontend/enso/__main__.py: -------------------------------------------------------------------------------- 1 | import click 2 | 3 | from enso.consts import ( 4 | DEFAULT_DSC_BUF_SIZE, 5 | DEFAULT_ETH_PORT, 6 | DEFAULT_FPGA, 7 | DEFAULT_NB_TX_CREDITS, 8 | DEFAULT_PKT_BUF_SIZE, 9 | ) 10 | from enso.enso_nic import EnsoNic 11 | 12 | 13 | @click.command() 14 | @click.argument("enso_path") 15 | @click.option( 16 | "--host", 17 | default="localhost", 18 | show_default=True, 19 | help="Host to connect to run Ensō on.", 20 | ) 21 | @click.option( 22 | "--fpga", default=DEFAULT_FPGA, show_default=True, help="Choose the FPGA." 23 | ) 24 | @click.option( 25 | "--dsc-buf-size", 26 | default=DEFAULT_DSC_BUF_SIZE, 27 | show_default=True, 28 | type=int, 29 | help="Buffer size used by each software descriptor buffer.", 30 | ) 31 | @click.option( 32 | "--pkt-buf-size", 33 | default=DEFAULT_PKT_BUF_SIZE, 34 | show_default=True, 35 | type=int, 36 | help="Buffer size used by each software packet buffer.", 37 | ) 38 | @click.option( 39 | "--tx-credits", 40 | default=DEFAULT_NB_TX_CREDITS, 41 | show_default=True, 42 | type=click.IntRange(256, 1000), 43 | help="Set number of in-flight descriptors allowed (credits).", 44 | ) 45 | @click.option( 46 | "--eth-port", 47 | default=DEFAULT_ETH_PORT, 48 | show_default=True, 49 | type=click.IntRange(0, 1), 50 | help="Set Ethernet port to use.", 51 | ) 52 | @click.option( 53 | "--desc-per-pkt/--reactive-desc", 54 | default=False, 55 | show_default=True, 56 | help="Use a descriptor per packet or reactive" " descriptors (default).", 57 | ) 58 | @click.option( 59 | "--latency-opt/--throughput-opt", 60 | default=True, 61 | show_default=True, 62 | help="Optimize for throughput/latency.", 63 | ) 64 | @click.option( 65 | "--load-bitstream/--no-load-bitstream", 66 | default=True, 67 | show_default=True, 68 | help="Enable/Disable packet FPGA bitstream reload.", 69 | ) 70 | def main( 71 | host, 72 | enso_path, 73 | fpga, 74 | dsc_buf_size, 75 | pkt_buf_size, 76 | tx_credits, 77 | eth_port, 78 | desc_per_pkt, 79 | latency_opt, 80 | load_bitstream, 81 | ): 82 | 83 | enso_nic = EnsoNic( 84 | fpga, 85 | enso_path, 86 | host_name=host, 87 | load_bitstream=load_bitstream, 88 | ensure_clean=True, 89 | setup_sw=True, 90 | dsc_buf_size=dsc_buf_size, 91 | pkt_buf_size=pkt_buf_size, 92 | tx_credits=tx_credits, 93 | ethernet_port=eth_port, 94 | desc_per_pkt=desc_per_pkt, 95 | latency_opt=latency_opt, 96 | verbose=True, 97 | log_file=True, 98 | ) 99 | 100 | enso_nic.interactive_shell() 101 | 102 | 103 | if __name__ == "__main__": 104 | main() 105 | -------------------------------------------------------------------------------- /frontend/enso/consts.py: -------------------------------------------------------------------------------- 1 | DEFAULT_FPGA = "1-12" 2 | DEFAULT_DSC_BUF_SIZE = 16384 3 | DEFAULT_PKT_BUF_SIZE = 32768 4 | DEFAULT_NB_TX_CREDITS = 500 5 | DEFAULT_ETH_PORT = 1 # Can be 0 or 1. 6 | 7 | # The following paths are relative to the enso path. 8 | SETUP_SW_CMD = "scripts/sw_setup.sh" 9 | ENSOGEN_CMD = "build/software/examples/ensogen" 10 | GET_PCAP_SIZE_CMD = "build/scripts/get_pcap_pkt_size" 11 | PCAPS_DIR = "frontend/pcaps/" 12 | PCAP_GEN_CMD = "build/hardware/input_gen/generate_synthetic_trace" 13 | 14 | FPGA_RATELIMIT_CLOCK = 200e6 # Hz 15 | -------------------------------------------------------------------------------- /frontend/pcaps/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | addopts = --doctest-modules 3 | testpaths = netexp 4 | -------------------------------------------------------------------------------- /frontend/scripts/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | python3 setup.py sdist bdist_wheel 6 | twine check dist/* 7 | twine upload dist/* 8 | -------------------------------------------------------------------------------- /frontend/setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description_file = README.md 3 | 4 | [aliases] 5 | test=pytest 6 | -------------------------------------------------------------------------------- /frontend/setup.py: -------------------------------------------------------------------------------- 1 | import io 2 | import re 3 | from setuptools import setup, find_packages 4 | 5 | with open("README.md", "r", encoding="utf-8") as readme_file: 6 | long_description = readme_file.read() 7 | 8 | package_name = "enso-nic" 9 | name = "enso" 10 | 11 | 12 | # Hack to avoid having to define metadata twice. Instead define it in the 13 | # `__init__.py`` file. This is adapted from here: 14 | # https://stackoverflow.com/a/39671214/2027390 15 | def find_meta(meta_name): 16 | return re.search( 17 | meta_name 18 | + r'\s*=\s*[\'"]([^\'"]*)[\'"]', # It excludes inline comment too 19 | io.open(f"{name}/__init__.py", encoding="utf_8_sig").read(), 20 | ).group(1) 21 | 22 | 23 | setup( 24 | name=package_name, 25 | version=find_meta("__version__"), 26 | description="Python frontend for the Ensō NIC.", 27 | long_description=long_description, 28 | long_description_content_type="text/markdown", 29 | packages=find_packages(), 30 | url="https://github.com/crossroadsfpga/enso", 31 | download_url="https://github.com/crossroadsfpga/enso", 32 | license="BSD", 33 | author=find_meta("__author__"), 34 | author_email=find_meta("__email__"), 35 | keywords=["network", "enso", "nic"], 36 | python_requires=">=3.9", 37 | entry_points={"console_scripts": ["enso=enso.__main__:main"]}, 38 | include_package_data=True, 39 | install_requires=["click>=8.0", "netexp==0.1.17", "scapy"], 40 | # setup_requires=["pytest-runner"], 41 | # tests_require=["pytest"], 42 | classifiers=[ 43 | "Development Status :: 4 - Beta", 44 | "Intended Audience :: Science/Research", 45 | "License :: OSI Approved :: BSD License", 46 | "Natural Language :: English", 47 | "Programming Language :: Python", 48 | "Programming Language :: Python :: 3", 49 | "Programming Language :: Python :: 3.9", 50 | "Programming Language :: Python :: 3.10", 51 | "Programming Language :: Python :: 3.11", 52 | "Topic :: System :: Networking", 53 | "Topic :: System :: Systems Administration", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /gcc.ini: -------------------------------------------------------------------------------- 1 | [constants] 2 | compiler_version = '9' 3 | 4 | [binaries] 5 | c = 'gcc-' + compiler_version 6 | cpp = 'g++-' + compiler_version 7 | ar = 'gcc-ar-' + compiler_version 8 | -------------------------------------------------------------------------------- /hardware/.gitignore: -------------------------------------------------------------------------------- 1 | *.ini 2 | input_gen/*.pcap 3 | input_gen/*.pkt 4 | transcript 5 | *.wlf 6 | libraries/ 7 | work/ 8 | -------------------------------------------------------------------------------- /hardware/esram/esram_1913/synth/iopll.v: -------------------------------------------------------------------------------- 1 | // iopll.v 2 | 3 | // Generated using ACDS version 19.3 222 4 | 5 | `timescale 1 ps / 1 ps 6 | module iopll ( 7 | input wire rst, // reset.reset 8 | output wire locked, // locked.export 9 | input wire permit_cal, // permit_cal.export 10 | output wire [7:0] phout, // phout.phout 11 | output wire [1:0] extclk_out, // extclk_out.extclk_out 12 | output wire [1:0] lvds_clk, // lvds_clk.lvds_clk 13 | output wire [1:0] loaden, // loaden.loaden 14 | output wire outclk_4, // outclk4.clk 15 | input wire adjpllin // adjpllin.clk 16 | ); 17 | 18 | esram_altera_iopll_1930_rnqonzq iopll ( 19 | .rst (rst), // input, width = 1, reset.reset 20 | .locked (locked), // output, width = 1, locked.export 21 | .permit_cal (permit_cal), // input, width = 1, permit_cal.export 22 | .phout (phout), // output, width = 8, phout.phout 23 | .extclk_out (extclk_out), // output, width = 2, extclk_out.extclk_out 24 | .lvds_clk (lvds_clk), // output, width = 2, lvds_clk.lvds_clk 25 | .loaden (loaden), // output, width = 2, loaden.loaden 26 | .outclk_4 (outclk_4), // output, width = 1, outclk4.clk 27 | .adjpllin (adjpllin) // input, width = 1, adjpllin.clk 28 | ); 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /hardware/esram/esram_1913/synth/stratix10_esram_sdc_parameters.tcl: -------------------------------------------------------------------------------- 1 | # eSRAM SDC Parameters 2 | 3 | #USER W A R N I N G ! 4 | #USER The parameters are statically defined in this 5 | #USER file at generation time! 6 | 7 | set var(vco_divider) 4 8 | set var(vco_div_internal) 4 9 | set var(ip_name) esram_esram_1913_a3ainji 10 | -------------------------------------------------------------------------------- /hardware/esram/esram_generation.rpt: -------------------------------------------------------------------------------- 1 | Info: Generated by version: 19.3 build 222 2 | Info: Starting: Create block symbol file (.bsf) 3 | Info: qsys-generate /home/zzhao1/project/gen_esram_19_3/esram.ip --block-symbol-file --output-directory=/home/zzhao1/project/gen_esram_19_3/esram --family="Stratix 10" --part=1SM21BHU2F53E2VGS1 4 | Info: esram.esram_0: Targeting device family: Stratix 10. 5 | Info: esram.esram_0.iopll: Able to implement PLL with user settings 6 | Info: qsys-generate succeeded. 7 | Info: Finished: Create block symbol file (.bsf) 8 | Info: 9 | Info: Starting: Create HDL design files for synthesis 10 | Info: qsys-generate /home/zzhao1/project/gen_esram_19_3/esram.ip --synthesis=VERILOG --output-directory=/home/zzhao1/project/gen_esram_19_3/esram --family="Stratix 10" --part=1SM21BHU2F53E2VGS1 11 | Info: esram.esram_0: Targeting device family: Stratix 10. 12 | Info: esram.esram_0.iopll: Able to implement PLL with user settings 13 | Info: esram_0.iopll: Able to implement PLL with user settings 14 | Info: esram: "Transforming system: esram" 15 | Info: esram: "Naming system components in system: esram" 16 | Info: esram: "Processing generation queue" 17 | Info: esram: "Generating: esram" 18 | Info: esram: "Generating: esram_esram_1913_a3ainji" 19 | Info: iopll: "Generating: iopll" 20 | Info: esram: "Generating: iopll" 21 | Info: esram: "Generating: esram_altera_iopll_1930_rnqonzq" 22 | Info: esram: Done "esram" with 4 modules, 10 files 23 | Info: qsys-generate succeeded. 24 | Info: Finished: Create HDL design files for synthesis 25 | Info: Starting: Generate IP Core Documentation 26 | Info: No documentation filesets were found for components in esram. No files generated. 27 | Info: Finished: Generate IP Core Documentation 28 | -------------------------------------------------------------------------------- /hardware/input_gen/generate_synthetic_trace.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import binascii 4 | import ipaddress 5 | import os 6 | import sys 7 | import warnings 8 | 9 | from itertools import cycle 10 | 11 | from scapy.all import IP, UDP, Ether, Raw, bytes_encode, PcapWriter, DLT_EN10MB 12 | 13 | 14 | # Bypassing scapy's awfully slow wrpcap, have to use raw packets as input 15 | # To get a raw packet from a scapy packet use `bytes_encode(pkt)`. 16 | def wrpcap(pcap_name, raw_packets): 17 | with PcapWriter(pcap_name, linktype=DLT_EN10MB) as pkt_wr: 18 | for raw_pkt in raw_packets: 19 | if not pkt_wr.header_present: 20 | pkt_wr._write_header(raw_pkt) 21 | pkt_wr._write_packet(raw_pkt) 22 | 23 | 24 | def generate_pcap(nb_pkts, out_pcap, pkt_size, nb_src, nb_dest, batch_size): 25 | sample_pkts = [] 26 | ipv4_len = pkt_size - 14 - 4 27 | for i in range(nb_dest): 28 | dst_ip = ipaddress.ip_address("192.168.0.0") + i 29 | src_offset = int(i / (nb_dest / nb_src)) 30 | src_ip = ipaddress.ip_address("192.168.0.0") + src_offset 31 | pkt = ( 32 | Ether() 33 | / IP(dst=str(dst_ip), src=str(src_ip), len=ipv4_len) 34 | / UDP(dport=80, sport=8080) 35 | ) 36 | 37 | missing_bytes = pkt_size - len(pkt) - 4 # no CRC 38 | payload = binascii.unhexlify("00" * missing_bytes) 39 | pkt = pkt / Raw(load=payload) 40 | pkt = bytes_encode(pkt) 41 | sample_pkts.append(pkt) 42 | 43 | def cycle_batches(): 44 | for pkt in cycle(sample_pkts): 45 | for _ in range(batch_size): 46 | yield pkt 47 | 48 | def pkt_gen(): 49 | for _, pkt in zip(range(nb_pkts), cycle_batches()): 50 | yield pkt 51 | 52 | wrpcap(out_pcap, pkt_gen()) 53 | 54 | 55 | def main(): 56 | if (len(sys.argv) < 6) or (len(sys.argv) > 7): 57 | print( 58 | "Usage:", 59 | sys.argv[0], 60 | "nb_pkts pkt_size nb_src nb_dest output_pcap [batch_size]", 61 | ) 62 | sys.exit(1) 63 | 64 | nb_pkts = int(sys.argv[1]) 65 | pkt_size = int(sys.argv[2]) 66 | nb_src = int(sys.argv[3]) 67 | nb_dest = int(sys.argv[4]) 68 | out_pcap = sys.argv[5] 69 | if len(sys.argv) > 6: 70 | batch_size = int(sys.argv[6]) 71 | else: 72 | batch_size = 1 73 | 74 | if os.path.exists(out_pcap): 75 | warnings.warn("Pcap with the same name already exists. Skipping.") 76 | sys.exit(0) 77 | 78 | generate_pcap(nb_pkts, out_pcap, pkt_size, nb_src, nb_dest, batch_size) 79 | 80 | 81 | if __name__ == "__main__": 82 | main() 83 | -------------------------------------------------------------------------------- /hardware/input_gen/meson.build: -------------------------------------------------------------------------------- 1 | pcap_dep = dependency('pcap', version : '>=1.0') 2 | 3 | executable('generate_synthetic_trace', 'generate_synthetic_trace.cpp', 4 | dependencies: [pcap_dep]) 5 | -------------------------------------------------------------------------------- /hardware/input_gen/parse_output_100.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import sys 3 | 4 | 5 | def parse_line(line): 6 | empty = 0 7 | temp = line.replace(" ", "") 8 | temp = temp.split(":")[1] 9 | length = len(temp) 10 | if length - 1 == 32: 11 | res = temp[:-1] 12 | else: 13 | empty = (32 - (length - 1)) // 2 14 | res = temp[:-1] + (empty * 2) * "f" 15 | 16 | return res, empty 17 | 18 | 19 | fname = sys.argv[1] 20 | outname = sys.argv[2] 21 | sop = 0 22 | eop = 1 23 | empty_p = 0 24 | empty_c = 0 25 | data_p = [None] * 4 26 | data_c = 0 27 | data_field = 0 28 | 29 | 30 | f = open(fname) 31 | fout = open(outname, "w") 32 | p = 0 33 | c = 0 34 | cnt = 0 35 | for i, line in enumerate(f): 36 | if "0x" in line and ">" not in line: 37 | c = 1 38 | data_c, empty_c = parse_line(line) 39 | else: 40 | c = 0 41 | 42 | if "0x0000:" in line: 43 | sop = 1 44 | 45 | if p == 1 and c == 1: 46 | eop = 0 47 | 48 | if cnt == 4: 49 | data_p_str = "" 50 | for i in data_p: 51 | assert i is not None 52 | data_p_str += i 53 | 54 | fout.write( 55 | str(sop) 56 | + str(eop) 57 | + str(format(empty_p, "x")).zfill(2) 58 | + data_p_str 59 | + "\n" 60 | ) 61 | cnt = 0 62 | sop = 0 63 | elif p == 1 and c == 0: 64 | eop = 1 65 | empty_p = empty_p + (4 - cnt) * 16 66 | for j in range(0, cnt): 67 | d = data_p[j] 68 | assert d is not None 69 | if j == 0: 70 | data_field = d 71 | else: 72 | data_field = data_field + d 73 | data_field = data_field + ((4 - cnt) * 16 * 2) * "f" 74 | fout.write( 75 | str(sop) 76 | + str(eop) 77 | + str(format(empty_p, "x")).zfill(2) 78 | + data_field 79 | + "\n" 80 | ) 81 | sop = 0 82 | cnt = 0 83 | else: 84 | eop = 0 85 | p = c 86 | 87 | if c: 88 | data_p[cnt] = data_c 89 | cnt += 1 90 | empty_p = empty_c 91 | 92 | f.close() 93 | fout.close() 94 | -------------------------------------------------------------------------------- /hardware/input_gen/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #print the raw bytes from pcap, first 10 pkts 3 | #tcpdump -r $1 -c 4096 -xxn > raw_bytes.txt 4 | # tcpdump -r $1 -c 100 -xxn > raw_bytes.txt 5 | tcpdump -r $1 -xxn > raw_bytes.txt 6 | 7 | #add an empty line at the end of the raw_bytes such that 8 | #python script would not miss the last pkt 9 | echo >> raw_bytes.txt 10 | 11 | OUTPUT_FILE=${2:-"output.pkt"} 12 | 13 | #convert the raw_bytes to verilog ROM content 14 | python3 parse_output_100.py raw_bytes.txt $OUTPUT_FILE 15 | 16 | #run Modelsim 17 | #./run_vsim.sh 18 | -------------------------------------------------------------------------------- /hardware/ip/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !*.tcl 4 | !*.template 5 | -------------------------------------------------------------------------------- /hardware/ip/alt_ehipc2_jtag_avalon.tcl: -------------------------------------------------------------------------------- 1 | package require -exact qsys 18.0 2 | 3 | # create the system "alt_ehipc2_jtag_avalon" 4 | proc do_create_alt_ehipc2_jtag_avalon {} { 5 | # create the system 6 | create_system alt_ehipc2_jtag_avalon 7 | set_project_property DEVICE {1SM21BHU2F53E1VG} 8 | set_project_property DEVICE_FAMILY {Stratix 10} 9 | set_project_property HIDE_FROM_IP_CATALOG {false} 10 | set_use_testbench_naming_pattern 0 {} 11 | 12 | # add the components 13 | add_instance altera_jtag_avalon_master_0 altera_jtag_avalon_master 19.1 14 | set_instance_parameter_value altera_jtag_avalon_master_0 {FAST_VER} {0} 15 | set_instance_parameter_value altera_jtag_avalon_master_0 {FIFO_DEPTHS} {2} 16 | set_instance_parameter_value altera_jtag_avalon_master_0 {PLI_PORT} {50000} 17 | set_instance_parameter_value altera_jtag_avalon_master_0 {USE_PLI} {0} 18 | set_instance_property altera_jtag_avalon_master_0 AUTO_EXPORT true 19 | 20 | # add wirelevel expressions 21 | 22 | # add the exports 23 | set_interface_property clk EXPORT_OF altera_jtag_avalon_master_0.clk 24 | set_interface_property clk_reset EXPORT_OF altera_jtag_avalon_master_0.clk_reset 25 | set_interface_property master_reset EXPORT_OF altera_jtag_avalon_master_0.master_reset 26 | set_interface_property master EXPORT_OF altera_jtag_avalon_master_0.master 27 | 28 | # set the the module properties 29 | set_module_property BONUS_DATA { 30 | 31 | 32 | 33 | 34 | 35 | } 36 | set_module_property FILE {alt_ehipc2_jtag_avalon.ip} 37 | set_module_property GENERATION_ID {0x00000000} 38 | set_module_property NAME {alt_ehipc2_jtag_avalon} 39 | 40 | # save the system 41 | sync_sysinfo_parameters 42 | save_system alt_ehipc2_jtag_avalon 43 | } 44 | 45 | # create all the systems, from bottom up 46 | do_create_alt_ehipc2_jtag_avalon 47 | -------------------------------------------------------------------------------- /hardware/ip/pcie_generic_component_0.v.template: -------------------------------------------------------------------------------- 1 | // generic_component_0.v 2 | 3 | // This file must be copied to the generated PCIe Core IP at: 4 | // pcie_ed/generic_component_0/synth/generic_component_0.v 5 | // 6 | // This is done automatically by the `synthesize.sh` script and the 7 | // `generate_ips.sh` script. 8 | 9 | `timescale 1 ps / 1 ps 10 | module generic_component_0 ( 11 | input wire coreclkin_hip, 12 | input wire app_nreset_status, 13 | output wire coreclkout_hip, 14 | output wire app_nreset_status_1 15 | ); 16 | 17 | assign coreclkout_hip = coreclkin_hip; 18 | assign app_nreset_status_1 = app_nreset_status; 19 | 20 | endmodule 21 | -------------------------------------------------------------------------------- /hardware/ip/probe8.tcl: -------------------------------------------------------------------------------- 1 | package require -exact qsys 18.0 2 | 3 | # create the system "probe8" 4 | proc do_create_probe8 {} { 5 | # create the system 6 | create_system probe8 7 | set_project_property DEVICE {1SM21BHU2F53E1VG} 8 | set_project_property DEVICE_FAMILY {Stratix 10} 9 | set_project_property HIDE_FROM_IP_CATALOG {false} 10 | set_use_testbench_naming_pattern 0 {} 11 | 12 | # add the components 13 | add_instance altera_in_system_sources_probes_0 altera_in_system_sources_probes 19.1 14 | set_instance_parameter_value altera_in_system_sources_probes_0 {create_source_clock} {0} 15 | set_instance_parameter_value altera_in_system_sources_probes_0 {create_source_clock_enable} {0} 16 | set_instance_parameter_value altera_in_system_sources_probes_0 {gui_use_auto_index} {1} 17 | set_instance_parameter_value altera_in_system_sources_probes_0 {instance_id} {NONE} 18 | set_instance_parameter_value altera_in_system_sources_probes_0 {probe_width} {8} 19 | set_instance_parameter_value altera_in_system_sources_probes_0 {sld_instance_index} {0} 20 | set_instance_parameter_value altera_in_system_sources_probes_0 {source_initial_value} {0} 21 | set_instance_parameter_value altera_in_system_sources_probes_0 {source_width} {1} 22 | set_instance_property altera_in_system_sources_probes_0 AUTO_EXPORT true 23 | 24 | # add wirelevel expressions 25 | 26 | # add the exports 27 | set_interface_property sources EXPORT_OF altera_in_system_sources_probes_0.sources 28 | set_interface_property probes EXPORT_OF altera_in_system_sources_probes_0.probes 29 | 30 | # set the the module properties 31 | set_module_property BONUS_DATA { 32 | 33 | 34 | 35 | 36 | 37 | } 38 | set_module_property FILE {probe8.ip} 39 | set_module_property GENERATION_ID {0x00000000} 40 | set_module_property NAME {probe8} 41 | 42 | # save the system 43 | sync_sysinfo_parameters 44 | save_system probe8 45 | } 46 | 47 | # create all the systems, from bottom up 48 | do_create_probe8 49 | -------------------------------------------------------------------------------- /hardware/ip/reset_ip.tcl: -------------------------------------------------------------------------------- 1 | package require -exact qsys 18.0 2 | 3 | # create the system "reset_ip" 4 | proc do_create_reset_ip {} { 5 | # create the system 6 | create_system reset_ip 7 | set_project_property DEVICE {1SM21BHU2F53E1VG} 8 | set_project_property DEVICE_FAMILY {Stratix 10} 9 | set_project_property HIDE_FROM_IP_CATALOG {false} 10 | set_use_testbench_naming_pattern 0 {} 11 | 12 | # add the components 13 | add_instance altera_s10_user_rst_clkgate_0 altera_s10_user_rst_clkgate 19.1.0 14 | set_instance_property altera_s10_user_rst_clkgate_0 AUTO_EXPORT true 15 | 16 | # add wirelevel expressions 17 | 18 | # add the exports 19 | set_interface_property ninit_done EXPORT_OF altera_s10_user_rst_clkgate_0.ninit_done 20 | 21 | # set the the module properties 22 | set_module_property BONUS_DATA { 23 | 24 | 25 | 26 | 27 | 28 | } 29 | set_module_property FILE {reset_ip.ip} 30 | set_module_property GENERATION_ID {0x00000000} 31 | set_module_property NAME {reset_ip} 32 | 33 | # save the system 34 | sync_sysinfo_parameters 35 | save_system reset_ip 36 | } 37 | 38 | # create all the systems, from bottom up 39 | do_create_reset_ip 40 | -------------------------------------------------------------------------------- /hardware/meson.build: -------------------------------------------------------------------------------- 1 | subdir('input_gen') 2 | -------------------------------------------------------------------------------- /hardware/quartus/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !*.qpf 4 | !*.qsf 5 | !*.sdc 6 | -------------------------------------------------------------------------------- /hardware/quartus/enso.qpf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2019 Intel Corporation. All rights reserved. 3 | # Your use of Intel Corporation's design tools, logic functions 4 | # and other software and tools, and any partner logic 5 | # functions, and any output files from any of the foregoing 6 | # (including device programming or simulation files), and any 7 | # associated documentation or information are expressly subject 8 | # to the terms and conditions of the Intel Program License 9 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 10 | # the Intel FPGA IP License Agreement, or other applicable license 11 | # agreement, including, without limitation, that your use is for 12 | # the sole purpose of programming logic devices manufactured by 13 | # Intel and sold by Intel or its authorized distributors. Please 14 | # refer to the applicable agreement for further details, at 15 | # https://fpgasoftware.intel.com/eula. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus Prime 20 | # Version 19.3.0 Build 222 09/23/2019 SC Pro Edition 21 | # Date created = 11:15:53 March 05, 2020 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "19.3" 26 | DATE = "11:15:53 March 05, 2020" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "enso" 31 | -------------------------------------------------------------------------------- /hardware/run_tb.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Usage ./run_tb.sh rate nb_pkts pkt_size nb_dsc_queues nb_pkt_queues 3 | # Optionally append --gui to the command to run graphical interface. 4 | 5 | # exit when error occurs 6 | set -e 7 | trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG 8 | trap 'echo "\"${last_command}\" command exited with code $?."' EXIT 9 | 10 | sim_lib_path="$HOME/sim_lib/verilog_libs" 11 | altera_ver="$sim_lib_path/altera_ver" 12 | lpm_ver="$sim_lib_path/lpm_ver" 13 | sgate_ver="$sim_lib_path/sgate_ver" 14 | altera_mf_ver="$sim_lib_path/altera_mf_ver" 15 | altera_lnsim_ver="$sim_lib_path/altera_lnsim_ver" 16 | fourteennm_ver="$sim_lib_path/fourteennm_ver" 17 | fourteennm_ct1_ver="$sim_lib_path/fourteennm_ct1_ver" 18 | 19 | USAGE="Usage: $0 rate nb_pkts pkt_size nb_dsc_queues nb_pkt_queues [--gui]" 20 | 21 | if [ "$#" -lt 5 ] || [ "$#" -gt 6 ]; then 22 | echo $USAGE 23 | exit 1 24 | fi 25 | 26 | if [ "$#" -eq 6 ] && [ "$6" != "--gui" ]; then 27 | echo $USAGE 28 | exit 1 29 | fi 30 | 31 | RATE=${1:-"100"} 32 | 33 | NB_PKTS=$2 34 | PKT_SIZE=$3 35 | NB_DSC_QS=$4 36 | NB_PKT_QS=$5 37 | PKT_FILE_BASE_NAME="${NB_PKTS}_${PKT_SIZE}_${NB_DSC_QS}_${NB_PKT_QS}" 38 | PKT_FILE="./input_gen/${PKT_FILE_BASE_NAME}.pkt" 39 | if [[ -f "$PKT_FILE" ]]; then 40 | echo "$PKT_FILE exists, using cache" 41 | else 42 | echo "Generating $PKT_FILE" 43 | cd "./input_gen" 44 | ./generate_synthetic_trace.py ${NB_PKTS} ${PKT_SIZE} ${NB_DSC_QS} \ 45 | ${NB_PKT_QS} "${PKT_FILE_BASE_NAME}.pcap" 46 | ./run.sh "${PKT_FILE_BASE_NAME}.pcap" "${PKT_FILE_BASE_NAME}.pkt" 47 | cd - 48 | fi 49 | 50 | echo "Using $NB_DSC_QS descriptor queues and $NB_PKT_QS packet queues." 51 | 52 | pwd 53 | PKT_FILE_NB_LINES=$(wc -l < $PKT_FILE) 54 | 55 | rm -rf work 56 | rm -f vsim.wlf 57 | 58 | shopt -s globstar # make sure we match all subdirs 59 | 60 | vlib work 61 | vlog +define+SIM ./src/**/*.sv -sv 62 | vlog +define+SIM ./src/**/*.v 63 | vlog +define+SIM \ 64 | +define+RATE=$RATE \ 65 | +define+PKT_FILE=\"$PKT_FILE\" \ 66 | +define+PKT_FILE_NB_LINES=$PKT_FILE_NB_LINES \ 67 | +define+NB_DSC_QUEUES=$NB_DSC_QS \ 68 | +define+NB_PKT_QUEUES=$NB_PKT_QS \ 69 | +define+PKT_SIZE=$PKT_SIZE \ 70 | ./tests/tb.sv -sv 71 | 72 | if [ "$6" = "--gui" ]; then 73 | # Use the following to activate the modelsim GUI. 74 | vsim -L $altera_mf_ver -L $altera_lnsim_ver -L $altera_ver -L $lpm_ver \ 75 | -L $sgate_ver -L $fourteennm_ver -L $fourteennm_ct1_ver \ 76 | -voptargs="+acc" tb 77 | else 78 | vsim -L $altera_mf_ver -L $altera_lnsim_ver -L $altera_ver -L $lpm_ver \ 79 | -L $sgate_ver -L $fourteennm_ver -L $fourteennm_ct1_ver \ 80 | -voptargs="+acc" -c -do "run -all" tb | grep --color -e 'Error' -e '^' 81 | fi 82 | -------------------------------------------------------------------------------- /hardware/run_tb_batch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Run testbench generating packets in a way that we send packets to the same 3 | # queue `batch_size` at a time. 4 | # Usage: ./run_tb_batch.sh rate nb_pkts pkt_size nb_dsc_queues nb_pkt_queues \ 5 | # batch_size 6 | # Optionally append --gui to the command to run graphical interface. 7 | 8 | # exit when error occurs 9 | set -e 10 | trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG 11 | trap 'echo "\"${last_command}\" command exited with code $?."' EXIT 12 | 13 | sim_lib_path="$HOME/sim_lib/verilog_libs" 14 | altera_ver="$sim_lib_path/altera_ver" 15 | lpm_ver="$sim_lib_path/lpm_ver" 16 | sgate_ver="$sim_lib_path/sgate_ver" 17 | altera_mf_ver="$sim_lib_path/altera_mf_ver" 18 | altera_lnsim_ver="$sim_lib_path/altera_lnsim_ver" 19 | fourteennm_ver="$sim_lib_path/fourteennm_ver" 20 | fourteennm_ct1_ver="$sim_lib_path/fourteennm_ct1_ver" 21 | 22 | RATE=${1:-"100"} 23 | 24 | NB_PKTS=$2 25 | PKT_SIZE=$3 26 | NB_DSC_QS=$4 27 | NB_PKT_QS=$5 28 | BATCH_SIZE=${6:-"64"} 29 | PKT_FILE_BASE_NAME="batch_${NB_PKTS}_${PKT_SIZE}_${NB_DSC_QS}_${NB_PKT_QS}_${BATCH_SIZE}" 30 | PKT_FILE="./input_gen/${PKT_FILE_BASE_NAME}.pkt" 31 | if [[ -f "$PKT_FILE" ]]; then 32 | echo "$PKT_FILE exists, using cache" 33 | else 34 | echo "Generating $PKT_FILE" 35 | cd "./input_gen" 36 | ./generate_synthetic_trace.py ${NB_PKTS} ${PKT_SIZE} ${NB_DSC_QS} \ 37 | ${NB_PKT_QS} "${PKT_FILE_BASE_NAME}.pcap" ${BATCH_SIZE} 38 | ./run.sh "${PKT_FILE_BASE_NAME}.pcap" "${PKT_FILE_BASE_NAME}.pkt" 39 | cd - 40 | fi 41 | 42 | echo "Using $NB_DSC_QS descriptor queues and $NB_PKT_QS packet queues." 43 | 44 | pwd 45 | PKT_FILE_NB_LINES=$(wc -l < $PKT_FILE) 46 | 47 | rm -rf work 48 | rm -f vsim.wlf 49 | 50 | shopt -s globstar # make sure we match all subdirs 51 | 52 | vlib work 53 | vlog +define+SIM ./src/**/*.sv -sv 54 | vlog +define+SIM ./src/**/*.v 55 | vlog +define+SIM \ 56 | +define+RATE=$RATE \ 57 | +define+PKT_FILE=\"$PKT_FILE\" \ 58 | +define+PKT_FILE_NB_LINES=$PKT_FILE_NB_LINES \ 59 | +define+NB_DSC_QUEUES=$NB_DSC_QS \ 60 | +define+NB_PKT_QUEUES=$NB_PKT_QS \ 61 | +define+PKT_SIZE=$PKT_SIZE \ 62 | ./tests/tb.sv -sv 63 | 64 | if [ "$7" = "--gui" ]; then 65 | # Use the following to activate the modelsim GUI. 66 | vsim -L $altera_mf_ver -L $altera_lnsim_ver -L $altera_ver -L $lpm_ver \ 67 | -L $sgate_ver -L $fourteennm_ver -L $fourteennm_ct1_ver \ 68 | -voptargs="+acc" tb 69 | else 70 | vsim -L $altera_mf_ver -L $altera_lnsim_ver -L $altera_ver -L $lpm_ver \ 71 | -L $sgate_ver -L $fourteennm_ver -L $fourteennm_ct1_ver \ 72 | -voptargs="+acc" -c -do "run -all" tb | grep --color -e 'Error' -e '^' 73 | fi 74 | -------------------------------------------------------------------------------- /hardware/run_tb_pcap.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Usage ./run_tb_pcap.sh rate pcap nb_fb_queues nb_dsc_queues nb_pkt_queues 3 | # Optionally append --gui to the command to run graphical interface. 4 | 5 | # exit when error occurs 6 | set -e 7 | trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG 8 | trap 'echo "\"${last_command}\" command exited with code $?."' EXIT 9 | 10 | sim_lib_path="$HOME/sim_lib/verilog_libs" 11 | altera_ver="$sim_lib_path/altera_ver" 12 | lpm_ver="$sim_lib_path/lpm_ver" 13 | sgate_ver="$sim_lib_path/sgate_ver" 14 | altera_mf_ver="$sim_lib_path/altera_mf_ver" 15 | altera_lnsim_ver="$sim_lib_path/altera_lnsim_ver" 16 | fourteennm_ver="$sim_lib_path/fourteennm_ver" 17 | fourteennm_ct1_ver="$sim_lib_path/fourteennm_ct1_ver" 18 | 19 | RATE=$1 20 | PCAP_FILE=$2 21 | NB_FALLBACK_QS=$3 22 | NB_DSC_QS=$4 23 | NB_PKT_QS=$5 24 | 25 | PCAP_FILE=$(readlink -f $PCAP_FILE) 26 | PKT_FILE_BASE_NAME=$(basename $PCAP_FILE) 27 | PKT_FILE="./input_gen/${PKT_FILE_BASE_NAME}.pkt" 28 | if [[ -f "$PKT_FILE" ]]; then 29 | echo "$PKT_FILE exists, using cache" 30 | else 31 | echo "Generating $PKT_FILE" 32 | cd "./input_gen" 33 | ./run.sh ${PCAP_FILE} "${PKT_FILE_BASE_NAME}.pkt" 34 | cd - 35 | fi 36 | 37 | echo "Using:" 38 | echo "$NB_FALLBACK_QS fallback queues" 39 | echo "$NB_DSC_QS dsc queues" 40 | echo "$NB_PKT_QS pkt queues" 41 | 42 | pwd 43 | PKT_FILE_NB_LINES=$(wc -l < $PKT_FILE) 44 | 45 | rm -rf work 46 | rm -f vsim.wlf 47 | 48 | shopt -s globstar # make sure we match all subdirs 49 | 50 | vlib work 51 | vlog +define+SIM ./src/**/*.sv -sv 52 | vlog +define+SIM ./src/**/*.v 53 | vlog +define+SIM \ 54 | +define+RATE=$RATE \ 55 | +define+PKT_FILE=\"$PKT_FILE\" \ 56 | +define+PKT_FILE_NB_LINES=$PKT_FILE_NB_LINES \ 57 | +define+NB_FALLBACK_QUEUES=$NB_FALLBACK_QS \ 58 | +define+NB_DSC_QUEUES=$NB_DSC_QS \ 59 | +define+NB_PKT_QUEUES=$NB_PKT_QS \ 60 | ./tests/tb.sv -sv 61 | 62 | VSIM_CMD="run -all" 63 | # VSIM_CMD="set BreakOnAssertion 2; run -all" 64 | 65 | if [ "$6" = "--gui" ]; then 66 | # Use the following to activate the modelsim GUI. 67 | vsim -L $altera_mf_ver -L $altera_lnsim_ver -L $altera_ver -L $lpm_ver \ 68 | -L $sgate_ver -L $fourteennm_ver -L $fourteennm_ct1_ver \ 69 | -voptargs="+acc" tb 70 | else 71 | vsim -L $altera_mf_ver -L $altera_lnsim_ver -L $altera_ver -L $lpm_ver \ 72 | -L $sgate_ver -L $fourteennm_ver -L $fourteennm_ct1_ver \ 73 | -voptargs="+acc" -c -do "$VSIM_CMD" tb | grep --color -e 'Error' -e '^' 74 | fi 75 | -------------------------------------------------------------------------------- /hardware/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Usage ./run_tests.sh 3 | 4 | # exit when error occurs 5 | set -e 6 | trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG 7 | trap 'echo "\"${last_command}\" command exited with code $?."' EXIT 8 | 9 | declare -a tests=( 10 | # 'test_pcie_top' 11 | # 'test_cpu_to_fpga' 12 | # 'test_queue_manager' 13 | # 'test_prefetch_rb' 14 | 'test_timestamp' 15 | # 'test_rate_limiter' 16 | # 'sketch' 17 | ) 18 | 19 | sim_lib_path="$HOME/sim_lib/verilog_libs" 20 | altera_ver="$sim_lib_path/altera_ver" 21 | lpm_ver="$sim_lib_path/lpm_ver" 22 | sgate_ver="$sim_lib_path/sgate_ver" 23 | altera_mf_ver="$sim_lib_path/altera_mf_ver" 24 | altera_lnsim_ver="$sim_lib_path/altera_lnsim_ver" 25 | fourteennm_ver="$sim_lib_path/fourteennm_ver" 26 | fourteennm_ct1_ver="$sim_lib_path/fourteennm_ct1_ver" 27 | 28 | RED='\033[0;31m' 29 | GREEN='\033[0;32m' 30 | NC='\033[0m' # No Color 31 | 32 | rm -rf work 33 | rm -f vsim.wlf 34 | 35 | shopt -s globstar # make sure we match all subdirs 36 | 37 | vlib work 38 | vlog ./src/**/*.sv -sv 39 | for t in ${tests[@]}; do 40 | echo "Compiling $t" 41 | vlog "./tests/$t.sv" -sv -lint -source | grep --color -e 'Error' -e '^' 42 | done 43 | vlog ./src/common/*.v 44 | 45 | # avoid trap 46 | output_if_error() { 47 | if grep -q -e "Errors: [^0]" out.txt; then 48 | grep --color -e 'Error' -e '^' out.txt 49 | printf "${RED}$1 failed!${NC}\n" 50 | return 1 51 | fi 52 | return 0 53 | } 54 | 55 | touch out.txt 56 | for t in ${tests[@]}; do 57 | echo "Running test: $t" 58 | if [ "$1" = "--gui" ]; then 59 | # Use the following to activate the modelsim GUI. 60 | vsim -L $altera_mf_ver -L $altera_lnsim_ver -L $altera_ver -L $lpm_ver \ 61 | -L $sgate_ver -L $fourteennm_ver -L $fourteennm_ct1_ver \ 62 | -voptargs="+acc" $t 63 | else 64 | vsim -L $altera_mf_ver -L $altera_lnsim_ver -L $altera_ver -L $lpm_ver \ 65 | -L $sgate_ver -L $fourteennm_ver -L $fourteennm_ct1_ver \ 66 | -voptargs="+acc" -c -do "run -all" $t #> out.txt 67 | fi 68 | #output_if_error $t 69 | done 70 | 71 | printf "${GREEN}All tests passed${NC}\n" 72 | -------------------------------------------------------------------------------- /hardware/src/common/alt_aeuex_user_mode_det.v: -------------------------------------------------------------------------------- 1 | // (C) 2001-2019 Intel Corporation. All rights reserved. 2 | // Your use of Intel Corporation's design tools, logic functions and other 3 | // software and tools, and its AMPP partner logic functions, and any output 4 | // files from any of the foregoing (including device programming or simulation 5 | // files), and any associated documentation or information are expressly subject 6 | // to the terms and conditions of the Intel Program License Subscription 7 | // Agreement, Intel FPGA IP License Agreement, or other applicable 8 | // license agreement, including, without limitation, that your use is for the 9 | // sole purpose of programming logic devices manufactured by Intel and sold by 10 | // Intel or its authorized distributors. Please refer to the applicable 11 | // agreement for further details. 12 | 13 | 14 | `timescale 1 ps / 1 ps 15 | 16 | module alt_aeuex_user_mode_det ( 17 | input ref_clk, 18 | output user_mode_sync); 19 | 20 | reg user_mode = 1'b0 /* synthesis preserve_syn_only */; 21 | 22 | always @(posedge ref_clk) 23 | begin 24 | user_mode <= 1'b1; 25 | end 26 | 27 | reg [7:0] user_mode_counter = 8'h00 /* synthesis preserve_syn_only */; 28 | always @(posedge ref_clk) 29 | begin 30 | if (user_mode && ! user_mode_counter[7]) 31 | user_mode_counter <= user_mode_counter + 1'b1; 32 | end 33 | assign user_mode_sync = user_mode_counter[7]; 34 | 35 | endmodule 36 | -------------------------------------------------------------------------------- /hardware/src/common/altera_dcfifo_synchronizer_bundle.v: -------------------------------------------------------------------------------- 1 | // $File: //acds/rel/18.1/ip/sopc/components/altera_avalon_dc_fifo/altera_dcfifo_synchronizer_bundle.v $ 2 | // $Revision: #1 $ 3 | // $Date: 2018/07/29 $ 4 | // $Author: psgswbuild $ 5 | //------------------------------------------------------------------------------- 6 | 7 | `timescale 1 ns / 1 ns 8 | module altera_dcfifo_synchronizer_bundle( 9 | clk, 10 | reset_n, 11 | din, 12 | dout 13 | ); 14 | parameter WIDTH = 1; 15 | parameter DEPTH = 3; 16 | 17 | input clk; 18 | input reset_n; 19 | input [WIDTH-1:0] din; 20 | output [WIDTH-1:0] dout; 21 | 22 | genvar i; 23 | 24 | generate 25 | for (i=0; i 100 could cause errors 17 | localparam MAX_PIPE_CAPPED = 18 | (MAX_PIPE > 100) ? 100 : ((MAX_PIPE < 0) ? 0 : MAX_PIPE); 19 | 20 | // Converting MAX_PIPE_CAPPED to string so it can be used as a string when setting altera_attribute 21 | localparam MAX_PIPE_STR = { 22 | ((MAX_PIPE_CAPPED / 100) % 10) + 8'd48, 23 | ((MAX_PIPE_CAPPED / 10) % 10) + 8'd48, 24 | (MAX_PIPE_CAPPED % 10) + 8'd48 25 | }; 26 | 27 | (* altera_attribute = { 28 | "-name ADV_NETLIST_OPT_ALLOWED NEVER_ALLOW; -name HYPER_RETIMER_ADD_PIPELINING ", 29 | MAX_PIPE_STR 30 | } *) 31 | reg [WIDTH-1:0] vlat_r /* synthesis preserve */; 32 | 33 | always @ (posedge clk) begin 34 | vlat_r <= din; 35 | end 36 | 37 | assign dout = vlat_r; 38 | 39 | endmodule 40 | -------------------------------------------------------------------------------- /hardware/src/common/mlab_ram.v: -------------------------------------------------------------------------------- 1 | // (C) 2001-2018 Intel Corporation. All rights reserved. 2 | // Your use of Intel Corporation's design tools, logic functions and other 3 | // software and tools, and its AMPP partner logic functions, and any output 4 | // files from any of the foregoing (including device programming or simulation 5 | // files), and any associated documentation or information are expressly subject 6 | // to the terms and conditions of the Intel Program License Subscription 7 | // Agreement, Intel FPGA IP License Agreement, or other applicable 8 | // license agreement, including, without limitation, that your use is for the 9 | // sole purpose of programming logic devices manufactured by Intel and sold by 10 | // Intel or its authorized distributors. Please refer to the applicable 11 | // agreement for further details. 12 | 13 | 14 | 15 | // synopsys translate_off 16 | `timescale 1 ps / 1 ps 17 | // synopsys translate_on 18 | module mlab_ram ( 19 | clock, 20 | data, 21 | rdaddress, 22 | wraddress, 23 | wren, 24 | q); 25 | parameter AWIDTH = 3; 26 | parameter DWIDTH = 16; 27 | input clock; 28 | input [DWIDTH-1:0] data; 29 | input [AWIDTH-1:0] rdaddress; 30 | input [AWIDTH-1:0] wraddress; 31 | input wren; 32 | output [DWIDTH-1:0] q; 33 | `ifndef ALTERA_RESERVED_QIS 34 | // synopsys translate_off 35 | `endif 36 | `ifndef ALTERA_RESERVED_QIS 37 | // synopsys translate_on 38 | `endif 39 | 40 | wire [DWIDTH-1:0] sub_wire0; 41 | wire [DWIDTH-1:0] q = sub_wire0[DWIDTH-1:0]; 42 | 43 | altdpram altdpram_component ( 44 | .data (data), 45 | .inclock (clock), 46 | .outclock (clock), 47 | .rdaddress (rdaddress), 48 | .wraddress (wraddress), 49 | .wren (wren), 50 | .q (sub_wire0), 51 | .aclr (1'b0), 52 | .sclr (1'b0), 53 | .byteena (1'b1), 54 | .inclocken (1'b1), 55 | .outclocken (1'b1), 56 | .rdaddressstall (1'b0), 57 | .rden (1'b1), 58 | .wraddressstall (1'b0)); 59 | defparam 60 | altdpram_component.indata_aclr = "OFF", 61 | altdpram_component.indata_reg = "INCLOCK", 62 | altdpram_component.intended_device_family = "Stratix 10", 63 | altdpram_component.lpm_type = "altdpram", 64 | altdpram_component.ram_block_type = "MLAB", 65 | altdpram_component.outdata_aclr = "OFF", 66 | altdpram_component.outdata_sclr = "OFF", 67 | altdpram_component.outdata_reg = "INCLOCK", 68 | altdpram_component.rdaddress_aclr = "OFF", 69 | altdpram_component.rdaddress_reg = "UNREGISTERED", 70 | altdpram_component.rdcontrol_aclr = "OFF", 71 | altdpram_component.rdcontrol_reg = "UNREGISTERED", 72 | altdpram_component.read_during_write_mode_mixed_ports = "DONT_CARE", 73 | altdpram_component.width = DWIDTH, 74 | altdpram_component.widthad = AWIDTH, 75 | altdpram_component.width_byteena = 1, 76 | altdpram_component.wraddress_aclr = "OFF", 77 | altdpram_component.wraddress_reg = "INCLOCK", 78 | altdpram_component.wrcontrol_aclr = "OFF", 79 | altdpram_component.wrcontrol_reg = "INCLOCK"; 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | endmodule 88 | -------------------------------------------------------------------------------- /hardware/src/common/prim_assert_dummy_macros.sv: -------------------------------------------------------------------------------- 1 | // Copyright lowRISC contributors. 2 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. 3 | // SPDX-License-Identifier: Apache-2.0 4 | // From: https://github.com/lowRISC/opentitan/blob/dfa60e3e8edfa7c6a1f362d2168a40377d794154/hw/ip/prim/rtl/prim_assert_dummy_macros.svh 5 | 6 | /// Macro bodies included by `prim_assert.sv` for tools that don't support 7 | //// assertions. See `prim_assert.sv` for documentation for each of the macros. 8 | 9 | `define ASSERT_I(__name, __prop) 10 | `define ASSERT_INIT(__name, __prop) 11 | `define ASSERT_INIT_NET(__name, __prop) 12 | `define ASSERT_FINAL(__name, __prop) 13 | `define ASSERT(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) 14 | `define ASSERT_NEVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) 15 | `define ASSERT_KNOWN(__name, __sig, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) 16 | `define COVER(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) 17 | `define ASSUME(__name, __prop, __clk = `ASSERT_DEFAULT_CLK, __rst = `ASSERT_DEFAULT_RST) 18 | `define ASSUME_I(__name, __prop) 19 | -------------------------------------------------------------------------------- /hardware/src/common/prim_assert_sec_cm.sv: -------------------------------------------------------------------------------- 1 | // Copyright lowRISC contributors. 2 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. 3 | // SPDX-License-Identifier: Apache-2.0 4 | // From: https://github.com/lowRISC/opentitan/blob/master/hw/ip/prim/rtl/prim_assert_sec_cm.svh 5 | 6 | /// Macros and helper code for security countermeasures. 7 | 8 | `ifndef PRIM_ASSERT_SEC_CM_SVH 9 | `define PRIM_ASSERT_SEC_CM_SVH 10 | 11 | // Helper macros. 12 | `define ASSERT_ERROR_TRIGGER_ALERT \ 13 | (NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_, ERR_NAME_) \ 14 | `ASSERT(FpvSecCm``NAME_``, $rose(PRIM_HIER_.ERR_NAME_) \ 15 | |-> ##[0:MAX_CYCLES_] (ALERT_.alert_p)) \ 16 | `ifdef INC_ASSERT \ 17 | assign PRIM_HIER_.unused_assert_connected = 1'b1; \ 18 | `endif \ 19 | `ASSUME_FPV(``NAME_``TriggerAfterAlertInit_S, $stable(rst_ni) == 0 |-> \ 20 | PRIM_HIER_.ERR_NAME_ == 0 [*10]) 21 | 22 | // Macros for security countermeasures. 23 | `define ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT \ 24 | (NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_ = 7) \ 25 | `ASSERT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_, err_o) 26 | 27 | `define ASSERT_PRIM_DOUBLE_LFSR_ERROR_TRIGGER_ALERT \ 28 | (NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_ = 7) \ 29 | `ASSERT_ERROR_TRIGGER_ALERT(NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_, err_o) 30 | 31 | `define ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT \ 32 | (NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_ = 7) \ 33 | `ASSERT_ERROR_TRIGGER_ALERT \ 34 | (NAME_, PRIM_HIER_, ALERT_, MAX_CYCLES_, unused_valid_st) 35 | 36 | `endif // PRIM_ASSERT_SEC_CM_SVH 37 | -------------------------------------------------------------------------------- /hardware/src/common/rom_2port_noreg_sim.v: -------------------------------------------------------------------------------- 1 | module rom_2port_noreg_sim ( 2 | address_a, 3 | address_b, 4 | clock, 5 | q_a, 6 | q_b); 7 | 8 | parameter DWIDTH = 16; 9 | parameter AWIDTH = 15; 10 | parameter MEM_SIZE = 32768; 11 | parameter INIT_FILE = "./hashtable0.mif"; 12 | 13 | input [AWIDTH-1:0] address_a; 14 | input [AWIDTH-1:0] address_b; 15 | input clock; 16 | output reg [DWIDTH-1:0] q_a; 17 | output reg [DWIDTH-1:0] q_b; 18 | 19 | 20 | reg [DWIDTH-1:0] mem [0:MEM_SIZE-1]; 21 | integer i; 22 | initial begin 23 | $readmemh(INIT_FILE, mem); 24 | end 25 | always @ (posedge clock) begin 26 | q_a <= mem[address_a]; 27 | q_b <= mem[address_b]; 28 | end 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /hardware/src/common/rom_2port_sim.v: -------------------------------------------------------------------------------- 1 | module rom_2port_sim ( 2 | address_a, 3 | address_b, 4 | clock, 5 | q_a, 6 | q_b); 7 | 8 | parameter DWIDTH = 16; 9 | parameter AWIDTH = 15; 10 | parameter MEM_SIZE = 32768; 11 | parameter INIT_FILE = "./hashtable0.mif"; 12 | 13 | input [AWIDTH-1:0] address_a; 14 | input [AWIDTH-1:0] address_b; 15 | input clock; 16 | output reg [DWIDTH-1:0] q_a; 17 | output reg [DWIDTH-1:0] q_b; 18 | 19 | 20 | reg [DWIDTH-1:0] mem [0:MEM_SIZE-1]; 21 | reg [DWIDTH-1:0] q_1; 22 | reg [DWIDTH-1:0] q_2; 23 | integer i; 24 | initial begin 25 | $readmemh(INIT_FILE, mem); 26 | end 27 | always @ (posedge clock) begin 28 | q_1 <= mem[address_a]; 29 | q_2 <= mem[address_b]; 30 | q_a <= q_1; 31 | q_b <= q_2; 32 | end 33 | 34 | endmodule 35 | -------------------------------------------------------------------------------- /hardware/src/common/singledsp.v: -------------------------------------------------------------------------------- 1 | // singledsp.v 2 | 3 | // Generated using ACDS version 18.1 222 4 | 5 | `timescale 1 ps / 1 ps 6 | module singledsp ( 7 | input wire [17:0] ay, // ay.ay 8 | input wire [17:0] ax, // ax.ax 9 | output wire [36:0] resulta, // resulta.resulta 10 | input wire clk0, // clk0.clk 11 | input wire clk1, // clk1.clk 12 | input wire clk2, // clk2.clk 13 | input wire [2:0] ena // ena.ena 14 | ); 15 | 16 | singledsp_altera_s10_native_fixed_point_dsp_181_op75vsa s10_native_fixed_point_dsp_0 ( 17 | .ay (ay), // input, width = 18, ay.ay 18 | .ax (ax), // input, width = 18, ax.ax 19 | .resulta (resulta), // output, width = 37, resulta.resulta 20 | .clk0 (clk0), // input, width = 1, clk0.clk 21 | .clk1 (clk1), // input, width = 1, clk1.clk 22 | .clk2 (clk2), // input, width = 1, clk2.clk 23 | .ena (ena) // input, width = 3, ena.ena 24 | ); 25 | 26 | endmodule 27 | -------------------------------------------------------------------------------- /hardware/src/configurator.sv: -------------------------------------------------------------------------------- 1 | `include "./constants.sv" 2 | module configurator( 3 | input logic clk, 4 | input logic rst, 5 | 6 | // Input. 7 | input var config_flit_t in_config_data, 8 | input logic in_config_valid, 9 | output logic in_config_ready, 10 | 11 | // Flow table configuration. 12 | output var flow_table_config_t out_conf_ft_data, 13 | output logic out_conf_ft_valid, 14 | input logic out_conf_ft_ready, 15 | 16 | // Timestamp configuration. 17 | output var timestamp_config_t out_conf_ts_data, 18 | output logic out_conf_ts_valid, 19 | input logic out_conf_ts_ready, 20 | 21 | // Rate limit configuration. 22 | output var rate_limit_config_t out_conf_rl_data, 23 | output logic out_conf_rl_valid, 24 | input logic out_conf_rl_ready, 25 | 26 | // Fallback queues configuration. 27 | output var fallback_queues_config_t out_conf_fq_data, 28 | output logic out_conf_fq_valid, 29 | input logic out_conf_fq_ready 30 | ); 31 | 32 | always_comb begin 33 | in_config_ready = 34 | out_conf_ft_ready & 35 | out_conf_ts_ready & 36 | out_conf_rl_ready & 37 | out_conf_fq_ready; 38 | 39 | out_conf_ft_valid = 0; 40 | out_conf_ts_valid = 0; 41 | out_conf_rl_valid = 0; 42 | out_conf_fq_valid = 0; 43 | 44 | out_conf_ft_data = in_config_data; 45 | out_conf_ts_data = in_config_data; 46 | out_conf_rl_data = in_config_data; 47 | out_conf_fq_data = in_config_data; 48 | 49 | if (in_config_valid) begin 50 | case (in_config_data.config_id) 51 | FLOW_TABLE_CONFIG_ID: begin 52 | out_conf_ft_valid = 1; 53 | end 54 | TIMESTAMP_CONFIG_ID: begin 55 | out_conf_ts_valid = 1; 56 | end 57 | RATE_LIMIT_CONFIG_ID: begin 58 | out_conf_rl_valid = 1; 59 | end 60 | FALLBACK_QUEUES_CONFIG_ID: begin 61 | out_conf_fq_valid = 1; 62 | end 63 | endcase 64 | end 65 | end 66 | 67 | endmodule 68 | -------------------------------------------------------------------------------- /hardware/src/dc_back_pressure.sv: -------------------------------------------------------------------------------- 1 | module dc_back_pressure( 2 | clk, 3 | rst, 4 | csr_address, 5 | csr_read, 6 | csr_write, 7 | csr_readdata, 8 | csr_writedata, 9 | 10 | almost_full 11 | ); 12 | 13 | parameter FULL_LEVEL = 490; 14 | 15 | input logic clk; 16 | input logic rst; 17 | 18 | output logic csr_address; 19 | output logic csr_read; 20 | output logic csr_write; 21 | input logic [31:0] csr_readdata; 22 | output logic [31:0] csr_writedata; 23 | output logic almost_full; 24 | 25 | 26 | assign csr_address = 0; 27 | assign csr_write = 0; 28 | assign csr_read = 1; 29 | assign csr_writedata = 0; 30 | 31 | always@(posedge clk)begin 32 | if(csr_readdata >= FULL_LEVEL)begin 33 | almost_full <= 1; 34 | end else begin 35 | almost_full <= 0; 36 | end 37 | end 38 | 39 | endmodule 40 | -------------------------------------------------------------------------------- /hardware/src/flow_director.sv: -------------------------------------------------------------------------------- 1 | `include "./constants.sv" 2 | module flow_director( 3 | input logic clk, 4 | input logic rst, 5 | 6 | // Input. 7 | input var metadata_t in_meta_data, 8 | input logic in_meta_valid, 9 | output logic in_meta_ready, 10 | 11 | // Output. 12 | output var metadata_t out_meta_data, 13 | output logic out_meta_valid, 14 | input logic out_meta_ready, 15 | 16 | // Configuration. 17 | input var fallback_queues_config_t conf_fd_data, 18 | input logic conf_fd_valid, 19 | output logic conf_fd_ready 20 | ); 21 | 22 | logic [31:0] nb_fallback_queues; 23 | logic [31:0] fallback_queue_mask; 24 | logic enable_rr; 25 | 26 | assign conf_fd_ready = 1'b1; 27 | 28 | logic [31:0] next_rr_queue; 29 | 30 | always @(posedge clk) begin 31 | if (rst) begin 32 | enable_rr <= 0; 33 | nb_fallback_queues <= 0; 34 | fallback_queue_mask <= 0; 35 | end else begin 36 | // Apply configuration. 37 | if (conf_fd_valid) begin 38 | nb_fallback_queues <= conf_fd_data.nb_fallback_queues; 39 | fallback_queue_mask <= conf_fd_data.fallback_queue_mask; 40 | enable_rr <= conf_fd_data.enable_rr; 41 | end 42 | end 43 | end 44 | 45 | always @(posedge clk) begin 46 | if (rst) begin 47 | next_rr_queue <= 0; 48 | end else begin 49 | if (enable_rr) begin 50 | next_rr_queue <= (next_rr_queue + 1) & fallback_queue_mask; 51 | end 52 | end 53 | end 54 | 55 | always_comb begin 56 | in_meta_ready = out_meta_ready; 57 | out_meta_data = in_meta_data; 58 | out_meta_valid = in_meta_valid; 59 | 60 | out_meta_data.pkt_flags = PKT_PCIE; 61 | 62 | // Packets that do not match any entry in the flow table are sent to a 63 | // fallback queue using a hash of the 5-tuple or round robin (if enabled). 64 | // If no fallback queue is configured, we drop the packet. 65 | if (in_meta_data.pkt_queue_id == '1) begin 66 | if (nb_fallback_queues == 0) begin 67 | out_meta_data.pkt_flags = PKT_DROP; 68 | end else begin 69 | if (enable_rr) begin 70 | out_meta_data.pkt_queue_id = next_rr_queue; 71 | end else begin 72 | out_meta_data.pkt_queue_id = 73 | in_meta_data.hash & fallback_queue_mask; 74 | end 75 | end 76 | end 77 | end 78 | 79 | endmodule 80 | -------------------------------------------------------------------------------- /hardware/src/hyper_pipe.sv: -------------------------------------------------------------------------------- 1 | //Copy from Intel s10_hp_hb.pdf 2 | module hyper_pipe #( 3 | parameter WIDTH = 1, 4 | parameter NUM_PIPES = 1) 5 | ( 6 | input clk, 7 | input [WIDTH-1:0] din, 8 | output [WIDTH-1:0] dout); 9 | 10 | reg [WIDTH-1:0] hp [NUM_PIPES-1:0]; 11 | genvar i; 12 | generate 13 | if (NUM_PIPES == 0) begin 14 | assign dout = din; 15 | end else begin 16 | always @ (posedge clk) 17 | hp[0] <= din; 18 | for (i=1;i < NUM_PIPES;i++) begin : hregs 19 | always @ ( posedge clk) begin 20 | hp[i] <= hp[i-1]; 21 | end 22 | end 23 | assign dout = hp[NUM_PIPES-1]; 24 | end 25 | endgenerate 26 | endmodule 27 | -------------------------------------------------------------------------------- /hardware/src/hyper_pipe_rst.sv: -------------------------------------------------------------------------------- 1 | //Copy from Intel s10_hp_hb.pdf 2 | module hyper_pipe_rst #( 3 | parameter WIDTH = 1, 4 | parameter NUM_PIPES = 1) 5 | ( 6 | input clk, 7 | input rst, 8 | input [WIDTH-1:0] din, 9 | output [WIDTH-1:0] dout); 10 | 11 | reg [WIDTH-1:0] hp [NUM_PIPES-1:0]; 12 | genvar i; 13 | generate 14 | if (NUM_PIPES == 0) begin 15 | assign dout = din; 16 | end else begin 17 | always @ (posedge clk) begin 18 | if(rst)begin 19 | hp[0] <= 0; 20 | end else begin 21 | hp[0] <= din; 22 | end 23 | end 24 | 25 | for (i=1;i < NUM_PIPES;i++) begin : hregs 26 | always @ (posedge clk) begin 27 | if(rst)begin 28 | hp[i] <= 0; 29 | end else begin 30 | hp[i] <= hp[i-1]; 31 | end 32 | end 33 | end 34 | assign dout = hp[NUM_PIPES-1]; 35 | end 36 | endgenerate 37 | endmodule 38 | -------------------------------------------------------------------------------- /hardware/src/pcie/bram_interface.sv: -------------------------------------------------------------------------------- 1 | `include "pcie_consts.sv" 2 | 3 | interface bram_interface_io #( 4 | parameter ADDR_WIDTH=BRAM_TABLE_IDX_WIDTH, 5 | parameter DATA_WIDTH=32 6 | ); 7 | logic [ADDR_WIDTH-1:0] addr; 8 | logic [DATA_WIDTH-1:0] wr_data; 9 | logic [DATA_WIDTH-1:0] rd_data; 10 | logic rd_en; 11 | logic wr_en; 12 | 13 | // the module that *owns* the BRAM 14 | modport owner ( 15 | input addr, wr_data, rd_en, wr_en, 16 | output rd_data 17 | ); 18 | 19 | // the module that *uses* the BRAM 20 | modport user ( 21 | input rd_data, 22 | output addr, wr_data, rd_en, wr_en 23 | ); 24 | endinterface 25 | -------------------------------------------------------------------------------- /hardware/src/pcie/bram_mux.sv: -------------------------------------------------------------------------------- 1 | `include "pcie_consts.sv" 2 | 3 | /// Use to join multiple BRAM blocks into one (adds 1 cycle delay for write and 4 | /// 2 cycles for read) 5 | module bram_mux #( 6 | parameter NB_BRAMS 7 | ) ( 8 | input logic clk, 9 | 10 | bram_interface_io.owner in, 11 | bram_interface_io.user out [NB_BRAMS] 12 | ); 13 | 14 | localparam BRAM_ID_WIDTH = $clog2(NB_BRAMS); 15 | 16 | logic [BRAM_ID_WIDTH-1:0] bram_id_r; 17 | logic [BRAM_ID_WIDTH-1:0] bram_id_r2; 18 | logic [BRAM_ID_WIDTH-1:0] bram_id_r3; 19 | 20 | logic rd_en_r; 21 | logic rd_en_r2; 22 | logic rd_en_r3; 23 | 24 | // We cannot use a non-constant index to index an instance array, so we use the 25 | // following as a workaround. 26 | logic [$bits(out[0].addr)-1:0] out_addr [NB_BRAMS]; 27 | logic [$bits(out[0].wr_data)-1:0] out_wr_data [NB_BRAMS]; 28 | logic [$bits(out[0].rd_data)-1:0] out_rd_data [NB_BRAMS]; 29 | logic out_rd_en [NB_BRAMS]; 30 | logic out_wr_en [NB_BRAMS]; 31 | generate; 32 | for (genvar i = 0; i < NB_BRAMS; i++) begin : gen_output 33 | assign out[i].addr = out_addr[i]; 34 | assign out[i].wr_data = out_wr_data[i]; 35 | assign out[i].rd_en = out_rd_en[i]; 36 | assign out[i].wr_en = out_wr_en[i]; 37 | 38 | assign out_rd_data[i] = out[i].rd_data; 39 | end : gen_output 40 | endgenerate 41 | 42 | localparam NON_NEG_BRAM_ID_MSB = BRAM_ID_WIDTH ? BRAM_ID_WIDTH - 1 : 0; 43 | 44 | always @(posedge clk) begin 45 | automatic logic [NON_NEG_BRAM_ID_MSB:0] bram_id; 46 | 47 | if (BRAM_ID_WIDTH > 0) begin 48 | bram_id = in.addr[NON_NEG_BRAM_ID_MSB:0]; 49 | end else begin 50 | bram_id = 0; 51 | end 52 | 53 | for (integer i = 0; i < NB_BRAMS; i++) begin 54 | out_rd_en[i] <= 0; 55 | out_wr_en[i] <= 0; 56 | end 57 | 58 | out_addr[bram_id] <= in.addr[BRAM_ID_WIDTH +: $bits(out[0].addr)]; 59 | out_wr_data[bram_id] <= in.wr_data; 60 | out_rd_en[bram_id] <= in.rd_en; 61 | out_wr_en[bram_id] <= in.wr_en; 62 | 63 | rd_en_r <= in.rd_en; 64 | rd_en_r2 <= rd_en_r; 65 | rd_en_r3 <= rd_en_r2; 66 | 67 | bram_id_r <= bram_id; 68 | bram_id_r2 <= bram_id_r; 69 | bram_id_r3 <= bram_id_r2; 70 | 71 | if (rd_en_r3) begin 72 | in.rd_data <= out_rd_data[bram_id_r2]; 73 | end 74 | end 75 | 76 | endmodule 77 | -------------------------------------------------------------------------------- /hardware/src/pcie/pcie_consts.sv: -------------------------------------------------------------------------------- 1 | `ifndef PCIE_CONSTS_SV 2 | `define PCIE_CONSTS_SV 3 | 4 | `include "../constants.sv" 5 | 6 | localparam PCIE_WRDM_BASE_ADDR = 32'h4000_0000; 7 | localparam PCIE_RDDM_BASE_ADDR = 32'h4000_0000; 8 | 9 | // Used for benchmarking purposes. When defined, packets are not DMAed 10 | // continuously. Instead, we leave a variable, but predictable, gap between 11 | // them. This makes sure that the CPU reads are not contiguous, not benefiting 12 | // from the stream prefetcher. 13 | // `define SKIP_AHEAD 14 | 15 | typedef struct packed 16 | { 17 | logic [31:0] tail; 18 | logic [31:0] head; 19 | logic [63:0] kmem_addr; 20 | } queue_state_t; 21 | 22 | typedef struct packed 23 | { 24 | logic [APP_IDX_WIDTH-1:0] dsc_queue_id; 25 | logic [FLOW_IDX_WIDTH-1:0] pkt_queue_id; 26 | logic [$clog2(MAX_PKT_SIZE):0] size; // In number of flits. 27 | logic needs_dsc; 28 | logic drop_data; 29 | logic drop_meta; 30 | logic descriptor_only; // If set, no data is associated with this metadata. 31 | queue_state_t dsc_q_state; 32 | queue_state_t pkt_q_state; 33 | } pkt_meta_with_queues_t; 34 | 35 | typedef struct packed 36 | { 37 | logic [319:0] pad; 38 | logic [63:0] tail; 39 | logic [63:0] queue_id; 40 | logic [63:0] signal; // Should always be 0x1. 41 | } pcie_rx_dsc_t; 42 | 43 | typedef struct packed 44 | { 45 | logic [363:0] pad; 46 | logic [19:0] length; // In bytes (up to 1MB). 47 | logic [63:0] addr; // Physical address of the data. 48 | logic [63:0] signal; // 0x1 if set from software, 0x0 if set from hardware, 49 | // 0x2 if a configuration descriptor (can only be 50 | // used in queue 0 and has no packet associated with 51 | // it). 52 | } pcie_tx_dsc_t; 53 | 54 | typedef struct packed 55 | { 56 | logic [19:0] length; // In bytes (up to 1MB). 57 | logic [63:0] transfer_addr; // Physical address of the data. 58 | logic [63:0] descriptor_addr; // Physical address of the descriptor. 59 | } tx_transfer_t; 60 | 61 | typedef struct packed 62 | { 63 | logic [13:0] pad; 64 | logic [7:0] descriptor_id; 65 | logic [2:0] app_spec; 66 | logic single_dst; // When unset, dst address is incremented at every 67 | // transfer. 68 | logic [1:0] reserved; 69 | logic [17:0] nb_dwords; // Up to 1MB. 70 | logic [63:0] dst_addr; // Avalon address. 71 | logic [63:0] src_addr; // PCIe address. 72 | } rddm_desc_t; 73 | 74 | `endif // PCIE_CONSTS_SV 75 | -------------------------------------------------------------------------------- /hardware/src/pcie/rx_dsc_queue_manager.sv: -------------------------------------------------------------------------------- 1 | `include "pcie_consts.sv" 2 | 3 | /* 4 | * This module specializes the generic queue manager to RX descriptor queues. 5 | */ 6 | 7 | module rx_dsc_queue_manager #( 8 | parameter NB_QUEUES 9 | )( 10 | input logic clk, 11 | input logic rst, 12 | 13 | // input metadata stream 14 | input var pkt_meta_with_queues_t in_meta_data, 15 | input logic in_meta_valid, 16 | output logic in_meta_ready, 17 | 18 | // output metadata stream 19 | output var pkt_meta_with_queues_t out_meta_data, 20 | output logic out_meta_valid, 21 | input logic out_meta_ready, 22 | 23 | // BRAM signals for queues 24 | bram_interface_io.owner q_table_tails, 25 | bram_interface_io.owner q_table_heads, 26 | bram_interface_io.owner q_table_l_addrs, 27 | bram_interface_io.owner q_table_h_addrs, 28 | 29 | // config signals 30 | input logic [RB_AWIDTH:0] rb_size, 31 | 32 | // counters 33 | output logic [31:0] full_cnt, 34 | output logic [31:0] in_cnt, 35 | output logic [31:0] out_cnt 36 | ); 37 | 38 | pkt_meta_with_queues_t out_meta_extra; 39 | queue_state_t out_q_state; 40 | logic out_drop; 41 | 42 | queue_manager #( 43 | .NB_QUEUES(NB_QUEUES), 44 | .EXTRA_META_BITS($bits(in_meta_data)), 45 | .UNIT_POINTER(1) 46 | ) 47 | queue_manager_inst ( 48 | .clk (clk), 49 | .rst (rst), 50 | .in_pass_through (!in_meta_data.needs_dsc), 51 | .in_queue_id (in_meta_data.dsc_queue_id), 52 | .in_size (in_meta_data.size), 53 | .in_meta_extra (in_meta_data), 54 | .in_meta_valid (in_meta_valid), 55 | .in_meta_ready (in_meta_ready), 56 | .out_q_state (out_q_state), 57 | .out_drop (out_drop), 58 | .out_meta_extra (out_meta_extra), 59 | .out_meta_valid (out_meta_valid), 60 | .out_meta_ready (out_meta_ready), 61 | .q_table_tails (q_table_tails), 62 | .q_table_heads (q_table_heads), 63 | .q_table_l_addrs (q_table_l_addrs), 64 | .q_table_h_addrs (q_table_h_addrs), 65 | .rb_size (rb_size), 66 | .full_cnt (full_cnt), 67 | .in_cnt (in_cnt), 68 | .out_cnt (out_cnt) 69 | ); 70 | 71 | always_comb begin 72 | out_meta_data = out_meta_extra; 73 | out_meta_data.dsc_q_state = out_q_state; 74 | // FIXME(sadok): If we drop the packet now, the packet queue would become 75 | // out of sync, as we have already advanced its pointer. So instead we only 76 | // prevent the descriptor from being sent. This may be problematic if no 77 | // descriptor is present for the associated packet queue, as software may 78 | // never know of this new packet. Right now this can be avoided by sizing 79 | // the descriptor queue appropriately so that it never becomes full. This is 80 | // possible to ensure with reactive descriptors -- as we should never have 81 | // more descriptors than packet queues at any given moment -- but not 82 | // possible if we send a descriptor per packet. A potential solution is to 83 | // send a request for an extra descriptor to the packet queue, using the 84 | // same mechanism that we use when software advances the pointer. 85 | if (out_drop) begin 86 | out_meta_data.needs_dsc = 0; 87 | end 88 | end 89 | 90 | endmodule 91 | -------------------------------------------------------------------------------- /hardware/src/rate_limiter.sv: -------------------------------------------------------------------------------- 1 | `include "./constants.sv" 2 | 3 | /* 4 | * Rate-limit packets according to configuration. 5 | * Rate is configured to `numerator`/`denominator`. 6 | * This means that we send `numerator` flits every `denominator` cycles. 7 | */ 8 | module rate_limiter #( 9 | )( 10 | input logic clk, 11 | input logic rst, 12 | 13 | // Input. 14 | input logic [511:0] in_pkt_data, 15 | input logic in_pkt_valid, 16 | output logic in_pkt_ready, 17 | input logic in_pkt_sop, 18 | input logic in_pkt_eop, 19 | input logic [5:0] in_pkt_empty, 20 | 21 | // Output. 22 | output logic [511:0] out_pkt_data, 23 | output logic out_pkt_valid, 24 | input logic out_pkt_ready, 25 | output logic out_pkt_sop, 26 | output logic out_pkt_eop, 27 | output logic [5:0] out_pkt_empty, 28 | 29 | // Configuration. 30 | input var rate_limit_config_t conf_rl_data, 31 | input logic conf_rl_valid, 32 | output logic conf_rl_ready 33 | ); 34 | 35 | logic rate_limit_enabled; 36 | 37 | logic [$bits(conf_rl_data.numerator)-1:0] numerator; 38 | logic [$bits(conf_rl_data.denominator)-1:0] denominator; 39 | logic [$bits(conf_rl_data.numerator)-1:0] period_counter; 40 | logic [$bits(conf_rl_data.numerator)-1:0] incr_period_counter; 41 | 42 | logic pause; 43 | 44 | always @(posedge clk) begin 45 | if (rst) begin 46 | rate_limit_enabled <= 0; 47 | end else begin 48 | // Apply configuration. 49 | if (conf_rl_valid) begin 50 | rate_limit_enabled <= conf_rl_data.enable; 51 | if (conf_rl_data.enable) begin 52 | numerator <= conf_rl_data.numerator; 53 | denominator <= conf_rl_data.denominator; 54 | period_counter <= 0; 55 | end 56 | end 57 | 58 | if (rate_limit_enabled) begin 59 | period_counter <= incr_period_counter; 60 | if (incr_period_counter >= denominator) begin 61 | period_counter <= 0; 62 | end 63 | end 64 | end 65 | end 66 | 67 | always_comb begin 68 | conf_rl_ready = 1'b1; 69 | out_pkt_data = in_pkt_data; 70 | out_pkt_sop = in_pkt_sop; 71 | out_pkt_eop = in_pkt_eop; 72 | out_pkt_empty = in_pkt_empty; 73 | 74 | incr_period_counter = period_counter + 1; 75 | 76 | pause = 0; 77 | 78 | if (rate_limit_enabled) begin 79 | if (period_counter >= numerator) begin 80 | pause = 1; 81 | end 82 | end 83 | 84 | in_pkt_ready = out_pkt_ready & !pause; 85 | out_pkt_valid = in_pkt_valid & !pause; 86 | end 87 | 88 | endmodule 89 | -------------------------------------------------------------------------------- /hardware/tests/.gitignore: -------------------------------------------------------------------------------- 1 | sketch.sv 2 | -------------------------------------------------------------------------------- /hardware/tests/helpers/test_template.sv: -------------------------------------------------------------------------------- 1 | `timescale 1 ns/10 ps // time-unit = 1 ns, precision = 10 ps 2 | `include "../src/constants.sv" 3 | 4 | module module_name; // Change me! 5 | 6 | localparam PERIOD = 4; 7 | 8 | logic clk; 9 | logic rst; 10 | logic [63:0] cnt; 11 | 12 | initial clk = 0; 13 | initial rst = 1; 14 | initial cnt = 0; 15 | 16 | always #(PERIOD) clk = ~clk; 17 | 18 | always @(posedge clk) begin 19 | cnt <= cnt + 1; 20 | if (cnt < 10) begin 21 | end else if (cnt == 10) begin 22 | rst <= 0; 23 | end else if (cnt == 11) begin 24 | /* Insert logic here */ 25 | end else if (cnt == 100) begin 26 | $finish; 27 | end 28 | end 29 | 30 | endmodule 31 | -------------------------------------------------------------------------------- /llvm.ini: -------------------------------------------------------------------------------- 1 | [constants] 2 | compiler_version = '8' 3 | 4 | [binaries] 5 | c = 'clang-' + compiler_version 6 | cpp = 'clang++-' + compiler_version 7 | ar = 'llvm-ar-' + compiler_version 8 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('enso', 'c', 'cpp', version: '0.4.6', license: 'BSD-3-Clause', 2 | meson_version: '>=0.58.0', 3 | default_options: [ 4 | 'prefix=/usr/local', 5 | 'cpp_std=c++17', 6 | 'debug=true', 7 | 'optimization=3', 8 | 'warning_level=3', 9 | 'werror=true', 10 | 'default_library=static', 11 | 'cpp_eh=none', # No exceptions. 12 | 'b_ndebug=true', # Disable asserts. 13 | 'b_lto=true', # Link-time optimization. 14 | 'cpp_rtti=false', # No RTTI. 15 | ]) 16 | 17 | add_global_arguments('-march=native', language: ['c', 'cpp']) 18 | 19 | notification_buf_size = get_option('notification_buf_size') 20 | enso_pipe_size = get_option('enso_pipe_size') 21 | latency_opt = get_option('latency_opt') 22 | dev_backend = get_option('dev_backend') 23 | 24 | add_global_arguments(f'-D NOTIFICATION_BUF_SIZE=@notification_buf_size@', 25 | language: ['c', 'cpp']) 26 | add_global_arguments(f'-D ENSO_PIPE_SIZE=@enso_pipe_size@', 27 | language: ['c', 'cpp']) 28 | 29 | if latency_opt 30 | add_global_arguments('-D LATENCY_OPT', language: ['c', 'cpp']) 31 | endif 32 | 33 | subdir('software') 34 | subdir('docs') 35 | subdir('hardware') 36 | subdir('scripts') 37 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | 2 | option('notification_buf_size', type: 'integer', min: 0, max: 32768, 3 | value: 16384, 4 | description: 'Buffer size used by each software notification buffer') 5 | option('enso_pipe_size', type: 'integer', min: 0, max: 32768, value: 32768, 6 | description: 'Buffer size used by each software enso pipe') 7 | option('latency_opt', type: 'boolean', value: true, 8 | description: 'Optimize for latency') 9 | option('dev_backend', type: 'combo', choices: ['intel_fpga', 'software'], 10 | value: 'intel_fpga', description: 'Device backend to use') 11 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Ensō 2 | site_url: https://enso.cs.cmu.edu/ 3 | site_author: Hugo Sadok 4 | site_description: >- 5 | Ensō is a fast and flexible streaming interface for NIC-application communication. 6 | 7 | # Repository 8 | repo_name: crossroadsfpga/enso 9 | repo_url: https://github.com/crossroadsfpga/enso 10 | 11 | # Copyright 12 | copyright: Copyright © 2025 Hugo Sadok 13 | 14 | theme: 15 | name: material 16 | features: 17 | - content.action.edit 18 | - content.action.view 19 | - content.code.annotate 20 | - content.code.copy 21 | - content.tooltips 22 | - navigation.footer 23 | - navigation.indexes 24 | - navigation.instant 25 | - navigation.sections 26 | - navigation.tabs 27 | - navigation.top 28 | - navigation.tracking 29 | - search.highlight 30 | - search.share 31 | - search.suggest 32 | - toc.follow 33 | language: en 34 | palette: 35 | - scheme: default 36 | primary: black 37 | accent: black 38 | font: 39 | text: Roboto 40 | code: Roboto Mono 41 | favicon: assets/enso-black.svg 42 | logo: assets/enso-white.svg 43 | 44 | extra: 45 | analytics: 46 | provider: google 47 | property: G-7WKNV89H63 48 | 49 | extra_javascript: 50 | - https://unpkg.com/tablesort@5.3.0/dist/tablesort.min.js 51 | - javascripts/tablesort.js 52 | 53 | markdown_extensions: 54 | - abbr 55 | - attr_list 56 | - md_in_html 57 | - footnotes 58 | - admonition 59 | - pymdownx.highlight 60 | - pymdownx.inlinehilite 61 | - pymdownx.keys 62 | - pymdownx.details 63 | - pymdownx.emoji: 64 | emoji_index: !!python/name:materialx.emoji.twemoji 65 | emoji_generator: !!python/name:materialx.emoji.to_svg 66 | - pymdownx.superfences: 67 | custom_fences: 68 | - name: mermaid 69 | class: mermaid 70 | format: !!python/name:pymdownx.superfences.fence_code_format 71 | - pymdownx.tabbed: 72 | alternate_style: true 73 | 74 | # Note that we are using the awesome-pages plugin, therefore nav is defined in 75 | # the .pages file present in each directory. 76 | # nav: 77 | 78 | plugins: 79 | - search 80 | - awesome-pages 81 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | scapy 2 | -------------------------------------------------------------------------------- /scripts/ensogen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Helper script to run ensogen with the correct arguments for numerator and 3 | # denominator depending on a given rate and pcap file. 4 | 5 | set -e 6 | 7 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 8 | 9 | ENSOGEN_PATH="${SCRIPT_DIR}/../build/software/examples/ensogen" 10 | ENSOGEN_PATH=$(realpath $ENSOGEN_PATH) 11 | 12 | GET_PCAP_SIZE_CMD_PATH="${SCRIPT_DIR}/../build/scripts/get_pcap_pkt_size" 13 | GET_PCAP_SIZE_CMD_PATH=$(realpath $GET_PCAP_SIZE_CMD_PATH) 14 | 15 | if [ $# -lt 2 ]; then 16 | echo "Usage: ./ensogen.sh PCAP_FILE RATE_GBPS [OPTIONS]" 17 | echo "Example: ./ensogen.sh /tmp/pcap_file.pcap 100 --pcie-addr 65:00.0" 18 | exit 1 19 | fi 20 | 21 | if [ ! -f $ENSOGEN_PATH ]; then 22 | echo "Error: Could not find ensogen binary at $ENSOGEN_PATH" 23 | echo "Make sure you have built the enso project." 24 | exit 2 25 | fi 26 | 27 | if [ ! -f $GET_PCAP_SIZE_CMD_PATH ]; then 28 | echo "Error: Could not find binary at $GET_PCAP_SIZE_CMD_PATH" 29 | echo "Make sure you have built the enso project." 30 | exit 3 31 | fi 32 | 33 | pcap_file=$1 34 | rate=$2 35 | extra_args=${@:3} 36 | 37 | pattern="Average packet size:" 38 | mean_pkt_size=$($GET_PCAP_SIZE_CMD_PATH $pcap_file) 39 | 40 | num_den=$(python3 </dev/null 2>&1 && pwd )" 11 | REPO_DIR=$SCRIPT_DIR/.. 12 | 13 | cd $REPO_DIR/hardware/ip 14 | 15 | generate_ip () { 16 | rm -rf $1 17 | rm -rf $1.ip 18 | qsys-script --script=$1.tcl --quartus-project=../quartus/enso.qsf 19 | } 20 | 21 | generate_ip alt_ehipc2_jtag_avalon 22 | generate_ip alt_ehipc2_sys_pll 23 | generate_ip ex_100G 24 | generate_ip my_pll 25 | generate_ip probe8 26 | generate_ip reset_ip 27 | 28 | rm -rf ip 29 | rm -rf pcie_ed.qsys 30 | rm -rf pcie_ed 31 | qsys-script --script=pcie_ed.tcl --quartus-project=../quartus/enso.qsf 32 | 33 | PROJECT_DIR=$REPO_DIR/hardware 34 | 35 | cd $PROJECT_DIR/quartus 36 | 37 | # Generate IPs. 38 | quartus_ipgenerate $PROJECT_NAME 39 | 40 | # We must copy the pcie_generic_component_0.v.template to the correct location. 41 | cp $PROJECT_DIR/ip/pcie_generic_component_0.v.template \ 42 | $PROJECT_DIR/ip/pcie_ed/generic_component_0/synth/generic_component_0.v 43 | -------------------------------------------------------------------------------- /scripts/hwtest/altera/alt_aeu_40/eth_ultra_mac_inc.tcl: -------------------------------------------------------------------------------- 1 | # (C) 2001-2019 Intel Corporation. All rights reserved. 2 | # Your use of Intel Corporation's design tools, logic functions and other 3 | # software and tools, and its AMPP partner logic functions, and any output 4 | # files from any of the foregoing (including device programming or simulation 5 | # files), and any associated documentation or information are expressly subject 6 | # to the terms and conditions of the Intel Program License Subscription 7 | # Agreement, Intel FPGA IP License Agreement, or other applicable 8 | # license agreement, including, without limitation, that your use is for the 9 | # sole purpose of programming logic devices manufactured by Intel and sold by 10 | # Intel or its authorized distributors. Please refer to the applicable 11 | # agreement for further details. 12 | 13 | 14 | ## ===================================================== 15 | ## Top level register map: Base Addresses 16 | ## ===================================================== 17 | source [file join [file dirname [info script]] "../sval_top/reg_map_inc.tcl"] 18 | 19 | ## ================================================================== 20 | ## Ethernet registers MAC(Tx and Rx) 21 | ## ================================================================== 22 | ## 23 | set ADDR_RXMAC_TFLCFG 0x00 24 | set ADDR_RXMAC_SZECFG 0x01 25 | set ADDR_RXMAC_CRCCFG 0x02 26 | set ADDR_RXMAC_LNKFLT 0x03 27 | 28 | proc chkmac_rx_maxframe_length {} { 29 | global BASE_RXMAC 30 | global ADDR_RXMAC_TFLCFG 31 | global ADDR_RXMAC_SZECFG 32 | global ADDR_RXMAC_CRCCFG 33 | global ADDR_RXMAC_LNKFLT 34 | puts "Accessing Mac Frame Length register in Rx MAC"; reg_read $BASE_RXMAC $ADDR_RXMAC_SZECFG 35 | puts "Modifying Mac Frame Length register in Rx MAC"; reg_write $BASE_RXMAC $ADDR_RXMAC_SZECFG 0x1550 36 | puts "Verifying Mac Frame Length register in Rx MAC"; reg_read $BASE_RXMAC $ADDR_RXMAC_SZECFG 37 | } 38 | -------------------------------------------------------------------------------- /scripts/hwtest/altera/alt_aeu_40/main.tcl: -------------------------------------------------------------------------------- 1 | # (C) 2001-2019 Intel Corporation. All rights reserved. 2 | # Your use of Intel Corporation's design tools, logic functions and other 3 | # software and tools, and its AMPP partner logic functions, and any output 4 | # files from any of the foregoing (including device programming or simulation 5 | # files), and any associated documentation or information are expressly subject 6 | # to the terms and conditions of the Intel Program License Subscription 7 | # Agreement, Intel FPGA IP License Agreement, or other applicable 8 | # license agreement, including, without limitation, that your use is for the 9 | # sole purpose of programming logic devices manufactured by Intel and sold by 10 | # Intel or its authorized distributors. Please refer to the applicable 11 | # agreement for further details. 12 | 13 | 14 | source [file join [file dirname [info script]] "eth_ultra_mac_inc.tcl"] 15 | source [file join [file dirname [info script]] "eth_ultra_phy_inc.tcl"] 16 | source [file join [file dirname [info script]] "eth_ultra_stats_inc.tcl"] 17 | -------------------------------------------------------------------------------- /scripts/hwtest/altera/optical_module/cfp_control_inc.tcl: -------------------------------------------------------------------------------- 1 | # (C) 2001-2019 Intel Corporation. All rights reserved. 2 | # Your use of Intel Corporation's design tools, logic functions and other 3 | # software and tools, and its AMPP partner logic functions, and any output 4 | # files from any of the foregoing (including device programming or simulation 5 | # files), and any associated documentation or information are expressly subject 6 | # to the terms and conditions of the Intel Program License Subscription 7 | # Agreement, Intel FPGA IP License Agreement, or other applicable 8 | # license agreement, including, without limitation, that your use is for the 9 | # sole purpose of programming logic devices manufactured by Intel and sold by 10 | # Intel or its authorized distributors. Please refer to the applicable 11 | # agreement for further details. 12 | 13 | 14 | # ===================================================== 15 | # word address to byte address translations should 16 | # happen inside the basic.tcl defining write & read 17 | # ______________________________________________________ 18 | 19 | source [file join [file dirname [info script]] "../sval_top/reg_map_inc.tcl"] 20 | 21 | set REG_MODNAME 0x00 22 | set REG_SCRATCH 0x01 23 | set REG_OPTXENA 0x02 24 | set REG_CFPSTTS 0x03 25 | set REG_CFPCTRL 0x04 26 | 27 | set REG_MDIWRDT 0x10 28 | set REG_MDIRDDT 0x11 29 | set REG_MDIADDR 0x12 30 | set REG_MDICMMD 0x13 31 | 32 | set REG_2WRWRDT 0x20 33 | set REG_2WRSTTS 0x21 34 | set REG_2WRADDR 0x22 35 | set REG_2WRCMMD 0x23 36 | 37 | # ===================================================== 38 | # test utilities 39 | # ===================================================== 40 | 41 | set log 0 42 | 43 | proc pmdc_init {LOG} { 44 | global log 45 | set log $LOG 46 | } 47 | 48 | proc cfp_on {} { 49 | global BASE_PMDC 50 | global REG_OPTXENA 51 | global rdata 52 | global log 53 | reg_write $BASE_PMDC $REG_OPTXENA 0x01 54 | set rdata [reg_read $BASE_PMDC $REG_OPTXENA] 55 | 56 | set msg_hdr_title "____________INFO: CFP Turn ON Confirmation _________________________" 57 | if {$log == "both"} {putl "$msg_hdr_title"; puts "$msg_hdr_title\r"} elseif {$log == "log"} {putl "$msg_hdr_title"} else {puts "$msg_hdr_title\r"} 58 | set msg_temp " CFP ENable Control Value (Verified): $rdata " 59 | if {$log == "both"} {putl "$msg_temp\r"; puts "$msg_temp\n"} elseif {$log == "log"} {putl "$msg_temp\r"} else {puts "$msg_temp\n"} 60 | } 61 | -------------------------------------------------------------------------------- /scripts/hwtest/altera/optical_module/main.tcl: -------------------------------------------------------------------------------- 1 | # (C) 2001-2019 Intel Corporation. All rights reserved. 2 | # Your use of Intel Corporation's design tools, logic functions and other 3 | # software and tools, and its AMPP partner logic functions, and any output 4 | # files from any of the foregoing (including device programming or simulation 5 | # files), and any associated documentation or information are expressly subject 6 | # to the terms and conditions of the Intel Program License Subscription 7 | # Agreement, Intel FPGA IP License Agreement, or other applicable 8 | # license agreement, including, without limitation, that your use is for the 9 | # sole purpose of programming logic devices manufactured by Intel and sold by 10 | # Intel or its authorized distributors. Please refer to the applicable 11 | # agreement for further details. 12 | 13 | 14 | source [file join [file dirname [info script]] "qsfp_control_inc.tcl"] 15 | -------------------------------------------------------------------------------- /scripts/hwtest/altera/pkt_client/pkt_client.tcl: -------------------------------------------------------------------------------- 1 | # (C) 2001-2019 Intel Corporation. All rights reserved. 2 | # Your use of Intel Corporation's design tools, logic functions and other 3 | # software and tools, and its AMPP partner logic functions, and any output 4 | # files from any of the foregoing (including device programming or simulation 5 | # files), and any associated documentation or information are expressly subject 6 | # to the terms and conditions of the Intel Program License Subscription 7 | # Agreement, Intel FPGA IP License Agreement, or other applicable 8 | # license agreement, including, without limitation, that your use is for the 9 | # sole purpose of programming logic devices manufactured by Intel and sold by 10 | # Intel or its authorized distributors. Please refer to the applicable 11 | # agreement for further details. 12 | 13 | 14 | # ===================================================== 15 | # Top level register map: Base Addresses 16 | # ===================================================== 17 | # word address to byte address translations should 18 | # happen inside the basic.tcl defining write & read 19 | # ______________________________________________________ 20 | 21 | set CLIENT_BASE $BASE_TRFC 22 | # ===================================================== 23 | # Ethernet registers (MAC + PHY) 24 | # ===================================================== 25 | 26 | set REG_TEMP_SENSE 0x0006 27 | # ===================================================== 28 | # test utilities 29 | # ===================================================== 30 | 31 | set log 0 32 | 33 | proc client_init {LOG} { 34 | global log 35 | set log $LOG 36 | } 37 | 38 | proc check_e_temp {} { 39 | global CLIENT_BASE 40 | global REG_TEMP_SENSE 41 | global rdata 42 | global log 43 | set rdata [reg_read $CLIENT_BASE $REG_TEMP_SENSE] 44 | return $rdata 45 | } 46 | 47 | 48 | proc stop_pkt_gen {} { 49 | global CLIENT_BASE 50 | 51 | global rdata 52 | global wdata 53 | global log 54 | 55 | reg_write $CLIENT_BASE 0x10 0x7 56 | } 57 | 58 | proc client_rom {} { 59 | global CLIENT_BASE 60 | global log 61 | global rdata 62 | global wdata 63 | reg_write $CLIENT_BASE 0x10 0x2 64 | } 65 | 66 | proc client_loop {} { 67 | global CLIENT_BASE 68 | reg_write $CLIENT_BASE 0x10 0xf 69 | } 70 | 71 | proc start_pkt_gen {} { 72 | global CLIENT_BASE 73 | global log 74 | global rdata 75 | global wdata 76 | reg_write $CLIENT_BASE 0x10 0x5 77 | } 78 | 79 | proc client_reset {} { 80 | global CLIENT_BASE 81 | 82 | reg_write $CLIENT_BASE 0x16 1 83 | after 100 84 | reg_write $CLIENT_BASE 0x16 0 85 | } 86 | -------------------------------------------------------------------------------- /scripts/hwtest/altera/sval_top/main.tcl: -------------------------------------------------------------------------------- 1 | # (C) 2001-2019 Intel Corporation. All rights reserved. 2 | # Your use of Intel Corporation's design tools, logic functions and other 3 | # software and tools, and its AMPP partner logic functions, and any output 4 | # files from any of the foregoing (including device programming or simulation 5 | # files), and any associated documentation or information are expressly subject 6 | # to the terms and conditions of the Intel Program License Subscription 7 | # Agreement, Intel FPGA IP License Agreement, or other applicable 8 | # license agreement, including, without limitation, that your use is for the 9 | # sole purpose of programming logic devices manufactured by Intel and sold by 10 | # Intel or its authorized distributors. Please refer to the applicable 11 | # agreement for further details. 12 | 13 | 14 | source [file join [file dirname [info script]] "../../common/main.tcl"] 15 | source [file join [file dirname [info script]] "reg_map_inc.tcl"] 16 | source [file join [file dirname [info script]] "../alt_aeu_40/main.tcl"] 17 | source [file join [file dirname [info script]] "../optical_module/main.tcl"] 18 | source [file join [file dirname [info script]] "../pkt_client/pkt_client.tcl"] 19 | source [file join [file dirname [info script]] "../kr4/kr4.tcl"] 20 | -------------------------------------------------------------------------------- /scripts/hwtest/altera/sval_top/reg_map_inc.tcl: -------------------------------------------------------------------------------- 1 | # (C) 2001-2019 Intel Corporation. All rights reserved. 2 | # Your use of Intel Corporation's design tools, logic functions and other 3 | # software and tools, and its AMPP partner logic functions, and any output 4 | # files from any of the foregoing (including device programming or simulation 5 | # files), and any associated documentation or information are expressly subject 6 | # to the terms and conditions of the Intel Program License Subscription 7 | # Agreement, Intel FPGA IP License Agreement, or other applicable 8 | # license agreement, including, without limitation, that your use is for the 9 | # sole purpose of programming logic devices manufactured by Intel and sold by 10 | # Intel or its authorized distributors. Please refer to the applicable 11 | # agreement for further details. 12 | 13 | 14 | #============================================================================== 15 | # High Level Address map 16 | #============================================================================== 17 | set BASE_KR4 0x00000 18 | set BASE_RXPHY 0x00300 19 | set BASE_TXMAC 0x00400 20 | set BASE_RXMAC 0x00500 21 | set BASE_TXSTATS 0x00800 22 | set BASE_RXSTATS 0x00900 23 | set BASE_TRFC 0x01000 24 | set BASE_PMDC 0x02000 25 | set BASE_S10RECO 0x10000 26 | set RECO_CH 0x01000 27 | #============================================================================== 28 | -------------------------------------------------------------------------------- /scripts/hwtest/common/main.tcl: -------------------------------------------------------------------------------- 1 | # (C) 2001-2019 Intel Corporation. All rights reserved. 2 | # Your use of Intel Corporation's design tools, logic functions and other 3 | # software and tools, and its AMPP partner logic functions, and any output 4 | # files from any of the foregoing (including device programming or simulation 5 | # files), and any associated documentation or information are expressly subject 6 | # to the terms and conditions of the Intel Program License Subscription 7 | # Agreement, Intel FPGA IP License Agreement, or other applicable 8 | # license agreement, including, without limitation, that your use is for the 9 | # sole purpose of programming logic devices manufactured by Intel and sold by 10 | # Intel or its authorized distributors. Please refer to the applicable 11 | # agreement for further details. 12 | 13 | 14 | source [file join [file dirname [info script]] "report.tcl"] 15 | source [file join [file dirname [info script]] "jtag_basic.tcl"] 16 | -------------------------------------------------------------------------------- /scripts/hwtest/common/report.tcl: -------------------------------------------------------------------------------- 1 | # (C) 2001-2019 Intel Corporation. All rights reserved. 2 | # Your use of Intel Corporation's design tools, logic functions and other 3 | # software and tools, and its AMPP partner logic functions, and any output 4 | # files from any of the foregoing (including device programming or simulation 5 | # files), and any associated documentation or information are expressly subject 6 | # to the terms and conditions of the Intel Program License Subscription 7 | # Agreement, Intel FPGA IP License Agreement, or other applicable 8 | # license agreement, including, without limitation, that your use is for the 9 | # sole purpose of programming logic devices manufactured by Intel and sold by 10 | # Intel or its authorized distributors. Please refer to the applicable 11 | # agreement for further details. 12 | 13 | 14 | #common procedures 15 | 16 | proc open_log_file {fname} { 17 | global LOGFILE 18 | set LOGFILE [open $fname a] 19 | } 20 | 21 | proc close_log_file {} { 22 | global LOGFILE 23 | close $LOGFILE 24 | } 25 | 26 | proc putl {txt} { 27 | global LOGFILE 28 | puts $LOGFILE "$txt \r"; 29 | } 30 | 31 | proc sleep {sec} { 32 | after [expr {int($sec * 1000)}]; 33 | } 34 | -------------------------------------------------------------------------------- /scripts/list_enso_nics.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This script lists the available Enso NICs. It scans both PCIe devices as well 3 | # as USB devices to be used with JTAG. 4 | 5 | YELLOW='\033[0;33m' 6 | NC='\033[0m' # No Color 7 | 8 | echo "PCIe devices" 9 | DEVICE_ID="0000" 10 | VENDOR_ID="1172" 11 | 12 | nb_pcie_devices=0 13 | 14 | while read -r line; do 15 | device=$(echo "$line" | awk '{print $1}') 16 | nb_pcie_devices=$((nb_pcie_devices+1)) 17 | echo " PCIe Address:" $device 18 | done < <(lspci -nn | grep ${VENDOR_ID}:${DEVICE_ID}) 19 | 20 | echo 21 | echo "USB devices" 22 | DEVICE_ID="6010" 23 | VENDOR_ID="09fb" 24 | 25 | nb_usb_devices=0 26 | 27 | while read -r line; do 28 | # Get the device number from each line 29 | device=$(echo "$line" | awk '{print $4}' | cut -d: -f1) 30 | device=$((10#$device)) 31 | 32 | bus=$(echo "$line" | cut -d " " -f 2) 33 | bus=$((10#$bus)) 34 | 35 | # capture the right bus 36 | bus_line=$(lsusb -t | grep "Bus .*${bus}\." -n | cut -d ":" -f 1) 37 | fpga_bus="$(lsusb -t | tail -n +${bus_line} -)" 38 | 39 | # Get the port number from lsusb -t using the device number 40 | port=$(echo "${fpga_bus}" | grep -m 1 "Dev $device" | awk '{print $3}') 41 | port=${port%?} 42 | 43 | # Combine bus and port to get the ID 44 | bus=$(echo "$line" | awk '{print $2}') 45 | bus=$((10#$bus)) 46 | 47 | id="$bus-$port" 48 | 49 | nb_usb_devices=$((nb_usb_devices+1)) 50 | 51 | echo " FPGA ID:" $id 52 | done < <(lsusb -d ${VENDOR_ID}:${DEVICE_ID}) 53 | 54 | if [ $nb_pcie_devices -ne $nb_usb_devices ]; then 55 | echo 56 | echo -e "${YELLOW}WARNING: The number of PCIe and USB devices is different."\ 57 | "Make sure to load the bitstream using scripts/load_bitstream.sh and"\ 58 | "to reboot the machine.${NC}" 59 | fi 60 | -------------------------------------------------------------------------------- /scripts/load.cdf: -------------------------------------------------------------------------------- 1 | /* Quartus Prime Version 19.3.0 Build 222 09/23/2019 SC Pro Edition */ 2 | JedecChain; 3 | FileRevision(JESD32A); 4 | DefaultMfr(6E); 5 | 6 | P ActionCode(Cfg) 7 | Device PartName(1SM21BHU2F53S1) File("enso.sof") MfrSpec(OpMask(1)); 8 | P ActionCode(Ign) 9 | Device PartName(VTAP10) MfrSpec(OpMask(0)); 10 | 11 | ChainEnd; 12 | 13 | AlteraBegin; 14 | ChainType(JTAG); 15 | AlteraEnd; 16 | -------------------------------------------------------------------------------- /scripts/load_bitstream.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 5 | 6 | VENDOR_ID="1172" 7 | DEVICE_ID="0000" 8 | 9 | FPGA_NB=${1:-"1-13"} 10 | 11 | cd $SCRIPT_DIR 12 | 13 | # Check if quartus_pgm is in the PATH. 14 | if ! command -v quartus_pgm &> /dev/null; then 15 | echo-e "${RED}quartus_pgm not in PATH. Add it to PATH and try again.${NC}" 16 | exit 1 17 | fi 18 | 19 | # We use taskset and chrt to benefit from multiple cores even when they are 20 | # isolated from the linux scheduler. This significantly speeds up loading the 21 | # bitstream. Note that we use all but the last core. 22 | sudo taskset -c 0-$((`nproc --all` - 2)) chrt -r 1 $(which quartus_pgm) \ 23 | -c "Intel Stratix 10 MX FPGA Development Kit [$FPGA_NB]" ./load.cdf 24 | 25 | # Remove device and force rescan, this will trigger the driver's probe function. 26 | DEVICE_ADDRS=$(lspci -nn | grep ${VENDOR_ID}:${DEVICE_ID} | grep Ethernet | \ 27 | awk '{print $1}') 28 | 29 | for device in $DEVICE_ADDRS; do 30 | if [ -n "$device" ]; then 31 | echo "1" | sudo tee -a /sys/bus/pci/devices/0000\:${device}/remove \ 32 | > /dev/null 33 | fi 34 | done 35 | echo "1" | sudo tee -a /sys/bus/pci/rescan > /dev/null 36 | 37 | SHA256_SUM=$(sha256sum ./enso.sof | awk '{print $1}') 38 | 39 | echo "Loaded bitstream with sha256sum: $SHA256_SUM" 40 | -------------------------------------------------------------------------------- /scripts/meson.build: -------------------------------------------------------------------------------- 1 | pcap_dep = dependency('pcap', version : '>=1.0') 2 | 3 | executable('get_pcap_pkt_size', 'get_pcap_pkt_size.cpp', 4 | include_directories: inc, dependencies: [pcap_dep]) 5 | -------------------------------------------------------------------------------- /scripts/path.tcl: -------------------------------------------------------------------------------- 1 | cd ./hwtest 2 | source main.tcl 3 | -------------------------------------------------------------------------------- /scripts/quartus_fit_save.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # exit when error occurs 4 | set -e 5 | trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG 6 | trap 'echo "\"${last_command}\" command exited with code $?."' EXIT 7 | 8 | PROJECT_NAME="enso" 9 | 10 | CUR_DIR=$(pwd) 11 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 12 | PROJECT_DIR=$SCRIPT_DIR/../hardware 13 | 14 | SEED=${1:-"0"} 15 | 16 | BITSTREAM_DESTINATION=$CUR_DIR 17 | 18 | echo "SEED=$SEED" 19 | 20 | PROJECT_OUTPUT_DIRECTORY="output_files" 21 | QUARTUS_STA_LOG_FILE="quartus_sta_${SEED}.log" 22 | 23 | start=$(date +%s.%N) 24 | 25 | compilation_dir="/tmp/${PROJECT_NAME}_$SEED" 26 | 27 | rm -rf $compilation_dir 28 | mkdir -p $compilation_dir/db 29 | 30 | cp -r $PROJECT_DIR/* $compilation_dir/ 31 | 32 | cd $compilation_dir/quartus 33 | 34 | quartus_fit --read_settings_files=on --write_settings_files=off $PROJECT_NAME \ 35 | -c $PROJECT_NAME --seed=$SEED 36 | 37 | # We use script instead of tee to capture the output and display it while 38 | # preserving colors. 39 | script --flush --quiet --return $QUARTUS_STA_LOG_FILE \ 40 | --command "quartus_sta $PROJECT_NAME -c $PROJECT_NAME --mode=finalize" 41 | quartus_asm --read_settings_files=on --write_settings_files=off $PROJECT_NAME \ 42 | -c $PROJECT_NAME 43 | 44 | dur=$(echo "$(date +%s.%N) - $start" | bc) 45 | printf "Fitting completed in %.6f seconds\n" $dur 46 | 47 | # Show Fmax. 48 | grep -A20 "; Fmax" "$PROJECT_OUTPUT_DIRECTORY/$PROJECT_NAME.sta.rpt" 49 | 50 | 51 | # Show resource utilization. 52 | cat "$PROJECT_OUTPUT_DIRECTORY/$PROJECT_NAME.fit.summary" 53 | 54 | if grep -q "Timing requirements not met" $QUARTUS_STA_LOG_FILE; then 55 | # Show slack. 56 | grep -C 10 "Timing requirements not met" $QUARTUS_STA_LOG_FILE 57 | RED='\033[0;31m' 58 | NC='\033[0m' # No Color. 59 | echo -e "${RED}===========================${NC}" 60 | echo -e "${RED}Timing requirements not met${NC}" 61 | echo -e "${RED}===========================${NC}" 62 | BITSTREAM_NAME="neg_slack_${PROJECT_NAME}_${SEED}.sof" 63 | else 64 | BITSTREAM_NAME="${PROJECT_NAME}_${SEED}.sof" 65 | fi 66 | 67 | BITSTREAM_DST_NAME="$BITSTREAM_DESTINATION/$BITSTREAM_NAME" 68 | 69 | # Copy sof. 70 | cp "$PROJECT_OUTPUT_DIRECTORY/$PROJECT_NAME.sof" $BITSTREAM_DST_NAME 71 | echo "Bitstream saved to: $BITSTREAM_DST_NAME" 72 | sha256sum $BITSTREAM_DST_NAME 73 | 74 | echo "Done (seed=$SEED)" 75 | 76 | # Announce that it is over. 77 | tput bel 78 | 79 | read -p "Press enter to continue" 80 | -------------------------------------------------------------------------------- /scripts/run_console.sh: -------------------------------------------------------------------------------- 1 | system-console -cli 2 | -------------------------------------------------------------------------------- /scripts/sample_pcaps/16_1518_1_16.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crossroadsfpga/enso/632133a3fcd1d894dd4c3a873e4fde91d58b8894/scripts/sample_pcaps/16_1518_1_16.pcap -------------------------------------------------------------------------------- /scripts/sample_pcaps/16_64_1_16.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crossroadsfpga/enso/632133a3fcd1d894dd4c3a873e4fde91d58b8894/scripts/sample_pcaps/16_64_1_16.pcap -------------------------------------------------------------------------------- /scripts/sample_pcaps/2_1518_1_2.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crossroadsfpga/enso/632133a3fcd1d894dd4c3a873e4fde91d58b8894/scripts/sample_pcaps/2_1518_1_2.pcap -------------------------------------------------------------------------------- /scripts/sample_pcaps/2_64_1_2.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crossroadsfpga/enso/632133a3fcd1d894dd4c3a873e4fde91d58b8894/scripts/sample_pcaps/2_64_1_2.pcap -------------------------------------------------------------------------------- /scripts/sample_pcaps/4_1518_1_4.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crossroadsfpga/enso/632133a3fcd1d894dd4c3a873e4fde91d58b8894/scripts/sample_pcaps/4_1518_1_4.pcap -------------------------------------------------------------------------------- /scripts/sample_pcaps/4_64_1_4.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crossroadsfpga/enso/632133a3fcd1d894dd4c3a873e4fde91d58b8894/scripts/sample_pcaps/4_64_1_4.pcap -------------------------------------------------------------------------------- /scripts/sample_pcaps/8_1518_1_8.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crossroadsfpga/enso/632133a3fcd1d894dd4c3a873e4fde91d58b8894/scripts/sample_pcaps/8_1518_1_8.pcap -------------------------------------------------------------------------------- /scripts/sample_pcaps/8_64_1_8.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crossroadsfpga/enso/632133a3fcd1d894dd4c3a873e4fde91d58b8894/scripts/sample_pcaps/8_64_1_8.pcap -------------------------------------------------------------------------------- /scripts/sw_setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # exit when error occurs 4 | set -e 5 | 6 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 7 | REPO_DIR=$SCRIPT_DIR/.. 8 | 9 | if [[ "$#" -ne 3 ]]; then 10 | echo "Syntax: ./sw_setup.sh NOTIFICATION_BUF_SIZE ENSO_PIPE_SIZE LATENCY_OPT" 11 | exit 1 12 | fi 13 | 14 | 15 | sudo mkdir -p /mnt/huge 16 | (sudo mount | grep /mnt/huge) > /dev/null || sudo mount -t hugetlbfs hugetlbfs /mnt/huge 17 | for i in /sys/devices/system/node/node[0-9]*; do 18 | echo 4096 | sudo tee "$i"/hugepages/hugepages-2048kB/nr_hugepages 19 | done 20 | 21 | cd $REPO_DIR/software/kernel/linux/ 22 | make 23 | ./install 24 | cd $REPO_DIR 25 | 26 | which python3 27 | which meson 28 | 29 | # Using GCC 30 | meson setup --native-file gcc.ini build-gcc 31 | ln -sfn build-gcc build 32 | 33 | # Using Clang 34 | # meson setup --native-file llvm.ini build-clang 35 | # ln -sfn build-clang build 36 | 37 | cd build 38 | meson configure -Dnotification_buf_size=$1 -Denso_pipe_size=$2 -Dlatency_opt=$3 39 | ninja -v 40 | sudo ninja install 41 | -------------------------------------------------------------------------------- /scripts/update_bitstream.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # exit when error occurs 4 | set -e 5 | 6 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 7 | 8 | RED='\033[0;31m' 9 | GREEN='\033[0;32m' 10 | NC='\033[0m' # No Color 11 | 12 | if [ $# -ne 1 ]; then 13 | echo "Must specify bitstream file or '--download'." 14 | echo 15 | echo "Usage: $0 BITSTREAM_FILE | --download" 16 | echo " BITSTREAM_FILE: Path to bitstream file to use." 17 | echo " --download: Automatically download bitstream for the current version." 18 | exit 1 19 | fi 20 | 21 | DST_BITSTREAM_FILE="scripts/enso.sof" 22 | 23 | cd $SCRIPT_DIR/.. 24 | 25 | if [ "$1" == "--download" ]; then 26 | echo "Downloading bitstream file." 27 | # Get latest tag. 28 | LATEST_TAG=$(git describe --tags --abbrev=0) 29 | echo "Latest tag: $LATEST_TAG" 30 | 31 | GH_RELEASE_URL="https://github.com/crossroadsfpga/enso/releases/download" 32 | BITSTREAM_NAME="intel_stratix10mx_bitstream.sof" 33 | BITSTREAM_URL="$GH_RELEASE_URL/$LATEST_TAG/$BITSTREAM_NAME" 34 | echo "Downloading bitstream file from: $BITSTREAM_URL" 35 | 36 | wget $BITSTREAM_URL 37 | mv $BITSTREAM_NAME $DST_BITSTREAM_FILE 38 | else 39 | BITSTREAM_FILE=$1 40 | 41 | # Check if bitstream file exists. 42 | if [ ! -f "$BITSTREAM_FILE" ]; then 43 | echo -e "${RED}Bitstream file $BITSTREAM_FILE does not exist.${NC}" 44 | exit 1 45 | fi 46 | 47 | # Copy bitstream file to the scripts directory. 48 | cp $BITSTREAM_FILE $DST_BITSTREAM_FILE 49 | fi 50 | 51 | echo "Successfully updated bitstream file. To load it, use the enso command." 52 | chksum=$(sha256sum $DST_BITSTREAM_FILE | cut -d " " -f 1) 53 | echo "sha256sum: $chksum" 54 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 4 | 5 | RED='\033[0;31m' 6 | GREEN='\033[0;32m' 7 | NC='\033[0m' # No Color 8 | 9 | SETUP_DONE_PATH="$SCRIPT_DIR/.setup_done" 10 | 11 | # If --no-quartus is passed, we don't check for quartus. 12 | if [[ $1 == "--no-quartus" ]]; then 13 | echo "Skipping quartus check." 14 | else 15 | # Check if quartus is in the PATH. 16 | if ! command -v quartus &> /dev/null; then 17 | echo -e "${RED}quartus not in PATH. Add it to PATH and try again.${NC}" 18 | exit 1 19 | fi 20 | 21 | # Check if quartus_pgm is in the PATH. 22 | if ! command -v quartus_pgm &> /dev/null; then 23 | echo-e "${RED}quartus_pgm not in PATH. Add it to PATH and try again.${NC}" 24 | exit 1 25 | fi 26 | fi 27 | 28 | # if .setup_done exists, then setup has already been run. 29 | if [ -f $SETUP_DONE_PATH ]; then 30 | echo "Setup has already been run. If you want to re-run the setup, delete" \ 31 | "$SETUP_DONE_PATH and run this script again." 32 | exit 0 33 | fi 34 | 35 | # Check if apt-get is available. If yes, install dependencies. 36 | if command -v apt-get &> /dev/null; then 37 | # Update if more than a month has passed since last update. 38 | last_update=$(stat -c %Y /var/cache/apt/pkgcache.bin) 39 | now=$(date +%s) 40 | if [ $((now - last_update)) -gt 2592000 ]; then 41 | sudo apt-get update -y 42 | fi 43 | sudo apt-get install -y \ 44 | python3-pip \ 45 | python3-setuptools \ 46 | python3-wheel \ 47 | gcc-9 \ 48 | g++-9 \ 49 | libpcap-dev \ 50 | wget 51 | else 52 | echo "apt-get not found. Please install dependencies manually." 53 | fi 54 | 55 | 56 | sudo python3 -m pip install meson ninja 57 | 58 | echo "Using python3 from $(which python3)" 59 | 60 | cd $SCRIPT_DIR 61 | python3 -m pip install -r requirements.txt 62 | 63 | # If the bitstream file is not present, download it. 64 | if [ ! -f "scripts/enso.sof" ]; then 65 | ./scripts/update_bitstream.sh --download 66 | else 67 | echo "Using existing bitstream file." 68 | fi 69 | 70 | # Setup the software. 71 | ./scripts/sw_setup.sh 16384 32768 true 72 | return_code=$? 73 | 74 | if [ $return_code -ne 0 ]; then 75 | echo -e "${RED}Failed to setup software.${NC}" 76 | exit 1 77 | fi 78 | 79 | touch $SETUP_DONE_PATH 80 | -------------------------------------------------------------------------------- /software/.gitignore: -------------------------------------------------------------------------------- 1 | build* 2 | -------------------------------------------------------------------------------- /software/examples/example_helpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022, Carnegie Mellon University 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted (subject to the limitations in the disclaimer 6 | * below) provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 11 | * * 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 | * * 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 | * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 20 | * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 22 | * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #ifndef SOFTWARE_EXAMPLES_EXAMPLE_HELPERS_H_ 34 | #define SOFTWARE_EXAMPLES_EXAMPLE_HELPERS_H_ 35 | 36 | #include 37 | 38 | #include 39 | 40 | const uint32_t kBaseIpAddress = ntohl(inet_addr("192.168.0.0")); 41 | const uint32_t kDstPort = 80; 42 | const uint32_t kProtocol = 0x11; 43 | 44 | #endif // SOFTWARE_EXAMPLES_EXAMPLE_HELPERS_H_ 45 | -------------------------------------------------------------------------------- /software/examples/meson.build: -------------------------------------------------------------------------------- 1 | 2 | thread_dep = dependency('threads') 3 | pcap_dep = dependency('pcap', version : '>=1.0') 4 | 5 | executable('echo', 'echo.cpp', dependencies: thread_dep, link_with: enso_lib, 6 | include_directories: inc) 7 | executable('echo_event', 'echo_event.cpp', dependencies: thread_dep, 8 | link_with: enso_lib, include_directories: inc) 9 | executable('echo_prefetch', 'echo_prefetch.cpp', dependencies: thread_dep, 10 | link_with: enso_lib, include_directories: inc) 11 | executable('echo_copy', 'echo_copy.cpp', dependencies: thread_dep, 12 | link_with: enso_lib, include_directories: inc) 13 | executable('ensogen', 'ensogen.cpp', dependencies: [thread_dep, pcap_dep], 14 | link_with: enso_lib, include_directories: inc) 15 | executable('capture', 'capture.cpp', dependencies: [thread_dep, pcap_dep], 16 | link_with: enso_lib, include_directories: inc) 17 | executable('l2_forward', 'l2_forward.cpp', dependencies: thread_dep, 18 | link_with: enso_lib, include_directories: inc) 19 | -------------------------------------------------------------------------------- /software/include/enso/ixy_helpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017, Paul Emmerich 3 | * Copyright (c) 2023, Hugo Sadok 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, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /** 33 | * @file 34 | * @brief Helper functions adapted from the 35 | * [ixy driver](https://github.com/emmericp/ixy/blob/master/src/memory.c) 36 | */ 37 | 38 | #ifndef SOFTWARE_INCLUDE_ENSO_IXY_HELPERS_H_ 39 | #define SOFTWARE_INCLUDE_ENSO_IXY_HELPERS_H_ 40 | 41 | #include 42 | #include 43 | 44 | namespace enso { 45 | 46 | /** 47 | * Converts a virtual address to a physical address. 48 | * 49 | * @param virt The virtual address to convert. 50 | * @return The physical address. 51 | */ 52 | uint64_t virt_to_phys(void* virt); 53 | 54 | /** 55 | * Allocates a huge page and returns a pointer to it. 56 | * 57 | * Huge pages are allocated to be `kBufPageSize` bytes in size. 58 | * 59 | * @param path Path to huge page file. 60 | * @param size The size of the huge page to be allocated. If 0, defaults to 61 | * `kBufPageSize`. 62 | * @param mirror Whether to mirror the huge page or not. Mirroring means that 63 | * the same page is mapped again right after the allocated memory. 64 | * This is useful to handle wrap-around in the buffers. Defaults 65 | * to false. 66 | * @return A pointer to the allocated huge page. 67 | */ 68 | void* get_huge_page(const std::string& path, size_t size = 0, 69 | bool mirror = false); 70 | 71 | } // namespace enso 72 | 73 | #endif // SOFTWARE_INCLUDE_ENSO_IXY_HELPERS_H_ 74 | -------------------------------------------------------------------------------- /software/include/enso/meson.build: -------------------------------------------------------------------------------- 1 | public_enso_headers = files( 2 | 'config.h', 3 | 'consts.h', 4 | 'helpers.h', 5 | 'ixy_helpers.h', 6 | 'internals.h', 7 | 'queue.h', 8 | 'pipe.h', 9 | 'socket.h' 10 | ) 11 | 12 | install_headers(public_enso_headers, subdir: 'enso') 13 | -------------------------------------------------------------------------------- /software/include/meson.build: -------------------------------------------------------------------------------- 1 | 2 | public_headers = files( 3 | 4 | ) # Add new headers here. 5 | 6 | install_headers(public_headers) 7 | 8 | subdir('enso') 9 | -------------------------------------------------------------------------------- /software/kernel/intel_fpga_pcie_ip_params.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018, Intel Corporation. 3 | * Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack 4 | * words and logos are trademarks of Intel Corporation or its subsidiaries 5 | * in the U.S. and/or other countries. Other marks and brands may be 6 | * claimed as the property of others. See Trademarks on intel.com for 7 | * full list of Intel trademarks or the Trademarks & Brands Names Database 8 | * (if Intel) or see www.intel.com/legal (if Altera). 9 | * All rights reserved. 10 | * 11 | * This software is available to you under a choice of one of two 12 | * licenses. You may choose to be licensed under the terms of the GNU 13 | * General Public License (GPL) Version 2, available from the file 14 | * COPYING in the main directory of this source tree, or the 15 | * BSD 3-Clause license below: 16 | * 17 | * Redistribution and use in source and binary forms, with or 18 | * without modification, are permitted provided that the following 19 | * conditions are met: 20 | * 21 | * - Redistributions of source code must retain the above 22 | * copyright notice, this list of conditions and the following 23 | * disclaimer. 24 | * 25 | * - Redistributions in binary form must reproduce the above 26 | * copyright notice, this list of conditions and the following 27 | * disclaimer in the documentation and/or other materials 28 | * provided with the distribution. 29 | * 30 | * - Neither Intel nor the names of its contributors may be 31 | * used to endorse or promote products derived from this 32 | * software without specific prior written permission. 33 | * 34 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 35 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 36 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 37 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 38 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 39 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 40 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 41 | * SOFTWARE. 42 | */ 43 | 44 | // AUTOGENERATED BY QSYS_GENERATE, DO NOT MODIFY 45 | 46 | #ifndef SOFTWARE_KERNEL_INTEL_FPGA_PCIE_IP_PARAMS_H_ 47 | #define SOFTWARE_KERNEL_INTEL_FPGA_PCIE_IP_PARAMS_H_ 48 | 49 | #define RXM 0 50 | #define HPRXM 1 51 | #define BAM 2 52 | 53 | #define BAR0_TYPE BAM 54 | #define BAR1_TYPE BAM 55 | #define BAR2_TYPE BAM 56 | #define BAR3_TYPE BAM 57 | #define BAR4_TYPE BAM 58 | #define BAR5_TYPE BAM 59 | 60 | #define DMA_SUPPORTED 1 61 | // 1 == g3x8 and below; 4 == g3x16 62 | #define DMA_VERSION_MAJOR 4 63 | 64 | #endif // SOFTWARE_KERNEL_INTEL_FPGA_PCIE_IP_PARAMS_H_ 65 | -------------------------------------------------------------------------------- /software/kernel/linux/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | .intel_fpga_pcie*.cmd 3 | *.ko 4 | *.ur-safe 5 | Module.symvers 6 | modules.order 7 | .cache.mk 8 | .tmp_versions 9 | -------------------------------------------------------------------------------- /software/kernel/linux/Makefile: -------------------------------------------------------------------------------- 1 | MODULE_NAME := intel_fpga_pcie_drv 2 | obj-m += $(MODULE_NAME).o 3 | $(MODULE_NAME)-y := intel_fpga_pcie_chr.o intel_fpga_pcie_dma.o \ 4 | intel_fpga_pcie_setup.o intel_fpga_pcie_ioctl.o event_queue.o \ 5 | event_handler.o 6 | USE_AVX ?= 0 7 | 8 | PWD := $(shell pwd) 9 | KDIR ?= /lib/modules/$(shell uname -r)/build 10 | CPPFLAGS += -include $(KDIR)/include/generated/autoconf.h 11 | EXTRA_CFLAGS += -Wall -Werror 12 | 13 | ifeq ($(USE_AVX), 1) 14 | # Enable wide accesses up to 32B 15 | EXTRA_CFLAGS += -mavx -mpreferred-stack-boundary=4 16 | endif 17 | 18 | all: 19 | $(MAKE) -C $(KDIR) M=$(PWD) modules 20 | 21 | clean: 22 | $(MAKE) -C $(KDIR) M=$(PWD) clean 23 | -------------------------------------------------------------------------------- /software/kernel/linux/event_handler.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Carnegie Mellon University 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted (subject to the limitations in the disclaimer 6 | * below) provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 11 | * * 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 | * * 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 | * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 20 | * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 22 | * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #include "event_handler.h" 34 | 35 | #include 36 | 37 | int handle_event(int queue_id) { 38 | // printk("Processing event for queue %i\n", queue_id); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /software/kernel/linux/event_handler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Carnegie Mellon University 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted (subject to the limitations in the disclaimer 6 | * below) provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 11 | * * 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 | * * 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 | * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 20 | * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 22 | * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #ifndef SOFTWARE_KERNEL_LINUX_EVENT_HANDLER_H_ 34 | #define SOFTWARE_KERNEL_LINUX_EVENT_HANDLER_H_ 35 | 36 | int handle_event(int queue_id); 37 | 38 | #endif // SOFTWARE_KERNEL_LINUX_EVENT_HANDLER_H_ 39 | -------------------------------------------------------------------------------- /software/kernel/linux/event_queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Carnegie Mellon University 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted (subject to the limitations in the disclaimer 6 | * below) provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 11 | * * 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 | * * 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 | * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 20 | * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 22 | * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #include "event_queue.h" 34 | 35 | #include "event_handler.h" 36 | #include "intel_fpga_pcie_setup.h" 37 | 38 | // HACK(sadok) number of queues should not be fixed 39 | #define NB_QUEUES 2 40 | 41 | int event_queue_loop(event_kthread_data_t* data) { 42 | int queue_id = 0; 43 | while (!kthread_should_stop()) { 44 | // FIXME(sadok) this is a very generous sleep that we should remove when 45 | // doing something useful here 46 | // we can also pass a condition here instead of 0 47 | wait_event_timeout(data->queue, 0, HZ); 48 | 49 | handle_event(queue_id); 50 | 51 | // FIXME(sadok) We are making up events 52 | queue_id = (queue_id + 1) % NB_QUEUES; 53 | } 54 | return 0; 55 | } 56 | 57 | int launch_event_kthread(void) { 58 | init_waitqueue_head(&global_bk.event_kthread_data.queue); 59 | 60 | global_bk.event_kthread_data.task = kthread_create_on_node( 61 | (int (*)(void*))event_queue_loop, &global_bk.event_kthread_data, 62 | NUMA_NO_NODE, // TODO(sadok) we can bind the kthread to a cpu 63 | "event_queue_loop"); 64 | 65 | if (global_bk.event_kthread_data.task <= 0) { 66 | return -1; 67 | } 68 | 69 | wake_up_process(global_bk.event_kthread_data.task); 70 | 71 | return 0; 72 | } 73 | 74 | void stop_event_kthread(void) { 75 | kthread_stop(global_bk.event_kthread_data.task); 76 | } 77 | -------------------------------------------------------------------------------- /software/kernel/linux/event_queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Carnegie Mellon University 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted (subject to the limitations in the disclaimer 6 | * below) provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 11 | * * 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 | * * 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 | * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 20 | * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 21 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 22 | * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #ifndef SOFTWARE_KERNEL_LINUX_EVENT_QUEUE_H_ 34 | #define SOFTWARE_KERNEL_LINUX_EVENT_QUEUE_H_ 35 | 36 | #include 37 | 38 | typedef struct kthread_struct { 39 | wait_queue_head_t queue; 40 | struct task_struct* task; 41 | } event_kthread_data_t; 42 | 43 | int event_queue_loop(event_kthread_data_t* data); 44 | int launch_event_kthread(void); 45 | void stop_event_kthread(void); 46 | 47 | #endif // SOFTWARE_KERNEL_LINUX_EVENT_QUEUE_H_ 48 | -------------------------------------------------------------------------------- /software/kernel/linux/install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | make 3 | if [[ `lsmod | grep -o intel_fpga_pcie_drv` ]] 4 | then 5 | echo "Unloading previous module" 6 | ./unload 7 | fi 8 | echo "Loading module" 9 | ./load 10 | -------------------------------------------------------------------------------- /software/kernel/linux/intel_fpga_pcie_drv.mod.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017-2018 Intel Corporation. 2 | // 3 | // Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words 4 | // and logos are trademarks of Intel Corporation or its subsidiaries in the 5 | // U.S. and/or other countries. Other marks and brands may be claimed as the 6 | // property of others. See Trademarks on intel.com for full list of Intel 7 | // trademarks or the Trademarks & Brands Names Database (if Intel) or see 8 | // www.intel.com/legal (if Altera). Your use of Intel Corporation's design 9 | // tools, logic functions and other software and tools, and its AMPP partner 10 | // logic functions, and any output files any of the foregoing (including 11 | // device programming or simulation files), and any associated documentation 12 | // or information are expressly subject to the terms and conditions of the 13 | // Altera Program License Subscription Agreement, Intel MegaCore Function 14 | // License Agreement, or other applicable license agreement, including, 15 | // without limitation, that your use is for the sole purpose of programming 16 | // logic devices manufactured by Intel and sold by Intel or its authorized 17 | // distributors. Please refer to the applicable agreement for further details. 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | MODULE_INFO(vermagic, VERMAGIC_STRING); 24 | MODULE_INFO(name, KBUILD_MODNAME); 25 | 26 | __visible struct module __this_module 27 | __attribute__((section(".gnu.linkonce.this_module"))) = { 28 | .name = KBUILD_MODNAME, 29 | .init = init_module, 30 | #ifdef CONFIG_MODULE_UNLOAD 31 | .exit = cleanup_module, 32 | #endif 33 | .arch = MODULE_ARCH_INIT, 34 | }; 35 | 36 | #ifdef CONFIG_RETPOLINE 37 | MODULE_INFO(retpoline, "Y"); 38 | #endif 39 | 40 | static const char __module_depends[] __used 41 | __attribute__((section(".modinfo"))) = "depends=uio"; 42 | 43 | MODULE_ALIAS("pci:v00001172d*sv*sd*bc*sc*i*"); 44 | 45 | MODULE_INFO(srcversion, "5DF3FFEA146BA522A377EC8"); 46 | -------------------------------------------------------------------------------- /software/kernel/linux/load: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | module="intel_fpga_pcie_drv" 4 | device="intel_fpga_pcie_drv" 5 | mode="666" 6 | 7 | # make sure uio module is loaded 8 | sudo modprobe uio 9 | 10 | # load the module 11 | sudo /sbin/insmod ./$module.ko $* || exit 1 12 | 13 | # Add device manually in case udev isn't set up to do so. 14 | if [ ! -e /dev/$device ]; then 15 | major=`grep -w $device /proc/devices | cut -f1 -d" "` 16 | sudo mknod /dev/$device c $major 0 17 | fi 18 | 19 | # change permissions to allow all users to read/write 20 | sudo chmod $mode /dev/$device 21 | -------------------------------------------------------------------------------- /software/kernel/linux/unload: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo rmmod intel_fpga_pcie_drv 3 | 4 | # Remove device manually in case udev isn't set up to do so. 5 | sudo rm -f /dev/intel_fpga_pcie_drv 6 | -------------------------------------------------------------------------------- /software/meson.build: -------------------------------------------------------------------------------- 1 | inc = include_directories('include') 2 | 3 | subdir('include') 4 | subdir('src') 5 | 6 | if dev_backend == 'intel_fpga' 7 | library_name = 'enso' 8 | elif dev_backend == 'software' 9 | library_name = 'enso_sw' 10 | else 11 | error('Unknown backend') 12 | endif 13 | 14 | enso_lib = library(library_name, project_sources, install: true, 15 | include_directories: [inc, backend_inc]) 16 | pkg_mod = import('pkgconfig') 17 | pkg_mod.generate(enso_lib) 18 | 19 | subdir('examples') 20 | subdir('test') 21 | -------------------------------------------------------------------------------- /software/src/backends/intel_fpga/linux/meson.build: -------------------------------------------------------------------------------- 1 | 2 | intel_fpga_linux_sources = files( 3 | 'intel_fpga_pcie_api_linux.cpp', 4 | ) 5 | 6 | project_sources += intel_fpga_linux_sources 7 | -------------------------------------------------------------------------------- /software/src/backends/intel_fpga/meson.build: -------------------------------------------------------------------------------- 1 | subdir('linux') 2 | -------------------------------------------------------------------------------- /software/src/backends/meson.build: -------------------------------------------------------------------------------- 1 | subdir(dev_backend) 2 | 3 | backend_inc = include_directories(dev_backend) 4 | -------------------------------------------------------------------------------- /software/src/backends/software/meson.build: -------------------------------------------------------------------------------- 1 | 2 | software_backend_sources = files( 3 | ) 4 | 5 | project_sources += software_backend_sources 6 | -------------------------------------------------------------------------------- /software/src/enso/meson.build: -------------------------------------------------------------------------------- 1 | 2 | enso_sources = files( 3 | 'config.cpp', 4 | 'helpers.cpp', 5 | 'ixy_helpers.cpp', 6 | 'pipe.cpp', 7 | 'socket.cpp', 8 | ) 9 | 10 | project_sources += enso_sources 11 | -------------------------------------------------------------------------------- /software/src/meson.build: -------------------------------------------------------------------------------- 1 | 2 | add_global_arguments(['-mavx'], language: ['c', 'cpp']) 3 | 4 | project_sources = [] 5 | project_libraries = [] 6 | 7 | subdir('enso') 8 | subdir('backends') 9 | 10 | project_sources += files( 11 | 'pcie.cpp' 12 | ) 13 | -------------------------------------------------------------------------------- /software/test/meson.build: -------------------------------------------------------------------------------- 1 | 2 | gtest_main_dep = dependency('gtest_main', version: ['>=1.13.0', '<1.14.0'], 3 | fallback : ['gtest', 'gtest_main_dep']) 4 | 5 | test_deps = [ 6 | gtest_main_dep 7 | ] 8 | 9 | queue_test = executable('queue_test', 'queue_test.cpp', 10 | dependencies: test_deps, link_with: enso_lib, 11 | include_directories: inc) 12 | 13 | test('queue_test', queue_test) 14 | -------------------------------------------------------------------------------- /subprojects/gtest.wrap: -------------------------------------------------------------------------------- 1 | [wrap-file] 2 | directory = googletest-1.13.0 3 | source_url = https://github.com/google/googletest/archive/refs/tags/v1.13.0.tar.gz 4 | source_filename = gtest-1.13.0.tar.gz 5 | source_hash = ad7fdba11ea011c1d925b3289cf4af2c66a352e18d4c7264392fead75e919363 6 | patch_filename = gtest_1.13.0-1_patch.zip 7 | patch_url = https://wrapdb.mesonbuild.com/v2/gtest_1.13.0-1/get_patch 8 | patch_hash = 6d82a02c3a45071cea989983bf6becde801cbbfd29196ba30dada0215393b082 9 | wrapdb_version = 1.13.0-1 10 | 11 | [provide] 12 | gtest = gtest_dep 13 | gtest_main = gtest_main_dep 14 | gmock = gmock_dep 15 | gmock_main = gmock_main_dep 16 | -------------------------------------------------------------------------------- /synthesize.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Usage: ./synthesize.sh [seed1] [seed2] ... 3 | # Syntheizes hardware. Launches as many workers as seeds that you specify. 4 | 5 | PROJECT_NAME="enso" 6 | 7 | SEEDS=${@:-0} 8 | NUMBER_SEEDS=$# 9 | 10 | CUR_DIR=$(pwd) 11 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 12 | SCRIPTS_DIR=$SCRIPT_DIR/scripts 13 | PROJECT_DIR=$SCRIPT_DIR/hardware 14 | 15 | # Exit when error occurs. 16 | set -e 17 | trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG 18 | trap 'echo "\"${last_command}\" command exited with code $?."' EXIT 19 | 20 | if [[ $NUMBER_SEEDS -gt 1 ]]; then 21 | if ! command -v parallel &> /dev/null; then 22 | echo "Error: GNU Parallel is not installed." 23 | echo "You need GNU Parallel to run multiple seeds." 24 | exit 1 25 | fi 26 | fi 27 | 28 | # Run synthesis. 29 | cd $PROJECT_DIR/quartus 30 | 31 | # Generate IPs if necessary. 32 | quartus_ipgenerate $PROJECT_NAME 33 | 34 | # We must copy the pcie_generic_component_0.v.template to the correct location. 35 | cp $PROJECT_DIR/ip/pcie_generic_component_0.v.template \ 36 | $PROJECT_DIR/ip/pcie_ed/generic_component_0/synth/generic_component_0.v 37 | 38 | # Enable/disable signal tap. 39 | # quartus_stp alt_ehipc2_hw --stp_file stp1.stp --enable 40 | # quartus_stp alt_ehipc2_hw --stp_file stp1.stp --disable 41 | 42 | quartus_syn --read_settings_files=on --write_settings_files=off $PROJECT_NAME \ 43 | -c $PROJECT_NAME 44 | 45 | # We need to go back to original directory to make sure we save the bitstream 46 | # to the correct directory. 47 | cd - 48 | 49 | # Check number of SEEDS. If more than one, run in parallel. 50 | if [[ $NUMBER_SEEDS -gt 1 ]]; then 51 | parallel --tmux \ 52 | "${SCRIPTS_DIR}/quartus_fit_save.sh {} ${bitstream_destination}" ::: $SEEDS 53 | else 54 | source ${SCRIPTS_DIR}/quartus_fit_save.sh $SEEDS $bitstream_destination 55 | fi 56 | --------------------------------------------------------------------------------