Chisel Cheatsheet

Download as pdf or txt
Download as pdf or txt
You are on page 1of 2

Chisel Cheat Sheet Basic Data Types State Elements

Version 0.5 (beta): May 22, 2015 Constructors: Registers retain state until updated
Notation In This Document: Bool([x:Boolean]) val my_reg = Reg([outType:Data], [next:Data],
For Functions and Constructors: Bits/UInt/SInt([x:Int/String], [width:Int]) [init:Data])
Arguments given as kwd:type (name and type(s)) x (optional) create a literal from Scala type/ outType (optional) register type (or inferred)
Arguments in brackets ([...]) are optional. pased String, or declare unassigned if missing next (optional) update value every clock
For Operators: width (optional) bit width (inferred if missing) init (optional) initialization value on reset
c, x, y are Chisel Data; n, m are Scala Int Bits, UInt, SInt Casts: reinterpret cast except for: Updating: assign to latch new value on next clock:
w(x), w(y) are the widths of x, y (respectively) UInt → SInt Zero-extend to SInt my_reg := next_val
minVal(x), maxVal(x) are the minimum or Bool Operators: The last update (lexically, per clock) runs
maximum possible values of x Chisel Explanation Width Read-Write Memory provide addressable memories
!x Logical NOT 1 val my_mem = Mem(out:Data, n:Int,
Basic Chisel Constructs
x && y Logical AND 1 seqRead:Boolean)
Chisel Wire Operators: x || y Logical OR 1 out memory element type
val x = UInt() Allocate a as wire of type UInt() Bits Operators: n memory depth (elements)
x := y Assign (connect) wire y to wire x Chisel Explanation Width seqRead only update reads on clock edge
x <> y Connect x and y, wire directionality
x(n) Extract bit, 0 is LSB 1 Using: access elements by indexing:
is automatically inferred
x(n, m) Extract bitfield n - m + 1 val readVal = my_mem(addr:UInt/Int)
When executes blocks conditionally by Bool, x << y Dynamic left shift w(x) + maxVal(y) for synchronous read: assign output to Reg
and is equivalent to Verilog if x >> y Dynamic right shift w(x) - minVal(y) mu_mem(addr:UInt/Int) := y
when ( condition1 ) { x << n Static left shift w(x) + n
// run if condition1 true and skip rest Modules
x >> n Static right shift w(x) - n Defining: subclass Module with elements, code:
} . elsewhen ( condition2 ) {
Fill(n, x) Replicate x, n times n * w(x) class Accum ( width : Int ) extends Module {
// run if condition2 true and skip rest
} . unless ( condition3 ) {
Cat(x, y) Concatenate bits w(x) + w(y) val io = new Bundle {
// run if condition3 false and skip rest Mux(c, x, y) If c, then x; else y max(w(x), w(y)) val in = UInt ( INPUT , width )
} . otherwise { ~x Bitwise NOT w(x) val out = UInt ( OUTPUT , width )
// run if none of the above ran x & y Bitwise AND max(w(x), w(y)) }
} x | y Bitwise OR max(w(x), w(y)) val sum = new Reg ( UInt ())
x ^ y Bitwise XOR max(w(x), w(y)) sum := sum + io . in
Switch executes blocks conditionally by data io . out := sum
x === y Equality(triple equals) 1
switch ( x ) { }
is ( value1 ) { x != y Inequality 1
andR(x) AND-reduce 1 Usage: access elements using dot notation:
// run if x === value1
} is ( value2 ) { orR(x) OR-reduce 1 (code inside a Module is always running)
// run if x === value2 xorR(x) XOR-reduce 1 val my_module = Module ( new Accum (32))
} UInt, SInt Operators: (bitwdths given for UInts) my_module . io . in := some_data
} val sum := my_module . io . out
Chisel Explanation Width
Enum generates value literals for enumerations x + y Addition max(w(x), w(y)) Hardware Generation
val s1::s2:: ... ::sn::Nil x - y Subtraction max(w(x), w(y)) Functions provide block abstractions for code
= Enum(nodeType:UInt, n:Int) x * y Multiplication w(x) + w(y) Defining: write Scala functions with Chisel code:
s1, s2, ..., sn will be created as nodeType literals x / y Division w(x) def Adder ( op_a : UInt , op_b : UInt ): UInt = {
with distinct values x % y Modulus bits(maxVal(y) - 1) op_a + op_b
nodeType type of s1, s2, ..., sn x > y Greater than 1 }
n element count x >= y Greater than or equal 1 Usage: hardware is instantiated when called:
Math Helpers: x < y Less than 1 sum := Adder ( UInt (1) , some_data )
log2Up(in:Int): Int log2 (in) rounded up x <= y Less than or equal 1
log2Down(in:Int): Int log2 (in) rounded down x >> y Arithmetic right shift w(x) - minVal(y) If/For can be used to control hardware generation
isPow2(in:Int): Boolean True if in is a power of 2 x >> n Arithmetic right shift w(x) - n and is equivalent to Verilog generate if/for
Aggregate Types PriorityEncoder(in:Bits/Iterable[Bool]): UInt Pipe is a Module delaying input data
Returns the position the least significant 1 in in Constructor:
Bundle contains Data types indexed by name PriorityEncoderOH(in:Bits): UInt Pipe(enqValid:Bool, enqBits:Data, [latency:Int])
Defining: subclass Bundle, define components: Returns the position of the hot bit in in Pipe(enq:ValidIO, [latency:Int])
class MyBundle extends Bundle { Mux1H(in:Iterable[(Data, Bool]): Data enqValid input data, valid component
val a = Bool () Mux1H(sel:Bits/Iterable[Bool], enqBits input data, data component
val b = UInt ( width = 32) in:Iterable[Data]): Data enq input data as ValidIO
}
PriorityMux(in:Iterable[(Bool, Bits]): Bits latency (optional, default 1) cycles to delay data by
Constructor: instantiate Bundle subclass: PriorityMux(sel:Bits/Iterable[Bool], Interface:
val my_bundle = new MyBundle() in:Iterable[Bits]): Bits .io.enq ValidIO source (flipped)
Inline defining: define a Bundle type: A mux tree with either a one-hot select or multiple .io.deq ValidIO sink
val my_bundle = new Bundle { selects (where the first inputs are prioritized) Arbiters are Modules connecting multiple producers
val a = Bool () in iterable of combined input and select (Bool, Bits) to one consumer
val b = UInt ( width = 32) tuples or just mux input Bits Arbiter prioritizes lower producers
} sel select signals or bitvector, one per input RRArbiter runs in round-robin order
Using: access elements through dot notation: Constructor:
Stateful:
val bundleVal = my_bundle.a Arbiter(gen:Data, n:Int)
LFSR16([increment:Bool]): UInt
my_bundle.a := Bool(true) 16-bit LFSR (to generate pseudorandom numbers) gen data type
increment (optional, default True) shift on next clock n number of producers
Vec is an indexable vector of Data types Interface :
ShiftRegister(in:Data, n:Int, [en:Bool]): Data
val myVec = Vec(elts:Iterable[Data]) .io.in Vec of DecoupledIO inputs (flipped)
Shift register, returns n-cycle delayed input in
elts initial element Data (vector depth inferred) .io.out DecoupledIO output
en (optional, default True) enable
val myVec = Vec.fill(n:Int) {gen:Data} .io.chosen UInt input index on .io.out,
n vector depth (elements) Standard Library: Interfaces does not imply output is valid
gen initial element Data, called once per element Tester
DecoupledIO is a Bundle with a ready-valid interface
Using: access elements by dynamic or static indexing: Tester is a class with functions for testing Modules,
Constructor:
readVal := myVec(ind:Data/idx:Int) connecting and communicating with a simulator:
Decoupled(gen:Data)
myVec(ind:Data/idx:Int) := writeVal reset([n:Int]) reset the DUT for n (default 1) clocks
gen Chisel Data to wrap ready-valid protocol around
Functions: (T is the Vec element’s type) step(n:Int) steps the DUT for n clocks
Interface:
.forall(p:T=>Bool): Bool AND-reduce p on all elts (in) .ready ready Bool poke(data:Bits, x:BigInt) writes x to wire data
.exists(p:T=>Bool): Bool OR-reduce p on all elts (out) .valid valid Bool poke(data:Aggregate, x:Array[BigInt])
.contains(x:T): Bool True if this contains x (out) .bits data writes values from x to corresponding wires in data
.count(p:T=>Bool): UInt count elts where p is True
ValidIO is a Bundle with a valid interface peek(data:Bits): BigInt reads from wire data
.indexWhere(p:T=>Bool): UInt peek(data:Aggregate): Array[BigInt]
.lastIndexWhere(p:T=>Bool): UInt Constructor:
Valid(gen:Data) reads multiple values from source wires in data
.onlyIndexWhere(p:T=>Bool): UInt
gen Chisel Data to wrap valid protocol around expect(good:Boolean, msg:String): Boolean
Standard Library: Function Blocks Interface: fails unless good is True, msg should describe the test
(out) .valid valid Bool expect(data:Bits, target:BigInt): Boolean
Stateless: (out) .bits data fails unless the value in wire data equals target
PopCount(in:Bits/Seq[Bool]): UInt Defining:
Queue is a Module providing a hardware queue
Returns number of hot (= 1) bits in in Subclass Tester with testing code:
Constructor:
Reverse(in:UInt): UInt Queue(enq:DecoupledIO, entries:Int) class MuxTester ( c : Mux ) extends Tester ( c ) {
Reverses the bit order of in enq DecoupledIO source for the queue for ( sel <- 0 until 2) {
UIntToOH(in:UInt, [width:Int]): Bits poke ( c . io . sel , sel )
entries size of queue
Returns the one-hot encoding of in poke ( c . io . in0 , 0); poke ( c . io . in1 , 1)
Interface:
width (optional, else inferred) output width .io.enq DecoupledIO source (flipped) step (1)
OHToUInt(in:Bits/Seq[Bool]): UInt expect ( c . io . out , sel )
.io.deq DecoupledIO sink
}
Returns the UInt representation of one-hot in .io.count UInt count of elements in the queue }

You might also like