Skip to content
This repository has been archived by the owner on Apr 20, 2024. It is now read-only.

Refactor barstools for new versions of things. #35

Merged
merged 11 commits into from
Feb 13, 2019
17 changes: 9 additions & 8 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
// See LICENSE for license details.

import Dependencies._

val defaultVersions = Map(
"chisel3" -> "3.1-SNAPSHOT",
"chisel-iotesters" -> "1.2-SNAPSHOT"
"chisel3" -> "3.2-SNAPSHOT",
"chisel-iotesters" -> "1.3-SNAPSHOT"
)

lazy val commonSettings = Seq(
organization := "edu.berkeley.cs",
version := "0.1-SNAPSHOT",
scalaVersion := "2.11.8",
scalacOptions := Seq("-deprecation", "-feature", "-language:reflectiveCalls"),
libraryDependencies ++= commonDependencies,
scalaVersion := "2.12.8",
scalacOptions := Seq("-deprecation", "-feature", "-language:reflectiveCalls", "-Xsource:2.11"),
libraryDependencies ++= Seq("chisel3","chisel-iotesters").map {
dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep))
},
libraryDependencies in Test ++= Seq(
"org.scalatest" %% "scalatest" % "2.2.5" % "test",
"org.scalacheck" %% "scalacheck" % "1.12.4" % "test"
),
resolvers ++= Seq(
Resolver.sonatypeRepo("snapshots"),
Resolver.sonatypeRepo("releases")
Expand All @@ -30,7 +31,7 @@ lazy val macros = (project in file("macros"))
.settings(commonSettings)
.settings(Seq(
libraryDependencies ++= Seq(
"edu.berkeley.cs" %% "firrtl-interpreter" % "0.1-SNAPSHOT" % Test
"edu.berkeley.cs" %% "firrtl-interpreter" % "1.2-SNAPSHOT" % Test
),
mainClass := Some("barstools.macros.MacroCompiler")
))
Expand Down
33 changes: 23 additions & 10 deletions macros/src/main/scala/MacroCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import firrtl.ir._
import firrtl.PrimOps
import firrtl.Utils._
import firrtl.annotations._
import firrtl.transforms.{NoDCEAnnotation}
import firrtl.CompilerUtils.getLoweringTransforms
import mdf.macrolib.{PolarizedPort, PortPolarity}
import scala.collection.mutable.{ArrayBuffer, HashMap}
Expand Down Expand Up @@ -73,13 +74,14 @@ object MacroCompilerAnnotation {
* Parameters associated to this MacroCompilerAnnotation.
*
* @param mem Path to memory lib
* @param memFormat Type of memory lib (Some("conf"), Some("mdf"), or None (defaults to mdf))
* @param lib Path to library lib or None if no libraries
* @param costMetric Cost metric to use
* @param mode Compiler mode (see CompilerMode)
* @param forceCompile Set of memories to force compiling to lib regardless of the mode
* @param forceSynflops Set of memories to force compiling as flops regardless of the mode
*/
case class Params(mem: String, lib: Option[String], costMetric: CostMetric, mode: CompilerMode, useCompiler: Boolean,
case class Params(mem: String, memFormat: Option[String], lib: Option[String], costMetric: CostMetric, mode: CompilerMode, useCompiler: Boolean,
forceCompile: Set[String], forceSynflops: Set[String])

/**
Expand Down Expand Up @@ -609,7 +611,7 @@ class MacroCompilerTransform extends Transform {

def execute(state: CircuitState) = getMyAnnotations(state) match {
case Seq(MacroCompilerAnnotation(state.circuit.main,
MacroCompilerAnnotation.Params(memFile, libFile, costMetric, mode, useCompiler, forceCompile, forceSynflops))) =>
MacroCompilerAnnotation.Params(memFile, memFileFormat, libFile, costMetric, mode, useCompiler, forceCompile, forceSynflops))) =>
if (mode == MacroCompilerAnnotation.FallbackSynflops) {
throw new UnsupportedOperationException("Not implemented yet")
}
Expand All @@ -618,7 +620,10 @@ class MacroCompilerTransform extends Transform {
assert((forceCompile intersect forceSynflops).isEmpty, "Cannot have modules both forced to compile and synflops")

// Read, eliminate None, get only SRAM, make firrtl macro
val mems: Option[Seq[Macro]] = mdf.macrolib.Utils.readMDFFromPath(Some(memFile)) match {
val mems: Option[Seq[Macro]] = (memFileFormat match {
case Some("conf") => Utils.readConfFromPath(Some(memFile))
case _ => mdf.macrolib.Utils.readMDFFromPath(Some(memFile))
}) match {
case Some(x:Seq[mdf.macrolib.Macro]) =>
Some(Utils.filterForSRAM(Some(x)) getOrElse(List()) map {new Macro(_)})
case _ => None
Expand Down Expand Up @@ -687,6 +692,7 @@ class MacroCompiler extends Compiler {
object MacroCompiler extends App {
sealed trait MacroParam
case object Macros extends MacroParam
case object MacrosFormat extends MacroParam
case object Library extends MacroParam
case object Verilog extends MacroParam
case object Firrtl extends MacroParam
Expand All @@ -701,7 +707,8 @@ object MacroCompiler extends App {
.map { case (_, cmd, description) => s" $cmd: $description" }
val usage: String = (Seq(
"Options:",
" -m, --macro-list: The set of macros to compile",
" -n, --macro-conf: The set of macros to compile in firrtl-generated conf format (exclusive with -m)",
" -m, --macro-mdf: The set of macros to compile in MDF JSON format (exclusive with -n)",
" -l, --library: The set of macros that have blackbox instances",
" -u, --use-compiler: Flag, whether to use the memory compiler defined in library",
" -v, --verilog: Verilog output",
Expand All @@ -717,8 +724,10 @@ object MacroCompiler extends App {
args: List[String]): (MacroParamMap, CostParamMap, ForcedMemories) =
args match {
case Nil => (map, costMap, forcedMemories)
case ("-m" | "--macro-list") :: value :: tail =>
parseArgs(map + (Macros -> value), costMap, forcedMemories, tail)
case ("-n" | "--macro-conf") :: value :: tail =>
parseArgs(map + (Macros -> value) + (MacrosFormat -> "conf"), costMap, forcedMemories, tail)
case ("-m" | "--macro-mdf") :: value :: tail =>
parseArgs(map + (Macros -> value) + (MacrosFormat -> "mdf"), costMap, forcedMemories, tail)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if they specify both?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will take the last option specified. I think this is intuitive enough behavior to leave it as is.

case ("-l" | "--library") :: value :: tail =>
parseArgs(map + (Library -> value), costMap, forcedMemories, tail)
case ("-u" | "--use-compiler") :: tail =>
Expand Down Expand Up @@ -746,25 +755,29 @@ object MacroCompiler extends App {
def run(args: List[String]) {
val (params, costParams, forcedMemories) = parseArgs(Map[MacroParam, String](), Map[String, String](), (Set.empty, Set.empty), args)
try {
val macros = Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(params.get(Macros))).get map (x => (new Macro(x)).blackbox)
val macros = params.get(MacrosFormat) match {
case Some("conf") => Utils.filterForSRAM(Utils.readConfFromPath(params.get(Macros))).get map (x => (new Macro(x)).blackbox)
case _ => Utils.filterForSRAM(mdf.macrolib.Utils.readMDFFromPath(params.get(Macros))).get map (x => (new Macro(x)).blackbox)
}

if (macros.nonEmpty) {
// Note: the last macro in the input list is (seemingly arbitrarily)
// determined as the firrtl "top-level module".
val circuit = Circuit(NoInfo, macros, macros.last.name)
val annotations = AnnotationMap(
val annotations = AnnotationSeq(
Seq(MacroCompilerAnnotation(
circuit.main,
MacroCompilerAnnotation.Params(
params.get(Macros).get, params.get(Library),
params.get(Macros).get, params.get(MacrosFormat), params.get(Library),
CostMetric.getCostMetric(params.getOrElse(CostFunc, "default"), costParams),
MacroCompilerAnnotation.stringToCompilerMode(params.getOrElse(Mode, "default")),
params.contains(UseCompiler),
forceCompile = forcedMemories._1, forceSynflops = forcedMemories._2
)
))
)
val state = CircuitState(circuit, HighForm, Some(annotations))
// Append a NoDCEAnnotation to avoid dead code elimination removing the non-parent SRAMs
val state = CircuitState(circuit, HighForm, annotations :+ NoDCEAnnotation)

// Run the compiler.
val result = new MacroCompiler().compileAndEmit(state)
Expand Down
55 changes: 55 additions & 0 deletions macros/src/main/scala/MemConf.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// See LICENSE for license details.

package barstools.macros

import scala.util.matching._

sealed abstract class MemPort(val name: String) { override def toString = name }

case object ReadPort extends MemPort("read")
case object WritePort extends MemPort("write")
case object MaskedWritePort extends MemPort("mwrite")
case object ReadWritePort extends MemPort("rw")
case object MaskedReadWritePort extends MemPort("mrw")

object MemPort {

val all = Set(ReadPort, WritePort, MaskedWritePort, ReadWritePort, MaskedReadWritePort)

def apply(s: String): Option[MemPort] = MemPort.all.find(_.name == s)

def fromString(s: String): Seq[MemPort] = {
s.split(",").toSeq.map(MemPort.apply).map(_ match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need the toSeq?

case Some(x) => x
case _ => throw new Exception(s"Error parsing MemPort string : ${s}")
})
}
}

// This is based on firrtl.passes.memlib.ConfWriter
// TODO standardize this in FIRRTL
case class MemConf(
name: String,
depth: Int,
width: Int,
ports: Seq[MemPort],
maskGranularity: Option[Int]
) {

private def portsStr = ports.map(_.name).mkString(",")
private def maskGranStr = maskGranularity.map((p) => s"mask_gran $p").getOrElse("")

override def toString() = s"name ${name} depth ${depth} width ${width} ports ${portsStr} ${maskGranStr} "
}

object MemConf {

val regex = raw"\s*name\s+(\w+)\s+depth\s+(\d+)\s+width\s+(\d+)\s+ports\s+([^\s]+)\s+(?:mask_gran\s+(\d+))?\s*".r
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ports feels a little under specified but meh. Can you not just do [\w,]?


def fromString(s: String): Seq[MemConf] = {
s.split("\n").toSeq.map(_ match {
case MemConf.regex(name, depth, width, ports, maskGran) => MemConf(name, depth.toInt, width.toInt, MemPort.fromString(ports), Option(maskGran).map(_.toInt))
case _ => throw new Exception(s"Error parsing MemConf string : ${s}")
})
}
}
77 changes: 76 additions & 1 deletion macros/src/main/scala/Utils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import firrtl.ir._
import firrtl.PrimOps
import firrtl.Utils.{ceilLog2, BoolType}
import mdf.macrolib.{Constant, MacroPort, SRAMMacro}
import mdf.macrolib.{PolarizedPort, PortPolarity, ActiveLow, ActiveHigh, NegativeEdge, PositiveEdge}
import mdf.macrolib.{PolarizedPort, PortPolarity, ActiveLow, ActiveHigh, NegativeEdge, PositiveEdge, MacroExtraPort}
import java.io.File
import scala.language.implicitConversions

Expand Down Expand Up @@ -72,6 +72,81 @@ object Utils {
case _ => None
}
}
// This utility reads a conf in and returns MDF like mdf.macrolib.Utils.readMDFFromPath
def readConfFromPath(path: Option[String]): Option[Seq[mdf.macrolib.Macro]] = {
path.map((p) => Utils.readConfFromString(scala.io.Source.fromFile(p).mkString))
}
def readConfFromString(str: String): Seq[mdf.macrolib.Macro] = {
MemConf.fromString(str).map { m:MemConf =>
SRAMMacro(m.name, m.width, m.depth, "", Utils.portSpecToMacroPort(m.width, m.depth, m.maskGranularity, m.ports), Seq.empty[MacroExtraPort])
}
}
// This translates between two represenations of ports
def portSpecToMacroPort(width: Int, depth: Int, maskGran: Option[Int], ports: Seq[MemPort]): Seq[MacroPort] = {
var numR = 0
var numW = 0
var numRW = 0
ports.map { _ match {
case ReadPort => {
val portName = s"R${numR}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make a note at the top of this function where the names of these ports come from and that they are not arbitrary.

numR += 1
MacroPort(
width=Some(width), depth=Some(depth),
address=PolarizedPort(s"${portName}_addr", ActiveHigh),
clock=PolarizedPort(s"${portName}_clk", PositiveEdge),
chipEnable=Some(PolarizedPort(s"${portName}_en", ActiveHigh)),
output=Some(PolarizedPort(s"${portName}_data", ActiveHigh))
) }
case WritePort => {
val portName = s"W${numW}"
numW += 1
MacroPort(
width=Some(width), depth=Some(depth),
address=PolarizedPort(s"${portName}_addr", ActiveHigh),
clock=PolarizedPort(s"${portName}_clk", PositiveEdge),
writeEnable=Some(PolarizedPort(s"${portName}_en", ActiveHigh)),
input=Some(PolarizedPort(s"${portName}_data", ActiveHigh))
) }
case MaskedWritePort => {
val portName = s"W${numW}"
numW += 1
MacroPort(
width=Some(width), depth=Some(depth),
address=PolarizedPort(s"${portName}_addr", ActiveHigh),
clock=PolarizedPort(s"${portName}_clk", PositiveEdge),
writeEnable=Some(PolarizedPort(s"${portName}_en", ActiveHigh)),
maskPort=Some(PolarizedPort(s"${portName}_mask", ActiveHigh)),
maskGran=maskGran,
input=Some(PolarizedPort(s"${portName}_data", ActiveHigh))
) }
case ReadWritePort => {
val portName = s"RW${numRW}"
numRW += 1
MacroPort(
width=Some(width), depth=Some(depth),
address=PolarizedPort(s"${portName}_addr", ActiveHigh),
clock=PolarizedPort(s"${portName}_clk", PositiveEdge),
chipEnable=Some(PolarizedPort(s"${portName}_en", ActiveHigh)),
writeEnable=Some(PolarizedPort(s"${portName}_wmode", ActiveHigh)),
input=Some(PolarizedPort(s"${portName}_wdata", ActiveHigh)),
output=Some(PolarizedPort(s"${portName}_rdata", ActiveHigh))
) }
case MaskedReadWritePort => {
val portName = s"RW${numRW}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just trusting the number is correct here.

numRW += 1
MacroPort(
width=Some(width), depth=Some(depth),
address=PolarizedPort(s"${portName}_addr", ActiveHigh),
clock=PolarizedPort(s"${portName}_clk", PositiveEdge),
chipEnable=Some(PolarizedPort(s"${portName}_en", ActiveHigh)),
writeEnable=Some(PolarizedPort(s"${portName}_wmode", ActiveHigh)),
maskPort=Some(PolarizedPort(s"${portName}_wmask", ActiveHigh)),
maskGran=maskGran,
input=Some(PolarizedPort(s"${portName}_wdata", ActiveHigh)),
output=Some(PolarizedPort(s"${portName}_rdata", ActiveHigh))
) }
}}
}
def findSRAMCompiler(s: Option[Seq[mdf.macrolib.Macro]]): Option[mdf.macrolib.SRAMCompiler] = {
s match {
case Some(l:Seq[mdf.macrolib.Macro]) =>
Expand Down
2 changes: 1 addition & 1 deletion mdf
Submodule mdf updated from ee50cc to c13e31
22 changes: 0 additions & 22 deletions project/Dependencies.scala

This file was deleted.

2 changes: 0 additions & 2 deletions project/assembly.sbt

This file was deleted.

2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=0.13.12
sbt.version=1.2.7
2 changes: 2 additions & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5")
addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.9.2")
Loading