Skip to content
This repository has been archived by the owner on Jun 16, 2024. It is now read-only.

Commit

Permalink
add "alternate programming modes" option.
Browse files Browse the repository at this point in the history
  • Loading branch information
kivikakk committed May 30, 2024
1 parent 290643e commit e22a4ab
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 22 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/example-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK 22
uses: actions/setup-java@v4
with:
java-version: '22'
distribution: 'temurin'
cache: 'sbt'

- name: Build and run example app
run: sbt run
40 changes: 40 additions & 0 deletions src/main/scala/ee/hrzn/chryse/ChryseApp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,34 @@ abstract class ChryseApp {
),
)
else None

val program =
opt[Boolean](
descr = "Program the design onto the board after building",
)

val programMode =
if (targetPlatforms.exists(_.programmingModes.length > 1))
Some(
opt[String](
name = "program-mode",
short = 'm',
descr = "Alternate programming mode (use -m ? with a board specified to list)",
),
)
else None

if (board.isDefined && programMode.isDefined)
validateOpt(board.get, programMode.get) {
case (Some(b), Some(pm)) if pm != "?" =>
val plat = targetPlatforms.find(_.id == b).get
if (plat.programmingModes.exists(_._1 == pm))
Right(())
else
Left("Invalid programming mode (use -m ? to list)")
case _ => Right(())
}

val fullStacktrace = opt[Boolean](
short = 'F',
descr = "Include full Chisel stacktraces",
Expand Down Expand Up @@ -130,11 +154,27 @@ abstract class ChryseApp {
targetPlatforms.find(_.id == Conf.build.board.get()).get
else
targetPlatforms(0)

val programMode = Conf.build.programMode.flatMap(_.toOption)

if (programMode == Some("?")) {
println(s"Programming modes for ${platform.id}:")
val maxlen = platform.programmingModes.map(_._1.length()).max
for { ((name, desc), ix) <- platform.programmingModes.zipWithIndex }
println(
s"$name${" " * (maxlen - name.length())}" +
s"${if (ix == 0) " (default)" else " "}" +
s" $desc",
)
return
}

tasks.BuildTask(
this,
platform,
tasks.BuildTask.Options(
Conf.build.program(),
programMode.getOrElse(platform.programmingModes(0)._1),
Conf.build.fullStacktrace(),
),
)
Expand Down
5 changes: 4 additions & 1 deletion src/main/scala/ee/hrzn/chryse/ExampleApp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import chisel3._
import ee.hrzn.chryse.platform.Platform
import ee.hrzn.chryse.platform.cxxrtl.CXXRTLOptions
import ee.hrzn.chryse.platform.cxxrtl.CXXRTLPlatform
import ee.hrzn.chryse.platform.ecp5.LFE5U_85F
import ee.hrzn.chryse.platform.ecp5.ULX3SPlatform
import ee.hrzn.chryse.platform.ice40.IceBreakerPlatform

object ExampleApp extends ChryseApp {
class Top(implicit platform: Platform) extends Module {}

override val name = "example"
override def genTop()(implicit platform: Platform) = new Top
override val targetPlatforms = Seq(IceBreakerPlatform())
override val targetPlatforms =
Seq(IceBreakerPlatform(), ULX3SPlatform(LFE5U_85F))
override val cxxrtlOptions = Some(
CXXRTLOptions(platforms = Seq(new CXXRTLPlatform("ex") {
val clockHz = 3_000_000
Expand Down
5 changes: 4 additions & 1 deletion src/main/scala/ee/hrzn/chryse/platform/PlatformBoard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ trait PlatformBoard[PBR <: PlatformBoardResources]
jsonPath: String,
): BuildResult

def program(buildResult: BuildResult): Unit
def program(buildResult: BuildResult, mode: String): Unit

val resources: PBR
val programmingModes: Seq[(String, String)] = Seq(
("default", "Default programming mode for the board."),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ case class OrangeCrabPlatform(ecp5Variant: ECP5Variant)
val ecp5Package = "csfBGA285"
val ecp5Speed = 8

def program(binPath: BuildResult): Unit = ???
def program(binPath: BuildResult, programMode: String): Unit = ???

val resources = new OrangeCrabPlatformResources
}
Expand Down
19 changes: 15 additions & 4 deletions src/main/scala/ee/hrzn/chryse/platform/ecp5/ULX3SPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,29 @@ case class ULX3SPlatform(ecp5Variant: ECP5Variant)
val ecp5Speed = 6
override val ecp5PackOpts = Seq("--compress")

def program(bitAndSvf: BuildResult): Unit =
programImpl(bitAndSvf)
def program(bitAndSvf: BuildResult, mode: String): Unit =
programImpl(bitAndSvf, mode)

private object programImpl extends BaseTask {
def apply(bitAndSvf: BuildResult): Unit =
def apply(bitAndSvf: BuildResult, mode: String): Unit =
runCmd(
CmdStepProgram,
Seq("openFPGALoader", "-v", "-b", "ulx3s", "-m", bitAndSvf.bitPath),
Seq(
"openFPGALoader",
"-v",
"-b",
"ulx3s",
if (mode == "sram") "-m" else "-f",
bitAndSvf.bitPath,
),
)
}

val resources = new ULX3SPlatformResources
override val programmingModes = Seq(
("sram", "Program the design to SRAM directly."),
("flash", "Program the design to the flash."),
)
}

class ULX3SPlatformResources extends PlatformBoardResources {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ trait ICE40Platform { this: PlatformBoard[_ <: PlatformBoardResources] =>
}
}

def program(binPath: String): Unit =
def program(binPath: String, mode: String): Unit =
programImpl(binPath)

private object programImpl extends BaseTask {
Expand Down
5 changes: 2 additions & 3 deletions src/main/scala/ee/hrzn/chryse/tasks/BuildTask.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ import java.nio.file.Paths
object BuildTask extends BaseTask {
case class Options(
program: Boolean,
programMode: String,
fullStacktrace: Boolean,
)

// TODO (ECP5): refactor — different steps and build products are involved
// after synthesis.
def apply(
chryse: ChryseApp,
platform: PlatformBoard[_ <: PlatformBoardResources],
Expand Down Expand Up @@ -73,7 +72,7 @@ object BuildTask extends BaseTask {

if (options.program) {
println(s"Programming ${platform.id} ...")
platform.program(binPath)
platform.program(binPath, options.programMode)
}
}
}
11 changes: 0 additions & 11 deletions src/main/scala/ee/hrzn/chryse/tasks/CxxsimTask.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ object CxxsimTask extends BaseTask {
}
}

// XXX: We don't call ccPath buildDir/name-platform.cc because that'd imply
// the user needs to include different .h files depending on the chosen plat
// too.
val yosysScriptPath = s"$buildDir/${platform.id}/$name.ys"
val ccPath = s"$buildDir/${platform.id}/$name.cc"
writePath(
Expand All @@ -94,14 +91,6 @@ object CxxsimTask extends BaseTask {
)
runCu(CmdStepSynthesise, yosysCu)

// TODO: we need to decide how the simulation gets driven. How do we offer
// enough control to the user? Do we assume they/let them do all the setup
// themselves? etc.
//
// Fundamentally, the user may have many different ways of driving the
// process. We want to facilitate connecting blackboxes etc., but what else?
// Hrmmm. Let's start simple (just compiling everything, like rainhdx), and
// then see where we go.
val ccs = Seq(ccPath) ++ filesInDirWithExt(cxxsimDir, ".cc")
val headers = filesInDirWithExt(cxxsimDir, ".h").toSeq

Expand Down

0 comments on commit e22a4ab

Please sign in to comment.