NXPU

NXLang Documentation

The programming language for the NXPU reasoning chip. v0.3

NXLang is a Datalog-style language that compiles to NXPU hardware register writes. Write facts and rules in a human-readable syntax; the compiler handles symbol resolution, variable encoding, and hardware targeting.

NXLang programs run on real silicon. Every example on this page has been compiled and executed on the ZCU106 FPGA with 100% accuracy.

Installation

git clone https://github.com/dyber-pqc/NXPU.git
cd NXPU
pip install -r requirements.txt

# Verify installation
python nxc.py version
# NXLang Compiler (nxc) v0.3.0

Quick Start

Create a file hello.nx:

fact: parent(tom, bob).
fact: parent(bob, ann).

rule: grandparent(X, Z) :-
    parent(X, Y, _),
    parent(Y, Z, _).

# query: grandparent.

Compile and run:

# Compile to Tcl (for FPGA)
python nxc.py hw-compile hello.nx --format tcl

# Compile to binary
python nxc.py hw-compile hello.nx --format nxb

# Run in simulation
python nxc.py repl --transport sim
nxpu> fact parent(tom, bob)
nxpu> fact parent(bob, ann)
nxpu> rule grandparent(X, Z) :- parent(X, Y, _), parent(Y, Z, _)
nxpu> derive
  DeriveResult(count=1, cycles=19, time_us=0.19)
nxpu> query grandparent
  QueryResult(pred=grandparent, matches=1)

Facts

Facts are ground truth assertions stored in the NXPU's Content-Addressable Memory. Each fact has a predicate name and up to 3 arguments.

fact: vulnerable(CVE_2024_1234, openssl, v3_0_1).
fact: patient_takes(john, warfarin).
fact: internet_facing(web_01).

Internally, each fact is encoded as a 56-bit CAM entry:

FieldBitsDescription
Predicate ID[55:48]8-bit, auto-assigned by compiler
Argument 2[47:32]16-bit constant ID
Argument 1[31:16]16-bit constant ID
Argument 0[15:0]16-bit constant ID

Rules

Rules express logical inference. The head is derived when all body atoms are satisfied simultaneously with consistent variable bindings.

rule: at_risk(Server) :-
    runs_service(Server, Software, Version),
    vulnerable(_, Software, Version),
    internet_facing(Server, _, _).

Rules support up to 4 body atoms and 8 simultaneous variables. The hardware performs depth-first search with backtracking when partial bindings fail.

Variables shared across atoms enforce binding consistency. In the example above, Software must bind to the same value in both runs_service and vulnerable.

Queries

query: at_risk.             # Wildcard: all at_risk facts
query: patient_takes(john). # Filtered: john's medications

Variables & Constants

SyntaxTypeExample
UppercaseVariable (binds during unification)Server, Drug, X
Lowercase / quotedConstant (exact match)warfarin, web_01
Underscore _Don't-care (matches anything)vulnerable(_, S, V)

Type System

The compiler performs type checking including arity consistency (same predicate always has same number of args), head-variable-in-body verification (head variables must appear in at least one body atom), and hardware constraint validation (max 4 body atoms, max 8 variables, max 255 predicates, max 65535 constants).

Compiler Pipeline

NXLang Source (.nx)
    |
    v
Lexer (40+ token types, line/col errors)
    |
    v
Parser (recursive descent, 15 AST node types)
    |
    v
Type Checker (arity, variable, constraint validation)
    |
    v
NXIR (SSA-form IR with engine tags)
    |
    v
Optimizer (dead code elimination, parallel regions)
    |
    v
FPGA Backend
    |-- Symbol Table (names -> 8-bit/16-bit IDs)
    |-- Variable Encoder (rules -> packed register format)
    |-- Hardware Encoder (register write sequences)
    |
    v
Output: .tcl | .nxb | .json | .h

CLI Reference

