[xbar dv, testplan tool] Fixes to support PR #1530

- Updated testplan tool to allow imported testplan to set a default name
(or any scalar key value pair) that the parent tesplan hjson can
override
- Added fixes to generic tlul testplan and sim_cfg hjson files to make
them look more generic (moved vcs_cov_excl_files key to the generated
hjson sim cfg file instead)
- Added fixes to the generated xbar testplan and sim_cfg hjson files

Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/hw/ip/tlul/data/tlul_testplan.hjson b/hw/ip/tlul/data/tlul_testplan.hjson
index fe85048..f4b1c48 100644
--- a/hw/ip/tlul/data/tlul_testplan.hjson
+++ b/hw/ip/tlul/data/tlul_testplan.hjson
@@ -2,19 +2,21 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 {
-  name: "tlul"
+  // Use the name 'xbar' for this generic testplan. The actual testplan that imports
+  // this file can override the name if needed.
+  name: xbar
   entries: [
     {
       name: sanity
       desc: '''Sequentially test each host to access any device'''
       milestone: V1
-      tests: ["xbar_sanity"]
+      tests: ["{name}_sanity"]
     }
     {
       name: base_random_sequence
       desc: '''Enable all hosts to randomly send transactions to any device'''
       milestone: V2
-      tests: ["xbar_random"]
+      tests: ["{name}_random"]
     }
     {
       name: random_delay
@@ -23,8 +25,8 @@
             - Large delay from 0 ~ 1000 cycles
             - Small delay (0-10 cycles) for a_channel, large delay (0-1000 cycles) for d_channel'''
       milestone: V2
-      tests: ["xbar_sanity_zero_delays", "xbar_sanity_large_delays", "xbar_sanity_slow_rsp",
-              "xbar_random_zero_delays", "xbar_random_large_delays", "xbar_random_slow_rsp"]
+      tests: ["{name}_sanity_zero_delays", "{name}_sanity_large_delays", "{name}_sanity_slow_rsp",
+              "{name}_random_zero_delays", "{name}_random_large_delays", "{name}_random_slow_rsp"]
     }
     {
       name: unmapped_address
@@ -33,7 +35,7 @@
             - Ensure DUT returns d_error=1 if address is unmapped and transaction isn't passed down
               to any device'''
       milestone: V2
-      tests: ["xbar_unmapped_addr", "xbar_error_and_unmapped_addr"]
+      tests: ["{name}_unmapped_addr", "{name}_error_and_unmapped_addr"]
     }
     {
       name: error_cases
@@ -41,7 +43,7 @@
             - Drive any random value on size, mask, opcode in both channels
             - Ensure everything just pass through host to device or device to host'''
       milestone: V2
-      tests: ["xbar_error_random", "xbar_error_and_unmapped_addr"]
+      tests: ["{name}_error_random", "{name}_error_and_unmapped_addr"]
     }
     {
       name: all_access_same_device
@@ -50,13 +52,13 @@
             - If the device isn't accessible for the host, let the host randomly access the other
               devices'''
       milestone: V2
-      tests: ["xbar_access_same_device", "xbar_access_same_device_slow_rsp"]
+      tests: ["{name}_access_same_device", "{name}_access_same_device_slow_rsp"]
     }
     {
       name: all_hosts_use_same_source_id
       desc: '''Test all hosts use same ID at the same same'''
       milestone: V2
-      tests: ["xbar_same_source"]
+      tests: ["{name}_same_source"]
     }
     {
       name: stress_all
@@ -64,16 +66,16 @@
             - Combine all sequences and run in parallel
             - Add random reset between each iteration'''
       milestone: V2
-      tests: ["xbar_stress_all", "xbar_stress_all_with_error"]
+      tests: ["{name}_stress_all", "{name}_stress_all_with_error"]
     }
     {
       name: stress_with_reset
       desc: '''
-            - Inject reset while xbar_stress_all is running, after reset is completed, kill the
+            - Inject reset while stress_all is running, after reset is completed, kill the
               stress seq and then start a new stress seq
             - Run a few iteration to ensure reset doesn't break the design'''
       milestone: V2
-      tests: ["xbar_stress_all_with_rand_reset", "xbar_stress_all_with_reset_error"]
+      tests: ["{name}_stress_all_with_rand_reset", "{name}_stress_all_with_reset_error"]
     }
   ]
 }
