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。
我在模拟包含梳状回路的设计时遇到了一些麻烦。 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。