CommandDescription
nxc hw-compile <file> -f tclCompile to Vivado Tcl script
nxc hw-compile <file> -f nxbCompile to NXB binary
nxc hw-compile <file> -f jsonCompile to JSON
nxc hw-compile <file> -f cCompile to C header
nxc deploy <file> -t jtagUpload and run on FPGA
nxc repl -t simInteractive REPL (simulation)
nxc repl -t jtagInteractive REPL (hardware)
nxc query <pred>Query running hardware
nxc statusShow hardware status
nxc compile <file>Compile to simulation code
nxc check <file>Type-check only
nxc ir <file>Show NXIR intermediate representation

Output Formats

NXB Binary

Compiled, portable binary. 16-byte header + register writes + symbol table + CRC32.

Offset  Size  Field
0x00    4     Magic: "NXB\0" (0x4E584200)
0x04    2     Version: 0x0001
0x06    2     Flags
0x08    4     Write count
0x0C    4     Symbol table offset
0x10    N*8   Register writes (addr + data)
...     var   Symbol table (JSON)
...     4     CRC32

Python SDK

import nxpu

# Connect to hardware or simulation
session = nxpu.connect("sim")        # or "jtag"

# Add facts
session.add_fact("parent", "tom", "bob")
session.add_fact("parent", "bob", "ann")

# Add and run a rule
session.add_rule("grandparent(X,Z) :- parent(X,Y,_), parent(Y,Z,_)")
result = session.derive()
# DeriveResult(count=1, cycles=19, time_us=0.19)

# Query
q = session.query("grandparent")
# QueryResult(pred=grandparent, matches=1)

# Load a .nx file
session.load_file("pharma_safety.nx")

# Compile to binary
nxb = session.compile_to_nxb(facts, rules)

Session API

MethodDescription
add_fact(pred, *args)Add a fact to hardware CAM
add_fact_text(text)Add fact from string: "parent(tom, bob)"
add_rule(text)Register a rule for derivation
derive(rule_text=None)Run derivation, returns DeriveResult
derive_all()Run all registered rules
query(pred, *args)Query CAM, returns QueryResult
load_file(path)Compile and upload .nx file
load_nxb(path)Upload compiled .nxb binary
status()Returns HWStatus (entries, busy, etc.)
scratch_test()Verify hardware connectivity

Transports

TransportDescriptionUsage
simSoftware simulation (no hardware)Development, testing
jtagSSH + Vivado JTAG-to-AXIZCU106 FPGA
pciePCIe (future)M.2 / ASIC
uartUART serial (future)Embedded

Register Map

42 registers accessed via AXI4-Lite (8-bit address space):

AddressNameAccessDescription
0x00CMDW1=ADD_FACT, 3=QUERY, 4=DERIVE
0x04STATUSRbusy, entry_count, match_count
0x08-0x0CDATAR/WEntry bits [55:0]
0x10-0x14MASKR/WSearch mask
0x24SCRATCHR/WTest register (init: 0x4E585055)
0x28-0x44RULE_*R/WRule configuration (8 registers)
0x48DERIVED_COUNTRFacts derived by last DERIVE
0x4CCYCLE_COUNTRClock cycles for last DERIVE
0x50-0x5CNM_*R/WNeural Mesh I/O
0x60-0x64CF_*R/WConcept Formation
0x68-0x7CNLU_*R/WNLU Pipeline
0x80-0xA0FB/MR/PCR/WFeedback, Meta-Rule, Pattern Comp.

Variable Encoding

The most complex part of compilation. Each Datalog variable gets a 3-bit index (0-7). Indices are packed 9 bits per atom (3 args x 3 bits) into a 36-bit field split across VAR_IDX_LO (bits 31:0) and VAR_IDX_HI (bits 35:32).

The NXLang compiler automates this encoding. You never need to compute hex values manually. The variable encoder was validated against silicon-tested values (e.g., var_idx_lo=0x05811688 for the security benchmark).