chisel初见
Chisel是一种硬件设计语言,它有助于ASIC和FPGA数字逻辑设计的高级电路生成和设计重用。
Chisel将硬件构造原语添加到Scala编程语言中,为设计者提供了现代编程语言的强大功能,以编写复杂的、可参数化的电路生成器,从而生成可综合的Verilog。
这种生成器方法允许创建可重用的组件和库,比如Chisel标准库中的FIFO队列和仲裁器,在保持详细的控制的同时 提高了设计中的抽象级别。
Chisel由FIRRTL (RTL的灵活中间表示)驱动,这是一个硬件编译器框架,可以对Chisel生成的电路进行优化,并支持自定义的用户定义电路转换。
chiesel代码是什么样的?
以一个实现卷积运算的FIR滤波器为例,如下框图所示:
而chisel提供类似的基础原语,作为可综合的Verilog,并可以这样使用:
// 3-point moving average implemented in the style of a FIR filter class MovingAverage3(bitWidth: Int) extends Module { val io = IO(new Bundle { val in = Input(UInt(bitWidth.W)) val out = Output(UInt(bitWidth.W)) }) val z1 = RegNext(io.in) val z2 = RegNext(z1) io.out := (io.in * 1.U) + (z1 * 1.U) + (z2 * 1.U) }
chisel生成的驱动来自生成器,如 n FIR滤波器是由系数列表定义:
// Generalized FIR filter parameterized by the convolution coefficients class FirFilter(bitWidth: Int, coeffs: Seq[UInt]) extends Module { val io = IO(new Bundle { val in = Input(UInt(bitWidth.W)) val out = Output(UInt(bitWidth.W)) }) // Create the serial-in, parallel-out shift register val zs = Reg(Vec(coeffs.length, UInt(bitWidth.W))) zs(0) := io.in for (i <- 1 until coeffs.length) { zs(i) := zs(i-1) } // Do the multiplies val products = VecInit.tabulate(coeffs.length)(i => zs(i) * coeffs(i)) // Sum up the products io.out := products.reduce(_ + _) }
并在设计中使用和重复使用它们:
val movingAverage3Filter = Module(new FirFilter(8, Seq(1.U, 1.U, 1.U))) // same 3-point moving average filter as before val delayFilter = Module(new FirFilter(8, Seq(0.U, 1.U))) // 1-cycle delay as a FIR filter val triangleFilter = Module(new FirFilter(8, Seq(1.U, 2.U, 3.U, 2.U, 1.U))) // 5-point FIR filter with a triangle impulse response
以上可以通过chiselstage转换为Verilog:
import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation} (new chisel3.stage.ChiselStage).execute( Array("-X", "verilog"), Seq(ChiselGeneratorAnnotation(() => new FirFilter(8, Seq(1.U, 1.U, 1.U)))))
或者,您可以直接生成一些Verilog检查:
val verilogString = (new chisel3.stage.ChiselStage).emitVerilog(new FirFilter(8, Seq(0.U, 1.U))) println(verilogString)
Hello world! Keep coding!