Chisel3 Cheat Sheet                         Basic Data Types                                          Operators:
Version 0.5.1 (beta): February 28, 2021         Constructors:                                             Chisel       Explanation             Width
                                                        Bool()                      type, boolean value           !x           Logical NOT             1
 Notation In This Document:
                                                        true.B or false.B           literal values                x && y       Logical AND             1
 For Functions and Constructors:
                                                        UInt(32.W)                  type 32-bit unsigned          x || y       Logical OR              1
 Arguments given as kwd:type (name and type(s))
                                                        UInt()                      type, width inferred          x(n)         Extract bit, 0 is LSB 1
 Arguments in brackets ([...]) are optional.
                                                        77.U or "hdead".U           unsigned literals             x(n, m)      Extract bitfield        n - m + 1
 For Operators:
                                                        1.U(16.W)                   literal with forced width     x << y       Dynamic left shift      w(x) + maxVal(y)
 c, x, y are Chisel Data; n, m are Scala Int
                                                        SInt() or SInt(64.W)        like UInt                     x >> y       Dynamic right shift w(x) - minVal(y)
 w(x), w(y) are the widths of x, y (respectively)
                                                        -3.S or "h-44".S            signed literals               x << n       Static left shift       w(x) + n
 minVal(x), maxVal(x) are the minimum or
                                                        3.S(2.W)                    signed 2-bits wide value -1   x >> n       Static right shift      w(x) - n
   maximum possible values of x                         Bits, UInt, SInt Casts: reinterpret cast except for:
                                                                                                                  Fill(n, x) Replicate x, n times n * w(x)
Basic Chisel Constructs                                 UInt → SInt             Zero-extend to SInt
                                                                                                                  Cat(x, y)    Concatenate bits        w(x) + w(y)
Chisel Wire Operators:                                  State Elements                                            Mux(c, x, y) If c, then x; else y    max(w(x), w(y))
                                                                                                                  ~x           Bitwise NOT             w(x)
 // Allocate a as wire of type UInt ()                  Registers retain state until updated
 val x = Wire ( UInt ())                                                                                          x & y        Bitwise AND             max(w(x), w(y))
                                                        val my_reg = Reg(UInt(32.W))                              x | y        Bitwise OR              max(w(x), w(y))
 x := y // Connect wire y to wire x
                                                        Flavors                                                   x ^ y        Bitwise XOR             max(w(x), w(y))
When executes blocks conditionally by Bool,              RegInit(7.U(32.w))          reg with initial value 7
                                                                                                                  x === y      Equality(triple equals) 1
 and is equivalent to Verilog if                         RegNext(next_val)           update each clock, no init
                                                                                                                  x =/= y      Inequality              1
                                                         RegEnable(next, enable) update, with enable gate
 when ( condition1 ) {                                                                                            x + y        Addition                max(w(x),w(y))
                                                        Updating: assign to latch new value on next clock:
   // run if condition1 true and skip rest                                                                        x +% y       Addition                max(w(x),w(y))
 } . elsewhen ( condition2 ) {                          my_reg := next_val
                                                                                                                  x +& y       Addition                max(w(x),w(y))+1
   // run if condition2 true and skip rest              Read-Write Memory provide addressable memories            x - y        Subtraction             max(w(x),w(y))
 } . otherwise {
                                                        val my_mem = Mem(n:Int, out:Data)                         x -% y       Subtraction             max(w(x),w(y))
   // run if none of the above ran
                                                         out memory element type                                  x -& y       Subtraction             max(w(x),w(y))+1
 }
                                                         n memory depth (elements)                                x * y        Multiplication          w(x)+w(y)
Switch executes blocks conditionally by data            Using: access elements by indexing:                       x / y        Division                w(x)
 switch ( x ) {                                         val readVal = my_mem(addr:UInt/Int)                       x % y        Modulus                 bits(maxVal(y)-1)
   is ( value1 ) {                                        for synchronous read: assign output to Reg              x > y        Greater than            1
      // run if x === value1                            my_mem(addr:UInt/Int) := y                                x >= y       Greater than or equal 1
   }                                                                                                              x < y        Less than               1
   is ( value2 ) {                                      Modules                                                   x <= y       Less than or equal      1
      // run if x === value2                            Defining: subclass Module with elements, code:
                                                                                                                  x >> y       Arithmetic right shift w(x) - minVal(y)
   }                                                     class Accum ( width : Int ) extends Module {
                                                                                                                  x >> n       Arithmetic right shift w(x) - n
 }                                                          val io = IO ( new Bundle {
                                                               val in = Input ( UInt ( width . W ))
Enum generates value literals for enumerations                 val out = Output ( UInt ( width . W ))
val s1::s2:: ... ::sn::Nil                                  })                                                    UInt bit-reduction methods:
     = Enum(nodeType:UInt, n:Int)                           val sum = Reg ( UInt ())                               Chisel              Explanation                Width
 s1, s2, ..., sn will be created as nodeType literals       sum := sum + io . in
                                                                                                                   x.andR              AND-reduce                 1
                 with distinct values                       io . out := sum
                                                                                                                   x.orR               OR-reduce                  1
 nodeType        type of s1, s2, ..., sn                 }
                                                                                                                   x.xorR              XOR-reduce                 1
 n               element count                          Usage: access elements using dot notation:                As an example to apply the andR method to an   SInt use
                                                          (code inside a Module is always running)                x.asUInt.andR
Math Helpers:
                                                         val my_module = Module ( new Accum (32))
log2Ceil(in:Int): Int log2 (in) rounded up
                                                         my_module . io . in := some_data
