From 3b44f380d89ffcf1d960d650de2babc9aaafbf23 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Mon, 8 Jan 2018 18:13:00 -0800 Subject: [PATCH] TLRegMapper: emit a JSON file describing the register fields --- build.sbt | 2 ++ src/main/scala/tilelink/RegisterRouter.scala | 35 +++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 2fbb499d..f3cb18fd 100644 --- a/build.sbt +++ b/build.sbt @@ -15,6 +15,7 @@ lazy val commonSettings = Seq( traceLevel := 15, scalacOptions ++= Seq("-deprecation","-unchecked"), libraryDependencies ++= Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value), + libraryDependencies ++= Seq("org.json4s" %% "json4s-jackson" % "3.5.0"), addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full) ) @@ -44,3 +45,4 @@ val chipSettings = Seq( s"make -C $makeDir -j $jobs $target".! } ) + diff --git a/src/main/scala/tilelink/RegisterRouter.scala b/src/main/scala/tilelink/RegisterRouter.scala index 44df9669..5fedd959 100644 --- a/src/main/scala/tilelink/RegisterRouter.scala +++ b/src/main/scala/tilelink/RegisterRouter.scala @@ -7,9 +7,12 @@ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.regmapper._ import freechips.rocketchip.interrupts._ -import freechips.rocketchip.util.HeterogeneousBag +import freechips.rocketchip.util.{HeterogeneousBag, ElaborationArtefacts} import scala.math.{min,max} +import org.json4s.JsonDSL._ +import org.json4s.jackson.JsonMethods.{pretty, render} + case class TLRegisterNode( address: Seq[AddressSet], device: Device, @@ -80,6 +83,36 @@ case class TLRegisterNode( bundleIn.b.valid := Bool(false) bundleIn.c.ready := Bool(true) bundleIn.e.ready := Bool(true) + + // Dump out the register map for documentation purposes. + val registerDescriptions = mapping.map { case (offset, seq) => + var currentBitOffset = 0 + s"regAt0x${offset.toHexString}" -> ( + ("description" -> "None Provided") ~ + ("addressOffset" -> s"0x${offset.toHexString}") ~ + ("fields" -> seq.zipWithIndex.map { case (f, i) => { + val tmp = (f.description.map{ _.displayName }.getOrElse(s"unnamedRegField${i}") -> ( + ("description" -> f.description.map{_.description}.getOrElse("No Description Provided")) ~ + ("bitOffset" -> currentBitOffset) ~ + ("bitWidth" -> f.width) ~ + ("resetMask" -> f.description.map { d => if (d.resetType != RegFieldResetType.N) "all" else "none"}.getOrElse("none")) ~ + ("resetValue" -> f.description.map { _.resetValue}.getOrElse(0)) ~ + ("headerName" -> f.description.map { _.headerName}.getOrElse("")))) + currentBitOffset = currentBitOffset + f.width + tmp + }}))} + + val simpleDev = device.asInstanceOf[SimpleDevice] + val base = s"0x${address.head.base.toInt.toHexString}" + val json = ("peripheral" -> ( + ("displayName" -> s"deviceAt${base}") ~ + ("description" -> s"None Provided") ~ + ("baseAddress" -> base) ~ + ("regWidth" -> beatBytes) ~ + ("access" -> "rw") ~ // specified at field level + ("registers" -> registerDescriptions) + )) + ElaborationArtefacts.add(s"${base}.regmap.json", pretty(render(json))) } }