0% found this document useful (0 votes)
105 views

Chisel3 Cheat Sheet: Basic Data Types

This document provides a cheat sheet for the Chisel hardware description language, summarizing basic data types, operators, constructs like registers and memories, and common functions and methods. It covers essential Chisel concepts like defining modules, generating and connecting wires, and conditionally executing code blocks. The summary is intended to give a high-level overview of Chisel's capabilities for hardware modeling and code generation.

Uploaded by

ghdufos
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
105 views

Chisel3 Cheat Sheet: Basic Data Types

This document provides a cheat sheet for the Chisel hardware description language, summarizing basic data types, operators, constructs like registers and memories, and common functions and methods. It covers essential Chisel concepts like defining modules, generating and connecting wires, and conditionally executing code blocks. The summary is intended to give a high-level overview of Chisel's capabilities for hardware modeling and code generation.

Uploaded by

ghdufos
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 2

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

You might also like