Unfortunately, I had to touch a lot of code, which weren't quite possible to split up into multiple commits. This commit gets rid of the "extra" infrastructure to add periphery devices into Top.
87 lines
3.0 KiB
Scala
87 lines
3.0 KiB
Scala
// See LICENSE for license details.
|
|
|
|
package rocketchip
|
|
|
|
import Chisel._
|
|
import scala.collection.mutable.{LinkedHashSet,LinkedHashMap}
|
|
import cde._
|
|
import coreplex._
|
|
import java.io.{File, FileWriter}
|
|
|
|
case class ParsedInputNames(
|
|
targetDir: String,
|
|
topProject: String,
|
|
topModuleClass: String,
|
|
configProject: String,
|
|
configs: String) {
|
|
val configClasses: Seq[String] = configs.split('_')
|
|
val fullConfigClasses: Seq[String] = configClasses.map(configProject + "." + _)
|
|
val fullTopModuleClass: String = topProject + "." + topModuleClass
|
|
}
|
|
|
|
trait HasGeneratorUtilities {
|
|
def getConfig(names: ParsedInputNames): Config = {
|
|
names.fullConfigClasses.foldRight(new Config()) { case (currentName, config) =>
|
|
val currentConfig = try {
|
|
Class.forName(currentName).newInstance.asInstanceOf[Config]
|
|
} catch {
|
|
case e: java.lang.ClassNotFoundException =>
|
|
throwException(s"""Unable to find part "$currentName" from "${names.configs}", did you misspell it?""", e)
|
|
}
|
|
currentConfig ++ config
|
|
}
|
|
}
|
|
|
|
def getParameters(names: ParsedInputNames): Parameters = getParameters(getConfig(names))
|
|
|
|
def getParameters(config: Config): Parameters = Parameters.root(config.toInstance)
|
|
|
|
import chisel3.internal.firrtl.Circuit
|
|
def elaborate(names: ParsedInputNames, params: Parameters): Circuit = {
|
|
val gen = () =>
|
|
Class.forName(names.fullTopModuleClass)
|
|
.getConstructor(classOf[cde.Parameters])
|
|
.newInstance(params)
|
|
.asInstanceOf[Module]
|
|
|
|
Driver.elaborate(gen)
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
|
|
trait Generator extends App with HasGeneratorUtilities {
|
|
lazy val names = {
|
|
require(args.size == 5, "Usage: sbt> " +
|
|
"run TargetDir TopModuleProjectName TopModuleName ConfigProjectName ConfigNameString")
|
|
ParsedInputNames(
|
|
targetDir = args(0),
|
|
topProject = args(1),
|
|
topModuleClass = args(2),
|
|
configProject = args(3),
|
|
configs = args(4))
|
|
}
|
|
lazy val config = getConfig(names)
|
|
lazy val world = config.toInstance
|
|
lazy val params = Parameters.root(world)
|
|
lazy val circuit = elaborate(names, params)
|
|
}
|
|
|
|
object RocketChipGenerator extends Generator {
|
|
val longName = names.topModuleClass + "." + names.configs
|
|
val td = names.targetDir
|
|
Driver.dumpFirrtl(circuit, Some(new File(td, s"$longName.fir"))) // FIRRTL
|
|
TestGeneration.addSuite(new RegressionTestSuite(params(RegressionTestNames)))
|
|
writeOutputFile(td, s"$longName.d", TestGeneration.generateMakefrag) // Coreplex-specific test suites
|
|
writeOutputFile(td, s"$longName.prm", ParameterDump.getDump) // Parameters flagged with Dump()
|
|
writeOutputFile(td, s"${names.configs}.knb", world.getKnobs) // Knobs for DSE
|
|
writeOutputFile(td, s"${names.configs}.cst", world.getConstraints) // Constraints for DSE
|
|
writeOutputFile(td, s"${names.configs}.cfg", params(ConfigString).get) // String for software
|
|
}
|