# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
#
# Simple tcl script for DC to do some wire-load-model-based test syntheses.

#####################
##  PREPARE FLOW   ##
#####################

proc get_env_var {name} {
  if {[info exists ::env($name)]} {
    set val "[set ::env([set name])]"
    puts "::env($name) = $val"
    return $val
  } else {
    puts "ERROR: Script run without $name environment variable."
    quit
  }
}

set FOUNDRY_ROOT       [get_env_var "FOUNDRY_ROOT"]
set SYN_ROOT           [get_env_var "SYN_ROOT"]
set SV_FLIST           [get_env_var "SV_FLIST"]
set BUILD_DIR          [get_env_var "BUILD_DIR"]
set DUT                [get_env_var "DUT"]
set CONSTRAINT         [get_env_var "CONSTRAINT"]
set FOUNDRY_CONSTRAINT [get_env_var "FOUNDRY_CONSTRAINT"]
set PARAMS             [get_env_var "PARAMS"]
set POST_ELAB_SCRIPT   [get_env_var "POST_ELAB_SCRIPT"]

# if in interactive mode, do not exit at the end of the script
if { [info exists ::env(INTERACTIVE)] } {
  set RUN_INTERACTIVE 1
} else {
  set RUN_INTERACTIVE 0
}

# paths
set WORKLIB  "${BUILD_DIR}/WORK"
set REPDIR   "${BUILD_DIR}/REPORTS"
set DDCDIR   "${BUILD_DIR}/DDC"
set RESULTDIR "${BUILD_DIR}/results"
set VLOGDIR  "${BUILD_DIR}/NETLISTS"

exec mkdir -p ${REPDIR} ${DDCDIR} ${VLOGDIR} ${WORKLIB} ${RESULTDIR}

# define work lib path
define_design_lib WORK -path $WORKLIB

########################
## Library Setup      ##
########################

# if the foundry root is specified, some more library setup is needed.
if {$FOUNDRY_ROOT != ""} {
  source "${FOUNDRY_ROOT}/syn/dc/setup.tcl"
  # this PRIM_DEFAULT_IMPL selects the appropriate technology by defining
  # PRIM_DEFAULT_IMPL=prim_pkg::Impl<tech identifier>
  # PRIM_DEFAULT_IMPL is set inside the library setup script
  set DEFINE "PRIM_DEFAULT_IMPL=${PRIM_DEFAULT_IMPL}+${PRIM_STD_CELL_VARIANT}"
} else {
  # This black-boxes the 1p and 2p memory models (used for GTECH runs only).
  set DEFINE "SYNTHESIS_MEMORY_BLACK_BOXING=TRUE"
}

#######################
## CONFIGURATIONS   ###
#######################

# Define the verification setup file for Formality
set_svf ${RESULTDIR}/${DUT}.svf

# Setup SAIF Name Mapping Database
saif_map -start

###The following variable helps verification when there are differences between DC and FM while inferring logical hierarchies
set_app_var hdlin_enable_hier_map true

###########################
##   Env var file        ##
###########################

set fp [open "${BUILD_DIR}/env_variables.tcl" w+]
puts $fp "set ::env(INTERACTIVE) 1"
puts $fp "set ::env(SYN_ROOT) $SYN_ROOT"
puts $fp "set ::env(FOUNDRY_ROOT) $FOUNDRY_ROOT"
puts $fp "set ::env(PARAMS) $PARAMS"
puts $fp "set ::env(SV_FLIST) $SV_FLIST"
puts $fp "set ::env(BUILD_DIR) $BUILD_DIR"
puts $fp "set ::env(DUT) $DUT"
puts $fp "set ::env(CONSTRAINT) $CONSTRAINT"
puts $fp "set ::env(FOUNDRY_CONSTRAINT) $FOUNDRY_CONSTRAINT"
puts $fp "set ::env(POST_ELAB_SCRIPT) $POST_ELAB_SCRIPT"
close $fp

###########################
##   ELABORATE DESIGN    ##
###########################

