[reggen] Rewrite param value from the script

Now reggen.validate.validate function accepts positional argument, which
overwrites the default value of `param` in `param_list`.
This can let the tool creates multiple RTLs from a single hjson.

To do that, regtool.py also has `param` argument now. The format is
--param ParamA:ValueA ParamB:ValueB. You need to add the param argument
at the end of the script (after input path).

This is related to #30 #47
diff --git a/util/reggen/validate.py b/util/reggen/validate.py
index 5923608..db03afe 100644
--- a/util/reggen/validate.py
+++ b/util/reggen/validate.py
@@ -168,6 +168,17 @@
     return error
 
 
+def search_param(obj, key):
+    """return the param object if found, else return non zero error
+    """
+    for p in obj:
+        if p["name"] == key:
+            return p, 0
+
+    log.error("Param {} cannot be found".format(key))
+    return None, 1
+
+
 def check_keys(obj, required_keys, optional_keys, added_keys, err_prefix):
     error = 0
     for x in required_keys:
@@ -293,6 +304,7 @@
     'alert_list': ['ln', "list of peripheral alerts"],
     'regwidth': ['d', "width of registers in bits (default 32)"],
     'param_list': ['lp', "list of parameters of the IP"],
+    'scan': ['pb', 'Indicates the module have `scanmode_i`'],
     'SPDX-License-Identifier': ['s', "License ientifier (if using pure json) "\
                                 "Only use this if unable to put this "\
                                 "information in a comment at the top of the "\
@@ -1005,8 +1017,10 @@
     # associated with the index
     if len(rlist) == 1:
         if regwen_incr:
-            error +=1
-            log.error("%s multireg has only 1 register entry with regwen_incr set to true" % mrname)
+            error += 1
+            log.error(
+                "%s multireg has only 1 register entry with regwen_incr set to true"
+                % mrname)
         # TODO really should make the following a function that reverses the last node inserted
         # may have more properties than just genrnames in the future
         rlist[0]['name'] = mrname
@@ -1179,11 +1193,14 @@
 
     return error, nextoff
 
+
 """ Check that terms specified for regwen exist
 
 Regwen can be individual registers or fields within a register.  The function
 below checks for both and additional regwen properties.
 """
+
+
 def check_wen_regs(regs):
     error = 0
     idx = 0
@@ -1231,7 +1248,12 @@
     return error
 
 
-def validate(regs):
+def validate(regs, **kwargs):
+    if "params" in kwargs:
+        params = kwargs["params"]
+    else:
+        params = []
+
     if not 'name' in regs:
         log.error("Component has no name. Aborting.")
         return 1
@@ -1279,6 +1301,33 @@
         autoregs.extend(iregs)
         offset += addrsep * len(iregs)
 
+    # Change default param value if exists.
+    #   Assumed param list is already validated in above `check_keys` function
+    if "param_list" in regs and len(regs["param_list"]) != 0:
+        for p in params:
+            tokens = p.split('=')
+            if len(tokens) != 2:
+                error += 1
+                log.error("Parameter format isn't correct. {}".format(p))
+            key, value = tokens[0], tokens[1]
+            param, err = search_param(regs["param_list"], key)
+            if err != 0:
+                error += err
+                continue
+
+            value, err = check_int(
+                value, component + " param[{}]".format(param["name"]))
+            if err != 0:
+                error += err
+                continue
+
+            param["default"] = value
+
+    if "scan" in regs:
+        scan, err = check_bool(regs["scan"], component + " scan")
+    else:
+        regs["scan"] = "false"
+
     for x in regs['registers']:
         ck_err = check_zero_one_key(x, list_optone, "At " + hex(offset))
         if ck_err != 0:
diff --git a/util/regtool.py b/util/regtool.py
index 34bc935..84ff743 100755
--- a/util/regtool.py
+++ b/util/regtool.py
@@ -37,56 +37,64 @@
         formatter_class=argparse.RawDescriptionHelpFormatter,
         usage=USAGE,
         description=DESC)
