Port to MDF library and start re-developing tests

This commit is contained in:
Edward Wang
2017-07-19 19:18:42 -07:00
committed by edwardcwang
parent 57b0fec78e
commit c79ea47909
12 changed files with 1640 additions and 1469 deletions

View File

@@ -6,133 +6,70 @@ import firrtl._
import firrtl.ir._
import firrtl.PrimOps
import firrtl.Utils.{ceilLog2, BoolType}
import scala.util.parsing.json.JSON // Todo: this will be gone
import mdf.macrolib.{Constant, MacroPort, SRAMMacro}
import mdf.macrolib.{PolarizedPort, PortPolarity, ActiveLow, ActiveHigh, NegativeEdge, PositiveEdge}
import java.io.File
import scala.language.implicitConversions
trait PortPolarity
case object ActiveLow extends PortPolarity
case object ActiveHigh extends PortPolarity
case object NegativeEdge extends PortPolarity
case object PositiveEdge extends PortPolarity
object PortPolarity {
implicit def toPortPolarity(s: Any): PortPolarity =
s match {
case "active low" => ActiveLow
case "active high" => ActiveHigh
case "negative edge" => NegativeEdge
case "positive edge" => PositiveEdge
case _ => throw new firrtl.passes.PassException(s"Wrong port polarity: ${s.toString}")
}
implicit def toPortPolarity(s: Option[Any]): Option[PortPolarity] =
s map toPortPolarity
}
class FirrtlMacroPort(port: MacroPort) {
val src = port
case class MacroPort(
clockName: String,
clockPolarity: Option[PortPolarity],
addressName: String,
addressPolarity: Option[PortPolarity],
inputName: Option[String],
inputPolarity: Option[PortPolarity],
outputName: Option[String],
outputPolarity: Option[PortPolarity],
chipEnableName: Option[String],
chipEnablePolarity: Option[PortPolarity],
readEnableName: Option[String],
readEnablePolarity: Option[PortPolarity],
writeEnableName: Option[String],
writeEnablePolarity: Option[PortPolarity],
maskName: Option[String],
maskPolarity: Option[PortPolarity],
maskGran: Option[BigInt],
width: BigInt,
depth: BigInt) {
val effectiveMaskGran = maskGran.getOrElse(width)
val addrType = UIntType(IntWidth(ceilLog2(depth) max 1))
val dataType = UIntType(IntWidth(width))
val maskType = UIntType(IntWidth(width / effectiveMaskGran))
val isReader = !port.readEnable.isEmpty && port.writeEnable.isEmpty
val isWriter = !port.writeEnable.isEmpty && port.readEnable.isEmpty
val isReadWriter = !port.writeEnable.isEmpty && !port.readEnable.isEmpty
val AddrType = UIntType(IntWidth(ceilLog2(port.depth) max 1))
val DataType = UIntType(IntWidth(port.width))
val MaskType = UIntType(IntWidth(port.width / port.effectiveMaskGran))
// Bundle representing this macro port.
val tpe = BundleType(Seq(
Field(clockName, Flip, ClockType),
Field(addressName, Flip, addrType)) ++
(inputName map (Field(_, Flip, dataType))) ++
(outputName map (Field(_, Default, dataType))) ++
(chipEnableName map (Field(_, Flip, BoolType))) ++
(readEnableName map (Field(_, Flip, BoolType))) ++
(writeEnableName map (Field(_, Flip, BoolType))) ++
(maskName map (Field(_, Flip, maskType)))
Field(port.clock.name, Flip, ClockType),
Field(port.address.name, Flip, AddrType)) ++
(port.input map (p => Field(p.name, Flip, DataType))) ++
(port.output map (p => Field(p.name, Default, DataType))) ++
(port.chipEnable map (p => Field(p.name, Flip, BoolType))) ++
(port.readEnable map (p => Field(p.name, Flip, BoolType))) ++
(port.writeEnable map (p => Field(p.name, Flip, BoolType))) ++
(port.maskPort map (p => Field(p.name, Flip, MaskType)))
)
val ports = tpe.fields map (f => Port(
NoInfo, f.name, f.flip match { case Default => Output case Flip => Input }, f.tpe))
}
class Macro(lib: Map[String, Any]) {
val name = lib("name").asInstanceOf[String]
val width = BigInt(lib("width").asInstanceOf[Double].toLong)
val depth = BigInt(lib("depth").asInstanceOf[Double].toLong)
val ports = lib("ports").asInstanceOf[List[_]] map { x =>
val map = x.asInstanceOf[Map[String, Any]]
MacroPort(
map("clock port name").asInstanceOf[String],
map get "clock port polarity",
map("address port name").asInstanceOf[String],
map get "address port polarity",
map get "input port name" map (_.asInstanceOf[String]),
map get "input port polarity",
map get "output port name" map (_.asInstanceOf[String]),
map get "output port polarity",
map get "chip enable port name" map (_.asInstanceOf[String]),
map get "chip enable port polarity",
map get "read enable port name" map (_.asInstanceOf[String]),
map get "read enable port polarity",
map get "write enable port name" map (_.asInstanceOf[String]),
map get "write enable port polarity",
map get "mask port name" map (_.asInstanceOf[String]),
map get "mask port polarity",
map get "mask granularity" map (x => BigInt(x.asInstanceOf[Double].toLong)),
width,
depth
)
}
val writers = ports filter (p => p.inputName.isDefined && !p.outputName.isDefined)
val readers = ports filter (p => !p.inputName.isDefined && p.outputName.isDefined)
val readwriters = ports filter (p => p.inputName.isDefined && p.outputName.isDefined)
// Reads an SRAMMacro and generates firrtl blackboxes.
class Macro(srcMacro: SRAMMacro) {
val src = srcMacro
val firrtlPorts = srcMacro.ports map { new FirrtlMacroPort(_) }
val writers = firrtlPorts filter (p => p.isReader)
val readers = firrtlPorts filter (p => p.isWriter)
val readwriters = firrtlPorts filter (p => p.isReadWriter)
val sortedPorts = writers ++ readers ++ readwriters
val extraPorts = lib get "extra ports" match {
case None => Nil
case Some(p) => p.asInstanceOf[List[_]] map { x =>
val map = x.asInstanceOf[Map[String, Any]]
assert(map("type").asInstanceOf[String] == "constant") // TODO: release it?
val name = map("name").asInstanceOf[String]
val width = BigInt(map("width").asInstanceOf[Double].toLong)
val value = BigInt(map("value").asInstanceOf[Double].toLong)
(name -> UIntLiteral(value, IntWidth(width)))
}
val extraPorts = srcMacro.extraPorts map { p =>
assert(p.portType == Constant) // TODO: release it?
val name = p.name
val width = BigInt(p.width.asInstanceOf[Double].toLong)
val value = BigInt(p.value.asInstanceOf[Double].toLong)
(name -> UIntLiteral(value, IntWidth(width)))
}
val tpe = BundleType(ports flatMap (_.tpe.fields))
private val modPorts = (ports flatMap (_.ports)) ++
// Bundle representing this memory blackbox
val tpe = BundleType(firrtlPorts flatMap (_.tpe.fields))
private val modPorts = (firrtlPorts flatMap (_.ports)) ++
(extraPorts map { case (name, value) => Port(NoInfo, name, Input, value.tpe) })
val blackbox = ExtModule(NoInfo, name, modPorts, name, Nil)
def module(body: Statement) = Module(NoInfo, name, modPorts, body)
val blackbox = ExtModule(NoInfo, srcMacro.name, modPorts, srcMacro.name, Nil)
def module(body: Statement) = Module(NoInfo, srcMacro.name, modPorts, body)
}
object Utils {
def readJSON(file: Option[File]): Option[Seq[Map[String, Any]]] = file match {
case None => None
case Some(f) => try {
(JSON parseFull io.Source.fromFile(f).mkString) match {
case Some(p: List[Any]) => Some(
(p foldLeft Seq[Map[String, Any]]()){
case (res, x: Map[_, _]) =>
val map = x.asInstanceOf[Map[String, Any]]
if (map("type").asInstanceOf[String] == "sram") res :+ map else res
case (res, _) => res
}
)
case _ => Some(Nil)
}
} catch {
case _: Throwable => Some(Nil)
def filterForSRAM(s: Option[Seq[mdf.macrolib.Macro]]): Option[Seq[mdf.macrolib.SRAMMacro]] = {
s match {
case Some(l:Seq[mdf.macrolib.Macro]) => Some(l filter { _.macroType == mdf.macrolib.SRAM } map { m => m.asInstanceOf[mdf.macrolib.SRAMMacro] })
case _ => None
}
}
@@ -147,7 +84,11 @@ object Utils {
def not(e: Expression) =
DoPrim(PrimOps.Not, Seq(e), Nil, e.tpe)
def invert(exp: Expression, polarity: Option[PortPolarity]) =
// Convert a port to a FIRRTL expression, handling polarity along the way.
def portToExpression(pp: PolarizedPort): Expression =
portToExpression(WRef(pp.name), Some(pp.polarity))
def portToExpression(exp: Expression, polarity: Option[PortPolarity]): Expression =
polarity match {
case Some(ActiveLow) | Some(NegativeEdge) => not(exp)
case _ => exp