regmapper: refactor how json is emitted
This commit is contained in:
parent
ea89259dd4
commit
59d5e61366
23
src/main/scala/regmapper/Annotation.scala
Normal file
23
src/main/scala/regmapper/Annotation.scala
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
package freechips.rocketchip.regmapper
|
||||||
|
|
||||||
|
import org.json4s.JsonDSL._
|
||||||
|
import org.json4s.jackson.JsonMethods.{pretty, render}
|
||||||
|
|
||||||
|
object RegMappingAnnotation {
|
||||||
|
def serialize(base: BigInt, name: String, mapping: RegField.Map*): String = {
|
||||||
|
val regDescs = mapping.flatMap { case (byte, seq) =>
|
||||||
|
seq.map(_.width).scanLeft(0)(_ + _).zip(seq).map { case (bit, f) =>
|
||||||
|
val anonName = s"unnamedRegField${byte.toHexString}_${bit}"
|
||||||
|
(f.desc.map{ _.name}.getOrElse(anonName)) -> f.toJson(byte, bit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pretty(render(
|
||||||
|
("peripheral" -> (
|
||||||
|
("displayName" -> name) ~
|
||||||
|
("baseAddress" -> s"0x${base.toInt.toHexString}") ~
|
||||||
|
("regfields" -> regDescs)))))
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,10 @@ package freechips.rocketchip.regmapper
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import chisel3.util.{ReadyValidIO}
|
import chisel3.util.{ReadyValidIO}
|
||||||
|
|
||||||
|
import org.json4s.JsonDSL._
|
||||||
|
import org.json4s.JsonAST.JValue
|
||||||
|
import org.json4s.jackson.JsonMethods.{pretty, render}
|
||||||
|
|
||||||
import freechips.rocketchip.util.{SimpleRegIO}
|
import freechips.rocketchip.util.{SimpleRegIO}
|
||||||
|
|
||||||
// This information is not used internally by the regmap(...) function.
|
// This information is not used internally by the regmap(...) function.
|
||||||
@ -136,8 +140,29 @@ object RegWriteFn
|
|||||||
case class RegField(width: Int, read: RegReadFn, write: RegWriteFn, desc: Option[RegFieldDesc])
|
case class RegField(width: Int, read: RegReadFn, write: RegWriteFn, desc: Option[RegFieldDesc])
|
||||||
{
|
{
|
||||||
require (width > 0, s"RegField width must be > 0, not $width")
|
require (width > 0, s"RegField width must be > 0, not $width")
|
||||||
|
|
||||||
def pipelined = !read.combinational || !write.combinational
|
def pipelined = !read.combinational || !write.combinational
|
||||||
|
|
||||||
def readOnly = this.copy(write = (), desc = this.desc.map(_.copy(access = RegFieldAccessType.R)))
|
def readOnly = this.copy(write = (), desc = this.desc.map(_.copy(access = RegFieldAccessType.R)))
|
||||||
|
|
||||||
|
def toJson(byteOffset: Int, bitOffset: Int): JValue = {
|
||||||
|
( ("byteOffset" -> s"0x${byteOffset.toHexString}") ~
|
||||||
|
("bitOffset" -> bitOffset) ~
|
||||||
|
("bitWidth" -> width) ~
|
||||||
|
("name" -> desc.map(_.name)) ~
|
||||||
|
("description" -> desc.map{ d=> if (d.desc == "") None else Some(d.desc)}) ~
|
||||||
|
("resetValue" -> desc.map{_.reset}) ~
|
||||||
|
("group" -> desc.map{_.group}) ~
|
||||||
|
("groupDesc" -> desc.map{_.groupDesc}) ~
|
||||||
|
("accessType" -> desc.map {d => d.access.toString}) ~
|
||||||
|
("writeType" -> desc.map {d => d.wrType.map(_.toString)}) ~
|
||||||
|
("readAction" -> desc.map {d => d.rdAction.map(_.toString)}) ~
|
||||||
|
("volatile" -> desc.map {d => if (d.volatile) Some(true) else None}) ~
|
||||||
|
("enumerations" -> desc.map {d =>
|
||||||
|
Option(d.enumerations.map { case (key, (name, edesc)) =>
|
||||||
|
(("value" -> key) ~ ("name" -> name) ~ ("description" -> edesc))
|
||||||
|
}).filter(_.nonEmpty)}) )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object RegField
|
object RegField
|
||||||
|
@ -10,9 +10,6 @@ import freechips.rocketchip.interrupts._
|
|||||||
import freechips.rocketchip.util.{HeterogeneousBag, ElaborationArtefacts}
|
import freechips.rocketchip.util.{HeterogeneousBag, ElaborationArtefacts}
|
||||||
import scala.math.{min,max}
|
import scala.math.{min,max}
|
||||||
|
|
||||||
import org.json4s.JsonDSL._
|
|
||||||
import org.json4s.jackson.JsonMethods.{pretty, render}
|
|
||||||
|
|
||||||
case class TLRegisterNode(
|
case class TLRegisterNode(
|
||||||
address: Seq[AddressSet],
|
address: Seq[AddressSet],
|
||||||
device: Device,
|
device: Device,
|
||||||
@ -85,47 +82,15 @@ case class TLRegisterNode(
|
|||||||
bundleIn.e.ready := Bool(true)
|
bundleIn.e.ready := Bool(true)
|
||||||
|
|
||||||
// Dump out the register map for documentation purposes.
|
// Dump out the register map for documentation purposes.
|
||||||
val regDescs = mapping.flatMap { case (offset, seq) =>
|
val base = address.head.base
|
||||||
var currentBitOffset = 0
|
val baseHex = s"0x${base.toInt.toHexString}"
|
||||||
seq.zipWithIndex.map { case (f, i) => {
|
val name = s"deviceAt${baseHex}" //TODO: It would be better to name this other than "Device at ...."
|
||||||
val tmp = (f.desc.map{ _.name}.getOrElse(s"unnamedRegField${offset.toHexString}_${currentBitOffset}") -> (
|
val json = RegMappingAnnotation.serialize(base, name, mapping:_*)
|
||||||
("byteOffset" -> s"0x${offset.toHexString}") ~
|
|
||||||
("bitOffset" -> currentBitOffset) ~
|
|
||||||
("bitWidth" -> f.width) ~
|
|
||||||
("name" -> f.desc.map(_.name)) ~
|
|
||||||
("description" -> f.desc.map{d => if (d.desc == "") None else Some(d.desc)}) ~
|
|
||||||
("resetValue" -> f.desc.map{_.reset}) ~
|
|
||||||
("group" -> f.desc.map{_.group}) ~
|
|
||||||
("groupDesc" -> f.desc.map{_.groupDesc}) ~
|
|
||||||
("accessType" -> f.desc.map {d => d.access.toString}) ~
|
|
||||||
("writeType" -> f.desc.map {d => d.wrType.map(_.toString)}) ~
|
|
||||||
("readAction" -> f.desc.map {d => d.rdAction.map(_.toString)}) ~
|
|
||||||
("volatile" -> f.desc.map {d => if (d.volatile) Some(true) else None}) ~
|
|
||||||
("enumerations" -> f.desc.map {d =>
|
|
||||||
Option(d.enumerations.map { case (key, (name, desc)) =>
|
|
||||||
(("value" -> key) ~
|
|
||||||
("name" -> name) ~
|
|
||||||
("description" -> desc))
|
|
||||||
}).filter(_.nonEmpty)})
|
|
||||||
))
|
|
||||||
currentBitOffset = currentBitOffset + f.width
|
|
||||||
tmp
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: It would be better to name this other than "Device at ...."
|
|
||||||
val base = s"0x${address.head.base.toInt.toHexString}"
|
|
||||||
val json = ("peripheral" -> (
|
|
||||||
("displayName" -> s"deviceAt${base}") ~
|
|
||||||
("baseAddress" -> base) ~
|
|
||||||
("regfields" -> regDescs)
|
|
||||||
))
|
|
||||||
|
|
||||||
var suffix = 0
|
var suffix = 0
|
||||||
while( ElaborationArtefacts.contains(s"${base}.${suffix}.regmap.json")){
|
while( ElaborationArtefacts.contains(s"${baseHex}.${suffix}.regmap.json")){
|
||||||
suffix = suffix + 1
|
suffix = suffix + 1
|
||||||
}
|
}
|
||||||
ElaborationArtefacts.add(s"${base}.${suffix}.regmap.json", pretty(render(json)))
|
ElaborationArtefacts.add(s"${baseHex}.${suffix}.regmap.json", json)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user