• 沒有找到結果。

NFA Construction Algorithm

Generating HDL Code

4.4 NFA Construction Algorithm

Figure 4.3 shows the NFA construction algorithm and subroutines are shown in the Figure 4.4. To give different names for all modules and wires, it is necessary to compute how many logic structures are being used. Thus the counter, number, is used. After accepting the regular expression in the postfix form, the algorithm would check whether the regular expression finishes or not. If not, it examines the input symbol, and then processes the particular subroutine. Until the regular expression finishes, the algorithm processes the other recursion: examining whether the number which the stack pops is the last one or not. If not, the subroutine, routing for concatenation, works for concatenation, otherwise, the subroutine, routing for i/o port, works.

Figure 4.4(a) is used only when the symbol which has to be matched is accepted and this logic structure dominates how fast the circuit can be. In Figure 4.4(a), after naming wires and the comparator, ports of the comparator are assigned and then push the number of the comparator into the stack. Next, for the next logic structure used the number must be incremented. Figure 4.4(b), (c), (d), (e), (f) and (g) are similar, so we only take Figure 4.4(b) to explain. Since the union of the regular expression in the postfix form applies to the former two, the algorithm pops the stack two times. After names of wires and the logic structure of the union are declared, the algorithm completes the connection between wires by exploiting the “assign”. Figure 4.4(i) is about the i/o port. The i port is stuck to the power supply and the o port is just the wire.

Fig 4.4(i)

Figure 4.3: the NFA construction algorithm

printf("wire w%d_1, w%d_2 ;\n", number, number) ;

printf("comparator_%c comparator%d( w%d_1, w%d_2, clk, data ) ;\n\n", postfix[k], number, number, number ) ;

printf("wire w%d_1, w%d_2, w%d_3, w%d_4, w%d_5, w%d_6 ;\n", number, number, number, number, number, number) ;

printf("union union%d( w%d_1, w%d_2, w%d_3, w%d_4, w%d_5, w%d_6 ) ;\n", number, number, number, number, number, number, number ) ;

printf("assign w%d_2 = w%d_3 ;\n", number2, number ) ; printf("assign w%d_2 = w%d_5 ;\n", number1, number ) ; printf("assign w%d_4 = w%d_1 ;\n", number, number2 ) ; printf("assign w%d_6 = w%d_1 ;\n\n", number, number1 ) ; push(s2, number) ;

number++ ;

(b)

number1 = pop(s2) ;

printf("wire w%d_1, w%d_2, w%d_3, w%d_4 ;\n", number, number, number, number) ;

printf("closure closure%d( w%d_1, w%d_2, w%d_3, w%d_4 ) ;\n", number, number, number, number, number ) ; printf("assign w%d_4 = w%d_1 ;\n", number, number1 ) ;

printf("assign w%d_2 = w%d_3 ;\n\n", number1, number ) ; push(s2, number) ;

printf("wire w%d_1, w%d_2, w%d_3, w%d_4 ;\n", number, number, number, number) ;

printf("repetition repetition%d( w%d_1, w%d_2, w%d_3, w%d_4 ) ;\n", number, number, number, number, number ) ; printf("assign w%d_4 = w%d_1 ;\n", number, number1 ) ;

printf("assign w%d_2 = w%d_3 ;\n\n", number1, number ) ; push(s2, number) ;

number++ ;

number1 = pop(s2) ;

printf("wire w%d_1, w%d_2, w%d_3, w%d_4 ;\n", number, number, number, number) ;

printf("exclusion exclusion%d( w%d_1, w%d_2, w%d_3, w%d_4 ) ;\n", number, number, number, number, number ) ; printf("assign w%d_4 = w%d_1 ;\n", number, number1 ) ;

printf("assign w%d_2 = w%d_3 ;\n\n", number1, number ) ; push(s2, number) ;

number++ ;

number1 = pop(s2) ;

printf("wire w%d_1, w%d_2, w%d_3, w%d_4 ;\n", number, number, number, number) ;

printf("dot dot%d( w%d_1, w%d_2, w%d_3, w%d_4 ) ;\n", number, number, number, number, number ) ; printf("assign w%d_4 = w%d_1 ;\n", number, number1 ) ;

printf("assign w%d_2 = w%d_3 ;\n\n", number1, number ) ; push(s2, number) ;

printf("wire w%d_1, w%d_2, w%d_3, w%d_4 ;\n", number, number, number, number) ;

printf("anchor anchor%d( w%d_1, w%d_2, w%d_3, w%d_4, xxx ) ;\n", number, number, number, number, number ) ; printf("assign w%d_4 = w%d_1 ;\n", number, number1 ) ;

printf("assign w%d_2 = w%d_3 ;\n\n", number1, number ) ; push(s2, number) ;

number++ ;

number1 = pop(s2) ; number2 = pop(s2) ;

printf("wire w%d_1, w%d_2, w%d_3, w%d_4, w%d_5, w%d_6 ;\n", number, number, number, number, number, number) ;

printf("concatenation concatenation%d( w%d_1, w%d_2, w%d_3, w%d_4, w%d_5, w%d_6 ) ;\n", number, number, number, number, number, number, number ) ;

printf("assign w%d_2 = w%d_3 ;\n", number2, number ) ; printf("assign w%d_2 = w%d_5 ;\n", number1, number ) ; printf("assign w%d_4 = w%d_1 ;\n", number, number2 ) ; printf("assign w%d_6 = w%d_1 ;\n\n", number, number1 ) ; push(s2, number) ;

