#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Class {
EdgeMicro,
Edge,
CloudInstance,
PcieCard,
AcademicCluster,
Salvage,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum OpenFlow {
Full,
Partial,
VendorOnly,
}
pub struct FpgaTarget {
pub name: &'static str,
pub class: Class,
pub luts: u32,
pub lut6: bool,
pub bram_kb: u32,
pub dsp: u32,
pub clock_mhz: (u16, u16),
pub power_w: (f32, f32),
pub price: &'static str,
pub availability: &'static str,
pub open_flow: OpenFlow,
pub provenance: &'static str,
}
impl FpgaTarget {
pub fn est_pbits(&self) -> u32 {
let lut4_eq = if self.lut6 { self.luts as f64 * 1.6 } else { self.luts as f64 };
(lut4_eq / 150.0) as u32
}
pub fn est_flips_per_s(&self) -> f64 {
let mid = 0.5 * (self.clock_mhz.0 as f64 + self.clock_mhz.1 as f64) * 1e6;
let clk = mid.min(33e6);
self.est_pbits() as f64 / 4.0 * clk
}
}
pub const TARGETS: &[FpgaTarget] = &[
FpgaTarget { name: "Lattice iCE40 UP5K", class: Class::EdgeMicro, luts: 5280, lut6: false,
bram_kb: 1144, dsp: 8, clock_mhz: (12, 24), power_w: (0.001, 0.01),
price: "$11 part; UPduino $25-36; iCEBreaker $80 [SWEEP]",
availability: "in stock (DigiKey)", open_flow: OpenFlow::Full,
provenance: "[DS] 5,280 LUT4, 120Kb EBR + 1,024Kb SPRAM, 8 MAC16. [EST] clock, power. Milliwatt always-on class." },
FpgaTarget { name: "Gowin GW1NR-9 (Tang Nano 9K)", class: Class::EdgeMicro, luts: 8640, lut6: false,
bram_kb: 468, dsp: 20, clock_mhz: (27, 60), power_w: (0.02, 0.1),
price: "board $15-25 [SWEEP]", availability: "in stock (Sipeed/Seeed)", open_flow: OpenFlow::Partial,
provenance: "[DS] 8,640 LUT4, 468Kb BSRAM, +64Mb PSRAM in package. Apicula open flow first-class. Cheapest real FPGA." },
FpgaTarget { name: "Gowin GW2AR-18 (Tang Nano 20K)", class: Class::EdgeMicro, luts: 20736, lut6: false,
bram_kb: 828, dsp: 48, clock_mhz: (50, 100), power_w: (0.05, 0.3),
price: "board $25-40 [SWEEP]", availability: "in stock", open_flow: OpenFlow::Partial,
provenance: "[DS] 20,736 LUT4, 828Kb BSRAM, +64Mb SDRAM. [EST] best flips-per-dollar of the cheap fleet." },
FpgaTarget { name: "Lattice ECP5 LFE5U-85F", class: Class::Edge, luts: 83640, lut6: false,
bram_kb: 3700, dsp: 156, clock_mhz: (60, 100), power_w: (0.2, 1.5),
price: "$20-45 part; ULX3S $155; OrangeCrab ~$99 [SWEEP]", availability: "in stock", open_flow: OpenFlow::Full,
provenance: "[DS] 84K LUT4, 3.7Mb. Largest FPGA with a COMPLETE open flow (yosys+nextpnr+trellis) - the primary open compile target." },
FpgaTarget { name: "Lattice CertusPro-NX 100", class: Class::Edge, luts: 100000, lut6: false,
bram_kb: 7300, dsp: 156, clock_mhz: (100, 150), power_w: (0.2, 1.0),
price: "[EST] $100-250 part", availability: "in stock (DigiKey/Arrow)", open_flow: OpenFlow::VendorOnly,
provenance: "[DS] ~100K LC, 7.3Mb w/ LRAM (best weight-store per dollar in Lattice line), 28nm FD-SOI. Open flow covers smaller Nexus only." },
FpgaTarget { name: "AMD Artix-7 XC7A100T", class: Class::Edge, luts: 63400, lut6: true,
bram_kb: 4860, dsp: 240, clock_mhz: (100, 150), power_w: (1.0, 3.0),
price: "[EST] $100-200 part; Arty A7-100T ~$299", availability: "in stock", open_flow: OpenFlow::Partial,
provenance: "[DS] 63,400 LUT6, 4,860Kb BRAM, 240 DSP48E1. Vivado free tier; openXC7 experimental. The university-lab default." },
FpgaTarget { name: "AMD Artix-7 XC7A200T", class: Class::Edge, luts: 134600, lut6: true,
bram_kb: 13140, dsp: 740, clock_mhz: (100, 150), power_w: (2.0, 6.0),
price: "[EST] $300-500 part; boards $150-600", availability: "in stock", open_flow: OpenFlow::Partial,
provenance: "[DS] 134,600 LUT6, 13.1Mb, 740 DSP. [EST] cheapest plausible 0.1 Tflips/s-class part." },
FpgaTarget { name: "Alchitry Au (XC7A35T)", class: Class::Edge, luts: 20800, lut6: true,
bram_kb: 1800, dsp: 90, clock_mhz: (100, 150), power_w: (0.5, 2.0),
price: "[EST] ~$99-129 board (SparkFun/Alchitry)", availability: "in stock", open_flow: OpenFlow::Partial,
provenance: "[DS] XC7A35T: 20,800 LUT6, 1,800Kb BRAM, 90 DSP; 100 MHz osc + 256MB DDR3 on board. Named deployment target; facts sweep pending refinement." },
FpgaTarget { name: "Alchitry Au+ (XC7A100T)", class: Class::Edge, luts: 63400, lut6: true,
bram_kb: 4860, dsp: 240, clock_mhz: (100, 150), power_w: (1.0, 3.0),
price: "[EST] ~$299 board", availability: "in stock", open_flow: OpenFlow::Partial,
provenance: "[DS] XC7A100T fabric on the Alchitry form factor with DDR3. Named deployment target." },
FpgaTarget { name: "AMD Kria KV260 (K26 SOM)", class: Class::Edge, luts: 117120, lut6: true,
bram_kb: 23616, dsp: 1248, clock_mhz: (150, 300), power_w: (5.0, 15.0),
price: "$249 kit [DS-class]", availability: "in stock (AMD/distributors)", open_flow: OpenFlow::VendorOnly,
provenance: "[DS] XCK26 Zynq US+: 117,120 LUT6, 5.1Mb BRAM + 18Mb URAM, 1,248 DSP48E2, quad-A53 PS (host-on-module: the fabric samples, the PS serves results). Vivado supports Kria at no cost. Named deployment target." },
FpgaTarget { name: "Numato Aller (M.2 XC7A200T)", class: Class::Edge, luts: 134600, lut6: true,
bram_kb: 13140, dsp: 740, clock_mhz: (100, 150), power_w: (2.0, 8.0),
price: "[EST] ~$250-300", availability: "in stock (Numato)", open_flow: OpenFlow::Partial,
provenance: "[DS] XC7A200T in M.2 2280 with PCIe and 256MB DDR3 - the largest Artix in a COMPUTE-STICK form factor: the direct open-hardware answer to the vendor's announced M.2 sampling stick, buyable today. Named deployment target; facts sweep pending." },
FpgaTarget { name: "Salvage Kintex US+ KU3P (Alibaba AS02MC04)", class: Class::Salvage, luts: 163000, lut6: true,
bram_kb: 26200, dsp: 1368, clock_mhz: (200, 350), power_w: (10.0, 25.0),
price: "~$200 on eBay vs $900+ commercial boards [SWEEP]", availability: "salvage market, circulating Feb 2026",
open_flow: OpenFlow::VendorOnly,
provenance: "[DS-approx] 163K LUT6, 12.7Mb BRAM + 13.5Mb URAM, 1,368 DSP. UltraScale+ primitives = same-fabric CI target for VU47P/VU9P netlists; Vivado Standard (free) covers KU3P; RapidWright path exists." },
FpgaTarget { name: "AMD Alveo U55C (PCIe card)", class: Class::PcieCard, luts: 1304000, lut6: true,
bram_kb: 349000, dsp: 9024, clock_mhz: (250, 450), power_w: (75.0, 150.0),
price: "$4.5k refurb - $6.1k new [SWEEP]", availability: "ACTIVE product; in stock (SHI/DigiKey)",
open_flow: OpenFlow::VendorOnly,
provenance: "[DS] VU47P-class: 1,304K LUT6, 70.9Mb BRAM + 270Mb URAM, 9,024 DSP, 16GiB HBM2 @460GB/s. Same silicon as AWS F2: develop local, burst to cloud." },
FpgaTarget { name: "AMD Alveo V80 (PCIe card)", class: Class::PcieCard, luts: 2500000, lut6: true,
bram_kb: 0, dsp: 10848, clock_mhz: (300, 500), power_w: (150.0, 300.0),
price: "$9,495 MSRP; orderable, ~10wk lead [SWEEP]", availability: "ACTIVE flagship (AMD: 'all new designs')",
open_flow: OpenFlow::VendorOnly,
provenance: "[DS-approx] Versal HBM: ~2.5M LUTs, 10,848 DSP58, 32GiB HBM2e @820GB/s, hard NoC. No published Ising/sampling work yet [SWEEP: searched, empty] - first-mover slot; free validation units at ETHZ-HACC." },
FpgaTarget { name: "AWS EC2 F2 (f2.6xlarge, 1x VU47P)", class: Class::CloudInstance, luts: 1304000, lut6: true,
bram_kb: 349000, dsp: 9024, clock_mhz: (250, 450), power_w: (75.0, 150.0),
price: "$1.98/hr on-demand, ~$0.66 spot [SWEEP, us-east-1 Aug 2026]",
availability: "ACTIVE, 11+ regions; Vivado license included", open_flow: OpenFlow::VendorOnly,
provenance: "[DS] VU47P + 16GiB HBM2 + 64GiB DDR4; aws-fpga f2 branch, Vivado/Vitis 2024.1-2025.1. THE cloud target. F1 retired Dec 2025." },
FpgaTarget { name: "AWS EC2 F2 x8 (f2.48xlarge)", class: Class::CloudInstance, luts: 1304000, lut6: true,
bram_kb: 349000, dsp: 9024, clock_mhz: (250, 450), power_w: (600.0, 1200.0),
price: "$15.84/hr on-demand [SWEEP, us-east-1 Aug 2026]",
availability: "ACTIVE; 8x VU47P + 192 vCPU + 2 TiB + 100 Gbps", open_flow: OpenFlow::VendorOnly,
provenance: "[DS] 8 FPGAs per instance - the multi-chip tier for DSIM-2-style distributed Gibbs with 1-bit boundary exchange. Named deployment target; inter-FPGA topology facts sweep pending." },
FpgaTarget { name: "Azure NP10s (1x Alveo U250)", class: Class::CloudInstance, luts: 1728000, lut6: true,
bram_kb: 54000, dsp: 12288, clock_mhz: (250, 400), power_w: (100.0, 225.0),
price: "$1.65/hr on-demand, ~$0.30 spot [SWEEP]",
availability: "SUNSETTING: retirement May 31 2027; new reservations closed Apr 2026", open_flow: OpenFlow::VendorOnly,
provenance: "[DS] VU13P: 1,728K LUT6, 12,288 DSP (largest DSP pool of the family), 64GB DDR4. Attestation-gated bitstreams; older Vitis shells. 10-month experiment window only." },
FpgaTarget { name: "AMD HACC (ETHZ + partners, academic)", class: Class::AcademicCluster, luts: 1304000, lut6: true,
bram_kb: 349000, dsp: 9024, clock_mhz: (250, 450), power_w: (75.0, 300.0),
price: "$0 for accepted academic teams [SWEEP]",
availability: "10x U55C + U250/U280/VCK5000 + V80 at ETHZ; sister clusters UIUC/NUS/Paderborn; apply at amd-haccs.io",
open_flow: OpenFlow::VendorOnly,
provenance: "[SWEEP verified Aug 2026] maintained Vitis/Vivado, 100G inter-card. The zero-cost route to F2-class silicon and V80." },
FpgaTarget { name: "NSF Open Cloud Testbed (24x Alveo U280)", class: Class::AcademicCluster, luts: 1304000, lut6: true,
bram_kb: 349000, dsp: 9024, clock_mhz: (250, 450), power_w: (100.0, 225.0),
price: "$0, NSF-funded, allocation by proposal [SWEEP]",
availability: "bare-metal via CloudLab; dual 100GbE per card into shared switch",
open_flow: OpenFlow::VendorOnly,
provenance: "[DS] U280 = VU37P + 8GiB HBM2. The only two-dozen-card HBM FPGA mesh rentable for $0 - matches the DSIM-2 1-bit-boundary-exchange distributed-Gibbs pattern." },
];
pub const ANCHORS: &[(&str, &str)] = &[
("Aadit et al., Nature Electronics 2022 (VCU118 / VU9P)",
"multiplexed chromatic Gibbs sparse Ising machine; ~10^6x CPU Gibbs, 5-18x vs optimized TPU/GPU; flips/s linear in p-bits [measured]"),
("DSIM-2, arXiv:2606.25313 (Jun 2026, UCSB/CMU/Siemens/KFUPM)",
"18x Versal Premium VP1902; ~10^6 p-bits; graph-colored Gibbs, N_color=22, 100^3 Edwards-Anderson glass; 1e12 flips/s @ 11 MHz, 3e12 @ 33 MHz, 1.4-1.6 kW; 1-bit boundary exchange between chips [measured]"),
("Toshiba SBM on AWS F1 (2019) -> SQBM+ (Azure Quantum 2022, AWS Marketplace 2023)",
"FPGA dSB solver to 100,000-variable Ising [vendor claims]"),
];
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn database_is_coherent() {
assert!(TARGETS.len() >= 19);
for t in TARGETS {
assert!(t.luts > 0 && t.clock_mhz.0 <= t.clock_mhz.1);
assert!(!t.provenance.is_empty() && !t.price.is_empty());
let density = t.est_flips_per_s() / t.luts as f64;
assert!(density < 1.2e5, "{}: {:.1e} flips/s/LUT exceeds anchor-scaled density", t.name, density);
assert!(t.est_flips_per_s() < 3e11,
"{}: estimate {:.1e} exceeds the measured per-chip anchor", t.name, t.est_flips_per_s());
}
let up5k = &TARGETS[0];
let v80 = TARGETS.iter().find(|t| t.name.contains("V80")).unwrap();
assert!(up5k.est_pbits() < v80.est_pbits());
}
}