3

Here's what I'm trying to accomplish: I have a Chisel accelerator which calls another Chisel accelerator and passes in a value. I want the second one to have a while loop in it where the condition is partially based on the input value. Here's some sample code:

class Module1 extends Module {
    val in = 0.U
    val Module2Module = Module2()
    Module2Module.io.in := in
}

class Module2 extends Module {
    val io = IO(new Bundle {
        val in = Input(Reg(UInt))
    }
    val test = 0.U

    while (test < io.in) {

    }
}

I'm getting the error that "test < io.in" is a chisel.Bool, not a Boolean. I know that I can't convert that to Scala types, right?

What is the proper way to implement this? Is it by having signals sent to/from Module1 to Module2 to indicate that the accelerator isn't done yet and to only proceed when it is? If so, wouldn't this get complex quickly, if you have several functions, each in different modules?

anc
  • 191
  • 1
  • 19

2 Answers2

1

You will need to use registers, created by the Reg family of constructors and control the flow with when, elsewhen, and otherwise. I think a good example for you is in 2.6_testers2.ipynb of chisel bootcamp. The GCD circuit is equivalent to a while loop. The circuit continues until the y register is decremented to zero. Each clock cycle corresponds to a single iteration of a software while loop. The circuit uses the ready and valid fields of the Decoupled inputs and outputs to coordinate ingesting new data and reporting when a GCD value has been computed. Take a look at this example and see if you have more questions.

Chick Markley
  • 4,023
  • 16
  • 17
  • Thank you! I've actually done the Chisel bootcamp; I guess I'm just having trouble applying it in practice. Assuming I looked at the right thing, the 3.2 sections don't seem to have examples of control flow using elsewhen/otherwise; would you mind please recommending a specific example? – anc Feb 23 '20 at 03:58
  • Sorry, I will make an example tomorrow. I've been mostly offline – Chick Markley Feb 24 '20 at 05:59
0

Just to elaborate on why you can't use a while loop with hardware values like chisel3.Bool, you can think about a chisel3 design as a Scala program that constructs a hardware design as it executes. When chisel3 runs, it is just running a program who's output is your circuit (ultimately emitted as Verilog). while is a Scala construct so it's only available during the execution of the program, it doesn't exist in the actual hardware. There's a similar question and answer about for loops on the chisel-users mailing list.

Now to answer your question, as Chick mentioned you can use the chisel3 constructs when, .elsewhen, and .otherwise to handle control flow in the actual hardware:

class Module2 extends Module {
    val io = IO(new Bundle {
        val in = Input(Reg(UInt))
    }
    val test = 0.U

    when (test < io.in) {
      // Logic for that applies when (or while) the condition is true
    } .otherwise {
      // Logic that applies when it isn't
    }
}

Also as Chick mentioned, you'll likely need some state (using Regs) since you may need to do things over multiple clock cycles. It's hard to advise beyond this simple example without more info, but please expand on your question or ask more questions if you need more help.

If so, wouldn't this get complex quickly, if you have several functions, each in different modules?

I'm not sure how to answer this bit without more context, but the whole purpose of Chisel is to make it easier to create abstractions that allow you to handle complexity. Chisel enables software engineering when designing hardware.

Jack Koenig
  • 5,840
  • 15
  • 21