Chisel3:固定优先级仲裁器中的错误组合循环

时间:2017-07-19 17:46:33

标签: chisel

以下代码实现了一个n位固定优先级仲裁器。

import chisel3._
import chisel3.util._

class fixedPriorityArbiter(val n_reqs:Int = 4) extends Module {
    val NO_OF_REQS = n_reqs
    val io = IO(new Bundle {
        val req     = Input(UInt(NO_OF_REQS.W))
        val grant   = Output(UInt(NO_OF_REQS.W))
    })
    val higherPriReq   = Wire(UInt(NO_OF_REQS.W))

    higherPriReq := Cat((higherPriReq(NO_OF_REQS-2, 0) | io.req(NO_OF_REQS-2, 0)), UInt(0,1.W))
    io.grant := io.req & ~higherPriReq
}


object main_obj extends App {
  val DUT = () => new fixedPriorityArbiter()
  val margs = Array("--compiler", "verilog")

  chisel3.Driver.execute(args= margs, dut= DUT)
}

此代码报告了不一致的组合循环。凿源反映了下面电路的Verilog实现,当在Synopsys Synplify中合成时,该实现不报告任何组合环。 enter image description here

FIRRTL在Windows上的Eclipse IDE中报告以下编译错误,而FIRRTL没有生成任何Verilog源 enter image description here

1 个答案:

答案 0 :(得分:3)

FIRRTL不支持子词分析,所以在这里使用UInt你正在创建一个看似是组合循环的东西,即使它实际上并非如此。为了解决这个问题,您可以使用像Vecs这样的聚合类型,使Firrtl明确表示您正在对各个位进行处理。这是使用Vec的等效实现:

class FixedPriorityArbiter(val n_reqs: Int = 4) extends Module {
    val NO_OF_REQS = n_reqs
    val io = IO(new Bundle {
        val req     = Input(UInt(NO_OF_REQS.W))
        val grant   = Output(UInt(NO_OF_REQS.W))
    })
    val higherPriReq   = Wire(Vec(NO_OF_REQS, Bool()))

    // Vec implements scala.collection.Seq so you can use such operations as slice and map
    val upperOr = higherPriReq.slice(0, NO_OF_REQS-1).zip(io.req(NO_OF_REQS-2, 0).toBools)
                                                     .map { case (l, r) => l | r } 
    higherPriReq := false.B +: upperOr
    io.grant := io.req & ~higherPriReq.asUInt
}