[dv/build_seed] Fix build_seed

This PR replaces PR #12112 and fixes the issue by saving the
`build_seed` to a file during build time.
Then for run time, it will try to read the build_seed file. If the file
exists, re-generate OTP image with the build_seed.

Signed-off-by: Cindy Chen <chencindy@opentitan.org>
diff --git a/hw/dv/tools/dvsim/common_sim_cfg.hjson b/hw/dv/tools/dvsim/common_sim_cfg.hjson
index 9403399..5477427 100644
--- a/hw/dv/tools/dvsim/common_sim_cfg.hjson
+++ b/hw/dv/tools/dvsim/common_sim_cfg.hjson
@@ -19,6 +19,9 @@
   sw_build_dir:       "{scratch_path}"
   sw_root_dir:        "{proj_root}/sw"
 
+  // Default file to store build_seed value
+  build_seed_file_path: "{build_dir}/build_seed.log"
+
   // pass and fail patterns
   build_pass_patterns: []
   // TODO: Add back FuseSoC fail pattern after
diff --git a/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson b/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
index 7b328d3..77baff9 100644
--- a/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
+++ b/hw/ip/otp_ctrl/dv/otp_ctrl_sim_cfg.hjson
@@ -44,7 +44,7 @@
     // defined in `hw/dv/tools/dvsim/common_modes.hjson` for more details.
     {
       name: build_seed
-      pre_build_cmds: ["cd {proj_root} && ./util/design/gen-otp-mmap.py --seed {build_seed}"]
+      pre_build_cmds: ["cd {proj_root} && ./util/design/gen-otp-mmap.py --seed {seed}"]
       is_sim_mode: 1
     }
   ]
diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
index 5d5ed25..7730889 100644
--- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson
+++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
@@ -122,10 +122,18 @@
     {
       name: build_seed
       pre_build_cmds: [
-        '''cd {proj_root} && ./util/topgen.py -t {ral_spec} \
-               -o hw/top_earlgrey --rnd_cnst_seed {build_seed}
-        ''',
-        "cd {proj_root} && ./util/design/gen-otp-mmap.py --seed {build_seed}"
+        // TODO: find where in run phase we are using this pkg. It fails during ibex TLUL integrity
+        // check.
+        // '''cd {proj_root} && ./util/topgen.py -t {ral_spec} \
+        //        -o hw/top_earlgrey --rnd_cnst_seed {seed}
+        // ''',
+        "cd {proj_root} && ./util/design/gen-otp-mmap.py --seed {seed}",
+        // Use eval_cmd to save build_seed in a file and reuse that file during run phase.
+        // Create the build directory first because eval_cmd runs before actual build phase command
+        // execution.
+        '''{eval_cmd} mkdir -p {build_dir}; echo {seed} > {build_seed_file_path}; \
+           echo "echo create file {build_seed_file_path}"
+        '''
       ]
       is_sim_mode: 1
     }
@@ -140,8 +148,17 @@
   // Setup for generating OTP images.
   gen_otp_images_cfg_dir: "{proj_root}/hw/ip/otp_ctrl/data"
   gen_otp_images_cmd: "{proj_root}/util/design/gen-otp-img.py"
-  gen_otp_images_cmd_opts: ["--quiet", "--img-seed {seed}", "--otp-seed {build_seed}"]
-
+  gen_otp_images_cmd_opts: ["--quiet",
+                            "--img-seed {seed}",
+                            // Only provide `--otp-seed` argument if the file to store build_seed
+                            // is found. Set this option at the end of the list to avoid `eval_cmd`
+                            // take other options as eval_cmd.
+                            '''{eval_cmd} file=`echo {build_seed_file_path}`; \
+                               if [ -f $file ]; then \
+                                 while read line; do \
+                                   echo "--otp-seed $line"; \
+                                 done < $file; \
+                               fi ''']
   // Add run modes.
   run_modes: [
     // Generates OTP images with different LC states with cannonical values,
@@ -149,17 +166,20 @@
     {
       name: gen_otp_images_mode
       pre_run_cmds: [
-        '''{gen_otp_images_cmd} {gen_otp_images_cmd_opts} \
-               --img-cfg {gen_otp_images_cfg_dir}/otp_ctrl_img_raw.hjson \
-               --out {run_dir}/otp_ctrl_img_raw.vmem
+        '''{gen_otp_images_cmd} \
+              --img-cfg {gen_otp_images_cfg_dir}/otp_ctrl_img_raw.hjson \
+              --out {run_dir}/otp_ctrl_img_raw.vmem \
+              {gen_otp_images_cmd_opts}
         ''',
-        '''{gen_otp_images_cmd} {gen_otp_images_cmd_opts} \
-               --img-cfg {gen_otp_images_cfg_dir}/otp_ctrl_img_dev.hjson \
-               --out {run_dir}/otp_ctrl_img_dev.vmem
+         '''{gen_otp_images_cmd} \
+              --img-cfg {gen_otp_images_cfg_dir}/otp_ctrl_img_dev.hjson \
+              --out {run_dir}/otp_ctrl_img_dev.vmem \
+              {gen_otp_images_cmd_opts}
         ''',
-        '''{gen_otp_images_cmd} {gen_otp_images_cmd_opts} \
-               --img-cfg {gen_otp_images_cfg_dir}/otp_ctrl_img_rma.hjson \
-               --out {run_dir}/otp_ctrl_img_rma.vmem
+        '''{gen_otp_images_cmd} \
+              --img-cfg {gen_otp_images_cfg_dir}/otp_ctrl_img_rma.hjson \
+              --out {run_dir}/otp_ctrl_img_rma.vmem \
+              {gen_otp_images_cmd_opts}
         ''',
       ]
     }
diff --git a/util/dvsim/Deploy.py b/util/dvsim/Deploy.py
index 286145a..ae003db 100644
--- a/util/dvsim/Deploy.py
+++ b/util/dvsim/Deploy.py
@@ -299,7 +299,6 @@
     def __init__(self, build_mode, sim_cfg):
         self.build_mode_obj = build_mode
         self.seed = sim_cfg.build_seed
-        self.build_seed = sim_cfg.build_seed
         super().__init__(sim_cfg)
 
     def _define_attrs(self):
@@ -406,7 +405,6 @@
         self.test_obj = test
         self.index = index
         self.seed = RunTest.get_seed()
-        self.build_seed = sim_cfg.build_seed
         super().__init__(sim_cfg)
 
         if build_job is not None:
diff --git a/util/dvsim/SimCfg.py b/util/dvsim/SimCfg.py
index fcb2d94..9394df0 100644
--- a/util/dvsim/SimCfg.py
+++ b/util/dvsim/SimCfg.py
@@ -60,7 +60,7 @@
     # TODO: Find a way to set these in sim cfg instead
     ignored_wildcards = [
         "build_mode", "index", "test", "seed", "uvm_test", "uvm_test_seq",
-        "cov_db_dirs", "sw_images", "sw_build_device", "build_seed"
+        "cov_db_dirs", "sw_images", "sw_build_device"
     ]
 
     def __init__(self, flow_cfg_file, hjson_data, args, mk_config):
@@ -108,11 +108,6 @@
             self.en_build_modes.append("xprop")
         if self.build_seed:
             self.en_build_modes.append("build_seed")
-        else:
-            # TODO: when build_seed mode is not enabled, the script should not
-            # pass `--otp-seed` args. Temp support this by providing default
-            # build seed value.
-            self.build_seed = 10556718629619452145
 
         # Options built from cfg_file files
         self.project = ""