xiiregexbuilder

FPGA-Accelerated Regular Expression Matching Engine
commit b30c53a6930f47da584b261dadf3291ed63f4bcb
parent d1b99d1b6e876814a909ca047abe1eff3daddd37
Author: Vishrut Gurrala <maydayv7@gmail.com>
Date:   Mon,  6 Apr 2026 21:28:41 +0530

Week 3: Complete FPGA top wrapper and pin constraints (Part 2: Core logic)

Diffstat:
Moutput-eg/constraints.xdc | 13+++++++++++++
Moutput-eg/top_fpga.v | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/output-eg/constraints.xdc b/output-eg/constraints.xdc @@ -7,3 +7,16 @@ create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk set_property PACKAGE_PIN C4 [get_ports uart_rx_pin] set_property IOSTANDARD LVCMOS33 [get_ports uart_rx_pin] +set_property PACKAGE_PIN D4 [get_ports uart_tx_pin] +set_property IOSTANDARD LVCMOS33 [get_ports uart_tx_pin] + +## Buttons (Nexys A7 Center Button - BTNC) +set_property PACKAGE_PIN N17 [get_ports rst_btn] +set_property IOSTANDARD LVCMOS33 [get_ports rst_btn] + +## LEDs (Nexys A7 LED0 to LED15) +set_property PACKAGE_PIN H17 [get_ports {match_leds[0]}] +set_property IOSTANDARD LVCMOS33 [get_ports {match_leds[0]}] +set_property PACKAGE_PIN K15 [get_ports {match_leds[1]}] +set_property IOSTANDARD LVCMOS33 [get_ports {match_leds[1]}] +set_property PACKAGE_PIN J13 [get_ports {match_leds[2]}] diff --git a/output-eg/top_fpga.v b/output-eg/top_fpga.v @@ -211,3 +211,88 @@ module top_fpga #( tx_buf[p]=hex_char(tmp16[ 7: 4]); p=p+1; tx_buf[p]=hex_char(tmp16[ 3: 0]); p=p+1; tx_buf[p]=8'h2C; p=p+1; // ',' + tmp16 = match_count[4]; + tx_buf[p]=hex_char(tmp16[15:12]); p=p+1; + tx_buf[p]=hex_char(tmp16[11: 8]); p=p+1; + tx_buf[p]=hex_char(tmp16[ 7: 4]); p=p+1; + tx_buf[p]=hex_char(tmp16[ 3: 0]); p=p+1; + tx_buf[p]=8'h2C; p=p+1; // ',' + tmp16 = match_count[5]; + tx_buf[p]=hex_char(tmp16[15:12]); p=p+1; + tx_buf[p]=hex_char(tmp16[11: 8]); p=p+1; + tx_buf[p]=hex_char(tmp16[ 7: 4]); p=p+1; + tx_buf[p]=hex_char(tmp16[ 3: 0]); p=p+1; + tx_buf[p]=8'h0D; p=p+1; // CR + tx_buf[p]=8'h0A; p=p+1; // LF + tx_len = p[6:0]; + end + endtask + + // Main Control FSM + localparam S_IDLE = 4'd0; + localparam S_FETCH = 4'd1; + localparam S_DECODE = 4'd2; + localparam S_CHAR_LOAD = 4'd3; + localparam S_CHAR_STEP = 4'd4; + localparam S_EOL_END = 4'd5; + localparam S_EOL_MATCH = 4'd6; + localparam S_EOL_LATCH = 4'd7; + localparam S_TX_ARM = 4'd8; + localparam S_TX_WAIT = 4'd9; + localparam S_RESET_NFA = 4'd10; + localparam S_QUERY_TX = 4'd11; + + reg [3:0] state = S_RESET_NFA; + + reg [5:0] snap_match = 6'b0; + reg [31:0] snap_bytes = 32'd0; + integer k; + + always @(posedge clk) begin + tx_send <= 1'b0; + fifo_rd_en <= 1'b0; + nfa_en <= 1'b0; + nfa_start <= 1'b0; + + if (rst_btn) begin + state <= S_RESET_NFA; + match_leds <= 6'b0; + byte_count <= 32'd0; + for (k = 0; k < 16; k = k + 1) + match_count[k] <= 16'd0; + end else begin + case (state) + + S_IDLE: begin + nfa_end_of_str <= 1'b0; + if (!fifo_empty) state <= S_FETCH; + end + + S_FETCH: begin + fifo_rd_en <= 1'b1; + state <= S_DECODE; + end + + S_DECODE: begin + if (fifo_rd_data == 8'h0A || fifo_rd_data == 8'h0D) begin + nfa_end_of_str <= 1'b1; + state <= S_EOL_END; + end else if (fifo_rd_data == 8'h3F) begin // '?' + state <= S_QUERY_TX; + end else begin + nfa_char_in <= fifo_rd_data; + state <= S_CHAR_LOAD; + end + end + + S_CHAR_LOAD: state <= S_CHAR_STEP; + + S_CHAR_STEP: begin + nfa_en <= 1'b1; + byte_count <= byte_count + 1; + state <= S_IDLE; + end + + S_EOL_END: begin + nfa_en <= 1'b1; + state <= S_EOL_MATCH;