xiiregexbuilder
FPGA-Accelerated Regular Expression Matching Engineoutput-pii/top_fpga.v (5358B)
1`timescale 1ns / 1ps
2
3module top_fpga (
4 input wire clk, // 100 MHz system clock
5 input wire rst_btn, // Physical reset button
6 input wire uart_rx_pin,// USB UART RX pin
7 output wire uart_tx_pin // USB UART TX pin
8);
9
10
11 wire [7:0] rx_data;
12 wire rx_ready;
13
14 uart_rx uart_inst (
15 .clk(clk),
16 .rx(uart_rx_pin),
17 .rx_data(rx_data),
18 .rx_ready(rx_ready)
19 );
20
21 reg nfa_start = 1'b1;
22 reg [7:0] nfa_char_in = 8'h00;
23 reg nfa_en = 1'b0;
24 wire [6:0] match_bus;
25 wire [6:0] active_bus;
26
27 top regex_engine (
28 .clk(clk),
29 .en(nfa_en),
30 .rst(rst_btn),
31 .start(nfa_start),
32 .char_in(nfa_char_in),
33 .match_bus(match_bus),
34 .active_bus(active_bus)
35 );
36
37
38 // UART TX Signals
39 reg tx_start = 1'b0;
40 reg [7:0] tx_data = 8'h00;
41 wire tx_busy;
42
43 uart_tx uart_tx_inst (
44 .clk(clk),
45 .tx_start(tx_start),
46 .tx_data(tx_data),
47 .tx(uart_tx_pin),
48 .tx_busy(tx_busy)
49 );
50
51 // 128-Byte Latency Buffering with Precise Alignment
52 localparam DELAY_LEN = 128;
53 (* ram_style = "distributed" *) reg [7:0] delay_bram [0:DELAY_LEN-1];
54 reg [6:0] delay_ptr = 0;
55 reg [DELAY_LEN-1:0] commit_history = 0;
56
57 // Per-NFA Active Histories to isolate redaction contexts
58 reg [DELAY_LEN-1:0] active_history_0 = 0;
59 reg [DELAY_LEN-1:0] active_history_1 = 0;
60 reg [DELAY_LEN-1:0] active_history_2 = 0;
61 reg [DELAY_LEN-1:0] active_history_3 = 0;
62 reg [DELAY_LEN-1:0] active_history_4 = 0;
63 reg [DELAY_LEN-1:0] active_history_5 = 0;
64 reg [DELAY_LEN-1:0] active_history_6 = 0;
65
66 // Power-On-Reset Initialization
67 reg [7:0] por_count = 0;
68 wire por_rst = (por_count < 8'hFF);
69
70 reg rx_ready_prev = 0;
71 reg [1:0] step = 0;
72 reg [7:0] rx_latch = 0;
73
74 always @(posedge clk) begin
75 if (rst_btn || por_rst) begin
76 if (por_count < 8'h80) begin
77 delay_bram[por_count[6:0]] <= 8'h20; // Initialize BRAM sequentially
78 end
79 if (por_count < 8'hFF) por_count <= por_count + 1;
80
81 nfa_en <= 0;
82 nfa_start <= 1;
83 tx_start <= 0;
84 rx_ready_prev <= 0;
85 delay_ptr <= 0;
86 commit_history <= 0;
87 step <= 0;
88 active_history_0 <= 0;
89 active_history_1 <= 0;
90 active_history_2 <= 0;
91 active_history_3 <= 0;
92 active_history_4 <= 0;
93 active_history_5 <= 0;
94 active_history_6 <= 0;
95
96 end else begin
97 nfa_start <= 0;
98 nfa_en <= 0;
99 tx_start <= 0;
100 rx_ready_prev <= rx_ready;
101
102 // Character Processing Sequence
103 if (rx_ready && !rx_ready_prev) begin
104 rx_latch <= rx_data;
105 step <= 1;
106 end
107
108 case (step)
109 1: begin
110 // Step 1: Feed NFA Engine
111 nfa_char_in <= rx_latch;
112 nfa_en <= 1;
113 step <= 2;
114 end
115 2: begin
116 // Step 2: NFA Results and Redaction Output
117 // 1. Read delayed char and check redaction bit (Sampling BEFORE shift)
118 tx_data <= (commit_history[DELAY_LEN-2]) ? 8'h58 : delay_bram[delay_ptr];
119 tx_start <= 1;
120
121 // 2. Overwrite slot with new character
122 delay_bram[delay_ptr] <= rx_latch;
123 delay_ptr <= delay_ptr + 1;
124
125 // 3. Update Histories (Isolating contexts)
126 active_history_0 <= active_bus[0] ? {active_history_0[DELAY_LEN-2:0], 1'b1} : 128'd0;
127 active_history_1 <= active_bus[1] ? {active_history_1[DELAY_LEN-2:0], 1'b1} : 128'd0;
128 active_history_2 <= active_bus[2] ? {active_history_2[DELAY_LEN-2:0], 1'b1} : 128'd0;
129 active_history_3 <= active_bus[3] ? {active_history_3[DELAY_LEN-2:0], 1'b1} : 128'd0;
130 active_history_4 <= active_bus[4] ? {active_history_4[DELAY_LEN-2:0], 1'b1} : 128'd0;
131 active_history_5 <= active_bus[5] ? {active_history_5[DELAY_LEN-2:0], 1'b1} : 128'd0;
132 active_history_6 <= active_bus[6] ? {active_history_6[DELAY_LEN-2:0], 1'b1} : 128'd0;
133 commit_history <= {commit_history[DELAY_LEN-2:0], 1'b0}
134 | (match_bus[0] ? {active_history_0[DELAY_LEN-2:0], 1'b1} : 128'd0)
135 | (match_bus[1] ? {active_history_1[DELAY_LEN-2:0], 1'b1} : 128'd0)
136 | (match_bus[2] ? {active_history_2[DELAY_LEN-2:0], 1'b1} : 128'd0)
137 | (match_bus[3] ? {active_history_3[DELAY_LEN-2:0], 1'b1} : 128'd0)
138 | (match_bus[4] ? {active_history_4[DELAY_LEN-2:0], 1'b1} : 128'd0)
139 | (match_bus[5] ? {active_history_5[DELAY_LEN-2:0], 1'b1} : 128'd0)
140 | (match_bus[6] ? {active_history_6[DELAY_LEN-2:0], 1'b1} : 128'd0);
141
142 step <= 0;
143 end
144 endcase
145 end
146 end
147endmodule