Salatkopf Salatkopf - 3 months ago 21
Scala Question

Chisel3. Functional Module Mux4

I'm learning Chisel following the documentation on Github

Thus far, everything worked flawlessly. But i'm stuck at chapter 13, "Functional Module Creation"

I can't get the code to work. I created all my .scala classes in a copy of the chisel-template-project. Here is what i wrote / copied to create a Mux4 with variable bit width:

/chisel-template/src/main/scala/Mux4.scala

import Chisel._

class Mux4(w: Int) extends Module {
val io = IO(new Bundle {
val sel = UInt(INPUT, 2)
val in0 = UInt(INPUT, w)
val in1 = UInt(INPUT, w)
val in2 = UInt(INPUT, w)
val in3 = UInt(INPUT, w)
val out = UInt(OUTPUT, w)
})

io.out := Mux2(io.sel(1),
Mux2(io.sel(0), io.in0, io.in1),
Mux2(io.sel(0), io.in2, io.in3))
}


class Mux2(w: Int) extends Module {
val io = IO(new Bundle {
val sel = Bool(INPUT)
val in0 = UInt(INPUT, w)
val in1 = UInt(INPUT, w)
val out = UInt(OUTPUT, w)
})

when(io.sel) {
io.out := io.in0
}.otherwise {
io.out := io.in1
}
}


object Mux2 {
def apply(sel: UInt, in0: UInt, in1: UInt): UInt = {
val m = new Mux2(in0.getWidth)
m.io.sel := sel.toBool()
m.io.in0 := in0
m.io.in1 := in1
m.io.out
}
}


The Tester scala class i wrote:

/chisel-template/src/test/scala/Mux4Test.scala

import Chisel.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}

class Mux4Test(c: Mux4) extends PeekPokeTester(c) {

val sel = 3
val (in0, in1, in2, in3) = (5, 7, 11, 15)

poke(c.io.sel, sel)
poke(c.io.in0, in0)
poke(c.io.in1, in1)
poke(c.io.in2, in2)
poke(c.io.in3, in3)
step(1)
System.out.println("Circuit: "+peek(c.io.out)
+" Expected: "+TestMux4.result(sel, in0, in1, in2, in3))
}

object TestMux4{
def result(sel: Int, in0: Int, in1: Int, in2: Int, in3: Int): Int = {
val out = sel match{
case 0 => in3
case 1 => in2
case 2 => in1
case 3 => in0
}
out
}
}

class Mux4Tester extends ChiselFlatSpec {
behavior of "Mux4"
backends foreach {backend =>
it should s"do Mux4 $backend" in {
Driver(() => new Mux4(4), backend)(c => new Mux4Test(c)) should be (true)
}
}
}


The important part from the output

STEP 0 -> 1
Circuit: 0 Expected: 5


The Mux4 class (Circuit) returns 0 as output, whereas it should be 5, because the selection process is as follows:

00 -> io.out = in3 = 15

01 -> io.out = in2 = 11

10 -> io.out = in1 = 7

11 -> io.out = in0 = 5

In the Mux4Test.scala class i wrote val sel = 3. The bit representation of this is 11 and therefore i'd expect in0 = 5.

Where am i wrong?

Answer

Thank you for your interest in Chisel!

I ran your example, and after scratching my head for a while I found the problem: when you instantiate a Chisel Module, you need to make sure to wrap it in Module(...) (EDIT: The code on the wiki omitted this wrapper. This has been fixed). Thus, object Mux2 should instead be:

object Mux2 {
  def apply(sel: UInt, in0: UInt, in1: UInt): UInt = {
    val m = Module(new Mux2(in0.getWidth)) // <- See Here
    m.io.sel := sel.toBool()
    m.io.in0 := in0
    m.io.in1 := in1
    m.io.out
  }
}

With this change, it looks like the code works!