1
0

Merge pull request #1215 from freechipsproject/config-altermap

Misc updates to Config and Generator APIs
This commit is contained in:
Henry Cook 2018-01-31 14:22:17 -08:00 committed by GitHub
commit ad58b37437
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 26 deletions

View File

@ -23,18 +23,25 @@ abstract class View {
} }
abstract class Parameters extends View { abstract class Parameters extends View {
final def ++ (x: Parameters): Parameters = new ChainParameters(this, x) final def ++ (x: Parameters): Parameters =
final def alter(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = Parameters(f) ++ this new ChainParameters(this, x)
final def alterPartial(f: PartialFunction[Any,Any]): Parameters = Parameters((_,_,_) => f) ++ this
final def alter(f: (View, View, View) => PartialFunction[Any,Any]): Parameters =
Parameters(f) ++ this
final def alterPartial(f: PartialFunction[Any,Any]): Parameters =
Parameters((_,_,_) => f) ++ this
final def alterMap(m: Map[Any,Any]): Parameters =
new MapParameters(m) ++ this
protected[config] def chain[T](site: View, tail: View, pname: Field[T]): Option[T] protected[config] def chain[T](site: View, tail: View, pname: Field[T]): Option[T]
protected[config] def find[T](pname: Field[T], site: View) = chain(site, new TerminalView, pname) protected[config] def find[T](pname: Field[T], site: View) = chain(site, new TerminalView, pname)
} }
object Parameters { object Parameters {
def empty: Parameters = new EmptyParameters def empty: Parameters = new EmptyParameters
def apply(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = new PartialParameters(f) def apply(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = new PartialParameters(f)
def root(p: Parameters) = p
} }
class Config(p: Parameters) extends Parameters { class Config(p: Parameters) extends Parameters {
@ -69,3 +76,10 @@ private class PartialParameters(f: (View, View, View) => PartialFunction[Any,Any
if (g.isDefinedAt(pname)) Some(g.apply(pname).asInstanceOf[T]) else tail.find(pname, site) if (g.isDefinedAt(pname)) Some(g.apply(pname).asInstanceOf[T]) else tail.find(pname, site)
} }
} }
private class MapParameters(map: Map[Any, Any]) extends Parameters {
protected[config] def chain[T](site: View, tail: View, pname: Field[T]) = {
val g = map.get(pname)
if (g.isDefined) Some(g.get.asInstanceOf[T]) else tail.find(pname, site)
}
}

View File

@ -29,25 +29,25 @@ case class ParsedInputNames(
* canonical ways of building various JVM elaboration-time structures. * canonical ways of building various JVM elaboration-time structures.
*/ */
trait HasGeneratorUtilities { trait HasGeneratorUtilities {
def getConfig(names: ParsedInputNames): Config = { def getConfig(fullConfigClassNames: Seq[String]): Config = {
new Config(names.fullConfigClasses.foldRight(Parameters.empty) { case (currentName, config) => new Config(fullConfigClassNames.foldRight(Parameters.empty) { case (currentName, config) =>
val currentConfig = try { val currentConfig = try {
Class.forName(currentName).newInstance.asInstanceOf[Config] Class.forName(currentName).newInstance.asInstanceOf[Config]
} catch { } catch {
case e: java.lang.ClassNotFoundException => case e: java.lang.ClassNotFoundException =>
throwException(s"""Unable to find part "$currentName" from "${names.configs}", did you misspell it?""", e) throwException(s"""Unable to find part "$currentName" from "$fullConfigClassNames", did you misspell it?""", e)
} }
currentConfig ++ config currentConfig ++ config
}) })
} }
def getParameters(names: ParsedInputNames): Parameters = getParameters(getConfig(names)) def getParameters(names: Seq[String]): Parameters = getParameters(getConfig(names))
def getParameters(config: Config): Parameters = Parameters.root(config.toInstance) def getParameters(config: Config): Parameters = config.toInstance
def elaborate(names: ParsedInputNames, params: Parameters): Circuit = { def elaborate(fullTopModuleClassName: String, params: Parameters): Circuit = {
val gen = () => val gen = () =>
Class.forName(names.fullTopModuleClass) Class.forName(fullTopModuleClassName)
.getConstructor(classOf[Parameters]) .getConstructor(classOf[Parameters])
.newInstance(params) .newInstance(params)
.asInstanceOf[RawModule] .asInstanceOf[RawModule]
@ -69,17 +69,8 @@ trait HasGeneratorUtilities {
} }
res.toString res.toString
} }
def writeOutputFile(targetDir: String, fname: String, contents: String): File = {
val f = new File(targetDir, fname)
val fw = new FileWriter(f)
fw.write(contents)
fw.close
f
}
} }
/** Standardized command line interface for Scala entry point */ /** Standardized command line interface for Scala entry point */
trait GeneratorApp extends App with HasGeneratorUtilities { trait GeneratorApp extends App with HasGeneratorUtilities {
lazy val names: ParsedInputNames = { lazy val names: ParsedInputNames = {
@ -95,11 +86,10 @@ trait GeneratorApp extends App with HasGeneratorUtilities {
} }
// Canonical ways of building various JVM elaboration-time structures // Canonical ways of building various JVM elaboration-time structures
lazy val td = names.targetDir lazy val td: String = names.targetDir
lazy val config = getConfig(names) lazy val config: Config = getConfig(names.fullConfigClasses)
lazy val world = config.toInstance lazy val params: Parameters = config.toInstance
lazy val params = Parameters.root(world) lazy val circuit: Circuit = elaborate(names.fullTopModuleClass, params)
lazy val circuit = elaborate(names, params)
val longName: String // Exhaustive name used to interface with external build tool targets val longName: String // Exhaustive name used to interface with external build tool targets
@ -137,6 +127,14 @@ trait GeneratorApp extends App with HasGeneratorUtilities {
writeOutputFile(td, s"${names.configs}.${extension}", contents ()) writeOutputFile(td, s"${names.configs}.${extension}", contents ())
} }
} }
def writeOutputFile(targetDir: String, fname: String, contents: String): File = {
val f = new File(targetDir, fname)
val fw = new FileWriter(f)
fw.write(contents)
fw.close
f
}
} }
object ElaborationArtefacts { object ElaborationArtefacts {