Skip to content

Commit be91c14

Browse files
fix a fifo problem and add scripts to test/time the coprocessor
1 parent 97cca4f commit be91c14

File tree

10 files changed

+205
-60
lines changed

10 files changed

+205
-60
lines changed

re2compiler

rtl_src/fifo.sv

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ module fifo #(
3131
logic [2:0] state_cur, state_next;
3232
logic [COUNT_WIDTH-1:0] head , head_next , head_incremented;
3333
logic [COUNT_WIDTH-1:0] tail , tail_next , tail_incremented;
34-
34+
logic [COUNT_WIDTH-1:0] where_to_read;
3535

3636
(* ram_style = "block" *) logic [DWIDTH-1:0] content [(2**COUNT_WIDTH)-1:0];
3737
logic write_enable, read_enable;
@@ -50,6 +50,7 @@ always_ff @( posedge clk ) begin
5050
head <= head_next;
5151
tail <= tail_next;
5252
state_cur <= state_next;
53+
middle <= middle_next;
5354
end
5455
end
5556

@@ -60,9 +61,9 @@ always_ff @(posedge clk)begin
6061
content[tail] <= din;
6162
end
6263

63-
from_memory <= content[head_incremented];
64+
from_memory <= content[where_to_read];
6465

65-
middle <= middle_next;
66+
6667
end
6768
assign from_din = din;
6869

@@ -89,9 +90,9 @@ assign from_din = din;
8990
// v |
9091
// W,R&W,_
9192
always_comb begin //create full empty signals
92-
data_count = tail - head;
93-
head_incremented = head + 1 ;
94-
tail_incremented = tail + 1 ;
93+
data_count = tail - head;
94+
head_incremented = head + 1 ;
95+
tail_incremented = tail + 1 ;
9596

9697
//empty
9798
if( head == tail ) empty = 1'b1;
@@ -123,9 +124,11 @@ always_comb begin //create full empty signals
123124
//middle register and memory
124125
//bit states represent: register, memory_output, memory_content
125126
// validity.
126-
state_next = state_cur;
127-
middle_next = middle;
128-
dout = middle;
127+
state_next = state_cur;
128+
middle_next = middle;
129+
dout = middle;
130+
//all read from h+1 but not state 111 with an incoming read
131+
where_to_read = head_incremented;
129132
case(state_cur)
130133
3'b000:
131134
begin
@@ -159,11 +162,12 @@ always_comb begin //create full empty signals
159162
3'b101:
160163
begin
161164
dout = middle;
165+
162166
case({write_enable, read_enable})
163167
2'b11:
164168
begin
165169
state_next = 3'b011;
166-
//middle can't be updated (memory invalid)
170+
//middle can't be updated (memory output invalid)
167171
end
168172
2'b10:
169173
begin
@@ -173,7 +177,7 @@ always_comb begin //create full empty signals
173177
2'b01:
174178
begin
175179
state_next = 3'b010;
176-
//middle can't be updated (memory invalid)
180+
//middle can't be updated (memory output invalid)
177181
end
178182
default:
179183
begin
@@ -199,7 +203,7 @@ always_comb begin //create full empty signals
199203
2'b01:
200204
begin
201205
state_next = 3'b000;
202-
//queue is void
206+
//queue would be void
203207
end
204208
default:
205209
begin
@@ -216,7 +220,8 @@ always_comb begin //create full empty signals
216220
begin
217221
state_next = state_cur;
218222
//data_in is written in memory and
219-
//middle is not used
223+
//from_memory, which was intended for middle is redirected toward output
224+
//middle can't be updated
220225
end
221226
2'b10:
222227
begin
@@ -226,6 +231,7 @@ always_comb begin //create full empty signals
226231
2'b01:
227232
begin
228233
state_next = 3'b010;
234+
229235
end
230236
default:
231237
begin
@@ -238,13 +244,18 @@ always_comb begin //create full empty signals
238244
begin
239245
dout = middle;
240246

241-
if(read_enable )
247+
if(read_enable)
242248
begin
243-
middle_next= from_memory;
244-
if(data_count == 2 )
249+
middle_next = from_memory;
250+
where_to_read = head_incremented +1;
251+
if(data_count == 2 && ~ write_enable)
245252
begin
246253
state_next = 3'b100;
247254
end
255+
else if(data_count == 2 && write_enable)
256+
begin
257+
state_next = 3'b101;
258+
end
248259