number++ ;

number1 = pop(s2) ; printf("wire in ;\n") ;

printf("assign out = w%d_1 ;\n", number1) ; printf("assign w%d_2 = in ;\n\n", number1) ; printf("assign in = 1 ;\n\n") ;

(i)

Figure 4.4: (a) routing for comparator (b) routing for | (c) routing for * (d) routing for ? (e) routing for + (f) routing for . (d) routing for ? (g) routing for ^ or $

(h) routing for concatenation (d) routing for i/o ports

For more understanding, we demonstrate this method by entering a simple regular expression as the input of the system. Please refer to the Figure 4.1, Figure 4.3 and Figure 4.4. The process of constructing the NFA for the regular expression is below. The verilog code corresponding to the input, , is shown in Figure 4.5.

( | ) * ( | ) *a b c d e f g

( | ) * ( | ) *a b c d e f g ( | ) * ( | ) *a b c d e f g

(1) The regular expression is traversed from the infix form, , into the postfix form,

( | ) * ( | ) *a b c d e f g

| * | * ab cde f g

(2) In the beginning, the NFA construction algorithm prints 1st - 10th rows in Figure 4.5. The 5th row is shown for the circuit’s name and the i/o ports. The 6th, 7th and 8th rows declare that clk, data and sf are input ports, where the size of the data is 8-bits for ASCII characters. The 9th row declares the out as the output.

(3) The NFA construction algorithm begins to read the regular expression. After reading the character , the algorithm executes the subroutine shown in the Figure 4.4(a) since belongs to the character. Thus, 11

a

a th and 12th rows are printed, where

the 12th row declares the comparator and the i/o of the comparator. The stack stores the number of the comparator1.

(4) After reading the character , the process is similar with (3). The stack stores the number of the comparator2.

b

(5) After reading the metacharacter | , the algorithm executes the subroutine shown in the Figure 4.4(b). The stack pops 2 and 1. By means of the union3, the union of the a and bis implemented(shown in 18th – 23rd rows ). The stack stores the number of the union3.

(6) After reading the metacharacter *, the algorithm executes the subroutine shown in the Figure 4.4(c). The stack pops 3. By means of the closure4, the closure of

is implemented (shown in 25

( | )a b th – 27th rows). The stack stores the number of closure4.

(7) After reading the character , the process is similar with (3). The stack stores the number of the comparator5.

c

(8) After reading the character , the process is similar with (3). The stack stores the number of the comparator6.

d

(9) After reading the character , the process is similar with (3). The stack stores the number of the comparator7

e

(10) After reading the metacharacter | , the algorithm executes the subroutine shown in the Figure 4.4(b). The stack pops 7 and 6. By means of the union8, the union of d and is implemented (shown in 39e th – 43rd rows). The stack stores the number of the union8.

(11) After reading the character f , the process is similar with (3). The stack stores the number of the comparator9.

(12) After reading the metacharacter *, the algorithm executes the subroutine shown in the Figure 4.4(c). The stack pops 9. By means of the closure10, the closure of f is implemented (shown in 49th – 51st rows). The stack stores the number of closure10.

(13) After reading the character , the process is similar with (3). The stack stores the number of the comparator11.

g

(14) Reading the regular expression is finished; the algorithm executes the subroutine shown in the Figure 4.4(h). The stack pops 11 and 10. By means of the concatenation12, the concatenation of f * and is implemented (shown in 57g th – 61st rows ). The stack stores the number of the concatention12.

(15) The algorithm executes the subroutine shown in the Figure 4.4(h). The stack pops 12 and 8. By means of the concatenation13, the concatenation of ( | )d e and

*

f g is implemented (shown in 64th – 68th rows). The stack stores the number of the concatention13.

(16) The algorithm executes the subroutine shown in the Figure 4.4(h). The stack pops 13 and 5. By means of the concatenation14, the concatenation of c and

is implemented (shown in 71

( | ) *d e f g st – 75th rows). The stack stores the number

of the concatention14.

(17) The algorithm executes the subroutine shown in the Figure 4.4(h). The stack pops 14 and 4. By means of the concatenation15, the concatenation of and

is implemented (shown in 78

( | ) *a b ( | ) *

c d e f g th – 82nd rows). The stack stores the

number of the concatention15.

(18) Finally, the number, 15, which the stack pops is the last one. The algorithm executes the subroutine shown in the Figure 4.4(i), i/o ports of the circuit is connected (shown in 85th – 88th rows).

//*************************************** [01]

comparator_f comparator9( w9_1, w9_2, clk, data ) ; [46]

concatenation concatenation12( w12_1, w12_2, w12_3, w12_4, w12_5, w12_6 ) ; [57]

assign w10_2 = w12_3 ; [58]

concatenation concatenation13( w13_1, w13_2, w13_3, w13_4, w13_5, w13_6 ) ; [64]

assign w8_2 = w13_3 ; [65]

concatenation concatenation14( w14_1, w14_2, w14_3, w14_4, w14_5, w14_6 ) ; [71]

assign w5_2 = w14_3 ; [72]

concatenation concatenation15( w15_1, w15_2, w15_3, w15_4, w15_5, w15_6 ) ; [78]

assign w4_2 = w15_3 ; [79]

Chapter 5

相關文件