Chisel/FIRRTL 跨层次结构的持续传播和优化

Chisel/FIRRTL constant propagation & optimization across hierarchy

考虑一个执行一些简单运算并由几个参数控制的模块。一个参数控制顶层行为:模块要么从其模块端口读取输入,要么从其他参数读取输入。因此,结果要么是动态计算的,要么是在编译(咳咳,综合)时静态已知的。

正如预期的那样,Chisel 生成的 Verilog 对于该模块的各种风格具有不同的模块名称。对于静态已知结果的情况,有一个模块只有一个输出端口和一组分配了常量的内部电线,然后执行算法来驱动该输出。

是否可以要求 Chisel 或 FIRRTL 更进一步并完全优化它,即在下一层层次结构中,只需将实例化模块替换为其常量和静态已知结果? (假设这些常量值应该在综合过程中被优化掉,但也许在复杂的用例中这种精化时间优化可能有用)。

对于 Firrtl 目前知道如何持续传播的简单事物,它实际上已经做到了。问题是它目前没有 const prop 算术运算符。我计划在新年前后发布的 Chisel 3.1 版本中扩展可以持续传播的运算符。

下面是 3.0 行为常量传播逻辑 AND 和 MUX 的示例。

import chisel3._

class OptChild extends Module {
  val io = IO(new Bundle {
    val a = Input(UInt(32.W))
    val b = Input(UInt(32.W))
    val s = Input(Bool())
    val z = Output(UInt(32.W))
  })

  when (io.s) {
    io.z := io.a & "hffff0000".U
  } .otherwise {
    io.z := io.b & "h0000ffff".U
  }
}

class Optimize extends Module {
  val io = IO(new Bundle {
    val out = Output(UInt())
  })
  val child = Module(new OptChild)
  child.io.a := "hdeadbeef".U
  child.io.b := "hbadcad00".U
  child.io.s := true.B
  io.out := child.io.z

}

object OptimizeTop extends App {
  chisel3.Driver.execute(args, () => new Optimize)
}

发出的 Verilog 看起来像:

module Optimize(
  input         clock,
  input         reset,
  output [31:0] io_out
);
  assign io_out = 32'hdead0000;
endmodule