249260
end
250261
end

scripts/comparison.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import re2_driver
21
import pynq
32
from pynq import Overlay
3+
import re2_driver
44
from test_execution import time_full_match, time_match, time_ignore_prefix_match
55
import argparse
66

@@ -9,21 +9,23 @@
99
arg_parser.add_argument('-ignore_prefix' , help='do not pose any constraint on where the regular expression starts matching the string. Corresponds to .*<your_regex>' , default=False, action='store_true')
1010
args = arg_parser.parse_args()
1111

12-
re2_coprocessor = Overlay('re2_coprocessor.bit')
13-
regex_string = 'a?a?bb'
14-
string = 'b'+'a'*8
12+
re2_coprocessor = Overlay('../bitstreams/recopro2BBP100.bit')
13+
regex_string = '((R|K|X)(...?)?(D|B|E|Z|X)(...?)?(Y|X))|(.(G|X)(R|K|X)(R|K|X))|((S|T|X).(R|K|X))'
14+
string = 'MQNPLPEVMSPEHDKRTTTPMSKEANKFIRELDKKPGDLAVVSDFVKRNTGKRLPIGKRSNLYVRICDLSGTIYMGETFILESWEELYLPEPTKMEVLGTLESCCGIPPFPEWIVMVGEDQCVYAYGDEEILLFAYSVKQLVEEGIQETGISYKYPDDISDVDEEVLQQDEEIQKIRKKTREFVDKDAQEFQDFLNSLDASLLS'
1515
print('regex', regex_string, 'string', string)
1616
freq = 100_000_000
17-
has_accepted = re2_coprocessor.re2_copro_0.compile_and_run(regex_string, string, full_match=args.full_match,ignore_prefix=args.ignore_prefix )
17+
has_accepted = re2_coprocessor.re2_copro_0.compile_and_run(regex_string, string, full_match=args.full_match,ignore_prefix=args.ignore_prefix , O1=False)
1818
cc_number = re2_coprocessor.re2_copro_0.read_elapsed_clock_cycles()
1919
print('clock cycles taken:', cc_number)
2020
print('status:', re2_coprocessor.re2_copro_0.get_status())
2121
time = cc_number*1/freq*1_000_000_000
2222
print('time re2coprocessor', time, 'ns')
23+
'''
2324
if args.full_match:
2425
min_time,avg_time = time_full_match(regex_string, string)
2526
elif args.ignore_prefix:
2627
min_time,avg_time = time_ignore_prefix_match(regex_string, string)
2728
else:
2829
min_time,avg_time = time_match(regex_string, string)
29-
print('time python re module min:', min_time, 'avg:',avg_time, 'ns')
30+
print('time python re module min:', min_time, 'avg:',avg_time, 'ns')
31+
'''

scripts/re2_driver.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,13 @@ def reset(self):
175175
self.write_cmd(RE2_COPROCESSOR_COMMANDS.NOP)
176176
return True
177177

178-
def compile_and_run(self, regex_string, string, double_check =True,ignore_prefix=True, full_match=False ):
178+
def compile_and_run(self, regex_string, string, double_check =True,ignore_prefix=True, full_match=False, O1=True ):
179179

180180
try:
181181

