diff --git a/emulator/Makefrag-verilator b/emulator/Makefrag-verilator index 62a437e0..30e07acf 100644 --- a/emulator/Makefrag-verilator +++ b/emulator/Makefrag-verilator @@ -11,13 +11,11 @@ verilog_debug = $(generated_dir_debug)/$(MODEL).$(CONFIG).v $(generated_dir)/%.$(CONFIG).fir $(generated_dir)/%.$(CONFIG).prm $(generated_dir)/%.$(CONFIG).d: $(chisel_srcs) $(bootrom_img) mkdir -p $(dir $@) - cd $(base_dir) && $(SBT) "run $(PROJECT) $(MODEL) $(CONFIG) --targetDir $(generated_dir)" - mv $(generated_dir)/$(MODEL).fir $(generated_dir)/$(MODEL).$(CONFIG).fir + cd $(base_dir) && $(SBT) "run $(generated_dir) $(PROJECT) $(MODEL) $(PROJECT) $(CONFIG)" $(generated_dir_debug)/%.$(CONFIG).fir $(generated_dir_debug)/%.$(CONFIG).prm $(generated_dir_debug)/%.$(CONFIG).d: $(chisel_srcs) $(bootrom_img) mkdir -p $(dir $@) - cd $(base_dir) && $(SBT) "run $(PROJECT) $(MODEL) $(CONFIG) --targetDir $(generated_dir_debug)" - mv $(generated_dir_debug)/$(MODEL).fir $(generated_dir_debug)/$(MODEL).$(CONFIG).fir + cd $(base_dir) && $(SBT) "run $(generated_dir_debug) $(PROJECT) $(MODEL) $(PROJECT) $(CONFIG)" %.v: %.fir $(FIRRTL_JAR) mkdir -p $(dir $@) diff --git a/src/main/scala/coreplex/Testing.scala b/src/main/scala/coreplex/Testing.scala index e686c711..e59c4ee4 100644 --- a/src/main/scala/coreplex/Testing.scala +++ b/src/main/scala/coreplex/Testing.scala @@ -66,7 +66,7 @@ object TestGeneration { def addSuites(s: Seq[RocketTestSuite]) { s.foreach(addSuite) } - def generateMakefrag(topModuleName: String, configClassName: String) { + def generateMakefrag: String = { def gen(kind: String, s: Seq[RocketTestSuite]) = { if(s.length > 0) { val envs = s.groupBy(_.envName) @@ -93,18 +93,13 @@ run-$kind-tests-fast: $$(addprefix $$(output_dir)/, $$(addsuffix .run, $targets) } else { "\n" } } - val f = createOutputFile(s"$topModuleName.$configClassName.d") - f.write( - List( - gen("asm", asmSuites.values.toSeq), - gen("bmark", bmarkSuites.values.toSeq), - gen("regression", regressionSuites.values.toSeq) - ).mkString("\n")) - f.close + List( + gen("asm", asmSuites.values.toSeq), + gen("bmark", bmarkSuites.values.toSeq), + gen("regression", regressionSuites.values.toSeq) + ).mkString("\n") } - def createOutputFile(name: String) = - new java.io.FileWriter(s"${Driver.targetDir}/$name") } object DefaultTestSuites { diff --git a/src/main/scala/rocketchip/Generator.scala b/src/main/scala/rocketchip/Generator.scala index f8f25ecb..390ac353 100644 --- a/src/main/scala/rocketchip/Generator.scala +++ b/src/main/scala/rocketchip/Generator.scala @@ -4,81 +4,83 @@ package rocketchip import Chisel._ import scala.collection.mutable.{LinkedHashSet,LinkedHashMap} -import cde.{Parameters, ParameterDump, Config, Field, CDEMatchError, World} +import cde._ import coreplex._ +import java.io.{File, FileWriter} -object GeneratorUtils { - def getConfig(projectName: String, configClassName: String): Config = { - val aggregateConfigs = configClassName.split('_') +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 +} - aggregateConfigs.foldRight(new Config()) { case (currentConfigName, finalConfig) => +trait HasGeneratorUtilities { + def getConfig(names: ParsedInputNames): Config = { + names.fullConfigClasses.foldRight(new Config()) { case (currentName, config) => val currentConfig = try { - Class.forName(s"$projectName.$currentConfigName").newInstance.asInstanceOf[Config] + Class.forName(currentName).newInstance.asInstanceOf[Config] } catch { case e: java.lang.ClassNotFoundException => - throwException("Unable to find part \"" + currentConfigName + - "\" of configClassName \"" + configClassName + - "\", did you misspell it?", e) + throwException(s"""Unable to find part "$currentName" from "${names.configs}", did you misspell it?""", e) } - currentConfig ++ finalConfig + currentConfig ++ config } } - def getParameters(config: Config): Parameters = - Parameters.root(config.toInstance) + def getParameters(names: ParsedInputNames): Parameters = getParameters(getConfig(names)) - def getParameters(projectName: String, configClassName: String): Parameters = - getParameters(getConfig(projectName, configClassName)) + def getParameters(config: Config): Parameters = Parameters.root(config.toInstance) - def elaborate(fullName: String, args: Array[String], params: Parameters) { + import chisel3.internal.firrtl.Circuit + def elaborate(names: ParsedInputNames, params: Parameters): Circuit = { val gen = () => - Class.forName(fullName) + Class.forName(names.fullTopModuleClass) .getConstructor(classOf[cde.Parameters]) .newInstance(params) .asInstanceOf[Module] - chiselMain.run(args, gen) + Driver.elaborate(gen) } - def dumpParameters(fname: String) { - val pdFile = TestGeneration.createOutputFile(fname) - pdFile.write(ParameterDump.getDump) - pdFile.close - } - - def dumpKnobs(configClassName: String, world: World) { - val knbFile = TestGeneration.createOutputFile(configClassName + ".knb") - knbFile.write(world.getKnobs) - knbFile.close - - val cstFile = TestGeneration.createOutputFile(configClassName + ".cst") - cstFile.write(world.getConstraints) - cstFile.close - } - - def dumpConfigString(fname: String, params: Parameters) { - val cfgFile = new java.io.FileOutputStream(Driver.targetDir + "/" + fname) - cfgFile.write(params(ConfigString)) - cfgFile.close + 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 } } -import GeneratorUtils._ -object RocketChipGenerator extends App { - val projectName = args(0) - val topModuleName = args(1) - val configClassName = args(2) - - val config = getConfig(projectName, configClassName) - val world = config.toInstance - val paramsFromConfig = Parameters.root(world) - - elaborate(s"$projectName.$topModuleName", args.drop(3), paramsFromConfig) - - TestGeneration.addSuite(new RegressionTestSuite(paramsFromConfig(RegressionTestNames))) - TestGeneration.generateMakefrag(topModuleName, configClassName) - - dumpParameters(s"$topModuleName.$configClassName.prm") - dumpKnobs(configClassName, world) - dumpConfigString(s"$configClassName.cfg", paramsFromConfig) +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).toString) // String for software } diff --git a/vsim/Makefrag-verilog b/vsim/Makefrag-verilog index 5b3248a2..2f49ff3d 100644 --- a/vsim/Makefrag-verilog +++ b/vsim/Makefrag-verilog @@ -7,8 +7,7 @@ $(generated_dir)/%.$(CONFIG).fir $(generated_dir)/%.$(CONFIG).d $(generated_dir)/%.prm: $(chisel_srcs) $(bootrom_img) mkdir -p $(dir $@) - cd $(base_dir) && $(SBT) "run $(PROJECT) $(notdir $*) $(CONFIG) $(CHISEL_ARGS) --configDump --noInlineMem" - mv $(generated_dir)/$(MODEL).fir $(generated_dir)/$(MODEL).$(CONFIG).fir + cd $(base_dir) && $(SBT) "run $(generated_dir) $(PROJECT) $(notdir $*) $(PROJECT) $(CONFIG)" $(generated_dir)/%.v: $(generated_dir)/%.fir $(FIRRTL_JAR) mkdir -p $(dir $@)