[dvsim] Logic to copy repo to scratch area

This change adds logic to copy the repo to the scratch area using
`rsync` command. The copy is triggered on the presence of two things -
- DVSIM_REMOTE_DISPATCH env variable defined
- `scratch_root` not being tool-default

If these conditions are met, it is assumed that a different scratch
area is being used, which is accessible to the user's workspace /
workstation as well as to the remote dispatch system. It is also assumed
that the remote dispatch system cannot access the user's workspace,
which is why the copying is needed. If the repo is copied to the scratch
area, the `proj_root` is set to the destination location, so that in
HJson files, everything is referenced from the destination as opposed
to the actual project root.

The destination is chosen to be `{scratch_root}/{branch}/repo_top`. This
is common to all toolflows run from the same branch.

The other change is removal of `tool_srcs_dir` and `tool_srcs`, and
addition of `proj_root` as a mandatory variable set for the Makefile.
All sources that the EDA tools need to have access to can now be
referenced from `{proj_root}` in the HJson files.

Lastly, a `--local` switch is added to dvsim to prevent triggering the
repo copy. It is user's responsibility to ensure that with `--local`,
DVSim is invoked such that the EDA tools are invoked from user's
workstation.

In the `common_project_cfg.hjson`, the changes reflect the above
updates.

Signed-off-by: Srikrishna Iyer <sriyer@google.com>

[dvsim, dv] Removal of `tool_srcs*`

This changes removes `tool_srcs*` from HJson and other files and
references all dependent sources from `{proj_root}` instead. Commit
b7ed20676 is required to support this change.

Wherever applicable, `{dv_root}` is used in lieu of `{proj_root}` to
stay opentitan-independent.

Signed-off-by: Srikrishna Iyer <sriyer@google.com>

[dvsim, fpv] Removal of `tool_srcs*`

This changes removes `tool_srcs*` from HJson and other files and
references all dependent sources from `{proj_root}` instead. Commit
b7ed20676 is required to support this change.

The second change is addition of `fpv_root`, which is where things that
could be common across OT and other projects can be found. All
references to `{proj_root}/hw/formal` are replaced with `{fpv_root}`.

Signed-off-by: Srikrishna Iyer <sriyer@google.com>

[dvsim, lint] Removal of `tool_srcs*`

This changes removes `tool_srcs*` from HJson and other files and
references all dependent sources from `{proj_root}` instead. Commit
b7ed20676 is required to support this change.

The second change is addition of `{lint_root}`, which represents a
location where all lint sources common across projects may reside. All
references to `{proj_root}/hw/lint` are replaced with `{lint_root}`.

Signed-off-by: Srikrishna Iyer <sriyer@google.com>

[dvsim, syn] Removal of `tool_srcs*`

This changes removes `tool_srcs*` from HJson and other files and
references all dependent sources from `{proj_root}` instead. Commit
b7ed20676 is required to support this change.

The second change is the addion of `{syn_root}` where all common
synthesis sources common across projects may reside. All isntances of
`{proj_root}/hw/syn` are replaced with `{syn_root}` as applicable.

Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/hw/data/common_project_cfg.hjson b/hw/data/common_project_cfg.hjson
index 29bfc2f..eb0fc8c 100644
--- a/hw/data/common_project_cfg.hjson
+++ b/hw/data/common_project_cfg.hjson
@@ -8,9 +8,13 @@
   results_server:   reports.opentitan.org
 
   // Default directory structure for the output
-  scratch_base_path:  "{scratch_root}/{dut}.{flow}.{tool}"
-  scratch_path:       "{scratch_base_path}/{branch}"
-  tool_srcs_dir:      "{scratch_path}/{tool}"
+  scratch_base_path:  "{scratch_root}/{branch}"
+  scratch_path:       "{scratch_base_path}/{dut}-{flow}-{tool}"
+
+  exports: [
+    { SCRATCH_PATH: "{scratch_path}" },
+    { proj_root: "{proj_root}" }
+  ]
 
   // Results server stuff - indicate what command to use to copy over the results.
   // Workaround for gsutil to fall back to using python2.7.
diff --git a/hw/dv/tools/dvsim/common_sim_cfg.hjson b/hw/dv/tools/dvsim/common_sim_cfg.hjson
index f01860f..8c3b551 100644
--- a/hw/dv/tools/dvsim/common_sim_cfg.hjson
+++ b/hw/dv/tools/dvsim/common_sim_cfg.hjson
@@ -3,10 +3,9 @@
 // SPDX-License-Identifier: Apache-2.0
 {
   flow:             sim
-  flow_makefile:    "{dv_root}/tools/dvsim/sim.mk"
-
   // Where to find DV code
   dv_root:          "{proj_root}/hw/dv"
+  flow_makefile:    "{dv_root}/tools/dvsim/sim.mk"
 
   import_cfgs:      ["{proj_root}/hw/data/common_project_cfg.hjson",
                      "{dv_root}/tools/dvsim/common_modes.hjson",
@@ -70,8 +69,7 @@
 
   // Default list of things to export to shell
   exports: [
-    { SCRATCH_BASE_PATH: "{scratch_base_path}" },
-    { TOOL_SRCS_DIR: "{tool_srcs_dir}" },
+    { dv_root: "{dv_root}" },
     { SIMULATOR: "{tool}" },
     { WAVES: "{waves}" },
     { DUT_TOP: "{dut}" },
@@ -129,27 +127,20 @@
     }
   ]
 
-  // Add waves.tcl to the set of sources to be copied over to
-  // {tool_srcs_dir}. This can be sourced by the tool-specific TCL
-  // script to set up wave dumping.
-  tool_srcs:  ["{dv_root}/tools/sim.tcl",
-               "{dv_root}/tools/common.tcl",
-               "{dv_root}/tools/waves.tcl"]
-
   // Project defaults for VCS
   vcs_cov_cfg_file: "{{build_mode}_vcs_cov_cfg_file}"
-  vcs_unr_cfg_file: "{tool_srcs_dir}/unr.cfg"
-  vcs_cov_excl_files: ["{tool_srcs_dir}/common_cov_excl.el"]
+  vcs_unr_cfg_file: "{dv_root}/tools/vcs/unr.cfg"
+  vcs_cov_excl_files: ["{dv_root}/tools/vcs/common_cov_excl.el"]
 
   // Build-specific coverage cfg files for VCS.
-  default_vcs_cov_cfg_file: "-cm_hier {tool_srcs_dir}/cover.cfg"
-  cover_reg_top_vcs_cov_cfg_file: "-cm_hier {tool_srcs_dir}/cover_reg_top.cfg"
+  default_vcs_cov_cfg_file: "-cm_hier {dv_root}/tools/vcs/cover.cfg"
+  cover_reg_top_vcs_cov_cfg_file: "-cm_hier {dv_root}/tools/vcs/cover_reg_top.cfg"
 
   // Project defaults for Xcelium
   // xcelium_cov_cfg_file: "{{build_mode}_xcelium_cov_cfg_file}"
-  // xcelium_cov_refine_files: ["{tool_srcs_dir}/common_cov.vRefine"]
+  // xcelium_cov_refine_files: ["{dv_root}/tools/xcelium/common_cov.vRefine"]
 
   // Build-specific coverage cfg files for Xcelium.
-  // default_xcelium_cov_cfg_file: "-covfile {tool_srcs_dir}/cover.ccf"
-  // cover_reg_top_xcelium_cov_cfg_file: "-covfile {tool_srcs_dir}/cover_reg_top.ccf"
+  // default_xcelium_cov_cfg_file: "-covfile {dv_root}/tools/xcelium/cover.ccf"
+  // cover_reg_top_xcelium_cov_cfg_file: "-covfile {dv_root}/tools/xcelium/cover_reg_top.ccf"
 }
diff --git a/hw/dv/tools/dvsim/dsim.hjson b/hw/dv/tools/dvsim/dsim.hjson
index d16f1d0..5834496 100644
--- a/hw/dv/tools/dvsim/dsim.hjson
+++ b/hw/dv/tools/dvsim/dsim.hjson
@@ -5,12 +5,6 @@
   build_cmd:  "{job_prefix} dsim"
   run_cmd:    "{job_prefix} dsim"
 
