/** * A naive implementation of an FIR filter with an arbitrary number of taps. */ classScalaFirFilter(taps: Seq[Int]) { var pseudoRegisters = List.fill(taps.length)(0)
defpoke(value: Int): Int = { pseudoRegisters = value :: pseudoRegisters.take(taps.length - 1) var accumulator = 0 for(i <- taps.indices) { accumulator += taps(i) * pseudoRegisters(i) } accumulator } }
classRegisterFile(readPorts: Int) extendsModule{ require(readPorts >= 0) val io = IO(newBundle { val wen = Input(Bool()) val waddr = Input(UInt(5.W)) val wdata = Input(UInt(32.W)) val raddr = Input(Vec(readPorts, UInt(5.W))) val rdata = Output(Vec(readPorts, UInt(32.W))) }) // A Register of a vector of UInts val reg = RegInit(VecInit(Seq.fill(32)(0.U(32.W)))) when (io.wen) { reg(io.waddr) := io.wdata } for (i <- 0 until readPorts) { when (io.raddr(i) === 0.U) { io.rdata(i) := 0.U } .otherwise { io.rdata(i) := reg(io.raddr(i)) } } }
使用生成器的方法实现
另一种实现方法,我们将在后面讨论。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classMyManyDynamicElementVecFir(length: Int) extendsModule{ val io = IO(newBundle { val in = Input(UInt(8.W)) val valid = Input(Bool()) val out = Output(UInt(8.W)) val consts = Input(Vec(length, UInt(8.W))) }) // Such concision! You'll learn what all this means later. val taps = Seq(io.in) ++ Seq.fill(io.consts.length - 1)(RegInit(0.U(8.W))) taps.zip(taps.tail).foreach { case (a, b) => when (io.valid) { b := a } }
io.out := taps.zip(io.consts).map { case (a, b) => a * b }.reduce(_ + _) }