[syn/lint] Small scripting fixes in synthesis/lint flows

This fixes a regular expression and an error calculation
function in the synthesis result parsing script. Also, an
additional synthesis report is written out from DC
(check_design) for completeness, and a few unused Python libs
are removed.

Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/lint/tools/ascentlint/parse-lint-report.py b/hw/lint/tools/ascentlint/parse-lint-report.py
index bca4b8b..c013e62 100755
--- a/hw/lint/tools/ascentlint/parse-lint-report.py
+++ b/hw/lint/tools/ascentlint/parse-lint-report.py
@@ -5,13 +5,11 @@
 r"""Parses lint report and dump filtered messages in hjson format.
 """
 import argparse
-import datetime
 import re
 import sys
 from pathlib import Path
 
 import hjson
-import mistletoe
 
 
 def extract_messages(full_file, patterns, results):
diff --git a/hw/syn/tools/dc/parse-syn-report.py b/hw/syn/tools/dc/parse-syn-report.py
index f5ed801..a94b1bd 100755
--- a/hw/syn/tools/dc/parse-syn-report.py
+++ b/hw/syn/tools/dc/parse-syn-report.py
@@ -5,14 +5,11 @@
 r"""Parses lint report and dump filtered messages in hjson format.
 """
 import argparse
-import datetime
 import re
 import sys
 from pathlib import Path
 
 import hjson
-import mistletoe
-import numpy as np
 
 # this allows both scientific and fixed point numbers
 FP_NUMBER = r"[-+]?\d+\.\d+[Ee]?[-+]?\d*"
@@ -56,7 +53,7 @@
                     ]
         else:
             results["messages"]["flow_errors"] += [
-                "Pattern %s not found" % pattern
+                "Pattern '%s' of key '%s' not found" % (pattern, key)
             ]
 
     return results
@@ -89,7 +86,10 @@
     """
     Calculate relative error with respect to reference
     """
-    return abs(val - ref) / ref
+    if ref == 0.0:
+        return float("nan")
+    else:
+        return abs(val - ref) / ref
 
 
 def _extract_area(full_file, results, key):
@@ -118,16 +118,17 @@
     try:
         for item in matches:
             if item[0] not in results[key]["instances"]:
-                results[key]["instances"].update(
-                    {item[0]: {
-                         "comb": 0.0,
-                         "reg": 0.0,
-                         "buf": np.nan, # currently not available
-                         "macro": 0.0,
-                         "total": 0.0,
-                     }})
-            results[key]["instances"][item[0]]["comb"]  += float(item[3])
-            results[key]["instances"][item[0]]["reg"]   += float(item[4])
+                results[key]["instances"].update({
+                    item[0]: {
+                        "comb": 0.0,
+                        "reg": 0.0,
+                        "buf": float("nan"),  # not available here
+                        "macro": 0.0,
+                        "total": 0.0,
+                    }
+                })
+            results[key]["instances"][item[0]]["comb"] += float(item[3])
+            results[key]["instances"][item[0]]["reg"] += float(item[4])
             results[key]["instances"][item[0]]["macro"] += float(item[5])
             results[key]["instances"][item[0]]["total"] += float(item[3]) + \
                                                            float(item[4]) + \
@@ -167,7 +168,7 @@
                         full_file,
                         flags=re.MULTILINE)
     try:
-        # get TNS and WNS in that group
+        # get clock period
         for k, c in enumerate(clocks):
             if c[0].strip() not in results[key]:
                 results[key].update({
@@ -202,7 +203,7 @@
                     {g.strip(): {
                          "tns": 0.0,
                          "wns": 0.0,
-                         "period": np.nan
+                         "period": float("nan")
                      }})
             value = float(slack[k]) if float(slack[k]) < 0.0 else 0.0
             results[key][g]["wns"] = min(results[key][g]["wns"], value)
@@ -283,11 +284,11 @@
 
     # extract first 3 columns on that line
     patterns = [("net", r"^" + results["top"] + r"\s*(" + FP_NUMBER + r")\s*" +
-                 FP_NUMBER + r" \s*" + FP_NUMBER),
-                ("int", r"^" + results["top"] + r"\s* " + FP_NUMBER +
-                 r" \s*(" + FP_NUMBER + r")\s* " + FP_NUMBER),
-                ("leak", r"^" + results["top"] + r"\s* " + FP_NUMBER +
-                 r" \s* " + FP_NUMBER + r" \s*(" + FP_NUMBER + ")")]
+                 FP_NUMBER + r"\s*" + FP_NUMBER),
+                ("int", r"^" + results["top"] + r"\s*" + FP_NUMBER + r"\s*(" +
+                 FP_NUMBER + r")\s*" + FP_NUMBER),
+                ("leak", r"^" + results["top"] + r"\s*" + FP_NUMBER + r" \s*" +
+                 FP_NUMBER + r"\s*(" + FP_NUMBER + r")")]
 
     results = _match_fp_number(full_file, key, patterns, results)
 
