diff --git a/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Platform.scala b/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Platform.scala index 1f1cac2..cfe78aa 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Platform.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ecp5/ECP5Platform.scala @@ -59,7 +59,8 @@ trait ECP5Platform { this: PlatformBoard[_ <: PlatformBoardResources] => val lpfPath = s"$buildDir/${platform.id}/$name.lpf" writePath(lpfPath, topPlatform.lpf.toString()) - val textcfgPath = s"$buildDir/${platform.id}/$name.config" + val textcfgPath = s"$buildDir/${platform.id}/$name.config" + val nextpnrLogPath = s"$buildDir/${platform.id}/$name.config.log" val textcfgCu = CompilationUnit( Some(jsonPath), Seq(lpfPath), @@ -68,7 +69,7 @@ trait ECP5Platform { this: PlatformBoard[_ <: PlatformBoardResources] => "nextpnr-ecp5", "-q", "--log", - s"$buildDir/${platform.id}/$name.tim", + nextpnrLogPath, "--json", jsonPath, "--lpf", @@ -84,6 +85,8 @@ trait ECP5Platform { this: PlatformBoard[_ <: PlatformBoardResources] => ) runCu(CmdStepPNR, textcfgCu) + // TODO (ECP5): print statistics like ICE40Platform. + val bitPath = s"$buildDir/${platform.id}/$name.bit" val svfPath = s"$buildDir/${platform.id}/$name.svf" val bitCu = CompilationUnit( diff --git a/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Platform.scala b/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Platform.scala index 8e7ad23..fbc8281 100644 --- a/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Platform.scala +++ b/src/main/scala/ee/hrzn/chryse/platform/ice40/ICE40Platform.scala @@ -57,7 +57,8 @@ trait ICE40Platform { this: PlatformBoard[_ <: PlatformBoardResources] => val pcfPath = s"$buildDir/${platform.id}/$name.pcf" writePath(pcfPath, topPlatform.pcf.toString()) - val ascPath = s"$buildDir/${platform.id}/$name.asc" + val ascPath = s"$buildDir/${platform.id}/$name.asc" + val nextpnrLogPath = s"$buildDir/${platform.id}/$name.asc.log" val ascCu = CompilationUnit( Some(jsonPath), Seq(pcfPath), @@ -66,7 +67,7 @@ trait ICE40Platform { this: PlatformBoard[_ <: PlatformBoardResources] => "nextpnr-ice40", "-q", "--log", - s"$buildDir/${platform.id}/$name.tim", + nextpnrLogPath, "--json", jsonPath, "--pcf", @@ -80,6 +81,15 @@ trait ICE40Platform { this: PlatformBoard[_ <: PlatformBoardResources] => ) runCu(CmdStepPNR, ascCu) + println() + println("Device utilisation:") + logFileBetween( + nextpnrLogPath, + raw"Info: Device utilisation:".r, + raw"Info: Placed .*".r, + Some("Info: "), + ) + val binPath = s"$buildDir/${platform.id}/$name.bin" val binCu = CompilationUnit( Some(ascPath), diff --git a/src/main/scala/ee/hrzn/chryse/tasks/BaseTask.scala b/src/main/scala/ee/hrzn/chryse/tasks/BaseTask.scala index c296b95..b766f0e 100644 --- a/src/main/scala/ee/hrzn/chryse/tasks/BaseTask.scala +++ b/src/main/scala/ee/hrzn/chryse/tasks/BaseTask.scala @@ -130,6 +130,38 @@ trait BaseTask { .map(_.toString) .filter(_.endsWith(ext)) + protected def logFileBetween( + path: String, + start: Regex, + end: Regex, + prefix: Option[String] = None, + ): Unit = { + var started = false + var ended = false + val lines = Files.lines(Paths.get(path)).iterator.asScala + + while (!ended && lines.hasNext) { + val line = lines.next() + if (!started) { + started = start.matches(line) + } else if (end.matches(line)) { + ended = true + } else { + println(prefix match { + case Some(prefix) => + if ( + line.length >= prefix.length && line + .substring(0, prefix.length()) == prefix + ) + line.substring(prefix.length()) + else line + case None => + line + }) + } + } + } + case class CompilationUnit( val primaryInPath: Option[String], val otherInPaths: Seq[String], diff --git a/src/main/scala/ee/hrzn/chryse/tasks/BuildTask.scala b/src/main/scala/ee/hrzn/chryse/tasks/BuildTask.scala index 101cf05..a6aee54 100644 --- a/src/main/scala/ee/hrzn/chryse/tasks/BuildTask.scala +++ b/src/main/scala/ee/hrzn/chryse/tasks/BuildTask.scala @@ -66,22 +66,21 @@ private[chryse] object BuildTask extends BaseTask { |write_json $jsonPath""".stripMargin, ) + val yosysLogPath = s"$buildDir/${platform.id}/$name.json.log" val yosysCu = CompilationUnit( Some(verilogPath), Seq(yosysScriptPath), jsonPath, - Seq( - "yosys", - "-q", - "-g", - "-l", - s"$buildDir/${platform.id}/$name.rpt", - "-s", - yosysScriptPath, - ), + Seq("yosys", "-q", "-g", "-l", yosysLogPath, "-s", yosysScriptPath), ) runCu(CmdStepSynthesise, yosysCu) + logFileBetween( + yosysLogPath, + raw"\d+\.\d+\. Printing statistics\.".r, + raw"\d+\.\d+\. .*".r, + ) + val binPath = platform.build(chryse, topPlatform.get, jsonPath) if (options.program) {