[dvsim] Make build-randomization opt-in

THis commit changes the dvsim infra from the original implementation
of always enabling build randomization by default, to opt-in.
The build-randomization is now enabled only if the user passes
--build-seed <optional-seed>` explicitly on the command-line. This
enables the users to properly reproduce failures.

It also enables modification of in-tree sources via pre-build commands
that can modify random constant packages. The previous implementation
made it difficult to achieve reproduction of these mutated sources.
It also did not factor in the case where a design could have multiple
build-modes in effect (default, cover_reg_top, etc).

All build-time source modifications are now to be wrapped in `build_seed`
mode, which is a simulation mode that is strictly enabled on the
command-line. The nightly regressions run at Google will eventually
be updated to pass on this switch as well.

If the --build-seed switch is not passed, no build randomization is
performed - the staticly checked-in sources are used as-is. The BUILD_SEED
which was updated in the previous implementation on every invocation
is also now fixed to 1 in this scenario.

Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/util/dvsim/Deploy.py b/util/dvsim/Deploy.py
index 0318b95..ae003db 100644
--- a/util/dvsim/Deploy.py
+++ b/util/dvsim/Deploy.py
@@ -296,13 +296,9 @@
     cmds_list_vars = ["pre_build_cmds", "post_build_cmds"]
     weight = 5
 
-    # A static, randomized seed that is fixed across all builds.
-    # This value can be overridden by --build-seed switch.
-    seed = random.getrandbits(32)
-
     def __init__(self, build_mode, sim_cfg):
         self.build_mode_obj = build_mode
-        self.seed = CompileSim.seed
+        self.seed = sim_cfg.build_seed
         super().__init__(sim_cfg)
 
     def _define_attrs(self):
@@ -356,13 +352,8 @@
 
     target = "build"
 
-    # A static, randomized seed that is fixed across all builds.
-    # This value can be overridden by --build-seed switch.
-    seed = random.getrandbits(32)
-
     def __init__(self, build_mode, sim_cfg):
         self.build_mode_obj = build_mode
-        self.seed = CompileOneShot.seed
         super().__init__(sim_cfg)
 
     def _define_attrs(self):
diff --git a/util/dvsim/SimCfg.py b/util/dvsim/SimCfg.py
index 843feb1..9394df0 100644
--- a/util/dvsim/SimCfg.py
+++ b/util/dvsim/SimCfg.py
@@ -74,6 +74,7 @@
         self.en_run_modes = []
         self.en_run_modes.extend(args.run_modes)
         self.build_unique = args.build_unique
+        self.build_seed = args.build_seed
         self.build_only = args.build_only
         self.run_only = args.run_only
         self.reseed_ovrd = args.reseed
@@ -105,6 +106,8 @@
             self.en_build_modes.append("profile")
         if self.xprop_off is not True:
             self.en_build_modes.append("xprop")
+        if self.build_seed:
+            self.en_build_modes.append("build_seed")
 
         # Options built from cfg_file files
         self.project = ""
@@ -619,8 +622,9 @@
         results_str += f"### Simulator: {self.tool.upper()}\n"
 
         # Print the build seed used for clarity.
-        if not self.run_only:
-            results_str += f"### Build seed: {CompileSim.seed}\n"
+        if self.build_seed and not self.run_only:
+            results_str += ("### Build randomization enabled with "
+                            f"--build-seed {self.build_seed}\n")
 
         if not results.table:
             results_str += "No results to display.\n"
diff --git a/util/dvsim/dvsim.py b/util/dvsim/dvsim.py
index 16a748d..bf2bb69 100755
--- a/util/dvsim/dvsim.py
+++ b/util/dvsim/dvsim.py
@@ -23,6 +23,7 @@
 import datetime
 import logging as log
 import os
+import random
 import shlex
 import subprocess
 import sys
@@ -33,7 +34,7 @@
 import LauncherFactory
 import LocalLauncher
 from CfgFactory import make_cfg
-from Deploy import CompileOneShot, CompileSim, RunTest
+from Deploy import RunTest
 from Timer import Timer
 from utils import (TS_FORMAT, TS_FORMAT_LONG, VERBOSE, rm_path,
                    run_cmd_with_timeout)
@@ -474,9 +475,13 @@
     seedg = parser.add_argument_group('Build / test seeds')
 
     seedg.add_argument("--build-seed",
+                       nargs="?",
                        type=int,
+                       const=random.getrandbits(32),
                        metavar="S",
-                       help=('Seed used for compile-time randomization.'))
+                       help=('Randomize the build. Uses the seed value passed '
+                             'an additional argument, else it randomly picks '
+                             'a 32-bit unsigned integer.'))
 
     seedg.add_argument("--seeds",
                        "-s",
@@ -656,10 +661,7 @@
     setattr(args, "timestamp_long", curr_ts.strftime(TS_FORMAT_LONG))
     setattr(args, "timestamp", curr_ts.strftime(TS_FORMAT))
 
-    # Register the seeds from command line with Compile* / RunTest classes.
-    if args.build_seed:
-        CompileSim.seed = args.build_seed
-        CompileOneShot.seed = args.build_seed
+    # Register the seeds from command line with the RunTest class.
     RunTest.seeds = args.seeds
 
     # If we are fixing a seed value, no point in tests having multiple reseeds.