182182
import os.path
183-
code_output_file = regex_string+'.out'
184-
183+
code_output_file = regex_string+('_ignore_' if ignore_prefix else '')+('_full_match_' if full_match else '')+('_O1_' if O1 else '')+'.out'
184+
code_output_file = code_output_file.replace('/', u'\u2215')
185185
if os.path.exists(code_output_file):
186186
print('reusing previously compilation')
187187
code = ''
@@ -192,7 +192,7 @@ def compile_and_run(self, regex_string, string, double_check =True,ignore_prefix
192192
sys.path.append('../re2compiler')
193193
import re2compiler
194194
print('start compilation')
195-
code = re2compiler.compile(data=regex_string,o=code_output_file, O1=True,ignore_prefix=ignore_prefix, full_match=full_match)
195+
code = re2compiler.compile(data=regex_string,o=code_output_file, O1=O1,ignore_prefix=ignore_prefix, full_match=full_match)
196196
print('end compilation')
197197
code = code.split('\n')
198198
res = self.load_and_run( code , string)
@@ -244,18 +244,18 @@ def load_and_run(self, code, string):
244244
debug = False
245245
#IP_BASE_ADDRESS = 0x43C00000 or equivalently 1136656384
246246
#ADDRESS_RANGE = 6*4
247-
re2_coprocessor = Overlay('re2_coprocessor.bit')
247+
re2_coprocessor = Overlay('../bitstreams/re2_coprocessor16bbP85.bit')
248248
if debug :
249249
print('test:',re2_coprocessor.ip_dict)
250250

251251
cc_number = re2_coprocessor.re2_copro_0.read_elapsed_clock_cycles()
252252
print('status:', re2_coprocessor.re2_copro_0.get_status())
253253
time.sleep(1)
254254

255-
regex_string = 'a?a?bb'
255+
regex_string = '(R|K|X)(...?)?(D|B|E|Z|X)(...?)?(Y|X)'
256256
string = 'b'+'a'*8
257257

258-
string_to_accept = "a"*16+'bb'
258+
string_to_accept = "MSIIGATRLQNDKSDTYSAGPCYAGGCSAFTPRGTCGKDWDLGEQTCASGFCTSQPLCARIKKTQVCGLRYSSKGKDPLVSAEWDSRGAPYVRCTYDADLIDTQAQVDQFVSMFGESPSLAERYCMRGVKNTAGELVSRVSSDADPAGGWCRKWYSAHRGPDQDAALGSFCIKNPGAADCKCINRASDPVYQKVKTLHAYPDQCWYVPCAADVGELKMGTQRDTPTNCPTQVCQIVFNMLDDGSVTMDDVKNTINCDFSKYVPPPPPPKPTPPTPPTPPTPPTPPTPPTPPTPRPVHNRKVMFFVAGAVLVAILISTVRW"
259259
string_to_reject = "a"*15+"b"
260260
#test to accept
261261

scripts/test.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import test_execution
2+
import csv
3+
import os
4+
import argparse
5+
6+
arg_parser = argparse.ArgumentParser(description='test regular expression matching')
7+
arg_parser.add_argument('-startstr' , type=int , help='index first str.' , default=0 )
8+
arg_parser.add_argument('-endstr' , type=int , help='index end string.' , default=None)
9+
arg_parser.add_argument('-startreg' , type=int , help='index first reg.' , default=0 )
10+
arg_parser.add_argument('-endreg' , type=int , help='index end reg.' , default=None)
11+
arg_parser.add_argument('-testpy' , help='measure time taken by python', action='store_true' , default=False)
12+
arg_parser.add_argument('-testcopro' , help='measure time taken by copro.', action='store_true' , default=False)
13+
arg_parser.add_argument('-strfile' , type=str , help='file containing test input' , default='test2.input')
14+
arg_parser.add_argument('-regfile' , type=str , help='file containing test reg' , default='test.reg')
15+
arg_parser.add_argument('-bitstream' , type=str , help='bitstream file of the coprocessor' , default='re2_coprocessor4bbP110.bit')
16+
arg_parser.add_argument('-do_not_optimize' , help='do not optimize recopro code' ,action='store_true', default=False)
17+
18+
args = arg_parser.parse_args()
19+
optimize_str = 'O1' if not args.do_not_optimize else ''
20+
bitstream_filename = os.path.basename(args.bitstream)[:-4]
21+
with open(f'log_{bitstream_filename}_{optimize_str}.csv', 'w', newline='') as csvfile:
22+
fout = csv.writer(csvfile, delimiter=';', quoting=csv.QUOTE_MINIMAL)
23+
with open(args.strfile, 'r', errors='ignore') as f:
24+
lines = f.readlines()[args.startstr:args.endstr]
25+
for line in lines:
26+
print('len', len(line),'->', bytes(line,'utf-8'))
27+
line = line[:-1]
28+
fout.writerow(['string', line, '', ''])
29+
fout.writerow(['regex', 'result','copro', 'python re'])
30+
with open(args.regfile) as f:
31+
for r in f.readlines()[args.startreg:args.endreg]:
32+
r = r[:-1]
33+
print('regex', r,'\nstring', line)
34+
try:
35+
min_time_copro = 0
36+
has_accepted = 'UNK'
37+
if args.testcopro:
38+
import re2_driver
39+
import pynq
40+
from pynq import Overlay
41+
re2_coprocessor = Overlay(args.bitstream)
42+
43+
44+
#freq = 90_000_000
45+
has_accepted = re2_coprocessor.re2_copro_0.compile_and_run(r, line, ignore_prefix=True, O1=(not args.do_not_optimize) )
46+
cc_number = re2_coprocessor.re2_copro_0.read_elapsed_clock_cycles()
47+
print('clock cycles taken:', cc_number)
48+
print('status:', re2_coprocessor.re2_copro_0.get_status())
49+
min_time_copro = cc_number#*1/freq*1_000_000_000
50+
print('time re2coprocessor', min_time_copro, 'cc')
51+
min_time_re = 0
52+
if args.testpy:
53+
min_time_re = test_execution.time_ignore_prefix_match(r, line, perf_counter=True)
54+
print('minimum time', min_time_re, 'ns')
55+
56+
fout.writerow([r,has_accepted, min_time_copro, min_time_re,' '])
57+
except Exception as exc:
58+
raise exc
59+
print('error',r,exc)
60+
61+
62+
63+

scripts/test2.reg

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(((R|K|X)(R|K|X))?.(S|T|X))
2+
(S|T|X)(..)?(D|B|E|Z|X)
3+
(C|X).(D|B|N|B|X)(....)?(F|Y|X).(C|X).(C|X)
4+
(C|X)(.....?)?(C|X)(C|X)(S|X)(..)?(G|X).(C|X)(G|X)(....?)?(F|Y|W|X)(C|X)
5+
(C|X)(..(..)?)?(C|X)(...)?(L|I|V|M|F|Y|W|C|X)(........)?(H|X)(...(..)?)?(H|X)
6+
((L|I|V|M|F|E|Z|X)(F|Y|X)(P|X)(W|X)(M|X)(K|R|Q|Z|T|A|X))
7+
((L|X)(M|X)(A|X)(E|Z|Q|Z|X)(G|X)(L|X)(Y|X)(N|B|X))
8+
((R|X)(P|X)(C|X)(..........)?(C|X)(V|X)(S|X))
9+
(R|K|X)(...?)?(D|B|E|Z|X)(...?)?(Y|X)
10+
.(G|X)(R|K|X)(R|K|X)
11+
(S|T|X).(R|K|X)
12+
((R|K|X)(...?)?(D|B|E|Z|X)(...?)?(Y|X))|(.(G|X)(R|K|X)(R|K|X))|((S|T|X).(R|K|X))

scripts/test5.input

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
MAFSAEDVLKEYDRRRRMEALLLSLYYPNDRKLLDYKEWSPPRVQVECPKAPVEWNNPPSEKGLIVGHFSGIKYKGEKAQASEVDVNKMCCWVSKFKDAMRRYQGIQTCKIPGKVLSDLDAKIKAYNLTVEGVEGFVRYSRVTKQHVAAFLKELRHSKQYENVNLIHYILTDKRVDIQHLEKDLVKDFKALVESAHRMRQGHMINVKYILYQLLKKHGHGPDGPDILTVKTGSKGVLYDDSFRKIYTDLGWKFTPL
2+
MSIIGATRLQNDKSDTYSAGPCYAGGCSAFTPRGTCGKDWDLGEQTCASGFCTSQPLCARIKKTQVCGLRYSSKGKDPLVSAEWDSRGAPYVRCTYDADLIDTQAQVDQFVSMFGESPSLAERYCMRGVKNTAGELVSRVSSDADPAGGWCRKWYSAHRGPDQDAALGSFCIKNPGAADCKCINRASDPVYQKVKTLHAYPDQCWYVPCAADVGELKMGTQRDTPTNCPTQVCQIVFNMLDDGSVTMDDVKNTINCDFSKYVPPPPPPKPTPPTPPTPPTPPTPPTPPTPPTPRPVHNRKVMFFVAGAVLVAILISTVRW
3+
MASNTVSAQGGSNRPVRDFSNIQDVAQFLLFDPIWNEQPGSIVPWKMNREQALAERYPELQTSEPSEDYSGPVESLELLPLEIKLDIMQYLSWEQISWCKHPWLWTRWYKDNVVRVSAITFEDFQREYAFPEKIQEIHFTDTRAEEIKAILETTPNVTRLVIRRIDDMNYNTHGDLGLDDLEFLTHLMVEDACGFTDFWAPSLTHLTIKNLDMHPRWFGPVMDGIKSMQSTLKYLYIFETYGVNKPFVQWCTDNIETFYCTNSYRYENVPRPIYVWVLFQEDEWHGYRVEDNKFHRRYMYSTILHKRDTDWVENNPLKTPAQVEMYKFLLRISQLNRDGTGYESDSDPENEHFDDESFSSGEEDSSDEDDPTWAPDSDDSDWETETEEEPSVAARILEKGKLTITNLMKSLGFKPKPKKIQSIDRYFCSLDSNYNSEDEDFEYDSDSEDDDSDSEDDC
4+
MYQAINPCPQSWYGSPQLEREIVCKMSGAPHYPNYYPVHPNALGGAWFDTSLNARSLTTTPSLTTCTPPSLAACTPPTSLGMVDSPPHINPPRRIGTLCFDFGSAKSPQRCECVASDRPSTTSNTAPDTYRLLITNSKTRKNNYGTCRLEPLTYGI
5+
MARPLLGKTSSVRRRLESLSACSIFFFLRKFCQKMASLVFLNSPVYQMSNILLTERRQVDRAMGGSDDDGVMVVALSPSDFKTVLGSALLAVERDMVHVVPKYLQTPGILHDMLVLLTPIFGEALSVDMSGATDVMVQQIATAGFVDVDPLHSSVSWKDNVSCPVALLAVSNAVRTMMGQPCQVTLIIDVGTQNILRDLVNLPVEMSGDLQVMAYTKDPLGKVPAVGVSVFDSGSVQKGDAHSVGAPDGLVSFHTHPVSSAVELNYHAGWPSNVDMSSLLTMKNLMHVVVAEEGLWTMARTLSMQRLTKVLTDAEKDVMRAAAFNLFLPLNELRVMGTKDSNNKSLKTYFEVFETFTIGALMKHSGVTPTAFVDRRWLDNTIYHMGFIPWGRDMRFVVEYDLDGTNPFLNTVPTLMSVKRKAKIQEMFDNMVSRMVTS
6+
MNAKYDTDQGVGRMLFLGTIGLAVVVGGLMAYGYYYDGKTPSSGTSFHTASPSFSSRYRY
7+
MRYTVLIALQGALLLLLLIDDGQGQSPYPYPGMPCNSSRQCGLGTCVHSRCAHCSSDGTLCSPEDPTMVWPCCPESSCQLVVGLPSLVNHYNCLPNQCTDSSQCPGGFGCMTRRSKCELCKADGEACNSPYLDWRKDKECCSGYCHTEARGLEGVCIDPKKIFCTPKNPWQLAPYPPSYHQPTTLRPPTSLYDSWLMSGFLVKSTTAPSTQEEEDDY
8+
MQNPLPEVMSPEHDKRTTTPMSKEANKFIRELDKKPGDLAVVSDFVKRNTGKRLPIGKRSNLYVRICDLSGTIYMGETFILESWEELYLPEPTKMEVLGTLESCCGIPPFPEWIVMVGEDQCVYAYGDEEILLFAYSVKQLVEEGIQETGISYKYPDDISDVDEEVLQQDEEIQKIRKKTREFVDKDAQEFQDFLNSLDASLLS
9+
MDSLNEVCYEQIKGTFYKGLFGDFPLIVDKKTGCFNATKLCVLGGKRFVDWNKTLRSKKLIQYYETRCDIKTESLLYEIKGDNNDEITKQITGTYLPKEFILDIASWISVEFYDKCNNIIINYFVNEYKTMDKKTLQSKINEVEEKMQKLLNEKEEELQEKNDKIDELILFSKRMEEDRKKDREMMIKQEKMLRELGIHLEDVSSQNNELIEKVDEQVEQNAVLNFKIDNIQNKLEIAVEDRAPQPKQNLKRERFILLKRNDDYYPYYTIRAQDINARSALKRQKNLYNEVSVLLDLTCHPNSKTLYVRVKDELKQKGVVFNLCKVSISNSKINEEELIKAMETINDEKRDV
10+
MYKMYFLKDQKFSLSGTIRINDKTQSEYGSVWCPGLSITGLHHDAIDHNMFEEMETEIIEYLGPWVQAEYRRIKG

scripts/test_arbiter_creation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
BB_N = 10
1+
BB_N = 16
22
res = ""
33
res = 'digraph{\n'
44
for i in range(BB_N):

0 commit comments

Comments
 (0)