xiiregexbuilder

FPGA-Accelerated Regular Expression Matching Engine

processor/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