CNRV

关注RISC-V和Chisel以及开源IC和EDA在中国的发展

View the Project on GitHub

[CH001] CNRV Chisel挑战赛: MuxN

题目

给定一个2:1 Mux的BlackBox和一个正整数N (N>1),用chisel生成一个N:1的Mux。

要求:代码简洁、注释充分、电路最优、chisel的可读性好,生成的verilog可读性也要好。

奖金100元人民币,2020年9月11日周五晚上12点截止。

结果

qinghai胜出,在电路最优和生成的verilog代码基本相同的情况下,chisel代码即使没有注释依然能够读懂。Scastie Link

import chisel3._
import chisel3.util._
import chisel3.stage.ChiselStage

// z = s ? i1 : i0
class Mux2[T <: Data](gen: T) extends BlackBox {
  val io = IO(new Bundle {
    val i0 = Input(gen)
    val i1 = Input(gen)
    val s = Input(Bool())
    val z = Output(gen)
  })
}

object Mux2 {
  def apply[T <: Data](s: Bool, i1: T, i0: T): T = {
    val c = Module(new Mux2(chiselTypeOf(i0)))
    c.io.s := s
    c.io.i1 := i1
    c.io.i0 := i0
    c.io.z
  }
}

// r = d[s], N: d width, 1<s<N
object MuxN {
  private def iter[T <: Data](d: Vec[T], s: UInt, dw: Int): T = dw match {
    case 1 => d(0)
    case 2 => Mux2(s(0), d(1), d(0))
    case _ =>
      val sw = s.getWidth
      val half = 1 << (sw - 1)
      val sd = d.grouped(half).toSeq
      Mux2(
        s(sw - 1),
        iter(VecInit(sd(1)), s(sw - 2, 0), sd(1).size),
        iter(VecInit(sd(0)), s(sw - 2, 0), sd(0).size)
      )
  }

  def apply[T <: Data](d: Vec[T], s: UInt): T = iter(d, s, d.size)
}

另外,浩哲的代码也很简单易懂,思想是类似的。Github Gist

以及,罗剑文 的repo文档写的很细,给出了若干种实现方式: Github Repo


CNRV Chisel Challenge