diff --git a/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson b/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson
index d60d629..fd0f59b 100644
--- a/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson
+++ b/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson
@@ -3,19 +3,19 @@
 // SPDX-License-Identifier: Apache-2.0
 {
   // Name of the sim cfg - typically same as the name of the DUT.
-  name: xbar
+  name: "{dut}"
 
   // Top level testbench name (sv module).
   tb: tb
 
-  // dut is set in the autogenerated sim_cfg hjson file as following
-  // dut: xbar_main
+  // Top level dut name (sv module): set in the autogenerated sim cfg file that imports this.
+  // dut: xbar
 
   // Fusesoc core file used for building the file list.
-  fusesoc_core: lowrisc:dv:{dut}_sim:0.1
+  fusesoc_core: "lowrisc:dv:{dut}_sim:0.1"
 
-  // Testplan hjson file.
-  testplan: "{proj_root}/hw/ip/tlul/data/tlul_testplan.hjson"
+  // Testplan hjson file, set in the autogenerated sim cfg file that imports this.
+  // testplan: ""
 
   // no reg in xbar. This is a make variable in hw/dv/data/sim.mk. Set it to skip make target (RAL)
   exports: [
@@ -36,24 +36,21 @@
   uvm_test: xbar_base_test
   uvm_test_seq: xbar_base_vseq
 
-  // Add xbar specific exclusion files.
-  vcs_cov_excl_files: ["{proj_root}/hw/top_earlgrey/ip/{dut}/dv/autogen/cov/xbar_cov_excl.el"]
-
   // List of test specifications.
   tests: [
     {
-      name: xbar_sanity
+      name: "{name}_sanity"
       uvm_test_seq: xbar_sanity_vseq
     }
 
     {
-      name: xbar_sanity_zero_delays
+      name: "{name}_sanity_zero_delays"
       uvm_test_seq: xbar_sanity_vseq
       run_opts: ["+zero_delays=1"]
     }
 
     {
-      name: xbar_sanity_large_delays
+      name: "{name}_sanity_large_delays"
       uvm_test_seq: xbar_sanity_vseq
       run_opts: ["+max_host_req_delay=1000",
                  "+max_host_rsp_delay=1000",
@@ -62,7 +59,7 @@
     }
 
     {
-      name: xbar_sanity_slow_rsp
+      name: "{name}_sanity_slow_rsp"
       uvm_test_seq: xbar_sanity_vseq
       run_opts: ["+max_host_req_delay=10",
                  "+max_host_rsp_delay=1000",
@@ -71,18 +68,18 @@
     }
 
     {
-      name: xbar_random
+      name: "{name}_random"
       uvm_test_seq: xbar_random_vseq
     }
 
     {
-      name: xbar_random_zero_delays
+      name: "{name}_random_zero_delays"
       uvm_test_seq: xbar_random_vseq
       run_opts: ["+zero_delays=1"]
     }
 
     {
-      name: xbar_random_large_delays
+      name: "{name}_random_large_delays"
       uvm_test_seq: xbar_random_vseq
       run_opts: ["+max_host_req_delay=1000",
                  "+max_host_rsp_delay=1000",
@@ -91,7 +88,7 @@
     }
 
     {
-      name: xbar_random_slow_rsp
+      name: "{name}_random_slow_rsp"
       uvm_test_seq: xbar_random_vseq
       run_opts: ["+max_host_req_delay=10",
                  "+max_host_rsp_delay=1000",
@@ -100,12 +97,12 @@
     }
 
     {
-      name: xbar_access_same_device
+      name: "{name}_access_same_device"
       uvm_test_seq: xbar_access_same_device_vseq
     }
 
     {
-      name: xbar_access_same_device_slow_rsp
+      name: "{name}_access_same_device_slow_rsp"
       uvm_test_seq: xbar_access_same_device_vseq
       run_opts: ["+max_host_req_delay=10",
                  "+max_host_rsp_delay=1000",
@@ -114,45 +111,45 @@
     }
 
     {
-      name: xbar_same_source
+      name: "{name}_same_source"
       uvm_test_seq: xbar_same_source_vseq
     }
 
     {
-      name: xbar_error_random
+      name: "{name}_error_random"
       uvm_test: xbar_error_test
       uvm_test_seq: xbar_random_vseq
     }
 
     {
-      name: xbar_unmapped_addr
+      name: "{name}_unmapped_addr"
       uvm_test_seq: xbar_unmapped_addr_vseq
     }
 
     {
-      name: xbar_error_and_unmapped_addr
+      name: "{name}_error_and_unmapped_addr"
       uvm_test: xbar_error_test
       uvm_test_seq: xbar_unmapped_addr_vseq
     }
 
     {
-      name: xbar_stress_all
+      name: "{name}_stress_all"
       uvm_test_seq: xbar_stress_all_vseq
     }
 
     {
-      name: xbar_stress_all_with_rand_reset
+      name: "{name}_stress_all_with_rand_reset"
       uvm_test_seq: xbar_stress_all_with_rand_reset_vseq
     }
 
     {
-      name: xbar_stress_all_with_error
+      name: "{name}_stress_all_with_error"
       uvm_test: xbar_error_test
       uvm_test_seq: xbar_stress_all_vseq
     }
 
     {
-      name: xbar_stress_all_with_reset_error
+      name: "{name}_stress_all_with_reset_error"
       uvm_test: xbar_error_test
       uvm_test_seq: xbar_stress_all_with_rand_reset_vseq
     }
@@ -162,7 +159,7 @@
   regressions: [
     {
       name: sanity
-      tests: ["xbar_sanity"]
+      tests: ["{name}_sanity"]
     }
   ]
 }
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 20b8ba9..c5fb0d7 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
@@ -7,8 +7,13 @@
   // Top level dut name (sv module).
   dut: xbar_main
 
+  // Testplan hjson file.
+  testplan: "{proj_root}/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main_testplan.hjson"
+
+  // Add xbar_main specific exclusion files.
+  vcs_cov_excl_files: ["{proj_root}/hw/top_earlgrey/ip/xbar_main/dv/cov/xbar_cov_excl.el"]
+
   // Import additional common sim cfg files.
   import_cfgs: [// xbar common sim cfg file
                 "{proj_root}/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson"]
-
 }
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 e7685df..069de5e 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
@@ -7,8 +7,13 @@
   // Top level dut name (sv module).
   dut: xbar_peri
 
+  // Testplan hjson file.
+  testplan: "{proj_root}/hw/top_earlgrey/ip/xbar_peri/data/autogen/xbar_peri_testplan.hjson"
+
+  // Add xbar_peri specific exclusion files.
+  vcs_cov_excl_files: ["{proj_root}/hw/top_earlgrey/ip/xbar_peri/dv/cov/xbar_cov_excl.el"]
+
   // Import additional common sim cfg files.
   import_cfgs: [// xbar common sim cfg file
                 "{proj_root}/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson"]
-
 }
diff --git a/util/testplanner/testplan_utils.py b/util/testplanner/testplan_utils.py
index 6f1bf4c..7accf3b 100644
--- a/util/testplanner/testplan_utils.py
+++ b/util/testplanner/testplan_utils.py
@@ -132,13 +132,14 @@
         sys.exit(1)
 
 
-def merge_dicts(list1, list2):
+def merge_dicts(list1, list2, use_list1_for_defaults=True):
     '''merge 2 dicts into one
 
     This funciton takes 2 dicts as args list1 and list2. It recursively merges list2 into
     list1 and returns list1. The recursion happens when the the value of a key in both lists
     is a dict. If the values of the same key in both lists (at the same tree level) are of
-    type str (or of dissimilar type) then there is a conflict, and and error is thrown.
+    dissimilar type, then there is a conflict and an error is thrown. If they are of the same
+    scalar type, then the third arg "use_list1_for_defaults" is used to pick the final one.
     '''
     for key in list2.keys():
         if key in list1:
@@ -146,10 +147,15 @@
                 list1[key].extend(list2[key])
             elif type(list1[key]) is dict and type(list2[key]) is dict:
                 list1[key] = merge_dicts(list1[key], list2[key])
+            elif (type(list1[key]) == type(list2[key])):
+                if not use_list1_for_defaults:
+                    list1[key] = list2[key]
             else:
-                print("The type of value of key ", key, "in list1: ", str(type(list1[key])), \
-                      " does not match the type of value in list2: ", str(type(list2[key])), \
-                      " or they are not of type list or dict. The two lists cannot be merged.")
+                print("The type of value of key \"", key, "\" in list1: \"", \
+                      str(type(list1[key])), \
+                      "\" does not match the type of value in list2: \"", \
+                      str(type(list2[key])), \
+                      "\". The two lists cannot be merged.")
                 sys.exit(1)
         else:
             list1[key] = list2[key]
diff --git a/util/tlgen/xbar.sim_cfg.hjson.tpl b/util/tlgen/xbar.sim_cfg.hjson.tpl
index 243035d..decb93e 100644
--- a/util/tlgen/xbar.sim_cfg.hjson.tpl
+++ b/util/tlgen/xbar.sim_cfg.hjson.tpl
@@ -7,8 +7,13 @@
   // Top level dut name (sv module).
   dut: xbar_${xbar.name}
 
+  // Testplan hjson file.
+  testplan: "{proj_root}/hw/top_earlgrey/ip/xbar_${xbar.name}/data/autogen/xbar_${xbar.name}_testplan.hjson"
+
+  // Add xbar_${xbar.name} specific exclusion files.
+  vcs_cov_excl_files: ["{proj_root}/hw/top_earlgrey/ip/xbar_${xbar.name}/dv/cov/xbar_cov_excl.el"]
+
   // Import additional common sim cfg files.
   import_cfgs: [// xbar common sim cfg file
                 "{proj_root}/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson"]
-
 }