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