@@ -332,59 +333,58 @@
         },
         "area": {
             # gate equivalent of a NAND2 gate
-            "ge": np.nan,
+            "ge": float("nan"),
             # summary, in GE
-            "comb": np.nan,
-            "buf": np.nan,
-            "reg": np.nan,
-            "macro": np.nan,
-            "total": np.nan,
+            "comb": float("nan"),
+            "buf": float("nan"),
+            "reg": float("nan"),
+            "macro": float("nan"),
+            "total": float("nan"),
             # hierchical report with "comb", "buf", "reg", "macro", "total"
             "instances": {},
         },
         "power": {
-            "net": np.nan,
-            "int": np.nan,
-            "leak": np.nan,
+            "net": float("nan"),
+            "int": float("nan"),
+            "leak": float("nan"),
         },
         "units": {
-            "voltage": np.nan,
-            "capacitance": np.nan,
-            "time": np.nan,
-            "dynamic": np.nan,
-            "static": np.nan,
+            "voltage": float("nan"),
+            "capacitance": float("nan"),
+            "time": float("nan"),
+            "dynamic": float("nan"),
+            "static": float("nan"),
         }
     }
 
     results["top"] = dut
 
     # flow messages
-    results = _parse_file(logpath, 'synthesis.log',
-                          results, _extract_messages, "flow")
+    results = _parse_file(logpath, 'synthesis.log', results, _extract_messages,
+                          "flow")
 
     # messages
     for rep_type in ["analyze", "elab", "compile"]:
-        results = _parse_file(reppath, '%s.rpt' % rep_type,
-                              results, _extract_messages, rep_type)
+        results = _parse_file(reppath, '%s.rpt' % rep_type, results,
+                              _extract_messages, rep_type)
 
     # get gate equivalents
-    results = _parse_file(reppath, 'gate_equiv.rpt',
-                          results, _extract_gate_equiv, "area")
+    results = _parse_file(reppath, 'gate_equiv.rpt', results,
+                          _extract_gate_equiv, "area")
     # area
-    results = _parse_file(reppath, 'area.rpt',
-                          results, _extract_area, "area")
+    results = _parse_file(reppath, 'area.rpt', results, _extract_area, "area")
     # clocks. this complements the timing report later below
-    results = _parse_file(reppath, 'clocks.rpt',
-                          results, _extract_clocks, "timing")
+    results = _parse_file(reppath, 'clocks.rpt', results, _extract_clocks,
+                          "timing")
     # timing
-    results = _parse_file(reppath, 'timing.rpt',
-                          results, _extract_timing, "timing")
+    results = _parse_file(reppath, 'timing.rpt', results, _extract_timing,
+                          "timing")
     # power
-    results = _parse_file(reppath, 'power.rpt',
-                          results, _extract_power, "power")
+    results = _parse_file(reppath, 'power.rpt', results, _extract_power,
+                          "power")
     # units
-    results = _parse_file(reppath, 'power.rpt',
-                          results, _extract_units, "units")
+    results = _parse_file(reppath, 'power.rpt', results, _extract_units,
+                          "units")
 
     return results
 
@@ -468,20 +468,18 @@
         type=str,
         help="""Name of the DUT. This is needed to parse the reports.""")
 
-    parser.add_argument(
-        '--logpath',
-        type=str,
-        help="""Path to log files for the flow.
+    parser.add_argument('--logpath',
+                        type=str,
+                        help="""Path to log files for the flow.
                 This script expects the following log files to be present:
 
                             - <logpath>/synthesis.log : output of synopsys shell
 
                         """)
 
-    parser.add_argument(
-        '--reppath',
-        type=str,
-        help="""Path to report files of the flow.
+    parser.add_argument('--reppath',
+                        type=str,
+                        help="""Path to report files of the flow.
                 This script expects the following report files to be present:
 
                             - <reppath>/analyze.rpt : output of analyze command
@@ -493,7 +491,6 @@
 
                         """)
 
-
     parser.add_argument('--outdir',
                         type=str,
                         default="./",
diff --git a/hw/syn/tools/dc/run-syn.tcl b/hw/syn/tools/dc/run-syn.tcl
index ee77e3a..ff75db8 100644
--- a/hw/syn/tools/dc/run-syn.tcl
+++ b/hw/syn/tools/dc/run-syn.tcl
@@ -53,6 +53,7 @@
 analyze -vcs "-sverilog +define+${DEFINE} -f ${SV_FLIST}" > "${REPDIR}/analyze.rpt"
 elaborate  ${DUT} -parameters ${PARAMS}                   > "${REPDIR}/elab.rpt"
 link                                                      > "${REPDIR}/link.rpt"
+check_design                                              > "${REPDIR}/check.rpt"
 
 write_file -format ddc -hierarchy -output "${DDCDIR}/elab.ddc"
 write_file -format verilog -hierarchy -output "${DDCDIR}/elab.v"