This post is about getting started with Chisel which is scala based design library.
Scala Hello world Link to heading
First we need to install some packages. Most important one is probably java.
sudo apt install openjdk-8-jdk git make gtkwave
I found the apt scala
version is too old and it fails on Mint 12. So i got the binaries for scala. Now, we can run hello world
scala hello.scala
Similar to installing scala
, sbt
binaries needs to be installed and added to path.
First, we need to project with scala3.g8
with name ex
$ sbt new
b) typelevel/toolkit.local - Toolkit to start building Typelevel apps
c) sbt/cross-platform.local - A cross-JVM/JS/Native project
d) scala/scala3.g8 - Scala 3 seed template
e) scala/scala-seed.g8 - Scala 2 seed template
f) playframework/play-scala-seed.g8 - A Play project in Scala
g) playframework/play-java-seed.g8 - A Play project in Java
i) softwaremill/tapir.g8 - A tapir project using Netty
m) scala-js/vite.g8 - A Scala.JS + Vite project
n) holdenk/sparkProjectTemplate.g8 - A Scala Spark project
o) spotify/scio.g8 - A Scio project
p) disneystreaming/smithy4s.g8 - A Smithy4s project
q) quit
Select a template: d
A template to demonstrate a minimal Scala 3 application
name [Scala 3 Project Template]: ex
$ cd ex
To run the sbt project
sbt run
The output as follows
[info] running hello
Hello world!
I was compiled by Scala 3. :)
[success] Total time: 2 s, completed 3 Apr 2025, 23:02:49
Chisel Hello world Link to heading
I am using older version of chisel 3.6.1
. So, I had cryptic messages that pointed to firtool
1.37.0 we need to install firtool in PATH
.
The directory structure should look like this:
├── build.sbt
├── Makefile
└── src
└── main
└── scala
└── blinky
└── Blinky.scala
So, we need to create build.sbt
to point to chisel
$ more build.sbt
scalaVersion := "2.13.14"
val chiselVersion = "3.6.1"
addCompilerPlugin("edu.berkeley.cs" %% "chisel3-plugin" % chiselVersion cross CrossVersion.full)
libraryDependencies += "edu.berkeley.cs" %% "chisel3" % chiselVersion
libraryDependencies += "edu.berkeley.cs" %% "chiseltest" % "0.6.2"
To confirm things work, we can run sbt in console mode and import chisel
sbt console
scala> import chisel3._
import chisel3._
scala> Bits
val res0: chisel3.Bits.type = chisel3.package$Bits$@185a2b97
Then, Blinky
Modules can be defined as follows:
$ more src/main/scala/blinky/Blinky.scala
import chisel3._
import chisel3.util.Counter
import circt.stage.ChiselStage
class Blinky(freq: Int, startOn: Boolean = false) extends Module {
val io = IO(new Bundle {
val led0 = Output(Bool())
})
// Blink LED every second using Chisel built-in util.Counter
val led = RegInit(startOn.B)
val (_, counterWrap) = Counter(true.B, freq / 2)
when(counterWrap) {
led := ~led
}
io.led0 := led
}
object Main extends App {
// These lines generate the Verilog output
println(
ChiselStage.emitSystemVerilog(
new Blinky(1000),
firtoolOpts = Array("-disable-all-randomization", "-strip-debug-info")
)
)
}
Finally, we have generated verilog. That was easy.
// Generated by CIRCT firtool-1.37.0
module Blinky(
input clock,
reset,
output io_led0
);
reg led;
reg [8:0] counterWrap_c_value;
always @(posedge clock) begin
if (reset) begin
led <= 1'h0;
counterWrap_c_value <= 9'h0;
end
else begin
automatic logic counterWrap = counterWrap_c_value == 9'h1F3;
led <= counterWrap ^ led;
if (counterWrap)
counterWrap_c_value <= 9'h0;
else
counterWrap_c_value <= counterWrap_c_value + 9'h1;
end
end // always @(posedge)
assign io_led0 = led;
endmodule