Generate a C header of Parameters.scala

- Reflect out all Int type parameters, and generate a header file. The
  fields are named KP_originalScalaName.

Change-Id: I2915aa9971fc7741aa0bbf423c6d2138fd61087f
diff --git a/hdl/chisel/src/kelvin/BUILD b/hdl/chisel/src/kelvin/BUILD
index 516690a..9873eed 100644
--- a/hdl/chisel/src/kelvin/BUILD
+++ b/hdl/chisel/src/kelvin/BUILD
@@ -12,8 +12,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-load("@kelvin_hw//rules:chisel.bzl", "chisel_cc_library", "chisel_library",
-     "chisel_test")
+load("@kelvin_hw//rules:chisel.bzl",
+    "chisel_binary",
+    "chisel_cc_library",
+    "chisel_library",
+    "chisel_test")
 
 package(default_visibility = ["//visibility:public"])
 
@@ -220,3 +223,21 @@
     emit_class = "kelvin.EmitVSt",
     module_name = "VSt",
 )
+
+chisel_binary(
+    name = "emit_parameters_header",
+    deps = [
+        ":kelvin",
+    ],
+    main_class = "kelvin.EmitParametersHeader",
+)
+
+genrule(
+    name = "parameters_header",
+    outs = [
+        "kelvin_parameters.h",
+    ],
+    tools = [":emit_parameters_header"],
+    cmd = "$(location :emit_parameters_header) > $(location kelvin_parameters.h)",
+    visibility = ["//visibility:public"],
+)
diff --git a/hdl/chisel/src/kelvin/Parameters.scala b/hdl/chisel/src/kelvin/Parameters.scala
index 35b4929..0080486 100644
--- a/hdl/chisel/src/kelvin/Parameters.scala
+++ b/hdl/chisel/src/kelvin/Parameters.scala
@@ -52,7 +52,7 @@
   // Machine.
   val programCounterBits = 32
   val instructionBits = 32
-  val instructionLanes = 4
+  val instructionLanes = 8
 
   val vectorCountBits = log2Ceil(vectorBits / 8) + 1 + 2  // +2 stripmine
 
@@ -98,3 +98,33 @@
   val axi2AddrBits = 32
   val axi2DataBits = vectorBits
 }
+
+import scala.reflect.runtime.{universe => ru}
+object EmitParametersHeader extends App {
+  val p = new Parameters
+  val mirror = ru.runtimeMirror(ru.getClass.getClassLoader)
+  val instanceMirror = mirror.reflect(p)
+  val symbol = instanceMirror.symbol
+  val typeSym = symbol.toType
+  val fields = typeSym.decls.collect {
+    case t: (ru.TermSymbol @unchecked) if t.isVal || t.isVar => t
+  }
+
+  println("#ifndef KELVIN_PARAMETERS_H_")
+  println("#define KELVIN_PARAMETERS_H_")
+  fields.foreach { x =>
+    val fieldMirror = instanceMirror.reflectField(x.asTerm)
+    val fieldType = x.asTerm.typeSignature
+    val value = fieldMirror.get
+    val ctype = fieldType match {
+      case t if t =:= ru.typeOf[Int] => Some("int")
+      case _ => None
+    }
+    if (ctype != None) {
+      val ctypeStr = ctype.get
+      println(s"#define KP_${x.name} ${value}")
+      // println(s"${ctypeStr} KP_${x.name} = ${value};")
+    }
+  }
+  println("#endif")
+}
diff --git a/tests/verilator_sim/BUILD b/tests/verilator_sim/BUILD
index 10c126e..65963de 100644
--- a/tests/verilator_sim/BUILD
+++ b/tests/verilator_sim/BUILD
@@ -34,6 +34,7 @@
         "kelvin/debug_if.h",
         "kelvin/kelvin_cfg.h",
         "kelvin/memory_if.h",
+        "@kelvin_hw//hdl/chisel/src/kelvin:kelvin_parameters.h",
     ],
     defines = ["KELVIN_SIMD=256"],
 )