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)