Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ on:
branches: [ main ]

jobs:
pipebomb:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4

- name: deps
run: |
sudo apt-get update
sudo apt-get install -y verilator make g++

- name: lint
run: |
cd pipebomb
make lint

- name: test
run: |
cd pipebomb
make test

itch_streamgen:
runs-on: ubuntu-24.04
steps:
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
# punt-engine
is an open-source FPGA-accelerated high-frequency trading engine. See https://punt-engine.com for full documentation.
is an collection of open software and gateware modules for high-frequency trading.

> [!IMPORTANT]
> development paused, resuming dec 2025

## Components
## Modules

### Pipebomb
**P**ipebomb **I**s a **P**ipelined and **E**ventually **B**alanced **O**rder-**M**anaging **B**ook.
Expand All @@ -21,4 +18,7 @@ Learn more by reading the source or [the docs](https://punt-engine.com/notes/the

Most contributors are welcome. Begin by reading through our [docs](https://punt-engine.com) and looking through [open issues tagged "help wanted"](https://github.com/raquentin/punt-engine/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22).

## Resources

1. [Exploring the Potential of Reconfigurable Platforms for Order Book Update](https://www.doc.ic.ac.uk/~wl/papers/17/fpl17ch.pdf)
2. [Xilinx DMA IP Reference drivers](https://github.com/Xilinx/dma_ip_drivers/tree/master)
42 changes: 38 additions & 4 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -1 +1,34 @@
{
description = "punt-engine dev env";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
flake-utils.url = "github:numtide/flake-utils";
};

outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
in {
devShells.default = pkgs.mkShell {
name = "punt-engine";
buildInputs = [
pkgs.verilator
pkgs.yosys
pkgs.verible
pkgs.svls
pkgs.gtkwave
pkgs.gcc
pkgs.cmake
pkgs.pkg-config
];
shellHook = ''
echo "shell ready, $(verilator --version | head -1)"
alias svfmt='verible-verilog-format -inplace'
alias svlint='verible-verilog-lint --ruleset=all'
'';
};
formatter = pkgs.nixpkgs-fmt;
});
}
Empty file removed madlib/examples/gitkeep.cpp
Empty file.
1 change: 1 addition & 0 deletions pipebomb/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
wave.vcd
52 changes: 52 additions & 0 deletions pipebomb/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
TOP ?= pipebomb_top
RTL_DIR ?= ./rtl
TB ?= ./tb/tb_pipebomb_cross.cpp # override with: make sim TB=./tb/other.cpp




TRACE_FMT ?= vcd
ifeq ($(TRACE_FMT),fst)
TRACE_FLAG = --trace-fst
WAVE_FILE = wave.fst
else
TRACE_FLAG = --trace
WAVE_FILE = wave.vcd
endif




VERILATOR_FLAGS = -sv --language 1800-2017 $(TRACE_FLAG) --top-module $(TOP) -I$(RTL_DIR)
CXXFLAGS ?= -std=c++17 -O2

PKG = $(RTL_DIR)/pipebomb_pkg.sv
RTL_ALL = $(filter-out $(PKG),$(wildcard $(RTL_DIR)/*.sv))
SRC_SV = $(PKG) $(RTL_ALL)




.PHONY: all sim test binary lint clean waves help

all: test

obj_dir/V$(TOP): $(SRC_SV) $(TB)
verilator $(VERILATOR_FLAGS) --cc --exe $(SRC_SV) $(TB) -CFLAGS "$(CXXFLAGS)"
$(MAKE) -C obj_dir -f V$(TOP).mk V$(TOP)

sim: obj_dir/V$(TOP)
./obj_dir/V$(TOP)

test: sim
@test -s $(WAVE_FILE) || (echo "Wavefile '$(WAVE_FILE)' missing or empty"; exit 1)
@echo "OK: simulation completed and $(WAVE_FILE) generated."

binary:
verilator $(VERILATOR_FLAGS) --cc --exe --build $(SRC_SV) $(TB) -CFLAGS "$(CXXFLAGS)"

lint:
verilator $(VERILATOR_FLAGS) --lint-only $(SRC_SV)

clean:
rm -rf obj_dir *.vcd *.fst
Empty file removed pipebomb/rtl/.gitkeep
Empty file.
39 changes: 39 additions & 0 deletions pipebomb/rtl/accumulators.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module accumulators #(
parameter int PRICE_W = 48
) (
input logic clk,
rstn,
input logic [PRICE_W-1:0] best_bid_price,
input logic [PRICE_W-1:0] best_ask_price,
input logic best_valid,

output logic [pipebomb_pkg::PRICE_Q_W-1:0] mid_q32_16,
output logic [pipebomb_pkg::PRICE_Q_W-1:0] ema_q32_16,
output logic ema_valid
);
import pipebomb_pkg::*;

// convert integer prices -> Q32.16
logic [PRICE_Q_W-1:0] bid_fx, ask_fx, mid_next;
always_comb begin
bid_fx = {best_bid_price[PRICE_W-1:0], {PRICE_FRAC_W{1'b0}}};
ask_fx = {best_ask_price[PRICE_W-1:0], {PRICE_FRAC_W{1'b0}}};
mid_next = (bid_fx + ask_fx) >> 1;
end

// ema = ema + α*(mid - ema)
// α≈0.04 in Q1.15 (0.04*32768 ≈ 1311)
localparam logic [15:0] ALPHA_Q1_15 = 16'd1311;

always_ff @(posedge clk or negedge rstn) begin
if (!rstn) begin
mid_q32_16 <= '0;
ema_q32_16 <= '0;
ema_valid <= 1'b0;
end else if (best_valid) begin
mid_q32_16 <= mid_next;
ema_q32_16 <= ema_q32_16 + fxmul_q32_16_q1_15(mid_next - ema_q32_16, ALPHA_Q1_15);
ema_valid <= 1'b1;
end
end
endmodule
Loading