Chiselの改造をするためにいくつか型を追加する試行をしたが、一つ題材として浮動小数点をサポートできる型を作ってみたい。 この練習をするために、まずはChiselで標準的にサポートされているFixedPoint型について少し触ってみることにした。
ChiselのFixedPoint型を使うためには、以下のように宣言すればよいらしい。以下は入出力ポートをFixedPoint型にした様子。
class fixedpoint_test extends Module { val io = IO(new Bundle { val in1 = Input (FixedPoint(16.W, 12.BP)) val in2 = Input (FixedPoint(16.W, 12.BP)) val out = Output(FixedPoint(24.W, 16.BP)) }) io.out := io.in1 + io.in2 }
果たしてこれでどういうコードが出てくるかというと、
wire [15:0] _T_12; // @[fixedpoint.scala 15:20:@9.4] wire [15:0] _T_13; // @[fixedpoint.scala 15:20:@10.4] wire [19:0] _GEN_0; // @[fixedpoint.scala 15:10:@11.4] wire [19:0] _GEN_1; // @[fixedpoint.scala 15:10:@11.4] assign _T_12 = $signed(io_in1) + $signed(io_in2); // @[fixedpoint.scala 15:20:@9.4] assign _T_13 = $signed(_T_12); // @[fixedpoint.scala 15:20:@10.4] assign _GEN_0 = {{4{_T_13[15]}},_T_13}; // @[fixedpoint.scala 15:10:@11.4] assign _GEN_1 = $signed(_GEN_0) << 4; // @[fixedpoint.scala 15:10:@11.4] assign io_out = {{4{_GEN_1[19]}},_GEN_1}; // @[fixedpoint.scala 15:10:@11.4]
つまり、仮数部が12ビット、全体が16ビットのFixedPoint同氏を加算し、それを仮数部16ビット、全体で24ビットのFixedPointの値に拡張して出力する。 こういった処理が可能である。
いろんな長さのFixedPointの値を処理することができる。 以下は仮数部をずらした場合の処理。Chisel的には全体のビット数を合わせてから処理する。
指数部4ビット、仮数部12ビットのFixedPointと、指数部4ビット、仮数部8ビットの値のFixedPointの値を加算した場合の処理。
val io = IO(new Bundle { val in1 = Input (FixedPoint(16.W, 12.BP)) val in2 = Input (FixedPoint(12.W, 8.BP)) val out = Output(FixedPoint(16.W, 12.BP)) }) io.out := io.in1 + io.in2
今度はもう少し複雑。指数部4ビット、仮数部12ビットのFixedPointと、指数部6ビット、仮数部6ビットの値を加算する。
val io = IO(new Bundle { val in1 = Input (FixedPoint(16.W, 12.BP)) val in2 = Input (FixedPoint(12.W, 6.BP)) val out = Output(FixedPoint(18.W, 12.BP)) }) io.out := io.in1 + io.in2
wire [17:0] _GEN_0; // @[fixedpoint.scala 15:20:@8.4] wire [17:0] _GEN_1; // @[fixedpoint.scala 15:20:@8.4] wire [17:0] _GEN_2; // @[fixedpoint.scala 15:20:@8.4] wire [18:0] _T_11; // @[fixedpoint.scala 15:20:@8.4] wire [17:0] _T_12; // @[fixedpoint.scala 15:20:@9.4] assign _GEN_0 = {{6{io_in2[11]}},io_in2}; // @[fixedpoint.scala 15:20:@8.4] assign _GEN_1 = {{2{io_in1[15]}},io_in1}; // @[fixedpoint.scala 15:20:@8.4] assign _GEN_2 = $signed(_GEN_0) << 6; // @[fixedpoint.scala 15:20:@8.4] assign _T_11 = $signed(_GEN_1) + $signed(_GEN_2); // @[fixedpoint.scala 15:20:@8.4] assign _T_12 = $signed(_GEN_1) + $signed(_GEN_2); // @[fixedpoint.scala 15:20:@9.4] assign io_out = $signed(_T_12); // @[fixedpoint.scala 15:10:@11.4]