log2Floor(in:Int): Int log2 (in) rounded down
                                                         val sum := my_module . io . out
isPow2(in:Int): Boolean True if in is a power of 2
Hardware Generation                                          .indexWhere(p:T=>Bool): UInt                             gen Chisel Data to wrap ready-valid protocol around
                                                             .lastIndexWhere(p:T=>Bool): UInt                        Interface:
Functions provide block abstractions for code. Scala         .onlyIndexWhere(p:T=>Bool): UInt                          (in) .ready ready Bool
functions that instantiate or return Chisel types are code                                                            (out) .valid valid Bool
generators.                                                  Standard Library: Function Blocks
                                                                                                                      (out) .bits data
                                                             Stateless:
Also: Scala’s if and for can be used to control              PopCount(in:Bits/Seq[Bool]): UInt                       ValidIO is a Bundle with a valid interface
hardware generation and are equivalent to Verilog              Returns number of hot (= 1) bits in in                Constructor:
generate if/for                                              Reverse(in:UInt): UInt                                  Valid(gen:Data)
 val number = Reg ( if ( can_be_negative ) SInt ()             Reverses the bit order of in                           gen Chisel Data to wrap valid protocol around
                    else UInt ())                            UIntToOH(in:UInt, [width:Int]): Bits                    Interface :
will create a Register of type SInt or UInt depending on                                                              (out) .valid valid Bool
                                                              Returns the one-hot encoding of in
the value of a Scala variable                                                                                         (out) .bits data
                                                              width (optional, else inferred) output width
                                                             OHToUInt(in:Bits/Seq[Bool]): UInt                       Queue is a Module providing a hardware queue
Aggregate Types                                                                                                      Constructor:
                                                               Returns the UInt representation of one-hot in
Bundle contains Data types indexed by name                   PriorityEncoder(in:Bits/Iterable[Bool]): UInt           Queue(enq:DecoupledIO, entries:Int)
Defining: subclass Bundle, define components:                  Returns the position the least significant 1 in in     enq       DecoupledIO source for the queue
 class MyBundle extends Bundle {                             PriorityEncoderOH(in:Bits): UInt                         entries   size  of queue
                                                                                                                     Interface:
   val a = Bool ()                                             Returns the position of the hot bit in in              .io.enq DecoupledIO source (flipped)
   val b = UInt (32. W )                                     Mux1H(in:Iterable[(Data, Bool]): Data
 }
                                                                                                                      .io.deq DecoupledIO sink
                                                             Mux1H(sel:Bits/Iterable[Bool],                           .io.count UInt count of elements in the queue
Constructor: instantiate Bundle subclass:                             in:Iterable[Data]): Data
val my_bundle = new MyBundle()                                                                                       Pipe is a Module delaying input data
                                                             PriorityMux(in:Iterable[(Bool, Bits]): Bits
                                                                                                                     Constructor:
Inline defining: define a Bundle type:                       PriorityMux(sel:Bits/Iterable[Bool],
                                                                                                                     Pipe(enqValid:Bool, enqBits:Data, [latency:Int])
 val my_bundle = new Bundle {                                                       in:Iterable[Bits]): Bits
   val a = Bool ()                                            A mux tree with either a one-hot select or multiple    Pipe(enq:ValidIO, [latency:Int])
   val b = UInt (32. W )                                         selects (where the first inputs are prioritized)     enqValid input data, valid component
 }                                                            in iterable of combined input and select (Bool, Bits) enqBits input data, data component
                                                                    tuples or just mux input Bits                     enq        input data as ValidIO
Using: access elements through dot notation:
                                                              sel select signals or bitvector, one per input          latency    (optional, default 1) cycles to delay data by
val bundleVal = my_bundle.a
                                                                                                                     Interface:
my_bundle.a := true.B                                        Stateful:                                                .io.enq ValidIO source (flipped)
Vec is an indexable vector of Data types                                                                              .io.deq ValidIO sink
val myVec = Vec(elts:Iterable[Data])                         Counter(n:Int]): UInt                                   Arbiters are Modules connecting multiple producers
 elts initial element Data (vector depth inferred)             .inc() bumps counter returning true when n reached      to one consumer
val myVec = Vec.fill(n:Int) {gen:Data}                         .value returns current value                          Arbiter prioritizes lower producers
 n vector depth (elements)                                   LFSR16([increment:Bool]): UInt                          RRArbiter runs in round-robin order
                                                              16-bit LFSR (to generate pseudorandom numbers)
 gen initial element Data, called once per element                                                                   Constructor:
                                                              increment (optional, default True) shift on next clock
Using: access elements by dynamic or static indexing:                                                                Arbiter(gen:Data, n:Int)
                                                             ShiftRegister(in:Data, n:Int, [en:Bool]): Data
readVal := myVec(ind: UInt / idx: Int)                                                                                gen data type
                                                              Shift register, returns n-cycle delayed input in
myVec(ind: UInt / idx: Int) := writeVal                                                                               n number of producers
                                                              en (optional, default True) enable
Functions: (T is the Vec element’s type)                                                                             Interface:
 .forall(p:T=>Bool): Bool AND-reduce p on all elts           Standard Library: Interfaces                             .io.in         Vec of DecoupledIO inputs (flipped)
 .exists(p:T=>Bool): Bool OR-reduce p on all elts            DecoupledIO is a Bundle with a ready-valid interface     .io.out        DecoupledIO output
 .contains(x:T): Bool           True if this contains x      Constructor:                                             .io.chosen     UInt input index on .io.out,
 .count(p:T=>Bool): UInt count elts where p is True          Decoupled(gen:Data)                                                     does not imply output is valid