[dvsim] Allow testplan to be omitted

In the current implementation, `dvsim` makes it necessary to provide a
testplan, otherwise it results in errors being thrown.

This patch fixes that and allows testplan to be completely omitted. The
tests in that case appear as 'Unmapped Tests' in the final results
table. This is useful for DUTs such as `prim_lfsr` and `prim_present`.

Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/util/dvsim/SimCfg.py b/util/dvsim/SimCfg.py
index 0ccf344..2bf439b 100644
--- a/util/dvsim/SimCfg.py
+++ b/util/dvsim/SimCfg.py
@@ -17,7 +17,7 @@
 from Deploy import CompileSim, CovAnalyze, CovMerge, CovReport, RunTest, Deploy
 from FlowCfg import FlowCfg
 from Modes import BuildModes, Modes, Regressions, RunModes, Tests
-from testplanner import testplan_utils
+from testplanner import testplan_utils, class_defs
 from utils import VERBOSE, find_and_substitute_wildcards
 
 
@@ -290,6 +290,9 @@
             self.testplan = testplan_utils.parse_testplan(self.testplan)
             # Extract tests in each milestone and add them as regression target.
             self.regressions.extend(self.testplan.get_milestone_regressions())
+        else:
+            # Create a dummy testplan with no entries.
+            self.testplan = class_defs.Testplan(name=self.name)
 
         # Create regressions
         self.regressions = Regressions.create_regressions(self.regressions,
@@ -578,21 +581,24 @@
         if self.revision_string:
             results_str += "### " + self.revision_string + "\n"
 
-        # Add path to testplan.
-        if hasattr(self, "testplan_doc_path"):
-            testplan = "https://" + self.doc_server + '/' + self.testplan_doc_path
-        else:
-            testplan = "https://" + self.doc_server + '/' + self.rel_path
-            testplan = testplan.replace("/dv", "/doc/dv_plan/#testplan")
+        # Add path to testplan, only if it has entries (i.e., its not dummy).
+        if self.testplan.entries:
+            if hasattr(self, "testplan_doc_path"):
+                testplan = "https://{}/{}".format(self.doc_server,
+                                                  self.testplan_doc_path)
+            else:
+                testplan = "https://{}/{}".format(self.doc_server,
+                                                  self.rel_path)
+                testplan = testplan.replace("/dv", "/doc/dv_plan/#testplan")
 
-        results_str += "### [Testplan](" + testplan + ")\n"
+            results_str += "### [Testplan](" + testplan + ")\n"
+
         results_str += "### Simulator: " + self.tool.upper() + "\n\n"
 
         if regr_results == []:
             results_str += "No results to display.\n"
 
         else:
-            # TODO: check if testplan is not null?
             # Map regr results to the testplan entries.
             results_str += self.testplan.results_table(
                 regr_results=regr_results,
diff --git a/util/dvsim/testplanner/class_defs.py b/util/dvsim/testplanner/class_defs.py
index ee84e7e..1c2011a 100644
--- a/util/dvsim/testplanner/class_defs.py
+++ b/util/dvsim/testplanner/class_defs.py
@@ -312,7 +312,6 @@
         result = result.replace("&gt;", ">")
         return result
 
-
     def results_table(self, regr_results, map_full_testplan=True, fmt="pipe"):
         '''Print the mapped regression results into a table in the format
         specified by the 'fmt' arg.