Skip to content

Commit 3a2239c

Browse files
committed
make_hls.py: Now only required files are added for synthesis.
1 parent e38dc51 commit 3a2239c

File tree

5 files changed

+220
-126
lines changed

5 files changed

+220
-126
lines changed

include/layers/lstm/lstm_data_handler.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ class AcceleratorBlob {
418418
const int kU_RecTotalSize = kNumGates / 2 * this->rec_gates_["i"]->get_u()->get_pruned_total_size();
419419
const int kV_TotalSize = kNumGates * this->cur_gates_["i"]->get_v()->get_pruned_total_size();
420420
const int kS_TotalSize = kNumGates * refinement_steps;
421-
std::cout << "setting fix_u_cur_" << std::endl;
421+
// std::cout << "setting fix_u_cur_" << std::endl;
422422
// this->fix_u_cur_ = new FixType[kU_CurTotalSize]; // svd::AllocateContiguously<FixType>(kU_CurTotalSize);
423423
// this->fix_u_rec_ = new FixType[kU_RecTotalSize]; // svd::AllocateContiguously<FixType>(kU_RecTotalSize);
424424
// this->fix_v_ = new FixType[kV_TotalSize]; // svd::AllocateContiguously<FixType>(kV_TotalSize);
@@ -433,29 +433,29 @@ class AcceleratorBlob {
433433
// this->fix_nz_v_ = new ap_uint<NumTilesV>[kS_TotalSize]; // svd::AllocateContiguously<ap_uint<NumTilesV> >(kS_TotalSize);
434434
this->fix_nz_u_.resize(kS_TotalSize);
435435
this->fix_nz_v_.resize(kS_TotalSize);
436-
std::cout << "kS_TotalSize: " << kS_TotalSize << std::endl;
437-
std::cout << "kS_TotalSize / 8: " << kS_TotalSize / 8 << std::endl;
436+
// std::cout << "kS_TotalSize: " << kS_TotalSize << std::endl;
437+
// std::cout << "kS_TotalSize / 8: " << kS_TotalSize / 8 << std::endl;
438438
// NOTE: the following arrangement is: (R, E, G)
439439
const int kArrangementTypeREG = 2;
440440
const int kArrangementTypeRGE = 0;
441441
const int kU_CurLengthPruned = this->cur_gates_["i"]->get_u()->get_pruned_size();
442442
const int kU_RecLengthPruned = this->rec_gates_["i"]->get_u()->get_pruned_size();
443443
const int kV_LengthPruned = this->cur_gates_["i"]->get_v()->get_pruned_size();
444-
std::cout << "setting ArrangeWeights" << std::endl;
444+
// std::cout << "setting ArrangeWeights" << std::endl;
445445
svd::ArrangeWeights(kArrangementTypeREG, refinement_steps, kU_CurLengthPruned,
446446
this->cur_gates_["i"]->get_u()->fix_pruned_data(),
447447
this->cur_gates_["f"]->get_u()->fix_pruned_data(),
448448
this->cur_gates_["c"]->get_u()->fix_pruned_data(),
449449
this->cur_gates_["o"]->get_u()->fix_pruned_data(),
450450
this->fix_u_cur_.data());
451-
std::cout << "setting ArrangeWeights" << std::endl;
451+
// std::cout << "setting ArrangeWeights" << std::endl;
452452
svd::ArrangeWeights(kArrangementTypeREG, refinement_steps, kU_RecLengthPruned,
453453
this->rec_gates_["i"]->get_u()->fix_pruned_data(),
454454
this->rec_gates_["f"]->get_u()->fix_pruned_data(),
455455
this->rec_gates_["c"]->get_u()->fix_pruned_data(),
456456
this->rec_gates_["o"]->get_u()->fix_pruned_data(),
457457
this->fix_u_rec_.data());
458-
std::cout << "setting ArrangeWeights S" << std::endl;
458+
// std::cout << "setting ArrangeWeights S" << std::endl;
459459
svd::ArrangeWeights(kArrangementTypeREG, refinement_steps, kV_LengthPruned,
460460
kV_LengthPruned,
461461
this->cur_gates_["i"]->get_v()->fix_pruned_data(),
@@ -467,7 +467,7 @@ class AcceleratorBlob {
467467
this->rec_gates_["c"]->get_v()->fix_pruned_data(),
468468
this->rec_gates_["o"]->get_v()->fix_pruned_data(),
469469
this->fix_v_.data());
470-
std::cout << "setting ArrangeWeights NZu" << std::endl;
470+
// std::cout << "setting ArrangeWeights NZu" << std::endl;
471471
svd::ArrangeWeights(kArrangementTypeRGE, refinement_steps, 1, 1,
472472
this->cur_gates_["i"]->get_u()->get_fix_nz_idx(),
473473
this->cur_gates_["f"]->get_u()->get_fix_nz_idx(),
@@ -478,7 +478,7 @@ class AcceleratorBlob {
478478
this->rec_gates_["c"]->get_u()->get_fix_nz_idx(),
479479
this->rec_gates_["o"]->get_u()->get_fix_nz_idx(),
480480
this->fix_nz_u_.data());
481-
std::cout << "setting ArrangeWeights NZv" << std::endl;
481+
// std::cout << "setting ArrangeWeights NZv" << std::endl;
482482
svd::ArrangeWeights(kArrangementTypeRGE, refinement_steps, 1, 1,
483483
this->cur_gates_["i"]->get_v()->get_fix_nz_idx(),
484484
this->cur_gates_["f"]->get_v()->get_fix_nz_idx(),
@@ -531,7 +531,7 @@ class AcceleratorBlob {
531531
}
532532
}
533533
}
534-
std::cout << "allocation done." << std::endl;
534+
// std::cout << "allocation done." << std::endl;
535535
}
536536

537537
~AcceleratorBlob() {

include/math_utils/data_handler.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ class VectorBlob {
180180
this->fix_data_.push_back(FixType(tmp));
181181
this->fix_pruned_data_.push_back(FixType(tmp));
182182
}
183-
std::cout << "this->data_.size(): " << this->data_.size() << std::endl;
184183
}
185184
}
186185

make_hls.py

Lines changed: 164 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,22 @@ def is_top_file(filename, top):
4646

4747
def get_dependent_files(filename):
4848
headers = []
49+
headers_decl = []
4950
with open(filename, 'r') as f:
5051
for line in f:
5152
if '#include' in line:
52-
headers.append(line)
53+
headers_decl.append(line)
54+
for h in headers_decl:
55+
match = re.search('"(.*?)"', h)
56+
if match is not None:
57+
for m in match.groups():
58+
headers.append(m.replace('"', ''))
59+
match = re.search('<(.*?)>', h)
60+
if match is not None:
61+
for m in match.groups():
62+
tmp = m.replace('<', '')
63+
tmp = tmp.replace('>', '')
64+
headers.append(tmp)
5365
return headers
5466

5567
def main():
@@ -67,13 +79,15 @@ def main():
6779
parser.add_argument('--script_name', type=str, default='run_hls_test.tcl', help='Generated TCL filename. Default: run_hls.tcl.')
6880
parser.add_argument('--run_hls', action='store_true', help='Run th generated TCL file. Default: False.')
6981

70-
parser.add_argument('--board', type=str, choices=avail_fpgas.keys(), default='ZedBoard', help='The target FPGA board.')
82+
parser.add_argument('--board', type=str, choices=avail_fpgas.keys(), default='ZedBoard', help='The target FPGA board. Default: ZedBoard')
7183
parser.add_argument('--period', type=str, default='10', help='Clock period in ns. Default: 10.')
7284
# Actions
7385
parser.add_argument('--use_vivado_hls', action='store_true', help='Use Vivado HLS. Default is Vitis HLS.')
7486
parser.add_argument('--no_synthesis', action='store_true', help='Do not run synthesis.')
7587
parser.add_argument('--csim', action='store_true', help='Run C/C++ simulation.')
7688
parser.add_argument('--cosim', action='store_true', help='Run C/C++ co-simulation.')
89+
parser.add_argument('--cosim-all', action='store_true', help='Run C/C++ co-simulation and track all signals.')
90+
parser.add_argument('--cosim-port', action='store_true', help='Run C/C++ co-simulation and track ports.')
7791
parser.add_argument('--export', action='store_true', help='Export IP.')
7892
parser.add_argument('--place_and_route', action='store_true', help='Export IP and check place-and-route.')
7993
parser.add_argument('--no_reset_prj', action='store_true', help='Do not reset HLS project.')
@@ -96,7 +110,8 @@ def main():
96110

97111
args = parser.parse_args()
98112

99-
if args.csim and args.tb_file == '' or args.cosim and args.tb_file == '':
113+
run_cosim = args.cosim or args.cosim_port or args.cosim_all
114+
if args.csim and args.tb_file == '' or run_cosim and args.tb_file == '':
100115
parser.error('The --csim and --cosim arguments requires --tb_file.')
101116
# ==========================================================================
102117
# Setup
@@ -106,11 +121,11 @@ def main():
106121
hls_report_dir = hls_prj_dir + '/reports'
107122
hls_tool = 'vhls' if args.use_vivado_hls else 'vitis'
108123
prj_name = f'{hls_tool}_{args.board}_{args.top}'
109-
reset_string = ' -reset ' if args.no_reset_prj else ''
124+
reset_string = '' if args.no_reset_prj else ' -reset '
110125
# ==========================================================================
111126
# Adjust CFLAGS and add defines
112127
# ==========================================================================
113-
cflags = args.cflags + ' -I' + curr_dir + args.include
128+
cflags = args.cflags + ' -I' + curr_dir + args.include + ' -I/usr/local/include'
114129
if hls_tool == 'vhls':
115130
cflags = '-fno-builtin ' + cflags.replace('c++14', 'c++0x')
116131
print(f'[WARNING] Replacing C++14 with C++11 in Vivado HLS. CFLAGS: {cflags}')
@@ -126,7 +141,7 @@ def main():
126141
f.write(f'set_top "{args.top}"\n')
127142
if not args.no_reset_prj:
128143
pass
129-
if args.csim or args.cosim:
144+
if args.csim or run_cosim:
130145
pass
131146
if hls_tool == 'vitis':
132147
f.write(f'open_solution -flow_target vivado {reset_string} "solution_{args.top}"\n')
@@ -148,52 +163,146 @@ def main():
148163
# Add only significant files to synthesis
149164
# ======================================================================
150165
# TODO: Recursively include only the files from which the top function depends on.
166+
167+
def loadtxt(filename):
168+
with open(filename) as f:
169+
txt = ''.join(f.readlines())
170+
return txt
171+
172+
# ======================================================================
173+
# Search for the top function in the C++ or Header files
174+
# ======================================================================
175+
# regex group1, name group2, arguments group3
176+
rproc = r"((?<=[\s:~])(\w+)\s*\(([\w\s,<>\[\].=&':/*]*?)\)\s*(const)?\s*(?={))"
177+
prog = re.compile(rproc)
178+
syn_files = []
179+
tb_files = []
151180
headers = []
152-
if args.top_file:
181+
182+
def find_top_file(starting_dir):
183+
for fpath, subdirs, files in os.walk(starting_dir):
184+
for fname in files:
185+
unix_filename = curr_dir + '/' + fpath.replace('\\', '/') + '/' + fname
186+
is_cpp_file = fname.endswith('.cpp') or fname.endswith('.cc')
187+
is_h_file = fname.endswith('.hpp') or fname.endswith('.h')
188+
if is_cpp_file or is_h_file:
189+
code = loadtxt(unix_filename)
190+
cppwords = ['if', 'while', 'do', 'for', 'switch']
191+
procs = [(i.group(2), i.group(3)) for i in prog.finditer(code) \
192+
if i.group(2) not in cppwords]
193+
for i in procs:
194+
if i[0] == args.top:
195+
return unix_filename
196+
197+
def get_headers(headers, top_filename, starting_dir=args.src):
198+
added_headers = 0
199+
src_dir = curr_dir + starting_dir.replace('\\', '/') + '/'
200+
found_file = False
201+
for fpath, subdirs, files in os.walk(starting_dir):
202+
for fname in files:
203+
unix_filename = curr_dir + '/' + fpath.replace('\\', '/') + '/' + fname
204+
unix_filename = unix_filename.replace('//', '/')
205+
top_filename = top_filename.replace('//', '/')
206+
if unix_filename == top_filename:
207+
found_file = True
208+
hfiles = get_dependent_files(unix_filename)
209+
for h in hfiles:
210+
if h not in headers:
211+
headers.append(h)
212+
added_headers += 1
213+
return added_headers, found_file
214+
215+
top_file = find_top_file(args.src)
216+
if top_file is not None:
217+
get_headers(headers, top_file, starting_dir=args.src)
218+
get_headers(headers, top_file, starting_dir=args.include)
219+
else:
220+
top_file = find_top_file(args.include)
221+
if top_file is None:
222+
print(f'[ERROR] Top function {args.top} not found in files. Exiting.')
223+
exit(1)
224+
get_headers(headers, top_file, starting_dir=args.src)
225+
get_headers(headers, top_file, starting_dir=args.include)
226+
227+
for h in headers:
228+
inc_dir = curr_dir + args.include.replace('\\', '/') + '/'
229+
if os.path.isfile(inc_dir + h):
230+
syn_files.append(inc_dir + h)
231+
# Recursive search
232+
added_headers = 1
233+
while(added_headers != 0):
234+
added_headers = 0
235+
for h in headers:
236+
inc_dir = curr_dir + args.include.replace('\\', '/') + '/'
237+
src_dir = curr_dir + args.src.replace('\\', '/') + '/'
238+
num_headers, found_file = get_headers(headers, inc_dir + h, starting_dir=args.include)
239+
added_headers += num_headers
240+
if found_file and h not in tb_files:
241+
syn_files.append(inc_dir + h)
242+
tb_files.append(inc_dir + h)
243+
# Adding the corresponding C++ files
244+
for hext in ['.h', '.hpp']:
245+
for cppext in ['.cc', '.cpp']:
246+
cppfile = h.replace(hext, cppext)
247+
found_file = False
248+
num_headers, found_file = get_headers(headers, src_dir + cppfile, args.src)
249+
added_headers += num_headers
250+
if found_file and cppfile not in headers:
251+
headers.append(cppfile)
252+
syn_files.append(src_dir + cppfile)
253+
tb_files.append(src_dir + cppfile)
254+
f.write(f'# Synthesis files\n')
255+
for filename in syn_files:
256+
f.write(f'add_files {filename} -cflags "{cflags}"\n')
257+
258+
if args.tb_file != '':
259+
f.write(f'# TB files\n')
260+
# Search in src files
153261
for fpath, subdirs, files in os.walk(args.src):
154262
for fname in files:
155-
if args.top_file.replace('.cpp', '') == fname.replace('.cpp', '') or \
156-
args.top_file.replace('.h', '') == fname.replace('.h', ''):
157-
headers_decl = get_dependent_files(fpath + '/' + fname)
158-
for h in headers_decl:
159-
match = re.search('"(.*?)"', h)
160-
if match is not None:
161-
for m in match.groups():
162-
headers.append(m.replace('"', ''))
163-
match = re.search('<(.*?)>', h)
164-
if match is not None:
165-
for m in match.groups():
166-
tmp = m.replace('<', '')
167-
tmp = tmp.replace('>', '')
168-
headers.append(tmp)
169-
print(headers)
170-
# ======================================================================
171-
# Add files
172-
# ======================================================================
173-
f.write(f'# Source files\n')
174-
for fpath, subdirs, files in os.walk(args.src):
175-
for fname in files:
176-
unix_filename = curr_dir + '/' + fpath.replace('\\', '/') + '/' + fname
177-
if fname.endswith('.cpp') or fname.endswith('.cc'):
178-
if args.tb_dir.replace('\\', '/') not in fpath:
179-
print(f'[INFO] Adding synthesis file: {unix_filename}')
180-
f.write(f'add_files {unix_filename} -cflags "{cflags}"\n')
181-
else:
182-
if fname.startswith(args.tb_file):
183-
print(f'[INFO] Adding simulation file: {unix_filename}')
184-
f.write(f'add_files -tb {unix_filename} -cflags "{cflags}"\n')
185-
f.write(f'# Include files\n')
186-
for fpath, subdirs, files in os.walk(args.include):
187-
for fname in files:
188-
unix_filename = curr_dir + '/' + fpath.replace('\\', '/') + '/' + fname
189-
if fname.endswith('.h'):
190-
if args.tb_dir.replace('\\', '/') not in fpath:
191-
print(f'[INFO] Adding synthesis file: {unix_filename}')
192-
f.write(f'add_files {unix_filename} -cflags "{cflags}"\n')
193-
else:
194-
if fname.startswith(args.tb_file):
195-
print(f'[INFO] Adding simulation file: {unix_filename}')
196-
f.write(f'add_files -tb {unix_filename} -cflags "{cflags}"\n')
263+
unix_filename = curr_dir + '/' + fpath.replace('\\', '/') + '/' + fname
264+
if fname.startswith(args.tb_file):
265+
f.write(f'add_files -tb {unix_filename} -cflags "{cflags}"\n')
266+
# Search in include files
267+
for fpath, subdirs, files in os.walk(args.include):
268+
for fname in files:
269+
unix_filename = curr_dir + '/' + fpath.replace('\\', '/') + '/' + fname
270+
if fname.startswith(args.tb_file):
271+
f.write(f'add_files -tb {unix_filename} -cflags "{cflags}"\n')
272+
273+
# for filename in tb_files:
274+
# f.write(f'add_files -tb {filename} -cflags "{cflags}"\n')
275+
276+
# # ======================================================================
277+
# # Add files
278+
# # ======================================================================
279+
# f.write(f'# Source files\n')
280+
# for fpath, subdirs, files in os.walk(args.src):
281+
# for fname in files:
282+
# unix_filename = curr_dir + '/' + fpath.replace('\\', '/') + '/' + fname
283+
# if fname.endswith('.cpp') or fname.endswith('.cc'):
284+
# if args.tb_dir.replace('\\', '/') not in fpath:
285+
# # print(f'[INFO] Adding synthesis file: {unix_filename}')
286+
# f.write(f'add_files {unix_filename} -cflags "{cflags}"\n')
287+
# else:
288+
# if fname.startswith(args.tb_file):
289+
# # print(f'[INFO] Adding simulation file: {unix_filename}')
290+
# f.write(f'add_files -tb {unix_filename} -cflags "{cflags}"\n')
291+
292+
293+
# f.write(f'# Include files\n')
294+
# for fpath, subdirs, files in os.walk(args.include):
295+
# for fname in files:
296+
# unix_filename = curr_dir + '/' + fpath.replace('\\', '/') + '/' + fname
297+
# if fname.endswith('.hpp') or fname.endswith('.h'):
298+
# if args.tb_dir.replace('\\', '/') not in fpath:
299+
# # print(f'[INFO] Adding synthesis file: {unix_filename}')
300+
# f.write(f'add_files {unix_filename} -cflags "{cflags}"\n')
301+
# else:
302+
# if fname.startswith(args.tb_file):
303+
# # print(f'[INFO] Adding simulation file: {unix_filename}')
304+
# f.write(f'add_files -tb {unix_filename} -cflags "{cflags}"\n')
305+
197306
# ======================================================================
198307
# Start CSim
199308
# ======================================================================
@@ -224,8 +333,12 @@ def main():
224333
# ======================================================================
225334
# Run Cosim and report
226335
# ======================================================================
227-
if args.cosim:
228-
cosim_cmd = f'cosim_design -trace_level port -ldflags "{args.ldflags}" -argv "{args.argv}"'
336+
if run_cosim:
337+
cosim_cmd = f'cosim_design -ldflags "{args.ldflags}" -argv "{args.argv}"'
338+
if args.cosim_all:
339+
cosim_cmd += ' -trace_level all'
340+
if args.cosim_port:
341+
cosim_cmd += ' -trace_level port'
229342
if hls_tool == 'vitis' and args.debug_dataflow:
230343
cosim_cmd += ' -enable_dataflow_profiling=1 -enable_fifo_sizing=1'
231344

0 commit comments

Comments
 (0)