Skip to content

Commit

Permalink
fix nondefault project name handling (fastmachinelearning#626)
Browse files Browse the repository at this point in the history
* only rename value of ${myproject}, not the variable name

* consistently indent build_prj.tcl; be consistent in using myproject only as a variable

* fix parsing of Vivado reports

* migrate more to using variables instead of changing text; change function name to better match

* rename myproject to project_name in remaining Vivado places

* try to fix vivado accelerator for project_name

* replace forgotten myproject with project_name

* fix FIFO depth optimization tcl
  • Loading branch information
jmitrevs committed Aug 16, 2022
1 parent 6714dd1 commit e8f048a
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 211 deletions.
20 changes: 8 additions & 12 deletions hls4ml/report/vivado_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ def read_vivado_report(hls_dir, full_report=False):
prj_dir = None
top_func_name = None

if os.path.isfile(hls_dir + '/build_prj.tcl'):
prj_dir, top_func_name = _parse_build_script(hls_dir + '/build_prj.tcl')
if os.path.isfile(hls_dir + '/project.tcl'):
prj_dir, top_func_name = _parse_project_script(hls_dir)

if prj_dir is None or top_func_name is None:
print('Unable to read project data. Exiting.')
Expand All @@ -31,21 +31,17 @@ def read_vivado_report(hls_dir, full_report=False):
print('Reports for solution "{}":\n'.format(sln))
_find_reports(sln_dir + '/' + sln, top_func_name, full_report)

def _parse_build_script(path):
def _parse_project_script(path):
prj_dir = None
top_func_name = None

build_path = path + '/build_prj.tcl'
project_path = path + '/project.tcl'
with open(build_path, 'r') as f:
for line in f.readlines():
if 'set_top' in line:
top_func_name = line.split()[-1]

with open(project_path, 'r') as f:
for line in f.readlines():
if 'set myproject' in line:
prj_dir = line.split('"')[-2] + '_prj'
if 'set project_name' in line:
top_func_name = line.split('"')[-2]
prj_dir = top_func_name + '_prj'

return prj_dir, top_func_name

Expand Down Expand Up @@ -113,8 +109,8 @@ def parse_vivado_report(hls_dir):
prj_dir = None
top_func_name = None

if os.path.isfile(hls_dir + '/build_prj.tcl'):
prj_dir, top_func_name = _parse_build_script(hls_dir)
if os.path.isfile(hls_dir + '/project.tcl'):
prj_dir, top_func_name = _parse_project_script(hls_dir)

if prj_dir is None or top_func_name is None:
print('Unable to read project data. Exiting.')
Expand Down
252 changes: 125 additions & 127 deletions hls4ml/templates/vivado/build_prj.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
# HLS4ML
#################
array set opt {
reset 0
csim 1
synth 1
cosim 1
validation 1
export 0
vsynth 0
fifo_opt 0
reset 0
csim 1
synth 1
cosim 1
validation 1
export 0
vsynth 0
fifo_opt 0
}

set tcldir [file dirname [info script]]
Expand All @@ -19,7 +19,7 @@ proc remove_recursive_log_wave {} {
set tcldir [file dirname [info script]]
source [file join $tcldir project.tcl]

set filename ${myproject}_prj/solution1/sim/verilog/${myproject}.tcl
set filename ${project_name}_prj/solution1/sim/verilog/${project_name}.tcl
set timestamp [clock format [clock seconds] -format {%Y%m%d%H%M%S}]
set temp $filename.new.$timestamp
# set backup $filename.bak.$timestamp
Expand All @@ -35,19 +35,19 @@ proc remove_recursive_log_wave {} {
puts $out $line
}

close $in
close $out
close $in
close $out

# move the new data to the proper filename
file delete -force $filename
file rename -force $temp $filename
# move the new data to the proper filename
file delete -force $filename
file rename -force $temp $filename
}

proc add_vcd_instructions_tcl {} {
set tcldir [file dirname [info script]]
source [file join $tcldir project.tcl]

set filename ${myproject}_prj/solution1/sim/verilog/${myproject}.tcl
set filename ${project_name}_prj/solution1/sim/verilog/${project_name}.tcl
set timestamp [clock format [clock seconds] -format {%Y%m%d%H%M%S}]
set temp $filename.new.$timestamp
# set backup $filename.bak.$timestamp
Expand All @@ -58,45 +58,43 @@ proc add_vcd_instructions_tcl {} {
# line-by-line, read the original file
while {[gets $in line] != -1} {
if {[string equal "$line" "log_wave -r /"]} {
set line {source "../../../../project.tcl"
if {[string equal "$backend" "vivadoaccelerator"]} {
current_scope [get_scopes -regex /apatb_${myproject}_axi_top/AESL_inst_${myproject}_axi/${myproject}_U0.*]
set scopes [get_scopes -regexp {layer(\d*)_.*data_0_V_U.*}]
append scopes { }
current_scope /apatb_${myproject}_axi_top/AESL_inst_${myproject}_axi
append scopes [get_scopes -regexp {(in_local_V_data.*_0_.*)}]
append scopes { }
append scopes [get_scopes -regexp {(out_local_V_data.*_0_.*)}]
} else {
current_scope [get_scopes -regex /apatb_${myproject}_top/AESL_inst_${myproject}]
set scopes [get_scopes -regexp {layer(\d*)_.*data_0_V_U.*}]
}
open_vcd fifo_opt.vcd
foreach scope $scopes {
current_scope $scope
if {[catch [get_objects usedw]] == 0} {
puts "$scope skipped"
continue
}
set usedw [get_objects usedw]
set depth [get_objects DEPTH]
add_wave $usedw
log_vcd $usedw
log_wave $usedw
add_wave $depth
log_vcd $depth
log_wave $depth
}
}

set line [string map [list "myproject" $myproject] $line]
set line {source "../../../../project.tcl"
if {[string equal "$backend" "vivadoaccelerator"]} {
current_scope [get_scopes -regex "/apatb_${project_name}_axi_top/AESL_inst_${project_name}_axi/${project_name}_U0.*"]
set scopes [get_scopes -regexp {layer(\d*)_.*data_0_V_U.*}]
append scopes { }
current_scope "/apatb_${project_name}_axi_top/AESL_inst_${project_name}_axi"
append scopes [get_scopes -regexp {(in_local_V_data.*_0_.*)}]
append scopes { }
append scopes [get_scopes -regexp {(out_local_V_data.*_0_.*)}]
} else {
current_scope [get_scopes -regex "/apatb_${project_name}_top/AESL_inst_${project_name}"]
set scopes [get_scopes -regexp {layer(\d*)_.*data_0_V_U.*}]
}
open_vcd fifo_opt.vcd
foreach scope $scopes {
current_scope $scope
if {[catch [get_objects usedw]] == 0} {
puts "$scope skipped"
continue
}
set usedw [get_objects usedw]
set depth [get_objects DEPTH]
add_wave $usedw
log_vcd $usedw
log_wave $usedw
add_wave $depth
log_vcd $depth
log_wave $depth
}
}
}

if {[string equal "$line" "quit"]} {
set line {flush_vcd
close_vcd
quit
}
close_vcd
quit
}
}
# then write the transformed line
puts $out $line
Expand All @@ -111,17 +109,17 @@ quit
}

foreach arg $::argv {
foreach o [lsort [array names opt]] {
regexp "$o=+(\\w+)" $arg unused opt($o)
}
foreach o [lsort [array names opt]] {
regexp "$o=+(\\w+)" $arg unused opt($o)
}
}

proc report_time { op_name time_start time_end } {
set time_taken [expr $time_end - $time_start]
set time_s [expr ($time_taken / 1000) % 60]
set time_m [expr ($time_taken / (1000*60)) % 60]
set time_h [expr ($time_taken / (1000*60*60)) % 24]
puts "***** ${op_name} COMPLETED IN ${time_h}h${time_m}m${time_s}s *****"
set time_taken [expr $time_end - $time_start]
set time_s [expr ($time_taken / 1000) % 60]
set time_m [expr ($time_taken / (1000*60)) % 60]
set time_h [expr ($time_taken / (1000*60*60)) % 24]
puts "***** ${op_name} COMPLETED IN ${time_h}h${time_m}m${time_s}s *****"
}

# Compare file content: 1 = same, 0 = different
Expand Down Expand Up @@ -149,102 +147,102 @@ set CSIM_RESULTS "./tb_data/csim_results.log"
set RTL_COSIM_RESULTS "./tb_data/rtl_cosim_results.log"

if {$opt(reset)} {
open_project -reset ${myproject}_prj
open_project -reset ${project_name}_prj
} else {
open_project ${myproject}_prj
open_project ${project_name}_prj
}
set_top myproject
add_files firmware/myproject.cpp -cflags "-std=c++0x"
add_files -tb myproject_test.cpp -cflags "-std=c++0x"
set_top ${project_name}
add_files firmware/${project_name}.cpp -cflags "-std=c++0x"
add_files -tb ${project_name}_test.cpp -cflags "-std=c++0x"
add_files -tb firmware/weights
add_files -tb tb_data
if {$opt(reset)} {
open_solution -reset "solution1"
open_solution -reset "solution1"
} else {
open_solution "solution1"
open_solution "solution1"
}
catch {config_array_partition -maximum_size 4096}
config_compile -name_max_length 60
set_part {xcku115-flvb2104-2-i}
create_clock -period 5 -name default
set_part $part
create_clock -period $clock_period -name default


if {$opt(csim)} {
puts "***** C SIMULATION *****"
set time_start [clock clicks -milliseconds]
csim_design
set time_end [clock clicks -milliseconds]
report_time "C SIMULATION" $time_start $time_end
puts "***** C SIMULATION *****"
set time_start [clock clicks -milliseconds]
csim_design
set time_end [clock clicks -milliseconds]
report_time "C SIMULATION" $time_start $time_end
}

if {$opt(synth)} {
puts "***** C/RTL SYNTHESIS *****"
set time_start [clock clicks -milliseconds]
csynth_design
set time_end [clock clicks -milliseconds]
report_time "C/RTL SYNTHESIS" $time_start $time_end
puts "***** C/RTL SYNTHESIS *****"
set time_start [clock clicks -milliseconds]
csynth_design
set time_end [clock clicks -milliseconds]
report_time "C/RTL SYNTHESIS" $time_start $time_end
}

if {$opt(cosim)} {
puts "***** C/RTL SIMULATION *****"
# TODO: This is a workaround (Xilinx defines __RTL_SIMULATION__ only for SystemC testbenches).
add_files -tb myproject_test.cpp -cflags "-std=c++0x -DRTL_SIM"
set time_start [clock clicks -milliseconds]

cosim_design -trace_level all -setup

if {$opt(fifo_opt)} {
puts "\[hls4ml\] - FIFO optimization started"
add_vcd_instructions_tcl
}

remove_recursive_log_wave
set old_pwd [pwd]
cd ${myproject}_prj/solution1/sim/verilog/
source run_sim.tcl
cd $old_pwd

set time_end [clock clicks -milliseconds]
puts "INFO:"
if {[string equal "$backend" "vivadoaccelerator"]} {
puts [read [open ${myproject}_prj/solution1/sim/report/${myproject}_axi_cosim.rpt r]]
} else {
puts [read [open ${myproject}_prj/solution1/sim/report/${myproject}_cosim.rpt r]]
}
report_time "C/RTL SIMULATION" $time_start $time_end
puts "***** C/RTL SIMULATION *****"
# TODO: This is a workaround (Xilinx defines __RTL_SIMULATION__ only for SystemC testbenches).
add_files -tb ${project_name}_test.cpp -cflags "-std=c++0x -DRTL_SIM"
set time_start [clock clicks -milliseconds]

cosim_design -trace_level all -setup

if {$opt(fifo_opt)} {
puts "\[hls4ml\] - FIFO optimization started"
add_vcd_instructions_tcl
}

remove_recursive_log_wave
set old_pwd [pwd]
cd ${project_name}_prj/solution1/sim/verilog/
source run_sim.tcl
cd $old_pwd

set time_end [clock clicks -milliseconds]
puts "INFO:"
if {[string equal "$backend" "vivadoaccelerator"]} {
puts [read [open ${project_name}_prj/solution1/sim/report/${project_name}_axi_cosim.rpt r]]
} else {
puts [read [open ${project_name}_prj/solution1/sim/report/${project_name}_cosim.rpt r]]
}
report_time "C/RTL SIMULATION" $time_start $time_end
}

if {$opt(validation)} {
puts "***** C/RTL VALIDATION *****"
if {[compare_files $CSIM_RESULTS $RTL_COSIM_RESULTS]} {
puts "INFO: Test PASSED"
} else {
puts "ERROR: Test failed"
puts "ERROR: - csim log: $CSIM_RESULTS"
puts "ERROR: - RTL-cosim log: $RTL_COSIM_RESULTS"
exit 1
}
puts "***** C/RTL VALIDATION *****"
if {[compare_files $CSIM_RESULTS $RTL_COSIM_RESULTS]} {
puts "INFO: Test PASSED"
} else {
puts "ERROR: Test failed"
puts "ERROR: - csim log: $CSIM_RESULTS"
puts "ERROR: - RTL-cosim log: $RTL_COSIM_RESULTS"
exit 1
}
}

if {$opt(export)} {
puts "***** EXPORT IP *****"
set time_start [clock clicks -milliseconds]
export_design -format ip_catalog
set time_end [clock clicks -milliseconds]
report_time "EXPORT IP" $time_start $time_end
puts "***** EXPORT IP *****"
set time_start [clock clicks -milliseconds]
export_design -format ip_catalog
set time_end [clock clicks -milliseconds]
report_time "EXPORT IP" $time_start $time_end
}

if {$opt(vsynth)} {
puts "***** VIVADO SYNTHESIS *****"
if {[file exist ${myproject}_prj/solution1/syn/vhdl]} {
set time_start [clock clicks -milliseconds]
exec vivado -mode batch -source vivado_synth.tcl >@ stdout
set time_end [clock clicks -milliseconds]
report_time "VIVADO SYNTHESIS" $time_start $time_end
} else {
puts "ERROR: Cannot find generated VHDL files. Did you run C synthesis?"
exit 1
}
puts "***** VIVADO SYNTHESIS *****"
if {[file exist ${project_name}_prj/solution1/syn/vhdl]} {
set time_start [clock clicks -milliseconds]
exec vivado -mode batch -source vivado_synth.tcl >@ stdout
set time_end [clock clicks -milliseconds]
report_time "VIVADO SYNTHESIS" $time_start $time_end
} else {
puts "ERROR: Cannot find generated VHDL files. Did you run C synthesis?"
exit 1
}
}

exit
7 changes: 5 additions & 2 deletions hls4ml/templates/vivado/vivado_synth.tcl
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
add_files myproject_prj/solution1/syn/vhdl
synth_design -top myproject -part xcku115-flvb2104-2-i
set tcldir [file dirname [info script]]
source [file join $tcldir project.tcl]

add_files ${project_name}_prj/solution1/syn/vhdl
synth_design -top ${project_name} -part $part
report_utilization -file vivado_synth.rpt
Loading

0 comments on commit e8f048a

Please sign in to comment.