# this scripts queries some variables and put them in a VHDL file for use during synthesis
# start manually as follows:
# > cd [get_property DIRECTORY [current_project]]; source FASEC_prototype.srcs/tcl/set_registers.tcl
# if you want to use a remote machine, set the $_remote variable first, e.g.
set _remote {-host {htsynth2 32} -remote_cmd {ssh -q -o BatchMode=yes -l pvantrap}}

# xilinc tcl info:
# each class can have many properties, to list them:
# llength [list_property -class bd_cell]
# list_property [get_bd_cells fasec*]

# settings
set filefilter *top_mod.vhd
set git {/usr/bin/git}
set backupext .old
set backupnm {modules/fasec_hwtest/top_mod.vhd.old}
set backupnd {modules/fasec_hwtest}
set ipname system_design_fasec_hwtest_0_0
set runname ${ipname}_synth_1

if {[info exists _remote]==0} {
    set _remote ""
}
set projd [get_property DIRECTORY [current_project]]
puts $projd
set bdd [get_files -of_objects [get_filesets sources_1] *bd]
# using get_files avoids having to know the IP version etc.
set topfile [get_files -of_objects [get_filesets $ipname] $filefilter]
puts $topfile
if [llength $topfile]!=1 {
    return -1 error "ERROR: more than one topfile found!"
}

cd $projd
set dateCode [format %08X [clock seconds]]
set gitCode [string range [exec $git log --format=%H -n 1] 0 7]

#  scan $topfile first, if it does contain DEADBEE. strings it is new and backup should be removed
set fr [open $topfile r]
if [string first DEADBEE1 [read $fr]]!=-1 {
    puts "new IP detected, removing old backup file.."
    file delete $backupnm
}
close $fr
# create backup file if it doesn't exist to preserve the DEADBEE. strings
# file mkdir needed in case of fresh project creation after clone
if [file exists $backupnm]==0 {
    file mkdir $backupnd
    file copy -force $topfile $backupnm
}

# replace the strings from the backupfile, then write to output file
# backupfile will remain unmodified
set fr [open $backupnm r]
set fw [open $topfile r+]
if [string first DEADBEE1 [read $fr]]==-1 {
    return -1 error "ERROR: specific string sequence not found in backupfile!"
}
seek $fr 0; # back to beginning for reading
set cont [regsub -all {DEADBEE1} [read $fr] $dateCode]
set cont [regsub -all {DEADBEE2} $cont $gitCode]
seek $fw 0; # go to beginning of file to overwrite
puts $fw $cont
close $fw
close $fr

puts "SUCCESS: file modifs done"

# Vivado commands
reset_run synth_1
# using out-of-context per IP, the below IP (containing the modified registers) synthesis need to be rerun
reset_run $runname
# it's using VHDL-2008, fileset property is not persisent
set_property vhdl_version vhdl_2008 [get_filesets $ipname]
eval launch_runs $runname -jobs 4 $_remote
# after BD IP update, other runs might also need rerunning..
foreach a [get_runs *_synth_1] {
    if {[get_property PROGRESS [get_runs $a]] != "100%"} {
	reset_run $a
	eval launch_runs $a -jobs 4 $_remote
	wait_on_run $a
    }
}

# FIXME: we should iterate over all runs to see if they have finished..
# the above 'wait_on_run $a' fixes that but does then inhibit parallel job running - acceptable only if on fast remote
wait_on_run $runname

# eval concatenates its arguments in the same fashion as concat, and hands them to the interpreter to be evaluated as a Tcl script
eval launch_runs synth_1 -force -jobs 4 $_remote
wait_on_run synth_1
if {[get_property PROGRESS [get_runs synth_1]] != "100%"} {
    error "ERROR: synth_1 failed"
}

eval launch_runs impl_1 -to_step write_bitstream -jobs 4 $_remote
wait_on_run impl_1
if {[get_property PROGRESS [get_runs synth_1]] != "100%"} {
    error "ERROR: bitstream creation failed"
}

