Chisel3 vs Chisel2
Chisel2 Migration
For those moving from Chisel2, there were some backwards incompatible changes and your RTL needs to be modified to work with Chisel3. The required modifications are:
-
Wire declaration style:
val wire = UInt(width = 15)
becomes (in Chisel3):
val wire = Wire(UInt(15.W))
-
I/O declaration style:
val done = Bool(OUTPUT)
becomes (in Chisel3):
val wire = Output(Bool())
-
Sequential memories:
val addr = Reg(UInt()) val mem = Mem(UInt(8.W), 1024, seqRead = true) val dout = when(enable) { mem(addr) }
becomes (in Chisel3):
val addr = UInt() val mem = SyncReadMem(1024, UInt(8.W)) val dout = mem.read(addr, enable)
Notice the address register is now internal to the SyncReadMem(), but the data will still return on the subsequent cycle.
-
Generating Verilog with
object Hello { def main(args: Array[String]): Unit = { chiselMain(Array("--backend", "v"), () => Module(new Hello())) } }
becomes (in Chisel3):
object Hello { def main(args: Array[String]): Unit = { chisel3.Driver.execute(Array[String](), () => new Hello()) } }
-
Package changes:
- Chisel.log2Ceil -> chisel3.util.log2Ceil
- BitPat
- Decoupled is also in chisel3.util
Please refer to the Chisel3 compatibility section for instructions on preparing your Chisel2 designs for Chisel3.
Deprecated Usage
Vec(Reg)
should be replaced withReg(Vec)
,- type-only vals (no associated data) must be wrapped in a
Wire()
if they will be the destination of a wiring operation (“:=” or “ < >”), - masked bit patterns (‘b??’) should be created using BitPat(), not UInt() or Bits(),
- the
clone
method required for parameterized Bundles has been renamedcloneType
, - the con and alt inputs to a Mux must be type-compatible - both signed or both unsigned,
- bulk-connection to a node that has been procedurally assigned-to is illegal,
!=
is deprecated, use=/=
instead,- use
SyncReadMem(...)
instead ofMem(..., seqRead)
, - use
SyncReadMem(n:Int, out: => T)
instead ofSyncReadMem(out: => T, n:Int)
, - use
SyncReadMem(...)
instead ofSeqMem(...)
, - use
Mem(n:Int, t:T)
instead ofMem(out:T, n:Int)
, - use
Vec(n:Int, gen: => T)
instead ofVec(gen: => T, n:Int)
, - module io’s must be wrapped in
IO()
. - The methods
asInput
,asOutput
, andflip
should be replaced by theInput()
,Output()
, andFlipped()
object apply methods.
Unsupported constructs
Mem(..., orderedWrites)
is no longer supported,- masked writes are only supported for
Mem[Vec[_]]
, - Chisel3 Vecs must all have the same type, unlike with Chisel2. Use
MixedVec
(see Bundles and Vecs) for Vecs where the elements are of different types. - connections between
UInt
andSInt
are illegal. - the
Node
class and object no longer exist (the class should have been private in Chisel2) printf()
is defined in the Chisel object and produces simulation printf()’s. To use the ScalaPredef.printf()
, you need to qualify it withPredef
.- in Chisel2, bulk-connects
<>
with unconnected source components do not update connections from the unconnected components. ** In Chisel3, bulk-connects strictly adhere to last connection semantics and unconnected OUTPUTs will be connected to INPUTs resulting in the assignment of random values to those inputs. - In Chisel3, adding hardware inside
BlackBox
for simulation is no longer supported. (#289) ChiselError
is gone- Change
ChiselError.error("error msg")
tothrow new Error("error msg")
- Change
ChiselError.info("info msg")
toprintln("info msg")
- Change
- In Chisel3, subword assignments are not supported. Alternative constructions exist in Chisel3.
Further changes
- The clock signal was renamed from
clk
toclock
in Chisel3. - Change
getWidth()
togetWidth
Packaging
Chisel3 is implemented as several packages. The core DSL is differentiated from utility or library classes and objects, testers, and interpreters. The prime components of the Chisel3 front end (the DSL and library objects) are:
- coreMacros - source locators provide Chisel line numbers for
firrtl
detected errors, - chiselFrontend - main DSL components,
- chisel3 - compiler driver, interface packages, compatibility layer.
Due to the wonders of sbt
, you need only declare a dependency on the chisel3 package, and the others will be downloaded as required.
The firrtl
compiler is distributed as a separate package, and release versions will also be downloaded automatically as required.
If you choose to integrate the compiler into your own toolchain, or you’re working with the development (master) branch of chisel3, you should clone the firrtl repo
and follow the instructions for installing the firrtl
compiler.
The testers in Chisel3 are distributed as a separate package.
If you intend to use them in your tests, you will either need to clone the chisel-testers repo
or declare a dependency on the published version of the package.
See the build.sbt
file in either the chisel-template or chisel-tutorial
repos for examples of the latter.
Simulation
Chisel2 was capable of directly generating a C++
simulation from the Chisel code, or a harness for use with a vcs
simulation.
Chisel3 relies on verilator to generate the C++
simulation from the Verilog output of firrtl
.
See the Chisel3 README for directions on installing verilator
.
Compile Options and Front End Checks (Strict vs. NotStrict)
Chisel3 introduces a formal specification for hardware circuit graphs: FIRRTL,
and Chisel3 itself (the Scala library implementing the Chisel DSL), is a relatively thin front end that generates FIRRTL.
Since the firrtl
parser needs to validate FIRRTL input, most of the checks that were performed in Chisel2 were eliminated
from the initial Chisel3 front end (the DRY principle).
However, this does impact the ability to provide detailed messages for error conditions that could be detected in the Chisel3 front end. The decision was made to optionally enable stricter error checking (for connections and the use of raw types versus hardware objects), based on specific imports. This allows designs to move from less strict front end checks (largely compatible with Chisel2), to stricter checking, on a file by file basis, by adjusting specific import statements.
import chisel3.core.ExplicitCompileOptions.Strict
enables stricter connection and usage checks, while
import chisel3.core.ExplicitCompileOptions.NotStrict
defers these checks to the firrtl
compiler.
By default, the Chisel
compatibility layer, invoked by:
import Chisel._
implicitly defines the compile options as chisel3.core.ExplicitCompileOptions.NotStrict
whereas the Chisel3 package, invoked by:
import chisel3._
implicitly defines the compile options as chisel3.core.ExplicitCompileOptions.Strict
Again, these implicit compile options definitions may be overridden by explicit imports.
Currently, the specific error checks (found in CompileOptions.scala) are:
trait CompileOptions {
// Should Bundle connections require a strict match of fields.
// If true and the same fields aren't present in both source and sink, a MissingFieldException,
// MissingLeftFieldException, or MissingRightFieldException will be thrown.
val connectFieldsMustMatch: Boolean
// When creating an object that takes a type argument, the argument must be unbound (a pure type).
val declaredTypeMustBeUnbound: Boolean
// Module IOs should be wrapped in an IO() to define their bindings before the reset of the module is defined.
val requireIOWrap: Boolean
// If a connection operator fails, don't try the connection with the operands (source and sink) reversed.
val dontTryConnectionsSwapped: Boolean
// If connection directionality is not explicit, do not use heuristics to attempt to determine it.
val dontAssumeDirectionality: Boolean
// Issue a deprecation warning if Data.{flip, asInput,asOutput} is used
// instead of Flipped, Input, or Output.
val deprecateOldDirectionMethods: Boolean
// Check that referenced Data have actually been declared.
val checkSynthesizable: Boolean
}
chisel3.core.ExplicitCompileOptions.Strict
sets all CompileOptions fields to true and
chisel3.core.ExplicitCompileOptions.NotStrict
sets them all to false.
Clients are free to define their own settings for these options.
Examples may be found in the test CompileOptionsSpec