-  // Indicate the tool specific helper sources - these are copied over to the
-  // {tool_srcs_dir} before running the simulation.
-  // TODO, there is no dsim tool file, point to vcs for now to avoid error from script
-  // tool_srcs: ["{dv_root}/tools/dsim/*"]
-
-
   build_opts: ["-work {build_dir}/dsim_out",
                "-genimage image",
                "-sv",
@@ -59,13 +53,13 @@
   // Merging coverage.
   // "cov_db_dirs" is a special variable that appends all build directories in use.
   // It is constructed by the tool itself.
-  cov_merge_dir:    "{scratch_base_path}/cov_merge"
+  cov_merge_dir:    "{scratch_path}/cov_merge"
   cov_merge_db_dir: "{cov_merge_dir}/merged.vdb"
   cov_merge_cmd:    "{job_prefix} urg"
   cov_merge_opts:   []
 
   // Generate coverage reports in text as well as html.
-  cov_report_dir:   "{scratch_base_path}/cov_report"
+  cov_report_dir:   "{scratch_path}/cov_report"
   cov_report_cmd:   "{job_prefix} urg"
   cov_report_opts:  []
   cov_report_txt:   "{cov_report_dir}/dashboard.txt"
@@ -73,7 +67,7 @@
 
   // Analyzing coverage - this is done by invoking --cov-analyze switch. It opens up the
   // GUI for visual analysis.
-  cov_analyze_dir:  "{scratch_base_path}/cov_analyze"
+  cov_analyze_dir:  "{scratch_path}/cov_analyze"
   cov_analyze_cmd:  "{job_prefix} verdi"
   cov_analyze_opts: ["-cov",
                      "-covdir {cov_merge_db_dir}",
diff --git a/hw/dv/tools/dvsim/riviera.hjson b/hw/dv/tools/dvsim/riviera.hjson
index 324bebb..fb39718 100644
--- a/hw/dv/tools/dvsim/riviera.hjson
+++ b/hw/dv/tools/dvsim/riviera.hjson
@@ -5,10 +5,6 @@
   build_cmd:  "vlib work && {job_prefix} vlog"
   run_cmd:    "{job_prefix} vsim"
 
-  // Indicate the tool specific helper sources - these are copied over to the
-  // {tool_srcs_dir} before running the simulation.
-  tool_srcs:  ["{dv_root}/tools/riviera/*"]
-
   build_opts: ["-timescale 1ns/1ps",
                "+incdir+\"{RIVIERA_HOME}/vlib/uvm-1.2/src\"",
                "\"{RIVIERA_HOME}/vlib/uvm-1.2/src/uvm_pkg.sv\"",
@@ -31,7 +27,7 @@
   supported_wave_formats: []
 
   // Default tcl script used when running the sim. Override if needed.
-  run_script: "{tool_srcs_dir}/riviera_run.do"
+  run_script: "{dv_root}/tools/riviera/riviera_run.do"
 
   // Coverage related.
   // TODO: These options have to be filled in.
@@ -45,20 +41,20 @@
   // Merging coverage.
   // "cov_db_dirs" is a special variable that appends all build directories in use.
   // It is constructed by the tool itself.
-  cov_merge_dir:    "{scratch_base_path}/cov_merge"
+  cov_merge_dir:    "{scratch_path}/cov_merge"
   cov_merge_db_dir: ""
   cov_merge_cmd:    ""
   cov_merge_opts:   []
 
   // Generate covreage reports in text as well as html.
-  cov_report_dir:       "{scratch_base_path}/cov_report"
+  cov_report_dir:       "{scratch_path}/cov_report"
   cov_report_cmd:       ""
   cov_report_opts:      []
   cov_report_dashboard: ""
 
   // Analyzing coverage - this is done by invoking --cov-analyze switch. It opens up the
   // GUI for visual analysis.
-  cov_analyze_dir:  "{scratch_base_path}/cov_analyze"
+  cov_analyze_dir:  "{scratch_path}/cov_analyze"
   cov_analyze_cmd:  ""
   cov_analyze_opts: []
 
@@ -90,8 +86,8 @@
       is_sim_mode: 1
       build_opts: []
     }
-	{
     // TODO: Add build and run options to enable zero delay loop detection.
+    {
       name: riviera_loopdetect
       is_sim_mode: 1
       build_opts: []
diff --git a/hw/dv/tools/dvsim/sim.mk b/hw/dv/tools/dvsim/sim.mk
index f64748f..bc4e102 100644
--- a/hw/dv/tools/dvsim/sim.mk
+++ b/hw/dv/tools/dvsim/sim.mk
@@ -4,7 +4,6 @@
 
 .DEFAULT_GOAL := all
 
-LOCK_TOOL_SRCS_DIR ?= flock --timeout 3600 ${tool_srcs_dir} --command
 LOCK_SW_BUILD_DIR  ?= flock --timeout 3600 ${sw_build_dir} --command
 
 all: build run
@@ -14,14 +13,7 @@
 ###############################
 build: build_result
 
-prep_tool_srcs:
-	@echo "[make]: prep_tool_srcs"
-	mkdir -p ${tool_srcs_dir}
-ifneq (${tool_srcs},)
-	${LOCK_TOOL_SRCS_DIR} "cp -Ru ${tool_srcs} ${tool_srcs_dir}/."
-endif
-
-pre_build: prep_tool_srcs
+pre_build:
 	@echo "[make]: pre_build"
 	mkdir -p ${build_dir}
 ifneq (${pre_build_cmds},)
@@ -34,11 +26,11 @@
 	cd ${build_dir} && ${sv_flist_gen_cmd} ${sv_flist_gen_opts}
 endif
 
-build_tb: gen_sv_flist
-	@echo "[make]: build the testbench"
+do_build: gen_sv_flist
+	@echo "[make]: build"
 	cd ${sv_flist_gen_dir} && ${build_cmd} ${build_opts}
 
-post_build: build_tb
+post_build: do_build
 	@echo "[make]: post_build"
 ifneq (${post_build_cmds},)
 	cd ${build_dir} && ${post_build_cmds}
@@ -49,7 +41,7 @@
 
 run: run_result
 
-pre_run: prep_tool_srcs
+pre_run:
 	@echo "[make]: pre_run"
 	mkdir -p ${run_dir}
 ifneq (${pre_run_cmds},)
@@ -138,24 +130,23 @@
 	${cov_report_cmd} ${cov_report_opts}
 
 # Open coverage tool to review and create report or exclusion file.
-cov_analyze: prep_tool_srcs
+cov_analyze:
 	@echo "[make]: cov_analyze"
 	${cov_analyze_cmd} ${cov_analyze_opts}
 
 .PHONY: build \
-				prep_tool_srcs \
-				pre_build \
-				gen_sv_flist \
-				build_tb \
-				post_build \
-				build_result \
-				run \
-				pre_run \
-				sw_build \
-				simulate \
-				post_run \
-				run_result \
-				debug_waves \
-				cov_merge \
-				cov_analyze \
-				cov_report
+        pre_build \
+        gen_sv_flist \
+        do_build \
+        post_build \
+        build_result \
+        run \
+        pre_run \
+        sw_build \
+        simulate \
+        post_run \
+        run_result \
+        debug_waves \
+        cov_merge \
+        cov_analyze \
+        cov_report
diff --git a/hw/dv/tools/dvsim/vcs.hjson b/hw/dv/tools/dvsim/vcs.hjson
index 699c48d..784839e 100644
--- a/hw/dv/tools/dvsim/vcs.hjson
+++ b/hw/dv/tools/dvsim/vcs.hjson
@@ -6,10 +6,6 @@
   build_ex:   "{build_dir}/simv"
   run_cmd:    "{job_prefix} {build_ex}"
 
-  // Indicate the tool specific helper sources - these are copied over to the
-  // {tool_srcs_dir} before running the simulation.
-  tool_srcs:  ["{dv_root}/tools/vcs/*"]
-
   build_opts: ["-sverilog -full64 -licqueue -kdb -ntb_opts uvm-1.2",
                "-timescale=1ns/1ps",
                "-Mdir={build_ex}.csrc",
@@ -109,7 +105,7 @@
   supported_wave_formats: ["fsdb", "vpd"]
 
   // Default tcl script used when running the sim. Override if needed.
-  run_script: "{tool_srcs_dir}/sim.tcl"
+  run_script: "{dv_root}/tools/sim.tcl"
 
   // Coverage related.
   cov_db_dir: "{scratch_path}/coverage/{build_mode}.vdb"
@@ -122,7 +118,7 @@
   // Merging coverage.
   // "cov_db_dirs" is a special variable that appends all build directories in use.
   // It is constructed by the tool itself.
-  cov_merge_dir:    "{scratch_base_path}/cov_merge"
+  cov_merge_dir:    "{scratch_path}/cov_merge"
   cov_merge_db_dir: "{cov_merge_dir}/merged.vdb"
   cov_merge_cmd:    "{job_prefix} urg"
   cov_merge_opts:   ["-full64",
@@ -138,7 +134,7 @@
                      "-dbname {cov_merge_db_dir}"]
 
   // Generate coverage reports in text as well as html.
-  cov_report_dir:       "{scratch_base_path}/cov_report"
+  cov_report_dir:       "{scratch_path}/cov_report"
   cov_report_cmd:       "{job_prefix} urg"
   cov_report_opts:      ["-full64",
                         "+urg+lic+wait",
@@ -154,7 +150,7 @@
   // UNR related.
   // All code coverage, assert isn't supported
   cov_unr_metrics: "line+cond+fsm+tgl+branch"
-  cov_unr_dir:     "{scratch_base_path}/cov_unr"
+  cov_unr_dir:     "{scratch_path}/cov_unr"
 
   cov_unr_common_build_opts: ["-sverilog -full64 -licqueue -ntb_opts uvm-1.2",
                               "-timescale=1ns/1ps"]
@@ -187,7 +183,7 @@
 
   // Analyzing coverage - this is done by invoking --cov-analyze switch. It opens up the
   // GUI for visual analysis.
-  cov_analyze_dir:  "{scratch_base_path}/cov_analyze"
+  cov_analyze_dir:  "{scratch_path}/cov_analyze"
   cov_analyze_cmd:  "{job_prefix} verdi"
   cov_analyze_opts: ["-cov",
                      "-covdir {cov_merge_db_dir}",
@@ -261,7 +257,7 @@
     {
       name: vcs_xprop
       is_sim_mode: 1
-      build_opts: ["-xprop={tool_srcs_dir}/xprop.cfg"]
+      build_opts: ["-xprop={dv_root}/tools/vcs/xprop.cfg"]
     }
     {
       name: vcs_profile
diff --git a/hw/dv/tools/dvsim/verilator.hjson b/hw/dv/tools/dvsim/verilator.hjson
index 1306435..76da933 100644
--- a/hw/dv/tools/dvsim/verilator.hjson
+++ b/hw/dv/tools/dvsim/verilator.hjson
@@ -47,11 +47,6 @@
   ex_name:    "{eval_cmd} echo \"{fusesoc_core}\" | cut -d: -f3"
   run_cmd:    "{build_dir}/sim-verilator/V{ex_name}"
 
-  // Indicate the tool specific helper sources - these are copied over to the
-  // {tool_srcs_dir} before running the simulation.
-  // TODO: none at the moment.
-  tool_srcs:  []
-
   // TODO: Verilator has a few useful build switches. Need to figure out how to
   // pass them via FuseSoC.
 
diff --git a/hw/dv/tools/dvsim/xcelium.hjson b/hw/dv/tools/dvsim/xcelium.hjson
index ede16fb..60a906c 100644
--- a/hw/dv/tools/dvsim/xcelium.hjson
+++ b/hw/dv/tools/dvsim/xcelium.hjson
@@ -5,10 +5,6 @@
   build_cmd:  "{job_prefix} xrun"
   run_cmd:    "{job_prefix} xrun"
 
-  // Indicate the tool specific helper sources - these are copied over to the
-  // {tool_srcs_dir} before running the simulation.
-  tool_srcs:  ["{dv_root}/tools/xcelium/*"]
-
   build_opts: ["-elaborate -64bit -access +r -sv",
                "-licqueue",
                // TODO: duplicate primitives between OT and Ibex #1231
@@ -65,7 +61,7 @@
   supported_wave_formats: ["shm", "fsdb", "vcd"]
 
   // Default tcl script used when running the sim. Override if needed.
-  run_script: "{tool_srcs_dir}/sim.tcl"
+  run_script: "{dv_root}/tools/sim.tcl"
 
   // Coverage related.
   // By default, collect all coverage metrics: block:expr:fsm:toggle:functional.
@@ -90,26 +86,26 @@
 
   // Merging coverage.
   // It is constructed by the tool itself.
-  cov_merge_dir:    "{scratch_base_path}/cov_merge"
+  cov_merge_dir:    "{scratch_path}/cov_merge"
   cov_merge_db_dir: "{cov_merge_dir}/merged"
   cov_merge_cmd:    "{job_prefix} imc"
   cov_merge_opts:   ["-64bit",
                      "-licqueue",
-                     "-exec {tool_srcs_dir}/cov_merge.tcl"]
+                     "-exec {dv_root}/tools/xcelium/cov_merge.tcl"]
 
   // Generate covreage reports in text as well as html.
-  cov_report_dir:   "{scratch_base_path}/cov_report"
+  cov_report_dir:   "{scratch_path}/cov_report"
   cov_report_cmd:   "{job_prefix} imc"
   cov_report_opts:  ["-64bit",
                      "-licqueue",
-                     "-exec {tool_srcs_dir}/cov_report.tcl",
+                     "-exec {dv_root}/tools/xcelium/cov_report.tcl",
                      "{xcelium_cov_refine_files}"]
   cov_report_txt:   "{cov_report_dir}/cov_report.txt"
   cov_report_page:  "index.html"
 
   // Analyzing coverage - this is done by invoking --cov-analyze switch. It opens up the
   // GUI for visual analysis.
-  cov_analyze_dir:  "{scratch_base_path}/cov_analyze"
+  cov_analyze_dir:  "{scratch_path}/cov_analyze"
   cov_analyze_cmd:  "{job_prefix} imc"
   cov_analyze_opts: ["-gui",
                      "-64bit",
diff --git a/hw/dv/tools/sim.tcl b/hw/dv/tools/sim.tcl
index 9bad749..edaecb0 100644
--- a/hw/dv/tools/sim.tcl
+++ b/hw/dv/tools/sim.tcl
@@ -6,16 +6,16 @@
 # VCS syntax: -ucli -do <this file>
 # Xcelium syntax: -input <this file>
 
-set tool_srcs_dir ""
-if {[info exists ::env(TOOL_SRCS_DIR)]} {
-  set tool_srcs_dir "$::env(TOOL_SRCS_DIR)"
+set dv_root ""
+if {[info exists ::env(dv_root)]} {
+  set dv_root "$::env(dv_root)"
 } else {
-  puts "ERROR: Script run without TOOL_SRCS_DIR environment variable."
+  puts "ERROR: Script run without dv_root environment variable."
   quit
 }
 
-source "${tool_srcs_dir}/common.tcl"
-source "${tool_srcs_dir}/waves.tcl"
+source "${dv_root}/tools/common.tcl"
+source "${dv_root}/tools/waves.tcl"
 
 run
 quit
diff --git a/hw/dv/tools/vcs/unr.cfg b/hw/dv/tools/vcs/unr.cfg
index 1a6711a..1991b5f 100644
--- a/hw/dv/tools/vcs/unr.cfg
+++ b/hw/dv/tools/vcs/unr.cfg
@@ -2,7 +2,7 @@
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
 
--covInput $SCRATCH_BASE_PATH/cov_merge/merged.vdb
+-covInput $SCRATCH_PATH/cov_merge/merged.vdb
 -covDUT $dut_instance
 
 # Provide the clock specification
@@ -14,10 +14,10 @@
 # -blackBoxes -type design *
 
 # Include common el file, so that it doesn't generate reviewed common exclusions
--covEL $TOOL_SRCS_DIR/common_cov_excl.el
+-covEL $dv_root/tools/vcs/common_cov_excl.el
 
 # Name of the generated exclusion file
--save_exclusion $SCRATCH_BASE_PATH/cov_unr/unr_exclude.el
+-save_exclusion $SCRATCH_PATH/cov_unr/unr_exclude.el
 
 # Enables verbose reporting in addition to summary reporting.
 -verboseReport
diff --git a/hw/formal/tools/dvsim/common_fpv_cfg.hjson b/hw/formal/tools/dvsim/common_fpv_cfg.hjson
index ddc7edd..6cd6c1b 100644
--- a/hw/formal/tools/dvsim/common_fpv_cfg.hjson
+++ b/hw/formal/tools/dvsim/common_fpv_cfg.hjson
@@ -3,11 +3,12 @@
 // SPDX-License-Identifier: Apache-2.0
 {
   flow:             fpv
-  flow_makefile:    "{proj_root}/hw/formal/tools/dvsim/fpv.mk"
+  fpv_root:         "{proj_root}/hw/formal"
+  flow_makefile:    "{fpv_root}/tools/dvsim/fpv.mk"
 
   import_cfgs:      [// common server configuration for results upload
                      "{proj_root}/hw/data/common_project_cfg.hjson",
-                     "{proj_root}/hw/formal/tools/{tool}/{tool}.hjson"]
+                     "{fpv_root}/tools/{tool}/{tool}.hjson"]
 
   tool:             "jaspergold"
 
@@ -29,16 +30,13 @@
                       "--setup {fusesoc_core}"]
   sv_flist_gen_dir:  "{build_dir}/formal-icarus"
 
-  // Indicate the tool specific helper sources
-  tool_srcs: ["{proj_root}/hw/formal/tools/{tool}/fpv.tcl"]
-
   // Vars that need to exported to the env
   exports: [
     { FPV_TOP: "{dut}" },
     { COV: "{cov}" }
   ]
 
-  report_cmd:  "python3 {proj_root}/hw/formal/tools/{tool}/parse-fpv-report.py"
+  report_cmd:  "python3 {fpv_root}/tools/{tool}/parse-fpv-report.py"
   report_opts: ["--logpath={build_dir}/fpv.log",
                 "--reppath={build_dir}/results.hjson",
                 "--cov={cov}",
diff --git a/hw/formal/tools/dvsim/fpv.mk b/hw/formal/tools/dvsim/fpv.mk
index 63fbe5b..8da4636 100644
--- a/hw/formal/tools/dvsim/fpv.mk
+++ b/hw/formal/tools/dvsim/fpv.mk
@@ -1,6 +1,7 @@
 # Copyright lowRISC contributors.
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
+
 .DEFAULT_GOAL := all
 
 all: build
@@ -8,35 +9,36 @@
 ###################
 ## build targets ##
 ###################
-build: compile_result
+build: build_result
 
 gen_sv_flist:
 	@echo "[make]: gen_sv_flist"
 	cd ${build_dir} && ${sv_flist_gen_cmd} ${sv_flist_gen_opts}
 
-pre_compile: gen_sv_flist
-	@echo "[make]: pre_compile"
+pre_build: gen_sv_flist
+	@echo "[make]: pre_build"
 	mkdir -p ${build_dir}
-	env | sort > ${build_dir}/env_vars
-	cp -Ru ${tool_srcs} ${sv_flist_gen_dir}
+ifneq (${pre_build_cmds},)
+	cd ${build_dir} && ${pre_build_cmds}
+endif
 
-compile: pre_compile
-	@echo "[make]: compile"
-	# we check the status in the parse script below
+do_build: pre_build
+	@echo "[make]: do_build"
 	cd ${sv_flist_gen_dir} && ${build_cmd} ${build_opts} 2>&1 | tee ${build_dir}/fpv.log
 
-post_compile: compile
-	@echo "[make]: post_compile"
+post_build: do_build
+	@echo "[make]: post_build"
+ifneq (${post_build_cmds},)
+	cd ${build_dir} && ${post_build_cmds}
+endif
 
-# Parse out result
-compile_result: post_compile
-	@echo "[make]: compile_result"
+build_result: post_build
+	@echo "[make]: build_result"
 	${report_cmd} ${report_opts}
 
-.PHONY: \
-	build \
-	run \
-	pre_compile \
-	compile \
-	post_compile \
-	compile_result
+.PHONY: build \
+        gen_sv_flist \
+        pre_build \
+        do_build \
+        post_build \
+        build_result
diff --git a/hw/ip/aes/syn/aes_syn_cfg.hjson b/hw/ip/aes/syn/aes_syn_cfg.hjson
index 72fdab0..ce4e632 100644
--- a/hw/ip/aes/syn/aes_syn_cfg.hjson
+++ b/hw/ip/aes/syn/aes_syn_cfg.hjson
@@ -12,8 +12,7 @@
                 "{proj_root}/hw/syn/tools/dvsim/common_syn_cfg.hjson"]
 
   // Timing constraints for this module
-  sdc_path: "{proj_root}/hw/ip/aes/syn/"
-  sdc_file: "constraints.sdc"
+  sdc_file: "{proj_root}/hw/ip/aes/syn/constraints.sdc"
 
   // Configuration for result parser script
   area_depth: 1
diff --git a/hw/ip/alert_handler/dv/alert_handler_generic_sim_cfg.hjson b/hw/ip/alert_handler/dv/alert_handler_generic_sim_cfg.hjson
index b2cb1eb..b25cc23 100644
--- a/hw/ip/alert_handler/dv/alert_handler_generic_sim_cfg.hjson
+++ b/hw/ip/alert_handler/dv/alert_handler_generic_sim_cfg.hjson
@@ -36,13 +36,7 @@
   reseed: 50
 
   // Add ALERT_HANDLER specific exclusion files.
-
-  // Add excl files to tool_srcs so that it gets copied over to the scratch area.
-  tool_srcs: ["{proj_root}/hw/ip/alert_handler/dv/cov/alert_handler_cov_excl.el"]
-
-  // Refer to the excl file with vcs_cov_excl_files var with the rel path from tool_srcs_dir
-  // so the VCS can find it.
-  vcs_cov_excl_files: ["{tool_srcs_dir}/alert_handler_cov_excl.el"]
+  vcs_cov_excl_files: ["{proj_root}/hw/ip/alert_handler/dv/cov/alert_handler_cov_excl.el"]
 
   // Default UVM test and seq class name.
   uvm_test: alert_handler_base_test
diff --git a/hw/ip/gpio/dv/gpio_sim_cfg.hjson b/hw/ip/gpio/dv/gpio_sim_cfg.hjson
index ca90dc8..bbfdec1 100644
--- a/hw/ip/gpio/dv/gpio_sim_cfg.hjson
+++ b/hw/ip/gpio/dv/gpio_sim_cfg.hjson
@@ -43,13 +43,7 @@
   uvm_test_seq: gpio_base_vseq
 
   // Add GPIO specific exclusion files.
-
-  // Add excl files to tool_srcs so that it gets copied over to the scratch area.
-  tool_srcs: ["{proj_root}/hw/ip/gpio/dv/cov/gpio_cov_excl.el"]
-
-  // Refer to the excl file with vcs_cov_excl_files var with the rel path from tool_srcs_dir
-  // so the VCS can find it.
-  vcs_cov_excl_files: ["{tool_srcs_dir}/gpio_cov_excl.el"]
+  vcs_cov_excl_files: ["{proj_root}/hw/ip/gpio/dv/cov/gpio_cov_excl.el"]
 
   // List of test specifications.
   tests: [
diff --git a/hw/ip/hmac/dv/hmac_sim_cfg.hjson b/hw/ip/hmac/dv/hmac_sim_cfg.hjson
index 0d846d1..9d51f03 100644
--- a/hw/ip/hmac/dv/hmac_sim_cfg.hjson
+++ b/hw/ip/hmac/dv/hmac_sim_cfg.hjson
@@ -39,13 +39,7 @@
   reseed: 50
 
   // Add HMAC specific exclusion files.
-
-  // Add excl files to tool_srcs so that it gets copied over to the scratch area.
-  tool_srcs: ["{proj_root}/hw/ip/hmac/dv/cov/hmac_cov_excl.el"]
-
-  // Refer to the excl file with vcs_cov_excl_files var with the rel path from tool_srcs_dir
-  // so the VCS can find it.
-  vcs_cov_excl_files: ["{tool_srcs_dir}/hmac_cov_excl.el"]
+  vcs_cov_excl_files: ["{proj_root}/hw/ip/hmac/dv/cov/hmac_cov_excl.el"]
 
   // Default UVM test and seq class name.
   uvm_test: hmac_base_test
diff --git a/hw/ip/kmac/dv/kmac_base_sim_cfg.hjson b/hw/ip/kmac/dv/kmac_base_sim_cfg.hjson
index 4f1ec4d..854d0b2 100644
--- a/hw/ip/kmac/dv/kmac_base_sim_cfg.hjson
+++ b/hw/ip/kmac/dv/kmac_base_sim_cfg.hjson
@@ -41,8 +41,8 @@
   // Need to override the default output directory
   overrides: [
     {
-      name: scratch_base_path
-      value: "{scratch_root}/{variant}.{flow}.{tool}"
+      name: scratch_path
+      value: "{scratch_base_path}/{variant}-{flow}-{tool}"
     }
   ]
 
diff --git a/hw/ip/otbn/dv/uvm/otbn_sim_cfg.hjson b/hw/ip/otbn/dv/uvm/otbn_sim_cfg.hjson
index 4ce580b..b187216 100644
--- a/hw/ip/otbn/dv/uvm/otbn_sim_cfg.hjson
+++ b/hw/ip/otbn/dv/uvm/otbn_sim_cfg.hjson
@@ -21,6 +21,9 @@
   // Testplan hjson file.
   testplan: "{proj_root}/hw/ip/otbn/data/otbn_testplan.hjson"
 
+  exports: [
+    { REPO_TOP: "{proj_root}" },
+  ]
 
   // Import additional common sim cfg files.
   // TODO: remove imported cfgs that do not apply.
diff --git a/hw/ip/otbn/syn/otbn_syn_cfg.hjson b/hw/ip/otbn/syn/otbn_syn_cfg.hjson
index c605229..6b8e387 100644
--- a/hw/ip/otbn/syn/otbn_syn_cfg.hjson
+++ b/hw/ip/otbn/syn/otbn_syn_cfg.hjson
@@ -12,8 +12,7 @@
                 "{proj_root}/hw/syn/tools/dvsim/common_syn_cfg.hjson"]
 
   // Timing constraints for this module
-  sdc_path: "{proj_root}/hw/ip/otbn/syn/"
-  sdc_file: "constraints.sdc"
+  sdc_file: "{proj_root}/hw/ip/otbn/syn/constraints.sdc"
 
   // Configuration for result parser script
   area_depth: 1
diff --git a/hw/ip/prim/dv/prim_lfsr/prim_lfsr_sim_cfg.hjson b/hw/ip/prim/dv/prim_lfsr/prim_lfsr_sim_cfg.hjson
index 2ce01dd..f47d26a 100644
--- a/hw/ip/prim/dv/prim_lfsr/prim_lfsr_sim_cfg.hjson
+++ b/hw/ip/prim/dv/prim_lfsr/prim_lfsr_sim_cfg.hjson
@@ -23,13 +23,8 @@
   // Default iterations for all tests - each test entry can override this.
   reseed: 50
 
-  // Add the coverage configuration and exclusion files so they get copied
-  // over to the scratch area.
-  tool_srcs: ["{proj_root}/hw/ip/prim/dv/prim_lfsr/data/prim_lfsr_cover.cfg",
-              "{proj_root}/hw/ip/prim/dv/prim_lfsr/data/prim_lfsr_cover_assert.cfg",
-              "{proj_root}/hw/ip/prim/dv/prim_lfsr/data/prim_lfsr_cov_excl.el"]
-
-  vcs_cov_excl_files: ["{tool_srcs_dir}/prim_lfsr_cov_excl.el"]
+  // Add PRIM_LSFR specific exclusion files.
+  vcs_cov_excl_files: ["{proj_root}/hw/ip/prim/dv/prim_lfsr/data/prim_lfsr_cov_excl.el"]
 
   build_modes: [
     {
@@ -44,8 +39,8 @@
 
   // dw_8 is only used for "smoke" sims, so coverage collection is not needed.
   prim_lfsr_dw_8_vcs_cov_cfg_file: ""
-  prim_lfsr_dw_24_vcs_cov_cfg_file: "-cm_hier {tool_srcs_dir}/prim_lfsr_cover.cfg"
-  vcs_cov_assert_cfg_file: "-cm_assert_hier {tool_srcs_dir}/prim_lfsr_cover_assert.cfg"
+  prim_lfsr_dw_24_vcs_cov_cfg_file: "-cm_hier {proj_root}/hw/ip/prim/dv/prim_lfsr/data/prim_lfsr_cover.cfg"
+  vcs_cov_assert_cfg_file: "-cm_assert_hier {proj_root}/hw/ip/prim/dv/prim_lfsr/data/prim_lfsr_cover_assert.cfg"
 
   prim_lfsr_dw_8_xcelium_cov_cfg_file: ""
   prim_lfsr_dw_24_xcelium_cov_cfg_file: ""
diff --git a/hw/ip/prim/dv/prim_present/prim_present_sim_cfg.hjson b/hw/ip/prim/dv/prim_present/prim_present_sim_cfg.hjson
index 84745cf..2d5c95b 100644
--- a/hw/ip/prim/dv/prim_present/prim_present_sim_cfg.hjson
+++ b/hw/ip/prim/dv/prim_present/prim_present_sim_cfg.hjson
@@ -26,13 +26,10 @@
   // Default iterations for all tests - each test entry can override this.
   reseed: 50
 
-  // Add these to tool_srcs so that they get copied over.
-  tool_srcs: ["{proj_root}/hw/ip/prim/dv/prim_present/data/prim_present_cover.cfg"]
-
   overrides: [
     {
       name: vcs_cov_cfg_file
-      value: "-cm_hier {tool_srcs_dir}/prim_present_cover.cfg"
+      value: "-cm_hier {proj_root}/hw/ip/prim/dv/prim_present/data/prim_present_cover.cfg"
     }
   ]
 
diff --git a/hw/ip/prim/dv/prim_prince/prim_prince_sim_cfg.hjson b/hw/ip/prim/dv/prim_prince/prim_prince_sim_cfg.hjson
index 9240a16..755e52d 100644
--- a/hw/ip/prim/dv/prim_prince/prim_prince_sim_cfg.hjson
+++ b/hw/ip/prim/dv/prim_prince/prim_prince_sim_cfg.hjson
@@ -23,12 +23,10 @@
   // Default iterations for all tests - each test entry can override this.
   reseed: 50
 
-  tool_srcs: ["{proj_root}/hw/ip/prim/dv/prim_prince/data/prim_prince_cover.cfg"]
-
   overrides: [
     {
       name: vcs_cov_cfg_file
-      value: "-cm_hier {tool_srcs_dir}/prim_prince_cover.cfg"
+      value: "-cm_hier {proj_root}/hw/ip/prim/dv/prim_prince/data/prim_prince_cover.cfg"
     }
   ]
 
diff --git a/hw/ip/rv_core_ibex/syn/rv_core_ibex_syn_cfg.hjson b/hw/ip/rv_core_ibex/syn/rv_core_ibex_syn_cfg.hjson
index 37d6fd4..f962cf4 100644
--- a/hw/ip/rv_core_ibex/syn/rv_core_ibex_syn_cfg.hjson
+++ b/hw/ip/rv_core_ibex/syn/rv_core_ibex_syn_cfg.hjson
@@ -12,7 +12,5 @@
                 "{proj_root}/hw/syn/tools/dvsim/common_syn_cfg.hjson"]
 
   // Timing constraints for this module
-  sdc_path: "{proj_root}/hw/ip/rv_core_ibex/syn"
-  sdc_file: "constraints.sdc"
-
+  sdc_file: "{proj_root}/hw/ip/rv_core_ibex/syn/constraints.sdc"
  }
diff --git a/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson b/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson
index 43a98cc..606cc51 100644
--- a/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson
+++ b/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson
@@ -23,9 +23,6 @@
   // Set the path to testplan md file as it's not in the default location.
   testplan_doc_path: "hw/ip/tlul/doc/dv/#testplan"
 
-  // Add xbar specific exclusion files.
-  vcs_cov_excl_files: ["{tool_srcs_dir}/xbar_cov_excl.el"]
-
   // Import additional common sim cfg files.
   import_cfgs: [// Project wide common sim cfg file
                 "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson",
diff --git a/hw/ip/uart/dv/uart_sim_cfg.hjson b/hw/ip/uart/dv/uart_sim_cfg.hjson
index abf3954..08324a5 100644
--- a/hw/ip/uart/dv/uart_sim_cfg.hjson
+++ b/hw/ip/uart/dv/uart_sim_cfg.hjson
@@ -43,13 +43,7 @@
   uvm_test_seq: uart_base_vseq
 
   // Add UART specific exclusion files.
-
-  // Add excl files to tool_srcs so that it gets copied over to the scratch area.
-  tool_srcs: ["{proj_root}/hw/ip/uart/dv/cov/uart_cov_excl.el"]
-
-  // Refer to the excl file with vcs_cov_excl_files var with the rel path from tool_srcs_dir
-  // so the VCS can find it.
-  vcs_cov_excl_files: ["{tool_srcs_dir}/uart_cov_excl.el"]
+  vcs_cov_excl_files: ["{proj_root}/hw/ip/uart/dv/cov/uart_cov_excl.el"]
 
   // List of test specifications.
   tests: [
diff --git a/hw/lint/tools/dvsim/ascentlint.hjson b/hw/lint/tools/dvsim/ascentlint.hjson
index 548b526..632b91d 100644
--- a/hw/lint/tools/dvsim/ascentlint.hjson
+++ b/hw/lint/tools/dvsim/ascentlint.hjson
@@ -2,8 +2,10 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 {
-    // Ascentlint-specific results parsing script that is called after running lint
-    report_cmd: "{proj_root}/hw/lint/tools/{tool}/parse-lint-report.py "
-    report_opts: ["--repdir={build_dir}/lint-{tool}",
-                  "--outdir={build_dir}"]
+  tool: "ascentlint"
+
+  // Ascentlint-specific results parsing script that is called after running lint
+  report_cmd: "{lint_root}/tools/{tool}/parse-lint-report.py "
+  report_opts: ["--repdir={build_dir}/lint-{tool}",
+                "--outdir={build_dir}"]
 }
diff --git a/hw/lint/tools/dvsim/common_lint_cfg.hjson b/hw/lint/tools/dvsim/common_lint_cfg.hjson
index a4e571c..b8639d8 100644
--- a/hw/lint/tools/dvsim/common_lint_cfg.hjson
+++ b/hw/lint/tools/dvsim/common_lint_cfg.hjson
@@ -3,12 +3,13 @@
 // SPDX-License-Identifier: Apache-2.0
 {
   flow:             lint
-  flow_makefile:    "{proj_root}/hw/lint/tools/dvsim/lint.mk"
+  lint_root:        "{proj_root}/hw/lint"
+  flow_makefile:    "{lint_root}/tools/dvsim/lint.mk"
 
   import_cfgs:      [// common server configuration for results upload
                      "{proj_root}/hw/data/common_project_cfg.hjson"
                      // tool-specific configuration
-                     "{proj_root}/hw/lint/tools/dvsim/{tool}.hjson"]
+                     "{lint_root}/tools/dvsim/{tool}.hjson"]
 
   // Name of the DUT / top-level to be run through lint
   dut:        "{name}"
@@ -30,5 +31,4 @@
   sv_flist_gen_cmd:   ""
   sv_flist_gen_opts:  []
   sv_flist_gen_dir:   ""
-  tool_srcs:          []
 }
diff --git a/hw/lint/tools/dvsim/lint.mk b/hw/lint/tools/dvsim/lint.mk
index ede5374..89cd2eb 100644
--- a/hw/lint/tools/dvsim/lint.mk
+++ b/hw/lint/tools/dvsim/lint.mk
@@ -1,6 +1,7 @@
 # Copyright lowRISC contributors.
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
+
 .DEFAULT_GOAL := all
 
 all: build
@@ -8,30 +9,31 @@
 ###################
 ## build targets ##
 ###################
-build: compile_result
+build: build_result
 
-pre_compile:
-	@echo "[make]: pre_compile"
-	mkdir -p ${build_dir} && env | sort > ${build_dir}/env_vars
-	mkdir -p ${tool_srcs_dir}
-	-cp -Ru ${tool_srcs} ${tool_srcs_dir}
+pre_build:
+	@echo "[make]: pre_build"
+	mkdir -p ${build_dir}
+ifneq (${pre_build_cmds},)
+	cd ${build_dir} && ${pre_build_cmds}
+endif
 
-compile: pre_compile
-	@echo "[make]: compile"
-	# we check the status in the parse script below
+do_build: pre_build
+	@echo "[make]: do_build"
 	-cd ${build_dir} && ${build_cmd} ${build_opts} 2>&1 | tee ${build_log}
 
-post_compile: compile
-	@echo "[make]: post_compile"
+post_build: do_build
+	@echo "[make]: post_build"
+ifneq (${post_build_cmds},)
+	cd ${build_dir} && ${post_build_cmds}
+endif
 
-# Parse out result
-compile_result: post_compile
-	@echo "[make]: compile_result"
+build_result: post_build
+	@echo "[make]: build_result"
 	${report_cmd} ${report_opts}
 
 .PHONY: build \
-	run \
-	pre_compile \
-	compile \
-	post_compile \
-	compile_result
+        pre_build \
+        do_build \
+        post_build \
+        build_result
diff --git a/hw/lint/tools/dvsim/veriblelint.hjson b/hw/lint/tools/dvsim/veriblelint.hjson
index d7255d7..26219be 100644
--- a/hw/lint/tools/dvsim/veriblelint.hjson
+++ b/hw/lint/tools/dvsim/veriblelint.hjson
@@ -2,12 +2,14 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 {
-    // TODO(#1342): switch over to native structured tool output, once supported by Verible
-    // Verible lint-specific results parsing script that is called after running lint
-    report_cmd: "{proj_root}/hw/lint/tools/{tool}/parse-lint-report.py "
-    report_opts: ["--repdir={build_dir}",
-                  "--outdir={build_dir}"]
+  tool: "veriblelint"
 
-    // This customizes the report format for style lint
-    is_style_lint: True
+  // TODO(#1342): switch over to native structured tool output, once supported by Verible
+  // Verible lint-specific results parsing script that is called after running lint
+  report_cmd: "{lint_root}/tools/{tool}/parse-lint-report.py "
+  report_opts: ["--repdir={build_dir}",
+                "--outdir={build_dir}"]
+
+  // This customizes the report format for style lint
+  is_style_lint: True
 }
diff --git a/hw/lint/tools/dvsim/verilator.hjson b/hw/lint/tools/dvsim/verilator.hjson
index 6401d7f..698afba 100644
--- a/hw/lint/tools/dvsim/verilator.hjson
+++ b/hw/lint/tools/dvsim/verilator.hjson
@@ -2,8 +2,10 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 {
-    // Verilator lint-specific results parsing script that is called after running lint
-    report_cmd: "{proj_root}/hw/lint/tools/{tool}/parse-lint-report.py "
-    report_opts: ["--logpath={build_dir}/lint.log",
-                  "--reppath={build_dir}/results.hjson"]
+  tool: "verilator"
+
+  // Verilator lint-specific results parsing script that is called after running lint
+  report_cmd: "{lint_root}/tools/{tool}/parse-lint-report.py "
+  report_opts: ["--logpath={build_dir}/lint.log",
+                "--reppath={build_dir}/results.hjson"]
 }
diff --git a/hw/syn/tools/dc/run-syn.tcl b/hw/syn/tools/dc/run-syn.tcl
index fcdf25c..b43d83d 100644
--- a/hw/syn/tools/dc/run-syn.tcl
+++ b/hw/syn/tools/dc/run-syn.tcl
@@ -8,9 +8,26 @@
 ##  PREPARE FLOW   ##
 #####################
 
-# tool setup
-set CONFIG_PATH "./"
-source ${CONFIG_PATH}/setup.tcl
+set syn_root ""
+if {[info exists ::env(syn_root)]} {
+  set syn_root "$::env(syn_root)"
+} else {
+  puts "ERROR: Script run without syn_root environment variable."
+  quit
+}
+
+set foundry_root ""
+if {[info exists ::env(foundry_root)]} {
+  set foundry_root "$::env(foundry_root)"
+} else {
+  puts "ERROR: Script run without foundry_root environment variable."
+  quit
+}
+
+# Tool setup.
+# TODO: The below path assumes a certain directory structure in the foundry area which does not
+# exist in the open repo.
+source ${foundry_root}/syn/dc/setup.tcl
 
 # if in interactive mode, do not exit at the end of the script
 if { [info exists ::env(INTERACTIVE)] } {
diff --git a/hw/syn/tools/dvsim/common_syn_cfg.hjson b/hw/syn/tools/dvsim/common_syn_cfg.hjson
index 413bad6..fb069b8 100644
--- a/hw/syn/tools/dvsim/common_syn_cfg.hjson
+++ b/hw/syn/tools/dvsim/common_syn_cfg.hjson
@@ -3,14 +3,20 @@
 // SPDX-License-Identifier: Apache-2.0
 {
   flow:             syn
-  flow_makefile:    "{proj_root}/hw/syn/tools/dvsim/syn.mk"
+  syn_root:         "{proj_root}/hw/syn"
+  flow_makefile:    "{syn_root}/tools/dvsim/syn.mk"
+
+  // TODO: the path below is used to refer to the foundry area which does not exist in the open
+  // repo. This forces the closed "foundry" repo to be placed in that area. This might be subject to
+  // change in future.
+  foundry_root:     "{proj_root}/hw/foundry"
 
   import_cfgs:      [// common server configuration for results upload
                      // TODO: check whether this config file can be aligned such that it can
                      // be reused among different flow types
                      // "{proj_root}/hw/dv/tools/dvsim/fusesoc.hjson",
                      "{proj_root}/hw/data/common_project_cfg.hjson",
-                     "{proj_root}/hw/syn/tools/dvsim/{tool}.hjson"]
+                     "{syn_root}/tools/dvsim/{tool}.hjson"]
 
   // Default directory structure for the output
   dut:              "{name}"
@@ -34,4 +40,9 @@
                        "{fusesoc_core}"]
   sv_flist_gen_dir:   "{build_dir}/syn-icarus"
   sv_flist:           "{sv_flist_gen_dir}/{fusesoc_core_}.scr"
+
+  exports: [
+    { syn_root: "{syn_root}" },
+    { foundry_root: "{foundry_root}" },
+  ]
 }
diff --git a/hw/syn/tools/dvsim/dc.hjson b/hw/syn/tools/dvsim/dc.hjson
index 053b3fc..908f5a8 100644
--- a/hw/syn/tools/dvsim/dc.hjson
+++ b/hw/syn/tools/dvsim/dc.hjson
@@ -2,14 +2,6 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 {
-  // The tool sources include the technology setup file,
-  // the main synthesis run script and the constraints file
-  tool_srcs: ["{proj_root}/hw/foundry/syn/{tool}/setup.tcl"
-              "{proj_root}/hw/foundry/syn/{tool}/lib-setup.tcl"
-              "{proj_root}/hw/foundry/syn/{tool}/ram-macros-setup.tcl"
-              "{proj_root}/hw/syn/tools/{tool}/run-syn.tcl"
-              "{sdc_path}/{sdc_file}"]
-
   // Environment variables that are needed in the synthesis script
   exports: [
     { DUT:        "{dut}" },
@@ -20,10 +12,10 @@
 
   // Tool invocation
   build_cmd:  "{job_prefix} dc_shell-xg-t "
-  build_opts: ["-f run-syn.tcl"]
+  build_opts: ["-f {syn_root}/tools/dc/run-syn.tcl"]
 
   // DC-specific results parsing script that is called after running synthesis
-  report_cmd: "{proj_root}/hw/syn/tools/{tool}/parse-syn-report.py --depth {area_depth}"
+  report_cmd: "{syn_root}/tools/dc/parse-syn-report.py --depth {area_depth}"
   report_opts: ["--dut {dut}",
                 "--logpath {build_dir} ",
                 "--reppath {build_dir}/REPORTS",
diff --git a/hw/syn/tools/dvsim/syn.mk b/hw/syn/tools/dvsim/syn.mk
index 5327340..b51e626 100644
--- a/hw/syn/tools/dvsim/syn.mk
+++ b/hw/syn/tools/dvsim/syn.mk
@@ -1,6 +1,7 @@
 # Copyright lowRISC contributors.
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
+
 .DEFAULT_GOAL := all
 
 all: build
@@ -8,33 +9,36 @@
 ###################
 ## build targets ##
 ###################
-build: compile_result
+build: build_result
 
 gen_sv_flist:
 	@echo "[make]: gen_sv_flist"
 	cd ${build_dir} && ${sv_flist_gen_cmd} ${sv_flist_gen_opts}
 
-pre_compile: gen_sv_flist
-	@echo "[make]: pre_compile"
-	mkdir -p ${build_dir} && env | sort > ${build_dir}/env_vars
-	-cp -Ru ${tool_srcs} ${sv_flist_gen_dir}
+pre_build: gen_sv_flist
+	@echo "[make]: pre_build"
+	mkdir -p ${build_dir}
+ifneq (${pre_build_cmds},)
+	cd ${build_dir} && ${pre_build_cmds}
+endif
 
-compile: pre_compile
-	@echo "[make]: compile"
-	# we check the status in the parse script below
+do_build: pre_build
+	@echo "[make]: do_build"
 	cd ${sv_flist_gen_dir} && ${build_cmd} ${build_opts} 2>&1 | tee ${build_log}
 
-post_compile: compile
-	@echo "[make]: post_compile"
+post_build: do_build
+	@echo "[make]: post_build"
+ifneq (${post_build_cmds},)
+	cd ${build_dir} && ${post_build_cmds}
+endif
 
-# Parse out result
-compile_result: post_compile
-	@echo "[make]: compile_result"
+build_result: post_build
+	@echo "[make]: build_result"
 	${report_cmd} ${report_opts}
 
 .PHONY: build \
-	gen_sv_flist \
-	pre_compile \
-	compile \
-	post_compile \
-	compile_result
+        gen_sv_flist \
+        pre_build \
+        do_build \
+        post_build \
+        build_result
diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
index ed88687..ac0cad7 100644
--- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson
+++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
@@ -54,14 +54,14 @@
     // IPs. See `hw/dv/tools/dvsim/common_sim_cfg.hjson` for the default value.
     {
       name: default_vcs_cov_cfg_file
-      value: "-cm_hier {tool_srcs_dir}/chip_cover.cfg"
+      value: "-cm_hier {proj_root}/hw/top_earlgrey/dv/cov/chip_cover.cfg"
     }
     // Used by 'cover_reg_top' only builds - we only cover the *_reg_top of
     // the non-pre-verified modules at the chip level. See
     // `hw/dv/tools/dvsim//common_sim_cfg.hjson` for the default value.
     {
       name: cover_reg_top_vcs_cov_cfg_file
-      value: "-cm_hier {tool_srcs_dir}/chip_cover_reg_top.cfg"
+      value: "-cm_hier {proj_root)/hw/top_earlgrey/dv/cov/chip_cover_reg_top.cfg"
     }
 
     // This defaults to 'ip' in `hw/data/common_project_cfg.hjson`.
@@ -73,10 +73,7 @@
 
   // Set the vcs_cov_assert_hier to supply the chip specific assertion coverage
   // hierarchies.
-  vcs_cov_assert_hier: "-cm_assert_hier {tool_srcs_dir}/chip_assert_cover.cfg"
-
-  // Add these to tool_srcs so that they get copied over.
-  tool_srcs: ["{proj_root}/hw/top_earlgrey/dv/cov/*"]
+  vcs_cov_assert_hier: "-cm_assert_hier {proj_root}/hw/top_earlgrey/dv/cov/chip_assert_cover.cfg"
 
   // Default iterations for all tests - each test entry can override this.
   reseed: 1
diff --git a/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_main_sim_cfg.hjson b/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_main_sim_cfg.hjson
index c072255..35b7b85 100644
--- a/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_main_sim_cfg.hjson
+++ b/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_main_sim_cfg.hjson
@@ -12,8 +12,8 @@
   // Testplan hjson file.
   testplan: "{proj_root}/hw/top_earlgrey/ip/{dut}/data/autogen/{dut}_testplan.hjson"
 
-  // Add excl files to tool_srcs so that it gets copied over to the scratch area.
-  tool_srcs: ["{proj_root}/hw/top_earlgrey/ip/{dut}/dv/cov/xbar_cov_excl.el"]
+  // Add xbar_main specific exclusion files.
+  vcs_cov_excl_files: ["{proj_root}/hw/top_earlgrey/ip/{dut}/dv/cov/xbar_cov_excl.el"]
 
   // Import additional common sim cfg files.
   import_cfgs: [// xbar common sim cfg file
diff --git a/hw/top_earlgrey/ip/xbar_peri/dv/autogen/xbar_peri_sim_cfg.hjson b/hw/top_earlgrey/ip/xbar_peri/dv/autogen/xbar_peri_sim_cfg.hjson
index d348015..90cc441 100644
--- a/hw/top_earlgrey/ip/xbar_peri/dv/autogen/xbar_peri_sim_cfg.hjson
+++ b/hw/top_earlgrey/ip/xbar_peri/dv/autogen/xbar_peri_sim_cfg.hjson
@@ -12,8 +12,8 @@
   // Testplan hjson file.
   testplan: "{proj_root}/hw/top_earlgrey/ip/{dut}/data/autogen/{dut}_testplan.hjson"
 
-  // Add excl files to tool_srcs so that it gets copied over to the scratch area.
-  tool_srcs: ["{proj_root}/hw/top_earlgrey/ip/{dut}/dv/cov/xbar_cov_excl.el"]
+  // Add xbar_peri specific exclusion files.
+  vcs_cov_excl_files: ["{proj_root}/hw/top_earlgrey/ip/{dut}/dv/cov/xbar_cov_excl.el"]
 
   // Import additional common sim cfg files.
   import_cfgs: [// xbar common sim cfg file
diff --git a/hw/top_earlgrey/syn/top_earlgrey_syn_cfg.hjson b/hw/top_earlgrey/syn/top_earlgrey_syn_cfg.hjson
index 5523b9e..9ae03bb 100644
--- a/hw/top_earlgrey/syn/top_earlgrey_syn_cfg.hjson
+++ b/hw/top_earlgrey/syn/top_earlgrey_syn_cfg.hjson
@@ -20,13 +20,10 @@
   ]
 
   // Timing constraints for this module
-  sdc_path: "{proj_root}/hw/top_earlgrey/syn"
-  sdc_file: "constraints.sdc"
+  sdc_file: "{proj_root}/hw/top_earlgrey/syn/constraints.sdc"
 
   // Technology specific timing constraints for this module
-  foundry_sdc_path: "{proj_root}/hw/foundry/top_earlgrey/syn"
-  foundry_sdc_file: "foundry.constraints.sdc"
-  tool_srcs: ["{foundry_sdc_path}/{foundry_sdc_file}"]
+  foundry_sdc_file: "{proj_root}/hw/foundry/top_earlgrey/syn/foundry.constraints.sdc"
 
   // Configuration for result parser script
   area_depth: 1
diff --git a/util/dvsim/Deploy.py b/util/dvsim/Deploy.py
index 199d5a8..e43d854 100644
--- a/util/dvsim/Deploy.py
+++ b/util/dvsim/Deploy.py
@@ -654,8 +654,7 @@
 
         self.mandatory_cmd_attrs.update({
             # tool srcs
-            "tool_srcs": False,
-            "tool_srcs_dir": False,
+            "proj_root": False,
 
             # Flist gen
             "sv_flist_gen_cmd": False,
@@ -717,8 +716,7 @@
 
         self.mandatory_cmd_attrs.update({
             # tool srcs
-            "tool_srcs": False,
-            "tool_srcs_dir": False,
+            "proj_root": False,
 
             # Flist gen
             "sv_flist_gen_cmd": False,
@@ -727,8 +725,10 @@
 
             # Build
             "build_dir": False,
+            "pre_build_cmds": False,
             "build_cmd": False,
             "build_opts": False,
+            "post_build_cmds": False,
             "build_log": False,
 
             # Report processing
@@ -775,8 +775,6 @@
 
         self.mandatory_cmd_attrs.update({
             # tool srcs
-            "tool_srcs": False,
-            "tool_srcs_dir": False,
             "proj_root": False,
             "uvm_test": False,
             "uvm_test_seq": False,
@@ -866,8 +864,7 @@
         self.target = "cov_unr"
         self.mandatory_cmd_attrs.update({
             # tool srcs
-            "tool_srcs": False,
-            "tool_srcs_dir": False,
+            "proj_root": False,
 
             # Need to generate filelist based on build mode
             "sv_flist_gen_cmd": False,
@@ -1066,8 +1063,7 @@
 
         self.mandatory_cmd_attrs.update({
             # tool srcs
-            "tool_srcs": False,
-            "tool_srcs_dir": False,
+            "proj_root": False,
             "cov_analyze_cmd": False,
             "cov_analyze_opts": False
         })
diff --git a/util/dvsim/dvsim.py b/util/dvsim/dvsim.py
index 801e427..99c7247 100755
--- a/util/dvsim/dvsim.py
+++ b/util/dvsim/dvsim.py
@@ -28,13 +28,16 @@
 import textwrap
 from signal import SIGINT, signal
 
-from CfgFactory import make_cfg
 import Deploy
 import utils
+from CfgFactory import make_cfg
 
 # TODO: add dvsim_cfg.hjson to retrieve this info
 version = 0.1
 
+# By default, all build and run artifacts go here.
+DEFAULT_SCRATCH_ROOT = os.getcwd() + "/scratch"
+
 # The different categories that can be passed to the --list argument.
 _LIST_CATEGORIES = ["build_modes", "run_modes", "tests", "regressions"]
 
@@ -48,7 +51,7 @@
     scratch_root = os.environ.get('SCRATCH_ROOT')
     if not arg_scratch_root:
         if scratch_root is None:
-            arg_scratch_root = os.getcwd() + "/scratch"
+            arg_scratch_root = DEFAULT_SCRATCH_ROOT
         else:
             # Scratch space could be mounted in a filesystem (such as NFS) on a network drive.
             # If the network is down, it could cause the access access check to hang. So run a
@@ -60,7 +63,7 @@
             if status == 0 and out != "":
                 arg_scratch_root = scratch_root
             else:
-                arg_scratch_root = os.getcwd() + "/scratch"
+                arg_scratch_root = DEFAULT_SCRATCH_ROOT
                 log.warning(
                     "Env variable $SCRATCH_ROOT=\"{}\" is not accessible.\n"
                     "Using \"{}\" instead.".format(scratch_root,
@@ -150,6 +153,29 @@
     return (proj_root)
 
 
+def resolve_proj_root(args):
+    '''Update proj_root based on how DVSim is invoked.
+
+    If --remote env var is set, a location in the scratch area is chosen as the
+    new proj_root. The entire repo is copied over to this location. Else, the
+    proj_root is discovered using get_proj_root() method, unless the user
+    overrides it on the command line.
+
+    This function returns the updated proj_root path.
+    '''
+    proj_root = args.proj_root or get_proj_root()
+
+    # Check if jobs are dispatched to external compute machines. If yes,
+    # then the repo needs to be copied over to the scratch area
+    # accessible to those machines.
+    if args.remote:
+        dest = os.path.join(args.scratch_root, args.branch, "repo_top")
+        copy_repo(proj_root, dest, args.dry_run)
+        proj_root = dest
+
+    return proj_root
+
+
 def sigint_handler(signal_received, frame):
     # Kill processes and background jobs.
     log.debug('SIGINT or CTRL-C detected. Exiting gracefully')
@@ -158,6 +184,44 @@
     exit(1)
 
 
+def copy_repo(src, dest, dry_run):
+    '''Copy over the repo to a new location.
+
+    The repo is copied over from src to dest area. It tentatively uses the
+    rsync utility which provides the ability to specify a file containing some
+    exclude patterns to skip certain things from being copied over. With GitHub
+    repos, an existing `.gitignore` serves this purpose pretty well.
+    '''
+    rsync_cmd = "rsync --archive --update --executability --inplace "
+
+    # Supply `.gitignore` from the src area to skip temp files.
+    ignore_patterns_file = os.path.join(src, ".gitignore")
+    if os.path.exists(ignore_patterns_file):
+        # TODO: hack - include hw/foundry since it is excluded in .gitignore.
+        rsync_cmd += "--include=hw/foundry "
+        rsync_cmd += "--exclude-from={} ".format(ignore_patterns_file)
+        rsync_cmd += "--exclude=*.git* "
+
+    rsync_cmd += src + "/. " + dest
+
+    cmd = ["flock", "--timeout", "600", dest, "--command", rsync_cmd]
+
+    log.info("[copy_repo] [dest]: %s", dest)
+    log.log(utils.VERBOSE, "[copy_repo] [cmd]: \n%s", ' '.join(cmd))
+    if not dry_run:
+        # Make sure the dest exists first.
+        os.makedirs(dest, exist_ok=True)
+        try:
+            proc = subprocess.run(cmd,
+                                  check=True,
+                                  stdout=subprocess.PIPE,
+                                  stderr=subprocess.PIPE)
+        except subprocess.CalledProcessError as e:
+            log.error("Failed to copy over %s to %s: %s", src, dest,
+                      e.stderr.decode("utf-8").strip())
+    log.info("Done.")
+
+
 def wrapped_docstring():
     '''Return a text-wrapped version of the module docstring'''
     paras = []
@@ -236,6 +300,10 @@
                       help=('Prepend this string when running each tool '
                             'command.'))
 
+    disg.add_argument("--remote",
+                      action='store_true',
+                      help=('Trigger copying of the repo to scratch area.'))
+
     disg.add_argument("--max-parallel",
                       "-mp",
                       type=read_max_parallel,
@@ -530,6 +598,8 @@
     args.scratch_root = resolve_scratch_root(args.scratch_root)
     args.branch = resolve_branch(args.branch)
     args.cfg = os.path.abspath(args.cfg)
+    proj_root = resolve_proj_root(args)
+    log.info("[proj_root]: %s", proj_root)
 
     # Add timestamp to args that all downstream objects can use.
     # Static variables - indicate timestamp.
@@ -557,15 +627,6 @@
 
     # Build infrastructure from hjson file and create the list of items to
     # be deployed.
-
-    # Sets the project root directory: either specified from the command line
-    # or set by automatically assuming we are in a GitHub repository and
-    # automatically finding the root of this repository.
-    if args.proj_root:
-        proj_root = args.proj_root
-    else:
-        proj_root = get_proj_root()
-
     global cfg
     cfg = make_cfg(args.cfg, args, proj_root)
 
diff --git a/util/tlgen/xbar.sim_cfg.hjson.tpl b/util/tlgen/xbar.sim_cfg.hjson.tpl
index 9fdd341..68566ad 100644
--- a/util/tlgen/xbar.sim_cfg.hjson.tpl
+++ b/util/tlgen/xbar.sim_cfg.hjson.tpl
@@ -12,8 +12,8 @@
   // Testplan hjson file.
   testplan: "{proj_root}/${xbar.ip_path}/data/autogen/{dut}_testplan.hjson"
 
-  // Add excl files to tool_srcs so that it gets copied over to the scratch area.
-  tool_srcs: ["{proj_root}/${xbar.ip_path}/dv/cov/xbar_cov_excl.el"]
+  // Add xbar_${xbar.name} specific exclusion files.
+  vcs_cov_excl_files: ["{proj_root}/${xbar.ip_path}/dv/cov/xbar_cov_excl.el"]
 
   // Import additional common sim cfg files.
   import_cfgs: [// xbar common sim cfg file