{"id":33105992,"url":"https://github.com/rprinz08/hBPF","last_synced_at":"2025-11-15T05:01:26.330Z","repository":{"id":42506847,"uuid":"354273285","full_name":"rprinz08/hBPF","owner":"rprinz08","description":"hBPF = eBPF in hardware","archived":false,"fork":false,"pushed_at":"2023-01-27T12:01:25.000Z","size":8797,"stargazers_count":414,"open_issues_count":0,"forks_count":24,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-06-02T08:17:50.940Z","etag":null,"topics":["ebpf","fpga","litex","migen","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rprinz08.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-03T11:24:04.000Z","updated_at":"2025-04-17T16:44:47.000Z","dependencies_parsed_at":"2023-02-15T09:00:45.455Z","dependency_job_id":null,"html_url":"https://github.com/rprinz08/hBPF","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rprinz08/hBPF","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rprinz08%2FhBPF","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rprinz08%2FhBPF/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rprinz08%2FhBPF/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rprinz08%2FhBPF/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rprinz08","download_url":"https://codeload.github.com/rprinz08/hBPF/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rprinz08%2FhBPF/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284507666,"owners_count":27017331,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-15T02:00:06.050Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ebpf","fpga","litex","migen","python3"],"created_at":"2025-11-14T23:00:30.092Z","updated_at":"2025-11-15T05:01:26.324Z","avatar_url":"https://github.com/rprinz08.png","language":"Python","funding_links":[],"categories":["Articles and Presentations","文章和演示"],"sub_categories":["Hardware Offload","硬件卸载"],"readme":"# hBPF = eBPF in hardware\n\n![](doc/images/hbpf-logo-l.png)\n\nAn [extended Berkley Packet Filter (eBPF)](https://ebpf.io/)\nCPU written entirely in [Python3](https://www.python.org/)\nfor PC and FPGA.\n\n## History\n\nBack in 1992 the original [Berkeley Packet Filter (BPF)](http://www.tcpdump.org/papers/bpf-usenix93.pdf)\nwas designed\nfor capturing and filtering network packets that matched\nspecific rules. Filters are implemented as programs to be run\non a register-based virtual RISC machine providing a small\nnumber of instructions inside the Linux Kernel.\n\nSoon it became clear that extending the Kernel by\nuser-supplied programs proves to be useful. But the design of\nthe virtual machine e.g instruction set (ISA) or register\nwidth (32-bit vs. 64-bit) couldn't keep up with the demands.\n\nAt some point [in 2014](https://lwn.net/Articles/599755/),\nwork to extend the existing BPF virtual machine started to\nmake it useful in other parts of the Linux Kernel. More,\nwider registers, additional instructions and a JIT eventually\nresulted in [extended BPF](https://ebpf.io/). The original\nand now obsolete BPF version has been retroactively renamed\nto __classic BPF (cBPF)__. Nowadays, the Linux Kernel runs\neBPF only and loaded cBPF bytecode is transparently\ntranslated into eBPF before execution.\n\nFurther information can be found in the\n[eBPF specification](https://github.com/ebpffoundation/ebpf-docs) or in the [Linux Kernel documentation](https://docs.kernel.org/bpf/index.html).\n\nThe *hBPF* project now implements most of eBPF features in\nhardware (FPGA).\n\n## Goals\n\nThis project was started beginning of 2021 as an experiment\nof how fast and how far you can get, with using alternate\nhardware description languages (compared to the classic 'V'\nlanguages VHDL and Verilog), most of the time open-source\ntools (compared to expensive, commercial toolchains) and\ncheap development boards (e.g [Arty-S7](https://reference.digilentinc.com/reference/programmable-logic/arty-s7/start)).\n\nIt is not meant to compete with multi-core accelerator cards\nlike [Xilinx Alveo](https://www.xilinx.com/products/boards-and-kits/alveo.html), instead its used to gain\ninsights and perform experiments.\n\n## Current State\n\n* All unit-tests pass\n* Can process binaries created with assembler or C (LLVM) without any changes\n* Partially optimized\n    * This is a constant work in progress ...\n    * Statistic information per test case is collected as described [here](doc/statistics.md).\n    * Clock cycles per op-code are [available here](doc/opcodes.md).\n\n  Many op-codes require 1 clock cycle, jumps (conditional and unconditional) require 2 clock cycles and math op-codes like `mod` or `div` require the most clock cycles to complete.\n\n* no stack\n\nAdditional infos can be found in the [Blog](https://www.min.at/hbpf).\n\nTested with:\n\nMigen Git commit: 9a0be7a4210ff96043412539eb5388659b81831d\n\nLiteX Git commit: 85d6cb4b8df98730bd83b412dff6108df188bbb4\n\nLiteETH Git commit: 7acb2a8c1c1abda63496d422d093dc6bbfe135a8\n\n*Note: Ensure that you build hBPF with above Git commits of LiteX/Migen dependencies.*\n\n## Installation\n\nThe following instructions gets you going, assuming no\nrequirements are installed on your system. If some of the\nrequired components are already available then skip the\ncorresponding steps or packages.\n\n```bash\n# Install system dependencies (assuming Debian based distro)\n$ sudo apt install git curl clang llvm python3-pip make xxd \\\n                   libpcap0.8-dev libbpf-dev openocd\n# If you prefer 'hexdump' over of 'xxd'...\n$ sudo apt install bsdmainutils\n```\n\n```bash\n# For ubpf which uses python2\n$ sudo apt install python-pip\n$ pip install --user -r tools/ubpf/requirements.txt\n```\n\n```bash\n# Python3 dependencies\n$ pip3 install --user colour_runner\n$ pip3 install --user git+https://github.com/javawizard/parcon\n```\n\n*Note: Included submodule `ubpf` requires Python Parcon module. Dont install Parcon via\n`pip3 install --user parcon` but install directly from git via\n`pip3 install --user git+https://github.com/javawizard/parcon` as shown\nabove.*\n\n*Note: Depending on your installed Python version (e.g. \u003e 3.7) there might be\nan issue with Parcon module from git repo. In this case you will get\n`dummy_threading` errors when building. There is a\n[pull request #22](https://github.com/javawizard/parcon/pull/22) which\nfixes this. Alternatively you can install Parcon with:*\n\n```bash\n$ pip3 install --user git+https://github.com/rprinz08/parcon\n```\n\n```bash\n# Install rust - needed to compile tools\n# See additional infos at:\n# https://www.rust-lang.org/tools/install\n$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n$ source $HOME/.cargo/env\n```\n\n```bash\n# Create project root folder (e.g. projects)\n$ mkdir -p projects\n$ cd projects\n```\n\n```bash\n# Install Litex\n# See additional infos at:\n# https://github.com/enjoy-digital/litex\n$ mkdir litex\n$ cd litex\n$ curl -o litex_setup.py https://raw.githubusercontent.com/enjoy-digital/litex/master/litex_setup.py\n$ chmod +x litex_setup.py\n$ ./litex_setup.py init install --user\n```\n\n```bash\n# Install hBPF\n$ cd ..\n$ git clone https://github.com/rprinz08/hBPF.git\n$ cd hbpf\n$ git submodule init\n$ git submodule update\n```\n\n```bash\n# Compile Tools\n$ cd tools/rust-cbpf\n$ cargo build\n$ cd ../wishbone-utils/wishbone-tool\n$ cargo build\n```\n\n```bash\n# run Tests in tests folder\n$ cd ../../../tests\n\n# Test CPU emulator:\n# This completes fast\n$ ./test_vm.py\n\n# Test FPGA simulation:\n# This takes time ......\n$ ./test_fpga_sim.py\n\n# Test hardware:\n# This needs an FPGA board ....\n# (ensure that you change the configuration at the top of this\n# file to match your target hardware)\n$ ./test_fpga_hw.py\n```\n\nFor working with hardware you need in addition to the above,\na toolchain which supports your board/target.\nThis project includes two boards/targets from\nXilinx so to build the FPGA bitstreams yourself\nyou have to install [Xilinx Vivado](https://www.xilinx.com/products/design-tools/vivado.html).\n\n*Note: Prebuilt bitstreams for included targets are provided.*\n\n## Overview\n\nThe main purpose of implementing an eBPF CPU in hardware is\nthe same as that of the original cBPF: processing network\npackets.\n\nBy attaching a hBPF CPU directly to a network PHY/MAC a form\nof a [smart NIC](https://blog.mellanox.com/2018/08/defining-smartnic/) could be created. Such a NIC is capable\nto perform tasks on packets offloaded by the host CPU for\nperformance reasons.\n\nBut a hBPF CPU has most necessary features so it can even be\nused standalone as a simple microcontroller.\n\nThe following picture shows an overview of how hBPF can be\nused.\n\n![hBPF overview](doc/images/hbpf-overview.png)\n\nhBPF is implemented using the [LiteX](https://github.com/enjoy-digital/litex)\nSoC builder framework. LiteX itself is based on [Migen](https://github.com/m-labs/migen), a toolbox to create FPGA designs in Python3.\n\n![hBPF CPU](doc/images/cpu.png)\n\nThe hBPF CPU has access to separated program- and data-memory\n([Harvard architecture](https://en.wikipedia.org/wiki/Harvard_architecture)).\nData-memory (8-Bit) holds network\npackets (defaults to 2048 bytes) which are processed based on the\ninstructions in program memory (64-Bit, defaults to 1024 bytes).\n\nAt the moment the `/reset` signals goes HIGH,\nthe CPU starts processing instructions read\nfrom program memory.\nWhen processing the `exit` instruction, the `halt`\nsignal goes high and the CPU stops processing\ninstructions. Whenever an error occurs (e.g\ndivision by 0, invalid instruction etc.) the\n`error` signal is set HIGH and the CPU stops\nprocessing instructions setting signal `halt`\nHIGH as well.\n\nRegisters R1 - R5 are not cleared on reset and can be used\nas input arguments to a program, register R0 is used to\nreturn something. The same mechanism is also used when\ncalling FPGA extensions by using [call-handlers](doc/call_handler.md).\n\nWhen CPU starts, internal `ticks` register is\ncleared and incremented every clock tick until CPU\nhalts which can be used to measure execution speed.\n\nThe **math.divider** submodule contains decimal divider and\nthe **math.shifter** a left/right shifter including arithmetic\nshifts.\n\nThe project includes the following components:\n\n### Emulator\n\nTo get a better understanding of how eBPF works an emulator\nwas developed in Python3. It implements a complete eBPF CPU\nin Python and was a playground to try out concepts and\nexperiment with opcodes. The emulator code itself is not used\nin the FPGA implementations.\n\n### Simulator\n\nThe FPGA implementation of hBPF was done using LiteX and Migen\ntools. The same Python3 code which later is converted\nto Verilog can be tested with the simulation capabilities\nfrom LiteX.\n\n### FPGA Implementations\n\nThe LiteX hBPF implementation can be converted to\nVerilog and processed by toolchains for various\ntarget devices and boards. Included are three real\nhardware implementations for Xilinx devices\n(Spartan7, Artix7 and Zynq) on\n[Arty-S7](https://digilent.com/reference/programmable-logic/arty-s7/start),\n[Arty-A7](https://digilent.com/reference/programmable-logic/arty-a7/start) and\n[Zybo-Z7](https://digilent.com/reference/programmable-logic/zybo-z7/start) boards.\n\nBased on the following overview, they can be used to\ntest and debug hBPF and also to run the HW\nunit-tests as described under *testing* further\ndown. They are not connected to an Ethernet PHY/MAC at the moment. Next samples will show how to use LiteETH to process real network packets.\n\n![test-overview](doc/images/hbpf-debug-overview.png)\n\nEach implementation requires about 10500 LUTs\nincluding Wishbone Bridge and LiteScope Debugger.\nThe CPU core alone requires about 8000 LUTs. Both\nimplementations were tested with 100MHz.\n\n### Deviations from eBPF\n\nIn contrast to the eBPF implementation used in the Linux\nKernel, hBPF has some deviations and differences.\n\n#### Calls\n\nIn eBPF, the `call` instruction is used to call selected\nsubroutines in the Linux Kernel (so called *Helper Functions*). In the hBPF implementation, the `call` opcode can be used to extend the CPU by means of [call-handlers](doc/call_handler.md).\n\n#### Register R1\n\nIn the Linux eBPF implementation register R1 is used as base\npointer to the data-memory. This is not necessary for hBPF so\nregister R1 is used as input argument just as R2 - R5.\n\n#### Stack\n\nNot supported at the moment.\n\n## Development\n\nThis section is divided in two parts:\n\n* Developing hBPF\n\n    describes how to develop hBPF itself, modifying or extending it.\n\n* Developing for hBPF\n\n    describes how to develop software which runs on a hBPF (or eBPF) CPU.\n\n## Developing hBPF\n\n### Requirements\n\nhBPF is completely written in Python3 and uses the following tools:\n\n* [Python3](https://www.python.org/)\n* [LiteX](https://github.com/enjoy-digital/litex)\n* [userspace BPF (uBPF)](https://github.com/iovisor/ubpf)\n* [cbpf-rust](https://github.com/mmisono/rust-cbpf)\n* [wishbone-utils](https://github.com/litex-hub/wishbone-utils)\n* FPGA Toolchain (e.g. [Xilinx Vivado](https://www.xilinx.com/products/design-tools/vivado.html))\n* [OpenOCD](http://openocd.org/) to load/flash FPGA targets (can normally be done by toolchain but OpenOCD is simpler and faster)\n* [VS-Code](https://code.visualstudio.com/) as IDE and Test-runner\n\n### Building\n\nAssuming you have all prerequisites installed and their\nbinaries are available via search path, perform the following\nsteps:\n\n1. check out hBPFs Git repository\n\n2. open hBPF repository folder in VS-Code\n\n   * start developing\n\n3. run unit-tests either inside VS-Code or direct from the command line.\n\n4. to build an FPGA bitstream for a real hardware target, select a target in `source/fpga/hw` folder and run `build.py`.\n\n### Testing\n\nAll three hBPF implementations can be tested using\ncomprehensive unit-tests. All based on the same set of test\ncases. To accomplish this, the Python based eBPF assembler of\nthe [userspace BPF (uBPF)](https://github.com/iovisor/ubpf) project is used.\n\nUnit-tests can either be run from inside VS-Code or direct\nfrom command line in `tests` folder.\n\n* `test_vm.py` - run test cases against emulated CPU (fast)\n* `test_fpga_sim.py` - runs tests against simulated FPGA design (takes long, be patient)\n* `test_fpga_hw.py` - runs test-cases against hBPF CPU running on real hardware via a serial Wishbone bridge (medium fast)\n\nEach test-case consists of a file in the `test` (or one of\nits sub-folders) folder. Test files are text files with a `.test` file extension. It consists of sections starting with\n`--` describing the test. The following test description shows\na Fibonacci test with an `asm` section which is compiled on\nthe fly before the test is executed, an `args` section which\ndefines the input values, a `result` section defining whats\nexpected in register R0 after test completes and an `expected`\nsection which defines additional criteria that must be\nmet like the number of clock cycles the test may take.\n\n```asm\n# Example test case description. Calculating the Fibonacci\n# for provided input in register R1\n-- asm\nmov r0, r1\njeq r1, 0, +11\njeq r1, 1, +9\nmov r3, 0\nmov r0, 1\nmov r2, 2\nmov r4, r0\nadd r0, r3\nadd r2, 1\nmov r3, r4\njgt r2, r1, +2\nja -6\nmov r0, 1\nexit\n-- args\nr1 = 9\n-- result\n0x22\n-- expected\nclocks = 324\n```\n\nAlso available are a `raw` section which describes a test\nprogram as hex dump and a `mem` section which describes the\ndata-memory as hex dump.\n\nBefore executing a test the `asm` section is compiled to\nbinary and sent to the device under test (either the\nemulator, simulator or hardware). For real hardware this is\ndone using the Wishbone serial bridge. If a `raw` section is\nfound in the test description it is sent after converting to\nbinary from hex dump. Also the data-memory is loaded from the\n`mem` section contents if available.\n\nNext input registers R1-R5 are set according to `args`\nsection. If section is not available or some\nregisters are not set in section then they are set to 0. To\nstart the test the hBPF CPU is brought out of reset by\nsetting `RESET_N` signal to HIGH and monitoring hBPF CPU\nsignals until `HALT` signal goes high or expected clocks\n(when not specified default clocks = 1000) are reached. Then\ncontrol signals and output register R0 are compared against\nthe test definition.\n\nIn addition, statistic information per test case is collected as described\n[here](doc/statistics.md).\n\n## Developing for hBPF\n\nThe existing eBPF development tools (compilers, assemblers,\nfilters) can be used to develop for hBPF. Samples can be found\nin the `development` directory.\n\n## Hardware targets and examples\n\nSome examples on the included targets are provided:\n\nhBPF development targets\n* [Arty S7](source/fpga/hw/arty-s7-50/readme.md)\n* [Arty A7](source/fpga/hw/arty-a7-100/readme.md)\n* [Zybo Z7](source/fpga/hw/zybo-z7-20/readme.md)\n\nPacket processing with LiteETH and hBPF\n* [Arty S7 MultiNIC](source/fpga/hw/arty-s7-50-nic/readme.md)\n* [Arty A7 Network](source/fpga/hw/arty-a7-100-net/readme.md)\n\n## Misc\n\nThis project is by no means complete or error free or\nproduction ready. Feel free to play with it and contribute if\nyou find a bug or thing which could be made better.\n\n### License\n\nThis project is licensed under **BSD 3-Clause License**.\nSee [LICENSE](LICENSE) file.\n\n### Contributing\n\nIf you would like to contribute to hBPF (which we would greatly appreciate)\nplease read the [Contributing Guide](CONTRIBUTING.md) beforehand.\n\n### Code of conduct\n\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)\n\n\nAlso please read the [Code of Conduct](CODE_OF_CONDUCT.md) to keep the hBPF\ncommunity approachable and respectable!\n\n### Logo / Icon\n\n![hBPF Icon](doc/images/hbpf-icon-s.png)\n\nThe **PCbee** (Printed Circuit Board Bee) was created based\non [ebpf.io](ebpf.io)'s bee icon to visualize the hardware\naspect of hBPF.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frprinz08%2FhBPF","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frprinz08%2FhBPF","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frprinz08%2FhBPF/lists"}