148 lines
5.8 KiB
Scala
148 lines
5.8 KiB
Scala
package mdf.macrolib
|
|
|
|
import play.api.libs.json._
|
|
import scala.collection.mutable.ListBuffer
|
|
import scala.language.implicitConversions
|
|
|
|
sealed abstract class PortType { def toJSON(): JsString = JsString(toString) }
|
|
case object Digital extends PortType { override def toString: String = "digital" }
|
|
case object Analog extends PortType { override def toString: String = "analog" }
|
|
case object Power extends PortType { override def toString: String = "power" }
|
|
case object Ground extends PortType { override def toString: String = "ground" }
|
|
case object NoConnect extends PortType { override def toString: String = "NC" }
|
|
|
|
sealed abstract class Direction { def toJSON(): JsString = JsString(toString) }
|
|
case object Input extends Direction { override def toString: String = "input" }
|
|
case object Output extends Direction { override def toString: String = "output" }
|
|
case object InOut extends Direction { override def toString: String = "inout" }
|
|
|
|
sealed abstract class Termination { def toJSON(): JsValue }
|
|
case object CMOS extends Termination { override def toJSON(): JsString = JsString("CMOS") }
|
|
case class Resistive(ohms: Int) extends Termination { override def toJSON(): JsNumber = JsNumber(ohms) }
|
|
|
|
sealed abstract class TerminationType { def toJSON(): JsString }
|
|
case object Single extends TerminationType { override def toJSON(): JsString = JsString("single") }
|
|
case object Differential extends TerminationType { override def toJSON(): JsString = JsString("differential") }
|
|
|
|
// IO macro
|
|
case class IOMacro(
|
|
name: String,
|
|
tpe: PortType,
|
|
direction: Option[Direction] = None,
|
|
termination: Option[Termination] = None,
|
|
terminationType: Option[TerminationType] = None,
|
|
terminationReference: Option[String] = None,
|
|
matching: Seq[String] = Seq.empty[String],
|
|
bbname: Option[String] = None)
|
|
extends Macro {
|
|
override def toJSON(): JsObject = {
|
|
|
|
val output = new ListBuffer[(String, JsValue)]()
|
|
output.appendAll(
|
|
Seq(
|
|
"name" -> Json.toJson(name),
|
|
"type" -> tpe.toJSON()
|
|
)
|
|
)
|
|
if (direction.isDefined) output.append("direction" -> direction.get.toJSON)
|
|
if (termination.isDefined) output.append("termination" -> termination.get.toJSON)
|
|
if (terminationType.isDefined) output.append("terminationType" -> terminationType.get.toJSON)
|
|
if (terminationReference.isDefined) output.append("terminationReference" -> JsString(terminationReference.get))
|
|
if (matching.nonEmpty) output.append("match" -> JsArray(matching.map(JsString)))
|
|
if (bbname.nonEmpty) output.append("blackBox" -> JsString(bbname.get))
|
|
|
|
JsObject(output)
|
|
}
|
|
|
|
override def typeStr = "iomacro"
|
|
}
|
|
object IOMacro {
|
|
def parseJSON(json: Map[String, JsValue]): Option[IOMacro] = {
|
|
val name: String = json.get("name") match {
|
|
case Some(x: JsString) => x.as[String]
|
|
case _ => return None
|
|
}
|
|
val tpe: PortType = json.get("type") match {
|
|
case Some(JsString("power")) => Power
|
|
case Some(JsString("ground")) => Ground
|
|
case Some(JsString("digital")) => Digital
|
|
case Some(JsString("analog")) => Analog
|
|
case Some(JsString("NC")) => NoConnect
|
|
case _ => return None
|
|
}
|
|
val direction: Option[Direction] = json.get("direction") match {
|
|
case Some(JsString("input")) => Some(Input)
|
|
case Some(JsString("output")) => Some(Output)
|
|
case Some(JsString("inout")) => Some(InOut)
|
|
case _ => None
|
|
}
|
|
val termination: Option[Termination] = json.get("termination") match {
|
|
case Some(JsNumber(x)) => Some(Resistive(x.toInt))
|
|
case Some(JsString("CMOS")) => Some(CMOS)
|
|
case _ => None
|
|
}
|
|
val terminationType: Option[TerminationType] = json.get("terminationType") match {
|
|
case Some(JsString("differential")) => Some(Differential)
|
|
case Some(JsString("single")) => Some(Single)
|
|
case _ => None
|
|
}
|
|
val terminationRef: Option[String] = json.get("terminationReference") match {
|
|
case Some(JsString(x)) => Some(x)
|
|
case _ if terminationType.isDefined => return None
|
|
case _ => None
|
|
}
|
|
val matching: Seq[String] = json.get("match") match {
|
|
case Some(JsArray(array)) => array.map(_.as[JsString].value).toList
|
|
case _ => Seq.empty[String]
|
|
}
|
|
val bbname: Option[String] = json.get("blackBox") match {
|
|
case Some(JsString(module)) => Some(module)
|
|
case Some(_) => return None
|
|
case _ => None
|
|
}
|
|
Some(IOMacro(name, tpe, direction, termination, terminationType, terminationRef, matching, bbname))
|
|
}
|
|
}
|
|
|
|
case class IOProperties(name: String, top: String, ios: Seq[IOMacro]) extends Macro {
|
|
override def toJSON(): JsObject = {
|
|
val output = new ListBuffer[(String, JsValue)]()
|
|
output.appendAll(
|
|
Seq(
|
|
"name" -> Json.toJson(name),
|
|
"top" -> Json.toJson(top),
|
|
"type" -> Json.toJson(typeStr),
|
|
"ios" -> JsArray(ios.map(_.toJSON))
|
|
)
|
|
)
|
|
JsObject(output)
|
|
}
|
|
|
|
override def typeStr = "io_properties"
|
|
|
|
}
|
|
|
|
object IOProperties {
|
|
def parseJSON(json: Map[String, JsValue]): Option[IOProperties] = {
|
|
val name: String = json.get("name") match {
|
|
case Some(x: JsString) => x.as[String]
|
|
case _ => return None
|
|
}
|
|
val top: String = json.get("top") match {
|
|
case Some(x: JsString) => x.as[String]
|
|
case _ => return None
|
|
}
|
|
val ios: Seq[IOMacro] = json.get("ios") match {
|
|
case Some(x: JsArray) =>
|
|
x.as[List[Map[String, JsValue]]].map { a =>
|
|
val b = IOMacro.parseJSON(a);
|
|
if (b == None) {
|
|
return None
|
|
} else b.get
|
|
}
|
|
case _ => List()
|
|
}
|
|
Some(IOProperties(name, top, ios))
|
|
}
|
|
}
|