ubaabd
ubaabd

Reputation: 435

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.

Upvotes: 4

Views: 866

Answers (2)

ɹɐʎɯɐʞ
ɹɐʎɯɐʞ

Reputation: 568

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.

Upvotes: 2

jwvh
jwvh

Reputation: 51271

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)}
}

Upvotes: 1

Related Questions