xiiregexbuilder
FPGA-Accelerated Regular Expression Matching Engineprocessor/top_level.v (6954B)
1`timescale 1ns / 1ps
2
3module top_level (
4 input wire CLK100MHZ,
5 input wire CPU_RESETN,
6 input wire [15:0] SW,
7 input wire BTNC, // start
8 input wire BTNU, // char_valid
9 input wire BTND, // end_of_str
10 input wire UART_TXD_IN,
11 output wire UART_RXD_OUT,
12 output wire [15:0] LED,
13 output wire [ 7:0] SEG,
14 output wire [ 7:0] AN
15);
16
17 // --- Input Synchronization and Debouncing ---
18 reg [1:0] rst_sync;
19 always @(posedge CLK100MHZ) rst_sync <= {rst_sync[0], !CPU_RESETN};
20 wire rst = rst_sync[1];
21
22 reg [15:0] btnc_sync, btnu_sync, btnd_sync;
23 always @(posedge CLK100MHZ) begin
24 btnc_sync <= {btnc_sync[14:0], BTNC};
25 btnu_sync <= {btnu_sync[14:0], BTNU};
26 btnd_sync <= {btnd_sync[14:0], BTND};
27 end
28 wire btnc_debounced = &btnc_sync;
29 wire btnu_debounced = &btnu_sync;
30 wire btnd_debounced = &btnd_sync;
31
32 reg btnc_prev, btnu_prev, btnd_prev;
33 always @(posedge CLK100MHZ) begin
34 btnc_prev <= btnc_debounced;
35 btnu_prev <= btnu_debounced;
36 btnd_prev <= btnd_debounced;
37 end
38 wire btnc_pulse = btnc_debounced && !btnc_prev;
39 wire btnu_pulse = btnu_debounced && !btnu_prev;
40 wire btnd_pulse = btnd_debounced && !btnd_prev;
41
42 // UART Instance with FIFO
43 wire [7:0] rx_fifo_data;
44 wire rx_fifo_valid;
45 wire ready_out;
46 wire rx_rd_en = (rx_fifo_valid && (ready_out || prog_state != 0));
47
48 uart_rx #(
49 .CLK_FREQ(100000000),
50 .BAUD_RATE(115200),
51 .FIFO_DEPTH(32) // Increased FIFO
52 ) rx_inst (
53 .clk(CLK100MHZ),
54 .rst(rst),
55 .rx(UART_TXD_IN),
56 .data(rx_fifo_data),
57 .valid(rx_fifo_valid),
58 .rd_en(rx_rd_en)
59 );
60
61 reg [7:0] tx_data_reg;
62 reg tx_send_reg;
63 wire tx_ready;
64 uart_tx tx_inst (
65 .clk(CLK100MHZ),
66 .rst(rst),
67 .data(tx_data_reg),
68 .send(tx_send_reg),
69 .tx(UART_RXD_OUT),
70 .ready(tx_ready)
71 );
72
73 // Protocol Logic
74 wire is_stx = (rx_rd_en && rx_fifo_data == 8'h02 && prog_state == 0);
75 wire start_pulse = (btnc_pulse) || (rx_rd_en && rx_fifo_data == 8'h01 && prog_state == 0);
76 wire end_of_str_pulse = (btnd_pulse) || (rx_rd_en && (rx_fifo_data == 8'h0D || rx_fifo_data == 8'h0A) && prog_state == 0);
77 wire is_printable = (rx_fifo_data >= 8'h20 && rx_fifo_data <= 8'h7E);
78 wire char_valid_pulse = (btnu_pulse) || (rx_rd_en && is_printable && prog_state == 0);
79
80 // --- UART Programming Logic ---
81 reg [2:0] prog_state = 0;
82 reg [7:0] prog_addr_reg;
83 reg [31:0] prog_data_reg;
84 reg prog_en_reg;
85 reg [26:0] prog_watchdog = 0; // ~1.3s timeout at 100MHz
86
87 always @(posedge CLK100MHZ) begin
88 if (rst || prog_watchdog[26]) begin
89 prog_state <= 0;
90 prog_en_reg <= 0;
91 prog_watchdog <= 0;
92 end else begin
93 prog_en_reg <= 0;
94 if (prog_state != 0) prog_watchdog <= prog_watchdog + 1;
95 else prog_watchdog <= 0;
96
97 case (prog_state)
98 0: if (is_stx) prog_state <= 1;
99 1:
100 if (rx_fifo_valid) begin
101 prog_addr_reg <= rx_fifo_data;
102 prog_state <= 2;
103 prog_watchdog <= 0;
104 end
105 2:
106 if (rx_fifo_valid) begin
107 prog_data_reg[31:24] <= rx_fifo_data;
108 prog_state <= 3;
109 prog_watchdog <= 0;
110 end
111 3:
112 if (rx_fifo_valid) begin
113 prog_data_reg[23:16] <= rx_fifo_data;
114 prog_state <= 4;
115 prog_watchdog <= 0;
116 end
117 4:
118 if (rx_fifo_valid) begin
119 prog_data_reg[15:8] <= rx_fifo_data;
120 prog_state <= 5;
121 prog_watchdog <= 0;
122 end
123 5:
124 if (rx_fifo_valid) begin
125 prog_data_reg[7:0] <= rx_fifo_data;
126 prog_en_reg <= 1;
127 prog_state <= 0;
128 end
129 default: prog_state <= 0;
130 endcase
131 end
132 end
133
134 // --- UART Activity Monitor ---
135 reg [23:0] rx_activity_cnt;
136 reg [23:0] tx_activity_cnt;
137 always @(posedge CLK100MHZ) begin
138 if (rx_rd_en || (prog_state != 0 && rx_fifo_valid)) rx_activity_cnt <= 24'hFFFFFF;
139 else if (rx_activity_cnt > 0) rx_activity_cnt <= rx_activity_cnt - 1;
140
141 if (tx_send_reg) tx_activity_cnt <= 24'hFFFFFF;
142 else if (tx_activity_cnt > 0) tx_activity_cnt <= tx_activity_cnt - 1;
143 end
144
145 wire [15:0] match_bus;
146 regex_cpu #(
147 .NUM_REGEX(16)
148 ) cpu_inst (
149 .clk(CLK100MHZ),
150 .rst(rst),
151 .start(start_pulse),
152 .end_of_str(end_of_str_pulse),
153 .char_in(rx_fifo_valid ? rx_fifo_data : SW[7:0]),
154 .char_valid(char_valid_pulse),
155 .prog_en(prog_en_reg),
156 .prog_addr(prog_addr_reg),
157 .prog_data(prog_data_reg),
158 .ready(ready_out),
159 .match_bus(match_bus)
160 );
161
162 assign LED[11:0] = match_bus[11:0];
163 assign LED[13] = (tx_activity_cnt > 0); // TX Flash
164 assign LED[14] = (rx_activity_cnt > 0); // RX Flash
165 assign LED[15] = ready_out;
166
167 // --- UART Result Transmission ---
168 reg [ 2:0] tx_state = 0;
169 reg [19:0] tx_delay_cnt = 0;
170 always @(posedge CLK100MHZ) begin
171 if (rst) begin
172 tx_state <= 0;
173 tx_send_reg <= 0;
174 tx_delay_cnt <= 0;
175 end else begin
176 tx_send_reg <= 0;
177 case (tx_state)
178 0: if (end_of_str_pulse) tx_state <= 1;
179 1: if (ready_out) tx_state <= 2; // Wait for CPU to finish STATE_END_OF_STR
180 2:
181 if (tx_ready) begin
182 tx_data_reg <= match_bus[15:8];
183 tx_send_reg <= 1;
184 tx_state <= 3;
185 end
186 3: if (!tx_ready) tx_state <= 4;
187 4:
188 if (tx_ready) begin
189 if (tx_delay_cnt == 20'd100000) begin
190 tx_data_reg <= match_bus[7:0];
191 tx_send_reg <= 1;
192 tx_state <= 0;
193 tx_delay_cnt <= 0;
194 end else begin
195 tx_delay_cnt <= tx_delay_cnt + 1;
196 end
197 end
198 default: tx_state <= 0;
199 endcase
200 end
201 end
202
203 // --- 7-Segment Display (Unchanged) ---
204 function [6:0] sseg_dec;
205 input [3:0] val;
206 begin
207 case (val)
208 4'h0: sseg_dec = 7'b1000000;
209 4'h1: sseg_dec = 7'b1111001;
210 4'h2: sseg_dec = 7'b0100100;
211 4'h3: sseg_dec = 7'b0110000;
212 4'h4: sseg_dec = 7'b0011001;
213 4'h5: sseg_dec = 7'b0010010;
214 4'h6: sseg_dec = 7'b0000010;
215 4'h7: sseg_dec = 7'b1111000;
216 4'h8: sseg_dec = 7'b0000000;
217 4'h9: sseg_dec = 7'b0010000;
218 4'hA: sseg_dec = 7'b0001000;
219 4'hB: sseg_dec = 7'b0000011;
220 4'hC: sseg_dec = 7'b1000110;
221 4'hD: sseg_dec = 7'b0100001;
222 4'hE: sseg_dec = 7'b0000110;
223 4'hF: sseg_dec = 7'b0001110;
224 default: sseg_dec = 7'b1111111;
225 endcase
226 end
227 endfunction
228 reg [19:0] refresh_counter = 0;
229 always @(posedge CLK100MHZ) refresh_counter <= refresh_counter + 1;
230 assign AN = (refresh_counter[18]) ? 8'b11111110 : 8'b11111101;
231 assign SEG[6:0] = (refresh_counter[18]) ? sseg_dec(SW[3:0]) : sseg_dec(SW[7:4]);
232 assign SEG[7] = 1'b1;
233endmodule