Skip to content

Instantly share code, notes, and snippets.

@edcote edcote/chisel3.md
Last active Apr 5, 2018

Embed
What would you like to do?
Chisel3

Notes taken from: http://palms.ee.princeton.edu/system/files/Chisel+Overview.pdf

Datatypes

  • SInt, UInt, Bool, Clock

  • Examples:

val a = 5.S // signed decimal 4-bit lit from Scala Int
val b = "b1010".U // binary 4-bit lit from string
val c = true.B // Bool lit from Scala lit
val d = 5.U(8.W) // unsigned decimal 8-bit lit of type UInt
val e = "h_dead_beef".U // unsigned 32-bit lit of type UInt
  • .W is used to cast a Scala Int to a Chisel Width

Combinational Circuits and Wires

  • A circuit is represented as a graph of nodes

  • Examples:

val wire1 = false.B
val wire2 = (a & b) | (~c & d)
val wire3 = wire1 ^ wire2
//wire3 = true.B // not allowed

val myWire = Wire(UInt(8.W)) // allocate a wire of type UInt, width 8
myWire := 255.U
myWire := 0.U // connect to myWire, last one takes effect

Registers

  • Examples:
val r1 = Reg(UInt(4.W)) // reg without initialization
val r2 = RegInit(UInt(), 3.U(8.W)) // initialized to 0 upon reset
val r3 = RegInit(wire1) // type and width inferred
val r4 = RegNext(pcNext, 0.U(32.W)) // output a copy of pcNext
                                    // delayed by one clock cycle
r3 := next_val // assign to latch new value on next clock

Memory

  • Writes to Mem are posedge triggered and reads are either async or posedge triggered
val rf = Mem(256, UInt(8.W))
rf(42) := 3.U
val data = rf(42)
  • Better example
class Top(implicit val p: Parameters) extends Module {
  val io = IO(new Bundle {
    val adr = Input(UInt(5.W))
    val we = Input(Bool())
    val re = Input(Bool())
    val wdat = Input(UInt(18.W))
    val rdat = Output(UInt(18.W))
  })

  val mem = SyncReadMem(32, UInt(18.W))

  val rdat = WireInit(UInt(), 0.U(18.W))
  io.rdat := rdat

  when(io.we) {
    mem.write(io.adr, io.wdat)
  }.otherwise {
    rdat := mem.read(io.adr, io.re)
  }
}

Aggregate Types

  • Bundles
class MyBundle extends Bundle {
  val field1 = Bool()
  val field2 = UInt(8.W)
}
val x = Wire(new MyBundle)
x.field1 := true.B
val wire1 = x.field1 // true
  • Vecs (arrays), are 0 indexed
val myVec = Wire(Vec(5, SInt(23.W)))
myVec(0) := 3.U

val wire0 = myVec(0) // 3
val reg = RegInit(myVec(4)) // 0
val x = Vec(Array(1.U, 2.U, 3.U, 4.U, 5.U))

Ports

  • Any data object that has directions assigned to its fields
class ScaleIO extends Bundle {
  val valid = Input(Bool())
  val in = Input(UInt(32.W))
  val scale = Input(UInt(32.W))
  val out = Output(UInt(32.W))
}

Modules

  • Declarating a port inside a module
class Mux2 extends Module { // subclass of Module
  val io = IO(new Bundle { // io port
    val sel = Input(UInt(1.W))
    val in0 = Input(UInt(1.W))
    val in1 = Input(UInt(1.W))
    val out = Output(UInt(1.W))
  })
  io.out := (io.sel & io.in1) | (~io.sel & io.in0)
}
  • Instantiating modules
val myMux2 = Module(new Mux2())
myMux2.io.sel := 1.U
myMux2.io.in0 := 1.U
myMux2.io.in1 := 0.U

val r1 = Reg(UInt(1.W))
r1 := myMux2.io.out
  • Functional module creation, use companion object apply function
object Mux2 {
  def apply (sel: UInt, in0: UInt, in1: UInt) = {
    val m = Module(new Mux2)
    m.io.in0 := in0
    m.io.in1 := in1
    m.io.sel := sel
    m.io.out // return value
  }
}

  val r1 = Mux2(1.U, 1.U, 0.U) // much simpler

Conditional updates

  • Used to specify when updates to elements occur
when (c1) { u1 }
.elsewhen (c2) { u2 }
.otherwise { ud }
switch (idx) {
  is(v1) { u1 }
  is(v2) { u2 }
}

State elements

  • Updates with := are positive edge triggered
val r = Reg(SInt(2.W)); val s = Reg(SInt(2.W))
r := 3.S; s := 3.S
when (c1) {r := 1.S; s := 1.S}
when (c2) {r := 2.S}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.