Cookbook - lu-ping/chisel3 GitHub Wiki
Welcome to the Chisel cookbook. This cookbook is still in early stages. If you have any requests or examples to share, please file an issue and let us know!
Please note that these examples make use of [Chisel's scala-style printing](Printing in Chisel#scala-style).
- How do I create a UInt from an instance of a Bundle?
- How do I create a Bundle from a UInt?
- How do I create a Vec of Bools from a UInt?
- How do I create a UInt from a Vec of Bool?
- How do I create a Vector of Registers?
- How do I create a Reg of type Vec?
- How do I create a finite state machine?
- How do I unpack a value ("reverse concatenation") like in Verilog?
- How do I do subword assignment (assign to some bits in a UInt)?
How do I create a UInt from an instance of a Bundle?
Call asUInt on the Bundle instance
// Example
class MyBundle extends Bundle {
val foo = UInt(4.W)
val bar = UInt(4.W)
}
val bundle = Wire(new MyBundle)
bundle.foo := 0xc.U
bundle.bar := 0x3.U
val uint = bundle.asUInt
printf(p"$uint") // 195
// Test
assert(uint === 0xc3.U)
How do I create a Bundle from a UInt?
On an instance of the Bundle, call the method fromBits with the UInt as the argument
// Example
class MyBundle extends Bundle {
val foo = UInt(4.W)
val bar = UInt(4.W)
}
val uint = 0xb4.U
val bundle = (new MyBundle).fromBits(uint)
printf(p"$bundle") // Bundle(foo -> 11, bar -> 4)
// Test
assert(bundle.foo === 0xb.U)
assert(bundle.bar === 0x4.U)
How do I create a Vec of Bools from a UInt?
Use the builtin function chisel3.core.Bits.toBools to create a Scala Seq of Bool, then wrap the resulting Seq in Vec(...)
// Example
val uint = 0xc.U
val vec = Vec(uint.toBools)
printf(p"$vec") // Vec(0, 0, 1, 1)
// Test
assert(vec(0) === false.B)
assert(vec(1) === false.B)
assert(vec(2) === true.B)
assert(vec(3) === true.B)
How do I create a UInt from a Vec of Bool?
Use the builtin function asUInt
// Example
val vec = Vec(true.B, false.B, true.B, true.B)
val uint = vec.asUInt
printf(p"$uint") // 13
/* Test
*
* (remember leftmost Bool in Vec is low order bit)
*/
assert(0xd.U === uint)
Vectors and Registers
How do I create a Vector of Registers?
Rule! Use Reg of Vec not Vec of Reg!
You create a Reg of type Vec. Because Vecs are a type (like UInt
, Bool
) rather than a value, we must bind the Vec to some concrete value.
How do I create a Reg of type Vec?
For information, please see the API documentation (https://chisel.eecs.berkeley.edu/api/index.html#chisel3.core.Vec)
// Reg of Vec of 32-bit UInts without initialization
val regOfVec = Reg(Vec(4, UInt(32.W)))
regOfVec(0) := 123.U // a couple of assignments
regOfVec(2) := regOfVec(0)
// Reg of Vec of 32-bit UInts initialized to zero
// Note that Seq.fill constructs 4 32-bit UInt literals with the value 0
// Vec(...) then constructs a Wire of these literals
// The Reg is then initialized to the value of the Wire (which gives it the same type)
val initRegOfVec = Reg(init = Vec(Seq.fill(4)(0.U(32.W))))
// Simple test (cycle comes from superclass)
when (cycle === 2.U) { assert(regOfVec(2) === 123.U) }
for (elt <- initRegOfVec) { assert(elt === 0.U) }
How do I create a finite state machine?
Use Chisel Enum to construct the states and switch & is to construct the FSM control logic.
class DetectTwoOnes extends Module {
val io = IO(new Bundle {
val in = Input(Bool())
val out = Output(Bool())
})
val sNone :: sOne1 :: sTwo1s :: Nil = Enum(3)
val state = Reg(init = sNone)
io.out := (state === sTwo1s)
switch (state) {
is (sNone) {
when (io.in) {
state := sOne1
}
}
is (sOne1) {
when (io.in) {
state := sTwo1s
} .otherwise {
state := sNone
}
}
is (sTwo1s) {
when (!io.in) {
state := sNone
}
}
}
}
How do I unpack a value ("reverse concatenation") like in Verilog?
wire [1:0] a;
wire [3:0] b;
wire [2:0] c;
wire [8:0] z = [...];
assign {a,b,c} = z;
Unpacking often corresponds to reinterpreting an unstructured data type as a structured data type. Frequently, this structured type is used prolifically in the design, and has been declared as in the following example:
class MyBundle extends Bundle {
val a = UInt(2.W)
val b = UInt(4.W)
val c = UInt(3.W)
}
The easiest way to accomplish this in Chisel would be:
val z = Wire(UInt(9.W))
// z := ...
val unpacked = z.asTypeOf(new MyBundle)
unpacked.a
unpacked.b
unpacked.c
If you really need to do this for a one-off case (Think thrice! It is likely you can better structure the code using bundles), then rocket-chip has a Split utility which can accomplish this.
How do I do subword assignment (assign to some bits in a UInt)?
Example:
class TestModule extends Module {
val io = IO(new Bundle {
val in = Input(UInt(10.W))
val bit = Input(Bool())
val out = Output(UInt(10.W))
})
io.out(0) := io.bit
}
Chisel3 does not support subword assignment. We find that this type of thing can usually be better expressed with aggregate/structured types: Bundles and Vecs.
If you must express it this way, you can blast your UInt to a Vec of Bools and back:
class TestModule extends Module {
val io = IO(new Bundle {
val in = Input(UInt(10.W))
val bit = Input(Bool())
val out = Output(UInt(10.W))
})
val bools = VecInit(io.in.toBools)
bools(0) := io.bit
io.out := bools.asUInt
}