Skip to main content

Frequently Asked Questions

Where should I start if I want to learn Chisel?

We recommend the Chisel Bootcamp for getting started with Chisel.

How do I do ... (e.g. like that in Verilog) in Chisel?

See the cookbooks.

What versions of the various projects work together?

See Chisel Project Versioning.

How can I contribute to Chisel?

Check out the Contributor Documentation in the chisel3 repository.

Why DecoupledIO instead of ReadyValidIO?

There are multiple kinds of Ready/Valid interfaces that impose varying restrictions on the producers and consumers. Chisel currently provides the following:

  • DecoupledIO - No guarantees
  • IrrevocableIO - Producer promises to not change the value of 'bits' after a cycle where 'valid' is high and 'ready' is low. Additionally, once 'valid' is raised it will never be lowered until after 'ready' has also been raised.

Why do I have to wrap module instantiations in Module(...)?

In short: Limitations of Scala

Chisel Modules are written by defining a Scala class and implementing its constructor. As elaboration runs, Chisel constructs a hardware AST from these Modules. The compiler needs hooks to run before and after the actual construction of the Module object. In Scala, superclasses are fully initialized before subclasses, so by extending Module, Chisel has the ability to run some initialization code before the user's Module is constructed. However, there is no such hook to run after the Module object is initialized. By wrapping Module instantiations in the Module object's apply method (ie. Module(...)), Chisel is able to perform post-initialization actions. There is a proposed solution, so eventually this requirement will be lifted, but for now, wrap those Modules!

Why Chisel?

Please see Chisel Motivation

Does Chisel support X and Z logic values

Chisel does not directly support Verilog logic values x unknown and z high-impedance. There are a number of reasons to want to avoid these values. See:The Dangers of Living With An X and Malicious LUT: A stealthy FPGA Trojan injected and triggered by the design flow. Chisel has its own eco-system of unit and functional testers that limit the need for x and z and their omission simplify language implementation, design, and testing. The circuits created by chisel do not preclude developers from using x and z in downstream toolchains as they see fit.

Get me Verilog

I wrote a module and I want to see the Verilog; what do I do?

Here's a simple hello world module in a file HelloWorld.scala.

package intro
import chisel3._
class HelloWorld extends Module {
val io = IO(new Bundle{})
printf("hello world\n")
}

Add the following

import circt.stage.ChiselStage
object VerilogMain extends App {
ChiselStage.emitSystemVerilog(new HelloWorld)
}

Now you can get some Verilog. Start sbt:

bash> sbt
> run-main intro.VerilogMain
[info] Running intro.VerilogMain
[info] [0.004] Elaborating design...
[info] [0.100] Done elaborating.
[success] Total time: 1 s, completed Jan 12, 2017 6:24:03 PM

or as a one-liner:

bash> sbt 'runMain intro.VerilogMain'

After either of the above there will be a HelloWorld.v file in the current directory:

// Generated by CIRCT firtool-1.73.0

// Users can define 'PRINTF_COND' to add an extra gate to prints.
`ifndef PRINTF_COND_
`ifdef PRINTF_COND
`define PRINTF_COND_ (`PRINTF_COND)
`else // PRINTF_COND
`define PRINTF_COND_ 1
`endif // PRINTF_COND
`endif // not def PRINTF_COND_
module HelloWorld( // faqs.md:11:7
input clock, // faqs.md:11:7
reset // faqs.md:11:7
);

`ifndef SYNTHESIS // faqs.md:13:9
always @(posedge clock) begin // faqs.md:13:9
if ((`PRINTF_COND_) & ~reset) // faqs.md:13:9
$fwrite(32'h80000002, "hello world\n"); // faqs.md:13:9
end // always @(posedge)
`endif // not def SYNTHESIS
endmodule


You can see additional options with

bash> sbt 'runMain intro.HelloWorld --help'

This will return a comprehensive usage line with available options.

For example to place the output in a directory name buildstuff use

bash> sbt 'runMain intro.HelloWorld --target-dir buildstuff --top-name HelloWorld'

Alternatively, you can also use the sbt console to invoke the Verilog driver:

$ sbt
> console
[info] Starting scala interpreter...
Welcome to Scala 2.12.13 (OpenJDK 64-Bit Server VM, Java 1.8.0_275).
Type in expressions for evaluation. Or try :help.

scala> (new circt.stage.ChiselStage).emitSystemVerilog(new HelloWorld())
chisel3.Driver.execute(Array[String](), () => new HelloWorld)
Elaborating design...
Done elaborating.
res1: String =
"module HelloWorld(
input clock,
input reset
);
...

As before, there should be a HelloWorld.v file in the current directory.

Note: Using the following, without the new, will ONLY return the string representation, and will not emit a .v file:

ChiselStage.emitSystemVerilog(new HelloWorld())

Get me FIRRTL

If for some reason you don't want the Verilog (e.g. maybe you want to run some custom transformations before exporting to Verilog), then use something along these lines:

package intro

import chisel3._
import circt.stage.ChiselStage

class MyFirrtlModule extends Module {
val io = IO(new Bundle{})
}

object FirrtlMain extends App {
ChiselStage.emitCHIRRTL(new MyFirrtlModule)
}

Run it with:

sbt 'runMain intro.FirrtlMain'
FIRRTL version 4.0.0
circuit MyFirrtlModule :
public module MyFirrtlModule : @[faqs.md 64:7]
input clock : Clock @[faqs.md 64:7]
input reset : UInt<1> @[faqs.md 64:7]
output io : { } @[faqs.md 65:14]

skip


Alternatively, you can also use the sbt console to invoke the FIRRTL driver directly (replace MyFirrtlModule with your module name):

$ sbt
> console
[info] Starting scala interpreter...
Welcome to Scala 2.12.13 (OpenJDK 64-Bit Server VM, Java 1.8.0_275).
Type in expressions for evaluation. Or try :help.

scala> circt.stage.ChiselStage.emitCHIRRTL(new MyFirrtlModule)
Elaborating design...
Done elaborating.
res3: String = ...

Why doesn't Chisel tell me which wires aren't connected?

As long as your code uses import chisel3._ (and not import Chisel._), it does! See Unconnected Wires for details.

What does Reference ... is not fully initialized. mean?

It means that you have unconnected wires in your design which could be an indication of a design bug.

In Chisel2 compatibility mode (NotStrict compile options), chisel generates firrtl code that disables firrtl's initialized wire checks. In pure chisel3 (Strict compile options), the generated firrtl code does not contain these disablers (is invalid). Output wires that are not driven (not connected) are reported by firrtl as not fully initialized. Read more at Unconnected Wires for details on solving the problem.

Can I specify behavior before and after generated initial blocks?

Users may define the following macros if they wish to specify behavior before or after emitted initial blocks.

  • BEFORE_INITIAL, which is called before the emitted (non-empty) initial block if it is defined
  • AFTER_INITIAL, which is called after the emitted (non-empty) initial block if it is defined

These macros may be useful for turning coverage on and off.