# viv_do_all.tcl  PeterJ,    24-Jan-2018.
#
# This script does:
#      set project name
#      set part name
#      creates a new project
#      imports the source files
#      launches synthesis
#      launches implementation
#      generates a bitfile
# ------------------------------------

# do more cores threads.....set the parameter to max threads of the machine.
set_param general.maxThreads 16 

# set proj_name and proj_dir:
source proj_properties.tcl

# Format the raw time [clock seconds] to a date string
puts "[set date_string [clock format [clock seconds] -format "date: %y-%m-%d, time: %H:%M:%S"]] Implementation Started of $proj_name"

#Close currently open project and create a new one. (OVERWRITES PROJECT!!)
close_project -quiet

# Remove old and Create the new build directory
file delete -force $proj_dir
#file mkdir $proj_dir

create_project -force -part $device $proj_name ./$proj_dir
# work_directory is *full* path project directory.
# Vivado doesn't seem to accept relative paths!?
set work_directory [get_property DIRECTORY [current_project]]
set_property default_lib work [current_project]

# Create a hdl_version.xdc file to set the bitfile USERID to the revision date/version
set revision_log_file "revisiondate_log.txt"
if [file exists $revision_log_file] { 
    set revision_log_fileptr [open $revision_log_file]
    gets $revision_log_fileptr revision_log_date
    gets $revision_log_fileptr revision_log_revnumber
    close $revision_log_fileptr
    set userid [format "0x%6d%02d" $revision_log_date $revision_log_revnumber]
    puts "Bitfile USERID set to $userid"
} else {
    set userid 0xFFFFFFFF
    puts "WARNING Bitfile USERID set to 0xFFFFFFFF"
}
set hdl_version_file [open hdl_version.xdc w]
puts $hdl_version_file "set_property BITSTREAM.CONFIG.USERID $userid \[current_design\]"
close $hdl_version_file

set_property target_language VHDL [current_project]

# ------------------------------------------------------------------------------
# Read source files
# ------------------------------------------------------------------------------

set fp [open "proj_file_list.txt" r]
set file_data [read $fp]
close $fp
set content [split $file_data "\n"]

set use_bmm false

foreach line $content {
  puts $line
  set line_length [ string length $line ]
  if {[string range $line 0 0] == "#"} {
    # puts "comment"
  } elseif {[string range $line $line_length-4 $line_length] == ".vhd"} {
    # puts "vhdl"
    read_vhdl -library work $line
  } elseif {[string range $line $line_length-2 $line_length] == ".v"} {
    # puts "verilog"
    read_verilog -library work $line
  } elseif {[string range $line $line_length-3 $line_length] == ".vh"} {
    # puts "verilog"
    read_verilog -library work $line
  } elseif {[string range $line $line_length-3 $line_length] == ".sv"} {
    # puts "system verilog"
    read_verilog -sv  -library work $line
  } elseif {[string range $line $line_length-4 $line_length] == ".svh"} {
    # puts "system verilog"
    read_verilog -sv -library work $line
  } elseif {[string range $line $line_length-4 $line_length] == ".xci"} {
    # puts "xilinx ip"
    read_ip $line
  } elseif {[string range $line $line_length-5 $line_length] == ".xcix"} {
    # puts "xilinx ip"
    read_ip $line
  } elseif {[string range $line $line_length-4 $line_length] == ".xdc"} {
    # Read constraints file if any
    # puts "xdc"
    read_xdc -verbose $line
  } elseif {[string range $line $line_length-3 $line_length] == ".bd"} {
   # puts "xilinx bd"
    read_bd $line
    make_wrapper -files [get_files $line] -top -import
  } elseif {[string range $line $line_length-4 $line_length] == ".bmm"} {
    # Set pointer to bmm file if any
    # puts "bmm"
    set use_bmm true
    set bmm_file [pwd]/$line
    set bmm_bd ${proj_name}_bd.bmm
    add_files -norecurse $bmm_file
  }
}

# Set Top level
set_property top $proj_name [current_fileset]
set_property source_mgmt_mode All [current_project]
update_compile_order -fileset sources_1

# Pass generics
set_property generic $generics [current_fileset]
puts "INFO: Reading Source Files Done!"

# ------------------------------------------------------------------------------

source $script_dir/viv_do_synt.tcl 
source $script_dir/viv_do_impl.tcl
if {$use_bmm} {
  source $script_dir/viv_generate_bd_bmm.tcl
  source $script_dir/viv_generate_bd_mmi.tcl
}
close_design

# Generate a new name for .bit and .mmi file and copy to project directory.
# Create a senible name including date and time
set bitfile_name ${spec7_design}_[string range $device 3 6]_[clock format [clock seconds] -format %y%m%d_%H%M]
file copy ./work/${proj_name}.runs/impl_1/${proj_name}.bit ../${bitfile_name}.bit 
file copy ./${proj_name}.mmi ../${bitfile_name}.mmi 

set syn_dir [pwd]
# Get SHA codes for spec7, wr-cores and general-cores repositories
set spec7_sha [exec git rev-parse HEAD]
cd ../../wr-cores/ ; set wr_cores_sha [exec git rev-parse HEAD]
cd ip_cores/general-cores/ ; set general_cores_sha [exec git rev-parse HEAD]
cd $syn_dir 
# write SHA codes in log a file
set git_log_fp [open ../${bitfile_name}.log w]
puts $git_log_fp "Build was based on the following SHA codes:"
puts $git_log_fp "spec7.git           $spec7_sha"
puts $git_log_fp "wr-cores.git        $wr_cores_sha"
puts $git_log_fp "general-cores.git   $general_cores_sha"
close $git_log_fp

exec updatemem -meminfo ./${proj_name}.mmi -data ${lm32_wrpc_elf} -bit ./work/${proj_name}.runs/impl_1/${proj_name}.bit -proc ${lm32_wrpc_instpath} -out ../${bitfile_name}_elf.bit -force 
