From 5085bb07b66aa422cd13e0621e29b1643dfb624b Mon Sep 17 00:00:00 2001 From: Asherah Connor Date: Fri, 7 Jun 2024 14:34:59 +0300 Subject: [PATCH] CxxrtlTask: actually use "zig build" in final step, supply parameters. --- .../platform/cxxrtl/CxxrtlPlatform.scala | 2 +- .../scala/ee/hrzn/chryse/tasks/BaseTask.scala | 21 ++++--- .../ee/hrzn/chryse/tasks/CxxrtlTask.scala | 62 ++++++++++++++----- 3 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/main/scala/ee/hrzn/chryse/platform/cxxrtl/CxxrtlPlatform.scala b/src/main/scala/ee/hrzn/chryse/platform/cxxrtl/CxxrtlPlatform.scala index ab44da5..db19123 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/cxxrtl/CxxrtlPlatform.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/cxxrtl/CxxrtlPlatform.scala @@ -22,7 +22,7 @@ import chisel3._ import ee.hrzn.chryse.build.filesInDirWithExt import ee.hrzn.chryse.platform.ElaboratablePlatform -abstract case class CxxrtlPlatform(id: String, useZig: Boolean = false) +abstract case class CxxrtlPlatform(id: String, zig: Boolean = false) extends ElaboratablePlatform { type TopPlatform[Top <: Module] = Top diff --git a/src/main/scala/ee/hrzn/chryse/tasks/BaseTask.scala b/src/main/scala/ee/hrzn/chryse/tasks/BaseTask.scala index edceafc..2b11360 100644 --- a/src/main/scala/ee/hrzn/chryse/tasks/BaseTask.scala +++ b/src/main/scala/ee/hrzn/chryse/tasks/BaseTask.scala @@ -21,6 +21,7 @@ package ee.hrzn.chryse.tasks import ee.hrzn.chryse.ChryseAppStepFailureException import ee.hrzn.chryse.build.CompilationUnit +import java.io.File import java.io.PrintWriter import java.nio.file.Files import java.nio.file.Paths @@ -49,7 +50,7 @@ trait BaseTask { writePath(path)(_.write(content)) protected def runCmd(step: CmdStep, cmd: Seq[String]) = - runCmds(step, Seq(cmd)) + runCmds(step, Seq((cmd, None))) sealed protected class CmdStep(s: String) { override def toString() = s @@ -72,10 +73,11 @@ trait BaseTask { // This isn't rigorous and it isn't meant to be — for displaying on stdout // only. - private def formattedCmd(cmd: Seq[String]): String = { + private def formattedCmd(cmd: (Seq[String], Option[String])): String = { def fmtPart(part: String) = specialChar.replaceAllIn(part, Regex.quoteReplacement("\\") + "$0") - cmd.map(fmtPart).mkString(" ") + cmd._2.map(dir => s"(in $dir/) ").getOrElse("") + + cmd._1.map(fmtPart).mkString(" ") } sealed protected trait CmdAction @@ -85,7 +87,7 @@ trait BaseTask { protected def reportCmd( step: CmdStep, action: CmdAction, - cmd: Seq[String], + cmd: (Seq[String], Option[String]), ): Unit = { val paddedAction = action match { case CmdActionRun => "[run] " @@ -96,10 +98,13 @@ trait BaseTask { protected def runCmds( step: CmdStep, - cmds: Iterable[Seq[String]], + cmds: Iterable[(Seq[String], Option[String])], ): Unit = { cmds.foreach(reportCmd(step, CmdActionRun, _)) - val processes = cmds.map(cmd => (cmd, cmd.run())) + val processes = cmds.map { cmd => + val pb = Process(cmd._1, cmd._2.map(new File(_))) + (cmd, pb.run()) + } // TODO: consider an upper limit on concurrency. val failed = processes.collect { case (cmd, proc) if proc.exitValue() != 0 => cmd @@ -119,8 +124,8 @@ trait BaseTask { cus: Iterable[CompilationUnit], ): Unit = { val (skip, run) = cus.partition(_.isUpToDate()) - skip.foreach(cu => reportCmd(step, CmdActionSkip, cu.cmd)) - runCmds(step, run.map(_.cmd)) + skip.foreach(cu => reportCmd(step, CmdActionSkip, _)) + runCmds(step, run.map(cu => (cu.cmd, cu.chdir))) run.foreach(_.markUpToDate()) } diff --git a/src/main/scala/ee/hrzn/chryse/tasks/CxxrtlTask.scala b/src/main/scala/ee/hrzn/chryse/tasks/CxxrtlTask.scala index 15f6da4..27069f5 100644 --- a/src/main/scala/ee/hrzn/chryse/tasks/CxxrtlTask.scala +++ b/src/main/scala/ee/hrzn/chryse/tasks/CxxrtlTask.scala @@ -22,11 +22,13 @@ import circt.stage.ChiselStage import ee.hrzn.chryse.ChryseApp import ee.hrzn.chryse.ChryseAppStepFailureException import ee.hrzn.chryse.build.CompilationUnit +import ee.hrzn.chryse.build.filesInDirWithExt import ee.hrzn.chryse.platform.cxxrtl.BlackBoxGenerator import ee.hrzn.chryse.platform.cxxrtl.CxxrtlOptions import ee.hrzn.chryse.platform.cxxrtl.CxxrtlPlatform import org.apache.commons.io.FileUtils +import java.io.File import java.nio.file.Files import java.nio.file.Paths import scala.collection.mutable @@ -111,6 +113,13 @@ private[chryse] object CxxrtlTask extends BaseTask { val cxxOpts = new mutable.ArrayBuffer[String] cxxOpts.appendAll(platform.cxxOpts) cxxOpts.append(s"-DCLOCK_HZ=${platform.clockHz}") + if (platform.zig) + cxxOpts.appendAll( + Seq( + "-DCXXRTL_INCLUDE_CAPI_IMPL", + "-DCXXRTL_INCLUDE_VCD_CAPI_IMPL", + ), + ) if (runOptions.debug) cxxOpts.append("-g") if (runOptions.optimize) cxxOpts.append("-O3") @@ -121,7 +130,7 @@ private[chryse] object CxxrtlTask extends BaseTask { } def compileCmdForCc(cc: String, obj: String): Seq[String] = - (if (platform.useZig) Seq("zig") else Seq()) ++ Seq( + (if (platform.zig) Seq("zig") else Seq()) ++ Seq( "c++", s"-I$buildDir/${platform.id}", s"-I$buildDir", // XXX: other artefacts the user might generate @@ -146,19 +155,44 @@ private[chryse] object CxxrtlTask extends BaseTask { runCus(CmdStepCompile, cus) val binPath = s"$buildDir/${platform.id}/$name" - val linkCu = CompilationUnit( - None, - cus.map(_.outPath), - binPath, - (if (platform.useZig) Seq("zig") else Seq()) ++ Seq( - "c++", - "-o", + + if (platform.zig) { + // TODO: extract into a CxxrtlPlatform subclass, make the defines configurable there. + val linkCu = CompilationUnit( + None, + cus.map(_.outPath) ++ filesInDirWithExt(simDir, ".zig"), binPath, - ) ++ cxxOpts ++ cus.map( - _.outPath, - ) ++ appOptions.allLdFlags, - ) - runCu(CmdStepLink, linkCu) + Seq( + "zig", + "build", + s"-Dyosys_data_dir=$yosysDatDir", + s"-Dcxxrtl_o_paths=${cus.map(p => s"../${p.outPath}").mkString(",")}", + ) + ++ (if (runOptions.optimize) Seq("-Doptimize=ReleaseFast") + else Seq()), + chdir = Some(simDir), + ) + runCu(CmdStepLink, linkCu) + + FileUtils.copyFile( + new File(s"$simDir/zig-out/bin/$simDir"), + new File(binPath), + ) + } else { + val linkCu = CompilationUnit( + None, + cus.map(_.outPath), + binPath, + Seq( + "c++", + "-o", + binPath, + ) ++ cxxOpts ++ cus.map( + _.outPath, + ) ++ appOptions.allLdFlags, + ) + runCu(CmdStepLink, linkCu) + } if (runOptions.compileOnly) return @@ -168,7 +202,7 @@ private[chryse] object CxxrtlTask extends BaseTask { } val binCmd = Seq(binPath) ++ binArgs ++ runOptions.args - reportCmd(CmdStepExecute, CmdActionRun, binCmd) + reportCmd(CmdStepExecute, CmdActionRun, (binCmd, None)) val rc = binCmd.! println(s"$name exited with return code $rc")