简体   繁体   中英

Functional for loop in Scala/Chisel

I'm trying to find functional equivalent of the following algorithm (not really Scala or Chisel syntax):

val x = Wire(Vec(n, UInt(L.W)))
val z = Wire(UInt(L.W))
var y = 0;
for (i <- 0 to (L-1)) {
   y = 0;
   for (j <- 0 to (n-1)) {
      y = y || x(j, i)
   }
   z(i) = y;
}

Original Problem

I have n buses, each having L wires. I want to create an OR gate that has respective bits from each bus and produce an output. The reduction operators that I know works on a single bus. For example, I could use x(1).orR to create an OR gate, but how can I achieve this on an array of buses. I'm assuming Chisel requires all hardware-related behavioral models to be functional in nature. So, my question is two fold:

  1. Do I always need to write behavioral models in Chisel using functional programming?
  2. Can I create a functional for loop that achieves the above.
z := x.reduce(_ | _)

or use tree reduction for a more efficient hardware description:

io.z := io.x.reduceTree(_ | _)

See the generated Verilog here: https://scastie.scala-lang.org/kammoh/lxOjBBtXTJ69bqgYVClexw/2

Scala is multi paradigm programming language which supports functional, object oriented, and even imperative models. You don't have to use functional programming paradigm in Chisel, but it can definitely make your code more elegant and readable.

I don't do Chisel, so I can't test it, but I think this does the same thing without all those nasty mutable variables.

(0 until L).foldLeft((Wire(Vec(n,UInt(L.W))), Wire(UInt(L.W)))){
  case ((x,z),i) =>
    z(i) = (0 until n).foldLeft(0){case (y,j) => y || x(j,i)}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM