xiiregexbuilder

FPGA-Accelerated Regular Expression Matching Engine
commit 1638294121a88383f75e7e8c206f35f2e796a553
parent db8fb4edf3854d38715e2052d42f57c6ccaacff9
Author: Achuthan TM <achuthantm05@gmail.com>
Date:   Tue, 14 Apr 2026 12:25:42 +0530

Week 5: System-level integration and top level FPGA logic (Part 2: Core logic)

Diffstat:
MREADME.md | 79+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 47 insertions(+), 32 deletions(-)

diff --git a/README.md b/README.md @@ -6,7 +6,7 @@ Group Number: 6 Our project is a custom hardware accelerator for high-speed text processing. A C++ compiler translates regular expressions into parallel, one-hot encoded hardware Finite State Machines (FSMs) in Verilog. These FSMs are synthesised onto an FPGA to parse continuous ASCII character streams, bypassing the sequential bottleneck of software-based regex engines. -The host PC communicates with the FPGA over a standard USB-UART serial link at 115200 baud. An included Python terminal UI (`tui.py`) lets you type strings interactively and see per-regex match results, cumulative byte counts, and per-regex hit counters rendered in a colour-coded table. +The host PC communicates with the FPGA over a standard USB-UART serial link at 115200 baud. Included Python terminal UIs (`tui/engine.py` and `tui/processor.py`) let you type strings interactively and see per-regex match results, cumulative byte counts, and per-regex hit counters rendered in a colour-coded table. ## 2. Use Cases @@ -82,6 +82,15 @@ Send `?` at any time to query the current counters without feeding any character - **Input FIFO Buffer** (`uart_rx_fifo.v`): 16-byte circular FIFO decouples the UART receiver from the NFA engine FSM, eliminating byte-drop risk. - **Hardware Counters**: `byte_count` and per-regex `match_count` registers, queryable via UART or the Python TUI. +### Processor-based Dynamic Matching + +In addition to the static Verilog FSM generation, we have implemented a **Soft-Processor Regex Engine** (`processor/` directory). This approach allows regexes to be updated **dynamically at runtime** without re-synthesising the FPGA bitstream: + +- **Regex CPU**: A custom 32-bit RISC-like core designed specifically for NFA traversal. +- **Glushkov Assembler**: A Python-based toolchain (`compile_regex.py` and `asm.py`) that converts standard regex patterns into custom instruction sequences. +- **Dynamic Programming**: Regexes are loaded into the CPU's instruction memory via UART, enabling instantaneous updates to the filtering logic. +- **Parallel NFA Simulation**: The processor uses a bit-vector state representation to track multiple active NFA states simultaneously, maintaining high throughput for complex patterns. + ### Stretch Goal - Bounded quantifiers `{m,n}`: compiler and hardware support for repetition counts. @@ -115,48 +124,54 @@ make synth # runs synth.tcl through Vivado batch mode make program # programs the attached FPGA ``` -### Launch the Python TUI +### Launch the Python TUIs + +#### For the Static NFA Engine ```bash pip install pyserial rich -python tui.py --port /dev/ttyUSB0 --regexes inputs/regexes.txt -# On Windows: python tui.py --port COM3 --regexes inputs/regexes.txt +python tui/engine.py --port COM3 --regexes inputs/regexes.txt +``` + +#### For the Regex Processor + +```bash +python tui/processor.py --port COM3 --regexes processor/regex.txt ``` -The TUI auto-detects the first available USB-Serial port if `--port` is omitted. +The TUIs auto-detect the first available USB-Serial port if `--port` is omitted. + +### Processor-based Dynamic Matching Commands + +```bash +make proc_asm # Compiles regexes to instruction memory hex +make proc_sim # Simulates the processor in Vivado +make proc_synth # Synthesises the processor hardware +make proc_program # Programs the processor bitstream to FPGA +make proc_update_regex # Re-compiles and flashes new regexes over UART +``` ## 8. File Layout ```text XIIRegexBuilder/ ├── inputs/ -│ ├── regexes.txt # one regex per line -│ └── test_strings.txt # one test string per line -├── src/ -│ ├── main.cpp # pipeline entry point -│ ├── lexer.{h,cpp} # tokeniser -│ ├── parser.{h,cpp} # recursive-descent AST builder -│ ├── nfa.{h,cpp} # Glushkov NFA construction -│ ├── emitter.{h,cpp} # Verilog code generator -│ ├── golden.cpp # C++ std::regex reference -│ └── parser_tester.cpp # unit-test harness -├── output/ # generated by `make run` -│ ├── nfa_0.v … nfa_N.v -│ ├── top.v -│ ├── uart_rx.v # UART receiver -│ ├── uart_tx.v # UART transmitter -│ ├── uart_rx_fifo.v # Input FIFO -│ ├── top_fpga.v # FPGA top-level -│ ├── tb_top.v -│ ├── constraints.xdc -│ └── expected_matches.txt -├── tui.py # Python TUI +│ ├── regexes.txt # one regex per line (for Static Engine) +├── processor/ # Soft-Processor Regex Engine +│ ├── src/ # Python toolchain (asm, compiler, programmer) +│ ├── build/ # Build artifacts (hex, rasm, bitstream) +│ ├── regex_cpu.v # RISC-like NFA processor +│ ├── top_level.v # FPGA top-level for processor +│ └── regex.txt # Dynamic regex patterns +├── src/ # C++ Compiler source for Static Engine +├── output/ # Generated Verilog for Static Engine +├── tui/ # Interactive Terminal UIs +│ ├── engine.py # TUI for Static NFA Engine +│ └── processor.py # TUI for Regex Processor ├── scripts/ -│ ├── synth.tcl # Vivado synthesis script -│ └── program.tcl # Vivado programming script +│ ├── synth.tcl # Vivado synth for Static Engine +│ ├── synth_proc.tcl # Vivado synth for Processor +│ └── program.tcl # Generic Vivado programming script ├── Makefile -├── README.md -├── Specifications.md -├── details.md -└── usecase.md +└── README.md ```