# delete previous designs.
remove_design -designs
sh rm -rf $WORKLIB/*

analyze -vcs "-sverilog +define+${DEFINE} -f ${SV_FLIST}" > "${REPDIR}/analyze.rpt"
elaborate  ${DUT} -parameters ${PARAMS}                   > "${REPDIR}/elab.rpt"
link                                                      > "${REPDIR}/link.rpt"
check_design                                              > "${REPDIR}/check.rpt"

set_verification_top

if {$POST_ELAB_SCRIPT != ""} {
  source ${POST_ELAB_SCRIPT}
}

write_file -format ddc -hierarchy -output "${DDCDIR}/elab.ddc"

# write out a GTECH netlist and quit if libs are not defined
if {$FOUNDRY_ROOT == ""} {
  change_names -rules verilog -hierarchy
  define_name_rules fixbackslashes -allowed "A-Za-z0-9_" -first_restricted "\\" -remove_chars
  change_names -rule fixbackslashes -h
  write_file -format verilog -hierarchy -output "${VLOGDIR}/elab.v"
  exit
}

#############################
##   CLOCK GATING SETUP    ##
#############################

# be more specific if defaults do not suffice
# set_clock_gating_style -num_stages 1                   \
#                        -positive_edge_logic integrated \
#                        -control_point before           \
#                        -control_signal scan_enable

###########################
##   APPLY CONSTRAINTS   ##
###########################

puts "Applying constraints for ${DUT}"
source "${CONSTRAINT}"
source "${FOUNDRY_CONSTRAINT}"
puts "Done applying constraints for ${DUT}"

# If hold time should be fixed
# set_fix_hold ${CLK_PIN}

######################
##    MAP DESIGN    ##
######################

# preserve hierarchy for reports
compile_ultra -gate_clock -scan -no_autoungroup > "${REPDIR}/compile.rpt"

#################
##   REPORTS   ##
#################

# write NAND2 equivalent to file for the reporting scripts
sh echo ${NAND2_GATE_EQUIVALENT} > "${REPDIR}/gate_equiv.rpt"

report_clocks                                 > "${REPDIR}/clocks.rpt"
report_clock -groups                          > "${REPDIR}/clock.groups.rpt"
report_path_group                             > "${REPDIR}/path_group.rpt"
report_clock_gating -multi_stage -nosplit     > "${REPDIR}/clock_gating.rpt"
report_timing -nosplit -slack_lesser_than 0.0 > "${REPDIR}/timing.rpt"
report_area   -hier -nosplit                  > "${REPDIR}/area.rpt"
report_power  -hier -nosplit                  > "${REPDIR}/power.rpt"
report_constraints -all_violators             > "${REPDIR}/constraints.rpt"

report_timing      -nosplit -nworst 1000 -input -net -trans -cap > "${REPDIR}/timing_long.rpt"

#################
##   NETLIST   ##
#################

change_names -rules verilog -hierarchy
define_name_rules fixbackslashes -allowed "A-Za-z0-9_" -first_restricted "\\" -remove_chars
change_names -rule fixbackslashes -h
write_file -format ddc     -hierarchy -output "${DDCDIR}/mapped.ddc"
write_file -format verilog -hierarchy -output "${VLOGDIR}/mapped.v"

# Write final SDC
write_sdc -nosplit ${RESULTDIR}/${DUT}.final.sdc
# If SAIF is used, write out SAIF name mapping file for PrimeTime-PX
saif_map -type ptpx -write_map ${RESULTDIR}/${DUT}.mapped.SAIF.namemap
# ##############################
# ##  INCREMENTAL FLATTENING  ##
# ##############################

# compile_ultra -inc

# #################
# ##   REPORTS   ##
# #################

# report_timing      -nosplit -nworst 100 > "${REPDIR}/flat_timing.rpt"
# report_timing      -nosplit -nworst 1000 -input -net -trans -cap > "${REPDIR}/flat_timing_long.rpt"
# report_area  -hier -nosplit             > "${REPDIR}/flat_area.rpt"
# report_power -hier -nosplit             > "${REPDIR}/flat_power.rpt"
# report_constraints -all_violators       > "${REPDIR}/flat_constraints.rpt"

# #################
# ##   NETLIST   ##
# #################

# write_file -format ddc     -hierarchy -output "${DDCDIR}/flat.ddc"
# write_file -format verilog -hierarchy -output "${VLOGDIR}/flat.v"

if { $RUN_INTERACTIVE == 0 } {
  exit
}