-    parser.add_argument(
-        'input',
-        nargs='?',
-        metavar='file',
-        type=argparse.FileType('r'),
-        default=sys.stdin,
-        help='input file in hjson type')
-    parser.add_argument(
-        '-d', action='store_true', help='Output register documentation (html)')
-    parser.add_argument(
-        '--cdefines',
-        '-D',
-        action='store_true',
-        help='Output C defines header')
-    parser.add_argument(
-        '--ctdefines',
-        '-T',
-        action='store_true',
-        help='Output C defines header (Titan style)')
-    parser.add_argument(
-        '--doc',
-        action='store_true',
-        help='Output source file documentation (gfm)')
-    parser.add_argument(
-        '-j', action='store_true', help='Output as formatted JSON')
+    parser.add_argument('input',
+                        nargs='?',
+                        metavar='file',
+                        type=argparse.FileType('r'),
+                        default=sys.stdin,
+                        help='input file in hjson type')
+    parser.add_argument('-d',
+                        action='store_true',
+                        help='Output register documentation (html)')
+    parser.add_argument('--cdefines',
+                        '-D',
+                        action='store_true',
+                        help='Output C defines header')
+    parser.add_argument('--ctdefines',
+                        '-T',
+                        action='store_true',
+                        help='Output C defines header (Titan style)')
+    parser.add_argument('--doc',
+                        action='store_true',
+                        help='Output source file documentation (gfm)')
+    parser.add_argument('-j',
+                        action='store_true',
+                        help='Output as formatted JSON')
     parser.add_argument('-c', action='store_true', help='Output as JSON')
-    parser.add_argument(
-        '-r', action='store_true', help='Output as SystemVerilog RTL')
-    parser.add_argument(
-        '-s', action='store_true', help='Output as UVM Register class')
+    parser.add_argument('-r',
+                        action='store_true',
+                        help='Output as SystemVerilog RTL')
+    parser.add_argument('-s',
+                        action='store_true',
+                        help='Output as UVM Register class')
     parser.add_argument('--outdir', '-t',
                         help='Target directory for generated RTL, '\
                              'tool uses ../rtl if blank.')
-    parser.add_argument(
-        '--outfile',
-        '-o',
-        type=argparse.FileType('w'),
-        default=sys.stdout,
-        help='Target filename for json, html, gfm.')
-    parser.add_argument(
-        '--verbose',
-        '-v',
-        action='store_true',
-        help='Verbose and run validate twice')
-    parser.add_argument(
-        '--version', '-V', action='store_true', help='Show version')
-    parser.add_argument(
-        '--novalidate',
-        action='store_true',
-        help='Skip validate, just output json')
+    parser.add_argument('--outfile',
+                        '-o',
+                        type=argparse.FileType('w'),
+                        default=sys.stdout,
+                        help='Target filename for json, html, gfm.')
+    parser.add_argument('--verbose',
+                        '-v',
+                        action='store_true',
+                        help='Verbose and run validate twice')
+    parser.add_argument('--param',
+                        '-p',
+                        type=str,
+                        help='''Change the Parameter values.
+                                Only integer value is supported.
+                                You can add multiple param arguments.
+
+                                  Format: ParamA=ValA;ParamB=ValB
+                                  ''')
+    parser.add_argument('--version',
+                        '-V',
+                        action='store_true',
+                        help='Show version')
+    parser.add_argument('--novalidate',
+                        action='store_true',
+                        help='Skip validate, just output json')
 
     args = parser.parse_args()
 
@@ -113,6 +121,8 @@
 
     infile = args.input
 
+    params = args.param.split(';')
+
     if format == 'rtl':
         if args.outdir:
             outdir = args.outdir
@@ -141,10 +151,9 @@
     with infile:
         try:
             srcfull = infile.read()
-            obj = hjson.loads(
-                srcfull,
-                use_decimal=True,
-                object_pairs_hook=validate.checking_dict)
+            obj = hjson.loads(srcfull,
+                              use_decimal=True,
+                              object_pairs_hook=validate.checking_dict)
         except ValueError:
             raise SystemExit(sys.exc_info()[1])
 
@@ -152,10 +161,10 @@
         with outfile:
             gen_json.gen_json(obj, outfile, format)
             outfile.write('\n')
-    elif (validate.validate(obj) == 0):
+    elif (validate.validate(obj, params=params) == 0):
         if (verbose):
             log.info("Second validate pass (should show added optional keys)")
-            validate.validate(obj)
+            validate.validate(obj, params=params)
 
         if format == 'rtl':
             gen_rtl.gen_rtl(obj, outdir)