chisel-firrtl 组合循环处理

chisel-firrtl combinational loop handling

我在模拟包含梳状回路的设计时遇到了一些麻烦。 Firrtl 抛出异常

"No valid linearization for cyclic graph"

虽然 verilator 后端正常但有警告。

是否可以用 firrtl 后端模拟这样的设计? 我们是否可以在详细说明时将 --no-check-comb-loops 应用于所有设计而不是部分设计?

示例代码在这里:

import chisel3._
import chisel3.iotesters.PeekPokeTester

import org.scalatest.{FlatSpec, Matchers}

class Xor extends core.ImplicitModule {
  val io = IO(new Bundle {
    val a = Input(UInt(4.W))
    val b = Input(UInt(4.W))
    val out = Output(UInt(4.W))
  })

  io.out <> (io.a ^ io.b)
}

class Reverse extends core.ImplicitModule {
  val io = IO(new Bundle {
    val in = Input(UInt(4.W))
    val out = Output(UInt(4.W))
  })

  io.out <> util.Reverse(io.in)
}

class Loop extends core.ImplicitModule {
  val io = IO(new Bundle {
    val a = Input(UInt(4.W))
    val b = Input(UInt(4.W))
    val mux = Input(Bool())
    val out = Output(UInt(4.W))
  })
  val x = Module(new Xor)
  val r = Module(new Reverse)

  r.io.in <> Mux(io.mux, io.a, x.io.out)

  x.io.a <> Mux(io.mux, r.io.out, io.a)
  x.io.b <> io.b

  io.out <> Mux(io.mux, x.io.out, r.io.out)
}

class LoopBackExampleTester(cc: Loop) extends PeekPokeTester(cc) {
  poke(cc.io.mux, false)

  poke(cc.io.a, 0)
  poke(cc.io.b, 1)

  step(1)

  expect(cc.io.out, 8)
}

class LoopBackExample extends FlatSpec with Matchers {
  behavior of "Loop"

  it should "work" in {
    chisel3.iotesters.Driver.execute(Array("--no-check-comb-loops", "--fr-allow-cycles"), () => new Loop) { cc =>
      new LoopBackExampleTester(cc)
    } should be(true)
  }
}

首先我要指出,Chisel 旨在使同步的、基于触发器的数字设计更容易、更灵活。它不是旨在表示所有可能的数字电路。从根本上说,Chisel 的存在是为了让大多数事情变得更容易,同时将与实现技术(如模拟)更紧密耦合的事情留给 Verilog 或其他语言。

Chisel(以及 FIRRTL)不支持这种明显的组合循环,即使它可能表明循环不会由于 mux 选择上的实际值而发生。这样的循环会破坏综合中的时序分析,并可能使创建合理的电路变得困难。此外,循环 "can't occur" 并不是真的。除非在这里进行了仔细的物理设计,否则可能会有短暂的时刻(一个时钟周期的一小部分)出现短路,这可能会导致您的 ASIC 出现重大问题。除非你正在构建类似环形振荡器的东西,否则大多数物理设计团队都会要求你无论如何都不要这样做。对于有必要的情况,这些设计通常与实现技术(使用标准单元手工设计)密切相关,因此不属于 Chisel 的范畴。

如果您需要这样的循环,您可以用 Verilog 表达它并在您的 Chisel 中将设计实例化为 BlackBox。