Search code examples
chisel

Wiring Seq of chisel modules


I was following the answer from here: How to do a vector of modules?. I have a question regrading how to address previus items in the Seq. here is my code:

val ccfLinks = for (j <- 0 until (len - 1)) yield {
   val exe_unit = Module(new Ccflink(bitwidth))
      if (j == 0) { 
        // connnect the first stage //
        exe_unit.io.i_in := io.i_in
        exe_unit.io.q_in := io.q_in
        exe_unit.io.coeff_i := coeffs_i(0)
        exe_unit.io.coeff_q := coeffs_q(0)
        exe_unit.io.pre_i_product := SInt(0)
        exe_unit.io.pre_q_product := SInt(0)
    } else {
        // connect the rest of the chain //
        exe_unit.io.i_in := ccfLinks(j-1).io.i_out
        exe_unit.io.q_in := ccfLinks(j-1).io.q_out
        exe_unit.io.coeff_i := coeffs_i(j)
        exe_unit.io.coeff_q := coeffs_q(j)
        exe_unit.io.pre_i_product := ccfLinks(j-1).io.i_product
        exe_unit.io.pre_q_product := ccfLinks(j-1).io.q_product
    }
    exe_unit
}

I am trying to connect the current module to the previous, how do I address the previous module ? trying to compile the code above result in the next error:

"Ccf.scala:240: recursive value ccfLinks needs type [error] exe_unit.io.i_in := ccfLinks(j-1).io.i_out"


Solution

  • Here is fairly straight forward way of doing it. Note the use of foldLeft which takes an head of the list and calls the code thunk with successive pairs. Using more advanced list comprehensions can make this a little more succinct, but I think this is pretty clear what's going on when.

    class Element extends Module {
      val io = IO(new Bundle {
        val in0 = Input(UInt(8.W))
        val in1 = Input(UInt(8.W))
        val out0 = Output(UInt(8.W))
        val out1 = Output(UInt(8.W))
      })
    
      val reg0 = RegNext(io.in0, 0.U)
      val reg1 = RegNext(io.in1, 0.U)
    
      io.out0 := reg0
      io.out1 := reg1
    }
    
    /**
      * wire together a bunch of elements, into a basic queue
      * @param elementCount how big is the queue
      */
    class ElementQueue(val elementCount: Int) extends Module {
      val io = IO(new Bundle {
        val in0 = Input(UInt(8.W))
        val in1 = Input(UInt(8.W))
        val out0 = Output(UInt(8.W))
        val out1 = Output(UInt(8.W))
      })
    
      // create a scala Seq of Elements
      val elements = Seq.fill(elementCount)(Module(new Element))
    
      // wire the head to the inputs
      elements.head.io.in0 := io.in0
      elements.head.io.in1 := io.in1
    
      // wire the elements of the queue
      val last = elements.tail.foldLeft(elements.head) { case (prior, next) =>
        next.io.in0 := prior.io.out0
        next.io.in1 := prior.io.out1
        next
      }
    
      // wire the end of the queue to the outputs
      io.out0 := last.io.out0
      io.out1 := last.io.out1
    }